mirror of https://gitee.com/openkylin/linux.git
Sencond batch of iwlwifi patches for 4.14
* Some more code moved to a new directory; * Fixes in LED handling; * Some FW API updates; * General fixes and cleanups here and there. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEF3LNfgb2BPWm68smoUecoho8xfoFAlmNUfgACgkQoUecoho8 xfrOcg//fJFNdMg628vzxZmWCA9r3kEho9Z9ryKBZ/zUtFb0cskUXBFzHolWsdqm YbqxNIFZpvSH5kDW1hlZyUabG6dzImirC1R486Csu/ZbbECEC31Kb6VRFSF0myix f6USH23u/j8okKChaQ0c82PLBrLQlQeRyRtuLJmW6q02zGDmv/2Ol1UFopfh7IkO FLB389Cfv83TwB1QJpcmdkmtbyRYhlBVSygJOTVO7pydxXCXxoFACBUEDevmSeVT RS1Iips19U/fUPIyi8El4DqQ+/wjmmsB4jqb5I8kUI6LUWdPeh260ofgRJ7WIG4A jPWXkAUBWGqCGHnetj+0F+586fX6zqBVHTXenOVN0pWaSt1VD9O9Xp+I3YQAn2LN AeMkA+fyKZ35+h9zWHG2DONficVR2HvGkyS3WsWdgLqA77ZQvLVRNPECBL8vdBlw b/1HUmd7QjwePgZOtr27/Vd9USyLVXFbOACuYJByPrd0VnyYgI2yALb/gmNNn3hZ vm7XrOwWJ9guPeugnOck8cxPx7337kiv+CsR3GUQdKIJ45bV68M3MUBvupxt6PaJ NGVY9qqSQVvW/dB5Yc53/J6s122ImUSMNbYAA1OiGGky1NUu76AmJZpeQCQiliwe NvTWJmRHQt7yjPeA+g8vWDASok468Lx4/Q3YZpW6EFf3TUzzknA= =PgZZ -----END PGP SIGNATURE----- Merge tag 'iwlwifi-next-for-kalle-2017-08-11' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next Sencond batch of iwlwifi patches for 4.14 * Some more code moved to a new directory; * Fixes in LED handling; * Some FW API updates; * General fixes and cleanups here and there.
This commit is contained in:
commit
3d6b2d4e36
|
@ -12,7 +12,7 @@ iwlwifi-$(CONFIG_IWLMVM) += cfg/7000.o cfg/8000.o cfg/9000.o cfg/a000.o
|
|||
iwlwifi-objs += iwl-trans.o
|
||||
iwlwifi-objs += fw/notif-wait.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o fw/dbg.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += fw/common_rx.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += fw/common_rx.o fw/nvm.o
|
||||
|
||||
iwlwifi-objs += $(iwlwifi-m)
|
||||
|
||||
|
|
|
@ -75,11 +75,14 @@
|
|||
#define IWL_A000_JF_FW_PRE "iwlwifi-Qu-a0-jf-b0-"
|
||||
#define IWL_A000_HR_FW_PRE "iwlwifi-Qu-a0-hr-a0-"
|
||||
#define IWL_A000_HR_CDB_FW_PRE "iwlwifi-QuIcp-z0-hrcdb-a0-"
|
||||
#define IWL_A000_HR_F0_FW_PRE "iwlwifi-QuQnj-f0-hr-a0-"
|
||||
|
||||
#define IWL_A000_HR_MODULE_FIRMWARE(api) \
|
||||
IWL_A000_HR_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_A000_JF_MODULE_FIRMWARE(api) \
|
||||
IWL_A000_JF_FW_PRE "-" __stringify(api) ".ucode"
|
||||
#define IWL_A000_HR_QNJ_MODULE_FIRMWARE(api) \
|
||||
IWL_A000_HR_F0_FW_PRE "-" __stringify(api) ".ucode"
|
||||
|
||||
#define NVM_HW_SECTION_NUM_FAMILY_A000 10
|
||||
|
||||
|
@ -168,5 +171,16 @@ const struct iwl_cfg iwla000_2ax_cfg_hr = {
|
|||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwla000_2ax_cfg_qnj_hr = {
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_HR_F0_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_A000_JF_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL_A000_HR_QNJ_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
|
||||
|
|
|
@ -311,11 +311,6 @@ enum {
|
|||
|
||||
/**
|
||||
* rate_n_flags Tx antenna masks
|
||||
* 4965 has 2 transmitters
|
||||
* 5100 has 1 transmitter B
|
||||
* 5150 has 1 transmitter A
|
||||
* 5300 has 3 transmitters
|
||||
* 5350 has 3 transmitters
|
||||
* bit14:16
|
||||
*/
|
||||
#define RATE_MCS_ANT_POS 14
|
||||
|
@ -1230,7 +1225,6 @@ struct iwl_rx_mpdu_res_start {
|
|||
*/
|
||||
|
||||
/*
|
||||
* 4965 uCode updates these Tx attempt count values in host DRAM.
|
||||
* Used for managing Tx retries when expecting block-acks.
|
||||
* Driver should set these fields to 0.
|
||||
*/
|
||||
|
@ -1540,7 +1534,7 @@ struct iwl_link_qual_general_params {
|
|||
/* Best single antenna to use for single stream (legacy, SISO). */
|
||||
u8 single_stream_ant_msk; /* LINK_QUAL_ANT_* */
|
||||
|
||||
/* Best antennas to use for MIMO (unused for 4965, assumes both). */
|
||||
/* Best antennas to use for MIMO */
|
||||
u8 dual_stream_ant_msk; /* LINK_QUAL_ANT_* */
|
||||
|
||||
/*
|
||||
|
|
|
@ -220,12 +220,6 @@ enum iwl_bt_ci_compliance {
|
|||
BT_CI_COMPLIANCE_BOTH = 3,
|
||||
}; /* BT_COEX_CI_COMPLIENCE_E_VER_1 */
|
||||
|
||||
#define IWL_COEX_IS_TTC_ON(_ttc_rrc_status, _phy_id) \
|
||||
(_ttc_rrc_status & BIT(_phy_id))
|
||||
|
||||
#define IWL_COEX_IS_RRC_ON(_ttc_rrc_status, _phy_id) \
|
||||
((_ttc_rrc_status >> 4) & BIT(_phy_id))
|
||||
|
||||
/**
|
||||
* struct iwl_bt_coex_profile_notif - notification about BT coex
|
||||
* @mbox_msg: message from BT to WiFi
|
||||
|
@ -234,7 +228,8 @@ enum iwl_bt_ci_compliance {
|
|||
* @primary_ch_lut: LUT used for primary channel &enum iwl_bt_coex_lut_type
|
||||
* @secondary_ch_lut: LUT used for secondary channel &enum iwl_bt_coex_lut_type
|
||||
* @bt_activity_grading: the activity of BT &enum iwl_bt_activity_grading
|
||||
* @ttc_rrc_status: is TTC or RRC enabled - one bit per PHY
|
||||
* @ttc_status: is TTC enabled - one bit per PHY
|
||||
* @rrc_status: is RRC enabled - one bit per PHY
|
||||
* @reserved: reserved
|
||||
*/
|
||||
struct iwl_bt_coex_profile_notif {
|
||||
|
@ -245,8 +240,9 @@ struct iwl_bt_coex_profile_notif {
|
|||
__le32 primary_ch_lut;
|
||||
__le32 secondary_ch_lut;
|
||||
__le32 bt_activity_grading;
|
||||
u8 ttc_rrc_status;
|
||||
u8 reserved[3];
|
||||
u8 ttc_status;
|
||||
u8 rrc_status;
|
||||
__le16 reserved;
|
||||
} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_4 */
|
||||
|
||||
#endif /* __iwl_fw_api_coex_h__ */
|
||||
|
|
|
@ -287,6 +287,11 @@ enum iwl_legacy_cmds {
|
|||
*/
|
||||
NON_QOS_TX_COUNTER_CMD = 0x2d,
|
||||
|
||||
/**
|
||||
* @LEDS_CMD: command is &struct iwl_led_cmd
|
||||
*/
|
||||
LEDS_CMD = 0x48,
|
||||
|
||||
/**
|
||||
* @LQ_CMD: using &struct iwl_lq_cmd
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __iwl_fw_api_led_h__
|
||||
#define __iwl_fw_api_led_h__
|
||||
|
||||
/**
|
||||
* struct iwl_led_cmd - LED switching command
|
||||
*
|
||||
* @status: LED status (on/off)
|
||||
*/
|
||||
struct iwl_led_cmd {
|
||||
__le32 status;
|
||||
} __packed; /* LEDS_CMD_API_S_VER_2 */
|
||||
|
||||
#endif /* __iwl_fw_api_led_h__ */
|
|
@ -421,7 +421,7 @@ enum iwl_tx_status {
|
|||
* occur if tx failed for this frame when it was a member of a previous
|
||||
* aggregation block). If rate scaling is used, retry count indicates the
|
||||
* rate table entry used for all frames in the new agg.
|
||||
*@ AGG_TX_STATE_SEQ_NUM_MSK: Command ID and sequence number of Tx command for
|
||||
* @AGG_TX_STATE_SEQ_NUM_MSK: Command ID and sequence number of Tx command for
|
||||
* this frame
|
||||
*
|
||||
* TODO: complete documentation
|
||||
|
@ -786,13 +786,20 @@ struct iwl_mac_beacon_cmd_v7 {
|
|||
struct ieee80211_hdr frame[0];
|
||||
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_7 */
|
||||
|
||||
enum iwl_mac_beacon_flags {
|
||||
IWL_MAC_BEACON_CCK = BIT(8),
|
||||
IWL_MAC_BEACON_ANT_A = BIT(9),
|
||||
IWL_MAC_BEACON_ANT_B = BIT(10),
|
||||
IWL_MAC_BEACON_ANT_C = BIT(11),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_mac_beacon_cmd - beacon template command with offloaded CSA
|
||||
* @byte_cnt: byte count of the beacon frame
|
||||
* @flags: for future use
|
||||
* @byte_cnt: byte count of the beacon frame.
|
||||
* @flags: least significant byte for rate code. The most significant byte
|
||||
* is &enum iwl_mac_beacon_flags.
|
||||
* @reserved: reserved
|
||||
* @template_id: currently equal to the mac context id of the coresponding
|
||||
* mac.
|
||||
* @template_id: currently equal to the mac context id of the coresponding mac.
|
||||
* @tim_idx: the offset of the tim IE in the beacon
|
||||
* @tim_size: the length of the tim IE
|
||||
* @ecsa_offset: offset to the ECSA IE if present
|
||||
|
@ -809,7 +816,7 @@ struct iwl_mac_beacon_cmd {
|
|||
__le32 ecsa_offset;
|
||||
__le32 csa_offset;
|
||||
struct ieee80211_hdr frame[0];
|
||||
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_8 */
|
||||
} __packed; /* BEACON_TEMPLATE_CMD_API_S_VER_9 */
|
||||
|
||||
struct iwl_beacon_notif {
|
||||
struct iwl_mvm_tx_resp beacon_notify_hdr;
|
||||
|
|
|
@ -545,11 +545,13 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
|||
struct iwl_fw_error_dump_data *dump_data;
|
||||
struct iwl_fw_error_dump_info *dump_info;
|
||||
struct iwl_fw_error_dump_mem *dump_mem;
|
||||
struct iwl_fw_error_dump_smem_cfg *dump_smem_cfg;
|
||||
struct iwl_fw_error_dump_trigger_desc *dump_trig;
|
||||
struct iwl_fw_dump_ptrs *fw_error_dump;
|
||||
struct scatterlist *sg_dump_data;
|
||||
u32 sram_len, sram_ofs;
|
||||
const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem = fwrt->fw->dbg_mem_tlv;
|
||||
struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg;
|
||||
u32 file_len, fifo_data_len = 0, prph_len = 0, radio_len = 0;
|
||||
u32 smem_len = fwrt->fw->n_dbg_mem_tlv ? 0 : fwrt->trans->cfg->smem_len;
|
||||
u32 sram2_len = fwrt->fw->n_dbg_mem_tlv ?
|
||||
|
@ -585,8 +587,6 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
|||
|
||||
/* reading RXF/TXF sizes */
|
||||
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) {
|
||||
struct iwl_fwrt_shared_mem_cfg *mem_cfg = &fwrt->smem_cfg;
|
||||
|
||||
fifo_data_len = 0;
|
||||
|
||||
/* Count RXF2 size */
|
||||
|
@ -675,7 +675,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
|||
}
|
||||
|
||||
file_len = sizeof(*dump_file) +
|
||||
sizeof(*dump_data) * 2 +
|
||||
sizeof(*dump_data) * 3 +
|
||||
sizeof(*dump_smem_cfg) +
|
||||
fifo_data_len +
|
||||
prph_len +
|
||||
radio_len +
|
||||
|
@ -706,8 +707,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
|||
|
||||
/* If we only want a monitor dump, reset the file length */
|
||||
if (monitor_dump_only) {
|
||||
file_len = sizeof(*dump_file) + sizeof(*dump_data) +
|
||||
sizeof(*dump_info);
|
||||
file_len = sizeof(*dump_file) + sizeof(*dump_data) * 2 +
|
||||
sizeof(*dump_info) + sizeof(*dump_smem_cfg);
|
||||
}
|
||||
|
||||
if (fwrt->dump.desc)
|
||||
|
@ -744,6 +745,33 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
|||
sizeof(dump_info->bus_human_readable));
|
||||
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
|
||||
/* Dump shared memory configuration */
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_CFG);
|
||||
dump_data->len = cpu_to_le32(sizeof(*dump_smem_cfg));
|
||||
dump_smem_cfg = (void *)dump_data->data;
|
||||
dump_smem_cfg->num_lmacs = cpu_to_le32(mem_cfg->num_lmacs);
|
||||
dump_smem_cfg->num_txfifo_entries =
|
||||
cpu_to_le32(mem_cfg->num_txfifo_entries);
|
||||
for (i = 0; i < MAX_NUM_LMAC; i++) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < TX_FIFO_MAX_NUM; j++)
|
||||
dump_smem_cfg->lmac[i].txfifo_size[j] =
|
||||
cpu_to_le32(mem_cfg->lmac[i].txfifo_size[j]);
|
||||
dump_smem_cfg->lmac[i].rxfifo1_size =
|
||||
cpu_to_le32(mem_cfg->lmac[i].rxfifo1_size);
|
||||
}
|
||||
dump_smem_cfg->rxfifo2_size = cpu_to_le32(mem_cfg->rxfifo2_size);
|
||||
dump_smem_cfg->internal_txfifo_addr =
|
||||
cpu_to_le32(mem_cfg->internal_txfifo_addr);
|
||||
for (i = 0; i < TX_FIFO_INTERNAL_MAX_NUM; i++) {
|
||||
dump_smem_cfg->internal_txfifo_size[i] =
|
||||
cpu_to_le32(mem_cfg->internal_txfifo_size[i]);
|
||||
}
|
||||
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
|
||||
/* We only dump the FIFOs if the FW is in error state */
|
||||
if (test_bit(STATUS_FW_ERROR, &fwrt->trans->status)) {
|
||||
iwl_fw_dump_fifos(fwrt, &dump_data);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Copyright(c) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 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) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -92,6 +94,9 @@
|
|||
* @IWL_FW_ERROR_DUMP_EXTERNAL: used only by external code utilities, and
|
||||
* for that reason is not in use in any other place in the Linux Wi-Fi
|
||||
* stack.
|
||||
* @IWL_FW_ERROR_DUMP_MEM_CFG: the addresses and sizes of fifos in the smem,
|
||||
* which we get from the fw after ALIVE. The content is structured as
|
||||
* &struct iwl_fw_error_dump_smem_cfg.
|
||||
*/
|
||||
enum iwl_fw_error_dump_type {
|
||||
/* 0 is deprecated */
|
||||
|
@ -110,6 +115,7 @@ enum iwl_fw_error_dump_type {
|
|||
IWL_FW_ERROR_DUMP_RADIO_REG = 13,
|
||||
IWL_FW_ERROR_DUMP_INTERNAL_TXF = 14,
|
||||
IWL_FW_ERROR_DUMP_EXTERNAL = 15, /* Do not move */
|
||||
IWL_FW_ERROR_DUMP_MEM_CFG = 16,
|
||||
|
||||
IWL_FW_ERROR_DUMP_MAX,
|
||||
};
|
||||
|
@ -208,6 +214,30 @@ struct iwl_fw_error_dump_fw_mon {
|
|||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
#define MAX_NUM_LMAC 2
|
||||
#define TX_FIFO_INTERNAL_MAX_NUM 6
|
||||
#define TX_FIFO_MAX_NUM 15
|
||||
/**
|
||||
* struct iwl_fw_error_dump_smem_cfg - Dump SMEM configuration
|
||||
* This must follow &struct iwl_fwrt_shared_mem_cfg.
|
||||
* @num_lmacs: number of lmacs
|
||||
* @num_txfifo_entries: number of tx fifos
|
||||
* @lmac: sizes of lmacs txfifos and rxfifo1
|
||||
* @rxfifo2_size: size of rxfifo2
|
||||
* @internal_txfifo_addr: address of internal tx fifo
|
||||
* @internal_txfifo_size: size of internal tx fifo
|
||||
*/
|
||||
struct iwl_fw_error_dump_smem_cfg {
|
||||
__le32 num_lmacs;
|
||||
__le32 num_txfifo_entries;
|
||||
struct {
|
||||
__le32 txfifo_size[TX_FIFO_MAX_NUM];
|
||||
__le32 rxfifo1_size;
|
||||
} lmac[MAX_NUM_LMAC];
|
||||
__le32 rxfifo2_size;
|
||||
__le32 internal_txfifo_addr;
|
||||
__le32 internal_txfifo_size[TX_FIFO_INTERNAL_MAX_NUM];
|
||||
} __packed;
|
||||
/**
|
||||
* struct iwl_fw_error_dump_prph - periphery registers data
|
||||
* @prph_start: address of the first register in this chunk
|
||||
|
|
|
@ -260,6 +260,7 @@ enum iwl_ucode_tlv_api {
|
|||
IWL_UCODE_TLV_API_STA_TYPE = (__force iwl_ucode_tlv_api_t)30,
|
||||
IWL_UCODE_TLV_API_NAN2_VER2 = (__force iwl_ucode_tlv_api_t)31,
|
||||
/* API Set 1 */
|
||||
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34,
|
||||
IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35,
|
||||
|
||||
NUM_IWL_UCODE_TLV_API
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include "iwl-drv.h"
|
||||
#include "runtime.h"
|
||||
#include "fw/api/nvm-reg.h"
|
||||
#include "fw/api/commands.h"
|
||||
#include "iwl-nvm-parse.h"
|
||||
|
||||
struct iwl_nvm_data *iwl_fw_get_nvm(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
struct iwl_nvm_get_info cmd = {};
|
||||
struct iwl_nvm_get_info_rsp *rsp;
|
||||
struct iwl_trans *trans = fwrt->trans;
|
||||
struct iwl_nvm_data *nvm;
|
||||
struct iwl_host_cmd hcmd = {
|
||||
.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
|
||||
.data = { &cmd, },
|
||||
.len = { sizeof(cmd) },
|
||||
.id = WIDE_ID(REGULATORY_AND_NVM_GROUP, NVM_GET_INFO)
|
||||
};
|
||||
int ret;
|
||||
bool lar_fw_supported = !iwlwifi_mod_params.lar_disable &&
|
||||
fw_has_capa(&fwrt->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
|
||||
|
||||
ret = iwl_trans_send_cmd(trans, &hcmd);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp),
|
||||
"Invalid payload len in NVM response from FW %d",
|
||||
iwl_rx_packet_payload_len(hcmd.resp_pkt))) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rsp = (void *)hcmd.resp_pkt->data;
|
||||
if (le32_to_cpu(rsp->general.flags) & NVM_GENERAL_FLAGS_EMPTY_OTP)
|
||||
IWL_INFO(fwrt, "OTP is empty\n");
|
||||
|
||||
nvm = kzalloc(sizeof(*nvm) +
|
||||
sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
|
||||
GFP_KERNEL);
|
||||
if (!nvm) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
iwl_set_hw_address_from_csr(trans, nvm);
|
||||
/* TODO: if platform NVM has MAC address - override it here */
|
||||
|
||||
if (!is_valid_ether_addr(nvm->hw_addr)) {
|
||||
IWL_ERR(fwrt, "no valid mac address was found\n");
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
IWL_INFO(trans, "base HW address: %pM\n", nvm->hw_addr);
|
||||
|
||||
/* Initialize general data */
|
||||
nvm->nvm_version = le16_to_cpu(rsp->general.nvm_version);
|
||||
|
||||
/* Initialize MAC sku data */
|
||||
nvm->sku_cap_11ac_enable =
|
||||
le32_to_cpu(rsp->mac_sku.enable_11ac);
|
||||
nvm->sku_cap_11n_enable =
|
||||
le32_to_cpu(rsp->mac_sku.enable_11n);
|
||||
nvm->sku_cap_band_24GHz_enable =
|
||||
le32_to_cpu(rsp->mac_sku.enable_24g);
|
||||
nvm->sku_cap_band_52GHz_enable =
|
||||
le32_to_cpu(rsp->mac_sku.enable_5g);
|
||||
nvm->sku_cap_mimo_disabled =
|
||||
le32_to_cpu(rsp->mac_sku.mimo_disable);
|
||||
|
||||
/* Initialize PHY sku data */
|
||||
nvm->valid_tx_ant = (u8)le32_to_cpu(rsp->phy_sku.tx_chains);
|
||||
nvm->valid_rx_ant = (u8)le32_to_cpu(rsp->phy_sku.rx_chains);
|
||||
|
||||
/* Initialize regulatory data */
|
||||
nvm->lar_enabled =
|
||||
le32_to_cpu(rsp->regulatory.lar_enabled) && lar_fw_supported;
|
||||
|
||||
iwl_init_sbands(trans->dev, trans->cfg, nvm,
|
||||
rsp->regulatory.channel_profile,
|
||||
nvm->valid_tx_ant & fwrt->fw->valid_tx_ant,
|
||||
nvm->valid_rx_ant & fwrt->fw->valid_rx_ant,
|
||||
rsp->regulatory.lar_enabled && lar_fw_supported);
|
||||
|
||||
iwl_free_resp(&hcmd);
|
||||
return nvm;
|
||||
|
||||
err_free:
|
||||
kfree(nvm);
|
||||
out:
|
||||
iwl_free_resp(&hcmd);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_get_nvm);
|
|
@ -63,6 +63,7 @@
|
|||
#include "img.h"
|
||||
#include "fw/api/debug.h"
|
||||
#include "fw/api/paging.h"
|
||||
#include "iwl-eeprom-parse.h"
|
||||
|
||||
struct iwl_fw_runtime_ops {
|
||||
int (*dump_start)(void *ctx);
|
||||
|
@ -152,5 +153,6 @@ void iwl_get_shared_mem_conf(struct iwl_fw_runtime *fwrt);
|
|||
|
||||
void iwl_fwrt_handle_notification(struct iwl_fw_runtime *fwrt,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
struct iwl_nvm_data *iwl_fw_get_nvm(struct iwl_fw_runtime *fwrt);
|
||||
|
||||
#endif /* __iwl_fw_runtime_h__ */
|
||||
|
|
|
@ -113,6 +113,9 @@ static void iwl_parse_shared_mem(struct iwl_fw_runtime *fwrt,
|
|||
BUILD_BUG_ON(sizeof(fwrt->smem_cfg.internal_txfifo_size) !=
|
||||
sizeof(mem_cfg->internal_txfifo_size));
|
||||
|
||||
fwrt->smem_cfg.internal_txfifo_addr =
|
||||
le32_to_cpu(mem_cfg->internal_txfifo_addr);
|
||||
|
||||
for (i = 0;
|
||||
i < ARRAY_SIZE(fwrt->smem_cfg.internal_txfifo_size);
|
||||
i++)
|
||||
|
|
|
@ -463,6 +463,7 @@ extern const struct iwl_cfg iwla000_2ac_cfg_hr;
|
|||
extern const struct iwl_cfg iwla000_2ac_cfg_hr_cdb;
|
||||
extern const struct iwl_cfg iwla000_2ac_cfg_jf;
|
||||
extern const struct iwl_cfg iwla000_2ax_cfg_hr;
|
||||
extern const struct iwl_cfg iwla000_2ax_cfg_qnj_hr;
|
||||
#endif /* CONFIG_IWLMVM */
|
||||
|
||||
#endif /* __IWL_CONFIG_H__ */
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
|
||||
/*
|
||||
* CSR Hardware Revision Workaround Register. Indicates hardware rev;
|
||||
* "step" determines CCK backoff for txpower calculation. Used for 4965 only.
|
||||
* "step" determines CCK backoff for txpower calculation.
|
||||
* See also CSR_HW_REV register.
|
||||
* Bit fields:
|
||||
* 3-2: 0 = A, 1 = B, 2 = C, 3 = D step
|
||||
|
@ -356,7 +356,7 @@ enum {
|
|||
#define CSR_HW_REV_TYPE_NONE (0x00001F0)
|
||||
|
||||
/* RF_ID value */
|
||||
#define CSR_HW_RF_ID_TYPE_JF (0x00105000)
|
||||
#define CSR_HW_RF_ID_TYPE_JF (0x00105100)
|
||||
#define CSR_HW_RF_ID_TYPE_HR (0x0010A000)
|
||||
#define CSR_HW_RF_ID_TYPE_HRCDB (0x00109000)
|
||||
|
||||
|
|
|
@ -478,8 +478,8 @@ static int iwl_set_default_calib(struct iwl_drv *drv, const u8 *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
|
||||
struct iwl_ucode_capabilities *capa)
|
||||
static void iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
|
||||
struct iwl_ucode_capabilities *capa)
|
||||
{
|
||||
const struct iwl_ucode_api *ucode_api = (void *)data;
|
||||
u32 api_index = le32_to_cpu(ucode_api->api_index);
|
||||
|
@ -490,20 +490,17 @@ static int iwl_set_ucode_api_flags(struct iwl_drv *drv, const u8 *data,
|
|||
IWL_ERR(drv,
|
||||
"api flags index %d larger than supported by driver\n",
|
||||
api_index);
|
||||
/* don't return an error so we can load FW that has more bits */
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (api_flags & BIT(i))
|
||||
__set_bit(i + 32 * api_index, capa->_api);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
|
||||
struct iwl_ucode_capabilities *capa)
|
||||
static void iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
|
||||
struct iwl_ucode_capabilities *capa)
|
||||
{
|
||||
const struct iwl_ucode_capa *ucode_capa = (void *)data;
|
||||
u32 api_index = le32_to_cpu(ucode_capa->api_index);
|
||||
|
@ -514,16 +511,13 @@ static int iwl_set_ucode_capabilities(struct iwl_drv *drv, const u8 *data,
|
|||
IWL_ERR(drv,
|
||||
"capa flags index %d larger than supported by driver\n",
|
||||
api_index);
|
||||
/* don't return an error so we can load FW that has more bits */
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (api_flags & BIT(i))
|
||||
__set_bit(i + 32 * api_index, capa->_capa);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
|
||||
|
@ -765,14 +759,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
|||
case IWL_UCODE_TLV_API_CHANGES_SET:
|
||||
if (tlv_len != sizeof(struct iwl_ucode_api))
|
||||
goto invalid_tlv_len;
|
||||
if (iwl_set_ucode_api_flags(drv, tlv_data, capa))
|
||||
goto tlv_error;
|
||||
iwl_set_ucode_api_flags(drv, tlv_data, capa);
|
||||
break;
|
||||
case IWL_UCODE_TLV_ENABLED_CAPABILITIES:
|
||||
if (tlv_len != sizeof(struct iwl_ucode_capa))
|
||||
goto invalid_tlv_len;
|
||||
if (iwl_set_ucode_capabilities(drv, tlv_data, capa))
|
||||
goto tlv_error;
|
||||
iwl_set_ucode_capabilities(drv, tlv_data, capa);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
|
||||
if (tlv_len != sizeof(u32))
|
||||
|
|
|
@ -241,20 +241,12 @@ IWL_EXPORT_SYMBOL(iwl_clear_bits_prph);
|
|||
|
||||
void iwl_force_nmi(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->cfg->device_family < IWL_DEVICE_FAMILY_8000) {
|
||||
if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000)
|
||||
iwl_write_prph(trans, DEVICE_SET_NMI_REG,
|
||||
DEVICE_SET_NMI_VAL_DRV);
|
||||
iwl_write_prph(trans, DEVICE_SET_NMI_REG,
|
||||
DEVICE_SET_NMI_VAL_HW);
|
||||
} else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_A000) {
|
||||
else
|
||||
iwl_write_prph(trans, UREG_NIC_SET_NMI_DRIVER,
|
||||
DEVICE_SET_NMI_8000_VAL);
|
||||
} else {
|
||||
iwl_write_prph(trans, DEVICE_SET_NMI_8000_REG,
|
||||
DEVICE_SET_NMI_8000_VAL);
|
||||
iwl_write_prph(trans, DEVICE_SET_NMI_REG,
|
||||
DEVICE_SET_NMI_VAL_DRV);
|
||||
}
|
||||
UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_force_nmi);
|
||||
|
||||
|
|
|
@ -109,13 +109,12 @@
|
|||
/* Device system time */
|
||||
#define DEVICE_SYSTEM_TIME_REG 0xA0206C
|
||||
|
||||
/* Device NMI register */
|
||||
/* Device NMI register and value for 8000 family and lower hw's */
|
||||
#define DEVICE_SET_NMI_REG 0x00a01c30
|
||||
#define DEVICE_SET_NMI_VAL_HW BIT(0)
|
||||
#define DEVICE_SET_NMI_VAL_DRV BIT(7)
|
||||
#define DEVICE_SET_NMI_8000_REG 0x00a01c24
|
||||
#define DEVICE_SET_NMI_8000_VAL 0x1000000
|
||||
/* Device NMI register and value for 9000 family and above hw's */
|
||||
#define UREG_NIC_SET_NMI_DRIVER 0x00a05c10
|
||||
#define UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK 0xff000000
|
||||
|
||||
/* Shared registers (0x0..0x3ff, via target indirect or periphery */
|
||||
#define SHR_BASE 0x00a10000
|
||||
|
@ -404,6 +403,12 @@ enum aux_misc_master1_en {
|
|||
#define SB_CPU_2_STATUS 0xA01E34
|
||||
#define UMAG_SB_CPU_1_STATUS 0xA038C0
|
||||
#define UMAG_SB_CPU_2_STATUS 0xA038C4
|
||||
#define UMAG_GEN_HW_STATUS 0xA038C8
|
||||
|
||||
/* For UMAG_GEN_HW_STATUS reg check */
|
||||
enum {
|
||||
UMAG_GEN_HW_IS_FPGA = BIT(1),
|
||||
};
|
||||
|
||||
/* FW chicken bits */
|
||||
#define LMPM_CHICK 0xA01FF8
|
||||
|
|
|
@ -560,8 +560,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
|
|||
smps_mode = IEEE80211_SMPS_AUTOMATIC;
|
||||
|
||||
if (mvmvif->phy_ctxt &&
|
||||
IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status,
|
||||
mvmvif->phy_ctxt->id))
|
||||
(mvm->last_bt_notif.rrc_status & BIT(mvmvif->phy_ctxt->id)))
|
||||
smps_mode = IEEE80211_SMPS_AUTOMATIC;
|
||||
|
||||
IWL_DEBUG_COEX(data->mvm,
|
||||
|
@ -792,7 +791,7 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
|
|||
struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
|
||||
enum iwl_bt_coex_lut_type lut_type;
|
||||
|
||||
if (IWL_COEX_IS_TTC_ON(mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))
|
||||
if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id))
|
||||
return LINK_QUAL_AGG_TIME_LIMIT_DEF;
|
||||
|
||||
if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
|
||||
|
@ -816,7 +815,7 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
|
|||
struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
|
||||
enum iwl_bt_coex_lut_type lut_type;
|
||||
|
||||
if (IWL_COEX_IS_TTC_ON(mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))
|
||||
if (mvm->last_bt_notif.ttc_status & BIT(phy_ctxt->id))
|
||||
return true;
|
||||
|
||||
if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
|
||||
|
|
|
@ -82,6 +82,9 @@ static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file,
|
|||
char buf[16];
|
||||
int pos, budget;
|
||||
|
||||
if (!iwl_mvm_is_ctdp_supported(mvm))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!iwl_mvm_firmware_running(mvm) ||
|
||||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
|
||||
return -EIO;
|
||||
|
@ -103,6 +106,9 @@ static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf,
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (!iwl_mvm_is_ctdp_supported(mvm))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!iwl_mvm_firmware_running(mvm) ||
|
||||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
|
||||
return -EIO;
|
||||
|
@ -114,6 +120,18 @@ static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf,
|
|||
return ret ?: count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_force_ctkill_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
if (!iwl_mvm_firmware_running(mvm) ||
|
||||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)
|
||||
return -EIO;
|
||||
|
||||
iwl_mvm_enter_ctkill(mvm);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
@ -551,9 +569,9 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
|
|||
"antenna isolation = %d CORUN LUT index = %d\n",
|
||||
mvm->last_ant_isol, mvm->last_corun_lut);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "bt_rrc = %d\n",
|
||||
(notif->ttc_rrc_status >> 4) & 0xF);
|
||||
notif->rrc_status & 0xF);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "bt_ttc = %d\n",
|
||||
notif->ttc_rrc_status & 0xF);
|
||||
notif->ttc_status & 0xF);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "sync_sco = %d\n",
|
||||
IWL_MVM_BT_COEX_SYNC2SCO);
|
||||
|
@ -1641,6 +1659,7 @@ 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(force_ctkill, 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);
|
||||
|
@ -1828,6 +1847,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
|||
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(force_ctkill, 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);
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
#include "fw/api/commands.h"
|
||||
#include "fw/api/d3.h"
|
||||
#include "fw/api/filter.h"
|
||||
#include "fw/api/led.h"
|
||||
#include "fw/api/mac.h"
|
||||
#include "fw/api/nvm-reg.h"
|
||||
#include "fw/api/phy-ctxt.h"
|
||||
|
|
|
@ -412,8 +412,10 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
|
|||
|
||||
/* Read the NVM only at driver load time, no need to do this twice */
|
||||
if (!IWL_MVM_PARSE_NVM && read_nvm) {
|
||||
ret = iwl_mvm_nvm_get_from_fw(mvm);
|
||||
if (ret) {
|
||||
mvm->nvm_data = iwl_fw_get_nvm(&mvm->fwrt);
|
||||
if (IS_ERR(mvm->nvm_data)) {
|
||||
ret = PTR_ERR(mvm->nvm_data);
|
||||
mvm->nvm_data = NULL;
|
||||
IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1171,7 +1173,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||
}
|
||||
|
||||
/* TODO: read the budget from BIOS / Platform NVM */
|
||||
if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0) {
|
||||
|
||||
/*
|
||||
* In case there is no budget from BIOS / Platform NVM the default
|
||||
* budget should be 2000mW (cooling state 0).
|
||||
*/
|
||||
if (iwl_mvm_is_ctdp_supported(mvm)) {
|
||||
ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START,
|
||||
mvm->cooling_dev.cur_state);
|
||||
if (ret)
|
||||
|
@ -1217,6 +1224,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
iwl_mvm_leds_sync(mvm);
|
||||
|
||||
IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
|
||||
return 0;
|
||||
error:
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2017 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -66,26 +68,45 @@
|
|||
#include "iwl-csr.h"
|
||||
#include "mvm.h"
|
||||
|
||||
/* Set led register on */
|
||||
static void iwl_mvm_led_enable(struct iwl_mvm *mvm)
|
||||
static void iwl_mvm_send_led_fw_cmd(struct iwl_mvm *mvm, bool on)
|
||||
{
|
||||
iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_ON);
|
||||
struct iwl_led_cmd led_cmd = {
|
||||
.status = cpu_to_le32(on),
|
||||
};
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = WIDE_ID(LONG_GROUP, LEDS_CMD),
|
||||
.len = { sizeof(led_cmd), },
|
||||
.data = { &led_cmd, },
|
||||
.flags = CMD_ASYNC,
|
||||
};
|
||||
int err;
|
||||
|
||||
if (!iwl_mvm_firmware_running(mvm))
|
||||
return;
|
||||
|
||||
err = iwl_mvm_send_cmd(mvm, &cmd);
|
||||
|
||||
if (err)
|
||||
IWL_WARN(mvm, "LED command failed: %d\n", err);
|
||||
}
|
||||
|
||||
/* Set led register off */
|
||||
static void iwl_mvm_led_disable(struct iwl_mvm *mvm)
|
||||
static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on)
|
||||
{
|
||||
iwl_write32(mvm->trans, CSR_LED_REG, CSR_LED_REG_TURN_OFF);
|
||||
if (mvm->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
|
||||
iwl_mvm_send_led_fw_cmd(mvm, on);
|
||||
return;
|
||||
}
|
||||
|
||||
iwl_write32(mvm->trans, CSR_LED_REG,
|
||||
on ? CSR_LED_REG_TURN_ON : CSR_LED_REG_TURN_OFF);
|
||||
}
|
||||
|
||||
static void iwl_led_brightness_set(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct iwl_mvm *mvm = container_of(led_cdev, struct iwl_mvm, led);
|
||||
if (brightness > 0)
|
||||
iwl_mvm_led_enable(mvm);
|
||||
else
|
||||
iwl_mvm_led_disable(mvm);
|
||||
|
||||
iwl_mvm_led_set(mvm, brightness > 0);
|
||||
}
|
||||
|
||||
int iwl_mvm_leds_init(struct iwl_mvm *mvm)
|
||||
|
@ -127,10 +148,24 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void iwl_mvm_leds_sync(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
|
||||
return;
|
||||
|
||||
/*
|
||||
* if we control through the register, we're doing it
|
||||
* even when the firmware isn't up, so no need to sync
|
||||
*/
|
||||
if (mvm->cfg->device_family < IWL_DEVICE_FAMILY_8000)
|
||||
return;
|
||||
|
||||
iwl_mvm_led_set(mvm, mvm->led.brightness > 0);
|
||||
}
|
||||
|
||||
void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (iwlwifi_mod_params.led_mode == IWL_LED_DISABLE ||
|
||||
!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
|
||||
if (!(mvm->init_status & IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE))
|
||||
return;
|
||||
|
||||
led_classdev_unregister(&mvm->led);
|
||||
|
|
|
@ -923,6 +923,19 @@ static u32 iwl_mvm_find_ie_offset(u8 *beacon, u8 eid, u32 frame_size)
|
|||
return ie - beacon;
|
||||
}
|
||||
|
||||
static u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
u8 rate;
|
||||
|
||||
if (info->band == NL80211_BAND_5GHZ || vif->p2p)
|
||||
rate = IWL_FIRST_OFDM_RATE;
|
||||
else
|
||||
rate = IWL_FIRST_CCK_RATE;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct sk_buff *beacon,
|
||||
|
@ -930,7 +943,8 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
|
|||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct ieee80211_tx_info *info;
|
||||
u32 rate, tx_flags;
|
||||
u8 rate;
|
||||
u32 tx_flags;
|
||||
|
||||
info = IEEE80211_SKB_CB(beacon);
|
||||
|
||||
|
@ -955,14 +969,12 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
|
|||
cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
|
||||
RATE_MCS_ANT_POS);
|
||||
|
||||
if (info->band == NL80211_BAND_5GHZ || vif->p2p) {
|
||||
rate = IWL_FIRST_OFDM_RATE;
|
||||
} else {
|
||||
rate = IWL_FIRST_CCK_RATE;
|
||||
tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
|
||||
}
|
||||
rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
|
||||
|
||||
tx->rate_n_flags |= cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
|
||||
if (rate == IWL_FIRST_CCK_RATE)
|
||||
tx->rate_n_flags |= cpu_to_le32(RATE_MCS_CCK_MSK);
|
||||
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
|
||||
|
@ -1033,19 +1045,27 @@ static int iwl_mvm_mac_ctxt_send_beacon_v7(struct iwl_mvm *mvm,
|
|||
sizeof(beacon_cmd));
|
||||
}
|
||||
|
||||
static int iwl_mvm_mac_ctxt_send_beacon_v8(struct iwl_mvm *mvm,
|
||||
static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct sk_buff *beacon)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(beacon);
|
||||
struct iwl_mac_beacon_cmd beacon_cmd = {};
|
||||
u8 rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
|
||||
u16 flags;
|
||||
|
||||
flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
|
||||
|
||||
if (rate == IWL_FIRST_CCK_RATE)
|
||||
flags |= IWL_MAC_BEACON_CCK;
|
||||
|
||||
beacon_cmd.flags = cpu_to_le16(flags);
|
||||
beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
|
||||
beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
iwl_mvm_mac_ctxt_set_tim(mvm,
|
||||
&beacon_cmd.tim_idx,
|
||||
iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx,
|
||||
&beacon_cmd.tim_size,
|
||||
beacon->data, beacon->len);
|
||||
|
||||
|
@ -1073,10 +1093,11 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
|
|||
IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD))
|
||||
return iwl_mvm_mac_ctxt_send_beacon_v6(mvm, vif, beacon);
|
||||
|
||||
if (!iwl_mvm_has_new_tx_api(mvm))
|
||||
return iwl_mvm_mac_ctxt_send_beacon_v7(mvm, vif, beacon);
|
||||
if (fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE))
|
||||
return iwl_mvm_mac_ctxt_send_beacon_v9(mvm, vif, beacon);
|
||||
|
||||
return iwl_mvm_mac_ctxt_send_beacon_v8(mvm, vif, beacon);
|
||||
return iwl_mvm_mac_ctxt_send_beacon_v7(mvm, vif, beacon);
|
||||
}
|
||||
|
||||
/* The beacon template for the AP/GO/IBSS has changed and needs update */
|
||||
|
|
|
@ -1377,7 +1377,6 @@ void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm);
|
|||
|
||||
/* NVM */
|
||||
int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
|
||||
int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm);
|
||||
|
||||
|
@ -1566,6 +1565,7 @@ void iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
|
|||
#ifdef CONFIG_IWLWIFI_LEDS
|
||||
int iwl_mvm_leds_init(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_leds_sync(struct iwl_mvm *mvm);
|
||||
#else
|
||||
static inline int iwl_mvm_leds_init(struct iwl_mvm *mvm)
|
||||
{
|
||||
|
@ -1574,6 +1574,9 @@ static inline int iwl_mvm_leds_init(struct iwl_mvm *mvm)
|
|||
static inline void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
|
||||
{
|
||||
}
|
||||
static inline void iwl_mvm_leds_sync(struct iwl_mvm *mvm)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* D3 (WoWLAN, NetDetect) */
|
||||
|
@ -1751,6 +1754,7 @@ void iwl_mvm_thermal_exit(struct iwl_mvm *mvm);
|
|||
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);
|
||||
void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 budget);
|
||||
|
||||
|
|
|
@ -546,97 +546,6 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_nvm_get_from_fw(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_nvm_get_info cmd = {};
|
||||
struct iwl_nvm_get_info_rsp *rsp;
|
||||
struct iwl_trans *trans = mvm->trans;
|
||||
struct iwl_host_cmd hcmd = {
|
||||
.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
|
||||
.data = { &cmd, },
|
||||
.len = { sizeof(cmd) },
|
||||
.id = WIDE_ID(REGULATORY_AND_NVM_GROUP, NVM_GET_INFO)
|
||||
};
|
||||
int ret;
|
||||
bool lar_fw_supported = !iwlwifi_mod_params.lar_disable &&
|
||||
fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
ret = iwl_mvm_send_cmd(mvm, &hcmd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp),
|
||||
"Invalid payload len in NVM response from FW %d",
|
||||
iwl_rx_packet_payload_len(hcmd.resp_pkt))) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rsp = (void *)hcmd.resp_pkt->data;
|
||||
if (le32_to_cpu(rsp->general.flags) & NVM_GENERAL_FLAGS_EMPTY_OTP)
|
||||
IWL_INFO(mvm, "OTP is empty\n");
|
||||
|
||||
mvm->nvm_data = kzalloc(sizeof(*mvm->nvm_data) +
|
||||
sizeof(struct ieee80211_channel) *
|
||||
IWL_NUM_CHANNELS, GFP_KERNEL);
|
||||
if (!mvm->nvm_data) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
iwl_set_hw_address_from_csr(trans, mvm->nvm_data);
|
||||
/* TODO: if platform NVM has MAC address - override it here */
|
||||
|
||||
if (!is_valid_ether_addr(mvm->nvm_data->hw_addr)) {
|
||||
IWL_ERR(trans, "no valid mac address was found\n");
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
IWL_INFO(trans, "base HW address: %pM\n", mvm->nvm_data->hw_addr);
|
||||
|
||||
/* Initialize general data */
|
||||
mvm->nvm_data->nvm_version = le16_to_cpu(rsp->general.nvm_version);
|
||||
|
||||
/* Initialize MAC sku data */
|
||||
mvm->nvm_data->sku_cap_11ac_enable =
|
||||
le32_to_cpu(rsp->mac_sku.enable_11ac);
|
||||
mvm->nvm_data->sku_cap_11n_enable =
|
||||
le32_to_cpu(rsp->mac_sku.enable_11n);
|
||||
mvm->nvm_data->sku_cap_band_24GHz_enable =
|
||||
le32_to_cpu(rsp->mac_sku.enable_24g);
|
||||
mvm->nvm_data->sku_cap_band_52GHz_enable =
|
||||
le32_to_cpu(rsp->mac_sku.enable_5g);
|
||||
mvm->nvm_data->sku_cap_mimo_disabled =
|
||||
le32_to_cpu(rsp->mac_sku.mimo_disable);
|
||||
|
||||
/* Initialize PHY sku data */
|
||||
mvm->nvm_data->valid_tx_ant = (u8)le32_to_cpu(rsp->phy_sku.tx_chains);
|
||||
mvm->nvm_data->valid_rx_ant = (u8)le32_to_cpu(rsp->phy_sku.rx_chains);
|
||||
|
||||
/* Initialize regulatory data */
|
||||
mvm->nvm_data->lar_enabled =
|
||||
le32_to_cpu(rsp->regulatory.lar_enabled) && lar_fw_supported;
|
||||
|
||||
iwl_init_sbands(trans->dev, trans->cfg, mvm->nvm_data,
|
||||
rsp->regulatory.channel_profile,
|
||||
mvm->nvm_data->valid_tx_ant & mvm->fw->valid_tx_ant,
|
||||
mvm->nvm_data->valid_rx_ant & mvm->fw->valid_rx_ant,
|
||||
rsp->regulatory.lar_enabled && lar_fw_supported);
|
||||
|
||||
iwl_free_resp(&hcmd);
|
||||
return 0;
|
||||
|
||||
err_free:
|
||||
kfree(mvm->nvm_data);
|
||||
out:
|
||||
iwl_free_resp(&hcmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
|
||||
{
|
||||
int ret, section;
|
||||
|
|
|
@ -350,6 +350,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
|
|||
HCMD_NAME(BINDING_CONTEXT_CMD),
|
||||
HCMD_NAME(TIME_QUOTA_CMD),
|
||||
HCMD_NAME(NON_QOS_TX_COUNTER_CMD),
|
||||
HCMD_NAME(LEDS_CMD),
|
||||
HCMD_NAME(LQ_CMD),
|
||||
HCMD_NAME(FW_PAGING_BLOCK_CMD),
|
||||
HCMD_NAME(SCAN_OFFLOAD_REQUEST_CMD),
|
||||
|
|
|
@ -1277,6 +1277,50 @@ static void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm,
|
|||
}
|
||||
}
|
||||
|
||||
static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_int_sta *sta,
|
||||
const u8 *addr,
|
||||
u16 mac_id, u16 color)
|
||||
{
|
||||
struct iwl_mvm_add_sta_cmd cmd;
|
||||
int ret;
|
||||
u32 status;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.sta_id = sta->sta_id;
|
||||
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
|
||||
color));
|
||||
if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
|
||||
cmd.station_type = sta->type;
|
||||
|
||||
if (!iwl_mvm_has_new_tx_api(mvm))
|
||||
cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
|
||||
cmd.tid_disable_tx = cpu_to_le16(0xffff);
|
||||
|
||||
if (addr)
|
||||
memcpy(cmd.addr, addr, ETH_ALEN);
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
|
||||
iwl_mvm_add_sta_cmd_size(mvm),
|
||||
&cmd, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (status & IWL_ADD_STA_STATUS_MASK) {
|
||||
case ADD_STA_SUCCESS:
|
||||
IWL_DEBUG_INFO(mvm, "Internal station added.\n");
|
||||
return 0;
|
||||
default:
|
||||
ret = -EIO;
|
||||
IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
|
||||
status);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_add_sta(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
|
@ -1285,6 +1329,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
|
|||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
struct iwl_mvm_rxq_dup_data *dup_data;
|
||||
int i, ret, sta_id;
|
||||
bool sta_update = false;
|
||||
unsigned int sta_flags = 0;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
|
@ -1301,7 +1347,23 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
|
|||
|
||||
/* if this is a HW restart re-alloc existing queues */
|
||||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
struct iwl_mvm_int_sta tmp_sta = {
|
||||
.sta_id = sta_id,
|
||||
.type = mvm_sta->sta_type,
|
||||
};
|
||||
|
||||
/*
|
||||
* First add an empty station since allocating
|
||||
* a queue requires a valid station
|
||||
*/
|
||||
ret = iwl_mvm_add_int_sta_common(mvm, &tmp_sta, sta->addr,
|
||||
mvmvif->id, mvmvif->color);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
iwl_mvm_realloc_queues_after_restart(mvm, mvm_sta);
|
||||
sta_update = true;
|
||||
sta_flags = iwl_mvm_has_new_tx_api(mvm) ? 0 : STA_MODIFY_QUEUES;
|
||||
goto update_fw;
|
||||
}
|
||||
|
||||
|
@ -1368,7 +1430,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
|
|||
}
|
||||
|
||||
update_fw:
|
||||
ret = iwl_mvm_sta_send_to_fw(mvm, sta, false, 0);
|
||||
ret = iwl_mvm_sta_send_to_fw(mvm, sta, sta_update, sta_flags);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
@ -1637,50 +1699,6 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
|
|||
sta->sta_id = IWL_MVM_INVALID_STA;
|
||||
}
|
||||
|
||||
static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_int_sta *sta,
|
||||
const u8 *addr,
|
||||
u16 mac_id, u16 color)
|
||||
{
|
||||
struct iwl_mvm_add_sta_cmd cmd;
|
||||
int ret;
|
||||
u32 status;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.sta_id = sta->sta_id;
|
||||
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
|
||||
color));
|
||||
if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
|
||||
cmd.station_type = sta->type;
|
||||
|
||||
if (!iwl_mvm_has_new_tx_api(mvm))
|
||||
cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
|
||||
cmd.tid_disable_tx = cpu_to_le16(0xffff);
|
||||
|
||||
if (addr)
|
||||
memcpy(cmd.addr, addr, ETH_ALEN);
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
|
||||
iwl_mvm_add_sta_cmd_size(mvm),
|
||||
&cmd, &status);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (status & IWL_ADD_STA_STATUS_MASK) {
|
||||
case ADD_STA_SUCCESS:
|
||||
IWL_DEBUG_INFO(mvm, "Internal station added.\n");
|
||||
return 0;
|
||||
default:
|
||||
ret = -EIO;
|
||||
IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
|
||||
status);
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_mvm_enable_aux_queue(struct iwl_mvm *mvm)
|
||||
{
|
||||
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
|
||||
#define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ
|
||||
|
||||
static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
|
||||
void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
|
||||
u32 duration = tt->params.ct_kill_duration;
|
||||
|
@ -813,7 +813,7 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct thermal_cooling_device_ops tcooling_ops = {
|
||||
static const struct thermal_cooling_device_ops tcooling_ops = {
|
||||
.get_max_state = iwl_mvm_tcool_get_max_state,
|
||||
.get_cur_state = iwl_mvm_tcool_get_cur_state,
|
||||
.set_cur_state = iwl_mvm_tcool_set_cur_state,
|
||||
|
|
|
@ -806,6 +806,8 @@ int iwl_pcie_alloc_dma_ptr(struct iwl_trans *trans,
|
|||
struct iwl_dma_ptr *ptr, size_t size);
|
||||
void iwl_pcie_free_dma_ptr(struct iwl_trans *trans, struct iwl_dma_ptr *ptr);
|
||||
void iwl_pcie_apply_destination(struct iwl_trans *trans);
|
||||
void iwl_pcie_free_tso_page(struct iwl_trans_pcie *trans_pcie,
|
||||
struct sk_buff *skb);
|
||||
#ifdef CONFIG_INET
|
||||
struct iwl_tso_hdr_page *get_page_hdr(struct iwl_trans *trans, size_t len);
|
||||
#endif
|
||||
|
|
|
@ -1842,8 +1842,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
|
|||
* These bits say the device is running, and should keep running for
|
||||
* at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
|
||||
* but they do not indicate that embedded SRAM is restored yet;
|
||||
* 3945 and 4965 have volatile SRAM, and must save/restore contents
|
||||
* to/from host DRAM when sleeping/waking for power-saving.
|
||||
* HW with volatile SRAM must save/restore contents to/from
|
||||
* host DRAM when sleeping/waking for power-saving.
|
||||
* Each direction takes approximately 1/4 millisecond; with this
|
||||
* overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
|
||||
* series of register accesses are expected (e.g. reading Event Log),
|
||||
|
@ -1851,8 +1851,9 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
|
|||
*
|
||||
* CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
|
||||
* SRAM is okay/restored. We don't check that here because this call
|
||||
* is just for hardware register access; but GP1 MAC_SLEEP check is a
|
||||
* good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
|
||||
* is just for hardware register access; but GP1 MAC_SLEEP
|
||||
* check is a good idea before accessing the SRAM of HW with
|
||||
* volatile SRAM (e.g. reading Event Log).
|
||||
*
|
||||
* 5000 series and later (including 1000 series) have non-volatile SRAM,
|
||||
* and do not save/restore SRAM when power cycling.
|
||||
|
@ -3137,7 +3138,18 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
|
|||
iwl_set_bit(trans, CSR_HOST_CHICKEN,
|
||||
CSR_HOST_CHICKEN_PM_IDLE_SRC_DIS_SB_PME);
|
||||
|
||||
#if IS_ENABLED(CONFIG_IWLMVM)
|
||||
trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
|
||||
if (trans->hw_rf_id == CSR_HW_RF_ID_TYPE_HR) {
|
||||
u32 hw_status;
|
||||
|
||||
hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
|
||||
if (hw_status & UMAG_GEN_HW_IS_FPGA)
|
||||
trans->cfg = &iwla000_2ax_cfg_qnj_hr;
|
||||
else
|
||||
trans->cfg = &iwla000_2ac_cfg_hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
iwl_pcie_set_interrupt_capa(pdev, trans);
|
||||
trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
|
||||
|
|
|
@ -937,6 +937,15 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id)
|
|||
IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
|
||||
txq_id, txq->read_ptr);
|
||||
|
||||
if (txq_id != trans_pcie->cmd_queue) {
|
||||
int idx = get_cmd_index(txq, txq->read_ptr);
|
||||
struct sk_buff *skb = txq->entries[idx].skb;
|
||||
|
||||
if (WARN_ON_ONCE(!skb))
|
||||
continue;
|
||||
|
||||
iwl_pcie_free_tso_page(trans_pcie, skb);
|
||||
}
|
||||
iwl_pcie_gen2_free_tfd(trans, txq);
|
||||
txq->read_ptr = iwl_queue_inc_wrap(txq->read_ptr);
|
||||
|
||||
|
@ -1033,6 +1042,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
|
|||
.flags = CMD_WANT_SKB,
|
||||
};
|
||||
int ret, qid;
|
||||
u32 wr_ptr;
|
||||
|
||||
txq = kzalloc(sizeof(*txq), GFP_KERNEL);
|
||||
if (!txq)
|
||||
|
@ -1073,6 +1083,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
|
|||
|
||||
rsp = (void *)hcmd.resp_pkt->data;
|
||||
qid = le16_to_cpu(rsp->queue_number);
|
||||
wr_ptr = le16_to_cpu(rsp->write_pointer);
|
||||
|
||||
if (qid >= ARRAY_SIZE(trans_pcie->txq)) {
|
||||
WARN_ONCE(1, "queue index %d unsupported", qid);
|
||||
|
@ -1088,10 +1099,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
|
|||
|
||||
txq->id = qid;
|
||||
trans_pcie->txq[qid] = txq;
|
||||
wr_ptr &= (TFD_QUEUE_SIZE_MAX - 1);
|
||||
|
||||
/* Place first TFD at index corresponding to start sequence number */
|
||||
txq->read_ptr = le16_to_cpu(rsp->write_pointer);
|
||||
txq->write_ptr = le16_to_cpu(rsp->write_pointer);
|
||||
txq->read_ptr = wr_ptr;
|
||||
txq->write_ptr = wr_ptr;
|
||||
iwl_write_direct32(trans, HBUS_TARG_WRPTR,
|
||||
(txq->write_ptr) | (qid << 16));
|
||||
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);
|
||||
|
|
|
@ -577,8 +577,8 @@ int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_pcie_free_tso_page(struct iwl_trans_pcie *trans_pcie,
|
||||
struct sk_buff *skb)
|
||||
void iwl_pcie_free_tso_page(struct iwl_trans_pcie *trans_pcie,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct page **page_ptr;
|
||||
|
||||
|
|
Loading…
Reference in New Issue