diff options
Diffstat (limited to 'sys/dev/pci/if_iwnreg.h')
-rw-r--r-- | sys/dev/pci/if_iwnreg.h | 954 |
1 files changed, 677 insertions, 277 deletions
diff --git a/sys/dev/pci/if_iwnreg.h b/sys/dev/pci/if_iwnreg.h index 6f3e859d029..8f0444b94b0 100644 --- a/sys/dev/pci/if_iwnreg.h +++ b/sys/dev/pci/if_iwnreg.h @@ -1,7 +1,7 @@ -/* $OpenBSD: if_iwnreg.h,v 1.10 2008/04/27 19:01:59 damien Exp $ */ +/* $OpenBSD: if_iwnreg.h,v 1.11 2008/10/13 16:37:10 damien Exp $ */ /*- - * Copyright (c) 2007 + * Copyright (c) 2007, 2008 * Damien Bergamini <damien.bergamini@free.fr> * * Permission to use, copy, modify, and distribute this software for any @@ -18,177 +18,278 @@ */ #define IWN_TX_RING_COUNT 256 -#define IWN_RX_RING_COUNT 64 +#define IWN_TX_RING_LOMARK 192 +#define IWN_TX_RING_HIMARK 224 +#define IWN_RX_RING_COUNT_LOG 8 +#define IWN_RX_RING_COUNT (1 << IWN_RX_RING_COUNT_LOG) -#define IWN_NTXQUEUES 16 -#define IWN_NTXCHAINS 2 +#define IWN4965_NTXQUEUES 16 +#define IWN5000_NTXQUEUES 20 +#define IWN_SRVC_CHNL 9 -/* - * Rings must be aligned on a 256-byte boundary. - */ -#define IWN_RING_DMA_ALIGN 256 - -/* maximum scatter/gather */ +/* 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 */ +/* RX buffers must be large enough to hold a full 4K A-MPDU. */ #define IWN_RBUF_SIZE (4 * 1024) +/* Base Address Register. */ +#define IWN_PCI_BAR0 PCI_MAPREG_START + +/* Possible flags for PCIe Device Control Register (see PCIe 7.8.4) */ +#define PCI_PCIE_DCSR_ENA_NO_SNOOP (1 << 11) + +/* Possible flags for PCIe Link Control Register (see PCIe 7.8.7) */ +#define PCI_PCIE_LCSR_ASPM_L0S (1 << 0) +#define PCI_PCIE_LCSR_ASPM_L1 (1 << 1) + /* * Control and status registers. */ -#define IWN_HWCONFIG 0x000 -#define IWN_INTR_MIT 0x004 -#define IWN_INTR 0x008 +#define IWN_HW_IF_CONFIG 0x000 +#define IWN_INT_COALESCING 0x004 +#define IWN_INT 0x008 #define IWN_MASK 0x00c -#define IWN_INTR_STATUS 0x010 +#define IWN_FH_INT 0x010 #define IWN_RESET 0x020 -#define IWN_GPIO_CTL 0x024 -#define IWN_EEPROM_CTL 0x02c -#define IWN_UCODE_CLR 0x05c -#define IWN_CHICKEN 0x100 -#define IWN_QUEUE_OFFSET(qid) (0x380 + (qid) * 8) +#define IWN_GP_CNTRL 0x024 +#define IWN_HW_REV 0x028 +#define IWN_EEPROM 0x02c +#define IWN_EEPROM_GP 0x030 +#define IWN_GIO 0x03c +#define IWN_UCODE_GP1_CLR 0x05c +#define IWN_LED 0x094 +#define IWN_GIO_CHICKEN 0x100 +#define IWN_ANA_PLL 0x20c +#define IWN_DBG_HPET_MEM 0x240 +#define IWN_MEM_RADDR 0x40c #define IWN_MEM_WADDR 0x410 #define IWN_MEM_WDATA 0x418 -#define IWN_WRITE_MEM_ADDR 0x444 -#define IWN_READ_MEM_ADDR 0x448 -#define IWN_WRITE_MEM_DATA 0x44c -#define IWN_READ_MEM_DATA 0x450 -#define IWN_TX_WIDX 0x460 - -#define IWN_KW_BASE 0x197c -#define IWN_TX_BASE(qid) (0x19d0 + (qid) * 4) -#define IWN_RW_WIDX_PTR 0x1bc0 -#define IWN_RX_BASE 0x1bc4 -#define IWN_RX_WIDX 0x1bc8 -#define IWN_RX_CONFIG 0x1c00 -#define IWN_RX_STATUS 0x1c44 -#define IWN_TX_CONFIG(qid) (0x1d00 + (qid) * 32) -#define IWN_TX_STATUS 0x1eb0 - -#define IWN_SRAM_BASE 0xa02c00 -#define IWN_TX_ACTIVE (IWN_SRAM_BASE + 0x01c) -#define IWN_QUEUE_RIDX(qid) (IWN_SRAM_BASE + 0x064 + (qid) * 4) -#define IWN_SELECT_QCHAIN (IWN_SRAM_BASE + 0x0d0) -#define IWN_QUEUE_INTR_MASK (IWN_SRAM_BASE + 0x0e4) -#define IWN_TXQ_STATUS(qid) (IWN_SRAM_BASE + 0x104 + (qid) * 4) +#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 /* - * NIC internal memory offsets. + * Flow-Handler registers. */ -#define IWN_CLOCK_CTL 0x3000 -#define IWN_MEM_CLOCK2 0x3008 -#define IWN_MEM_POWER 0x300c -#define IWN_MEM_PCIDEV 0x3010 -#define IWN_MEM_UCODE_CTL 0x3400 -#define IWN_MEM_UCODE_SRC 0x3404 -#define IWN_MEM_UCODE_DST 0x3408 -#define IWN_MEM_UCODE_SIZE 0x340c -#define IWN_MEM_TEXT_BASE 0x3490 -#define IWN_MEM_TEXT_SIZE 0x3494 -#define IWN_MEM_DATA_BASE 0x3498 -#define IWN_MEM_DATA_SIZE 0x349c -#define IWN_MEM_UCODE_BASE 0x3800 +#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_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) -/* possible flags for register IWN_HWCONFIG */ -#define IWN_HW_EEPROM_LOCKED (1 << 21) - -/* possible flags for registers IWN_READ_MEM_ADDR/IWN_WRITE_MEM_ADDR */ -#define IWN_MEM_4 ((sizeof (uint32_t) - 1) << 24) +/* + * 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) -/* possible values for IWN_MEM_UCODE_DST */ -#define IWN_FW_TEXT 0x00000000 +/* + * NIC internal memory offsets. + */ +#define IWN_CLOCK_CTL 0x3000 +#define IWN_APMG_CLK_CTRL 0x3004 +#define IWN_APMG_CLK_DIS 0x3008 +#define IWN_APMG_PS 0x300c +#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 values for IWN_APMG_CLK_DIS */ +#define IWN_APMG_CLK_DMA_RQT (1 << 9) + +/* 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_HAP_WAKE_L1A (1 << 23) + +/* 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_NEVO_RESET (1 << 0) -#define IWN_SW_RESET (1 << 7) -#define IWN_MASTER_DISABLED (1 << 8) -#define IWN_STOP_MASTER (1 << 9) - -/* possible flags for register IWN_GPIO_CTL */ -#define IWN_GPIO_CLOCK (1 << 0) -#define IWN_GPIO_INIT (1 << 2) -#define IWN_GPIO_MAC (1 << 3) -#define IWN_GPIO_SLEEP (1 << 4) -#define IWN_GPIO_PWR_STATUS 0x07000000 -#define IWN_GPIO_PWR_SLEEP (4 << 24) -#define IWN_GPIO_RF_ENABLED (1 << 27) - -/* possible flags for register IWN_CHICKEN */ -#define IWN_CHICKEN_DISLOS (1 << 29) - -/* possible flags for register IWN_UCODE_CLR */ -#define IWN_RADIO_OFF (1 << 1) -#define IWN_DISABLE_CMD (1 << 2) -#define IWN_CTEMP_STOP_RF (1 << 3) - -/* possible flags for IWN_RX_STATUS */ -#define IWN_RX_IDLE (1 << 24) - -/* possible flags for register IWN_UC_CTL */ -#define IWN_UC_ENABLE (1 << 30) -#define IWN_UC_RUN (1 << 31) - -/* possible flags for register IWN_INTR */ -#define IWN_ALIVE_INTR (1 << 0) -#define IWN_WAKEUP_INTR (1 << 1) -#define IWN_SW_RX_INTR (1 << 3) -#define IWN_CT_REACHED (1 << 6) -#define IWN_RF_TOGGLED (1 << 7) -#define IWN_SW_ERROR (1 << 25) -#define IWN_TX_INTR (1 << 27) -#define IWN_HW_ERROR (1 << 29) -#define IWN_RX_INTR (1 << 31) - -#define IWN_INTR_MASK \ - (IWN_SW_ERROR | IWN_HW_ERROR | IWN_TX_INTR | IWN_RX_INTR | \ - IWN_ALIVE_INTR | IWN_WAKEUP_INTR | IWN_SW_RX_INTR | \ - IWN_CT_REACHED | IWN_RF_TOGGLED) - -/* possible flags for register IWN_INTR_STATUS */ -#define IWN_STATUS_TXQ(x) (1 << (x)) -#define IWN_STATUS_RXQ(x) (1 << ((x) + 16)) -#define IWN_STATUS_PRI (1 << 30) +#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) + +/* 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) + +/* possibles 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 + +/* 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_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 for register IWN_LED */ +#define IWN_LED_BSM_CTRL (1 << 5) + +/* 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_FH_TX (1 << 27) +#define IWN_INT_HW_ERR (1 << 29) +#define IWN_INT_FH_RX (1 << 31) + +#define IWN_INT_MASK \ + (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_TX_STATUS_INTR \ - (IWN_STATUS_TXQ(0) | IWN_STATUS_TXQ(1) | IWN_STATUS_TXQ(6)) -#define IWN_RX_STATUS_INTR \ - (IWN_STATUS_RXQ(0) | IWN_STATUS_RXQ(1) | IWN_STATUS_RXQ(2) | \ - IWN_STATUS_PRI) - -/* possible flags for register IWN_TX_STATUS */ -#define IWN_TX_IDLE(qid) (1 << ((qid) + 24) | 1 << ((qid) + 16)) - -/* possible flags for register IWN_EEPROM_CTL */ -#define IWN_EEPROM_READY (1 << 0) +#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 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_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_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_TXQ_STATUS */ -#define IWN_TXQ_STATUS_ACTIVE 0x0007fc01 - -/* possible flags for register IWN_MEM_POWER */ -#define IWN_POWER_RESET (1 << 26) - -/* possible flags for register IWN_MEM_TEXT_SIZE */ +/* possible flags for register IWN5000_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 register IWN_APMG_CLK_CTRL */ +#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_MASK (3 << 24) +#define IWN_APMG_PS_PWR_SRC(x) ((x) << 24) +#define IWN_APMG_PS_PWR_SRC_VMAIN 0 + +/* 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) -/* possible flags for device-specific PCI register 0xe8 */ -#define IWN_DIS_NOSNOOP (1 << 11) - -/* possible flags for device-specific PCI register 0xf0 */ -#define IWN_ENA_L1 (1 << 1) - - -#define IWN_TX_WINDOW 64 -struct iwn_shared { - uint16_t len[IWN_NTXQUEUES][512]; /* 16KB total */ - uint16_t closed_count; - uint16_t closed_rx_count; - uint16_t finished_count; - uint16_t finished_rx_count; - uint32_t reserved[2]; -} __packed; +#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 { uint32_t flags; @@ -217,21 +318,31 @@ struct iwn_tx_desc { } \ } while (0) +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 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_AMPDU_RX_START 192 -#define IWN_AMPDU_RX_DONE 193 -#define IWN_RX_DONE 195 +#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_AMPDU_RX_START 192 +#define IWN_AMPDU_RX_DONE 193 +#define IWN_RX_DONE 195 uint8_t flags; uint8_t idx; @@ -249,15 +360,18 @@ struct iwn_tx_cmd { #define IWN_CMD_CONFIGURE 16 #define IWN_CMD_ASSOCIATE 17 #define IWN_CMD_EDCA_PARAMS 19 -#define IWN_CMD_TSF 20 +#define IWN_CMD_TIMING 20 #define IWN_CMD_ADD_NODE 24 #define IWN_CMD_TX_DATA 28 #define IWN_CMD_NODE_MRR_SETUP 78 #define IWN_CMD_SET_LED 72 +#define IWN5000_CMD_WIMAX_COEX 90 +#define IWN5000_CMD_CALIB_CONFIG 101 #define IWN_CMD_SET_POWER_MODE 119 #define IWN_CMD_SCAN 128 #define IWN_CMD_TXPOWER 151 -#define IWN_CMD_BLUETOOTH 155 +#define IWN_CMD_TXPOWER_DBM 152 +#define IWN_CMD_BT_COEX 155 #define IWN_CMD_GET_STATISTICS 156 #define IWN_CMD_SET_CRITICAL_TEMP 164 #define IWN_SENSITIVITY 168 @@ -270,7 +384,7 @@ struct iwn_tx_cmd { } __packed; /* structure for command IWN_CMD_CONFIGURE */ -struct iwn_config { +struct iwn_rxon { uint8_t myaddr[IEEE80211_ADDR_LEN]; uint16_t reserved1; uint8_t bssid[IEEE80211_ADDR_LEN]; @@ -283,24 +397,37 @@ struct iwn_config { #define IWN_MODE_IBSS 4 #define IWN_MODE_MONITOR 6 - uint8_t reserved4; + uint8_t air; uint16_t rxchain; -#define IWN_RXCHAIN_ANTMSK_SHIFT 1 -#define IWN_RXCHAIN_FORCE_MIMO (1 << 14) +#define IWN_ANT_A (1 << 0) +#define IWN_ANT_B (1 << 1) +#define IWN_ANT_C (1 << 2) +/* Shortcut. */ +#define IWN_ANT_ABC (IWN_ANT_A | IWN_ANT_B | IWN_ANT_C) + +#define IWN_RXCHAIN_FORCE (1 << 0) +#define IWN_RXCHAIN_VALID(x) ((x) << 1) +#define IWN_RXCHAIN_SEL(x) ((x) << 4) +#define IWN_RXCHAIN_MIMO(x) ((x) << 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_CONFIG_24GHZ (1 << 0) -#define IWN_CONFIG_CCK (1 << 1) -#define IWN_CONFIG_AUTO (1 << 2) -#define IWN_CONFIG_SHSLOT (1 << 4) -#define IWN_CONFIG_SHPREAMBLE (1 << 5) -#define IWN_CONFIG_NODIVERSITY (1 << 7) -#define IWN_CONFIG_ANTENNA_A (1 << 8) -#define IWN_CONFIG_ANTENNA_B (1 << 9) -#define IWN_CONFIG_TSF (1 << 15) +#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) @@ -308,13 +435,22 @@ struct iwn_config { #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 reserved5; + 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; @@ -339,8 +475,8 @@ struct iwn_edca_params { } __packed ac[EDCA_NUM_AC]; } __packed; -/* structure for command IWN_CMD_TSF */ -struct iwn_cmd_tsf { +/* structure for command IWN_CMD_TIMING */ +struct iwn_cmd_timing { uint64_t tstamp; uint16_t bintval; uint16_t atim; @@ -355,61 +491,100 @@ struct iwn_node_info { #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 IWN_ID_BROADCAST 31 +#define IWN5000_ID_BROADCAST 15 +#define IWN4965_ID_BROADCAST 31 uint8_t flags; -#define IWN_FLAG_SET_KEY (1 << 0) +#define IWN_FLAG_SET_KEY (1 << 0) +#define IWN_FLAG_SET_DISABLE_TID (1 << 1) uint16_t reserved3; - uint16_t security; + + uint16_t keyflags; uint8_t tsc2; /* TKIP TSC2 */ uint8_t reserved4; uint16_t ttak[5]; - uint16_t reserved5; - uint8_t key[IEEE80211_KEYBUF_SIZE]; + uint8_t kid; + uint8_t reserved5; + uint8_t key[16]; + uint64_t tsc; + uint8_t rxmic[IEEE80211_TKIP_MICLEN]; + uint8_t txmic[IEEE80211_TKIP_MICLEN]; + uint32_t htflags; -#define IWN_AMDPU_SIZE_FACTOR_SHIFT 19 -#define IWN_AMDPU_DENSITY_SHIFT 23 +#define IWN_AMDPU_SIZE_FACTOR(x) ((x) << 19) +#define IWN_AMDPU_DENSITY(x) ((x) << 23) uint32_t mask; - uint16_t tid; - uint8_t rate; - uint8_t rflags; + uint16_t disable_tid; + uint16_t reserved6; + + uint8_t addba; + uint8_t delba; + 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 keyflags; + 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; + uint8_t delba; + uint16_t addba_ssn; + uint32_t reserved7; +} __packed; + #define IWN_RFLAG_CCK (1 << 1) #define IWN_RFLAG_ANT_A (1 << 6) #define IWN_RFLAG_ANT_B (1 << 7) - uint8_t add_imm; - uint8_t del_imm; - uint16_t add_imm_start; - uint32_t reserved6; -} __packed; - /* structure for command IWN_CMD_TX_DATA */ struct iwn_cmd_data { uint16_t len; uint16_t lnext; uint32_t flags; +#define IWN5000_TX_NEED_RTS_CTS (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_MRR_INDEX (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) uint8_t ntries; uint8_t bluetooth; uint16_t reserved1; + uint8_t rate; uint8_t rflags; uint16_t xrflags; + uint8_t id; uint8_t security; #define IWN_CIPHER_WEP40 1 @@ -419,7 +594,7 @@ struct iwn_cmd_data { uint8_t ridx; uint8_t reserved2; - uint8_t key[IEEE80211_KEYBUF_SIZE]; + uint8_t key[16]; uint16_t fnext; uint16_t reserved3; uint32_t lifetime; @@ -451,14 +626,13 @@ struct iwn_cmd_mrr { uint32_t reserved2; struct { uint8_t rate; + uint8_t rflags; + uint16_t xrflags; #define IWN_CCK1 0 #define IWN_CCK11 3 #define IWN_OFDM6 4 #define IWN_OFDM54 11 - - uint8_t rflags; - uint16_t xrflags; - } table[IWN_MAX_TX_RETRIES]; + } __packed table[IWN_MAX_TX_RETRIES]; uint32_t reserved3; } __packed; @@ -474,16 +648,52 @@ struct iwn_cmd_led { uint8_t reserved; } __packed; +/* structure for command IWN5000_CMD_WIMAX_COEX */ +struct iwn5000_wimax_coex { + uint32_t flags; + struct { + 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_power { +struct iwn_pmgt_cmd { uint16_t flags; -#define IWN_POWER_CAM 0 /* constantly awake mode */ +#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 alive; + uint8_t keepalive; uint8_t debug; - uint32_t rx_timeout; - uint32_t tx_timeout; - uint32_t sleep[5]; + uint32_t rxtimeout; + uint32_t txtimeout; + uint32_t intval[5]; uint32_t beacons; } __packed; @@ -498,8 +708,8 @@ struct iwn_scan_hdr { uint16_t len; uint8_t reserved1; uint8_t nchan; - uint16_t quiet; - uint16_t plcp_threshold; + uint16_t quiet_time; + uint16_t quiet_threshold; uint16_t crc_threshold; uint16_t rxchain; uint32_t max_svc; /* background scans */ @@ -508,17 +718,17 @@ struct iwn_scan_hdr { uint32_t filter; /* followed by a struct iwn_cmd_data */ - /* followed by an array of 4x struct iwn_scan_essid */ + /* followed by an array of 20 struct iwn_scan_essid */ /* followed by probe request body */ /* followed by nchan x struct iwn_scan_chan */ } __packed; struct iwn_scan_chan { - uint8_t flags; + uint32_t type; #define IWN_CHAN_ACTIVE (1 << 0) #define IWN_CHAN_DIRECT (1 << 1) - uint8_t chan; + uint16_t chan; uint8_t rf_gain; uint8_t dsp_gain; uint16_t active; /* msecs */ @@ -527,15 +737,28 @@ struct iwn_scan_chan { /* structure for command IWN_CMD_TXPOWER */ #define IWN_RIDX_MAX 32 -struct iwn_cmd_txpower { - uint8_t band; - uint8_t reserved1; - uint8_t chan; - uint8_t reserved2; +struct iwn4965_cmd_txpower { + uint8_t band; + uint8_t reserved1; + uint8_t chan; + uint8_t reserved2; struct { - uint8_t rf_gain[IWN_NTXCHAINS]; - uint8_t dsp_gain[IWN_NTXCHAINS]; - } power[IWN_RIDX_MAX + 1]; + uint8_t rf_gain[2]; + uint8_t dsp_gain[2]; + } __packed power[IWN_RIDX_MAX + 1]; +} __packed; + +/* structure for command IWN_CMD_TXPOWER_DBM */ +struct iwn5000_cmd_txpower { + int8_t global_limit; /* in half-dBm */ +#define IWN5000_TX_POWER_AUTO 0x7f +#define IWN5000_TX_POWER_MAX_DBM 16 + + uint8_t flags; +#define IWN5000_TX_POWER_NO_CLOSED (1 << 6) + + int8_t srv_limit; /* in half-dBm */ + uint8_t reserved; } __packed; /* structure for command IWN_CMD_BLUETOOTH */ @@ -581,16 +804,38 @@ struct iwn_sensitivity_cmd { /* structure for command IWN_PHY_CALIB */ struct iwn_phy_calib_cmd { uint8_t code; -#define IWN_SET_DIFF_GAIN 7 uint8_t flags; uint16_t reserved1; int8_t gain[3]; -#define IWN_GAIN_SET (1 << 2) - uint8_t reserved2; } __packed; +struct iwn5000_calib { + uint8_t code; +#define IWN4965_SET_DIFF_GAIN 7 +#define IWN5000_PHY_CALIB_LO 9 +#define IWN5000_PHY_CALIB_LO_TX_IQ 11 +#define IWN5000_PHY_CALIB_CRYSTAL 15 +#define IWN5000_PHY_CALIB_LO_TX_IQ_PERD 17 +#define IWN5000_PHY_CALIB_RESET_NOISE_GAIN 18 +#define IWN5000_PHY_CALIB_NOISE_GAIN 19 + + uint8_t group; + uint8_t ngroups; + uint8_t valid; +} __packed; + +/* structure for command IWN_PHY_CALIB */ +struct iwn5000_phy_calib { + uint8_t code; + + uint8_t group; + uint8_t ngroups; + uint8_t valid; + uint8_t data[2]; +} __packed; + /* structure for IWN_UC_READY notification */ #define IWN_NATTEN_GROUPS 5 @@ -616,15 +861,15 @@ struct iwn_ucode_info { int32_t chan20MHz; int32_t chan40MHz; } __packed temp[4]; - int32_t atten[IWN_NATTEN_GROUPS][IWN_NTXCHAINS]; + int32_t atten[IWN_NATTEN_GROUPS][2]; } __packed; /* structure for IWN_TX_DONE notification */ -struct iwn_tx_stat { +struct iwn4965_tx_stat { uint8_t nframes; - uint8_t nkill; - uint8_t nrts; - uint8_t ntries; + uint8_t killcnt; + uint8_t rtscnt; + uint8_t retrycnt; uint8_t rate; uint8_t rflags; uint16_t xrflags; @@ -634,6 +879,25 @@ struct iwn_tx_stat { uint32_t status; } __packed; +struct iwn5000_tx_stat { + uint8_t nframes; + uint8_t killcnt; + uint8_t rtscnt; + uint8_t retrycnt; + 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; + uint32_t tlc; + uint16_t status; + uint16_t sequence; +} __packed; + /* structure for IWN_BEACON_MISSED notification */ struct iwn_beacon_missed { uint32_t consecutive; @@ -648,7 +912,20 @@ struct iwn_rx_ampdu { uint16_t reserved; } __packed; -/* structure for IWN_RX_DONE and IWN_AMPDU_RX_START notifications */ +/* structures for IWN_RX_DONE and IWN_AMPDU_RX_START 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; @@ -660,12 +937,7 @@ struct iwn_rx_stat { uint32_t beacon; uint16_t flags; uint16_t chan; - uint16_t antenna; - uint16_t agc; - uint8_t rssi[6]; -#define IWN_RSSI_TO_DBM 44 - - uint8_t reserved2[22]; + uint8_t phybuf[32]; uint8_t rate; uint8_t rflags; uint16_t xrflags; @@ -673,6 +945,8 @@ struct iwn_rx_stat { uint16_t reserve3; } __packed; +#define IWN_RSSI_TO_DBM 44 + /* structure for IWN_START_SCAN notification */ struct iwn_start_scan { uint64_t tstamp; @@ -819,28 +1093,47 @@ struct iwn_firmware_hdr { uint32_t boot_textsz; } __packed; -#define IWN_FW_MAIN_TEXT_MAXSZ (96 * 1024) -#define IWN_FW_MAIN_DATA_MAXSZ (40 * 1024) -#define IWN_FW_INIT_TEXT_MAXSZ (96 * 1024) -#define IWN_FW_INIT_DATA_MAXSZ (40 * 1024) +#define IWN4965_FW_TEXT_MAXSZ ( 96 * 1024) +#define IWN4965_FW_DATA_MAXSZ ( 40 * 1024) +#define IWN5000_FW_TEXT_MAXSZ (128 * 1024) +#define IWN5000_FW_DATA_MAXSZ ( 48 * 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_DOMAIN 0x060 -#define IWN_EEPROM_BAND1 0x063 -#define IWN_EEPROM_BAND2 0x072 -#define IWN_EEPROM_BAND3 0x080 -#define IWN_EEPROM_BAND4 0x08d -#define IWN_EEPROM_BAND5 0x099 -#define IWN_EEPROM_BAND6 0x0a0 -#define IWN_EEPROM_BAND7 0x0a8 -#define IWN_EEPROM_MAXPOW 0x0e8 -#define IWN_EEPROM_VOLTAGE 0x0e9 -#define IWN_EEPROM_BANDS 0x0ea +#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 IWN5000_EEPROM_CRYSTAL 0x094 + +/* possible flags for IWN_EEPROM_RFCFG */ +#define IWN_RFCFG_TYPE(x) (((x) >> 0) & 3) +#define IWN_RFCFG_STEP(x) (((x) >> 2) & 3) +#define IWN_RFCFG_DASH(x) (((x) >> 4) & 3) struct iwn_eeprom_chan { uint8_t flags; @@ -853,44 +1146,59 @@ struct iwn_eeprom_chan { } __packed; #define IWN_NSAMPLES 3 -struct iwn_eeprom_chan_samples { +struct iwn4965_eeprom_chan_samples { uint8_t num; struct { uint8_t temp; uint8_t gain; uint8_t power; int8_t pa_det; - } samples[IWN_NTXCHAINS][IWN_NSAMPLES]; + } samples[2][IWN_NSAMPLES]; } __packed; #define IWN_NBANDS 8 -struct iwn_eeprom_band { +struct iwn4965_eeprom_band { uint8_t lo; /* low channel number */ uint8_t hi; /* high channel number */ - struct iwn_eeprom_chan_samples chans[2]; + 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 { - uint32_t addr; /* offset in EEPROM */ - uint8_t nchan; - uint8_t chan[IWN_MAX_CHAN_PER_BAND]; + uint8_t nchan; + uint8_t chan[IWN_MAX_CHAN_PER_BAND]; } iwn_bands[] = { - { IWN_EEPROM_BAND1, 14, - { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } }, - { IWN_EEPROM_BAND2, 13, - { 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 } }, - { IWN_EEPROM_BAND3, 12, - { 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 } }, - { IWN_EEPROM_BAND4, 11, - { 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 } }, - { IWN_EEPROM_BAND5, 6, - { 145, 149, 153, 157, 161, 165 } }, - { IWN_EEPROM_BAND6, 7, - { 1, 2, 3, 4, 5, 6, 7 } }, - { IWN_EEPROM_BAND7, 11, - { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } } + { 14, { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } }, + { 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 } }, + { 7, { 1, 2, 3, 4, 5, 6, 7 } }, + { 11, { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 } } }; static const uint8_t iwn_ridx_to_plcp[] = { @@ -898,13 +1206,13 @@ static const uint8_t iwn_ridx_to_plcp[] = { 0xd, 0xf, 0x5, 0x7, 0x9, 0xb, 0x1, 0x3, 0x3 /* OFDM R1-R4 */ }; -#define IWN_MAX_PWR_INDEX 107 +#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 iwn_rf_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = { +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, @@ -917,7 +1225,7 @@ static const uint8_t iwn_rf_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static const uint8_t iwn_rf_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = { +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, @@ -934,7 +1242,7 @@ static const uint8_t iwn_rf_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = { * DSP pre-DAC gain values from highest to lowest power (values obtained * from the reference driver.) */ -static const uint8_t iwn_dsp_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = { +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, @@ -947,7 +1255,7 @@ static const uint8_t iwn_dsp_gain_2ghz[IWN_MAX_PWR_INDEX + 1] = { 0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b }; -static const uint8_t iwn_dsp_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = { +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, @@ -960,12 +1268,104 @@ static const uint8_t iwn_dsp_gain_5ghz[IWN_MAX_PWR_INDEX + 1] = { 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, + 170, 210, + 85, 120, + 170, 210, + 125, 200, + 200, 400, + 97, + 100, + 100 +}; + +static const struct iwn_sensitivity_limits iwn5000_sensitivity_limits = { + 120, 155, + 240, 290, + 90, 120, + 170, 210, + 125, 200, + 170, 400, + 95, + 95, + 95 +}; + +/* 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 +}; + #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_REGION_4(sc, offset, datap, count) \ - bus_space_write_region_4((sc)->sc_st, (sc)->sc_sh, (offset), \ - (datap), (count)) +#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)) |