summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kconfig2
-rw-r--r--Makefile20
-rw-r--r--Makefile.external20
-rw-r--r--Makefile.kernel14
-rw-r--r--dev.h419
-rw-r--r--fwcmd.c (renamed from mwl_fwcmd.c)3020
-rw-r--r--fwcmd.h (renamed from mwl_fwcmd.h)31
-rw-r--r--fwdl.c (renamed from mwl_fwdl.c)129
-rw-r--r--fwdl.h19
-rw-r--r--isr.c142
-rw-r--r--isr.h20
-rw-r--r--mac80211.c (renamed from mwl_mac80211.c)618
-rw-r--r--mac80211.h19
-rw-r--r--main.c (renamed from mwl_main.c)672
-rw-r--r--mwl_debug.c207
-rw-r--r--mwl_debug.h118
-rw-r--r--mwl_dev.h465
-rw-r--r--mwl_fwdl.h29
-rw-r--r--mwl_mac80211.h32
-rw-r--r--mwl_rx.h30
-rw-r--r--mwl_tx.h34
-rw-r--r--rx.c (renamed from mwl_rx.c)519
-rw-r--r--rx.h19
-rw-r--r--sysadpt.h (renamed from mwl_sysadpt.h)35
-rw-r--r--test/hostapd.conf.1.multi_bssid2
-rw-r--r--test/hostapd.conf.1.open2
-rw-r--r--test/hostapd.conf.36.multi_bssid2
-rw-r--r--test/hostapd.conf.36.open2
-rw-r--r--test/hostapd.conf.36.open.80mhz2
-rw-r--r--test/hostapd.conf.36.wpa2pskaes2
-rw-r--r--test/hostapd.conf.36.wpa2pskaes.80mhz2
-rw-r--r--[-rwxr-xr-x]test/wpa_supplicant.conf.open0
-rw-r--r--[-rwxr-xr-x]test/wpa_supplicant.conf.psk0
-rw-r--r--tx.c (renamed from mwl_tx.c)1024
-rw-r--r--tx.h22
35 files changed, 3101 insertions, 4592 deletions
diff --git a/Kconfig b/Kconfig
index ffafe5d..fd60ea2 100644
--- a/Kconfig
+++ b/Kconfig
@@ -1,6 +1,6 @@
config MWLWIFI
tristate "Marvell Wireless WiFi driver (mwlwifi)"
- depends on PCI && MAC80211
+ depends on PCI && MAC80211 && MWIFIEX_PCIE=n
select FW_LOADER
select OF
---help---
diff --git a/Makefile b/Makefile
index 5771f78..f5e7e74 100644
--- a/Makefile
+++ b/Makefile
@@ -1,23 +1,19 @@
obj-m += mwlwifi.o
-mwlwifi-objs += mwl_main.o
-mwlwifi-objs += mwl_mac80211.o
-mwlwifi-objs += mwl_fwdl.o
-mwlwifi-objs += mwl_fwcmd.o
-mwlwifi-objs += mwl_tx.o
-mwlwifi-objs += mwl_rx.o
-mwlwifi-objs += mwl_debug.o
+mwlwifi-objs += main.o
+mwlwifi-objs += mac80211.o
+mwlwifi-objs += fwdl.o
+mwlwifi-objs += fwcmd.o
+mwlwifi-objs += tx.o
+mwlwifi-objs += rx.o
+mwlwifi-objs += isr.o
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
-ifeq (1, $(MWLDBG))
-EXTRA_CFLAGS+= -DMWL_DEBUG
-endif
-
EXTRA_CFLAGS+= -I${KDIR}
-EXTRA_CFLAGS+= -O2 -funroll-loops -DDEBUG
+EXTRA_CFLAGS+= -O2 -funroll-loops
EXTRA_CFLAGS+= -I${PWD}
diff --git a/Makefile.external b/Makefile.external
index 5771f78..f5e7e74 100644
--- a/Makefile.external
+++ b/Makefile.external
@@ -1,23 +1,19 @@
obj-m += mwlwifi.o
-mwlwifi-objs += mwl_main.o
-mwlwifi-objs += mwl_mac80211.o
-mwlwifi-objs += mwl_fwdl.o
-mwlwifi-objs += mwl_fwcmd.o
-mwlwifi-objs += mwl_tx.o
-mwlwifi-objs += mwl_rx.o
-mwlwifi-objs += mwl_debug.o
+mwlwifi-objs += main.o
+mwlwifi-objs += mac80211.o
+mwlwifi-objs += fwdl.o
+mwlwifi-objs += fwcmd.o
+mwlwifi-objs += tx.o
+mwlwifi-objs += rx.o
+mwlwifi-objs += isr.o
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
-ifeq (1, $(MWLDBG))
-EXTRA_CFLAGS+= -DMWL_DEBUG
-endif
-
EXTRA_CFLAGS+= -I${KDIR}
-EXTRA_CFLAGS+= -O2 -funroll-loops -DDEBUG
+EXTRA_CFLAGS+= -O2 -funroll-loops
EXTRA_CFLAGS+= -I${PWD}
diff --git a/Makefile.kernel b/Makefile.kernel
index ad97138..c6e03a3 100644
--- a/Makefile.kernel
+++ b/Makefile.kernel
@@ -1,9 +1,9 @@
obj-$(CONFIG_MWLWIFI) += mwlwifi.o
-mwlwifi-objs += mwl_main.o
-mwlwifi-objs += mwl_mac80211.o
-mwlwifi-objs += mwl_fwdl.o
-mwlwifi-objs += mwl_fwcmd.o
-mwlwifi-objs += mwl_tx.o
-mwlwifi-objs += mwl_rx.o
-mwlwifi-objs += mwl_debug.o
+mwlwifi-objs += main.o
+mwlwifi-objs += mac80211.o
+mwlwifi-objs += fwdl.o
+mwlwifi-objs += fwcmd.o
+mwlwifi-objs += tx.o
+mwlwifi-objs += rx.o
+mwlwifi-objs += isr.o
diff --git a/dev.h b/dev.h
new file mode 100644
index 0000000..c2c5a06
--- /dev/null
+++ b/dev.h
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Description: This file defines device related information.
+ */
+
+#ifndef _mwl_dev_h_
+#define _mwl_dev_h_
+
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <net/mac80211.h>
+
+/* Map to 0x80000000 (Bus control) on BAR0 */
+#define MACREG_REG_H2A_INTERRUPT_EVENTS 0x00000C18 /* (From host to ARM) */
+#define MACREG_REG_H2A_INTERRUPT_CAUSE 0x00000C1C /* (From host to ARM) */
+#define MACREG_REG_H2A_INTERRUPT_MASK 0x00000C20 /* (From host to ARM) */
+#define MACREG_REG_H2A_INTERRUPT_CLEAR_SEL 0x00000C24 /* (From host to ARM) */
+#define MACREG_REG_H2A_INTERRUPT_STATUS_MASK 0x00000C28 /* (From host to ARM) */
+
+#define MACREG_REG_A2H_INTERRUPT_EVENTS 0x00000C2C /* (From ARM to host) */
+#define MACREG_REG_A2H_INTERRUPT_CAUSE 0x00000C30 /* (From ARM to host) */
+#define MACREG_REG_A2H_INTERRUPT_MASK 0x00000C34 /* (From ARM to host) */
+#define MACREG_REG_A2H_INTERRUPT_CLEAR_SEL 0x00000C38 /* (From ARM to host) */
+#define MACREG_REG_A2H_INTERRUPT_STATUS_MASK 0x00000C3C /* (From ARM to host) */
+
+/* Map to 0x80000000 on BAR1 */
+#define MACREG_REG_GEN_PTR 0x00000C10
+#define MACREG_REG_INT_CODE 0x00000C14
+
+/* Bit definitio for MACREG_REG_A2H_INTERRUPT_CAUSE (A2HRIC) */
+#define MACREG_A2HRIC_BIT_TX_DONE BIT(0)
+#define MACREG_A2HRIC_BIT_RX_RDY BIT(1)
+#define MACREG_A2HRIC_BIT_OPC_DONE BIT(2)
+#define MACREG_A2HRIC_BIT_MAC_EVENT BIT(3)
+#define MACREG_A2HRIC_BIT_RX_PROBLEM BIT(4)
+#define MACREG_A2HRIC_BIT_RADIO_OFF BIT(5)
+#define MACREG_A2HRIC_BIT_RADIO_ON BIT(6)
+#define MACREG_A2HRIC_BIT_RADAR_DETECT BIT(7)
+#define MACREG_A2HRIC_BIT_ICV_ERROR BIT(8)
+#define MACREG_A2HRIC_BIT_WEAKIV_ERROR BIT(9)
+#define MACREG_A2HRIC_BIT_QUEUE_EMPTY BIT(10)
+#define MACREG_A2HRIC_BIT_QUEUE_FULL BIT(11)
+#define MACREG_A2HRIC_BIT_CHAN_SWITCH BIT(12)
+#define MACREG_A2HRIC_BIT_TX_WATCHDOG BIT(13)
+#define MACREG_A2HRIC_BA_WATCHDOG BIT(14)
+/* 15 taken by ISR_TXACK */
+#define MACREG_A2HRIC_BIT_SSU_DONE BIT(16)
+#define MACREG_A2HRIC_CONSEC_TXFAIL BIT(17)
+
+#define ISR_SRC_BITS (MACREG_A2HRIC_BIT_RX_RDY | \
+ MACREG_A2HRIC_BIT_TX_DONE | \
+ MACREG_A2HRIC_BIT_OPC_DONE | \
+ MACREG_A2HRIC_BIT_MAC_EVENT | \
+ MACREG_A2HRIC_BIT_WEAKIV_ERROR | \
+ MACREG_A2HRIC_BIT_ICV_ERROR | \
+ MACREG_A2HRIC_BIT_SSU_DONE | \
+ MACREG_A2HRIC_BIT_RADAR_DETECT | \
+ MACREG_A2HRIC_BIT_CHAN_SWITCH | \
+ MACREG_A2HRIC_BIT_TX_WATCHDOG | \
+ MACREG_A2HRIC_BIT_QUEUE_EMPTY | \
+ MACREG_A2HRIC_BA_WATCHDOG | \
+ MACREG_A2HRIC_CONSEC_TXFAIL)
+
+#define MACREG_A2HRIC_BIT_MASK ISR_SRC_BITS
+
+/* Bit definitio for MACREG_REG_H2A_INTERRUPT_CAUSE (H2ARIC) */
+#define MACREG_H2ARIC_BIT_PPA_READY BIT(0)
+#define MACREG_H2ARIC_BIT_DOOR_BELL BIT(1)
+#define MACREG_H2ARIC_BIT_PS BIT(2)
+#define MACREG_H2ARIC_BIT_PSPOLL BIT(3)
+#define ISR_RESET BIT(15)
+#define ISR_RESET_AP33 BIT(26)
+
+/* Data descriptor related constants */
+#define EAGLE_RXD_CTRL_DRIVER_OWN 0x00
+#define EAGLE_RXD_CTRL_DMA_OWN 0x80
+
+#define EAGLE_RXD_STATUS_OK 0x01
+
+#define EAGLE_TXD_STATUS_IDLE 0x00000000
+#define EAGLE_TXD_STATUS_OK 0x00000001
+#define EAGLE_TXD_STATUS_FW_OWNED 0x80000000
+
+/* Antenna control */
+#define ANTENNA_TX_4_AUTO 0
+#define ANTENNA_TX_2 3
+#define ANTENNA_RX_4_AUTO 0
+#define ANTENNA_RX_2 2
+
+/* Band related constants */
+#define BAND_24_CHANNEL_NUM 14
+#define BAND_24_RATE_NUM 13
+#define BAND_50_CHANNEL_NUM 24
+#define BAND_50_RATE_NUM 8
+
+/* vif and station */
+#define NUM_WEP_KEYS 4
+#define MWL_MAX_TID 8
+#define MWL_AMSDU_SIZE_4K 0
+#define MWL_AMSDU_SIZE_8K 1
+
+/* power init */
+#define MWL_POWER_INIT_1 1
+#define MWL_POWER_INIT_2 2
+
+enum {
+ MWL8864 = 0,
+ MWL8897,
+ MWLUNKNOWN,
+};
+
+enum {
+ AP_MODE_11AC = 0x10, /* generic 11ac indication mode */
+ AP_MODE_2_4GHZ_11AC_MIXED = 0x17,
+};
+
+enum {
+ AMPDU_NO_STREAM,
+ AMPDU_STREAM_NEW,
+ AMPDU_STREAM_IN_PROGRESS,
+ AMPDU_STREAM_ACTIVE,
+};
+
+struct mwl_chip_info {
+ char *part_name;
+ char *fw_image;
+};
+
+struct mwl_tx_pwr_tbl {
+ u8 channel;
+ u8 setcap;
+ u16 tx_power[SYSADPT_TX_POWER_LEVEL_TOTAL];
+ u8 cdd; /* 0: off, 1: on */
+ u16 txantenna2;
+};
+
+struct mwl_hw_data {
+ u32 fw_release_num; /* MajNbr:MinNbr:SubMin:PatchLevel */
+ u8 hw_version; /* plain number indicating version */
+ u8 host_interface; /* plain number of interface */
+ u16 max_num_tx_desc; /* max number of TX descriptors */
+ u16 max_num_mc_addr; /* max number multicast addresses */
+ u16 num_antennas; /* number antennas used */
+ u16 region_code; /* region (eg. 0x10 for USA FCC) */
+ unsigned char mac_addr[ETH_ALEN]; /* well known -> AA:BB:CC:DD:EE:FF */
+};
+
+#define MWL_TX_RATE_FORMAT_MASK 0x00000003
+#define MWL_TX_RATE_BANDWIDTH_MASK 0x00000030
+#define MWL_TX_RATE_BANDWIDTH_SHIFT 4
+#define MWL_TX_RATE_SHORTGI_MASK 0x00000040
+#define MWL_TX_RATE_SHORTGI_SHIFT 6
+#define MWL_TX_RATE_RATEIDMCS_MASK 0x00007F00
+#define MWL_TX_RATE_RATEIDMCS_SHIFT 8
+
+struct mwl_tx_desc {
+ u8 data_rate;
+ u8 tx_priority;
+ __le16 qos_ctrl;
+ __le32 pkt_ptr;
+ __le16 pkt_len;
+ u8 dest_addr[ETH_ALEN];
+ __le32 pphys_next;
+ __le32 sap_pkt_info;
+ __le32 rate_info;
+ u8 type;
+ u8 xmit_control; /* bit 0: use rateinfo, bit 1: disable ampdu */
+ __le16 reserved;
+ __le32 tcpack_sn;
+ __le32 tcpack_src_dst;
+ struct sk_buff *psk_buff;
+ struct mwl_tx_desc *pnext;
+ u8 reserved1[2];
+ u8 packet_info;
+ u8 packet_id;
+ __le16 packet_len_and_retry;
+ __le16 packet_rate_info;
+ u8 *sta_info;
+ __le32 status;
+} __packed;
+
+#define MWL_RX_RATE_FORMAT_MASK 0x0007
+#define MWL_RX_RATE_NSS_MASK 0x0018
+#define MWL_RX_RATE_NSS_SHIFT 3
+#define MWL_RX_RATE_BW_MASK 0x0060
+#define MWL_RX_RATE_BW_SHIFT 5
+#define MWL_RX_RATE_GI_MASK 0x0080
+#define MWL_RX_RATE_GI_SHIFT 7
+#define MWL_RX_RATE_RT_MASK 0xFF00
+#define MWL_RX_RATE_RT_SHIFT 8
+
+struct mwl_rx_desc {
+ __le16 pkt_len; /* total length of received data */
+ __le16 rate; /* receive rate information */
+ __le32 pphys_buff_data; /* physical address of payload data */
+ __le32 pphys_next; /* physical address of next RX desc */
+ __le16 qos_ctrl; /* received QosCtrl field variable */
+ __le16 ht_sig2; /* like name states */
+ __le32 hw_rssi_info;
+ __le32 hw_noise_floor_info;
+ u8 noise_floor;
+ u8 reserved[3];
+ u8 rssi; /* received signal strengt indication */
+ u8 status; /* status field containing USED bit */
+ u8 channel; /* channel this pkt was received on */
+ u8 rx_control; /* the control element of the desc */
+ /* above are 32bits aligned and is same as FW, RxControl put at end
+ * for sync
+ */
+ struct sk_buff *psk_buff; /* associated sk_buff for Linux */
+ void *pbuff_data; /* virtual address of payload data */
+ struct mwl_rx_desc *pnext; /* virtual address of next RX desc */
+} __packed;
+
+struct mwl_desc_data {
+ dma_addr_t pphys_tx_ring; /* ptr to first TX desc (phys.) */
+ struct mwl_tx_desc *ptx_ring; /* ptr to first TX desc (virt.) */
+ struct mwl_tx_desc *pnext_tx_desc; /* next TX desc that can be used */
+ struct mwl_tx_desc *pstale_tx_desc;/* the staled TX descriptor */
+ dma_addr_t pphys_rx_ring; /* ptr to first RX desc (phys.) */
+ struct mwl_rx_desc *prx_ring; /* ptr to first RX desc (virt.) */
+ struct mwl_rx_desc *pnext_rx_desc; /* next RX desc that can be used */
+ unsigned int wcb_base; /* FW base offset for registers */
+ unsigned int rx_desc_write; /* FW descriptor write position */
+ unsigned int rx_desc_read; /* FW descriptor read position */
+ unsigned int rx_buf_size; /* length of the RX buffers */
+} __packed;
+
+struct mwl_ampdu_stream {
+ struct ieee80211_sta *sta;
+ u8 tid;
+ u8 state;
+ u8 idx;
+};
+
+struct mwl_priv {
+ struct ieee80211_hw *hw;
+ const struct firmware *fw_ucode;
+ int chip_type;
+
+ struct device_node *dt_node;
+ struct device_node *pwr_node;
+ bool disable_2g;
+ bool disable_5g;
+ int antenna_tx;
+ int antenna_rx;
+
+ struct mwl_tx_pwr_tbl tx_pwr_tbl[SYSADPT_MAX_NUM_CHANNELS];
+ u32 cdd; /* 0: off, 1: on */
+ u16 txantenna2;
+ u8 powinited;
+ u16 max_tx_pow[SYSADPT_TX_POWER_LEVEL_TOTAL]; /* max tx power (dBm) */
+ u16 target_powers[SYSADPT_TX_POWER_LEVEL_TOTAL]; /* target powers */
+ u8 cal_tbl[200];
+
+ struct pci_dev *pdev;
+ void *iobase0; /* MEM Base Address Register 0 */
+ void *iobase1; /* MEM Base Address Register 1 */
+ u32 next_bar_num;
+
+ spinlock_t fwcmd_lock; /* for firmware command */
+ unsigned short *pcmd_buf; /* pointer to CmdBuf (virtual) */
+ dma_addr_t pphys_cmd_buf; /* pointer to CmdBuf (physical) */
+ bool in_send_cmd;
+
+ int irq;
+ struct mwl_hw_data hw_data; /* Adapter HW specific info */
+
+ /* various descriptor data */
+ spinlock_t tx_desc_lock; /* for tx descriptor data */
+ struct mwl_desc_data desc_data[SYSADPT_NUM_OF_DESC_DATA];
+ struct sk_buff_head txq[SYSADPT_NUM_OF_DESC_DATA];
+ struct sk_buff_head delay_q;
+ /* number of descriptors owned by fw at any one time */
+ int fw_desc_cnt[SYSADPT_NUM_OF_DESC_DATA];
+
+ struct tasklet_struct tx_task;
+ struct tasklet_struct rx_task;
+ int txq_limit;
+ bool is_tx_schedule;
+ int recv_limit;
+ bool is_rx_schedule;
+ s8 noise; /* Most recently reported noise in dBm */
+ struct ieee80211_supported_band band_24;
+ struct ieee80211_channel channels_24[BAND_24_CHANNEL_NUM];
+ struct ieee80211_rate rates_24[BAND_24_RATE_NUM];
+ struct ieee80211_supported_band band_50;
+ struct ieee80211_channel channels_50[BAND_50_CHANNEL_NUM];
+ struct ieee80211_rate rates_50[BAND_50_RATE_NUM];
+
+ u32 ap_macids_supported;
+ u32 sta_macids_supported;
+ u32 macids_used;
+ spinlock_t vif_lock; /* for private interface info */
+ struct list_head vif_list; /* List of interfaces. */
+ u32 running_bsses; /* bitmap of running BSSes */
+
+ spinlock_t sta_lock; /* for private sta info */
+ struct list_head sta_list; /* List of stations */
+
+ bool radio_on;
+ bool radio_short_preamble;
+ bool wmm_enabled;
+ struct ieee80211_tx_queue_params wmm_params[SYSADPT_TX_WMM_QUEUES];
+
+ /* Ampdu stream information */
+ u8 num_ampdu_queues;
+ spinlock_t stream_lock; /* for ampdu stream */
+ struct mwl_ampdu_stream ampdu[SYSADPT_TX_AMPDU_QUEUES];
+ struct work_struct watchdog_ba_handle;
+};
+
+struct beacon_info {
+ bool valid;
+ u16 cap_info;
+ u8 b_rate_set[SYSADPT_MAX_DATA_RATES_G];
+ u8 op_rate_set[SYSADPT_MAX_DATA_RATES_G];
+ u16 ie_wmm_len; /* Keep WMM IE */
+ u8 *ie_wmm_ptr;
+ u16 ie_rsn_len; /* Keep WPA IE */
+ u8 *ie_rsn_ptr;
+ u16 ie_rsn48_len; /* Keep WPA2 IE */
+ u8 *ie_rsn48_ptr;
+ u16 ie_ht_len; /* Keep HT IE */
+ u8 *ie_ht_ptr;
+ u8 ie_list_ht[148];
+ u16 ie_vht_len; /* Keep VHT IE */
+ u8 *ie_vht_ptr;
+ u8 ie_list_vht[24];
+};
+
+struct mwl_vif {
+ struct list_head list;
+ struct ieee80211_vif *vif;
+ int macid; /* Firmware macid for this vif. */
+ u16 seqno; /* Non AMPDU sequence number assigned by driver. */
+ struct { /* Saved WEP keys */
+ u8 enabled;
+ u8 key[sizeof(struct ieee80211_key_conf) + WLAN_KEY_LEN_WEP104];
+ } wep_key_conf[NUM_WEP_KEYS];
+ u8 bssid[ETH_ALEN]; /* BSSID */
+ u8 sta_mac[ETH_ALEN]; /* Station mac address */
+ /* A flag to indicate is HW crypto is enabled for this bssid */
+ bool is_hw_crypto_enabled;
+ /* Indicate if this is station mode */
+ bool is_sta;
+ struct beacon_info beacon_info;
+ u16 iv16;
+ u32 iv32;
+ s8 keyidx;
+};
+
+struct mwl_tx_info {
+ u32 start_time;
+ u32 pkts;
+};
+
+struct mwl_amsdu_frag {
+ struct sk_buff *skb;
+ u8 pad;
+ u8 *cur_pos;
+ u8 num;
+ u32 jiffies;
+};
+
+struct mwl_amsdu_ctrl {
+ struct mwl_amsdu_frag frag[SYSADPT_TX_WMM_QUEUES];
+ u8 cap;
+};
+
+struct mwl_sta {
+ struct list_head list;
+ struct ieee80211_sta *sta;
+ bool is_ampdu_allowed;
+ struct mwl_tx_info tx_stats[MWL_MAX_TID];
+ bool is_amsdu_allowed;
+ struct mwl_amsdu_ctrl amsdu_ctrl;
+ u16 iv16;
+ u32 iv32;
+};
+
+/* DMA header used by firmware and hardware. */
+struct mwl_dma_data {
+ __le16 fwlen;
+ struct ieee80211_hdr wh;
+ char data[0];
+} __packed;
+
+/* Transmission information to transmit a socket buffer. */
+struct mwl_tx_ctrl {
+ u8 tx_priority;
+ u16 qos_ctrl;
+ u8 type;
+ u8 xmit_control;
+ void *sta;
+ void *vif;
+ void *k_conf;
+} __packed;
+
+static inline struct mwl_vif *mwl_dev_get_vif(const struct ieee80211_vif *vif)
+{
+ return (struct mwl_vif *)&vif->drv_priv;
+}
+
+static inline struct mwl_sta *mwl_dev_get_sta(const struct ieee80211_sta *sta)
+{
+ return (struct mwl_sta *)&sta->drv_priv;
+}
+
+#endif /* _mwl_dev_h_ */
diff --git a/mwl_fwcmd.c b/fwcmd.c
index e5ddb44..1fb2ed9 100644
--- a/mwl_fwcmd.c
+++ b/fwcmd.c
@@ -1,36 +1,24 @@
/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
/* Description: This file implements frimware host command related functions.
-*/
+ */
#include <linux/etherdevice.h>
-#include "mwl_sysadpt.h"
-#include "mwl_dev.h"
-#include "mwl_debug.h"
-#include "mwl_fwcmd.h"
-
-/* CONSTANTS AND MACROS
-*/
+#include "sysadpt.h"
+#include "dev.h"
+#include "fwcmd.h"
#define MAX_WAIT_FW_COMPLETE_ITERATIONS 10000
+#define MAX_WAIT_GET_HW_SPECS_ITERATONS 3
-/* 16 bit host command code
- */
+/* 16 bit host command code */
#define HOSTCMD_CMD_GET_HW_SPEC 0x0003
#define HOSTCMD_CMD_SET_HW_SPEC 0x0004
#define HOSTCMD_CMD_802_11_GET_STAT 0x0014
@@ -60,10 +48,9 @@
#define HOSTCMD_CMD_FW_FLUSH_TIMER 0x1148
#define HOSTCMD_CMD_SET_CDD 0x1150
-/* Define general result code for each command
- */
-#define HOSTCMD_RESULT_OK 0x0000 /* OK */
-/* Genenral error */
+/* Define general result code for each command */
+#define HOSTCMD_RESULT_OK 0x0000
+/* General error */
#define HOSTCMD_RESULT_ERROR 0x0001
/* Command is not valid */
#define HOSTCMD_RESULT_NOT_SUPPORT 0x0002
@@ -74,8 +61,7 @@
/* Data buffer is not big enough */
#define HOSTCMD_RESULT_PARTIAL_DATA 0x0005
-/* Define channel related constants
- */
+/* Define channel related constants */
#define FREQ_BAND_2DOT4GHZ 0x1
#define FREQ_BAND_4DOT9GHZ 0x2
#define FREQ_BAND_5GHZ 0x4
@@ -90,77 +76,45 @@
#define EXT_CH_BELOW_CTRL_CH 0x3
#define NO_EXT_CHANNEL 0x0
-/* active primary 1st 20MHz channel */
#define ACT_PRIMARY_CHAN_0 0
-/* active primary 2nd 20MHz channel */
#define ACT_PRIMARY_CHAN_1 1
-/* active primary 3rd 20MHz channel */
#define ACT_PRIMARY_CHAN_2 2
-/* active primary 4th 20MHz channel */
#define ACT_PRIMARY_CHAN_3 3
-/* active primary 5th 20MHz channel */
-#define ACT_PRIMARY_CHAN_4 4
-/* active primary 6th 20MHz channel */
-#define ACT_PRIMARY_CHAN_5 5
-/* active primary 7th 20MHz channel */
-#define ACT_PRIMARY_CHAN_6 6
-/* active primary 8th 20MHz channel */
-#define ACT_PRIMARY_CHAN_7 7
-
-/* Define rate related constants
- */
+
+/* Define rate related constants */
#define HOSTCMD_ACT_NOT_USE_FIXED_RATE 0x0002
-/* Define station related constants
- */
+/* Define station related constants */
#define HOSTCMD_ACT_STA_ACTION_ADD 0
#define HOSTCMD_ACT_STA_ACTION_REMOVE 2
-/* Define key related constants
- */
+/* Define key related constants */
#define MAX_ENCR_KEY_LENGTH 16
#define MIC_KEY_LENGTH 8
-/* Key type is WEP */
#define KEY_TYPE_ID_WEP 0x00
-/* Key type is TKIP */
#define KEY_TYPE_ID_TKIP 0x01
-/* Key type is AES-CCMP */
#define KEY_TYPE_ID_AES 0x02
-/* Group key for TX */
#define ENCR_KEY_FLAG_TXGROUPKEY 0x00000004
-/* pairwise */
#define ENCR_KEY_FLAG_PAIRWISE 0x00000008
-/* Sequence counters are valid */
#define ENCR_KEY_FLAG_TSC_VALID 0x00000040
-/* Tx key for WEP */
#define ENCR_KEY_FLAG_WEP_TXKEY 0x01000000
-/* Tx/Rx MIC keys are valid */
#define ENCR_KEY_FLAG_MICKEY_VALID 0x02000000
-/* Define block ack related constants
- */
+/* Define block ack related constants */
#define BASTREAM_FLAG_IMMEDIATE_TYPE 1
#define BASTREAM_FLAG_DIRECTION_UPSTREAM 0
-/* Define general purpose action
- */
+/* Define general purpose action */
#define HOSTCMD_ACT_GEN_SET 0x0001
#define HOSTCMD_ACT_GEN_SET_LIST 0x0002
#define HOSTCMD_ACT_GEN_GET_LIST 0x0003
-/* Misc
-*/
-#define MWL_SPIN_LOCK(X) SPIN_LOCK_IRQSAVE(X, flags)
-#define MWL_SPIN_UNLOCK(X) SPIN_UNLOCK_IRQRESTORE(X, flags)
-
+/* Misc */
#define MAX_ENCR_KEY_LENGTH 16
#define MIC_KEY_LENGTH 8
-/* TYPE DEFINITION
-*/
-
enum {
WL_DISABLE = 0,
WL_ENABLE = 1,
@@ -204,40 +158,34 @@ enum mac_type {
WL_MAC_TYPE_SECONDARY_AP,
};
-/* General host command header
- */
-
+/* General host command header */
struct hostcmd_header {
- u16 cmd;
- u16 len;
+ __le16 cmd;
+ __le16 len;
u8 seq_num;
u8 macid;
- u16 result;
+ __le16 result;
} __packed;
-/* HOSTCMD_CMD_GET_HW_SPEC
- */
-
+/* HOSTCMD_CMD_GET_HW_SPEC */
struct hostcmd_cmd_get_hw_spec {
struct hostcmd_header cmd_hdr;
u8 version; /* version of the HW */
u8 host_if; /* host interface */
- u16 num_wcb; /* Max. number of WCB FW can handle */
- u16 num_mcast_addr; /* MaxNbr of MC addresses FW can handle */
+ __le16 num_wcb; /* Max. number of WCB FW can handle */
+ __le16 num_mcast_addr; /* MaxNbr of MC addresses FW can handle */
u8 permanent_addr[ETH_ALEN]; /* MAC address programmed in HW */
- u16 region_code;
- u16 num_antenna; /* Number of antenna used */
- u32 fw_release_num; /* 4 byte of FW release number */
- u32 wcb_base0;
- u32 rxpd_wr_ptr;
- u32 rxpd_rd_ptr;
- u32 fw_awake_cookie;
- u32 wcb_base[SYSADPT_TOTAL_TX_QUEUES - 1];
+ __le16 region_code;
+ __le16 num_antenna; /* Number of antenna used */
+ __le32 fw_release_num; /* 4 byte of FW release number */
+ __le32 wcb_base0;
+ __le32 rxpd_wr_ptr;
+ __le32 rxpd_rd_ptr;
+ __le32 fw_awake_cookie;
+ __le32 wcb_base[SYSADPT_TOTAL_TX_QUEUES - 1];
} __packed;
-/* HOSTCMD_CMD_SET_HW_SPEC
- */
-
+/* HOSTCMD_CMD_SET_HW_SPEC */
struct hostcmd_cmd_set_hw_spec {
struct hostcmd_header cmd_hdr;
/* HW revision */
@@ -245,208 +193,164 @@ struct hostcmd_cmd_set_hw_spec {
/* Host interface */
u8 host_if;
/* Max. number of Multicast address FW can handle */
- u16 num_mcast_addr;
+ __le16 num_mcast_addr;
/* MAC address */
u8 permanent_addr[ETH_ALEN];
/* Region Code */
- u16 region_code;
+ __le16 region_code;
/* 4 byte of FW release number, example 0x1234=1.2.3.4 */
- u32 fw_release_num;
+ __le32 fw_release_num;
/* Firmware awake cookie - used to ensure that the device
* is not in sleep mode
*/
- u32 fw_awake_cookie;
+ __le32 fw_awake_cookie;
/* Device capabilities (see above) */
- u32 device_caps;
+ __le32 device_caps;
/* Rx shared memory queue */
- u32 rxpd_wr_ptr;
+ __le32 rxpd_wr_ptr;
/* Actual number of TX queues in WcbBase array */
- u32 num_tx_queues;
+ __le32 num_tx_queues;
/* TX WCB Rings */
- u32 wcb_base[SYSADPT_NUM_OF_DESC_DATA];
+ __le32 wcb_base[SYSADPT_NUM_OF_DESC_DATA];
/* Max AMSDU size (00 - AMSDU Disabled,
* 01 - 4K, 10 - 8K, 11 - not defined)
*/
- u32 max_amsdu_size:2;
- /* Indicates supported AMPDU type
- * (1 = implicit, 0 = explicit (default))
- */
- u32 implicit_ampdu_ba:1;
- /* indicates mbss features disable in FW */
- u32 disablembss:1;
- u32 host_form_beacon:1;
- u32 host_form_probe_response:1;
- u32 host_power_save:1;
- u32 host_encr_decr_mgt:1;
- u32 host_intra_bss_offload:1;
- u32 host_iv_offload:1;
- u32 host_encr_decr_frame:1;
- u32 reserved: 21; /* Reserved */
- u32 tx_wcb_num_per_queue;
- u32 total_rx_wcb;
+ __le32 features;
+ __le32 tx_wcb_num_per_queue;
+ __le32 total_rx_wcb;
} __packed;
-/* HOSTCMD_CMD_802_11_GET_STAT
- */
-
+/* HOSTCMD_CMD_802_11_GET_STAT */
struct hostcmd_cmd_802_11_get_stat {
struct hostcmd_header cmd_hdr;
- u32 tx_retry_successes;
- u32 tx_multiple_retry_successes;
- u32 tx_failures;
- u32 rts_successes;
- u32 rts_failures;
- u32 ack_failures;
- u32 rx_duplicate_frames;
- u32 rx_fcs_errors;
- u32 tx_watchdog_timeouts;
- u32 rx_overflows;
- u32 rx_frag_errors;
- u32 rx_mem_errors;
- u32 pointer_errors;
- u32 tx_underflows;
- u32 tx_done;
- u32 tx_done_buf_try_put;
- u32 tx_done_buf_put;
+ __le32 tx_retry_successes;
+ __le32 tx_multiple_retry_successes;
+ __le32 tx_failures;
+ __le32 rts_successes;
+ __le32 rts_failures;
+ __le32 ack_failures;
+ __le32 rx_duplicate_frames;
+ __le32 rx_fcs_errors;
+ __le32 tx_watchdog_timeouts;
+ __le32 rx_overflows;
+ __le32 rx_frag_errors;
+ __le32 rx_mem_errors;
+ __le32 pointer_errors;
+ __le32 tx_underflows;
+ __le32 tx_done;
+ __le32 tx_done_buf_try_put;
+ __le32 tx_done_buf_put;
/* Put size of requested buffer in here */
- u32 wait_for_tx_buf;
- u32 tx_attempts;
- u32 tx_successes;
- u32 tx_fragments;
- u32 tx_multicasts;
- u32 rx_non_ctl_pkts;
- u32 rx_multicasts;
- u32 rx_undecryptable_frames;
- u32 rx_icv_errors;
- u32 rx_excluded_frames;
- u32 rx_weak_iv_count;
- u32 rx_unicasts;
- u32 rx_bytes;
- u32 rx_errors;
- u32 rx_rts_count;
- u32 tx_cts_count;
-} __packed;
-
-/* HOSTCMD_CMD_802_11_RADIO_CONTROL
- */
-
+ __le32 wait_for_tx_buf;
+ __le32 tx_attempts;
+ __le32 tx_successes;
+ __le32 tx_fragments;
+ __le32 tx_multicasts;
+ __le32 rx_non_ctl_pkts;
+ __le32 rx_multicasts;
+ __le32 rx_undecryptable_frames;
+ __le32 rx_icv_errors;
+ __le32 rx_excluded_frames;
+ __le32 rx_weak_iv_count;
+ __le32 rx_unicasts;
+ __le32 rx_bytes;
+ __le32 rx_errors;
+ __le32 rx_rts_count;
+ __le32 tx_cts_count;
+} __packed;
+
+/* HOSTCMD_CMD_802_11_RADIO_CONTROL */
struct hostcmd_cmd_802_11_radio_control {
struct hostcmd_header cmd_hdr;
- u16 action;
+ __le16 action;
/* @bit0: 1/0,on/off, @bit1: 1/0, long/short @bit2: 1/0,auto/fix */
- u16 control;
- u16 radio_on;
+ __le16 control;
+ __le16 radio_on;
} __packed;
-/* HOSTCMD_CMD_802_11_TX_POWER
- */
-
+/* HOSTCMD_CMD_802_11_TX_POWER */
struct hostcmd_cmd_802_11_tx_power {
struct hostcmd_header cmd_hdr;
- u16 action;
- u16 band;
- u16 ch;
- u16 bw;
- u16 sub_ch;
- u16 power_level_list[SYSADPT_TX_POWER_LEVEL_TOTAL];
+ __le16 action;
+ __le16 band;
+ __le16 ch;
+ __le16 bw;
+ __le16 sub_ch;
+ __le16 power_level_list[SYSADPT_TX_POWER_LEVEL_TOTAL];
} __packed;
-/* HOSTCMD_CMD_802_11_RF_ANTENNA
- */
-
+/* HOSTCMD_CMD_802_11_RF_ANTENNA */
struct hostcmd_cmd_802_11_rf_antenna {
struct hostcmd_header cmd_hdr;
- u16 action;
- u16 antenna_mode; /* Number of antennas or 0xffff(diversity) */
+ __le16 action;
+ __le16 antenna_mode; /* Number of antennas or 0xffff(diversity) */
} __packed;
-/* HOSTCMD_CMD_BROADCAST_SSID_ENABLE
- */
-
+/* HOSTCMD_CMD_BROADCAST_SSID_ENABLE */
struct hostcmd_cmd_broadcast_ssid_enable {
struct hostcmd_header cmd_hdr;
- u32 enable;
+ __le32 enable;
} __packed;
-/* HOSTCMD_CMD_SET_RF_CHANNEL
- */
-
-struct chnl_flags_11ac {
- /* bit0=1: 2.4GHz,bit1=1: 4.9GHz,bit2=1: 5GHz,bit3=1: 5.2GHz, */
- u32 freq_band:6;
- /* bit6=1:10MHz, bit7=1:20MHz, bit8=1:40MHz */
- u32 chnl_width:5;
- /* 000: 1st 20MHz chan, 001:2nd 20MHz chan, 011:3rd 20MHz chan,
- * 100:4th 20MHz chan
- */
- u32 act_primary:3;
- u32 reserved:18;
-} __packed;
+/* HOSTCMD_CMD_SET_RF_CHANNEL */
+#define FREQ_BAND_MASK 0x0000003f
+#define CHNL_WIDTH_MASK 0x000007c0
+#define CHNL_WIDTH_SHIFT 6
+#define ACT_PRIMARY_MASK 0x00003800
+#define ACT_PRIMARY_SHIFT 11
struct hostcmd_cmd_set_rf_channel {
struct hostcmd_header cmd_hdr;
- u16 action;
+ __le16 action;
u8 curr_chnl;
- struct chnl_flags_11ac chnl_flags;
+ __le32 chnl_flags;
} __packed;
-/* HOSTCMD_CMD_SET_AID
- */
-
+/* HOSTCMD_CMD_SET_AID */
struct hostcmd_cmd_set_aid {
struct hostcmd_header cmd_hdr;
- u16 aid;
+ __le16 aid;
u8 mac_addr[ETH_ALEN]; /* AP's Mac Address(BSSID) */
- u32 gprotect;
+ __le32 gprotect;
u8 ap_rates[SYSADPT_MAX_DATA_RATES_G];
} __packed;
-/* HOSTCMD_CMD_SET_INFRA_MODE
- */
-
+/* HOSTCMD_CMD_SET_INFRA_MODE */
struct hostcmd_cmd_set_infra_mode {
struct hostcmd_header cmd_hdr;
} __packed;
-/* HOSTCMD_CMD_802_11_RTS_THSD
- */
-
+/* HOSTCMD_CMD_802_11_RTS_THSD */
struct hostcmd_cmd_802_11_rts_thsd {
struct hostcmd_header cmd_hdr;
- u16 action;
- u16 threshold;
+ __le16 action;
+ __le16 threshold;
} __packed;
-/* HOSTCMD_CMD_SET_EDCA_PARAMS
- */
-
+/* HOSTCMD_CMD_SET_EDCA_PARAMS */
struct hostcmd_cmd_set_edca_params {
struct hostcmd_header cmd_hdr;
/* 0 = get all, 0x1 =set CWMin/Max, 0x2 = set TXOP , 0x4 =set AIFSN */
- u16 action;
- u16 txop; /* in unit of 32 us */
- u32 cw_max; /* 0~15 */
- u32 cw_min; /* 0~15 */
+ __le16 action;
+ __le16 txop; /* in unit of 32 us */
+ __le32 cw_max; /* 0~15 */
+ __le32 cw_min; /* 0~15 */
u8 aifsn;
u8 txq_num; /* Tx Queue number. */
} __packed;
-/* HOSTCMD_CMD_SET_WMM_MODE
- */
-
+/* HOSTCMD_CMD_SET_WMM_MODE */
struct hostcmd_cmd_set_wmm_mode {
struct hostcmd_header cmd_hdr;
- u16 action; /* 0->unset, 1->set */
+ __le16 action; /* 0->unset, 1->set */
} __packed;
-/* HOSTCMD_CMD_SET_FIXED_RATE
- */
-
+/* HOSTCMD_CMD_SET_FIXED_RATE */
struct fix_rate_flag { /* lower rate after the retry count */
/* 0: legacy, 1: HT */
- u32 fix_rate_type;
+ __le32 fix_rate_type;
/* 0: retry count is not valid, 1: use retry count specified */
- u32 retry_count_valid;
+ __le32 retry_count_valid;
} __packed;
struct fix_rate_entry {
@@ -454,88 +358,76 @@ struct fix_rate_entry {
/* depending on the flags above, this can be either a legacy
* rate(not index) or an MCS code.
*/
- u32 fixed_rate;
- u32 retry_count;
+ __le32 fixed_rate;
+ __le32 retry_count;
} __packed;
struct hostcmd_cmd_set_fixed_rate {
struct hostcmd_header cmd_hdr;
/* HOSTCMD_ACT_NOT_USE_FIXED_RATE 0x0002 */
- u32 action;
+ __le32 action;
/* use fixed rate specified but firmware can drop to */
- u32 allow_rate_drop;
- u32 entry_count;
+ __le32 allow_rate_drop;
+ __le32 entry_count;
struct fix_rate_entry fixed_rate_table[4];
u8 multicast_rate;
u8 multi_rate_tx_type;
u8 management_rate;
} __packed;
-/* HOSTCMD_CMD_SET_IES
- */
-
+/* HOSTCMD_CMD_SET_IES */
struct hostcmd_cmd_set_ies {
struct hostcmd_header cmd_hdr;
- u16 action; /* 0->unset, 1->set */
- u16 ie_list_len_ht;
- u16 ie_list_len_vht;
- u16 ie_list_len_proprietary;
+ __le16 action; /* 0->unset, 1->set */
+ __le16 ie_list_len_ht;
+ __le16 ie_list_len_vht;
+ __le16 ie_list_len_proprietary;
/*Buffer size same as Generic_Beacon*/
u8 ie_list_ht[148];
u8 ie_list_vht[24];
u8 ie_list_proprietary[112];
} __packed;
-/* HOSTCMD_CMD_SET_RATE_ADAPT_MODE
- */
-
+/* HOSTCMD_CMD_SET_RATE_ADAPT_MODE */
struct hostcmd_cmd_set_rate_adapt_mode {
struct hostcmd_header cmd_hdr;
- u16 action;
- u16 rate_adapt_mode; /* 0:Indoor, 1:Outdoor */
+ __le16 action;
+ __le16 rate_adapt_mode; /* 0:Indoor, 1:Outdoor */
} __packed;
-/* HOSTCMD_CMD_SET_MAC_ADDR, HOSTCMD_CMD_DEL_MAC_ADDR
- */
-
+/* HOSTCMD_CMD_SET_MAC_ADDR, HOSTCMD_CMD_DEL_MAC_ADDR */
struct hostcmd_cmd_set_mac_addr {
struct hostcmd_header cmd_hdr;
- u16 mac_type;
+ __le16 mac_type;
u8 mac_addr[ETH_ALEN];
} __packed;
-/* HOSTCMD_CMD_GET_WATCHDOG_BITMAP
- */
-
+/* HOSTCMD_CMD_GET_WATCHDOG_BITMAP */
struct hostcmd_cmd_get_watchdog_bitmap {
struct hostcmd_header cmd_hdr;
u8 watchdog_bitmap; /* for SW/BA */
} __packed;
-/* HOSTCMD_CMD_BSS_START
- */
-
+/* HOSTCMD_CMD_BSS_START */
struct hostcmd_cmd_bss_start {
struct hostcmd_header cmd_hdr;
- u32 enable; /* FALSE: Disable or TRUE: Enable */
+ __le32 enable; /* FALSE: Disable or TRUE: Enable */
} __packed;
-/* HOSTCMD_CMD_AP_BEACON
- */
-
+/* HOSTCMD_CMD_AP_BEACON */
struct cf_params {
u8 elem_id;
u8 len;
u8 cfp_cnt;
u8 cfp_period;
- u16 cfp_max_duration;
- u16 cfp_duration_remaining;
+ __le16 cfp_max_duration;
+ __le16 cfp_duration_remaining;
} __packed;
struct ibss_params {
u8 elem_id;
u8 len;
- u16 atim_window;
+ __le16 atim_window;
} __packed;
union ss_params {
@@ -546,7 +438,7 @@ union ss_params {
struct fh_params {
u8 elem_id;
u8 len;
- u16 dwell_time;
+ __le16 dwell_time;
u8 hop_set;
u8 hop_pattern;
u8 hop_index;
@@ -590,22 +482,10 @@ struct rsn48_ie {
u8 reserved[8];
} __packed;
-struct aci_aifsn_field {
- u8 aifsn:4;
- u8 acm:1;
- u8 aci:2;
- u8 rsvd:1;
-} __packed;
-
-struct ecw_min_max_field {
- u8 ecw_min:4;
- u8 ecw_max:4;
-} __packed;
-
struct ac_param_rcd {
- struct aci_aifsn_field aci_aifsn;
- struct ecw_min_max_field ecw_min_max;
- u16 txop_lim;
+ u8 aci_aifsn;
+ u8 ecw_min_max;
+ __le16 txop_lim;
} __packed;
struct wmm_param_elem {
@@ -633,25 +513,25 @@ struct country {
u8 len;
u8 country_str[3];
struct channel_info channel_info[40];
-} __packetd;
+} __packed;
struct start_cmd {
u8 sta_mac_addr[ETH_ALEN];
u8 ssid[IEEE80211_MAX_SSID_LEN];
u8 bss_type;
- u16 bcn_period;
+ __le16 bcn_period;
u8 dtim_period;
union ss_params ss_param_set;
union phy_params phy_param_set;
- u16 probe_delay;
- u16 cap_info;
+ __le16 probe_delay;
+ __le16 cap_info;
u8 b_rate_set[SYSADPT_MAX_DATA_RATES_G];
u8 op_rate_set[SYSADPT_MAX_DATA_RATES_G];
struct rsn_ie rsn_ie;
struct rsn48_ie rsn48_ie;
struct wmm_param_elem wmm_param;
struct country country;
- u32 ap_rf_type; /* 0->B, 1->G, 2->Mixed, 3->A, 4->11J */
+ __le32 ap_rf_type; /* 0->B, 1->G, 2->Mixed, 3->A, 4->11J */
} __packed;
struct hostcmd_cmd_ap_beacon {
@@ -659,107 +539,56 @@ struct hostcmd_cmd_ap_beacon {
struct start_cmd start_cmd;
} __packed;
-/* HOSTCMD_CMD_SET_NEW_STN
- */
-
-struct cap_info {
- u16 ess:1;
- u16 ibss:1;
- u16 cf_pollable:1;
- u16 cf_poll_rqst:1;
- u16 privacy:1;
- u16 short_preamble:1;
- u16 pbcc:1;
- u16 chan_agility:1;
- u16 spectrum_mgmt:1;
- u16 qoS:1;
- u16 short_slot_time:1;
- u16 apsd:1;
- u16 rsrvd1:1;
- u16 dsss_ofdm:1;
- u16 block_ack:1;
- u16 rsrvd2:1;
-} __packed;
-
-struct add_ht_chnl {
- u8 ext_chnl_offset:2;
- u8 sta_chnl_width:1;
- u8 rifs_mode:1;
- u8 psmp_stas_only:1;
- u8 srvc_intvl_gran:3;
-} __packed;
-
-struct add_ht_op_mode {
- u16 op_mode:2;
- u16 non_gf_sta_present:1;
- u16 rrans_burst_limit:1;
- u16 non_ht_sta_present:1;
- u16 rsrv:11;
-} __packed;
-
-struct add_ht_stbc {
- u16 bsc_stbc:7;
- u16 dual_stbc_proc:1;
- u16 scd_bcn:1;
- u16 lsig_txop_proc_full_sup:1;
- u16 pco_active:1;
- u16 pco_phase:1;
- u16 rsrv:4;
-} __packed;
-
+/* HOSTCMD_CMD_SET_NEW_STN */
struct add_ht_info {
u8 control_chnl;
- struct add_ht_chnl add_chnl;
- struct add_ht_op_mode op_mode;
- struct add_ht_stbc stbc;
+ u8 add_chnl;
+ __le16 op_mode;
+ __le16 stbc;
} __packed;
struct peer_info {
- u32 legacy_rate_bitmap;
+ __le32 legacy_rate_bitmap;
u8 ht_rates[4];
- struct cap_info cap_info;
- u16 ht_cap_info;
+ __le16 cap_info;
+ __le16 ht_cap_info;
u8 mac_ht_param_info;
u8 mrvl_sta;
struct add_ht_info add_ht_info;
- u32 tx_bf_capabilities; /* EXBF_SUPPORT */
- u32 vht_max_rx_mcs;
- u32 vht_cap;
+ __le32 tx_bf_capabilities; /* EXBF_SUPPORT */
+ __le32 vht_max_rx_mcs;
+ __le32 vht_cap;
/* 0:20Mhz, 1:40Mhz, 2:80Mhz, 3:160 or 80+80Mhz */
u8 vht_rx_channel_width;
} __packed;
struct hostcmd_cmd_set_new_stn {
struct hostcmd_header cmd_hdr;
- u16 aid;
+ __le16 aid;
u8 mac_addr[ETH_ALEN];
- u16 stn_id;
- u16 action;
- u16 reserved;
+ __le16 stn_id;
+ __le16 action;
+ __le16 reserved;
struct peer_info peer_info;
/* UAPSD_SUPPORT */
u8 qos_info;
u8 is_qos_sta;
- u32 fw_sta_ptr;
+ __le32 fw_sta_ptr;
} __packed;
-/* HOSTCMD_CMD_SET_APMODE
- */
-
+/* HOSTCMD_CMD_SET_APMODE */
struct hostcmd_cmd_set_apmode {
struct hostcmd_header cmd_hdr;
u8 apmode;
} __packed;
-/* HOSTCMD_CMD_UPDATE_ENCRYPTION
- */
-
-struct hostcmd_cmd_update_encryptoin {
+/* HOSTCMD_CMD_UPDATE_ENCRYPTION */
+struct hostcmd_cmd_update_encryption {
struct hostcmd_header cmd_hdr;
/* Action type - see encr_action_type */
- u32 action_type; /* encr_action_type */
+ __le32 action_type; /* encr_action_type */
/* size of the data buffer attached. */
- u32 data_length;
+ __le32 data_length;
u8 mac_addr[ETH_ALEN];
u8 action_data[1];
} __packed;
@@ -770,8 +599,8 @@ struct wep_type_key {
} __packed;
struct encr_tkip_seqcnt {
- u16 low;
- u32 high;
+ __le16 low;
+ __le32 high;
} __packed;
struct tkip_type_key {
@@ -793,23 +622,23 @@ struct aes_type_key {
} __packed;
union mwl_key_type {
- struct wep_type_key wep_key;
+ struct wep_type_key wep_key;
struct tkip_type_key tkip_key;
- struct aes_type_key aes_key;
+ struct aes_type_key aes_key;
} __packed;
struct key_param_set {
/* Total length of this structure (Key is variable size array) */
- u16 length;
+ __le16 length;
/* Key type - WEP, TKIP or AES-CCMP. */
/* See definitions above */
- u16 key_type_id;
+ __le16 key_type_id;
/* key flags (ENCR_KEY_FLAG_XXX_ */
- u32 key_info;
+ __le32 key_info;
/* For WEP only - actual key index */
- u32 key_index;
+ __le32 key_index;
/* Size of the key */
- u16 key_len;
+ __le16 key_len;
/* Key material (variable size array) */
union mwl_key_type key;
u8 mac_addr[ETH_ALEN];
@@ -818,38 +647,34 @@ struct key_param_set {
struct hostcmd_cmd_set_key {
struct hostcmd_header cmd_hdr;
/* Action type - see encr_action_type */
- u32 action_type; /* encr_action_type */
+ __le32 action_type; /* encr_action_type */
/* size of the data buffer attached. */
- u32 data_length;
+ __le32 data_length;
/* data buffer - maps to one KEY_PARAM_SET structure */
struct key_param_set key_param;
} __packed;
-/* HOSTCMD_CMD_BASTREAM
- */
-
-struct ba_stream_flags {
- u32 ba_type:1;
- u32 ba_direction:3;
- u32 reserved:24;
-} __packed;
+/* HOSTCMD_CMD_BASTREAM */
+#define BA_TYPE_MASK 0x00000001
+#define BA_DIRECTION_MASK 0x00000006
+#define BA_DIRECTION_SHIFT 1
struct ba_context {
- u32 context;
+ __le32 context;
} __packed;
/* parameters for block ack creation */
struct create_ba_params {
/* BA Creation flags - see above */
- struct ba_stream_flags flags;
+ __le32 flags;
/* idle threshold */
- u32 idle_thrs;
+ __le32 idle_thrs;
/* block ack transmit threshold (after how many pkts should we
* send BAR?)
*/
- u32 bar_thrs;
+ __le32 bar_thrs;
/* receiver window size */
- u32 window_size;
+ __le32 window_size;
/* MAC Address of the BA partner */
u8 peer_mac_addr[ETH_ALEN];
/* Dialog Token */
@@ -865,7 +690,7 @@ struct create_ba_params {
*/
struct ba_context fw_ba_context;
u8 reset_seq_no; /** 0 or 1**/
- u16 current_seq;
+ __le16 current_seq;
/* This is for virtual station in Sta proxy mode for V6FW */
u8 sta_src_mac_addr[ETH_ALEN];
} __packed;
@@ -873,16 +698,16 @@ struct create_ba_params {
/* new transmit sequence number information */
struct ba_update_seq_num {
/* BA flags - see above */
- struct ba_stream_flags flags;
+ __le32 flags;
/* returned by firmware in the create ba stream response */
struct ba_context fw_ba_context;
/* new sequence number for this block ack stream */
- u16 ba_seq_num;
+ __le16 ba_seq_num;
} __packed;
struct ba_stream_context {
/* BA Stream flags */
- struct ba_stream_flags flags;
+ __le32 flags;
/* returned by firmware in the create ba stream response */
struct ba_context fw_ba_context;
} __packed;
@@ -900,95 +725,685 @@ union ba_info {
struct hostcmd_cmd_bastream {
struct hostcmd_header cmd_hdr;
- u32 action_type;
+ __le32 action_type;
union ba_info ba_info;
} __packed;
-/* HOSTCMD_CMD_DWDS_ENABLE
- */
-
+/* HOSTCMD_CMD_DWDS_ENABLE */
struct hostcmd_cmd_dwds_enable {
struct hostcmd_header cmd_hdr;
- u32 enable; /* 0 -- Disable. or 1 -- Enable. */
+ __le32 enable; /* 0 -- Disable. or 1 -- Enable. */
} __packed;
-/* HOSTCMD_CMD_FW_FLUSH_TIMER
- */
-
+/* HOSTCMD_CMD_FW_FLUSH_TIMER */
struct hostcmd_cmd_fw_flush_timer {
struct hostcmd_header cmd_hdr;
/* 0 -- Disable. > 0 -- holds time value in usecs. */
- u32 value;
+ __le32 value;
} __packed;
-/* HOSTCMD_CMD_SET_CDD
- */
-
+/* HOSTCMD_CMD_SET_CDD */
struct hostcmd_cmd_set_cdd {
struct hostcmd_header cmd_hdr;
- u32 enable;
+ __le32 enable;
} __packed;
-/* PRIVATE FUNCTION DECLARATION
-*/
+static bool mwl_fwcmd_chk_adapter(struct mwl_priv *priv)
+{
+ u32 regval;
+
+ regval = readl(priv->iobase1 + MACREG_REG_INT_CODE);
+
+ if (regval == 0xffffffff) {
+ wiphy_err(priv->hw->wiphy, "adapter is not existed");
+ return false;
+ }
+
+ return true;
+}
+
+static void mwl_fwcmd_send_cmd(struct mwl_priv *priv)
+{
+ writel(priv->pphys_cmd_buf, priv->iobase1 + MACREG_REG_GEN_PTR);
+ writel(MACREG_H2ARIC_BIT_DOOR_BELL,
+ priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
+}
+
+static char *mwl_fwcmd_get_cmd_string(unsigned short cmd)
+{
+ int max_entries = 0;
+ int curr_cmd = 0;
+
+ static const struct {
+ u16 cmd;
+ char *cmd_string;
+ } cmds[] = {
+ { HOSTCMD_CMD_GET_HW_SPEC, "GetHwSpecifications" },
+ { HOSTCMD_CMD_SET_HW_SPEC, "SetHwSepcifications" },
+ { HOSTCMD_CMD_802_11_GET_STAT, "80211GetStat" },
+ { HOSTCMD_CMD_802_11_RADIO_CONTROL, "80211RadioControl" },
+ { HOSTCMD_CMD_802_11_TX_POWER, "80211TxPower" },
+ { HOSTCMD_CMD_802_11_RF_ANTENNA, "80211RfAntenna" },
+ { HOSTCMD_CMD_BROADCAST_SSID_ENABLE, "broadcast_ssid_enable" },
+ { HOSTCMD_CMD_SET_RF_CHANNEL, "SetRfChannel" },
+ { HOSTCMD_CMD_SET_AID, "SetAid" },
+ { HOSTCMD_CMD_SET_INFRA_MODE, "SetInfraMode" },
+ { HOSTCMD_CMD_802_11_RTS_THSD, "80211RtsThreshold" },
+ { HOSTCMD_CMD_SET_EDCA_PARAMS, "SetEDCAParams" },
+ { HOSTCMD_CMD_SET_WMM_MODE, "SetWMMMode" },
+ { HOSTCMD_CMD_SET_FIXED_RATE, "SetFixedRate" },
+ { HOSTCMD_CMD_SET_IES, "SetInformationElements" },
+ { HOSTCMD_CMD_SET_RATE_ADAPT_MODE, "SetRateAdaptationMode" },
+ { HOSTCMD_CMD_SET_MAC_ADDR, "SetMacAddr" },
+ { HOSTCMD_CMD_GET_WATCHDOG_BITMAP, "GetWatchdogBitMap" },
+ { HOSTCMD_CMD_DEL_MAC_ADDR, "DelMacAddr" },
+ { HOSTCMD_CMD_BSS_START, "BssStart" },
+ { HOSTCMD_CMD_AP_BEACON, "SetApBeacon" },
+ { HOSTCMD_CMD_SET_NEW_STN, "SetNewStation" },
+ { HOSTCMD_CMD_SET_APMODE, "SetApMode" },
+ { HOSTCMD_CMD_UPDATE_ENCRYPTION, "UpdateEncryption" },
+ { HOSTCMD_CMD_BASTREAM, "BAStream" },
+ { HOSTCMD_CMD_DWDS_ENABLE, "DwdsEnable" },
+ { HOSTCMD_CMD_FW_FLUSH_TIMER, "FwFlushTimer" },
+ { HOSTCMD_CMD_SET_CDD, "SetCDD" },
+ };
+
+ max_entries = sizeof(cmds) / sizeof(cmds[0]);
+
+ for (curr_cmd = 0; curr_cmd < max_entries; curr_cmd++)
+ if ((cmd & 0x7fff) == cmds[curr_cmd].cmd)
+ return cmds[curr_cmd].cmd_string;
-static bool mwl_fwcmd_chk_adapter(struct mwl_priv *priv);
-static int mwl_fwcmd_exec_cmd(struct mwl_priv *priv, unsigned short cmd);
-static void mwl_fwcmd_send_cmd(struct mwl_priv *priv);
-static int mwl_fwcmd_wait_complete(struct mwl_priv *priv, unsigned short cmd);
+ return "unknown";
+}
+
+static int mwl_fwcmd_wait_complete(struct mwl_priv *priv, unsigned short cmd)
+{
+ unsigned int curr_iteration = MAX_WAIT_FW_COMPLETE_ITERATIONS;
+
+ unsigned short int_code = 0;
+
+ do {
+ int_code = le16_to_cpu(*((__le16 *)&priv->pcmd_buf[0]));
+ mdelay(1);
+ } while ((int_code != cmd) && (--curr_iteration));
+
+ if (curr_iteration == 0) {
+ wiphy_err(priv->hw->wiphy, "cmd 0x%04x=%s timed out",
+ cmd, mwl_fwcmd_get_cmd_string(cmd));
+ return -EIO;
+ }
+
+ mdelay(3);
+
+ return 0;
+}
+
+static int mwl_fwcmd_exec_cmd(struct mwl_priv *priv, unsigned short cmd)
+{
+ bool busy = false;
+
+ if (!mwl_fwcmd_chk_adapter(priv)) {
+ wiphy_err(priv->hw->wiphy, "no adapter existed");
+ priv->in_send_cmd = false;
+ return -EIO;
+ }
+
+ if (!priv->in_send_cmd) {
+ priv->in_send_cmd = true;
+ mwl_fwcmd_send_cmd(priv);
+ if (mwl_fwcmd_wait_complete(priv, 0x8000 | cmd)) {
+ wiphy_err(priv->hw->wiphy, "timeout");
+ priv->in_send_cmd = false;
+ return -EIO;
+ }
+ } else {
+ wiphy_warn(priv->hw->wiphy,
+ "previous command is still running");
+ busy = true;
+ }
+
+ if (!busy)
+ priv->in_send_cmd = false;
+
+ return 0;
+}
static int mwl_fwcmd_802_11_radio_control(struct mwl_priv *priv,
- bool enable, bool force);
+ bool enable, bool force)
+{
+ struct hostcmd_cmd_802_11_radio_control *pcmd;
+ unsigned long flags;
+
+ if (enable == priv->radio_on && !force)
+ return 0;
+
+ pcmd = (struct hostcmd_cmd_802_11_radio_control *)&priv->pcmd_buf[0];
+
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_802_11_RADIO_CONTROL);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->action = cpu_to_le16(WL_SET);
+ pcmd->control = cpu_to_le16(priv->radio_short_preamble ?
+ WL_AUTO_PREAMBLE : WL_LONG_PREAMBLE);
+ pcmd->radio_on = cpu_to_le16(enable ? WL_ENABLE : WL_DISABLE);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_RADIO_CONTROL)) {
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(priv->hw->wiphy, "failed execution");
+ return -EIO;
+ }
+
+ priv->radio_on = enable;
+
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+
+ return 0;
+}
+
static int mwl_fwcmd_get_tx_powers(struct mwl_priv *priv, u16 *powlist, u16 ch,
- u16 band, u16 width, u16 sub_ch);
+ u16 band, u16 width, u16 sub_ch)
+{
+ struct hostcmd_cmd_802_11_tx_power *pcmd;
+ unsigned long flags;
+ int i;
+
+ pcmd = (struct hostcmd_cmd_802_11_tx_power *)&priv->pcmd_buf[0];
+
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_802_11_TX_POWER);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->action = cpu_to_le16(HOSTCMD_ACT_GEN_GET_LIST);
+ pcmd->ch = cpu_to_le16(ch);
+ pcmd->bw = cpu_to_le16(width);
+ pcmd->band = cpu_to_le16(band);
+ pcmd->sub_ch = cpu_to_le16(sub_ch);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_TX_POWER)) {
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(priv->hw->wiphy, "failed execution");
+ return -EIO;
+ }
+
+ for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++)
+ powlist[i] = le16_to_cpu(pcmd->power_level_list[i]);
+
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+
+ return 0;
+}
+
static int mwl_fwcmd_set_tx_powers(struct mwl_priv *priv, u16 txpow[],
u8 action, u16 ch, u16 band,
- u16 width, u16 sub_ch);
-static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel);
+ u16 width, u16 sub_ch)
+{
+ struct hostcmd_cmd_802_11_tx_power *pcmd;
+ unsigned long flags;
+ int i;
+
+ pcmd = (struct hostcmd_cmd_802_11_tx_power *)&priv->pcmd_buf[0];
+
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_802_11_TX_POWER);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->action = cpu_to_le16(action);
+ pcmd->ch = cpu_to_le16(ch);
+ pcmd->bw = cpu_to_le16(width);
+ pcmd->band = cpu_to_le16(band);
+ pcmd->sub_ch = cpu_to_le16(sub_ch);
+
+ for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++)
+ pcmd->power_level_list[i] = cpu_to_le16(txpow[i]);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_TX_POWER)) {
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(priv->hw->wiphy, "failed execution");
+ return -EIO;
+ }
+
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+
+ return 0;
+}
+
+static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel)
+{
+ u8 act_primary = ACT_PRIMARY_CHAN_0;
+
+ switch (channel) {
+ case 36:
+ act_primary = ACT_PRIMARY_CHAN_0;
+ break;
+ case 40:
+ act_primary = ACT_PRIMARY_CHAN_1;
+ break;
+ case 44:
+ act_primary = ACT_PRIMARY_CHAN_2;
+ break;
+ case 48:
+ act_primary = ACT_PRIMARY_CHAN_3;
+ break;
+ case 52:
+ act_primary = ACT_PRIMARY_CHAN_0;
+ break;
+ case 56:
+ act_primary = ACT_PRIMARY_CHAN_1;
+ break;
+ case 60:
+ act_primary = ACT_PRIMARY_CHAN_2;
+ break;
+ case 64:
+ act_primary = ACT_PRIMARY_CHAN_3;
+ break;
+ case 100:
+ act_primary = ACT_PRIMARY_CHAN_0;
+ break;
+ case 104:
+ act_primary = ACT_PRIMARY_CHAN_1;
+ break;
+ case 108:
+ act_primary = ACT_PRIMARY_CHAN_2;
+ break;
+ case 112:
+ act_primary = ACT_PRIMARY_CHAN_3;
+ break;
+ case 116:
+ act_primary = ACT_PRIMARY_CHAN_0;
+ break;
+ case 120:
+ act_primary = ACT_PRIMARY_CHAN_1;
+ break;
+ case 124:
+ act_primary = ACT_PRIMARY_CHAN_2;
+ break;
+ case 128:
+ act_primary = ACT_PRIMARY_CHAN_3;
+ break;
+ case 132:
+ act_primary = ACT_PRIMARY_CHAN_0;
+ break;
+ case 136:
+ act_primary = ACT_PRIMARY_CHAN_1;
+ break;
+ case 140:
+ act_primary = ACT_PRIMARY_CHAN_2;
+ break;
+ case 144:
+ act_primary = ACT_PRIMARY_CHAN_3;
+ break;
+ case 149:
+ act_primary = ACT_PRIMARY_CHAN_0;
+ break;
+ case 153:
+ act_primary = ACT_PRIMARY_CHAN_1;
+ break;
+ case 157:
+ act_primary = ACT_PRIMARY_CHAN_2;
+ break;
+ case 161:
+ act_primary = ACT_PRIMARY_CHAN_3;
+ break;
+ }
+
+ return act_primary;
+}
+
static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
- struct mwl_vif *vif, u8 *beacon, int len);
-static int mwl_fwcmd_set_ies(struct mwl_priv *priv, struct mwl_vif *mwl_vif);
+ struct mwl_vif *vif, u8 *beacon, int len)
+{
+ struct ieee80211_mgmt *mgmt;
+ struct beacon_info *beacon_info;
+ int baselen;
+ u8 *pos;
+ size_t left;
+ bool elem_parse_failed;
+
+ mgmt = (struct ieee80211_mgmt *)beacon;
+
+ baselen = (u8 *)mgmt->u.beacon.variable - (u8 *)mgmt;
+ if (baselen > len)
+ return;
+
+ beacon_info = &vif->beacon_info;
+ memset(beacon_info, 0, sizeof(struct beacon_info));
+ beacon_info->valid = false;
+ beacon_info->ie_ht_ptr = &beacon_info->ie_list_ht[0];
+ beacon_info->ie_vht_ptr = &beacon_info->ie_list_vht[0];
+
+ beacon_info->cap_info = le16_to_cpu(mgmt->u.beacon.capab_info);
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ left = len - baselen;
+
+ elem_parse_failed = false;
+
+ while (left >= 2) {
+ u8 id, elen;
+
+ id = *pos++;
+ elen = *pos++;
+ left -= 2;
+
+ if (elen > left) {
+ elem_parse_failed = true;
+ break;
+ }
+
+ switch (id) {
+ case WLAN_EID_SUPP_RATES:
+ case WLAN_EID_EXT_SUPP_RATES:
+ {
+ int idx, bi, oi;
+ u8 rate;
+
+ for (bi = 0; bi < SYSADPT_MAX_DATA_RATES_G;
+ bi++) {
+ if (beacon_info->b_rate_set[bi] == 0)
+ break;
+ }
+
+ for (oi = 0; oi < SYSADPT_MAX_DATA_RATES_G;
+ oi++) {
+ if (beacon_info->op_rate_set[oi] == 0)
+ break;
+ }
+
+ for (idx = 0; idx < elen; idx++) {
+ rate = pos[idx];
+ if ((rate & 0x80) != 0) {
+ if (bi < SYSADPT_MAX_DATA_RATES_G)
+ beacon_info->b_rate_set[bi++]
+ = rate & 0x7f;
+ else {
+ elem_parse_failed = true;
+ break;
+ }
+ }
+ if (oi < SYSADPT_MAX_DATA_RATES_G)
+ beacon_info->op_rate_set[oi++] =
+ rate & 0x7f;
+ else {
+ elem_parse_failed = true;
+ break;
+ }
+ }
+ }
+ break;
+ case WLAN_EID_RSN:
+ beacon_info->ie_rsn48_len = (elen + 2);
+ beacon_info->ie_rsn48_ptr = (pos - 2);
+ break;
+ case WLAN_EID_HT_CAPABILITY:
+ case WLAN_EID_HT_OPERATION:
+ case WLAN_EID_OVERLAP_BSS_SCAN_PARAM:
+ case WLAN_EID_EXT_CAPABILITY:
+ beacon_info->ie_ht_len += (elen + 2);
+ if (beacon_info->ie_ht_len >
+ sizeof(beacon_info->ie_list_ht)) {
+ elem_parse_failed = true;
+ } else {
+ *beacon_info->ie_ht_ptr++ = id;
+ *beacon_info->ie_ht_ptr++ = elen;
+ memcpy(beacon_info->ie_ht_ptr, pos, elen);
+ beacon_info->ie_ht_ptr += elen;
+ }
+ break;
+ case WLAN_EID_VHT_CAPABILITY:
+ case WLAN_EID_VHT_OPERATION:
+ case WLAN_EID_OPMODE_NOTIF:
+ beacon_info->ie_vht_len += (elen + 2);
+ if (beacon_info->ie_vht_len >
+ sizeof(beacon_info->ie_list_vht)) {
+ elem_parse_failed = true;
+ } else {
+ *beacon_info->ie_vht_ptr++ = id;
+ *beacon_info->ie_vht_ptr++ = elen;
+ memcpy(beacon_info->ie_vht_ptr, pos, elen);
+ beacon_info->ie_vht_ptr += elen;
+ }
+ break;
+ case WLAN_EID_VENDOR_SPECIFIC:
+ if ((pos[0] == 0x00) && (pos[1] == 0x50) &&
+ (pos[2] == 0xf2)) {
+ if (pos[3] == 0x01) {
+ beacon_info->ie_rsn_len = (elen + 2);
+ beacon_info->ie_rsn_ptr = (pos - 2);
+ }
+
+ if (pos[3] == 0x02) {
+ beacon_info->ie_wmm_len = (elen + 2);
+ beacon_info->ie_wmm_ptr = (pos - 2);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ left -= elen;
+ pos += elen;
+ }
+
+ if (!elem_parse_failed) {
+ beacon_info->ie_ht_ptr = &beacon_info->ie_list_ht[0];
+ beacon_info->ie_vht_ptr = &beacon_info->ie_list_vht[0];
+ beacon_info->valid = true;
+
+ wiphy_info(priv->hw->wiphy,
+ "wmm:%d, rsn:%d, rsn48:%d, ht:%d, vht:%d",
+ beacon_info->ie_wmm_len,
+ beacon_info->ie_rsn_len,
+ beacon_info->ie_rsn48_len,
+ beacon_info->ie_ht_len,
+ beacon_info->ie_vht_len);
+ }
+}
+
+static int mwl_fwcmd_set_ies(struct mwl_priv *priv, struct mwl_vif *mwl_vif)
+{
+ struct hostcmd_cmd_set_ies *pcmd;
+ unsigned long flags;
+
+ if (!mwl_vif->beacon_info.valid)
+ return -EINVAL;
+
+ if (mwl_vif->beacon_info.ie_ht_len > sizeof(pcmd->ie_list_ht))
+ goto einval;
+
+ if (mwl_vif->beacon_info.ie_vht_len > sizeof(pcmd->ie_list_vht))
+ goto einval;
+
+ pcmd = (struct hostcmd_cmd_set_ies *)&priv->pcmd_buf[0];
+
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_IES);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->cmd_hdr.macid = mwl_vif->macid;
+
+ pcmd->action = cpu_to_le16(HOSTCMD_ACT_GEN_SET);
+
+ pcmd->ie_list_len_ht = cpu_to_le16(mwl_vif->beacon_info.ie_ht_len);
+ memcpy(pcmd->ie_list_ht, mwl_vif->beacon_info.ie_ht_ptr,
+ mwl_vif->beacon_info.ie_ht_len);
+
+ pcmd->ie_list_len_vht = cpu_to_le16(mwl_vif->beacon_info.ie_vht_len);
+ memcpy(pcmd->ie_list_vht, mwl_vif->beacon_info.ie_vht_ptr,
+ mwl_vif->beacon_info.ie_vht_len);
+
+ if (priv->chip_type == MWL8897) {
+ pcmd->ie_list_len_proprietary =
+ cpu_to_le16(mwl_vif->beacon_info.ie_wmm_len);
+ memcpy(pcmd->ie_list_proprietary,
+ mwl_vif->beacon_info.ie_wmm_ptr,
+ mwl_vif->beacon_info.ie_wmm_len);
+ }
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_IES)) {
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(priv->hw->wiphy, "failed execution");
+ return -EIO;
+ }
+
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+
+ return 0;
+
+einval:
+
+ wiphy_err(priv->hw->wiphy, "length of IE is too long");
+
+ return -EINVAL;
+}
+
static int mwl_fwcmd_set_ap_beacon(struct mwl_priv *priv,
struct mwl_vif *mwl_vif,
- struct ieee80211_bss_conf *bss_conf);
+ struct ieee80211_bss_conf *bss_conf)
+{
+ struct hostcmd_cmd_ap_beacon *pcmd;
+ unsigned long flags;
+ struct ds_params *phy_ds_param_set;
+
+ if (!mwl_vif->beacon_info.valid)
+ return -EINVAL;
+
+ /* wmm structure of start command is defined less one byte,
+ * due to following field country is not used, add byte one
+ * to bypass the check.
+ */
+ if (mwl_vif->beacon_info.ie_wmm_len >
+ (sizeof(pcmd->start_cmd.wmm_param) + 1))
+ goto ielenerr;
+
+ if (mwl_vif->beacon_info.ie_rsn_len > sizeof(pcmd->start_cmd.rsn_ie))
+ goto ielenerr;
+
+ if (mwl_vif->beacon_info.ie_rsn48_len >
+ sizeof(pcmd->start_cmd.rsn48_ie))
+ goto ielenerr;
+
+ pcmd = (struct hostcmd_cmd_ap_beacon *)&priv->pcmd_buf[0];
+
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
+
+ memset(pcmd, 0x00, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_AP_BEACON);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->cmd_hdr.macid = mwl_vif->macid;
+
+ ether_addr_copy(pcmd->start_cmd.sta_mac_addr, mwl_vif->bssid);
+ memcpy(pcmd->start_cmd.ssid, bss_conf->ssid, bss_conf->ssid_len);
+ pcmd->start_cmd.bss_type = 1;
+ pcmd->start_cmd.bcn_period = cpu_to_le16(bss_conf->beacon_int);
+ pcmd->start_cmd.dtim_period = bss_conf->dtim_period; /* 8bit */
+
+ phy_ds_param_set = &pcmd->start_cmd.phy_param_set.ds_param_set;
+ phy_ds_param_set->elem_id = WLAN_EID_DS_PARAMS;
+ phy_ds_param_set->len = sizeof(phy_ds_param_set->current_chnl);
+ phy_ds_param_set->current_chnl = bss_conf->chandef.chan->hw_value;
+
+ pcmd->start_cmd.probe_delay = cpu_to_le16(10);
+ pcmd->start_cmd.cap_info = cpu_to_le16(mwl_vif->beacon_info.cap_info);
+
+ memcpy(&pcmd->start_cmd.wmm_param, mwl_vif->beacon_info.ie_wmm_ptr,
+ mwl_vif->beacon_info.ie_wmm_len);
+
+ memcpy(&pcmd->start_cmd.rsn_ie, mwl_vif->beacon_info.ie_rsn_ptr,
+ mwl_vif->beacon_info.ie_rsn_len);
+
+ memcpy(&pcmd->start_cmd.rsn48_ie, mwl_vif->beacon_info.ie_rsn48_ptr,
+ mwl_vif->beacon_info.ie_rsn48_len);
+
+ memcpy(pcmd->start_cmd.b_rate_set, mwl_vif->beacon_info.b_rate_set,
+ SYSADPT_MAX_DATA_RATES_G);
+
+ memcpy(pcmd->start_cmd.op_rate_set, mwl_vif->beacon_info.op_rate_set,
+ SYSADPT_MAX_DATA_RATES_G);
+
+ if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_AP_BEACON)) {
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(priv->hw->wiphy, "failed execution");
+ return -EIO;
+ }
+
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+
+ return 0;
+
+ielenerr:
+
+ wiphy_err(priv->hw->wiphy, "length of IE is too long");
+
+ return -EINVAL;
+}
+
static int mwl_fwcmd_encryption_set_cmd_info(struct hostcmd_cmd_set_key *cmd,
u8 *addr,
- struct ieee80211_key_conf *key);
+ struct ieee80211_key_conf *key)
+{
+ cmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_UPDATE_ENCRYPTION);
+ cmd->cmd_hdr.len = cpu_to_le16(sizeof(*cmd));
+ cmd->key_param.length = cpu_to_le16(sizeof(*cmd) -
+ offsetof(struct hostcmd_cmd_set_key, key_param));
+ cmd->key_param.key_index = cpu_to_le32(key->keyidx);
+ cmd->key_param.key_len = cpu_to_le16(key->keylen);
+ ether_addr_copy(cmd->key_param.mac_addr, addr);
-#ifdef MWL_DEBUG
-static char *mwl_fwcmd_get_cmd_string(unsigned short cmd);
-#endif
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ cmd->key_param.key_type_id = cpu_to_le16(KEY_TYPE_ID_WEP);
+ if (key->keyidx == 0)
+ cmd->key_param.key_info =
+ cpu_to_le32(ENCR_KEY_FLAG_WEP_TXKEY);
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ cmd->key_param.key_type_id = cpu_to_le16(KEY_TYPE_ID_TKIP);
+ cmd->key_param.key_info =
+ (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
+ cpu_to_le32(ENCR_KEY_FLAG_PAIRWISE) :
+ cpu_to_le32(ENCR_KEY_FLAG_TXGROUPKEY);
+ cmd->key_param.key_info |=
+ cpu_to_le32(ENCR_KEY_FLAG_MICKEY_VALID |
+ ENCR_KEY_FLAG_TSC_VALID);
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ cmd->key_param.key_type_id = cpu_to_le16(KEY_TYPE_ID_AES);
+ cmd->key_param.key_info =
+ (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
+ cpu_to_le32(ENCR_KEY_FLAG_PAIRWISE) :
+ cpu_to_le32(ENCR_KEY_FLAG_TXGROUPKEY);
+ break;
+ default:
+ return -ENOTSUPP;
+ }
-/* PUBLIC FUNCTION DEFINITION
-*/
+ return 0;
+}
void mwl_fwcmd_reset(struct ieee80211_hw *hw)
{
struct mwl_priv *priv;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
- if (mwl_fwcmd_chk_adapter(priv)) {
+ if (mwl_fwcmd_chk_adapter(priv))
writel(ISR_RESET,
priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
- }
-
- WLDBG_EXIT(DBG_LEVEL_2);
}
void mwl_fwcmd_int_enable(struct ieee80211_hw *hw)
{
struct mwl_priv *priv;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
if (mwl_fwcmd_chk_adapter(priv)) {
writel(0x00,
@@ -996,26 +1411,17 @@ void mwl_fwcmd_int_enable(struct ieee80211_hw *hw)
writel((MACREG_A2HRIC_BIT_MASK),
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_MASK);
}
-
- WLDBG_EXIT(DBG_LEVEL_2);
}
void mwl_fwcmd_int_disable(struct ieee80211_hw *hw)
{
struct mwl_priv *priv;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
- if (mwl_fwcmd_chk_adapter(priv)) {
+ if (mwl_fwcmd_chk_adapter(priv))
writel(0x00,
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_MASK);
- }
-
- WLDBG_EXIT(DBG_LEVEL_2);
}
int mwl_fwcmd_get_hw_specs(struct ieee80211_hw *hw)
@@ -1023,59 +1429,56 @@ int mwl_fwcmd_get_hw_specs(struct ieee80211_hw *hw)
struct mwl_priv *priv;
struct hostcmd_cmd_get_hw_spec *pcmd;
unsigned long flags;
+ int retry;
int i;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_get_hw_spec *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
- WLDBG_PRINT("pcmd = %x", (unsigned int)pcmd);
+ wiphy_debug(hw->wiphy, "pcmd = %x", (unsigned int)pcmd);
memset(pcmd, 0x00, sizeof(*pcmd));
memset(&pcmd->permanent_addr[0], 0xff, ETH_ALEN);
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_GET_HW_SPEC);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->fw_awake_cookie = ENDIAN_SWAP32(priv->pphys_cmd_buf + 2048);
-
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_GET_HW_SPEC);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->fw_awake_cookie = cpu_to_le32(priv->pphys_cmd_buf + 2048);
+ retry = 0;
while (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_GET_HW_SPEC)) {
- WLDBG_PRINT("failed execution");
- WL_MSEC_SLEEP(1000);
- WLDBG_PRINT("repeat command = %x", (unsigned int)pcmd);
+ if (retry++ > MAX_WAIT_GET_HW_SPECS_ITERATONS) {
+ wiphy_err(hw->wiphy, "can't get hw specs");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ return -EIO;
+ }
+
+ mdelay(1000);
+ wiphy_debug(hw->wiphy,
+ "repeat command = %x", (unsigned int)pcmd);
}
ether_addr_copy(&priv->hw_data.mac_addr[0], pcmd->permanent_addr);
priv->desc_data[0].wcb_base =
- ENDIAN_SWAP32(pcmd->wcb_base0) & 0x0000ffff;
+ le32_to_cpu(pcmd->wcb_base0) & 0x0000ffff;
#if SYSADPT_NUM_OF_DESC_DATA > 3
for (i = 1; i < SYSADPT_TOTAL_TX_QUEUES; i++)
priv->desc_data[i].wcb_base =
- ENDIAN_SWAP32(pcmd->wcb_base[i - 1]) & 0x0000ffff;
+ le32_to_cpu(pcmd->wcb_base[i - 1]) & 0x0000ffff;
#endif
priv->desc_data[0].rx_desc_read =
- ENDIAN_SWAP32(pcmd->rxpd_rd_ptr) & 0x0000ffff;
+ le32_to_cpu(pcmd->rxpd_rd_ptr) & 0x0000ffff;
priv->desc_data[0].rx_desc_write =
- ENDIAN_SWAP32(pcmd->rxpd_wr_ptr) & 0x0000ffff;
- priv->hw_data.region_code = ENDIAN_SWAP16(pcmd->region_code) & 0x00ff;
- priv->hw_data.fw_release_num = ENDIAN_SWAP32(pcmd->fw_release_num);
- priv->hw_data.max_num_tx_desc = ENDIAN_SWAP16(pcmd->num_wcb);
- priv->hw_data.max_num_mc_addr = ENDIAN_SWAP16(pcmd->num_mcast_addr);
- priv->hw_data.num_antennas = ENDIAN_SWAP16(pcmd->num_antenna);
+ le32_to_cpu(pcmd->rxpd_wr_ptr) & 0x0000ffff;
+ priv->hw_data.region_code = le16_to_cpu(pcmd->region_code) & 0x00ff;
+ priv->hw_data.fw_release_num = le32_to_cpu(pcmd->fw_release_num);
+ priv->hw_data.max_num_tx_desc = le16_to_cpu(pcmd->num_wcb);
+ priv->hw_data.max_num_mc_addr = le16_to_cpu(pcmd->num_mcast_addr);
+ priv->hw_data.num_antennas = le16_to_cpu(pcmd->num_antenna);
priv->hw_data.hw_version = pcmd->version;
priv->hw_data.host_interface = pcmd->host_if;
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
-
- WLDBG_EXIT_INFO(DBG_LEVEL_2,
- "region code is %i (0x%x), HW version is %i (0x%x)",
- priv->hw_data.region_code, priv->hw_data.region_code,
- priv->hw_data.hw_version, priv->hw_data.hw_version);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1087,57 +1490,52 @@ int mwl_fwcmd_set_hw_specs(struct ieee80211_hw *hw)
unsigned long flags;
int i;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
/* Info for debugging
*/
- WLDBG_PRINT("%s ...", __func__);
- WLDBG_PRINT(" -->pPhysTxRing[0] = %x",
- priv->desc_data[0].pphys_tx_ring);
- WLDBG_PRINT(" -->pPhysTxRing[1] = %x",
- priv->desc_data[1].pphys_tx_ring);
- WLDBG_PRINT(" -->pPhysTxRing[2] = %x",
- priv->desc_data[2].pphys_tx_ring);
- WLDBG_PRINT(" -->pPhysTxRing[3] = %x",
- priv->desc_data[3].pphys_tx_ring);
- WLDBG_PRINT(" -->pPhysRxRing = %x",
- priv->desc_data[0].pphys_rx_ring);
- WLDBG_PRINT(" -->numtxq %d wcbperq %d totalrxwcb %d",
- SYSADPT_NUM_OF_DESC_DATA,
- SYSADPT_MAX_NUM_TX_DESC,
- SYSADPT_MAX_NUM_RX_DESC);
+ wiphy_info(hw->wiphy, "%s ...", __func__);
+ wiphy_info(hw->wiphy, " -->pPhysTxRing[0] = %x",
+ priv->desc_data[0].pphys_tx_ring);
+ wiphy_info(hw->wiphy, " -->pPhysTxRing[1] = %x",
+ priv->desc_data[1].pphys_tx_ring);
+ wiphy_info(hw->wiphy, " -->pPhysTxRing[2] = %x",
+ priv->desc_data[2].pphys_tx_ring);
+ wiphy_info(hw->wiphy, " -->pPhysTxRing[3] = %x",
+ priv->desc_data[3].pphys_tx_ring);
+ wiphy_info(hw->wiphy, " -->pPhysRxRing = %x",
+ priv->desc_data[0].pphys_rx_ring);
+ wiphy_info(hw->wiphy, " -->numtxq %d wcbperq %d totalrxwcb %d",
+ SYSADPT_NUM_OF_DESC_DATA,
+ SYSADPT_MAX_NUM_TX_DESC,
+ SYSADPT_MAX_NUM_RX_DESC);
pcmd = (struct hostcmd_cmd_set_hw_spec *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_HW_SPEC);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->wcb_base[0] = ENDIAN_SWAP32(priv->desc_data[0].pphys_tx_ring);
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_HW_SPEC);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->wcb_base[0] = cpu_to_le32(priv->desc_data[0].pphys_tx_ring);
#if SYSADPT_NUM_OF_DESC_DATA > 3
for (i = 1; i < SYSADPT_TOTAL_TX_QUEUES; i++)
pcmd->wcb_base[i] =
- ENDIAN_SWAP32(priv->desc_data[i].pphys_tx_ring);
+ cpu_to_le32(priv->desc_data[i].pphys_tx_ring);
#endif
- pcmd->tx_wcb_num_per_queue = ENDIAN_SWAP32(SYSADPT_MAX_NUM_TX_DESC);
- pcmd->num_tx_queues = ENDIAN_SWAP32(SYSADPT_NUM_OF_DESC_DATA);
- pcmd->total_rx_wcb = ENDIAN_SWAP32(SYSADPT_MAX_NUM_RX_DESC);
- pcmd->rxpd_wr_ptr = ENDIAN_SWAP32(priv->desc_data[0].pphys_rx_ring);
- pcmd->disablembss = 0;
+ pcmd->tx_wcb_num_per_queue = cpu_to_le32(SYSADPT_MAX_NUM_TX_DESC);
+ pcmd->num_tx_queues = cpu_to_le32(SYSADPT_NUM_OF_DESC_DATA);
+ pcmd->total_rx_wcb = cpu_to_le32(SYSADPT_MAX_NUM_RX_DESC);
+ pcmd->rxpd_wr_ptr = cpu_to_le32(priv->desc_data[0].pphys_rx_ring);
+ pcmd->features = 0;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_HW_SPEC)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1149,75 +1547,44 @@ int mwl_fwcmd_get_stat(struct ieee80211_hw *hw,
struct hostcmd_cmd_802_11_get_stat *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_802_11_get_stat *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_802_11_GET_STAT);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_802_11_GET_STAT);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_GET_STAT)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
stats->dot11ACKFailureCount =
- ENDIAN_SWAP32(pcmd->ack_failures);
+ le32_to_cpu(pcmd->ack_failures);
stats->dot11RTSFailureCount =
- ENDIAN_SWAP32(pcmd->rts_failures);
+ le32_to_cpu(pcmd->rts_failures);
stats->dot11FCSErrorCount =
- ENDIAN_SWAP32(pcmd->rx_fcs_errors);
+ le32_to_cpu(pcmd->rx_fcs_errors);
stats->dot11RTSSuccessCount =
- ENDIAN_SWAP32(pcmd->rts_successes);
+ le32_to_cpu(pcmd->rts_successes);
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
int mwl_fwcmd_radio_enable(struct ieee80211_hw *hw)
{
- struct mwl_priv *priv;
- int rc;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
- priv = hw->priv;
- BUG_ON(!priv);
-
- rc = mwl_fwcmd_802_11_radio_control(priv, true, false);
-
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return rc;
+ return mwl_fwcmd_802_11_radio_control(hw->priv, true, false);
}
int mwl_fwcmd_radio_disable(struct ieee80211_hw *hw)
{
- struct mwl_priv *priv;
- int rc;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
- priv = hw->priv;
- BUG_ON(!priv);
-
- rc = mwl_fwcmd_802_11_radio_control(priv, false, false);
-
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return rc;
+ return mwl_fwcmd_802_11_radio_control(hw->priv, false, false);
}
int mwl_fwcmd_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
@@ -1225,17 +1592,11 @@ int mwl_fwcmd_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
struct mwl_priv *priv;
int rc;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
priv->radio_short_preamble = short_preamble;
rc = mwl_fwcmd_802_11_radio_control(priv, true, true);
- WLDBG_EXIT(DBG_LEVEL_2);
-
return rc;
}
@@ -1250,11 +1611,7 @@ int mwl_fwcmd_max_tx_power(struct ieee80211_hw *hw,
int i, tmp;
int rc;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
switch (fraction) {
case 0:
@@ -1280,35 +1637,40 @@ int mwl_fwcmd_max_tx_power(struct ieee80211_hw *hw,
else if (channel->band == IEEE80211_BAND_5GHZ)
band = FREQ_BAND_5GHZ;
- if ((conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
- (conf->chandef.width == NL80211_CHAN_WIDTH_20)) {
+ switch (conf->chandef.width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
width = CH_20_MHZ_WIDTH;
sub_ch = NO_EXT_CHANNEL;
-
- } else if (conf->chandef.width == NL80211_CHAN_WIDTH_40) {
+ break;
+ case NL80211_CHAN_WIDTH_40:
width = CH_40_MHZ_WIDTH;
if (conf->chandef.center_freq1 > channel->center_freq)
sub_ch = EXT_CH_ABOVE_CTRL_CH;
else
sub_ch = EXT_CH_BELOW_CTRL_CH;
- } else if (conf->chandef.width == NL80211_CHAN_WIDTH_80) {
+ break;
+ case NL80211_CHAN_WIDTH_80:
width = CH_80_MHZ_WIDTH;
if (conf->chandef.center_freq1 > channel->center_freq)
sub_ch = EXT_CH_ABOVE_CTRL_CH;
else
sub_ch = EXT_CH_BELOW_CTRL_CH;
+ break;
+ default:
+ return -EINVAL;
}
- if ((priv->powinited & 2) == 0) {
+ if ((priv->powinited & MWL_POWER_INIT_2) == 0) {
mwl_fwcmd_get_tx_powers(priv, priv->max_tx_pow,
channel->hw_value, band, width, sub_ch);
- priv->powinited |= 2;
+ priv->powinited |= MWL_POWER_INIT_2;
}
- if ((priv->powinited & 1) == 0) {
+ if ((priv->powinited & MWL_POWER_INIT_1) == 0) {
mwl_fwcmd_get_tx_powers(priv, priv->target_powers,
channel->hw_value, band, width, sub_ch);
- priv->powinited |= 1;
+ priv->powinited |= MWL_POWER_INIT_1;
}
for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++) {
@@ -1322,8 +1684,6 @@ int mwl_fwcmd_max_tx_power(struct ieee80211_hw *hw,
rc = mwl_fwcmd_set_tx_powers(priv, maxtxpow, HOSTCMD_ACT_GEN_SET,
channel->hw_value, band, width, sub_ch);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "return code: %d", rc);
-
return rc;
}
@@ -1339,11 +1699,7 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
int i, tmp;
int rc;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
switch (fraction) {
case 0:
@@ -1369,33 +1725,37 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
else if (channel->band == IEEE80211_BAND_5GHZ)
band = FREQ_BAND_5GHZ;
- if ((conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
- (conf->chandef.width == NL80211_CHAN_WIDTH_20)) {
+ switch (conf->chandef.width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
width = CH_20_MHZ_WIDTH;
sub_ch = NO_EXT_CHANNEL;
- } else if (conf->chandef.width == NL80211_CHAN_WIDTH_40) {
+ break;
+ case NL80211_CHAN_WIDTH_40:
width = CH_40_MHZ_WIDTH;
if (conf->chandef.center_freq1 > channel->center_freq)
sub_ch = EXT_CH_ABOVE_CTRL_CH;
else
sub_ch = EXT_CH_BELOW_CTRL_CH;
- } else if (conf->chandef.width == NL80211_CHAN_WIDTH_80) {
+ break;
+ case NL80211_CHAN_WIDTH_80:
width = CH_80_MHZ_WIDTH;
if (conf->chandef.center_freq1 > channel->center_freq)
sub_ch = EXT_CH_ABOVE_CTRL_CH;
else
sub_ch = EXT_CH_BELOW_CTRL_CH;
+ break;
+ default:
+ return -EINVAL;
}
- /* search tx power table if exist
- */
+ /* search tx power table if exist */
for (index = 0; index < SYSADPT_MAX_NUM_CHANNELS; index++) {
struct mwl_tx_pwr_tbl *tx_pwr;
tx_pwr = &priv->tx_pwr_tbl[index];
- /* do nothing if table is not loaded
- */
+ /* do nothing if table is not loaded */
if (tx_pwr->channel == 0)
break;
@@ -1404,9 +1764,9 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
priv->txantenna2 = tx_pwr->txantenna2;
if (tx_pwr->setcap)
- priv->powinited = 0x01;
+ priv->powinited = MWL_POWER_INIT_1;
else
- priv->powinited = 0x02;
+ priv->powinited = MWL_POWER_INIT_2;
for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++) {
if (tx_pwr->setcap)
@@ -1422,18 +1782,18 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
}
}
- if ((priv->powinited & 2) == 0) {
+ if ((priv->powinited & MWL_POWER_INIT_2) == 0) {
mwl_fwcmd_get_tx_powers(priv, priv->max_tx_pow,
channel->hw_value, band, width, sub_ch);
- priv->powinited |= 2;
+ priv->powinited |= MWL_POWER_INIT_2;
}
- if ((priv->powinited & 1) == 0) {
+ if ((priv->powinited & MWL_POWER_INIT_1) == 0) {
mwl_fwcmd_get_tx_powers(priv, priv->target_powers,
channel->hw_value, band, width, sub_ch);
- priv->powinited |= 1;
+ priv->powinited |= MWL_POWER_INIT_1;
}
for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++) {
@@ -1457,8 +1817,6 @@ int mwl_fwcmd_tx_power(struct ieee80211_hw *hw,
rc = mwl_fwcmd_set_tx_powers(priv, txpow, HOSTCMD_ACT_GEN_SET_LIST,
channel->hw_value, band, width, sub_ch);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "return code: %d", rc);
-
return rc;
}
@@ -1468,48 +1826,41 @@ int mwl_fwcmd_rf_antenna(struct ieee80211_hw *hw, int dir, int antenna)
struct hostcmd_cmd_802_11_rf_antenna *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_802_11_rf_antenna *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_802_11_RF_ANTENNA);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_802_11_RF_ANTENNA);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(dir);
+ pcmd->action = cpu_to_le16(dir);
if (dir == WL_ANTENNATYPE_RX) {
u8 rx_antenna = 4; /* if auto, set 4 rx antennas in SC2 */
if (antenna != 0)
- pcmd->antenna_mode = ENDIAN_SWAP16(antenna);
+ pcmd->antenna_mode = cpu_to_le16(antenna);
else
- pcmd->antenna_mode = ENDIAN_SWAP16(rx_antenna);
+ pcmd->antenna_mode = cpu_to_le16(rx_antenna);
} else {
u8 tx_antenna = 0xf; /* if auto, set 4 tx antennas in SC2 */
if (antenna != 0)
- pcmd->antenna_mode = ENDIAN_SWAP16(antenna);
+ pcmd->antenna_mode = cpu_to_le16(antenna);
else
- pcmd->antenna_mode = ENDIAN_SWAP16(tx_antenna);
+ pcmd->antenna_mode = cpu_to_le16(tx_antenna);
}
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
-
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_RF_ANTENNA)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1522,34 +1873,26 @@ int mwl_fwcmd_broadcast_ssid_enable(struct ieee80211_hw *hw,
struct hostcmd_cmd_broadcast_ssid_enable *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_broadcast_ssid_enable *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_BROADCAST_SSID_ENABLE);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_BROADCAST_SSID_ENABLE);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->enable = ENDIAN_SWAP32(enable);
+ pcmd->enable = cpu_to_le32(enable);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BROADCAST_SSID_ENABLE)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1561,54 +1904,62 @@ int mwl_fwcmd_set_rf_channel(struct ieee80211_hw *hw,
struct mwl_priv *priv;
struct hostcmd_cmd_set_rf_channel *pcmd;
unsigned long flags;
+ u32 chnl_flags, freq_band, chnl_width, act_primary;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_set_rf_channel *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_RF_CHANNEL);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(WL_SET);
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_RF_CHANNEL);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->action = cpu_to_le16(WL_SET);
pcmd->curr_chnl = channel->hw_value;
if (channel->band == IEEE80211_BAND_2GHZ)
- pcmd->chnl_flags.freq_band = FREQ_BAND_2DOT4GHZ;
+ freq_band = FREQ_BAND_2DOT4GHZ;
else if (channel->band == IEEE80211_BAND_5GHZ)
- pcmd->chnl_flags.freq_band = FREQ_BAND_5GHZ;
-
- if ((conf->chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
- (conf->chandef.width == NL80211_CHAN_WIDTH_20)) {
- pcmd->chnl_flags.chnl_width = CH_20_MHZ_WIDTH;
- pcmd->chnl_flags.act_primary = ACT_PRIMARY_CHAN_0;
- } else if (conf->chandef.width == NL80211_CHAN_WIDTH_40) {
- pcmd->chnl_flags.chnl_width = CH_40_MHZ_WIDTH;
+ freq_band = FREQ_BAND_5GHZ;
+ else
+ return -EINVAL;
+
+ switch (conf->chandef.width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ case NL80211_CHAN_WIDTH_20:
+ chnl_width = CH_20_MHZ_WIDTH;
+ act_primary = ACT_PRIMARY_CHAN_0;
+ break;
+ case NL80211_CHAN_WIDTH_40:
+ chnl_width = CH_40_MHZ_WIDTH;
if (conf->chandef.center_freq1 > channel->center_freq)
- pcmd->chnl_flags.act_primary = ACT_PRIMARY_CHAN_0;
+ act_primary = ACT_PRIMARY_CHAN_0;
else
- pcmd->chnl_flags.act_primary = ACT_PRIMARY_CHAN_1;
- } else if (conf->chandef.width == NL80211_CHAN_WIDTH_80) {
- pcmd->chnl_flags.chnl_width = CH_80_MHZ_WIDTH;
- pcmd->chnl_flags.act_primary =
+ act_primary = ACT_PRIMARY_CHAN_1;
+ break;
+ case NL80211_CHAN_WIDTH_80:
+ chnl_width = CH_80_MHZ_WIDTH;
+ act_primary =
mwl_fwcmd_get_80m_pri_chnl_offset(pcmd->curr_chnl);
+ break;
+ default:
+ return -EINVAL;
}
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
+ chnl_flags = (freq_band & FREQ_BAND_MASK) |
+ ((chnl_width << CHNL_WIDTH_SHIFT) & CHNL_WIDTH_MASK) |
+ ((act_primary << ACT_PRIMARY_SHIFT) & ACT_PRIMARY_MASK);
+
+ pcmd->chnl_flags = cpu_to_le32(chnl_flags);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_RF_CHANNEL)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1621,35 +1972,27 @@ int mwl_fwcmd_set_aid(struct ieee80211_hw *hw,
struct hostcmd_cmd_set_aid *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_aid *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_AID);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_AID);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->aid = ENDIAN_SWAP16(aid);
+ pcmd->aid = cpu_to_le16(aid);
ether_addr_copy(pcmd->mac_addr, bssid);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_AID)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1662,33 +2005,25 @@ int mwl_fwcmd_set_infra_mode(struct ieee80211_hw *hw,
struct hostcmd_cmd_set_infra_mode *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_infra_mode *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_INFRA_MODE);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_INFRA_MODE);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_INFRA_MODE)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1699,30 +2034,25 @@ int mwl_fwcmd_set_rts_threshold(struct ieee80211_hw *hw, int threshold)
struct hostcmd_cmd_802_11_rts_thsd *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_802_11_rts_thsd *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_802_11_RTS_THSD);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(WL_SET);
- pcmd->threshold = ENDIAN_SWAP16(threshold);
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_802_11_RTS_THSD);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->action = cpu_to_le16(WL_SET);
+ pcmd->threshold = cpu_to_le16(threshold);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_RTS_THSD)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1734,24 +2064,20 @@ int mwl_fwcmd_set_edca_params(struct ieee80211_hw *hw, u8 index,
struct hostcmd_cmd_set_edca_params *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_set_edca_params *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_EDCA_PARAMS);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_EDCA_PARAMS);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(0xffff);
- pcmd->txop = ENDIAN_SWAP16(txop);
- pcmd->cw_max = ENDIAN_SWAP32(ilog2(cw_max + 1));
- pcmd->cw_min = ENDIAN_SWAP32(ilog2(cw_min + 1));
+ pcmd->action = cpu_to_le16(0xffff);
+ pcmd->txop = cpu_to_le16(txop);
+ pcmd->cw_max = cpu_to_le32(ilog2(cw_max + 1));
+ pcmd->cw_min = cpu_to_le32(ilog2(cw_min + 1));
pcmd->aifsn = aifs;
pcmd->txq_num = index;
@@ -1764,16 +2090,13 @@ int mwl_fwcmd_set_edca_params(struct ieee80211_hw *hw, u8 index,
else if (index == 1)
pcmd->txq_num = 0;
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
-
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_EDCA_PARAMS)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1784,29 +2107,24 @@ int mwl_fwcmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable)
struct hostcmd_cmd_set_wmm_mode *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_set_wmm_mode *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_WMM_MODE);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(enable ? WL_ENABLE : WL_DISABLE);
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_WMM_MODE);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->action = cpu_to_le16(enable ? WL_ENABLE : WL_DISABLE);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_WMM_MODE)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1817,32 +2135,27 @@ int mwl_fwcmd_use_fixed_rate(struct ieee80211_hw *hw, int mcast, int mgmt)
struct hostcmd_cmd_set_fixed_rate *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_set_fixed_rate *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_FIXED_RATE);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_FIXED_RATE);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP32(HOSTCMD_ACT_NOT_USE_FIXED_RATE);
+ pcmd->action = cpu_to_le32(HOSTCMD_ACT_NOT_USE_FIXED_RATE);
pcmd->multicast_rate = mcast;
pcmd->management_rate = mgmt;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_FIXED_RATE)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1853,30 +2166,25 @@ int mwl_fwcmd_set_rate_adapt_mode(struct ieee80211_hw *hw, u16 mode)
struct hostcmd_cmd_set_rate_adapt_mode *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_set_rate_adapt_mode *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_RATE_ADAPT_MODE);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(WL_SET);
- pcmd->rate_adapt_mode = ENDIAN_SWAP16(mode);
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_RATE_ADAPT_MODE);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->action = cpu_to_le16(WL_SET);
+ pcmd->rate_adapt_mode = cpu_to_le16(mode);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_RATE_ADAPT_MODE)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1889,35 +2197,27 @@ int mwl_fwcmd_set_mac_addr_client(struct ieee80211_hw *hw,
struct hostcmd_cmd_set_mac_addr *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_mac_addr *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_MAC_ADDR);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_MAC_ADDR);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->mac_type = WL_MAC_TYPE_SECONDARY_CLIENT;
+ pcmd->mac_type = cpu_to_le16(WL_MAC_TYPE_SECONDARY_CLIENT);
ether_addr_copy(pcmd->mac_addr, mac_addr);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_MAC_ADDR)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1928,30 +2228,25 @@ int mwl_fwcmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap)
struct hostcmd_cmd_get_watchdog_bitmap *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_get_watchdog_bitmap *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_GET_WATCHDOG_BITMAP);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_GET_WATCHDOG_BITMAP);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_GET_WATCHDOG_BITMAP)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
*bitmap = pcmd->watchdog_bitmap;
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -1964,34 +2259,26 @@ int mwl_fwcmd_remove_mac_addr(struct ieee80211_hw *hw,
struct hostcmd_cmd_set_mac_addr *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_mac_addr *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_DEL_MAC_ADDR);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_DEL_MAC_ADDR);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
ether_addr_copy(pcmd->mac_addr, mac_addr);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_DEL_MAC_ADDR)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2004,15 +2291,8 @@ int mwl_fwcmd_bss_start(struct ieee80211_hw *hw,
struct hostcmd_cmd_bss_start *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
if (enable && (priv->running_bsses & (1 << mwl_vif->macid)))
return 0;
@@ -2022,25 +2302,25 @@ int mwl_fwcmd_bss_start(struct ieee80211_hw *hw,
pcmd = (struct hostcmd_cmd_bss_start *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_BSS_START);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_BSS_START);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
if (enable) {
- pcmd->enable = ENDIAN_SWAP32(WL_ENABLE);
+ pcmd->enable = cpu_to_le32(WL_ENABLE);
} else {
if (mwl_vif->macid == 0)
- pcmd->enable = ENDIAN_SWAP32(WL_DISABLE);
+ pcmd->enable = cpu_to_le32(WL_DISABLE);
else
- pcmd->enable = ENDIAN_SWAP32(WL_DISABLE_VMAC);
+ pcmd->enable = cpu_to_le32(WL_DISABLE_VMAC);
}
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BSS_START)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
@@ -2049,8 +2329,7 @@ int mwl_fwcmd_bss_start(struct ieee80211_hw *hw,
else
priv->running_bsses &= ~(1 << mwl_vif->macid);
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2061,15 +2340,8 @@ int mwl_fwcmd_set_beacon(struct ieee80211_hw *hw,
struct mwl_priv *priv;
struct mwl_vif *mwl_vif;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
mwl_fwcmd_parse_beacon(priv, mwl_vif, beacon, len);
@@ -2081,16 +2353,12 @@ int mwl_fwcmd_set_beacon(struct ieee80211_hw *hw,
mwl_vif->beacon_info.valid = false;
- WLDBG_EXIT(DBG_LEVEL_2);
-
return 0;
err:
mwl_vif->beacon_info.valid = false;
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "set beacon failed");
-
return -EIO;
}
@@ -2104,34 +2372,25 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
unsigned long flags;
u32 rates;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
-
- BUG_ON(!sta);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_new_stn *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_NEW_STN);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_NEW_STN);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->action = ENDIAN_SWAP16(HOSTCMD_ACT_STA_ACTION_ADD);
+ pcmd->action = cpu_to_le16(HOSTCMD_ACT_STA_ACTION_ADD);
if (mwl_vif->is_sta) {
pcmd->aid = 0;
pcmd->stn_id = 0;
} else {
- pcmd->aid = ENDIAN_SWAP16(sta->aid);
- pcmd->stn_id = ENDIAN_SWAP16(sta->aid);
+ pcmd->aid = cpu_to_le16(sta->aid);
+ pcmd->stn_id = cpu_to_le16(sta->aid);
}
ether_addr_copy(pcmd->mac_addr, sta->addr);
@@ -2139,14 +2398,14 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
else
rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
- pcmd->peer_info.legacy_rate_bitmap = ENDIAN_SWAP32(rates);
+ pcmd->peer_info.legacy_rate_bitmap = cpu_to_le32(rates);
if (sta->ht_cap.ht_supported) {
pcmd->peer_info.ht_rates[0] = sta->ht_cap.mcs.rx_mask[0];
pcmd->peer_info.ht_rates[1] = sta->ht_cap.mcs.rx_mask[1];
pcmd->peer_info.ht_rates[2] = sta->ht_cap.mcs.rx_mask[2];
pcmd->peer_info.ht_rates[3] = sta->ht_cap.mcs.rx_mask[3];
- pcmd->peer_info.ht_cap_info = ENDIAN_SWAP16(sta->ht_cap.cap);
+ pcmd->peer_info.ht_cap_info = cpu_to_le16(sta->ht_cap.cap);
pcmd->peer_info.mac_ht_param_info =
(sta->ht_cap.ampdu_factor & 3) |
((sta->ht_cap.ampdu_density & 7) << 2);
@@ -2154,9 +2413,9 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
if (sta->vht_cap.vht_supported) {
pcmd->peer_info.vht_max_rx_mcs =
- ENDIAN_SWAP32(*((u32 *)
+ cpu_to_le32(*((u32 *)
&sta->vht_cap.vht_mcs.rx_mcs_map));
- pcmd->peer_info.vht_cap = ENDIAN_SWAP32(sta->vht_cap.cap);
+ pcmd->peer_info.vht_cap = cpu_to_le32(sta->vht_cap.cap);
pcmd->peer_info.vht_rx_channel_width = sta->bandwidth;
}
@@ -2164,8 +2423,8 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
pcmd->qos_info = ((sta->uapsd_queues << 4) | (sta->max_sp << 1));
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
@@ -2173,14 +2432,13 @@ int mwl_fwcmd_set_new_stn_add(struct ieee80211_hw *hw,
ether_addr_copy(pcmd->mac_addr, mwl_vif->sta_mac);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2193,36 +2451,28 @@ int mwl_fwcmd_set_new_stn_add_self(struct ieee80211_hw *hw,
struct hostcmd_cmd_set_new_stn *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_new_stn *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_NEW_STN);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_NEW_STN);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->action = ENDIAN_SWAP16(HOSTCMD_ACT_STA_ACTION_ADD);
+ pcmd->action = cpu_to_le16(HOSTCMD_ACT_STA_ACTION_ADD);
ether_addr_copy(pcmd->mac_addr, vif->addr);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2235,31 +2485,24 @@ int mwl_fwcmd_set_new_stn_del(struct ieee80211_hw *hw,
struct hostcmd_cmd_set_new_stn *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_new_stn *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_NEW_STN);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_NEW_STN);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->action = ENDIAN_SWAP16(HOSTCMD_ACT_STA_ACTION_REMOVE);
+ pcmd->action = cpu_to_le16(HOSTCMD_ACT_STA_ACTION_REMOVE);
ether_addr_copy(pcmd->mac_addr, addr);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
@@ -2267,14 +2510,13 @@ int mwl_fwcmd_set_new_stn_del(struct ieee80211_hw *hw,
ether_addr_copy(pcmd->mac_addr, mwl_vif->sta_mac);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_NEW_STN)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2285,29 +2527,24 @@ int mwl_fwcmd_set_apmode(struct ieee80211_hw *hw, u8 apmode)
struct hostcmd_cmd_set_apmode *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_set_apmode *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_APMODE);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_APMODE);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->apmode = apmode;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_APMODE)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2318,35 +2555,28 @@ int mwl_fwcmd_update_encryption_enable(struct ieee80211_hw *hw,
{
struct mwl_priv *priv;
struct mwl_vif *mwl_vif;
- struct hostcmd_cmd_update_encryptoin *pcmd;
+ struct hostcmd_cmd_update_encryption *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
- pcmd = (struct hostcmd_cmd_update_encryptoin *)&priv->pcmd_buf[0];
+ pcmd = (struct hostcmd_cmd_update_encryption *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_UPDATE_ENCRYPTION);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_UPDATE_ENCRYPTION);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->action_type = ENDIAN_SWAP32(ENCR_ACTION_ENABLE_HW_ENCR);
+ pcmd->action_type = cpu_to_le32(ENCR_ACTION_ENABLE_HW_ENCR);
ether_addr_copy(pcmd->mac_addr, addr);
pcmd->action_data[0] = encr_type;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
@@ -2357,14 +2587,13 @@ int mwl_fwcmd_update_encryption_enable(struct ieee80211_hw *hw,
ether_addr_copy(pcmd->mac_addr, mwl_vif->bssid);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2382,29 +2611,22 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
u32 action;
u8 idx;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_key *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_UPDATE_ENCRYPTION);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_UPDATE_ENCRYPTION);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
rc = mwl_fwcmd_encryption_set_cmd_info(pcmd, addr, key);
if (rc) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "encryption not support");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "encryption not support");
return rc;
}
@@ -2434,17 +2656,17 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
keymlen = key->keylen;
break;
default:
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "encryption not support");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "encryption not support");
return -ENOTSUPP;
}
memcpy((void *)&pcmd->key_param.key, key->key, keymlen);
- pcmd->action_type = ENDIAN_SWAP32(action);
+ pcmd->action_type = cpu_to_le32(action);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
@@ -2457,14 +2679,13 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
mwl_vif->bssid);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2479,46 +2700,38 @@ int mwl_fwcmd_encryption_remove_key(struct ieee80211_hw *hw,
unsigned long flags;
int rc;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_set_key *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_UPDATE_ENCRYPTION);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_UPDATE_ENCRYPTION);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
rc = mwl_fwcmd_encryption_set_cmd_info(pcmd, addr, key);
if (rc) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "encryption not support");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "encryption not support");
return rc;
}
- pcmd->action_type = ENDIAN_SWAP32(ENCR_ACTION_TYPE_REMOVE_KEY);
+ pcmd->action_type = cpu_to_le32(ENCR_ACTION_TYPE_REMOVE_KEY);
if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
key->cipher == WLAN_CIPHER_SUITE_WEP104)
mwl_vif->wep_key_conf[key->keyidx].enabled = 0;
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_UPDATE_ENCRYPTION)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2531,55 +2744,45 @@ int mwl_fwcmd_check_ba(struct ieee80211_hw *hw,
struct mwl_vif *mwl_vif;
struct hostcmd_cmd_bastream *pcmd;
unsigned long flags;
+ u32 ba_flags, ba_type, ba_direction;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!stream);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_bastream *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_BASTREAM);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_BASTREAM);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->cmd_hdr.result = ENDIAN_SWAP16(0xffff);
+ pcmd->cmd_hdr.result = cpu_to_le16(0xffff);
- pcmd->action_type = ENDIAN_SWAP32(BA_CHECK_STREAM);
+ pcmd->action_type = cpu_to_le32(BA_CHECK_STREAM);
memcpy(&pcmd->ba_info.create_params.peer_mac_addr[0],
stream->sta->addr, ETH_ALEN);
pcmd->ba_info.create_params.tid = stream->tid;
- pcmd->ba_info.create_params.flags.ba_type =
- BASTREAM_FLAG_IMMEDIATE_TYPE;
- pcmd->ba_info.create_params.flags.ba_direction =
- BASTREAM_FLAG_DIRECTION_UPSTREAM;
+ ba_type = BASTREAM_FLAG_IMMEDIATE_TYPE;
+ ba_direction = BASTREAM_FLAG_DIRECTION_UPSTREAM;
+ ba_flags = (ba_type & BA_TYPE_MASK) |
+ ((ba_direction << BA_DIRECTION_SHIFT) & BA_DIRECTION_MASK);
+ pcmd->ba_info.create_params.flags = cpu_to_le32(ba_flags);
pcmd->ba_info.create_params.queue_id = stream->idx;
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
-
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BASTREAM)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
if (pcmd->cmd_hdr.result != 0) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "result error");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "result error");
return -EINVAL;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2592,39 +2795,32 @@ int mwl_fwcmd_create_ba(struct ieee80211_hw *hw,
struct mwl_vif *mwl_vif;
struct hostcmd_cmd_bastream *pcmd;
unsigned long flags;
+ u32 ba_flags, ba_type, ba_direction;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!stream);
-
- BUG_ON(!vif);
- mwl_vif = MWL_VIF(vif);
- BUG_ON(!mwl_vif);
+ mwl_vif = mwl_dev_get_vif(vif);
pcmd = (struct hostcmd_cmd_bastream *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_BASTREAM);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_BASTREAM);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
pcmd->cmd_hdr.macid = mwl_vif->macid;
- pcmd->cmd_hdr.result = ENDIAN_SWAP16(0xffff);
+ pcmd->cmd_hdr.result = cpu_to_le16(0xffff);
- pcmd->action_type = ENDIAN_SWAP32(BA_CREATE_STREAM);
- pcmd->ba_info.create_params.bar_thrs = ENDIAN_SWAP32(buf_size);
- pcmd->ba_info.create_params.window_size = ENDIAN_SWAP32(buf_size);
+ pcmd->action_type = cpu_to_le32(BA_CREATE_STREAM);
+ pcmd->ba_info.create_params.bar_thrs = cpu_to_le32(buf_size);
+ pcmd->ba_info.create_params.window_size = cpu_to_le32(buf_size);
memcpy(&pcmd->ba_info.create_params.peer_mac_addr[0],
stream->sta->addr, ETH_ALEN);
pcmd->ba_info.create_params.tid = stream->tid;
- pcmd->ba_info.create_params.flags.ba_type =
- BASTREAM_FLAG_IMMEDIATE_TYPE;
- pcmd->ba_info.create_params.flags.ba_direction =
- BASTREAM_FLAG_DIRECTION_UPSTREAM;
+ ba_type = BASTREAM_FLAG_IMMEDIATE_TYPE;
+ ba_direction = BASTREAM_FLAG_DIRECTION_UPSTREAM;
+ ba_flags = (ba_type & BA_TYPE_MASK) |
+ ((ba_direction << BA_DIRECTION_SHIFT) & BA_DIRECTION_MASK);
+ pcmd->ba_info.create_params.flags = cpu_to_le32(ba_flags);
pcmd->ba_info.create_params.queue_id = stream->idx;
pcmd->ba_info.create_params.param_info =
(stream->sta->ht_cap.ampdu_factor &
@@ -2632,24 +2828,21 @@ int mwl_fwcmd_create_ba(struct ieee80211_hw *hw,
((stream->sta->ht_cap.ampdu_density << 2) &
IEEE80211_HT_AMPDU_PARM_DENSITY);
pcmd->ba_info.create_params.reset_seq_no = 1;
- pcmd->ba_info.create_params.current_seq = ENDIAN_SWAP16(0);
-
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
+ pcmd->ba_info.create_params.current_seq = cpu_to_le16(0);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BASTREAM)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
if (pcmd->cmd_hdr.result != 0) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "result error");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "result error");
return -EINVAL;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2660,42 +2853,38 @@ int mwl_fwcmd_destroy_ba(struct ieee80211_hw *hw,
struct mwl_priv *priv;
struct hostcmd_cmd_bastream *pcmd;
unsigned long flags;
+ u32 ba_flags, ba_type, ba_direction;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_bastream *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_BASTREAM);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_BASTREAM);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
- pcmd->action_type = ENDIAN_SWAP32(BA_DESTROY_STREAM);
- pcmd->ba_info.destroy_params.flags.ba_type =
- BASTREAM_FLAG_IMMEDIATE_TYPE;
- pcmd->ba_info.destroy_params.flags.ba_direction =
- BASTREAM_FLAG_DIRECTION_UPSTREAM;
- pcmd->ba_info.destroy_params.fw_ba_context.context = ENDIAN_SWAP32(idx);
+ pcmd->action_type = cpu_to_le32(BA_DESTROY_STREAM);
+ ba_type = BASTREAM_FLAG_IMMEDIATE_TYPE;
+ ba_direction = BASTREAM_FLAG_DIRECTION_UPSTREAM;
+ ba_flags = (ba_type & BA_TYPE_MASK) |
+ ((ba_direction << BA_DIRECTION_SHIFT) & BA_DIRECTION_MASK);
+ pcmd->ba_info.destroy_params.flags = cpu_to_le32(ba_flags);
+ pcmd->ba_info.destroy_params.fw_ba_context.context = cpu_to_le32(idx);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BASTREAM)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
-/* caller must hold priv->locks.stream_lock when calling the stream functions
-*/
+/* caller must hold priv->stream_lock when calling the stream functions */
struct mwl_ampdu_stream *mwl_fwcmd_add_stream(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
u8 tid)
@@ -2704,11 +2893,7 @@ struct mwl_ampdu_stream *mwl_fwcmd_add_stream(struct ieee80211_hw *hw,
struct mwl_ampdu_stream *stream;
int i;
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!sta);
for (i = 0; i < SYSADPT_TX_AMPDU_QUEUES; i++) {
stream = &priv->ampdu[i];
@@ -2728,11 +2913,7 @@ struct mwl_ampdu_stream *mwl_fwcmd_add_stream(struct ieee80211_hw *hw,
int mwl_fwcmd_start_stream(struct ieee80211_hw *hw,
struct mwl_ampdu_stream *stream)
{
- BUG_ON(!hw);
- BUG_ON(!stream);
-
- /* if the stream has already been started, don't start it again
- */
+ /* if the stream has already been started, don't start it again */
if (stream->state != AMPDU_STREAM_NEW)
return 0;
@@ -2742,9 +2923,6 @@ int mwl_fwcmd_start_stream(struct ieee80211_hw *hw,
void mwl_fwcmd_remove_stream(struct ieee80211_hw *hw,
struct mwl_ampdu_stream *stream)
{
- BUG_ON(!hw);
- BUG_ON(!stream);
-
memset(stream, 0, sizeof(*stream));
}
@@ -2755,9 +2933,7 @@ struct mwl_ampdu_stream *mwl_fwcmd_lookup_stream(struct ieee80211_hw *hw,
struct mwl_ampdu_stream *stream;
int i;
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
for (i = 0; i < SYSADPT_TX_AMPDU_QUEUES; i++) {
stream = &priv->ampdu[i];
@@ -2778,9 +2954,7 @@ bool mwl_fwcmd_ampdu_allowed(struct ieee80211_sta *sta, u8 tid)
struct mwl_sta *sta_info;
struct mwl_tx_info *tx_stats;
- BUG_ON(!sta);
- sta_info = MWL_STA(sta);
- BUG_ON(!sta_info);
+ sta_info = mwl_dev_get_sta(sta);
BUG_ON(tid >= SYSADPT_MAX_TID);
@@ -2796,29 +2970,24 @@ int mwl_fwcmd_set_dwds_stamode(struct ieee80211_hw *hw, bool enable)
struct hostcmd_cmd_dwds_enable *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_dwds_enable *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_DWDS_ENABLE);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->enable = ENDIAN_SWAP32(enable);
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_DWDS_ENABLE);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->enable = cpu_to_le32(enable);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_DWDS_ENABLE)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2829,29 +2998,24 @@ int mwl_fwcmd_set_fw_flush_timer(struct ieee80211_hw *hw, u32 value)
struct hostcmd_cmd_fw_flush_timer *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_fw_flush_timer *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_FW_FLUSH_TIMER);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->value = ENDIAN_SWAP32(value);
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_FW_FLUSH_TIMER);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->value = cpu_to_le32(value);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_FW_FLUSH_TIMER)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
@@ -2862,754 +3026,24 @@ int mwl_fwcmd_set_cdd(struct ieee80211_hw *hw)
struct hostcmd_cmd_set_cdd *pcmd;
unsigned long flags;
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
pcmd = (struct hostcmd_cmd_set_cdd *)&priv->pcmd_buf[0];
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
+ spin_lock_irqsave(&priv->fwcmd_lock, flags);
memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_CDD);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->enable = ENDIAN_SWAP32(priv->cdd);
+ pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_SET_CDD);
+ pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
+ pcmd->enable = cpu_to_le32(priv->cdd);
if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_CDD)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
- return -EIO;
- }
-
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return 0;
-}
-
-/* PRIVATE FUNCTION DEFINITION
-*/
-
-static bool mwl_fwcmd_chk_adapter(struct mwl_priv *priv)
-{
- u32 regval;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
-
- regval = readl(priv->iobase1 + MACREG_REG_INT_CODE);
-
- if (regval == 0xffffffff) {
- WLDBG_ERROR(DBG_LEVEL_2, "adapter is not existed");
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "adapter is not existed");
-
- return false;
- }
-
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return true;
-}
-
-static int mwl_fwcmd_exec_cmd(struct mwl_priv *priv, unsigned short cmd)
-{
- bool busy = false;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
-
- if (!mwl_fwcmd_chk_adapter(priv)) {
- WLDBG_ERROR(DBG_LEVEL_2, "no adapter existed");
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "no adapter plugged in");
- priv->in_send_cmd = false;
- return -EIO;
- }
-
- if (!priv->in_send_cmd) {
- priv->in_send_cmd = true;
- mwl_fwcmd_send_cmd(priv);
- if (mwl_fwcmd_wait_complete(priv, 0x8000 | cmd)) {
- WLDBG_ERROR(DBG_LEVEL_2, "timeout");
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "timeout");
- priv->in_send_cmd = false;
- return -EIO;
- }
- } else {
- WLDBG_WARNING(DBG_LEVEL_2, "previous command is still running");
- busy = true;
- }
-
- WLDBG_EXIT(DBG_LEVEL_2);
- if (!busy)
- priv->in_send_cmd = false;
-
- return 0;
-}
-
-static void mwl_fwcmd_send_cmd(struct mwl_priv *priv)
-{
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
-
- writel(priv->pphys_cmd_buf, priv->iobase1 + MACREG_REG_GEN_PTR);
- writel(MACREG_H2ARIC_BIT_DOOR_BELL,
- priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
-
- WLDBG_EXIT(DBG_LEVEL_2);
-}
-
-static int mwl_fwcmd_wait_complete(struct mwl_priv *priv, unsigned short cmd)
-{
- unsigned int curr_iteration = MAX_WAIT_FW_COMPLETE_ITERATIONS;
-
- unsigned short int_code = 0;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
-
- do {
- int_code = ENDIAN_SWAP16(priv->pcmd_buf[0]);
- WL_MSEC_SLEEP(1);
- } while ((int_code != cmd) && (--curr_iteration));
-
- if (curr_iteration == 0) {
- WLDBG_ERROR(DBG_LEVEL_2, "cmd 0x%04x=%s timed out",
- cmd, mwl_fwcmd_get_cmd_string(cmd));
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "timeout");
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
+ wiphy_err(hw->wiphy, "failed execution");
return -EIO;
}
- WL_MSEC_SLEEP(3);
-
- WLDBG_EXIT(DBG_LEVEL_2);
+ spin_unlock_irqrestore(&priv->fwcmd_lock, flags);
return 0;
}
-
-static int mwl_fwcmd_802_11_radio_control(struct mwl_priv *priv,
- bool enable, bool force)
-{
- struct hostcmd_cmd_802_11_radio_control *pcmd;
- unsigned long flags;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
-
- if (enable == priv->radio_on && !force)
- return 0;
-
- pcmd = (struct hostcmd_cmd_802_11_radio_control *)&priv->pcmd_buf[0];
-
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
-
- memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_802_11_RADIO_CONTROL);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(WL_SET);
- pcmd->control = ENDIAN_SWAP16(priv->radio_short_preamble ?
- WL_AUTO_PREAMBLE : WL_LONG_PREAMBLE);
- pcmd->radio_on = ENDIAN_SWAP16(enable ? WL_ENABLE : WL_DISABLE);
-
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
-
- if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_RADIO_CONTROL)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
- return -EIO;
- }
-
- priv->radio_on = enable;
-
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return 0;
-}
-
-static int mwl_fwcmd_get_tx_powers(struct mwl_priv *priv, u16 *powlist, u16 ch,
- u16 band, u16 width, u16 sub_ch)
-{
- struct hostcmd_cmd_802_11_tx_power *pcmd;
- unsigned long flags;
- int i;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
-
- pcmd = (struct hostcmd_cmd_802_11_tx_power *)&priv->pcmd_buf[0];
-
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
-
- memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_802_11_TX_POWER);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(HOSTCMD_ACT_GEN_GET_LIST);
- pcmd->ch = ENDIAN_SWAP16(ch);
- pcmd->bw = ENDIAN_SWAP16(width);
- pcmd->band = ENDIAN_SWAP16(band);
- pcmd->sub_ch = ENDIAN_SWAP16(sub_ch);
-
- if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_TX_POWER)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
- return -EIO;
- }
-
- for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++)
- powlist[i] = (u8)ENDIAN_SWAP16(pcmd->power_level_list[i]);
-
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return 0;
-}
-
-static int mwl_fwcmd_set_tx_powers(struct mwl_priv *priv, u16 txpow[],
- u8 action, u16 ch, u16 band,
- u16 width, u16 sub_ch)
-{
- struct hostcmd_cmd_802_11_tx_power *pcmd;
- unsigned long flags;
- int i;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
-
- pcmd = (struct hostcmd_cmd_802_11_tx_power *)&priv->pcmd_buf[0];
-
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
-
- memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_802_11_TX_POWER);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->action = ENDIAN_SWAP16(action);
- pcmd->ch = ENDIAN_SWAP16(ch);
- pcmd->bw = ENDIAN_SWAP16(width);
- pcmd->band = ENDIAN_SWAP16(band);
- pcmd->sub_ch = ENDIAN_SWAP16(sub_ch);
-
- for (i = 0; i < SYSADPT_TX_POWER_LEVEL_TOTAL; i++)
- pcmd->power_level_list[i] = ENDIAN_SWAP16(txpow[i]);
-
- if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_802_11_TX_POWER)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
- return -EIO;
- }
-
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return 0;
-}
-
-static u8 mwl_fwcmd_get_80m_pri_chnl_offset(u8 channel)
-{
- u8 act_primary = ACT_PRIMARY_CHAN_0;
-
- switch (channel) {
- case 36:
- act_primary = ACT_PRIMARY_CHAN_0;
- break;
- case 40:
- act_primary = ACT_PRIMARY_CHAN_1;
- break;
- case 44:
- act_primary = ACT_PRIMARY_CHAN_2;
- break;
- case 48:
- act_primary = ACT_PRIMARY_CHAN_3;
- break;
- case 52:
- act_primary = ACT_PRIMARY_CHAN_0;
- break;
- case 56:
- act_primary = ACT_PRIMARY_CHAN_1;
- break;
- case 60:
- act_primary = ACT_PRIMARY_CHAN_2;
- break;
- case 64:
- act_primary = ACT_PRIMARY_CHAN_3;
- break;
- case 100:
- act_primary = ACT_PRIMARY_CHAN_0;
- break;
- case 104:
- act_primary = ACT_PRIMARY_CHAN_1;
- break;
- case 108:
- act_primary = ACT_PRIMARY_CHAN_2;
- break;
- case 112:
- act_primary = ACT_PRIMARY_CHAN_3;
- break;
- case 116:
- act_primary = ACT_PRIMARY_CHAN_0;
- break;
- case 120:
- act_primary = ACT_PRIMARY_CHAN_1;
- break;
- case 124:
- act_primary = ACT_PRIMARY_CHAN_2;
- break;
- case 128:
- act_primary = ACT_PRIMARY_CHAN_3;
- break;
- case 132:
- act_primary = ACT_PRIMARY_CHAN_0;
- break;
- case 136:
- act_primary = ACT_PRIMARY_CHAN_1;
- break;
- case 140:
- act_primary = ACT_PRIMARY_CHAN_2;
- break;
- case 144:
- act_primary = ACT_PRIMARY_CHAN_3;
- break;
- case 149:
- act_primary = ACT_PRIMARY_CHAN_0;
- break;
- case 153:
- act_primary = ACT_PRIMARY_CHAN_1;
- break;
- case 157:
- act_primary = ACT_PRIMARY_CHAN_2;
- break;
- case 161:
- act_primary = ACT_PRIMARY_CHAN_3;
- break;
- }
-
- return act_primary;
-}
-
-static void mwl_fwcmd_parse_beacon(struct mwl_priv *priv,
- struct mwl_vif *vif, u8 *beacon, int len)
-{
- struct ieee80211_mgmt *mgmt;
- struct beacon_info *beacon_info;
- int baselen;
- u8 *pos;
- size_t left;
- bool elem_parse_failed;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!vif);
- BUG_ON(!beacon);
-
- mgmt = (struct ieee80211_mgmt *)beacon;
-
- baselen = (u8 *)mgmt->u.beacon.variable - (u8 *)mgmt;
- if (baselen > len)
- return;
-
- beacon_info = &vif->beacon_info;
- memset(beacon_info, 0, sizeof(struct beacon_info));
- beacon_info->valid = false;
- beacon_info->ie_ht_ptr = &beacon_info->ie_list_ht[0];
- beacon_info->ie_vht_ptr = &beacon_info->ie_list_vht[0];
-
- beacon_info->cap_info = mgmt->u.beacon.capab_info;
-
- pos = (u8 *)mgmt->u.beacon.variable;
- left = len - baselen;
-
- elem_parse_failed = false;
-
- while (left >= 2) {
- u8 id, elen;
-
- id = *pos++;
- elen = *pos++;
- left -= 2;
-
- if (elen > left) {
- elem_parse_failed = true;
- break;
- }
-
- switch (id) {
- case WLAN_EID_SUPP_RATES:
- case WLAN_EID_EXT_SUPP_RATES:
- {
- int idx, bi, oi;
- u8 rate;
-
- for (bi = 0; bi < SYSADPT_MAX_DATA_RATES_G;
- bi++) {
- if (beacon_info->b_rate_set[bi] == 0)
- break;
- }
-
- for (oi = 0; oi < SYSADPT_MAX_DATA_RATES_G;
- oi++) {
- if (beacon_info->op_rate_set[oi] == 0)
- break;
- }
-
- for (idx = 0; idx < elen; idx++) {
- rate = pos[idx];
- if ((rate & 0x80) != 0) {
- if (bi < SYSADPT_MAX_DATA_RATES_G)
- beacon_info->b_rate_set[bi++]
- = rate & 0x7f;
- else {
- elem_parse_failed = true;
- break;
- }
- }
- if (oi < SYSADPT_MAX_DATA_RATES_G)
- beacon_info->op_rate_set[oi++] =
- rate & 0x7f;
- else {
- elem_parse_failed = true;
- break;
- }
- }
- }
- break;
- case WLAN_EID_RSN:
- beacon_info->ie_rsn48_len = (elen + 2);
- beacon_info->ie_rsn48_ptr = (pos - 2);
- break;
- case WLAN_EID_HT_CAPABILITY:
- case WLAN_EID_HT_OPERATION:
- case WLAN_EID_OVERLAP_BSS_SCAN_PARAM:
- case WLAN_EID_EXT_CAPABILITY:
- beacon_info->ie_ht_len += (elen + 2);
- if (beacon_info->ie_ht_len >
- sizeof(beacon_info->ie_list_ht)) {
- elem_parse_failed = true;
- } else {
- *beacon_info->ie_ht_ptr++ = id;
- *beacon_info->ie_ht_ptr++ = elen;
- memcpy(beacon_info->ie_ht_ptr, pos, elen);
- beacon_info->ie_ht_ptr += elen;
- }
- break;
- case WLAN_EID_VHT_CAPABILITY:
- case WLAN_EID_VHT_OPERATION:
- case WLAN_EID_OPMODE_NOTIF:
- beacon_info->ie_vht_len += (elen + 2);
- if (beacon_info->ie_vht_len >
- sizeof(beacon_info->ie_list_vht)) {
- elem_parse_failed = true;
- } else {
- *beacon_info->ie_vht_ptr++ = id;
- *beacon_info->ie_vht_ptr++ = elen;
- memcpy(beacon_info->ie_vht_ptr, pos, elen);
- beacon_info->ie_vht_ptr += elen;
- }
- break;
- case WLAN_EID_VENDOR_SPECIFIC:
- if ((pos[0] == 0x00) && (pos[1] == 0x50) &&
- (pos[2] == 0xf2)) {
- if (pos[3] == 0x01) {
- beacon_info->ie_rsn_len = (elen + 2);
- beacon_info->ie_rsn_ptr = (pos - 2);
- }
-
- if (pos[3] == 0x02) {
- beacon_info->ie_wmm_len = (elen + 2);
- beacon_info->ie_wmm_ptr = (pos - 2);
- }
- }
- break;
- default:
- break;
- }
-
- left -= elen;
- pos += elen;
- }
-
- if (!elem_parse_failed) {
- beacon_info->ie_ht_ptr = &beacon_info->ie_list_ht[0];
- beacon_info->ie_vht_ptr = &beacon_info->ie_list_vht[0];
- beacon_info->valid = true;
-
- WLDBG_INFO(DBG_LEVEL_2,
- "wmm:%d, rsn:%d, rsn48:%d, ht:%d, vht:%d",
- beacon_info->ie_wmm_len,
- beacon_info->ie_rsn_len,
- beacon_info->ie_rsn48_len,
- beacon_info->ie_ht_len,
- beacon_info->ie_vht_len);
-
- WLDBG_DUMP_DATA(DBG_LEVEL_2, beacon_info->b_rate_set,
- SYSADPT_MAX_DATA_RATES_G);
-
- WLDBG_DUMP_DATA(DBG_LEVEL_2, beacon_info->op_rate_set,
- SYSADPT_MAX_DATA_RATES_G);
- }
-
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "parse valid:%d", beacon_info->valid);
-}
-
-static int mwl_fwcmd_set_ies(struct mwl_priv *priv, struct mwl_vif *mwl_vif)
-{
- struct hostcmd_cmd_set_ies *pcmd;
- unsigned long flags;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
- BUG_ON(!mwl_vif);
-
- if (!mwl_vif->beacon_info.valid)
- return -EINVAL;
-
- if (mwl_vif->beacon_info.ie_ht_len > sizeof(pcmd->ie_list_ht))
- goto einval;
-
- if (mwl_vif->beacon_info.ie_vht_len > sizeof(pcmd->ie_list_vht))
- goto einval;
-
- pcmd = (struct hostcmd_cmd_set_ies *)&priv->pcmd_buf[0];
-
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
-
- memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_SET_IES);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->cmd_hdr.macid = mwl_vif->macid;
-
- pcmd->action = ENDIAN_SWAP16(HOSTCMD_ACT_GEN_SET);
-
- pcmd->ie_list_len_ht = mwl_vif->beacon_info.ie_ht_len;
- memcpy(pcmd->ie_list_ht, mwl_vif->beacon_info.ie_ht_ptr,
- pcmd->ie_list_len_ht);
-
- pcmd->ie_list_len_vht = mwl_vif->beacon_info.ie_vht_len;
- memcpy(pcmd->ie_list_vht, mwl_vif->beacon_info.ie_vht_ptr,
- pcmd->ie_list_len_vht);
-
- if (priv->chip_type == MWL8897) {
- pcmd->ie_list_len_proprietary = mwl_vif->beacon_info.ie_wmm_len;
- memcpy(pcmd->ie_list_proprietary,
- mwl_vif->beacon_info.ie_wmm_ptr,
- pcmd->ie_list_len_proprietary);
- }
-
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
-
- if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_SET_IES)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
- return -EIO;
- }
-
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return 0;
-
-einval:
-
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "length of IE is too long");
-
- return -EINVAL;
-}
-
-static int mwl_fwcmd_set_ap_beacon(struct mwl_priv *priv,
- struct mwl_vif *mwl_vif,
- struct ieee80211_bss_conf *bss_conf)
-{
- struct hostcmd_cmd_ap_beacon *pcmd;
- unsigned long flags;
- struct ds_params *phy_ds_param_set;
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- BUG_ON(!priv);
- BUG_ON(!mwl_vif);
- BUG_ON(!bss_conf);
-
- if (!mwl_vif->beacon_info.valid)
- return -EINVAL;
-
- /* wmm structure of start command is defined less one byte,
- * due to following field country is not used, add byte one
- * to bypass the check.
- */
- if (mwl_vif->beacon_info.ie_wmm_len >
- (sizeof(pcmd->start_cmd.wmm_param) + 1))
- goto ielenerr;
-
- if (mwl_vif->beacon_info.ie_rsn_len > sizeof(pcmd->start_cmd.rsn_ie))
- goto ielenerr;
-
- if (mwl_vif->beacon_info.ie_rsn48_len >
- sizeof(pcmd->start_cmd.rsn48_ie))
- goto ielenerr;
-
- pcmd = (struct hostcmd_cmd_ap_beacon *)&priv->pcmd_buf[0];
-
- MWL_SPIN_LOCK(&priv->locks.fwcmd_lock);
-
- memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_AP_BEACON);
- pcmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*pcmd));
- pcmd->cmd_hdr.macid = mwl_vif->macid;
-
- ether_addr_copy(pcmd->start_cmd.sta_mac_addr, mwl_vif->bssid);
- memcpy(pcmd->start_cmd.ssid, bss_conf->ssid, bss_conf->ssid_len);
- pcmd->start_cmd.bss_type = 1;
- pcmd->start_cmd.bcn_period = ENDIAN_SWAP16(bss_conf->beacon_int);
- pcmd->start_cmd.dtim_period = bss_conf->dtim_period; /* 8bit */
-
- phy_ds_param_set = &pcmd->start_cmd.phy_param_set.ds_param_set;
- phy_ds_param_set->elem_id = WLAN_EID_DS_PARAMS;
- phy_ds_param_set->len = sizeof(phy_ds_param_set->current_chnl);
- phy_ds_param_set->current_chnl = bss_conf->chandef.chan->hw_value;
-
- pcmd->start_cmd.probe_delay = ENDIAN_SWAP16(10);
- pcmd->start_cmd.cap_info = ENDIAN_SWAP16(mwl_vif->beacon_info.cap_info);
-
- memcpy(&pcmd->start_cmd.wmm_param, mwl_vif->beacon_info.ie_wmm_ptr,
- mwl_vif->beacon_info.ie_wmm_len);
-
- memcpy(&pcmd->start_cmd.rsn_ie, mwl_vif->beacon_info.ie_rsn_ptr,
- mwl_vif->beacon_info.ie_rsn_len);
-
- memcpy(&pcmd->start_cmd.rsn48_ie, mwl_vif->beacon_info.ie_rsn48_ptr,
- mwl_vif->beacon_info.ie_rsn48_len);
-
- memcpy(pcmd->start_cmd.b_rate_set, mwl_vif->beacon_info.b_rate_set,
- SYSADPT_MAX_DATA_RATES_G);
-
- memcpy(pcmd->start_cmd.op_rate_set, mwl_vif->beacon_info.op_rate_set,
- SYSADPT_MAX_DATA_RATES_G);
-
- WLDBG_DUMP_DATA(DBG_LEVEL_2, (void *)pcmd, sizeof(*pcmd));
-
- if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_AP_BEACON)) {
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "failed execution");
- return -EIO;
- }
-
- MWL_SPIN_UNLOCK(&priv->locks.fwcmd_lock);
- WLDBG_EXIT(DBG_LEVEL_2);
-
- return 0;
-
-ielenerr:
-
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "length of IE is too long");
-
- return -EINVAL;
-}
-
-static int mwl_fwcmd_encryption_set_cmd_info(struct hostcmd_cmd_set_key *cmd,
- u8 *addr,
- struct ieee80211_key_conf *key)
-{
- cmd->cmd_hdr.cmd = ENDIAN_SWAP16(HOSTCMD_CMD_UPDATE_ENCRYPTION);
- cmd->cmd_hdr.len = ENDIAN_SWAP16(sizeof(*cmd));
- cmd->key_param.length = ENDIAN_SWAP16(sizeof(*cmd) -
- offsetof(struct hostcmd_cmd_set_key, key_param));
- cmd->key_param.key_index = ENDIAN_SWAP32(key->keyidx);
- cmd->key_param.key_len = ENDIAN_SWAP16(key->keylen);
- ether_addr_copy(cmd->key_param.mac_addr, addr);
-
- switch (key->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- cmd->key_param.key_type_id = ENDIAN_SWAP16(KEY_TYPE_ID_WEP);
- if (key->keyidx == 0)
- cmd->key_param.key_info =
- ENDIAN_SWAP32(ENCR_KEY_FLAG_WEP_TXKEY);
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- cmd->key_param.key_type_id = ENDIAN_SWAP16(KEY_TYPE_ID_TKIP);
- cmd->key_param.key_info =
- (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
- ENDIAN_SWAP32(ENCR_KEY_FLAG_PAIRWISE) :
- ENDIAN_SWAP32(ENCR_KEY_FLAG_TXGROUPKEY);
- cmd->key_param.key_info |=
- ENDIAN_SWAP32(ENCR_KEY_FLAG_MICKEY_VALID |
- ENCR_KEY_FLAG_TSC_VALID);
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- cmd->key_param.key_type_id = ENDIAN_SWAP16(KEY_TYPE_ID_AES);
- cmd->key_param.key_info =
- (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ?
- ENDIAN_SWAP32(ENCR_KEY_FLAG_PAIRWISE) :
- ENDIAN_SWAP32(ENCR_KEY_FLAG_TXGROUPKEY);
- break;
- default:
- return -ENOTSUPP;
- }
-
- return 0;
-}
-
-#ifdef MWL_DEBUG
-static char *mwl_fwcmd_get_cmd_string(unsigned short cmd)
-{
- int max_entries = 0;
- int curr_cmd = 0;
-
- static const struct {
- u16 cmd;
- char *cmd_string;
- } cmds[] = {
- { HOSTCMD_CMD_GET_HW_SPEC, "GetHwSpecifications" },
- { HOSTCMD_CMD_SET_HW_SPEC, "SetHwSepcifications" },
- { HOSTCMD_CMD_802_11_GET_STAT, "80211GetStat" },
- { HOSTCMD_CMD_802_11_RADIO_CONTROL, "80211RadioControl" },
- { HOSTCMD_CMD_802_11_TX_POWER, "80211TxPower" },
- { HOSTCMD_CMD_802_11_RF_ANTENNA, "80211RfAntenna" },
- { HOSTCMD_CMD_BROADCAST_SSID_ENABLE, "broadcast_ssid_enable" },
- { HOSTCMD_CMD_SET_RF_CHANNEL, "SetRfChannel" },
- { HOSTCMD_CMD_SET_AID, "SetAid" },
- { HOSTCMD_CMD_SET_INFRA_MODE, "SetInfraMode" },
- { HOSTCMD_CMD_802_11_RTS_THSD, "80211RtsThreshold" },
- { HOSTCMD_CMD_SET_EDCA_PARAMS, "SetEDCAParams" },
- { HOSTCMD_CMD_SET_WMM_MODE, "SetWMMMode" },
- { HOSTCMD_CMD_SET_FIXED_RATE, "SetFixedRate" },
- { HOSTCMD_CMD_SET_IES, "SetInformationElements" },
- { HOSTCMD_CMD_SET_RATE_ADAPT_MODE, "SetRateAdaptationMode" },
- { HOSTCMD_CMD_SET_MAC_ADDR, "SetMacAddr" },
- { HOSTCMD_CMD_GET_WATCHDOG_BITMAP, "GetWatchdogBitMap" },
- { HOSTCMD_CMD_DEL_MAC_ADDR. "DelMacAddr" },
- { HOSTCMD_CMD_BSS_START, "BssStart" },
- { HOSTCMD_CMD_AP_BEACON, "SetApBeacon" },
- { HOSTCMD_CMD_SET_NEW_STN, "SetNewStation" },
- { HOSTCMD_CMD_SET_APMODE, "SetApMode" },
- { HOSTCMD_CMD_UPDATE_ENCRYPTION, "UpdateEncryption" },
- { HOSTCMD_CMD_BASTREAM, "BAStream" },
- { HOSTCMD_CMD_DWDS_ENABLE, "DwdsEnable" },
- { HOSTCMD_CMD_FW_FLUSH_TIMER, "FwFlushTimer" },
- { HOSTCMD_CMD_SET_CDD, "SetCDD" },
- };
-
- WLDBG_ENTER(DBG_LEVEL_2);
-
- max_entries = sizeof(cmds) / sizeof(cmds[0]);
-
- for (curr_cmd = 0; curr_cmd < max_entries; curr_cmd++) {
- if ((cmd & 0x7fff) == cmds[curr_cmd].cmd) {
- WLDBG_EXIT(DBG_LEVEL_2);
- return cmds[curr_cmd].cmd_string;
- }
- }
-
- WLDBG_EXIT_INFO(DBG_LEVEL_2, "unknown");
-
- return "unknown";
-}
-#endif
diff --git a/mwl_fwcmd.h b/fwcmd.h
index 36b27eb..247b01f 100644
--- a/mwl_fwcmd.h
+++ b/fwcmd.h
@@ -1,28 +1,17 @@
/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
/* Description: This file defines firmware host command related functions.
-*/
+ */
#ifndef _mwl_fwcmd_h_
#define _mwl_fwcmd_h_
-/* CONSTANTS AND MACROS
-*/
-
/* Define OpMode for SoftAP/Station mode
*
* The following mode signature has to be written to PCI scratch register#0
@@ -36,9 +25,6 @@
#define HOSTCMD_STA_FWRDY_SIGNATURE 0xF0F1F2F4
#define HOSTCMD_SOFTAP_FWRDY_SIGNATURE 0xF1F2F4A5
-/* TYPE DEFINITION
-*/
-
enum {
WL_ANTENNATYPE_RX = 1,
WL_ANTENNATYPE_TX = 2,
@@ -52,9 +38,6 @@ enum encr_type {
ENCR_TYPE_MIX = 7,
};
-/* PUBLIC FUNCTION DECLARATION
-*/
-
void mwl_fwcmd_reset(struct ieee80211_hw *hw);
void mwl_fwcmd_int_enable(struct ieee80211_hw *hw);
diff --git a/mwl_fwdl.c b/fwdl.c
index 442c21c..f3826cf 100644
--- a/mwl_fwdl.c
+++ b/fwdl.c
@@ -1,46 +1,45 @@
/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
/* Description: This file implements firmware download related functions.
-*/
+ */
#include <linux/io.h>
-#include "mwl_sysadpt.h"
-#include "mwl_dev.h"
-#include "mwl_debug.h"
-#include "mwl_fwcmd.h"
-#include "mwl_fwdl.h"
-
-/* CONSTANTS AND MACROS
-*/
+#include "sysadpt.h"
+#include "dev.h"
+#include "fwcmd.h"
+#include "fwdl.h"
#define FW_DOWNLOAD_BLOCK_SIZE 256
#define FW_CHECK_MSECS 1
#define FW_MAX_NUM_CHECKS 0xffff
-/* PRIVATE FUNCTION DECLARATION
-*/
+static void mwl_fwdl_trig_pcicmd(struct mwl_priv *priv)
+{
+ writel(priv->pphys_cmd_buf, priv->iobase1 + MACREG_REG_GEN_PTR);
+
+ writel(0x00, priv->iobase1 + MACREG_REG_INT_CODE);
+
+ writel(MACREG_H2ARIC_BIT_DOOR_BELL,
+ priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
+}
+
+static void mwl_fwdl_trig_pcicmd_bootcode(struct mwl_priv *priv)
+{
+ writel(priv->pphys_cmd_buf, priv->iobase1 + MACREG_REG_GEN_PTR);
-static void mwl_fwdl_trig_pcicmd(struct mwl_priv *priv);
-static void mwl_fwdl_trig_pcicmd_bootcode(struct mwl_priv *priv);
+ writel(0x00, priv->iobase1 + MACREG_REG_INT_CODE);
-/* PUBLIC FUNCTION DEFINITION
-*/
+ writel(MACREG_H2ARIC_BIT_DOOR_BELL,
+ priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
+}
int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
{
@@ -51,20 +50,15 @@ int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
u32 int_code = 0;
u32 len = 0;
- WLDBG_ENTER(DBG_LEVEL_1);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
fw = priv->fw_ucode;
- BUG_ON(!fw);
mwl_fwcmd_reset(hw);
/* FW before jumping to boot rom, it will enable PCIe transaction retry,
* wait for boot code to stop it.
*/
- WL_MSEC_SLEEP(FW_CHECK_MSECS);
+ mdelay(FW_CHECK_MSECS);
writel(MACREG_A2HRIC_BIT_MASK,
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_CLEAR_SEL);
@@ -78,14 +72,12 @@ int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
* reside on its respective blocks such as ITCM, DTCM, SQRAM,
* (or even DDR, AFTER DDR is init'd before fw download
*/
- WLDBG_PRINT("fw download start 88");
+ wiphy_info(hw->wiphy, "fw download start 88");
- /* Disable PFU before FWDL
- */
+ /* Disable PFU before FWDL */
writel(0x100, priv->iobase1 + 0xE0E4);
- /* make sure SCRATCH2 C40 is clear, in case we are too quick
- */
+ /* make sure SCRATCH2 C40 is clear, in case we are too quick */
while (readl(priv->iobase1 + 0xc40) == 0)
;
@@ -99,8 +91,7 @@ int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
memcpy((char *)&priv->pcmd_buf[0],
(fw->data + size_fw_downloaded), len);
- /* this function writes pdata to c10, then write 2 to c18
- */
+ /* this function writes pdata to c10, then write 2 to c18 */
mwl_fwdl_trig_pcicmd_bootcode(priv);
/* this is arbitrary per your platform; we use 0xffff */
@@ -134,15 +125,17 @@ int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
* without locking up your entire system just because fw
* download failed
*/
- WLDBG_PRINT("Exhausted curr_iteration for fw download");
+ wiphy_err(hw->wiphy,
+ "Exhausted curr_iteration for fw download");
goto err_download;
}
size_fw_downloaded += len;
}
- WLDBG_PRINT("FwSize = %d downloaded Size = %d curr_iteration %d",
- (int)fw->size, size_fw_downloaded, curr_iteration);
+ wiphy_info(hw->wiphy,
+ "FwSize = %d downloaded Size = %d curr_iteration %d",
+ (int)fw->size, size_fw_downloaded, curr_iteration);
/* Now firware is downloaded successfully, so this part is to check
* whether fw can properly execute to an extent that write back
@@ -156,23 +149,22 @@ int mwl_fwdl_download_firmware(struct ieee80211_hw *hw)
do {
curr_iteration--;
writel(HOSTCMD_SOFTAP_MODE, priv->iobase1 + MACREG_REG_GEN_PTR);
- WL_MSEC_SLEEP(FW_CHECK_MSECS);
+ mdelay(FW_CHECK_MSECS);
int_code = readl(priv->iobase1 + MACREG_REG_INT_CODE);
if (!(curr_iteration % 0xff))
- WLDBG_PRINT("%x;", int_code);
+ wiphy_err(hw->wiphy, "%x;", int_code);
} while ((curr_iteration) &&
(int_code != HOSTCMD_SOFTAP_FWRDY_SIGNATURE));
if (curr_iteration == 0) {
- WLDBG_PRINT("Exhausted curr_iteration for fw signature");
+ wiphy_err(hw->wiphy,
+ "Exhausted curr_iteration for fw signature");
goto err_download;
}
- WLDBG_PRINT("complete");
+ wiphy_info(hw->wiphy, "complete");
writel(0x00, priv->iobase1 + MACREG_REG_INT_CODE);
- WLDBG_EXIT(DBG_LEVEL_1);
-
return 0;
err_download:
@@ -181,38 +173,3 @@ err_download:
return -EIO;
}
-
-/* PRIVATE FUNCTION DEFINITION
-*/
-
-static void mwl_fwdl_trig_pcicmd(struct mwl_priv *priv)
-{
- WLDBG_ENTER(DBG_LEVEL_1);
-
- BUG_ON(!priv);
-
- writel(priv->pphys_cmd_buf, priv->iobase1 + MACREG_REG_GEN_PTR);
-
- writel(0x00, priv->iobase1 + MACREG_REG_INT_CODE);
-
- writel(MACREG_H2ARIC_BIT_DOOR_BELL,
- priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
-
- WLDBG_EXIT(DBG_LEVEL_1);
-}
-
-static void mwl_fwdl_trig_pcicmd_bootcode(struct mwl_priv *priv)
-{
- WLDBG_ENTER(DBG_LEVEL_1);
-
- BUG_ON(!priv);
-
- writel(priv->pphys_cmd_buf, priv->iobase1 + MACREG_REG_GEN_PTR);
-
- writel(0x00, priv->iobase1 + MACREG_REG_INT_CODE);
-
- writel(MACREG_H2ARIC_BIT_DOOR_BELL,
- priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
-
- WLDBG_EXIT(DBG_LEVEL_1);
-}
diff --git a/fwdl.h b/fwdl.h
new file mode 100644
index 0000000..dc3c3f0
--- /dev/null
+++ b/fwdl.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Description: This file defines firmware download related functions.
+ */
+
+#ifndef _mwl_fwdl_h_
+#define _mwl_fwdl_h_
+
+#include <net/mac80211.h>
+
+int mwl_fwdl_download_firmware(struct ieee80211_hw *hw);
+
+#endif /* _mwl_fwdl_h_ */
diff --git a/isr.c b/isr.c
new file mode 100644
index 0000000..7109896
--- /dev/null
+++ b/isr.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Description: This file implements interrupt related functions.
+ */
+
+#include "sysadpt.h"
+#include "dev.h"
+#include "fwcmd.h"
+#include "isr.h"
+
+#define INVALID_WATCHDOG 0xAA
+
+irqreturn_t mwl_isr(int irq, void *dev_id)
+{
+ struct ieee80211_hw *hw = dev_id;
+ struct mwl_priv *priv;
+ void *int_status_mask;
+ unsigned int int_status, clr_status;
+ u32 status;
+
+ priv = hw->priv;
+
+ int_status_mask = priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK;
+
+ int_status = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_CAUSE);
+
+ if (int_status == 0x00000000)
+ return IRQ_NONE;
+
+ if (int_status == 0xffffffff) {
+ wiphy_warn(hw->wiphy, "card plugged out???");
+ } else {
+ clr_status = int_status;
+
+ if (int_status & MACREG_A2HRIC_BIT_TX_DONE) {
+ int_status &= ~MACREG_A2HRIC_BIT_TX_DONE;
+
+ if (!priv->is_tx_schedule) {
+ status = readl(int_status_mask);
+ writel((status & ~MACREG_A2HRIC_BIT_TX_DONE),
+ int_status_mask);
+ tasklet_schedule(&priv->tx_task);
+ priv->is_tx_schedule = true;
+ }
+ }
+
+ if (int_status & MACREG_A2HRIC_BIT_RX_RDY) {
+ int_status &= ~MACREG_A2HRIC_BIT_RX_RDY;
+
+ if (!priv->is_rx_schedule) {
+ status = readl(int_status_mask);
+ writel((status & ~MACREG_A2HRIC_BIT_RX_RDY),
+ int_status_mask);
+ tasklet_schedule(&priv->rx_task);
+ priv->is_rx_schedule = true;
+ }
+ }
+
+ if (int_status & MACREG_A2HRIC_BA_WATCHDOG) {
+ status = readl(int_status_mask);
+ writel((status & ~MACREG_A2HRIC_BA_WATCHDOG),
+ int_status_mask);
+ int_status &= ~MACREG_A2HRIC_BA_WATCHDOG;
+ ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
+ }
+
+ writel(~clr_status,
+ priv->iobase1 + MACREG_REG_A2H_INTERRUPT_CAUSE);
+ }
+
+ return IRQ_HANDLED;
+}
+
+void mwl_watchdog_ba_events(struct work_struct *work)
+{
+ int rc;
+ u8 bitmap = 0, stream_index;
+ struct mwl_ampdu_stream *streams;
+ struct mwl_priv *priv =
+ container_of(work, struct mwl_priv, watchdog_ba_handle);
+ struct ieee80211_hw *hw = priv->hw;
+ u32 status;
+
+ rc = mwl_fwcmd_get_watchdog_bitmap(priv->hw, &bitmap);
+
+ if (rc)
+ goto done;
+
+ spin_lock(&priv->stream_lock);
+
+ /* the bitmap is the hw queue number. Map it to the ampdu queue. */
+ if (bitmap != INVALID_WATCHDOG) {
+ if (bitmap == SYSADPT_TX_AMPDU_QUEUES)
+ stream_index = 0;
+ else if (bitmap > SYSADPT_TX_AMPDU_QUEUES)
+ stream_index = bitmap - SYSADPT_TX_AMPDU_QUEUES;
+ else
+ stream_index = bitmap + 3; /** queue 0 is stream 3*/
+
+ if (bitmap != 0xFF) {
+ /* Check if the stream is in use before disabling it */
+ streams = &priv->ampdu[stream_index];
+
+ if (streams->state == AMPDU_STREAM_ACTIVE) {
+ ieee80211_stop_tx_ba_session(streams->sta,
+ streams->tid);
+ spin_unlock(&priv->stream_lock);
+ mwl_fwcmd_destroy_ba(hw, stream_index);
+ spin_lock(&priv->stream_lock);
+ }
+ } else {
+ for (stream_index = 0;
+ stream_index < SYSADPT_TX_AMPDU_QUEUES;
+ stream_index++) {
+ streams = &priv->ampdu[stream_index];
+
+ if (streams->state != AMPDU_STREAM_ACTIVE)
+ continue;
+
+ ieee80211_stop_tx_ba_session(streams->sta,
+ streams->tid);
+ spin_unlock(&priv->stream_lock);
+ mwl_fwcmd_destroy_ba(hw, stream_index);
+ spin_lock(&priv->stream_lock);
+ }
+ }
+ }
+
+ spin_unlock(&priv->stream_lock);
+
+done:
+
+ status = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
+ writel(status | MACREG_A2HRIC_BA_WATCHDOG,
+ priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
+}
diff --git a/isr.h b/isr.h
new file mode 100644
index 0000000..1c8c146
--- /dev/null
+++ b/isr.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Description: This file defines interrupt related functions.
+ */
+
+#ifndef _mwl_isr_h_
+#define _mwl_isr_h_
+
+#include <linux/interrupt.h>
+
+irqreturn_t mwl_isr(int irq, void *dev_id);
+void mwl_watchdog_ba_events(struct work_struct *work);
+
+#endif /* _mwl_isr_h_ */
diff --git a/mwl_mac80211.c b/mac80211.c
index 41475d0..4000ea5 100644
--- a/mwl_mac80211.c
+++ b/mac80211.c
@@ -1,122 +1,27 @@
/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
/* Description: This file implements mac80211 related functions.
-*/
+ */
#include <linux/etherdevice.h>
-#include "mwl_sysadpt.h"
-#include "mwl_dev.h"
-#include "mwl_debug.h"
-#include "mwl_fwcmd.h"
-#include "mwl_tx.h"
-#include "mwl_mac80211.h"
-
-/* CONSTANTS AND MACROS
-*/
+#include "sysadpt.h"
+#include "dev.h"
+#include "fwcmd.h"
+#include "tx.h"
+#include "mac80211.h"
+#include "isr.h"
#define MWL_DRV_NAME KBUILD_MODNAME
#define MAX_AMPDU_ATTEMPTS 5
-/* PRIVATE FUNCTION DECLARATION
-*/
-
-static void mwl_mac80211_tx(struct ieee80211_hw *hw,
- struct ieee80211_tx_control *control,
- struct sk_buff *skb);
-static int mwl_mac80211_start(struct ieee80211_hw *hw);
-static void mwl_mac80211_stop(struct ieee80211_hw *hw);
-static int mwl_mac80211_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
-static void mwl_mac80211_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
-static int mwl_mac80211_config(struct ieee80211_hw *hw,
- u32 changed);
-static void mwl_mac80211_bss_info_changed(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u32 changed);
-static void mwl_mac80211_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags,
- u64 multicast);
-static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
- enum set_key_cmd cmd_param,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta,
- struct ieee80211_key_conf *key);
-static int mwl_mac80211_set_rts_threshold(struct ieee80211_hw *hw,
- u32 value);
-static int mwl_mac80211_sta_add(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-static int mwl_mac80211_sta_remove(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta);
-static int mwl_mac80211_conf_tx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- u16 queue,
- const struct ieee80211_tx_queue_params *params);
-static int mwl_mac80211_get_stats(struct ieee80211_hw *hw,
- struct ieee80211_low_level_stats *stats);
-static int mwl_mac80211_get_survey(struct ieee80211_hw *hw,
- int idx,
- struct survey_info *survey);
-static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta,
- u16 tid, u16 *ssn, u8 buf_size);
-static void mwl_mac80211_remove_vif(struct mwl_priv *priv,
- struct mwl_vif *vif);
-static void mwl_mac80211_bss_info_changed_sta(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u32 changed);
-static void mwl_mac80211_bss_info_changed_ap(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u32 changed);
-
-/* PRIVATE VARIABLES
-*/
-
-static struct ieee80211_ops mwl_mac80211_ops = {
- .tx = mwl_mac80211_tx,
- .start = mwl_mac80211_start,
- .stop = mwl_mac80211_stop,
- .add_interface = mwl_mac80211_add_interface,
- .remove_interface = mwl_mac80211_remove_interface,
- .config = mwl_mac80211_config,
- .bss_info_changed = mwl_mac80211_bss_info_changed,
- .configure_filter = mwl_mac80211_configure_filter,
- .set_key = mwl_mac80211_set_key,
- .set_rts_threshold = mwl_mac80211_set_rts_threshold,
- .sta_add = mwl_mac80211_sta_add,
- .sta_remove = mwl_mac80211_sta_remove,
- .conf_tx = mwl_mac80211_conf_tx,
- .get_stats = mwl_mac80211_get_stats,
- .get_survey = mwl_mac80211_get_survey,
- .ampdu_action = mwl_mac80211_ampdu_action,
-};
-
-static irqreturn_t (*mwl_mac80211_isr)(int irq, void *dev_id);
-
static const struct ieee80211_rate mwl_rates_24[] = {
{ .bitrate = 10, .hw_value = 2, },
{ .bitrate = 20, .hw_value = 4, },
@@ -144,53 +49,22 @@ static const struct ieee80211_rate mwl_rates_50[] = {
{ .bitrate = 540, .hw_value = 108, },
};
-/* PUBLIC FUNCTION DEFINITION
-*/
-
-struct ieee80211_ops *mwl_mac80211_get_ops(void)
-{
- return &mwl_mac80211_ops;
-}
-
-void mwl_mac80211_set_isr(irqreturn_t (*isr)(int irq, void *dev_id))
-{
- WLDBG_ENTER(DBG_LEVEL_5);
-
- mwl_mac80211_isr = isr;
-
- WLDBG_EXIT(DBG_LEVEL_5);
-}
-
-/* PRIVATE FUNCTION DEFINITION
-*/
-
static void mwl_mac80211_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
- struct sk_buff *skb)
+ struct sk_buff *skb)
{
struct mwl_priv *priv;
- int index;
-
- WLDBG_ENTER(DBG_LEVEL_5);
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!skb);
if (!priv->radio_on) {
- WLDBG_EXIT_INFO(DBG_LEVEL_5,
- "dropped TX frame since radio disabled");
+ wiphy_warn(hw->wiphy,
+ "dropped TX frame since radio disabled");
dev_kfree_skb_any(skb);
return;
}
- index = skb_get_queue_mapping(skb);
-
- mwl_tx_xmit(hw, index, control->sta, skb);
-
- WLDBG_EXIT(DBG_LEVEL_5);
+ mwl_tx_xmit(hw, control, skb);
}
static int mwl_mac80211_start(struct ieee80211_hw *hw)
@@ -198,55 +72,49 @@ static int mwl_mac80211_start(struct ieee80211_hw *hw)
struct mwl_priv *priv;
int rc;
- WLDBG_ENTER(DBG_LEVEL_5);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
- rc = request_irq(priv->pdev->irq, mwl_mac80211_isr,
+ rc = request_irq(priv->pdev->irq, mwl_isr,
IRQF_SHARED, MWL_DRV_NAME, hw);
if (rc) {
priv->irq = -1;
- WLDBG_ERROR(DBG_LEVEL_5, "fail to register IRQ handler");
+ wiphy_err(hw->wiphy, "fail to register IRQ handler");
return rc;
}
priv->irq = priv->pdev->irq;
- /* Enable TX reclaim and RX tasklets.
- */
+ /* Enable TX reclaim and RX tasklets. */
tasklet_enable(&priv->tx_task);
tasklet_enable(&priv->rx_task);
- /* Enable interrupts
- */
+ /* Enable interrupts */
mwl_fwcmd_int_enable(hw);
rc = mwl_fwcmd_radio_enable(hw);
+ if (rc)
+ goto fwcmd_fail;
+ rc = mwl_fwcmd_set_rate_adapt_mode(hw, 0);
+ if (rc)
+ goto fwcmd_fail;
+ rc = mwl_fwcmd_set_wmm_mode(hw, true);
+ if (rc)
+ goto fwcmd_fail;
+ rc = mwl_fwcmd_set_dwds_stamode(hw, true);
+ if (rc)
+ goto fwcmd_fail;
+ rc = mwl_fwcmd_set_fw_flush_timer(hw, 0);
+ if (rc)
+ goto fwcmd_fail;
- if (!rc)
- rc = mwl_fwcmd_set_rate_adapt_mode(hw, 0);
-
- if (!rc)
- rc = mwl_fwcmd_set_wmm_mode(hw, true);
-
- if (!rc)
- rc = mwl_fwcmd_set_dwds_stamode(hw, true);
-
- if (!rc)
- rc = mwl_fwcmd_set_fw_flush_timer(hw, 0);
-
- if (rc) {
- mwl_fwcmd_int_disable(hw);
- free_irq(priv->pdev->irq, hw);
- priv->irq = -1;
- tasklet_disable(&priv->tx_task);
- tasklet_disable(&priv->rx_task);
- } else {
- ieee80211_wake_queues(hw);
- }
+ ieee80211_wake_queues(hw);
+ return 0;
- WLDBG_EXIT(DBG_LEVEL_5);
+fwcmd_fail:
+ mwl_fwcmd_int_disable(hw);
+ free_irq(priv->pdev->irq, hw);
+ priv->irq = -1;
+ tasklet_disable(&priv->tx_task);
+ tasklet_disable(&priv->rx_task);
return rc;
}
@@ -255,18 +123,13 @@ static void mwl_mac80211_stop(struct ieee80211_hw *hw)
{
struct mwl_priv *priv;
- WLDBG_ENTER(DBG_LEVEL_5);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
mwl_fwcmd_radio_disable(hw);
ieee80211_stop_queues(hw);
- /* Disable interrupts
- */
+ /* Disable interrupts */
mwl_fwcmd_int_disable(hw);
if (priv->irq != -1) {
@@ -276,16 +139,12 @@ static void mwl_mac80211_stop(struct ieee80211_hw *hw)
cancel_work_sync(&priv->watchdog_ba_handle);
- /* Disable TX reclaim and RX tasklets.
- */
+ /* Disable TX reclaim and RX tasklets. */
tasklet_disable(&priv->tx_task);
tasklet_disable(&priv->rx_task);
- /* Return all skbs to mac80211
- */
+ /* Return all skbs to mac80211 */
mwl_tx_done((unsigned long)hw);
-
- WLDBG_EXIT(DBG_LEVEL_5);
}
static int mwl_mac80211_add_interface(struct ieee80211_hw *hw,
@@ -295,8 +154,7 @@ static int mwl_mac80211_add_interface(struct ieee80211_hw *hw,
struct mwl_vif *mwl_vif;
u32 macids_supported;
int macid;
-
- WLDBG_ENTER(DBG_LEVEL_5);
+ unsigned long flags;
switch (vif->type) {
case NL80211_IFTYPE_AP:
@@ -312,13 +170,12 @@ static int mwl_mac80211_add_interface(struct ieee80211_hw *hw,
macid = ffs(macids_supported & ~priv->macids_used);
if (!macid--) {
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "no macid can be allocated");
+ wiphy_warn(hw->wiphy, "no macid can be allocated");
return -EBUSY;
}
- /* Setup driver private area.
- */
- mwl_vif = MWL_VIF(vif);
+ /* Setup driver private area. */
+ mwl_vif = mwl_dev_get_vif(vif);
memset(mwl_vif, 0, sizeof(*mwl_vif));
mwl_vif->vif = vif;
mwl_vif->macid = macid;
@@ -344,20 +201,50 @@ static int mwl_mac80211_add_interface(struct ieee80211_hw *hw,
}
priv->macids_used |= 1 << mwl_vif->macid;
+ spin_lock_irqsave(&priv->vif_lock, flags);
list_add_tail(&mwl_vif->list, &priv->vif_list);
-
- WLDBG_EXIT(DBG_LEVEL_5);
+ spin_unlock_irqrestore(&priv->vif_lock, flags);
return 0;
}
+static void mwl_mac80211_remove_vif(struct mwl_priv *priv, struct mwl_vif *vif)
+{
+ unsigned long flags;
+ int num;
+ struct sk_buff *skb, *tmp;
+ struct ieee80211_tx_info *tx_info;
+ struct mwl_tx_ctrl *tx_ctrl;
+
+ if (!priv->macids_used)
+ return;
+
+ for (num = 1; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
+ spin_lock_irqsave(&priv->txq[num].lock, flags);
+ skb_queue_walk_safe(&priv->txq[num], skb, tmp) {
+ tx_info = IEEE80211_SKB_CB(skb);
+ tx_ctrl = (struct mwl_tx_ctrl *)&tx_info->status;
+ if (tx_ctrl->vif == vif) {
+ __skb_unlink(skb, &priv->txq[num]);
+ dev_kfree_skb_any(skb);
+ }
+ }
+ spin_unlock_irqrestore(&priv->txq[num].lock, flags);
+ }
+
+ priv->macids_used &= ~(1 << vif->macid);
+ spin_lock_irqsave(&priv->vif_lock, flags);
+ list_del(&vif->list);
+ spin_unlock_irqrestore(&priv->vif_lock, flags);
+}
+
static void mwl_mac80211_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct mwl_priv *priv = hw->priv;
- struct mwl_vif *mwl_vif = MWL_VIF(vif);
+ struct mwl_vif *mwl_vif;
- WLDBG_ENTER(DBG_LEVEL_5);
+ mwl_vif = mwl_dev_get_vif(vif);
if (vif->type == NL80211_IFTYPE_STATION)
mwl_fwcmd_remove_mac_addr(hw, vif, vif->addr);
@@ -366,8 +253,6 @@ static void mwl_mac80211_remove_interface(struct ieee80211_hw *hw,
mwl_fwcmd_set_new_stn_del(hw, vif, vif->addr);
mwl_mac80211_remove_vif(priv, mwl_vif);
-
- WLDBG_EXIT(DBG_LEVEL_5);
}
static int mwl_mac80211_config(struct ieee80211_hw *hw,
@@ -376,9 +261,7 @@ static int mwl_mac80211_config(struct ieee80211_hw *hw,
struct ieee80211_conf *conf = &hw->conf;
int rc;
- WLDBG_ENTER(DBG_LEVEL_5);
-
- WLDBG_INFO(DBG_LEVEL_5, "change: 0x%x", changed);
+ wiphy_debug(hw->wiphy, "change: 0x%x", changed);
if (conf->flags & IEEE80211_CONF_IDLE)
rc = mwl_fwcmd_radio_disable(hw);
@@ -400,52 +283,103 @@ static int mwl_mac80211_config(struct ieee80211_hw *hw,
}
rc = mwl_fwcmd_set_rf_channel(hw, conf);
-
if (rc)
goto out;
-
rc = mwl_fwcmd_use_fixed_rate(hw, rate, rate);
-
if (rc)
goto out;
-
rc = mwl_fwcmd_max_tx_power(hw, conf, 0);
-
if (rc)
goto out;
-
rc = mwl_fwcmd_tx_power(hw, conf, 0);
-
if (rc)
goto out;
-
rc = mwl_fwcmd_set_cdd(hw);
}
out:
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "return code: %d", rc);
-
return rc;
}
+static void mwl_mac80211_bss_info_changed_sta(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ if (changed & BSS_CHANGED_ERP_PREAMBLE)
+ mwl_fwcmd_set_radio_preamble(hw,
+ vif->bss_conf.use_short_preamble);
+
+ if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc)
+ mwl_fwcmd_set_aid(hw, vif, (u8 *)vif->bss_conf.bssid,
+ vif->bss_conf.aid);
+}
+
+static void mwl_mac80211_bss_info_changed_ap(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ if (changed & BSS_CHANGED_ERP_PREAMBLE)
+ mwl_fwcmd_set_radio_preamble(hw,
+ vif->bss_conf.use_short_preamble);
+
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ int idx;
+ int rate;
+
+ /* Use lowest supported basic rate for multicasts
+ * and management frames (such as probe responses --
+ * beacons will always go out at 1 Mb/s).
+ */
+ idx = ffs(vif->bss_conf.basic_rates);
+ if (idx)
+ idx--;
+
+ if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
+ rate = mwl_rates_24[idx].hw_value;
+ else
+ rate = mwl_rates_50[idx].hw_value;
+
+ mwl_fwcmd_use_fixed_rate(hw, rate, rate);
+ }
+
+ if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
+ struct sk_buff *skb;
+
+ skb = ieee80211_beacon_get(hw, vif);
+
+ if (skb) {
+ mwl_fwcmd_set_beacon(hw, vif, skb->data, skb->len);
+ dev_kfree_skb_any(skb);
+ }
+
+ if ((info->ssid[0] != '\0') &&
+ (info->ssid_len != 0) &&
+ (!info->hidden_ssid))
+ mwl_fwcmd_broadcast_ssid_enable(hw, vif, true);
+ else
+ mwl_fwcmd_broadcast_ssid_enable(hw, vif, false);
+ }
+
+ if (changed & BSS_CHANGED_BEACON_ENABLED)
+ mwl_fwcmd_bss_start(hw, vif, info->enable_beacon);
+}
+
static void mwl_mac80211_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
u32 changed)
{
- WLDBG_ENTER(DBG_LEVEL_5);
-
- WLDBG_INFO(DBG_LEVEL_5, "interface: %d, change: 0x%x",
- vif->type, changed);
+ wiphy_debug(hw->wiphy, "interface: %d, change: 0x%x",
+ vif->type, changed);
if (vif->type == NL80211_IFTYPE_STATION)
mwl_mac80211_bss_info_changed_sta(hw, vif, info, changed);
if (vif->type == NL80211_IFTYPE_AP)
mwl_mac80211_bss_info_changed_ap(hw, vif, info, changed);
-
- WLDBG_EXIT(DBG_LEVEL_5);
}
static void mwl_mac80211_configure_filter(struct ieee80211_hw *hw,
@@ -453,14 +387,10 @@ static void mwl_mac80211_configure_filter(struct ieee80211_hw *hw,
unsigned int *total_flags,
u64 multicast)
{
- WLDBG_ENTER(DBG_LEVEL_5);
-
/* AP firmware doesn't allow fine-grained control over
* the receive filter.
*/
*total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
-
- WLDBG_EXIT(DBG_LEVEL_5);
}
static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
@@ -469,16 +399,12 @@ static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
+ struct mwl_vif *mwl_vif;
int rc = 0;
u8 encr_type;
u8 *addr;
- struct mwl_vif *mwl_vif = MWL_VIF(vif);
- struct mwl_sta *sta_info = MWL_STA(sta);
-
- WLDBG_ENTER(DBG_LEVEL_5);
- BUG_ON(!mwl_vif);
- BUG_ON(!sta_info);
+ mwl_vif = mwl_dev_get_vif(vif);
if (!sta) {
addr = vif->addr;
@@ -511,59 +437,57 @@ static int mwl_mac80211_set_key(struct ieee80211_hw *hw,
rc = mwl_fwcmd_update_encryption_enable(hw, vif, addr,
encr_type);
-
if (rc)
goto out;
mwl_vif->is_hw_crypto_enabled = true;
} else {
rc = mwl_fwcmd_encryption_remove_key(hw, vif, addr, key);
-
if (rc)
goto out;
}
out:
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "return code: %d", rc);
-
return rc;
}
static int mwl_mac80211_set_rts_threshold(struct ieee80211_hw *hw,
u32 value)
{
- int rc;
-
- WLDBG_ENTER(DBG_LEVEL_5);
-
- rc = mwl_fwcmd_set_rts_threshold(hw, value);
-
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "return code: %d", rc);
-
- return rc;
+ return mwl_fwcmd_set_rts_threshold(hw, value);
}
static int mwl_mac80211_sta_add(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
- struct mwl_vif *mwl_vif = MWL_VIF(vif);
- struct mwl_sta *sta_info = MWL_STA(sta);
+ struct mwl_priv *priv = hw->priv;
+ struct mwl_vif *mwl_vif;
+ struct mwl_sta *sta_info;
+ unsigned long flags;
struct ieee80211_key_conf *key;
int rc;
int i;
- WLDBG_ENTER(DBG_LEVEL_5);
-
- BUG_ON(!mwl_vif);
- BUG_ON(!sta_info);
+ mwl_vif = mwl_dev_get_vif(vif);
+ sta_info = mwl_dev_get_sta(sta);
memset(sta_info, 0, sizeof(*sta_info));
+ sta_info->sta = sta;
+ if (sta->ht_cap.ht_supported) {
+ sta_info->is_ampdu_allowed = true;
+ sta_info->is_amsdu_allowed = true;
+ if (sta->ht_cap.cap & IEEE80211_HT_CAP_MAX_AMSDU)
+ sta_info->amsdu_ctrl.cap = MWL_AMSDU_SIZE_8K;
+ else
+ sta_info->amsdu_ctrl.cap = MWL_AMSDU_SIZE_4K;
+ }
sta_info->iv16 = 1;
sta_info->iv32 = 0;
- if (sta->ht_cap.ht_supported)
- sta_info->is_ampdu_allowed = true;
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ list_add_tail(&sta_info->list, &priv->sta_list);
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
if (mwl_vif->is_sta)
mwl_fwcmd_set_new_stn_del(hw, vif, sta->addr);
@@ -571,14 +495,12 @@ static int mwl_mac80211_sta_add(struct ieee80211_hw *hw,
rc = mwl_fwcmd_set_new_stn_add(hw, vif, sta);
for (i = 0; i < NUM_WEP_KEYS; i++) {
- key = IEEE80211_KEY_CONF(mwl_vif->wep_key_conf[i].key);
+ key = (struct ieee80211_key_conf *)mwl_vif->wep_key_conf[i].key;
if (mwl_vif->wep_key_conf[i].enabled)
mwl_mac80211_set_key(hw, SET_KEY, vif, sta, key);
}
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "return code: %d", rc);
-
return rc;
}
@@ -586,13 +508,35 @@ static int mwl_mac80211_sta_remove(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
+ struct mwl_priv *priv = hw->priv;
+ struct mwl_sta *sta_info;
+ unsigned long flags;
+ int num;
+ struct sk_buff *skb, *tmp;
+ struct ieee80211_tx_info *tx_info;
+ struct mwl_tx_ctrl *tx_ctrl;
int rc;
- WLDBG_ENTER(DBG_LEVEL_5);
+ sta_info = mwl_dev_get_sta(sta);
+
+ for (num = 1; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
+ spin_lock_irqsave(&priv->txq[num].lock, flags);
+ skb_queue_walk_safe(&priv->txq[num], skb, tmp) {
+ tx_info = IEEE80211_SKB_CB(skb);
+ tx_ctrl = (struct mwl_tx_ctrl *)&tx_info->status;
+ if (tx_ctrl->sta == sta) {
+ __skb_unlink(skb, &priv->txq[num]);
+ dev_kfree_skb_any(skb);
+ }
+ }
+ spin_unlock_irqrestore(&priv->txq[num].lock, flags);
+ }
rc = mwl_fwcmd_set_new_stn_del(hw, vif, sta->addr);
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "return code: %d", rc);
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ list_del(&sta_info->list);
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
return rc;
}
@@ -605,8 +549,6 @@ static int mwl_mac80211_conf_tx(struct ieee80211_hw *hw,
struct mwl_priv *priv = hw->priv;
int rc = 0;
- WLDBG_ENTER(DBG_LEVEL_5);
-
BUG_ON(queue > SYSADPT_TX_WMM_QUEUES - 1);
memcpy(&priv->wmm_params[queue], params, sizeof(*params));
@@ -621,26 +563,16 @@ static int mwl_mac80211_conf_tx(struct ieee80211_hw *hw,
rc = mwl_fwcmd_set_edca_params(hw, q,
params->cw_min, params->cw_max,
- params->aifs, params->txop);
+ params->aifs, params->txop);
}
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "return code: %d", rc);
-
return rc;
}
static int mwl_mac80211_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
- int rc;
-
- WLDBG_ENTER(DBG_LEVEL_5);
-
- rc = mwl_fwcmd_get_stat(hw, stats);
-
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "return code: %d", rc);
-
- return rc;
+ return mwl_fwcmd_get_stat(hw, stats);
}
static int mwl_mac80211_get_survey(struct ieee80211_hw *hw,
@@ -650,8 +582,6 @@ static int mwl_mac80211_get_survey(struct ieee80211_hw *hw,
struct mwl_priv *priv = hw->priv;
struct ieee80211_conf *conf = &hw->conf;
- WLDBG_ENTER(DBG_LEVEL_5);
-
if (idx != 0)
return -ENOENT;
@@ -659,8 +589,6 @@ static int mwl_mac80211_get_survey(struct ieee80211_hw *hw,
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = priv->noise;
- WLDBG_EXIT(DBG_LEVEL_5);
-
return 0;
}
@@ -674,16 +602,11 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
struct mwl_priv *priv = hw->priv;
struct mwl_ampdu_stream *stream;
u8 *addr = sta->addr, idx;
- struct mwl_sta *sta_info = MWL_STA(sta);
+ struct mwl_sta *sta_info;
- WLDBG_ENTER(DBG_LEVEL_5);
+ sta_info = mwl_dev_get_sta(sta);
- if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) {
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "no HW AMPDU");
- return -ENOTSUPP;
- }
-
- SPIN_LOCK(&priv->locks.stream_lock);
+ spin_lock(&priv->stream_lock);
stream = mwl_fwcmd_lookup_stream(hw, addr, tid);
@@ -713,26 +636,24 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
}
if (!stream) {
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "no stream found");
+ wiphy_warn(hw->wiphy, "no stream found");
rc = -EBUSY;
break;
}
stream->state = AMPDU_STREAM_IN_PROGRESS;
- /* Release the lock before we do the time consuming stuff
- */
- SPIN_UNLOCK(&priv->locks.stream_lock);
+ /* Release the lock before we do the time consuming stuff */
+ spin_unlock(&priv->stream_lock);
for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
- /* Check if link is still valid
- */
+ /* Check if link is still valid */
if (!sta_info->is_ampdu_allowed) {
- SPIN_LOCK(&priv->locks.stream_lock);
+ spin_lock(&priv->stream_lock);
mwl_fwcmd_remove_stream(hw, stream);
- SPIN_UNLOCK(&priv->locks.stream_lock);
- WLDBG_EXIT_INFO(DBG_LEVEL_5,
- "link is no valid now");
+ spin_unlock(&priv->stream_lock);
+ wiphy_warn(hw->wiphy,
+ "link is no valid now");
return -EBUSY;
}
@@ -741,14 +662,14 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
if (!rc)
break;
- WL_MSEC_SLEEP(1000);
+ mdelay(1000);
}
- SPIN_LOCK(&priv->locks.stream_lock);
+ spin_lock(&priv->stream_lock);
if (rc) {
mwl_fwcmd_remove_stream(hw, stream);
- WLDBG_EXIT_INFO(DBG_LEVEL_5, "error code: %d", rc);
+ wiphy_err(hw->wiphy, "error code: %d", rc);
rc = -EBUSY;
break;
}
@@ -761,9 +682,9 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
if (stream) {
if (stream->state == AMPDU_STREAM_ACTIVE) {
idx = stream->idx;
- SPIN_UNLOCK(&priv->locks.stream_lock);
+ spin_unlock(&priv->stream_lock);
mwl_fwcmd_destroy_ba(hw, idx);
- SPIN_LOCK(&priv->locks.stream_lock);
+ spin_lock(&priv->stream_lock);
}
mwl_fwcmd_remove_stream(hw, stream);
@@ -772,19 +693,18 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
- BUG_ON(!stream);
BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS);
- SPIN_UNLOCK(&priv->locks.stream_lock);
+ spin_unlock(&priv->stream_lock);
rc = mwl_fwcmd_create_ba(hw, stream, buf_size, vif);
- SPIN_LOCK(&priv->locks.stream_lock);
+ spin_lock(&priv->stream_lock);
if (!rc) {
stream->state = AMPDU_STREAM_ACTIVE;
} else {
idx = stream->idx;
- SPIN_UNLOCK(&priv->locks.stream_lock);
+ spin_unlock(&priv->stream_lock);
mwl_fwcmd_destroy_ba(hw, idx);
- SPIN_LOCK(&priv->locks.stream_lock);
+ spin_lock(&priv->stream_lock);
mwl_fwcmd_remove_stream(hw, stream);
}
break;
@@ -792,86 +712,26 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
rc = -ENOTSUPP;
}
- SPIN_UNLOCK(&priv->locks.stream_lock);
-
- WLDBG_EXIT(DBG_LEVEL_5);
+ spin_unlock(&priv->stream_lock);
return rc;
}
-static void mwl_mac80211_remove_vif(struct mwl_priv *priv, struct mwl_vif *vif)
-{
- if (!priv->macids_used)
- return;
-
- priv->macids_used &= ~(1 << vif->macid);
- list_del(&vif->list);
-}
-
-static void mwl_mac80211_bss_info_changed_sta(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u32 changed)
-{
- if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- mwl_fwcmd_set_radio_preamble(hw,
- vif->bss_conf.use_short_preamble);
- }
-
- if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) {
- mwl_fwcmd_set_aid(hw, vif, (u8 *)vif->bss_conf.bssid,
- vif->bss_conf.aid);
- }
-}
-
-static void mwl_mac80211_bss_info_changed_ap(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *info,
- u32 changed)
-{
- if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- mwl_fwcmd_set_radio_preamble(hw,
- vif->bss_conf.use_short_preamble);
- }
-
- if (changed & BSS_CHANGED_BASIC_RATES) {
- int idx;
- int rate;
-
- /* Use lowest supported basic rate for multicasts
- * and management frames (such as probe responses --
- * beacons will always go out at 1 Mb/s).
- */
- idx = ffs(vif->bss_conf.basic_rates);
- if (idx)
- idx--;
-
- if (hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
- rate = mwl_rates_24[idx].hw_value;
- else
- rate = mwl_rates_50[idx].hw_value;
-
- mwl_fwcmd_use_fixed_rate(hw, rate, rate);
- }
-
- if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
- struct sk_buff *skb;
-
- skb = ieee80211_beacon_get(hw, vif);
-
- if (skb) {
- mwl_fwcmd_set_beacon(hw, vif, skb->data, skb->len);
- dev_kfree_skb_any(skb);
- }
-
- if ((info->ssid[0] != '\0') &&
- (info->ssid_len != 0) &&
- (!info->hidden_ssid))
- mwl_fwcmd_broadcast_ssid_enable(hw, vif, true);
- else
- mwl_fwcmd_broadcast_ssid_enable(hw, vif, false);
- }
-
- if (changed & BSS_CHANGED_BEACON_ENABLED)
- mwl_fwcmd_bss_start(hw, vif, info->enable_beacon);
-}
+const struct ieee80211_ops mwl_mac80211_ops = {
+ .tx = mwl_mac80211_tx,
+ .start = mwl_mac80211_start,
+ .stop = mwl_mac80211_stop,
+ .add_interface = mwl_mac80211_add_interface,
+ .remove_interface = mwl_mac80211_remove_interface,
+ .config = mwl_mac80211_config,
+ .bss_info_changed = mwl_mac80211_bss_info_changed,
+ .configure_filter = mwl_mac80211_configure_filter,
+ .set_key = mwl_mac80211_set_key,
+ .set_rts_threshold = mwl_mac80211_set_rts_threshold,
+ .sta_add = mwl_mac80211_sta_add,
+ .sta_remove = mwl_mac80211_sta_remove,
+ .conf_tx = mwl_mac80211_conf_tx,
+ .get_stats = mwl_mac80211_get_stats,
+ .get_survey = mwl_mac80211_get_survey,
+ .ampdu_action = mwl_mac80211_ampdu_action,
+};
diff --git a/mac80211.h b/mac80211.h
new file mode 100644
index 0000000..b70598a
--- /dev/null
+++ b/mac80211.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Description: This file defines mac80211 related functions.
+ */
+
+#ifndef _mwl_mac80211_h_
+#define _mwl_mac80211_h_
+
+#include <net/mac80211.h>
+
+extern const struct ieee80211_ops mwl_mac80211_ops;
+
+#endif /* _mwl_mac80211_h_ */
diff --git a/mwl_main.c b/main.c
index fd67660..24a3686 100644
--- a/mwl_main.c
+++ b/main.c
@@ -1,84 +1,40 @@
/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
/* Description: This file implements main functions of this module.
-*/
+ */
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include "mwl_sysadpt.h"
-#include "mwl_dev.h"
-#include "mwl_debug.h"
-#include "mwl_fwdl.h"
-#include "mwl_fwcmd.h"
-#include "mwl_tx.h"
-#include "mwl_rx.h"
-#include "mwl_mac80211.h"
-
-/* CONSTANTS AND MACROS
-*/
+#include "sysadpt.h"
+#include "dev.h"
+#include "fwdl.h"
+#include "fwcmd.h"
+#include "tx.h"
+#include "rx.h"
+#include "mac80211.h"
+#include "isr.h"
#define MWL_DESC "Marvell 802.11ac Wireless Network Driver"
-#define MWL_DEV_NAME "Marvell 88W8864 802.11ac Adapter"
+#define MWL_DEV_NAME "Marvell 802.11ac Adapter"
#define MWL_DRV_NAME KBUILD_MODNAME
-#define MWL_DRV_VERSION "10.3.0.2--"
+#define MWL_DRV_VERSION "10.3.0.3"
#define FILE_PATH_LEN 64
#define CMD_BUF_SIZE 0x4000
-#define INVALID_WATCHDOG 0xAA
-
-/* PRIVATE FUNCTION DECLARATION
-*/
-
-static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id);
-static void mwl_remove(struct pci_dev *pdev);
-static int mwl_alloc_pci_resource(struct mwl_priv *priv);
-static void mwl_free_pci_resource(struct mwl_priv *priv);
-static int mwl_init_firmware(struct mwl_priv *priv, char *fw_image);
-static void mwl_reg_notifier(struct wiphy *wiphy,
- struct regulatory_request *request);
-static int mwl_process_of_dts(struct mwl_priv *priv);
-static void mwl_set_ht_caps(struct mwl_priv *priv,
- struct ieee80211_supported_band *band);
-static void mwl_set_vht_caps(struct mwl_priv *priv,
- struct ieee80211_supported_band *band);
-static void mwl_set_caps(struct mwl_priv *priv);
-static int mwl_wl_init(struct mwl_priv *priv);
-static void mwl_wl_deinit(struct mwl_priv *priv);
-static void mwl_watchdog_ba_events(struct work_struct *work);
-static irqreturn_t mwl_interrupt(int irq, void *dev_id);
-
-/* PRIVATE VARIABLES
-*/
-
static struct pci_device_id mwl_pci_id_tbl[] = {
{ PCI_VDEVICE(MARVELL, 0x2a55), .driver_data = MWL8864, },
{ PCI_VDEVICE(MARVELL, 0x2b38), .driver_data = MWL8897, },
{ },
};
-static struct pci_driver mwl_pci_driver = {
- .name = MWL_DRV_NAME,
- .id_table = mwl_pci_id_tbl,
- .probe = mwl_probe,
- .remove = mwl_remove
-};
-
static struct mwl_chip_info mwl_chip_tbl[] = {
[MWL8864] = {
.part_name = "88W8864",
@@ -173,144 +129,6 @@ static const struct ieee80211_iface_combination ap_if_comb = {
.num_different_channels = 1,
};
-/* PRIVATE FUNCTION DEFINITION
-*/
-
-static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- static bool printed_version;
- struct ieee80211_hw *hw;
- struct mwl_priv *priv;
- int rc = 0;
-
- WLDBG_ENTER(DBG_LEVEL_0);
-
- if (id->driver_data >= MWLUNKNOWN)
- return -ENODEV;
-
- if (!printed_version) {
- WLDBG_PRINT("<<%s version %s>>", MWL_DESC, MWL_DRV_VERSION);
- printed_version = true;
- }
-
- rc = pci_enable_device(pdev);
- if (rc) {
- WLDBG_PRINT("%s: cannot enable new PCI device",
- MWL_DRV_NAME);
- WLDBG_EXIT_INFO(DBG_LEVEL_0, "init error");
- return rc;
- }
-
- rc = pci_set_dma_mask(pdev, 0xffffffff);
- if (rc) {
- WLDBG_PRINT("%s: 32-bit PCI DMA not supported",
- MWL_DRV_NAME);
- goto err_pci_disable_device;
- }
-
- pci_set_master(pdev);
-
- hw = ieee80211_alloc_hw(sizeof(*priv), mwl_mac80211_get_ops());
- if (!hw) {
- WLDBG_PRINT("%s: ieee80211 alloc failed",
- MWL_DRV_NAME);
- rc = -ENOMEM;
- goto err_pci_disable_device;
- }
-
- /* hook regulatory domain change notification
- */
- hw->wiphy->reg_notifier = mwl_reg_notifier;
-
- /* set interrupt service routine to mac80211 module
- */
- mwl_mac80211_set_isr(mwl_interrupt);
-
- SET_IEEE80211_DEV(hw, &pdev->dev);
- pci_set_drvdata(pdev, hw);
-
- priv = hw->priv;
- priv->hw = hw;
- priv->pdev = pdev;
- priv->chip_type = id->driver_data;
-
- rc = mwl_alloc_pci_resource(priv);
- if (rc)
- goto err_alloc_pci_resource;
-
- rc = mwl_init_firmware(priv, mwl_chip_tbl[priv->chip_type].fw_image);
- if (rc) {
- WLDBG_PRINT("%s: fail to initialize firmware",
- MWL_DRV_NAME);
- goto err_init_firmware;
- }
-
- /* firmware is loaded to H/W, it can be released now
- */
- release_firmware(priv->fw_ucode);
-
- rc = mwl_process_of_dts(priv);
- if (rc) {
- WLDBG_PRINT("%s: fail to load dts mwlwifi parameters",
- MWL_DRV_NAME);
- goto err_process_of_dts;
- }
-
- rc = mwl_wl_init(priv);
- if (rc) {
- WLDBG_PRINT("%s: fail to initialize wireless lan",
- MWL_DRV_NAME);
- goto err_wl_init;
- }
-
- WLDBG_EXIT(DBG_LEVEL_0);
-
- return rc;
-
-err_wl_init:
-err_process_of_dts:
-err_init_firmware:
-
- mwl_fwcmd_reset(hw);
-
-err_alloc_pci_resource:
-
- pci_set_drvdata(pdev, NULL);
- ieee80211_free_hw(hw);
-
-err_pci_disable_device:
-
- pci_disable_device(pdev);
-
- WLDBG_EXIT_INFO(DBG_LEVEL_0, "init error");
-
- return rc;
-}
-
-static void mwl_remove(struct pci_dev *pdev)
-{
- struct ieee80211_hw *hw = pci_get_drvdata(pdev);
- struct mwl_priv *priv;
-
- WLDBG_ENTER(DBG_LEVEL_0);
-
- if (!hw) {
- WLDBG_EXIT_INFO(DBG_LEVEL_0, "ieee80211 hw is null");
- return;
- }
-
- priv = hw->priv;
- BUG_ON(!priv);
-
- mwl_wl_deinit(priv);
- mwl_free_pci_resource(priv);
- pci_set_drvdata(pdev, NULL);
- ieee80211_free_hw(hw);
- pci_disable_device(pdev);
-
- WLDBG_EXIT(DBG_LEVEL_0);
-}
-
static int mwl_alloc_pci_resource(struct mwl_priv *priv)
{
struct pci_dev *pdev;
@@ -319,11 +137,7 @@ static int mwl_alloc_pci_resource(struct mwl_priv *priv)
void *phys_addr1[2];
void *phys_addr2[2];
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!priv);
pdev = priv->pdev;
- BUG_ON(!pdev);
phys_addr = pci_resource_start(pdev, 0);
flags = pci_resource_flags(pdev, 0);
@@ -335,9 +149,9 @@ static int mwl_alloc_pci_resource(struct mwl_priv *priv)
if (!request_mem_region(phys_addr, pci_resource_len(pdev, 0),
MWL_DRV_NAME)) {
- WLDBG_ERROR(DBG_LEVEL_0,
- "%s: cannot reserve PCI memory region 0",
- MWL_DRV_NAME);
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot reserve PCI memory region 0",
+ MWL_DRV_NAME);
goto err_reserve_mem_region_bar0;
}
@@ -346,21 +160,23 @@ static int mwl_alloc_pci_resource(struct mwl_priv *priv)
priv->iobase0 = phys_addr1[0];
if (!priv->iobase0) {
- WLDBG_ERROR(DBG_LEVEL_0, "%s: cannot remap PCI memory region 0",
- MWL_DRV_NAME);
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot remap PCI memory region 0",
+ MWL_DRV_NAME);
goto err_release_mem_region_bar0;
}
- WLDBG_PRINT("priv->iobase0 = %x", (unsigned int)priv->iobase0);
+ wiphy_info(priv->hw->wiphy, "priv->iobase0 = %x",
+ (unsigned int)priv->iobase0);
phys_addr = pci_resource_start(pdev, priv->next_bar_num);
if (!request_mem_region(phys_addr,
pci_resource_len(pdev, priv->next_bar_num),
MWL_DRV_NAME)) {
- WLDBG_ERROR(DBG_LEVEL_0,
- "%s: cannot reserve PCI memory region 1",
- MWL_DRV_NAME);
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot reserve PCI memory region 1",
+ MWL_DRV_NAME);
goto err_iounmap_iobase0;
}
@@ -370,12 +186,14 @@ static int mwl_alloc_pci_resource(struct mwl_priv *priv)
priv->iobase1 = phys_addr2[0];
if (!priv->iobase1) {
- WLDBG_ERROR(DBG_LEVEL_0, "%s: cannot remap PCI memory region 1",
- MWL_DRV_NAME);
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot remap PCI memory region 1",
+ MWL_DRV_NAME);
goto err_release_mem_region_bar1;
}
- WLDBG_PRINT("priv->iobase1 = %x", (unsigned int)priv->iobase1);
+ wiphy_info(priv->hw->wiphy, "priv->iobase1 = %x",
+ (unsigned int)priv->iobase1);
priv->pcmd_buf =
(unsigned short *)dma_alloc_coherent(&priv->pdev->dev,
@@ -384,20 +202,19 @@ static int mwl_alloc_pci_resource(struct mwl_priv *priv)
GFP_KERNEL);
if (!priv->pcmd_buf) {
- WLDBG_ERROR(DBG_LEVEL_0,
- "%s: cannot alloc memory for command buffer",
- MWL_DRV_NAME);
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot alloc memory for command buffer",
+ MWL_DRV_NAME);
goto err_iounmap_iobase1;
}
- WLDBG_PRINT("priv->pcmd_buf = %x priv->pphys_cmd_buf = %x",
- (unsigned int)priv->pcmd_buf,
- (unsigned int)priv->pphys_cmd_buf);
+ wiphy_info(priv->hw->wiphy,
+ "priv->pcmd_buf = %x priv->pphys_cmd_buf = %x",
+ (unsigned int)priv->pcmd_buf,
+ (unsigned int)priv->pphys_cmd_buf);
memset(priv->pcmd_buf, 0x00, CMD_BUF_SIZE);
- WLDBG_EXIT(DBG_LEVEL_0);
-
return 0;
err_iounmap_iobase1:
@@ -420,7 +237,7 @@ err_release_mem_region_bar0:
err_reserve_mem_region_bar0:
- WLDBG_EXIT_INFO(DBG_LEVEL_0, "pci alloc fail");
+ wiphy_err(priv->hw->wiphy, "pci alloc fail");
return -EIO;
}
@@ -429,11 +246,7 @@ static void mwl_free_pci_resource(struct mwl_priv *priv)
{
struct pci_dev *pdev;
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!priv);
pdev = priv->pdev;
- BUG_ON(!pdev);
iounmap(priv->iobase0);
iounmap(priv->iobase1);
@@ -443,8 +256,6 @@ static void mwl_free_pci_resource(struct mwl_priv *priv)
pci_resource_len(pdev, 0));
dma_free_coherent(&priv->pdev->dev, CMD_BUF_SIZE,
priv->pcmd_buf, priv->pphys_cmd_buf);
-
- WLDBG_EXIT(DBG_LEVEL_0);
}
static int mwl_init_firmware(struct mwl_priv *priv, char *fw_name)
@@ -452,29 +263,24 @@ static int mwl_init_firmware(struct mwl_priv *priv, char *fw_name)
struct pci_dev *pdev;
int rc = 0;
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!priv);
pdev = priv->pdev;
- BUG_ON(!pdev);
rc = request_firmware(&priv->fw_ucode, fw_name, &priv->pdev->dev);
if (rc) {
- WLDBG_ERROR(DBG_LEVEL_0, "%s: cannot load firmware image <%s>",
- MWL_DRV_NAME, fw_name);
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot load firmware image <%s>",
+ MWL_DRV_NAME, fw_name);
goto err_load_fw;
}
rc = mwl_fwdl_download_firmware(priv->hw);
if (rc) {
- WLDBG_ERROR(DBG_LEVEL_0,
- "%s: cannot download firmware image <%s>",
- MWL_DRV_NAME, fw_name);
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot download firmware image <%s>",
+ MWL_DRV_NAME, fw_name);
goto err_download_fw;
}
- WLDBG_EXIT(DBG_LEVEL_0);
-
return rc;
err_download_fw:
@@ -483,7 +289,7 @@ err_download_fw:
err_load_fw:
- WLDBG_EXIT_INFO(DBG_LEVEL_0, "firmware init fail");
+ wiphy_err(priv->hw->wiphy, "firmware init fail");
return rc;
}
@@ -500,13 +306,8 @@ static void mwl_reg_notifier(struct wiphy *wiphy,
u32 prop_value;
int i, j, k;
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!wiphy);
hw = (struct ieee80211_hw *)wiphy_priv(wiphy);
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
if (priv->pwr_node) {
for_each_property_of_node(priv->pwr_node, prop) {
@@ -531,49 +332,50 @@ static void mwl_reg_notifier(struct wiphy *wiphy,
}
if (prop) {
- /* Reset the whole table
- */
+ /* Reset the whole table */
for (i = 0; i < SYSADPT_MAX_NUM_CHANNELS; i++)
memset(&priv->tx_pwr_tbl[i], 0,
sizeof(struct mwl_tx_pwr_tbl));
- /* Load related power table
- */
+ /* Load related power table */
i = 0;
j = 0;
while (i < prop->length) {
prop_value =
- be32_to_cpu(*(u32 *)(prop->value + i));
+ be32_to_cpu(*(__be32 *)
+ (prop->value + i));
priv->tx_pwr_tbl[j].channel = prop_value;
i += 4;
prop_value =
- be32_to_cpu(*(u32 *)(prop->value + i));
+ be32_to_cpu(*(__be32 *)
+ (prop->value + i));
priv->tx_pwr_tbl[j].setcap = prop_value;
i += 4;
for (k = 0; k < SYSADPT_TX_POWER_LEVEL_TOTAL;
k++) {
prop_value =
- be32_to_cpu(*(u32 *)
+ be32_to_cpu(*(__be32 *)
(prop->value + i));
priv->tx_pwr_tbl[j].tx_power[k] =
prop_value;
i += 4;
}
prop_value =
- be32_to_cpu(*(u32 *)(prop->value + i));
+ be32_to_cpu(*(__be32 *)
+ (prop->value + i));
priv->tx_pwr_tbl[j].cdd = prop_value;
i += 4;
prop_value =
- be32_to_cpu(*(u32 *)(prop->value + i));
+ be32_to_cpu(*(__be32 *)
+ (prop->value + i));
priv->tx_pwr_tbl[j].txantenna2 = prop_value;
i += 4;
j++;
}
- /* Dump loaded power tabel
- */
- WLDBG_PRINT("%s: %s\n", dev_name(&wiphy->dev),
- prop->name);
+ /* Dump loaded power tabel */
+ wiphy_info(hw->wiphy, "%s: %s\n", dev_name(&wiphy->dev),
+ prop->name);
for (i = 0; i < SYSADPT_MAX_NUM_CHANNELS; i++) {
struct mwl_tx_pwr_tbl *pwr_tbl;
char disp_buf[64];
@@ -582,11 +384,12 @@ static void mwl_reg_notifier(struct wiphy *wiphy,
pwr_tbl = &priv->tx_pwr_tbl[i];
if (pwr_tbl->channel == 0)
break;
- WLDBG_PRINT("Channel: %d: 0x%x 0x%x 0x%x",
- pwr_tbl->channel,
- pwr_tbl->setcap,
- pwr_tbl->cdd,
- pwr_tbl->txantenna2);
+ wiphy_info(hw->wiphy,
+ "Channel: %d: 0x%x 0x%x 0x%x",
+ pwr_tbl->channel,
+ pwr_tbl->setcap,
+ pwr_tbl->cdd,
+ pwr_tbl->txantenna2);
disp_ptr = disp_buf;
for (j = 0; j < SYSADPT_TX_POWER_LEVEL_TOTAL;
j++) {
@@ -594,12 +397,10 @@ static void mwl_reg_notifier(struct wiphy *wiphy,
sprintf(disp_ptr, "%x ",
pwr_tbl->tx_power[j]);
}
- WLDBG_PRINT("%s", disp_buf);
+ wiphy_info(hw->wiphy, "%s", disp_buf);
}
}
}
-
- WLDBG_EXIT(DBG_LEVEL_0);
}
static int mwl_process_of_dts(struct mwl_priv *priv)
@@ -607,10 +408,6 @@ static int mwl_process_of_dts(struct mwl_priv *priv)
struct property *prop;
u32 prop_value;
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!priv);
-
priv->disable_2g = false;
priv->disable_5g = false;
priv->antenna_tx = ANTENNA_TX_4_AUTO;
@@ -622,19 +419,19 @@ static int mwl_process_of_dts(struct mwl_priv *priv)
if (!priv->dt_node)
return -EPERM;
- /* look for all matching property names
- */
+ /* look for all matching property names */
for_each_property_of_node(priv->dt_node, prop) {
if (strcmp(prop->name, "marvell,2ghz") == 0)
priv->disable_2g = true;
if (strcmp(prop->name, "marvell,5ghz") == 0)
priv->disable_5g = true;
if (strcmp(prop->name, "marvell,chainmask") == 0) {
- prop_value = be32_to_cpu(*((u32 *)prop->value));
+ prop_value = be32_to_cpu(*((__be32 *)prop->value));
if (prop_value == 2)
priv->antenna_tx = ANTENNA_TX_2;
- prop_value = be32_to_cpu(*((u32 *)(prop->value + 4)));
+ prop_value = be32_to_cpu(*((__be32 *)
+ (prop->value + 4)));
if (prop_value == 2)
priv->antenna_rx = ANTENNA_RX_2;
}
@@ -643,23 +440,23 @@ static int mwl_process_of_dts(struct mwl_priv *priv)
priv->pwr_node = of_find_node_by_name(priv->dt_node,
"marvell,powertable");
- WLDBG_PRINT("2G: %s\n", priv->disable_2g ? "disable" : "enable");
- WLDBG_PRINT("5G: %s\n", priv->disable_5g ? "disable" : "enable");
+ wiphy_info(priv->hw->wiphy,
+ "2G: %s\n", priv->disable_2g ? "disable" : "enable");
+ wiphy_info(priv->hw->wiphy,
+ "5G: %s\n", priv->disable_5g ? "disable" : "enable");
if (priv->antenna_tx == ANTENNA_TX_4_AUTO)
- WLDBG_PRINT("TX: 4 antennas\n");
+ wiphy_info(priv->hw->wiphy, "TX: 4 antennas\n");
else if (priv->antenna_tx == ANTENNA_TX_2)
- WLDBG_PRINT("TX: 2 antennas\n");
+ wiphy_info(priv->hw->wiphy, "TX: 2 antennas\n");
else
- WLDBG_PRINT("TX: unknown\n");
+ wiphy_info(priv->hw->wiphy, "TX: unknown\n");
if (priv->antenna_rx == ANTENNA_RX_4_AUTO)
- WLDBG_PRINT("RX: 4 antennas\n");
+ wiphy_info(priv->hw->wiphy, "RX: 4 antennas\n");
else if (priv->antenna_rx == ANTENNA_RX_2)
- WLDBG_PRINT("RX: 2 antennas\n");
+ wiphy_info(priv->hw->wiphy, "RX: 2 antennas\n");
else
- WLDBG_PRINT("RX: unknown\n");
-
- WLDBG_EXIT(DBG_LEVEL_0);
+ wiphy_info(priv->hw->wiphy, "RX: unknown\n");
return 0;
}
@@ -669,11 +466,7 @@ static void mwl_set_ht_caps(struct mwl_priv *priv,
{
struct ieee80211_hw *hw;
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!priv);
hw = priv->hw;
- BUG_ON(!hw);
band->ht_cap.ht_supported = 1;
@@ -694,54 +487,41 @@ static void mwl_set_ht_caps(struct mwl_priv *priv,
band->ht_cap.mcs.rx_mask[4] = 0x01;
band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
-
- WLDBG_EXIT(DBG_LEVEL_0);
}
static void mwl_set_vht_caps(struct mwl_priv *priv,
struct ieee80211_supported_band *band)
{
- WLDBG_ENTER(DBG_LEVEL_0);
-
band->vht_cap.vht_supported = 1;
- band->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
+ band->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
band->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
band->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
- band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
- band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
band->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
band->vht_cap.cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
band->vht_cap.cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
if (priv->antenna_rx == ANTENNA_RX_2)
- band->vht_cap.vht_mcs.rx_mcs_map = 0xfffa;
+ band->vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(0xfffa);
else
- band->vht_cap.vht_mcs.rx_mcs_map = 0xffea;
+ band->vht_cap.vht_mcs.rx_mcs_map = cpu_to_le16(0xffea);
if (priv->antenna_tx == ANTENNA_TX_2)
- band->vht_cap.vht_mcs.tx_mcs_map = 0xfffa;
+ band->vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(0xfffa);
else
- band->vht_cap.vht_mcs.tx_mcs_map = 0xffea;
-
- WLDBG_EXIT(DBG_LEVEL_0);
+ band->vht_cap.vht_mcs.tx_mcs_map = cpu_to_le16(0xffea);
}
static void mwl_set_caps(struct mwl_priv *priv)
{
struct ieee80211_hw *hw;
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!priv);
hw = priv->hw;
- BUG_ON(!hw);
- /* set up band information for 2.4G
- */
+ /* set up band information for 2.4G */
if (!priv->disable_2g) {
BUILD_BUG_ON(sizeof(priv->channels_24) !=
sizeof(mwl_channels_24));
@@ -763,8 +543,7 @@ static void mwl_set_caps(struct mwl_priv *priv)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24;
}
- /* set up band information for 5G
- */
+ /* set up band information for 5G */
if (!priv->disable_5g) {
BUILD_BUG_ON(sizeof(priv->channels_50) !=
sizeof(mwl_channels_50));
@@ -785,8 +564,6 @@ static void mwl_set_caps(struct mwl_priv *priv)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50;
}
-
- WLDBG_EXIT(DBG_LEVEL_0);
}
static int mwl_wl_init(struct mwl_priv *priv)
@@ -795,21 +572,12 @@ static int mwl_wl_init(struct mwl_priv *priv)
int rc;
int i;
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!priv);
hw = priv->hw;
- BUG_ON(!hw);
- /* Extra headroom is the size of the required DMA header
- * minus the size of the smallest 802.11 frame (CTS frame).
- */
- hw->extra_tx_headroom =
- sizeof(struct mwl_dma_data) - sizeof(struct ieee80211_cts);
+ hw->extra_tx_headroom = SYSADPT_MIN_BYTES_HEADROOM;
hw->queues = SYSADPT_TX_WMM_QUEUES;
- /* Set rssi values to dBm
- */
+ /* Set rssi values to dBm */
hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL;
/* Ask mac80211 to not to trigger PS mode
@@ -824,17 +592,16 @@ static int mwl_wl_init(struct mwl_priv *priv)
priv->sta_macids_supported = 0x00010000;
priv->macids_used = 0;
INIT_LIST_HEAD(&priv->vif_list);
+ INIT_LIST_HEAD(&priv->sta_list);
- /* Set default radio state, preamble and wmm
- */
+ /* Set default radio state, preamble and wmm */
priv->radio_on = false;
priv->radio_short_preamble = false;
priv->wmm_enabled = false;
priv->powinited = 0;
- /* Handle watchdog ba events
- */
+ /* Handle watchdog ba events */
INIT_WORK(&priv->watchdog_ba_handle, mwl_watchdog_ba_events);
tasklet_init(&priv->tx_task, (void *)mwl_tx_done, (unsigned long)hw);
@@ -846,28 +613,30 @@ static int mwl_wl_init(struct mwl_priv *priv)
priv->recv_limit = SYSADPT_RECEIVE_LIMIT;
priv->is_rx_schedule = false;
- SPIN_LOCK_INIT(&priv->locks.xmit_lock);
- SPIN_LOCK_INIT(&priv->locks.fwcmd_lock);
- SPIN_LOCK_INIT(&priv->locks.stream_lock);
+ spin_lock_init(&priv->tx_desc_lock);
+ spin_lock_init(&priv->fwcmd_lock);
+ spin_lock_init(&priv->vif_lock);
+ spin_lock_init(&priv->sta_lock);
+ spin_lock_init(&priv->stream_lock);
rc = mwl_tx_init(hw);
if (rc) {
- WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to initialize TX",
- MWL_DRV_NAME);
+ wiphy_err(hw->wiphy, "%s: fail to initialize TX",
+ MWL_DRV_NAME);
goto err_mwl_tx_init;
}
rc = mwl_rx_init(hw);
if (rc) {
- WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to initialize RX",
- MWL_DRV_NAME);
+ wiphy_err(hw->wiphy, "%s: fail to initialize RX",
+ MWL_DRV_NAME);
goto err_mwl_rx_init;
}
rc = mwl_fwcmd_get_hw_specs(hw);
if (rc) {
- WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to get HW specifications",
- MWL_DRV_NAME);
+ wiphy_err(hw->wiphy, "%s: fail to get HW specifications",
+ MWL_DRV_NAME);
goto err_get_hw_specs;
}
@@ -887,12 +656,13 @@ static int mwl_wl_init(struct mwl_priv *priv)
rc = mwl_fwcmd_set_hw_specs(hw);
if (rc) {
- WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to set HW specifications",
- MWL_DRV_NAME);
+ wiphy_err(hw->wiphy, "%s: fail to set HW specifications",
+ MWL_DRV_NAME);
goto err_set_hw_specs;
}
- WLDBG_PRINT("firmware version: 0x%x", priv->hw_data.fw_release_num);
+ wiphy_info(hw->wiphy,
+ "firmware version: 0x%x", priv->hw_data.fw_release_num);
mwl_fwcmd_radio_disable(hw);
@@ -910,13 +680,11 @@ static int mwl_wl_init(struct mwl_priv *priv)
rc = ieee80211_register_hw(hw);
if (rc) {
- WLDBG_ERROR(DBG_LEVEL_0, "%s: fail to register device",
- MWL_DRV_NAME);
+ wiphy_err(hw->wiphy, "%s: fail to register device",
+ MWL_DRV_NAME);
goto err_register_hw;
}
- WLDBG_EXIT(DBG_LEVEL_0);
-
return rc;
err_register_hw:
@@ -931,7 +699,7 @@ err_mwl_rx_init:
err_mwl_tx_init:
- WLDBG_EXIT_INFO(DBG_LEVEL_0, "init fail");
+ wiphy_err(hw->wiphy, "init fail");
return rc;
}
@@ -940,11 +708,7 @@ static void mwl_wl_deinit(struct mwl_priv *priv)
{
struct ieee80211_hw *hw;
- WLDBG_ENTER(DBG_LEVEL_0);
-
- BUG_ON(!priv);
hw = priv->hw;
- BUG_ON(!hw);
ieee80211_unregister_hw(hw);
mwl_rx_deinit(hw);
@@ -952,144 +716,136 @@ static void mwl_wl_deinit(struct mwl_priv *priv)
tasklet_kill(&priv->rx_task);
tasklet_kill(&priv->tx_task);
mwl_fwcmd_reset(hw);
-
- WLDBG_EXIT(DBG_LEVEL_0);
}
-static void mwl_watchdog_ba_events(struct work_struct *work)
+static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
- int rc;
- u8 bitmap = 0, stream_index;
- struct mwl_ampdu_stream *streams;
- struct mwl_priv *priv =
- container_of(work, struct mwl_priv, watchdog_ba_handle);
- struct ieee80211_hw *hw = priv->hw;
- u32 status;
+ static bool printed_version;
+ struct ieee80211_hw *hw;
+ struct mwl_priv *priv;
+ int rc = 0;
+
+ if (id->driver_data >= MWLUNKNOWN)
+ return -ENODEV;
- rc = mwl_fwcmd_get_watchdog_bitmap(priv->hw, &bitmap);
+ if (!printed_version) {
+ pr_info("<<%s version %s>>",
+ MWL_DESC, MWL_DRV_VERSION);
+ printed_version = true;
+ }
- if (rc)
- goto done;
-
- SPIN_LOCK(&priv->locks.stream_lock);
-
- /* the bitmap is the hw queue number. Map it to the ampdu queue.
- */
- if (bitmap != INVALID_WATCHDOG) {
- if (bitmap == SYSADPT_TX_AMPDU_QUEUES)
- stream_index = 0;
- else if (bitmap > SYSADPT_TX_AMPDU_QUEUES)
- stream_index = bitmap - SYSADPT_TX_AMPDU_QUEUES;
- else
- stream_index = bitmap + 3; /** queue 0 is stream 3*/
-
- if (bitmap != 0xFF) {
- /* Check if the stream is in use before disabling it
- */
- streams = &priv->ampdu[stream_index];
-
- if (streams->state == AMPDU_STREAM_ACTIVE) {
- ieee80211_stop_tx_ba_session(streams->sta,
- streams->tid);
- SPIN_UNLOCK(&priv->locks.stream_lock);
- mwl_fwcmd_destroy_ba(hw, stream_index);
- SPIN_LOCK(&priv->locks.stream_lock);
- }
- } else {
- for (stream_index = 0;
- stream_index < SYSADPT_TX_AMPDU_QUEUES;
- stream_index++) {
- streams = &priv->ampdu[stream_index];
-
- if (streams->state != AMPDU_STREAM_ACTIVE)
- continue;
-
- ieee80211_stop_tx_ba_session(streams->sta,
- streams->tid);
- SPIN_UNLOCK(&priv->locks.stream_lock);
- mwl_fwcmd_destroy_ba(hw, stream_index);
- SPIN_LOCK(&priv->locks.stream_lock);
- }
- }
+ rc = pci_enable_device(pdev);
+ if (rc) {
+ pr_err("%s: cannot enable new PCI device",
+ MWL_DRV_NAME);
+ return rc;
+ }
+
+ rc = pci_set_dma_mask(pdev, 0xffffffff);
+ if (rc) {
+ pr_err("%s: 32-bit PCI DMA not supported",
+ MWL_DRV_NAME);
+ goto err_pci_disable_device;
}
- SPIN_UNLOCK(&priv->locks.stream_lock);
+ pci_set_master(pdev);
-done:
+ hw = ieee80211_alloc_hw(sizeof(*priv), &mwl_mac80211_ops);
+ if (!hw) {
+ pr_err("%s: ieee80211 alloc failed",
+ MWL_DRV_NAME);
+ rc = -ENOMEM;
+ goto err_pci_disable_device;
+ }
- status = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
- writel(status | MACREG_A2HRIC_BA_WATCHDOG,
- priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
-}
+ /* hook regulatory domain change notification */
+ hw->wiphy->reg_notifier = mwl_reg_notifier;
-static irqreturn_t mwl_interrupt(int irq, void *dev_id)
-{
- struct ieee80211_hw *hw = dev_id;
- struct mwl_priv *priv;
- void *int_status_mask;
- unsigned int int_status, clr_status;
- u32 status;
+ SET_IEEE80211_DEV(hw, &pdev->dev);
+ pci_set_drvdata(pdev, hw);
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
+ priv->hw = hw;
+ priv->pdev = pdev;
+ priv->chip_type = id->driver_data;
- int_status_mask = priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK;
+ rc = mwl_alloc_pci_resource(priv);
+ if (rc)
+ goto err_alloc_pci_resource;
- int_status = readl(priv->iobase1 + MACREG_REG_A2H_INTERRUPT_CAUSE);
+ rc = mwl_init_firmware(priv, mwl_chip_tbl[priv->chip_type].fw_image);
+ if (rc) {
+ wiphy_err(hw->wiphy, "%s: fail to initialize firmware",
+ MWL_DRV_NAME);
+ goto err_init_firmware;
+ }
- if (int_status == 0x00000000)
- return IRQ_NONE;
+ /* firmware is loaded to H/W, it can be released now */
+ release_firmware(priv->fw_ucode);
- if (int_status == 0xffffffff) {
- WLDBG_INFO(DBG_LEVEL_0, "card plugged out???");
- } else {
- clr_status = int_status;
+ rc = mwl_process_of_dts(priv);
+ if (rc) {
+ wiphy_err(hw->wiphy, "%s: fail to load dts mwlwifi parameters",
+ MWL_DRV_NAME);
+ goto err_process_of_dts;
+ }
- if (int_status & MACREG_A2HRIC_BIT_TX_DONE) {
- int_status &= ~MACREG_A2HRIC_BIT_TX_DONE;
+ rc = mwl_wl_init(priv);
+ if (rc) {
+ wiphy_err(hw->wiphy, "%s: fail to initialize wireless lan",
+ MWL_DRV_NAME);
+ goto err_wl_init;
+ }
- if (!priv->is_tx_schedule) {
- status = readl(int_status_mask);
- writel((status & ~MACREG_A2HRIC_BIT_TX_DONE),
- int_status_mask);
- tasklet_schedule(&priv->tx_task);
- priv->is_tx_schedule = true;
- }
- }
+ return rc;
- if (int_status & MACREG_A2HRIC_BIT_RX_RDY) {
- int_status &= ~MACREG_A2HRIC_BIT_RX_RDY;
+err_wl_init:
+err_process_of_dts:
+err_init_firmware:
- if (!priv->is_rx_schedule) {
- status = readl(int_status_mask);
- writel((status & ~MACREG_A2HRIC_BIT_RX_RDY),
- int_status_mask);
- tasklet_schedule(&priv->rx_task);
- priv->is_rx_schedule = true;
- }
- }
+ mwl_fwcmd_reset(hw);
- if (int_status & MACREG_A2HRIC_BA_WATCHDOG) {
- status = readl(int_status_mask);
- writel((status & ~MACREG_A2HRIC_BA_WATCHDOG),
- int_status_mask);
- int_status &= ~MACREG_A2HRIC_BA_WATCHDOG;
- ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
- }
+err_alloc_pci_resource:
- writel(~clr_status,
- priv->iobase1 + MACREG_REG_A2H_INTERRUPT_CAUSE);
- }
+ pci_set_drvdata(pdev, NULL);
+ ieee80211_free_hw(hw);
+
+err_pci_disable_device:
+
+ pci_disable_device(pdev);
+
+ return rc;
+}
+
+static void mwl_remove(struct pci_dev *pdev)
+{
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct mwl_priv *priv;
+
+ if (!hw)
+ return;
+
+ priv = hw->priv;
- return IRQ_HANDLED;
+ mwl_wl_deinit(priv);
+ mwl_free_pci_resource(priv);
+ pci_set_drvdata(pdev, NULL);
+ ieee80211_free_hw(hw);
+ pci_disable_device(pdev);
}
+static struct pci_driver mwl_pci_driver = {
+ .name = MWL_DRV_NAME,
+ .id_table = mwl_pci_id_tbl,
+ .probe = mwl_probe,
+ .remove = mwl_remove
+};
+
module_pci_driver(mwl_pci_driver);
MODULE_DESCRIPTION(MWL_DESC);
MODULE_VERSION(MWL_DRV_VERSION);
MODULE_AUTHOR("Marvell Semiconductor, Inc.");
-MODULE_LICENSE("Dual BSD/GPL");
+MODULE_LICENSE("GPL v2");
MODULE_SUPPORTED_DEVICE(MWL_DEV_NAME);
MODULE_DEVICE_TABLE(pci, mwl_pci_id_tbl);
diff --git a/mwl_debug.c b/mwl_debug.c
deleted file mode 100644
index 1ac270c..0000000
--- a/mwl_debug.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/* Description: This file implements debug related functions.
-*/
-
-#include <linux/printk.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include "mwl_debug.h"
-
-/* CONSTANTS AND MACROS
-*/
-
-#define WLDBG_CLASSES ( \
- DBG_CLASS_PANIC | \
- DBG_CLASS_ERROR | \
- DBG_CLASS_WARNING | \
- DBG_CLASS_INFO | \
- DBG_CLASS_DATA | \
- DBG_CLASS_ENTER | \
- DBG_CLASS_EXIT)
-
-#define PRT_8BYTES "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n"
-
-/* PRIVATE VARIABLES
-*/
-
-static u32 dbg_levels;
-
-/* PUBLIC FUNCTION DEFINITION
-*/
-
-void mwl_debug_prt(u32 classlevel, const char *func, const char *format, ...)
-{
- unsigned char *debug_string;
- u32 level = classlevel & 0x0000ffff;
- u32 class = classlevel & 0xffff0000;
- va_list a_start;
-
- if (classlevel != 0) {
- if ((class & WLDBG_CLASSES) != class)
- return;
-
- if ((level & dbg_levels) != level) {
- if (class != DBG_CLASS_PANIC &&
- class != DBG_CLASS_ERROR)
- return;
- }
- }
-
- debug_string = kmalloc(1024, GFP_ATOMIC);
-
- if (!debug_string)
- return;
-
- if (format) {
- va_start(a_start, format);
- vsprintf(debug_string, format, a_start);
- va_end(a_start);
- } else {
- debug_string[0] = '\0';
- }
-
- switch (class) {
- case DBG_CLASS_ENTER:
- pr_debug("Enter %s() ...\n", func);
- break;
- case DBG_CLASS_EXIT:
- pr_debug("... Exit %s()\n", func);
- break;
- case DBG_CLASS_WARNING:
- pr_debug("WARNING: ");
- break;
- case DBG_CLASS_ERROR:
- pr_debug("ERROR: ");
- break;
- case DBG_CLASS_PANIC:
- pr_debug("PANIC: ");
- break;
- default:
- break;
- }
-
- if (strlen(debug_string) > 0) {
- if (debug_string[strlen(debug_string) - 1] == '\n')
- debug_string[strlen(debug_string) - 1] = '\0';
- pr_debug("%s(): %s\n", func, debug_string);
- }
-
- kfree(debug_string);
-}
-
-void mwl_debug_prtdata(u32 classlevel, const char *func,
- const void *data, int len, const char *format, ...)
-{
- unsigned char *dbg_string;
- unsigned char dbg_data[16] = "";
- unsigned char *memptr = (unsigned char *)data;
- u32 level = classlevel & 0x0000ffff;
- u32 class = classlevel & 0xffff0000;
- int curr_byte = 0;
- int num_bytes = 0;
- int offset = 0;
- va_list a_start;
-
- if ((class & WLDBG_CLASSES) != class)
- return;
-
- if ((level & dbg_levels) != level)
- return;
-
- dbg_string = kmalloc(len + 1024, GFP_ATOMIC);
-
- if (!dbg_string)
- return;
-
- if (format) {
- va_start(a_start, format);
- vsprintf(dbg_string, format, a_start);
- va_end(a_start);
- } else {
- dbg_string[0] = '\0';
- }
-
- if (strlen(dbg_string) > 0) {
- if (dbg_string[strlen(dbg_string) - 1] == '\n')
- dbg_string[strlen(dbg_string) - 1] = '\0';
- pr_debug("%s() %s\n", func, dbg_string);
- } else {
- pr_debug("%s()\n", func);
- }
-
- for (curr_byte = 0; curr_byte < len; curr_byte = curr_byte + 8) {
- if ((curr_byte + 8) < len) {
- pr_debug(PRT_8BYTES,
- *(memptr + curr_byte + 0),
- *(memptr + curr_byte + 1),
- *(memptr + curr_byte + 2),
- *(memptr + curr_byte + 3),
- *(memptr + curr_byte + 4),
- *(memptr + curr_byte + 5),
- *(memptr + curr_byte + 6),
- *(memptr + curr_byte + 7));
- } else {
- num_bytes = len - curr_byte;
- offset = curr_byte;
- for (curr_byte = 0; curr_byte < num_bytes;
- curr_byte++) {
- sprintf(dbg_data, "0x%02x ",
- *(memptr + offset + curr_byte));
- strcat(dbg_string, dbg_data);
- }
- pr_debug("%s\n", dbg_string);
- break;
- }
- }
-
- kfree(dbg_string);
-}
-
-void mwl_debug_dumpdata(const void *data, int len, char *marker)
-{
- unsigned char *memptr = (unsigned char *)data;
- int curr_byte = 0;
- int num_bytes = 0;
- int offset = 0;
-
- pr_debug("%s\n", marker);
-
- for (curr_byte = 0; curr_byte < len; curr_byte = curr_byte + 8) {
- if ((curr_byte + 8) < len) {
- pr_debug(PRT_8BYTES,
- *(memptr + curr_byte + 0),
- *(memptr + curr_byte + 1),
- *(memptr + curr_byte + 2),
- *(memptr + curr_byte + 3),
- *(memptr + curr_byte + 4),
- *(memptr + curr_byte + 5),
- *(memptr + curr_byte + 6),
- *(memptr + curr_byte + 7));
- } else {
- num_bytes = len - curr_byte;
- offset = curr_byte;
- for (curr_byte = 0; curr_byte < num_bytes;
- curr_byte++)
- pr_debug("0x%02x ",
- *(memptr + offset + curr_byte));
- pr_debug("\n\n");
- break;
- }
- }
-}
diff --git a/mwl_debug.h b/mwl_debug.h
deleted file mode 100644
index 226db7b..0000000
--- a/mwl_debug.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/* Description: This file defines debug related functions.
-*/
-
-#ifndef _mwl_debug_h_
-#define _mwl_debug_h_
-
-#include <linux/types.h>
-#include <linux/bitops.h>
-
-/* CONSTANTS AND MACROS
-*/
-
-#define DBG_LEVEL_0 BIT(0) /* mwl_main.c */
-#define DBG_LEVEL_1 BIT(1) /* mwl_fwdl.c */
-#define DBG_LEVEL_2 BIT(2) /* mwl_fwcmd.c */
-#define DBG_LEVEL_3 BIT(3) /* mwl_tx.c */
-#define DBG_LEVEL_4 BIT(4) /* mwl_rx.c */
-#define DBG_LEVEL_5 BIT(5) /* mwl_mac80211.c */
-#define DBG_LEVEL_6 BIT(6)
-#define DBG_LEVEL_7 BIT(7)
-#define DBG_LEVEL_8 BIT(8)
-#define DBG_LEVEL_9 BIT(9)
-#define DBG_LEVEL_10 BIT(10)
-#define DBG_LEVEL_11 BIT(11)
-#define DBG_LEVEL_12 BIT(12)
-#define DBG_LEVEL_13 BIT(13)
-#define DBG_LEVEL_14 BIT(14)
-#define DBG_LEVEL_15 BIT(15)
-
-#define DBG_CLASS_PANIC BIT(16)
-#define DBG_CLASS_ERROR BIT(17)
-#define DBG_CLASS_WARNING BIT(18)
-#define DBG_CLASS_ENTER BIT(19)
-#define DBG_CLASS_EXIT BIT(20)
-#define DBG_CLASS_INFO BIT(21)
-#define DBG_CLASS_DATA BIT(22)
-#define DBG_CLASS_7 BIT(23)
-#define DBG_CLASS_8 BIT(24)
-#define DBG_CLASS_9 BIT(25)
-#define DBG_CLASS_10 BIT(26)
-#define DBG_CLASS_11 BIT(27)
-#define DBG_CLASS_12 BIT(28)
-#define DBG_CLASS_13 BIT(29)
-#define DBG_CLASS_14 BIT(30)
-#define DBG_CLASS_15 BIT(31)
-
-#define WLDBG_PRINT(...) \
- mwl_debug_prt(0, __func__, __VA_ARGS__)
-
-#ifdef MWL_DEBUG
-
-#define WLDBG_DUMP_DATA(classlevel, data, len) \
- mwl_debug_prtdata(classlevel | DBG_CLASS_DATA, \
- __func__, data, len, NULL)
-
-#define WLDBG_ENTER(classlevel) \
- mwl_debug_prt(classlevel | DBG_CLASS_ENTER, __func__, NULL)
-
-#define WLDBG_ENTER_INFO(classlevel, ...) \
- mwl_debug_prt(classlevel | DBG_CLASS_ENTER, __func__, __VA_ARGS__)
-
-#define WLDBG_EXIT(classlevel) \
- mwl_debug_prt(classlevel | DBG_CLASS_EXIT, __func__, NULL)
-
-#define WLDBG_EXIT_INFO(classlevel, ...) \
- mwl_debug_prt(classlevel | DBG_CLASS_EXIT, __func__, __VA_ARGS__)
-
-#define WLDBG_INFO(classlevel, ...) \
- mwl_debug_prt(classlevel | DBG_CLASS_INFO, __func__, __VA_ARGS__)
-
-#define WLDBG_WARNING(classlevel, ...) \
- mwl_debug_prt(classlevel | DBG_CLASS_WARNING, __func__, __VA_ARGS__)
-
-#define WLDBG_ERROR(classlevel, ...) \
- mwl_debug_prt(classlevel | DBG_CLASS_ERROR, __func__, __VA_ARGS__)
-
-#define WLDBG_PANIC(classlevel, ...) \
- mwl_debug_prt(classlevel | DBG_CLASS_PANIC, __func__, __VA_ARGS__)
-
-#else
-
-#define WLDBG_DUMP_DATA(classlevel, data, len)
-#define WLDBG_ENTER(classlevel)
-#define WLDBG_ENTER_INFO(classlevel, ...)
-#define WLDBG_EXIT(classlevel)
-#define WLDBG_EXIT_INFO(classlevel, ...)
-#define WLDBG_INFO(classlevel, ...)
-#define WLDBG_WARNING(classlevel, ...)
-#define WLDBG_ERROR(classlevel, ...)
-#define WLDBG_PANIC(classlevel, ...)
-
-#endif /* MWL_DEBUG */
-
-/* PUBLIC FUNCTION DECLARATION
-*/
-
-void mwl_debug_prt(u32 classlevel, const char *func, const char *format, ...);
-void mwl_debug_prtdata(u32 classlevel, const char *func,
- const void *data, int len, const char *format, ...);
-void mwl_debug_dumpdata(const void *data, int len, char *marker);
-
-#endif /* _mwl_debug_h_ */
diff --git a/mwl_dev.h b/mwl_dev.h
deleted file mode 100644
index 7c6facc..0000000
--- a/mwl_dev.h
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/* Description: This file defines device related information.
-*/
-
-#ifndef _mwl_dev_h_
-#define _mwl_dev_h_
-
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-#include <net/mac80211.h>
-
-/* CONSTANTS AND MACROS
-*/
-
-/* Map to 0x80000000 (Bus control) on BAR0
-*/
-#define MACREG_REG_H2A_INTERRUPT_EVENTS 0x00000C18 /* (From host to ARM) */
-#define MACREG_REG_H2A_INTERRUPT_CAUSE 0x00000C1C /* (From host to ARM) */
-#define MACREG_REG_H2A_INTERRUPT_MASK 0x00000C20 /* (From host to ARM) */
-#define MACREG_REG_H2A_INTERRUPT_CLEAR_SEL 0x00000C24 /* (From host to ARM) */
-#define MACREG_REG_H2A_INTERRUPT_STATUS_MASK 0x00000C28 /* (From host to ARM) */
-
-#define MACREG_REG_A2H_INTERRUPT_EVENTS 0x00000C2C /* (From ARM to host) */
-#define MACREG_REG_A2H_INTERRUPT_CAUSE 0x00000C30 /* (From ARM to host) */
-#define MACREG_REG_A2H_INTERRUPT_MASK 0x00000C34 /* (From ARM to host) */
-#define MACREG_REG_A2H_INTERRUPT_CLEAR_SEL 0x00000C38 /* (From ARM to host) */
-#define MACREG_REG_A2H_INTERRUPT_STATUS_MASK 0x00000C3C /* (From ARM to host) */
-
-/* Map to 0x80000000 on BAR1
-*/
-#define MACREG_REG_GEN_PTR 0x00000C10
-#define MACREG_REG_INT_CODE 0x00000C14
-#define MACREG_REG_SCRATCH 0x00000C40
-#define MACREG_REG_FW_PRESENT 0x0000BFFC
-
-/* Bit definitio for MACREG_REG_A2H_INTERRUPT_CAUSE (A2HRIC)
-*/
-#define MACREG_A2HRIC_BIT_TX_DONE 0x00000001 /* bit 0 */
-#define MACREG_A2HRIC_BIT_RX_RDY 0x00000002 /* bit 1 */
-#define MACREG_A2HRIC_BIT_OPC_DONE 0x00000004 /* bit 2 */
-#define MACREG_A2HRIC_BIT_MAC_EVENT 0x00000008 /* bit 3 */
-#define MACREG_A2HRIC_BIT_RX_PROBLEM 0x00000010 /* bit 4 */
-#define MACREG_A2HRIC_BIT_RADIO_OFF 0x00000020 /* bit 5 */
-#define MACREG_A2HRIC_BIT_RADIO_ON 0x00000040 /* bit 6 */
-#define MACREG_A2HRIC_BIT_RADAR_DETECT 0x00000080 /* bit 7 */
-#define MACREG_A2HRIC_BIT_ICV_ERROR 0x00000100 /* bit 8 */
-#define MACREG_A2HRIC_BIT_WEAKIV_ERROR 0x00000200 /* bit 9 */
-#define MACREG_A2HRIC_BIT_QUEUE_EMPTY BIT(10)
-#define MACREG_A2HRIC_BIT_QUEUE_FULL BIT(11)
-#define MACREG_A2HRIC_BIT_CHAN_SWITCH BIT(12) /* IEEE80211_DH */
-#define MACREG_A2HRIC_BIT_TX_WATCHDOG BIT(13)
-#define MACREG_A2HRIC_BA_WATCHDOG BIT(14)
-#define MACREG_A2HRIC_BIT_SSU_DONE BIT(16)
-#define MACREG_A2HRIC_CONSEC_TXFAIL BIT(17) /* 15 taken by ISR_TXACK */
-
-#define ISR_SRC_BITS ((MACREG_A2HRIC_BIT_RX_RDY) | \
- (MACREG_A2HRIC_BIT_TX_DONE) | \
- (MACREG_A2HRIC_BIT_OPC_DONE) | \
- (MACREG_A2HRIC_BIT_MAC_EVENT) | \
- (MACREG_A2HRIC_BIT_WEAKIV_ERROR) | \
- (MACREG_A2HRIC_BIT_ICV_ERROR) | \
- (MACREG_A2HRIC_BIT_SSU_DONE) | \
- (MACREG_A2HRIC_BIT_RADAR_DETECT) | \
- (MACREG_A2HRIC_BIT_CHAN_SWITCH) | \
- (MACREG_A2HRIC_BIT_TX_WATCHDOG) | \
- (MACREG_A2HRIC_BIT_QUEUE_EMPTY) | \
- (MACREG_A2HRIC_BA_WATCHDOG) | \
- (MACREG_A2HRIC_CONSEC_TXFAIL))
-
-#define MACREG_A2HRIC_BIT_MASK ISR_SRC_BITS
-
-/* Bit definitio for MACREG_REG_H2A_INTERRUPT_CAUSE (H2ARIC)
-*/
-#define MACREG_H2ARIC_BIT_PPA_READY 0x00000001 /* bit 0 */
-#define MACREG_H2ARIC_BIT_DOOR_BELL 0x00000002 /* bit 1 */
-#define MACREG_H2ARIC_BIT_PS 0x00000004 /* bit 2 */
-#define MACREG_H2ARIC_BIT_PSPOLL 0x00000008 /* bit 3 */
-#define ISR_RESET BIT(15)
-#define ISR_RESET_AP33 BIT(26)
-
-/* Data descriptor related constants
-*/
-#define EAGLE_RXD_CTRL_DRIVER_OWN 0x00
-#define EAGLE_RXD_CTRL_OS_OWN 0x04
-#define EAGLE_RXD_CTRL_DMA_OWN 0x80
-
-#define EAGLE_RXD_STATUS_IDLE 0x00
-#define EAGLE_RXD_STATUS_OK 0x01
-#define EAGLE_RXD_STATUS_MULTICAST_RX 0x02
-#define EAGLE_RXD_STATUS_BROADCAST_RX 0x04
-#define EAGLE_RXD_STATUS_FRAGMENT_RX 0x08
-
-#define EAGLE_TXD_STATUS_IDLE 0x00000000
-#define EAGLE_TXD_STATUS_USED 0x00000001
-#define EAGLE_TXD_STATUS_OK 0x00000001
-#define EAGLE_TXD_STATUS_OK_RETRY 0x00000002
-#define EAGLE_TXD_STATUS_OK_MORE_RETRY 0x00000004
-#define EAGLE_TXD_STATUS_MULTICAST_TX 0x00000008
-#define EAGLE_TXD_STATUS_BROADCAST_TX 0x00000010
-#define EAGLE_TXD_STATUS_FAILED_LINK_ERROR 0x00000020
-#define EAGLE_TXD_STATUS_FAILED_EXCEED_LIMIT 0x00000040
-#define EAGLE_TXD_STATUS_FAILED_AGING 0x00000080
-#define EAGLE_TXD_STATUS_FW_OWNED 0x80000000
-
-#define EAGLE_TXD_XMITCTRL_USE_RATEINFO 0x1
-#define EAGLE_TXD_XMITCTRL_DISABLE_AMPDU 0x2
-#define EAGLE_TXD_XMITCTRL_ENABLE_AMPDU 0x4
-#define EAGLE_TXD_XMITCTRL_USE_MC_RATE 0x8
-
-#define NBR_BYTES_FW_RX_PREPEND_LEN 2
-#define NBR_BYTES_FW_TX_PREPEND_LEN 2
-
-/* Antenna control
-*/
-#define ANTENNA_TX_4_AUTO 0
-#define ANTENNA_TX_2 3
-#define ANTENNA_RX_4_AUTO 0
-#define ANTENNA_RX_2 2
-
-/* Band related constants
-*/
-#define BAND_24_CHANNEL_NUM 14
-#define BAND_24_RATE_NUM 13
-#define BAND_50_CHANNEL_NUM 24
-#define BAND_50_RATE_NUM 8
-
-/* Misc
-*/
-#define WL_SEC_SLEEP(num_secs) mdelay(num_secs * 1000)
-#define WL_MSEC_SLEEP(num_milli_secs) mdelay(num_milli_secs)
-
-#define ENDIAN_SWAP32(_val) (cpu_to_le32(_val))
-#define ENDIAN_SWAP16(_val) (cpu_to_le16(_val))
-
-#define DECLARE_LOCK(l) spinlock_t l
-#define SPIN_LOCK_INIT(l) spin_lock_init(l)
-#define SPIN_LOCK(l) spin_lock(l)
-#define SPIN_UNLOCK(l) spin_unlock(l)
-#define SPIN_LOCK_IRQSAVE(l, f) spin_lock_irqsave(l, f)
-#define SPIN_UNLOCK_IRQRESTORE(l, f) spin_unlock_irqrestore(l, f)
-
-/* vif and station
-*/
-#define MAX_WEP_KEY_LEN 13
-#define NUM_WEP_KEYS 4
-#define MWL_MAX_TID 8
-#define MWL_VIF(_vif) ((struct mwl_vif *)&((_vif)->drv_priv))
-#define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
-#define MWL_STA(_sta) ((struct mwl_sta *)&((_sta)->drv_priv))
-
-/* TYPE DEFINITION
-*/
-
-enum {
- MWL8864 = 0,
- MWL8897,
- MWLUNKNOWN,
-};
-
-enum {
- AP_MODE_11AC = 0x10, /* generic 11ac indication mode */
- AP_MODE_2_4GHZ_11AC_MIXED = 0x17,
-};
-
-enum {
- AMPDU_NO_STREAM,
- AMPDU_STREAM_NEW,
- AMPDU_STREAM_IN_PROGRESS,
- AMPDU_STREAM_ACTIVE,
-};
-
-enum {
- IEEE_TYPE_MANAGEMENT = 0,
- IEEE_TYPE_CONTROL,
- IEEE_TYPE_DATA
-};
-
-struct mwl_chip_info {
- char *part_name;
- char *fw_image;
-};
-
-struct mwl_tx_pwr_tbl {
- u8 channel;
- u8 setcap;
- u16 tx_power[SYSADPT_TX_POWER_LEVEL_TOTAL];
- u8 cdd; /* 0: off, 1: on */
- u16 txantenna2;
-};
-
-struct mwl_hw_data {
- u32 fw_release_num; /* MajNbr:MinNbr:SubMin:PatchLevel */
- u8 hw_version; /* plain number indicating version */
- u8 host_interface; /* plain number of interface */
- u16 max_num_tx_desc; /* max number of TX descriptors */
- u16 max_num_mc_addr; /* max number multicast addresses */
- u16 num_antennas; /* number antennas used */
- u16 region_code; /* region (eg. 0x10 for USA FCC) */
- unsigned char mac_addr[ETH_ALEN]; /* well known -> AA:BB:CC:DD:EE:FF */
-};
-
-struct mwl_rate_info {
- u32 format:2; /* 0 = Legacy, 1 = 11n, 2 = 11ac */
- u32 stbc:1;
- u32 rsvd1:1;
- u32 bandwidth:2; /* 0 = 20 MHz, 1 = 40 MHz, 2 = 80 MHz */
- u32 short_gi:1; /* 0 = standard guard interval, 1 = short */
- u32 rsvd2:1;
- u32 rate_id_mcs:7;
- u32 preamble_type:1; /* Preambletype 0 = Long, 1 = Short; */
- u32 power_id:6;
- u32 adv_coding:1; /* ldpc */
- u32 bf:1;
- u32 ant_select:8; /* Bitmap to select one of the transmit antenna */
-} __packed;
-
-struct mwl_tx_desc {
- u8 data_rate;
- u8 tx_priority;
- u16 qos_ctrl;
- u32 pkt_ptr;
- u16 pkt_len;
- u8 dest_addr[ETH_ALEN];
- u32 pphys_next;
- u32 sap_pkt_info;
- struct mwl_rate_info rate_info;
- u8 type;
- u8 xmit_control; /* bit 0: use rateinfo, bit 1: disable ampdu */
- u16 reserved;
- u32 tcpack_sn;
- u32 tcpack_src_dst;
- struct sk_buff *psk_buff;
- struct mwl_tx_desc *pnext;
- u8 reserved1[2];
- u8 packet_info;
- u8 packet_id;
- u16 packet_len_and_retry;
- u16 packet_rate_info;
- u8 *sta_info;
- u32 status;
-} __packed;
-
-struct mwl_hw_rssi_info {
- u32 rssi_a:8;
- u32 rssi_b:8;
- u32 rssi_c:8;
- u32 rssi_d:8;
-} __packed;
-
-struct mwl_hw_noise_floor_info {
- u32 noise_floor_a:8;
- u32 noise_floor_b:8;
- u32 noise_floor_c:8;
- u32 noise_floor_d:8;
-} __packed;
-
-struct mwl_rxrate_info {
- u16 format:3; /* 0: 11a, 1: 11b, 2: 11n, 4: 11ac */
- u16 nss:2; /* number space spectrum */
- u16 bw:2; /* 0: ht20, 1: ht40, 2: ht80 */
- u16 gi:1; /* 0: long interval, 1: short interval*/
- u16 rt:8; /* 11a/11b: 1,2,5,11,22,6,9,12,18,24,36,48,54,72*/
-} __packed; /* 11n/11ac: MCS */
-
-struct mwl_rx_desc {
- u16 pkt_len; /* total length of received data */
- struct mwl_rxrate_info rate; /* receive rate information */
- u32 pphys_buff_data; /* physical address of payload data */
- u32 pphys_next; /* physical address of next RX desc */
- u16 qos_ctrl; /* received QosCtrl field variable */
- u16 ht_sig2; /* like name states */
- struct mwl_hw_rssi_info hw_rssi_info;
- struct mwl_hw_noise_floor_info hw_noise_floor_info;
- u8 noise_floor;
- u8 reserved[3];
- u8 rssi; /* received signal strengt indication */
- u8 status; /* status field containing USED bit */
- u8 channel; /* channel this pkt was received on */
- u8 rx_control; /* the control element of the desc */
- /* above are 32bits aligned and is same as FW, RxControl put at end
- * for sync
- */
- struct sk_buff *psk_buff; /* associated sk_buff for Linux */
- void *pbuff_data; /* virtual address of payload data */
- struct mwl_rx_desc *pnext; /* virtual address of next RX desc */
-} __packed;
-
-struct mwl_desc_data {
- dma_addr_t pphys_tx_ring; /* ptr to first TX desc (phys.) */
- struct mwl_tx_desc *ptx_ring; /* ptr to first TX desc (virt.) */
- struct mwl_tx_desc *pnext_tx_desc; /* next TX desc that can be used */
- struct mwl_tx_desc *pstale_tx_desc;/* the staled TX descriptor */
- dma_addr_t pphys_rx_ring; /* ptr to first RX desc (phys.) */
- struct mwl_rx_desc *prx_ring; /* ptr to first RX desc (virt.) */
- struct mwl_rx_desc *pnext_rx_desc; /* next RX desc that can be used */
- unsigned int wcb_base; /* FW base offset for registers */
- unsigned int rx_desc_write; /* FW descriptor write position */
- unsigned int rx_desc_read; /* FW descriptor read position */
- unsigned int rx_buf_size; /* length of the RX buffers */
-} __packed;
-
-struct mwl_locks {
- DECLARE_LOCK(xmit_lock); /* used to protect TX actions */
- DECLARE_LOCK(fwcmd_lock); /* used to protect FW commands */
- DECLARE_LOCK(stream_lock); /* used to protect stream */
-};
-
-struct mwl_ampdu_stream {
- struct ieee80211_sta *sta;
- u8 tid;
- u8 state;
- u8 idx;
-};
-
-struct mwl_priv {
- struct ieee80211_hw *hw;
- const struct firmware *fw_ucode;
- int chip_type;
- struct device_node *dt_node;
- struct device_node *pwr_node;
- bool disable_2g;
- bool disable_5g;
- int antenna_tx;
- int antenna_rx;
- struct mwl_tx_pwr_tbl tx_pwr_tbl[SYSADPT_MAX_NUM_CHANNELS];
- u32 cdd; /* 0: off, 1: on */
- u16 txantenna2;
- u8 powinited;
- u16 max_tx_pow[SYSADPT_TX_POWER_LEVEL_TOTAL]; /* max tx power (dBm) */
- u16 target_powers[SYSADPT_TX_POWER_LEVEL_TOTAL]; /* target powers */
- u8 cal_tbl[200];
- struct pci_dev *pdev;
- void *iobase0; /* MEM Base Address Register 0 */
- void *iobase1; /* MEM Base Address Register 1 */
- u32 next_bar_num;
- unsigned short *pcmd_buf; /* pointer to CmdBuf (virtual) */
- dma_addr_t pphys_cmd_buf; /* pointer to CmdBuf (physical) */
- bool in_send_cmd;
- int irq;
- struct mwl_hw_data hw_data; /* Adapter HW specific info */
- /* various descriptor data */
- struct mwl_desc_data desc_data[SYSADPT_NUM_OF_DESC_DATA];
- struct sk_buff_head txq[SYSADPT_NUM_OF_DESC_DATA];
- struct sk_buff_head delay_q;
- /* number of descriptors owned by fw at any one time */
- int fw_desc_cnt[SYSADPT_NUM_OF_DESC_DATA];
- struct mwl_locks locks; /* various spinlocks */
- struct tasklet_struct tx_task;
- struct tasklet_struct rx_task;
- int txq_limit;
- bool is_tx_schedule;
- int recv_limit;
- bool is_rx_schedule;
- s8 noise; /* Most recently reported noise in dBm */
- struct ieee80211_supported_band band_24;
- struct ieee80211_channel channels_24[BAND_24_CHANNEL_NUM];
- struct ieee80211_rate rates_24[BAND_24_RATE_NUM];
- struct ieee80211_supported_band band_50;
- struct ieee80211_channel channels_50[BAND_50_CHANNEL_NUM];
- struct ieee80211_rate rates_50[BAND_50_RATE_NUM];
- u32 ap_macids_supported;
- u32 sta_macids_supported;
- u32 macids_used;
- struct list_head vif_list; /* List of interfaces. */
- u32 running_bsses; /* bitmap of running BSSes */
- bool radio_on;
- bool radio_short_preamble;
- bool wmm_enabled;
- struct ieee80211_tx_queue_params wmm_params[SYSADPT_TX_WMM_QUEUES];
- /* Ampdu stream information */
- u8 num_ampdu_queues;
- struct mwl_ampdu_stream ampdu[SYSADPT_TX_AMPDU_QUEUES];
- struct work_struct watchdog_ba_handle;
-};
-
-struct beacon_info {
- bool valid;
- u16 cap_info;
- u8 b_rate_set[SYSADPT_MAX_DATA_RATES_G];
- u8 op_rate_set[SYSADPT_MAX_DATA_RATES_G];
- u8 ie_wmm_len; /* Keep WMM IE */
- u8 *ie_wmm_ptr;
- u8 ie_rsn_len; /* Keep WPA IE */
- u8 *ie_rsn_ptr;
- u8 ie_rsn48_len; /* Keep WPA2 IE */
- u8 *ie_rsn48_ptr;
- u8 ie_ht_len; /* Keep HT IE */
- u8 *ie_ht_ptr;
- u8 ie_list_ht[148];
- u8 ie_vht_len; /* Keep VHT IE */
- u8 *ie_vht_ptr;
- u8 ie_list_vht[24];
-};
-
-struct mwl_vif {
- struct list_head list;
- struct ieee80211_vif *vif;
- int macid; /* Firmware macid for this vif. */
- u16 seqno; /* Non AMPDU sequence number assigned by driver. */
- struct { /* Saved WEP keys */
- u8 enabled;
- u8 key[sizeof(struct ieee80211_key_conf) + MAX_WEP_KEY_LEN];
- } wep_key_conf[NUM_WEP_KEYS];
- u8 bssid[ETH_ALEN]; /* BSSID */
- u8 sta_mac[ETH_ALEN]; /* Station mac address */
- /* A flag to indicate is HW crypto is enabled for this bssid */
- bool is_hw_crypto_enabled;
- /* Indicate if this is station mode */
- bool is_sta;
- struct beacon_info beacon_info;
- u16 iv16;
- u32 iv32;
- s8 keyidx;
-};
-
-struct mwl_tx_info {
- u32 start_time;
- u32 pkts;
-};
-
-struct mwl_sta {
- u8 is_ampdu_allowed;
- struct mwl_tx_info tx_stats[MWL_MAX_TID];
- u16 iv16;
- u32 iv32;
-};
-
-/* DMA header used by firmware and hardware.
-*/
-struct mwl_dma_data {
- u16 fwlen;
- struct ieee80211_hdr wh;
- char data[0];
-} __packed;
-
-/* Transmission information to transmit a socket buffer.
- */
-struct mwl_tx_ctrl {
- u8 tx_priority;
- u16 qos_ctrl;
- u8 type;
- u8 xmit_control;
- u8 *sta_info;
- bool ccmp;
-} __packed;
-
-#endif /* _mwl_dev_h_ */
diff --git a/mwl_fwdl.h b/mwl_fwdl.h
deleted file mode 100644
index cad4056..0000000
--- a/mwl_fwdl.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/* Description: This file defines firmware download related functions.
-*/
-
-#ifndef _mwl_fwdl_h_
-#define _mwl_fwdl_h_
-
-#include <net/mac80211.h>
-
-/* PUBLIC FUNCTION DECLARATION
-*/
-int mwl_fwdl_download_firmware(struct ieee80211_hw *hw);
-
-#endif /* _mwl_fwdl_h_ */
diff --git a/mwl_mac80211.h b/mwl_mac80211.h
deleted file mode 100644
index 71fc4f8..0000000
--- a/mwl_mac80211.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/* Description: This file defines mac80211 related functions.
-*/
-
-#ifndef _mwl_mac80211_h_
-#define _mwl_mac80211_h_
-
-#include <linux/interrupt.h>
-#include <net/mac80211.h>
-
-/* PUBLIC FUNCTION DECLARATION
-*/
-
-struct ieee80211_ops *mwl_mac80211_get_ops(void);
-void mwl_mac80211_set_isr(irqreturn_t (*isr)(int irq, void *dev_id));
-
-#endif /* _mwl_mac80211_h_ */
diff --git a/mwl_rx.h b/mwl_rx.h
deleted file mode 100644
index 184ff31..0000000
--- a/mwl_rx.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/* Description: This file defines receive related functions.
-*/
-
-#ifndef _mwl_rx_h_
-#define _mwl_rx_h_
-
-/* PUBLIC FUNCTION DECLARATION
-*/
-
-int mwl_rx_init(struct ieee80211_hw *hw);
-void mwl_rx_deinit(struct ieee80211_hw *hw);
-void mwl_rx_recv(unsigned long data);
-
-#endif /* _mwl_rx_h_ */
diff --git a/mwl_tx.h b/mwl_tx.h
deleted file mode 100644
index 20a8772..0000000
--- a/mwl_tx.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-
-/* Description: This file defines transmit related functions.
-*/
-
-#ifndef _mwl_tx_h_
-#define _mwl_tx_h_
-
-/* PUBLIC FUNCTION DECLARATION
-*/
-
-int mwl_tx_init(struct ieee80211_hw *hw);
-void mwl_tx_deinit(struct ieee80211_hw *hw);
-void mwl_tx_xmit(struct ieee80211_hw *hw,
- int index,
- struct ieee80211_sta *sta,
- struct sk_buff *skb);
-void mwl_tx_done(unsigned long data);
-
-#endif /* _mwl_tx_h_ */
diff --git a/mwl_rx.c b/rx.c
index 7d813f3..34dafdf 100644
--- a/mwl_rx.c
+++ b/rx.c
@@ -1,31 +1,19 @@
/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
/* Description: This file implements receive related functions.
-*/
+ */
#include <linux/skbuff.h>
-#include "mwl_sysadpt.h"
-#include "mwl_dev.h"
-#include "mwl_debug.h"
-#include "mwl_rx.h"
-
-/* CONSTANTS AND MACROS
-*/
+#include "sysadpt.h"
+#include "dev.h"
+#include "rx.h"
#define MAX_NUM_RX_RING_BYTES (SYSADPT_MAX_NUM_RX_DESC * \
sizeof(struct mwl_rx_desc))
@@ -43,8 +31,7 @@
#define W836X_RSSI_OFFSET 8
-/* Receive rate information constants
-*/
+/* Receive rate information constants */
#define RX_RATE_INFO_FORMAT_11A 0
#define RX_RATE_INFO_FORMAT_11B 1
#define RX_RATE_INFO_FORMAT_11N 2
@@ -57,205 +44,8 @@
#define RX_RATE_INFO_LONG_INTERVAL 0
#define RX_RATE_INFO_SHORT_INTERVAL 1
-/* PRIVATE FUNCTION DECLARATION
-*/
-
-static int mwl_rx_ring_alloc(struct mwl_priv *priv);
-static int mwl_rx_ring_init(struct mwl_priv *priv);
-static void mwl_rx_ring_cleanup(struct mwl_priv *priv);
-static void mwl_rx_ring_free(struct mwl_priv *priv);
-static inline void mwl_rx_prepare_status(struct mwl_rx_desc *pdesc,
- struct ieee80211_rx_status *status);
-static inline struct mwl_vif *mwl_rx_find_vif_bss(struct list_head *vif_list,
- u8 *bssid);
-static inline void mwl_rx_remove_dma_header(struct sk_buff *skb, u16 qos);
-static int mwl_rx_refill(struct mwl_priv *priv, struct mwl_rx_desc *pdesc);
-
-/* PUBLIC FUNCTION DEFINITION
-*/
-
-int mwl_rx_init(struct ieee80211_hw *hw)
-{
- struct mwl_priv *priv;
- int rc;
-
- WLDBG_ENTER(DBG_LEVEL_4);
-
- BUG_ON(!hw);
- priv = hw->priv;
- BUG_ON(!priv);
-
- rc = mwl_rx_ring_alloc(priv);
- if (rc) {
- WLDBG_ERROR(DBG_LEVEL_4, "allocating RX ring failed");
- } else {
- rc = mwl_rx_ring_init(priv);
- if (rc) {
- mwl_rx_ring_free(priv);
- WLDBG_ERROR(DBG_LEVEL_4,
- "initializing RX ring failed");
- }
- }
-
- WLDBG_EXIT(DBG_LEVEL_4);
-
- return rc;
-}
-
-void mwl_rx_deinit(struct ieee80211_hw *hw)
-{
- struct mwl_priv *priv;
-
- WLDBG_ENTER(DBG_LEVEL_4);
-
- BUG_ON(!hw);
- priv = hw->priv;
- BUG_ON(!priv);
-
- mwl_rx_ring_cleanup(priv);
- mwl_rx_ring_free(priv);
-
- WLDBG_EXIT(DBG_LEVEL_4);
-}
-
-void mwl_rx_recv(unsigned long data)
-{
- struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
- struct mwl_priv *priv;
- struct mwl_rx_desc *curr_desc;
- int work_done = 0;
- struct sk_buff *prx_skb = NULL;
- int pkt_len;
- struct ieee80211_rx_status status;
- struct mwl_vif *mwl_vif = NULL;
- struct ieee80211_hdr *wh;
- u32 status_mask;
-
- WLDBG_ENTER(DBG_LEVEL_4);
-
- BUG_ON(!hw);
- priv = hw->priv;
- BUG_ON(!priv);
-
- curr_desc = priv->desc_data[0].pnext_rx_desc;
-
- if (!curr_desc) {
- status_mask = readl(priv->iobase1 +
- MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
- writel(status_mask | MACREG_A2HRIC_BIT_RX_RDY,
- priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
-
- priv->is_rx_schedule = false;
-
- WLDBG_EXIT_INFO(DBG_LEVEL_4, "busy or no receiving packets");
- return;
- }
-
- while ((curr_desc->rx_control == EAGLE_RXD_CTRL_DMA_OWN) &&
- (work_done < priv->recv_limit)) {
- prx_skb = curr_desc->psk_buff;
- if (!prx_skb)
- goto out;
- pci_unmap_single(priv->pdev,
- ENDIAN_SWAP32(curr_desc->pphys_buff_data),
- priv->desc_data[0].rx_buf_size,
- PCI_DMA_FROMDEVICE);
- pkt_len = curr_desc->pkt_len;
-
- if (skb_tailroom(prx_skb) < pkt_len) {
- WLDBG_PRINT("Critical error: %x %x %x %x",
- skb_tailroom(prx_skb), pkt_len,
- curr_desc, curr_desc->pbuff_data);
- dev_kfree_skb_any(prx_skb);
- goto out;
- }
-
- if (curr_desc->channel != hw->conf.chandef.chan->hw_value) {
- dev_kfree_skb_any(prx_skb);
- goto out;
- }
-
- mwl_rx_prepare_status(curr_desc, &status);
-
- priv->noise = -curr_desc->noise_floor;
-
- wh = &((struct mwl_dma_data *)prx_skb->data)->wh;
-
- if (ieee80211_has_protected(wh->frame_control)) {
- /* Check if hw crypto has been enabled for
- * this bss. If yes, set the status flags
- * accordingly
- */
- if (ieee80211_has_tods(wh->frame_control))
- mwl_vif = mwl_rx_find_vif_bss(&priv->vif_list,
- wh->addr1);
- else
- mwl_vif = mwl_rx_find_vif_bss(&priv->vif_list,
- wh->addr2);
-
- if (mwl_vif && mwl_vif->is_hw_crypto_enabled) {
- /* When MMIC ERROR is encountered
- * by the firmware, payload is
- * dropped and only 32 bytes of
- * mwl8k Firmware header is sent
- * to the host.
- *
- * We need to add four bytes of
- * key information. In it
- * MAC80211 expects keyidx set to
- * 0 for triggering Counter
- * Measure of MMIC failure.
- */
- if (status.flag & RX_FLAG_MMIC_ERROR) {
- struct mwl_dma_data *tr;
-
- tr = (struct mwl_dma_data *)
- prx_skb->data;
- memset((void *)&tr->data, 0, 4);
- pkt_len += 4;
- }
-
- if (!ieee80211_is_auth(wh->frame_control))
- status.flag |= RX_FLAG_IV_STRIPPED |
- RX_FLAG_DECRYPTED |
- RX_FLAG_MMIC_STRIPPED;
- }
- }
-
- skb_put(prx_skb, pkt_len);
- mwl_rx_remove_dma_header(prx_skb, curr_desc->qos_ctrl);
- memcpy(IEEE80211_SKB_RXCB(prx_skb), &status, sizeof(status));
- ieee80211_rx(hw, prx_skb);
-out:
- mwl_rx_refill(priv, curr_desc);
- curr_desc->rx_control = EAGLE_RXD_CTRL_DRIVER_OWN;
- curr_desc->qos_ctrl = 0;
- curr_desc = curr_desc->pnext;
- work_done++;
- }
-
- priv->desc_data[0].pnext_rx_desc = curr_desc;
-
- status_mask = readl(priv->iobase1 +
- MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
- writel(status_mask | MACREG_A2HRIC_BIT_RX_RDY,
- priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
-
- priv->is_rx_schedule = false;
-
- WLDBG_EXIT(DBG_LEVEL_4);
-}
-
-/* PRIVATE FUNCTION DEFINITION
-*/
-
static int mwl_rx_ring_alloc(struct mwl_priv *priv)
{
- WLDBG_ENTER_INFO(DBG_LEVEL_4, "allocating %i (0x%x) bytes",
- MAX_NUM_RX_RING_BYTES, MAX_NUM_RX_RING_BYTES);
-
- BUG_ON(!priv);
-
priv->desc_data[0].prx_ring =
(struct mwl_rx_desc *)
dma_alloc_coherent(&priv->pdev->dev,
@@ -264,17 +54,12 @@ static int mwl_rx_ring_alloc(struct mwl_priv *priv)
GFP_KERNEL);
if (!priv->desc_data[0].prx_ring) {
- WLDBG_ERROR(DBG_LEVEL_4, "can not alloc mem");
- WLDBG_EXIT_INFO(DBG_LEVEL_4, "no memory");
+ wiphy_err(priv->hw->wiphy, "can not alloc mem");
return -ENOMEM;
}
memset(priv->desc_data[0].prx_ring, 0x00, MAX_NUM_RX_RING_BYTES);
- WLDBG_EXIT_INFO(DBG_LEVEL_4, "RX ring vaddr: 0x%x paddr: 0x%x",
- priv->desc_data[0].prx_ring,
- priv->desc_data[0].pphys_rx_ring);
-
return 0;
}
@@ -283,9 +68,6 @@ static int mwl_rx_ring_init(struct mwl_priv *priv)
int curr_desc;
struct mwl_desc_data *desc;
- WLDBG_ENTER_INFO(DBG_LEVEL_4, "initializing %i descriptors",
- SYSADPT_MAX_NUM_RX_DESC);
-
desc = &priv->desc_data[0];
if (desc->prx_ring) {
@@ -298,10 +80,8 @@ static int mwl_rx_ring_init(struct mwl_priv *priv)
if (skb_linearize(CURR_RXD.psk_buff)) {
dev_kfree_skb_any(CURR_RXD.psk_buff);
- WLDBG_ERROR(DBG_LEVEL_4,
- "need linearize memory");
- WLDBG_EXIT_INFO(DBG_LEVEL_4,
- "no suitable memory");
+ wiphy_err(priv->hw->wiphy,
+ "need linearize memory");
return -ENOMEM;
}
@@ -317,57 +97,37 @@ static int mwl_rx_ring_init(struct mwl_priv *priv)
dma_addr_t dma;
u32 val;
- CURR_RXD.pkt_len = SYSADPT_MAX_AGGR_SIZE;
+ CURR_RXD.pkt_len =
+ cpu_to_le16(SYSADPT_MAX_AGGR_SIZE);
CURR_RXD.pbuff_data = CURR_RXD.psk_buff->data;
dma = pci_map_single(priv->pdev,
CURR_RXD.psk_buff->data,
desc->rx_buf_size,
PCI_DMA_FROMDEVICE);
CURR_RXD.pphys_buff_data =
- ENDIAN_SWAP32(dma);
+ cpu_to_le32(dma);
CURR_RXD.pnext = &NEXT_RXD;
val = (u32)desc->pphys_rx_ring +
((curr_desc + 1) *
sizeof(struct mwl_rx_desc));
CURR_RXD.pphys_next =
- ENDIAN_SWAP32(val);
- WLDBG_INFO(DBG_LEVEL_4,
- "rxdesc:%i 0x%x(%i) 0x%x(%i)",
- curr_desc,
- EAGLE_TXD_STATUS_IDLE,
- EAGLE_TXD_STATUS_IDLE,
- desc->rx_buf_size,
- desc->rx_buf_size);
- WLDBG_INFO(DBG_LEVEL_4,
- "rxdesc: %i vnext: 0x%p pnext: 0x%x",
- curr_desc,
- CURR_RXD.pnext,
- ENDIAN_SWAP32(CURR_RXD.pphys_next));
+ cpu_to_le32(val);
} else {
- WLDBG_ERROR(DBG_LEVEL_4,
- "rxdesc %i: no skbuff available",
- curr_desc);
- WLDBG_EXIT_INFO(DBG_LEVEL_4,
- "no socket buffer");
+ wiphy_err(priv->hw->wiphy,
+ "rxdesc %i: no skbuff available",
+ curr_desc);
return -ENOMEM;
}
}
LAST_RXD.pphys_next =
- ENDIAN_SWAP32((u32)desc->pphys_rx_ring);
+ cpu_to_le32((u32)desc->pphys_rx_ring);
LAST_RXD.pnext = &FIRST_RXD;
priv->desc_data[0].pnext_rx_desc = &FIRST_RXD;
- WLDBG_EXIT_INFO(DBG_LEVEL_4,
- "last rxdesc vnext:0x%p pnext:0x%x vfirst 0x%x",
- LAST_RXD.pnext,
- ENDIAN_SWAP32(LAST_RXD.pphys_next),
- desc->pnext_rx_desc);
-
return 0;
}
- WLDBG_ERROR(DBG_LEVEL_4, "no valid RX mem");
- WLDBG_EXIT_INFO(DBG_LEVEL_4, "no valid RX mem");
+ wiphy_err(priv->hw->wiphy, "no valid RX mem");
return -ENOMEM;
}
@@ -376,10 +136,6 @@ static void mwl_rx_ring_cleanup(struct mwl_priv *priv)
{
int curr_desc;
- WLDBG_ENTER(DBG_LEVEL_4);
-
- BUG_ON(!priv);
-
if (priv->desc_data[0].prx_ring) {
for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_RX_DESC;
curr_desc++) {
@@ -393,33 +149,27 @@ static void mwl_rx_ring_cleanup(struct mwl_priv *priv)
skb_shinfo(CURR_RXD.psk_buff)->frag_list = NULL;
pci_unmap_single(priv->pdev,
- ENDIAN_SWAP32
+ le32_to_cpu
(CURR_RXD.pphys_buff_data),
priv->desc_data[0].rx_buf_size,
PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(CURR_RXD.psk_buff);
- WLDBG_INFO(DBG_LEVEL_4,
+ wiphy_info(priv->hw->wiphy,
"unmapped+free'd %i 0x%p 0x%x %i",
curr_desc, CURR_RXD.pbuff_data,
- ENDIAN_SWAP32(CURR_RXD.pphys_buff_data),
+ le32_to_cpu(CURR_RXD.pphys_buff_data),
priv->desc_data[0].rx_buf_size);
CURR_RXD.pbuff_data = NULL;
CURR_RXD.psk_buff = NULL;
}
}
-
- WLDBG_EXIT(DBG_LEVEL_4);
}
static void mwl_rx_ring_free(struct mwl_priv *priv)
{
- WLDBG_ENTER(DBG_LEVEL_4);
-
- BUG_ON(!priv);
-
if (priv->desc_data[0].prx_ring) {
mwl_rx_ring_cleanup(priv);
@@ -432,43 +182,45 @@ static void mwl_rx_ring_free(struct mwl_priv *priv)
}
priv->desc_data[0].pnext_rx_desc = NULL;
-
- WLDBG_EXIT(DBG_LEVEL_4);
}
static inline void mwl_rx_prepare_status(struct mwl_rx_desc *pdesc,
struct ieee80211_rx_status *status)
{
- WLDBG_ENTER(DBG_LEVEL_4);
-
- BUG_ON(!pdesc);
- BUG_ON(!status);
+ u16 rate, format, nss, bw, gi, rt;
memset(status, 0, sizeof(*status));
status->signal = -(pdesc->rssi + W836X_RSSI_OFFSET);
- switch (pdesc->rate.format) {
+ rate = le16_to_cpu(pdesc->rate);
+ format = rate & MWL_RX_RATE_FORMAT_MASK;
+ nss = (rate & MWL_RX_RATE_NSS_MASK) >> MWL_RX_RATE_NSS_SHIFT;
+ bw = (rate & MWL_RX_RATE_BW_MASK) >> MWL_RX_RATE_BW_SHIFT;
+ gi = (rate & MWL_RX_RATE_GI_MASK) >> MWL_RX_RATE_GI_SHIFT;
+ rt = (rate & MWL_RX_RATE_RT_MASK) >> MWL_RX_RATE_RT_SHIFT;
+
+ switch (format) {
case RX_RATE_INFO_FORMAT_11N:
status->flag |= RX_FLAG_HT;
- if (pdesc->rate.bw == RX_RATE_INFO_HT40)
+ if (bw == RX_RATE_INFO_HT40)
status->flag |= RX_FLAG_40MHZ;
- if (pdesc->rate.gi == RX_RATE_INFO_SHORT_INTERVAL)
+ if (gi == RX_RATE_INFO_SHORT_INTERVAL)
status->flag |= RX_FLAG_SHORT_GI;
break;
case RX_RATE_INFO_FORMAT_11AC:
status->flag |= RX_FLAG_VHT;
- if (pdesc->rate.bw == RX_RATE_INFO_HT40)
+ if (bw == RX_RATE_INFO_HT40)
status->flag |= RX_FLAG_40MHZ;
- if (pdesc->rate.bw == RX_RATE_INFO_HT80)
+ if (bw == RX_RATE_INFO_HT80)
status->vht_flag |= RX_VHT_FLAG_80MHZ;
- if (pdesc->rate.gi == RX_RATE_INFO_SHORT_INTERVAL)
+ if (gi == RX_RATE_INFO_SHORT_INTERVAL)
status->flag |= RX_FLAG_SHORT_GI;
- status->vht_nss = (pdesc->rate.nss + 1);
+ status->vht_nss = (nss + 1);
break;
}
- status->rate_idx = pdesc->rate.rt;
+ status->rate_idx = rt;
if (pdesc->channel > BAND_24_CHANNEL_NUM) {
status->band = IEEE80211_BAND_5GHZ;
@@ -506,24 +258,27 @@ static inline void mwl_rx_prepare_status(struct mwl_rx_desc *pdesc,
}
}
}
-
- WLDBG_EXIT(DBG_LEVEL_4);
}
-static inline struct mwl_vif *mwl_rx_find_vif_bss(struct list_head *vif_list,
+static inline struct mwl_vif *mwl_rx_find_vif_bss(struct mwl_priv *priv,
u8 *bssid)
{
struct mwl_vif *mwl_vif;
+ unsigned long flags;
- list_for_each_entry(mwl_vif, vif_list, list) {
- if (memcmp(bssid, mwl_vif->bssid, ETH_ALEN) == 0)
+ spin_lock_irqsave(&priv->vif_lock, flags);
+ list_for_each_entry(mwl_vif, &priv->vif_list, list) {
+ if (memcmp(bssid, mwl_vif->bssid, ETH_ALEN) == 0) {
+ spin_unlock_irqrestore(&priv->vif_lock, flags);
return mwl_vif;
+ }
}
+ spin_unlock_irqrestore(&priv->vif_lock, flags);
return NULL;
}
-static inline void mwl_rx_remove_dma_header(struct sk_buff *skb, u16 qos)
+static inline void mwl_rx_remove_dma_header(struct sk_buff *skb, __le16 qos)
{
struct mwl_dma_data *tr;
int hdrlen;
@@ -534,7 +289,7 @@ static inline void mwl_rx_remove_dma_header(struct sk_buff *skb, u16 qos)
if (hdrlen != sizeof(tr->wh)) {
if (ieee80211_is_data_qos(tr->wh.frame_control)) {
memmove(tr->data - hdrlen, &tr->wh, hdrlen - 2);
- *((u16 *)(tr->data - 2)) = qos;
+ *((__le16 *)(tr->data - 2)) = qos;
} else {
memmove(tr->data - hdrlen, &tr->wh, hdrlen);
}
@@ -546,11 +301,6 @@ static inline void mwl_rx_remove_dma_header(struct sk_buff *skb, u16 qos)
static int mwl_rx_refill(struct mwl_priv *priv, struct mwl_rx_desc *pdesc)
{
- WLDBG_ENTER(DBG_LEVEL_4);
-
- BUG_ON(!priv);
- BUG_ON(!pdesc);
-
pdesc->psk_buff = dev_alloc_skb(priv->desc_data[0].rx_buf_size);
if (!pdesc->psk_buff)
@@ -558,7 +308,7 @@ static int mwl_rx_refill(struct mwl_priv *priv, struct mwl_rx_desc *pdesc)
if (skb_linearize(pdesc->psk_buff)) {
dev_kfree_skb_any(pdesc->psk_buff);
- WLDBG_ERROR(DBG_LEVEL_4, "need linearize memory");
+ wiphy_err(priv->hw->wiphy, "need linearize memory");
goto nomem;
}
@@ -569,21 +319,168 @@ static int mwl_rx_refill(struct mwl_priv *priv, struct mwl_rx_desc *pdesc)
pdesc->channel = 0x00;
pdesc->rssi = 0x00;
- pdesc->pkt_len = priv->desc_data[0].rx_buf_size;
+ pdesc->pkt_len = cpu_to_le16(priv->desc_data[0].rx_buf_size);
pdesc->pbuff_data = pdesc->psk_buff->data;
pdesc->pphys_buff_data =
- ENDIAN_SWAP32(pci_map_single(priv->pdev,
- pdesc->psk_buff->data,
- priv->desc_data[0].rx_buf_size,
- PCI_DMA_BIDIRECTIONAL));
-
- WLDBG_EXIT(DBG_LEVEL_4);
+ cpu_to_le32(pci_map_single(priv->pdev,
+ pdesc->psk_buff->data,
+ priv->desc_data[0].rx_buf_size,
+ PCI_DMA_BIDIRECTIONAL));
return 0;
nomem:
- WLDBG_EXIT_INFO(DBG_LEVEL_4, "no memory");
+ wiphy_err(priv->hw->wiphy, "no memory");
return -ENOMEM;
}
+
+int mwl_rx_init(struct ieee80211_hw *hw)
+{
+ struct mwl_priv *priv;
+ int rc;
+
+ priv = hw->priv;
+
+ rc = mwl_rx_ring_alloc(priv);
+ if (rc) {
+ wiphy_err(hw->wiphy, "allocating RX ring failed");
+ } else {
+ rc = mwl_rx_ring_init(priv);
+ if (rc) {
+ mwl_rx_ring_free(priv);
+ wiphy_err(hw->wiphy,
+ "initializing RX ring failed");
+ }
+ }
+
+ return rc;
+}
+
+void mwl_rx_deinit(struct ieee80211_hw *hw)
+{
+ struct mwl_priv *priv;
+
+ priv = hw->priv;
+
+ mwl_rx_ring_cleanup(priv);
+ mwl_rx_ring_free(priv);
+}
+
+void mwl_rx_recv(unsigned long data)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+ struct mwl_priv *priv;
+ struct mwl_rx_desc *curr_desc;
+ int work_done = 0;
+ struct sk_buff *prx_skb = NULL;
+ int pkt_len;
+ struct ieee80211_rx_status status;
+ struct mwl_vif *mwl_vif = NULL;
+ struct ieee80211_hdr *wh;
+ u32 status_mask;
+
+ priv = hw->priv;
+
+ curr_desc = priv->desc_data[0].pnext_rx_desc;
+
+ if (!curr_desc) {
+ status_mask = readl(priv->iobase1 +
+ MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
+ writel(status_mask | MACREG_A2HRIC_BIT_RX_RDY,
+ priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
+
+ priv->is_rx_schedule = false;
+
+ wiphy_warn(hw->wiphy, "busy or no receiving packets");
+ return;
+ }
+
+ while ((curr_desc->rx_control == EAGLE_RXD_CTRL_DMA_OWN) &&
+ (work_done < priv->recv_limit)) {
+ prx_skb = curr_desc->psk_buff;
+ if (!prx_skb)
+ goto out;
+ pci_unmap_single(priv->pdev,
+ le32_to_cpu(curr_desc->pphys_buff_data),
+ priv->desc_data[0].rx_buf_size,
+ PCI_DMA_FROMDEVICE);
+ pkt_len = le16_to_cpu(curr_desc->pkt_len);
+
+ if (skb_tailroom(prx_skb) < pkt_len) {
+ dev_kfree_skb_any(prx_skb);
+ goto out;
+ }
+
+ if (curr_desc->channel != hw->conf.chandef.chan->hw_value) {
+ dev_kfree_skb_any(prx_skb);
+ goto out;
+ }
+
+ mwl_rx_prepare_status(curr_desc, &status);
+
+ priv->noise = -curr_desc->noise_floor;
+
+ wh = &((struct mwl_dma_data *)prx_skb->data)->wh;
+
+ if (ieee80211_has_protected(wh->frame_control)) {
+ /* Check if hw crypto has been enabled for
+ * this bss. If yes, set the status flags
+ * accordingly
+ */
+ if (ieee80211_has_tods(wh->frame_control))
+ mwl_vif = mwl_rx_find_vif_bss(priv, wh->addr1);
+ else
+ mwl_vif = mwl_rx_find_vif_bss(priv, wh->addr2);
+
+ if (mwl_vif && mwl_vif->is_hw_crypto_enabled) {
+ /* When MMIC ERROR is encountered
+ * by the firmware, payload is
+ * dropped and only 32 bytes of
+ * mwl8k Firmware header is sent
+ * to the host.
+ *
+ * We need to add four bytes of
+ * key information. In it
+ * MAC80211 expects keyidx set to
+ * 0 for triggering Counter
+ * Measure of MMIC failure.
+ */
+ if (status.flag & RX_FLAG_MMIC_ERROR) {
+ struct mwl_dma_data *tr;
+
+ tr = (struct mwl_dma_data *)
+ prx_skb->data;
+ memset((void *)&tr->data, 0, 4);
+ pkt_len += 4;
+ }
+
+ if (!ieee80211_is_auth(wh->frame_control))
+ status.flag |= RX_FLAG_IV_STRIPPED |
+ RX_FLAG_DECRYPTED |
+ RX_FLAG_MMIC_STRIPPED;
+ }
+ }
+
+ skb_put(prx_skb, pkt_len);
+ mwl_rx_remove_dma_header(prx_skb, curr_desc->qos_ctrl);
+ memcpy(IEEE80211_SKB_RXCB(prx_skb), &status, sizeof(status));
+ ieee80211_rx(hw, prx_skb);
+out:
+ mwl_rx_refill(priv, curr_desc);
+ curr_desc->rx_control = EAGLE_RXD_CTRL_DRIVER_OWN;
+ curr_desc->qos_ctrl = 0;
+ curr_desc = curr_desc->pnext;
+ work_done++;
+ }
+
+ priv->desc_data[0].pnext_rx_desc = curr_desc;
+
+ status_mask = readl(priv->iobase1 +
+ MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
+ writel(status_mask | MACREG_A2HRIC_BIT_RX_RDY,
+ priv->iobase1 + MACREG_REG_A2H_INTERRUPT_STATUS_MASK);
+
+ priv->is_rx_schedule = false;
+}
diff --git a/rx.h b/rx.h
new file mode 100644
index 0000000..a4d2478
--- /dev/null
+++ b/rx.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Description: This file defines receive related functions.
+ */
+
+#ifndef _mwl_rx_h_
+#define _mwl_rx_h_
+
+int mwl_rx_init(struct ieee80211_hw *hw);
+void mwl_rx_deinit(struct ieee80211_hw *hw);
+void mwl_rx_recv(unsigned long data);
+
+#endif /* _mwl_rx_h_ */
diff --git a/mwl_sysadpt.h b/sysadpt.h
index 1b17ec0..eb6fa86 100644
--- a/mwl_sysadpt.h
+++ b/sysadpt.h
@@ -1,28 +1,17 @@
/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
/* Description: This file defines system adaptation related information.
-*/
+ */
#ifndef _mwl_sysadpt_h_
#define _mwl_sysadpt_h_
-/* CONSTANTS AND MACROS
-*/
-
#define SYSADPT_MAX_NUM_CHANNELS 64
#define SYSADPT_MAX_DATA_RATES_G 14
@@ -53,12 +42,20 @@
#define SYSADPT_RECEIVE_LIMIT 64
-#define SYSADPT_MAX_AGGR_SIZE 4096
+#define SYSADPT_MAX_AGGR_SIZE 8192
#define SYSADPT_MIN_BYTES_HEADROOM 64
#define SYSADPT_AMPDU_PACKET_THRESHOLD 64
+#define SYSADPT_AMSDU_MAX_SIZE 3300
+
+#define SYSADPT_AMSDU_ALLOW_SIZE 1540
+
+#define SYSADPT_AMSDU_FLUSH_TIME 500
+
+#define SYSADPT_AMSDU_PACKET_THRESHOLD 10
+
#define SYSADPT_MAX_TID 8
#endif /* _mwl_sysadpt_h_ */
diff --git a/test/hostapd.conf.1.multi_bssid b/test/hostapd.conf.1.multi_bssid
index a2845b3..228ba1c 100644
--- a/test/hostapd.conf.1.multi_bssid
+++ b/test/hostapd.conf.1.multi_bssid
@@ -10,7 +10,7 @@ wmm_enabled=1
ieee80211n=1
ht_capab=[LDPC][SHORT-GI-20][SHORT-GI-40]
ieee80211ac=1
-vht_capab=[RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
+vht_capab=[RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
bss=wlan0_0
ssid=mwlwifi_ap_tset2
wpa=2
diff --git a/test/hostapd.conf.1.open b/test/hostapd.conf.1.open
index 562b111..d5cc39d 100644
--- a/test/hostapd.conf.1.open
+++ b/test/hostapd.conf.1.open
@@ -10,5 +10,5 @@ wmm_enabled=1
ieee80211n=1
ht_capab=[LDPC][SHORT-GI-20][SHORT-GI-40]
ieee80211ac=1
-vht_capab=[RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
+vht_capab=[RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
diff --git a/test/hostapd.conf.36.multi_bssid b/test/hostapd.conf.36.multi_bssid
index da0a5fe..0e5492d 100644
--- a/test/hostapd.conf.36.multi_bssid
+++ b/test/hostapd.conf.36.multi_bssid
@@ -10,7 +10,7 @@ wmm_enabled=1
ieee80211n=1
ht_capab=[LDPC][SHORT-GI-20][SHORT-GI-40]
ieee80211ac=1
-vht_capab=[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
+vht_capab=[MAX-MPDU-7991][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
bss=wlan1_0
ssid=mwlwifi_ap_tset2
wpa=2
diff --git a/test/hostapd.conf.36.open b/test/hostapd.conf.36.open
index 08cd7f8..842a1cb 100644
--- a/test/hostapd.conf.36.open
+++ b/test/hostapd.conf.36.open
@@ -10,5 +10,5 @@ wmm_enabled=1
ieee80211n=1
ht_capab=[LDPC][SHORT-GI-20][SHORT-GI-40]
ieee80211ac=1
-vht_capab=[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
+vht_capab=[MAX-MPDU-7991][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
diff --git a/test/hostapd.conf.36.open.80mhz b/test/hostapd.conf.36.open.80mhz
index 8310bba..5d094f2 100644
--- a/test/hostapd.conf.36.open.80mhz
+++ b/test/hostapd.conf.36.open.80mhz
@@ -10,7 +10,7 @@ wmm_enabled=1
ieee80211n=1
ht_capab=[LDPC][HT40+][SHORT-GI-20][SHORT-GI-40]
ieee80211ac=1
-vht_capab=[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
+vht_capab=[MAX-MPDU-7991][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
vht_oper_chwidth=1
vht_oper_centr_freq_seg0_idx=42
diff --git a/test/hostapd.conf.36.wpa2pskaes b/test/hostapd.conf.36.wpa2pskaes
index 4bf4061..cf60121 100644
--- a/test/hostapd.conf.36.wpa2pskaes
+++ b/test/hostapd.conf.36.wpa2pskaes
@@ -14,5 +14,5 @@ wmm_enabled=1
ieee80211n=1
ht_capab=[LDPC][SHORT-GI-20][SHORT-GI-40]
ieee80211ac=1
-vht_capab=[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
+vht_capab=[MAX-MPDU-7991][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
diff --git a/test/hostapd.conf.36.wpa2pskaes.80mhz b/test/hostapd.conf.36.wpa2pskaes.80mhz
index 5ab66a7..492fc17 100644
--- a/test/hostapd.conf.36.wpa2pskaes.80mhz
+++ b/test/hostapd.conf.36.wpa2pskaes.80mhz
@@ -14,7 +14,7 @@ wmm_enabled=1
ieee80211n=1
ht_capab=[LDPC][HT40+][SHORT-GI-20][SHORT-GI-40]
ieee80211ac=1
-vht_capab=[MAX-MPDU-11454][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MU-BEAMFORMER][MU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
+vht_capab=[MAX-MPDU-7991][RXLDPC][SHORT-GI-80][RX-STBC-1][SU-BEAMFORMER][SU-BEAMFORMEE][MAX-A-MPDU-LEN-EXP7][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]
vht_oper_chwidth=1
vht_oper_centr_freq_seg0_idx=42
diff --git a/test/wpa_supplicant.conf.open b/test/wpa_supplicant.conf.open
index d7677b9..d7677b9 100755..100644
--- a/test/wpa_supplicant.conf.open
+++ b/test/wpa_supplicant.conf.open
diff --git a/test/wpa_supplicant.conf.psk b/test/wpa_supplicant.conf.psk
index ce154a6..ce154a6 100755..100644
--- a/test/wpa_supplicant.conf.psk
+++ b/test/wpa_supplicant.conf.psk
diff --git a/mwl_tx.c b/tx.c
index 3bd1979..57b6dd4 100644
--- a/mwl_tx.c
+++ b/tx.c
@@ -1,33 +1,21 @@
/*
-* Copyright (c) 2006-2015 Marvell International Ltd.
-*
-* Permission to use, copy, modify, and/or distribute this software for any
-* purpose with or without fee is hereby granted, provided that the above
-* copyright notice and this permission notice appear in all copies.
-*
-* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
-* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
/* Description: This file implements transmit related functions.
-*/
+ */
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include "mwl_sysadpt.h"
-#include "mwl_dev.h"
-#include "mwl_debug.h"
-#include "mwl_fwcmd.h"
-#include "mwl_tx.h"
-
-/* CONSTANTS AND MACROS
-*/
+#include "sysadpt.h"
+#include "dev.h"
+#include "fwcmd.h"
+#include "tx.h"
#define MAX_NUM_TX_RING_BYTES (SYSADPT_MAX_NUM_TX_DESC * \
sizeof(struct mwl_tx_desc))
@@ -53,8 +41,7 @@
(iv32)++; \
}
-/* Transmit rate information constants
-*/
+/* Transmit rate information constants */
#define TX_RATE_FORMAT_LEGACY 0
#define TX_RATE_FORMAT_11N 1
#define TX_RATE_FORMAT_11AC 2
@@ -66,55 +53,420 @@
#define TX_RATE_INFO_STD_GI 0
#define TX_RATE_INFO_SHORT_GI 1
-/* PRIVATE FUNCTION DECLARATION
-*/
+enum {
+ IEEE_TYPE_MANAGEMENT = 0,
+ IEEE_TYPE_CONTROL,
+ IEEE_TYPE_DATA
+};
+
+static int mwl_tx_ring_alloc(struct mwl_priv *priv)
+{
+ int num;
+ u8 *mem;
+
+ mem = (u8 *)dma_alloc_coherent(&priv->pdev->dev,
+ MAX_NUM_TX_RING_BYTES * SYSADPT_NUM_OF_DESC_DATA,
+ &priv->desc_data[0].pphys_tx_ring, GFP_KERNEL);
+
+ if (!mem) {
+ wiphy_err(priv->hw->wiphy, "can not alloc mem");
+ return -ENOMEM;
+ }
+
+ for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
+ priv->desc_data[num].ptx_ring = (struct mwl_tx_desc *)
+ (mem + num * MAX_NUM_TX_RING_BYTES);
+
+ priv->desc_data[num].pphys_tx_ring = (dma_addr_t)
+ ((u32)priv->desc_data[0].pphys_tx_ring +
+ num * MAX_NUM_TX_RING_BYTES);
+
+ memset(priv->desc_data[num].ptx_ring, 0x00,
+ MAX_NUM_TX_RING_BYTES);
+ }
+
+ return 0;
+}
+
+static int mwl_tx_ring_init(struct mwl_priv *priv)
+{
+ int curr_desc;
+ struct mwl_desc_data *desc;
+ int num;
+
+ for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
+ skb_queue_head_init(&priv->txq[num]);
+ priv->fw_desc_cnt[num] = 0;
+
+ desc = &priv->desc_data[num];
+
+ if (desc->ptx_ring) {
+ for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_TX_DESC;
+ curr_desc++) {
+ CURR_TXD(num).status =
+ cpu_to_le32(EAGLE_TXD_STATUS_IDLE);
+ CURR_TXD(num).pnext = &NEXT_TXD(num);
+ CURR_TXD(num).pphys_next =
+ cpu_to_le32((u32)desc->pphys_tx_ring +
+ ((curr_desc + 1) *
+ sizeof(struct mwl_tx_desc)));
+ }
+ LAST_TXD(num).pnext = &FIRST_TXD(num);
+ LAST_TXD(num).pphys_next =
+ cpu_to_le32((u32)desc->pphys_tx_ring);
+ desc->pstale_tx_desc = &FIRST_TXD(num);
+ desc->pnext_tx_desc = &FIRST_TXD(num);
+ } else {
+ wiphy_err(priv->hw->wiphy, "no valid TX mem");
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+static void mwl_tx_ring_cleanup(struct mwl_priv *priv)
+{
+ int cleaned_tx_desc = 0;
+ int curr_desc;
+ int num;
+
+ for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
+ skb_queue_purge(&priv->txq[num]);
+ priv->fw_desc_cnt[num] = 0;
+ if (priv->desc_data[num].ptx_ring) {
+ for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_TX_DESC;
+ curr_desc++) {
+ if (!CURR_TXD(num).psk_buff)
+ continue;
+
+ wiphy_info(priv->hw->wiphy,
+ "unmapped and free'd %i 0x%p 0x%x",
+ curr_desc,
+ CURR_TXD(num).psk_buff->data,
+ le32_to_cpu(
+ CURR_TXD(num).pkt_ptr));
+ pci_unmap_single(priv->pdev,
+ le32_to_cpu(
+ CURR_TXD(num).pkt_ptr),
+ CURR_TXD(num).psk_buff->len,
+ PCI_DMA_TODEVICE);
+ dev_kfree_skb_any(CURR_TXD(num).psk_buff);
+ CURR_TXD(num).status =
+ cpu_to_le32(EAGLE_TXD_STATUS_IDLE);
+ CURR_TXD(num).psk_buff = NULL;
+ CURR_TXD(num).pkt_ptr = 0;
+ CURR_TXD(num).pkt_len = 0;
+ cleaned_tx_desc++;
+ }
+ }
+ }
+
+ wiphy_info(priv->hw->wiphy, "cleaned %i TX descr", cleaned_tx_desc);
+}
+
+static void mwl_tx_ring_free(struct mwl_priv *priv)
+{
+ int num;
+
+ if (priv->desc_data[0].ptx_ring) {
+ dma_free_coherent(&priv->pdev->dev,
+ MAX_NUM_TX_RING_BYTES *
+ SYSADPT_NUM_OF_DESC_DATA,
+ priv->desc_data[0].ptx_ring,
+ priv->desc_data[0].pphys_tx_ring);
+ }
+
+ for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
+ if (priv->desc_data[num].ptx_ring)
+ priv->desc_data[num].ptx_ring = NULL;
+ priv->desc_data[num].pstale_tx_desc = NULL;
+ priv->desc_data[num].pnext_tx_desc = NULL;
+ }
+}
-static int mwl_tx_ring_alloc(struct mwl_priv *priv);
-static int mwl_tx_ring_init(struct mwl_priv *priv);
-static void mwl_tx_ring_cleanup(struct mwl_priv *priv);
-static void mwl_tx_ring_free(struct mwl_priv *priv);
static inline void mwl_tx_add_dma_header(struct mwl_priv *priv,
struct sk_buff *skb,
int head_pad,
- int tail_pad);
+ int tail_pad)
+{
+ struct ieee80211_hdr *wh;
+ int hdrlen;
+ int reqd_hdrlen;
+ struct mwl_dma_data *tr;
+
+ /* Add a firmware DMA header; the firmware requires that we
+ * present a 2-byte payload length followed by a 4-address
+ * header (without QoS field), followed (optionally) by any
+ * WEP/ExtIV header (but only filled in for CCMP).
+ */
+ wh = (struct ieee80211_hdr *)skb->data;
+
+ hdrlen = ieee80211_hdrlen(wh->frame_control);
+
+ reqd_hdrlen = sizeof(*tr) + head_pad;
+
+ if (hdrlen != reqd_hdrlen)
+ skb_push(skb, reqd_hdrlen - hdrlen);
+
+ if (ieee80211_is_data_qos(wh->frame_control))
+ hdrlen -= IEEE80211_QOS_CTL_LEN;
+
+ tr = (struct mwl_dma_data *)skb->data;
+
+ if (wh != &tr->wh)
+ memmove(&tr->wh, wh, hdrlen);
+
+ if (hdrlen != sizeof(tr->wh))
+ memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
+
+ /* Firmware length is the length of the fully formed "802.11
+ * payload". That is, everything except for the 802.11 header.
+ * This includes all crypto material including the MIC.
+ */
+ tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
+}
+
static inline void mwl_tx_encapsulate_frame(struct mwl_priv *priv,
- struct sk_buff *skb, bool *ccmp);
+ struct sk_buff *skb,
+ struct ieee80211_key_conf *k_conf,
+ bool *ccmp)
+{
+ int head_pad = 0;
+ int data_pad = 0;
+
+ /* Make sure the packet header is in the DMA header format (4-address
+ * without QoS), and add head & tail padding when HW crypto is enabled.
+ *
+ * We have the following trailer padding requirements:
+ * - WEP: 4 trailer bytes (ICV)
+ * - TKIP: 12 trailer bytes (8 MIC + 4 ICV)
+ * - CCMP: 8 trailer bytes (MIC)
+ */
+
+ if (k_conf) {
+ head_pad = k_conf->iv_len;
+
+ switch (k_conf->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ data_pad = 4;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ data_pad = 12;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ data_pad = 8;
+ *ccmp = true;
+ break;
+ }
+ }
+
+ mwl_tx_add_dma_header(priv, skb, head_pad, data_pad);
+}
+
static inline void mwl_tx_insert_ccmp_hdr(u8 *pccmp_hdr,
- u8 key_id, u16 iv16, u32 iv32);
-static inline int mwl_tx_tid_queue_mapping(u8 tid);
-static inline void mwl_tx_count_packet(struct ieee80211_sta *sta, u8 tid);
-static inline void mwl_tx_skbs(struct ieee80211_hw *hw);
-/* static void mwl_tx_descriptor_dump(struct mwl_priv *priv); */
+ u8 key_id, u16 iv16, u32 iv32)
+{
+ *((u16 *)pccmp_hdr) = iv16;
+ pccmp_hdr[2] = 0;
+ pccmp_hdr[3] = EXT_IV | (key_id << 6);
+ *((u32 *)&pccmp_hdr[4]) = iv32;
+}
+
+static inline int mwl_tx_tid_queue_mapping(u8 tid)
+{
+ BUG_ON(tid > 7);
+
+ switch (tid) {
+ case 0:
+ case 3:
+ return IEEE80211_AC_BE;
+ case 1:
+ case 2:
+ return IEEE80211_AC_BK;
+ case 4:
+ case 5:
+ return IEEE80211_AC_VI;
+ case 6:
+ case 7:
+ return IEEE80211_AC_VO;
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+static inline void mwl_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
+{
+ struct mwl_sta *sta_info;
+ struct mwl_tx_info *tx_stats;
+
+ BUG_ON(tid >= SYSADPT_MAX_TID);
+
+ sta_info = mwl_dev_get_sta(sta);
+
+ tx_stats = &sta_info->tx_stats[tid];
+
+ if (tx_stats->start_time == 0)
+ tx_stats->start_time = jiffies;
+
+ /* reset the packet count after each second elapses. If the number of
+ * packets ever exceeds the ampdu_min_traffic threshold, we will allow
+ * an ampdu stream to be started.
+ */
+ if (jiffies - tx_stats->start_time > HZ) {
+ tx_stats->pkts = 0;
+ tx_stats->start_time = 0;
+ } else {
+ tx_stats->pkts++;
+ }
+}
+
+static inline bool mwl_tx_available(struct mwl_priv *priv, int desc_num)
+{
+ if (!priv->desc_data[desc_num].pnext_tx_desc)
+ return false;
+
+ if (priv->desc_data[desc_num].pnext_tx_desc->status !=
+ EAGLE_TXD_STATUS_IDLE) {
+ /* Interrupt F/W anyway */
+ if (priv->desc_data[desc_num].pnext_tx_desc->status &
+ cpu_to_le32(EAGLE_TXD_STATUS_FW_OWNED))
+ writel(MACREG_H2ARIC_BIT_PPA_READY,
+ priv->iobase1 +
+ MACREG_REG_H2A_INTERRUPT_EVENTS);
+ return false;
+ }
+
+ return true;
+}
+
+static inline void mwl_tx_skb(struct mwl_priv *priv, int desc_num,
+ struct sk_buff *tx_skb)
+{
+ struct ieee80211_tx_info *tx_info;
+ struct mwl_tx_ctrl *tx_ctrl;
+ struct mwl_tx_desc *tx_desc;
+ struct ieee80211_sta *sta;
+ struct mwl_vif *mwl_vif;
+ struct ieee80211_key_conf *k_conf;
+ bool ccmp = false;
+ struct mwl_dma_data *dma_data;
+ struct ieee80211_hdr *wh;
+
+ BUG_ON(!tx_skb);
+
+ tx_info = IEEE80211_SKB_CB(tx_skb);
+ tx_ctrl = (struct mwl_tx_ctrl *)&tx_info->status;
+ sta = (struct ieee80211_sta *)tx_ctrl->sta;
+ mwl_vif = (struct mwl_vif *)tx_ctrl->vif;
+ k_conf = (struct ieee80211_key_conf *)tx_ctrl->k_conf;
+
+ mwl_tx_encapsulate_frame(priv, tx_skb, k_conf, &ccmp);
+
+ dma_data = (struct mwl_dma_data *)tx_skb->data;
+ wh = &dma_data->wh;
+
+ if (ieee80211_is_data(wh->frame_control)) {
+ if (is_multicast_ether_addr(wh->addr1)) {
+ if (ccmp) {
+ mwl_tx_insert_ccmp_hdr(dma_data->data,
+ mwl_vif->keyidx,
+ mwl_vif->iv16,
+ mwl_vif->iv32);
+ INCREASE_IV(mwl_vif->iv16, mwl_vif->iv32);
+ }
+ } else {
+ if (ccmp) {
+ if (mwl_vif->is_sta) {
+ mwl_tx_insert_ccmp_hdr(dma_data->data,
+ mwl_vif->keyidx,
+ mwl_vif->iv16,
+ mwl_vif->iv32);
+ INCREASE_IV(mwl_vif->iv16,
+ mwl_vif->iv32);
+ } else {
+ struct mwl_sta *sta_info;
+
+ sta_info = mwl_dev_get_sta(sta);
+
+ mwl_tx_insert_ccmp_hdr(dma_data->data,
+ 0,
+ sta_info->iv16,
+ sta_info->iv32);
+ INCREASE_IV(sta_info->iv16,
+ sta_info->iv32);
+ }
+ }
+ }
+ }
-/* PUBLIC FUNCTION DEFINITION
-*/
+ tx_desc = priv->desc_data[desc_num].pnext_tx_desc;
+ tx_desc->tx_priority = tx_ctrl->tx_priority;
+ tx_desc->qos_ctrl = cpu_to_le16(tx_ctrl->qos_ctrl);
+ tx_desc->psk_buff = tx_skb;
+ tx_desc->pkt_len = cpu_to_le16(tx_skb->len);
+ tx_desc->packet_info = 0;
+ tx_desc->data_rate = 0;
+ tx_desc->sta_info = tx_ctrl->sta;
+ tx_desc->type = tx_ctrl->type;
+ tx_desc->xmit_control = tx_ctrl->xmit_control;
+ tx_desc->sap_pkt_info = 0;
+ tx_desc->pkt_ptr =
+ cpu_to_le32(pci_map_single(priv->pdev, tx_skb->data,
+ tx_skb->len, PCI_DMA_TODEVICE));
+ tx_desc->status = cpu_to_le32(EAGLE_TXD_STATUS_FW_OWNED);
+ priv->desc_data[desc_num].pnext_tx_desc = tx_desc->pnext;
+ /* make sure all the memory transactions done by cpu were completed */
+ wmb(); /*Data Memory Barrier*/
+ writel(MACREG_H2ARIC_BIT_PPA_READY,
+ priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
+ priv->fw_desc_cnt[desc_num]++;
+}
+
+static inline void mwl_tx_skbs(struct ieee80211_hw *hw)
+{
+ struct mwl_priv *priv;
+ int num = SYSADPT_NUM_OF_DESC_DATA;
+ struct sk_buff *tx_skb;
+ unsigned long flags;
+
+ priv = hw->priv;
+
+ spin_lock_irqsave(&priv->tx_desc_lock, flags);
+ while (num--) {
+ while (skb_queue_len(&priv->txq[num]) > 0) {
+ if (mwl_tx_available(priv, num) == false)
+ break;
+ tx_skb = skb_dequeue(&priv->txq[num]);
+ mwl_tx_skb(priv, num, tx_skb);
+ }
+ }
+ spin_unlock_irqrestore(&priv->tx_desc_lock, flags);
+}
int mwl_tx_init(struct ieee80211_hw *hw)
{
struct mwl_priv *priv;
int rc;
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
skb_queue_head_init(&priv->delay_q);
rc = mwl_tx_ring_alloc(priv);
if (rc) {
- WLDBG_ERROR(DBG_LEVEL_3, "allocating TX ring failed");
+ wiphy_err(hw->wiphy, "allocating TX ring failed");
} else {
rc = mwl_tx_ring_init(priv);
if (rc) {
mwl_tx_ring_free(priv);
- WLDBG_ERROR(DBG_LEVEL_3, "initializing TX ring failed");
+ wiphy_err(hw->wiphy, "initializing TX ring failed");
}
}
- WLDBG_EXIT(DBG_LEVEL_3);
-
return rc;
}
@@ -122,26 +474,21 @@ void mwl_tx_deinit(struct ieee80211_hw *hw)
{
struct mwl_priv *priv;
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
skb_queue_purge(&priv->delay_q);
mwl_tx_ring_cleanup(priv);
mwl_tx_ring_free(priv);
-
- WLDBG_EXIT(DBG_LEVEL_3);
}
void mwl_tx_xmit(struct ieee80211_hw *hw,
- int index,
- struct ieee80211_sta *sta,
- struct sk_buff *skb)
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
{
struct mwl_priv *priv;
+ int index;
+ struct ieee80211_sta *sta;
struct ieee80211_tx_info *tx_info;
struct mwl_vif *mwl_vif;
struct ieee80211_hdr *wh;
@@ -154,22 +501,17 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
bool mgmtframe = false;
struct ieee80211_mgmt *mgmt;
bool eapol_frame = false;
- bool ccmp = false;
- struct mwl_dma_data *dma_data;
struct mwl_tx_ctrl *tx_ctrl;
+ struct ieee80211_key_conf *k_conf = NULL;
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- BUG_ON(!skb);
+ index = skb_get_queue_mapping(skb);
+ sta = control->sta;
wh = (struct ieee80211_hdr *)skb->data;
if (ieee80211_is_data_qos(wh->frame_control))
- qos = ENDIAN_SWAP16(*((u16 *)ieee80211_get_qos_ctl(wh)));
+ qos = *((u16 *)ieee80211_get_qos_ctl(wh));
else
qos = 0;
@@ -183,22 +525,16 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
mgmt = (struct ieee80211_mgmt *)skb->data;
}
- mwl_tx_encapsulate_frame(priv, skb, &ccmp);
-
- dma_data = (struct mwl_dma_data *)skb->data;
- wh = &dma_data->wh;
-
tx_info = IEEE80211_SKB_CB(skb);
- mwl_vif = MWL_VIF(tx_info->control.vif);
+ mwl_vif = mwl_dev_get_vif(tx_info->control.vif);
if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- wh->seq_ctrl &= ENDIAN_SWAP16(IEEE80211_SCTL_FRAG);
- wh->seq_ctrl |= ENDIAN_SWAP16(mwl_vif->seqno);
+ wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+ wh->seq_ctrl |= cpu_to_le16(mwl_vif->seqno);
mwl_vif->seqno += 0x10;
}
- /* Setup firmware control bit fields for each frame type.
- */
+ /* Setup firmware control bit fields for each frame type. */
xmitcontrol = 0;
if (mgmtframe || ieee80211_is_ctl(wh->frame_control)) {
@@ -214,37 +550,10 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
qos |= MWL_QOS_ACK_POLICY_NORMAL;
}
- if (is_multicast_ether_addr(wh->addr1)) {
+ if (is_multicast_ether_addr(wh->addr1))
xmitcontrol |= EAGLE_TXD_XMITCTRL_USE_MC_RATE;
- if (ccmp) {
- mwl_tx_insert_ccmp_hdr(dma_data->data,
- mwl_vif->keyidx,
- mwl_vif->iv16,
- mwl_vif->iv32);
- INCREASE_IV(mwl_vif->iv16, mwl_vif->iv32);
- }
- } else {
- if (ccmp) {
- if (mwl_vif->is_sta) {
- mwl_tx_insert_ccmp_hdr(dma_data->data,
- mwl_vif->keyidx,
- mwl_vif->iv16,
- mwl_vif->iv32);
- INCREASE_IV(mwl_vif->iv16,
- mwl_vif->iv32);
- } else {
- struct mwl_sta *sta_info = MWL_STA(sta);
-
- mwl_tx_insert_ccmp_hdr(dma_data->data,
- 0,
- sta_info->iv16,
- sta_info->iv32);
- INCREASE_IV(sta_info->iv16,
- sta_info->iv32);
- }
- }
- }
+ k_conf = tx_info->control.hw_key;
}
/* Queue ADDBA request in the respective data queue. While setting up
@@ -262,20 +571,21 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)) {
u16 capab =
- ENDIAN_SWAP16(mgmt->u.action.u.addba_req.capab);
+ le16_to_cpu(mgmt->u.action.u.addba_req.capab);
tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
index = mwl_tx_tid_queue_mapping(tid);
}
}
- txpriority = SYSADPT_TX_WMM_QUEUES - index - 1;
+ index = SYSADPT_TX_WMM_QUEUES - index - 1;
+ txpriority = index;
if (sta && sta->ht_cap.ht_supported && !eapol_frame &&
ieee80211_is_data_qos(wh->frame_control)) {
tid = qos & 0xf;
mwl_tx_count_packet(sta, tid);
- SPIN_LOCK(&priv->locks.stream_lock);
+ spin_lock(&priv->stream_lock);
stream = mwl_fwcmd_lookup_stream(hw, sta->addr, tid);
if (stream) {
@@ -306,9 +616,9 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
* mac80211 queues our packets for us in this
* case, so this is really just a safety check.
*/
- WLDBG_WARNING(DBG_LEVEL_3,
- "can't send packet during ADDBA");
- SPIN_UNLOCK(&priv->locks.stream_lock);
+ wiphy_warn(hw->wiphy,
+ "can't send packet during ADDBA");
+ spin_unlock(&priv->stream_lock);
dev_kfree_skb_any(skb);
return;
}
@@ -326,7 +636,7 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
}
}
- SPIN_UNLOCK(&priv->locks.stream_lock);
+ spin_unlock(&priv->stream_lock);
} else {
qos &= ~MWL_QOS_ACK_POLICY_MASK;
qos |= MWL_QOS_ACK_POLICY_NORMAL;
@@ -337,28 +647,24 @@ void mwl_tx_xmit(struct ieee80211_hw *hw,
tx_ctrl->qos_ctrl = qos;
tx_ctrl->type = (mgmtframe ? IEEE_TYPE_MANAGEMENT : IEEE_TYPE_DATA);
tx_ctrl->xmit_control = xmitcontrol;
- tx_ctrl->sta_info = (u8 *)sta;
- tx_ctrl->ccmp = ccmp;
+ tx_ctrl->sta = (void *)sta;
+ tx_ctrl->vif = (void *)mwl_vif;
+ tx_ctrl->k_conf = (void *)k_conf;
- if (skb_queue_len(&priv->txq[index]) > priv->txq_limit) {
+ if (skb_queue_len(&priv->txq[index]) > priv->txq_limit)
dev_kfree_skb_any(skb);
- WLDBG_INFO(DBG_LEVEL_3, "queue len > limit");
- } else {
+ else
skb_queue_tail(&priv->txq[index], skb);
- }
mwl_tx_skbs(hw);
- /* Initiate the ampdu session here
- */
+ /* Initiate the ampdu session here */
if (start_ba_session) {
- SPIN_LOCK(&priv->locks.stream_lock);
+ spin_lock(&priv->stream_lock);
if (mwl_fwcmd_start_stream(hw, stream))
mwl_fwcmd_remove_stream(hw, stream);
- SPIN_UNLOCK(&priv->locks.stream_lock);
+ spin_unlock(&priv->stream_lock);
}
-
- WLDBG_EXIT(DBG_LEVEL_3);
}
void mwl_tx_done(unsigned long data)
@@ -368,34 +674,29 @@ void mwl_tx_done(unsigned long data)
unsigned long flags;
int num;
struct sk_buff *done_skb;
- struct mwl_rate_info rate_info;
+ u32 rate, format, bandwidth, short_gi, rate_id;
struct mwl_dma_data *tr;
struct ieee80211_tx_info *info;
int hdrlen;
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!hw);
priv = hw->priv;
- BUG_ON(!priv);
-
- SPIN_LOCK_IRQSAVE(&priv->locks.xmit_lock, flags);
+ spin_lock_irqsave(&priv->tx_desc_lock, flags);
for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
while (STALE_TXD(num) && (STALE_TXD(num)->status &
- ENDIAN_SWAP32(EAGLE_TXD_STATUS_OK)) &&
+ cpu_to_le32(EAGLE_TXD_STATUS_OK)) &&
(!(STALE_TXD(num)->status &
- ENDIAN_SWAP32(EAGLE_TXD_STATUS_FW_OWNED)))) {
+ cpu_to_le32(EAGLE_TXD_STATUS_FW_OWNED)))) {
pci_unmap_single(priv->pdev,
- ENDIAN_SWAP32(STALE_TXD(num)->pkt_ptr),
+ le32_to_cpu(STALE_TXD(num)->pkt_ptr),
STALE_TXD(num)->psk_buff->len,
PCI_DMA_TODEVICE);
done_skb = STALE_TXD(num)->psk_buff;
- rate_info = STALE_TXD(num)->rate_info;
+ rate = le32_to_cpu(STALE_TXD(num)->rate_info);
STALE_TXD(num)->pkt_len = 0;
STALE_TXD(num)->psk_buff = NULL;
STALE_TXD(num)->status =
- ENDIAN_SWAP32(EAGLE_TXD_STATUS_IDLE);
+ cpu_to_le32(EAGLE_TXD_STATUS_IDLE);
priv->fw_desc_cnt[num]--;
STALE_TXD(num) = STALE_TXD(num)->pnext;
wmb(); /* memory barrier */
@@ -416,29 +717,36 @@ void mwl_tx_done(unsigned long data)
dev_kfree_skb_any(
skb_dequeue(&priv->delay_q));
- /* Prepare rate information
- */
- info->status.rates[0].idx =
- rate_info.rate_id_mcs;
- if (rate_info.format == TX_RATE_FORMAT_LEGACY) {
+ /* Prepare rate information */
+ format = rate & MWL_TX_RATE_FORMAT_MASK;
+ bandwidth =
+ (rate & MWL_TX_RATE_BANDWIDTH_MASK) >>
+ MWL_TX_RATE_BANDWIDTH_SHIFT;
+ short_gi = (rate & MWL_TX_RATE_SHORTGI_MASK) >>
+ MWL_TX_RATE_SHORTGI_SHIFT;
+ rate_id = (rate & MWL_TX_RATE_RATEIDMCS_MASK) >>
+ MWL_TX_RATE_RATEIDMCS_SHIFT;
+
+ info->status.rates[0].idx = rate_id;
+ if (format == TX_RATE_FORMAT_LEGACY) {
if (hw->conf.chandef.chan->hw_value >
BAND_24_CHANNEL_NUM) {
info->status.rates[0].idx -= 5;
}
}
- if (rate_info.format == TX_RATE_FORMAT_11N)
+ if (format == TX_RATE_FORMAT_11N)
info->status.rates[0].flags |=
IEEE80211_TX_RC_MCS;
- if (rate_info.format == TX_RATE_FORMAT_11AC)
+ if (format == TX_RATE_FORMAT_11AC)
info->status.rates[0].flags |=
IEEE80211_TX_RC_VHT_MCS;
- if (rate_info.bandwidth == TX_RATE_BANDWIDTH_40)
+ if (bandwidth == TX_RATE_BANDWIDTH_40)
info->status.rates[0].flags |=
IEEE80211_TX_RC_40_MHZ_WIDTH;
- if (rate_info.bandwidth == TX_RATE_BANDWIDTH_80)
+ if (bandwidth == TX_RATE_BANDWIDTH_80)
info->status.rates[0].flags |=
IEEE80211_TX_RC_80_MHZ_WIDTH;
- if (rate_info.short_gi == TX_RATE_INFO_SHORT_GI)
+ if (short_gi == TX_RATE_INFO_SHORT_GI)
info->status.rates[0].flags |=
IEEE80211_TX_RC_SHORT_GI;
info->status.rates[0].count = 1;
@@ -446,8 +754,7 @@ void mwl_tx_done(unsigned long data)
info->status.rates[1].idx = -1;
}
- /* Remove H/W dma header
- */
+ /* Remove H/W dma header */
hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
memmove(tr->data - hdrlen, &tr->wh, hdrlen);
skb_pull(done_skb, sizeof(*tr) - hdrlen);
@@ -456,8 +763,7 @@ void mwl_tx_done(unsigned long data)
ieee80211_tx_status(hw, done_skb);
}
}
-
- SPIN_UNLOCK_IRQRESTORE(&priv->locks.xmit_lock, flags);
+ spin_unlock_irqrestore(&priv->tx_desc_lock, flags);
if (priv->irq != -1) {
u32 status;
@@ -471,422 +777,4 @@ void mwl_tx_done(unsigned long data)
}
priv->is_tx_schedule = false;
-
- WLDBG_EXIT(DBG_LEVEL_3);
-}
-
-/* PRIVATE FUNCTION DEFINITION
-*/
-
-static int mwl_tx_ring_alloc(struct mwl_priv *priv)
-{
- int num;
- u8 *mem;
-
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!priv);
-
- mem = (u8 *)dma_alloc_coherent(&priv->pdev->dev,
- MAX_NUM_TX_RING_BYTES * SYSADPT_NUM_OF_DESC_DATA,
- &priv->desc_data[0].pphys_tx_ring, GFP_KERNEL);
-
- if (!mem) {
- WLDBG_ERROR(DBG_LEVEL_3, "can not alloc mem");
- WLDBG_EXIT_INFO(DBG_LEVEL_3, "no memory");
- return -ENOMEM;
- }
-
- for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
- WLDBG_INFO(DBG_LEVEL_3, "allocating %i (0x%x) bytes",
- MAX_NUM_TX_RING_BYTES, MAX_NUM_TX_RING_BYTES);
-
- priv->desc_data[num].ptx_ring = (struct mwl_tx_desc *)
- (mem + num * MAX_NUM_TX_RING_BYTES);
-
- priv->desc_data[num].pphys_tx_ring = (dma_addr_t)
- ((u32)priv->desc_data[0].pphys_tx_ring +
- num * MAX_NUM_TX_RING_BYTES);
-
- memset(priv->desc_data[num].ptx_ring, 0x00,
- MAX_NUM_TX_RING_BYTES);
-
- WLDBG_INFO(DBG_LEVEL_3, "TX ring vaddr: 0x%x paddr: 0x%x",
- priv->desc_data[num].ptx_ring,
- priv->desc_data[num].pphys_tx_ring);
- }
-
- WLDBG_EXIT(DBG_LEVEL_3);
-
- return 0;
-}
-
-static int mwl_tx_ring_init(struct mwl_priv *priv)
-{
- int curr_desc;
- struct mwl_desc_data *desc;
- int num;
-
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!priv);
-
- for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
- skb_queue_head_init(&priv->txq[num]);
- priv->fw_desc_cnt[num] = 0;
-
- desc = &priv->desc_data[num];
-
- if (desc->ptx_ring) {
- WLDBG_INFO(DBG_LEVEL_3, "initializing %i descriptors",
- SYSADPT_MAX_NUM_TX_DESC);
-
- for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_TX_DESC;
- curr_desc++) {
- CURR_TXD(num).status =
- ENDIAN_SWAP32(EAGLE_TXD_STATUS_IDLE);
- CURR_TXD(num).pnext = &NEXT_TXD(num);
- CURR_TXD(num).pphys_next =
- ENDIAN_SWAP32((u32)desc->pphys_tx_ring +
- ((curr_desc + 1) *
- sizeof(struct mwl_tx_desc)));
- WLDBG_INFO(DBG_LEVEL_3,
- "txdesc: %i 0x%x (%i) 0x%p 0x%x",
- curr_desc, EAGLE_TXD_STATUS_IDLE,
- EAGLE_TXD_STATUS_IDLE,
- CURR_TXD(num).pnext,
- ENDIAN_SWAP32(
- CURR_TXD(num).pphys_next));
- }
- LAST_TXD(num).pnext = &FIRST_TXD(num);
- LAST_TXD(num).pphys_next =
- ENDIAN_SWAP32((u32)desc->pphys_tx_ring);
- desc->pstale_tx_desc = &FIRST_TXD(num);
- desc->pnext_tx_desc = &FIRST_TXD(num);
-
- WLDBG_INFO(DBG_LEVEL_3,
- "last txdesc vnext: 0x%p 0x%x 0x%x 0x%x",
- LAST_TXD(num).pnext,
- ENDIAN_SWAP32(LAST_TXD(num).pphys_next),
- desc->pstale_tx_desc, desc->pnext_tx_desc);
- } else {
- WLDBG_ERROR(DBG_LEVEL_3, "no valid TX mem");
- WLDBG_EXIT_INFO(DBG_LEVEL_3, "no valid memory");
- return -ENOMEM;
- }
- }
-
- WLDBG_EXIT(DBG_LEVEL_3);
-
- return 0;
-}
-
-static void mwl_tx_ring_cleanup(struct mwl_priv *priv)
-{
- int cleaned_tx_desc = 0;
- int curr_desc;
- int num;
-
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!priv);
-
- for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
- skb_queue_purge(&priv->txq[num]);
- priv->fw_desc_cnt[num] = 0;
- if (priv->desc_data[num].ptx_ring) {
- for (curr_desc = 0; curr_desc < SYSADPT_MAX_NUM_TX_DESC;
- curr_desc++) {
- if (!CURR_TXD(num).psk_buff)
- continue;
-
- WLDBG_INFO(DBG_LEVEL_3,
- "unmapped and free'd %i 0x%p 0x%x",
- curr_desc,
- CURR_TXD(num).psk_buff->data,
- ENDIAN_SWAP32(
- CURR_TXD(num).pkt_ptr));
- pci_unmap_single(priv->pdev,
- ENDIAN_SWAP32(
- CURR_TXD(num).pkt_ptr),
- CURR_TXD(num).psk_buff->len,
- PCI_DMA_TODEVICE);
- dev_kfree_skb_any(CURR_TXD(num).psk_buff);
- CURR_TXD(num).status =
- ENDIAN_SWAP32(EAGLE_TXD_STATUS_IDLE);
- CURR_TXD(num).psk_buff = NULL;
- CURR_TXD(num).pkt_ptr = 0;
- CURR_TXD(num).pkt_len = 0;
- cleaned_tx_desc++;
- }
- }
- }
-
- WLDBG_EXIT_INFO(DBG_LEVEL_3, "cleaned %i TX descr", cleaned_tx_desc);
-}
-
-static void mwl_tx_ring_free(struct mwl_priv *priv)
-{
- int num;
-
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!priv);
-
- if (priv->desc_data[0].ptx_ring) {
- dma_free_coherent(&priv->pdev->dev,
- MAX_NUM_TX_RING_BYTES *
- SYSADPT_NUM_OF_DESC_DATA,
- priv->desc_data[0].ptx_ring,
- priv->desc_data[0].pphys_tx_ring);
- }
-
- for (num = 0; num < SYSADPT_NUM_OF_DESC_DATA; num++) {
- if (priv->desc_data[num].ptx_ring)
- priv->desc_data[num].ptx_ring = NULL;
- priv->desc_data[num].pstale_tx_desc = NULL;
- priv->desc_data[num].pnext_tx_desc = NULL;
- }
-
- WLDBG_EXIT(DBG_LEVEL_3);
-}
-
-static inline void mwl_tx_add_dma_header(struct mwl_priv *priv,
- struct sk_buff *skb,
- int head_pad,
- int tail_pad)
-{
- struct ieee80211_hdr *wh;
- int hdrlen;
- int reqd_hdrlen;
- struct mwl_dma_data *tr;
-
- /* Add a firmware DMA header; the firmware requires that we
- * present a 2-byte payload length followed by a 4-address
- * header (without QoS field), followed (optionally) by any
- * WEP/ExtIV header (but only filled in for CCMP).
- */
- wh = (struct ieee80211_hdr *)skb->data;
-
- hdrlen = ieee80211_hdrlen(wh->frame_control);
-
- reqd_hdrlen = sizeof(*tr) + head_pad;
-
- if (hdrlen != reqd_hdrlen)
- skb_push(skb, reqd_hdrlen - hdrlen);
-
- if (ieee80211_is_data_qos(wh->frame_control))
- hdrlen -= IEEE80211_QOS_CTL_LEN;
-
- tr = (struct mwl_dma_data *)skb->data;
-
- if (wh != &tr->wh)
- memmove(&tr->wh, wh, hdrlen);
-
- if (hdrlen != sizeof(tr->wh))
- memset(((void *)&tr->wh) + hdrlen, 0, sizeof(tr->wh) - hdrlen);
-
- /* Firmware length is the length of the fully formed "802.11
- * payload". That is, everything except for the 802.11 header.
- * This includes all crypto material including the MIC.
- */
- tr->fwlen = ENDIAN_SWAP16(skb->len - sizeof(*tr) + tail_pad);
-}
-
-static inline void mwl_tx_encapsulate_frame(struct mwl_priv *priv,
- struct sk_buff *skb, bool *ccmp)
-{
- struct ieee80211_hdr *wh;
- struct ieee80211_tx_info *tx_info;
- struct ieee80211_key_conf *key_conf;
- int data_pad;
- int head_pad = 0;
-
- wh = (struct ieee80211_hdr *)skb->data;
-
- tx_info = IEEE80211_SKB_CB(skb);
-
- key_conf = NULL;
-
- if (ieee80211_is_data(wh->frame_control))
- key_conf = tx_info->control.hw_key;
-
- /* Make sure the packet header is in the DMA header format (4-address
- * without QoS), and add head & tail padding when HW crypto is enabled.
- *
- * We have the following trailer padding requirements:
- * - WEP: 4 trailer bytes (ICV)
- * - TKIP: 12 trailer bytes (8 MIC + 4 ICV)
- * - CCMP: 8 trailer bytes (MIC)
- */
- data_pad = 0;
-
- if (key_conf) {
- head_pad = key_conf->iv_len;
-
- switch (key_conf->cipher) {
- case WLAN_CIPHER_SUITE_WEP40:
- case WLAN_CIPHER_SUITE_WEP104:
- data_pad = 4;
- break;
- case WLAN_CIPHER_SUITE_TKIP:
- data_pad = 12;
- break;
- case WLAN_CIPHER_SUITE_CCMP:
- data_pad = 8;
- *ccmp = true;
- break;
- }
- }
-
- mwl_tx_add_dma_header(priv, skb, head_pad, data_pad);
-}
-
-static inline void mwl_tx_insert_ccmp_hdr(u8 *pccmp_hdr,
- u8 key_id, u16 iv16, u32 iv32)
-{
- *((u16 *)pccmp_hdr) = iv16;
- pccmp_hdr[2] = 0;
- pccmp_hdr[3] = EXT_IV | (key_id << 6);
- *((u32 *)&pccmp_hdr[4]) = iv32;
-}
-
-static inline int mwl_tx_tid_queue_mapping(u8 tid)
-{
- BUG_ON(tid > 7);
-
- switch (tid) {
- case 0:
- case 3:
- return IEEE80211_AC_BE;
- case 1:
- case 2:
- return IEEE80211_AC_BK;
- case 4:
- case 5:
- return IEEE80211_AC_VI;
- case 6:
- case 7:
- return IEEE80211_AC_VO;
- default:
- break;
- }
-
- return -1;
-}
-
-static inline void mwl_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
-{
- struct mwl_sta *sta_info = MWL_STA(sta);
- struct mwl_tx_info *tx_stats;
-
- BUG_ON(!sta);
- sta_info = MWL_STA(sta);
- BUG_ON(!sta_info);
-
- BUG_ON(tid >= SYSADPT_MAX_TID);
-
- tx_stats = &sta_info->tx_stats[tid];
-
- if (tx_stats->start_time == 0)
- tx_stats->start_time = jiffies;
-
- /* reset the packet count after each second elapses. If the number of
- * packets ever exceeds the ampdu_min_traffic threshold, we will allow
- * an ampdu stream to be started.
- */
- if (jiffies - tx_stats->start_time > HZ) {
- tx_stats->pkts = 0;
- tx_stats->start_time = 0;
- } else {
- tx_stats->pkts++;
- }
-}
-
-static inline void mwl_tx_skbs(struct ieee80211_hw *hw)
-{
- struct mwl_priv *priv;
- unsigned long flags;
- int num = SYSADPT_NUM_OF_DESC_DATA;
- struct mwl_desc_data *desc;
- struct sk_buff *tx_skb;
- struct ieee80211_tx_info *tx_info;
- struct mwl_tx_ctrl *tx_ctrl;
-
- WLDBG_ENTER(DBG_LEVEL_3);
-
- BUG_ON(!hw);
- priv = hw->priv;
- BUG_ON(!priv);
-
- SPIN_LOCK_IRQSAVE(&priv->locks.xmit_lock, flags);
-
- while (num--) {
- while (skb_queue_len(&priv->txq[num]) > 0) {
- desc = &priv->desc_data[num];
-
- if (!desc->pnext_tx_desc)
- break;
-
- /* Only queue to tx desc when Status is 0 (not when 0x1
- * or 0x80000000). If we queue even when Status==0x1
- * (DMA'd to fw but txdone haven't change Status to 0),
- * mismatch of fwDescCnt with actual number of desc
- * with Status==0 could happen. E.g fwDescCnt 256
- * instead of 255 when there is one desc with Status==0.
- * This can cause Tx to stall when fwDescCnt==256 and
- * pStaleTxDesc->Status==0.
- */
- if (desc->pnext_tx_desc->status !=
- EAGLE_TXD_STATUS_IDLE) {
- /* Interrupt F/W anyway
- */
- if (desc->pnext_tx_desc->status &
- ENDIAN_SWAP32(EAGLE_TXD_STATUS_FW_OWNED))
- writel(MACREG_H2ARIC_BIT_PPA_READY,
- priv->iobase1 +
- MACREG_REG_H2A_INTERRUPT_EVENTS);
- break;
- }
-
- tx_skb = skb_dequeue(&priv->txq[num]);
-
- BUG_ON(!tx_skb);
-
- tx_info = IEEE80211_SKB_CB(tx_skb);
- tx_ctrl = (struct mwl_tx_ctrl *)&tx_info->status;
-
- desc->pnext_tx_desc->tx_priority = tx_ctrl->tx_priority;
- desc->pnext_tx_desc->qos_ctrl = tx_ctrl->qos_ctrl;
- desc->pnext_tx_desc->psk_buff = tx_skb;
- desc->pnext_tx_desc->pkt_len =
- ENDIAN_SWAP16(tx_skb->len);
- desc->pnext_tx_desc->packet_info = 0;
- desc->pnext_tx_desc->data_rate = 0;
- desc->pnext_tx_desc->sta_info = tx_ctrl->sta_info;
- desc->pnext_tx_desc->type = tx_ctrl->type;
- desc->pnext_tx_desc->xmit_control =
- tx_ctrl->xmit_control;
- desc->pnext_tx_desc->sap_pkt_info = 0;
- desc->pnext_tx_desc->pkt_ptr =
- ENDIAN_SWAP32(pci_map_single(priv->pdev,
- tx_skb->data,
- tx_skb->len,
- PCI_DMA_TODEVICE));
- desc->pnext_tx_desc->status =
- ENDIAN_SWAP32(EAGLE_TXD_STATUS_FW_OWNED);
- desc->pnext_tx_desc = desc->pnext_tx_desc->pnext;
- /* make sure all the memory transactions done by cpu
- * were completed
- */
- wmb(); /*Data Memory Barrier*/
- writel(MACREG_H2ARIC_BIT_PPA_READY,
- priv->iobase1 + MACREG_REG_H2A_INTERRUPT_EVENTS);
- priv->fw_desc_cnt[num]++;
- }
- }
-
- SPIN_UNLOCK_IRQRESTORE(&priv->locks.xmit_lock, flags);
-
- WLDBG_EXIT(DBG_LEVEL_3);
}
diff --git a/tx.h b/tx.h
new file mode 100644
index 0000000..df485f9
--- /dev/null
+++ b/tx.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2006-2015, Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/* Description: This file defines transmit related functions.
+ */
+
+#ifndef _mwl_tx_h_
+#define _mwl_tx_h_
+
+int mwl_tx_init(struct ieee80211_hw *hw);
+void mwl_tx_deinit(struct ieee80211_hw *hw);
+void mwl_tx_xmit(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb);
+void mwl_tx_done(unsigned long data);
+
+#endif /* _mwl_tx_h_ */