diff options
author | David Lin <dlin@marvell.com> | 2015-11-24 16:39:14 +0800 |
---|---|---|
committer | David Lin <dlin@marvell.com> | 2015-11-24 16:39:14 +0800 |
commit | ea52835827ac5fc71665cee7a435e157b40ffe5f (patch) | |
tree | abf7c7e724708e2782ee94828dbad630957942d6 | |
parent | 2e54ced68eec408c9c0e8c3742105bf7bc724f99 (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.c | 59 | ||||
-rw-r--r-- | debugfs.h | 6 | ||||
-rw-r--r-- | dev.h | 48 | ||||
-rw-r--r-- | fwcmd.c | 119 | ||||
-rw-r--r-- | fwcmd.h | 12 | ||||
-rw-r--r-- | fwdl.h | 6 | ||||
-rw-r--r-- | hostcmd.h | 29 | ||||
-rw-r--r-- | isr.c | 16 | ||||
-rw-r--r-- | isr.h | 6 | ||||
-rw-r--r-- | mac80211.c | 14 | ||||
-rw-r--r-- | main.c | 38 | ||||
-rw-r--r-- | rx.c | 6 | ||||
-rw-r--r-- | rx.h | 6 | ||||
-rw-r--r-- | sysadpt.h | 6 | ||||
-rw-r--r-- | tx.c | 11 | ||||
-rw-r--r-- | tx.h | 6 |
16 files changed, 166 insertions, 222 deletions
@@ -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; @@ -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_ */ @@ -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_ */ @@ -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); @@ -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_ */ @@ -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_ */ @@ -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_ */ @@ -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; + } } } @@ -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_ */ @@ -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; @@ -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); @@ -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 @@ -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_ */ @@ -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_ */ @@ -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 */ @@ -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_ */ |