wireless-drivers patches for 4.6
Major changes: rtl8xxxu * add 8723bu support wl18xx * add radar_debug_mode debugfs file for DFS testing -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJW5m6PAAoJEG4XJFUm622bbZcIAIkYDxDHyXgc1vIWSHgYaarQ naz4jmONiGIrSWZBC+GBzCrwUbqgokybN1VRsSmwrB+nS0PtrxivvSs4GItGUdhK 7v+Ygq2tAIHFLiHI2GbztLybg8dLLuJTBlfSpR9QLVN2ApeAE9YQe9QzYkqqHtFy XtC7HYfwCS+jmmV1ONNVEwTtiOsnncdxYmscm0ZyldukGTbu/B2itkczv2ZfK9XP rfhovEjGYioSKd165+/SsUgVMdLOnOIe2v7ZmK0msX6dRfSFBdhL/q0Xflb54ez7 5BZx6o/2L4rKlTCJTMhCTInIuDJEelC9bch48V/Khxne4U+HSQ5/ZPYZLjHhAYM= =ejBA -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-next-for-davem-2016-03-14' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next Kalle Valo says: ==================== wireless-drivers patches for 4.6 Major changes: rtl8xxxu * add 8723bu support wl18xx * add radar_debug_mode debugfs file for DFS testing ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
d3bf9b19ff
|
@ -677,10 +677,8 @@ static void brcmf_pcie_handle_mb_data(struct brcmf_pciedev_info *devinfo)
|
|||
brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP EXIT\n");
|
||||
if (dtoh_mb_data & BRCMF_D2H_DEV_D3_ACK) {
|
||||
brcmf_dbg(PCIE, "D2H_MB_DATA: D3 ACK\n");
|
||||
if (waitqueue_active(&devinfo->mbdata_resp_wait)) {
|
||||
devinfo->mbdata_completed = true;
|
||||
wake_up(&devinfo->mbdata_resp_wait);
|
||||
}
|
||||
devinfo->mbdata_completed = true;
|
||||
wake_up(&devinfo->mbdata_resp_wait);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1652,10 +1652,10 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
|
|||
|
||||
trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
|
||||
table.data1, table.data2, table.line,
|
||||
table.blink1, table.blink2, table.ilink1,
|
||||
table.ilink2, table.bcon_time, table.gp1,
|
||||
table.gp2, table.gp3, table.ucode_ver,
|
||||
table.hw_ver, 0, table.brd_ver);
|
||||
table.blink2, table.ilink1, table.ilink2,
|
||||
table.bcon_time, table.gp1, table.gp2,
|
||||
table.gp3, table.ucode_ver, table.hw_ver,
|
||||
0, table.brd_ver);
|
||||
IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id,
|
||||
desc_lookup(table.error_id));
|
||||
IWL_ERR(priv, "0x%08X | uPc\n", table.pc);
|
||||
|
|
|
@ -140,7 +140,8 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
|||
.thermal_params = &iwl9000_tt_params, \
|
||||
.apmg_not_supported = true, \
|
||||
.mq_rx_supported = true, \
|
||||
.vht_mu_mimo_supported = true
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = true
|
||||
|
||||
const struct iwl_cfg iwl9260_2ac_cfg = {
|
||||
.name = "Intel(R) Dual Band Wireless AC 9260",
|
||||
|
|
|
@ -297,6 +297,7 @@ struct iwl_pwr_tx_backoff {
|
|||
* @host_interrupt_operation_mode: device needs host interrupt operation
|
||||
* mode set
|
||||
* @nvm_hw_section_num: the ID of the HW NVM section
|
||||
* @mac_addr_from_csr: read HW address from CSR registers
|
||||
* @features: hw features, any combination of feature_whitelist
|
||||
* @pwr_tx_backoffs: translation table between power limits and backoffs
|
||||
* @max_rx_agg_size: max RX aggregation size of the ADDBA request/response
|
||||
|
@ -345,6 +346,7 @@ struct iwl_cfg {
|
|||
const bool host_interrupt_operation_mode;
|
||||
bool high_temp;
|
||||
u8 nvm_hw_section_num;
|
||||
bool mac_addr_from_csr;
|
||||
bool lp_xtal_workaround;
|
||||
const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;
|
||||
bool no_power_up_nic_in_init;
|
||||
|
|
|
@ -598,4 +598,14 @@ enum msix_hw_int_causes {
|
|||
#define MSIX_AUTO_CLEAR_CAUSE 0
|
||||
#define MSIX_NON_AUTO_CLEAR_CAUSE BIT(7)
|
||||
|
||||
/*****************************************************************************
|
||||
* HW address related registers *
|
||||
*****************************************************************************/
|
||||
|
||||
#define CSR_ADDR_BASE (0x380)
|
||||
#define CSR_MAC_ADDR0_OTP (CSR_ADDR_BASE)
|
||||
#define CSR_MAC_ADDR1_OTP (CSR_ADDR_BASE + 4)
|
||||
#define CSR_MAC_ADDR0_STRAP (CSR_ADDR_BASE + 8)
|
||||
#define CSR_MAC_ADDR1_STRAP (CSR_ADDR_BASE + 0xC)
|
||||
|
||||
#endif /* !__iwl_csr_h__ */
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
*
|
||||
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 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
|
||||
|
@ -121,13 +122,12 @@ TRACE_EVENT(iwlwifi_dev_tx,
|
|||
|
||||
TRACE_EVENT(iwlwifi_dev_ucode_error,
|
||||
TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
|
||||
u32 data1, u32 data2, u32 line, u32 blink1,
|
||||
u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
|
||||
u32 gp1, u32 gp2, u32 gp3, u32 major, u32 minor, u32 hw_ver,
|
||||
u32 brd_ver),
|
||||
u32 data1, u32 data2, u32 line, u32 blink2, u32 ilink1,
|
||||
u32 ilink2, u32 bcon_time, u32 gp1, u32 gp2, u32 rev_type,
|
||||
u32 major, u32 minor, u32 hw_ver, u32 brd_ver),
|
||||
TP_ARGS(dev, desc, tsf_low, data1, data2, line,
|
||||
blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
|
||||
gp3, major, minor, hw_ver, brd_ver),
|
||||
blink2, ilink1, ilink2, bcon_time, gp1, gp2,
|
||||
rev_type, major, minor, hw_ver, brd_ver),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__field(u32, desc)
|
||||
|
@ -135,14 +135,13 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
|
|||
__field(u32, data1)
|
||||
__field(u32, data2)
|
||||
__field(u32, line)
|
||||
__field(u32, blink1)
|
||||
__field(u32, blink2)
|
||||
__field(u32, ilink1)
|
||||
__field(u32, ilink2)
|
||||
__field(u32, bcon_time)
|
||||
__field(u32, gp1)
|
||||
__field(u32, gp2)
|
||||
__field(u32, gp3)
|
||||
__field(u32, rev_type)
|
||||
__field(u32, major)
|
||||
__field(u32, minor)
|
||||
__field(u32, hw_ver)
|
||||
|
@ -155,29 +154,27 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
|
|||
__entry->data1 = data1;
|
||||
__entry->data2 = data2;
|
||||
__entry->line = line;
|
||||
__entry->blink1 = blink1;
|
||||
__entry->blink2 = blink2;
|
||||
__entry->ilink1 = ilink1;
|
||||
__entry->ilink2 = ilink2;
|
||||
__entry->bcon_time = bcon_time;
|
||||
__entry->gp1 = gp1;
|
||||
__entry->gp2 = gp2;
|
||||
__entry->gp3 = gp3;
|
||||
__entry->rev_type = rev_type;
|
||||
__entry->major = major;
|
||||
__entry->minor = minor;
|
||||
__entry->hw_ver = hw_ver;
|
||||
__entry->brd_ver = brd_ver;
|
||||
),
|
||||
TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
|
||||
"blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
|
||||
"bcon_tm %010u gp 0x%08X 0x%08X 0x%08X major 0x%08X "
|
||||
"blink2 0x%05X ilink 0x%05X 0x%05X "
|
||||
"bcon_tm %010u gp 0x%08X 0x%08X rev_type 0x%08X major 0x%08X "
|
||||
"minor 0x%08X hw 0x%08X brd 0x%08X",
|
||||
__get_str(dev), __entry->desc, __entry->tsf_low,
|
||||
__entry->data1,
|
||||
__entry->data2, __entry->line, __entry->blink1,
|
||||
__entry->data1, __entry->data2, __entry->line,
|
||||
__entry->blink2, __entry->ilink1, __entry->ilink2,
|
||||
__entry->bcon_time, __entry->gp1, __entry->gp2,
|
||||
__entry->gp3, __entry->major, __entry->minor,
|
||||
__entry->rev_type, __entry->major, __entry->minor,
|
||||
__entry->hw_ver, __entry->brd_ver)
|
||||
);
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 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) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -374,15 +376,12 @@ static int iwl_store_cscheme(struct iwl_fw *fw, const u8 *data, const u32 len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_store_gscan_capa(struct iwl_fw *fw, const u8 *data,
|
||||
const u32 len)
|
||||
static void iwl_store_gscan_capa(struct iwl_fw *fw, const u8 *data,
|
||||
const u32 len)
|
||||
{
|
||||
struct iwl_fw_gscan_capabilities *fw_capa = (void *)data;
|
||||
struct iwl_gscan_capabilities *capa = &fw->gscan_capa;
|
||||
|
||||
if (len < sizeof(*fw_capa))
|
||||
return -EINVAL;
|
||||
|
||||
capa->max_scan_cache_size = le32_to_cpu(fw_capa->max_scan_cache_size);
|
||||
capa->max_scan_buckets = le32_to_cpu(fw_capa->max_scan_buckets);
|
||||
capa->max_ap_cache_per_scan =
|
||||
|
@ -395,7 +394,15 @@ static int iwl_store_gscan_capa(struct iwl_fw *fw, const u8 *data,
|
|||
le32_to_cpu(fw_capa->max_significant_change_aps);
|
||||
capa->max_bssid_history_entries =
|
||||
le32_to_cpu(fw_capa->max_bssid_history_entries);
|
||||
return 0;
|
||||
capa->max_hotlist_ssids = le32_to_cpu(fw_capa->max_hotlist_ssids);
|
||||
capa->max_number_epno_networks =
|
||||
le32_to_cpu(fw_capa->max_number_epno_networks);
|
||||
capa->max_number_epno_networks_by_ssid =
|
||||
le32_to_cpu(fw_capa->max_number_epno_networks_by_ssid);
|
||||
capa->max_number_of_white_listed_ssid =
|
||||
le32_to_cpu(fw_capa->max_number_of_white_listed_ssid);
|
||||
capa->max_number_of_black_listed_ssid =
|
||||
le32_to_cpu(fw_capa->max_number_of_black_listed_ssid);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1023,8 +1030,15 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_FW_GSCAN_CAPA:
|
||||
if (iwl_store_gscan_capa(&drv->fw, tlv_data, tlv_len))
|
||||
goto invalid_tlv_len;
|
||||
/*
|
||||
* Don't return an error in case of a shorter tlv_len
|
||||
* to enable loading of FW that has an old format
|
||||
* of GSCAN capabilities TLV.
|
||||
*/
|
||||
if (tlv_len < sizeof(struct iwl_fw_gscan_capabilities))
|
||||
break;
|
||||
|
||||
iwl_store_gscan_capa(&drv->fw, tlv_data, tlv_len);
|
||||
gscan_capa = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -1046,12 +1060,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If ucode advertises that it supports GSCAN but GSCAN
|
||||
* capabilities TLV is not present, warn and continue without GSCAN.
|
||||
*/
|
||||
if (fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) &&
|
||||
WARN(!gscan_capa,
|
||||
if (WARN(fw_has_capa(capa, IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT) &&
|
||||
!gscan_capa,
|
||||
"GSCAN is supported but capabilities TLV is unavailable\n"))
|
||||
__clear_bit((__force long)IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT,
|
||||
capa->_capa);
|
||||
|
|
|
@ -511,9 +511,12 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
|
|||
*/
|
||||
#define FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN (0x00000002)
|
||||
|
||||
#define MQ_RX_TABLE_SIZE 512
|
||||
#define MQ_RX_TABLE_MASK (MQ_RX_TABLE_SIZE - 1)
|
||||
#define MQ_RX_POOL_SIZE MQ_RX_TABLE_MASK
|
||||
#define MQ_RX_TABLE_SIZE 512
|
||||
#define MQ_RX_TABLE_MASK (MQ_RX_TABLE_SIZE - 1)
|
||||
#define MQ_RX_NUM_RBDS (MQ_RX_TABLE_SIZE - 1)
|
||||
#define RX_POOL_SIZE (MQ_RX_NUM_RBDS + \
|
||||
IWL_MAX_RX_HW_QUEUES * \
|
||||
(RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC))
|
||||
|
||||
#define RX_QUEUE_SIZE 256
|
||||
#define RX_QUEUE_MASK 255
|
||||
|
|
|
@ -809,6 +809,12 @@ struct iwl_fw_dbg_conf_tlv {
|
|||
* change APs.
|
||||
* @max_bssid_history_entries: number of BSSID/RSSI entries that the device can
|
||||
* hold.
|
||||
* @max_hotlist_ssids: maximum number of entries for hotlist SSIDs.
|
||||
* @max_number_epno_networks: max number of epno entries.
|
||||
* @max_number_epno_networks_by_ssid: max number of epno entries if ssid is
|
||||
* specified.
|
||||
* @max_number_of_white_listed_ssid: max number of white listed SSIDs.
|
||||
* @max_number_of_black_listed_ssid: max number of black listed SSIDs.
|
||||
*/
|
||||
struct iwl_fw_gscan_capabilities {
|
||||
__le32 max_scan_cache_size;
|
||||
|
@ -819,6 +825,11 @@ struct iwl_fw_gscan_capabilities {
|
|||
__le32 max_hotlist_aps;
|
||||
__le32 max_significant_change_aps;
|
||||
__le32 max_bssid_history_entries;
|
||||
__le32 max_hotlist_ssids;
|
||||
__le32 max_number_epno_networks;
|
||||
__le32 max_number_epno_networks_by_ssid;
|
||||
__le32 max_number_of_white_listed_ssid;
|
||||
__le32 max_number_of_black_listed_ssid;
|
||||
} __packed;
|
||||
|
||||
#endif /* __iwl_fw_file_h__ */
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 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) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -205,6 +207,12 @@ struct iwl_fw_cscheme_list {
|
|||
* change APs.
|
||||
* @max_bssid_history_entries: number of BSSID/RSSI entries that the device can
|
||||
* hold.
|
||||
* @max_hotlist_ssids: maximum number of entries for hotlist SSIDs.
|
||||
* @max_number_epno_networks: max number of epno entries.
|
||||
* @max_number_epno_networks_by_ssid: max number of epno entries if ssid is
|
||||
* specified.
|
||||
* @max_number_of_white_listed_ssid: max number of white listed SSIDs.
|
||||
* @max_number_of_black_listed_ssid: max number of black listed SSIDs.
|
||||
*/
|
||||
struct iwl_gscan_capabilities {
|
||||
u32 max_scan_cache_size;
|
||||
|
@ -215,6 +223,11 @@ struct iwl_gscan_capabilities {
|
|||
u32 max_hotlist_aps;
|
||||
u32 max_significant_change_aps;
|
||||
u32 max_bssid_history_entries;
|
||||
u32 max_hotlist_ssids;
|
||||
u32 max_number_epno_networks;
|
||||
u32 max_number_epno_networks_by_ssid;
|
||||
u32 max_number_of_white_listed_ssid;
|
||||
u32 max_number_of_black_listed_ssid;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 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
|
||||
|
@ -69,6 +70,9 @@
|
|||
#include "iwl-drv.h"
|
||||
#include "iwl-modparams.h"
|
||||
#include "iwl-nvm-parse.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-csr.h"
|
||||
|
||||
/* NVM offsets (in words) definitions */
|
||||
enum wkp_nvm_offsets {
|
||||
|
@ -522,27 +526,41 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
|
|||
data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(radio_cfg);
|
||||
}
|
||||
|
||||
static void iwl_set_hw_address(const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const __le16 *nvm_sec)
|
||||
static void iwl_flip_hw_address(__le32 mac_addr0, __le32 mac_addr1, u8 *dest)
|
||||
{
|
||||
const u8 *hw_addr = (const u8 *)(nvm_sec + HW_ADDR);
|
||||
const u8 *hw_addr;
|
||||
|
||||
/* The byte order is little endian 16 bit, meaning 214365 */
|
||||
data->hw_addr[0] = hw_addr[1];
|
||||
data->hw_addr[1] = hw_addr[0];
|
||||
data->hw_addr[2] = hw_addr[3];
|
||||
data->hw_addr[3] = hw_addr[2];
|
||||
data->hw_addr[4] = hw_addr[5];
|
||||
data->hw_addr[5] = hw_addr[4];
|
||||
hw_addr = (const u8 *)&mac_addr0;
|
||||
dest[0] = hw_addr[3];
|
||||
dest[1] = hw_addr[2];
|
||||
dest[2] = hw_addr[1];
|
||||
dest[3] = hw_addr[0];
|
||||
|
||||
hw_addr = (const u8 *)&mac_addr1;
|
||||
dest[4] = hw_addr[1];
|
||||
dest[5] = hw_addr[0];
|
||||
}
|
||||
|
||||
static void iwl_set_hw_address_family_8000(struct device *dev,
|
||||
static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
|
||||
struct iwl_nvm_data *data)
|
||||
{
|
||||
__le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP));
|
||||
__le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP));
|
||||
|
||||
/* If OEM did not fuse address - get it from OTP */
|
||||
if (!mac_addr0 && !mac_addr1) {
|
||||
mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
|
||||
mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
|
||||
}
|
||||
|
||||
iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
|
||||
}
|
||||
|
||||
static void iwl_set_hw_address_family_8000(struct iwl_trans *trans,
|
||||
const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
const __le16 *mac_override,
|
||||
const __le16 *nvm_hw,
|
||||
__le32 mac_addr0, __le32 mac_addr1)
|
||||
const __le16 *nvm_hw)
|
||||
{
|
||||
const u8 *hw_addr;
|
||||
|
||||
|
@ -568,45 +586,68 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
|
|||
memcmp(reserved_mac, hw_addr, ETH_ALEN) != 0)
|
||||
return;
|
||||
|
||||
IWL_ERR_DEV(dev,
|
||||
"mac address from nvm override section is not valid\n");
|
||||
IWL_ERR(trans,
|
||||
"mac address from nvm override section is not valid\n");
|
||||
}
|
||||
|
||||
if (nvm_hw) {
|
||||
/* read the MAC address from HW resisters */
|
||||
hw_addr = (const u8 *)&mac_addr0;
|
||||
data->hw_addr[0] = hw_addr[3];
|
||||
data->hw_addr[1] = hw_addr[2];
|
||||
data->hw_addr[2] = hw_addr[1];
|
||||
data->hw_addr[3] = hw_addr[0];
|
||||
/* read the mac address from WFMP registers */
|
||||
__le32 mac_addr0 = cpu_to_le32(iwl_trans_read_prph(trans,
|
||||
WFMP_MAC_ADDR_0));
|
||||
__le32 mac_addr1 = cpu_to_le32(iwl_trans_read_prph(trans,
|
||||
WFMP_MAC_ADDR_1));
|
||||
|
||||
hw_addr = (const u8 *)&mac_addr1;
|
||||
data->hw_addr[4] = hw_addr[1];
|
||||
data->hw_addr[5] = hw_addr[0];
|
||||
|
||||
if (!is_valid_ether_addr(data->hw_addr))
|
||||
IWL_ERR_DEV(dev,
|
||||
"mac address (%pM) from hw section is not valid\n",
|
||||
data->hw_addr);
|
||||
iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
IWL_ERR_DEV(dev, "mac address is not found\n");
|
||||
IWL_ERR(trans, "mac address is not found\n");
|
||||
}
|
||||
|
||||
static int iwl_set_hw_address(struct iwl_trans *trans,
|
||||
const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data, const __le16 *nvm_hw,
|
||||
const __le16 *mac_override)
|
||||
{
|
||||
if (cfg->mac_addr_from_csr) {
|
||||
iwl_set_hw_address_from_csr(trans, data);
|
||||
} else if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR);
|
||||
|
||||
/* The byte order is little endian 16 bit, meaning 214365 */
|
||||
data->hw_addr[0] = hw_addr[1];
|
||||
data->hw_addr[1] = hw_addr[0];
|
||||
data->hw_addr[2] = hw_addr[3];
|
||||
data->hw_addr[3] = hw_addr[2];
|
||||
data->hw_addr[4] = hw_addr[5];
|
||||
data->hw_addr[5] = hw_addr[4];
|
||||
} else {
|
||||
iwl_set_hw_address_family_8000(trans, cfg, data,
|
||||
mac_override, nvm_hw);
|
||||
}
|
||||
|
||||
if (!is_valid_ether_addr(data->hw_addr)) {
|
||||
IWL_ERR(trans, "no valid mac address was found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct iwl_nvm_data *
|
||||
iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
iwl_parse_nvm_data(struct iwl_trans *trans, 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,
|
||||
__le32 mac_addr0, __le32 mac_addr1)
|
||||
u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
|
||||
{
|
||||
struct device *dev = trans->dev;
|
||||
struct iwl_nvm_data *data;
|
||||
u32 sku;
|
||||
u32 radio_cfg;
|
||||
bool lar_enabled;
|
||||
u32 sku, radio_cfg;
|
||||
u16 lar_config;
|
||||
const __le16 *ch_section;
|
||||
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
|
||||
data = kzalloc(sizeof(*data) +
|
||||
|
@ -645,21 +686,16 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
|
|||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
/* Checking for required sections */
|
||||
if (!nvm_calib) {
|
||||
IWL_ERR_DEV(dev,
|
||||
"Can't parse empty Calib NVM sections\n");
|
||||
IWL_ERR(trans,
|
||||
"Can't parse empty Calib NVM sections\n");
|
||||
kfree(data);
|
||||
return NULL;
|
||||
}
|
||||
/* in family 8000 Xtal calibration values moved to OTP */
|
||||
data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
|
||||
data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
|
||||
}
|
||||
|
||||
if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
iwl_set_hw_address(cfg, data, nvm_hw);
|
||||
|
||||
iwl_init_sbands(dev, cfg, data, nvm_sw,
|
||||
tx_chains, rx_chains, lar_fw_supported);
|
||||
lar_enabled = true;
|
||||
ch_section = nvm_sw;
|
||||
} else {
|
||||
u16 lar_offset = data->nvm_version < 0xE39 ?
|
||||
NVM_LAR_OFFSET_FAMILY_8000_OLD :
|
||||
|
@ -668,16 +704,18 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
|
|||
lar_config = le16_to_cpup(regulatory + lar_offset);
|
||||
data->lar_enabled = !!(lar_config &
|
||||
NVM_LAR_ENABLED_FAMILY_8000);
|
||||
|
||||
/* MAC address in family 8000 */
|
||||
iwl_set_hw_address_family_8000(dev, cfg, data, mac_override,
|
||||
nvm_hw, mac_addr0, mac_addr1);
|
||||
|
||||
iwl_init_sbands(dev, cfg, data, regulatory,
|
||||
tx_chains, rx_chains,
|
||||
lar_fw_supported && data->lar_enabled);
|
||||
lar_enabled = data->lar_enabled;
|
||||
ch_section = regulatory;
|
||||
}
|
||||
|
||||
/* If no valid mac address was found - bail out */
|
||||
if (iwl_set_hw_address(trans, cfg, data, nvm_hw, mac_override)) {
|
||||
kfree(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
|
||||
lar_fw_supported && lar_enabled);
|
||||
data->calib_version = 255;
|
||||
|
||||
return data;
|
||||
|
|
|
@ -74,12 +74,11 @@
|
|||
* later with iwl_free_nvm_data().
|
||||
*/
|
||||
struct iwl_nvm_data *
|
||||
iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
|
||||
iwl_parse_nvm_data(struct iwl_trans *trans, 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,
|
||||
__le32 mac_addr0, __le32 mac_addr1);
|
||||
u8 tx_chains, u8 rx_chains, bool lar_fw_supported);
|
||||
|
||||
/**
|
||||
* iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
|
||||
|
|
|
@ -73,6 +73,44 @@
|
|||
#include "debugfs.h"
|
||||
#include "iwl-fw-error-dump.h"
|
||||
|
||||
static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
char buf[16];
|
||||
int pos, budget;
|
||||
|
||||
if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
|
||||
return -EIO;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
budget = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_REPORT, 0);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
if (budget < 0)
|
||||
return budget;
|
||||
|
||||
pos = scnprintf(buf, sizeof(buf), "%d\n", budget);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!mvm->ucode_loaded || mvm->cur_ucode != IWL_UCODE_REGULAR)
|
||||
return -EIO;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_STOP, 0);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return ret ?: count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
@ -1493,6 +1531,8 @@ iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf,
|
|||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
|
||||
|
||||
/* Device wide debugfs entries */
|
||||
MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8);
|
||||
|
@ -1542,6 +1582,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
|||
MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir,
|
||||
S_IWUSR | S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
|
||||
|
|
|
@ -264,9 +264,8 @@ enum iwl_rx_mpdu_mac_flags2 {
|
|||
};
|
||||
|
||||
enum iwl_rx_mpdu_amsdu_info {
|
||||
IWL_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK = 0x3f,
|
||||
IWL_RX_MPDU_AMSDU_LAST_SUBFRAME = 0x40,
|
||||
/* 0x80 bit reserved for now */
|
||||
IWL_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK = 0x7f,
|
||||
IWL_RX_MPDU_AMSDU_LAST_SUBFRAME = 0x80,
|
||||
};
|
||||
|
||||
enum iwl_rx_l3l4_flags {
|
||||
|
|
|
@ -610,8 +610,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||
IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT))
|
||||
hw->wiphy->features |= NL80211_FEATURE_WFA_TPC_IE_IN_PROBES;
|
||||
|
||||
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_RRM);
|
||||
|
||||
mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
@ -2556,10 +2554,8 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
|
|||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
u32 duration = min(IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
|
||||
200 + vif->bss_conf.beacon_int);
|
||||
u32 min_duration = min(IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
|
||||
100 + vif->bss_conf.beacon_int);
|
||||
u32 duration = IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
|
||||
u32 min_duration = IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS;
|
||||
|
||||
if (WARN_ON_ONCE(vif->bss_conf.assoc))
|
||||
return;
|
||||
|
@ -2690,8 +2686,12 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
|
|||
* GTK on AP interface is a TX-only key, return 0;
|
||||
* on IBSS they're per-station and because we're lazy
|
||||
* we don't support them for RX, so do the same.
|
||||
* CMAC in AP/IBSS modes must be done in software.
|
||||
*/
|
||||
ret = 0;
|
||||
if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC)
|
||||
ret = -EOPNOTSUPP;
|
||||
else
|
||||
ret = 0;
|
||||
key->hw_key_idx = STA_KEY_IDX_INVALID;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -543,8 +543,8 @@ struct iwl_mvm_thermal_device {
|
|||
};
|
||||
|
||||
/*
|
||||
* iwl_mvm_cooling_device
|
||||
* @cur_state: current state in milliwatts
|
||||
* struct iwl_mvm_cooling_device
|
||||
* @cur_state: current state
|
||||
* @cdev: struct thermal cooling device
|
||||
*/
|
||||
struct iwl_mvm_cooling_device {
|
||||
|
@ -1575,7 +1575,6 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
|
|||
int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp);
|
||||
void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
|
||||
int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_cooling_device_register(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 budget);
|
||||
|
||||
/* Location Aware Regulatory */
|
||||
|
|
|
@ -300,7 +300,6 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
|||
struct iwl_nvm_section *sections = mvm->nvm_sections;
|
||||
const __le16 *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku;
|
||||
bool lar_enabled;
|
||||
__le32 mac_addr0, mac_addr1;
|
||||
|
||||
/* Checking for required sections */
|
||||
if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
|
||||
|
@ -336,12 +335,6 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
|||
if (WARN_ON(!mvm->cfg))
|
||||
return NULL;
|
||||
|
||||
/* read the mac address from WFMP registers */
|
||||
mac_addr0 = cpu_to_le32(iwl_trans_read_prph(mvm->trans,
|
||||
WFMP_MAC_ADDR_0));
|
||||
mac_addr1 = cpu_to_le32(iwl_trans_read_prph(mvm->trans,
|
||||
WFMP_MAC_ADDR_1));
|
||||
|
||||
hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
|
||||
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
|
||||
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
|
||||
|
@ -354,10 +347,10 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
|||
fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
|
||||
|
||||
return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
|
||||
return iwl_parse_nvm_data(mvm->trans, mvm->cfg, hw, sw, calib,
|
||||
regulatory, mac_override, phy_sku,
|
||||
mvm->fw->valid_tx_ant, mvm->fw->valid_rx_ant,
|
||||
lar_enabled, mac_addr0, mac_addr1);
|
||||
lar_enabled);
|
||||
}
|
||||
|
||||
#define MAX_NVM_FILE_LEN 16384
|
||||
|
|
|
@ -205,79 +205,107 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
|
|||
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
|
||||
}
|
||||
|
||||
/**
|
||||
* enum iwl_rx_handler_context context for Rx handler
|
||||
* @RX_HANDLER_SYNC : this means that it will be called in the Rx path
|
||||
* which can't acquire mvm->mutex.
|
||||
* @RX_HANDLER_ASYNC_LOCKED : If the handler needs to hold mvm->mutex
|
||||
* (and only in this case!), it should be set as ASYNC. In that case,
|
||||
* it will be called from a worker with mvm->mutex held.
|
||||
* @RX_HANDLER_ASYNC_UNLOCKED : in case the handler needs to lock the
|
||||
* mutex itself, it will be called from a worker without mvm->mutex held.
|
||||
*/
|
||||
enum iwl_rx_handler_context {
|
||||
RX_HANDLER_SYNC,
|
||||
RX_HANDLER_ASYNC_LOCKED,
|
||||
RX_HANDLER_ASYNC_UNLOCKED,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_rx_handlers handler for FW notification
|
||||
* @cmd_id: command id
|
||||
* @context: see &iwl_rx_handler_context
|
||||
* @fn: the function is called when notification is received
|
||||
*/
|
||||
struct iwl_rx_handlers {
|
||||
u16 cmd_id;
|
||||
bool async;
|
||||
enum iwl_rx_handler_context context;
|
||||
void (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
|
||||
};
|
||||
|
||||
#define RX_HANDLER(_cmd_id, _fn, _async) \
|
||||
{ .cmd_id = _cmd_id , .fn = _fn , .async = _async }
|
||||
#define RX_HANDLER_GRP(_grp, _cmd, _fn, _async) \
|
||||
{ .cmd_id = WIDE_ID(_grp, _cmd), .fn = _fn, .async = _async }
|
||||
#define RX_HANDLER(_cmd_id, _fn, _context) \
|
||||
{ .cmd_id = _cmd_id, .fn = _fn, .context = _context }
|
||||
#define RX_HANDLER_GRP(_grp, _cmd, _fn, _context) \
|
||||
{ .cmd_id = WIDE_ID(_grp, _cmd), .fn = _fn, .context = _context }
|
||||
|
||||
/*
|
||||
* Handlers for fw notifications
|
||||
* Convention: RX_HANDLER(CMD_NAME, iwl_mvm_rx_CMD_NAME
|
||||
* This list should be in order of frequency for performance purposes.
|
||||
*
|
||||
* The handler can be SYNC - this means that it will be called in the Rx path
|
||||
* which can't acquire mvm->mutex. If the handler needs to hold mvm->mutex (and
|
||||
* only in this case!), it should be set as ASYNC. In that case, it will be
|
||||
* called from a worker with mvm->mutex held.
|
||||
* The handler can be one from three contexts, see &iwl_rx_handler_context
|
||||
*/
|
||||
static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
|
||||
RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, false),
|
||||
RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false),
|
||||
RX_HANDLER(TX_CMD, iwl_mvm_rx_tx_cmd, RX_HANDLER_SYNC),
|
||||
RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, RX_HANDLER_SYNC),
|
||||
|
||||
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
|
||||
RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, true),
|
||||
RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true),
|
||||
RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics,
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION,
|
||||
iwl_mvm_rx_ant_coupling_notif, true),
|
||||
iwl_mvm_rx_ant_coupling_notif, RX_HANDLER_ASYNC_LOCKED),
|
||||
|
||||
RX_HANDLER(BA_WINDOW_STATUS_NOTIFICATION_ID,
|
||||
iwl_mvm_window_status_notif, false),
|
||||
iwl_mvm_window_status_notif, RX_HANDLER_SYNC),
|
||||
|
||||
RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
|
||||
RX_HANDLER(MCC_CHUB_UPDATE_CMD, iwl_mvm_rx_chub_update_mcc, true),
|
||||
RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif,
|
||||
RX_HANDLER_SYNC),
|
||||
RX_HANDLER(MCC_CHUB_UPDATE_CMD, iwl_mvm_rx_chub_update_mcc,
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
|
||||
RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false),
|
||||
RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, RX_HANDLER_SYNC),
|
||||
|
||||
RX_HANDLER(SCAN_ITERATION_COMPLETE,
|
||||
iwl_mvm_rx_lmac_scan_iter_complete_notif, false),
|
||||
iwl_mvm_rx_lmac_scan_iter_complete_notif, RX_HANDLER_SYNC),
|
||||
RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
|
||||
iwl_mvm_rx_lmac_scan_complete_notif, true),
|
||||
iwl_mvm_rx_lmac_scan_complete_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_match_found,
|
||||
false),
|
||||
RX_HANDLER_SYNC),
|
||||
RX_HANDLER(SCAN_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_complete_notif,
|
||||
true),
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER(SCAN_ITERATION_COMPLETE_UMAC,
|
||||
iwl_mvm_rx_umac_scan_iter_complete_notif, false),
|
||||
iwl_mvm_rx_umac_scan_iter_complete_notif, RX_HANDLER_SYNC),
|
||||
|
||||
RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
|
||||
RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif,
|
||||
RX_HANDLER_SYNC),
|
||||
|
||||
RX_HANDLER(MISSED_BEACONS_NOTIFICATION, iwl_mvm_rx_missed_beacons_notif,
|
||||
false),
|
||||
RX_HANDLER_SYNC),
|
||||
|
||||
RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, false),
|
||||
RX_HANDLER(REPLY_ERROR, iwl_mvm_rx_fw_error, RX_HANDLER_SYNC),
|
||||
RX_HANDLER(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION,
|
||||
iwl_mvm_power_uapsd_misbehaving_ap_notif, false),
|
||||
RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true),
|
||||
iwl_mvm_power_uapsd_misbehaving_ap_notif, RX_HANDLER_SYNC),
|
||||
RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif,
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER_GRP(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE,
|
||||
iwl_mvm_temp_notif, true),
|
||||
iwl_mvm_temp_notif, RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER_GRP(PHY_OPS_GROUP, CT_KILL_NOTIFICATION,
|
||||
iwl_mvm_ct_kill_notif, false),
|
||||
iwl_mvm_ct_kill_notif, RX_HANDLER_SYNC),
|
||||
|
||||
RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif,
|
||||
true),
|
||||
RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif, false),
|
||||
RX_HANDLER(TOF_NOTIFICATION, iwl_mvm_tof_resp_handler, true),
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif,
|
||||
RX_HANDLER_SYNC),
|
||||
RX_HANDLER(TOF_NOTIFICATION, iwl_mvm_tof_resp_handler,
|
||||
RX_HANDLER_ASYNC_LOCKED),
|
||||
RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF,
|
||||
iwl_mvm_rx_stored_beacon_notif, false),
|
||||
iwl_mvm_rx_stored_beacon_notif, RX_HANDLER_SYNC),
|
||||
RX_HANDLER_GRP(DATA_PATH_GROUP, MU_GROUP_MGMT_NOTIF,
|
||||
iwl_mvm_mu_mimo_grp_notif, false),
|
||||
|
||||
iwl_mvm_mu_mimo_grp_notif, RX_HANDLER_SYNC),
|
||||
};
|
||||
#undef RX_HANDLER
|
||||
#undef RX_HANDLER_GRP
|
||||
|
@ -611,9 +639,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||
IWL_INFO(mvm, "Detected %s, REV=0x%X\n",
|
||||
mvm->cfg->name, mvm->trans->hw_rev);
|
||||
|
||||
min_backoff = calc_min_backoff(trans, cfg);
|
||||
iwl_mvm_thermal_initialize(mvm, min_backoff);
|
||||
|
||||
if (iwlwifi_mod_params.nvm_file)
|
||||
mvm->nvm_file_name = iwlwifi_mod_params.nvm_file;
|
||||
else
|
||||
|
@ -666,6 +691,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||
if (err)
|
||||
goto out_free;
|
||||
|
||||
min_backoff = calc_min_backoff(trans, cfg);
|
||||
iwl_mvm_thermal_initialize(mvm, min_backoff);
|
||||
|
||||
err = iwl_mvm_dbgfs_register(mvm, dbgfs_dir);
|
||||
if (err)
|
||||
goto out_unregister;
|
||||
|
@ -743,6 +771,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
|
|||
struct iwl_async_handler_entry {
|
||||
struct list_head list;
|
||||
struct iwl_rx_cmd_buffer rxb;
|
||||
enum iwl_rx_handler_context context;
|
||||
void (*fn)(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
|
||||
};
|
||||
|
||||
|
@ -769,7 +798,6 @@ static void iwl_mvm_async_handlers_wk(struct work_struct *wk)
|
|||
INIT_LIST_HEAD(&local_list);
|
||||
|
||||
/* Ensure that we are not in stop flow (check iwl_mvm_mac_stop) */
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
/*
|
||||
* Sync with Rx path with a lock. Remove all the entries from this list,
|
||||
|
@ -780,12 +808,15 @@ static void iwl_mvm_async_handlers_wk(struct work_struct *wk)
|
|||
spin_unlock_bh(&mvm->async_handlers_lock);
|
||||
|
||||
list_for_each_entry_safe(entry, tmp, &local_list, list) {
|
||||
if (entry->context == RX_HANDLER_ASYNC_LOCKED)
|
||||
mutex_lock(&mvm->mutex);
|
||||
entry->fn(mvm, &entry->rxb);
|
||||
iwl_free_rxb(&entry->rxb);
|
||||
list_del(&entry->list);
|
||||
if (entry->context == RX_HANDLER_ASYNC_LOCKED)
|
||||
mutex_unlock(&mvm->mutex);
|
||||
kfree(entry);
|
||||
}
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm,
|
||||
|
@ -842,7 +873,7 @@ static void iwl_mvm_rx_common(struct iwl_mvm *mvm,
|
|||
if (rx_h->cmd_id != WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd))
|
||||
continue;
|
||||
|
||||
if (!rx_h->async) {
|
||||
if (rx_h->context == RX_HANDLER_SYNC) {
|
||||
rx_h->fn(mvm, rxb);
|
||||
return;
|
||||
}
|
||||
|
@ -856,6 +887,7 @@ static void iwl_mvm_rx_common(struct iwl_mvm *mvm,
|
|||
entry->rxb._offset = rxb->_offset;
|
||||
entry->rxb._rx_page_order = rxb->_rx_page_order;
|
||||
entry->fn = rx_h->fn;
|
||||
entry->context = rx_h->context;
|
||||
spin_lock(&mvm->async_handlers_lock);
|
||||
list_add_tail(&entry->list, &mvm->async_handlers_list);
|
||||
spin_unlock(&mvm->async_handlers_lock);
|
||||
|
|
|
@ -519,6 +519,18 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
|||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Our hardware de-aggregates AMSDUs but copies the mac header
|
||||
* as it to the de-aggregated MPDUs. We need to turn off the
|
||||
* AMSDU bit in the QoS control ourselves.
|
||||
*/
|
||||
if ((desc->mac_flags2 & IWL_RX_MPDU_MFLG2_AMSDU) &&
|
||||
!WARN_ON(!ieee80211_is_data_qos(hdr->frame_control))) {
|
||||
u8 *qc = ieee80211_get_qos_ctl(hdr);
|
||||
|
||||
*qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -371,20 +371,13 @@ static int iwl_mvm_aux_roc_te_handle_notif(struct iwl_mvm *mvm,
|
|||
|
||||
iwl_mvm_te_check_trigger(mvm, notif, te_data);
|
||||
|
||||
if (!le32_to_cpu(notif->status)) {
|
||||
IWL_DEBUG_TE(mvm,
|
||||
"ERROR: Aux ROC Time Event %s notification failure\n",
|
||||
(le32_to_cpu(notif->action) &
|
||||
TE_V2_NOTIF_HOST_EVENT_START) ? "start" : "end");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
IWL_DEBUG_TE(mvm,
|
||||
"Aux ROC time event notification - UID = 0x%x action %d\n",
|
||||
"Aux ROC time event notification - UID = 0x%x action %d (error = %d)\n",
|
||||
le32_to_cpu(notif->unique_id),
|
||||
le32_to_cpu(notif->action));
|
||||
le32_to_cpu(notif->action), le32_to_cpu(notif->status));
|
||||
|
||||
if (le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_END) {
|
||||
if (!le32_to_cpu(notif->status) ||
|
||||
le32_to_cpu(notif->action) == TE_V2_NOTIF_HOST_EVENT_END) {
|
||||
/* End TE, notify mac80211 */
|
||||
ieee80211_remain_on_channel_expired(mvm->hw);
|
||||
iwl_mvm_roc_finished(mvm); /* flush aux queue */
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
* needed by the driver.
|
||||
*/
|
||||
|
||||
#define IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 500
|
||||
#define IWL_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS 600
|
||||
#define IWL_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
|
||||
|
||||
/**
|
||||
|
|
|
@ -211,10 +211,14 @@ void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
|
|||
* the firmware and hence to take the mutex.
|
||||
* Avoid the deadlock by unlocking the mutex here.
|
||||
*/
|
||||
mutex_unlock(&mvm->mutex);
|
||||
thermal_notify_framework(mvm->tz_device.tzone,
|
||||
mvm->tz_device.fw_trips_index[ths_crossed]);
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (mvm->tz_device.tzone) {
|
||||
struct iwl_mvm_thermal_device *tz_dev = &mvm->tz_device;
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
thermal_notify_framework(tz_dev->tzone,
|
||||
tz_dev->fw_trips_index[ths_crossed]);
|
||||
mutex_lock(&mvm->mutex);
|
||||
}
|
||||
#endif /* CONFIG_THERMAL */
|
||||
}
|
||||
|
||||
|
@ -506,6 +510,74 @@ static const struct iwl_tt_params iwl_mvm_default_tt_params = {
|
|||
.support_tx_backoff = true,
|
||||
};
|
||||
|
||||
/* budget in mWatt */
|
||||
static const u32 iwl_mvm_cdev_budgets[] = {
|
||||
2000, /* cooling state 0 */
|
||||
1800, /* cooling state 1 */
|
||||
1600, /* cooling state 2 */
|
||||
1400, /* cooling state 3 */
|
||||
1200, /* cooling state 4 */
|
||||
1000, /* cooling state 5 */
|
||||
900, /* cooling state 6 */
|
||||
800, /* cooling state 7 */
|
||||
700, /* cooling state 8 */
|
||||
650, /* cooling state 9 */
|
||||
600, /* cooling state 10 */
|
||||
550, /* cooling state 11 */
|
||||
500, /* cooling state 12 */
|
||||
450, /* cooling state 13 */
|
||||
400, /* cooling state 14 */
|
||||
350, /* cooling state 15 */
|
||||
300, /* cooling state 16 */
|
||||
250, /* cooling state 17 */
|
||||
200, /* cooling state 18 */
|
||||
150, /* cooling state 19 */
|
||||
};
|
||||
|
||||
int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state)
|
||||
{
|
||||
struct iwl_mvm_ctdp_cmd cmd = {
|
||||
.operation = cpu_to_le32(op),
|
||||
.budget = cpu_to_le32(iwl_mvm_cdev_budgets[state]),
|
||||
.window_size = 0,
|
||||
};
|
||||
int ret;
|
||||
u32 status;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP,
|
||||
CTDP_CONFIG_CMD),
|
||||
sizeof(cmd), &cmd, &status);
|
||||
|
||||
if (ret) {
|
||||
IWL_ERR(mvm, "cTDP command failed (err=%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case CTDP_CMD_OPERATION_START:
|
||||
#ifdef CONFIG_THERMAL
|
||||
mvm->cooling_dev.cur_state = state;
|
||||
#endif /* CONFIG_THERMAL */
|
||||
break;
|
||||
case CTDP_CMD_OPERATION_REPORT:
|
||||
IWL_DEBUG_TEMP(mvm, "cTDP avg energy in mWatt = %d\n", status);
|
||||
/* when the function is called with CTDP_CMD_OPERATION_REPORT
|
||||
* option the function should return the average budget value
|
||||
* that is received from the FW.
|
||||
* The budget can't be less or equal to 0, so it's possible
|
||||
* to distinguish between error values and budgets.
|
||||
*/
|
||||
return status;
|
||||
case CTDP_CMD_OPERATION_STOP:
|
||||
IWL_DEBUG_TEMP(mvm, "cTDP stopped successfully\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_THERMAL
|
||||
static int compare_temps(const void *a, const void *b)
|
||||
{
|
||||
|
@ -520,16 +592,20 @@ int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (!mvm->tz_device.tzone)
|
||||
return -EINVAL;
|
||||
|
||||
/* The driver holds array of temperature trips that are unsorted
|
||||
* and uncompressed, the FW should get it compressed and sorted
|
||||
*/
|
||||
|
||||
/* compress temp_trips to cmd array, remove uninitialized values*/
|
||||
for (i = 0; i < IWL_MAX_DTS_TRIPS; i++)
|
||||
for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
|
||||
if (mvm->tz_device.temp_trips[i] != S16_MIN) {
|
||||
cmd.thresholds[idx++] =
|
||||
cpu_to_le16(mvm->tz_device.temp_trips[i]);
|
||||
}
|
||||
}
|
||||
cmd.num_temps = cpu_to_le32(idx);
|
||||
|
||||
if (!idx)
|
||||
|
@ -696,6 +772,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
|
|||
IWL_DEBUG_TEMP(mvm,
|
||||
"Failed to register to thermal zone (err = %ld)\n",
|
||||
PTR_ERR(mvm->tz_device.tzone));
|
||||
mvm->tz_device.tzone = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -706,59 +783,6 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
|
|||
mvm->tz_device.temp_trips[i] = S16_MIN;
|
||||
}
|
||||
|
||||
static const u32 iwl_mvm_cdev_budgets[] = {
|
||||
2000, /* cooling state 0 */
|
||||
1800, /* cooling state 1 */
|
||||
1600, /* cooling state 2 */
|
||||
1400, /* cooling state 3 */
|
||||
1200, /* cooling state 4 */
|
||||
1000, /* cooling state 5 */
|
||||
900, /* cooling state 6 */
|
||||
800, /* cooling state 7 */
|
||||
700, /* cooling state 8 */
|
||||
650, /* cooling state 9 */
|
||||
600, /* cooling state 10 */
|
||||
550, /* cooling state 11 */
|
||||
500, /* cooling state 12 */
|
||||
450, /* cooling state 13 */
|
||||
400, /* cooling state 14 */
|
||||
350, /* cooling state 15 */
|
||||
300, /* cooling state 16 */
|
||||
250, /* cooling state 17 */
|
||||
200, /* cooling state 18 */
|
||||
150, /* cooling state 19 */
|
||||
};
|
||||
|
||||
int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 budget)
|
||||
{
|
||||
struct iwl_mvm_ctdp_cmd cmd = {
|
||||
.operation = cpu_to_le32(op),
|
||||
.budget = cpu_to_le32(budget),
|
||||
.window_size = 0,
|
||||
};
|
||||
int ret;
|
||||
u32 status;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP,
|
||||
CTDP_CONFIG_CMD),
|
||||
sizeof(cmd), &cmd, &status);
|
||||
|
||||
if (ret) {
|
||||
IWL_ERR(mvm, "cTDP command failed (err=%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (op == CTDP_CMD_OPERATION_START)
|
||||
mvm->cooling_dev.cur_state = budget;
|
||||
|
||||
else if (op == CTDP_CMD_OPERATION_REPORT)
|
||||
IWL_DEBUG_TEMP(mvm, "cTDP avg energy in mWatt = %d\n", status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
|
@ -776,6 +800,7 @@ static int iwl_mvm_tcool_get_cur_state(struct thermal_cooling_device *cdev,
|
|||
return -EBUSY;
|
||||
|
||||
*state = mvm->cooling_dev.cur_state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -799,7 +824,7 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev,
|
|||
}
|
||||
|
||||
ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START,
|
||||
iwl_mvm_cdev_budgets[new_state]);
|
||||
new_state);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
@ -812,15 +837,12 @@ static struct thermal_cooling_device_ops tcooling_ops = {
|
|||
.set_cur_state = iwl_mvm_tcool_set_cur_state,
|
||||
};
|
||||
|
||||
int iwl_mvm_cooling_device_register(struct iwl_mvm *mvm)
|
||||
static void iwl_mvm_cooling_device_register(struct iwl_mvm *mvm)
|
||||
{
|
||||
char name[] = "iwlwifi";
|
||||
|
||||
if (!iwl_mvm_is_ctdp_supported(mvm)) {
|
||||
mvm->cooling_dev.cdev = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (!iwl_mvm_is_ctdp_supported(mvm))
|
||||
return;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
|
||||
|
||||
|
@ -833,34 +855,29 @@ int iwl_mvm_cooling_device_register(struct iwl_mvm *mvm)
|
|||
IWL_DEBUG_TEMP(mvm,
|
||||
"Failed to register to cooling device (err = %ld)\n",
|
||||
PTR_ERR(mvm->cooling_dev.cdev));
|
||||
return PTR_ERR(mvm->cooling_dev.cdev);
|
||||
mvm->cooling_dev.cdev = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_mvm_thermal_zone_unregister(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (!iwl_mvm_is_tt_in_fw(mvm))
|
||||
if (!iwl_mvm_is_tt_in_fw(mvm) || !mvm->tz_device.tzone)
|
||||
return;
|
||||
|
||||
if (mvm->tz_device.tzone) {
|
||||
IWL_DEBUG_TEMP(mvm, "Thermal zone device unregister\n");
|
||||
thermal_zone_device_unregister(mvm->tz_device.tzone);
|
||||
mvm->tz_device.tzone = NULL;
|
||||
}
|
||||
IWL_DEBUG_TEMP(mvm, "Thermal zone device unregister\n");
|
||||
thermal_zone_device_unregister(mvm->tz_device.tzone);
|
||||
mvm->tz_device.tzone = NULL;
|
||||
}
|
||||
|
||||
static void iwl_mvm_cooling_device_unregister(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (!iwl_mvm_is_ctdp_supported(mvm))
|
||||
if (!iwl_mvm_is_ctdp_supported(mvm) || !mvm->cooling_dev.cdev)
|
||||
return;
|
||||
|
||||
if (mvm->cooling_dev.cdev) {
|
||||
IWL_DEBUG_TEMP(mvm, "Cooling device unregister\n");
|
||||
thermal_cooling_device_unregister(mvm->cooling_dev.cdev);
|
||||
mvm->cooling_dev.cdev = NULL;
|
||||
}
|
||||
IWL_DEBUG_TEMP(mvm, "Cooling device unregister\n");
|
||||
thermal_cooling_device_unregister(mvm->cooling_dev.cdev);
|
||||
mvm->cooling_dev.cdev = NULL;
|
||||
}
|
||||
#endif /* CONFIG_THERMAL */
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 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
|
||||
|
@ -963,6 +964,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||
struct sk_buff_head skbs;
|
||||
u8 skb_freed = 0;
|
||||
u16 next_reclaimed, seq_ctl;
|
||||
bool is_ndp = false;
|
||||
|
||||
__skb_queue_head_init(&skbs);
|
||||
|
||||
|
@ -1016,6 +1018,20 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||
seq_ctl = le16_to_cpu(hdr->seq_ctrl);
|
||||
}
|
||||
|
||||
if (unlikely(!seq_ctl)) {
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
|
||||
/*
|
||||
* If it is an NDP, we can't update next_reclaim since
|
||||
* its sequence control is 0. Note that for that same
|
||||
* reason, NDPs are never sent to A-MPDU'able queues
|
||||
* so that we can never have more than one freed frame
|
||||
* for a single Tx resonse (see WARN_ON below).
|
||||
*/
|
||||
if (ieee80211_is_qos_nullfunc(hdr->frame_control))
|
||||
is_ndp = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: this is not accurate if we are freeing more than one
|
||||
* packet.
|
||||
|
@ -1079,9 +1095,16 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||
bool send_eosp_ndp = false;
|
||||
|
||||
spin_lock_bh(&mvmsta->lock);
|
||||
tid_data->next_reclaimed = next_reclaimed;
|
||||
IWL_DEBUG_TX_REPLY(mvm, "Next reclaimed packet:%d\n",
|
||||
next_reclaimed);
|
||||
if (!is_ndp) {
|
||||
tid_data->next_reclaimed = next_reclaimed;
|
||||
IWL_DEBUG_TX_REPLY(mvm,
|
||||
"Next reclaimed packet:%d\n",
|
||||
next_reclaimed);
|
||||
} else {
|
||||
IWL_DEBUG_TX_REPLY(mvm,
|
||||
"NDP - don't update next_reclaimed\n");
|
||||
}
|
||||
|
||||
iwl_mvm_check_ratid_empty(mvm, sta, tid);
|
||||
|
||||
if (mvmsta->sleep_tx_count) {
|
||||
|
|
|
@ -376,8 +376,8 @@ struct iwl_error_event_table_v1 {
|
|||
struct iwl_error_event_table {
|
||||
u32 valid; /* (nonzero) valid, (0) log is empty */
|
||||
u32 error_id; /* type of error */
|
||||
u32 pc; /* program counter */
|
||||
u32 blink1; /* branch link */
|
||||
u32 trm_hw_status0; /* TRM HW status */
|
||||
u32 trm_hw_status1; /* TRM HW status */
|
||||
u32 blink2; /* branch link */
|
||||
u32 ilink1; /* interrupt link */
|
||||
u32 ilink2; /* interrupt link */
|
||||
|
@ -389,7 +389,7 @@ struct iwl_error_event_table {
|
|||
u32 tsf_hi; /* network timestamp function timer */
|
||||
u32 gp1; /* GP1 timer register */
|
||||
u32 gp2; /* GP2 timer register */
|
||||
u32 gp3; /* GP3 timer register */
|
||||
u32 fw_rev_type; /* firmware revision type */
|
||||
u32 major; /* uCode version major */
|
||||
u32 minor; /* uCode version minor */
|
||||
u32 hw_ver; /* HW Silicon version */
|
||||
|
@ -408,7 +408,7 @@ struct iwl_error_event_table {
|
|||
* time_flag */
|
||||
u32 isr4; /* isr status register LMPM_NIC_ISR4:
|
||||
* wico interrupt */
|
||||
u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
|
||||
u32 last_cmd_id; /* last HCMD id handled by the firmware */
|
||||
u32 wait_event; /* wait event() caller address */
|
||||
u32 l2p_control; /* L2pControlField */
|
||||
u32 l2p_duration; /* L2pDurationField */
|
||||
|
@ -419,7 +419,7 @@ struct iwl_error_event_table {
|
|||
u32 u_timestamp; /* indicate when the date and time of the
|
||||
* compilation */
|
||||
u32 flow_handler; /* FH read/write pointers, RX credit */
|
||||
} __packed /* LOG_ERROR_TABLE_API_S_VER_2 */;
|
||||
} __packed /* LOG_ERROR_TABLE_API_S_VER_3 */;
|
||||
|
||||
/*
|
||||
* UMAC error struct - relevant starting from family 8000 chip.
|
||||
|
@ -529,9 +529,9 @@ static void iwl_mvm_dump_nic_error_log_old(struct iwl_mvm *mvm)
|
|||
|
||||
trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
|
||||
table.data1, table.data2, table.data3,
|
||||
table.blink1, table.blink2, table.ilink1,
|
||||
table.ilink2, table.bcon_time, table.gp1,
|
||||
table.gp2, table.gp3, table.ucode_ver, 0,
|
||||
table.blink2, table.ilink1, table.ilink2,
|
||||
table.bcon_time, table.gp1, table.gp2,
|
||||
table.gp3, table.ucode_ver, 0,
|
||||
table.hw_ver, table.brd_ver);
|
||||
IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
|
||||
desc_lookup(table.error_id));
|
||||
|
@ -615,14 +615,14 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
|
|||
|
||||
trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
|
||||
table.data1, table.data2, table.data3,
|
||||
table.blink1, table.blink2, table.ilink1,
|
||||
table.blink2, table.ilink1,
|
||||
table.ilink2, table.bcon_time, table.gp1,
|
||||
table.gp2, table.gp3, table.major,
|
||||
table.gp2, table.fw_rev_type, table.major,
|
||||
table.minor, table.hw_ver, table.brd_ver);
|
||||
IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
|
||||
desc_lookup(table.error_id));
|
||||
IWL_ERR(mvm, "0x%08X | uPc\n", table.pc);
|
||||
IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1);
|
||||
IWL_ERR(mvm, "0x%08X | trm_hw_status0\n", table.trm_hw_status0);
|
||||
IWL_ERR(mvm, "0x%08X | trm_hw_status1\n", table.trm_hw_status1);
|
||||
IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2);
|
||||
IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1);
|
||||
IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2);
|
||||
|
@ -634,7 +634,7 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
|
|||
IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi);
|
||||
IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1);
|
||||
IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2);
|
||||
IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3);
|
||||
IWL_ERR(mvm, "0x%08X | uCode revision type\n", table.fw_rev_type);
|
||||
IWL_ERR(mvm, "0x%08X | uCode version major\n", table.major);
|
||||
IWL_ERR(mvm, "0x%08X | uCode version minor\n", table.minor);
|
||||
IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver);
|
||||
|
@ -645,7 +645,7 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
|
|||
IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2);
|
||||
IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3);
|
||||
IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4);
|
||||
IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref);
|
||||
IWL_ERR(mvm, "0x%08X | last cmd Id\n", table.last_cmd_id);
|
||||
IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event);
|
||||
IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control);
|
||||
IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration);
|
||||
|
|
|
@ -631,13 +631,31 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
/* if RTPM is in use, enable it in our device */
|
||||
if (iwl_trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
|
||||
/* We explicitly set the device to active here to
|
||||
* clear contingent errors.
|
||||
*/
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev,
|
||||
iwlwifi_mod_params.d0i3_entry_delay);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
|
||||
/* We are not supposed to call pm_runtime_allow() by
|
||||
* ourselves, but let userspace enable runtime PM via
|
||||
* sysfs. However, since we don't enable this from
|
||||
* userspace yet, we need to allow/forbid() ourselves.
|
||||
*/
|
||||
pm_runtime_allow(&pdev->dev);
|
||||
}
|
||||
|
||||
/* The PCI device starts with a reference taken and we are
|
||||
* supposed to release it here. But to simplify the
|
||||
* interaction with the opmode, we don't do it now, but let
|
||||
* the opmode release it when it's ready. To account for this
|
||||
* reference, we start with ref_count set to 1.
|
||||
*/
|
||||
trans_pcie->ref_count = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_drv:
|
||||
|
@ -652,7 +670,17 @@ static void iwl_pci_remove(struct pci_dev *pdev)
|
|||
struct iwl_trans *trans = pci_get_drvdata(pdev);
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
/* if RTPM was in use, restore it to the state before probe */
|
||||
if (trans->runtime_pm_mode != IWL_PLAT_PM_MODE_DISABLED) {
|
||||
/* We should not call forbid here, but we do for now.
|
||||
* Check the comment to pm_runtime_allow() in
|
||||
* iwl_pci_probe().
|
||||
*/
|
||||
pm_runtime_forbid(trans->dev);
|
||||
}
|
||||
|
||||
iwl_drv_stop(trans_pcie->drv);
|
||||
|
||||
iwl_trans_pcie_free(trans);
|
||||
}
|
||||
|
||||
|
|
|
@ -347,7 +347,7 @@ struct iwl_tso_hdr_page {
|
|||
*/
|
||||
struct iwl_trans_pcie {
|
||||
struct iwl_rxq *rxq;
|
||||
struct iwl_rx_mem_buffer rx_pool[MQ_RX_POOL_SIZE];
|
||||
struct iwl_rx_mem_buffer rx_pool[RX_POOL_SIZE];
|
||||
struct iwl_rx_mem_buffer *global_table[MQ_RX_TABLE_SIZE];
|
||||
struct iwl_rb_allocator rba;
|
||||
struct iwl_trans *trans;
|
||||
|
|
|
@ -231,6 +231,9 @@ static void iwl_pcie_rxq_check_wrptr(struct iwl_trans *trans)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* iwl_pcie_rxq_mq_restock - restock implementation for multi-queue rx
|
||||
*/
|
||||
static void iwl_pcie_rxq_mq_restock(struct iwl_trans *trans,
|
||||
struct iwl_rxq *rxq)
|
||||
{
|
||||
|
@ -277,17 +280,10 @@ static void iwl_pcie_rxq_mq_restock(struct iwl_trans *trans,
|
|||
}
|
||||
|
||||
/*
|
||||
* iwl_pcie_rxq_restock - refill RX queue from pre-allocated pool
|
||||
*
|
||||
* If there are slots in the RX queue that need to be restocked,
|
||||
* and we have free pre-allocated buffers, fill the ranks as much
|
||||
* as we can, pulling from rx_free.
|
||||
*
|
||||
* This moves the 'write' index forward to catch up with 'processed', and
|
||||
* also updates the memory address in the firmware to reference the new
|
||||
* target buffer.
|
||||
* iwl_pcie_rxq_sq_restock - restock implementation for single queue rx
|
||||
*/
|
||||
static void iwl_pcie_rxq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq)
|
||||
static void iwl_pcie_rxq_sq_restock(struct iwl_trans *trans,
|
||||
struct iwl_rxq *rxq)
|
||||
{
|
||||
struct iwl_rx_mem_buffer *rxb;
|
||||
|
||||
|
@ -331,6 +327,26 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* iwl_pcie_rxq_restock - refill RX queue from pre-allocated pool
|
||||
*
|
||||
* If there are slots in the RX queue that need to be restocked,
|
||||
* and we have free pre-allocated buffers, fill the ranks as much
|
||||
* as we can, pulling from rx_free.
|
||||
*
|
||||
* This moves the 'write' index forward to catch up with 'processed', and
|
||||
* also updates the memory address in the firmware to reference the new
|
||||
* target buffer.
|
||||
*/
|
||||
static
|
||||
void iwl_pcie_rxq_restock(struct iwl_trans *trans, struct iwl_rxq *rxq)
|
||||
{
|
||||
if (trans->cfg->mq_rx_supported)
|
||||
iwl_pcie_rxq_mq_restock(trans, rxq);
|
||||
else
|
||||
iwl_pcie_rxq_sq_restock(trans, rxq);
|
||||
}
|
||||
|
||||
/*
|
||||
* iwl_pcie_rx_alloc_page - allocates and returns a page.
|
||||
*
|
||||
|
@ -434,7 +450,7 @@ static void iwl_pcie_free_rbs_pool(struct iwl_trans *trans)
|
|||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MQ_RX_POOL_SIZE; i++) {
|
||||
for (i = 0; i < RX_POOL_SIZE; i++) {
|
||||
if (!trans_pcie->rx_pool[i].page)
|
||||
continue;
|
||||
dma_unmap_page(trans->dev, trans_pcie->rx_pool[i].page_dma,
|
||||
|
@ -539,40 +555,46 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans)
|
|||
}
|
||||
|
||||
/*
|
||||
* iwl_pcie_rx_allocator_get - Returns the pre-allocated pages
|
||||
* iwl_pcie_rx_allocator_get - returns the pre-allocated pages
|
||||
.*
|
||||
.* Called by queue when the queue posted allocation request and
|
||||
* has freed 8 RBDs in order to restock itself.
|
||||
* This function directly moves the allocated RBs to the queue's ownership
|
||||
* and updates the relevant counters.
|
||||
*/
|
||||
static int iwl_pcie_rx_allocator_get(struct iwl_trans *trans,
|
||||
struct iwl_rx_mem_buffer
|
||||
*out[RX_CLAIM_REQ_ALLOC])
|
||||
static void iwl_pcie_rx_allocator_get(struct iwl_trans *trans,
|
||||
struct iwl_rxq *rxq)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_rb_allocator *rba = &trans_pcie->rba;
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&rxq->lock);
|
||||
|
||||
/*
|
||||
* atomic_dec_if_positive returns req_ready - 1 for any scenario.
|
||||
* If req_ready is 0 atomic_dec_if_positive will return -1 and this
|
||||
* function will return -ENOMEM, as there are no ready requests.
|
||||
* function will return early, as there are no ready requests.
|
||||
* atomic_dec_if_positive will perofrm the *actual* decrement only if
|
||||
* req_ready > 0, i.e. - there are ready requests and the function
|
||||
* hands one request to the caller.
|
||||
*/
|
||||
if (atomic_dec_if_positive(&rba->req_ready) < 0)
|
||||
return -ENOMEM;
|
||||
return;
|
||||
|
||||
spin_lock(&rba->lock);
|
||||
for (i = 0; i < RX_CLAIM_REQ_ALLOC; i++) {
|
||||
/* Get next free Rx buffer, remove it from free list */
|
||||
out[i] = list_first_entry(&rba->rbd_allocated,
|
||||
struct iwl_rx_mem_buffer, list);
|
||||
list_del(&out[i]->list);
|
||||
struct iwl_rx_mem_buffer *rxb =
|
||||
list_first_entry(&rba->rbd_allocated,
|
||||
struct iwl_rx_mem_buffer, list);
|
||||
|
||||
list_move(&rxb->list, &rxq->rx_free);
|
||||
}
|
||||
spin_unlock(&rba->lock);
|
||||
|
||||
return 0;
|
||||
rxq->used_count -= RX_CLAIM_REQ_ALLOC;
|
||||
rxq->free_count += RX_CLAIM_REQ_ALLOC;
|
||||
}
|
||||
|
||||
static void iwl_pcie_rx_allocator_work(struct work_struct *data)
|
||||
|
@ -795,11 +817,10 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans)
|
|||
|
||||
/*
|
||||
* Activate DMA snooping.
|
||||
* Set RX DMA chunk size to 128 bit
|
||||
* Set RX DMA chunk size to 64B
|
||||
* Default queue is 0
|
||||
*/
|
||||
iwl_write_prph(trans, RFH_GEN_CFG, RFH_GEN_CFG_RFH_DMA_SNOOP |
|
||||
RFH_GEN_CFG_RB_CHUNK_SIZE |
|
||||
(DEFAULT_RXQ_NUM << RFH_GEN_CFG_DEFAULT_RXQ_NUM_POS) |
|
||||
RFH_GEN_CFG_SERVICE_DMA_SNOOP);
|
||||
/* Enable the relevant rx queues */
|
||||
|
@ -830,7 +851,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
|
|||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_rxq *def_rxq;
|
||||
struct iwl_rb_allocator *rba = &trans_pcie->rba;
|
||||
int i, err, num_rbds, allocator_pool_size;
|
||||
int i, err, queue_size, allocator_pool_size, num_alloc;
|
||||
|
||||
if (!trans_pcie->rxq) {
|
||||
err = iwl_pcie_rx_alloc(trans);
|
||||
|
@ -882,11 +903,12 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
|
|||
}
|
||||
|
||||
/* move the pool to the default queue and allocator ownerships */
|
||||
num_rbds = trans->cfg->mq_rx_supported ?
|
||||
MQ_RX_POOL_SIZE : RX_QUEUE_SIZE;
|
||||
queue_size = trans->cfg->mq_rx_supported ?
|
||||
MQ_RX_NUM_RBDS : RX_QUEUE_SIZE;
|
||||
allocator_pool_size = trans->num_rx_queues *
|
||||
(RX_CLAIM_REQ_ALLOC - RX_POST_REQ_ALLOC);
|
||||
for (i = 0; i < num_rbds; i++) {
|
||||
num_alloc = queue_size + allocator_pool_size;
|
||||
for (i = 0; i < num_alloc; i++) {
|
||||
struct iwl_rx_mem_buffer *rxb = &trans_pcie->rx_pool[i];
|
||||
|
||||
if (i < allocator_pool_size)
|
||||
|
@ -901,7 +923,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
|
|||
if (trans->cfg->mq_rx_supported) {
|
||||
iwl_pcie_rx_mq_hw_init(trans);
|
||||
} else {
|
||||
iwl_pcie_rxq_restock(trans, def_rxq);
|
||||
iwl_pcie_rxq_sq_restock(trans, def_rxq);
|
||||
iwl_pcie_rx_hw_init(trans, def_rxq);
|
||||
}
|
||||
|
||||
|
@ -1149,7 +1171,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans, int queue)
|
|||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_rxq *rxq = &trans_pcie->rxq[queue];
|
||||
u32 r, i, j, count = 0;
|
||||
u32 r, i, count = 0;
|
||||
bool emergency = false;
|
||||
|
||||
restart:
|
||||
|
@ -1193,62 +1215,36 @@ restart:
|
|||
|
||||
i = (i + 1) & (rxq->queue_size - 1);
|
||||
|
||||
/* If we have RX_CLAIM_REQ_ALLOC released rx buffers -
|
||||
* try to claim the pre-allocated buffers from the allocator */
|
||||
if (rxq->used_count >= RX_CLAIM_REQ_ALLOC) {
|
||||
/*
|
||||
* If we have RX_CLAIM_REQ_ALLOC released rx buffers -
|
||||
* try to claim the pre-allocated buffers from the allocator.
|
||||
* If not ready - will try to reclaim next time.
|
||||
* There is no need to reschedule work - allocator exits only
|
||||
* on success
|
||||
*/
|
||||
if (rxq->used_count >= RX_CLAIM_REQ_ALLOC)
|
||||
iwl_pcie_rx_allocator_get(trans, rxq);
|
||||
|
||||
if (rxq->used_count % RX_CLAIM_REQ_ALLOC == 0 && !emergency) {
|
||||
struct iwl_rb_allocator *rba = &trans_pcie->rba;
|
||||
struct iwl_rx_mem_buffer *out[RX_CLAIM_REQ_ALLOC];
|
||||
|
||||
if (rxq->used_count % RX_CLAIM_REQ_ALLOC == 0 &&
|
||||
!emergency) {
|
||||
/* Add the remaining 6 empty RBDs
|
||||
* for allocator use
|
||||
*/
|
||||
spin_lock(&rba->lock);
|
||||
list_splice_tail_init(&rxq->rx_used,
|
||||
&rba->rbd_empty);
|
||||
spin_unlock(&rba->lock);
|
||||
}
|
||||
|
||||
/* If not ready - continue, will try to reclaim later.
|
||||
* No need to reschedule work - allocator exits only on
|
||||
* success */
|
||||
if (!iwl_pcie_rx_allocator_get(trans, out)) {
|
||||
/* If success - then RX_CLAIM_REQ_ALLOC
|
||||
* buffers were retrieved and should be added
|
||||
* to free list */
|
||||
rxq->used_count -= RX_CLAIM_REQ_ALLOC;
|
||||
for (j = 0; j < RX_CLAIM_REQ_ALLOC; j++) {
|
||||
list_add_tail(&out[j]->list,
|
||||
&rxq->rx_free);
|
||||
rxq->free_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (emergency) {
|
||||
/* Add the remaining empty RBDs for allocator use */
|
||||
spin_lock(&rba->lock);
|
||||
list_splice_tail_init(&rxq->rx_used, &rba->rbd_empty);
|
||||
spin_unlock(&rba->lock);
|
||||
} else if (emergency) {
|
||||
count++;
|
||||
if (count == 8) {
|
||||
count = 0;
|
||||
if (rxq->used_count < rxq->queue_size / 3)
|
||||
emergency = false;
|
||||
|
||||
rxq->read = i;
|
||||
spin_unlock(&rxq->lock);
|
||||
iwl_pcie_rxq_alloc_rbs(trans, GFP_ATOMIC, rxq);
|
||||
spin_lock(&rxq->lock);
|
||||
}
|
||||
}
|
||||
/* handle restock for three cases, can be all of them at once:
|
||||
* - we just pulled buffers from the allocator
|
||||
* - we have 8+ unstolen pages accumulated
|
||||
* - we are in emergency and allocated buffers
|
||||
*/
|
||||
if (rxq->free_count >= RX_CLAIM_REQ_ALLOC) {
|
||||
rxq->read = i;
|
||||
spin_unlock(&rxq->lock);
|
||||
if (trans->cfg->mq_rx_supported)
|
||||
iwl_pcie_rxq_mq_restock(trans, rxq);
|
||||
else
|
||||
iwl_pcie_rxq_restock(trans, rxq);
|
||||
goto restart;
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
out:
|
||||
|
@ -1273,6 +1269,8 @@ out:
|
|||
|
||||
if (rxq->napi.poll)
|
||||
napi_gro_flush(&rxq->napi, false);
|
||||
|
||||
iwl_pcie_rxq_restock(trans, rxq);
|
||||
}
|
||||
|
||||
static struct iwl_trans_pcie *iwl_pcie_get_trans_pcie(struct msix_entry *entry)
|
||||
|
|
|
@ -1646,9 +1646,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
|
|||
trans->command_groups = trans_cfg->command_groups;
|
||||
trans->command_groups_size = trans_cfg->command_groups_size;
|
||||
|
||||
/* init ref_count to 1 (should be cleared when ucode is loaded) */
|
||||
trans_pcie->ref_count = 1;
|
||||
|
||||
/* Initialize NAPI here - it should be before registering to mac80211
|
||||
* in the opmode but after the HW struct is allocated.
|
||||
* As this function may be called again in some corner cases don't
|
||||
|
@ -1663,9 +1660,6 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
|
|||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int i;
|
||||
|
||||
/* TODO: check if this is really needed */
|
||||
pm_runtime_disable(trans->dev);
|
||||
|
||||
iwl_pcie_synchronize_irqs(trans);
|
||||
|
||||
iwl_pcie_tx_free(trans);
|
||||
|
|
|
@ -1118,7 +1118,8 @@ int lbs_start_card(struct lbs_private *priv)
|
|||
else
|
||||
pr_info("%s: mesh disabled\n", dev->name);
|
||||
|
||||
if (lbs_cfg_register(priv)) {
|
||||
ret = lbs_cfg_register(priv);
|
||||
if (ret) {
|
||||
pr_err("cannot register device\n");
|
||||
goto done;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "cfg80211.h"
|
||||
#include "main.h"
|
||||
#include "11n.h"
|
||||
#include "wmm.h"
|
||||
|
||||
static char *reg_alpha2;
|
||||
module_param(reg_alpha2, charp, 0);
|
||||
|
@ -3259,7 +3260,7 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
|
|||
{
|
||||
struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
|
||||
struct mwifiex_ds_hs_cfg hs_cfg;
|
||||
int i, ret = 0;
|
||||
int i, ret = 0, retry_num = 10;
|
||||
struct mwifiex_private *priv;
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
|
@ -3269,6 +3270,21 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
|
|||
|
||||
mwifiex_cancel_all_pending_cmd(adapter);
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv && priv->netdev)
|
||||
mwifiex_stop_net_dev_queue(priv->netdev, adapter);
|
||||
}
|
||||
|
||||
for (i = 0; i < retry_num; i++) {
|
||||
if (!mwifiex_wmm_lists_empty(adapter) ||
|
||||
!mwifiex_bypass_txlist_empty(adapter) ||
|
||||
!skb_queue_empty(&adapter->tx_data_q))
|
||||
usleep_range(10000, 15000);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!wowlan) {
|
||||
mwifiex_dbg(adapter, ERROR,
|
||||
"None of the WOWLAN triggers enabled\n");
|
||||
|
@ -3321,12 +3337,18 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
|
|||
static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
|
||||
struct mwifiex_private *priv =
|
||||
mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
|
||||
struct mwifiex_private *priv;
|
||||
struct mwifiex_ds_wakeup_reason wakeup_reason;
|
||||
struct cfg80211_wowlan_wakeup wakeup_report;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < adapter->priv_num; i++) {
|
||||
priv = adapter->priv[i];
|
||||
if (priv && priv->netdev)
|
||||
mwifiex_wake_up_net_dev_queue(priv->netdev, adapter);
|
||||
}
|
||||
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
|
||||
mwifiex_get_wakeup_reason(priv, HostCmd_ACT_GEN_GET, MWIFIEX_SYNC_CMD,
|
||||
&wakeup_reason);
|
||||
memset(&wakeup_report, 0, sizeof(struct cfg80211_wowlan_wakeup));
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -34,7 +34,7 @@
|
|||
#define RTL8XXXU_MAX_REG_POLL 500
|
||||
#define USB_INTR_CONTENT_LENGTH 56
|
||||
|
||||
#define RTL8XXXU_OUT_ENDPOINTS 3
|
||||
#define RTL8XXXU_OUT_ENDPOINTS 4
|
||||
|
||||
#define REALTEK_USB_READ 0xc0
|
||||
#define REALTEK_USB_WRITE 0x40
|
||||
|
@ -53,14 +53,24 @@
|
|||
|
||||
#define RTL8723A_CHANNEL_GROUPS 3
|
||||
#define RTL8723A_MAX_RF_PATHS 2
|
||||
#define RTL8723B_CHANNEL_GROUPS 6
|
||||
#define RTL8723B_TX_COUNT 4
|
||||
#define RTL8723B_MAX_RF_PATHS 4
|
||||
#define RTL8XXXU_MAX_CHANNEL_GROUPS 6
|
||||
#define RF6052_MAX_TX_PWR 0x3f
|
||||
|
||||
#define EFUSE_MAP_LEN_8723A 256
|
||||
#define EFUSE_MAX_SECTION_8723A 32
|
||||
#define EFUSE_MAP_LEN 512
|
||||
#define EFUSE_MAX_SECTION_8723A 64
|
||||
#define EFUSE_REAL_CONTENT_LEN_8723A 512
|
||||
#define EFUSE_BT_MAP_LEN_8723A 1024
|
||||
#define EFUSE_MAX_WORD_UNIT 4
|
||||
|
||||
enum rtl8xxxu_rx_type {
|
||||
RX_TYPE_DATA_PKT = 0,
|
||||
RX_TYPE_C2H = 1,
|
||||
RX_TYPE_ERROR = -1
|
||||
};
|
||||
|
||||
struct rtl8xxxu_rx_desc {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u32 pktlen:14;
|
||||
|
@ -197,7 +207,132 @@ struct rtl8xxxu_rx_desc {
|
|||
#endif
|
||||
};
|
||||
|
||||
struct rtl8xxxu_tx_desc {
|
||||
struct rtl8723bu_rx_desc {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u32 pktlen:14;
|
||||
u32 crc32:1;
|
||||
u32 icverr:1;
|
||||
u32 drvinfo_sz:4;
|
||||
u32 security:3;
|
||||
u32 qos:1;
|
||||
u32 shift:2;
|
||||
u32 phy_stats:1;
|
||||
u32 swdec:1;
|
||||
u32 ls:1;
|
||||
u32 fs:1;
|
||||
u32 eor:1;
|
||||
u32 own:1;
|
||||
|
||||
u32 macid:7;
|
||||
u32 dummy1_0:1;
|
||||
u32 tid:4;
|
||||
u32 dummy1_1:1;
|
||||
u32 amsdu:1;
|
||||
u32 rxid_match:1;
|
||||
u32 paggr:1;
|
||||
u32 a1fit:4; /* 16 */
|
||||
u32 chkerr:1;
|
||||
u32 ipver:1;
|
||||
u32 tcpudp:1;
|
||||
u32 chkvld:1;
|
||||
u32 pam:1;
|
||||
u32 pwr:1;
|
||||
u32 more_data:1;
|
||||
u32 more_frag:1;
|
||||
u32 type:2;
|
||||
u32 mc:1;
|
||||
u32 bc:1;
|
||||
|
||||
u32 seq:12;
|
||||
u32 frag:4;
|
||||
u32 rx_is_qos:1; /* 16 */
|
||||
u32 dummy2_0:1;
|
||||
u32 wlanhd_iv_len:6;
|
||||
u32 dummy2_1:4;
|
||||
u32 rpt_sel:1;
|
||||
u32 dummy2_2:3;
|
||||
|
||||
u32 rxmcs:7;
|
||||
u32 dummy3_0:3;
|
||||
u32 htc:1;
|
||||
u32 eosp:1;
|
||||
u32 bssidfit:2;
|
||||
u32 dummy3_1:2;
|
||||
u32 usb_agg_pktnum:8; /* 16 */
|
||||
u32 dummy3_2:5;
|
||||
u32 pattern_match:1;
|
||||
u32 unicast_match:1;
|
||||
u32 magic_match:1;
|
||||
|
||||
u32 splcp:1;
|
||||
u32 ldcp:1;
|
||||
u32 stbc:1;
|
||||
u32 dummy4_0:1;
|
||||
u32 bw:2;
|
||||
u32 dummy4_1:26;
|
||||
#else
|
||||
u32 own:1;
|
||||
u32 eor:1;
|
||||
u32 fs:1;
|
||||
u32 ls:1;
|
||||
u32 swdec:1;
|
||||
u32 phy_stats:1;
|
||||
u32 shift:2;
|
||||
u32 qos:1;
|
||||
u32 security:3;
|
||||
u32 drvinfo_sz:4;
|
||||
u32 icverr:1;
|
||||
u32 crc32:1;
|
||||
u32 pktlen:14;
|
||||
|
||||
u32 bc:1;
|
||||
u32 mc:1;
|
||||
u32 type:2;
|
||||
u32 mf:1;
|
||||
u32 md:1;
|
||||
u32 pwr:1;
|
||||
u32 pam:1;
|
||||
u32 a2fit:4;
|
||||
u32 a1fit:4;
|
||||
u32 faggr:1;
|
||||
u32 paggr:1;
|
||||
u32 amsdu:1;
|
||||
u32 hwrsvd:4;
|
||||
u32 tid:4;
|
||||
u32 macid:5;
|
||||
|
||||
u32 dummy2_2:3;
|
||||
u32 rpt_sel:1;
|
||||
u32 dummy2_1:4;
|
||||
u32 wlanhd_iv_len:6;
|
||||
u32 dummy2_0:1;
|
||||
u32 rx_is_qos:1;
|
||||
u32 frag:4; /* 16 */
|
||||
u32 seq:12;
|
||||
|
||||
u32 magic_match:1;
|
||||
u32 unicast_match:1;
|
||||
u32 pattern_match:1;
|
||||
u32 dummy3_2:5;
|
||||
u32 usb_agg_pktnum:8;
|
||||
u32 dummy3_1:2; /* 16 */
|
||||
u32 bssidfit:2;
|
||||
u32 eosp:1;
|
||||
u32 htc:1;
|
||||
u32 dummy3_0:3;
|
||||
u32 rxmcs:7;
|
||||
|
||||
u32 dumm4_1:26;
|
||||
u32 bw:2;
|
||||
u32 dummy4_0:1;
|
||||
u32 stbc:1;
|
||||
u32 ldcp:1;
|
||||
u32 splcp:1;
|
||||
#endif
|
||||
__le32 tsfl;
|
||||
};
|
||||
|
||||
struct rtl8723au_tx_desc {
|
||||
__le16 pkt_size;
|
||||
u8 pkt_offset;
|
||||
u8 txdw0;
|
||||
|
@ -211,6 +346,22 @@ struct rtl8xxxu_tx_desc {
|
|||
__le16 txdw7;
|
||||
};
|
||||
|
||||
struct rtl8723bu_tx_desc {
|
||||
__le16 pkt_size;
|
||||
u8 pkt_offset;
|
||||
u8 txdw0;
|
||||
__le32 txdw1;
|
||||
__le32 txdw2;
|
||||
__le32 txdw3;
|
||||
__le32 txdw4;
|
||||
__le32 txdw5;
|
||||
__le32 txdw6;
|
||||
__le16 csum;
|
||||
__le16 txdw7;
|
||||
__le32 txdw8;
|
||||
__le32 txdw9;
|
||||
};
|
||||
|
||||
/* CCK Rates, TxHT = 0 */
|
||||
#define DESC_RATE_1M 0x00
|
||||
#define DESC_RATE_2M 0x01
|
||||
|
@ -256,15 +407,25 @@ struct rtl8xxxu_tx_desc {
|
|||
#define TXDESC_OWN BIT(31)
|
||||
#else
|
||||
#define TXDESC_BROADMULTICAST BIT(0)
|
||||
#define TXDESC_HTC BIT(1)
|
||||
#define TXDESC_LAST_SEGMENT BIT(2)
|
||||
#define TXDESC_FIRST_SEGMENT BIT(3)
|
||||
#define TXDESC_LINIP BIT(4)
|
||||
#define TXDESC_NO_ACM BIT(5)
|
||||
#define TXDESC_GF BIT(6)
|
||||
#define TXDESC_OWN BIT(7)
|
||||
#endif
|
||||
|
||||
/* Word 1 */
|
||||
/*
|
||||
* Bits 0-7 differ dependent on chip generation. For 8723au bits 5/6 are
|
||||
* aggregation enable and break respectively. For 8723bu, bits 0-7 are macid.
|
||||
*/
|
||||
#define TXDESC_PKT_OFFSET_SZ 0
|
||||
#define TXDESC_AGG_ENABLE BIT(5)
|
||||
#define TXDESC_BK BIT(6)
|
||||
#define TXDESC_AGG_ENABLE_8723A BIT(5)
|
||||
#define TXDESC_AGG_BREAK_8723A BIT(6)
|
||||
#define TXDESC_MACID_SHIFT_8723B 0
|
||||
#define TXDESC_MACID_MASK_8723B 0x00f0
|
||||
#define TXDESC_QUEUE_SHIFT 8
|
||||
#define TXDESC_QUEUE_MASK 0x1f00
|
||||
#define TXDESC_QUEUE_BK 0x2
|
||||
|
@ -276,6 +437,9 @@ struct rtl8xxxu_tx_desc {
|
|||
#define TXDESC_QUEUE_MGNT 0x12
|
||||
#define TXDESC_QUEUE_CMD 0x13
|
||||
#define TXDESC_QUEUE_MAX (TXDESC_QUEUE_CMD + 1)
|
||||
#define TXDESC_RDG_NAV_EXT_8723B BIT(13)
|
||||
#define TXDESC_LSIG_TXOP_ENABLE_8723B BIT(14)
|
||||
#define TXDESC_PIFS_8723B BIT(15)
|
||||
|
||||
#define DESC_RATE_ID_SHIFT 16
|
||||
#define DESC_RATE_ID_MASK 0xf
|
||||
|
@ -287,41 +451,72 @@ struct rtl8xxxu_tx_desc {
|
|||
#define TXDESC_HWPC BIT(31)
|
||||
|
||||
/* Word 2 */
|
||||
#define TXDESC_ACK_REPORT BIT(19)
|
||||
#define TXDESC_PAID_SHIFT_8723B 0
|
||||
#define TXDESC_PAID_MASK_8723B 0x1ff
|
||||
#define TXDESC_CCA_RTS_SHIFT_8723B 10
|
||||
#define TXDESC_CCA_RTS_MASK_8723B 0xc00
|
||||
#define TXDESC_AGG_ENABLE_8723B BIT(12)
|
||||
#define TXDESC_RDG_ENABLE_8723B BIT(13)
|
||||
#define TXDESC_AGG_BREAK_8723B BIT(16)
|
||||
#define TXDESC_MORE_FRAG_8723B BIT(17)
|
||||
#define TXDESC_RAW_8723B BIT(18)
|
||||
#define TXDESC_ACK_REPORT_8723A BIT(19)
|
||||
#define TXDESC_SPE_RPT_8723B BIT(19)
|
||||
#define TXDESC_AMPDU_DENSITY_SHIFT 20
|
||||
#define TXDESC_BT_INT_8723B BIT(23)
|
||||
#define TXDESC_GID_8723B BIT(24)
|
||||
|
||||
/* Word 3 */
|
||||
#define TXDESC_SEQ_SHIFT 16
|
||||
#define TXDESC_SEQ_MASK 0x0fff0000
|
||||
#define TXDESC_USE_DRIVER_RATE_8723B BIT(8)
|
||||
#define TXDESC_CTS_SELF_ENABLE_8723B BIT(11)
|
||||
#define TXDESC_RTS_CTS_ENABLE_8723B BIT(12)
|
||||
#define TXDESC_HW_RTS_ENABLE_8723B BIT(13)
|
||||
#define TXDESC_SEQ_SHIFT_8723A 16
|
||||
#define TXDESC_SEQ_MASK_8723A 0x0fff0000
|
||||
|
||||
/* Word 4 */
|
||||
#define TXDESC_QOS BIT(6)
|
||||
#define TXDESC_HW_SEQ_ENABLE BIT(7)
|
||||
#define TXDESC_USE_DRIVER_RATE BIT(8)
|
||||
#define TXDESC_RTS_RATE_SHIFT_8723A 0
|
||||
#define TXDESC_RTS_RATE_MASK_8723A 0x3f
|
||||
#define TXDESC_QOS_8723A BIT(6)
|
||||
#define TXDESC_HW_SEQ_ENABLE_8723A BIT(7)
|
||||
#define TXDESC_USE_DRIVER_RATE_8723A BIT(8)
|
||||
#define TXDESC_DISABLE_DATA_FB BIT(10)
|
||||
#define TXDESC_CTS_SELF_ENABLE BIT(11)
|
||||
#define TXDESC_RTS_CTS_ENABLE BIT(12)
|
||||
#define TXDESC_HW_RTS_ENABLE BIT(13)
|
||||
#define TXDESC_CTS_SELF_ENABLE_8723A BIT(11)
|
||||
#define TXDESC_RTS_CTS_ENABLE_8723A BIT(12)
|
||||
#define TXDESC_HW_RTS_ENABLE_8723A BIT(13)
|
||||
#define TXDESC_PRIME_CH_OFF_LOWER BIT(20)
|
||||
#define TXDESC_PRIME_CH_OFF_UPPER BIT(21)
|
||||
#define TXDESC_SHORT_PREAMBLE BIT(24)
|
||||
#define TXDESC_SHORT_PREAMBLE_8723A BIT(24)
|
||||
#define TXDESC_DATA_BW BIT(25)
|
||||
#define TXDESC_RTS_DATA_BW BIT(27)
|
||||
#define TXDESC_RTS_PRIME_CH_OFF_LOWER BIT(28)
|
||||
#define TXDESC_RTS_PRIME_CH_OFF_UPPER BIT(29)
|
||||
#define TXDESC_DATA_RATE_FB_SHIFT_8723B 8
|
||||
#define TXDESC_DATA_RATE_FB_MASK_8723B 0x00001f00
|
||||
#define TXDESC_RETRY_LIMIT_ENABLE_8723B BIT(17)
|
||||
#define TXDESC_RETRY_LIMIT_SHIFT_8723B 18
|
||||
#define TXDESC_RETRY_LIMIT_MASK_8723B 0x00fc0000
|
||||
#define TXDESC_RTS_RATE_SHIFT_8723B 24
|
||||
#define TXDESC_RTS_RATE_MASK_8723B 0x3f000000
|
||||
|
||||
/* Word 5 */
|
||||
#define TXDESC_RTS_RATE_SHIFT 0
|
||||
#define TXDESC_RTS_RATE_MASK 0x3f
|
||||
#define TXDESC_SHORT_PREAMBLE_8723B BIT(4)
|
||||
#define TXDESC_SHORT_GI BIT(6)
|
||||
#define TXDESC_CCX_TAG BIT(7)
|
||||
#define TXDESC_RETRY_LIMIT_ENABLE BIT(17)
|
||||
#define TXDESC_RETRY_LIMIT_SHIFT 18
|
||||
#define TXDESC_RETRY_LIMIT_MASK 0x00fc0000
|
||||
#define TXDESC_RETRY_LIMIT_ENABLE_8723A BIT(17)
|
||||
#define TXDESC_RETRY_LIMIT_SHIFT_8723A 18
|
||||
#define TXDESC_RETRY_LIMIT_MASK_8723A 0x00fc0000
|
||||
|
||||
/* Word 6 */
|
||||
#define TXDESC_MAX_AGG_SHIFT 11
|
||||
|
||||
/* Word 8 */
|
||||
#define TXDESC_HW_SEQ_ENABLE_8723B BIT(15)
|
||||
|
||||
/* Word 9 */
|
||||
#define TXDESC_SEQ_SHIFT_8723B 12
|
||||
#define TXDESC_SEQ_MASK_8723B 0x00fff000
|
||||
|
||||
struct phy_rx_agc_info {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
u8 gain:7, trsw:1;
|
||||
|
@ -500,6 +695,125 @@ struct rtl8192cu_efuse {
|
|||
u8 customer_id;
|
||||
};
|
||||
|
||||
struct rtl8723bu_pwr_idx {
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
int ht20:4;
|
||||
int ht40:4;
|
||||
int ofdm:4;
|
||||
int cck:4;
|
||||
#else
|
||||
int cck:4;
|
||||
int ofdm:4;
|
||||
int ht40:4;
|
||||
int ht20:4;
|
||||
#endif
|
||||
} __attribute__((packed));
|
||||
|
||||
struct rtl8723bu_efuse_tx_power {
|
||||
u8 cck_base[6];
|
||||
u8 ht40_base[5];
|
||||
struct rtl8723au_idx ht20_ofdm_1s_diff;
|
||||
struct rtl8723bu_pwr_idx pwr_diff[3];
|
||||
u8 dummy5g[24]; /* max channel group (14) + power diff offset (10) */
|
||||
};
|
||||
|
||||
struct rtl8723bu_efuse {
|
||||
__le16 rtl_id;
|
||||
u8 res0[0x0e];
|
||||
struct rtl8723bu_efuse_tx_power tx_power_index_A; /* 0x10 */
|
||||
struct rtl8723bu_efuse_tx_power tx_power_index_B; /* 0x3a */
|
||||
struct rtl8723bu_efuse_tx_power tx_power_index_C; /* 0x64 */
|
||||
struct rtl8723bu_efuse_tx_power tx_power_index_D; /* 0x8e */
|
||||
u8 channel_plan; /* 0xb8 */
|
||||
u8 xtal_k;
|
||||
u8 thermal_meter;
|
||||
u8 iqk_lck;
|
||||
u8 pa_type; /* 0xbc */
|
||||
u8 lna_type_2g; /* 0xbd */
|
||||
u8 res2[3];
|
||||
u8 rf_board_option;
|
||||
u8 rf_feature_option;
|
||||
u8 rf_bt_setting;
|
||||
u8 eeprom_version;
|
||||
u8 eeprom_customer_id;
|
||||
u8 res3[2];
|
||||
u8 tx_pwr_calibrate_rate;
|
||||
u8 rf_antenna_option; /* 0xc9 */
|
||||
u8 rfe_option;
|
||||
u8 res4[9];
|
||||
u8 usb_optional_function;
|
||||
u8 res5[0x1e];
|
||||
u8 res6[2];
|
||||
u8 serial[0x0b]; /* 0xf5 */
|
||||
u8 vid; /* 0x100 */
|
||||
u8 res7;
|
||||
u8 pid;
|
||||
u8 res8[4];
|
||||
u8 mac_addr[ETH_ALEN]; /* 0x107 */
|
||||
u8 res9[2];
|
||||
u8 vendor_name[0x07];
|
||||
u8 res10[2];
|
||||
u8 device_name[0x14];
|
||||
u8 res11[0xcf];
|
||||
u8 package_type; /* 0x1fb */
|
||||
u8 res12[0x4];
|
||||
};
|
||||
|
||||
struct rtl8192eu_efuse_tx_power {
|
||||
u8 cck_base[6];
|
||||
u8 ht40_base[5];
|
||||
struct rtl8723au_idx ht20_ofdm_1s_diff;
|
||||
struct rtl8723au_idx ht40_ht20_2s_diff;
|
||||
struct rtl8723au_idx ofdm_cck_2s_diff; /* not used */
|
||||
struct rtl8723au_idx ht40_ht20_3s_diff;
|
||||
struct rtl8723au_idx ofdm_cck_3s_diff; /* not used */
|
||||
struct rtl8723au_idx ht40_ht20_4s_diff;
|
||||
struct rtl8723au_idx ofdm_cck_4s_diff; /* not used */
|
||||
};
|
||||
|
||||
struct rtl8192eu_efuse {
|
||||
__le16 rtl_id;
|
||||
u8 res0[0x0e];
|
||||
struct rtl8192eu_efuse_tx_power tx_power_index_A; /* 0x10 */
|
||||
struct rtl8192eu_efuse_tx_power tx_power_index_B; /* 0x22 */
|
||||
struct rtl8192eu_efuse_tx_power tx_power_index_C; /* 0x34 */
|
||||
struct rtl8192eu_efuse_tx_power tx_power_index_D; /* 0x46 */
|
||||
u8 res1[0x60];
|
||||
u8 channel_plan; /* 0xb8 */
|
||||
u8 xtal_k;
|
||||
u8 thermal_meter;
|
||||
u8 iqk_lck;
|
||||
u8 pa_type; /* 0xbc */
|
||||
u8 lna_type_2g; /* 0xbd */
|
||||
u8 res2[1];
|
||||
u8 lna_type_5g; /* 0xbf */
|
||||
u8 res13[1];
|
||||
u8 rf_board_option;
|
||||
u8 rf_feature_option;
|
||||
u8 rf_bt_setting;
|
||||
u8 eeprom_version;
|
||||
u8 eeprom_customer_id;
|
||||
u8 res3[3];
|
||||
u8 rf_antenna_option; /* 0xc9 */
|
||||
u8 res4[6];
|
||||
u8 vid; /* 0xd0 */
|
||||
u8 res5[1];
|
||||
u8 pid; /* 0xd2 */
|
||||
u8 res6[1];
|
||||
u8 usb_optional_function;
|
||||
u8 res7[2];
|
||||
u8 mac_addr[ETH_ALEN]; /* 0xd7 */
|
||||
u8 res8[2];
|
||||
u8 vendor_name[7];
|
||||
u8 res9[2];
|
||||
u8 device_name[0x0b]; /* 0xe8 */
|
||||
u8 res10[2];
|
||||
u8 serial[0x0b]; /* 0xf5 */
|
||||
u8 res11[0x30];
|
||||
u8 unknown[0x0d]; /* 0x130 */
|
||||
u8 res12[0xc3];
|
||||
};
|
||||
|
||||
struct rtl8xxxu_reg8val {
|
||||
u16 reg;
|
||||
u8 val;
|
||||
|
@ -531,27 +845,110 @@ struct rtl8xxxu_rfregs {
|
|||
|
||||
#define H2C_MAX_MBOX 4
|
||||
#define H2C_EXT BIT(7)
|
||||
#define H2C_SET_POWER_MODE 1
|
||||
#define H2C_JOIN_BSS_REPORT 2
|
||||
#define H2C_JOIN_BSS_DISCONNECT 0
|
||||
#define H2C_JOIN_BSS_CONNECT 1
|
||||
#define H2C_SET_RSSI 5
|
||||
#define H2C_SET_RATE_MASK (6 | H2C_EXT)
|
||||
|
||||
/*
|
||||
* H2C (firmware) commands differ between the older generation chips
|
||||
* 8188[cr]u, 819[12]cu, and 8723au, and the more recent chips 8723bu,
|
||||
* 8192[de]u, 8192eu, and 8812.
|
||||
*/
|
||||
enum h2c_cmd_8723a {
|
||||
H2C_SET_POWER_MODE = 1,
|
||||
H2C_JOIN_BSS_REPORT = 2,
|
||||
H2C_SET_RSSI = 5,
|
||||
H2C_SET_RATE_MASK = (6 | H2C_EXT),
|
||||
};
|
||||
|
||||
enum h2c_cmd_8723b {
|
||||
/*
|
||||
* Common Class: 000
|
||||
*/
|
||||
H2C_8723B_RSVD_PAGE = 0x00,
|
||||
H2C_8723B_MEDIA_STATUS_RPT = 0x01,
|
||||
H2C_8723B_SCAN_ENABLE = 0x02,
|
||||
H2C_8723B_KEEP_ALIVE = 0x03,
|
||||
H2C_8723B_DISCON_DECISION = 0x04,
|
||||
H2C_8723B_PSD_OFFLOAD = 0x05,
|
||||
H2C_8723B_AP_OFFLOAD = 0x08,
|
||||
H2C_8723B_BCN_RSVDPAGE = 0x09,
|
||||
H2C_8723B_PROBERSP_RSVDPAGE = 0x0A,
|
||||
H2C_8723B_FCS_RSVDPAGE = 0x10,
|
||||
H2C_8723B_FCS_INFO = 0x11,
|
||||
H2C_8723B_AP_WOW_GPIO_CTRL = 0x13,
|
||||
|
||||
/*
|
||||
* PoweSave Class: 001
|
||||
*/
|
||||
H2C_8723B_SET_PWR_MODE = 0x20,
|
||||
H2C_8723B_PS_TUNING_PARA = 0x21,
|
||||
H2C_8723B_PS_TUNING_PARA2 = 0x22,
|
||||
H2C_8723B_P2P_LPS_PARAM = 0x23,
|
||||
H2C_8723B_P2P_PS_OFFLOAD = 0x24,
|
||||
H2C_8723B_PS_SCAN_ENABLE = 0x25,
|
||||
H2C_8723B_SAP_PS_ = 0x26,
|
||||
H2C_8723B_INACTIVE_PS_ = 0x27,
|
||||
H2C_8723B_FWLPS_IN_IPS_ = 0x28,
|
||||
|
||||
/*
|
||||
* Dynamic Mechanism Class: 010
|
||||
*/
|
||||
H2C_8723B_MACID_CFG_RAID = 0x40,
|
||||
H2C_8723B_TXBF = 0x41,
|
||||
H2C_8723B_RSSI_SETTING = 0x42,
|
||||
H2C_8723B_AP_REQ_TXRPT = 0x43,
|
||||
H2C_8723B_INIT_RATE_COLLECT = 0x44,
|
||||
|
||||
/*
|
||||
* BT Class: 011
|
||||
*/
|
||||
H2C_8723B_B_TYPE_TDMA = 0x60,
|
||||
H2C_8723B_BT_INFO = 0x61,
|
||||
H2C_8723B_FORCE_BT_TXPWR = 0x62,
|
||||
H2C_8723B_BT_IGNORE_WLANACT = 0x63,
|
||||
H2C_8723B_DAC_SWING_VALUE = 0x64,
|
||||
H2C_8723B_ANT_SEL_RSV = 0x65,
|
||||
H2C_8723B_WL_OPMODE = 0x66,
|
||||
H2C_8723B_BT_MP_OPER = 0x67,
|
||||
H2C_8723B_BT_CONTROL = 0x68,
|
||||
H2C_8723B_BT_WIFI_CTRL = 0x69,
|
||||
H2C_8723B_BT_FW_PATCH = 0x6a,
|
||||
H2C_8723B_BT_WLAN_CALIBRATION = 0x6d,
|
||||
H2C_8723B_BT_GRANT = 0x6e,
|
||||
|
||||
/*
|
||||
* WOWLAN Class: 100
|
||||
*/
|
||||
H2C_8723B_WOWLAN = 0x80,
|
||||
H2C_8723B_REMOTE_WAKE_CTRL = 0x81,
|
||||
H2C_8723B_AOAC_GLOBAL_INFO = 0x82,
|
||||
H2C_8723B_AOAC_RSVD_PAGE = 0x83,
|
||||
H2C_8723B_AOAC_RSVD_PAGE2 = 0x84,
|
||||
H2C_8723B_D0_SCAN_OFFLOAD_CTRL = 0x85,
|
||||
H2C_8723B_D0_SCAN_OFFLOAD_INFO = 0x86,
|
||||
H2C_8723B_CHNL_SWITCH_OFFLOAD = 0x87,
|
||||
|
||||
H2C_8723B_RESET_TSF = 0xC0,
|
||||
};
|
||||
|
||||
|
||||
struct h2c_cmd {
|
||||
union {
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 data[5];
|
||||
u8 data[7];
|
||||
} __packed cmd;
|
||||
struct {
|
||||
__le32 data;
|
||||
__le16 ext;
|
||||
} __packed raw;
|
||||
struct {
|
||||
__le32 data;
|
||||
__le32 ext;
|
||||
} __packed raw_wide;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 data;
|
||||
u8 pad[4];
|
||||
} __packed joinbss;
|
||||
struct {
|
||||
u8 cmd;
|
||||
|
@ -559,6 +956,182 @@ struct h2c_cmd {
|
|||
u8 arg;
|
||||
__le16 mask_lo;
|
||||
} __packed ramask;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 parm;
|
||||
u8 macid;
|
||||
u8 macid_end;
|
||||
} __packed media_status_rpt;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 macid;
|
||||
/*
|
||||
* [0:4] - RAID
|
||||
* [7] - SGI
|
||||
*/
|
||||
u8 data1;
|
||||
/*
|
||||
* [0:1] - Bandwidth
|
||||
* [3] - No Update
|
||||
* [4:5] - VHT enable
|
||||
* [6] - DISPT
|
||||
* [7] - DISRA
|
||||
*/
|
||||
u8 data2;
|
||||
u8 ramask0;
|
||||
u8 ramask1;
|
||||
u8 ramask2;
|
||||
u8 ramask3;
|
||||
} __packed b_macid_cfg;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 data1;
|
||||
u8 data2;
|
||||
u8 data3;
|
||||
u8 data4;
|
||||
u8 data5;
|
||||
} __packed b_type_dma;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 data;
|
||||
} __packed bt_info;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 operreq;
|
||||
u8 opcode;
|
||||
u8 data;
|
||||
u8 addr;
|
||||
} __packed bt_mp_oper;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 data;
|
||||
} __packed bt_wlan_calibration;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 data;
|
||||
} __packed ignore_wlan;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 ant_inverse;
|
||||
u8 int_switch_type;
|
||||
} __packed ant_sel_rsv;
|
||||
struct {
|
||||
u8 cmd;
|
||||
u8 data;
|
||||
} __packed bt_grant;
|
||||
};
|
||||
};
|
||||
|
||||
enum c2h_evt_8723b {
|
||||
C2H_8723B_DEBUG = 0,
|
||||
C2H_8723B_TSF = 1,
|
||||
C2H_8723B_AP_RPT_RSP = 2,
|
||||
C2H_8723B_CCX_TX_RPT = 3,
|
||||
C2H_8723B_BT_RSSI = 4,
|
||||
C2H_8723B_BT_OP_MODE = 5,
|
||||
C2H_8723B_EXT_RA_RPT = 6,
|
||||
C2H_8723B_BT_INFO = 9,
|
||||
C2H_8723B_HW_INFO_EXCH = 0x0a,
|
||||
C2H_8723B_BT_MP_INFO = 0x0b,
|
||||
C2H_8723B_RA_REPORT = 0x0c,
|
||||
C2H_8723B_FW_DEBUG = 0xff,
|
||||
};
|
||||
|
||||
enum bt_info_src_8723b {
|
||||
BT_INFO_SRC_8723B_WIFI_FW = 0x0,
|
||||
BT_INFO_SRC_8723B_BT_RSP = 0x1,
|
||||
BT_INFO_SRC_8723B_BT_ACTIVE_SEND = 0x2,
|
||||
};
|
||||
|
||||
enum bt_mp_oper_opcode_8723b {
|
||||
BT_MP_OP_GET_BT_VERSION = 0x00,
|
||||
BT_MP_OP_RESET = 0x01,
|
||||
BT_MP_OP_TEST_CTRL = 0x02,
|
||||
BT_MP_OP_SET_BT_MODE = 0x03,
|
||||
BT_MP_OP_SET_CHNL_TX_GAIN = 0x04,
|
||||
BT_MP_OP_SET_PKT_TYPE_LEN = 0x05,
|
||||
BT_MP_OP_SET_PKT_CNT_L_PL_TYPE = 0x06,
|
||||
BT_MP_OP_SET_PKT_CNT_H_PKT_INTV = 0x07,
|
||||
BT_MP_OP_SET_PKT_HEADER = 0x08,
|
||||
BT_MP_OP_SET_WHITENCOEFF = 0x09,
|
||||
BT_MP_OP_SET_BD_ADDR_L = 0x0a,
|
||||
BT_MP_OP_SET_BD_ADDR_H = 0x0b,
|
||||
BT_MP_OP_WRITE_REG_ADDR = 0x0c,
|
||||
BT_MP_OP_WRITE_REG_VALUE = 0x0d,
|
||||
BT_MP_OP_GET_BT_STATUS = 0x0e,
|
||||
BT_MP_OP_GET_BD_ADDR_L = 0x0f,
|
||||
BT_MP_OP_GET_BD_ADDR_H = 0x10,
|
||||
BT_MP_OP_READ_REG = 0x11,
|
||||
BT_MP_OP_SET_TARGET_BD_ADDR_L = 0x12,
|
||||
BT_MP_OP_SET_TARGET_BD_ADDR_H = 0x13,
|
||||
BT_MP_OP_SET_TX_POWER_CALIBRATION = 0x14,
|
||||
BT_MP_OP_GET_RX_PKT_CNT_L = 0x15,
|
||||
BT_MP_OP_GET_RX_PKT_CNT_H = 0x16,
|
||||
BT_MP_OP_GET_RX_ERROR_BITS_L = 0x17,
|
||||
BT_MP_OP_GET_RX_ERROR_BITS_H = 0x18,
|
||||
BT_MP_OP_GET_RSSI = 0x19,
|
||||
BT_MP_OP_GET_CFO_HDR_QUALITY_L = 0x1a,
|
||||
BT_MP_OP_GET_CFO_HDR_QUALITY_H = 0x1b,
|
||||
BT_MP_OP_GET_TARGET_BD_ADDR_L = 0x1c,
|
||||
BT_MP_OP_GET_TARGET_BD_ADDR_H = 0x1d,
|
||||
BT_MP_OP_GET_AFH_MAP_L = 0x1e,
|
||||
BT_MP_OP_GET_AFH_MAP_M = 0x1f,
|
||||
BT_MP_OP_GET_AFH_MAP_H = 0x20,
|
||||
BT_MP_OP_GET_AFH_STATUS = 0x21,
|
||||
BT_MP_OP_SET_TRACKING_INTERVAL = 0x22,
|
||||
BT_MP_OP_SET_THERMAL_METER = 0x23,
|
||||
BT_MP_OP_ENABLE_CFO_TRACKING = 0x24,
|
||||
};
|
||||
|
||||
struct rtl8723bu_c2h {
|
||||
u8 id;
|
||||
u8 seq;
|
||||
union {
|
||||
struct {
|
||||
u8 payload[0];
|
||||
} __packed raw;
|
||||
struct {
|
||||
u8 ext_id;
|
||||
u8 status:4;
|
||||
u8 retlen:4;
|
||||
u8 opcode_ver:4;
|
||||
u8 req_num:4;
|
||||
u8 payload[2];
|
||||
} __packed bt_mp_info;
|
||||
struct {
|
||||
u8 response_source:4;
|
||||
u8 dummy0_0:4;
|
||||
|
||||
u8 bt_info;
|
||||
|
||||
u8 retry_count:4;
|
||||
u8 dummy2_0:1;
|
||||
u8 bt_page:1;
|
||||
u8 tx_rx_mask:1;
|
||||
u8 dummy2_2:1;
|
||||
|
||||
u8 rssi;
|
||||
|
||||
u8 basic_rate:1;
|
||||
u8 bt_has_reset:1;
|
||||
u8 dummy4_1:1;;
|
||||
u8 ignore_wlan:1;
|
||||
u8 auto_report:1;
|
||||
u8 dummy4_2:3;
|
||||
|
||||
u8 a4;
|
||||
u8 a5;
|
||||
} __packed bt_info;
|
||||
struct {
|
||||
u8 rate:7;
|
||||
u8 dummy0_0:1;
|
||||
u8 macid;
|
||||
u8 ldpc:1;
|
||||
u8 txbf:1;
|
||||
u8 noisy_state:1;
|
||||
u8 dummy2_0:5;
|
||||
u8 dummy3_0;
|
||||
} __packed ra_report;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -582,19 +1155,28 @@ struct rtl8xxxu_priv {
|
|||
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
char chip_name[8];
|
||||
u8 cck_tx_power_index_A[3]; /* 0x10 */
|
||||
u8 cck_tx_power_index_B[3];
|
||||
u8 ht40_1s_tx_power_index_A[3]; /* 0x16 */
|
||||
u8 ht40_1s_tx_power_index_B[3];
|
||||
char chip_vendor[8];
|
||||
u8 cck_tx_power_index_A[RTL8XXXU_MAX_CHANNEL_GROUPS];
|
||||
u8 cck_tx_power_index_B[RTL8XXXU_MAX_CHANNEL_GROUPS];
|
||||
u8 ht40_1s_tx_power_index_A[RTL8XXXU_MAX_CHANNEL_GROUPS];
|
||||
u8 ht40_1s_tx_power_index_B[RTL8XXXU_MAX_CHANNEL_GROUPS];
|
||||
/*
|
||||
* The following entries are half-bytes split as:
|
||||
* bits 0-3: path A, bits 4-7: path B, all values 4 bits signed
|
||||
*/
|
||||
struct rtl8723au_idx ht40_2s_tx_power_index_diff[3];
|
||||
struct rtl8723au_idx ht20_tx_power_index_diff[3];
|
||||
struct rtl8723au_idx ofdm_tx_power_index_diff[3];
|
||||
struct rtl8723au_idx ht40_max_power_offset[3];
|
||||
struct rtl8723au_idx ht20_max_power_offset[3];
|
||||
struct rtl8723au_idx ht40_2s_tx_power_index_diff[
|
||||
RTL8723A_CHANNEL_GROUPS];
|
||||
struct rtl8723au_idx ht20_tx_power_index_diff[RTL8723A_CHANNEL_GROUPS];
|
||||
struct rtl8723au_idx ofdm_tx_power_index_diff[RTL8723A_CHANNEL_GROUPS];
|
||||
struct rtl8723au_idx ht40_max_power_offset[RTL8723A_CHANNEL_GROUPS];
|
||||
struct rtl8723au_idx ht20_max_power_offset[RTL8723A_CHANNEL_GROUPS];
|
||||
/*
|
||||
* Newer generation chips only keep power diffs per TX count,
|
||||
* not per channel group.
|
||||
*/
|
||||
struct rtl8723au_idx ofdm_tx_power_diff[RTL8723B_TX_COUNT];
|
||||
struct rtl8723au_idx ht20_tx_power_diff[RTL8723B_TX_COUNT];
|
||||
struct rtl8723au_idx ht40_tx_power_diff[RTL8723B_TX_COUNT];
|
||||
u32 chip_cut:4;
|
||||
u32 rom_rev:4;
|
||||
u32 is_multi_func:1;
|
||||
|
@ -604,19 +1186,20 @@ struct rtl8xxxu_priv {
|
|||
u32 has_gps:1;
|
||||
u32 hi_pa:1;
|
||||
u32 vendor_umc:1;
|
||||
u32 vendor_smic:1;
|
||||
u32 has_polarity_ctrl:1;
|
||||
u32 has_eeprom:1;
|
||||
u32 boot_eeprom:1;
|
||||
u32 usb_interrupts:1;
|
||||
u32 ep_tx_high_queue:1;
|
||||
u32 ep_tx_normal_queue:1;
|
||||
u32 ep_tx_low_queue:1;
|
||||
u32 path_a_hi_power:1;
|
||||
u32 path_a_rf_paths:4;
|
||||
u32 has_xtalk:1;
|
||||
u8 xtalk;
|
||||
unsigned int pipe_interrupt;
|
||||
unsigned int pipe_in;
|
||||
unsigned int pipe_out[TXDESC_QUEUE_MAX];
|
||||
u8 out_ep[RTL8XXXU_OUT_ENDPOINTS];
|
||||
u8 path_a_ig_value;
|
||||
u8 ep_tx_count;
|
||||
u8 rf_paths;
|
||||
u8 rx_paths;
|
||||
|
@ -643,9 +1226,11 @@ struct rtl8xxxu_priv {
|
|||
u8 val8;
|
||||
} usb_buf;
|
||||
union {
|
||||
u8 raw[EFUSE_MAP_LEN_8723A];
|
||||
u8 raw[EFUSE_MAP_LEN];
|
||||
struct rtl8723au_efuse efuse8723;
|
||||
struct rtl8723bu_efuse efuse8723bu;
|
||||
struct rtl8192cu_efuse efuse8192;
|
||||
struct rtl8192eu_efuse efuse8192eu;
|
||||
} efuse_wifi;
|
||||
u32 adda_backup[RTL8XXXU_ADDA_REGS];
|
||||
u32 mac_backup[RTL8XXXU_MAC_REGS];
|
||||
|
@ -672,5 +1257,31 @@ struct rtl8xxxu_fileops {
|
|||
int (*parse_efuse) (struct rtl8xxxu_priv *priv);
|
||||
int (*load_firmware) (struct rtl8xxxu_priv *priv);
|
||||
int (*power_on) (struct rtl8xxxu_priv *priv);
|
||||
void (*power_off) (struct rtl8xxxu_priv *priv);
|
||||
void (*reset_8051) (struct rtl8xxxu_priv *priv);
|
||||
int (*llt_init) (struct rtl8xxxu_priv *priv, u8 last_tx_page);
|
||||
void (*phy_init_antenna_selection) (struct rtl8xxxu_priv *priv);
|
||||
void (*phy_iq_calibrate) (struct rtl8xxxu_priv *priv);
|
||||
void (*config_channel) (struct ieee80211_hw *hw);
|
||||
int (*parse_rx_desc) (struct rtl8xxxu_priv *priv, struct sk_buff *skb,
|
||||
struct ieee80211_rx_status *rx_status);
|
||||
void (*init_aggregation) (struct rtl8xxxu_priv *priv);
|
||||
void (*init_statistics) (struct rtl8xxxu_priv *priv);
|
||||
void (*enable_rf) (struct rtl8xxxu_priv *priv);
|
||||
void (*disable_rf) (struct rtl8xxxu_priv *priv);
|
||||
void (*set_tx_power) (struct rtl8xxxu_priv *priv, int channel,
|
||||
bool ht40);
|
||||
void (*update_rate_mask) (struct rtl8xxxu_priv *priv,
|
||||
u32 ramask, int sgi);
|
||||
void (*report_connect) (struct rtl8xxxu_priv *priv,
|
||||
u8 macid, bool connect);
|
||||
int writeN_block_size;
|
||||
u16 mbox_ext_reg;
|
||||
char mbox_ext_width;
|
||||
char tx_desc_size;
|
||||
char has_s0s1;
|
||||
u32 adda_1t_init;
|
||||
u32 adda_1t_path_on;
|
||||
u32 adda_2t_path_on_a;
|
||||
u32 adda_2t_path_on_b;
|
||||
};
|
||||
|
|
|
@ -70,8 +70,11 @@
|
|||
|
||||
#define REG_EE_VPD 0x000c
|
||||
#define REG_AFE_MISC 0x0010
|
||||
#define AFE_MISC_WL_XTAL_CTRL BIT(6)
|
||||
|
||||
#define REG_SPS0_CTRL 0x0011
|
||||
#define REG_SPS_OCP_CFG 0x0018
|
||||
#define REG_8192E_LDOV12_CTRL 0x0014
|
||||
#define REG_RSV_CTRL 0x001c
|
||||
|
||||
#define REG_RF_CTRL 0x001f
|
||||
|
@ -132,6 +135,8 @@
|
|||
#define EFUSE_ACCESS_DISABLE 0x00 /* RTL8723 only */
|
||||
|
||||
#define REG_PWR_DATA 0x0038
|
||||
#define PWR_DATA_EEPRPAD_RFE_CTRL_EN BIT(11)
|
||||
|
||||
#define REG_CAL_TIMER 0x003c
|
||||
#define REG_ACLK_MON 0x003e
|
||||
#define REG_GPIO_MUXCFG 0x0040
|
||||
|
@ -139,7 +144,10 @@
|
|||
#define REG_MAC_PINMUX_CFG 0x0043
|
||||
#define REG_GPIO_PIN_CTRL 0x0044
|
||||
#define REG_GPIO_INTM 0x0048
|
||||
#define GPIO_INTM_EDGE_TRIG_IRQ BIT(9)
|
||||
|
||||
#define REG_LEDCFG0 0x004c
|
||||
#define LEDCFG0_DPDT_SELECT BIT(23)
|
||||
#define REG_LEDCFG1 0x004d
|
||||
#define REG_LEDCFG2 0x004e
|
||||
#define LEDCFG2_DPDT_SELECT BIT(7)
|
||||
|
@ -153,6 +161,12 @@
|
|||
#define REG_GPIO_PIN_CTRL_2 0x0060
|
||||
/* RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. */
|
||||
#define REG_GPIO_IO_SEL_2 0x0062
|
||||
#define GPIO_IO_SEL_2_GPIO09_INPUT BIT(1)
|
||||
#define GPIO_IO_SEL_2_GPIO09_IRQ BIT(9)
|
||||
|
||||
/* RTL8723B */
|
||||
#define REG_PAD_CTRL1 0x0064
|
||||
#define PAD_CTRL1_SW_DPDT_SEL_DATA BIT(0)
|
||||
|
||||
/* RTL8723 only WIFI/BT/GPS Multi-Function control source. */
|
||||
#define REG_MULTI_FUNC_CTRL 0x0068
|
||||
|
@ -178,6 +192,8 @@
|
|||
control */
|
||||
#define MULTI_GPS_FUNC_EN BIT(22) /* GPS function enable */
|
||||
|
||||
#define REG_LDO_SW_CTRL 0x007c /* 8192eu */
|
||||
|
||||
#define REG_MCU_FW_DL 0x0080
|
||||
#define MCU_FW_DL_ENABLE BIT(0)
|
||||
#define MCU_FW_DL_READY BIT(1)
|
||||
|
@ -193,6 +209,12 @@
|
|||
#define REG_HMBOX_EXT_1 0x008a
|
||||
#define REG_HMBOX_EXT_2 0x008c
|
||||
#define REG_HMBOX_EXT_3 0x008e
|
||||
/* Interrupt registers for 8192e/8723bu/8812 */
|
||||
#define REG_HIMR0 0x00b0
|
||||
#define REG_HISR0 0x00b4
|
||||
#define REG_HIMR1 0x00b8
|
||||
#define REG_HISR1 0x00bc
|
||||
|
||||
/* Host suspend counter on FPGA platform */
|
||||
#define REG_HOST_SUSP_CNT 0x00bc
|
||||
/* Efuse access protection for RTL8723 */
|
||||
|
@ -222,9 +244,14 @@
|
|||
#define SYS_CFG_CHIP_VER (BIT(12) | BIT(13) | BIT(14) | BIT(15))
|
||||
#define SYS_CFG_BT_FUNC BIT(16)
|
||||
#define SYS_CFG_VENDOR_ID BIT(19)
|
||||
#define SYS_CFG_VENDOR_EXT_MASK (BIT(18) | BIT(19))
|
||||
#define SYS_CFG_VENDOR_ID_TSMC 0
|
||||
#define SYS_CFG_VENDOR_ID_SMIC BIT(18)
|
||||
#define SYS_CFG_VENDOR_ID_UMC BIT(19)
|
||||
#define SYS_CFG_PAD_HWPD_IDN BIT(22)
|
||||
#define SYS_CFG_TRP_VAUX_EN BIT(23)
|
||||
#define SYS_CFG_TRP_BT_EN BIT(24)
|
||||
#define SYS_CFG_SPS_LDO_SEL BIT(24) /* 8192eu */
|
||||
#define SYS_CFG_BD_PKG_SEL BIT(25)
|
||||
#define SYS_CFG_BD_HCI_SEL BIT(26)
|
||||
#define SYS_CFG_TYPE_ID BIT(27)
|
||||
|
@ -257,6 +284,8 @@
|
|||
#define GPIO_USB_SUSEN BIT(23)
|
||||
#define GPIO_RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28))
|
||||
|
||||
#define REG_SYS_CFG2 0x00fc /* 8192eu */
|
||||
|
||||
/* 0x0100 ~ 0x01FF MACTOP General Configuration */
|
||||
#define REG_CR 0x0100
|
||||
#define CR_HCI_TXDMA_ENABLE BIT(0)
|
||||
|
@ -289,6 +318,7 @@
|
|||
#define PBP_PAGE_SIZE_1024 0x4
|
||||
|
||||
#define REG_TRXDMA_CTRL 0x010c
|
||||
#define TRXDMA_CTRL_RXDMA_AGG_EN BIT(2)
|
||||
#define TRXDMA_CTRL_VOQ_SHIFT 4
|
||||
#define TRXDMA_CTRL_VIQ_SHIFT 6
|
||||
#define TRXDMA_CTRL_BEQ_SHIFT 8
|
||||
|
@ -323,6 +353,8 @@
|
|||
#define REG_MBIST_DONE 0x0178
|
||||
#define REG_MBIST_FAIL 0x017c
|
||||
#define REG_C2HEVT_MSG_NORMAL 0x01a0
|
||||
/* 8192EU/8723BU/8812 */
|
||||
#define REG_C2HEVT_CMD_ID_8723B 0x01ae
|
||||
#define REG_C2HEVT_CLEAR 0x01af
|
||||
#define REG_C2HEVT_MSG_TEST 0x01b8
|
||||
#define REG_MCUTST_1 0x01c0
|
||||
|
@ -357,16 +389,29 @@
|
|||
#define REG_FIFOPAGE 0x0204
|
||||
#define REG_TDECTRL 0x0208
|
||||
#define REG_TXDMA_OFFSET_CHK 0x020c
|
||||
#define TXDMA_OFFSET_DROP_DATA_EN BIT(9)
|
||||
#define REG_TXDMA_STATUS 0x0210
|
||||
#define REG_RQPN_NPQ 0x0214
|
||||
#define RQPN_NPQ_SHIFT 0
|
||||
#define RQPN_EPQ_SHIFT 16
|
||||
|
||||
#define REG_AUTO_LLT 0x0224
|
||||
#define AUTO_LLT_INIT_LLT BIT(16)
|
||||
|
||||
#define REG_DWBCN1_CTRL_8723B 0x0228
|
||||
|
||||
/* 0x0280 ~ 0x02FF RXDMA Configuration */
|
||||
#define REG_RXDMA_AGG_PG_TH 0x0280
|
||||
#define RXDMA_USB_AGG_ENABLE BIT(31)
|
||||
#define REG_RXPKT_NUM 0x0284
|
||||
#define RXPKT_NUM_RXDMA_IDLE BIT(17)
|
||||
#define RXPKT_NUM_RW_RELEASE_EN BIT(18)
|
||||
#define REG_RXDMA_STATUS 0x0288
|
||||
|
||||
/* Presumably only found on newer chips such as 8723bu */
|
||||
#define REG_RX_DMA_CTRL_8723B 0x0286
|
||||
#define REG_RXDMA_PRO_8723B 0x0290
|
||||
|
||||
#define REG_RF_BB_CMD_ADDR 0x02c0
|
||||
#define REG_RF_BB_CMD_DATA 0x02c4
|
||||
|
||||
|
@ -438,20 +483,26 @@
|
|||
#define REG_ARFR1 0x0448
|
||||
#define REG_ARFR2 0x044c
|
||||
#define REG_ARFR3 0x0450
|
||||
#define REG_AMPDU_MAX_TIME_8723B 0x0456
|
||||
#define REG_AGGLEN_LMT 0x0458
|
||||
#define REG_AMPDU_MIN_SPACE 0x045c
|
||||
#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045d
|
||||
#define REG_FAST_EDCA_CTRL 0x0460
|
||||
#define REG_RD_RESP_PKT_TH 0x0463
|
||||
#define REG_INIRTS_RATE_SEL 0x0480
|
||||
/* 8723bu */
|
||||
#define REG_DATA_SUBCHANNEL 0x0483
|
||||
/* 8723au */
|
||||
#define REG_INIDATA_RATE_SEL 0x0484
|
||||
|
||||
#define REG_POWER_STATUS 0x04a4
|
||||
#define REG_POWER_STAGE1 0x04b4
|
||||
#define REG_POWER_STAGE2 0x04b8
|
||||
#define REG_AMPDU_BURST_MODE_8723B 0x04bc
|
||||
#define REG_PKT_VO_VI_LIFE_TIME 0x04c0
|
||||
#define REG_PKT_BE_BK_LIFE_TIME 0x04c2
|
||||
#define REG_STBC_SETTING 0x04c4
|
||||
#define REG_HT_SINGLE_AMPDU_8723B 0x04c7
|
||||
#define REG_PROT_MODE_CTRL 0x04c8
|
||||
#define REG_MAX_AGGR_NUM 0x04ca
|
||||
#define REG_RTS_MAX_AGGR_NUM 0x04cb
|
||||
|
@ -463,6 +514,8 @@
|
|||
#define REG_PKT_LOSE_RPT 0x04e1
|
||||
#define REG_PTCL_ERR_STATUS 0x04e2
|
||||
#define REG_TX_REPORT_CTRL 0x04ec
|
||||
#define TX_REPORT_CTRL_TIMER_ENABLE BIT(1)
|
||||
|
||||
#define REG_TX_REPORT_TIME 0x04f0
|
||||
#define REG_DUMMY 0x04fc
|
||||
|
||||
|
@ -516,6 +569,7 @@
|
|||
#define BEACON_DMA_ATIME_INT_TIME 2
|
||||
|
||||
#define REG_ATIMWND 0x055a
|
||||
#define REG_USTIME_TSF_8723B 0x055c
|
||||
#define REG_BCN_MAX_ERR 0x055d
|
||||
#define REG_RXTSF_OFFSET_CCK 0x055e
|
||||
#define REG_RXTSF_OFFSET_OFDM 0x055f
|
||||
|
@ -628,6 +682,10 @@
|
|||
#define REG_FWDLY 0x0661
|
||||
#define REG_RXERR_RPT 0x0664
|
||||
#define REG_WMAC_TRXPTCL_CTL 0x0668
|
||||
#define WMAC_TRXPTCL_CTL_BW_MASK (BIT(7) | BIT(8))
|
||||
#define WMAC_TRXPTCL_CTL_BW_20 0
|
||||
#define WMAC_TRXPTCL_CTL_BW_40 BIT(7)
|
||||
#define WMAC_TRXPTCL_CTL_BW_80 BIT(8)
|
||||
|
||||
/* Security */
|
||||
#define REG_CAM_CMD 0x0670
|
||||
|
@ -672,12 +730,23 @@
|
|||
#define REG_BCN_PSR_RPT 0x06a8
|
||||
#define REG_CALB32K_CTRL 0x06ac
|
||||
#define REG_PKT_MON_CTRL 0x06b4
|
||||
#define REG_BT_COEX_TABLE 0x06c0
|
||||
#define REG_BT_COEX_TABLE1 0x06c0
|
||||
#define REG_BT_COEX_TABLE2 0x06c4
|
||||
#define REG_BT_COEX_TABLE3 0x06c8
|
||||
#define REG_BT_COEX_TABLE4 0x06cc
|
||||
#define REG_WMAC_RESP_TXINFO 0x06d8
|
||||
|
||||
#define REG_MACID1 0x0700
|
||||
#define REG_BSSID1 0x0708
|
||||
|
||||
/*
|
||||
* This seems to be 8723bu specific
|
||||
*/
|
||||
#define REG_BT_CONTROL_8723BU 0x0764
|
||||
#define BT_CONTROL_BT_GRANT BIT(12)
|
||||
|
||||
#define REG_WLAN_ACT_CONTROL_8723B 0x076e
|
||||
|
||||
#define REG_FPGA0_RF_MODE 0x0800
|
||||
#define FPGA_RF_MODE BIT(0)
|
||||
#define FPGA_RF_MODE_JAPAN BIT(1)
|
||||
|
@ -768,6 +837,11 @@
|
|||
#define REG_FPGA0_ANALOG3 0x0888
|
||||
#define REG_FPGA0_ANALOG4 0x088c
|
||||
|
||||
#define REG_NHM_TH9_TH10_8723B 0x0890
|
||||
#define REG_NHM_TIMER_8723B 0x0894
|
||||
#define REG_NHM_TH3_TO_TH0_8723B 0x0898
|
||||
#define REG_NHM_TH7_TO_TH4_8723B 0x089c
|
||||
|
||||
#define REG_FPGA0_XA_LSSI_READBACK 0x08a0 /* Tranceiver LSSI Readback */
|
||||
#define REG_FPGA0_XB_LSSI_READBACK 0x08a4
|
||||
#define REG_HSPI_XA_READBACK 0x08b8 /* Transceiver A HSPI read */
|
||||
|
@ -780,6 +854,7 @@
|
|||
#define REG_RFE_CTRL_ANTA_SRC 0x0930 /* 8723BU */
|
||||
#define REG_RFE_PATH_SELECT 0x0940 /* 8723BU */
|
||||
#define REG_RFE_BUFFER 0x0944 /* 8723BU */
|
||||
#define REG_S0S1_PATH_SWITCH 0x0948 /* 8723BU */
|
||||
|
||||
#define REG_CCK0_SYSTEM 0x0a00
|
||||
#define CCK0_SIDEBAND BIT(4)
|
||||
|
@ -803,6 +878,8 @@
|
|||
|
||||
#define REG_OFDM0_TR_MUX_PAR 0x0c08
|
||||
|
||||
#define REG_OFDM0_FA_RSTC 0x0c0c
|
||||
|
||||
#define REG_OFDM0_XA_RX_IQ_IMBALANCE 0x0c14
|
||||
#define REG_OFDM0_XB_RX_IQ_IMBALANCE 0x0c1c
|
||||
|
||||
|
@ -835,6 +912,9 @@
|
|||
|
||||
#define REG_OFDM0_RX_IQ_EXT_ANTA 0x0ca0
|
||||
|
||||
/* 8723bu */
|
||||
#define REG_OFDM0_TX_PSDO_NOISE_WEIGHT 0x0ce4
|
||||
|
||||
#define REG_OFDM1_LSTF 0x0d00
|
||||
#define OFDM_LSTF_PRIME_CH_LOW BIT(10)
|
||||
#define OFDM_LSTF_PRIME_CH_HIGH BIT(11)
|
||||
|
@ -993,6 +1073,10 @@
|
|||
#define RF6052_REG_MODE_AG 0x18 /* RF channel and BW switch */
|
||||
#define MODE_AG_CHANNEL_MASK 0x3ff
|
||||
#define MODE_AG_CHANNEL_20MHZ BIT(10)
|
||||
#define MODE_AG_BW_MASK (BIT(10) | BIT(11))
|
||||
#define MODE_AG_BW_20MHZ_8723B (BIT(10) | BIT(11))
|
||||
#define MODE_AG_BW_40MHZ_8723B BIT(10)
|
||||
#define MODE_AG_BW_80MHZ_8723B 0
|
||||
|
||||
#define RF6052_REG_TOP 0x19
|
||||
#define RF6052_REG_RX_G1 0x1a
|
||||
|
@ -1020,3 +1104,14 @@
|
|||
#define RF6052_REG_TXPA_G1 0x31 /* RF TX PA control */
|
||||
#define RF6052_REG_TXPA_G2 0x32 /* RF TX PA control */
|
||||
#define RF6052_REG_TXPA_G3 0x33 /* RF TX PA control */
|
||||
|
||||
/*
|
||||
* NextGen regs: 8723BU
|
||||
*/
|
||||
#define RF6052_REG_T_METER_8723B 0x42
|
||||
#define RF6052_REG_UNKNOWN_43 0x43
|
||||
#define RF6052_REG_UNKNOWN_55 0x55
|
||||
#define RF6052_REG_S0S1 0xb0
|
||||
#define RF6052_REG_UNKNOWN_DF 0xdf
|
||||
#define RF6052_REG_UNKNOWN_ED 0xed
|
||||
#define RF6052_REG_WE_LUT 0xef
|
||||
|
|
|
@ -345,6 +345,69 @@ static const struct file_operations dynamic_fw_traces_ops = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
|
||||
static ssize_t radar_debug_mode_write(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct wl1271 *wl = file->private_data;
|
||||
struct wl12xx_vif *wlvif;
|
||||
unsigned long value;
|
||||
int ret;
|
||||
|
||||
ret = kstrtoul_from_user(user_buf, count, 10, &value);
|
||||
if (ret < 0) {
|
||||
wl1271_warning("illegal radar_debug_mode value!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* valid values: 0/1 */
|
||||
if (!(value == 0 || value == 1)) {
|
||||
wl1271_warning("value is not in valid!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
wl->radar_debug_mode = value;
|
||||
|
||||
if (unlikely(wl->state != WLCORE_STATE_ON))
|
||||
goto out;
|
||||
|
||||
ret = wl1271_ps_elp_wakeup(wl);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
wl12xx_for_each_wlvif_ap(wl, wlvif) {
|
||||
wlcore_cmd_generic_cfg(wl, wlvif,
|
||||
WLCORE_CFG_FEATURE_RADAR_DEBUG,
|
||||
wl->radar_debug_mode, 0);
|
||||
}
|
||||
|
||||
wl1271_ps_elp_sleep(wl);
|
||||
out:
|
||||
mutex_unlock(&wl->mutex);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t radar_debug_mode_read(struct file *file,
|
||||
char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct wl1271 *wl = file->private_data;
|
||||
|
||||
return wl1271_format_buffer(userbuf, count, ppos,
|
||||
"%d\n", wl->radar_debug_mode);
|
||||
}
|
||||
|
||||
static const struct file_operations radar_debug_mode_ops = {
|
||||
.write = radar_debug_mode_write,
|
||||
.read = radar_debug_mode_read,
|
||||
.open = simple_open,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
#endif /* CFG80211_CERTIFICATION_ONUS */
|
||||
|
||||
int wl18xx_debugfs_add_files(struct wl1271 *wl,
|
||||
struct dentry *rootdir)
|
||||
{
|
||||
|
@ -510,6 +573,9 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl,
|
|||
|
||||
DEBUGFS_ADD(conf, moddir);
|
||||
DEBUGFS_ADD(radar_detection, moddir);
|
||||
#ifdef CONFIG_CFG80211_CERTIFICATION_ONUS
|
||||
DEBUGFS_ADD(radar_debug_mode, moddir);
|
||||
#endif
|
||||
DEBUGFS_ADD(dynamic_fw_traces, moddir);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -146,7 +146,8 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
|
|||
mbox->radar_channel,
|
||||
wl18xx_radar_type_decode(mbox->radar_type));
|
||||
|
||||
ieee80211_radar_detected(wl->hw);
|
||||
if (!wl->radar_debug_mode)
|
||||
ieee80211_radar_detected(wl->hw);
|
||||
}
|
||||
|
||||
if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
|
||||
|
|
|
@ -558,6 +558,11 @@ static int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (wl->radar_debug_mode)
|
||||
wlcore_cmd_generic_cfg(wl, wlvif,
|
||||
WLCORE_CFG_FEATURE_RADAR_DEBUG,
|
||||
wl->radar_debug_mode, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -5495,7 +5495,7 @@ static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
|
|||
{
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
struct wl1271 *wl = hw->priv;
|
||||
int channel, ret = 0;
|
||||
int channel, active_roc, ret = 0;
|
||||
|
||||
channel = ieee80211_frequency_to_channel(chan->center_freq);
|
||||
|
||||
|
@ -5508,9 +5508,9 @@ static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
|
|||
goto out;
|
||||
|
||||
/* return EBUSY if we can't ROC right now */
|
||||
if (WARN_ON(wl->roc_vif ||
|
||||
find_first_bit(wl->roc_map,
|
||||
WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES)) {
|
||||
active_roc = find_first_bit(wl->roc_map, WL12XX_MAX_ROLES);
|
||||
if (wl->roc_vif || active_roc < WL12XX_MAX_ROLES) {
|
||||
wl1271_warning("active roc on role %d", active_roc);
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -463,6 +463,7 @@ struct wl1271 {
|
|||
|
||||
/* the current dfs region */
|
||||
enum nl80211_dfs_regions dfs_region;
|
||||
bool radar_debug_mode;
|
||||
|
||||
/* size of the private FW status data */
|
||||
size_t fw_status_len;
|
||||
|
|
Загрузка…
Ссылка в новой задаче