iwm(4): 3165 works fine with iwlwifi-7265D-17.ucode firmware.

firmware from http://git.kernel.org/cgit/linux/kernel/git/iwlwifi/linux-firmware.git/tree/?id=be8a6fcba2e48e00674d1f35e6def56e2268039c
This commit is contained in:
nonaka 2017-01-13 11:21:47 +00:00
parent 99c59bece0
commit 4480eb3627
6 changed files with 342 additions and 206 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1149 2017/01/11 12:02:24 joerg Exp $
# $NetBSD: mi,v 1.1150 2017/01/13 11:21:47 nonaka Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@ -163,7 +163,8 @@
./libdata/firmware/if_iwm/iwlwifi-7260-9.ucode base-obsolete obsolete
./libdata/firmware/if_iwm/iwlwifi-7265-16.ucode base-firmware-root
./libdata/firmware/if_iwm/iwlwifi-7265-9.ucode base-obsolete obsolete
./libdata/firmware/if_iwm/iwlwifi-7265D-16.ucode base-firmware-root
./libdata/firmware/if_iwm/iwlwifi-7265D-16.ucode base-obsolete obsolete
./libdata/firmware/if_iwm/iwlwifi-7265D-17.ucode base-firmware-root
./libdata/firmware/if_iwm/iwlwifi-8000C-16.ucode base-firmware-root
./libdata/firmware/if_iwn base-firmware-root
./libdata/firmware/if_iwn/LICENSE.iwlwifi-100-ucode base-firmware-root

View File

