summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lin <dlin@marvell.com>2015-11-24 16:39:14 +0800
committerDavid Lin <dlin@marvell.com>2015-11-24 16:39:14 +0800
commitea52835827ac5fc71665cee7a435e157b40ffe5f (patch)
treeabf7c7e724708e2782ee94828dbad630957942d6
parent2e54ced68eec408c9c0e8c3742105bf7bc724f99 (diff)
Commit code to support following items:
1. Use compiler attribute "____cacheline_aligned_in_smp" to let spin lock be cacheline aligned. 2. Avoid to trigger queue empty tasklet more than one time within one tick. Signed-off-by: David Lin <dlin@marvell.com>
-rw-r--r--debugfs.c59
-rw-r--r--debugfs.h6
-rw-r--r--dev.h48
-rw-r--r--fwcmd.c119
-rw-r--r--fwcmd.h12
-rw-r--r--fwdl.h6
-rw-r--r--hostcmd.h29
-rw-r--r--isr.c16
-rw-r--r--isr.h6
-rw-r--r--mac80211.c14
-rw-r--r--main.c38
-rw-r--r--rx.c6
-rw-r--r--rx.h6
-rw-r--r--sysadpt.h6
-rw-r--r--tx.c11
-rw-r--r--tx.h6
16 files changed, 166 insertions, 222 deletions
diff --git a/debugfs.c b/debugfs.c
index 0eb6336..7638aa6 100644
--- a/debugfs.c
+++ b/debugfs.c
@@ -59,18 +59,18 @@ static int dump_data(char *p, u8 *data, int len, char *title)
if ((cur_byte + 8) < len) {
for (i = 0; i < 8; i++)
str += sprintf(str, "0x%02x ",
- *(data+cur_byte+i));
+ *(data + cur_byte + i));
str += sprintf(str, "\n");
} else {
for (i = 0; i < (len - cur_byte); i++)
str += sprintf(str, "0x%02x ",
- *(data+cur_byte+i));
+ *(data + cur_byte + i));
str += sprintf(str, "\n");
break;
}
}
- return str-p;
+ return (str - p);
}
static ssize_t mwl_debugfs_info_read(struct file *file, char __user *ubuf,
@@ -108,11 +108,12 @@ static ssize_t mwl_debugfs_info_read(struct file *file, char __user *ubuf,
p += sprintf(p, "sta macid support: %08x\n",
priv->sta_macids_supported);
p += sprintf(p, "macid used: %08x\n", priv->macids_used);
+ p += sprintf(p, "qe trigger number: %d\n", priv->qe_trigger_num);
p += sprintf(p, "mfg mode: %s\n", priv->mfg_mode ? "true" : "false");
p += sprintf(p, "\n");
- ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
- (unsigned long) p - page);
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
+ (unsigned long)p - page);
free_page(page);
return ret;
@@ -126,7 +127,7 @@ static ssize_t mwl_debugfs_vif_read(struct file *file, char __user *ubuf,
char *p = (char *)page;
struct mwl_vif *mwl_vif;
struct ieee80211_vif *vif;
- char ssid[IEEE80211_MAX_SSID_LEN+1];
+ char ssid[IEEE80211_MAX_SSID_LEN + 1];
ssize_t ret;
if (!p)
@@ -177,8 +178,8 @@ static ssize_t mwl_debugfs_vif_read(struct file *file, char __user *ubuf,
}
spin_unlock_bh(&priv->vif_lock);
- ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
- (unsigned long) p - page);
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
+ (unsigned long)p - page);
free_page(page);
return ret;
@@ -218,8 +219,8 @@ static ssize_t mwl_debugfs_sta_read(struct file *file, char __user *ubuf,
}
spin_unlock_bh(&priv->sta_lock);
- ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
- (unsigned long) p - page);
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
+ (unsigned long)p - page);
free_page(page);
return ret;
@@ -246,15 +247,16 @@ static ssize_t mwl_debugfs_ampdu_read(struct file *file, char __user *ubuf,
p += sprintf(p, "idx: %u\n", stream->idx);
p += sprintf(p, "state: %u\n", stream->state);
if (stream->sta) {
- p += sprintf(p, "mac address: %pM\n", stream->sta->addr);
+ p += sprintf(p, "mac address: %pM\n",
+ stream->sta->addr);
p += sprintf(p, "tid: %u\n", stream->tid);
}
}
spin_unlock_bh(&priv->stream_lock);
p += sprintf(p, "\n");
- ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
- (unsigned long) p - page);
+ ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
+ (unsigned long)p - page);
free_page(page);
return ret;
@@ -270,18 +272,6 @@ static int mwl_debugfs_reg_access(struct mwl_priv *priv, bool write)
set = write ? WL_SET : WL_GET;
switch (priv->reg_type) {
- case MWL_ACCESS_RF:
- ret = mwl_fwcmd_reg_rf(hw, set, priv->reg_offset,
- &priv->reg_value);
- break;
- case MWL_ACCESS_BBP:
- ret = mwl_fwcmd_reg_bb(hw, set, priv->reg_offset,
- &priv->reg_value);
- break;
- case MWL_ACCESS_CAU:
- ret = mwl_fwcmd_reg_cau(hw, set, priv->reg_offset,
- &priv->reg_value);
- break;
case MWL_ACCESS_ADDR0:
if (set == WL_GET)
priv->reg_value =
@@ -308,8 +298,9 @@ static int mwl_debugfs_reg_access(struct mwl_priv *priv, bool write)
if ((!ret) && (set == WL_GET))
priv->reg_value = addr_val[0];
kfree(addr_val);
- } else
+ } else {
ret = -ENOMEM;
+ }
break;
default:
ret = -EINVAL;
@@ -324,7 +315,7 @@ static ssize_t mwl_debugfs_regrdwr_read(struct file *file, char __user *ubuf,
{
struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *) addr;
+ char *buf = (char *)addr;
int pos = 0, ret = 0;
if (!buf)
@@ -345,9 +336,15 @@ static ssize_t mwl_debugfs_regrdwr_read(struct file *file, char __user *ubuf,
ret = mwl_debugfs_reg_access(priv, false);
done:
- pos += snprintf(buf, PAGE_SIZE, "%u 0x%08x 0x%08x\n",
- priv->reg_type, priv->reg_offset,
- priv->reg_value);
+ if (!ret)
+ pos += snprintf(buf, PAGE_SIZE, "%u 0x%08x 0x%08x\n",
+ priv->reg_type, priv->reg_offset,
+ priv->reg_value);
+ else
+ pos += snprintf(buf, PAGE_SIZE, "error: %d(%u 0x%08x 0x%08x)\n",
+ ret, priv->reg_type, priv->reg_offset,
+ priv->reg_value);
+
ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
none:
@@ -362,7 +359,7 @@ static ssize_t mwl_debugfs_regrdwr_write(struct file *file,
{
struct mwl_priv *priv = (struct mwl_priv *)file->private_data;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
- char *buf = (char *) addr;
+ char *buf = (char *)addr;
size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
int ret;
u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
diff --git a/debugfs.h b/debugfs.h
index dfc2a3c..90cfe66 100644
--- a/debugfs.h
+++ b/debugfs.h
@@ -15,10 +15,10 @@
/* Description: This file defines debug fs related functions. */
-#ifndef _debugfs_h_
-#define _debugfs_h_
+#ifndef _MWL_DEBUGFS_H_
+#define _MWL_DEBUGFS_H_
void mwl_debugfs_init(struct ieee80211_hw *hw);
void mwl_debugfs_remove(struct ieee80211_hw *hw);
-#endif /* _debugfs_h_ */
+#endif /* _MWL_DEBUGFS_H_ */
diff --git a/dev.h b/dev.h
index 3f9a863..fc8c200 100644
--- a/dev.h
+++ b/dev.h
@@ -15,8 +15,8 @@
/* Description: This file defines device related information. */
-#ifndef _dev_h_
-#define _dev_h_
+#ifndef _DEV_H_
+#define _DEV_H_
#include <linux/version.h>
#include <linux/interrupt.h>
@@ -143,7 +143,6 @@ enum {
struct mwl_chip_info {
const char *part_name;
const char *fw_image;
- const char *mfg_fw_image;
int antenna_tx;
int antenna_rx;
};
@@ -265,7 +264,7 @@ struct mwl_ampdu_stream {
};
#ifdef CONFIG_DEBUG_FS
-#define MAC_REG_ADDR_PCI(offset) ((priv->iobase1+0xA000) + offset)
+#define MAC_REG_ADDR_PCI(offset) ((priv->iobase1 + 0xA000) + offset)
#define MWL_ACCESS_MAC 1
#define MWL_ACCESS_RF 2
@@ -310,8 +309,10 @@ struct mwl_priv {
struct mwl_hw_data hw_data; /* Adapter HW specific info */
/* various descriptor data */
- spinlock_t tx_desc_lock; /* for tx descriptor data */
- spinlock_t rx_desc_lock; /* for rx descriptor data */
+ /* for tx descriptor data */
+ spinlock_t tx_desc_lock ____cacheline_aligned_in_smp;
+ /* for rx descriptor data */
+ spinlock_t rx_desc_lock ____cacheline_aligned_in_smp;
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;
@@ -326,6 +327,9 @@ struct mwl_priv {
int recv_limit;
bool is_rx_schedule;
bool is_qe_schedule;
+ u32 qe_trigger_num;
+ unsigned long qe_trigger_time;
+
s8 noise; /* Most recently reported noise in dBm */
struct ieee80211_supported_band band_24;
struct ieee80211_channel channels_24[BAND_24_CHANNEL_NUM];
@@ -337,22 +341,29 @@ struct mwl_priv {
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 */
+ struct {
+ spinlock_t vif_lock; /* for private interface info */
+ struct list_head vif_list; /* List of interfaces. */
+ } ____cacheline_aligned_in_smp;
+
+ struct {
+ spinlock_t sta_lock; /* for private sta info */
+ struct list_head sta_list; /* List of stations */
+ } ____cacheline_aligned_in_smp;
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];
+ /* ampdu stream information */
+ /* for ampdu stream */
+ struct {
+ spinlock_t stream_lock;
+ struct mwl_ampdu_stream ampdu[SYSADPT_TX_AMPDU_QUEUES];
+ } ____cacheline_aligned_in_smp;
struct work_struct watchdog_ba_handle;
bool mfg_mode;
@@ -437,8 +448,11 @@ struct mwl_sta {
bool is_ampdu_allowed;
struct mwl_tx_info tx_stats[MWL_MAX_TID];
bool is_amsdu_allowed;
- spinlock_t amsdu_lock; /* for amsdu aggregation */
- struct mwl_amsdu_ctrl amsdu_ctrl;
+ /* for amsdu aggregation */
+ struct {
+ spinlock_t amsdu_lock;
+ struct mwl_amsdu_ctrl amsdu_ctrl;
+ } ____cacheline_aligned_in_smp;
u16 iv16;
u32 iv32;
};
@@ -479,4 +493,4 @@ static inline struct mwl_sta *mwl_dev_get_sta(const struct ieee80211_sta *sta)
/* Defined in mac80211.c. */
extern const struct ieee80211_ops mwl_mac80211_ops;
-#endif /* _dev_h_ */
+#endif /* _DEV_H_ */
diff --git a/fwcmd.c b/fwcmd.c
index f879e1b..0685930 100644
--- a/fwcmd.c
+++ b/fwcmd.c
@@ -75,8 +75,6 @@ static char *mwl_fwcmd_get_cmd_string(unsigned short cmd)
{ HOSTCMD_CMD_GET_HW_SPEC, "GetHwSpecifications" },
{ HOSTCMD_CMD_SET_HW_SPEC, "SetHwSepcifications" },
{ HOSTCMD_CMD_802_11_GET_STAT, "80211GetStat" },
- { HOSTCMD_CMD_BBP_REG_ACCESS, "BBPRegAccess" },
- { HOSTCMD_CMD_RF_REG_ACCESS, "RFRegAccess" },
{ HOSTCMD_CMD_802_11_RADIO_CONTROL, "80211RadioControl" },
{ HOSTCMD_CMD_MEM_ADDR_ACCESS, "MEMAddrAccess" },
{ HOSTCMD_CMD_802_11_TX_POWER, "80211TxPower" },
@@ -106,7 +104,6 @@ static char *mwl_fwcmd_get_cmd_string(unsigned short cmd)
{ HOSTCMD_CMD_DWDS_ENABLE, "DwdsEnable" },
{ HOSTCMD_CMD_FW_FLUSH_TIMER, "FwFlushTimer" },
{ HOSTCMD_CMD_SET_CDD, "SetCDD" },
- { HOSTCMD_CMD_CAU_REG_ACCESS, "CAURegAccess" },
};
max_entries = ARRAY_SIZE(cmds);
@@ -698,6 +695,8 @@ static int mwl_fwcmd_encryption_set_cmd_info(struct hostcmd_cmd_set_key *cmd,
cpu_to_le32(ENCR_KEY_FLAG_PAIRWISE) :
cpu_to_le32(ENCR_KEY_FLAG_TXGROUPKEY);
break;
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ return 1;
default:
return -ENOTSUPP;
}
@@ -721,7 +720,7 @@ void mwl_fwcmd_int_enable(struct ieee80211_hw *hw)
if (mwl_fwcmd_chk_adapter(priv)) {
writel(0x00,
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_MASK);
- writel((MACREG_A2HRIC_BIT_MASK),
+ writel(MACREG_A2HRIC_BIT_MASK,
priv->iobase1 + MACREG_REG_A2H_INTERRUPT_MASK);
}
}
@@ -863,64 +862,6 @@ int mwl_fwcmd_get_stat(struct ieee80211_hw *hw,
return 0;
}
-int mwl_fwcmd_reg_bb(struct ieee80211_hw *hw, u8 flag, u32 reg, u32 *val)
-{
- struct mwl_priv *priv = hw->priv;
- struct hostcmd_cmd_bbp_reg_access *pcmd;
-
- pcmd = (struct hostcmd_cmd_bbp_reg_access *)&priv->pcmd_buf[0];
-
- spin_lock_bh(&priv->fwcmd_lock);
-
- memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_BBP_REG_ACCESS);
- pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
- pcmd->offset = cpu_to_le16(reg);
- pcmd->action = cpu_to_le16(flag);
- pcmd->value = *val;
-
- if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_BBP_REG_ACCESS)) {
- spin_unlock_bh(&priv->fwcmd_lock);
- wiphy_err(hw->wiphy, "failed execution\n");
- return -EIO;
- }
-
- *val = pcmd->value;
-
- spin_unlock_bh(&priv->fwcmd_lock);
-
- return 0;
-}
-
-int mwl_fwcmd_reg_rf(struct ieee80211_hw *hw, u8 flag, u32 reg, u32 *val)
-{
- struct mwl_priv *priv = hw->priv;
- struct hostcmd_cmd_rf_reg_access *pcmd;
-
- pcmd = (struct hostcmd_cmd_rf_reg_access *)&priv->pcmd_buf[0];
-
- spin_lock_bh(&priv->fwcmd_lock);
-
- memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_RF_REG_ACCESS);
- pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
- pcmd->offset = cpu_to_le16(reg);
- pcmd->action = cpu_to_le16(flag);
- pcmd->value = *val;
-
- if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_RF_REG_ACCESS)) {
- spin_unlock_bh(&priv->fwcmd_lock);
- wiphy_err(hw->wiphy, "failed execution\n");
- return -EIO;
- }
-
- *val = pcmd->value;
-
- spin_unlock_bh(&priv->fwcmd_lock);
-
- return 0;
-}
-
int mwl_fwcmd_radio_enable(struct ieee80211_hw *hw)
{
return mwl_fwcmd_802_11_radio_control(hw->priv, true, false);
@@ -2008,16 +1949,22 @@ int mwl_fwcmd_encryption_set_key(struct ieee80211_hw *hw,
rc = mwl_fwcmd_encryption_set_cmd_info(pcmd, addr, key);
if (rc) {
spin_unlock_bh(&priv->fwcmd_lock);
- wiphy_err(hw->wiphy, "encryption not support\n");
+ if (rc != 1)
+ wiphy_err(hw->wiphy, "encryption not support\n");
return rc;
}
idx = key->keyidx;
- if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
+ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
action = ENCR_ACTION_TYPE_SET_KEY;
- else
+ } else {
action = ENCR_ACTION_TYPE_SET_GROUP_KEY;
+ if (vif->type == NL80211_IFTYPE_MESH_POINT &&
+ !ether_addr_equal(mwl_vif->bssid, addr))
+ pcmd->key_param.key_info |=
+ cpu_to_le32(ENCR_KEY_FLAG_RXGROUPKEY);
+ }
switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
@@ -2095,7 +2042,8 @@ int mwl_fwcmd_encryption_remove_key(struct ieee80211_hw *hw,
rc = mwl_fwcmd_encryption_set_cmd_info(pcmd, addr, key);
if (rc) {
spin_unlock_bh(&priv->fwcmd_lock);
- wiphy_err(hw->wiphy, "encryption not support\n");
+ if (rc != 1)
+ wiphy_err(hw->wiphy, "encryption not support\n");
return rc;
}
@@ -2139,7 +2087,7 @@ int mwl_fwcmd_check_ba(struct ieee80211_hw *hw,
pcmd->action_type = cpu_to_le32(BA_CHECK_STREAM);
ether_addr_copy(&pcmd->ba_info.create_params.peer_mac_addr[0],
- stream->sta->addr);
+ stream->sta->addr);
pcmd->ba_info.create_params.tid = stream->tid;
ba_type = BASTREAM_FLAG_IMMEDIATE_TYPE;
ba_direction = BASTREAM_FLAG_DIRECTION_UPSTREAM;
@@ -2191,7 +2139,7 @@ int mwl_fwcmd_create_ba(struct ieee80211_hw *hw,
pcmd->ba_info.create_params.bar_thrs = cpu_to_le32(buf_size);
pcmd->ba_info.create_params.window_size = cpu_to_le32(buf_size);
ether_addr_copy(&pcmd->ba_info.create_params.peer_mac_addr[0],
- stream->sta->addr);
+ stream->sta->addr);
pcmd->ba_info.create_params.tid = stream->tid;
ba_type = BASTREAM_FLAG_IMMEDIATE_TYPE;
ba_direction = BASTREAM_FLAG_DIRECTION_UPSTREAM;
@@ -2453,39 +2401,10 @@ int mwl_fwcmd_set_cdd(struct ieee80211_hw *hw)
return 0;
}
-int mwl_fwcmd_reg_cau(struct ieee80211_hw *hw, u8 flag, u32 reg, u32 *val)
-{
- struct mwl_priv *priv = hw->priv;
- struct hostcmd_cmd_bbp_reg_access *pcmd;
-
- pcmd = (struct hostcmd_cmd_bbp_reg_access *)&priv->pcmd_buf[0];
-
- spin_lock_bh(&priv->fwcmd_lock);
-
- memset(pcmd, 0x00, sizeof(*pcmd));
- pcmd->cmd_hdr.cmd = cpu_to_le16(HOSTCMD_CMD_CAU_REG_ACCESS);
- pcmd->cmd_hdr.len = cpu_to_le16(sizeof(*pcmd));
- pcmd->offset = cpu_to_le16(reg);
- pcmd->action = cpu_to_le16(flag);
- pcmd->value = *val;
-
- if (mwl_fwcmd_exec_cmd(priv, HOSTCMD_CMD_CAU_REG_ACCESS)) {
- spin_unlock_bh(&priv->fwcmd_lock);
- wiphy_err(hw->wiphy, "failed execution\n");
- return -EIO;
- }
-
- *val = pcmd->value;
-
- spin_unlock_bh(&priv->fwcmd_lock);
-
- return 0;
-}
-
int mwl_fwcmd_send_mfg_cmd(struct mwl_priv *priv, char *mfgcmd)
{
struct hostcmd_header *pcmd;
- struct cmd_header *cmd_hd = (struct cmd_header *)(mfgcmd+4);
+ struct cmd_header *cmd_hd = (struct cmd_header *)(mfgcmd + 4);
u16 len;
u16 cmd;
@@ -2494,8 +2413,8 @@ int mwl_fwcmd_send_mfg_cmd(struct mwl_priv *priv, char *mfgcmd)
spin_lock_bh(&priv->fwcmd_lock);
len = le16_to_cpu(cmd_hd->len);
- memset(pcmd, 0x00, len+4);
- memcpy((char *)pcmd, mfgcmd, len+4);
+ memset(pcmd, 0x00, len + 4);
+ memcpy((char *)pcmd, mfgcmd, len + 4);
cmd = le16_to_cpu(cmd_hd->command);
if (mwl_fwcmd_exec_cmd(priv, cmd)) {
spin_unlock_bh(&priv->fwcmd_lock);
diff --git a/fwcmd.h b/fwcmd.h
index 202b05a..cc4b7d9 100644
--- a/fwcmd.h
+++ b/fwcmd.h
@@ -17,8 +17,8 @@
* functions.
*/
-#ifndef _fwcmd_h_
-#define _fwcmd_h_
+#ifndef _FWCMD_H_
+#define _FWCMD_H_
/* Define OpMode for SoftAP/Station mode
*
@@ -68,10 +68,6 @@ int mwl_fwcmd_set_hw_specs(struct ieee80211_hw *hw);
int mwl_fwcmd_get_stat(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
-int mwl_fwcmd_reg_bb(struct ieee80211_hw *hw, u8 flag, u32 reg, u32 *val);
-
-int mwl_fwcmd_reg_rf(struct ieee80211_hw *hw, u8 flag, u32 reg, u32 *val);
-
int mwl_fwcmd_radio_enable(struct ieee80211_hw *hw);
int mwl_fwcmd_radio_disable(struct ieee80211_hw *hw);
@@ -197,8 +193,6 @@ int mwl_fwcmd_set_fw_flush_timer(struct ieee80211_hw *hw, u32 value);
int mwl_fwcmd_set_cdd(struct ieee80211_hw *hw);
-int mwl_fwcmd_reg_cau(struct ieee80211_hw *hw, u8 flag, u32 reg, u32 *val);
-
int mwl_fwcmd_send_mfg_cmd(struct mwl_priv *priv, char *mfgcmd);
-#endif /* _fwcmd_h_ */
+#endif /* _FWCMD_H_ */
diff --git a/fwdl.h b/fwdl.h
index b117142..c3e0e57 100644
--- a/fwdl.h
+++ b/fwdl.h
@@ -17,9 +17,9 @@
* functions.
*/
-#ifndef _fwdl_h_
-#define _fwdl_h_
+#ifndef _FWDL_H_
+#define _FWDL_H_
int mwl_fwdl_download_firmware(struct ieee80211_hw *hw);
-#endif /* _fwdl_h_ */
+#endif /* _FWDL_H_ */
diff --git a/hostcmd.h b/hostcmd.h
index 8f265a1..37729b0 100644
--- a/hostcmd.h
+++ b/hostcmd.h
@@ -17,15 +17,13 @@
* structure.
*/
-#ifndef _hostcmd_h_
-#define _hostcmd_h_
+#ifndef _HOSTCMD_H_
+#define _HOSTCMD_H_
/* 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
-#define HOSTCMD_CMD_BBP_REG_ACCESS 0x001a
-#define HOSTCMD_CMD_RF_REG_ACCESS 0x001b
#define HOSTCMD_CMD_802_11_RADIO_CONTROL 0x001c
#define HOSTCMD_CMD_MEM_ADDR_ACCESS 0x001d
#define HOSTCMD_CMD_802_11_TX_POWER 0x001f
@@ -55,7 +53,6 @@
#define HOSTCMD_CMD_DWDS_ENABLE 0x1144
#define HOSTCMD_CMD_FW_FLUSH_TIMER 0x1148
#define HOSTCMD_CMD_SET_CDD 0x1150
-#define HOSTCMD_CMD_CAU_REG_ACCESS 0x1157
/* Define general result code for each command */
#define HOSTCMD_RESULT_OK 0x0000
@@ -105,6 +102,8 @@
#define KEY_TYPE_ID_TKIP 0x01
#define KEY_TYPE_ID_AES 0x02
+/* Group key for RX only */
+#define ENCR_KEY_FLAG_RXGROUPKEY 0x00000002
#define ENCR_KEY_FLAG_TXGROUPKEY 0x00000004
#define ENCR_KEY_FLAG_PAIRWISE 0x00000008
#define ENCR_KEY_FLAG_TSC_VALID 0x00000040
@@ -268,24 +267,6 @@ struct hostcmd_cmd_802_11_get_stat {
__le32 tx_cts_count;
} __packed;
-/* HOSTCMD_CMD_BBP_REG_ACCESS */
-struct hostcmd_cmd_bbp_reg_access {
- struct hostcmd_header cmd_hdr;
- __le16 action;
- __le16 offset;
- u8 value;
- u8 reserverd[3];
-} __packed;
-
-/* HOSTCMD_CMD_RF_REG_ACCESS */
-struct hostcmd_cmd_rf_reg_access {
- struct hostcmd_header cmd_hdr;
- __le16 action;
- __le16 offset;
- u8 value;
- u8 reserverd[3];
-} __packed;
-
/* HOSTCMD_CMD_802_11_RADIO_CONTROL */
struct hostcmd_cmd_802_11_radio_control {
struct hostcmd_header cmd_hdr;
@@ -804,4 +785,4 @@ struct hostcmd_cmd_set_cdd {
__le32 enable;
} __packed;
-#endif /* _hostcmd_h_ */
+#endif /* _HOSTCMD_H_ */
diff --git a/isr.c b/isr.c
index 20b6088..227b39d 100644
--- a/isr.c
+++ b/isr.c
@@ -70,11 +70,17 @@ irqreturn_t mwl_isr(int irq, void *dev_id)
int_status &= ~MACREG_A2HRIC_BIT_QUE_EMPTY;
if (!priv->is_qe_schedule) {
- status = readl(int_status_mask);
- writel((status & ~MACREG_A2HRIC_BIT_QUE_EMPTY),
- int_status_mask);
- tasklet_schedule(&priv->qe_task);
- priv->is_qe_schedule = true;
+ if (time_after(jiffies,
+ (priv->qe_trigger_time + 1))) {
+ status = readl(int_status_mask);
+ writel((status &
+ ~MACREG_A2HRIC_BIT_QUE_EMPTY),
+ int_status_mask);
+ tasklet_schedule(&priv->qe_task);
+ priv->qe_trigger_num++;
+ priv->is_qe_schedule = true;
+ priv->qe_trigger_time = jiffies;
+ }
}
}
diff --git a/isr.h b/isr.h
index 2598115..4c317e2 100644
--- a/isr.h
+++ b/isr.h
@@ -15,12 +15,12 @@
/* Description: This file defines interrupt related functions. */
-#ifndef _isr_h_
-#define _isr_h_
+#ifndef _ISR_H_
+#define _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 /* _isr_h_ */
+#endif /* _ISR_H_ */
diff --git a/mac80211.c b/mac80211.c
index 85e5168..d55be10 100644
--- a/mac80211.c
+++ b/mac80211.c
@@ -572,11 +572,19 @@ static int mwl_mac80211_get_survey(struct ieee80211_hw *hw,
return 0;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
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)
+#else
+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, bool amsdu)
+#endif
{
int rc = 0;
struct mwl_priv *priv = hw->priv;
@@ -638,8 +646,9 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
mwl_fwcmd_remove_stream(hw, stream);
ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
- } else
+ } else {
rc = -EPERM;
+ }
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
if (stream) {
@@ -664,8 +673,9 @@ static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw,
"ampdu operation error code: %d\n",
rc);
}
- } else
+ } else {
rc = -EPERM;
+ }
break;
default:
rc = -ENOTSUPP;
diff --git a/main.c b/main.c
index ffe3f31..a3d038f 100644
--- a/main.c
+++ b/main.c
@@ -50,14 +50,12 @@ static struct mwl_chip_info mwl_chip_tbl[] = {
[MWL8864] = {
.part_name = "88W8864",
.fw_image = "mwlwifi/88W8864.bin",
- .mfg_fw_image = "./88W8864-MFG.bin",
.antenna_tx = ANTENNA_TX_4_AUTO,
.antenna_rx = ANTENNA_RX_4_AUTO,
},
[MWL8897] = {
.part_name = "88W8897",
.fw_image = "mwlwifi/88W8897.bin",
- .mfg_fw_image = "./88W8897-MFG.bin",
.antenna_tx = ANTENNA_TX_2,
.antenna_rx = ANTENNA_RX_2,
},
@@ -213,24 +211,30 @@ static int mwl_init_firmware(struct mwl_priv *priv, const char *fw_name)
#ifdef CONFIG_SUPPORT_MFG
if (priv->mfg_mode)
- rc = mwl_mfg_request_firmware(priv, fw_name);
+ rc = mwl_mfg_request_firmware(priv);
else
#endif
rc = request_firmware((const struct firmware **)&priv->fw_ucode,
fw_name, &priv->pdev->dev);
if (rc) {
- wiphy_err(priv->hw->wiphy,
- "%s: cannot load firmware image <%s>\n",
- MWL_DRV_NAME, fw_name);
+ if (priv->mfg_mode)
+ wiphy_err(priv->hw->wiphy, "cannot find firmware\n");
+ else
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot find firmware image <%s>\n",
+ MWL_DRV_NAME, fw_name);
goto err_load_fw;
}
rc = mwl_fwdl_download_firmware(priv->hw);
if (rc) {
- wiphy_err(priv->hw->wiphy,
- "%s: cannot download firmware image <%s>\n",
- MWL_DRV_NAME, fw_name);
+ if (priv->mfg_mode)
+ wiphy_err(priv->hw->wiphy, "download firmware fail\n");
+ else
+ wiphy_err(priv->hw->wiphy,
+ "%s: cannot download firmware image <%s>\n",
+ MWL_DRV_NAME, fw_name);
goto err_download_fw;
}
@@ -536,6 +540,16 @@ static int mwl_wl_init(struct mwl_priv *priv)
ieee80211_hw_set(hw, AP_LINK_PS);
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
+ hw->flags |= IEEE80211_HW_SUPPORTS_PER_STA_GTK |
+ IEEE80211_HW_MFP_CAPABLE;
+#else
+ ieee80211_hw_set(hw, SUPPORTS_PER_STA_GTK);
+ ieee80211_hw_set(hw, HW_MFP_CAPABLE);
+#endif
+
+ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
hw->vif_data_size = sizeof(struct mwl_vif);
hw->sta_data_size = sizeof(struct mwl_sta);
@@ -567,6 +581,8 @@ static int mwl_wl_init(struct mwl_priv *priv)
priv->recv_limit = SYSADPT_RECEIVE_LIMIT;
priv->is_rx_schedule = false;
priv->is_qe_schedule = false;
+ priv->qe_trigger_num = 0;
+ priv->qe_trigger_time = jiffies;
spin_lock_init(&priv->tx_desc_lock);
spin_lock_init(&priv->rx_desc_lock);
@@ -755,10 +771,8 @@ static int mwl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
fw_name = mwl_chip_tbl[priv->chip_type].fw_image;
#ifdef CONFIG_SUPPORT_MFG
- if (mfg_mode) {
+ if (mfg_mode)
mwl_mfg_handler_init(priv);
- fw_name = mwl_chip_tbl[priv->chip_type].mfg_fw_image;
- }
#endif
rc = mwl_init_firmware(priv, fw_name);
diff --git a/rx.c b/rx.c
index 3ed9d59..1795744 100644
--- a/rx.c
+++ b/rx.c
@@ -542,7 +542,11 @@ void mwl_rx_recv(unsigned long data)
else
mwl_vif = mwl_rx_find_vif_bss(priv, wh->addr2);
- if (mwl_vif && mwl_vif->is_hw_crypto_enabled) {
+ if ((mwl_vif && mwl_vif->is_hw_crypto_enabled) ||
+ is_multicast_ether_addr(wh->addr1) ||
+ (ieee80211_is_mgmt(wh->frame_control) &&
+ ieee80211_has_protected(wh->frame_control) &&
+ !is_multicast_ether_addr(wh->addr1))) {
/* When MMIC ERROR is encountered
* by the firmware, payload is
* dropped and only 32 bytes of
diff --git a/rx.h b/rx.h
index d32c558..5b9b647 100644
--- a/rx.h
+++ b/rx.h
@@ -15,11 +15,11 @@
/* Description: This file defines receive related functions. */
-#ifndef _rx_h_
-#define _rx_h_
+#ifndef _RX_H_
+#define _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 /* _rx_h_ */
+#endif /* _RX_H_ */
diff --git a/sysadpt.h b/sysadpt.h
index 8a1706a..9944197 100644
--- a/sysadpt.h
+++ b/sysadpt.h
@@ -15,8 +15,8 @@
/* Description: This file defines system adaptation related information. */
-#ifndef _mwl_sysadpt_h_
-#define _mwl_sysadpt_h_
+#ifndef _SYSADPT_H_
+#define _SYSADPT_H_
#define SYSADPT_MAX_NUM_CHANNELS 64
@@ -70,4 +70,4 @@
#define SYSADPT_MAX_TID 8
-#endif /* _mwl_sysadpt_h_ */
+#endif /* _SYSADPT_H_ */
diff --git a/tx.c b/tx.c
index 85a7c7c..ac12aec 100644
--- a/tx.c
+++ b/tx.c
@@ -424,7 +424,10 @@ static inline void mwl_tx_skb(struct mwl_priv *priv, int desc_num,
dma_data = (struct mwl_dma_data *)tx_skb->data;
wh = &dma_data->wh;
- if (ieee80211_is_data(wh->frame_control)) {
+ if (ieee80211_is_data(wh->frame_control) ||
+ (ieee80211_is_mgmt(wh->frame_control) &&
+ ieee80211_has_protected(wh->frame_control) &&
+ !is_multicast_ether_addr(wh->addr1))) {
if (is_multicast_ether_addr(wh->addr1)) {
if (ccmp) {
mwl_tx_insert_ccmp_hdr(dma_data->data,
@@ -1138,10 +1141,12 @@ void mwl_tx_done(unsigned long data)
amsdu_pkts);
dev_kfree_skb_any(done_skb);
done_skb = NULL;
- } else
+ } else {
mwl_tx_prepare_info(hw, rate, info);
- } else
+ }
+ } else {
mwl_tx_prepare_info(hw, 0, info);
+ }
if (done_skb) {
/* Remove H/W dma header */
diff --git a/tx.h b/tx.h
index ef1c7c5..e4b4ff4 100644
--- a/tx.h
+++ b/tx.h
@@ -15,8 +15,8 @@
/* Description: This file defines transmit related functions. */
-#ifndef _tx_h_
-#define _tx_h_
+#ifndef _TX_H_
+#define _TX_H_
int mwl_tx_init(struct ieee80211_hw *hw);
void mwl_tx_deinit(struct ieee80211_hw *hw);
@@ -33,4 +33,4 @@ void mwl_tx_done(unsigned long data);
void mwl_tx_flush_amsdu(unsigned long data);
void mwl_tx_del_sta_amsdu_pkts(struct ieee80211_sta *sta);
-#endif /* _tx_h_ */
+#endif /* _TX_H_ */