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;
};
#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;
uint8_t wt_hwqueue;
};
#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_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;
void *fws_alloc;
size_t fws_allocsize;
} 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;
bool lar_enabled;
};
#define IWM_MAX_CMD_TBS_PER_TFD 2
struct iwm_rx_packet;
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 done;
};
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;
};
#define IWM_RX_RING_COUNT 256
#define IWM_RBUF_COUNT (IWM_RX_RING_COUNT + 32)
#define IWM_RBUF_SIZE 4096
struct iwm_rx_data {
struct mbuf *m;
bus_dmamap_t map;
};
struct iwm_rx_ring {
struct iwm_dma_info desc_dma;
struct iwm_dma_info stat_dma;
struct iwm_dma_info buf_dma;
uint32_t *desc;
struct iwm_rb_status *stat;
struct iwm_rx_data data[IWM_RX_RING_COUNT];
int cur;
};
#define IWM_FLAG_USE_ICT __BIT(0)
#define IWM_FLAG_HW_INITED __BIT(1)
#define IWM_FLAG_STOPPED __BIT(2)
#define IWM_FLAG_RFKILL __BIT(3)
#define IWM_FLAG_SCANNING __BIT(4)
#define IWM_FLAG_ATTACHED __BIT(5)
#define IWM_FLAG_FW_LOADED __BIT(6)
#define IWM_FLAG_TE_ACTIVE __BIT(7)
#define IWM_FLAG_MAC_ACTIVE __BIT(8)
#define IWM_FLAG_BINDING_ACTIVE __BIT(9)
#define IWM_FLAG_STA_ACTIVE __BIT(10)
#define IWM_FLAG_BGSCAN __BIT(11)
#define IWM_FLAG_TXFLUSH __BIT(12)
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_IDLE -1
#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;
};
struct iwm_bf_data {
int bf_enabled;
int ba_enabled;
int ave_beacon_signal;
int last_cqm_event;
};
struct iwm_softc {
device_t sc_dev;
struct ethercom sc_ec;
struct ieee80211com sc_ic;
int attached;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
struct ieee80211_amrr sc_amrr;
struct callout sc_calib_to;
struct callout sc_led_blink_to;
bus_space_tag_t sc_st;
bus_space_handle_t sc_sh;
pci_intr_handle_t *sc_pihp;
bus_size_t sc_sz;
bus_dma_tag_t sc_dmat;
pci_chipset_tag_t sc_pct;
pcitag_t sc_pcitag;
pcireg_t sc_pciid;
const void *sc_ih;
void *sc_soft_ih;
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 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
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;
int sc_generation;
int sc_cap_off;
const char *sc_fwname;
bus_size_t sc_fwdmasegsz;
struct iwm_fw_info sc_fw;
int sc_fw_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;
int sc_rx_ba_sessions;
int sc_scan_last_antenna;
int sc_mgmt_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];
kmutex_t sc_nic_mtx;
int sc_nic_locks;
struct workqueue *sc_nswq;
struct workqueue *sc_setratewq;
struct iwm_rx_phy_info sc_last_phy_info;
int sc_ampdu_ref;
struct iwm_phy_ctxt sc_phyctxt[IWM_NUM_PHY_CTX];
uint32_t sc_time_event_uid;
struct iwm_notif_statistics sc_stats;
int sc_noise;
int sc_cmd_hold_nic_awake;
int host_interrupt_operation_mode;
int sc_ltr_enabled;
enum iwm_nvm_type nvm_type;
#ifdef notyet
int sc_mqrx_supported;
int sc_integrated;
int sc_ltr_delay;
int sc_xtal_latency;
int sc_low_latency_xtal;
#endif
int apmg_wake_up_wa;
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;
struct sysctllog *sc_clog;
struct bpf_if *sc_drvbpf;
kmutex_t sc_media_mtx;
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;
};
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 iwm_lq_cmd in_lq;
struct ieee80211_amrr_node in_amn;
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