struct iwm_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
uint64_t wr_tsft;
uint8_t wr_flags;
uint8_t wr_rate;
uint16_t wr_chan_freq;
uint16_t wr_chan_flags;
int8_t wr_dbm_antsignal;
int8_t wr_dbm_antnoise;
} __packed;
#define IWM_RX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_TSFT) | \
(1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE))
struct iwm_tx_radiotap_header {
struct ieee80211_radiotap_header wt_ihdr;
uint8_t wt_flags;
uint8_t wt_rate;
uint16_t wt_chan_freq;
uint16_t wt_chan_flags;
} __packed;
#define IWM_TX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL))
#define IWM_UCODE_SECT_MAX 16
#define IWM_FWDMASEGSZ (192*1024)
#define IWM_FWDMASEGSZ_8000 (320*1024)
#define IWM_FWMAXSIZE (2*1024*1024)
#define IWM_FW_STATUS_NONE 0
#define IWM_FW_STATUS_INPROGRESS 1
#define IWM_FW_STATUS_DONE 2
enum iwm_ucode_type {
IWM_UCODE_TYPE_REGULAR,
IWM_UCODE_TYPE_INIT,
IWM_UCODE_TYPE_WOW,
IWM_UCODE_TYPE_REGULAR_USNIFFER,
IWM_UCODE_TYPE_MAX
};
struct iwm_fw_info {
void *fw_rawdata;
size_t fw_rawsize;
int fw_status;
struct iwm_fw_sects {
struct iwm_fw_onesect {
void *fws_data;
uint32_t fws_len;
uint32_t fws_devoff;
} fw_sect[IWM_UCODE_SECT_MAX];
size_t fw_totlen;
int fw_count;
uint32_t paging_mem_size;
} fw_sects[IWM_UCODE_TYPE_MAX];
};
struct iwm_nvm_data {
int n_hw_addrs;
uint8_t hw_addr[ETHER_ADDR_LEN];
uint8_t calib_version;
uint16_t calib_voltage;
uint16_t raw_temperature;
uint16_t kelvin_temperature;
uint16_t kelvin_voltage;
uint16_t xtal_calib[2];
int sku_cap_band_24GHz_enable;
int sku_cap_band_52GHz_enable;
int sku_cap_11n_enable;
int sku_cap_11ac_enable;
int sku_cap_amt_enable;
int sku_cap_ipan_enable;
int sku_cap_mimo_disable;
uint8_t radio_cfg_type;
uint8_t radio_cfg_step;
uint8_t radio_cfg_dash;
uint8_t radio_cfg_pnum;
uint8_t valid_tx_ant, valid_rx_ant;
uint16_t nvm_version;
uint8_t max_tx_pwr_half_dbm;
int lar_enabled;
};
#define IWM_MAX_CMD_TBS_PER_TFD 2
struct iwm_host_cmd {
const void *data[IWM_MAX_CMD_TBS_PER_TFD];
struct iwm_rx_packet *resp_pkt;
size_t resp_pkt_len;
unsigned long _rx_page_addr;
uint32_t _rx_page_order;
int handler_status;
uint32_t flags;
uint16_t len[IWM_MAX_CMD_TBS_PER_TFD];
uint8_t dataflags[IWM_MAX_CMD_TBS_PER_TFD];
uint32_t id;
};
struct iwm_dma_info {
bus_dma_tag_t tag;
bus_dmamap_t map;
bus_dma_segment_t seg;
bus_addr_t paddr;
void *vaddr;
bus_size_t size;
};
struct iwm_fw_paging {
struct iwm_dma_info fw_paging_block;
uint32_t fw_paging_size;
};
#define IWM_TX_RING_COUNT 256
#define IWM_TX_RING_LOMARK 192
#define IWM_TX_RING_HIMARK 224
#define IWM_AGG_SSN_TO_TXQ_IDX(x) ((x) & (IWM_TX_RING_COUNT - 1))
struct iwm_tx_data {
bus_dmamap_t map;
bus_addr_t cmd_paddr;
bus_addr_t scratch_paddr;
struct mbuf *m;
struct iwm_node *in;
int txmcs;
int txrate;
int ampdu_txmcs;
int ampdu_txnss;
int ampdu_nframes;
};
struct iwm_tx_ring {
struct iwm_dma_info desc_dma;
struct iwm_dma_info cmd_dma;
struct iwm_tfd *desc;
struct iwm_device_cmd *cmd;
struct iwm_tx_data data[IWM_TX_RING_COUNT];
int qid;
int queued;
int cur;
int tail;
};
#define IWM_RX_MQ_RING_COUNT 512
#define IWM_RX_RING_COUNT 256
#define IWM_RBUF_SIZE 4096
struct iwm_rx_data {
struct mbuf *m;
bus_dmamap_t map;
};
struct iwm_rx_ring {
struct iwm_dma_info free_desc_dma;
struct iwm_dma_info stat_dma;
struct iwm_dma_info used_desc_dma;
void *desc;
struct iwm_rb_status *stat;
struct iwm_rx_data data[IWM_RX_MQ_RING_COUNT];
int cur;
};
#define IWM_FLAG_USE_ICT 0x01
#define IWM_FLAG_RFKILL 0x02
#define IWM_FLAG_SCANNING 0x04
#define IWM_FLAG_MAC_ACTIVE 0x08
#define IWM_FLAG_BINDING_ACTIVE 0x10
#define IWM_FLAG_STA_ACTIVE 0x20
#define IWM_FLAG_TE_ACTIVE 0x40
#define IWM_FLAG_HW_ERR 0x80
#define IWM_FLAG_SHUTDOWN 0x100
#define IWM_FLAG_BGSCAN 0x200
#define IWM_FLAG_TXFLUSH 0x400
struct iwm_ucode_status {
uint32_t uc_error_event_table;
uint32_t uc_umac_error_event_table;
uint32_t uc_log_event_table;
int uc_ok;
int uc_intr;
};
#define IWM_CMD_RESP_MAX PAGE_SIZE
#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 16384
#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 32768
#define IWM_TE_SESSION_PROTECTION_MAX_TIME_MS 1000
#define IWM_TE_SESSION_PROTECTION_MIN_TIME_MS 400
enum IWM_CMD_MODE {
IWM_CMD_ASYNC = (1 << 0),
IWM_CMD_WANT_RESP = (1 << 1),
IWM_CMD_SEND_IN_RFKILL = (1 << 2),
};
enum iwm_hcmd_dataflag {
IWM_HCMD_DFL_NOCOPY = (1 << 0),
IWM_HCMD_DFL_DUP = (1 << 1),
};
#define IWM_NUM_PAPD_CH_GROUPS 9
#define IWM_NUM_TXP_CH_GROUPS 9
struct iwm_phy_db_entry {
uint16_t size;
uint8_t *data;
};
struct iwm_phy_db {
struct iwm_phy_db_entry cfg;
struct iwm_phy_db_entry calib_nch;
struct iwm_phy_db_entry calib_ch_group_papd[IWM_NUM_PAPD_CH_GROUPS];
struct iwm_phy_db_entry calib_ch_group_txp[IWM_NUM_TXP_CH_GROUPS];
};
struct iwm_phy_ctxt {
uint16_t id;
uint16_t color;
uint32_t ref;
struct ieee80211_channel *channel;
uint8_t sco;
uint8_t vht_chan_width;
};
struct iwm_bf_data {
int bf_enabled;
int ba_enabled;
int ave_beacon_signal;
int last_cqm_event;
};
struct iwm_reorder_buffer {
uint16_t head_sn;
uint16_t num_stored;
uint16_t buf_size;
uint16_t last_amsdu;
uint8_t last_sub_index;
struct timeout reorder_timer;
int removed;
int valid;
unsigned int consec_oldsn_drops;
uint32_t consec_oldsn_ampdu_gp2;
unsigned int consec_oldsn_prev_drop;
#define IWM_AMPDU_CONSEC_DROPS_DELBA 10
};
struct iwm_reorder_buf_entry {
struct mbuf_list frames;
struct timeval reorder_time;
uint32_t rx_pkt_status;
int chanidx;
int is_shortpre;
uint32_t rate_n_flags;
uint32_t device_timestamp;
struct ieee80211_rxinfo rxi;
};
struct iwm_rxba_data {
uint8_t sta_id;
uint8_t tid;
uint8_t baid;
uint16_t timeout;
uint16_t entries_per_queue;
struct timeval last_rx;
struct timeout session_timer;
struct iwm_softc *sc;
struct iwm_reorder_buffer reorder_buf;
struct iwm_reorder_buf_entry entries[IEEE80211_BA_MAX_WINSZ];
};
static inline struct iwm_rxba_data *
iwm_rxba_data_from_reorder_buf(struct iwm_reorder_buffer *buf)
{
return (void *)((uint8_t *)buf -
offsetof(struct iwm_rxba_data, reorder_buf));
}
struct iwm_rxq_dup_data {
uint16_t last_seq[IWM_MAX_TID_COUNT + 1];
uint8_t last_sub_frame[IWM_MAX_TID_COUNT + 1];
};
struct iwm_ba_task_data {
uint32_t start_tidmask;
uint32_t stop_tidmask;
};
struct iwm_softc {
#ifdef __FreeBSD_version
device_t sc_dev;
#else
struct device sc_dev;
#endif
struct ieee80211com sc_ic;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
int sc_newstate_pending;
int attached;
struct ieee80211_amrr sc_amrr;
struct timeout sc_calib_to;
struct timeout sc_led_blink_to;
struct task init_task;
struct refcnt task_refs;
struct task newstate_task;
enum ieee80211_state ns_nstate;
int ns_arg;
int deauth_sent;
struct task ba_task;
struct iwm_ba_task_data ba_rx;
struct iwm_ba_task_data ba_tx;
struct task mac_ctxt_task;
struct task phy_ctxt_task;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
bus_size_t sc_sz;
bus_dma_tag_t sc_dmat;
#ifndef __FreeBSD_version
pci_chipset_tag_t sc_pct;
pcitag_t sc_pcitag;
#endif
const void *sc_ih;
int sc_msix;
struct iwm_dma_info sched_dma;
uint32_t sched_base;
struct iwm_tx_ring txq[IWM_MAX_QUEUES];
struct iwm_rx_ring rxq;
int qfullmsk;
int qenablemsk;
int cmdqid;
int sc_sf_state;
struct iwm_dma_info ict_dma;
int ict_cur;
int sc_hw_rev;
#define IWM_SILICON_A_STEP 0
#define IWM_SILICON_B_STEP 1
#define IWM_SILICON_C_STEP 2
#define IWM_SILICON_D_STEP 3
int sc_hw_id;
int sc_device_family;
#define IWM_DEVICE_FAMILY_7000 1
#define IWM_DEVICE_FAMILY_8000 2
#define IWM_DEVICE_FAMILY_9000 3
struct iwm_dma_info kw_dma;
struct iwm_dma_info fw_dma;
int sc_fw_chunk_done;
int sc_init_complete;
#define IWM_INIT_COMPLETE 0x01
#define IWM_CALIB_COMPLETE 0x02
struct iwm_ucode_status sc_uc;
enum iwm_ucode_type sc_uc_current;
char sc_fwver[32];
int sc_capaflags;
int sc_capa_max_probe_len;
int sc_capa_n_scan_channels;
uint8_t sc_ucode_api[howmany(IWM_NUM_UCODE_TLV_API, NBBY)];
uint8_t sc_enabled_capa[howmany(IWM_NUM_UCODE_TLV_CAPA, NBBY)];
#define IWM_MAX_FW_CMD_VERSIONS 64
struct iwm_fw_cmd_version cmd_versions[IWM_MAX_FW_CMD_VERSIONS];
int n_cmd_versions;
int sc_intmask;
int sc_flags;
uint32_t sc_fh_init_mask;
uint32_t sc_hw_init_mask;
uint32_t sc_fh_mask;
uint32_t sc_hw_mask;
int sc_generation;
struct rwlock ioctl_rwl;
int sc_cap_off;
const char *sc_fwname;
bus_size_t sc_fwdmasegsz;
size_t sc_nvm_max_section_size;
struct iwm_fw_info sc_fw;
uint32_t sc_fw_phy_config;
uint32_t sc_extra_phy_config;
struct iwm_tlv_calib_ctrl sc_default_calib[IWM_UCODE_TYPE_MAX];
struct iwm_nvm_data sc_nvm;
struct iwm_phy_db sc_phy_db;
struct iwm_bf_data sc_bf;
int sc_tx_timer[IWM_MAX_QUEUES];
int sc_rx_ba_sessions;
int tx_ba_queue_mask;
struct task bgscan_done_task;
struct ieee80211_node_switch_bss_arg *bgscan_unref_arg;
size_t bgscan_unref_arg_size;
int sc_scan_last_antenna;
int sc_fixed_ridx;
int sc_staid;
int sc_nodecolor;
uint8_t *sc_cmd_resp_pkt[IWM_TX_RING_COUNT];
size_t sc_cmd_resp_len[IWM_TX_RING_COUNT];
int sc_nic_locks;
struct taskq *sc_nswq;
struct iwm_rx_phy_info sc_last_phy_info;
int sc_ampdu_ref;
#define IWM_MAX_BAID 32
struct iwm_rxba_data sc_rxba_data[IWM_MAX_BAID];
uint32_t sc_time_event_uid;
struct iwm_phy_ctxt sc_phyctxt[IWM_NUM_PHY_CTX];
struct iwm_notif_statistics sc_stats;
int sc_noise;
int host_interrupt_operation_mode;
int sc_ltr_enabled;
enum iwm_nvm_type nvm_type;
int sc_mqrx_supported;
int sc_integrated;
int sc_ltr_delay;
int sc_xtal_latency;
int sc_low_latency_xtal;
struct iwm_fw_paging fw_paging_db[IWM_NUM_OF_FW_PAGING_BLOCKS];
uint16_t num_of_paging_blk;
uint16_t num_of_pages_in_last_blk;
#if NBPFILTER > 0
caddr_t sc_drvbpf;
union {
struct iwm_rx_radiotap_header th;
uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
} sc_rxtapu;
#define sc_rxtap sc_rxtapu.th
int sc_rxtap_len;
union {
struct iwm_tx_radiotap_header th;
uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
} sc_txtapu;
#define sc_txtap sc_txtapu.th
int sc_txtap_len;
#endif
};
struct iwm_node {
struct ieee80211_node in_ni;
struct iwm_phy_ctxt *in_phyctxt;
uint8_t in_macaddr[ETHER_ADDR_LEN];
uint16_t in_id;
uint16_t in_color;
struct ieee80211_amrr_node in_amn;
struct ieee80211_ra_node in_rn;
struct ieee80211_ra_vht_node in_rn_vht;
int lq_rate_mismatch;
struct iwm_rxq_dup_data dup_data;
uint32_t tfd_queue_msk;
uint16_t tid_disable_ampdu;
};
#define IWM_STATION_ID 0
#define IWM_AUX_STA_ID 1
#define IWM_MONITOR_STA_ID 2
#define IWM_ICT_SIZE 4096
#define IWM_ICT_COUNT (IWM_ICT_SIZE / sizeof (uint32_t))
#define IWM_ICT_PADDR_SHIFT 12