@ -1,9 +1,9 @@
# $NetBSD: Makefile,v 1.3 2016/12/18 17:57:38 christos Exp $
# $NetBSD: Makefile,v 1.4 2017/01/13 11:21:47 nonaka Exp $
NOMAN= # define
FILES= dist/LICENSE.iwlwifi-7265-ucode dist/README.iwlwifi-7265-ucode \
dist/iwlwifi-7265-16.ucode dist/iwlwifi-7265D-16.ucode
dist/iwlwifi-7265-16.ucode dist/iwlwifi-7265D-17.ucode
FILESDIR= /libdata/firmware/if_iwm

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_iwm.c,v 1.60 2017/01/10 08:40:27 nonaka Exp $ */
/* $NetBSD: if_iwm.c,v 1.61 2017/01/13 11:21:47 nonaka Exp $ */
/* OpenBSD: if_iwm.c,v 1.148 2016/11/19 21:07:08 stsp Exp */
#define IEEE80211_NO_HT
/*
@ -107,7 +107,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.60 2017/01/10 08:40:27 nonaka Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.61 2017/01/13 11:21:47 nonaka Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@ -239,7 +239,7 @@ static int iwm_store_cscheme(struct iwm_softc *, uint8_t *, size_t);
static int iwm_firmware_store_section(struct iwm_softc *,
enum iwm_ucode_type, uint8_t *, size_t);
static int iwm_set_default_calib(struct iwm_softc *, const void *);
static int iwm_read_firmware(struct iwm_softc *);
static int iwm_read_firmware(struct iwm_softc *, enum iwm_ucode_type);
static uint32_t iwm_read_prph(struct iwm_softc *, uint32_t);
static void iwm_write_prph(struct iwm_softc *, uint32_t, uint32_t);
#ifdef IWM_DEBUG
@ -474,8 +474,8 @@ static void iwm_nic_error(struct iwm_softc *);
static void iwm_nic_umac_error(struct iwm_softc *);
#endif
static void iwm_notif_intr(struct iwm_softc *);
static void iwm_softintr(void *);
static int iwm_intr(void *);
static void iwm_softintr(void *);
static int iwm_preinit(struct iwm_softc *);
static void iwm_attach_hook(device_t);
static void iwm_attach(device_t, device_t, void *);
@ -490,6 +490,11 @@ static int iwm_sysctl_fw_loaded_handler(SYSCTLFN_PROTO);
static int iwm_sysctl_root_num;
static int iwm_lar_disable;
#ifndef IWM_DEFAULT_MCC
#define IWM_DEFAULT_MCC "ZZ"
#endif
static char iwm_default_mcc[3] = IWM_DEFAULT_MCC;
static int
iwm_firmload(struct iwm_softc *sc)
{
@ -648,7 +653,7 @@ iwm_set_default_calib(struct iwm_softc *sc, const void *data)
}
static int
iwm_read_firmware(struct iwm_softc *sc)
iwm_read_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
{
struct iwm_fw_info *fw = &sc->sc_fw;
struct iwm_tlv_ucode_header *uhdr;
@ -658,6 +663,10 @@ iwm_read_firmware(struct iwm_softc *sc)
int err, status;
size_t len;
if (ucode_type != IWM_UCODE_TYPE_INIT &&
fw->fw_status == IWM_FW_STATUS_DONE)
return 0;
if (fw->fw_status == IWM_FW_STATUS_NONE) {
fw->fw_status = IWM_FW_STATUS_INPROGRESS;
} else {
@ -819,6 +828,7 @@ iwm_read_firmware(struct iwm_softc *sc)
api = (struct iwm_ucode_api *)tlv_data;
/* Flags may exceed 32 bits in future firmware. */
if (le32toh(api->api_index) > 0) {
err = EINVAL;
goto parse_out;
}
sc->sc_ucode_api = le32toh(api->api_flags);
@ -835,6 +845,7 @@ iwm_read_firmware(struct iwm_softc *sc)
capa = (struct iwm_ucode_capa *)tlv_data;
idx = le32toh(capa->api_index);
if (idx >= howmany(IWM_NUM_UCODE_TLV_CAPA, 32)) {
err = EINVAL;
goto parse_out;
}
for (i = 0; i < 32; i++) {
@ -1019,7 +1030,7 @@ iwm_nic_lock(struct iwm_softc *sc)
| IWM_CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP, 15000)) {
rv = 1;
} else {
aprint_error_dev(sc->sc_dev, "device timeout\n");
aprint_error_dev(sc->sc_dev, "resetting device via NMI\n");
IWM_WRITE(sc, IWM_CSR_RESET, IWM_CSR_RESET_REG_FLAG_FORCE_NMI);
}
@ -1228,7 +1239,7 @@ iwm_alloc_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring, int qid)
{
bus_addr_t paddr;
bus_size_t size;
int i, err;
int i, err, nsegs;
ring->qid = qid;
ring->queued = 0;
@ -1271,13 +1282,15 @@ iwm_alloc_tx_ring(struct iwm_softc *sc, struct iwm_tx_ring *ring, int qid)
paddr += sizeof(struct iwm_device_cmd);
/* FW commands may require more mapped space than packets. */
if (qid == IWM_CMD_QUEUE)
mapsize = (sizeof(struct iwm_cmd_header) +
IWM_MAX_CMD_PAYLOAD_SIZE);
else
if (qid == IWM_CMD_QUEUE) {
mapsize = IWM_RBUF_SIZE;
nsegs = 1;
} else {
mapsize = MCLBYTES;
err = bus_dmamap_create(sc->sc_dmat, mapsize,
IWM_NUM_OF_TBS - 2, mapsize, 0, BUS_DMA_NOWAIT, &data->map);
nsegs = IWM_NUM_OF_TBS - 2;
}
err = bus_dmamap_create(sc->sc_dmat, mapsize, nsegs, mapsize,
0, BUS_DMA_NOWAIT, &data->map);
if (err) {
aprint_error_dev(sc->sc_dev,
"could not create TX buf DMA map\n");
@ -1555,9 +1568,10 @@ iwm_apm_init(struct iwm_softc *sc)
int err = 0;
/* Disable L0S exit timer (platform NMI workaround) */
if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000)
if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) {
IWM_SETBITS(sc, IWM_CSR_GIO_CHICKEN_BITS,
IWM_CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
}
/*
* Disable L0s without affecting L1;
@ -1725,11 +1739,15 @@ iwm_stop_device(struct iwm_softc *sc)
for (qid = 0; qid < __arraycount(sc->txq); qid++)
iwm_reset_tx_ring(sc, &sc->txq[qid]);
/*
* Power-down device's busmaster DMA clocks
*/
iwm_write_prph(sc, IWM_APMG_CLK_DIS_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT);
DELAY(5);
if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
/* Power-down device's busmaster DMA clocks */
if (iwm_nic_lock(sc)) {
iwm_write_prph(sc, IWM_APMG_CLK_DIS_REG,
IWM_APMG_CLK_VAL_DMA_CLK_RQT);
DELAY(5);
iwm_nic_unlock(sc);
}
}
/* Make sure (redundant) we've released our request to stay awake */
IWM_CLRBITS(sc, IWM_CSR_GP_CNTRL,
@ -1785,10 +1803,11 @@ iwm_nic_config(struct iwm_softc *sc)
* (PCIe power is lost before PERST# is asserted), causing ME FW
* to lose ownership and not being able to obtain it back.
*/
if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000)
if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
~IWM_APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
}
}
static int
@ -1822,8 +1841,8 @@ iwm_nic_rx_init(struct iwm_softc *sc)
IWM_FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | /* HW bug */
IWM_FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
IWM_FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
(IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) |
IWM_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K |
(IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) |
IWM_RX_QUEUE_SIZE_LOG << IWM_FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS);
IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF);
@ -1880,10 +1899,11 @@ iwm_nic_init(struct iwm_softc *sc)
int err;
iwm_apm_init(sc);
if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000)
if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
iwm_set_bits_mask_prph(sc, IWM_APMG_PS_CTRL_REG,
IWM_APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
~IWM_APMG_PS_CTRL_MSK_PWR_SRC);
}
iwm_nic_config(sc);
@ -1923,9 +1943,14 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
(0 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE)
| (1 << IWM_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
iwm_nic_unlock(sc);
iwm_clear_bits_prph(sc, IWM_SCD_AGGR_SEL, (1 << qid));
if (!iwm_nic_lock(sc))
return EBUSY;
iwm_write_prph(sc, IWM_SCD_QUEUE_RDPTR(qid), 0);
iwm_nic_unlock(sc);
iwm_write_mem32(sc,
sc->sched_base + IWM_SCD_CONTEXT_QUEUE_OFFSET(qid), 0);
@ -1940,6 +1965,8 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
<< IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
IWM_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
if (!iwm_nic_lock(sc))
return EBUSY;
iwm_write_prph(sc, IWM_SCD_QUEUE_STATUS_BITS(qid),
(1 << IWM_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
(fifo << IWM_SCD_QUEUE_STTS_REG_POS_TXF) |
@ -1981,7 +2008,8 @@ iwm_enable_txq(struct iwm_softc *sc, int sta_id, int qid, int fifo)
static int
iwm_post_alive(struct iwm_softc *sc)
{
int nwords;
int nwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
IWM_SCD_CONTEXT_MEM_LOWER_BOUND) / sizeof(uint32_t);
int err, chnl;
uint32_t base;
@ -1992,21 +2020,21 @@ iwm_post_alive(struct iwm_softc *sc)
if (sc->sched_base != base) {
DPRINTF(("%s: sched addr mismatch: 0x%08x != 0x%08x\n",
DEVNAME(sc), sc->sched_base, base));
err = EINVAL;
goto out;
sc->sched_base = base;
}
iwm_nic_unlock(sc);
iwm_ict_reset(sc);
/* Clear TX scheduler state in SRAM. */
nwords = (IWM_SCD_TRANS_TBL_MEM_UPPER_BOUND -
IWM_SCD_CONTEXT_MEM_LOWER_BOUND)
/ sizeof(uint32_t);
err = iwm_write_mem(sc,
sc->sched_base + IWM_SCD_CONTEXT_MEM_LOWER_BOUND,
NULL, nwords);
sc->sched_base + IWM_SCD_CONTEXT_MEM_LOWER_BOUND, NULL, nwords);
if (err)
goto out;
return err;
if (!iwm_nic_lock(sc))
return EBUSY;
/* Set physical address of TX scheduler rings (1KB aligned). */
iwm_write_prph(sc, IWM_SCD_DRAM_BASE_ADDR, sc->sched_dma.paddr >> 10);
@ -2037,13 +2065,14 @@ iwm_post_alive(struct iwm_softc *sc)
IWM_FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
/* Enable L1-Active */
if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000)
if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) {
iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG,
IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
}
out:
iwm_nic_unlock(sc);
return err;
return 0;
}
static struct iwm_phy_db_entry *
@ -2408,7 +2437,8 @@ static const int iwm_nvm_to_read[] = {
/* Default NVM size to read */
#define IWM_NVM_DEFAULT_CHUNK_SIZE (2*1024)
#define IWM_MAX_NVM_SECTION_SIZE 8192
#define IWM_MAX_NVM_SECTION_SIZE_7000 (16 * 512 * sizeof(uint16_t)) /*16 KB*/
#define IWM_MAX_NVM_SECTION_SIZE_8000 (32 * 512 * sizeof(uint16_t)) /*32 KB*/
#define IWM_NVM_WRITE_OPCODE 1
#define IWM_NVM_READ_OPCODE 0
@ -2501,7 +2531,7 @@ iwm_nvm_read_section(struct iwm_softc *sc, uint16_t section, uint8_t *data,
err = iwm_nvm_read_chunk(sc, section, *len, chunklen, data,
&seglen);
if (err) {
DPRINTF(("%s:Cannot read NVM from section %d "
DPRINTF(("%s: Cannot read NVM from section %d "
"offset %d, length %d\n",
DEVNAME(sc), section, *len, chunklen));
return err;
@ -2817,8 +2847,6 @@ iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_t *nvm_hw,
uint8_t hw_addr[ETHER_ADDR_LEN];
uint32_t sku;
data->nvm_version = le16_to_cpup(nvm_sw + IWM_NVM_VERSION);
if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) {
uint16_t radio_cfg = le16_to_cpup(nvm_sw + IWM_RADIO_CFG);
data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg);
@ -2826,10 +2854,10 @@ iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_t *nvm_hw,
data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg);
data->radio_cfg_pnum = IWM_NVM_RF_CFG_PNUM_MSK(radio_cfg);
data->nvm_version = le16_to_cpup(nvm_sw + IWM_NVM_VERSION);
sku = le16_to_cpup(nvm_sw + IWM_SKU);
} else {
uint32_t radio_cfg = le32_to_cpup(
(const uint32_t *)(phy_sku + IWM_RADIO_CFG_8000));
uint32_t radio_cfg = le32_to_cpup(phy_sku + IWM_RADIO_CFG_8000);
data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK_8000(radio_cfg);
data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK_8000(radio_cfg);
data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK_8000(radio_cfg);
@ -2837,8 +2865,8 @@ iwm_parse_nvm_data(struct iwm_softc *sc, const uint16_t *nvm_hw,
data->valid_tx_ant = IWM_NVM_RF_CFG_TX_ANT_MSK_8000(radio_cfg);
data->valid_rx_ant = IWM_NVM_RF_CFG_RX_ANT_MSK_8000(radio_cfg);
sku = le32_to_cpup(
(const uint32_t *)(phy_sku + IWM_SKU_8000));
data->nvm_version = le32_to_cpup(nvm_sw + IWM_NVM_VERSION_8000);
sku = le32_to_cpup(phy_sku + IWM_SKU_8000);
}
data->sku_cap_band_24GHz_enable = sku & IWM_NVM_SKU_CAP_BAND_24GHZ;
@ -2942,7 +2970,8 @@ iwm_nvm_init(struct iwm_softc *sc)
int i, section, err;
uint16_t len;
uint8_t *buf;
const size_t bufsz = IWM_MAX_NVM_SECTION_SIZE;
const size_t bufsz = (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) ?
IWM_MAX_NVM_SECTION_SIZE_8000 : IWM_MAX_NVM_SECTION_SIZE_7000;
/* Read From FW NVM */
DPRINTF(("Read NVM\n"));
@ -2994,12 +3023,26 @@ iwm_firmware_load_sect(struct iwm_softc *sc, uint32_t dst_addr,
for (offset = 0; offset < byte_cnt; offset += chunk_sz) {
uint32_t addr, len;
const uint8_t *data;
bool is_extended = false;
addr = dst_addr + offset;
len = MIN(chunk_sz, byte_cnt - offset);
data = section + offset;
if (addr >= IWM_FW_MEM_EXTENDED_START &&
addr <= IWM_FW_MEM_EXTENDED_END)
is_extended = true;
if (is_extended)
iwm_set_bits_prph(sc, IWM_LMPM_CHICK,
IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
err = iwm_firmware_load_chunk(sc, addr, data, len);
if (is_extended)
iwm_clear_bits_prph(sc, IWM_LMPM_CHICK,
IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
if (err)
break;
}
@ -3012,7 +3055,6 @@ iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
const uint8_t *section, uint32_t byte_cnt)
{
struct iwm_dma_info *dma = &sc->fw_dma;
bool is_extended = false;
int err;
/* Copy firmware chunk into pre-allocated DMA-safe memory. */
@ -3020,23 +3062,10 @@ iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
bus_dmamap_sync(sc->sc_dmat, dma->map, 0, byte_cnt,
BUS_DMASYNC_PREWRITE);
if (dst_addr >= IWM_FW_MEM_EXTENDED_START &&
dst_addr <= IWM_FW_MEM_EXTENDED_END)
is_extended = true;
if (is_extended) {
iwm_set_bits_prph(sc, IWM_LMPM_CHICK,
IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
}
sc->sc_fw_chunk_done = 0;
if (!iwm_nic_lock(sc)) {
if (is_extended)
iwm_clear_bits_prph(sc, IWM_LMPM_CHICK,
IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
if (!iwm_nic_lock(sc))
return EBUSY;
}
IWM_WRITE(sc, IWM_FH_TCSR_CHNL_TX_CONFIG_REG(IWM_FH_SRVC_CHNL),
IWM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
@ -3066,17 +3095,8 @@ iwm_firmware_load_chunk(struct iwm_softc *sc, uint32_t dst_addr,
break;
}
if (!sc->sc_fw_chunk_done) {
aprint_error_dev(sc->sc_dev,
"fw chunk addr 0x%x len %d failed to load\n",
dst_addr, byte_cnt);
}
if (is_extended) {
int rv = iwm_nic_lock(sc);
iwm_clear_bits_prph(sc, IWM_LMPM_CHICK,
IWM_LMPM_CHICK_EXTENDED_ADDR_SPACE);
if (rv == 0)
iwm_nic_unlock(sc);
DPRINTF(("%s: fw chunk addr 0x%x len %d failed to load\n",
DEVNAME(sc), dst_addr, byte_cnt));
}
return err;
@ -3101,9 +3121,8 @@ iwm_load_firmware_7000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
} else
err = iwm_firmware_load_sect(sc, offset, data, dlen);
if (err) {
aprint_error_dev(sc->sc_dev,
"could not load firmware chunk %u of %u\n",
i, fws->fw_count);
DPRINTF(("%s: could not load firmware chunk %u of %u\n",
DEVNAME(sc), i, fws->fw_count));
return err;
}
}
@ -3153,9 +3172,8 @@ iwm_load_cpu_sections_8000(struct iwm_softc *sc, struct iwm_fw_sects *fws,
} else
err = iwm_firmware_load_sect(sc, offset, data, dlen);
if (err) {
aprint_error_dev(sc->sc_dev,
"could not load firmware chunk %d (error %d)\n",
i, err);
DPRINTF(("%s: could not load firmware chunk %d "
"(error %d)\n", DEVNAME(sc), i, err));
return err;
}
@ -3198,7 +3216,11 @@ iwm_load_firmware_8000(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
/* configure the ucode to be ready to get the secured image */
/* release CPU reset */
iwm_write_prph(sc, IWM_RELEASE_CPU_RESET, IWM_RELEASE_CPU_RESET_BIT);
if (iwm_nic_lock(sc)) {
iwm_write_prph(sc, IWM_RELEASE_CPU_RESET,
IWM_RELEASE_CPU_RESET_BIT);
iwm_nic_unlock(sc);
}
/* load to FW the binary Secured sections of CPU1 */
err = iwm_load_cpu_sections_8000(sc, fws, 1, &first_ucode_section);
@ -3220,15 +3242,23 @@ iwm_load_firmware(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
err = iwm_load_firmware_8000(sc, ucode_type);
else
err = iwm_load_firmware_7000(sc, ucode_type);
if (err)
return err;
/* wait for the firmware to load */
for (w = 0; !sc->sc_uc.uc_intr && w < 10; w++)
err = tsleep(&sc->sc_uc, 0, "iwmuc", mstohz(100));
if (err || !sc->sc_uc.uc_ok)
aprint_error_dev(sc->sc_dev, "could not load firmware\n");
if (err || !sc->sc_uc.uc_ok) {
aprint_error_dev(sc->sc_dev,
"could not load firmware (error %d, ok %d)\n",
err, sc->sc_uc.uc_ok);
if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) {
aprint_error_dev(sc->sc_dev, "cpu1 status: 0x%x\n",
iwm_read_prph(sc, IWM_SB_CPU_1_STATUS));
aprint_error_dev(sc->sc_dev, "cpu2 status: 0x%x\n",
iwm_read_prph(sc, IWM_SB_CPU_2_STATUS));
}
}
return err;
}
@ -3297,7 +3327,7 @@ iwm_load_ucode_wait_alive(struct iwm_softc *sc, enum iwm_ucode_type ucode_type)
enum iwm_ucode_type old_type = sc->sc_uc_current;
int err;
err = iwm_read_firmware(sc);
err = iwm_read_firmware(sc, ucode_type);
if (err)
return err;
@ -3325,7 +3355,7 @@ iwm_run_init_mvm_ucode(struct iwm_softc *sc, int justnvm)
sc->sc_init_complete = 0;
err = iwm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_INIT);
if (err) {
aprint_error_dev(sc->sc_dev, "failed to load init firmware\n");
DPRINTF(("%s: failed to load init firmware\n", DEVNAME(sc)));
return err;
}
@ -3602,7 +3632,8 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
if (phy_info->phy_flags &
htole16(IWM_RX_RES_PHY_FLAGS_OFDM_HT)) {
uint8_t mcs = (phy_info->rate_n_flags &
htole32(IWM_RATE_HT_MCS_RATE_CODE_MSK));
htole32(IWM_RATE_HT_MCS_RATE_CODE_MSK |
IWM_RATE_HT_MCS_NSS_MSK));
tap->wr_rate = (0x80 | mcs);
} else {
uint8_t rate = (phy_info->rate_n_flags &
@ -3672,10 +3703,14 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
struct iwm_tx_ring *ring = &sc->txq[qid];
struct iwm_tx_data *txd = &ring->data[idx];
struct iwm_node *in = txd->in;
int s;
s = splnet();
if (txd->done) {
DPRINTF(("%s: got tx interrupt that's already been handled!\n",
DEVNAME(sc)));
splx(s);
return;
}
@ -3701,12 +3736,14 @@ iwm_rx_tx_cmd(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
ieee80211_free_node(&in->in_ni);
if (--ring->queued < IWM_TX_RING_LOMARK) {
sc->qfullmsk &= ~(1 << ring->qid);
sc->qfullmsk &= ~(1 << qid);
if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
ifp->if_flags &= ~IFF_OACTIVE;
if_start_lock(ifp);
}
}
splx(s);
}
static int
@ -3920,16 +3957,16 @@ iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd)
code, hdrlen + paylen, async ? " (async)" : ""));
if (paylen > datasz) {
bus_dmamap_sync(sc->sc_dmat, txdata->map, 0,
hdrlen + paylen, BUS_DMASYNC_PREWRITE);
bus_dmamap_sync(sc->sc_dmat, txdata->map, 0, hdrlen + paylen,
BUS_DMASYNC_PREWRITE);
} else {
bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
(char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
hdrlen + paylen, BUS_DMASYNC_PREWRITE);
(uint8_t *)cmd - (uint8_t *)ring->cmd, hdrlen + paylen,
BUS_DMASYNC_PREWRITE);
}
bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
(char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
sizeof(*desc), BUS_DMASYNC_PREWRITE);
(uint8_t *)desc - (uint8_t *)ring->desc, sizeof(*desc),
BUS_DMASYNC_PREWRITE);
err = iwm_set_cmd_in_flight(sc);
if (err)
@ -4048,11 +4085,14 @@ iwm_cmd_done(struct iwm_softc *sc, int qid, int idx)
{
struct iwm_tx_ring *ring = &sc->txq[IWM_CMD_QUEUE];
struct iwm_tx_data *data;
int s;
if (qid != IWM_CMD_QUEUE) {
return; /* Not a command ack. */
}
s = splnet();
data = &ring->data[idx];
if (data->m != NULL) {
@ -4073,6 +4113,8 @@ iwm_cmd_done(struct iwm_softc *sc, int qid, int idx)
KASSERT(ring->queued > 0);
if (--ring->queued == 0)
iwm_clear_cmd_in_flight(sc);
splx(s);
}
#if 0
@ -4124,7 +4166,7 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
struct ieee80211_node *ni = &in->in_ni;
const struct iwm_rate *rinfo;
int type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
int ridx, rate_flags, i;
int ridx, rate_flags, i, ind;
int nrates = ni->ni_rates.rs_nrates;
tx->rts_retry_limit = IWM_RTS_DFAULT_RETRY_LIMIT;
@ -4167,7 +4209,15 @@ iwm_tx_fill_cmd(struct iwm_softc *sc, struct iwm_node *in,
}
rinfo = &iwm_rates[ridx];
rate_flags = 1 << IWM_RATE_MCS_ANT_POS;
for (i = 0, ind = sc->sc_mgmt_last_antenna;
i < IWM_RATE_MCS_ANT_NUM; i++) {
ind = (ind + 1) % IWM_RATE_MCS_ANT_NUM;
if (iwm_fw_valid_tx_ant(sc) & (1 << ind)) {
sc->sc_mgmt_last_antenna = ind;
break;
}
}
rate_flags = (1 << sc->sc_mgmt_last_antenna) << IWM_RATE_MCS_ANT_POS;
if (IWM_RIDX_IS_CCK(ridx))
rate_flags |= IWM_RATE_MCS_CCK_MSK;
#ifndef IEEE80211_NO_HT
@ -4307,7 +4357,7 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
tx->dram_msb_ptr = iwm_get_dma_hi_addr(data->scratch_paddr);
/* Copy 802.11 header in TX command. */
memcpy(((uint8_t *)tx) + sizeof(*tx), wh, hdrlen);
memcpy(tx + 1, wh, hdrlen);
flags |= IWM_TX_CMD_FLG_BT_DIS | IWM_TX_CMD_FLG_SEQ_CTL;
@ -4361,8 +4411,12 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
DPRINTFN(8, ("sending txd %p, in %p\n", data, data->in));
KASSERT(data->in != NULL);
DPRINTFN(8, ("sending data: qid=%d idx=%d len=%d nsegs=%d\n",
ring->qid, ring->cur, totlen, data->map->dm_nsegs));
DPRINTFN(8, ("sending data: qid=%d idx=%d len=%d nsegs=%d type=%d "
"subtype=%x tx_flags=%08x init_rateidx=%08x rate_n_flags=%08x\n",
ring->qid, ring->cur, totlen, data->map->dm_nsegs, type,
(wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >> 4,
le32toh(tx->tx_flags), le32toh(tx->initial_rate_index),
le32toh(tx->rate_n_flags)));
/* Fill TX descriptor. */
desc->num_tbs = 2 + data->map->dm_nsegs;
@ -4387,11 +4441,11 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac)
bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize,
BUS_DMASYNC_PREWRITE);
bus_dmamap_sync(sc->sc_dmat, ring->cmd_dma.map,
(char *)(void *)cmd - (char *)(void *)ring->cmd_dma.vaddr,
sizeof (*cmd), BUS_DMASYNC_PREWRITE);
(uint8_t *)cmd - (uint8_t *)ring->cmd, sizeof(*cmd),
BUS_DMASYNC_PREWRITE);
bus_dmamap_sync(sc->sc_dmat, ring->desc_dma.map,
(char *)(void *)desc - (char *)(void *)ring->desc_dma.vaddr,
sizeof (*desc), BUS_DMASYNC_PREWRITE);
(uint8_t *)desc - (uint8_t *)ring->desc, sizeof(*desc),
BUS_DMASYNC_PREWRITE);
#if 0
iwm_update_sched(sc, ring->qid, ring->cur, tx->sta_id,
@ -4799,12 +4853,11 @@ iwm_lmac_scan_fill_channels(struct iwm_softc *sc,
chan->channel_num = htole16(ieee80211_mhz2ieee(c->ic_freq, 0));
chan->iter_count = htole16(1);
chan->iter_interval = 0;
chan->iter_interval = htole32(0);
chan->flags = htole32(IWM_UNIFIED_SCAN_CHANNEL_PARTIAL);
#if 0 /* makes scanning while associated less useful */
if (n_ssids != 0)
chan->flags |= htole32(1 << 1); /* select SSID 0 */
#endif
chan->flags |= htole32(IWM_SCAN_CHANNEL_NSSIDS(n_ssids));
if (!IEEE80211_IS_CHAN_PASSIVE(c) && n_ssids != 0)
chan->flags |= htole32(IWM_SCAN_CHANNEL_TYPE_ACTIVE);
chan++;
nchan++;
}
@ -4826,13 +4879,11 @@ iwm_umac_scan_fill_channels(struct iwm_softc *sc,
c++) {
if (c->ic_flags == 0)
continue;
chan->channel_num = ieee80211_mhz2ieee(c->ic_freq, 0);
chan->iter_count = 1;
chan->iter_interval = htole16(0);
#if 0 /* makes scanning while associated less useful */
if (n_ssids != 0)
chan->flags = htole32(1 << 0); /* select SSID 0 */
#endif
chan->flags = htole32(IWM_SCAN_CHANNEL_UMAC_NSSIDS(n_ssids));
chan++;
nchan++;
}
@ -5961,11 +6012,14 @@ static void
iwm_endscan(struct iwm_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
int s;
DPRINTF(("scan ended\n"));
DPRINTF(("%s: scan ended\n", DEVNAME(sc)));
CLR(sc->sc_flags, IWM_FLAG_SCANNING);
ieee80211_end_scan(ic);
s = splnet();
if (ic->ic_state == IEEE80211_S_SCAN)
ieee80211_end_scan(ic);
splx(s);
}
/*
@ -6213,7 +6267,8 @@ iwm_init_hw(struct iwm_softc *sc)
/* Restart, this time with the regular firmware */
err = iwm_load_ucode_wait_alive(sc, IWM_UCODE_TYPE_REGULAR);
if (err) {
aprint_error_dev(sc->sc_dev, "could not load firmware\n");
aprint_error_dev(sc->sc_dev,
"could not load firmware (error %d)\n", err);
goto err;
}
@ -6282,7 +6337,7 @@ iwm_init_hw(struct iwm_softc *sc)
goto err;
}
err = iwm_send_update_mcc_cmd(sc, "ZZ");
err = iwm_send_update_mcc_cmd(sc, iwm_default_mcc);
if (err) {
aprint_error_dev(sc->sc_dev,
"could not init LAR (error %d)\n", err);
@ -6353,6 +6408,7 @@ iwm_init(struct ifnet *ifp)
{
struct iwm_softc *sc = ifp->if_softc;
int err;
int s;
if (ISSET(sc->sc_flags, IWM_FLAG_HW_INITED))
return 0;
@ -6369,7 +6425,10 @@ iwm_init(struct ifnet *ifp)
ifp->if_flags &= ~IFF_OACTIVE;
ifp->if_flags |= IFF_RUNNING;
s = splnet();
ieee80211_begin_scan(&sc->sc_ic, 0);
splx(s);
SET(sc->sc_flags, IWM_FLAG_HW_INITED);
return 0;
@ -6467,6 +6526,7 @@ iwm_stop(struct ifnet *ifp, int disable)
struct iwm_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
int s;
sc->sc_flags &= ~IWM_FLAG_HW_INITED;
sc->sc_flags |= IWM_FLAG_STOPPED;
@ -6476,8 +6536,10 @@ iwm_stop(struct ifnet *ifp, int disable)
if (in)
in->in_phyctxt = NULL;
s = splnet();
if (ic->ic_state != IEEE80211_S_INIT)
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
splx(s);
callout_stop(&sc->sc_calib_to);
iwm_led_blink_stop(sc);
@ -6986,7 +7048,25 @@ iwm_notif_intr(struct iwm_softc *sc)
}
case IWM_DTS_MEASUREMENT_NOTIFICATION:
case IWM_WIDE_ID(IWM_PHY_OPS_GROUP,
IWM_DTS_MEASUREMENT_NOTIF_WIDE): {
struct iwm_dts_measurement_notif_v1 *notif1;
struct iwm_dts_measurement_notif_v2 *notif2;
if (iwm_rx_packet_payload_len(pkt) == sizeof(*notif1)) {
SYNC_RESP_STRUCT(notif1, pkt);
DPRINTF(("%s: DTS temp=%d \n",
DEVNAME(sc), notif1->temp));
break;
}
if (iwm_rx_packet_payload_len(pkt) == sizeof(*notif2)) {
SYNC_RESP_STRUCT(notif2, pkt);
DPRINTF(("%s: DTS temp=%d \n",
DEVNAME(sc), notif2->temp));
break;
}
break;
}
case IWM_PHY_CONFIGURATION_CMD:
case IWM_TX_ANT_CONFIGURATION_CMD:
@ -7000,7 +7080,9 @@ iwm_notif_intr(struct iwm_softc *sc)
case IWM_SCAN_REQUEST_CMD:
case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_CFG_CMD):
case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_REQ_UMAC):
case IWM_WIDE_ID(IWM_ALWAYS_LONG_GROUP, IWM_SCAN_ABORT_UMAC):
case IWM_SCAN_OFFLOAD_REQUEST_CMD:
case IWM_SCAN_OFFLOAD_ABORT_CMD:
case IWM_REPLY_BEACON_FILTERING_CMD:
case IWM_MAC_PM_POWER_TABLE:
case IWM_TIME_QUOTA_CMD:
@ -7017,7 +7099,7 @@ iwm_notif_intr(struct iwm_softc *sc)
break;
/* ignore */
case 0x6c: /* IWM_PHY_DB_CMD */
case IWM_PHY_DB_CMD:
break;
case IWM_INIT_COMPLETE_NOTIF:
@ -7034,21 +7116,30 @@ iwm_notif_intr(struct iwm_softc *sc)
case IWM_SCAN_ITERATION_COMPLETE: {
struct iwm_lmac_scan_complete_notif *notif;
SYNC_RESP_STRUCT(notif, pkt);
iwm_endscan(sc);
if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
CLR(sc->sc_flags, IWM_FLAG_SCANNING);
iwm_endscan(sc);
}
break;
}
case IWM_SCAN_COMPLETE_UMAC: {
struct iwm_umac_scan_complete *notif;
SYNC_RESP_STRUCT(notif, pkt);
iwm_endscan(sc);
if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
CLR(sc->sc_flags, IWM_FLAG_SCANNING);
iwm_endscan(sc);
}
break;
}
case IWM_SCAN_ITERATION_COMPLETE_UMAC: {
struct iwm_umac_scan_iter_complete_notif *notif;
SYNC_RESP_STRUCT(notif, pkt);
iwm_endscan(sc);
if (ISSET(sc->sc_flags, IWM_FLAG_SCANNING)) {
CLR(sc->sc_flags, IWM_FLAG_SCANNING);
iwm_endscan(sc);
}
break;
}
@ -7105,6 +7196,68 @@ iwm_notif_intr(struct iwm_softc *sc)
IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, hw & ~7);
}
static int
iwm_intr(void *arg)
{
struct iwm_softc *sc = arg;
int r1, r2;
IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
if (sc->sc_flags & IWM_FLAG_USE_ICT) {
uint32_t *ict = sc->ict_dma.vaddr;
int tmp;
bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map,
0, sc->ict_dma.size, BUS_DMASYNC_POSTREAD);
tmp = htole32(ict[sc->ict_cur]);
if (!tmp)
goto out_ena;
/*
* ok, there was something. keep plowing until we have all.
*/
r1 = r2 = 0;
while (tmp) {
r1 |= tmp;
ict[sc->ict_cur] = 0; /* Acknowledge. */
bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map,
&ict[sc->ict_cur] - ict, sizeof(*ict),
BUS_DMASYNC_PREWRITE);
sc->ict_cur = (sc->ict_cur + 1) % IWM_ICT_COUNT;
tmp = htole32(ict[sc->ict_cur]);
}
/* this is where the fun begins. don't ask */
if (r1 == 0xffffffff)
r1 = 0;
/* i am not expected to understand this */
if (r1 & 0xc0000)
r1 |= 0x8000;
r1 = (0xff & r1) | ((0xff00 & r1) << 16);
} else {
r1 = IWM_READ(sc, IWM_CSR_INT);
if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
goto out;
r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS);
}
if (r1 == 0 && r2 == 0) {
goto out_ena;
}
IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
atomic_or_32(&sc->sc_soft_flags, r1);
softint_schedule(sc->sc_soft_ih);
return 1;
out_ena:
iwm_restore_interrupts(sc);
out:
return 0;
}
static void
iwm_softintr(void *arg)
{
@ -7115,7 +7268,6 @@ iwm_softintr(void *arg)
r1 = atomic_swap_32(&sc->sc_soft_flags, 0);
restart:
if (r1 & IWM_CSR_INT_BIT_SW_ERR) {
#ifdef IWM_DEBUG
int i;
@ -7185,75 +7337,9 @@ iwm_softintr(void *arg)
IWM_CSR_INT_PERIODIC_ENA);
}
r1 = atomic_swap_32(&sc->sc_soft_flags, 0);
if (r1 != 0)
goto restart;
iwm_restore_interrupts(sc);
}
static int
iwm_intr(void *arg)
{
struct iwm_softc *sc = arg;
int r1, r2;
IWM_WRITE(sc, IWM_CSR_INT_MASK, 0);
if (sc->sc_flags & IWM_FLAG_USE_ICT) {
uint32_t *ict = sc->ict_dma.vaddr;
int tmp;
bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map,
0, sc->ict_dma.size, BUS_DMASYNC_POSTREAD);
tmp = htole32(ict[sc->ict_cur]);
if (!tmp)
goto out_ena;
/*
* ok, there was something. keep plowing until we have all.
*/
r1 = r2 = 0;
while (tmp) {
r1 |= tmp;
ict[sc->ict_cur] = 0; /* Acknowledge. */
bus_dmamap_sync(sc->sc_dmat, sc->ict_dma.map,
&ict[sc->ict_cur] - ict, sizeof(*ict),
BUS_DMASYNC_PREWRITE);
sc->ict_cur = (sc->ict_cur + 1) % IWM_ICT_COUNT;
tmp = htole32(ict[sc->ict_cur]);
}
/* this is where the fun begins. don't ask */
if (r1 == 0xffffffff)
r1 = 0;
/* i am not expected to understand this */
if (r1 & 0xc0000)
r1 |= 0x8000;
r1 = (0xff & r1) | ((0xff00 & r1) << 16);
} else {
r1 = IWM_READ(sc, IWM_CSR_INT);
if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0)
goto out;
r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS);
}
if (r1 == 0 && r2 == 0) {
goto out_ena;
}
IWM_WRITE(sc, IWM_CSR_INT, r1 | ~sc->sc_intmask);
atomic_or_32(&sc->sc_soft_flags, r1);
softint_schedule(sc->sc_soft_ih);
return 1;
out_ena:
iwm_restore_interrupts(sc);
out:
return 0;
}
/*
* Autoconf glue-sniffing
*/
@ -7265,10 +7351,8 @@ static const pci_product_id_t iwm_devices[] = {
PCI_PRODUCT_INTEL_WIFI_LINK_3160_2,
PCI_PRODUCT_INTEL_WIFI_LINK_7265_1,
PCI_PRODUCT_INTEL_WIFI_LINK_7265_2,
#ifdef notyet
PCI_PRODUCT_INTEL_WIFI_LINK_3165_1,
PCI_PRODUCT_INTEL_WIFI_LINK_3165_2,
#endif
PCI_PRODUCT_INTEL_WIFI_LINK_8260_1,
PCI_PRODUCT_INTEL_WIFI_LINK_8260_2,
PCI_PRODUCT_INTEL_WIFI_LINK_4165_1,
@ -7413,15 +7497,12 @@ iwm_attach(device_t parent, device_t self, void *aux)
aprint_error_dev(self, "can't allocate interrupt\n");
return;
}
if (pci_intr_type(sc->sc_pct, sc->sc_pihp[0]) == PCI_INTR_TYPE_INTX) {
reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag,
PCI_COMMAND_STATUS_REG);
if (ISSET(reg, PCI_COMMAND_INTERRUPT_DISABLE)) {
CLR(reg, PCI_COMMAND_INTERRUPT_DISABLE);
pci_conf_write(sc->sc_pct, sc->sc_pcitag,
PCI_COMMAND_STATUS_REG, reg);
}
}
reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
if (pci_intr_type(sc->sc_pct, sc->sc_pihp[0]) == PCI_INTR_TYPE_INTX)
CLR(reg, PCI_COMMAND_INTERRUPT_DISABLE);
else
SET(reg, PCI_COMMAND_INTERRUPT_DISABLE);
pci_conf_write(sc->sc_pct, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, reg);
intrstr = pci_intr_string(sc->sc_pct, sc->sc_pihp[0], intrbuf,
sizeof(intrbuf));
sc->sc_ih = pci_intr_establish_xname(sc->sc_pct, sc->sc_pihp[0],
@ -7449,7 +7530,7 @@ iwm_attach(device_t parent, device_t self, void *aux)
break;
case PCI_PRODUCT_INTEL_WIFI_LINK_3165_1:
case PCI_PRODUCT_INTEL_WIFI_LINK_3165_2:
sc->sc_fwname = "iwlwifi-7265D-16.ucode";
sc->sc_fwname = "iwlwifi-7265D-17.ucode";
sc->host_interrupt_operation_mode = 0;
sc->apmg_wake_up_wa = 1;
sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
@ -7467,7 +7548,7 @@ iwm_attach(device_t parent, device_t self, void *aux)
case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2:
sc->sc_fwname = (sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK) ==
IWM_CSR_HW_REV_TYPE_7265D ?
"iwlwifi-7265D-16.ucode": "iwlwifi-7265-16.ucode";
"iwlwifi-7265D-17.ucode": "iwlwifi-7265-16.ucode";
sc->host_interrupt_operation_mode = 0;
sc->apmg_wake_up_wa = 1;
sc->sc_device_family = IWM_DEVICE_FAMILY_7000;
@ -7686,7 +7767,6 @@ iwm_attach(device_t parent, device_t self, void *aux)
#endif
/* Use common softint-based if_input */
ifp->if_percpuq = if_percpuq_create(ifp);
if_deferred_start_init(ifp, NULL);
if_register(ifp);
callout_init(&sc->sc_calib_to, 0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_iwmreg.h,v 1.4 2017/01/09 09:15:54 nonaka Exp $ */
/* $NetBSD: if_iwmreg.h,v 1.5 2017/01/13 11:21:47 nonaka Exp $ */
/* OpenBSD: if_iwmreg.h,v 1.19 2016/09/20 11:46:09 stsp Exp */
/******************************************************************************
@ -1777,7 +1777,7 @@ enum {
/* Phy */
IWM_PHY_CONFIGURATION_CMD = 0x6a,
IWM_CALIB_RES_NOTIF_PHY_DB = 0x6b,
/* IWM_PHY_DB_CMD = 0x6c, */
IWM_PHY_DB_CMD = 0x6c,
/* Power - legacy power table command */
IWM_POWER_TABLE_CMD = 0x77,
@ -1867,6 +1867,25 @@ enum {
IWM_REPLY_MAX = 0xff,
};
enum iwm_phy_ops_subcmd_ids {
IWM_CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0,
IWM_CTDP_CONFIG_CMD = 0x03,
IWM_TEMP_REPORTING_THRESHOLDS_CMD = 0x04,
IWM_CT_KILL_NOTIFICATION = 0xFE,
IWM_DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
};
/* command groups */
enum {
IWM_LEGACY_GROUP = 0x0,
IWM_LONG_GROUP = 0x1,
IWM_SYSTEM_GROUP = 0x2,
IWM_MAC_CONF_GROUP = 0x3,
IWM_PHY_OPS_GROUP = 0x4,
IWM_DATA_PATH_GROUP = 0x5,
IWM_PROT_OFFLOAD_GROUP = 0xb,
};
/**
* struct iwm_cmd_response - generic response struct for most commands
* @status: status of the command asked, changes for each one
@ -1966,8 +1985,6 @@ enum iwm_phy_db_section_type {
IWM_PHY_DB_MAX
};
#define IWM_PHY_DB_CMD 0x6c /* TEMP API - The actual is 0x8c */
/*
* phy db - configure operational ucode
*/
@ -4816,6 +4833,7 @@ struct iwm_scd_txq_cfg_rsp {
/* Masks for iwm_scan_channel.type flags */
#define IWM_SCAN_CHANNEL_TYPE_ACTIVE (1 << 0)
#define IWM_SCAN_CHANNEL_NSSIDS(x) (((1 << (x)) - 1) << 1)
#define IWM_SCAN_CHANNEL_NARROW_BAND (1 << 22)
/* Max number of IEs for direct SSID scans in a command */
@ -5622,6 +5640,7 @@ enum iwm_umac_scan_general_flags {
*/
struct iwm_scan_channel_cfg_umac {
uint32_t flags;
#define IWM_SCAN_CHANNEL_UMAC_NSSIDS(x) ((1 << (x)) - 1)
uint8_t channel_num;
uint8_t iter_count;
uint16_t iter_interval;
@ -6321,6 +6340,30 @@ enum iwm_mcc_source {
IWM_MCC_SOURCE_GETTING_MCC_TEST_MODE = 0x11,
};
/**
* struct iwm_dts_measurement_notif_v1 - measurements notification
*
* @temp: the measured temperature
* @voltage: the measured voltage
*/
struct iwm_dts_measurement_notif_v1 {
int32_t temp;
int32_t voltage;
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_1*/
/**
* struct iwm_dts_measurement_notif_v2 - measurements notification
*
* @temp: the measured temperature
* @voltage: the measured voltage
* @threshold_idx: the trip index that was crossed
*/
struct iwm_dts_measurement_notif_v2 {
int32_t temp;
int32_t voltage;
int32_t threshold_idx;
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_2 */
/*
* Some cherry-picked definitions
*/
@ -6386,6 +6429,12 @@ struct iwm_cmd_header_wide {
uint8_t version;
} __packed;
/**
* enum iwm_power_scheme
* @IWM_POWER_LEVEL_CAM - Continuously Active Mode
* @IWM_POWER_LEVEL_BPS - Balanced Power Save (default)
* @IWM_POWER_LEVEL_LP - Low Power
*/
enum iwm_power_scheme {
IWM_POWER_SCHEME_CAM = 1,
IWM_POWER_SCHEME_BPS,
@ -6450,6 +6499,11 @@ iwm_rx_packet_payload_len(const struct iwm_rx_packet *pkt)
return iwm_rx_packet_len(pkt) - sizeof(pkt->hdr);
}
/*
* Maximum number of HW queues the transport layer
* currently supports
*/
#define IWM_MAX_TID_COUNT 8
#define IWM_MIN_DBM -100
#define IWM_MAX_DBM -33 /* realistic guess */

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_iwmvar.h,v 1.14 2017/01/10 08:40:27 nonaka Exp $ */
/* $NetBSD: if_iwmvar.h,v 1.15 2017/01/13 11:21:47 nonaka Exp $ */
/* OpenBSD: if_iwmvar.h,v 1.24 2016/09/21 13:53:18 stsp Exp */
/*
@ -448,6 +448,7 @@ struct iwm_softc {
int sc_rx_ba_sessions;
int sc_scan_last_antenna;
int sc_mgmt_last_antenna;
int sc_fixed_ridx;