f67e656794
Obtained from: OpenBSD MFC after: 2 weeks
1718 lines
45 KiB
C
1718 lines
45 KiB
C
/* $FreeBSD$ */
|
|
/* $OpenBSD: if_iwnreg.h,v 1.40 2010/05/05 19:41:57 damien Exp $ */
|
|
|
|
/*-
|
|
* Copyright (c) 2007, 2008
|
|
* Damien Bergamini <damien.bergamini@free.fr>
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#define IWN_TX_RING_COUNT 256
|
|
#define IWN_TX_RING_LOMARK 192
|
|
#define IWN_TX_RING_HIMARK 224
|
|
#define IWN_RX_RING_COUNT_LOG 6
|
|
#define IWN_RX_RING_COUNT (1 << IWN_RX_RING_COUNT_LOG)
|
|
|
|
#define IWN4965_NTXQUEUES 16
|
|
#define IWN5000_NTXQUEUES 20
|
|
|
|
#define IWN4965_NDMACHNLS 7
|
|
#define IWN5000_NDMACHNLS 8
|
|
|
|
#define IWN_SRVC_DMACHNL 9
|
|
|
|
#define IWN_ICT_SIZE 4096
|
|
#define IWN_ICT_COUNT (IWN_ICT_SIZE / sizeof (uint32_t))
|
|
|
|
/* Maximum number of DMA segments for TX. */
|
|
#define IWN_MAX_SCATTER 20
|
|
|
|
/* RX buffers must be large enough to hold a full 4K A-MPDU. */
|
|
#define IWN_RBUF_SIZE (4 * 1024)
|
|
|
|
#if defined(__LP64__)
|
|
/* HW supports 36-bit DMA addresses. */
|
|
#define IWN_LOADDR(paddr) ((uint32_t)(paddr))
|
|
#define IWN_HIADDR(paddr) (((paddr) >> 32) & 0xf)
|
|
#else
|
|
#define IWN_LOADDR(paddr) (paddr)
|
|
#define IWN_HIADDR(paddr) (0)
|
|
#endif
|
|
|
|
/* Base Address Register. */
|
|
#define IWN_PCI_BAR0 PCI_MAPREG_START
|
|
|
|
/*
|
|
* Control and status registers.
|
|
*/
|
|
#define IWN_HW_IF_CONFIG 0x000
|
|
#define IWN_INT_COALESCING 0x004
|
|
#define IWN_INT_PERIODIC 0x005 /* use IWN_WRITE_1 */
|
|
#define IWN_INT 0x008
|
|
#define IWN_INT_MASK 0x00c
|
|
#define IWN_FH_INT 0x010
|
|
#define IWN_RESET 0x020
|
|
#define IWN_GP_CNTRL 0x024
|
|
#define IWN_HW_REV 0x028
|
|
#define IWN_EEPROM 0x02c
|
|
#define IWN_EEPROM_GP 0x030
|
|
#define IWN_OTP_GP 0x034
|
|
#define IWN_GIO 0x03c
|
|
#define IWN_GP_DRIVER 0x050
|
|
#define IWN_UCODE_GP1_CLR 0x05c
|
|
#define IWN_LED 0x094
|
|
#define IWN_DRAM_INT_TBL 0x0a0
|
|
#define IWN_GIO_CHICKEN 0x100
|
|
#define IWN_ANA_PLL 0x20c
|
|
#define IWN_HW_REV_WA 0x22c
|
|
#define IWN_DBG_HPET_MEM 0x240
|
|
#define IWN_DBG_LINK_PWR_MGMT 0x250
|
|
#define IWN_MEM_RADDR 0x40c
|
|
#define IWN_MEM_WADDR 0x410
|
|
#define IWN_MEM_WDATA 0x418
|
|
#define IWN_MEM_RDATA 0x41c
|
|
#define IWN_PRPH_WADDR 0x444
|
|
#define IWN_PRPH_RADDR 0x448
|
|
#define IWN_PRPH_WDATA 0x44c
|
|
#define IWN_PRPH_RDATA 0x450
|
|
#define IWN_HBUS_TARG_WRPTR 0x460
|
|
|
|
/*
|
|
* Flow-Handler registers.
|
|
*/
|
|
#define IWN_FH_TFBD_CTRL0(qid) (0x1900 + (qid) * 8)
|
|
#define IWN_FH_TFBD_CTRL1(qid) (0x1904 + (qid) * 8)
|
|
#define IWN_FH_KW_ADDR 0x197c
|
|
#define IWN_FH_SRAM_ADDR(qid) (0x19a4 + (qid) * 4)
|
|
#define IWN_FH_CBBC_QUEUE(qid) (0x19d0 + (qid) * 4)
|
|
#define IWN_FH_STATUS_WPTR 0x1bc0
|
|
#define IWN_FH_RX_BASE 0x1bc4
|
|
#define IWN_FH_RX_WPTR 0x1bc8
|
|
#define IWN_FH_RX_CONFIG 0x1c00
|
|
#define IWN_FH_RX_STATUS 0x1c44
|
|
#define IWN_FH_TX_CONFIG(qid) (0x1d00 + (qid) * 32)
|
|
#define IWN_FH_TXBUF_STATUS(qid) (0x1d08 + (qid) * 32)
|
|
#define IWN_FH_TX_CHICKEN 0x1e98
|
|
#define IWN_FH_TX_STATUS 0x1eb0
|
|
|
|
/*
|
|
* TX scheduler registers.
|
|
*/
|
|
#define IWN_SCHED_BASE 0xa02c00
|
|
#define IWN_SCHED_SRAM_ADDR (IWN_SCHED_BASE + 0x000)
|
|
#define IWN5000_SCHED_DRAM_ADDR (IWN_SCHED_BASE + 0x008)
|
|
#define IWN4965_SCHED_DRAM_ADDR (IWN_SCHED_BASE + 0x010)
|
|
#define IWN5000_SCHED_TXFACT (IWN_SCHED_BASE + 0x010)
|
|
#define IWN4965_SCHED_TXFACT (IWN_SCHED_BASE + 0x01c)
|
|
#define IWN4965_SCHED_QUEUE_RDPTR(qid) (IWN_SCHED_BASE + 0x064 + (qid) * 4)
|
|
#define IWN5000_SCHED_QUEUE_RDPTR(qid) (IWN_SCHED_BASE + 0x068 + (qid) * 4)
|
|
#define IWN4965_SCHED_QCHAIN_SEL (IWN_SCHED_BASE + 0x0d0)
|
|
#define IWN4965_SCHED_INTR_MASK (IWN_SCHED_BASE + 0x0e4)
|
|
#define IWN5000_SCHED_QCHAIN_SEL (IWN_SCHED_BASE + 0x0e8)
|
|
#define IWN4965_SCHED_QUEUE_STATUS(qid) (IWN_SCHED_BASE + 0x104 + (qid) * 4)
|
|
#define IWN5000_SCHED_INTR_MASK (IWN_SCHED_BASE + 0x108)
|
|
#define IWN5000_SCHED_QUEUE_STATUS(qid) (IWN_SCHED_BASE + 0x10c + (qid) * 4)
|
|
#define IWN5000_SCHED_AGGR_SEL (IWN_SCHED_BASE + 0x248)
|
|
|
|
/*
|
|
* Offsets in TX scheduler's SRAM.
|
|
*/
|
|
#define IWN4965_SCHED_CTX_OFF 0x380
|
|
#define IWN4965_SCHED_CTX_LEN 416
|
|
#define IWN4965_SCHED_QUEUE_OFFSET(qid) (0x380 + (qid) * 8)
|
|
#define IWN4965_SCHED_TRANS_TBL(qid) (0x500 + (qid) * 2)
|
|
#define IWN5000_SCHED_CTX_OFF 0x600
|
|
#define IWN5000_SCHED_CTX_LEN 520
|
|
#define IWN5000_SCHED_QUEUE_OFFSET(qid) (0x600 + (qid) * 8)
|
|
#define IWN5000_SCHED_TRANS_TBL(qid) (0x7e0 + (qid) * 2)
|
|
|
|
/*
|
|
* NIC internal memory offsets.
|
|
*/
|
|
#define IWN_APMG_CLK_CTRL 0x3000
|
|
#define IWN_APMG_CLK_EN 0x3004
|
|
#define IWN_APMG_CLK_DIS 0x3008
|
|
#define IWN_APMG_PS 0x300c
|
|
#define IWN_APMG_DIGITAL_SVR 0x3058
|
|
#define IWN_APMG_ANALOG_SVR 0x306c
|
|
#define IWN_APMG_PCI_STT 0x3010
|
|
#define IWN_BSM_WR_CTRL 0x3400
|
|
#define IWN_BSM_WR_MEM_SRC 0x3404
|
|
#define IWN_BSM_WR_MEM_DST 0x3408
|
|
#define IWN_BSM_WR_DWCOUNT 0x340c
|
|
#define IWN_BSM_DRAM_TEXT_ADDR 0x3490
|
|
#define IWN_BSM_DRAM_TEXT_SIZE 0x3494
|
|
#define IWN_BSM_DRAM_DATA_ADDR 0x3498
|
|
#define IWN_BSM_DRAM_DATA_SIZE 0x349c
|
|
#define IWN_BSM_SRAM_BASE 0x3800
|
|
|
|
/* Possible flags for register IWN_HW_IF_CONFIG. */
|
|
#define IWN_HW_IF_CONFIG_4965_R (1 << 4)
|
|
#define IWN_HW_IF_CONFIG_MAC_SI (1 << 8)
|
|
#define IWN_HW_IF_CONFIG_RADIO_SI (1 << 9)
|
|
#define IWN_HW_IF_CONFIG_EEPROM_LOCKED (1 << 21)
|
|
#define IWN_HW_IF_CONFIG_NIC_READY (1 << 22)
|
|
#define IWN_HW_IF_CONFIG_HAP_WAKE_L1A (1 << 23)
|
|
#define IWN_HW_IF_CONFIG_PREPARE_DONE (1 << 25)
|
|
#define IWN_HW_IF_CONFIG_PREPARE (1 << 27)
|
|
|
|
/* Possible values for register IWN_INT_PERIODIC. */
|
|
#define IWN_INT_PERIODIC_DIS 0x00
|
|
#define IWN_INT_PERIODIC_ENA 0xff
|
|
|
|
/* Possible flags for registers IWN_PRPH_RADDR/IWN_PRPH_WADDR. */
|
|
#define IWN_PRPH_DWORD ((sizeof (uint32_t) - 1) << 24)
|
|
|
|
/* Possible values for IWN_BSM_WR_MEM_DST. */
|
|
#define IWN_FW_TEXT_BASE 0x00000000
|
|
#define IWN_FW_DATA_BASE 0x00800000
|
|
|
|
/* Possible flags for register IWN_RESET. */
|
|
#define IWN_RESET_NEVO (1 << 0)
|
|
#define IWN_RESET_SW (1 << 7)
|
|
#define IWN_RESET_MASTER_DISABLED (1 << 8)
|
|
#define IWN_RESET_STOP_MASTER (1 << 9)
|
|
#define IWN_RESET_LINK_PWR_MGMT_DIS (1 << 31)
|
|
|
|
/* Possible flags for register IWN_GP_CNTRL. */
|
|
#define IWN_GP_CNTRL_MAC_ACCESS_ENA (1 << 0)
|
|
#define IWN_GP_CNTRL_MAC_CLOCK_READY (1 << 0)
|
|
#define IWN_GP_CNTRL_INIT_DONE (1 << 2)
|
|
#define IWN_GP_CNTRL_MAC_ACCESS_REQ (1 << 3)
|
|
#define IWN_GP_CNTRL_SLEEP (1 << 4)
|
|
#define IWN_GP_CNTRL_RFKILL (1 << 27)
|
|
|
|
/* Possible flags for register IWN_HW_REV. */
|
|
#define IWN_HW_REV_TYPE_SHIFT 4
|
|
#define IWN_HW_REV_TYPE_MASK 0x000000f0
|
|
#define IWN_HW_REV_TYPE_4965 0
|
|
#define IWN_HW_REV_TYPE_5300 2
|
|
#define IWN_HW_REV_TYPE_5350 3
|
|
#define IWN_HW_REV_TYPE_5150 4
|
|
#define IWN_HW_REV_TYPE_5100 5
|
|
#define IWN_HW_REV_TYPE_1000 6
|
|
#define IWN_HW_REV_TYPE_6000 7
|
|
#define IWN_HW_REV_TYPE_6050 8
|
|
#define IWN_HW_REV_TYPE_6005 11
|
|
|
|
/* Possible flags for register IWN_GIO_CHICKEN. */
|
|
#define IWN_GIO_CHICKEN_L1A_NO_L0S_RX (1 << 23)
|
|
#define IWN_GIO_CHICKEN_DIS_L0S_TIMER (1 << 29)
|
|
|
|
/* Possible flags for register IWN_GIO. */
|
|
#define IWN_GIO_L0S_ENA (1 << 1)
|
|
|
|
/* Possible flags for register IWN_GP_DRIVER. */
|
|
#define IWN_GP_DRIVER_RADIO_3X3_HYB (0 << 0)
|
|
#define IWN_GP_DRIVER_RADIO_2X2_HYB (1 << 0)
|
|
#define IWN_GP_DRIVER_RADIO_2X2_IPA (2 << 0)
|
|
#define IWN_GP_DRIVER_CALIB_VER6 (1 << 2)
|
|
|
|
/* Possible flags for register IWN_UCODE_GP1_CLR. */
|
|
#define IWN_UCODE_GP1_RFKILL (1 << 1)
|
|
#define IWN_UCODE_GP1_CMD_BLOCKED (1 << 2)
|
|
#define IWN_UCODE_GP1_CTEMP_STOP_RF (1 << 3)
|
|
|
|
/* Possible flags/values for register IWN_LED. */
|
|
#define IWN_LED_BSM_CTRL (1 << 5)
|
|
#define IWN_LED_OFF 0x00000038
|
|
#define IWN_LED_ON 0x00000078
|
|
|
|
/* Possible flags for register IWN_DRAM_INT_TBL. */
|
|
#define IWN_DRAM_INT_TBL_WRAP_CHECK (1 << 27)
|
|
#define IWN_DRAM_INT_TBL_ENABLE (1 << 31)
|
|
|
|
/* Possible values for register IWN_ANA_PLL. */
|
|
#define IWN_ANA_PLL_INIT 0x00880300
|
|
|
|
/* Possible flags for register IWN_FH_RX_STATUS. */
|
|
#define IWN_FH_RX_STATUS_IDLE (1 << 24)
|
|
|
|
/* Possible flags for register IWN_BSM_WR_CTRL. */
|
|
#define IWN_BSM_WR_CTRL_START_EN (1 << 30)
|
|
#define IWN_BSM_WR_CTRL_START (1 << 31)
|
|
|
|
/* Possible flags for register IWN_INT. */
|
|
#define IWN_INT_ALIVE (1 << 0)
|
|
#define IWN_INT_WAKEUP (1 << 1)
|
|
#define IWN_INT_SW_RX (1 << 3)
|
|
#define IWN_INT_CT_REACHED (1 << 6)
|
|
#define IWN_INT_RF_TOGGLED (1 << 7)
|
|
#define IWN_INT_SW_ERR (1 << 25)
|
|
#define IWN_INT_SCHED (1 << 26)
|
|
#define IWN_INT_FH_TX (1 << 27)
|
|
#define IWN_INT_RX_PERIODIC (1 << 28)
|
|
#define IWN_INT_HW_ERR (1 << 29)
|
|
#define IWN_INT_FH_RX (1 << 31)
|
|
|
|
/* Shortcut. */
|
|
#define IWN_INT_MASK_DEF \
|
|
(IWN_INT_SW_ERR | IWN_INT_HW_ERR | IWN_INT_FH_TX | \
|
|
IWN_INT_FH_RX | IWN_INT_ALIVE | IWN_INT_WAKEUP | \
|
|
IWN_INT_SW_RX | IWN_INT_CT_REACHED | IWN_INT_RF_TOGGLED)
|
|
|
|
/* Possible flags for register IWN_FH_INT. */
|
|
#define IWN_FH_INT_TX_CHNL(x) (1 << (x))
|
|
#define IWN_FH_INT_RX_CHNL(x) (1 << ((x) + 16))
|
|
#define IWN_FH_INT_HI_PRIOR (1 << 30)
|
|
/* Shortcuts for the above. */
|
|
#define IWN_FH_INT_TX \
|
|
(IWN_FH_INT_TX_CHNL(0) | IWN_FH_INT_TX_CHNL(1))
|
|
#define IWN_FH_INT_RX \
|
|
(IWN_FH_INT_RX_CHNL(0) | IWN_FH_INT_RX_CHNL(1) | IWN_FH_INT_HI_PRIOR)
|
|
|
|
/* Possible flags/values for register IWN_FH_TX_CONFIG. */
|
|
#define IWN_FH_TX_CONFIG_DMA_PAUSE 0
|
|
#define IWN_FH_TX_CONFIG_DMA_ENA (1 << 31)
|
|
#define IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD (1 << 20)
|
|
|
|
/* Possible flags/values for register IWN_FH_TXBUF_STATUS. */
|
|
#define IWN_FH_TXBUF_STATUS_TBNUM(x) ((x) << 20)
|
|
#define IWN_FH_TXBUF_STATUS_TBIDX(x) ((x) << 12)
|
|
#define IWN_FH_TXBUF_STATUS_TFBD_VALID 3
|
|
|
|
/* Possible flags for register IWN_FH_TX_CHICKEN. */
|
|
#define IWN_FH_TX_CHICKEN_SCHED_RETRY (1 << 1)
|
|
|
|
/* Possible flags for register IWN_FH_TX_STATUS. */
|
|
#define IWN_FH_TX_STATUS_IDLE(chnl) \
|
|
(1 << ((chnl) + 24) | 1 << ((chnl) + 16))
|
|
|
|
/* Possible flags for register IWN_FH_RX_CONFIG. */
|
|
#define IWN_FH_RX_CONFIG_ENA (1 << 31)
|
|
#define IWN_FH_RX_CONFIG_NRBD(x) ((x) << 20)
|
|
#define IWN_FH_RX_CONFIG_RB_SIZE_8K (1 << 16)
|
|
#define IWN_FH_RX_CONFIG_SINGLE_FRAME (1 << 15)
|
|
#define IWN_FH_RX_CONFIG_IRQ_DST_HOST (1 << 12)
|
|
#define IWN_FH_RX_CONFIG_RB_TIMEOUT(x) ((x) << 4)
|
|
#define IWN_FH_RX_CONFIG_IGN_RXF_EMPTY (1 << 2)
|
|
|
|
/* Possible flags for register IWN_FH_TX_CONFIG. */
|
|
#define IWN_FH_TX_CONFIG_DMA_ENA (1 << 31)
|
|
#define IWN_FH_TX_CONFIG_DMA_CREDIT_ENA (1 << 3)
|
|
|
|
/* Possible flags for register IWN_EEPROM. */
|
|
#define IWN_EEPROM_READ_VALID (1 << 0)
|
|
#define IWN_EEPROM_CMD (1 << 1)
|
|
|
|
/* Possible flags for register IWN_EEPROM_GP. */
|
|
#define IWN_EEPROM_GP_IF_OWNER 0x00000180
|
|
|
|
/* Possible flags for register IWN_OTP_GP. */
|
|
#define IWN_OTP_GP_DEV_SEL_OTP (1 << 16)
|
|
#define IWN_OTP_GP_RELATIVE_ACCESS (1 << 17)
|
|
#define IWN_OTP_GP_ECC_CORR_STTS (1 << 20)
|
|
#define IWN_OTP_GP_ECC_UNCORR_STTS (1 << 21)
|
|
|
|
/* Possible flags for register IWN_SCHED_QUEUE_STATUS. */
|
|
#define IWN4965_TXQ_STATUS_ACTIVE 0x0007fc01
|
|
#define IWN4965_TXQ_STATUS_INACTIVE 0x0007fc00
|
|
#define IWN4965_TXQ_STATUS_AGGR_ENA (1 << 5 | 1 << 8)
|
|
#define IWN4965_TXQ_STATUS_CHGACT (1 << 10)
|
|
#define IWN5000_TXQ_STATUS_ACTIVE 0x00ff0018
|
|
#define IWN5000_TXQ_STATUS_INACTIVE 0x00ff0010
|
|
#define IWN5000_TXQ_STATUS_CHGACT (1 << 19)
|
|
|
|
/* Possible flags for registers IWN_APMG_CLK_*. */
|
|
#define IWN_APMG_CLK_CTRL_DMA_CLK_RQT (1 << 9)
|
|
#define IWN_APMG_CLK_CTRL_BSM_CLK_RQT (1 << 11)
|
|
|
|
/* Possible flags for register IWN_APMG_PS. */
|
|
#define IWN_APMG_PS_EARLY_PWROFF_DIS (1 << 22)
|
|
#define IWN_APMG_PS_PWR_SRC(x) ((x) << 24)
|
|
#define IWN_APMG_PS_PWR_SRC_VMAIN 0
|
|
#define IWN_APMG_PS_PWR_SRC_VAUX 2
|
|
#define IWN_APMG_PS_PWR_SRC_MASK IWN_APMG_PS_PWR_SRC(3)
|
|
#define IWN_APMG_PS_RESET_REQ (1 << 26)
|
|
|
|
/* Possible flags for register IWN_APMG_DIGITAL_SVR. */
|
|
#define IWN_APMG_DIGITAL_SVR_VOLTAGE(x) (((x) & 0xf) << 5)
|
|
#define IWN_APMG_DIGITAL_SVR_VOLTAGE_MASK \
|
|
IWN_APMG_DIGITAL_SVR_VOLTAGE(0xf)
|
|
#define IWN_APMG_DIGITAL_SVR_VOLTAGE_1_32 \
|
|
IWN_APMG_DIGITAL_SVR_VOLTAGE(3)
|
|
|
|
/* Possible flags for IWN_APMG_PCI_STT. */
|
|
#define IWN_APMG_PCI_STT_L1A_DIS (1 << 11)
|
|
|
|
/* Possible flags for register IWN_BSM_DRAM_TEXT_SIZE. */
|
|
#define IWN_FW_UPDATED (1 << 31)
|
|
|
|
#define IWN_SCHED_WINSZ 64
|
|
#define IWN_SCHED_LIMIT 64
|
|
#define IWN4965_SCHED_COUNT 512
|
|
#define IWN5000_SCHED_COUNT (IWN_TX_RING_COUNT + IWN_SCHED_WINSZ)
|
|
#define IWN4965_SCHEDSZ (IWN4965_NTXQUEUES * IWN4965_SCHED_COUNT * 2)
|
|
#define IWN5000_SCHEDSZ (IWN5000_NTXQUEUES * IWN5000_SCHED_COUNT * 2)
|
|
|
|
struct iwn_tx_desc {
|
|
uint8_t reserved1[3];
|
|
uint8_t nsegs;
|
|
struct {
|
|
uint32_t addr;
|
|
uint16_t len;
|
|
} __packed segs[IWN_MAX_SCATTER];
|
|
/* Pad to 128 bytes. */
|
|
uint32_t reserved2;
|
|
} __packed;
|
|
|
|
struct iwn_rx_status {
|
|
uint16_t closed_count;
|
|
uint16_t closed_rx_count;
|
|
uint16_t finished_count;
|
|
uint16_t finished_rx_count;
|
|
uint32_t reserved[2];
|
|
} __packed;
|
|
|
|
struct iwn_rx_desc {
|
|
uint32_t len;
|
|
uint8_t type;
|
|
#define IWN_UC_READY 1
|
|
#define IWN_ADD_NODE_DONE 24
|
|
#define IWN_TX_DONE 28
|
|
#define IWN5000_CALIBRATION_RESULT 102
|
|
#define IWN5000_CALIBRATION_DONE 103
|
|
#define IWN_START_SCAN 130
|
|
#define IWN_STOP_SCAN 132
|
|
#define IWN_RX_STATISTICS 156
|
|
#define IWN_BEACON_STATISTICS 157
|
|
#define IWN_STATE_CHANGED 161
|
|
#define IWN_BEACON_MISSED 162
|
|
#define IWN_RX_PHY 192
|
|
#define IWN_MPDU_RX_DONE 193
|
|
#define IWN_RX_DONE 195
|
|
#define IWN_RX_COMPRESSED_BA 197
|
|
|
|
uint8_t flags;
|
|
uint8_t idx;
|
|
uint8_t qid;
|
|
} __packed;
|
|
|
|
/* Possible RX status flags. */
|
|
#define IWN_RX_NO_CRC_ERR (1 << 0)
|
|
#define IWN_RX_NO_OVFL_ERR (1 << 1)
|
|
/* Shortcut for the above. */
|
|
#define IWN_RX_NOERROR (IWN_RX_NO_CRC_ERR | IWN_RX_NO_OVFL_ERR)
|
|
#define IWN_RX_MPDU_MIC_OK (1 << 6)
|
|
#define IWN_RX_CIPHER_MASK (7 << 8)
|
|
#define IWN_RX_CIPHER_CCMP (2 << 8)
|
|
#define IWN_RX_MPDU_DEC (1 << 11)
|
|
#define IWN_RX_DECRYPT_MASK (3 << 11)
|
|
#define IWN_RX_DECRYPT_OK (3 << 11)
|
|
|
|
struct iwn_tx_cmd {
|
|
uint8_t code;
|
|
#define IWN_CMD_RXON 16
|
|
#define IWN_CMD_RXON_ASSOC 17
|
|
#define IWN_CMD_EDCA_PARAMS 19
|
|
#define IWN_CMD_TIMING 20
|
|
#define IWN_CMD_ADD_NODE 24
|
|
#define IWN_CMD_TX_DATA 28
|
|
#define IWN_CMD_LINK_QUALITY 78
|
|
#define IWN_CMD_SET_LED 72
|
|
#define IWN5000_CMD_WIMAX_COEX 90
|
|
#define IWN5000_CMD_CALIB_CONFIG 101
|
|
#define IWN5000_CMD_CALIB_RESULT 102
|
|
#define IWN5000_CMD_CALIB_COMPLETE 103
|
|
#define IWN_CMD_SET_POWER_MODE 119
|
|
#define IWN_CMD_SCAN 128
|
|
#define IWN_CMD_SCAN_RESULTS 131
|
|
#define IWN_CMD_TXPOWER_DBM 149
|
|
#define IWN_CMD_TXPOWER 151
|
|
#define IWN5000_CMD_TX_ANT_CONFIG 152
|
|
#define IWN_CMD_BT_COEX 155
|
|
#define IWN_CMD_GET_STATISTICS 156
|
|
#define IWN_CMD_SET_CRITICAL_TEMP 164
|
|
#define IWN_CMD_SET_SENSITIVITY 168
|
|
#define IWN_CMD_PHY_CALIB 176
|
|
|
|
uint8_t flags;
|
|
uint8_t idx;
|
|
uint8_t qid;
|
|
uint8_t data[136];
|
|
} __packed;
|
|
|
|
/* Antenna flags, used in various commands. */
|
|
#define IWN_ANT_A (1 << 0)
|
|
#define IWN_ANT_B (1 << 1)
|
|
#define IWN_ANT_C (1 << 2)
|
|
/* Shortcuts. */
|
|
#define IWN_ANT_AB (IWN_ANT_A | IWN_ANT_B)
|
|
#define IWN_ANT_BC (IWN_ANT_B | IWN_ANT_C)
|
|
#define IWN_ANT_ABC (IWN_ANT_A | IWN_ANT_B | IWN_ANT_C)
|
|
|
|
/* Structure for command IWN_CMD_RXON. */
|
|
struct iwn_rxon {
|
|
uint8_t myaddr[IEEE80211_ADDR_LEN];
|
|
uint16_t reserved1;
|
|
uint8_t bssid[IEEE80211_ADDR_LEN];
|
|
uint16_t reserved2;
|
|
uint8_t wlap[IEEE80211_ADDR_LEN];
|
|
uint16_t reserved3;
|
|
uint8_t mode;
|
|
#define IWN_MODE_HOSTAP 1
|
|
#define IWN_MODE_STA 3
|
|
#define IWN_MODE_IBSS 4
|
|
#define IWN_MODE_MONITOR 6
|
|
|
|
uint8_t air;
|
|
uint16_t rxchain;
|
|
#define IWN_RXCHAIN_DRIVER_FORCE (1 << 0)
|
|
#define IWN_RXCHAIN_VALID(x) (((x) & IWN_ANT_ABC) << 1)
|
|
#define IWN_RXCHAIN_FORCE_SEL(x) (((x) & IWN_ANT_ABC) << 4)
|
|
#define IWN_RXCHAIN_FORCE_MIMO_SEL(x) (((x) & IWN_ANT_ABC) << 7)
|
|
#define IWN_RXCHAIN_IDLE_COUNT(x) ((x) << 10)
|
|
#define IWN_RXCHAIN_MIMO_COUNT(x) ((x) << 12)
|
|
#define IWN_RXCHAIN_MIMO_FORCE (1 << 14)
|
|
|
|
uint8_t ofdm_mask;
|
|
uint8_t cck_mask;
|
|
uint16_t associd;
|
|
uint32_t flags;
|
|
#define IWN_RXON_24GHZ (1 << 0)
|
|
#define IWN_RXON_CCK (1 << 1)
|
|
#define IWN_RXON_AUTO (1 << 2)
|
|
#define IWN_RXON_SHSLOT (1 << 4)
|
|
#define IWN_RXON_SHPREAMBLE (1 << 5)
|
|
#define IWN_RXON_NODIVERSITY (1 << 7)
|
|
#define IWN_RXON_ANTENNA_A (1 << 8)
|
|
#define IWN_RXON_ANTENNA_B (1 << 9)
|
|
#define IWN_RXON_TSF (1 << 15)
|
|
#define IWN_RXON_CTS_TO_SELF (1 << 30)
|
|
|
|
uint32_t filter;
|
|
#define IWN_FILTER_PROMISC (1 << 0)
|
|
#define IWN_FILTER_CTL (1 << 1)
|
|
#define IWN_FILTER_MULTICAST (1 << 2)
|
|
#define IWN_FILTER_NODECRYPT (1 << 3)
|
|
#define IWN_FILTER_BSS (1 << 5)
|
|
#define IWN_FILTER_BEACON (1 << 6)
|
|
|
|
uint8_t chan;
|
|
uint8_t reserved4;
|
|
uint8_t ht_single_mask;
|
|
uint8_t ht_dual_mask;
|
|
/* The following fields are for >=5000 Series only. */
|
|
uint8_t ht_triple_mask;
|
|
uint8_t reserved5;
|
|
uint16_t acquisition;
|
|
uint16_t reserved6;
|
|
} __packed;
|
|
|
|
#define IWN4965_RXONSZ (sizeof (struct iwn_rxon) - 6)
|
|
#define IWN5000_RXONSZ (sizeof (struct iwn_rxon))
|
|
|
|
/* Structure for command IWN_CMD_ASSOCIATE. */
|
|
struct iwn_assoc {
|
|
uint32_t flags;
|
|
uint32_t filter;
|
|
uint8_t ofdm_mask;
|
|
uint8_t cck_mask;
|
|
uint16_t reserved;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_EDCA_PARAMS. */
|
|
struct iwn_edca_params {
|
|
uint32_t flags;
|
|
#define IWN_EDCA_UPDATE (1 << 0)
|
|
#define IWN_EDCA_TXOP (1 << 4)
|
|
|
|
struct {
|
|
uint16_t cwmin;
|
|
uint16_t cwmax;
|
|
uint8_t aifsn;
|
|
uint8_t reserved;
|
|
uint16_t txoplimit;
|
|
} __packed ac[WME_NUM_AC];
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_TIMING. */
|
|
struct iwn_cmd_timing {
|
|
uint64_t tstamp;
|
|
uint16_t bintval;
|
|
uint16_t atim;
|
|
uint32_t binitval;
|
|
uint16_t lintval;
|
|
uint16_t reserved;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_ADD_NODE. */
|
|
struct iwn_node_info {
|
|
uint8_t control;
|
|
#define IWN_NODE_UPDATE (1 << 0)
|
|
|
|
uint8_t reserved1[3];
|
|
|
|
uint8_t macaddr[IEEE80211_ADDR_LEN];
|
|
uint16_t reserved2;
|
|
uint8_t id;
|
|
#define IWN_ID_BSS 0
|
|
#define IWN5000_ID_BROADCAST 15
|
|
#define IWN4965_ID_BROADCAST 31
|
|
|
|
uint8_t flags;
|
|
#define IWN_FLAG_SET_KEY (1 << 0)
|
|
#define IWN_FLAG_SET_DISABLE_TID (1 << 1)
|
|
#define IWN_FLAG_SET_TXRATE (1 << 2)
|
|
#define IWN_FLAG_SET_ADDBA (1 << 3)
|
|
#define IWN_FLAG_SET_DELBA (1 << 4)
|
|
|
|
uint16_t reserved3;
|
|
uint16_t kflags;
|
|
#define IWN_KFLAG_CCMP (1 << 1)
|
|
#define IWN_KFLAG_MAP (1 << 3)
|
|
#define IWN_KFLAG_KID(kid) ((kid) << 8)
|
|
#define IWN_KFLAG_INVALID (1 << 11)
|
|
#define IWN_KFLAG_GROUP (1 << 14)
|
|
|
|
uint8_t tsc2; /* TKIP TSC2 */
|
|
uint8_t reserved4;
|
|
uint16_t ttak[5];
|
|
uint8_t kid;
|
|
uint8_t reserved5;
|
|
uint8_t key[16];
|
|
/* The following 3 fields are for 5000 Series only. */
|
|
uint64_t tsc;
|
|
uint8_t rxmic[8];
|
|
uint8_t txmic[8];
|
|
|
|
uint32_t htflags;
|
|
#define IWN_AMDPU_SIZE_FACTOR(x) ((x) << 19)
|
|
#define IWN_AMDPU_DENSITY(x) ((x) << 23)
|
|
|
|
uint32_t mask;
|
|
uint16_t disable_tid;
|
|
uint16_t reserved6;
|
|
uint8_t addba_tid;
|
|
uint8_t delba_tid;
|
|
uint16_t addba_ssn;
|
|
uint32_t reserved7;
|
|
} __packed;
|
|
|
|
struct iwn4965_node_info {
|
|
uint8_t control;
|
|
uint8_t reserved1[3];
|
|
uint8_t macaddr[IEEE80211_ADDR_LEN];
|
|
uint16_t reserved2;
|
|
uint8_t id;
|
|
uint8_t flags;
|
|
uint16_t reserved3;
|
|
uint16_t kflags;
|
|
uint8_t tsc2; /* TKIP TSC2 */
|
|
uint8_t reserved4;
|
|
uint16_t ttak[5];
|
|
uint8_t kid;
|
|
uint8_t reserved5;
|
|
uint8_t key[16];
|
|
uint32_t htflags;
|
|
uint32_t mask;
|
|
uint16_t disable_tid;
|
|
uint16_t reserved6;
|
|
uint8_t addba_tid;
|
|
uint8_t delba_tid;
|
|
uint16_t addba_ssn;
|
|
uint32_t reserved7;
|
|
} __packed;
|
|
|
|
#define IWN_RFLAG_CCK (1 << 1)
|
|
#define IWN_RFLAG_ANT(x) ((x) << 6)
|
|
|
|
/* Structure for command IWN_CMD_TX_DATA. */
|
|
struct iwn_cmd_data {
|
|
uint16_t len;
|
|
uint16_t lnext;
|
|
uint32_t flags;
|
|
#define IWN_TX_NEED_PROTECTION (1 << 0) /* 5000 only */
|
|
#define IWN_TX_NEED_RTS (1 << 1)
|
|
#define IWN_TX_NEED_CTS (1 << 2)
|
|
#define IWN_TX_NEED_ACK (1 << 3)
|
|
#define IWN_TX_LINKQ (1 << 4)
|
|
#define IWN_TX_IMM_BA (1 << 6)
|
|
#define IWN_TX_FULL_TXOP (1 << 7)
|
|
#define IWN_TX_BT_DISABLE (1 << 12) /* bluetooth coexistence */
|
|
#define IWN_TX_AUTO_SEQ (1 << 13)
|
|
#define IWN_TX_MORE_FRAG (1 << 14)
|
|
#define IWN_TX_INSERT_TSTAMP (1 << 16)
|
|
#define IWN_TX_NEED_PADDING (1 << 20)
|
|
|
|
uint32_t scratch;
|
|
uint8_t plcp;
|
|
uint8_t rflags;
|
|
uint16_t xrflags;
|
|
|
|
uint8_t id;
|
|
uint8_t security;
|
|
#define IWN_CIPHER_WEP40 1
|
|
#define IWN_CIPHER_CCMP 2
|
|
#define IWN_CIPHER_TKIP 3
|
|
#define IWN_CIPHER_WEP104 9
|
|
|
|
uint8_t linkq;
|
|
uint8_t reserved2;
|
|
uint8_t key[16];
|
|
uint16_t fnext;
|
|
uint16_t reserved3;
|
|
uint32_t lifetime;
|
|
#define IWN_LIFETIME_INFINITE 0xffffffff
|
|
|
|
uint32_t loaddr;
|
|
uint8_t hiaddr;
|
|
uint8_t rts_ntries;
|
|
uint8_t data_ntries;
|
|
uint8_t tid;
|
|
uint16_t timeout;
|
|
uint16_t txop;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_LINK_QUALITY. */
|
|
#define IWN_MAX_TX_RETRIES 16
|
|
struct iwn_cmd_link_quality {
|
|
uint8_t id;
|
|
uint8_t reserved1;
|
|
uint16_t ctl;
|
|
uint8_t flags;
|
|
uint8_t mimo;
|
|
uint8_t antmsk_1stream;
|
|
uint8_t antmsk_2stream;
|
|
uint8_t ridx[WME_NUM_AC];
|
|
uint16_t ampdu_limit;
|
|
uint8_t ampdu_threshold;
|
|
uint8_t ampdu_max;
|
|
uint32_t reserved2;
|
|
struct {
|
|
uint8_t plcp;
|
|
uint8_t rflags;
|
|
uint16_t xrflags;
|
|
} __packed retry[IWN_MAX_TX_RETRIES];
|
|
uint32_t reserved3;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_SET_LED. */
|
|
struct iwn_cmd_led {
|
|
uint32_t unit; /* multiplier (in usecs) */
|
|
uint8_t which;
|
|
#define IWN_LED_ACTIVITY 1
|
|
#define IWN_LED_LINK 2
|
|
|
|
uint8_t off;
|
|
uint8_t on;
|
|
uint8_t reserved;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN5000_CMD_WIMAX_COEX. */
|
|
struct iwn5000_wimax_coex {
|
|
uint32_t flags;
|
|
#define IWN_WIMAX_COEX_STA_TABLE_VALID (1 << 0)
|
|
#define IWN_WIMAX_COEX_UNASSOC_WA_UNMASK (1 << 2)
|
|
#define IWN_WIMAX_COEX_ASSOC_WA_UNMASK (1 << 3)
|
|
#define IWN_WIMAX_COEX_ENABLE (1 << 7)
|
|
|
|
struct iwn5000_wimax_event {
|
|
uint8_t request;
|
|
uint8_t window;
|
|
uint8_t reserved;
|
|
uint8_t flags;
|
|
} __packed events[16];
|
|
} __packed;
|
|
|
|
/* Structures for command IWN5000_CMD_CALIB_CONFIG. */
|
|
struct iwn5000_calib_elem {
|
|
uint32_t enable;
|
|
uint32_t start;
|
|
uint32_t send;
|
|
uint32_t apply;
|
|
uint32_t reserved;
|
|
} __packed;
|
|
|
|
struct iwn5000_calib_status {
|
|
struct iwn5000_calib_elem once;
|
|
struct iwn5000_calib_elem perd;
|
|
uint32_t flags;
|
|
} __packed;
|
|
|
|
struct iwn5000_calib_config {
|
|
struct iwn5000_calib_status ucode;
|
|
struct iwn5000_calib_status driver;
|
|
uint32_t reserved;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_SET_POWER_MODE. */
|
|
struct iwn_pmgt_cmd {
|
|
uint16_t flags;
|
|
#define IWN_PS_ALLOW_SLEEP (1 << 0)
|
|
#define IWN_PS_NOTIFY (1 << 1)
|
|
#define IWN_PS_SLEEP_OVER_DTIM (1 << 2)
|
|
#define IWN_PS_PCI_PMGT (1 << 3)
|
|
#define IWN_PS_FAST_PD (1 << 4)
|
|
|
|
uint8_t keepalive;
|
|
uint8_t debug;
|
|
uint32_t rxtimeout;
|
|
uint32_t txtimeout;
|
|
uint32_t intval[5];
|
|
uint32_t beacons;
|
|
} __packed;
|
|
|
|
/* Structures for command IWN_CMD_SCAN. */
|
|
struct iwn_scan_essid {
|
|
uint8_t id;
|
|
uint8_t len;
|
|
uint8_t data[IEEE80211_NWID_LEN];
|
|
} __packed;
|
|
|
|
struct iwn_scan_hdr {
|
|
uint16_t len;
|
|
uint8_t reserved1;
|
|
uint8_t nchan;
|
|
uint16_t quiet_time;
|
|
uint16_t quiet_threshold;
|
|
uint16_t crc_threshold;
|
|
uint16_t rxchain;
|
|
uint32_t max_svc; /* background scans */
|
|
uint32_t pause_svc; /* background scans */
|
|
uint32_t flags;
|
|
uint32_t filter;
|
|
|
|
/* Followed by a struct iwn_cmd_data. */
|
|
/* Followed by an array of 20 structs iwn_scan_essid. */
|
|
/* Followed by probe request body. */
|
|
/* Followed by an array of ``nchan'' structs iwn_scan_chan. */
|
|
} __packed;
|
|
|
|
struct iwn_scan_chan {
|
|
uint32_t flags;
|
|
#define IWN_CHAN_ACTIVE (1 << 0)
|
|
#define IWN_CHAN_NPBREQS(x) (((1 << (x)) - 1) << 1)
|
|
|
|
uint16_t chan;
|
|
uint8_t rf_gain;
|
|
uint8_t dsp_gain;
|
|
uint16_t active; /* msecs */
|
|
uint16_t passive; /* msecs */
|
|
} __packed;
|
|
|
|
/* Maximum size of a scan command. */
|
|
#define IWN_SCAN_MAXSZ (MCLBYTES - 4)
|
|
|
|
/* Structure for command IWN_CMD_TXPOWER (4965AGN only.) */
|
|
#define IWN_RIDX_MAX 32
|
|
struct iwn4965_cmd_txpower {
|
|
uint8_t band;
|
|
uint8_t reserved1;
|
|
uint8_t chan;
|
|
uint8_t reserved2;
|
|
struct {
|
|
uint8_t rf_gain[2];
|
|
uint8_t dsp_gain[2];
|
|
} __packed power[IWN_RIDX_MAX + 1];
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_TXPOWER_DBM (5000 Series only.) */
|
|
struct iwn5000_cmd_txpower {
|
|
int8_t global_limit; /* in half-dBm */
|
|
#define IWN5000_TXPOWER_AUTO 0x7f
|
|
#define IWN5000_TXPOWER_MAX_DBM 16
|
|
|
|
uint8_t flags;
|
|
#define IWN5000_TXPOWER_NO_CLOSED (1 << 6)
|
|
|
|
int8_t srv_limit; /* in half-dBm */
|
|
uint8_t reserved;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_BLUETOOTH. */
|
|
struct iwn_bluetooth {
|
|
uint8_t flags;
|
|
#define IWN_BT_COEX_CHAN_ANN (1 << 0)
|
|
#define IWN_BT_COEX_BT_PRIO (1 << 1)
|
|
#define IWN_BT_COEX_2_WIRE (1 << 2)
|
|
|
|
uint8_t lead_time;
|
|
#define IWN_BT_LEAD_TIME_DEF 30
|
|
|
|
uint8_t max_kill;
|
|
#define IWN_BT_MAX_KILL_DEF 5
|
|
|
|
uint8_t reserved;
|
|
uint32_t kill_ack;
|
|
uint32_t kill_cts;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_SET_CRITICAL_TEMP. */
|
|
struct iwn_critical_temp {
|
|
uint32_t reserved;
|
|
uint32_t tempM;
|
|
uint32_t tempR;
|
|
/* degK <-> degC conversion macros. */
|
|
#define IWN_CTOK(c) ((c) + 273)
|
|
#define IWN_KTOC(k) ((k) - 273)
|
|
#define IWN_CTOMUK(c) (((c) * 1000000) + 273150000)
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_SET_SENSITIVITY. */
|
|
struct iwn_sensitivity_cmd {
|
|
uint16_t which;
|
|
#define IWN_SENSITIVITY_DEFAULTTBL 0
|
|
#define IWN_SENSITIVITY_WORKTBL 1
|
|
|
|
uint16_t energy_cck;
|
|
uint16_t energy_ofdm;
|
|
uint16_t corr_ofdm_x1;
|
|
uint16_t corr_ofdm_mrc_x1;
|
|
uint16_t corr_cck_mrc_x4;
|
|
uint16_t corr_ofdm_x4;
|
|
uint16_t corr_ofdm_mrc_x4;
|
|
uint16_t corr_barker;
|
|
uint16_t corr_barker_mrc;
|
|
uint16_t corr_cck_x4;
|
|
uint16_t energy_ofdm_th;
|
|
} __packed;
|
|
|
|
/* Structures for command IWN_CMD_PHY_CALIB. */
|
|
struct iwn_phy_calib {
|
|
uint8_t code;
|
|
#define IWN4965_PHY_CALIB_DIFF_GAIN 7
|
|
#define IWN5000_PHY_CALIB_DC 8
|
|
#define IWN5000_PHY_CALIB_LO 9
|
|
#define IWN5000_PHY_CALIB_TX_IQ 11
|
|
#define IWN5000_PHY_CALIB_CRYSTAL 15
|
|
#define IWN5000_PHY_CALIB_BASE_BAND 16
|
|
#define IWN5000_PHY_CALIB_TX_IQ_PERIODIC 17
|
|
#define IWN5000_PHY_CALIB_RESET_NOISE_GAIN 18
|
|
#define IWN5000_PHY_CALIB_NOISE_GAIN 19
|
|
|
|
uint8_t group;
|
|
uint8_t ngroups;
|
|
uint8_t isvalid;
|
|
} __packed;
|
|
|
|
struct iwn5000_phy_calib_crystal {
|
|
uint8_t code;
|
|
uint8_t group;
|
|
uint8_t ngroups;
|
|
uint8_t isvalid;
|
|
|
|
uint8_t cap_pin[2];
|
|
uint8_t reserved[2];
|
|
} __packed;
|
|
|
|
struct iwn_phy_calib_gain {
|
|
uint8_t code;
|
|
uint8_t group;
|
|
uint8_t ngroups;
|
|
uint8_t isvalid;
|
|
|
|
int8_t gain[3];
|
|
uint8_t reserved;
|
|
} __packed;
|
|
|
|
/* Structure for command IWN_CMD_SPECTRUM_MEASUREMENT. */
|
|
struct iwn_spectrum_cmd {
|
|
uint16_t len;
|
|
uint8_t token;
|
|
uint8_t id;
|
|
uint8_t origin;
|
|
uint8_t periodic;
|
|
uint16_t timeout;
|
|
uint32_t start;
|
|
uint32_t reserved1;
|
|
uint32_t flags;
|
|
uint32_t filter;
|
|
uint16_t nchan;
|
|
uint16_t reserved2;
|
|
struct {
|
|
uint32_t duration;
|
|
uint8_t chan;
|
|
uint8_t type;
|
|
#define IWN_MEASUREMENT_BASIC (1 << 0)
|
|
#define IWN_MEASUREMENT_CCA (1 << 1)
|
|
#define IWN_MEASUREMENT_RPI_HISTOGRAM (1 << 2)
|
|
#define IWN_MEASUREMENT_NOISE_HISTOGRAM (1 << 3)
|
|
#define IWN_MEASUREMENT_FRAME (1 << 4)
|
|
#define IWN_MEASUREMENT_IDLE (1 << 7)
|
|
|
|
uint16_t reserved;
|
|
} __packed chan[10];
|
|
} __packed;
|
|
|
|
/* Structure for IWN_UC_READY notification. */
|
|
#define IWN_NATTEN_GROUPS 5
|
|
struct iwn_ucode_info {
|
|
uint8_t minor;
|
|
uint8_t major;
|
|
uint16_t reserved1;
|
|
uint8_t revision[8];
|
|
uint8_t type;
|
|
uint8_t subtype;
|
|
#define IWN_UCODE_RUNTIME 0
|
|
#define IWN_UCODE_INIT 9
|
|
|
|
uint16_t reserved2;
|
|
uint32_t logptr;
|
|
uint32_t errptr;
|
|
uint32_t tstamp;
|
|
uint32_t valid;
|
|
|
|
/* The following fields are for UCODE_INIT only. */
|
|
int32_t volt;
|
|
struct {
|
|
int32_t chan20MHz;
|
|
int32_t chan40MHz;
|
|
} __packed temp[4];
|
|
int32_t atten[IWN_NATTEN_GROUPS][2];
|
|
} __packed;
|
|
|
|
/* Structures for IWN_TX_DONE notification. */
|
|
#define IWN_TX_SUCCESS 0x00
|
|
#define IWN_TX_FAIL 0x80 /* all failures have 0x80 set */
|
|
#define IWN_TX_FAIL_SHORT_LIMIT 0x82 /* too many RTS retries */
|
|
#define IWN_TX_FAIL_LONG_LIMIT 0x83 /* too many retries */
|
|
#define IWN_TX_FAIL_FIFO_UNDERRRUN 0x84 /* tx fifo not kept running */
|
|
#define IWN_TX_FAIL_DEST_IN_PS 0x88 /* sta found in power save */
|
|
#define IWN_TX_FAIL_TX_LOCKED 0x90 /* waiting to see traffic */
|
|
|
|
struct iwn4965_tx_stat {
|
|
uint8_t nframes;
|
|
uint8_t btkillcnt;
|
|
uint8_t rtsfailcnt;
|
|
uint8_t ackfailcnt;
|
|
uint8_t rate;
|
|
uint8_t rflags;
|
|
uint16_t xrflags;
|
|
uint16_t duration;
|
|
uint16_t reserved;
|
|
uint32_t power[2];
|
|
uint32_t status;
|
|
} __packed;
|
|
|
|
struct iwn5000_tx_stat {
|
|
uint8_t nframes;
|
|
uint8_t btkillcnt;
|
|
uint8_t rtsfailcnt;
|
|
uint8_t ackfailcnt;
|
|
uint8_t rate;
|
|
uint8_t rflags;
|
|
uint16_t xrflags;
|
|
uint16_t duration;
|
|
uint16_t reserved;
|
|
uint32_t power[2];
|
|
uint32_t info;
|
|
uint16_t seq;
|
|
uint16_t len;
|
|
uint8_t tlc;
|
|
uint8_t ratid;
|
|
uint8_t fc[2];
|
|
uint16_t status;
|
|
uint16_t sequence;
|
|
} __packed;
|
|
|
|
/* Structure for IWN_BEACON_MISSED notification. */
|
|
struct iwn_beacon_missed {
|
|
uint32_t consecutive;
|
|
uint32_t total;
|
|
uint32_t expected;
|
|
uint32_t received;
|
|
} __packed;
|
|
|
|
/* Structure for IWN_MPDU_RX_DONE notification. */
|
|
struct iwn_rx_mpdu {
|
|
uint16_t len;
|
|
uint16_t reserved;
|
|
} __packed;
|
|
|
|
/* Structures for IWN_RX_DONE and IWN_MPDU_RX_DONE notifications. */
|
|
struct iwn4965_rx_phystat {
|
|
uint16_t antenna;
|
|
uint16_t agc;
|
|
uint8_t rssi[6];
|
|
} __packed;
|
|
|
|
struct iwn5000_rx_phystat {
|
|
uint32_t reserved1;
|
|
uint32_t agc;
|
|
uint16_t rssi[3];
|
|
} __packed;
|
|
|
|
struct iwn_rx_stat {
|
|
uint8_t phy_len;
|
|
uint8_t cfg_phy_len;
|
|
#define IWN_STAT_MAXLEN 20
|
|
|
|
uint8_t id;
|
|
uint8_t reserved1;
|
|
uint64_t tstamp;
|
|
uint32_t beacon;
|
|
uint16_t flags;
|
|
#define IWN_STAT_FLAG_SHPREAMBLE (1 << 2)
|
|
|
|
uint16_t chan;
|
|
uint8_t phybuf[32];
|
|
uint8_t rate;
|
|
uint8_t rflags;
|
|
uint16_t xrflags;
|
|
uint16_t len;
|
|
uint16_t reserve3;
|
|
} __packed;
|
|
|
|
#define IWN_RSSI_TO_DBM 44
|
|
|
|
/* Structure for IWN_RX_COMPRESSED_BA notification. */
|
|
struct iwn_compressed_ba {
|
|
uint8_t macaddr[IEEE80211_ADDR_LEN];
|
|
uint16_t reserved;
|
|
uint8_t id;
|
|
uint8_t tid;
|
|
uint16_t seq;
|
|
uint64_t bitmap;
|
|
uint16_t qid;
|
|
uint16_t ssn;
|
|
} __packed;
|
|
|
|
/* Structure for IWN_START_SCAN notification. */
|
|
struct iwn_start_scan {
|
|
uint64_t tstamp;
|
|
uint32_t tbeacon;
|
|
uint8_t chan;
|
|
uint8_t band;
|
|
uint16_t reserved;
|
|
uint32_t status;
|
|
} __packed;
|
|
|
|
/* Structure for IWN_STOP_SCAN notification. */
|
|
struct iwn_stop_scan {
|
|
uint8_t nchan;
|
|
uint8_t status;
|
|
uint8_t reserved;
|
|
uint8_t chan;
|
|
uint64_t tsf;
|
|
} __packed;
|
|
|
|
/* Structure for IWN_SPECTRUM_MEASUREMENT notification. */
|
|
struct iwn_spectrum_notif {
|
|
uint8_t id;
|
|
uint8_t token;
|
|
uint8_t idx;
|
|
uint8_t state;
|
|
#define IWN_MEASUREMENT_START 0
|
|
#define IWN_MEASUREMENT_STOP 1
|
|
|
|
uint32_t start;
|
|
uint8_t band;
|
|
uint8_t chan;
|
|
uint8_t type;
|
|
uint8_t reserved1;
|
|
uint32_t cca_ofdm;
|
|
uint32_t cca_cck;
|
|
uint32_t cca_time;
|
|
uint8_t basic;
|
|
uint8_t reserved2[3];
|
|
uint32_t ofdm[8];
|
|
uint32_t cck[8];
|
|
uint32_t stop;
|
|
uint32_t status;
|
|
#define IWN_MEASUREMENT_OK 0
|
|
#define IWN_MEASUREMENT_CONCURRENT 1
|
|
#define IWN_MEASUREMENT_CSA_CONFLICT 2
|
|
#define IWN_MEASUREMENT_TGH_CONFLICT 3
|
|
#define IWN_MEASUREMENT_STOPPED 6
|
|
#define IWN_MEASUREMENT_TIMEOUT 7
|
|
#define IWN_MEASUREMENT_FAILED 8
|
|
} __packed;
|
|
|
|
/* Structures for IWN_{RX,BEACON}_STATISTICS notification. */
|
|
struct iwn_rx_phy_stats {
|
|
uint32_t ina;
|
|
uint32_t fina;
|
|
uint32_t bad_plcp;
|
|
uint32_t bad_crc32;
|
|
uint32_t overrun;
|
|
uint32_t eoverrun;
|
|
uint32_t good_crc32;
|
|
uint32_t fa;
|
|
uint32_t bad_fina_sync;
|
|
uint32_t sfd_timeout;
|
|
uint32_t fina_timeout;
|
|
uint32_t no_rts_ack;
|
|
uint32_t rxe_limit;
|
|
uint32_t ack;
|
|
uint32_t cts;
|
|
uint32_t ba_resp;
|
|
uint32_t dsp_kill;
|
|
uint32_t bad_mh;
|
|
uint32_t rssi_sum;
|
|
uint32_t reserved;
|
|
} __packed;
|
|
|
|
struct iwn_rx_general_stats {
|
|
uint32_t bad_cts;
|
|
uint32_t bad_ack;
|
|
uint32_t not_bss;
|
|
uint32_t filtered;
|
|
uint32_t bad_chan;
|
|
uint32_t beacons;
|
|
uint32_t missed_beacons;
|
|
uint32_t adc_saturated; /* time in 0.8us */
|
|
uint32_t ina_searched; /* time in 0.8us */
|
|
uint32_t noise[3];
|
|
uint32_t flags;
|
|
uint32_t load;
|
|
uint32_t fa;
|
|
uint32_t rssi[3];
|
|
uint32_t energy[3];
|
|
} __packed;
|
|
|
|
struct iwn_rx_ht_phy_stats {
|
|
uint32_t bad_plcp;
|
|
uint32_t overrun;
|
|
uint32_t eoverrun;
|
|
uint32_t good_crc32;
|
|
uint32_t bad_crc32;
|
|
uint32_t bad_mh;
|
|
uint32_t good_ampdu_crc32;
|
|
uint32_t ampdu;
|
|
uint32_t fragment;
|
|
uint32_t reserved;
|
|
} __packed;
|
|
|
|
struct iwn_rx_stats {
|
|
struct iwn_rx_phy_stats ofdm;
|
|
struct iwn_rx_phy_stats cck;
|
|
struct iwn_rx_general_stats general;
|
|
struct iwn_rx_ht_phy_stats ht;
|
|
} __packed;
|
|
|
|
struct iwn_tx_stats {
|
|
uint32_t preamble;
|
|
uint32_t rx_detected;
|
|
uint32_t bt_defer;
|
|
uint32_t bt_kill;
|
|
uint32_t short_len;
|
|
uint32_t cts_timeout;
|
|
uint32_t ack_timeout;
|
|
uint32_t exp_ack;
|
|
uint32_t ack;
|
|
uint32_t msdu;
|
|
uint32_t busrt_err1;
|
|
uint32_t burst_err2;
|
|
uint32_t cts_collision;
|
|
uint32_t ack_collision;
|
|
uint32_t ba_timeout;
|
|
uint32_t ba_resched;
|
|
uint32_t query_ampdu;
|
|
uint32_t query;
|
|
uint32_t query_ampdu_frag;
|
|
uint32_t query_mismatch;
|
|
uint32_t not_ready;
|
|
uint32_t underrun;
|
|
uint32_t bt_ht_kill;
|
|
uint32_t rx_ba_resp;
|
|
uint32_t reserved[2];
|
|
} __packed;
|
|
|
|
struct iwn_general_stats {
|
|
uint32_t temp;
|
|
uint32_t temp_m;
|
|
uint32_t burst_check;
|
|
uint32_t burst;
|
|
uint32_t reserved1[4];
|
|
uint32_t sleep;
|
|
uint32_t slot_out;
|
|
uint32_t slot_idle;
|
|
uint32_t ttl_tstamp;
|
|
uint32_t tx_ant_a;
|
|
uint32_t tx_ant_b;
|
|
uint32_t exec;
|
|
uint32_t probe;
|
|
uint32_t reserved2[2];
|
|
uint32_t rx_enabled;
|
|
uint32_t reserved3[3];
|
|
} __packed;
|
|
|
|
struct iwn_stats {
|
|
uint32_t flags;
|
|
struct iwn_rx_stats rx;
|
|
struct iwn_tx_stats tx;
|
|
struct iwn_general_stats general;
|
|
} __packed;
|
|
|
|
|
|
/* Firmware error dump. */
|
|
struct iwn_fw_dump {
|
|
uint32_t valid;
|
|
uint32_t id;
|
|
uint32_t pc;
|
|
uint32_t branch_link[2];
|
|
uint32_t interrupt_link[2];
|
|
uint32_t error_data[2];
|
|
uint32_t src_line;
|
|
uint32_t tsf;
|
|
uint32_t time[2];
|
|
} __packed;
|
|
|
|
/* TLV firmware header. */
|
|
struct iwn_fw_tlv_hdr {
|
|
uint32_t zero; /* Always 0, to differentiate from legacy. */
|
|
uint32_t signature;
|
|
#define IWN_FW_SIGNATURE 0x0a4c5749 /* "IWL\n" */
|
|
|
|
uint8_t descr[64];
|
|
uint32_t rev;
|
|
#define IWN_FW_API(x) (((x) >> 8) & 0xff)
|
|
|
|
uint32_t build;
|
|
uint64_t altmask;
|
|
} __packed;
|
|
|
|
/* TLV header. */
|
|
struct iwn_fw_tlv {
|
|
uint16_t type;
|
|
#define IWN_FW_TLV_MAIN_TEXT 1
|
|
#define IWN_FW_TLV_MAIN_DATA 2
|
|
#define IWN_FW_TLV_INIT_TEXT 3
|
|
#define IWN_FW_TLV_INIT_DATA 4
|
|
#define IWN_FW_TLV_BOOT_TEXT 5
|
|
#define IWN_FW_TLV_PBREQ_MAXLEN 6
|
|
|
|
uint16_t alt;
|
|
uint32_t len;
|
|
} __packed;
|
|
|
|
#define IWN4965_FW_TEXT_MAXSZ ( 96 * 1024)
|
|
#define IWN4965_FW_DATA_MAXSZ ( 40 * 1024)
|
|
#define IWN5000_FW_TEXT_MAXSZ (256 * 1024)
|
|
#define IWN5000_FW_DATA_MAXSZ ( 80 * 1024)
|
|
#define IWN_FW_BOOT_TEXT_MAXSZ 1024
|
|
#define IWN4965_FWSZ (IWN4965_FW_TEXT_MAXSZ + IWN4965_FW_DATA_MAXSZ)
|
|
#define IWN5000_FWSZ IWN5000_FW_TEXT_MAXSZ
|
|
|
|
/*
|
|
* Offsets into EEPROM.
|
|
*/
|
|
#define IWN_EEPROM_MAC 0x015
|
|
#define IWN_EEPROM_RFCFG 0x048
|
|
#define IWN4965_EEPROM_DOMAIN 0x060
|
|
#define IWN4965_EEPROM_BAND1 0x063
|
|
#define IWN5000_EEPROM_REG 0x066
|
|
#define IWN5000_EEPROM_CAL 0x067
|
|
#define IWN4965_EEPROM_BAND2 0x072
|
|
#define IWN4965_EEPROM_BAND3 0x080
|
|
#define IWN4965_EEPROM_BAND4 0x08d
|
|
#define IWN4965_EEPROM_BAND5 0x099
|
|
#define IWN4965_EEPROM_BAND6 0x0a0
|
|
#define IWN4965_EEPROM_BAND7 0x0a8
|
|
#define IWN4965_EEPROM_MAXPOW 0x0e8
|
|
#define IWN4965_EEPROM_VOLTAGE 0x0e9
|
|
#define IWN4965_EEPROM_BANDS 0x0ea
|
|
/* Indirect offsets. */
|
|
#define IWN5000_EEPROM_DOMAIN 0x001
|
|
#define IWN5000_EEPROM_BAND1 0x004
|
|
#define IWN5000_EEPROM_BAND2 0x013
|
|
#define IWN5000_EEPROM_BAND3 0x021
|
|
#define IWN5000_EEPROM_BAND4 0x02e
|
|
#define IWN5000_EEPROM_BAND5 0x03a
|
|
#define IWN5000_EEPROM_BAND6 0x041
|
|
#define IWN5000_EEPROM_BAND7 0x049
|
|
#define IWN6000_EEPROM_ENHINFO 0x054
|
|
#define IWN5000_EEPROM_CRYSTAL 0x128
|
|
#define IWN5000_EEPROM_TEMP 0x12a
|
|
#define IWN5000_EEPROM_VOLT 0x12b
|
|
|
|
/* Possible flags for IWN_EEPROM_RFCFG. */
|
|
#define IWN_RFCFG_TYPE(x) (((x) >> 0) & 0x3)
|
|
#define IWN_RFCFG_STEP(x) (((x) >> 2) & 0x3)
|
|
#define IWN_RFCFG_DASH(x) (((x) >> 4) & 0x3)
|
|
#define IWN_RFCFG_TXANTMSK(x) (((x) >> 8) & 0xf)
|
|
#define IWN_RFCFG_RXANTMSK(x) (((x) >> 12) & 0xf)
|
|
|
|
struct iwn_eeprom_chan {
|
|
uint8_t flags;
|
|
#define IWN_EEPROM_CHAN_VALID (1 << 0)
|
|
#define IWN_EEPROM_CHAN_IBSS (1 << 1)
|
|
#define IWN_EEPROM_CHAN_ACTIVE (1 << 3)
|
|
#define IWN_EEPROM_CHAN_RADAR (1 << 4)
|
|
|
|
int8_t maxpwr;
|
|
} __packed;
|
|
|
|
struct iwn_eeprom_enhinfo {
|
|
uint16_t chan;
|
|
int8_t chain[3]; /* max power in half-dBm */
|
|
uint8_t reserved;
|
|
int8_t mimo2; /* max power in half-dBm */
|
|
int8_t mimo3; /* max power in half-dBm */
|
|
} __packed;
|
|
|
|
struct iwn5000_eeprom_calib_hdr {
|
|
uint8_t version;
|
|
uint8_t pa_type;
|
|
uint16_t volt;
|
|
} __packed;
|
|
|
|
#define IWN_NSAMPLES 3
|
|
struct iwn4965_eeprom_chan_samples {
|
|
uint8_t num;
|
|
struct {
|
|
uint8_t temp;
|
|
uint8_t gain;
|
|
uint8_t power;
|
|
int8_t pa_det;
|
|
} samples[2][IWN_NSAMPLES];
|
|
} __packed;
|
|
|
|
#define IWN_NBANDS 8
|
|
struct iwn4965_eeprom_band {
|
|
uint8_t lo; /* low channel number */
|
|
uint8_t hi; /* high channel number */
|
|
struct iwn4965_eeprom_chan_samples chans[2];
|
|
} __packed;
|
|
|
|
/*
|
|
* Offsets of channels descriptions in EEPROM.
|
|
*/
|
|
static const uint32_t iwn4965_regulatory_bands[IWN_NBANDS] = {
|
|
IWN4965_EEPROM_BAND1,
|
|
IWN4965_EEPROM_BAND2,
|
|
IWN4965_EEPROM_BAND3,
|
|
IWN4965_EEPROM_BAND4,
|
|
IWN4965_EEPROM_BAND5,
|
|
IWN4965_EEPROM_BAND6,
|
|
IWN4965_EEPROM_BAND7
|
|
};
|
|
|
|
static const uint32_t iwn5000_regulatory_bands[IWN_NBANDS] = {
|
|
IWN5000_EEPROM_BAND1,
|
|
IWN5000_EEPROM_BAND2,
|
|
IWN5000_EEPROM_BAND3,
|
|
IWN5000_EEPROM_BAND4,
|
|
IWN5000_EEPROM_BAND5,
|
|
IWN5000_EEPROM_BAND6,
|
|
IWN5000_EEPROM_BAND7
|
|
};
|
|
|
|
#define IWN_CHAN_BANDS_COUNT 7
|
|
#define IWN_MAX_CHAN_PER_BAND 14
|
|
static const struct iwn_chan_band {
|
|
uint8_t nchan;
|
|
uint8_t chan[IWN_MAX_CHAN_PER_BAND];
|
|
} iwn_bands[] = {
|
|
/* 20MHz channels, 2GHz band. */
|
|
{ 14, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } },
|
|
/* 20MHz channels, 5GHz band. */
|
|
{ 13, { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } },
|
|
{ 12, { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } },
|
|
{ 11, { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } },
|
|
{ 6, { 145, 149, 153, 157, 161, 165 } },
|
|
/* 40MHz channels (primary channels), 2GHz band. */
|
|
{ 7, { 1, 2, 3, 4, 5, 6, 7 } },
|
|
/* 40MHz channels (primary channels), 5GHz band. */
|
|
{ 11, { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } }
|
|
};
|
|
|
|
#define IWN1000_OTP_NBLOCKS 3
|
|
#define IWN6000_OTP_NBLOCKS 4
|
|
#define IWN6050_OTP_NBLOCKS 7
|
|
|
|
/* HW rate indices. */
|
|
#define IWN_RIDX_CCK1 0
|
|
#define IWN_RIDX_CCK11 3
|
|
#define IWN_RIDX_OFDM6 4
|
|
#define IWN_RIDX_OFDM54 11
|
|
|
|
static const struct iwn_rate {
|
|
uint8_t rate;
|
|
uint8_t plcp;
|
|
uint8_t flags;
|
|
} iwn_rates[IWN_RIDX_MAX + 1] = {
|
|
{ 2, 10, IWN_RFLAG_CCK },
|
|
{ 4, 20, IWN_RFLAG_CCK },
|
|
{ 11, 55, IWN_RFLAG_CCK },
|
|
{ 22, 110, IWN_RFLAG_CCK },
|
|
{ 12, 0xd, 0 },
|
|
{ 18, 0xf, 0 },
|
|
{ 24, 0x5, 0 },
|
|
{ 36, 0x7, 0 },
|
|
{ 48, 0x9, 0 },
|
|
{ 72, 0xb, 0 },
|
|
{ 96, 0x1, 0 },
|
|
{ 108, 0x3, 0 },
|
|
{ 120, 0x3, 0 }
|
|
};
|
|
|
|
#define IWN4965_MAX_PWR_INDEX 107
|
|
|
|
/*
|
|
* RF Tx gain values from highest to lowest power (values obtained from
|
|
* the reference driver.)
|
|
*/
|
|
static const uint8_t iwn4965_rf_gain_2ghz[IWN4965_MAX_PWR_INDEX + 1] = {
|
|
0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c,
|
|
0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39, 0x39, 0x38,
|
|
0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35,
|
|
0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31,
|
|
0x31, 0x30, 0x30, 0x30, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x04,
|
|
0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
static const uint8_t iwn4965_rf_gain_5ghz[IWN4965_MAX_PWR_INDEX + 1] = {
|
|
0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e, 0x3e, 0x3d, 0x3d, 0x3d,
|
|
0x3c, 0x3c, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39, 0x39,
|
|
0x39, 0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x35,
|
|
0x35, 0x35, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32,
|
|
0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x25, 0x25, 0x25, 0x24, 0x24,
|
|
0x24, 0x23, 0x23, 0x23, 0x22, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16,
|
|
0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13,
|
|
0x12, 0x08, 0x08, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x05, 0x05,
|
|
0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01,
|
|
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
/*
|
|
* DSP pre-DAC gain values from highest to lowest power (values obtained
|
|
* from the reference driver.)
|
|
*/
|
|
static const uint8_t iwn4965_dsp_gain_2ghz[IWN4965_MAX_PWR_INDEX + 1] = {
|
|
0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
|
|
0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
|
|
0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
|
|
0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
|
|
0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
|
|
0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
|
|
0x6e, 0x68, 0x62, 0x61, 0x60, 0x5f, 0x5e, 0x5d, 0x5c, 0x5b, 0x5a,
|
|
0x59, 0x58, 0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f,
|
|
0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46, 0x45, 0x44,
|
|
0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b
|
|
};
|
|
|
|
static const uint8_t iwn4965_dsp_gain_5ghz[IWN4965_MAX_PWR_INDEX + 1] = {
|
|
0x7b, 0x75, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
|
|
0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
|
|
0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
|
|
0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
|
|
0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
|
|
0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
|
|
0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62,
|
|
0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68,
|
|
0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e, 0x68, 0x62, 0x6e,
|
|
0x68, 0x62, 0x6e, 0x68, 0x62, 0x5d, 0x58, 0x53, 0x4e
|
|
};
|
|
|
|
/*
|
|
* Power saving settings (values obtained from the reference driver.)
|
|
*/
|
|
#define IWN_NDTIMRANGES 3
|
|
#define IWN_NPOWERLEVELS 6
|
|
static const struct iwn_pmgt {
|
|
uint32_t rxtimeout;
|
|
uint32_t txtimeout;
|
|
uint32_t intval[5];
|
|
int skip_dtim;
|
|
} iwn_pmgt[IWN_NDTIMRANGES][IWN_NPOWERLEVELS] = {
|
|
/* DTIM <= 2 */
|
|
{
|
|
{ 0, 0, { 0, 0, 0, 0, 0 }, 0 }, /* CAM */
|
|
{ 200, 500, { 1, 2, 2, 2, -1 }, 0 }, /* PS level 1 */
|
|
{ 200, 300, { 1, 2, 2, 2, -1 }, 0 }, /* PS level 2 */
|
|
{ 50, 100, { 2, 2, 2, 2, -1 }, 0 }, /* PS level 3 */
|
|
{ 50, 25, { 2, 2, 4, 4, -1 }, 1 }, /* PS level 4 */
|
|
{ 25, 25, { 2, 2, 4, 6, -1 }, 2 } /* PS level 5 */
|
|
},
|
|
/* 3 <= DTIM <= 10 */
|
|
{
|
|
{ 0, 0, { 0, 0, 0, 0, 0 }, 0 }, /* CAM */
|
|
{ 200, 500, { 1, 2, 3, 4, 4 }, 0 }, /* PS level 1 */
|
|
{ 200, 300, { 1, 2, 3, 4, 7 }, 0 }, /* PS level 2 */
|
|
{ 50, 100, { 2, 4, 6, 7, 9 }, 0 }, /* PS level 3 */
|
|
{ 50, 25, { 2, 4, 6, 9, 10 }, 1 }, /* PS level 4 */
|
|
{ 25, 25, { 2, 4, 7, 10, 10 }, 2 } /* PS level 5 */
|
|
},
|
|
/* DTIM >= 11 */
|
|
{
|
|
{ 0, 0, { 0, 0, 0, 0, 0 }, 0 }, /* CAM */
|
|
{ 200, 500, { 1, 2, 3, 4, -1 }, 0 }, /* PS level 1 */
|
|
{ 200, 300, { 2, 4, 6, 7, -1 }, 0 }, /* PS level 2 */
|
|
{ 50, 100, { 2, 7, 9, 9, -1 }, 0 }, /* PS level 3 */
|
|
{ 50, 25, { 2, 7, 9, 9, -1 }, 0 }, /* PS level 4 */
|
|
{ 25, 25, { 4, 7, 10, 10, -1 }, 0 } /* PS level 5 */
|
|
}
|
|
};
|
|
|
|
struct iwn_sensitivity_limits {
|
|
uint32_t min_ofdm_x1;
|
|
uint32_t max_ofdm_x1;
|
|
uint32_t min_ofdm_mrc_x1;
|
|
uint32_t max_ofdm_mrc_x1;
|
|
uint32_t min_ofdm_x4;
|
|
uint32_t max_ofdm_x4;
|
|
uint32_t min_ofdm_mrc_x4;
|
|
uint32_t max_ofdm_mrc_x4;
|
|
uint32_t min_cck_x4;
|
|
uint32_t max_cck_x4;
|
|
uint32_t min_cck_mrc_x4;
|
|
uint32_t max_cck_mrc_x4;
|
|
uint32_t min_energy_cck;
|
|
uint32_t energy_cck;
|
|
uint32_t energy_ofdm;
|
|
};
|
|
|
|
/*
|
|
* RX sensitivity limits (values obtained from the reference driver.)
|
|
*/
|
|
static const struct iwn_sensitivity_limits iwn4965_sensitivity_limits = {
|
|
105, 140,
|
|
220, 270,
|
|
85, 120,
|
|
170, 210,
|
|
125, 200,
|
|
200, 400,
|
|
97,
|
|
100,
|
|
100
|
|
};
|
|
|
|
static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = {
|
|
120, 120, /* min = max for performance bug in DSP. */
|
|
240, 240, /* min = max for performance bug in DSP. */
|
|
90, 120,
|
|
170, 210,
|
|
125, 200,
|
|
170, 400,
|
|
95,
|
|
95,
|
|
95
|
|
};
|
|
|
|
static const struct iwn_sensitivity_limits iwn5150_sensitivity_limits = {
|
|
105, 105, /* min = max for performance bug in DSP. */
|
|
220, 220, /* min = max for performance bug in DSP. */
|
|
90, 120,
|
|
170, 210,
|
|
125, 200,
|
|
170, 400,
|
|
95,
|
|
95,
|
|
95
|
|
};
|
|
|
|
static const struct iwn_sensitivity_limits iwn1000_sensitivity_limits = {
|
|
120, 155,
|
|
240, 290,
|
|
90, 120,
|
|
170, 210,
|
|
125, 200,
|
|
170, 400,
|
|
95,
|
|
95,
|
|
95
|
|
};
|
|
|
|
static const struct iwn_sensitivity_limits iwn6000_sensitivity_limits = {
|
|
105, 110,
|
|
192, 232,
|
|
80, 145,
|
|
128, 232,
|
|
125, 175,
|
|
160, 310,
|
|
97,
|
|
97,
|
|
100
|
|
};
|
|
|
|
/* Map TID to TX scheduler's FIFO. */
|
|
static const uint8_t iwn_tid2fifo[] = {
|
|
1, 0, 0, 1, 2, 2, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 3
|
|
};
|
|
|
|
/* WiFi/WiMAX coexist event priority table for 6050. */
|
|
static const struct iwn5000_wimax_event iwn6050_wimax_events[] = {
|
|
{ 0x04, 0x03, 0x00, 0x00 },
|
|
{ 0x04, 0x03, 0x00, 0x03 },
|
|
{ 0x04, 0x03, 0x00, 0x03 },
|
|
{ 0x04, 0x03, 0x00, 0x03 },
|
|
{ 0x04, 0x03, 0x00, 0x00 },
|
|
{ 0x04, 0x03, 0x00, 0x07 },
|
|
{ 0x04, 0x03, 0x00, 0x00 },
|
|
{ 0x04, 0x03, 0x00, 0x03 },
|
|
{ 0x04, 0x03, 0x00, 0x03 },
|
|
{ 0x04, 0x03, 0x00, 0x00 },
|
|
{ 0x06, 0x03, 0x00, 0x07 },
|
|
{ 0x04, 0x03, 0x00, 0x00 },
|
|
{ 0x06, 0x06, 0x00, 0x03 },
|
|
{ 0x04, 0x03, 0x00, 0x07 },
|
|
{ 0x04, 0x03, 0x00, 0x00 },
|
|
{ 0x04, 0x03, 0x00, 0x00 }
|
|
};
|
|
|
|
/* Firmware errors. */
|
|
static const char * const iwn_fw_errmsg[] = {
|
|
"OK",
|
|
"FAIL",
|
|
"BAD_PARAM",
|
|
"BAD_CHECKSUM",
|
|
"NMI_INTERRUPT_WDG",
|
|
"SYSASSERT",
|
|
"FATAL_ERROR",
|
|
"BAD_COMMAND",
|
|
"HW_ERROR_TUNE_LOCK",
|
|
"HW_ERROR_TEMPERATURE",
|
|
"ILLEGAL_CHAN_FREQ",
|
|
"VCC_NOT_STABLE",
|
|
"FH_ERROR",
|
|
"NMI_INTERRUPT_HOST",
|
|
"NMI_INTERRUPT_ACTION_PT",
|
|
"NMI_INTERRUPT_UNKNOWN",
|
|
"UCODE_VERSION_MISMATCH",
|
|
"HW_ERROR_ABS_LOCK",
|
|
"HW_ERROR_CAL_LOCK_FAIL",
|
|
"NMI_INTERRUPT_INST_ACTION_PT",
|
|
"NMI_INTERRUPT_DATA_ACTION_PT",
|
|
"NMI_TRM_HW_ER",
|
|
"NMI_INTERRUPT_TRM",
|
|
"NMI_INTERRUPT_BREAKPOINT"
|
|
"DEBUG_0",
|
|
"DEBUG_1",
|
|
"DEBUG_2",
|
|
"DEBUG_3",
|
|
"ADVANCED_SYSASSERT"
|
|
};
|
|
|
|
/* Find least significant bit that is set. */
|
|
#define IWN_LSB(x) ((((x) - 1) & (x)) ^ (x))
|
|
|
|
#define IWN_READ(sc, reg) \
|
|
bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
|
|
|
|
#define IWN_WRITE(sc, reg, val) \
|
|
bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
|
|
|
|
#define IWN_WRITE_1(sc, reg, val) \
|
|
bus_space_write_1((sc)->sc_st, (sc)->sc_sh, (reg), (val))
|
|
|
|
#define IWN_SETBITS(sc, reg, mask) \
|
|
IWN_WRITE(sc, reg, IWN_READ(sc, reg) | (mask))
|
|
|
|
#define IWN_CLRBITS(sc, reg, mask) \
|
|
IWN_WRITE(sc, reg, IWN_READ(sc, reg) & ~(mask))
|
|
|
|
#define IWN_BARRIER_WRITE(sc) \
|
|
bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz, \
|
|
BUS_SPACE_BARRIER_WRITE)
|
|
|
|
#define IWN_BARRIER_READ_WRITE(sc) \
|
|
bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz, \
|
|
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
|