mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-06 06:35:12 +00:00
brcfmac
* support bcm4359 which can operate in two bands concurrently * disable runtime pm for USB avoiding issues * use generic pm callback in PCIe driver * support wowlan wake indication reporting * add beamforming support * unified handling of firmware files ath10k * support Manegement Frame Protection (MFP) * add thermal throttling support for 10.4 firmware * add support for pktlog in QCA99X0 * add debugfs file to enable Bluetooth coexistence feature * use firmware's native mesh interface type instead of raw mode iwlwifi * BT coex improvements * D3 operation bugfixes * rate control improvements * firmware debugging infra improvements * ground work for multi Rx * various security fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJWZcQtAAoJEG4XJFUm622bgcMH/1VRwtzAKpYVwAyAN0MtVLxe uANi0Pw1PmEAeEI3TxEBckEH0JYfpg+aAwX7S8scnQSvLP3FYeC5IcHG551vlh0s FlkGexcXqGrDqjt8mz8hxqqAmMH9YEVlzj2HJf6YFjNS4K84CEgpaSjaSG8S7Wc8 hTSA5K+XxrnEeX41W7FYmeBFLejisg0gVTkS3ZCe4qYz4Gh1oamoA0pOdU+AYOMy 0XBkCT8fqTVXWLHh9/+J7IZOYrjBl4rVaHofeygEAfSRNNfmmjZXX1R+FCQoJEZC IOEQ31T64G4A37t2N2RGOhiG+2vckdbPg2JsqJosI1L2OZSBbeGZsVW48w+5cgc= =GQDA -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-next-for-davem-2015-12-07' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next Kalle Vallo says: ==================== brcfmac * support bcm4359 which can operate in two bands concurrently * disable runtime pm for USB avoiding issues * use generic pm callback in PCIe driver * support wowlan wake indication reporting * add beamforming support * unified handling of firmware files ath10k * support Manegement Frame Protection (MFP) * add thermal throttling support for 10.4 firmware * add support for pktlog in QCA99X0 * add debugfs file to enable Bluetooth coexistence feature * use firmware's native mesh interface type instead of raw mode iwlwifi * BT coex improvements * D3 operation bugfixes * rate control improvements * firmware debugging infra improvements * ground work for multi Rx * various security fixes ==================== Conflicts: drivers/net/wireless/ath/ath10k/pci.c The conflict resolution at: http://article.gmane.org/gmane.linux.kernel.next/37391 by Stephen Rothwell was used. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
e370abd956
147 changed files with 3290 additions and 2066 deletions
|
@ -2,6 +2,7 @@ config ATH10K
|
|||
tristate "Atheros 802.11ac wireless cards support"
|
||||
depends on MAC80211 && HAS_DMA
|
||||
select ATH_COMMON
|
||||
select CRC32
|
||||
---help---
|
||||
This module adds support for wireless adapters based on
|
||||
Atheros IEEE 802.11ac family of chipsets.
|
||||
|
|
|
@ -59,6 +59,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
|
||||
.fw = {
|
||||
.dir = QCA988X_HW_2_0_FW_DIR,
|
||||
.fw = QCA988X_HW_2_0_FW_FILE,
|
||||
|
@ -95,6 +96,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
|
||||
.fw = {
|
||||
.dir = QCA6174_HW_2_1_FW_DIR,
|
||||
.fw = QCA6174_HW_2_1_FW_FILE,
|
||||
|
@ -113,6 +115,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
|
||||
.fw = {
|
||||
.dir = QCA6174_HW_3_0_FW_DIR,
|
||||
.fw = QCA6174_HW_3_0_FW_FILE,
|
||||
|
@ -131,6 +134,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.otp_exe_param = 0,
|
||||
.channel_counters_freq_hz = 88000,
|
||||
.max_probe_resp_desc_thres = 0,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
|
||||
.fw = {
|
||||
/* uses same binaries as hw3.0 */
|
||||
.dir = QCA6174_HW_3_0_FW_DIR,
|
||||
|
@ -151,6 +155,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.continuous_frag_desc = true,
|
||||
.channel_counters_freq_hz = 150000,
|
||||
.max_probe_resp_desc_thres = 24,
|
||||
.hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
|
||||
.fw = {
|
||||
.dir = QCA99X0_HW_2_0_FW_DIR,
|
||||
.fw = QCA99X0_HW_2_0_FW_FILE,
|
||||
|
@ -211,6 +216,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
|
|||
[ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
|
||||
[ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
|
||||
[ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
|
||||
[ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",
|
||||
};
|
||||
|
||||
static unsigned int ath10k_core_get_fw_feature_str(char *buf,
|
||||
|
@ -887,7 +893,7 @@ out:
|
|||
if (!ar->board_data || !ar->board_len) {
|
||||
ath10k_err(ar,
|
||||
"failed to fetch board data for %s from %s/%s\n",
|
||||
ar->hw_params.fw.dir, boardname, filename);
|
||||
boardname, ar->hw_params.fw.dir, filename);
|
||||
ret = -ENODATA;
|
||||
goto err;
|
||||
}
|
||||
|
@ -1790,9 +1796,11 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
goto err_power_down;
|
||||
}
|
||||
|
||||
ath10k_debug_print_hwfw_info(ar);
|
||||
|
||||
ret = ath10k_core_get_board_id_from_otp(ar);
|
||||
if (ret && ret != -EOPNOTSUPP) {
|
||||
ath10k_err(ar, "failed to get board id from otp for qca99x0: %d\n",
|
||||
ath10k_err(ar, "failed to get board id from otp: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1803,6 +1811,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
goto err_free_firmware_files;
|
||||
}
|
||||
|
||||
ath10k_debug_print_board_info(ar);
|
||||
|
||||
ret = ath10k_core_init_firmware_features(ar);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "fatal problem with firmware features: %d\n",
|
||||
|
@ -1825,7 +1835,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
goto err_unlock;
|
||||
}
|
||||
|
||||
ath10k_print_driver_info(ar);
|
||||
ath10k_debug_print_boot_info(ar);
|
||||
ath10k_core_stop(ar);
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
|
|
@ -81,26 +81,20 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
enum ath10k_skb_flags {
|
||||
ATH10K_SKB_F_NO_HWCRYPT = BIT(0),
|
||||
ATH10K_SKB_F_DTIM_ZERO = BIT(1),
|
||||
ATH10K_SKB_F_DELIVER_CAB = BIT(2),
|
||||
ATH10K_SKB_F_MGMT = BIT(3),
|
||||
ATH10K_SKB_F_QOS = BIT(4),
|
||||
};
|
||||
|
||||
struct ath10k_skb_cb {
|
||||
dma_addr_t paddr;
|
||||
u8 flags;
|
||||
u8 eid;
|
||||
u8 vdev_id;
|
||||
enum ath10k_hw_txrx_mode txmode;
|
||||
bool is_protected;
|
||||
|
||||
struct {
|
||||
u8 tid;
|
||||
u16 freq;
|
||||
bool is_offchan;
|
||||
bool nohwcrypt;
|
||||
struct ath10k_htt_txbuf *txbuf;
|
||||
u32 txbuf_paddr;
|
||||
} __packed htt;
|
||||
|
||||
struct {
|
||||
bool dtim_zero;
|
||||
bool deliver_cab;
|
||||
} bcn;
|
||||
u16 msdu_id;
|
||||
struct ieee80211_vif *vif;
|
||||
} __packed;
|
||||
|
||||
struct ath10k_skb_rxcb {
|
||||
|
@ -151,6 +145,7 @@ struct ath10k_wmi {
|
|||
struct wmi_vdev_param_map *vdev_param;
|
||||
struct wmi_pdev_param_map *pdev_param;
|
||||
const struct wmi_ops *ops;
|
||||
const struct wmi_peer_flags_map *peer_flags;
|
||||
|
||||
u32 num_mem_chunks;
|
||||
u32 rx_decap_mode;
|
||||
|
@ -512,6 +507,9 @@ enum ath10k_fw_features {
|
|||
/* Firmware Supports Adaptive CCA*/
|
||||
ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA = 11,
|
||||
|
||||
/* Firmware supports management frame protection */
|
||||
ATH10K_FW_FEATURE_MFP_SUPPORT = 12,
|
||||
|
||||
/* keep last */
|
||||
ATH10K_FW_FEATURE_COUNT,
|
||||
};
|
||||
|
@ -534,6 +532,9 @@ enum ath10k_dev_flags {
|
|||
|
||||
/* Disable HW crypto engine */
|
||||
ATH10K_FLAG_HW_CRYPTO_DISABLED,
|
||||
|
||||
/* Bluetooth coexistance enabled */
|
||||
ATH10K_FLAG_BTCOEX,
|
||||
};
|
||||
|
||||
enum ath10k_cal_mode {
|
||||
|
@ -662,6 +663,9 @@ struct ath10k {
|
|||
*/
|
||||
u32 max_probe_resp_desc_thres;
|
||||
|
||||
/* The padding bytes's location is different on various chips */
|
||||
enum ath10k_hw_4addr_pad hw_4addr_pad;
|
||||
|
||||
struct ath10k_hw_params_fw {
|
||||
const char *dir;
|
||||
const char *fw;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <linux/debugfs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
|
@ -122,28 +124,51 @@ void ath10k_info(struct ath10k *ar, const char *fmt, ...)
|
|||
}
|
||||
EXPORT_SYMBOL(ath10k_info);
|
||||
|
||||
void ath10k_print_driver_info(struct ath10k *ar)
|
||||
void ath10k_debug_print_hwfw_info(struct ath10k *ar)
|
||||
{
|
||||
char fw_features[128] = {};
|
||||
char boardinfo[100];
|
||||
|
||||
ath10k_core_get_fw_features_str(ar, fw_features, sizeof(fw_features));
|
||||
|
||||
if (ar->id.bmi_ids_valid)
|
||||
scnprintf(boardinfo, sizeof(boardinfo), "bmi %d:%d",
|
||||
ar->id.bmi_chip_id, ar->id.bmi_board_id);
|
||||
else
|
||||
scnprintf(boardinfo, sizeof(boardinfo), "sub %04x:%04x",
|
||||
ar->id.subsystem_vendor, ar->id.subsystem_device);
|
||||
|
||||
ath10k_info(ar, "%s (0x%08x, 0x%08x %s) fw %s fwapi %d bdapi %d htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d features %s\n",
|
||||
ath10k_info(ar, "%s target 0x%08x chip_id 0x%08x sub %04x:%04x",
|
||||
ar->hw_params.name,
|
||||
ar->target_version,
|
||||
ar->chip_id,
|
||||
boardinfo,
|
||||
ar->id.subsystem_vendor, ar->id.subsystem_device);
|
||||
|
||||
ath10k_info(ar, "kconfig debug %d debugfs %d tracing %d dfs %d testmode %d\n",
|
||||
config_enabled(CONFIG_ATH10K_DEBUG),
|
||||
config_enabled(CONFIG_ATH10K_DEBUGFS),
|
||||
config_enabled(CONFIG_ATH10K_TRACING),
|
||||
config_enabled(CONFIG_ATH10K_DFS_CERTIFIED),
|
||||
config_enabled(CONFIG_NL80211_TESTMODE));
|
||||
|
||||
ath10k_info(ar, "firmware ver %s api %d features %s crc32 %08x\n",
|
||||
ar->hw->wiphy->fw_version,
|
||||
ar->fw_api,
|
||||
fw_features,
|
||||
crc32_le(0, ar->firmware->data, ar->firmware->size));
|
||||
}
|
||||
|
||||
void ath10k_debug_print_board_info(struct ath10k *ar)
|
||||
{
|
||||
char boardinfo[100];
|
||||
|
||||
if (ar->id.bmi_ids_valid)
|
||||
scnprintf(boardinfo, sizeof(boardinfo), "%d:%d",
|
||||
ar->id.bmi_chip_id, ar->id.bmi_board_id);
|
||||
else
|
||||
scnprintf(boardinfo, sizeof(boardinfo), "N/A");
|
||||
|
||||
ath10k_info(ar, "board_file api %d bmi_id %s crc32 %08x",
|
||||
ar->bd_api,
|
||||
boardinfo,
|
||||
crc32_le(0, ar->board->data, ar->board->size));
|
||||
}
|
||||
|
||||
void ath10k_debug_print_boot_info(struct ath10k *ar)
|
||||
{
|
||||
ath10k_info(ar, "htt-ver %d.%d wmi-op %d htt-op %d cal %s max-sta %d raw %d hwcrypto %d\n",
|
||||
ar->htt.target_version_major,
|
||||
ar->htt.target_version_minor,
|
||||
ar->wmi.op_version,
|
||||
|
@ -151,14 +176,14 @@ void ath10k_print_driver_info(struct ath10k *ar)
|
|||
ath10k_cal_mode_str(ar->cal_mode),
|
||||
ar->max_num_stations,
|
||||
test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags),
|
||||
!test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags),
|
||||
fw_features);
|
||||
ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
|
||||
config_enabled(CONFIG_ATH10K_DEBUG),
|
||||
config_enabled(CONFIG_ATH10K_DEBUGFS),
|
||||
config_enabled(CONFIG_ATH10K_TRACING),
|
||||
config_enabled(CONFIG_ATH10K_DFS_CERTIFIED),
|
||||
config_enabled(CONFIG_NL80211_TESTMODE));
|
||||
!test_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags));
|
||||
}
|
||||
|
||||
void ath10k_print_driver_info(struct ath10k *ar)
|
||||
{
|
||||
ath10k_debug_print_hwfw_info(ar);
|
||||
ath10k_debug_print_board_info(ar);
|
||||
ath10k_debug_print_boot_info(ar);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_print_driver_info);
|
||||
|
||||
|
@ -2074,6 +2099,121 @@ static const struct file_operations fops_quiet_period = {
|
|||
.open = simple_open
|
||||
};
|
||||
|
||||
static ssize_t ath10k_write_btcoex(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
char buf[32];
|
||||
size_t buf_size;
|
||||
bool val;
|
||||
|
||||
buf_size = min(count, (sizeof(buf) - 1));
|
||||
if (copy_from_user(buf, ubuf, buf_size))
|
||||
return -EFAULT;
|
||||
|
||||
buf[buf_size] = '\0';
|
||||
|
||||
if (strtobool(buf, &val) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val))
|
||||
goto exit;
|
||||
|
||||
if (val)
|
||||
set_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
|
||||
else
|
||||
clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
|
||||
|
||||
if (ar->state != ATH10K_STATE_ON)
|
||||
goto exit;
|
||||
|
||||
ath10k_info(ar, "restarting firmware due to btcoex change");
|
||||
|
||||
queue_work(ar->workqueue, &ar->restart_work);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
char buf[32];
|
||||
struct ath10k *ar = file->private_data;
|
||||
int len = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
len = scnprintf(buf, sizeof(buf) - len, "%d\n",
|
||||
test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags));
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return simple_read_from_buffer(ubuf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_btcoex = {
|
||||
.read = ath10k_read_btcoex,
|
||||
.write = ath10k_write_btcoex,
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
static ssize_t ath10k_debug_fw_checksums_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
unsigned int len = 0, buf_len = 4096;
|
||||
ssize_t ret_cnt;
|
||||
char *buf;
|
||||
|
||||
buf = kzalloc(buf_len, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (len > buf_len)
|
||||
len = buf_len;
|
||||
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"firmware-N.bin\t\t%08x\n",
|
||||
crc32_le(0, ar->firmware->data, ar->firmware->size));
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"athwlan\t\t\t%08x\n",
|
||||
crc32_le(0, ar->firmware_data, ar->firmware_len));
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"otp\t\t\t%08x\n",
|
||||
crc32_le(0, ar->otp_data, ar->otp_len));
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"codeswap\t\t%08x\n",
|
||||
crc32_le(0, ar->swap.firmware_codeswap_data,
|
||||
ar->swap.firmware_codeswap_len));
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"board-N.bin\t\t%08x\n",
|
||||
crc32_le(0, ar->board->data, ar->board->size));
|
||||
len += scnprintf(buf + len, buf_len - len,
|
||||
"board\t\t\t%08x\n",
|
||||
crc32_le(0, ar->board_data, ar->board_len));
|
||||
|
||||
ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
kfree(buf);
|
||||
return ret_cnt;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_fw_checksums = {
|
||||
.read = ath10k_debug_fw_checksums_read,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int ath10k_debug_create(struct ath10k *ar)
|
||||
{
|
||||
ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
|
||||
|
@ -2123,8 +2263,8 @@ int ath10k_debug_register(struct ath10k *ar)
|
|||
debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar,
|
||||
&fops_wmi_services);
|
||||
|
||||
debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_simulate_fw_crash);
|
||||
debugfs_create_file("simulate_fw_crash", S_IRUSR | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_simulate_fw_crash);
|
||||
|
||||
debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_fw_crash_dump);
|
||||
|
@ -2141,15 +2281,15 @@ int ath10k_debug_register(struct ath10k *ar)
|
|||
debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_chip_id);
|
||||
|
||||
debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_htt_stats_mask);
|
||||
debugfs_create_file("htt_stats_mask", S_IRUSR | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_htt_stats_mask);
|
||||
|
||||
debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar,
|
||||
&fops_htt_max_amsdu_ampdu);
|
||||
|
||||
debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_fw_dbglog);
|
||||
debugfs_create_file("fw_dbglog", S_IRUSR | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_fw_dbglog);
|
||||
|
||||
debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_cal_data);
|
||||
|
@ -2183,6 +2323,13 @@ int ath10k_debug_register(struct ath10k *ar)
|
|||
debugfs_create_file("tpc_stats", S_IRUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_tpc_stats);
|
||||
|
||||
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
|
||||
debugfs_create_file("btcoex", S_IRUGO | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_btcoex);
|
||||
|
||||
debugfs_create_file("fw_checksums", S_IRUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_fw_checksums);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,10 @@ extern unsigned int ath10k_debug_mask;
|
|||
__printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...);
|
||||
__printf(2, 3) void ath10k_err(struct ath10k *ar, const char *fmt, ...);
|
||||
__printf(2, 3) void ath10k_warn(struct ath10k *ar, const char *fmt, ...);
|
||||
|
||||
void ath10k_debug_print_hwfw_info(struct ath10k *ar);
|
||||
void ath10k_debug_print_board_info(struct ath10k *ar);
|
||||
void ath10k_debug_print_boot_info(struct ath10k *ar);
|
||||
void ath10k_print_driver_info(struct ath10k *ar);
|
||||
|
||||
#ifdef CONFIG_ATH10K_DEBUGFS
|
||||
|
|
|
@ -166,8 +166,13 @@ struct htt_data_tx_desc {
|
|||
__le16 len;
|
||||
__le16 id;
|
||||
__le32 frags_paddr;
|
||||
__le16 peerid;
|
||||
__le16 freq;
|
||||
union {
|
||||
__le32 peerid;
|
||||
struct {
|
||||
__le16 peerid;
|
||||
__le16 freq;
|
||||
} __packed offchan_tx;
|
||||
} __packed;
|
||||
u8 prefetch[0]; /* start of frame, for FW classification engine */
|
||||
} __packed;
|
||||
|
||||
|
@ -1597,6 +1602,10 @@ void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt, bool limit_mgmt_desc);
|
|||
int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb);
|
||||
void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id);
|
||||
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *);
|
||||
int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *);
|
||||
int ath10k_htt_tx(struct ath10k_htt *htt,
|
||||
enum ath10k_hw_txrx_mode txmode,
|
||||
struct sk_buff *msdu);
|
||||
void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
|
||||
struct sk_buff *skb);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -536,7 +536,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
|
|||
|
||||
size = htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring);
|
||||
|
||||
vaddr = dma_alloc_coherent(htt->ar->dev, size, &paddr, GFP_DMA);
|
||||
vaddr = dma_alloc_coherent(htt->ar->dev, size, &paddr, GFP_KERNEL);
|
||||
if (!vaddr)
|
||||
goto err_dma_ring;
|
||||
|
||||
|
@ -545,7 +545,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
|
|||
|
||||
vaddr = dma_alloc_coherent(htt->ar->dev,
|
||||
sizeof(*htt->rx_ring.alloc_idx.vaddr),
|
||||
&paddr, GFP_DMA);
|
||||
&paddr, GFP_KERNEL);
|
||||
if (!vaddr)
|
||||
goto err_dma_idx;
|
||||
|
||||
|
@ -674,7 +674,7 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
|
|||
rate &= ~RX_PPDU_START_RATE_FLAG;
|
||||
|
||||
sband = &ar->mac.sbands[status->band];
|
||||
status->rate_idx = ath10k_mac_hw_rate_to_idx(sband, rate);
|
||||
status->rate_idx = ath10k_mac_hw_rate_to_idx(sband, rate, cck);
|
||||
break;
|
||||
case HTT_RX_HT:
|
||||
case HTT_RX_HT_WITH_TXBF:
|
||||
|
@ -1114,7 +1114,20 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
|
|||
*/
|
||||
|
||||
/* pull decapped header and copy SA & DA */
|
||||
hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
if ((ar->hw_params.hw_4addr_pad == ATH10K_HW_4ADDR_PAD_BEFORE) &&
|
||||
ieee80211_has_a4(((struct ieee80211_hdr *)first_hdr)->frame_control)) {
|
||||
/* The QCA99X0 4 address mode pad 2 bytes at the
|
||||
* beginning of MSDU
|
||||
*/
|
||||
hdr = (struct ieee80211_hdr *)(msdu->data + 2);
|
||||
/* The skb length need be extended 2 as the 2 bytes at the tail
|
||||
* be excluded due to the padding
|
||||
*/
|
||||
skb_put(msdu, 2);
|
||||
} else {
|
||||
hdr = (struct ieee80211_hdr *)(msdu->data);
|
||||
}
|
||||
|
||||
hdr_len = ath10k_htt_rx_nwifi_hdrlen(ar, hdr);
|
||||
ether_addr_copy(da, ieee80211_get_DA(hdr));
|
||||
ether_addr_copy(sa, ieee80211_get_SA(hdr));
|
||||
|
@ -2127,6 +2140,18 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
|||
}
|
||||
EXPORT_SYMBOL(ath10k_htt_t2h_msg_handler);
|
||||
|
||||
void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ath10k_pktlog_10_4_hdr *hdr =
|
||||
(struct ath10k_pktlog_10_4_hdr *)skb->data;
|
||||
|
||||
trace_ath10k_htt_pktlog(ar, hdr->payload,
|
||||
sizeof(*hdr) + __le16_to_cpu(hdr->size));
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler);
|
||||
|
||||
static void ath10k_htt_txrx_compl_task(unsigned long ptr)
|
||||
{
|
||||
struct ath10k_htt *htt = (struct ath10k_htt *)ptr;
|
||||
|
|
|
@ -111,7 +111,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
|
|||
size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf);
|
||||
htt->txbuf.vaddr = dma_alloc_coherent(ar->dev, size,
|
||||
&htt->txbuf.paddr,
|
||||
GFP_DMA);
|
||||
GFP_KERNEL);
|
||||
if (!htt->txbuf.vaddr) {
|
||||
ath10k_err(ar, "failed to alloc tx buffer\n");
|
||||
ret = -ENOMEM;
|
||||
|
@ -124,7 +124,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
|
|||
size = htt->max_num_pending_tx * sizeof(struct htt_msdu_ext_desc);
|
||||
htt->frag_desc.vaddr = dma_alloc_coherent(ar->dev, size,
|
||||
&htt->frag_desc.paddr,
|
||||
GFP_DMA);
|
||||
GFP_KERNEL);
|
||||
if (!htt->frag_desc.vaddr) {
|
||||
ath10k_warn(ar, "failed to alloc fragment desc memory\n");
|
||||
ret = -ENOMEM;
|
||||
|
@ -439,6 +439,35 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static u8 ath10k_htt_tx_get_vdev_id(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
|
||||
struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
|
||||
return ar->scan.vdev_id;
|
||||
else if (cb->vif)
|
||||
return arvif->vdev_id;
|
||||
else if (ar->monitor_started)
|
||||
return ar->monitor_vdev_id;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 ath10k_htt_tx_get_tid(struct sk_buff *skb, bool is_eth)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
|
||||
|
||||
if (!is_eth && ieee80211_is_mgmt(hdr->frame_control))
|
||||
return HTT_DATA_TX_EXT_TID_MGMT;
|
||||
else if (cb->flags & ATH10K_SKB_F_QOS)
|
||||
return skb->priority % IEEE80211_QOS_CTL_TID_MASK;
|
||||
else
|
||||
return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
|
||||
}
|
||||
|
||||
int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
||||
{
|
||||
struct ath10k *ar = htt->ar;
|
||||
|
@ -446,7 +475,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
struct sk_buff *txdesc = NULL;
|
||||
struct htt_cmd *cmd;
|
||||
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
|
||||
u8 vdev_id = skb_cb->vdev_id;
|
||||
u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
|
||||
int len = 0;
|
||||
int msdu_id = -1;
|
||||
int res;
|
||||
|
@ -477,6 +506,13 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
|
||||
msdu_id = res;
|
||||
|
||||
if ((ieee80211_is_action(hdr->frame_control) ||
|
||||
ieee80211_is_deauth(hdr->frame_control) ||
|
||||
ieee80211_is_disassoc(hdr->frame_control)) &&
|
||||
ieee80211_has_protected(hdr->frame_control)) {
|
||||
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
||||
}
|
||||
|
||||
txdesc = ath10k_htc_alloc_skb(ar, len);
|
||||
if (!txdesc) {
|
||||
res = -ENOMEM;
|
||||
|
@ -503,8 +539,6 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
memcpy(cmd->mgmt_tx.hdr, msdu->data,
|
||||
min_t(int, msdu->len, HTT_MGMT_FRM_HDR_DOWNLOAD_LEN));
|
||||
|
||||
skb_cb->htt.txbuf = NULL;
|
||||
|
||||
res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc);
|
||||
if (res)
|
||||
goto err_unmap_msdu;
|
||||
|
@ -525,21 +559,27 @@ err:
|
|||
return res;
|
||||
}
|
||||
|
||||
int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
||||
int ath10k_htt_tx(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
|
||||
struct sk_buff *msdu)
|
||||
{
|
||||
struct ath10k *ar = htt->ar;
|
||||
struct device *dev = ar->dev;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
|
||||
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
|
||||
struct ath10k_hif_sg_item sg_items[2];
|
||||
struct ath10k_htt_txbuf *txbuf;
|
||||
struct htt_data_tx_desc_frag *frags;
|
||||
u8 vdev_id = skb_cb->vdev_id;
|
||||
u8 tid = skb_cb->htt.tid;
|
||||
bool is_eth = (txmode == ATH10K_HW_TXRX_ETHERNET);
|
||||
u8 vdev_id = ath10k_htt_tx_get_vdev_id(ar, msdu);
|
||||
u8 tid = ath10k_htt_tx_get_tid(msdu, is_eth);
|
||||
int prefetch_len;
|
||||
int res;
|
||||
u8 flags0 = 0;
|
||||
u16 msdu_id, flags1 = 0;
|
||||
u16 freq = 0;
|
||||
u32 frags_paddr = 0;
|
||||
u32 txbuf_paddr;
|
||||
struct htt_msdu_ext_desc *ext_desc = NULL;
|
||||
bool limit_mgmt_desc = false;
|
||||
bool is_probe_resp = false;
|
||||
|
@ -567,17 +607,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
prefetch_len = min(htt->prefetch_len, msdu->len);
|
||||
prefetch_len = roundup(prefetch_len, 4);
|
||||
|
||||
skb_cb->htt.txbuf = &htt->txbuf.vaddr[msdu_id];
|
||||
skb_cb->htt.txbuf_paddr = htt->txbuf.paddr +
|
||||
(sizeof(struct ath10k_htt_txbuf) * msdu_id);
|
||||
txbuf = &htt->txbuf.vaddr[msdu_id];
|
||||
txbuf_paddr = htt->txbuf.paddr +
|
||||
(sizeof(struct ath10k_htt_txbuf) * msdu_id);
|
||||
|
||||
if ((ieee80211_is_action(hdr->frame_control) ||
|
||||
ieee80211_is_deauth(hdr->frame_control) ||
|
||||
ieee80211_is_disassoc(hdr->frame_control)) &&
|
||||
ieee80211_has_protected(hdr->frame_control)) {
|
||||
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
||||
} else if (!skb_cb->htt.nohwcrypt &&
|
||||
skb_cb->txmode == ATH10K_HW_TXRX_RAW &&
|
||||
} else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
|
||||
txmode == ATH10K_HW_TXRX_RAW &&
|
||||
ieee80211_has_protected(hdr->frame_control)) {
|
||||
skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
||||
}
|
||||
|
@ -590,7 +630,10 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
goto err_free_msdu_id;
|
||||
}
|
||||
|
||||
switch (skb_cb->txmode) {
|
||||
if (unlikely(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN))
|
||||
freq = ar->scan.roc_freq;
|
||||
|
||||
switch (txmode) {
|
||||
case ATH10K_HW_TXRX_RAW:
|
||||
case ATH10K_HW_TXRX_NATIVE_WIFI:
|
||||
flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
|
||||
|
@ -610,16 +653,16 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
frags_paddr = htt->frag_desc.paddr +
|
||||
(sizeof(struct htt_msdu_ext_desc) * msdu_id);
|
||||
} else {
|
||||
frags = skb_cb->htt.txbuf->frags;
|
||||
frags = txbuf->frags;
|
||||
frags[0].dword_addr.paddr =
|
||||
__cpu_to_le32(skb_cb->paddr);
|
||||
frags[0].dword_addr.len = __cpu_to_le32(msdu->len);
|
||||
frags[1].dword_addr.paddr = 0;
|
||||
frags[1].dword_addr.len = 0;
|
||||
|
||||
frags_paddr = skb_cb->htt.txbuf_paddr;
|
||||
frags_paddr = txbuf_paddr;
|
||||
}
|
||||
flags0 |= SM(skb_cb->txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
|
||||
flags0 |= SM(txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
|
||||
break;
|
||||
case ATH10K_HW_TXRX_MGMT:
|
||||
flags0 |= SM(ATH10K_HW_TXRX_MGMT,
|
||||
|
@ -646,17 +689,13 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
* avoid extra memory allocations, compress data structures and thus
|
||||
* improve performance. */
|
||||
|
||||
skb_cb->htt.txbuf->htc_hdr.eid = htt->eid;
|
||||
skb_cb->htt.txbuf->htc_hdr.len = __cpu_to_le16(
|
||||
sizeof(skb_cb->htt.txbuf->cmd_hdr) +
|
||||
sizeof(skb_cb->htt.txbuf->cmd_tx) +
|
||||
prefetch_len);
|
||||
skb_cb->htt.txbuf->htc_hdr.flags = 0;
|
||||
txbuf->htc_hdr.eid = htt->eid;
|
||||
txbuf->htc_hdr.len = __cpu_to_le16(sizeof(txbuf->cmd_hdr) +
|
||||
sizeof(txbuf->cmd_tx) +
|
||||
prefetch_len);
|
||||
txbuf->htc_hdr.flags = 0;
|
||||
|
||||
if (skb_cb->htt.nohwcrypt)
|
||||
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
|
||||
|
||||
if (!skb_cb->is_protected)
|
||||
if (skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT)
|
||||
flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT;
|
||||
|
||||
flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
|
||||
|
@ -675,20 +714,27 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
*/
|
||||
flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED;
|
||||
|
||||
skb_cb->htt.txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
|
||||
skb_cb->htt.txbuf->cmd_tx.flags0 = flags0;
|
||||
skb_cb->htt.txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
|
||||
skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
|
||||
skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
|
||||
skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
|
||||
skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
|
||||
skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq);
|
||||
txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM;
|
||||
txbuf->cmd_tx.flags0 = flags0;
|
||||
txbuf->cmd_tx.flags1 = __cpu_to_le16(flags1);
|
||||
txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
|
||||
txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
|
||||
txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
|
||||
if (ath10k_mac_tx_frm_has_freq(ar)) {
|
||||
txbuf->cmd_tx.offchan_tx.peerid =
|
||||
__cpu_to_le16(HTT_INVALID_PEERID);
|
||||
txbuf->cmd_tx.offchan_tx.freq =
|
||||
__cpu_to_le16(freq);
|
||||
} else {
|
||||
txbuf->cmd_tx.peerid =
|
||||
__cpu_to_le32(HTT_INVALID_PEERID);
|
||||
}
|
||||
|
||||
trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
|
||||
ath10k_dbg(ar, ATH10K_DBG_HTT,
|
||||
"htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu freq %hu\n",
|
||||
flags0, flags1, msdu->len, msdu_id, frags_paddr,
|
||||
(u32)skb_cb->paddr, vdev_id, tid, skb_cb->htt.freq);
|
||||
(u32)skb_cb->paddr, vdev_id, tid, freq);
|
||||
ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ",
|
||||
msdu->data, msdu->len);
|
||||
trace_ath10k_tx_hdr(ar, msdu->data, msdu->len);
|
||||
|
@ -696,12 +742,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
|||
|
||||
sg_items[0].transfer_id = 0;
|
||||
sg_items[0].transfer_context = NULL;
|
||||
sg_items[0].vaddr = &skb_cb->htt.txbuf->htc_hdr;
|
||||
sg_items[0].paddr = skb_cb->htt.txbuf_paddr +
|
||||
sizeof(skb_cb->htt.txbuf->frags);
|
||||
sg_items[0].len = sizeof(skb_cb->htt.txbuf->htc_hdr) +
|
||||
sizeof(skb_cb->htt.txbuf->cmd_hdr) +
|
||||
sizeof(skb_cb->htt.txbuf->cmd_tx);
|
||||
sg_items[0].vaddr = &txbuf->htc_hdr;
|
||||
sg_items[0].paddr = txbuf_paddr +
|
||||
sizeof(txbuf->frags);
|
||||
sg_items[0].len = sizeof(txbuf->htc_hdr) +
|
||||
sizeof(txbuf->cmd_hdr) +
|
||||
sizeof(txbuf->cmd_tx);
|
||||
|
||||
sg_items[1].transfer_id = 0;
|
||||
sg_items[1].transfer_context = NULL;
|
||||
|
|
|
@ -286,6 +286,16 @@ struct ath10k_pktlog_hdr {
|
|||
u8 payload[0];
|
||||
} __packed;
|
||||
|
||||
struct ath10k_pktlog_10_4_hdr {
|
||||
__le16 flags;
|
||||
__le16 missed_cnt;
|
||||
__le16 log_type;
|
||||
__le16 size;
|
||||
__le32 timestamp;
|
||||
__le32 type_specific_data;
|
||||
u8 payload[0];
|
||||
} __packed;
|
||||
|
||||
enum ath10k_hw_rate_ofdm {
|
||||
ATH10K_HW_RATE_OFDM_48M = 0,
|
||||
ATH10K_HW_RATE_OFDM_24M,
|
||||
|
@ -307,6 +317,11 @@ enum ath10k_hw_rate_cck {
|
|||
ATH10K_HW_RATE_CCK_SP_2M,
|
||||
};
|
||||
|
||||
enum ath10k_hw_4addr_pad {
|
||||
ATH10K_HW_4ADDR_PAD_AFTER,
|
||||
ATH10K_HW_4ADDR_PAD_BEFORE,
|
||||
};
|
||||
|
||||
/* Target specific defines for MAIN firmware */
|
||||
#define TARGET_NUM_VDEVS 8
|
||||
#define TARGET_NUM_PEER_AST 2
|
||||
|
|
|
@ -90,7 +90,7 @@ static u8 ath10k_mac_bitrate_to_rate(int bitrate)
|
|||
}
|
||||
|
||||
u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
|
||||
u8 hw_rate)
|
||||
u8 hw_rate, bool cck)
|
||||
{
|
||||
const struct ieee80211_rate *rate;
|
||||
int i;
|
||||
|
@ -98,6 +98,9 @@ u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
|
|||
for (i = 0; i < sband->n_bitrates; i++) {
|
||||
rate = &sband->bitrates[i];
|
||||
|
||||
if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
|
||||
continue;
|
||||
|
||||
if (rate->hw_value == hw_rate)
|
||||
return i;
|
||||
else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
|
||||
|
@ -1960,7 +1963,7 @@ static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
|
|||
ether_addr_copy(arg->addr, sta->addr);
|
||||
arg->vdev_id = arvif->vdev_id;
|
||||
arg->peer_aid = aid;
|
||||
arg->peer_flags |= WMI_PEER_AUTH;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
|
||||
arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
|
||||
arg->peer_num_spatial_streams = 1;
|
||||
arg->peer_caps = vif->bss_conf.assoc_capability;
|
||||
|
@ -1968,6 +1971,7 @@ static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
|
|||
|
||||
static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct wmi_peer_assoc_complete_arg *arg)
|
||||
{
|
||||
struct ieee80211_bss_conf *info = &vif->bss_conf;
|
||||
|
@ -2002,12 +2006,17 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
|
|||
/* FIXME: base on RSN IE/WPA IE is a correct idea? */
|
||||
if (rsnie || wpaie) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
|
||||
arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
|
||||
}
|
||||
|
||||
if (wpaie) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
|
||||
arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
|
||||
}
|
||||
|
||||
if (sta->mfp &&
|
||||
test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT, ar->fw_features)) {
|
||||
arg->peer_flags |= ar->wmi.peer_flags->pmf;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2104,7 +2113,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
|||
ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
|
||||
return;
|
||||
|
||||
arg->peer_flags |= WMI_PEER_HT;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->ht;
|
||||
arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
ht_cap->ampdu_factor)) - 1;
|
||||
|
||||
|
@ -2115,10 +2124,10 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
|||
arg->peer_rate_caps |= WMI_RC_HT_FLAG;
|
||||
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
|
||||
arg->peer_flags |= WMI_PEER_LDPC;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->ldbc;
|
||||
|
||||
if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
|
||||
arg->peer_flags |= WMI_PEER_40MHZ;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->bw40;
|
||||
arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
|
||||
}
|
||||
|
||||
|
@ -2132,7 +2141,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
|||
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
|
||||
arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
|
||||
arg->peer_flags |= WMI_PEER_STBC;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->stbc;
|
||||
}
|
||||
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
|
||||
|
@ -2140,7 +2149,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
|||
stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
|
||||
stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
|
||||
arg->peer_rate_caps |= stbc;
|
||||
arg->peer_flags |= WMI_PEER_STBC;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->stbc;
|
||||
}
|
||||
|
||||
if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
|
||||
|
@ -2321,10 +2330,10 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
|||
if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
|
||||
return;
|
||||
|
||||
arg->peer_flags |= WMI_PEER_VHT;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->vht;
|
||||
|
||||
if (def.chan->band == IEEE80211_BAND_2GHZ)
|
||||
arg->peer_flags |= WMI_PEER_VHT_2G;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
|
||||
|
||||
arg->peer_vht_caps = vht_cap->cap;
|
||||
|
||||
|
@ -2341,7 +2350,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
|||
ampdu_factor)) - 1);
|
||||
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
|
||||
arg->peer_flags |= WMI_PEER_80MHZ;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->bw80;
|
||||
|
||||
arg->peer_vht_rates.rx_max_rate =
|
||||
__le16_to_cpu(vht_cap->vht_mcs.rx_highest);
|
||||
|
@ -2366,27 +2375,28 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
|
|||
switch (arvif->vdev_type) {
|
||||
case WMI_VDEV_TYPE_AP:
|
||||
if (sta->wme)
|
||||
arg->peer_flags |= WMI_PEER_QOS;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
|
||||
|
||||
if (sta->wme && sta->uapsd_queues) {
|
||||
arg->peer_flags |= WMI_PEER_APSD;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
|
||||
arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
|
||||
}
|
||||
break;
|
||||
case WMI_VDEV_TYPE_STA:
|
||||
if (vif->bss_conf.qos)
|
||||
arg->peer_flags |= WMI_PEER_QOS;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
|
||||
break;
|
||||
case WMI_VDEV_TYPE_IBSS:
|
||||
if (sta->wme)
|
||||
arg->peer_flags |= WMI_PEER_QOS;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
|
||||
sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
|
||||
sta->addr, !!(arg->peer_flags &
|
||||
arvif->ar->wmi.peer_flags->qos));
|
||||
}
|
||||
|
||||
static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
|
||||
|
@ -2479,7 +2489,7 @@ static int ath10k_peer_assoc_prepare(struct ath10k *ar,
|
|||
memset(arg, 0, sizeof(*arg));
|
||||
|
||||
ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_crypto(ar, vif, arg);
|
||||
ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
|
||||
|
@ -3112,35 +3122,11 @@ void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
|
|||
spin_unlock_bh(&ar->htt.tx_lock);
|
||||
}
|
||||
|
||||
static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
|
||||
{
|
||||
if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
return HTT_DATA_TX_EXT_TID_MGMT;
|
||||
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
|
||||
|
||||
if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
|
||||
return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
|
||||
|
||||
return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
|
||||
}
|
||||
|
||||
static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
|
||||
{
|
||||
if (vif)
|
||||
return ath10k_vif_to_arvif(vif)->vdev_id;
|
||||
|
||||
if (ar->monitor_started)
|
||||
return ar->monitor_vdev_id;
|
||||
|
||||
ath10k_warn(ar, "failed to resolve vdev id\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum ath10k_hw_txrx_mode
|
||||
ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, struct sk_buff *skb)
|
||||
ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
|
@ -3190,14 +3176,22 @@ ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
|
|||
}
|
||||
|
||||
static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
|
||||
struct sk_buff *skb) {
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
const struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
||||
IEEE80211_TX_CTL_INJECTED;
|
||||
|
||||
if (!ieee80211_has_protected(hdr->frame_control))
|
||||
return false;
|
||||
|
||||
if ((info->flags & mask) == mask)
|
||||
return false;
|
||||
|
||||
if (vif)
|
||||
return !ath10k_vif_to_arvif(vif)->nohwcrypt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3224,7 +3218,7 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|||
*/
|
||||
hdr = (void *)skb->data;
|
||||
if (ieee80211_is_qos_nullfunc(hdr->frame_control))
|
||||
cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
|
||||
cb->flags &= ~ATH10K_SKB_F_QOS;
|
||||
|
||||
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
|
||||
}
|
||||
|
@ -3280,7 +3274,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
|
|||
}
|
||||
}
|
||||
|
||||
static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
|
||||
bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
|
||||
{
|
||||
/* FIXME: Not really sure since when the behaviour changed. At some
|
||||
* point new firmware stopped requiring creation of peer entries for
|
||||
|
@ -3288,8 +3282,9 @@ static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
|
|||
* tx credit replenishment and reliability). Assuming it's at least 3.4
|
||||
* because that's when the `freq` was introduced to TX_FRM HTT command.
|
||||
*/
|
||||
return !(ar->htt.target_version_major >= 3 &&
|
||||
ar->htt.target_version_minor >= 4);
|
||||
return (ar->htt.target_version_major >= 3 &&
|
||||
ar->htt.target_version_minor >= 4 &&
|
||||
ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
|
||||
}
|
||||
|
||||
static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
|
||||
|
@ -3314,24 +3309,24 @@ unlock:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
|
||||
static void ath10k_mac_tx(struct ath10k *ar, enum ath10k_hw_txrx_mode txmode,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
|
||||
struct ath10k_htt *htt = &ar->htt;
|
||||
int ret = 0;
|
||||
|
||||
switch (cb->txmode) {
|
||||
switch (txmode) {
|
||||
case ATH10K_HW_TXRX_RAW:
|
||||
case ATH10K_HW_TXRX_NATIVE_WIFI:
|
||||
case ATH10K_HW_TXRX_ETHERNET:
|
||||
ret = ath10k_htt_tx(htt, skb);
|
||||
ret = ath10k_htt_tx(htt, txmode, skb);
|
||||
break;
|
||||
case ATH10K_HW_TXRX_MGMT:
|
||||
if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
|
||||
ar->fw_features))
|
||||
ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
|
||||
else if (ar->htt.target_version_major >= 3)
|
||||
ret = ath10k_htt_tx(htt, skb);
|
||||
ret = ath10k_htt_tx(htt, txmode, skb);
|
||||
else
|
||||
ret = ath10k_htt_mgmt_tx(htt, skb);
|
||||
break;
|
||||
|
@ -3361,9 +3356,13 @@ void ath10k_offchan_tx_work(struct work_struct *work)
|
|||
{
|
||||
struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
|
||||
struct ath10k_peer *peer;
|
||||
struct ath10k_vif *arvif;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_sta *sta;
|
||||
struct sk_buff *skb;
|
||||
const u8 *peer_addr;
|
||||
enum ath10k_hw_txrx_mode txmode;
|
||||
int vdev_id;
|
||||
int ret;
|
||||
unsigned long time_left;
|
||||
|
@ -3388,9 +3387,9 @@ void ath10k_offchan_tx_work(struct work_struct *work)
|
|||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
peer_addr = ieee80211_get_DA(hdr);
|
||||
vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
vdev_id = ar->scan.vdev_id;
|
||||
peer = ath10k_peer_find(ar, vdev_id, peer_addr);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
|
@ -3413,7 +3412,22 @@ void ath10k_offchan_tx_work(struct work_struct *work)
|
|||
ar->offchan_tx_skb = skb;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
ath10k_mac_tx(ar, skb);
|
||||
/* It's safe to access vif and sta - conf_mutex guarantees that
|
||||
* sta_state() and remove_interface() are locked exclusively
|
||||
* out wrt to this offchannel worker.
|
||||
*/
|
||||
arvif = ath10k_get_arvif(ar, vdev_id);
|
||||
if (arvif) {
|
||||
vif = arvif->vif;
|
||||
sta = ieee80211_find_sta(vif, peer_addr);
|
||||
} else {
|
||||
vif = NULL;
|
||||
sta = NULL;
|
||||
}
|
||||
|
||||
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
|
||||
ath10k_mac_tx(ar, txmode, skb);
|
||||
|
||||
time_left =
|
||||
wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
|
||||
|
@ -3488,6 +3502,7 @@ void __ath10k_scan_finish(struct ath10k *ar)
|
|||
case ATH10K_SCAN_STARTING:
|
||||
ar->scan.state = ATH10K_SCAN_IDLE;
|
||||
ar->scan_channel = NULL;
|
||||
ar->scan.roc_freq = 0;
|
||||
ath10k_offchan_tx_purge(ar);
|
||||
cancel_delayed_work(&ar->scan.timeout);
|
||||
complete_all(&ar->scan.completed);
|
||||
|
@ -3631,25 +3646,32 @@ static void ath10k_tx(struct ieee80211_hw *hw,
|
|||
struct sk_buff *skb)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_vif *vif = info->control.vif;
|
||||
struct ieee80211_sta *sta = control->sta;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
enum ath10k_hw_txrx_mode txmode;
|
||||
|
||||
/* We should disable CCK RATE due to P2P */
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
|
||||
|
||||
ATH10K_SKB_CB(skb)->htt.is_offchan = false;
|
||||
ATH10K_SKB_CB(skb)->htt.freq = 0;
|
||||
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
|
||||
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
|
||||
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
|
||||
ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
|
||||
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
|
||||
switch (ATH10K_SKB_CB(skb)->txmode) {
|
||||
skb_cb->flags = 0;
|
||||
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
|
||||
skb_cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
|
||||
|
||||
if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
skb_cb->flags |= ATH10K_SKB_F_MGMT;
|
||||
|
||||
if (ieee80211_is_data_qos(hdr->frame_control))
|
||||
skb_cb->flags |= ATH10K_SKB_F_QOS;
|
||||
|
||||
skb_cb->vif = vif;
|
||||
|
||||
switch (txmode) {
|
||||
case ATH10K_HW_TXRX_MGMT:
|
||||
case ATH10K_HW_TXRX_NATIVE_WIFI:
|
||||
ath10k_tx_h_nwifi(hw, skb);
|
||||
|
@ -3668,15 +3690,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
|
||||
ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
if (ath10k_mac_need_offchan_tx_work(ar)) {
|
||||
ATH10K_SKB_CB(skb)->htt.freq = 0;
|
||||
ATH10K_SKB_CB(skb)->htt.is_offchan = true;
|
||||
|
||||
if (!ath10k_mac_tx_frm_has_freq(ar)) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
|
||||
skb);
|
||||
|
||||
|
@ -3686,7 +3700,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
|
|||
}
|
||||
}
|
||||
|
||||
ath10k_mac_tx(ar, skb);
|
||||
ath10k_mac_tx(ar, txmode, skb);
|
||||
}
|
||||
|
||||
/* Must not be called with conf_mutex held as workers can use that also. */
|
||||
|
@ -4350,7 +4364,9 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|||
arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
|
||||
if (test_bit(WMI_SERVICE_MESH, ar->wmi.svc_map)) {
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH;
|
||||
} else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
|
||||
ret = -EINVAL;
|
||||
ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
|
||||
goto err;
|
||||
|
@ -6907,35 +6923,39 @@ void ath10k_mac_destroy(struct ath10k *ar)
|
|||
|
||||
static const struct ieee80211_iface_limit ath10k_if_limits[] = {
|
||||
{
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_STATION)
|
||||
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_STATION)
|
||||
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
||||
},
|
||||
{
|
||||
.max = 3,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_GO)
|
||||
.max = 3,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_GO)
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
|
||||
},
|
||||
{
|
||||
.max = 7,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
.max = 7,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
| BIT(NL80211_IFTYPE_MESH_POINT)
|
||||
| BIT(NL80211_IFTYPE_MESH_POINT)
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
|
||||
{
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
| BIT(NL80211_IFTYPE_MESH_POINT)
|
||||
| BIT(NL80211_IFTYPE_MESH_POINT)
|
||||
#endif
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_STATION)
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination ath10k_if_comb[] = {
|
||||
|
|
|
@ -66,7 +66,7 @@ void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
|
|||
enum wmi_tlv_tx_pause_action action);
|
||||
|
||||
u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
|
||||
u8 hw_rate);
|
||||
u8 hw_rate, bool cck);
|
||||
u8 ath10k_mac_bitrate_to_idx(const struct ieee80211_supported_band *sband,
|
||||
u32 bitrate);
|
||||
|
||||
|
@ -74,6 +74,7 @@ void ath10k_mac_tx_lock(struct ath10k *ar, int reason);
|
|||
void ath10k_mac_tx_unlock(struct ath10k *ar, int reason);
|
||||
void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason);
|
||||
void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason);
|
||||
bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar);
|
||||
|
||||
static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
|
||||
{
|
||||
|
|
|
@ -108,6 +108,7 @@ static void ath10k_pci_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
|
|||
static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
|
||||
static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state);
|
||||
static void ath10k_pci_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state);
|
||||
static void ath10k_pci_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state);
|
||||
|
||||
static struct ce_attr host_ce_config_wlan[] = {
|
||||
/* CE0: host->target HTC control and raw streams */
|
||||
|
@ -186,6 +187,7 @@ static struct ce_attr host_ce_config_wlan[] = {
|
|||
.src_nentries = 0,
|
||||
.src_sz_max = 2048,
|
||||
.dest_nentries = 128,
|
||||
.recv_cb = ath10k_pci_pktlog_rx_cb,
|
||||
},
|
||||
|
||||
/* CE9 target autonomous qcache memcpy */
|
||||
|
@ -1215,6 +1217,15 @@ static void ath10k_pci_htt_htc_rx_cb(struct ath10k_ce_pipe *ce_state)
|
|||
ath10k_pci_process_rx_cb(ce_state, ath10k_htc_rx_completion_handler);
|
||||
}
|
||||
|
||||
/* Called by lower (CE) layer when data is received from the Target.
|
||||
* Only 10.4 firmware uses separate CE to transfer pktlog data.
|
||||
*/
|
||||
static void ath10k_pci_pktlog_rx_cb(struct ath10k_ce_pipe *ce_state)
|
||||
{
|
||||
ath10k_pci_process_rx_cb(ce_state,
|
||||
ath10k_htt_rx_pktlog_completion_handler);
|
||||
}
|
||||
|
||||
/* Called by lower (CE) layer when a send to HTT Target completes. */
|
||||
static void ath10k_pci_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
|
||||
{
|
||||
|
|
|
@ -187,7 +187,7 @@ int ath10k_thermal_register(struct ath10k *ar)
|
|||
/* Do not register hwmon device when temperature reading is not
|
||||
* supported by firmware
|
||||
*/
|
||||
if (ar->wmi.op_version != ATH10K_FW_WMI_OP_VERSION_10_2_4)
|
||||
if (!(ar->wmi.ops->gen_pdev_get_temperature))
|
||||
return 0;
|
||||
|
||||
/* Avoid linking error on devm_hwmon_device_register_with_groups, I
|
||||
|
|
|
@ -23,7 +23,12 @@
|
|||
|
||||
static void ath10k_report_offchan_tx(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
if (!ATH10K_SKB_CB(skb)->htt.is_offchan)
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
if (likely(!(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)))
|
||||
return;
|
||||
|
||||
if (ath10k_mac_tx_frm_has_freq(ar))
|
||||
return;
|
||||
|
||||
/* If the original wait_for_completion() timed out before
|
||||
|
@ -52,8 +57,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
|||
struct ieee80211_tx_info *info;
|
||||
struct ath10k_skb_cb *skb_cb;
|
||||
struct sk_buff *msdu;
|
||||
struct ieee80211_hdr *hdr;
|
||||
__le16 fc;
|
||||
bool limit_mgmt_desc = false;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_HTT,
|
||||
|
@ -76,10 +79,9 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
|||
return;
|
||||
}
|
||||
|
||||
hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
fc = hdr->frame_control;
|
||||
skb_cb = ATH10K_SKB_CB(msdu);
|
||||
|
||||
if (unlikely(ieee80211_is_mgmt(fc)) &&
|
||||
if (unlikely(skb_cb->flags & ATH10K_SKB_F_MGMT) &&
|
||||
ar->hw_params.max_probe_resp_desc_thres)
|
||||
limit_mgmt_desc = true;
|
||||
|
||||
|
@ -89,7 +91,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
|||
wake_up(&htt->empty_tx_wq);
|
||||
spin_unlock_bh(&htt->tx_lock);
|
||||
|
||||
skb_cb = ATH10K_SKB_CB(msdu);
|
||||
dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
|
||||
|
||||
ath10k_report_offchan_tx(htt->ar, msdu);
|
||||
|
|
|
@ -3485,6 +3485,24 @@ static const struct wmi_ops wmi_tlv_ops = {
|
|||
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
|
||||
.auth = WMI_TLV_PEER_AUTH,
|
||||
.qos = WMI_TLV_PEER_QOS,
|
||||
.need_ptk_4_way = WMI_TLV_PEER_NEED_PTK_4_WAY,
|
||||
.need_gtk_2_way = WMI_TLV_PEER_NEED_GTK_2_WAY,
|
||||
.apsd = WMI_TLV_PEER_APSD,
|
||||
.ht = WMI_TLV_PEER_HT,
|
||||
.bw40 = WMI_TLV_PEER_40MHZ,
|
||||
.stbc = WMI_TLV_PEER_STBC,
|
||||
.ldbc = WMI_TLV_PEER_LDPC,
|
||||
.dyn_mimops = WMI_TLV_PEER_DYN_MIMOPS,
|
||||
.static_mimops = WMI_TLV_PEER_STATIC_MIMOPS,
|
||||
.spatial_mux = WMI_TLV_PEER_SPATIAL_MUX,
|
||||
.vht = WMI_TLV_PEER_VHT,
|
||||
.bw80 = WMI_TLV_PEER_80MHZ,
|
||||
.pmf = WMI_TLV_PEER_PMF,
|
||||
};
|
||||
|
||||
/************/
|
||||
/* TLV init */
|
||||
/************/
|
||||
|
@ -3495,4 +3513,5 @@ void ath10k_wmi_tlv_attach(struct ath10k *ar)
|
|||
ar->wmi.vdev_param = &wmi_tlv_vdev_param_map;
|
||||
ar->wmi.pdev_param = &wmi_tlv_pdev_param_map;
|
||||
ar->wmi.ops = &wmi_tlv_ops;
|
||||
ar->wmi.peer_flags = &wmi_tlv_peer_flags_map;
|
||||
}
|
||||
|
|
|
@ -527,6 +527,24 @@ enum wmi_tlv_vdev_param {
|
|||
WMI_TLV_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE,
|
||||
};
|
||||
|
||||
enum wmi_tlv_peer_flags {
|
||||
WMI_TLV_PEER_AUTH = 0x00000001,
|
||||
WMI_TLV_PEER_QOS = 0x00000002,
|
||||
WMI_TLV_PEER_NEED_PTK_4_WAY = 0x00000004,
|
||||
WMI_TLV_PEER_NEED_GTK_2_WAY = 0x00000010,
|
||||
WMI_TLV_PEER_APSD = 0x00000800,
|
||||
WMI_TLV_PEER_HT = 0x00001000,
|
||||
WMI_TLV_PEER_40MHZ = 0x00002000,
|
||||
WMI_TLV_PEER_STBC = 0x00008000,
|
||||
WMI_TLV_PEER_LDPC = 0x00010000,
|
||||
WMI_TLV_PEER_DYN_MIMOPS = 0x00020000,
|
||||
WMI_TLV_PEER_STATIC_MIMOPS = 0x00040000,
|
||||
WMI_TLV_PEER_SPATIAL_MUX = 0x00200000,
|
||||
WMI_TLV_PEER_VHT = 0x02000000,
|
||||
WMI_TLV_PEER_80MHZ = 0x04000000,
|
||||
WMI_TLV_PEER_PMF = 0x08000000,
|
||||
};
|
||||
|
||||
enum wmi_tlv_tag {
|
||||
WMI_TLV_TAG_LAST_RESERVED = 15,
|
||||
|
||||
|
|
|
@ -1546,6 +1546,61 @@ static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
|
|||
.arp_dstaddr = WMI_10_4_PDEV_PARAM_ARP_DSTADDR,
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_peer_flags_map = {
|
||||
.auth = WMI_PEER_AUTH,
|
||||
.qos = WMI_PEER_QOS,
|
||||
.need_ptk_4_way = WMI_PEER_NEED_PTK_4_WAY,
|
||||
.need_gtk_2_way = WMI_PEER_NEED_GTK_2_WAY,
|
||||
.apsd = WMI_PEER_APSD,
|
||||
.ht = WMI_PEER_HT,
|
||||
.bw40 = WMI_PEER_40MHZ,
|
||||
.stbc = WMI_PEER_STBC,
|
||||
.ldbc = WMI_PEER_LDPC,
|
||||
.dyn_mimops = WMI_PEER_DYN_MIMOPS,
|
||||
.static_mimops = WMI_PEER_STATIC_MIMOPS,
|
||||
.spatial_mux = WMI_PEER_SPATIAL_MUX,
|
||||
.vht = WMI_PEER_VHT,
|
||||
.bw80 = WMI_PEER_80MHZ,
|
||||
.vht_2g = WMI_PEER_VHT_2G,
|
||||
.pmf = WMI_PEER_PMF,
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_10x_peer_flags_map = {
|
||||
.auth = WMI_10X_PEER_AUTH,
|
||||
.qos = WMI_10X_PEER_QOS,
|
||||
.need_ptk_4_way = WMI_10X_PEER_NEED_PTK_4_WAY,
|
||||
.need_gtk_2_way = WMI_10X_PEER_NEED_GTK_2_WAY,
|
||||
.apsd = WMI_10X_PEER_APSD,
|
||||
.ht = WMI_10X_PEER_HT,
|
||||
.bw40 = WMI_10X_PEER_40MHZ,
|
||||
.stbc = WMI_10X_PEER_STBC,
|
||||
.ldbc = WMI_10X_PEER_LDPC,
|
||||
.dyn_mimops = WMI_10X_PEER_DYN_MIMOPS,
|
||||
.static_mimops = WMI_10X_PEER_STATIC_MIMOPS,
|
||||
.spatial_mux = WMI_10X_PEER_SPATIAL_MUX,
|
||||
.vht = WMI_10X_PEER_VHT,
|
||||
.bw80 = WMI_10X_PEER_80MHZ,
|
||||
};
|
||||
|
||||
static const struct wmi_peer_flags_map wmi_10_2_peer_flags_map = {
|
||||
.auth = WMI_10_2_PEER_AUTH,
|
||||
.qos = WMI_10_2_PEER_QOS,
|
||||
.need_ptk_4_way = WMI_10_2_PEER_NEED_PTK_4_WAY,
|
||||
.need_gtk_2_way = WMI_10_2_PEER_NEED_GTK_2_WAY,
|
||||
.apsd = WMI_10_2_PEER_APSD,
|
||||
.ht = WMI_10_2_PEER_HT,
|
||||
.bw40 = WMI_10_2_PEER_40MHZ,
|
||||
.stbc = WMI_10_2_PEER_STBC,
|
||||
.ldbc = WMI_10_2_PEER_LDPC,
|
||||
.dyn_mimops = WMI_10_2_PEER_DYN_MIMOPS,
|
||||
.static_mimops = WMI_10_2_PEER_STATIC_MIMOPS,
|
||||
.spatial_mux = WMI_10_2_PEER_SPATIAL_MUX,
|
||||
.vht = WMI_10_2_PEER_VHT,
|
||||
.bw80 = WMI_10_2_PEER_80MHZ,
|
||||
.vht_2g = WMI_10_2_PEER_VHT_2G,
|
||||
.pmf = WMI_10_2_PEER_PMF,
|
||||
};
|
||||
|
||||
void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
|
||||
const struct wmi_channel_arg *arg)
|
||||
{
|
||||
|
@ -1660,6 +1715,8 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
|
|||
struct ath10k *ar = arvif->ar;
|
||||
struct ath10k_skb_cb *cb;
|
||||
struct sk_buff *bcn;
|
||||
bool dtim_zero;
|
||||
bool deliver_cab;
|
||||
int ret;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
@ -1679,12 +1736,14 @@ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
|
|||
arvif->beacon_state = ATH10K_BEACON_SENDING;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
dtim_zero = !!(cb->flags & ATH10K_SKB_F_DTIM_ZERO);
|
||||
deliver_cab = !!(cb->flags & ATH10K_SKB_F_DELIVER_CAB);
|
||||
ret = ath10k_wmi_beacon_send_ref_nowait(arvif->ar,
|
||||
arvif->vdev_id,
|
||||
bcn->data, bcn->len,
|
||||
cb->paddr,
|
||||
cb->bcn.dtim_zero,
|
||||
cb->bcn.deliver_cab);
|
||||
dtim_zero,
|
||||
deliver_cab);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
||||
|
@ -1755,16 +1814,24 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
|
|||
static struct sk_buff *
|
||||
ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
|
||||
{
|
||||
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
|
||||
struct ath10k_vif *arvif = (void *)cb->vif->drv_priv;
|
||||
struct wmi_mgmt_tx_cmd *cmd;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *skb;
|
||||
int len;
|
||||
u32 vdev_id;
|
||||
u32 buf_len = msdu->len;
|
||||
u16 fc;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)msdu->data;
|
||||
fc = le16_to_cpu(hdr->frame_control);
|
||||
|
||||
if (cb->vif)
|
||||
vdev_id = arvif->vdev_id;
|
||||
else
|
||||
vdev_id = 0;
|
||||
|
||||
if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
|
@ -1786,7 +1853,7 @@ ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
|
|||
|
||||
cmd = (struct wmi_mgmt_tx_cmd *)skb->data;
|
||||
|
||||
cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(msdu)->vdev_id);
|
||||
cmd->hdr.vdev_id = __cpu_to_le32(vdev_id);
|
||||
cmd->hdr.tx_rate = 0;
|
||||
cmd->hdr.tx_power = 0;
|
||||
cmd->hdr.buf_len = __cpu_to_le32(buf_len);
|
||||
|
@ -2204,22 +2271,9 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
|
|||
ath10k_dbg(ar, ATH10K_DBG_MGMT,
|
||||
"event mgmt rx status %08x\n", rx_status);
|
||||
|
||||
if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) {
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rx_status & WMI_RX_STATUS_ERR_DECRYPT) {
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rx_status & WMI_RX_STATUS_ERR_KEY_CACHE_MISS) {
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rx_status & WMI_RX_STATUS_ERR_CRC) {
|
||||
if ((test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) ||
|
||||
(rx_status & (WMI_RX_STATUS_ERR_DECRYPT |
|
||||
WMI_RX_STATUS_ERR_KEY_CACHE_MISS | WMI_RX_STATUS_ERR_CRC))) {
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3115,10 +3169,10 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
|
|||
memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);
|
||||
|
||||
if (tim->dtim_count == 0) {
|
||||
ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true;
|
||||
ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DTIM_ZERO;
|
||||
|
||||
if (__le32_to_cpu(tim_info->tim_mcast) == 1)
|
||||
ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true;
|
||||
ATH10K_SKB_CB(bcn)->flags |= ATH10K_SKB_F_DELIVER_CAB;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n",
|
||||
|
@ -5061,6 +5115,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
|||
case WMI_10_4_UPDATE_STATS_EVENTID:
|
||||
ath10k_wmi_event_update_stats(ar, skb);
|
||||
break;
|
||||
case WMI_10_4_PDEV_TEMPERATURE_EVENTID:
|
||||
ath10k_wmi_event_temperature(ar, skb);
|
||||
break;
|
||||
default:
|
||||
ath10k_warn(ar, "Unknown eventid: %d\n", id);
|
||||
break;
|
||||
|
@ -5431,8 +5488,11 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
|
|||
cmd = (struct wmi_init_cmd_10_2 *)buf->data;
|
||||
|
||||
features = WMI_10_2_RX_BATCH_MODE;
|
||||
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
|
||||
|
||||
if (test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) &&
|
||||
test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
|
||||
features |= WMI_10_2_COEX_GPIO;
|
||||
|
||||
cmd->resource_config.feature_mask = __cpu_to_le32(features);
|
||||
|
||||
memcpy(&cmd->resource_config.common, &config, sizeof(config));
|
||||
|
@ -6328,6 +6388,16 @@ ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void *buf,
|
|||
cmd->info0 = __cpu_to_le32(info0);
|
||||
}
|
||||
|
||||
static void
|
||||
ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf,
|
||||
const struct wmi_peer_assoc_complete_arg *arg)
|
||||
{
|
||||
struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
|
||||
|
||||
ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
|
||||
cmd->peer_bw_rxnss_override = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg)
|
||||
{
|
||||
|
@ -6416,6 +6486,31 @@ ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar,
|
|||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_10_4_op_gen_peer_assoc(struct ath10k *ar,
|
||||
const struct wmi_peer_assoc_complete_arg *arg)
|
||||
{
|
||||
size_t len = sizeof(struct wmi_10_4_peer_assoc_complete_cmd);
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
ret = ath10k_wmi_peer_assoc_check_arg(arg);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, len);
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
ath10k_wmi_peer_assoc_fill_10_4(ar, skb->data, arg);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi peer assoc vdev %d addr %pM (%s)\n",
|
||||
arg->vdev_id, arg->addr,
|
||||
arg->peer_reassoc ? "reassociate" : "new");
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar)
|
||||
{
|
||||
|
@ -7536,6 +7631,7 @@ static const struct wmi_ops wmi_10_4_ops = {
|
|||
.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
|
||||
.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
|
||||
.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
|
||||
.gen_peer_assoc = ath10k_wmi_10_4_op_gen_peer_assoc,
|
||||
.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
|
||||
.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
|
||||
.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
|
||||
|
@ -7555,8 +7651,8 @@ static const struct wmi_ops wmi_10_4_ops = {
|
|||
.fw_stats_fill = ath10k_wmi_10_4_op_fw_stats_fill,
|
||||
|
||||
/* shared with 10.2 */
|
||||
.gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
|
||||
.gen_request_stats = ath10k_wmi_op_gen_request_stats,
|
||||
.gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
|
||||
};
|
||||
|
||||
int ath10k_wmi_attach(struct ath10k *ar)
|
||||
|
@ -7567,30 +7663,35 @@ int ath10k_wmi_attach(struct ath10k *ar)
|
|||
ar->wmi.cmd = &wmi_10_4_cmd_map;
|
||||
ar->wmi.vdev_param = &wmi_10_4_vdev_param_map;
|
||||
ar->wmi.pdev_param = &wmi_10_4_pdev_param_map;
|
||||
ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
|
||||
ar->wmi.cmd = &wmi_10_2_4_cmd_map;
|
||||
ar->wmi.ops = &wmi_10_2_4_ops;
|
||||
ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map;
|
||||
ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map;
|
||||
ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_2:
|
||||
ar->wmi.cmd = &wmi_10_2_cmd_map;
|
||||
ar->wmi.ops = &wmi_10_2_ops;
|
||||
ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
|
||||
ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
|
||||
ar->wmi.peer_flags = &wmi_10_2_peer_flags_map;
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_1:
|
||||
ar->wmi.cmd = &wmi_10x_cmd_map;
|
||||
ar->wmi.ops = &wmi_10_1_ops;
|
||||
ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
|
||||
ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
|
||||
ar->wmi.peer_flags = &wmi_10x_peer_flags_map;
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_MAIN:
|
||||
ar->wmi.cmd = &wmi_cmd_map;
|
||||
ar->wmi.ops = &wmi_ops;
|
||||
ar->wmi.vdev_param = &wmi_vdev_param_map;
|
||||
ar->wmi.pdev_param = &wmi_pdev_param_map;
|
||||
ar->wmi.peer_flags = &wmi_peer_flags_map;
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_TLV:
|
||||
ath10k_wmi_tlv_attach(ar);
|
||||
|
|
|
@ -175,6 +175,8 @@ enum wmi_service {
|
|||
WMI_SERVICE_AUX_SPECTRAL_INTF,
|
||||
WMI_SERVICE_AUX_CHAN_LOAD_INTF,
|
||||
WMI_SERVICE_BSS_CHANNEL_INFO_64,
|
||||
WMI_SERVICE_EXT_RES_CFG_SUPPORT,
|
||||
WMI_SERVICE_MESH,
|
||||
|
||||
/* keep last */
|
||||
WMI_SERVICE_MAX,
|
||||
|
@ -206,6 +208,11 @@ enum wmi_10x_service {
|
|||
WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT,
|
||||
WMI_10X_SERVICE_ATF,
|
||||
WMI_10X_SERVICE_COEX_GPIO,
|
||||
WMI_10X_SERVICE_AUX_SPECTRAL_INTF,
|
||||
WMI_10X_SERVICE_AUX_CHAN_LOAD_INTF,
|
||||
WMI_10X_SERVICE_BSS_CHANNEL_INFO_64,
|
||||
WMI_10X_SERVICE_MESH,
|
||||
WMI_10X_SERVICE_EXT_RES_CFG_SUPPORT,
|
||||
};
|
||||
|
||||
enum wmi_main_service {
|
||||
|
@ -286,6 +293,8 @@ enum wmi_10_4_service {
|
|||
WMI_10_4_SERVICE_AUX_SPECTRAL_INTF,
|
||||
WMI_10_4_SERVICE_AUX_CHAN_LOAD_INTF,
|
||||
WMI_10_4_SERVICE_BSS_CHANNEL_INFO_64,
|
||||
WMI_10_4_SERVICE_EXT_RES_CFG_SUPPORT,
|
||||
WMI_10_4_SERVICE_MESH,
|
||||
};
|
||||
|
||||
static inline char *wmi_service_name(int service_id)
|
||||
|
@ -375,6 +384,8 @@ static inline char *wmi_service_name(int service_id)
|
|||
SVCSTR(WMI_SERVICE_AUX_SPECTRAL_INTF);
|
||||
SVCSTR(WMI_SERVICE_AUX_CHAN_LOAD_INTF);
|
||||
SVCSTR(WMI_SERVICE_BSS_CHANNEL_INFO_64);
|
||||
SVCSTR(WMI_SERVICE_EXT_RES_CFG_SUPPORT);
|
||||
SVCSTR(WMI_SERVICE_MESH);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -442,6 +453,16 @@ static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out,
|
|||
WMI_SERVICE_ATF, len);
|
||||
SVCMAP(WMI_10X_SERVICE_COEX_GPIO,
|
||||
WMI_SERVICE_COEX_GPIO, len);
|
||||
SVCMAP(WMI_10X_SERVICE_AUX_SPECTRAL_INTF,
|
||||
WMI_SERVICE_AUX_SPECTRAL_INTF, len);
|
||||
SVCMAP(WMI_10X_SERVICE_AUX_CHAN_LOAD_INTF,
|
||||
WMI_SERVICE_AUX_CHAN_LOAD_INTF, len);
|
||||
SVCMAP(WMI_10X_SERVICE_BSS_CHANNEL_INFO_64,
|
||||
WMI_SERVICE_BSS_CHANNEL_INFO_64, len);
|
||||
SVCMAP(WMI_10X_SERVICE_MESH,
|
||||
WMI_SERVICE_MESH, len);
|
||||
SVCMAP(WMI_10X_SERVICE_EXT_RES_CFG_SUPPORT,
|
||||
WMI_SERVICE_EXT_RES_CFG_SUPPORT, len);
|
||||
}
|
||||
|
||||
static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out,
|
||||
|
@ -600,6 +621,10 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
|
|||
WMI_SERVICE_AUX_CHAN_LOAD_INTF, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_BSS_CHANNEL_INFO_64,
|
||||
WMI_SERVICE_BSS_CHANNEL_INFO_64, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_EXT_RES_CFG_SUPPORT,
|
||||
WMI_SERVICE_EXT_RES_CFG_SUPPORT, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_MESH,
|
||||
WMI_SERVICE_MESH, len);
|
||||
}
|
||||
|
||||
#undef SVCMAP
|
||||
|
@ -1576,6 +1601,9 @@ enum wmi_10_4_cmd_id {
|
|||
WMI_10_4_MU_CAL_START_CMDID,
|
||||
WMI_10_4_SET_CCA_PARAMS_CMDID,
|
||||
WMI_10_4_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
|
||||
WMI_10_4_EXT_RESOURCE_CFG_CMDID,
|
||||
WMI_10_4_VDEV_SET_IE_CMDID,
|
||||
WMI_10_4_SET_LTEU_CONFIG_CMDID,
|
||||
WMI_10_4_PDEV_UTF_CMDID = WMI_10_4_END_CMDID - 1,
|
||||
};
|
||||
|
||||
|
@ -1638,6 +1666,7 @@ enum wmi_10_4_event_id {
|
|||
WMI_10_4_PDEV_TEMPERATURE_EVENTID,
|
||||
WMI_10_4_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID,
|
||||
WMI_10_4_PDEV_BSS_CHAN_INFO_EVENTID,
|
||||
WMI_10_4_MU_REPORT_EVENTID,
|
||||
WMI_10_4_PDEV_UTF_EVENTID = WMI_10_4_END_EVENTID - 1,
|
||||
};
|
||||
|
||||
|
@ -3650,6 +3679,12 @@ enum wmi_10_4_pdev_param {
|
|||
WMI_10_4_PDEV_PARAM_WAPI_MBSSID_OFFSET,
|
||||
WMI_10_4_PDEV_PARAM_ARP_SRCADDR,
|
||||
WMI_10_4_PDEV_PARAM_ARP_DSTADDR,
|
||||
WMI_10_4_PDEV_PARAM_TXPOWER_DECR_DB,
|
||||
WMI_10_4_PDEV_PARAM_RX_BATCHMODE,
|
||||
WMI_10_4_PDEV_PARAM_PACKET_AGGR_DELAY,
|
||||
WMI_10_4_PDEV_PARAM_ATF_OBSS_NOISE_SCH,
|
||||
WMI_10_4_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR,
|
||||
WMI_10_4_PDEV_PARAM_CUST_TXPOWER_SCALE,
|
||||
};
|
||||
|
||||
struct wmi_pdev_set_param_cmd {
|
||||
|
@ -4239,6 +4274,8 @@ enum wmi_vdev_subtype {
|
|||
WMI_VDEV_SUBTYPE_P2P_DEVICE = 1,
|
||||
WMI_VDEV_SUBTYPE_P2P_CLIENT = 2,
|
||||
WMI_VDEV_SUBTYPE_P2P_GO = 3,
|
||||
WMI_VDEV_SUBTYPE_PROXY_STA = 4,
|
||||
WMI_VDEV_SUBTYPE_MESH = 5,
|
||||
};
|
||||
|
||||
/* values for vdev_subtype */
|
||||
|
@ -5641,21 +5678,79 @@ struct wmi_peer_set_q_empty_callback_cmd {
|
|||
__le32 callback_enable;
|
||||
} __packed;
|
||||
|
||||
#define WMI_PEER_AUTH 0x00000001
|
||||
#define WMI_PEER_QOS 0x00000002
|
||||
#define WMI_PEER_NEED_PTK_4_WAY 0x00000004
|
||||
#define WMI_PEER_NEED_GTK_2_WAY 0x00000010
|
||||
#define WMI_PEER_APSD 0x00000800
|
||||
#define WMI_PEER_HT 0x00001000
|
||||
#define WMI_PEER_40MHZ 0x00002000
|
||||
#define WMI_PEER_STBC 0x00008000
|
||||
#define WMI_PEER_LDPC 0x00010000
|
||||
#define WMI_PEER_DYN_MIMOPS 0x00020000
|
||||
#define WMI_PEER_STATIC_MIMOPS 0x00040000
|
||||
#define WMI_PEER_SPATIAL_MUX 0x00200000
|
||||
#define WMI_PEER_VHT 0x02000000
|
||||
#define WMI_PEER_80MHZ 0x04000000
|
||||
#define WMI_PEER_VHT_2G 0x08000000
|
||||
struct wmi_peer_flags_map {
|
||||
u32 auth;
|
||||
u32 qos;
|
||||
u32 need_ptk_4_way;
|
||||
u32 need_gtk_2_way;
|
||||
u32 apsd;
|
||||
u32 ht;
|
||||
u32 bw40;
|
||||
u32 stbc;
|
||||
u32 ldbc;
|
||||
u32 dyn_mimops;
|
||||
u32 static_mimops;
|
||||
u32 spatial_mux;
|
||||
u32 vht;
|
||||
u32 bw80;
|
||||
u32 vht_2g;
|
||||
u32 pmf;
|
||||
};
|
||||
|
||||
enum wmi_peer_flags {
|
||||
WMI_PEER_AUTH = 0x00000001,
|
||||
WMI_PEER_QOS = 0x00000002,
|
||||
WMI_PEER_NEED_PTK_4_WAY = 0x00000004,
|
||||
WMI_PEER_NEED_GTK_2_WAY = 0x00000010,
|
||||
WMI_PEER_APSD = 0x00000800,
|
||||
WMI_PEER_HT = 0x00001000,
|
||||
WMI_PEER_40MHZ = 0x00002000,
|
||||
WMI_PEER_STBC = 0x00008000,
|
||||
WMI_PEER_LDPC = 0x00010000,
|
||||
WMI_PEER_DYN_MIMOPS = 0x00020000,
|
||||
WMI_PEER_STATIC_MIMOPS = 0x00040000,
|
||||
WMI_PEER_SPATIAL_MUX = 0x00200000,
|
||||
WMI_PEER_VHT = 0x02000000,
|
||||
WMI_PEER_80MHZ = 0x04000000,
|
||||
WMI_PEER_VHT_2G = 0x08000000,
|
||||
WMI_PEER_PMF = 0x10000000,
|
||||
};
|
||||
|
||||
enum wmi_10x_peer_flags {
|
||||
WMI_10X_PEER_AUTH = 0x00000001,
|
||||
WMI_10X_PEER_QOS = 0x00000002,
|
||||
WMI_10X_PEER_NEED_PTK_4_WAY = 0x00000004,
|
||||
WMI_10X_PEER_NEED_GTK_2_WAY = 0x00000010,
|
||||
WMI_10X_PEER_APSD = 0x00000800,
|
||||
WMI_10X_PEER_HT = 0x00001000,
|
||||
WMI_10X_PEER_40MHZ = 0x00002000,
|
||||
WMI_10X_PEER_STBC = 0x00008000,
|
||||
WMI_10X_PEER_LDPC = 0x00010000,
|
||||
WMI_10X_PEER_DYN_MIMOPS = 0x00020000,
|
||||
WMI_10X_PEER_STATIC_MIMOPS = 0x00040000,
|
||||
WMI_10X_PEER_SPATIAL_MUX = 0x00200000,
|
||||
WMI_10X_PEER_VHT = 0x02000000,
|
||||
WMI_10X_PEER_80MHZ = 0x04000000,
|
||||
};
|
||||
|
||||
enum wmi_10_2_peer_flags {
|
||||
WMI_10_2_PEER_AUTH = 0x00000001,
|
||||
WMI_10_2_PEER_QOS = 0x00000002,
|
||||
WMI_10_2_PEER_NEED_PTK_4_WAY = 0x00000004,
|
||||
WMI_10_2_PEER_NEED_GTK_2_WAY = 0x00000010,
|
||||
WMI_10_2_PEER_APSD = 0x00000800,
|
||||
WMI_10_2_PEER_HT = 0x00001000,
|
||||
WMI_10_2_PEER_40MHZ = 0x00002000,
|
||||
WMI_10_2_PEER_STBC = 0x00008000,
|
||||
WMI_10_2_PEER_LDPC = 0x00010000,
|
||||
WMI_10_2_PEER_DYN_MIMOPS = 0x00020000,
|
||||
WMI_10_2_PEER_STATIC_MIMOPS = 0x00040000,
|
||||
WMI_10_2_PEER_SPATIAL_MUX = 0x00200000,
|
||||
WMI_10_2_PEER_VHT = 0x02000000,
|
||||
WMI_10_2_PEER_80MHZ = 0x04000000,
|
||||
WMI_10_2_PEER_VHT_2G = 0x08000000,
|
||||
WMI_10_2_PEER_PMF = 0x10000000,
|
||||
};
|
||||
|
||||
/*
|
||||
* Peer rate capabilities.
|
||||
|
@ -5721,6 +5816,11 @@ struct wmi_10_2_peer_assoc_complete_cmd {
|
|||
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
|
||||
} __packed;
|
||||
|
||||
struct wmi_10_4_peer_assoc_complete_cmd {
|
||||
struct wmi_10_2_peer_assoc_complete_cmd cmd;
|
||||
__le32 peer_bw_rxnss_override;
|
||||
} __packed;
|
||||
|
||||
struct wmi_peer_assoc_complete_arg {
|
||||
u8 addr[ETH_ALEN];
|
||||
u32 vdev_id;
|
||||
|
|
|
@ -414,7 +414,7 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
|
|||
return;
|
||||
}
|
||||
|
||||
if (epid >= ENDPOINT_MAX) {
|
||||
if (epid < 0 || epid >= ENDPOINT_MAX) {
|
||||
if (pipe_id != USB_REG_IN_PIPE)
|
||||
dev_kfree_skb_any(skb);
|
||||
else
|
||||
|
|
|
@ -345,6 +345,8 @@ enum wcn36xx_hal_host_msg_type {
|
|||
WCN36XX_HAL_DHCP_START_IND = 189,
|
||||
WCN36XX_HAL_DHCP_STOP_IND = 190,
|
||||
|
||||
WCN36XX_HAL_AVOID_FREQ_RANGE_IND = 233,
|
||||
|
||||
WCN36XX_HAL_MSG_MAX = WCN36XX_HAL_MSG_TYPE_MAX_ENUM_SIZE
|
||||
};
|
||||
|
||||
|
|
|
@ -302,6 +302,22 @@ static int wcn36xx_smd_rsp_status_check(void *buf, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wcn36xx_smd_rsp_status_check_v2(struct wcn36xx *wcn, void *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct wcn36xx_fw_msg_status_rsp_v2 *rsp;
|
||||
|
||||
if (len < sizeof(struct wcn36xx_hal_msg_header) + sizeof(*rsp))
|
||||
return wcn36xx_smd_rsp_status_check(buf, len);
|
||||
|
||||
rsp = buf + sizeof(struct wcn36xx_hal_msg_header);
|
||||
|
||||
if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status)
|
||||
return rsp->status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wcn36xx_smd_load_nv(struct wcn36xx *wcn)
|
||||
{
|
||||
struct nv_data *nv_d;
|
||||
|
@ -1582,7 +1598,8 @@ int wcn36xx_smd_remove_bsskey(struct wcn36xx *wcn,
|
|||
wcn36xx_err("Sending hal_remove_bsskey failed\n");
|
||||
goto out;
|
||||
}
|
||||
ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
|
||||
ret = wcn36xx_smd_rsp_status_check_v2(wcn, wcn->hal_buf,
|
||||
wcn->hal_rsp_len);
|
||||
if (ret) {
|
||||
wcn36xx_err("hal_remove_bsskey response failed err=%d\n", ret);
|
||||
goto out;
|
||||
|
@ -1951,7 +1968,8 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
|
|||
wcn36xx_err("Sending hal_trigger_ba failed\n");
|
||||
goto out;
|
||||
}
|
||||
ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len);
|
||||
ret = wcn36xx_smd_rsp_status_check_v2(wcn, wcn->hal_buf,
|
||||
wcn->hal_rsp_len);
|
||||
if (ret) {
|
||||
wcn36xx_err("hal_trigger_ba response failed err=%d\n", ret);
|
||||
goto out;
|
||||
|
@ -2128,6 +2146,8 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len)
|
|||
complete(&wcn->hal_rsp_compl);
|
||||
break;
|
||||
|
||||
case WCN36XX_HAL_COEX_IND:
|
||||
case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
|
||||
case WCN36XX_HAL_OTA_TX_COMPL_IND:
|
||||
case WCN36XX_HAL_MISSED_BEACON_IND:
|
||||
case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
|
||||
|
@ -2174,6 +2194,9 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
|
|||
msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg;
|
||||
|
||||
switch (msg_header->msg_type) {
|
||||
case WCN36XX_HAL_COEX_IND:
|
||||
case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
|
||||
break;
|
||||
case WCN36XX_HAL_OTA_TX_COMPL_IND:
|
||||
wcn36xx_smd_tx_compl_ind(wcn,
|
||||
hal_ind_msg->msg,
|
||||
|
|
|
@ -44,6 +44,15 @@ struct wcn36xx_fw_msg_status_rsp {
|
|||
u32 status;
|
||||
} __packed;
|
||||
|
||||
/* wcn3620 returns this for tigger_ba */
|
||||
|
||||
struct wcn36xx_fw_msg_status_rsp_v2 {
|
||||
u8 bss_id[6];
|
||||
u32 status __packed;
|
||||
u16 count_following_candidates __packed;
|
||||
/* candidate list follows */
|
||||
};
|
||||
|
||||
struct wcn36xx_hal_ind_msg {
|
||||
struct list_head list;
|
||||
u8 *msg;
|
||||
|
|
|
@ -401,20 +401,26 @@ void wil_bcast_fini(struct wil6210_priv *wil)
|
|||
|
||||
static void wil_connect_worker(struct work_struct *work)
|
||||
{
|
||||
int rc;
|
||||
int rc, cid, ringid;
|
||||
struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
|
||||
connect_worker);
|
||||
struct net_device *ndev = wil_to_ndev(wil);
|
||||
|
||||
int cid = wil->pending_connect_cid;
|
||||
int ringid = wil_find_free_vring(wil);
|
||||
mutex_lock(&wil->mutex);
|
||||
|
||||
cid = wil->pending_connect_cid;
|
||||
if (cid < 0) {
|
||||
wil_err(wil, "No connection pending\n");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
ringid = wil_find_free_vring(wil);
|
||||
if (ringid < 0) {
|
||||
wil_err(wil, "No free vring found\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
wil_dbg_wmi(wil, "Configure for connection CID %d\n", cid);
|
||||
wil_dbg_wmi(wil, "Configure for connection CID %d vring %d\n",
|
||||
cid, ringid);
|
||||
|
||||
rc = wil_vring_init_tx(wil, ringid, 1 << tx_ring_order, cid, 0);
|
||||
wil->pending_connect_cid = -1;
|
||||
|
@ -424,6 +430,8 @@ static void wil_connect_worker(struct work_struct *work)
|
|||
} else {
|
||||
wil_disconnect_cid(wil, cid, WLAN_REASON_UNSPECIFIED, true);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&wil->mutex);
|
||||
}
|
||||
|
||||
int wil_priv_init(struct wil6210_priv *wil)
|
||||
|
|
|
@ -160,6 +160,7 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
|
|||
struct device *dev = wil_to_dev(wil);
|
||||
size_t sz = vring->size * sizeof(vring->va[0]);
|
||||
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
if (tx) {
|
||||
int vring_index = vring - wil->vring_tx;
|
||||
|
||||
|
@ -749,6 +750,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
|
|||
|
||||
wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
|
||||
cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
if (vring->va) {
|
||||
wil_err(wil, "Tx ring [%d] already allocated\n", id);
|
||||
|
@ -821,6 +823,7 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
|
|||
|
||||
wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
|
||||
cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
if (vring->va) {
|
||||
wil_err(wil, "Tx ring [%d] already allocated\n", id);
|
||||
|
@ -872,7 +875,7 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
|
|||
struct vring *vring = &wil->vring_tx[id];
|
||||
struct vring_tx_data *txdata = &wil->vring_tx_data[id];
|
||||
|
||||
WARN_ON(!mutex_is_locked(&wil->mutex));
|
||||
lockdep_assert_held(&wil->mutex);
|
||||
|
||||
if (!vring->va)
|
||||
return;
|
||||
|
|
|
@ -187,7 +187,8 @@ retry:
|
|||
goto retry;
|
||||
if (id != bcdc->reqid) {
|
||||
brcmf_err("%s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
|
||||
brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id,
|
||||
bcdc->reqid);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
@ -234,7 +235,8 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
|||
|
||||
if (id != bcdc->reqid) {
|
||||
brcmf_err("%s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
|
||||
brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id,
|
||||
bcdc->reqid);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
@ -298,13 +300,13 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws,
|
|||
if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
|
||||
BCDC_PROTO_VER) {
|
||||
brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
|
||||
brcmf_ifname(tmp_if), h->flags);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
if (h->flags & BCDC_FLAG_SUM_GOOD) {
|
||||
brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
|
||||
brcmf_ifname(tmp_if), h->flags);
|
||||
pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ struct brcmf_bus {
|
|||
bool always_use_fws_queue;
|
||||
bool wowl_supported;
|
||||
|
||||
struct brcmf_bus_ops *ops;
|
||||
const struct brcmf_bus_ops *ops;
|
||||
struct brcmf_bus_msgbuf *msgbuf;
|
||||
};
|
||||
|
||||
|
|
|
@ -776,7 +776,8 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
|
|||
s32 ap = 0;
|
||||
s32 err = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type);
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
|
||||
type);
|
||||
|
||||
/* WAR: There are a number of p2p interface related problems which
|
||||
* need to be handled initially (before doing the validate).
|
||||
|
@ -945,7 +946,7 @@ static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
|
|||
|
||||
static s32
|
||||
brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
|
||||
struct cfg80211_scan_request *request, u16 action)
|
||||
struct cfg80211_scan_request *request)
|
||||
{
|
||||
s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
|
||||
offsetof(struct brcmf_escan_params_le, params_le);
|
||||
|
@ -959,7 +960,7 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
|
|||
params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
|
||||
|
||||
/* Allocate space for populating ssids in struct */
|
||||
params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
|
||||
params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
|
||||
}
|
||||
|
||||
params = kzalloc(params_size, GFP_KERNEL);
|
||||
|
@ -970,7 +971,7 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
|
|||
BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
|
||||
brcmf_escan_prep(cfg, ¶ms->params_le, request);
|
||||
params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
|
||||
params->action = cpu_to_le16(action);
|
||||
params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
|
||||
params->sync_id = cpu_to_le16(0x1234);
|
||||
|
||||
err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
|
||||
|
@ -1012,7 +1013,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
|
|||
results->count = 0;
|
||||
results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
|
||||
|
||||
err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
|
||||
err = escan->run(cfg, ifp, request);
|
||||
if (err)
|
||||
brcmf_scan_config_mpc(ifp, 1);
|
||||
return err;
|
||||
|
@ -1291,6 +1292,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
|
|||
s32 wsec = 0;
|
||||
s32 bcnprd;
|
||||
u16 chanspec;
|
||||
u32 ssid_len;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
if (!check_vif_up(ifp->vif))
|
||||
|
@ -1368,17 +1370,15 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
|
|||
memset(&join_params, 0, sizeof(struct brcmf_join_params));
|
||||
|
||||
/* SSID */
|
||||
profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
|
||||
memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
|
||||
memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
|
||||
join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
|
||||
ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
|
||||
memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
|
||||
join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
|
||||
join_params_size = sizeof(join_params.ssid_le);
|
||||
|
||||
/* BSSID */
|
||||
if (params->bssid) {
|
||||
memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
|
||||
join_params_size = sizeof(join_params.ssid_le) +
|
||||
BRCMF_ASSOC_PARAMS_FIXED_SIZE;
|
||||
join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
|
||||
memcpy(profile->bssid, params->bssid, ETH_ALEN);
|
||||
} else {
|
||||
eth_broadcast_addr(join_params.params_le.bssid);
|
||||
|
@ -1728,7 +1728,6 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
|||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
|
||||
struct ieee80211_channel *chan = sme->channel;
|
||||
struct brcmf_join_params join_params;
|
||||
size_t join_params_size;
|
||||
|
@ -1739,6 +1738,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
|||
struct brcmf_ext_join_params_le *ext_join_params;
|
||||
u16 chanspec;
|
||||
s32 err = 0;
|
||||
u32 ssid_len;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
if (!check_vif_up(ifp->vif))
|
||||
|
@ -1824,15 +1824,6 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
|||
goto done;
|
||||
}
|
||||
|
||||
profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
|
||||
(u32)sme->ssid_len);
|
||||
memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
|
||||
if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
|
||||
profile->ssid.SSID[profile->ssid.SSID_len] = 0;
|
||||
brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
|
||||
profile->ssid.SSID_len);
|
||||
}
|
||||
|
||||
/* Join with specific BSSID and cached SSID
|
||||
* If SSID is zero join based on BSSID only
|
||||
*/
|
||||
|
@ -1845,9 +1836,12 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
|||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
|
||||
memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
|
||||
profile->ssid.SSID_len);
|
||||
ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
|
||||
ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
|
||||
memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
|
||||
if (ssid_len < IEEE80211_MAX_SSID_LEN)
|
||||
brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
|
||||
ext_join_params->ssid_le.SSID, ssid_len);
|
||||
|
||||
/* Set up join scan parameters */
|
||||
ext_join_params->scan_le.scan_type = -1;
|
||||
|
@ -1895,8 +1889,8 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
|
|||
memset(&join_params, 0, sizeof(join_params));
|
||||
join_params_size = sizeof(join_params.ssid_le);
|
||||
|
||||
memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
|
||||
join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
|
||||
memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
|
||||
join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
|
||||
|
||||
if (sme->bssid)
|
||||
memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
|
||||
|
@ -2775,9 +2769,7 @@ CleanUp:
|
|||
static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
|
||||
struct brcmf_if *ifp)
|
||||
{
|
||||
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
|
||||
struct brcmf_bss_info_le *bi;
|
||||
struct brcmf_ssid *ssid;
|
||||
const struct brcmf_tlv *tim;
|
||||
u16 beacon_interval;
|
||||
u8 dtim_period;
|
||||
|
@ -2789,8 +2781,6 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
|
|||
if (brcmf_is_ibssmode(ifp->vif))
|
||||
return err;
|
||||
|
||||
ssid = &profile->ssid;
|
||||
|
||||
*(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
|
||||
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
|
||||
cfg->extra_buf, WL_EXTRA_BUF_MAX);
|
||||
|
@ -2921,7 +2911,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
|
|||
status = e->status;
|
||||
|
||||
if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
|
||||
brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
|
||||
brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
|
@ -3061,6 +3051,67 @@ static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
{
|
||||
struct brcmf_wowl_wakeind_le wake_ind_le;
|
||||
struct cfg80211_wowlan_wakeup wakeup_data;
|
||||
struct cfg80211_wowlan_wakeup *wakeup;
|
||||
u32 wakeind;
|
||||
s32 err;
|
||||
|
||||
err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
|
||||
sizeof(wake_ind_le));
|
||||
if (!err) {
|
||||
brcmf_err("Get wowl_wakeind failed, err = %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
|
||||
if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
|
||||
BRCMF_WOWL_RETR | BRCMF_WOWL_NET)) {
|
||||
wakeup = &wakeup_data;
|
||||
memset(&wakeup_data, 0, sizeof(wakeup_data));
|
||||
wakeup_data.pattern_idx = -1;
|
||||
|
||||
if (wakeind & BRCMF_WOWL_MAGIC) {
|
||||
brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
|
||||
wakeup_data.magic_pkt = true;
|
||||
}
|
||||
if (wakeind & BRCMF_WOWL_DIS) {
|
||||
brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
|
||||
wakeup_data.disconnect = true;
|
||||
}
|
||||
if (wakeind & BRCMF_WOWL_BCN) {
|
||||
brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
|
||||
wakeup_data.disconnect = true;
|
||||
}
|
||||
if (wakeind & BRCMF_WOWL_RETR) {
|
||||
brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
|
||||
wakeup_data.disconnect = true;
|
||||
}
|
||||
if (wakeind & BRCMF_WOWL_NET) {
|
||||
brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
|
||||
/* For now always map to pattern 0, no API to get
|
||||
* correct information available at the moment.
|
||||
*/
|
||||
wakeup_data.pattern_idx = 0;
|
||||
}
|
||||
} else {
|
||||
wakeup = NULL;
|
||||
}
|
||||
cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
|
@ -3070,11 +3121,12 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
|
|||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
if (cfg->wowl_enabled) {
|
||||
brcmf_report_wowl_wakeind(wiphy, ifp);
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
|
||||
brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
|
||||
brcmf_configure_arp_offload(ifp, true);
|
||||
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
|
||||
cfg->pre_wowl_pmmode);
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
|
||||
brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
|
||||
cfg->wowl_enabled = false;
|
||||
}
|
||||
return 0;
|
||||
|
@ -3108,6 +3160,7 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
|
|||
wowl->patterns[i].pkt_offset);
|
||||
}
|
||||
}
|
||||
brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear"));
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
|
||||
brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
|
||||
brcmf_bus_wowl_config(cfg->pub->bus_if, true);
|
||||
|
@ -3877,7 +3930,8 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
|
|||
ifp = vif->ifp;
|
||||
saved_ie = &vif->saved_ie;
|
||||
|
||||
brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
|
||||
brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
|
||||
pktflag);
|
||||
iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
|
||||
if (!iovar_ie_buf)
|
||||
return -ENOMEM;
|
||||
|
@ -4183,7 +4237,9 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
|||
}
|
||||
}
|
||||
|
||||
if (dev_role == NL80211_IFTYPE_AP) {
|
||||
if ((dev_role == NL80211_IFTYPE_AP) &&
|
||||
((ifp->ifidx == 0) ||
|
||||
!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
|
||||
if (err < 0) {
|
||||
brcmf_err("BRCMF_C_DOWN error %d\n", err);
|
||||
|
@ -4239,7 +4295,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
|
|||
brcmf_err("setting ssid failed %d\n", err);
|
||||
goto exit;
|
||||
}
|
||||
bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
|
||||
bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
|
||||
bss_enable.enable = cpu_to_le32(1);
|
||||
err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
|
||||
sizeof(bss_enable));
|
||||
|
@ -4306,7 +4362,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
|
|||
if (err < 0)
|
||||
brcmf_err("BRCMF_C_UP error %d\n", err);
|
||||
} else {
|
||||
bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
|
||||
bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
|
||||
bss_enable.enable = cpu_to_le32(0);
|
||||
err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
|
||||
sizeof(bss_enable));
|
||||
|
@ -4700,7 +4756,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
|
|||
vif->wdev.iftype = type;
|
||||
|
||||
vif->pm_block = pm_block;
|
||||
vif->roam_off = -1;
|
||||
|
||||
brcmf_init_prof(&vif->profile);
|
||||
|
||||
|
@ -5092,9 +5147,9 @@ static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
|
|||
struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
|
||||
brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
|
||||
ifevent->action, ifevent->flags, ifevent->ifidx,
|
||||
ifevent->bssidx);
|
||||
ifevent->bsscfgidx);
|
||||
|
||||
mutex_lock(&event->vif_event_lock);
|
||||
event->action = ifevent->action;
|
||||
|
@ -5250,35 +5305,33 @@ static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
|
|||
mutex_init(&event->vif_event_lock);
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
|
||||
static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
|
||||
{
|
||||
s32 err = 0;
|
||||
s32 err;
|
||||
u32 bcn_timeout;
|
||||
__le32 roamtrigger[2];
|
||||
__le32 roam_delta[2];
|
||||
|
||||
/*
|
||||
* Setup timeout if Beacons are lost and roam is
|
||||
* off to report link down
|
||||
*/
|
||||
if (brcmf_roamoff) {
|
||||
err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
|
||||
if (err) {
|
||||
brcmf_err("bcn_timeout error (%d)\n", err);
|
||||
goto dongle_rom_out;
|
||||
}
|
||||
/* Configure beacon timeout value based upon roaming setting */
|
||||
if (brcmf_roamoff)
|
||||
bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
|
||||
else
|
||||
bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
|
||||
err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
|
||||
if (err) {
|
||||
brcmf_err("bcn_timeout error (%d)\n", err);
|
||||
goto roam_setup_done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable/Disable built-in roaming to allow supplicant
|
||||
* to take care of roaming
|
||||
/* Enable/Disable built-in roaming to allow supplicant to take care of
|
||||
* roaming.
|
||||
*/
|
||||
brcmf_dbg(INFO, "Internal Roaming = %s\n",
|
||||
brcmf_roamoff ? "Off" : "On");
|
||||
err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
|
||||
if (err) {
|
||||
brcmf_err("roam_off error (%d)\n", err);
|
||||
goto dongle_rom_out;
|
||||
goto roam_setup_done;
|
||||
}
|
||||
|
||||
roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
|
||||
|
@ -5287,7 +5340,7 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
|
|||
(void *)roamtrigger, sizeof(roamtrigger));
|
||||
if (err) {
|
||||
brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
|
||||
goto dongle_rom_out;
|
||||
goto roam_setup_done;
|
||||
}
|
||||
|
||||
roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
|
||||
|
@ -5296,10 +5349,10 @@ brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
|
|||
(void *)roam_delta, sizeof(roam_delta));
|
||||
if (err) {
|
||||
brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
|
||||
goto dongle_rom_out;
|
||||
goto roam_setup_done;
|
||||
}
|
||||
|
||||
dongle_rom_out:
|
||||
roam_setup_done:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -5619,7 +5672,8 @@ static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
|
|||
}
|
||||
|
||||
static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
|
||||
u32 bw_cap[2], u32 nchain)
|
||||
u32 bw_cap[2], u32 nchain, u32 txstreams,
|
||||
u32 txbf_bfe_cap, u32 txbf_bfr_cap)
|
||||
{
|
||||
__le16 mcs_map;
|
||||
|
||||
|
@ -5638,6 +5692,25 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
|
|||
mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
|
||||
band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
|
||||
band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
|
||||
|
||||
/* Beamforming support information */
|
||||
if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
|
||||
band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
|
||||
if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
|
||||
band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
|
||||
if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
|
||||
band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
|
||||
if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
|
||||
band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
|
||||
|
||||
if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
|
||||
band->vht_cap.cap |=
|
||||
(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
|
||||
band->vht_cap.cap |= ((txstreams - 1) <<
|
||||
IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
|
||||
band->vht_cap.cap |=
|
||||
IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
|
||||
}
|
||||
}
|
||||
|
||||
static int brcmf_setup_wiphybands(struct wiphy *wiphy)
|
||||
|
@ -5652,6 +5725,9 @@ static int brcmf_setup_wiphybands(struct wiphy *wiphy)
|
|||
int err;
|
||||
s32 i;
|
||||
struct ieee80211_supported_band *band;
|
||||
u32 txstreams = 0;
|
||||
u32 txbf_bfe_cap = 0;
|
||||
u32 txbf_bfr_cap = 0;
|
||||
|
||||
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
|
||||
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
|
||||
|
@ -5680,6 +5756,14 @@ static int brcmf_setup_wiphybands(struct wiphy *wiphy)
|
|||
return err;
|
||||
}
|
||||
|
||||
if (vhtmode) {
|
||||
(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
|
||||
(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
|
||||
&txbf_bfe_cap);
|
||||
(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
|
||||
&txbf_bfr_cap);
|
||||
}
|
||||
|
||||
wiphy = cfg_to_wiphy(cfg);
|
||||
for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
|
||||
band = wiphy->bands[i];
|
||||
|
@ -5689,7 +5773,8 @@ static int brcmf_setup_wiphybands(struct wiphy *wiphy)
|
|||
if (nmode)
|
||||
brcmf_update_ht_cap(band, bw_cap, nchain);
|
||||
if (vhtmode)
|
||||
brcmf_update_vht_cap(band, bw_cap, nchain);
|
||||
brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
|
||||
txbf_bfe_cap, txbf_bfr_cap);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -6014,7 +6099,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
|
|||
brcmf_dbg(INFO, "power save set to %s\n",
|
||||
(power_mode ? "enabled" : "disabled"));
|
||||
|
||||
err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
|
||||
err = brcmf_dongle_roam(ifp);
|
||||
if (err)
|
||||
goto default_conf_out;
|
||||
err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#define WL_EXTRA_BUF_MAX 2048
|
||||
#define WL_ROAM_TRIGGER_LEVEL -75
|
||||
#define WL_ROAM_DELTA 20
|
||||
#define WL_BEACON_TIMEOUT 3
|
||||
|
||||
#define WL_SCAN_CHANNEL_TIME 40
|
||||
#define WL_SCAN_UNASSOC_TIME 40
|
||||
|
@ -77,6 +76,9 @@
|
|||
|
||||
#define BRCMF_MAX_DEFAULT_KEYS 4
|
||||
|
||||
/* beacon loss timeout defaults */
|
||||
#define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON 2
|
||||
#define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF 4
|
||||
|
||||
/**
|
||||
* enum brcmf_scan_status - scan engine status
|
||||
|
@ -124,13 +126,11 @@ struct brcmf_cfg80211_security {
|
|||
/**
|
||||
* struct brcmf_cfg80211_profile - profile information.
|
||||
*
|
||||
* @ssid: ssid of associated/associating ap.
|
||||
* @bssid: bssid of joined/joining ibss.
|
||||
* @sec: security information.
|
||||
* @key: key information
|
||||
*/
|
||||
struct brcmf_cfg80211_profile {
|
||||
struct brcmf_ssid ssid;
|
||||
u8 bssid[ETH_ALEN];
|
||||
struct brcmf_cfg80211_security sec;
|
||||
struct brcmf_wsec_key key[BRCMF_MAX_DEFAULT_KEYS];
|
||||
|
@ -180,7 +180,6 @@ struct vif_saved_ie {
|
|||
* @ifp: lower layer interface pointer
|
||||
* @wdev: wireless device.
|
||||
* @profile: profile information.
|
||||
* @roam_off: roaming state.
|
||||
* @sme_state: SME state using enum brcmf_vif_status bits.
|
||||
* @pm_block: power-management blocked.
|
||||
* @list: linked list.
|
||||
|
@ -191,7 +190,6 @@ struct brcmf_cfg80211_vif {
|
|||
struct brcmf_if *ifp;
|
||||
struct wireless_dev wdev;
|
||||
struct brcmf_cfg80211_profile profile;
|
||||
s32 roam_off;
|
||||
unsigned long sme_state;
|
||||
bool pm_block;
|
||||
struct vif_saved_ie saved_ie;
|
||||
|
@ -233,7 +231,7 @@ struct escan_info {
|
|||
struct wiphy *wiphy;
|
||||
struct brcmf_if *ifp;
|
||||
s32 (*run)(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
|
||||
struct cfg80211_scan_request *request, u16 action);
|
||||
struct cfg80211_scan_request *request);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -681,6 +681,7 @@ static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
|
|||
case BRCM_CC_43569_CHIP_ID:
|
||||
case BRCM_CC_43570_CHIP_ID:
|
||||
case BRCM_CC_4358_CHIP_ID:
|
||||
case BRCM_CC_4359_CHIP_ID:
|
||||
case BRCM_CC_43602_CHIP_ID:
|
||||
case BRCM_CC_4371_CHIP_ID:
|
||||
return 0x180000;
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
#define BRCMF_DEFAULT_BCN_TIMEOUT 3
|
||||
#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
|
||||
#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
|
||||
|
||||
|
@ -107,26 +106,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup timeout if Beacons are lost and roam is off to report
|
||||
* link down
|
||||
*/
|
||||
err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout",
|
||||
BRCMF_DEFAULT_BCN_TIMEOUT);
|
||||
if (err) {
|
||||
brcmf_err("bcn_timeout error (%d)\n", err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Enable/Disable build-in roaming to allowed ext supplicant to take
|
||||
* of romaing
|
||||
*/
|
||||
err = brcmf_fil_iovar_int_set(ifp, "roam_off", 1);
|
||||
if (err) {
|
||||
brcmf_err("roam_off error (%d)\n", err);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Setup join_pref to select target by RSSI(with boost on 5GHz) */
|
||||
join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
|
||||
join_pref_params[0].len = 2;
|
||||
|
@ -174,6 +153,9 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Enable tx beamforming, errors can be ignored (not supported) */
|
||||
(void)brcmf_fil_iovar_int_set(ifp, "txbf", 1);
|
||||
|
||||
/* do bus specific preinit here */
|
||||
err = brcmf_bus_preinit(ifp->drvr->bus_if);
|
||||
done:
|
||||
|
|
|
@ -66,20 +66,13 @@ static int brcmf_p2p_enable;
|
|||
module_param_named(p2pon, brcmf_p2p_enable, int, 0);
|
||||
MODULE_PARM_DESC(p2pon, "enable legacy p2p management functionality");
|
||||
|
||||
char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
|
||||
char *brcmf_ifname(struct brcmf_if *ifp)
|
||||
{
|
||||
if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
|
||||
brcmf_err("ifidx %d out of range\n", ifidx);
|
||||
return "<if_bad>";
|
||||
}
|
||||
|
||||
if (drvr->iflist[ifidx] == NULL) {
|
||||
brcmf_err("null i/f %d\n", ifidx);
|
||||
if (!ifp)
|
||||
return "<if_null>";
|
||||
}
|
||||
|
||||
if (drvr->iflist[ifidx]->ndev)
|
||||
return drvr->iflist[ifidx]->ndev->name;
|
||||
if (ifp->ndev)
|
||||
return ifp->ndev->name;
|
||||
|
||||
return "<if_none>";
|
||||
}
|
||||
|
@ -87,7 +80,7 @@ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
|
|||
struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
s32 bssidx;
|
||||
s32 bsscfgidx;
|
||||
|
||||
if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
|
||||
brcmf_err("ifidx %d out of range\n", ifidx);
|
||||
|
@ -95,9 +88,9 @@ struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
|
|||
}
|
||||
|
||||
ifp = NULL;
|
||||
bssidx = drvr->if2bss[ifidx];
|
||||
if (bssidx >= 0)
|
||||
ifp = drvr->iflist[bssidx];
|
||||
bsscfgidx = drvr->if2bss[ifidx];
|
||||
if (bsscfgidx >= 0)
|
||||
ifp = drvr->iflist[bsscfgidx];
|
||||
|
||||
return ifp;
|
||||
}
|
||||
|
@ -115,7 +108,7 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
|
|||
|
||||
ifp = container_of(work, struct brcmf_if, multicast_work);
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
|
||||
ndev = ifp->ndev;
|
||||
|
||||
|
@ -175,7 +168,7 @@ _brcmf_set_mac_address(struct work_struct *work)
|
|||
|
||||
ifp = container_of(work, struct brcmf_if, setmacaddr_work);
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
|
||||
err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
|
||||
ETH_ALEN);
|
||||
|
@ -213,7 +206,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
|
|||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
struct ethhdr *eh = (struct ethhdr *)(skb->data);
|
||||
|
||||
brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
|
||||
brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
|
||||
/* Can the device send data? */
|
||||
if (drvr->bus_if->state != BRCMF_BUS_UP) {
|
||||
|
@ -224,27 +217,19 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!drvr->iflist[ifp->bssidx]) {
|
||||
brcmf_err("bad ifidx %d\n", ifp->bssidx);
|
||||
netif_stop_queue(ndev);
|
||||
dev_kfree_skb(skb);
|
||||
ret = -ENODEV;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Make sure there's enough room for any header */
|
||||
if (skb_headroom(skb) < drvr->hdrlen) {
|
||||
struct sk_buff *skb2;
|
||||
|
||||
brcmf_dbg(INFO, "%s: insufficient headroom\n",
|
||||
brcmf_ifname(drvr, ifp->bssidx));
|
||||
brcmf_ifname(ifp));
|
||||
drvr->bus_if->tx_realloc++;
|
||||
skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
|
||||
dev_kfree_skb(skb);
|
||||
skb = skb2;
|
||||
if (skb == NULL) {
|
||||
brcmf_err("%s: skb_realloc_headroom failed\n",
|
||||
brcmf_ifname(drvr, ifp->bssidx));
|
||||
brcmf_ifname(ifp));
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
@ -282,8 +267,8 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
|
|||
if (!ifp || !ifp->ndev)
|
||||
return;
|
||||
|
||||
brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n",
|
||||
ifp->bssidx, ifp->netif_stop, reason, state);
|
||||
brcmf_dbg(TRACE, "enter: bsscfgidx=%d stop=0x%X reason=%d state=%d\n",
|
||||
ifp->bsscfgidx, ifp->netif_stop, reason, state);
|
||||
|
||||
spin_lock_irqsave(&ifp->netif_stop_lock, flags);
|
||||
if (state) {
|
||||
|
@ -602,7 +587,7 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
|
|||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
|
||||
return &ifp->stats;
|
||||
}
|
||||
|
@ -631,7 +616,7 @@ static int brcmf_netdev_stop(struct net_device *ndev)
|
|||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
|
||||
brcmf_cfg80211_down(ndev);
|
||||
|
||||
|
@ -647,7 +632,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
|
|||
struct brcmf_bus *bus_if = drvr->bus_if;
|
||||
u32 toe_ol;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
|
||||
/* If bus is not ready, can't continue */
|
||||
if (bus_if->state != BRCMF_BUS_UP) {
|
||||
|
@ -689,7 +674,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
|
|||
struct net_device *ndev;
|
||||
s32 err;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,
|
||||
ifp->mac_addr);
|
||||
ndev = ifp->ndev;
|
||||
|
||||
|
@ -721,7 +706,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
drvr->iflist[ifp->bssidx] = NULL;
|
||||
drvr->iflist[ifp->bsscfgidx] = NULL;
|
||||
ndev->netdev_ops = NULL;
|
||||
free_netdev(ndev);
|
||||
return -EBADE;
|
||||
|
@ -739,7 +724,8 @@ void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
|
|||
{
|
||||
struct net_device *ndev;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d carrier=%d\n", ifp->bssidx, on);
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d carrier=%d\n", ifp->bsscfgidx,
|
||||
on);
|
||||
|
||||
ndev = ifp->ndev;
|
||||
brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_DISCONNECTED, !on);
|
||||
|
@ -786,7 +772,7 @@ static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
|
|||
{
|
||||
struct net_device *ndev;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d mac=%pM\n", ifp->bssidx,
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx,
|
||||
ifp->mac_addr);
|
||||
ndev = ifp->ndev;
|
||||
|
||||
|
@ -805,34 +791,35 @@ static int brcmf_net_p2p_attach(struct brcmf_if *ifp)
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
ifp->drvr->iflist[ifp->bssidx] = NULL;
|
||||
ifp->drvr->iflist[ifp->bsscfgidx] = NULL;
|
||||
ndev->netdev_ops = NULL;
|
||||
free_netdev(ndev);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
||||
bool is_p2pdev, char *name, u8 *mac_addr)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
struct net_device *ndev;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifidx);
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, ifidx);
|
||||
|
||||
ifp = drvr->iflist[bssidx];
|
||||
ifp = drvr->iflist[bsscfgidx];
|
||||
/*
|
||||
* Delete the existing interface before overwriting it
|
||||
* in case we missed the BRCMF_E_IF_DEL event.
|
||||
*/
|
||||
if (ifp) {
|
||||
brcmf_err("ERROR: netdev:%s already exists\n",
|
||||
ifp->ndev->name);
|
||||
if (ifidx) {
|
||||
brcmf_err("ERROR: netdev:%s already exists\n",
|
||||
ifp->ndev->name);
|
||||
netif_stop_queue(ifp->ndev);
|
||||
brcmf_net_detach(ifp->ndev);
|
||||
drvr->iflist[bssidx] = NULL;
|
||||
drvr->iflist[bsscfgidx] = NULL;
|
||||
} else {
|
||||
brcmf_err("ignore IF event\n");
|
||||
brcmf_dbg(INFO, "netdev:%s ignore IF event\n",
|
||||
ifp->ndev->name);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
}
|
||||
|
@ -854,15 +841,15 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
|
|||
ndev->destructor = brcmf_cfg80211_free_netdev;
|
||||
ifp = netdev_priv(ndev);
|
||||
ifp->ndev = ndev;
|
||||
/* store mapping ifidx to bssidx */
|
||||
/* store mapping ifidx to bsscfgidx */
|
||||
if (drvr->if2bss[ifidx] == BRCMF_BSSIDX_INVALID)
|
||||
drvr->if2bss[ifidx] = bssidx;
|
||||
drvr->if2bss[ifidx] = bsscfgidx;
|
||||
}
|
||||
|
||||
ifp->drvr = drvr;
|
||||
drvr->iflist[bssidx] = ifp;
|
||||
drvr->iflist[bsscfgidx] = ifp;
|
||||
ifp->ifidx = ifidx;
|
||||
ifp->bssidx = bssidx;
|
||||
ifp->bsscfgidx = bsscfgidx;
|
||||
|
||||
init_waitqueue_head(&ifp->pend_8021x_wait);
|
||||
spin_lock_init(&ifp->netif_stop_lock);
|
||||
|
@ -876,21 +863,22 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
|
|||
return ifp;
|
||||
}
|
||||
|
||||
static void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
|
||||
static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx)
|
||||
{
|
||||
struct brcmf_if *ifp;
|
||||
|
||||
ifp = drvr->iflist[bssidx];
|
||||
drvr->iflist[bssidx] = NULL;
|
||||
ifp = drvr->iflist[bsscfgidx];
|
||||
drvr->iflist[bsscfgidx] = NULL;
|
||||
if (!ifp) {
|
||||
brcmf_err("Null interface, idx=%d\n", bssidx);
|
||||
brcmf_err("Null interface, bsscfgidx=%d\n", bsscfgidx);
|
||||
return;
|
||||
}
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
|
||||
if (drvr->if2bss[ifp->ifidx] == bssidx)
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx,
|
||||
ifp->ifidx);
|
||||
if (drvr->if2bss[ifp->ifidx] == bsscfgidx)
|
||||
drvr->if2bss[ifp->ifidx] = BRCMF_BSSIDX_INVALID;
|
||||
if (ifp->ndev) {
|
||||
if (bssidx == 0) {
|
||||
if (bsscfgidx == 0) {
|
||||
if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
|
||||
rtnl_lock();
|
||||
brcmf_netdev_stop(ifp->ndev);
|
||||
|
@ -920,12 +908,12 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
|
|||
|
||||
void brcmf_remove_interface(struct brcmf_if *ifp)
|
||||
{
|
||||
if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bssidx] != ifp))
|
||||
if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp))
|
||||
return;
|
||||
brcmf_dbg(TRACE, "Enter, bssidx=%d, ifidx=%d\n", ifp->bssidx,
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx,
|
||||
ifp->ifidx);
|
||||
brcmf_fws_del_interface(ifp);
|
||||
brcmf_del_if(ifp->drvr, ifp->bssidx);
|
||||
brcmf_del_if(ifp->drvr, ifp->bsscfgidx);
|
||||
}
|
||||
|
||||
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr)
|
||||
|
@ -940,10 +928,10 @@ int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr)
|
|||
highest = 2;
|
||||
for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) {
|
||||
if (drvr->iflist[ifidx]) {
|
||||
if (drvr->iflist[ifidx]->bssidx == bsscfgidx)
|
||||
if (drvr->iflist[ifidx]->bsscfgidx == bsscfgidx)
|
||||
bsscfgidx = highest + 1;
|
||||
else if (drvr->iflist[ifidx]->bssidx > highest)
|
||||
highest = drvr->iflist[ifidx]->bssidx;
|
||||
else if (drvr->iflist[ifidx]->bsscfgidx > highest)
|
||||
highest = drvr->iflist[ifidx]->bsscfgidx;
|
||||
} else {
|
||||
available = true;
|
||||
}
|
||||
|
@ -1095,6 +1083,8 @@ fail:
|
|||
brcmf_net_detach(ifp->ndev);
|
||||
if (p2p_ifp)
|
||||
brcmf_net_detach(p2p_ifp->ndev);
|
||||
drvr->iflist[0] = NULL;
|
||||
drvr->iflist[1] = NULL;
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -174,7 +174,7 @@ enum brcmf_netif_stop_reason {
|
|||
* @multicast_work: worker object for multicast provisioning.
|
||||
* @fws_desc: interface specific firmware-signalling descriptor.
|
||||
* @ifidx: interface index in device firmware.
|
||||
* @bssidx: index of bss associated with this interface.
|
||||
* @bsscfgidx: index of bss associated with this interface.
|
||||
* @mac_addr: assigned mac address.
|
||||
* @netif_stop: bitmap indicates reason why netif queues are stopped.
|
||||
* @netif_stop_lock: spinlock for update netif_stop from multiple sources.
|
||||
|
@ -190,7 +190,7 @@ struct brcmf_if {
|
|||
struct work_struct multicast_work;
|
||||
struct brcmf_fws_mac_descriptor *fws_desc;
|
||||
int ifidx;
|
||||
s32 bssidx;
|
||||
s32 bsscfgidx;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 netif_stop;
|
||||
spinlock_t netif_stop_lock;
|
||||
|
@ -205,10 +205,10 @@ struct brcmf_skb_reorder_data {
|
|||
int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
|
||||
|
||||
/* Return pointer to interface name */
|
||||
char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
|
||||
char *brcmf_ifname(struct brcmf_if *ifp);
|
||||
struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
|
||||
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
|
||||
bool is_p2pdev, char *name, u8 *mac_addr);
|
||||
void brcmf_remove_interface(struct brcmf_if *ifp);
|
||||
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
|
||||
|
|
|
@ -49,7 +49,7 @@ static int brcmf_debug_psm_watchdog_notify(struct brcmf_if *ifp,
|
|||
const struct brcmf_event_msg *evtmsg,
|
||||
void *data)
|
||||
{
|
||||
brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
|
||||
brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
|
||||
return brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
|
||||
evtmsg->datalen);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#ifndef BRCMFMAC_DEBUG_H
|
||||
#define BRCMFMAC_DEBUG_H
|
||||
|
||||
#include <linux/net.h> /* net_ratelimit() */
|
||||
|
||||
/* message levels */
|
||||
#define BRCMF_TRACE_VAL 0x00000002
|
||||
#define BRCMF_INFO_VAL 0x00000004
|
||||
|
|
|
@ -137,6 +137,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
|
|||
if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
|
||||
brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
|
||||
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
|
||||
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
|
||||
|
||||
if (brcmf_feature_disable) {
|
||||
brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n",
|
||||
|
|
|
@ -24,13 +24,16 @@
|
|||
* PNO: preferred network offload.
|
||||
* WOWL: Wake-On-WLAN.
|
||||
* P2P: peer-to-peer
|
||||
* RSDB: Real Simultaneous Dual Band
|
||||
*/
|
||||
#define BRCMF_FEAT_LIST \
|
||||
BRCMF_FEAT_DEF(MBSS) \
|
||||
BRCMF_FEAT_DEF(MCHAN) \
|
||||
BRCMF_FEAT_DEF(PNO) \
|
||||
BRCMF_FEAT_DEF(WOWL) \
|
||||
BRCMF_FEAT_DEF(P2P)
|
||||
BRCMF_FEAT_DEF(P2P) \
|
||||
BRCMF_FEAT_DEF(RSDB)
|
||||
|
||||
/*
|
||||
* Quirks:
|
||||
*
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
#define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */
|
||||
#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */
|
||||
|
||||
char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
|
||||
static char brcmf_firmware_path[BRCMF_FW_NAME_LEN];
|
||||
module_param_string(alternative_fw_path, brcmf_firmware_path,
|
||||
BRCMF_FW_PATH_LEN, 0440);
|
||||
BRCMF_FW_NAME_LEN, 0440);
|
||||
|
||||
enum nvram_parser_state {
|
||||
IDLE,
|
||||
|
@ -449,8 +449,7 @@ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
|
|||
|
||||
if (raw_nvram)
|
||||
bcm47xx_nvram_release_contents(data);
|
||||
if (fw)
|
||||
release_firmware(fw);
|
||||
release_firmware(fw);
|
||||
if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
|
||||
goto fail;
|
||||
|
||||
|
@ -540,3 +539,43 @@ int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
|
|||
0);
|
||||
}
|
||||
|
||||
int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev,
|
||||
struct brcmf_firmware_mapping mapping_table[],
|
||||
u32 table_size, char fw_name[BRCMF_FW_NAME_LEN],
|
||||
char nvram_name[BRCMF_FW_NAME_LEN])
|
||||
{
|
||||
u32 i;
|
||||
char end;
|
||||
|
||||
for (i = 0; i < table_size; i++) {
|
||||
if (mapping_table[i].chipid == chip &&
|
||||
mapping_table[i].revmask & BIT(chiprev))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == table_size) {
|
||||
brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* check if firmware path is provided by module parameter */
|
||||
if (brcmf_firmware_path[0] != '\0') {
|
||||
strlcpy(fw_name, brcmf_firmware_path, BRCMF_FW_NAME_LEN);
|
||||
if ((nvram_name) && (mapping_table[i].nvram))
|
||||
strlcpy(nvram_name, brcmf_firmware_path,
|
||||
BRCMF_FW_NAME_LEN);
|
||||
|
||||
end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
|
||||
if (end != '/') {
|
||||
strlcat(fw_name, "/", BRCMF_FW_NAME_LEN);
|
||||
if ((nvram_name) && (mapping_table[i].nvram))
|
||||
strlcat(nvram_name, "/", BRCMF_FW_NAME_LEN);
|
||||
}
|
||||
}
|
||||
strlcat(fw_name, mapping_table[i].fw, BRCMF_FW_NAME_LEN);
|
||||
if ((nvram_name) && (mapping_table[i].nvram))
|
||||
strlcat(nvram_name, mapping_table[i].nvram, BRCMF_FW_NAME_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,11 +21,51 @@
|
|||
#define BRCMF_FW_REQ_FLAGS 0x00F0
|
||||
#define BRCMF_FW_REQ_NV_OPTIONAL 0x0010
|
||||
|
||||
#define BRCMF_FW_PATH_LEN 256
|
||||
#define BRCMF_FW_NAME_LEN 32
|
||||
#define BRCMF_FW_NAME_LEN 320
|
||||
|
||||
extern char brcmf_firmware_path[];
|
||||
#define BRCMF_FW_DEFAULT_PATH "brcm/"
|
||||
|
||||
/**
|
||||
* struct brcmf_firmware_mapping - Used to map chipid/revmask to firmware
|
||||
* filename and nvram filename. Each bus type implementation should create
|
||||
* a table of firmware mappings (using the macros defined below).
|
||||
*
|
||||
* @chipid: ID of chip.
|
||||
* @revmask: bitmask of revisions, e.g. 0x10 means rev 4 only, 0xf means rev 0-3
|
||||
* @fw: name of the firmware file.
|
||||
* @nvram: name of nvram file.
|
||||
*/
|
||||
struct brcmf_firmware_mapping {
|
||||
u32 chipid;
|
||||
u32 revmask;
|
||||
const char *fw;
|
||||
const char *nvram;
|
||||
};
|
||||
|
||||
#define BRCMF_FW_NVRAM_DEF(fw_nvram_name, fw, nvram) \
|
||||
static const char BRCM_ ## fw_nvram_name ## _FIRMWARE_NAME[] = \
|
||||
BRCMF_FW_DEFAULT_PATH fw; \
|
||||
static const char BRCM_ ## fw_nvram_name ## _NVRAM_NAME[] = \
|
||||
BRCMF_FW_DEFAULT_PATH nvram; \
|
||||
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw); \
|
||||
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH nvram)
|
||||
|
||||
#define BRCMF_FW_DEF(fw_name, fw) \
|
||||
static const char BRCM_ ## fw_name ## _FIRMWARE_NAME[] = \
|
||||
BRCMF_FW_DEFAULT_PATH fw; \
|
||||
MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH fw) \
|
||||
|
||||
#define BRCMF_FW_NVRAM_ENTRY(chipid, mask, name) \
|
||||
{ chipid, mask, \
|
||||
BRCM_ ## name ## _FIRMWARE_NAME, BRCM_ ## name ## _NVRAM_NAME }
|
||||
|
||||
#define BRCMF_FW_ENTRY(chipid, mask, name) \
|
||||
{ chipid, mask, BRCM_ ## name ## _FIRMWARE_NAME, NULL }
|
||||
|
||||
int brcmf_fw_map_chip_to_name(u32 chip, u32 chiprev,
|
||||
struct brcmf_firmware_mapping mapping_table[],
|
||||
u32 table_size, char fw_name[BRCMF_FW_NAME_LEN],
|
||||
char nvram_name[BRCMF_FW_NAME_LEN]);
|
||||
void brcmf_fw_nvram_free(void *nvram);
|
||||
/*
|
||||
* Request firmware(s) asynchronously. When the asynchronous request
|
||||
|
|
|
@ -182,8 +182,8 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
|
|||
bool is_p2pdev;
|
||||
int err = 0;
|
||||
|
||||
brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u role: %u\n",
|
||||
ifevent->action, ifevent->ifidx, ifevent->bssidx,
|
||||
brcmf_dbg(EVENT, "action: %u ifidx: %u bsscfgidx: %u flags: %u role: %u\n",
|
||||
ifevent->action, ifevent->ifidx, ifevent->bsscfgidx,
|
||||
ifevent->flags, ifevent->role);
|
||||
|
||||
/* The P2P Device interface event must not be ignored contrary to what
|
||||
|
@ -204,12 +204,12 @@ static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr,
|
|||
return;
|
||||
}
|
||||
|
||||
ifp = drvr->iflist[ifevent->bssidx];
|
||||
ifp = drvr->iflist[ifevent->bsscfgidx];
|
||||
|
||||
if (ifevent->action == BRCMF_E_IF_ADD) {
|
||||
brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname,
|
||||
emsg->addr);
|
||||
ifp = brcmf_add_if(drvr, ifevent->bssidx, ifevent->ifidx,
|
||||
ifp = brcmf_add_if(drvr, ifevent->bsscfgidx, ifevent->ifidx,
|
||||
is_p2pdev, emsg->ifname, emsg->addr);
|
||||
if (IS_ERR(ifp))
|
||||
return;
|
||||
|
|
|
@ -219,7 +219,7 @@ struct brcmf_if_event {
|
|||
u8 ifidx;
|
||||
u8 action;
|
||||
u8 flags;
|
||||
u8 bssidx;
|
||||
u8 bsscfgidx;
|
||||
u8 role;
|
||||
};
|
||||
|
||||
|
|
|
@ -126,7 +126,8 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
|
|||
|
||||
brcmf_dbg(FIL, "Failed: %s (%d)\n",
|
||||
brcmf_fil_get_errstr((u32)(-err)), err);
|
||||
return -EBADE;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
s32
|
||||
|
@ -293,22 +294,22 @@ brcmf_fil_iovar_int_get(struct brcmf_if *ifp, char *name, u32 *data)
|
|||
}
|
||||
|
||||
static u32
|
||||
brcmf_create_bsscfg(s32 bssidx, char *name, char *data, u32 datalen, char *buf,
|
||||
u32 buflen)
|
||||
brcmf_create_bsscfg(s32 bsscfgidx, char *name, char *data, u32 datalen,
|
||||
char *buf, u32 buflen)
|
||||
{
|
||||
const s8 *prefix = "bsscfg:";
|
||||
s8 *p;
|
||||
u32 prefixlen;
|
||||
u32 namelen;
|
||||
u32 iolen;
|
||||
__le32 bssidx_le;
|
||||
__le32 bsscfgidx_le;
|
||||
|
||||
if (bssidx == 0)
|
||||
if (bsscfgidx == 0)
|
||||
return brcmf_create_iovar(name, data, datalen, buf, buflen);
|
||||
|
||||
prefixlen = strlen(prefix);
|
||||
namelen = strlen(name) + 1; /* lengh of iovar name + null */
|
||||
iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen;
|
||||
iolen = prefixlen + namelen + sizeof(bsscfgidx_le) + datalen;
|
||||
|
||||
if (buflen < iolen) {
|
||||
brcmf_err("buffer is too short\n");
|
||||
|
@ -326,9 +327,9 @@ brcmf_create_bsscfg(s32 bssidx, char *name, char *data, u32 datalen, char *buf,
|
|||
p += namelen;
|
||||
|
||||
/* bss config index as first data */
|
||||
bssidx_le = cpu_to_le32(bssidx);
|
||||
memcpy(p, &bssidx_le, sizeof(bssidx_le));
|
||||
p += sizeof(bssidx_le);
|
||||
bsscfgidx_le = cpu_to_le32(bsscfgidx);
|
||||
memcpy(p, &bsscfgidx_le, sizeof(bsscfgidx_le));
|
||||
p += sizeof(bsscfgidx_le);
|
||||
|
||||
/* parameter buffer follows */
|
||||
if (datalen)
|
||||
|
@ -347,12 +348,12 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name,
|
|||
|
||||
mutex_lock(&drvr->proto_block);
|
||||
|
||||
brcmf_dbg(FIL, "ifidx=%d, bssidx=%d, name=%s, len=%d\n", ifp->ifidx,
|
||||
ifp->bssidx, name, len);
|
||||
brcmf_dbg(FIL, "ifidx=%d, bsscfgidx=%d, name=%s, len=%d\n", ifp->ifidx,
|
||||
ifp->bsscfgidx, name, len);
|
||||
brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
|
||||
min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
|
||||
|
||||
buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len,
|
||||
buflen = brcmf_create_bsscfg(ifp->bsscfgidx, name, data, len,
|
||||
drvr->proto_buf, sizeof(drvr->proto_buf));
|
||||
if (buflen) {
|
||||
err = brcmf_fil_cmd_data(ifp, BRCMF_C_SET_VAR, drvr->proto_buf,
|
||||
|
@ -376,7 +377,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name,
|
|||
|
||||
mutex_lock(&drvr->proto_block);
|
||||
|
||||
buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len,
|
||||
buflen = brcmf_create_bsscfg(ifp->bsscfgidx, name, data, len,
|
||||
drvr->proto_buf, sizeof(drvr->proto_buf));
|
||||
if (buflen) {
|
||||
err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf,
|
||||
|
@ -387,8 +388,8 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name,
|
|||
err = -EPERM;
|
||||
brcmf_err("Creating bsscfg failed\n");
|
||||
}
|
||||
brcmf_dbg(FIL, "ifidx=%d, bssidx=%d, name=%s, len=%d\n", ifp->ifidx,
|
||||
ifp->bssidx, name, len);
|
||||
brcmf_dbg(FIL, "ifidx=%d, bsscfgidx=%d, name=%s, len=%d\n", ifp->ifidx,
|
||||
ifp->bsscfgidx, name, len);
|
||||
brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data,
|
||||
min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n");
|
||||
|
||||
|
|
|
@ -121,6 +121,11 @@
|
|||
|
||||
#define BRCMF_MAX_ASSOCLIST 128
|
||||
|
||||
#define BRCMF_TXBF_SU_BFE_CAP BIT(0)
|
||||
#define BRCMF_TXBF_MU_BFE_CAP BIT(1)
|
||||
#define BRCMF_TXBF_SU_BFR_CAP BIT(0)
|
||||
#define BRCMF_TXBF_MU_BFR_CAP BIT(1)
|
||||
|
||||
/* join preference types for join_pref iovar */
|
||||
enum brcmf_join_pref_types {
|
||||
BRCMF_JOIN_PREF_RSSI = 1,
|
||||
|
@ -170,7 +175,7 @@ struct brcmf_fil_af_params_le {
|
|||
};
|
||||
|
||||
struct brcmf_fil_bss_enable_le {
|
||||
__le32 bsscfg_idx;
|
||||
__le32 bsscfgidx;
|
||||
__le32 enable;
|
||||
};
|
||||
|
||||
|
@ -282,14 +287,9 @@ struct brcm_rateset_le {
|
|||
u8 rates[BRCMF_MAXRATES_IN_SET];
|
||||
};
|
||||
|
||||
struct brcmf_ssid {
|
||||
u32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
};
|
||||
|
||||
struct brcmf_ssid_le {
|
||||
__le32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
unsigned char SSID[IEEE80211_MAX_SSID_LEN];
|
||||
};
|
||||
|
||||
struct brcmf_scan_params_le {
|
||||
|
@ -634,4 +634,16 @@ struct brcmf_assoclist_le {
|
|||
u8 mac[BRCMF_MAX_ASSOCLIST][ETH_ALEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_wowl_wakeind_le - Wakeup indicators
|
||||
* Note: note both fields contain same information.
|
||||
*
|
||||
* @pci_wakeind: Whether PCI PMECSR PMEStatus bit was set.
|
||||
* @ucode_wakeind: What wakeup-event indication was set by ucode
|
||||
*/
|
||||
struct brcmf_wowl_wakeind_le {
|
||||
__le32 pci_wakeind;
|
||||
__le32 ucode_wakeind;
|
||||
};
|
||||
|
||||
#endif /* FWIL_TYPES_H_ */
|
||||
|
|
|
@ -719,7 +719,7 @@ static void brcmf_fws_macdesc_init(struct brcmf_fws_mac_descriptor *desc,
|
|||
desc->state = BRCMF_FWS_STATE_OPEN;
|
||||
desc->requested_credit = 0;
|
||||
desc->requested_packet = 0;
|
||||
/* depending on use may need ifp->bssidx instead */
|
||||
/* depending on use may need ifp->bsscfgidx instead */
|
||||
desc->interface_id = ifidx;
|
||||
desc->ac_bitmap = 0xff; /* update this when handling APSD */
|
||||
if (addr)
|
||||
|
@ -1938,7 +1938,7 @@ void brcmf_fws_reset_interface(struct brcmf_if *ifp)
|
|||
{
|
||||
struct brcmf_fws_mac_descriptor *entry = ifp->fws_desc;
|
||||
|
||||
brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
|
||||
brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
|
|
|
@ -625,11 +625,10 @@ exit:
|
|||
* @num_chans: number of channels to scan.
|
||||
* @chanspecs: channel parameters for @num_chans channels.
|
||||
* @search_state: P2P discover state to use.
|
||||
* @action: scan action to pass to firmware.
|
||||
* @bss_type: type of P2P bss.
|
||||
*/
|
||||
static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
|
||||
u16 chanspecs[], s32 search_state, u16 action,
|
||||
u16 chanspecs[], s32 search_state,
|
||||
enum p2p_bss_type bss_type)
|
||||
{
|
||||
s32 ret = 0;
|
||||
|
@ -642,7 +641,6 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
|
|||
struct brcmf_cfg80211_vif *vif;
|
||||
struct brcmf_p2p_scan_le *p2p_params;
|
||||
struct brcmf_scan_params_le *sparams;
|
||||
struct brcmf_ssid ssid;
|
||||
|
||||
memsize += num_chans * sizeof(__le16);
|
||||
memblk = kzalloc(memsize, GFP_KERNEL);
|
||||
|
@ -655,16 +653,16 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
|
|||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
p2p_params = (struct brcmf_p2p_scan_le *)memblk;
|
||||
sparams = &p2p_params->eparams.params_le;
|
||||
|
||||
switch (search_state) {
|
||||
case WL_P2P_DISC_ST_SEARCH:
|
||||
/*
|
||||
* If we in SEARCH STATE, we don't need to set SSID explictly
|
||||
* because dongle use P2P WILDCARD internally by default
|
||||
* because dongle use P2P WILDCARD internally by default, use
|
||||
* null ssid, which it is already due to kzalloc.
|
||||
*/
|
||||
/* use null ssid */
|
||||
ssid.SSID_len = 0;
|
||||
memset(ssid.SSID, 0, sizeof(ssid.SSID));
|
||||
break;
|
||||
case WL_P2P_DISC_ST_SCAN:
|
||||
/*
|
||||
|
@ -673,8 +671,10 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
|
|||
* P2P WILDCARD because we just do broadcast scan unless
|
||||
* setting SSID.
|
||||
*/
|
||||
ssid.SSID_len = BRCMF_P2P_WILDCARD_SSID_LEN;
|
||||
memcpy(ssid.SSID, BRCMF_P2P_WILDCARD_SSID, ssid.SSID_len);
|
||||
sparams->ssid_le.SSID_len =
|
||||
cpu_to_le32(BRCMF_P2P_WILDCARD_SSID_LEN);
|
||||
memcpy(sparams->ssid_le.SSID, BRCMF_P2P_WILDCARD_SSID,
|
||||
BRCMF_P2P_WILDCARD_SSID_LEN);
|
||||
break;
|
||||
default:
|
||||
brcmf_err(" invalid search state %d\n", search_state);
|
||||
|
@ -687,11 +687,9 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
|
|||
/*
|
||||
* set p2p scan parameters.
|
||||
*/
|
||||
p2p_params = (struct brcmf_p2p_scan_le *)memblk;
|
||||
p2p_params->type = 'E';
|
||||
|
||||
/* determine the scan engine parameters */
|
||||
sparams = &p2p_params->eparams.params_le;
|
||||
sparams->bss_type = DOT11_BSSTYPE_ANY;
|
||||
if (p2p->cfg->active_scan)
|
||||
sparams->scan_type = 0;
|
||||
|
@ -699,9 +697,6 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
|
|||
sparams->scan_type = 1;
|
||||
|
||||
eth_broadcast_addr(sparams->bssid);
|
||||
if (ssid.SSID_len)
|
||||
memcpy(sparams->ssid_le.SSID, ssid.SSID, ssid.SSID_len);
|
||||
sparams->ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
|
||||
sparams->home_time = cpu_to_le32(P2PAPI_SCAN_HOME_TIME_MS);
|
||||
|
||||
/*
|
||||
|
@ -742,7 +737,7 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
|
|||
|
||||
/* set the escan specific parameters */
|
||||
p2p_params->eparams.version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
|
||||
p2p_params->eparams.action = cpu_to_le16(action);
|
||||
p2p_params->eparams.action = cpu_to_le16(WL_ESCAN_ACTION_START);
|
||||
p2p_params->eparams.sync_id = cpu_to_le16(0x1234);
|
||||
/* perform p2p scan on primary device */
|
||||
ret = brcmf_fil_bsscfg_data_set(vif->ifp, "p2p_scan", memblk, memsize);
|
||||
|
@ -766,8 +761,7 @@ exit:
|
|||
*/
|
||||
static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
|
||||
struct brcmf_if *ifp,
|
||||
struct cfg80211_scan_request *request,
|
||||
u16 action)
|
||||
struct cfg80211_scan_request *request)
|
||||
{
|
||||
struct brcmf_p2p_info *p2p = &cfg->p2p;
|
||||
s32 err = 0;
|
||||
|
@ -827,7 +821,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
|
|||
num_nodfs++;
|
||||
}
|
||||
err = brcmf_p2p_escan(p2p, num_nodfs, chanspecs, search_state,
|
||||
action, P2PAPI_BSSCFG_DEVICE);
|
||||
P2PAPI_BSSCFG_DEVICE);
|
||||
kfree(chanspecs);
|
||||
}
|
||||
exit:
|
||||
|
@ -1096,8 +1090,7 @@ static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel)
|
|||
default_chan_list[2] = ch.chspec;
|
||||
}
|
||||
err = brcmf_p2p_escan(p2p, channel_cnt, default_chan_list,
|
||||
WL_P2P_DISC_ST_SEARCH, WL_ESCAN_ACTION_START,
|
||||
P2PAPI_BSSCFG_DEVICE);
|
||||
WL_P2P_DISC_ST_SEARCH, P2PAPI_BSSCFG_DEVICE);
|
||||
kfree(default_chan_list);
|
||||
exit:
|
||||
return err;
|
||||
|
@ -2067,7 +2060,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
|
|||
struct brcmf_if *p2p_ifp;
|
||||
struct brcmf_if *pri_ifp;
|
||||
int err;
|
||||
u32 bssidx;
|
||||
u32 bsscfgidx;
|
||||
|
||||
if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
|
||||
return ERR_PTR(-ENOSPC);
|
||||
|
@ -2113,13 +2106,13 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
|
|||
memcpy(&p2p_vif->wdev.address, p2p->dev_addr, sizeof(p2p->dev_addr));
|
||||
|
||||
/* verify bsscfg index for P2P discovery */
|
||||
err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
|
||||
err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bsscfgidx);
|
||||
if (err < 0) {
|
||||
brcmf_err("retrieving discover bsscfg index failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
WARN_ON(p2p_ifp->bssidx != bssidx);
|
||||
WARN_ON(p2p_ifp->bsscfgidx != bsscfgidx);
|
||||
|
||||
init_completion(&p2p->send_af_done);
|
||||
INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
|
||||
|
|
|
@ -112,7 +112,6 @@ struct afx_hdl {
|
|||
* @int_addr: P2P interface address.
|
||||
* @bss_idx: informate for P2P bss types.
|
||||
* @listen_timer: timer for @WL_P2P_DISC_ST_LISTEN discover state.
|
||||
* @ssid: ssid for P2P GO.
|
||||
* @listen_channel: channel for @WL_P2P_DISC_ST_LISTEN discover state.
|
||||
* @remain_on_channel: contains copy of struct used by cfg80211.
|
||||
* @remain_on_channel_cookie: cookie counter for remain on channel cmd
|
||||
|
@ -133,7 +132,6 @@ struct brcmf_p2p_info {
|
|||
u8 int_addr[ETH_ALEN];
|
||||
struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
|
||||
struct timer_list listen_timer;
|
||||
struct brcmf_ssid ssid;
|
||||
u8 listen_channel;
|
||||
struct ieee80211_channel remain_on_channel;
|
||||
u32 remain_on_channel_cookie;
|
||||
|
|
|
@ -44,23 +44,29 @@ enum brcmf_pcie_state {
|
|||
BRCMFMAC_PCIE_STATE_UP
|
||||
};
|
||||
|
||||
BRCMF_FW_NVRAM_DEF(43602, "brcmfmac43602-pcie.bin", "brcmfmac43602-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4350, "brcmfmac4350-pcie.bin", "brcmfmac4350-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-pcie.bin", "brcmfmac4356-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt");
|
||||
|
||||
#define BRCMF_PCIE_43602_FW_NAME "brcm/brcmfmac43602-pcie.bin"
|
||||
#define BRCMF_PCIE_43602_NVRAM_NAME "brcm/brcmfmac43602-pcie.txt"
|
||||
#define BRCMF_PCIE_4350_FW_NAME "brcm/brcmfmac4350-pcie.bin"
|
||||
#define BRCMF_PCIE_4350_NVRAM_NAME "brcm/brcmfmac4350-pcie.txt"
|
||||
#define BRCMF_PCIE_4356_FW_NAME "brcm/brcmfmac4356-pcie.bin"
|
||||
#define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt"
|
||||
#define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin"
|
||||
#define BRCMF_PCIE_43570_NVRAM_NAME "brcm/brcmfmac43570-pcie.txt"
|
||||
#define BRCMF_PCIE_4358_FW_NAME "brcm/brcmfmac4358-pcie.bin"
|
||||
#define BRCMF_PCIE_4358_NVRAM_NAME "brcm/brcmfmac4358-pcie.txt"
|
||||
#define BRCMF_PCIE_4365_FW_NAME "brcm/brcmfmac4365b-pcie.bin"
|
||||
#define BRCMF_PCIE_4365_NVRAM_NAME "brcm/brcmfmac4365b-pcie.txt"
|
||||
#define BRCMF_PCIE_4366_FW_NAME "brcm/brcmfmac4366b-pcie.bin"
|
||||
#define BRCMF_PCIE_4366_NVRAM_NAME "brcm/brcmfmac4366b-pcie.txt"
|
||||
#define BRCMF_PCIE_4371_FW_NAME "brcm/brcmfmac4371-pcie.bin"
|
||||
#define BRCMF_PCIE_4371_NVRAM_NAME "brcm/brcmfmac4371-pcie.txt"
|
||||
static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFFFF, 4350),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFFF, 4365B),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFFF, 4366B),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
|
||||
};
|
||||
|
||||
#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */
|
||||
|
||||
|
@ -200,24 +206,6 @@ enum brcmf_pcie_state {
|
|||
#define BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB 3
|
||||
|
||||
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4350_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4350_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4358_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4358_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4365_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4365_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4366_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4366_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4371_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_PCIE_4371_NVRAM_NAME);
|
||||
|
||||
|
||||
struct brcmf_pcie_console {
|
||||
u32 base_addr;
|
||||
u32 buf_addr;
|
||||
|
@ -253,10 +241,9 @@ struct brcmf_pcie_core_info {
|
|||
struct brcmf_pciedev_info {
|
||||
enum brcmf_pcie_state state;
|
||||
bool in_irq;
|
||||
bool irq_requested;
|
||||
struct pci_dev *pdev;
|
||||
char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
|
||||
char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
|
||||
char fw_name[BRCMF_FW_NAME_LEN];
|
||||
char nvram_name[BRCMF_FW_NAME_LEN];
|
||||
void __iomem *regs;
|
||||
void __iomem *tcm;
|
||||
u32 tcm_size;
|
||||
|
@ -622,7 +609,9 @@ static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo,
|
|||
brcmf_chip_resetcore(core, 0, 0, 0);
|
||||
}
|
||||
|
||||
return !brcmf_chip_set_active(devinfo->ci, resetintr);
|
||||
if (!brcmf_chip_set_active(devinfo->ci, resetintr))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -885,7 +874,6 @@ static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
|
|||
|
||||
brcmf_dbg(PCIE, "Enter\n");
|
||||
/* is it a v1 or v2 implementation */
|
||||
devinfo->irq_requested = false;
|
||||
pci_enable_msi(pdev);
|
||||
if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) {
|
||||
if (request_threaded_irq(pdev->irq,
|
||||
|
@ -908,7 +896,6 @@ static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
|
|||
return -EIO;
|
||||
}
|
||||
}
|
||||
devinfo->irq_requested = true;
|
||||
devinfo->irq_allocated = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -926,9 +913,6 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
|
|||
pdev = devinfo->pdev;
|
||||
|
||||
brcmf_pcie_intr_disable(devinfo);
|
||||
if (!devinfo->irq_requested)
|
||||
return;
|
||||
devinfo->irq_requested = false;
|
||||
free_irq(pdev->irq, devinfo);
|
||||
pci_disable_msi(pdev);
|
||||
|
||||
|
@ -1390,10 +1374,6 @@ static void brcmf_pcie_wowl_config(struct device *dev, bool enabled)
|
|||
|
||||
brcmf_dbg(PCIE, "Configuring WOWL, enabled=%d\n", enabled);
|
||||
devinfo->wowl_enabled = enabled;
|
||||
if (enabled)
|
||||
device_set_wakeup_enable(&devinfo->pdev->dev, true);
|
||||
else
|
||||
device_set_wakeup_enable(&devinfo->pdev->dev, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1419,7 +1399,7 @@ static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
|
|||
}
|
||||
|
||||
|
||||
static struct brcmf_bus_ops brcmf_pcie_bus_ops = {
|
||||
static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
|
||||
.txdata = brcmf_pcie_tx,
|
||||
.stop = brcmf_pcie_down,
|
||||
.txctl = brcmf_pcie_tx_ctlpkt,
|
||||
|
@ -1484,80 +1464,6 @@ brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
|
|||
}
|
||||
|
||||
|
||||
static int brcmf_pcie_get_fwnames(struct brcmf_pciedev_info *devinfo)
|
||||
{
|
||||
char *fw_name;
|
||||
char *nvram_name;
|
||||
uint fw_len, nv_len;
|
||||
char end;
|
||||
|
||||
brcmf_dbg(PCIE, "Enter, chip 0x%04x chiprev %d\n", devinfo->ci->chip,
|
||||
devinfo->ci->chiprev);
|
||||
|
||||
switch (devinfo->ci->chip) {
|
||||
case BRCM_CC_43602_CHIP_ID:
|
||||
fw_name = BRCMF_PCIE_43602_FW_NAME;
|
||||
nvram_name = BRCMF_PCIE_43602_NVRAM_NAME;
|
||||
break;
|
||||
case BRCM_CC_4350_CHIP_ID:
|
||||
fw_name = BRCMF_PCIE_4350_FW_NAME;
|
||||
nvram_name = BRCMF_PCIE_4350_NVRAM_NAME;
|
||||
break;
|
||||
case BRCM_CC_4356_CHIP_ID:
|
||||
fw_name = BRCMF_PCIE_4356_FW_NAME;
|
||||
nvram_name = BRCMF_PCIE_4356_NVRAM_NAME;
|
||||
break;
|
||||
case BRCM_CC_43567_CHIP_ID:
|
||||
case BRCM_CC_43569_CHIP_ID:
|
||||
case BRCM_CC_43570_CHIP_ID:
|
||||
fw_name = BRCMF_PCIE_43570_FW_NAME;
|
||||
nvram_name = BRCMF_PCIE_43570_NVRAM_NAME;
|
||||
break;
|
||||
case BRCM_CC_4358_CHIP_ID:
|
||||
fw_name = BRCMF_PCIE_4358_FW_NAME;
|
||||
nvram_name = BRCMF_PCIE_4358_NVRAM_NAME;
|
||||
break;
|
||||
case BRCM_CC_4365_CHIP_ID:
|
||||
fw_name = BRCMF_PCIE_4365_FW_NAME;
|
||||
nvram_name = BRCMF_PCIE_4365_NVRAM_NAME;
|
||||
break;
|
||||
case BRCM_CC_4366_CHIP_ID:
|
||||
fw_name = BRCMF_PCIE_4366_FW_NAME;
|
||||
nvram_name = BRCMF_PCIE_4366_NVRAM_NAME;
|
||||
break;
|
||||
case BRCM_CC_4371_CHIP_ID:
|
||||
fw_name = BRCMF_PCIE_4371_FW_NAME;
|
||||
nvram_name = BRCMF_PCIE_4371_NVRAM_NAME;
|
||||
break;
|
||||
default:
|
||||
brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
fw_len = sizeof(devinfo->fw_name) - 1;
|
||||
nv_len = sizeof(devinfo->nvram_name) - 1;
|
||||
/* check if firmware path is provided by module parameter */
|
||||
if (brcmf_firmware_path[0] != '\0') {
|
||||
strncpy(devinfo->fw_name, brcmf_firmware_path, fw_len);
|
||||
strncpy(devinfo->nvram_name, brcmf_firmware_path, nv_len);
|
||||
fw_len -= strlen(devinfo->fw_name);
|
||||
nv_len -= strlen(devinfo->nvram_name);
|
||||
|
||||
end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
|
||||
if (end != '/') {
|
||||
strncat(devinfo->fw_name, "/", fw_len);
|
||||
strncat(devinfo->nvram_name, "/", nv_len);
|
||||
fw_len--;
|
||||
nv_len--;
|
||||
}
|
||||
}
|
||||
strncat(devinfo->fw_name, fw_name, fw_len);
|
||||
strncat(devinfo->nvram_name, nvram_name, nv_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
|
||||
const struct firmware *fw, void *nvram,
|
||||
u32 nvram_len)
|
||||
|
@ -1893,7 +1799,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot);
|
||||
dev_set_drvdata(&pdev->dev, bus);
|
||||
|
||||
ret = brcmf_pcie_get_fwnames(devinfo);
|
||||
ret = brcmf_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev,
|
||||
brcmf_pcie_fwnames,
|
||||
ARRAY_SIZE(brcmf_pcie_fwnames),
|
||||
devinfo->fw_name, devinfo->nvram_name);
|
||||
if (ret)
|
||||
goto fail_bus;
|
||||
|
||||
|
@ -1959,15 +1868,14 @@ brcmf_pcie_remove(struct pci_dev *pdev)
|
|||
#ifdef CONFIG_PM
|
||||
|
||||
|
||||
static int brcmf_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
static int brcmf_pcie_pm_enter_D3(struct device *dev)
|
||||
{
|
||||
struct brcmf_pciedev_info *devinfo;
|
||||
struct brcmf_bus *bus;
|
||||
int err;
|
||||
|
||||
brcmf_dbg(PCIE, "Enter, state=%d, pdev=%p\n", state.event, pdev);
|
||||
brcmf_err("Enter\n");
|
||||
|
||||
bus = dev_get_drvdata(&pdev->dev);
|
||||
bus = dev_get_drvdata(dev);
|
||||
devinfo = bus->bus_priv.pcie->devinfo;
|
||||
|
||||
brcmf_bus_change_state(bus, BRCMF_BUS_DOWN);
|
||||
|
@ -1982,62 +1890,45 @@ static int brcmf_pcie_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
brcmf_err("Timeout on response for entering D3 substate\n");
|
||||
return -EIO;
|
||||
}
|
||||
brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM_IN_USE);
|
||||
|
||||
err = pci_save_state(pdev);
|
||||
if (err)
|
||||
brcmf_err("pci_save_state failed, err=%d\n", err);
|
||||
if ((err) || (!devinfo->wowl_enabled)) {
|
||||
brcmf_chip_detach(devinfo->ci);
|
||||
devinfo->ci = NULL;
|
||||
brcmf_pcie_remove(pdev);
|
||||
return 0;
|
||||
}
|
||||
devinfo->state = BRCMFMAC_PCIE_STATE_DOWN;
|
||||
|
||||
return pci_prepare_to_sleep(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_pcie_resume(struct pci_dev *pdev)
|
||||
|
||||
static int brcmf_pcie_pm_leave_D3(struct device *dev)
|
||||
{
|
||||
struct brcmf_pciedev_info *devinfo;
|
||||
struct brcmf_bus *bus;
|
||||
struct pci_dev *pdev;
|
||||
int err;
|
||||
|
||||
bus = dev_get_drvdata(&pdev->dev);
|
||||
brcmf_dbg(PCIE, "Enter, pdev=%p, bus=%p\n", pdev, bus);
|
||||
brcmf_err("Enter\n");
|
||||
|
||||
err = pci_set_power_state(pdev, PCI_D0);
|
||||
if (err) {
|
||||
brcmf_err("pci_set_power_state failed, err=%d\n", err);
|
||||
goto cleanup;
|
||||
}
|
||||
pci_restore_state(pdev);
|
||||
pci_enable_wake(pdev, PCI_D3hot, false);
|
||||
pci_enable_wake(pdev, PCI_D3cold, false);
|
||||
bus = dev_get_drvdata(dev);
|
||||
devinfo = bus->bus_priv.pcie->devinfo;
|
||||
brcmf_dbg(PCIE, "Enter, dev=%p, bus=%p\n", dev, bus);
|
||||
|
||||
/* Check if device is still up and running, if so we are ready */
|
||||
if (bus) {
|
||||
devinfo = bus->bus_priv.pcie->devinfo;
|
||||
if (brcmf_pcie_read_reg32(devinfo,
|
||||
BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
|
||||
if (brcmf_pcie_send_mb_data(devinfo,
|
||||
BRCMF_H2D_HOST_D0_INFORM))
|
||||
goto cleanup;
|
||||
brcmf_dbg(PCIE, "Hot resume, continue....\n");
|
||||
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
|
||||
brcmf_bus_change_state(bus, BRCMF_BUS_UP);
|
||||
brcmf_pcie_intr_enable(devinfo);
|
||||
return 0;
|
||||
}
|
||||
if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0) {
|
||||
brcmf_dbg(PCIE, "Try to wakeup device....\n");
|
||||
if (brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D0_INFORM))
|
||||
goto cleanup;
|
||||
brcmf_dbg(PCIE, "Hot resume, continue....\n");
|
||||
devinfo->state = BRCMFMAC_PCIE_STATE_UP;
|
||||
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
|
||||
brcmf_bus_change_state(bus, BRCMF_BUS_UP);
|
||||
brcmf_pcie_intr_enable(devinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (bus) {
|
||||
devinfo = bus->bus_priv.pcie->devinfo;
|
||||
brcmf_chip_detach(devinfo->ci);
|
||||
devinfo->ci = NULL;
|
||||
brcmf_pcie_remove(pdev);
|
||||
}
|
||||
brcmf_chip_detach(devinfo->ci);
|
||||
devinfo->ci = NULL;
|
||||
pdev = devinfo->pdev;
|
||||
brcmf_pcie_remove(pdev);
|
||||
|
||||
err = brcmf_pcie_probe(pdev, NULL);
|
||||
if (err)
|
||||
brcmf_err("probe after resume failed, err=%d\n", err);
|
||||
|
@ -2046,6 +1937,14 @@ cleanup:
|
|||
}
|
||||
|
||||
|
||||
static const struct dev_pm_ops brcmf_pciedrvr_pm = {
|
||||
.suspend = brcmf_pcie_pm_enter_D3,
|
||||
.resume = brcmf_pcie_pm_leave_D3,
|
||||
.freeze = brcmf_pcie_pm_enter_D3,
|
||||
.restore = brcmf_pcie_pm_leave_D3,
|
||||
};
|
||||
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
||||
|
@ -2058,6 +1957,7 @@ static struct pci_device_id brcmf_pcie_devid_table[] = {
|
|||
BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4358_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_4359_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID),
|
||||
BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID),
|
||||
|
@ -2083,9 +1983,8 @@ static struct pci_driver brcmf_pciedrvr = {
|
|||
.probe = brcmf_pcie_probe,
|
||||
.remove = brcmf_pcie_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = brcmf_pcie_suspend,
|
||||
.resume = brcmf_pcie_resume
|
||||
#endif /* CONFIG_PM */
|
||||
.driver.pm = &brcmf_pciedrvr_pm,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -460,7 +460,6 @@ struct brcmf_sdio {
|
|||
|
||||
struct sk_buff *glomd; /* Packet containing glomming descriptor */
|
||||
struct sk_buff_head glom; /* Packet list for glommed superframe */
|
||||
uint glomerr; /* Glom packet read errors */
|
||||
|
||||
u8 *rxbuf; /* Buffer for receiving control packets */
|
||||
uint rxblen; /* Allocated length of rxbuf */
|
||||
|
@ -597,136 +596,41 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
|
|||
{4, 0x1}
|
||||
};
|
||||
|
||||
#define BCM43143_FIRMWARE_NAME "brcm/brcmfmac43143-sdio.bin"
|
||||
#define BCM43143_NVRAM_NAME "brcm/brcmfmac43143-sdio.txt"
|
||||
#define BCM43241B0_FIRMWARE_NAME "brcm/brcmfmac43241b0-sdio.bin"
|
||||
#define BCM43241B0_NVRAM_NAME "brcm/brcmfmac43241b0-sdio.txt"
|
||||
#define BCM43241B4_FIRMWARE_NAME "brcm/brcmfmac43241b4-sdio.bin"
|
||||
#define BCM43241B4_NVRAM_NAME "brcm/brcmfmac43241b4-sdio.txt"
|
||||
#define BCM43241B5_FIRMWARE_NAME "brcm/brcmfmac43241b5-sdio.bin"
|
||||
#define BCM43241B5_NVRAM_NAME "brcm/brcmfmac43241b5-sdio.txt"
|
||||
#define BCM4329_FIRMWARE_NAME "brcm/brcmfmac4329-sdio.bin"
|
||||
#define BCM4329_NVRAM_NAME "brcm/brcmfmac4329-sdio.txt"
|
||||
#define BCM4330_FIRMWARE_NAME "brcm/brcmfmac4330-sdio.bin"
|
||||
#define BCM4330_NVRAM_NAME "brcm/brcmfmac4330-sdio.txt"
|
||||
#define BCM4334_FIRMWARE_NAME "brcm/brcmfmac4334-sdio.bin"
|
||||
#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt"
|
||||
#define BCM43340_FIRMWARE_NAME "brcm/brcmfmac43340-sdio.bin"
|
||||
#define BCM43340_NVRAM_NAME "brcm/brcmfmac43340-sdio.txt"
|
||||
#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin"
|
||||
#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt"
|
||||
#define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin"
|
||||
#define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt"
|
||||
#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
|
||||
#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
|
||||
#define BCM43430_FIRMWARE_NAME "brcm/brcmfmac43430-sdio.bin"
|
||||
#define BCM43430_NVRAM_NAME "brcm/brcmfmac43430-sdio.txt"
|
||||
#define BCM43455_FIRMWARE_NAME "brcm/brcmfmac43455-sdio.bin"
|
||||
#define BCM43455_NVRAM_NAME "brcm/brcmfmac43455-sdio.txt"
|
||||
#define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin"
|
||||
#define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt"
|
||||
BRCMF_FW_NVRAM_DEF(43143, "brcmfmac43143-sdio.bin", "brcmfmac43143-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43241B0, "brcmfmac43241b0-sdio.bin",
|
||||
"brcmfmac43241b0-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43241B4, "brcmfmac43241b4-sdio.bin",
|
||||
"brcmfmac43241b4-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43241B5, "brcmfmac43241b5-sdio.bin",
|
||||
"brcmfmac43241b5-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4329, "brcmfmac4329-sdio.bin", "brcmfmac4329-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4330, "brcmfmac4330-sdio.bin", "brcmfmac4330-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4334, "brcmfmac4334-sdio.bin", "brcmfmac4334-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43340, "brcmfmac43340-sdio.bin", "brcmfmac43340-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4335, "brcmfmac4335-sdio.bin", "brcmfmac4335-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43362, "brcmfmac43362-sdio.bin", "brcmfmac43362-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4339, "brcmfmac4339-sdio.bin", "brcmfmac4339-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43430, "brcmfmac43430-sdio.bin", "brcmfmac43430-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43455, "brcmfmac43455-sdio.bin", "brcmfmac43455-sdio.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4354, "brcmfmac4354-sdio.bin", "brcmfmac4354-sdio.txt");
|
||||
|
||||
MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM43241B0_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43241B0_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM43241B4_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43241B4_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM43241B5_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43241B5_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM4329_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4329_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM4330_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4330_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4334_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM43340_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43340_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4335_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43430_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM43455_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43455_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
|
||||
|
||||
struct brcmf_firmware_names {
|
||||
u32 chipid;
|
||||
u32 revmsk;
|
||||
const char *bin;
|
||||
const char *nv;
|
||||
static struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, 43241B5),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, 4329),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, 43430),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354)
|
||||
};
|
||||
|
||||
enum brcmf_firmware_type {
|
||||
BRCMF_FIRMWARE_BIN,
|
||||
BRCMF_FIRMWARE_NVRAM
|
||||
};
|
||||
|
||||
#define BRCMF_FIRMWARE_NVRAM(name) \
|
||||
name ## _FIRMWARE_NAME, name ## _NVRAM_NAME
|
||||
|
||||
static const struct brcmf_firmware_names brcmf_fwname_data[] = {
|
||||
{ BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
|
||||
{ BRCM_CC_43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
|
||||
{ BRCM_CC_43241_CHIP_ID, 0x00000020, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
|
||||
{ BRCM_CC_43241_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43241B5) },
|
||||
{ BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
|
||||
{ BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
|
||||
{ BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
|
||||
{ BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43340) },
|
||||
{ BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
|
||||
{ BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
|
||||
{ BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
|
||||
{ BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) },
|
||||
{ BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43455) },
|
||||
{ BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
|
||||
};
|
||||
|
||||
static int brcmf_sdio_get_fwnames(struct brcmf_chip *ci,
|
||||
struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
int i;
|
||||
char end;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
|
||||
if (brcmf_fwname_data[i].chipid == ci->chip &&
|
||||
brcmf_fwname_data[i].revmsk & BIT(ci->chiprev))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(brcmf_fwname_data)) {
|
||||
brcmf_err("Unknown chipid %d [%d]\n", ci->chip, ci->chiprev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* check if firmware path is provided by module parameter */
|
||||
if (brcmf_firmware_path[0] != '\0') {
|
||||
strlcpy(sdiodev->fw_name, brcmf_firmware_path,
|
||||
sizeof(sdiodev->fw_name));
|
||||
strlcpy(sdiodev->nvram_name, brcmf_firmware_path,
|
||||
sizeof(sdiodev->nvram_name));
|
||||
|
||||
end = brcmf_firmware_path[strlen(brcmf_firmware_path) - 1];
|
||||
if (end != '/') {
|
||||
strlcat(sdiodev->fw_name, "/",
|
||||
sizeof(sdiodev->fw_name));
|
||||
strlcat(sdiodev->nvram_name, "/",
|
||||
sizeof(sdiodev->nvram_name));
|
||||
}
|
||||
}
|
||||
strlcat(sdiodev->fw_name, brcmf_fwname_data[i].bin,
|
||||
sizeof(sdiodev->fw_name));
|
||||
strlcat(sdiodev->nvram_name, brcmf_fwname_data[i].nv,
|
||||
sizeof(sdiodev->nvram_name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pkt_align(struct sk_buff *p, int len, int align)
|
||||
{
|
||||
uint datalign;
|
||||
|
@ -1654,20 +1558,15 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
|||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
bus->sdcnt.f2rxdata++;
|
||||
|
||||
/* On failure, kill the superframe, allow a couple retries */
|
||||
/* On failure, kill the superframe */
|
||||
if (errcode < 0) {
|
||||
brcmf_err("glom read of %d bytes failed: %d\n",
|
||||
dlen, errcode);
|
||||
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
if (bus->glomerr++ < 3) {
|
||||
brcmf_sdio_rxfail(bus, true, true);
|
||||
} else {
|
||||
bus->glomerr = 0;
|
||||
brcmf_sdio_rxfail(bus, true, false);
|
||||
bus->sdcnt.rxglomfail++;
|
||||
brcmf_sdio_free_glom(bus);
|
||||
}
|
||||
brcmf_sdio_rxfail(bus, true, false);
|
||||
bus->sdcnt.rxglomfail++;
|
||||
brcmf_sdio_free_glom(bus);
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1708,19 +1607,11 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
|||
}
|
||||
|
||||
if (errcode) {
|
||||
/* Terminate frame on error, request
|
||||
a couple retries */
|
||||
/* Terminate frame on error */
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
if (bus->glomerr++ < 3) {
|
||||
/* Restore superframe header space */
|
||||
skb_push(pfirst, sfdoff);
|
||||
brcmf_sdio_rxfail(bus, true, true);
|
||||
} else {
|
||||
bus->glomerr = 0;
|
||||
brcmf_sdio_rxfail(bus, true, false);
|
||||
bus->sdcnt.rxglomfail++;
|
||||
brcmf_sdio_free_glom(bus);
|
||||
}
|
||||
brcmf_sdio_rxfail(bus, true, false);
|
||||
bus->sdcnt.rxglomfail++;
|
||||
brcmf_sdio_free_glom(bus);
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
bus->cur_read.len = 0;
|
||||
return 0;
|
||||
|
@ -4025,7 +3916,7 @@ brcmf_sdio_watchdog(unsigned long data)
|
|||
}
|
||||
}
|
||||
|
||||
static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
|
||||
static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
|
||||
.stop = brcmf_sdio_bus_stop,
|
||||
.preinit = brcmf_sdio_bus_preinit,
|
||||
.txdata = brcmf_sdio_bus_txdata,
|
||||
|
@ -4266,7 +4157,10 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
|||
brcmf_sdio_debugfs_create(bus);
|
||||
brcmf_dbg(INFO, "completed!!\n");
|
||||
|
||||
ret = brcmf_sdio_get_fwnames(bus->ci, sdiodev);
|
||||
ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev,
|
||||
brcmf_sdio_fwnames,
|
||||
ARRAY_SIZE(brcmf_sdio_fwnames),
|
||||
sdiodev->fw_name, sdiodev->nvram_name);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
|
|
|
@ -195,8 +195,8 @@ struct brcmf_sdio_dev {
|
|||
uint max_segment_size;
|
||||
uint txglomsz;
|
||||
struct sg_table sgtable;
|
||||
char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
|
||||
char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
|
||||
char fw_name[BRCMF_FW_NAME_LEN];
|
||||
char nvram_name[BRCMF_FW_NAME_LEN];
|
||||
bool wowl_enabled;
|
||||
enum brcmf_sdiod_state state;
|
||||
struct brcmf_sdiod_freezer *freezer;
|
||||
|
|
|
@ -43,10 +43,20 @@
|
|||
#define BRCMF_USB_CBCTL_READ 1
|
||||
#define BRCMF_USB_MAX_PKT_SIZE 1600
|
||||
|
||||
#define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin"
|
||||
#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin"
|
||||
#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
|
||||
#define BRCMF_USB_43569_FW_NAME "brcm/brcmfmac43569.bin"
|
||||
BRCMF_FW_DEF(43143, "brcmfmac43143.bin");
|
||||
BRCMF_FW_DEF(43236B, "brcmfmac43236b.bin");
|
||||
BRCMF_FW_DEF(43242A, "brcmfmac43242a.bin");
|
||||
BRCMF_FW_DEF(43569, "brcmfmac43569.bin");
|
||||
|
||||
static struct brcmf_firmware_mapping brcmf_usb_fwnames[] = {
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43235_CHIP_ID, 0x00000008, 43236B),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43236_CHIP_ID, 0x00000008, 43236B),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43238_CHIP_ID, 0x00000008, 43236B),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43242_CHIP_ID, 0xFFFFFFFF, 43242A),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43566_CHIP_ID, 0xFFFFFFFF, 43569),
|
||||
BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43569)
|
||||
};
|
||||
|
||||
#define TRX_MAGIC 0x30524448 /* "HDR0" */
|
||||
#define TRX_MAX_OFFSET 3 /* Max number of file offsets */
|
||||
|
@ -139,6 +149,7 @@ struct brcmf_usbdev_info {
|
|||
struct brcmf_usbreq *tx_reqs;
|
||||
struct brcmf_usbreq *rx_reqs;
|
||||
|
||||
char fw_name[BRCMF_FW_NAME_LEN];
|
||||
const u8 *image; /* buffer for combine fw and nvram */
|
||||
int image_len;
|
||||
|
||||
|
@ -983,45 +994,15 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool brcmf_usb_chip_support(int chipid, int chiprev)
|
||||
{
|
||||
switch(chipid) {
|
||||
case BRCM_CC_43143_CHIP_ID:
|
||||
return true;
|
||||
case BRCM_CC_43235_CHIP_ID:
|
||||
case BRCM_CC_43236_CHIP_ID:
|
||||
case BRCM_CC_43238_CHIP_ID:
|
||||
return (chiprev == 3);
|
||||
case BRCM_CC_43242_CHIP_ID:
|
||||
return true;
|
||||
case BRCM_CC_43566_CHIP_ID:
|
||||
case BRCM_CC_43569_CHIP_ID:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
|
||||
{
|
||||
int devid, chiprev;
|
||||
int err;
|
||||
|
||||
brcmf_dbg(USB, "Enter\n");
|
||||
if (devinfo == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
devid = devinfo->bus_pub.devid;
|
||||
chiprev = devinfo->bus_pub.chiprev;
|
||||
|
||||
if (!brcmf_usb_chip_support(devid, chiprev)) {
|
||||
brcmf_err("unsupported chip %d rev %d\n",
|
||||
devid, chiprev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!devinfo->image) {
|
||||
brcmf_err("No firmware!\n");
|
||||
return -ENOENT;
|
||||
|
@ -1071,25 +1052,6 @@ static int check_file(const u8 *headers)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
|
||||
{
|
||||
switch (devinfo->bus_pub.devid) {
|
||||
case BRCM_CC_43143_CHIP_ID:
|
||||
return BRCMF_USB_43143_FW_NAME;
|
||||
case BRCM_CC_43235_CHIP_ID:
|
||||
case BRCM_CC_43236_CHIP_ID:
|
||||
case BRCM_CC_43238_CHIP_ID:
|
||||
return BRCMF_USB_43236_FW_NAME;
|
||||
case BRCM_CC_43242_CHIP_ID:
|
||||
return BRCMF_USB_43242_FW_NAME;
|
||||
case BRCM_CC_43566_CHIP_ID:
|
||||
case BRCM_CC_43569_CHIP_ID:
|
||||
return BRCMF_USB_43569_FW_NAME;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
|
||||
|
@ -1163,7 +1125,7 @@ static void brcmf_usb_wowl_config(struct device *dev, bool enabled)
|
|||
device_set_wakeup_enable(devinfo->dev, false);
|
||||
}
|
||||
|
||||
static struct brcmf_bus_ops brcmf_usb_bus_ops = {
|
||||
static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
|
||||
.txdata = brcmf_usb_tx,
|
||||
.stop = brcmf_usb_down,
|
||||
.txctl = brcmf_usb_tx_ctlpkt,
|
||||
|
@ -1274,9 +1236,16 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
|
|||
bus->chip = bus_pub->devid;
|
||||
bus->chiprev = bus_pub->chiprev;
|
||||
|
||||
ret = brcmf_fw_map_chip_to_name(bus_pub->devid, bus_pub->chiprev,
|
||||
brcmf_usb_fwnames,
|
||||
ARRAY_SIZE(brcmf_usb_fwnames),
|
||||
devinfo->fw_name, NULL);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/* request firmware here */
|
||||
ret = brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo),
|
||||
NULL, brcmf_usb_probe_phase2);
|
||||
ret = brcmf_fw_get_firmwares(dev, 0, devinfo->fw_name, NULL,
|
||||
brcmf_usb_probe_phase2);
|
||||
if (ret) {
|
||||
brcmf_err("firmware request failed: %d\n", ret);
|
||||
goto fail;
|
||||
|
@ -1472,8 +1441,7 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
|
|||
|
||||
brcmf_dbg(USB, "Enter\n");
|
||||
|
||||
return brcmf_fw_get_firmwares(&usb->dev, 0,
|
||||
brcmf_usb_get_fwname(devinfo), NULL,
|
||||
return brcmf_fw_get_firmwares(&usb->dev, 0, devinfo->fw_name, NULL,
|
||||
brcmf_usb_probe_phase2);
|
||||
}
|
||||
|
||||
|
@ -1491,10 +1459,6 @@ static struct usb_device_id brcmf_usb_devid_table[] = {
|
|||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43569_FW_NAME);
|
||||
|
||||
static struct usb_driver brcmf_usbdrvr = {
|
||||
.name = KBUILD_MODNAME,
|
||||
|
@ -1504,7 +1468,6 @@ static struct usb_driver brcmf_usbdrvr = {
|
|||
.suspend = brcmf_usb_suspend,
|
||||
.resume = brcmf_usb_resume,
|
||||
.reset_resume = brcmf_usb_reset_resume,
|
||||
.supports_autosuspend = 1,
|
||||
.disable_hub_initiated_lpm = 1,
|
||||
};
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#define BRCM_CC_43569_CHIP_ID 43569
|
||||
#define BRCM_CC_43570_CHIP_ID 43570
|
||||
#define BRCM_CC_4358_CHIP_ID 0x4358
|
||||
#define BRCM_CC_4359_CHIP_ID 0x4359
|
||||
#define BRCM_CC_43602_CHIP_ID 43602
|
||||
#define BRCM_CC_4365_CHIP_ID 0x4365
|
||||
#define BRCM_CC_4366_CHIP_ID 0x4366
|
||||
|
@ -66,6 +67,7 @@
|
|||
#define BRCM_PCIE_43567_DEVICE_ID 0x43d3
|
||||
#define BRCM_PCIE_43570_DEVICE_ID 0x43d9
|
||||
#define BRCM_PCIE_4358_DEVICE_ID 0x43e9
|
||||
#define BRCM_PCIE_4359_DEVICE_ID 0x43ef
|
||||
#define BRCM_PCIE_43602_DEVICE_ID 0x43ba
|
||||
#define BRCM_PCIE_43602_2G_DEVICE_ID 0x43bb
|
||||
#define BRCM_PCIE_43602_5G_DEVICE_ID 0x43bc
|
||||
|
|
|
@ -5137,21 +5137,9 @@ static void proc_APList_on_close( struct inode *inode, struct file *file ) {
|
|||
memset(APList_rid, 0, sizeof(*APList_rid));
|
||||
APList_rid->len = cpu_to_le16(sizeof(*APList_rid));
|
||||
|
||||
for( i = 0; i < 4 && data->writelen >= (i+1)*6*3; i++ ) {
|
||||
int j;
|
||||
for( j = 0; j < 6*3 && data->wbuffer[j+i*6*3]; j++ ) {
|
||||
switch(j%3) {
|
||||
case 0:
|
||||
APList_rid->ap[i][j/3]=
|
||||
hex_to_bin(data->wbuffer[j+i*6*3])<<4;
|
||||
break;
|
||||
case 1:
|
||||
APList_rid->ap[i][j/3]|=
|
||||
hex_to_bin(data->wbuffer[j+i*6*3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 4 && data->writelen >= (i + 1) * 6 * 3; i++)
|
||||
mac_pton(data->wbuffer + i * 6 * 3, APList_rid->ap[i]);
|
||||
|
||||
disable_MAC(ai, 1);
|
||||
writeAPListRid(ai, APList_rid, 1);
|
||||
enable_MAC(ai, 1);
|
||||
|
|
|
@ -53,7 +53,7 @@ config IWLWIFI_LEDS
|
|||
|
||||
config IWLDVM
|
||||
tristate "Intel Wireless WiFi DVM Firmware support"
|
||||
default IWLWIFI
|
||||
depends on m
|
||||
help
|
||||
This is the driver that supports the DVM firmware. The list
|
||||
of the devices that use this firmware is available here:
|
||||
|
|
|
@ -8,7 +8,7 @@ iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o
|
|||
iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o
|
||||
iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
|
||||
iwlwifi-$(CONFIG_IWLDVM) += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += iwl-7000.o iwl-8000.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += iwl-7000.o iwl-8000.o iwl-9000.o
|
||||
iwlwifi-objs += iwl-trans.o
|
||||
|
||||
iwlwifi-objs += $(iwlwifi-m)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -134,8 +134,6 @@ static int iwl_led_cmd(struct iwl_priv *priv,
|
|||
on = IWL_LED_SOLID;
|
||||
}
|
||||
|
||||
IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
|
||||
priv->cfg->base_params->led_compensation);
|
||||
led_cmd.on = iwl_blink_compensation(priv, on,
|
||||
priv->cfg->base_params->led_compensation);
|
||||
led_cmd.off = iwl_blink_compensation(priv, off,
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -1411,13 +1411,7 @@ static void iwlagn_mac_remove_interface(struct ieee80211_hw *hw,
|
|||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (WARN_ON(ctx->vif != vif)) {
|
||||
struct iwl_rxon_context *tmp;
|
||||
IWL_ERR(priv, "ctx->vif = %p, vif = %p\n", ctx->vif, vif);
|
||||
for_each_context(priv, tmp)
|
||||
IWL_ERR(priv, "\tID = %d:\tctx = %p\tctx->vif = %p\n",
|
||||
tmp->ctxid, tmp, tmp->vif);
|
||||
}
|
||||
WARN_ON(ctx->vif != vif);
|
||||
ctx->vif = NULL;
|
||||
|
||||
iwl_teardown_interface(priv, vif, false);
|
||||
|
|
|
@ -1227,7 +1227,21 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
|||
trans_cfg.op_mode = op_mode;
|
||||
trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
|
||||
trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
|
||||
trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
|
||||
|
||||
switch (iwlwifi_mod_params.amsdu_size) {
|
||||
case IWL_AMSDU_4K:
|
||||
trans_cfg.rx_buf_size = IWL_AMSDU_4K;
|
||||
break;
|
||||
case IWL_AMSDU_8K:
|
||||
trans_cfg.rx_buf_size = IWL_AMSDU_8K;
|
||||
break;
|
||||
case IWL_AMSDU_12K:
|
||||
default:
|
||||
trans_cfg.rx_buf_size = IWL_AMSDU_4K;
|
||||
pr_err("Unsupported amsdu_size: %d\n",
|
||||
iwlwifi_mod_params.amsdu_size);
|
||||
}
|
||||
|
||||
trans_cfg.cmd_q_wdg_timeout = IWL_WATCHDOG_DISABLED;
|
||||
|
||||
trans_cfg.command_names = iwl_dvm_cmd_strings;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
#ifndef __iwl_power_setting_h__
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
@ -33,6 +34,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -274,6 +276,17 @@ const struct iwl_cfg iwl3165_2ac_cfg = {
|
|||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl3168_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 3168",
|
||||
.fw_name_pre = IWL7265D_FW_PRE,
|
||||
IWL_DEVICE_7000,
|
||||
.ht_params = &iwl7000_ht_params,
|
||||
.nvm_ver = IWL3165_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL3165_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 7265",
|
||||
.fw_name_pre = IWL7265_FW_PRE,
|
||||
|
|
|
@ -154,7 +154,6 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
|||
.base_params = &iwl8000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \
|
||||
.d0i3 = true, \
|
||||
.features = NETIF_F_RXCSUM, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.dccm_offset = IWL8260_DCCM_OFFSET, \
|
||||
|
@ -187,6 +186,16 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
|
|||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl8265_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 8265",
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
IWL_DEVICE_8000,
|
||||
.ht_params = &iwl8000_ht_params,
|
||||
.nvm_ver = IWL8000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL8000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl4165_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 4165",
|
||||
.fw_name_pre = IWL8000_FW_PRE,
|
||||
|
|
163
drivers/net/wireless/intel/iwlwifi/iwl-9000.c
Normal file
163
drivers/net/wireless/intel/iwlwifi/iwl-9000.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/stringify.h>
|
||||
#include "iwl-config.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL9000_UCODE_API_MAX 16
|
||||
|
||||
/* Oldest version we won't warn about */
|
||||
#define IWL9000_UCODE_API_OK 13
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL9000_UCODE_API_MIN 13
|
||||
|
||||
/* NVM versions */
|
||||
#define IWL9000_NVM_VERSION 0x0a1d
|
||||
#define IWL9000_TX_POWER_VERSION 0xffff /* meaningless */
|
||||
|
||||
/* Memory offsets and lengths */
|
||||
#define IWL9000_DCCM_OFFSET 0x800000
|
||||
#define IWL9000_DCCM_LEN 0x18000
|
||||
#define IWL9000_DCCM2_OFFSET 0x880000
|
||||
#define IWL9000_DCCM2_LEN 0x8000
|
||||
#define IWL9000_SMEM_OFFSET 0x400000
|
||||
#define IWL9000_SMEM_LEN 0x68000
|
||||
|
||||
#define IWL9000_FW_PRE "iwlwifi-9000-"
|
||||
#define IWL9000_MODULE_FIRMWARE(api) \
|
||||
IWL9000_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_9000 10
|
||||
|
||||
static const struct iwl_base_params iwl9000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_9000,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.pll_cfg_val = 0,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 57,
|
||||
.wd_timeout = IWL_LONG_WD_TIMEOUT,
|
||||
.max_event_log_size = 512,
|
||||
.shadow_reg_enable = true,
|
||||
.pcie_l1_allowed = true,
|
||||
};
|
||||
|
||||
static const struct iwl_ht_params iwl9000_ht_params = {
|
||||
.stbc = true,
|
||||
.ldpc = true,
|
||||
.ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
|
||||
};
|
||||
|
||||
static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.ct_kill_entry = 115,
|
||||
.ct_kill_exit = 93,
|
||||
.ct_kill_duration = 5,
|
||||
.dynamic_smps_entry = 111,
|
||||
.dynamic_smps_exit = 107,
|
||||
.tx_protection_entry = 112,
|
||||
.tx_protection_exit = 105,
|
||||
.tx_backoff = {
|
||||
{.temperature = 110, .backoff = 200},
|
||||
{.temperature = 111, .backoff = 600},
|
||||
{.temperature = 112, .backoff = 1200},
|
||||
{.temperature = 113, .backoff = 2000},
|
||||
{.temperature = 114, .backoff = 4000},
|
||||
},
|
||||
.support_ct_kill = true,
|
||||
.support_dynamic_smps = true,
|
||||
.support_tx_protection = true,
|
||||
.support_tx_backoff = true,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_9000 \
|
||||
.ucode_api_max = IWL9000_UCODE_API_MAX, \
|
||||
.ucode_api_ok = IWL9000_UCODE_API_OK, \
|
||||
.ucode_api_min = IWL9000_UCODE_API_MIN, \
|
||||
.device_family = IWL_DEVICE_FAMILY_8000, \
|
||||
.max_inst_size = IWL60_RTC_INST_SIZE, \
|
||||
.max_data_size = IWL60_RTC_DATA_SIZE, \
|
||||
.base_params = &iwl9000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_9000, \
|
||||
.non_shared_ant = ANT_A, \
|
||||
.dccm_offset = IWL9000_DCCM_OFFSET, \
|
||||
.dccm_len = IWL9000_DCCM_LEN, \
|
||||
.dccm2_offset = IWL9000_DCCM2_OFFSET, \
|
||||
.dccm2_len = IWL9000_DCCM2_LEN, \
|
||||
.smem_offset = IWL9000_SMEM_OFFSET, \
|
||||
.smem_len = IWL9000_SMEM_LEN, \
|
||||
.thermal_params = &iwl9000_tt_params, \
|
||||
.apmg_not_supported = true
|
||||
|
||||
const struct iwl_cfg iwl9260_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 9260",
|
||||
.fw_name_pre = IWL9000_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl5165_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 5165",
|
||||
.fw_name_pre = IWL9000_FW_PRE,
|
||||
IWL_DEVICE_9000,
|
||||
.ht_params = &iwl9000_ht_params,
|
||||
.nvm_ver = IWL9000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL9000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL9000_MODULE_FIRMWARE(IWL9000_UCODE_API_OK));
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -254,6 +254,7 @@ struct iwl_tt_params {
|
|||
#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(u16)) /* 16 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(u16)) /* 32 KB */
|
||||
#define OTP_LOW_IMAGE_SIZE_FAMILY_9000 OTP_LOW_IMAGE_SIZE_FAMILY_8000
|
||||
|
||||
struct iwl_eeprom_params {
|
||||
const u8 regulatory_bands[7];
|
||||
|
@ -295,7 +296,6 @@ struct iwl_pwr_tx_backoff {
|
|||
* @high_temp: Is this NIC is designated to be in high temperature.
|
||||
* @host_interrupt_operation_mode: device needs host interrupt operation
|
||||
* mode set
|
||||
* @d0i3: device uses d0i3 instead of d3
|
||||
* @nvm_hw_section_num: the ID of the HW NVM section
|
||||
* @features: hw features, any combination of feature_whitelist
|
||||
* @pwr_tx_backoffs: translation table between power limits and backoffs
|
||||
|
@ -342,7 +342,6 @@ struct iwl_cfg {
|
|||
const bool internal_wimax_coex;
|
||||
const bool host_interrupt_operation_mode;
|
||||
bool high_temp;
|
||||
bool d0i3;
|
||||
u8 nvm_hw_section_num;
|
||||
bool lp_xtal_workaround;
|
||||
const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;
|
||||
|
@ -421,6 +420,7 @@ extern const struct iwl_cfg iwl3160_2ac_cfg;
|
|||
extern const struct iwl_cfg iwl3160_2n_cfg;
|
||||
extern const struct iwl_cfg iwl3160_n_cfg;
|
||||
extern const struct iwl_cfg iwl3165_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl3168_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl7265_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl7265_2n_cfg;
|
||||
extern const struct iwl_cfg iwl7265_n_cfg;
|
||||
|
@ -429,9 +429,12 @@ extern const struct iwl_cfg iwl7265d_2n_cfg;
|
|||
extern const struct iwl_cfg iwl7265d_n_cfg;
|
||||
extern const struct iwl_cfg iwl8260_2n_cfg;
|
||||
extern const struct iwl_cfg iwl8260_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl8265_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl4165_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
|
||||
extern const struct iwl_cfg iwl4165_2ac_sdio_cfg;
|
||||
extern const struct iwl_cfg iwl9260_2ac_cfg;
|
||||
extern const struct iwl_cfg iwl5165_2ac_cfg;
|
||||
#endif /* CONFIG_IWLMVM */
|
||||
|
||||
#endif /* __IWL_CONFIG_H__ */
|
||||
|
|
|
@ -163,7 +163,6 @@ do { \
|
|||
#define IWL_DL_FW 0x00010000
|
||||
#define IWL_DL_RF_KILL 0x00020000
|
||||
#define IWL_DL_FW_ERRORS 0x00040000
|
||||
#define IWL_DL_LED 0x00080000
|
||||
/* 0x00F00000 - 0x00100000 */
|
||||
#define IWL_DL_RATE 0x00100000
|
||||
#define IWL_DL_CALIB 0x00200000
|
||||
|
@ -189,7 +188,6 @@ do { \
|
|||
#define IWL_DEBUG_RX(p, f, a...) IWL_DEBUG(p, IWL_DL_RX, f, ## a)
|
||||
#define IWL_DEBUG_TX(p, f, a...) IWL_DEBUG(p, IWL_DL_TX, f, ## a)
|
||||
#define IWL_DEBUG_ISR(p, f, a...) IWL_DEBUG(p, IWL_DL_ISR, f, ## a)
|
||||
#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a)
|
||||
#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
|
||||
#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
|
||||
#define IWL_DEBUG_QUOTA(p, f, a...) IWL_DEBUG(p, IWL_DL_QUOTA, f, ## a)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
|
|
@ -451,7 +451,9 @@ static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
|
|||
int i;
|
||||
|
||||
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_API, 32)) {
|
||||
IWL_ERR(drv, "api_index larger than supported by driver\n");
|
||||
IWL_ERR(drv,
|
||||
"api flags index %d larger than supported by driver\n",
|
||||
api_index);
|
||||
/* don't return an error so we can load FW that has more bits */
|
||||
return 0;
|
||||
}
|
||||
|
@ -473,7 +475,9 @@ static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
|
|||
int i;
|
||||
|
||||
if (api_index >= DIV_ROUND_UP(NUM_IWL_UCODE_TLV_CAPA, 32)) {
|
||||
IWL_ERR(drv, "api_index larger than supported by driver\n");
|
||||
IWL_ERR(drv,
|
||||
"capa flags index %d larger than supported by driver\n",
|
||||
api_index);
|
||||
/* don't return an error so we can load FW that has more bits */
|
||||
return 0;
|
||||
}
|
||||
|
@ -1323,6 +1327,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
|||
sizeof(struct iwl_fw_dbg_trigger_time_event);
|
||||
trigger_tlv_sz[FW_DBG_TRIGGER_BA] =
|
||||
sizeof(struct iwl_fw_dbg_trigger_ba);
|
||||
trigger_tlv_sz[FW_DBG_TRIGGER_TDLS] =
|
||||
sizeof(struct iwl_fw_dbg_trigger_tdls);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) {
|
||||
if (pieces->dbg_trigger_tlv[i]) {
|
||||
|
@ -1539,6 +1545,7 @@ struct iwl_mod_params iwlwifi_mod_params = {
|
|||
.bt_coex_active = true,
|
||||
.power_level = IWL_POWER_INDEX_1,
|
||||
.d0i3_disable = true,
|
||||
.d0i3_entry_delay = 1000,
|
||||
#ifndef CONFIG_IWLWIFI_UAPSD
|
||||
.uapsd_disable = true,
|
||||
#endif /* CONFIG_IWLWIFI_UAPSD */
|
||||
|
@ -1637,9 +1644,9 @@ MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
|
|||
module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(11n_disable,
|
||||
"disable 11n functionality, bitmap: 1: full, 2: disable agg TX, 4: disable agg RX, 8 enable agg TX");
|
||||
module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
|
||||
module_param_named(amsdu_size, iwlwifi_mod_params.amsdu_size,
|
||||
int, S_IRUGO);
|
||||
MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)");
|
||||
MODULE_PARM_DESC(amsdu_size, "amsdu size 0:4K 1:8K 2:12K (default 0)");
|
||||
module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)");
|
||||
|
||||
|
@ -1704,3 +1711,7 @@ MODULE_PARM_DESC(power_level,
|
|||
module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(fw_monitor,
|
||||
"firmware monitor - to debug FW (default: false - needs lots of memory)");
|
||||
|
||||
module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_entry_delay,
|
||||
uint, S_IRUGO);
|
||||
MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)");
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -766,7 +766,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
|
|||
if (cfg->ht_params->ldpc)
|
||||
ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
|
||||
|
||||
if (iwlwifi_mod_params.amsdu_size_8K)
|
||||
if (iwlwifi_mod_params.amsdu_size >= IWL_AMSDU_8K)
|
||||
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
|
||||
ht_info->ampdu_factor = cfg->max_ht_ampdu_exponent;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -288,6 +288,9 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
|
|||
* @FW_DBG_TRIGGER_TIME_EVENT: trigger log collection upon time events related
|
||||
* events.
|
||||
* @FW_DBG_TRIGGER_BA: trigger log collection upon BlockAck related events.
|
||||
* @FW_DBG_TX_LATENCY: trigger log collection when the tx latency goes above a
|
||||
* threshold.
|
||||
* @FW_DBG_TDLS: trigger log collection upon TDLS related events.
|
||||
*/
|
||||
enum iwl_fw_dbg_trigger {
|
||||
FW_DBG_TRIGGER_INVALID = 0,
|
||||
|
@ -302,6 +305,8 @@ enum iwl_fw_dbg_trigger {
|
|||
FW_DBG_TRIGGER_TXQ_TIMERS,
|
||||
FW_DBG_TRIGGER_TIME_EVENT,
|
||||
FW_DBG_TRIGGER_BA,
|
||||
FW_DBG_TRIGGER_TX_LATENCY,
|
||||
FW_DBG_TRIGGER_TDLS,
|
||||
|
||||
/* must be last */
|
||||
FW_DBG_TRIGGER_MAX,
|
||||
|
|
|
@ -308,6 +308,7 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
|
|||
* @IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT: supports gscan
|
||||
* @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement
|
||||
* @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts
|
||||
* @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT
|
||||
*
|
||||
* @NUM_IWL_UCODE_TLV_CAPA: number of bits used
|
||||
*/
|
||||
|
@ -334,6 +335,7 @@ enum iwl_ucode_tlv_capa {
|
|||
IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31,
|
||||
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
|
||||
IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65,
|
||||
IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67,
|
||||
|
||||
NUM_IWL_UCODE_TLV_CAPA
|
||||
#ifdef __CHECKER__
|
||||
|
@ -722,6 +724,19 @@ struct iwl_fw_dbg_trigger_ba {
|
|||
__le16 frame_timeout;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_trigger_tdls - configures trigger for TDLS events.
|
||||
* @action_bitmap: the TDLS action to trigger the collection upon
|
||||
* @peer_mode: trigger on specific peer or all
|
||||
* @peer: the TDLS peer to trigger the collection on
|
||||
*/
|
||||
struct iwl_fw_dbg_trigger_tdls {
|
||||
u8 action_bitmap;
|
||||
u8 peer_mode;
|
||||
u8 peer[ETH_ALEN];
|
||||
u8 reserved[4];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
|
||||
* @id: conf id
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -305,18 +305,4 @@ iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
|
|||
return conf_tlv->usniffer;
|
||||
}
|
||||
|
||||
#define iwl_fw_dbg_trigger_enabled(fw, id) ({ \
|
||||
void *__dbg_trigger = (fw)->dbg_trigger_tlv[(id)]; \
|
||||
unlikely(__dbg_trigger); \
|
||||
})
|
||||
|
||||
static inline struct iwl_fw_dbg_trigger_tlv*
|
||||
iwl_fw_dbg_get_trigger(const struct iwl_fw *fw, u8 id)
|
||||
{
|
||||
if (WARN_ON(id >= ARRAY_SIZE(fw->dbg_trigger_tlv)))
|
||||
return NULL;
|
||||
|
||||
return fw->dbg_trigger_tlv[id];
|
||||
}
|
||||
|
||||
#endif /* __iwl_fw_h__ */
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project.
|
||||
*
|
||||
|
@ -117,18 +118,20 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
|
|||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_poll_direct_bit);
|
||||
|
||||
u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs)
|
||||
u32 iwl_read_prph_no_grab(struct iwl_trans *trans, u32 ofs)
|
||||
{
|
||||
u32 val = iwl_trans_read_prph(trans, ofs);
|
||||
trace_iwlwifi_dev_ioread_prph32(trans->dev, ofs, val);
|
||||
return val;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_read_prph_no_grab);
|
||||
|
||||
void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
|
||||
void iwl_write_prph_no_grab(struct iwl_trans *trans, u32 ofs, u32 val)
|
||||
{
|
||||
trace_iwlwifi_dev_iowrite_prph32(trans->dev, ofs, val);
|
||||
iwl_trans_write_prph(trans, ofs, val);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_write_prph_no_grab);
|
||||
|
||||
u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
|
||||
{
|
||||
|
@ -136,7 +139,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
|
|||
u32 val = 0x5a5a5a5a;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
val = __iwl_read_prph(trans, ofs);
|
||||
val = iwl_read_prph_no_grab(trans, ofs);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
return val;
|
||||
|
@ -148,7 +151,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
|
|||
unsigned long flags;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
__iwl_write_prph(trans, ofs, val);
|
||||
iwl_write_prph_no_grab(trans, ofs, val);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
}
|
||||
|
@ -174,8 +177,9 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
|
|||
unsigned long flags;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
__iwl_write_prph(trans, ofs,
|
||||
__iwl_read_prph(trans, ofs) | mask);
|
||||
iwl_write_prph_no_grab(trans, ofs,
|
||||
iwl_read_prph_no_grab(trans, ofs) |
|
||||
mask);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
}
|
||||
|
@ -187,8 +191,9 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
|
|||
unsigned long flags;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
__iwl_write_prph(trans, ofs,
|
||||
(__iwl_read_prph(trans, ofs) & mask) | bits);
|
||||
iwl_write_prph_no_grab(trans, ofs,
|
||||
(iwl_read_prph_no_grab(trans, ofs) &
|
||||
mask) | bits);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
}
|
||||
|
@ -200,8 +205,8 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
|
|||
u32 val;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
val = __iwl_read_prph(trans, ofs);
|
||||
__iwl_write_prph(trans, ofs, (val & ~mask));
|
||||
val = iwl_read_prph_no_grab(trans, ofs);
|
||||
iwl_write_prph_no_grab(trans, ofs, (val & ~mask));
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -55,9 +55,9 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg);
|
|||
void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value);
|
||||
|
||||
|
||||
u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs);
|
||||
u32 iwl_read_prph_no_grab(struct iwl_trans *trans, u32 ofs);
|
||||
u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs);
|
||||
void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val);
|
||||
void iwl_write_prph_no_grab(struct iwl_trans *trans, u32 ofs, u32 val);
|
||||
void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val);
|
||||
int iwl_poll_prph_bit(struct iwl_trans *trans, u32 addr,
|
||||
u32 bits, u32 mask, int timeout);
|
||||
|
|
|
@ -86,6 +86,12 @@ enum iwl_disable_11n {
|
|||
IWL_ENABLE_HT_TXAGG = BIT(3),
|
||||
};
|
||||
|
||||
enum iwl_amsdu_size {
|
||||
IWL_AMSDU_4K = 0,
|
||||
IWL_AMSDU_8K = 1,
|
||||
IWL_AMSDU_12K = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_mod_params
|
||||
*
|
||||
|
@ -94,7 +100,7 @@ enum iwl_disable_11n {
|
|||
* @sw_crypto: using hardware encryption, default = 0
|
||||
* @disable_11n: disable 11n capabilities, default = 0,
|
||||
* use IWL_[DIS,EN]ABLE_HT_* constants
|
||||
* @amsdu_size_8K: enable 8K amsdu size, default = 0
|
||||
* @amsdu_size: enable 8K amsdu size, default = 4K. enum iwl_amsdu_size.
|
||||
* @restart_fw: restart firmware, default = 1
|
||||
* @bt_coex_active: enable bt coex, default = true
|
||||
* @led_mode: system default, default = 0
|
||||
|
@ -103,13 +109,15 @@ enum iwl_disable_11n {
|
|||
* @debug_level: levels are IWL_DL_*
|
||||
* @ant_coupling: antenna coupling in dB, default = 0
|
||||
* @d0i3_disable: disable d0i3, default = 1,
|
||||
* @d0i3_entry_delay: time to wait after no refs are taken before
|
||||
* entering D0i3 (in msecs)
|
||||
* @lar_disable: disable LAR (regulatory), default = 0
|
||||
* @fw_monitor: allow to use firmware monitor
|
||||
*/
|
||||
struct iwl_mod_params {
|
||||
int sw_crypto;
|
||||
unsigned int disable_11n;
|
||||
int amsdu_size_8K;
|
||||
int amsdu_size;
|
||||
bool restart_fw;
|
||||
bool bt_coex_active;
|
||||
int led_mode;
|
||||
|
@ -122,6 +130,7 @@ struct iwl_mod_params {
|
|||
char *nvm_file;
|
||||
bool uapsd_disable;
|
||||
bool d0i3_disable;
|
||||
unsigned int d0i3_entry_delay;
|
||||
bool lar_disable;
|
||||
bool fw_monitor;
|
||||
};
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -379,8 +379,19 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
|
|||
else
|
||||
vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
|
||||
|
||||
if (iwlwifi_mod_params.amsdu_size_8K)
|
||||
switch (iwlwifi_mod_params.amsdu_size) {
|
||||
case IWL_AMSDU_4K:
|
||||
vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
|
||||
break;
|
||||
case IWL_AMSDU_8K:
|
||||
vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
|
||||
break;
|
||||
case IWL_AMSDU_12K:
|
||||
vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
vht_cap->vht_mcs.rx_mcs_map =
|
||||
cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
|
||||
|
@ -580,15 +591,13 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
|
|||
IWL_ERR_DEV(dev, "mac address is not found\n");
|
||||
}
|
||||
|
||||
#define IWL_4165_DEVICE_ID 0x5501
|
||||
|
||||
struct iwl_nvm_data *
|
||||
iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
const __le16 *nvm_hw, const __le16 *nvm_sw,
|
||||
const __le16 *nvm_calib, const __le16 *regulatory,
|
||||
const __le16 *mac_override, const __le16 *phy_sku,
|
||||
u8 tx_chains, u8 rx_chains, bool lar_fw_supported,
|
||||
u32 mac_addr0, u32 mac_addr1, u32 hw_id)
|
||||
u32 mac_addr0, u32 mac_addr1)
|
||||
{
|
||||
struct iwl_nvm_data *data;
|
||||
u32 sku;
|
||||
|
@ -627,17 +636,6 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
|
|||
(sku & NVM_SKU_CAP_11AC_ENABLE);
|
||||
data->sku_cap_mimo_disabled = sku & NVM_SKU_CAP_MIMO_DISABLE;
|
||||
|
||||
/*
|
||||
* OTP 0x52 bug work around
|
||||
* define antenna 1x1 according to MIMO disabled
|
||||
*/
|
||||
if (hw_id == IWL_4165_DEVICE_ID && data->sku_cap_mimo_disabled) {
|
||||
data->valid_tx_ant = ANT_B;
|
||||
data->valid_rx_ant = ANT_B;
|
||||
tx_chains = ANT_B;
|
||||
rx_chains = ANT_B;
|
||||
}
|
||||
|
||||
data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
|
||||
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -79,7 +79,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
|
|||
const __le16 *nvm_calib, const __le16 *regulatory,
|
||||
const __le16 *mac_override, const __le16 *phy_sku,
|
||||
u8 tx_chains, u8 rx_chains, bool lar_fw_supported,
|
||||
u32 mac_addr0, u32 mac_addr1, u32 hw_id);
|
||||
u32 mac_addr0, u32 mac_addr1);
|
||||
|
||||
/**
|
||||
* iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -423,6 +423,22 @@ enum iwl_trans_status {
|
|||
STATUS_TRANS_DEAD,
|
||||
};
|
||||
|
||||
static inline int
|
||||
iwl_trans_get_rb_size_order(enum iwl_amsdu_size rb_size)
|
||||
{
|
||||
switch (rb_size) {
|
||||
case IWL_AMSDU_4K:
|
||||
return get_order(4 * 1024);
|
||||
case IWL_AMSDU_8K:
|
||||
return get_order(8 * 1024);
|
||||
case IWL_AMSDU_12K:
|
||||
return get_order(12 * 1024);
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* struct iwl_trans_config - transport configuration
|
||||
*
|
||||
|
@ -436,7 +452,7 @@ enum iwl_trans_status {
|
|||
* list of such notifications to filter. Max length is
|
||||
* %MAX_NO_RECLAIM_CMDS.
|
||||
* @n_no_reclaim_cmds: # of commands in list
|
||||
* @rx_buf_size_8k: 8 kB RX buffer size needed for A-MSDUs,
|
||||
* @rx_buf_size: RX buffer size needed for A-MSDUs
|
||||
* if unset 4k will be the RX buffer size
|
||||
* @bc_table_dword: set to true if the BC table expects the byte count to be
|
||||
* in DWORD (as opposed to bytes)
|
||||
|
@ -456,7 +472,7 @@ struct iwl_trans_config {
|
|||
const u8 *no_reclaim_cmds;
|
||||
unsigned int n_no_reclaim_cmds;
|
||||
|
||||
bool rx_buf_size_8k;
|
||||
enum iwl_amsdu_size rx_buf_size;
|
||||
bool bc_table_dword;
|
||||
bool scd_set_active;
|
||||
bool wide_cmd_header;
|
||||
|
@ -526,8 +542,6 @@ struct iwl_trans_txq_scd_cfg {
|
|||
* @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
|
||||
* @freeze_txq_timer: prevents the timer of the queue from firing until the
|
||||
* queue is set to awake. Must be atomic.
|
||||
* @dbgfs_register: add the dbgfs files under this directory. Files will be
|
||||
* automatically deleted.
|
||||
* @write8: write a u8 to a register at offset ofs from the BAR
|
||||
* @write32: write a u32 to a register at offset ofs from the BAR
|
||||
* @read32: read a u32 register at offset ofs from the BAR
|
||||
|
@ -583,7 +597,6 @@ struct iwl_trans_ops {
|
|||
void (*txq_disable)(struct iwl_trans *trans, int queue,
|
||||
bool configure_scd);
|
||||
|
||||
int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
|
||||
int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
|
||||
void (*freeze_txq_timer)(struct iwl_trans *trans, unsigned long txqs,
|
||||
bool freeze);
|
||||
|
@ -1006,12 +1019,6 @@ static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
|
|||
return trans->ops->wait_tx_queue_empty(trans, txqs);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
|
||||
struct dentry *dir)
|
||||
{
|
||||
return trans->ops->dbgfs_register(trans, dir);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_write8(struct iwl_trans *trans, u32 ofs, u8 val)
|
||||
{
|
||||
trans->ops->write8(trans, ofs, val);
|
||||
|
|
|
@ -6,7 +6,7 @@ iwlmvm-y += power.o coex.o coex_legacy.o
|
|||
iwlmvm-y += tt.o offloading.o tdls.o
|
||||
iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
|
||||
iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
|
||||
iwlmvm-y += tof.o
|
||||
iwlmvm-y += tof.o fw-dbg.o
|
||||
iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
|
||||
|
||||
ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
|
|
@ -443,11 +443,8 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
|
|||
if (iwl_mvm_bt_is_plcr_supported(mvm))
|
||||
bt_cmd.enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED);
|
||||
|
||||
if (IWL_MVM_BT_COEX_MPLUT) {
|
||||
if (iwl_mvm_is_mplut_supported(mvm))
|
||||
bt_cmd.enabled_modules |= cpu_to_le32(BT_COEX_MPLUT_ENABLED);
|
||||
bt_cmd.enabled_modules |=
|
||||
cpu_to_le32(BT_COEX_MPLUT_BOOST_ENABLED);
|
||||
}
|
||||
|
||||
bt_cmd.enabled_modules |= cpu_to_le32(BT_COEX_HIGH_BAND_RET);
|
||||
|
||||
|
@ -904,6 +901,7 @@ u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
|
|||
struct ieee80211_tx_info *info, u8 ac)
|
||||
{
|
||||
__le16 fc = hdr->frame_control;
|
||||
bool mplut_enabled = iwl_mvm_is_mplut_supported(mvm);
|
||||
|
||||
if (info->band != IEEE80211_BAND_2GHZ)
|
||||
return 0;
|
||||
|
@ -911,22 +909,27 @@ u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
|
|||
if (unlikely(mvm->bt_tx_prio))
|
||||
return mvm->bt_tx_prio - 1;
|
||||
|
||||
/* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */
|
||||
if (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO ||
|
||||
is_multicast_ether_addr(hdr->addr1) ||
|
||||
ieee80211_is_ctl(fc) || ieee80211_is_mgmt(fc) ||
|
||||
ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc))
|
||||
if (likely(ieee80211_is_data(fc))) {
|
||||
if (likely(ieee80211_is_data_qos(fc))) {
|
||||
switch (ac) {
|
||||
case IEEE80211_AC_BE:
|
||||
return mplut_enabled ? 1 : 0;
|
||||
case IEEE80211_AC_VI:
|
||||
return mplut_enabled ? 2 : 3;
|
||||
case IEEE80211_AC_VO:
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} else if (is_multicast_ether_addr(hdr->addr1)) {
|
||||
return 3;
|
||||
} else
|
||||
return 0;
|
||||
} else if (ieee80211_is_mgmt(fc)) {
|
||||
return ieee80211_is_disassoc(fc) ? 0 : 3;
|
||||
} else if (ieee80211_is_ctl(fc)) {
|
||||
/* ignore cfend and cfendack frames as we never send those */
|
||||
return 3;
|
||||
|
||||
switch (ac) {
|
||||
case IEEE80211_AC_BE:
|
||||
return 1;
|
||||
case IEEE80211_AC_VO:
|
||||
return 3;
|
||||
case IEEE80211_AC_VI:
|
||||
return 2;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue