#ifndef __iwl_trans_h__
#define __iwl_trans_h__
#include <linux/ieee80211.h>
#include <linux/mm.h>
#include <linux/lockdep.h>
#include <linux/kernel.h>
#include "iwl-debug.h"
#include "iwl-config.h"
#include "fw/img.h"
#include "iwl-op-mode.h"
#include <linux/firmware.h>
#include "fw/api/cmdhdr.h"
#include "fw/api/txq.h"
#include "fw/api/dbg-tlv.h"
#include "iwl-dbg-tlv.h"
#define IWL_FW_DBG_DOMAIN_POS 16
#define IWL_FW_DBG_DOMAIN BIT(IWL_FW_DBG_DOMAIN_POS)
#define IWL_TRANS_FW_DBG_DOMAIN(trans) IWL_FW_INI_DOMAIN_ALWAYS_ON
#define FH_RSCSR_FRAME_SIZE_MSK 0x00003FFF
#define FH_RSCSR_FRAME_INVALID 0x55550000
#define FH_RSCSR_FRAME_ALIGN 0x40
#define FH_RSCSR_RPA_EN BIT(25)
#define FH_RSCSR_RADA_EN BIT(26)
#define FH_RSCSR_RXQ_POS 16
#define FH_RSCSR_RXQ_MASK 0x3F0000
struct iwl_rx_packet {
__le32 len_n_flags;
struct iwl_cmd_header hdr;
u8 data[];
} __packed;
static inline u32 iwl_rx_packet_len(const struct iwl_rx_packet *pkt)
{
return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
}
static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt)
{
return iwl_rx_packet_len(pkt) - sizeof(pkt->hdr);
}
enum CMD_MODE {
CMD_ASYNC = BIT(0),
CMD_WANT_SKB = BIT(1),
CMD_SEND_IN_RFKILL = BIT(2),
CMD_BLOCK_TXQS = BIT(3),
};
#define CMD_MODE_BITS 5
#define DEF_CMD_PAYLOAD_SIZE 320
struct iwl_device_cmd {
union {
struct {
struct iwl_cmd_header hdr;
u8 payload[DEF_CMD_PAYLOAD_SIZE];
};
struct {
struct iwl_cmd_header_wide hdr_wide;
u8 payload_wide[DEF_CMD_PAYLOAD_SIZE -
sizeof(struct iwl_cmd_header_wide) +
sizeof(struct iwl_cmd_header)];
};
};
} __packed;
struct iwl_device_tx_cmd {
struct iwl_cmd_header hdr;
u8 payload[];
} __packed;
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
#define IWL_MAX_CMD_PAYLOAD_SIZE \
(TFD_MAX_PAYLOAD_SIZE - sizeof(struct iwl_cmd_header_wide))
#define IWL_MAX_CMD_TBS_PER_TFD 2
enum iwl_hcmd_dataflag {
IWL_HCMD_DFL_NOCOPY = BIT(0),
IWL_HCMD_DFL_DUP = BIT(1),
};
enum iwl_error_event_table_status {
IWL_ERROR_EVENT_TABLE_LMAC1 = BIT(0),
IWL_ERROR_EVENT_TABLE_LMAC2 = BIT(1),
IWL_ERROR_EVENT_TABLE_UMAC = BIT(2),
IWL_ERROR_EVENT_TABLE_TCM1 = BIT(3),
IWL_ERROR_EVENT_TABLE_TCM2 = BIT(4),
IWL_ERROR_EVENT_TABLE_RCM1 = BIT(5),
IWL_ERROR_EVENT_TABLE_RCM2 = BIT(6),
};
struct iwl_host_cmd {
const void *data[IWL_MAX_CMD_TBS_PER_TFD];
struct iwl_rx_packet *resp_pkt;
unsigned long _rx_page_addr;
u32 _rx_page_order;
u32 flags;
u32 id;
u16 len[IWL_MAX_CMD_TBS_PER_TFD];
u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD];
};
static inline void iwl_free_resp(struct iwl_host_cmd *cmd)
{
free_pages(cmd->_rx_page_addr, cmd->_rx_page_order);
}
struct iwl_rx_cmd_buffer {
struct page *_page;
int _offset;
bool _page_stolen;
u32 _rx_page_order;
unsigned int truesize;
};
static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r)
{
return (void *)((unsigned long)page_address(r->_page) + r->_offset);
}
static inline int rxb_offset(struct iwl_rx_cmd_buffer *r)
{
return r->_offset;
}
static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
{
r->_page_stolen = true;
get_page(r->_page);
return r->_page;
}
static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r)
{
__free_pages(r->_page, r->_rx_page_order);
}
#define MAX_NO_RECLAIM_CMDS 6
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
#define IWL_MAX_HW_QUEUES 32
#define IWL_MAX_TVQM_QUEUES 512
#define IWL_MAX_TID_COUNT 8
#define IWL_MGMT_TID 15
#define IWL_FRAME_LIMIT 64
#define IWL_MAX_RX_HW_QUEUES 16
#define IWL_9000_MAX_RX_HW_QUEUES 1
enum iwl_trans_status {
STATUS_SYNC_HCMD_ACTIVE,
STATUS_DEVICE_ENABLED,
STATUS_TPOWER_PMI,
STATUS_INT_ENABLED,
STATUS_RFKILL_HW,
STATUS_RFKILL_OPMODE,
STATUS_FW_ERROR,
STATUS_TRANS_DEAD,
STATUS_IN_SW_RESET,
STATUS_RESET_PENDING,
STATUS_TRANS_RESET_IN_PROGRESS,
};
static inline int
iwl_trans_get_rb_size_order(enum iwl_amsdu_size rb_size)
{
switch (rb_size) {
case IWL_AMSDU_2K:
return get_order(2 * 1024);
case IWL_AMSDU_4K:
return get_order(4 * 1024);
case IWL_AMSDU_8K:
return get_order(8 * 1024);
case IWL_AMSDU_12K:
return get_order(16 * 1024);
default:
WARN_ON(1);
return -1;
}
}
static inline int
iwl_trans_get_rb_size(enum iwl_amsdu_size rb_size)
{
switch (rb_size) {
case IWL_AMSDU_2K:
return 2 * 1024;
case IWL_AMSDU_4K:
return 4 * 1024;
case IWL_AMSDU_8K:
return 8 * 1024;
case IWL_AMSDU_12K:
return 16 * 1024;
default:
WARN_ON(1);
return 0;
}
}
struct iwl_hcmd_names {
u8 cmd_id;
const char *const cmd_name;
};
#define HCMD_NAME(x) \
{ .cmd_id = x, .cmd_name = #x }
struct iwl_hcmd_arr {
const struct iwl_hcmd_names *arr;
int size;
};
#define HCMD_ARR(x) \
{ .arr = x, .size = ARRAY_SIZE(x) }
struct iwl_dump_sanitize_ops {
void (*frob_txf)(void *ctx, void *buf, size_t buflen);
void (*frob_hcmd)(void *ctx, void *hcmd, size_t buflen);
void (*frob_mem)(void *ctx, u32 mem_addr, void *mem, size_t buflen);
};
struct iwl_trans_config {
u8 cmd_queue;
u8 cmd_fifo;
u8 n_no_reclaim_cmds;
u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
enum iwl_amsdu_size rx_buf_size;
bool scd_set_active;
const struct iwl_hcmd_arr *command_groups;
int command_groups_size;
u8 cb_data_offs;
bool fw_reset_handshake;
u8 queue_alloc_cmd_ver;
bool wide_cmd_header;
u8 rx_mpdu_cmd, rx_mpdu_cmd_hdr_size;
u8 dsbr_urm_fw_dependent:1,
dsbr_urm_permanent:1,
ext_32khz_clock_valid:1;
u32 mbx_addr_0_step;
u32 mbx_addr_1_step;
};
struct iwl_trans_dump_data {
u32 len;
u8 data[];
};
struct iwl_trans;
struct iwl_trans_txq_scd_cfg {
u8 fifo;
u8 sta_id;
u8 tid;
bool aggregate;
int frame_limit;
};
struct iwl_trans_rxq_dma_data {
u64 fr_bd_cb;
u32 fr_bd_wid;
u64 urbd_stts_wrptr;
u64 ur_bd_cb;
};
#define IPC_DRAM_MAP_ENTRY_NUM_MAX 64
struct iwl_pnvm_image {
struct {
const void *data;
u32 len;
} chunks[IPC_DRAM_MAP_ENTRY_NUM_MAX];
u32 n_chunks;
u32 version;
};
enum iwl_trans_state {
IWL_TRANS_NO_FW,
IWL_TRANS_FW_STARTED,
IWL_TRANS_FW_ALIVE,
};
enum iwl_ini_cfg_state {
IWL_INI_CFG_STATE_NOT_LOADED,
IWL_INI_CFG_STATE_LOADED,
IWL_INI_CFG_STATE_CORRUPTED,
};
#define IWL_TRANS_NMI_TIMEOUT (HZ / 4)
struct iwl_dram_data {
dma_addr_t physical;
void *block;
int size;
};
struct iwl_dram_regions {
struct iwl_dram_data drams[IPC_DRAM_MAP_ENTRY_NUM_MAX];
struct iwl_dram_data prph_scratch_mem_desc;
u8 n_regions;
};
struct iwl_fw_mon {
u32 num_frags;
struct iwl_dram_data *frags;
};
struct iwl_self_init_dram {
struct iwl_dram_data *fw;
int fw_cnt;
struct iwl_dram_data *paging;
int paging_cnt;
};
struct iwl_imr_data {
u32 imr_enable;
u32 imr_size;
u32 sram_addr;
u32 sram_size;
u32 imr2sram_remainbyte;
u64 imr_curr_addr;
__le64 imr_base_addr;
};
#define IWL_TRANS_CURRENT_PC_NAME_MAX_BYTES 32
struct iwl_pc_data {
u8 pc_name[IWL_TRANS_CURRENT_PC_NAME_MAX_BYTES];
u32 pc_address;
};
struct iwl_trans_debug {
u8 n_dest_reg;
bool rec_on;
const struct iwl_fw_dbg_dest_tlv_v1 *dest_tlv;
u32 lmac_error_event_table[2];
u32 umac_error_event_table;
u32 tcm_error_event_table[2];
u32 rcm_error_event_table[2];
unsigned int error_event_table_tlv_status;
enum iwl_ini_cfg_state internal_ini_cfg;
enum iwl_ini_cfg_state external_ini_cfg;
struct iwl_fw_ini_allocation_tlv fw_mon_cfg[IWL_FW_INI_ALLOCATION_NUM];
struct iwl_fw_mon fw_mon_ini[IWL_FW_INI_ALLOCATION_NUM];
struct iwl_dram_data fw_mon;
bool hw_error;
enum iwl_fw_ini_buffer_location ini_dest;
u64 unsupported_region_msk;
struct iwl_ucode_tlv *active_regions[IWL_FW_INI_MAX_REGION_ID];
struct list_head debug_info_tlv_list;
struct iwl_dbg_tlv_time_point_data time_point[IWL_FW_INI_TIME_POINT_NUM];
struct list_head periodic_trig_list;
u32 domains_bitmap;
u32 ucode_preset;
bool restart_required;
u32 last_tp_resetfw;
struct iwl_imr_data imr_data;
u32 num_pc;
struct iwl_pc_data *pc_data;
bool yoyo_bin_loaded;
};
struct iwl_dma_ptr {
dma_addr_t dma;
void *addr;
size_t size;
};
struct iwl_cmd_meta {
struct iwl_host_cmd *source;
u32 flags: CMD_MODE_BITS;
u32 sg_offset: PAGE_SHIFT;
u32 tbs;
};
struct iwl_trans_info {
const char *name;
u32 max_skb_frags;
u32 hw_rev;
u32 hw_rev_step;
u32 hw_rf_id;
u32 hw_crf_id;
u32 hw_cnv_id;
u32 hw_id;
u8 pcie_link_speed;
u8 num_rxqs;
};
struct iwl_trans {
bool csme_own;
struct iwl_op_mode *op_mode;
const struct iwl_mac_cfg *mac_cfg;
const struct iwl_rf_cfg *cfg;
struct iwl_drv *drv;
struct iwl_trans_config conf;
enum iwl_trans_state state;
unsigned long status;
struct device *dev;
const struct iwl_trans_info info;
bool reduced_cap_sku;
bool step_urm;
bool suppress_cmd_error_once;
u8 pnvm_loaded:1;
u8 fail_to_parse_pnvm_image:1;
u8 reduce_power_loaded:1;
u8 failed_to_load_reduce_power_image:1;
struct dentry *dbgfs_dir;
#ifdef CONFIG_LOCKDEP
struct lockdep_map sync_cmd_lockdep_map;
#endif
struct iwl_trans_debug dbg;
struct iwl_self_init_dram init_dram;
struct {
struct delayed_work wk;
struct iwl_fw_error_dump_mode mode;
bool during_reset;
} restart;
u8 request_top_reset:1,
do_top_reset:1;
char trans_specific[] __aligned(sizeof(void *));
};
const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id);
void iwl_trans_op_mode_enter(struct iwl_trans *trans,
struct iwl_op_mode *op_mode);
int iwl_trans_start_hw(struct iwl_trans *trans);
void iwl_trans_op_mode_leave(struct iwl_trans *trans);
void iwl_trans_fw_alive(struct iwl_trans *trans);
int iwl_trans_start_fw(struct iwl_trans *trans, const struct iwl_fw *fw,
enum iwl_ucode_type ucode_type, bool run_in_rfkill);
void iwl_trans_stop_device(struct iwl_trans *trans);
int iwl_trans_d3_suspend(struct iwl_trans *trans, bool reset);
int iwl_trans_d3_resume(struct iwl_trans *trans, bool reset);
struct iwl_trans_dump_data *
iwl_trans_dump_data(struct iwl_trans *trans, u32 dump_mask,
const struct iwl_dump_sanitize_ops *sanitize_ops,
void *sanitize_ctx);
struct iwl_device_tx_cmd *iwl_trans_alloc_tx_cmd(struct iwl_trans *trans);
int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
struct iwl_device_tx_cmd *dev_cmd);
int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_device_tx_cmd *dev_cmd, int queue);
void iwl_trans_reclaim(struct iwl_trans *trans, int queue, int ssn,
struct sk_buff_head *skbs, bool is_flush);
void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue, int ptr);
void iwl_trans_txq_disable(struct iwl_trans *trans, int queue,
bool configure_scd);
bool iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn,
const struct iwl_trans_txq_scd_cfg *cfg,
unsigned int queue_wdg_timeout);
int iwl_trans_get_rxq_dma_data(struct iwl_trans *trans, int queue,
struct iwl_trans_rxq_dma_data *data);
void iwl_trans_txq_free(struct iwl_trans *trans, int queue);
int iwl_trans_txq_alloc(struct iwl_trans *trans, u32 flags, u32 sta_mask,
u8 tid, int size, unsigned int wdg_timeout);
void iwl_trans_txq_set_shared_mode(struct iwl_trans *trans,
int txq_id, bool shared_mode);
static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
int fifo, int sta_id, int tid,
int frame_limit, u16 ssn,
unsigned int queue_wdg_timeout)
{
struct iwl_trans_txq_scd_cfg cfg = {
.fifo = fifo,
.sta_id = sta_id,
.tid = tid,
.frame_limit = frame_limit,
.aggregate = sta_id >= 0,
};
iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg, queue_wdg_timeout);
}
static inline
void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, int fifo,
unsigned int queue_wdg_timeout)
{
struct iwl_trans_txq_scd_cfg cfg = {
.fifo = fifo,
.sta_id = -1,
.tid = IWL_MAX_TID_COUNT,
.frame_limit = IWL_FRAME_LIMIT,
.aggregate = false,
};
iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg, queue_wdg_timeout);
}
void iwl_trans_freeze_txq_timer(struct iwl_trans *trans,
unsigned long txqs, bool freeze);
int iwl_trans_wait_tx_queues_empty(struct iwl_trans *trans, u32 txqs);
int iwl_trans_wait_txq_empty(struct iwl_trans *trans, int queue);
void iwl_trans_write8(struct iwl_trans *trans, u32 ofs, u8 val);
void iwl_trans_write32(struct iwl_trans *trans, u32 ofs, u32 val);
u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs);
u32 iwl_trans_read_prph(struct iwl_trans *trans, u32 ofs);
void iwl_trans_write_prph(struct iwl_trans *trans, u32 ofs, u32 val);
int iwl_trans_read_mem(struct iwl_trans *trans, u32 addr,
void *buf, int dwords);
int iwl_trans_read_mem_no_grab(struct iwl_trans *trans, u32 addr,
void *buf, u32 dwords);
int iwl_trans_read_config32(struct iwl_trans *trans, u32 ofs,
u32 *val);
#ifdef CONFIG_IWLWIFI_DEBUGFS
void iwl_trans_debugfs_cleanup(struct iwl_trans *trans);
#endif
#define iwl_trans_read_mem_bytes(trans, addr, buf, bufsize) \
({ \
if (__builtin_constant_p(bufsize)) \
BUILD_BUG_ON((bufsize) % sizeof(u32)); \
iwl_trans_read_mem(trans, addr, buf, \
(bufsize) / sizeof(u32)); \
})
static inline int
iwl_trans_read_mem_bytes_no_grab(struct iwl_trans *trans,
u32 addr, void *buf, u32 bufsize)
{
return iwl_trans_read_mem_no_grab(trans, addr, buf,
bufsize / sizeof(u32));
}
int iwl_trans_write_imr_mem(struct iwl_trans *trans, u32 dst_addr,
u64 src_addr, u32 byte_cnt);
static inline u32 iwl_trans_read_mem32(struct iwl_trans *trans, u32 addr)
{
u32 value;
if (iwl_trans_read_mem(trans, addr, &value, 1))
return 0xa5a5a5a5;
return value;
}
int iwl_trans_write_mem(struct iwl_trans *trans, u32 addr,
const void *buf, int dwords);
static inline u32 iwl_trans_write_mem32(struct iwl_trans *trans, u32 addr,
u32 val)
{
return iwl_trans_write_mem(trans, addr, &val, 1);
}
void iwl_trans_set_pmi(struct iwl_trans *trans, bool state);
int iwl_trans_sw_reset(struct iwl_trans *trans);
void iwl_trans_set_bits_mask(struct iwl_trans *trans, u32 reg,
u32 mask, u32 value);
bool iwl_trans_grab_nic_access(struct iwl_trans *trans);
void iwl_trans_resched_with_nic_access(struct iwl_trans *trans);
void __releases(nic_access)
iwl_trans_release_nic_access(struct iwl_trans *trans);
static inline void iwl_trans_schedule_reset(struct iwl_trans *trans,
enum iwl_fw_error_type type)
{
if (test_bit(STATUS_TRANS_DEAD, &trans->status))
return;
if (test_and_set_bit(STATUS_TRANS_RESET_IN_PROGRESS, &trans->status))
return;
trans->restart.mode.type = type;
trans->restart.mode.context = IWL_ERR_CONTEXT_WORKER;
set_bit(STATUS_RESET_PENDING, &trans->status);
trans->restart.during_reset = test_bit(STATUS_IN_SW_RESET,
&trans->status);
queue_delayed_work(system_dfl_wq, &trans->restart.wk, 0);
}
static inline void iwl_trans_fw_error(struct iwl_trans *trans,
enum iwl_fw_error_type type)
{
if (WARN_ON_ONCE(!trans->op_mode))
return;
if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status)) {
trans->state = IWL_TRANS_NO_FW;
iwl_op_mode_nic_error(trans->op_mode, type);
iwl_trans_schedule_reset(trans, type);
}
}
static inline void iwl_trans_opmode_sw_reset(struct iwl_trans *trans,
enum iwl_fw_error_type type)
{
if (WARN_ON_ONCE(!trans->op_mode))
return;
set_bit(STATUS_IN_SW_RESET, &trans->status);
if (WARN_ON(type == IWL_ERR_TYPE_TOP_RESET_BY_BT))
return;
if (!trans->op_mode->ops->sw_reset ||
!trans->op_mode->ops->sw_reset(trans->op_mode, type))
clear_bit(STATUS_IN_SW_RESET, &trans->status);
}
static inline bool iwl_trans_fw_running(struct iwl_trans *trans)
{
return trans->state == IWL_TRANS_FW_ALIVE;
}
void iwl_trans_sync_nmi(struct iwl_trans *trans);
void iwl_trans_sync_nmi_with_addr(struct iwl_trans *trans, u32 inta_addr,
u32 sw_err_bit);
int iwl_trans_load_pnvm(struct iwl_trans *trans,
const struct iwl_pnvm_image *pnvm_data,
const struct iwl_ucode_capabilities *capa);
void iwl_trans_set_pnvm(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa);
int iwl_trans_load_reduce_power(struct iwl_trans *trans,
const struct iwl_pnvm_image *payloads,
const struct iwl_ucode_capabilities *capa);
void iwl_trans_set_reduce_power(struct iwl_trans *trans,
const struct iwl_ucode_capabilities *capa);
static inline bool iwl_trans_dbg_ini_valid(struct iwl_trans *trans)
{
return trans->dbg.internal_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED ||
trans->dbg.external_ini_cfg != IWL_INI_CFG_STATE_NOT_LOADED;
}
void iwl_trans_interrupts(struct iwl_trans *trans, bool enable);
int iwl_trans_activate_nic(struct iwl_trans *trans);
static inline void iwl_trans_finish_sw_reset(struct iwl_trans *trans)
{
clear_bit(STATUS_IN_SW_RESET, &trans->status);
}
struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
struct device *dev,
const struct iwl_mac_cfg *mac_cfg);
void iwl_trans_free(struct iwl_trans *trans);
static inline bool iwl_trans_is_hw_error_value(u32 val)
{
return ((val & ~0xf) == 0xa5a5a5a0) || ((val & ~0xf) == 0x5a5a5a50);
}
void iwl_trans_free_restart_list(void);
static inline u16 iwl_trans_get_num_rbds(struct iwl_trans *trans)
{
u16 result = trans->cfg->num_rbds;
if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
return 2 * result;
return result;
}
static inline bool iwl_trans_device_enabled(struct iwl_trans *trans)
{
return test_bit(STATUS_DEVICE_ENABLED, &trans->status);
}
static inline bool iwl_trans_is_dead(struct iwl_trans *trans)
{
return test_bit(STATUS_TRANS_DEAD, &trans->status);
}
static inline bool iwl_trans_is_fw_error(struct iwl_trans *trans)
{
return test_bit(STATUS_FW_ERROR, &trans->status);
}
static inline void iwl_trans_notify_fw_error(struct iwl_trans *trans)
{
trans->state = IWL_TRANS_NO_FW;
set_bit(STATUS_FW_ERROR, &trans->status);
}
int __must_check iwl_pci_register_driver(void);
void iwl_pci_unregister_driver(void);
enum iwl_reset_mode {
IWL_RESET_MODE_SW_RESET,
IWL_RESET_MODE_REPROBE,
IWL_RESET_MODE_TOP_RESET,
IWL_RESET_MODE_REMOVE_ONLY,
IWL_RESET_MODE_RESCAN,
IWL_RESET_MODE_FUNC_RESET,
IWL_RESET_MODE_PROD_RESET,
IWL_RESET_MODE_BACKOFF,
};
void iwl_trans_pcie_reset(struct iwl_trans *trans, enum iwl_reset_mode mode);
void iwl_trans_pcie_fw_reset_handshake(struct iwl_trans *trans);
static inline void iwl_trans_set_info(struct iwl_trans *trans,
struct iwl_trans_info *info)
{
struct iwl_trans_info *write;
write = (void *)(uintptr_t)&trans->info;
*write = *info;
}
static inline u16 iwl_trans_get_device_id(struct iwl_trans *trans)
{
return u32_get_bits(trans->info.hw_id, GENMASK(31, 16));
}
bool iwl_trans_is_pm_supported(struct iwl_trans *trans);
bool iwl_trans_is_ltr_enabled(struct iwl_trans *trans);
static inline bool iwl_trans_is_top_reset_supported(struct iwl_trans *trans)
{
if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_SC)
return false;
if (trans->mac_cfg->device_family == IWL_DEVICE_FAMILY_SC &&
CSR_HW_REV_TYPE(trans->info.hw_rev) == IWL_CFG_MAC_TYPE_SC)
return false;
if (CSR_HW_RFID_TYPE(trans->info.hw_rf_id) < IWL_CFG_RF_TYPE_PE)
return false;
return true;
}
#endif