From owner-svn-src-all@freebsd.org Mon Feb 6 03:29:51 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B99EECD2223; Mon, 6 Feb 2017 03:29:51 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7C0B6A66; Mon, 6 Feb 2017 03:29:51 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v163Tojo034754; Mon, 6 Feb 2017 03:29:50 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v163TofP034751; Mon, 6 Feb 2017 03:29:50 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201702060329.v163TofP034751@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Mon, 6 Feb 2017 03:29:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r313312 - head/sys/dev/iwm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Feb 2017 03:29:51 -0000 Author: adrian Date: Mon Feb 6 03:29:50 2017 New Revision: 313312 URL: https://svnweb.freebsd.org/changeset/base/313312 Log: [iwm] Use chipset configuration structs like iwlwifi does. * This makes it a bit easier to factor out common parts for e.g. the 7000 chipset family. * Add iwm7265d config, and recognize the 7265D chipset variant via the hardware revision. Tested: * 7260, STA mode (2ghz) Obtained from: Dragonflybsd commit cc8d6ccf5583fd45964f3bde9b057ee4f834c0e0 Modified: head/sys/dev/iwm/if_iwm.c head/sys/dev/iwm/if_iwm_pcie_trans.c head/sys/dev/iwm/if_iwmvar.h Modified: head/sys/dev/iwm/if_iwm.c ============================================================================== --- head/sys/dev/iwm/if_iwm.c Mon Feb 6 03:06:11 2017 (r313311) +++ head/sys/dev/iwm/if_iwm.c Mon Feb 6 03:29:50 2017 (r313312) @@ -165,6 +165,67 @@ __FBSDID("$FreeBSD$"); #include #include +#define IWM_NVM_HW_SECTION_NUM_FAMILY_7000 0 +#define IWM_NVM_HW_SECTION_NUM_FAMILY_8000 10 + +/* lower blocks contain EEPROM image and calibration data */ +#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(uint16_t)) /* 16 KB */ +#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(uint16_t)) /* 32 KB */ + +#define IWM7260_FW "iwm7260fw" +#define IWM3160_FW "iwm3160fw" +#define IWM7265_FW "iwm7265fw" +#define IWM7265D_FW "iwm7265Dfw" +#define IWM8000_FW "iwm8000Cfw" + +#define IWM_DEVICE_7000_COMMON \ + .device_family = IWM_DEVICE_FAMILY_7000, \ + .eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000, \ + .nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000 + +const struct iwm_cfg iwm7260_cfg = { + .fw_name = IWM7260_FW, + IWM_DEVICE_7000_COMMON, + .host_interrupt_operation_mode = 1, +}; + +const struct iwm_cfg iwm3160_cfg = { + .fw_name = IWM3160_FW, + IWM_DEVICE_7000_COMMON, + .host_interrupt_operation_mode = 1, +}; + +const struct iwm_cfg iwm3165_cfg = { + /* XXX IWM7265D_FW doesn't seem to work properly yet */ + .fw_name = IWM7265_FW, + IWM_DEVICE_7000_COMMON, + .host_interrupt_operation_mode = 0, +}; + +const struct iwm_cfg iwm7265_cfg = { + .fw_name = IWM7265_FW, + IWM_DEVICE_7000_COMMON, + .host_interrupt_operation_mode = 0, +}; + +const struct iwm_cfg iwm7265d_cfg = { + /* XXX IWM7265D_FW doesn't seem to work properly yet */ + .fw_name = IWM7265_FW, + IWM_DEVICE_7000_COMMON, + .host_interrupt_operation_mode = 0, +}; + +#define IWM_DEVICE_8000_COMMON \ + .device_family = IWM_DEVICE_FAMILY_8000, \ + .eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000, \ + .nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_8000 + +const struct iwm_cfg iwm8260_cfg = { + .fw_name = IWM8000_FW, + IWM_DEVICE_8000_COMMON, + .host_interrupt_operation_mode = 0, +}; + const uint8_t iwm_nvm_channels[] = { /* 2.4 GHz */ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, @@ -512,12 +573,12 @@ iwm_read_firmware(struct iwm_softc *sc, * fw_fp will be set. */ IWM_UNLOCK(sc); - fwp = firmware_get(sc->sc_fwname); + fwp = firmware_get(sc->cfg->fw_name); IWM_LOCK(sc); if (fwp == NULL) { device_printf(sc->sc_dev, "could not read firmware %s (error %d)\n", - sc->sc_fwname, error); + sc->cfg->fw_name, error); goto out; } fw->fw_fp = fwp; @@ -536,7 +597,7 @@ iwm_read_firmware(struct iwm_softc *sc, if (*(const uint32_t *)fw->fw_fp->data != 0 || le32toh(uhdr->magic) != IWM_TLV_UCODE_MAGIC) { device_printf(sc->sc_dev, "invalid firmware %s\n", - sc->sc_fwname); + sc->cfg->fw_name); error = EINVAL; goto out; } @@ -1370,7 +1431,7 @@ iwm_mvm_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->cfg->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); @@ -1416,7 +1477,7 @@ iwm_nic_rx_init(struct iwm_softc *sc) IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF); /* W/A for interrupt coalescing bug in 7260 and 3160 */ - if (sc->host_interrupt_operation_mode) + if (sc->cfg->host_interrupt_operation_mode) IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE); /* @@ -1473,7 +1534,7 @@ iwm_nic_init(struct iwm_softc *sc) int error; iwm_apm_init(sc); - if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) iwm_set_pwr(sc); iwm_mvm_nic_config(sc); @@ -1633,7 +1694,7 @@ 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->cfg->device_family != IWM_DEVICE_FAMILY_8000) { iwm_clear_bits_prph(sc, IWM_APMG_PCIDEV_STT_REG, IWM_APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } @@ -1649,9 +1710,6 @@ iwm_post_alive(struct iwm_softc *sc) * iwlwifi/mvm/nvm.c */ -#define IWM_NVM_HW_SECTION_NUM_FAMILY_7000 0 -#define IWM_NVM_HW_SECTION_NUM_FAMILY_8000 10 - /* Default NVM size to read */ #define IWM_NVM_DEFAULT_CHUNK_SIZE (2*1024) @@ -1777,7 +1835,7 @@ iwm_nvm_read_section(struct iwm_softc *s while (seglen == length) { /* Check no memory assumptions fail and cause an overflow */ if ((size_read + offset + length) > - sc->eeprom_size) { + sc->cfg->eeprom_size) { device_printf(sc->sc_dev, "EEPROM size is too small for NVM\n"); return ENOBUFS; @@ -1899,10 +1957,6 @@ enum iwm_nvm_channel_flags { IWM_NVM_CHANNEL_160MHZ = (1 << 11), }; -/* lower blocks contain EEPROM image and calibration data */ -#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000 (16 * 512 * sizeof(uint16_t)) /* 16 KB */ -#define IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(uint16_t)) /* 32 KB */ - /* * Translate EEPROM flags to net80211. */ @@ -1938,7 +1992,7 @@ iwm_add_channel_band(struct iwm_softc *s for (; ch_idx < ch_num; ch_idx++) { ch_flags = le16_to_cpup(nvm_ch_flags + ch_idx); - if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) ieee = iwm_nvm_channels[ch_idx]; else ieee = iwm_nvm_channels_8000[ch_idx]; @@ -1988,7 +2042,7 @@ iwm_init_channel_map(struct ieee80211com IWM_NUM_2GHZ_CHANNELS - 1, IWM_NUM_2GHZ_CHANNELS, bands); if (data->sku_cap_band_52GHz_enable) { - if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) ch_num = nitems(iwm_nvm_channels); else ch_num = nitems(iwm_nvm_channels_8000); @@ -2062,7 +2116,7 @@ static int iwm_get_sku(const struct iwm_softc *sc, const uint16_t *nvm_sw, const uint16_t *phy_sku) { - if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) + if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + IWM_SKU); return le32_to_cpup((const uint32_t *)(phy_sku + IWM_SKU_8000)); @@ -2071,7 +2125,7 @@ iwm_get_sku(const struct iwm_softc *sc, static int iwm_get_nvm_version(const struct iwm_softc *sc, const uint16_t *nvm_sw) { - if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) + if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + IWM_NVM_VERSION); else return le32_to_cpup((const uint32_t *)(nvm_sw + @@ -2082,7 +2136,7 @@ static int iwm_get_radio_cfg(const struct iwm_softc *sc, const uint16_t *nvm_sw, const uint16_t *phy_sku) { - if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) + if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + IWM_RADIO_CFG); return le32_to_cpup((const uint32_t *)(phy_sku + IWM_RADIO_CFG_8000)); @@ -2093,7 +2147,7 @@ iwm_get_n_hw_addrs(const struct iwm_soft { int n_hw_addr; - if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) + if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) return le16_to_cpup(nvm_sw + IWM_N_HW_ADDRS); n_hw_addr = le32_to_cpup((const uint32_t *)(nvm_sw + IWM_N_HW_ADDRS_8000)); @@ -2105,7 +2159,7 @@ static void iwm_set_radio_cfg(const struct iwm_softc *sc, struct iwm_nvm_data *data, uint32_t radio_cfg) { - if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) { + if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { data->radio_cfg_type = IWM_NVM_RF_CFG_TYPE_MSK(radio_cfg); data->radio_cfg_step = IWM_NVM_RF_CFG_STEP_MSK(radio_cfg); data->radio_cfg_dash = IWM_NVM_RF_CFG_DASH_MSK(radio_cfg); @@ -2131,7 +2185,7 @@ iwm_set_hw_address(struct iwm_softc *sc, iwm_set_hw_address_from_csr(sc, data); } else #endif - if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) { + if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { const uint8_t *hw_addr = (const uint8_t *)(nvm_hw + IWM_HW_ADDR); /* The byte order is little endian 16 bit, meaning 214365 */ @@ -2162,7 +2216,7 @@ iwm_parse_nvm_data(struct iwm_softc *sc, struct iwm_nvm_data *data; uint32_t sku, radio_cfg; - if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) { + if (sc->cfg->device_family != IWM_DEVICE_FAMILY_8000) { data = malloc(sizeof(*data) + IWM_NUM_CHANNELS * sizeof(uint16_t), M_DEVBUF, M_NOWAIT | M_ZERO); @@ -2192,7 +2246,7 @@ iwm_parse_nvm_data(struct iwm_softc *sc, return NULL; } - if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) { + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) { memcpy(data->nvm_ch_flags, &nvm_sw[IWM_NVM_CHANNELS], IWM_NUM_CHANNELS * sizeof(uint16_t)); } else { @@ -2216,14 +2270,14 @@ iwm_parse_nvm_sections(struct iwm_softc const uint16_t *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku; /* Checking for required sections */ - if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) { + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) { if (!sections[IWM_NVM_SECTION_TYPE_SW].data || - !sections[sc->nvm_hw_section_num].data) { + !sections[sc->cfg->nvm_hw_section_num].data) { device_printf(sc->sc_dev, "Can't parse empty OTP/NVM sections\n"); return NULL; } - } else if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) { + } else if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) { /* SW and REGULATORY sections are mandatory */ if (!sections[IWM_NVM_SECTION_TYPE_SW].data || !sections[IWM_NVM_SECTION_TYPE_REGULATORY].data) { @@ -2232,7 +2286,7 @@ iwm_parse_nvm_sections(struct iwm_softc return NULL; } /* MAC_OVERRIDE or at least HW section must exist */ - if (!sections[sc->nvm_hw_section_num].data && + if (!sections[sc->cfg->nvm_hw_section_num].data && !sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].data) { device_printf(sc->sc_dev, "Can't parse mac_address, empty sections\n"); @@ -2246,10 +2300,10 @@ iwm_parse_nvm_sections(struct iwm_softc return NULL; } } else { - panic("unknown device family %d\n", sc->sc_device_family); + panic("unknown device family %d\n", sc->cfg->device_family); } - hw = (const uint16_t *) sections[sc->nvm_hw_section_num].data; + hw = (const uint16_t *) sections[sc->cfg->nvm_hw_section_num].data; sw = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_SW].data; calib = (const uint16_t *) sections[IWM_NVM_SECTION_TYPE_CALIBRATION].data; @@ -2274,14 +2328,14 @@ iwm_nvm_init(struct iwm_softc *sc) memset(nvm_sections, 0, sizeof(nvm_sections)); - if (sc->nvm_hw_section_num >= IWM_NVM_MAX_NUM_SECTIONS) + if (sc->cfg->nvm_hw_section_num >= IWM_NVM_MAX_NUM_SECTIONS) return EINVAL; /* load NVM values from nic */ /* Read From FW NVM */ IWM_DPRINTF(sc, IWM_DEBUG_EEPROM, "Read from NVM\n"); - nvm_buffer = malloc(sc->eeprom_size, M_DEVBUF, M_NOWAIT | M_ZERO); + nvm_buffer = malloc(sc->cfg->eeprom_size, M_DEVBUF, M_NOWAIT | M_ZERO); if (!nvm_buffer) return ENOMEM; for (section = 0; section < IWM_NVM_MAX_NUM_SECTIONS; section++) { @@ -2562,7 +2616,7 @@ iwm_load_firmware(struct iwm_softc *sc, { int error, w; - if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) error = iwm_load_firmware_8000(sc, ucode_type); else error = iwm_load_firmware_7000(sc, ucode_type); @@ -2575,7 +2629,7 @@ iwm_load_firmware(struct iwm_softc *sc, } if (error || !sc->sc_uc.uc_ok) { device_printf(sc->sc_dev, "could not load firmware\n"); - if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) { + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) { device_printf(sc->sc_dev, "cpu1 status: 0x%x\n", iwm_read_prph(sc, IWM_SB_CPU_1_STATUS)); device_printf(sc->sc_dev, "cpu2 status: 0x%x\n", @@ -4498,7 +4552,7 @@ iwm_mvm_sf_config(struct iwm_softc *sc, }; int ret = 0; - if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) sf_cmd.state |= htole32(IWM_SF_CFG_DUMMY_NOTIF_OFF); switch (new_state) { @@ -4686,7 +4740,7 @@ iwm_init_hw(struct iwm_softc *sc) } /* Initialize tx backoffs to the minimum. */ - if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) iwm_mvm_tt_tx_backoff(sc, 0); error = iwm_mvm_power_update_device(sc); @@ -5682,51 +5736,30 @@ iwm_dev_check(device_t dev) sc = device_get_softc(dev); - sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV); switch (pci_get_device(dev)) { case PCI_PRODUCT_INTEL_WL_3160_1: case PCI_PRODUCT_INTEL_WL_3160_2: - sc->sc_fwname = "iwm3160fw"; - sc->host_interrupt_operation_mode = 1; - sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000; - sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000; - sc->sc_device_family = IWM_DEVICE_FAMILY_7000; + sc->cfg = &iwm3160_cfg; sc->sc_fwdmasegsz = IWM_FWDMASEGSZ; return (0); case PCI_PRODUCT_INTEL_WL_3165_1: case PCI_PRODUCT_INTEL_WL_3165_2: - sc->sc_fwname = "iwm7265fw"; - sc->host_interrupt_operation_mode = 0; - sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000; - sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000; - sc->sc_device_family = IWM_DEVICE_FAMILY_7000; + sc->cfg = &iwm3165_cfg; sc->sc_fwdmasegsz = IWM_FWDMASEGSZ; return (0); case PCI_PRODUCT_INTEL_WL_7260_1: case PCI_PRODUCT_INTEL_WL_7260_2: - sc->sc_fwname = "iwm7260fw"; - sc->host_interrupt_operation_mode = 1; - sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000; - sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000; - sc->sc_device_family = IWM_DEVICE_FAMILY_7000; + sc->cfg = &iwm7260_cfg; sc->sc_fwdmasegsz = IWM_FWDMASEGSZ; return (0); case PCI_PRODUCT_INTEL_WL_7265_1: case PCI_PRODUCT_INTEL_WL_7265_2: - sc->sc_fwname = "iwm7265fw"; - sc->host_interrupt_operation_mode = 0; - sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_7000; - sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_7000; - sc->sc_device_family = IWM_DEVICE_FAMILY_7000; + sc->cfg = &iwm7265_cfg; sc->sc_fwdmasegsz = IWM_FWDMASEGSZ; return (0); case PCI_PRODUCT_INTEL_WL_8260_1: case PCI_PRODUCT_INTEL_WL_8260_2: - sc->sc_fwname = "iwm8000Cfw"; - sc->host_interrupt_operation_mode = 0; - sc->eeprom_size = IWM_OTP_LOW_IMAGE_SIZE_FAMILY_8000; - sc->nvm_hw_section_num = IWM_NVM_HW_SECTION_NUM_FAMILY_8000; - sc->sc_device_family = IWM_DEVICE_FAMILY_8000; + sc->cfg = &iwm8260_cfg; sc->sc_fwdmasegsz = IWM_FWDMASEGSZ_8000; return (0); default: @@ -5842,16 +5875,14 @@ iwm_attach(device_t dev) if (error != 0) goto fail; - /* - * We now start fiddling with the hardware - */ + sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV); /* * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have * changed, and now the revision step also includes bit 0-1 (no more * "dash" value). To keep hw_rev backwards compatible - we'll store it * in the old format. */ - if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) | (IWM_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2); @@ -5860,7 +5891,7 @@ iwm_attach(device_t dev) goto fail; } - if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) { + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) { int ret; uint32_t hw_step; @@ -5898,6 +5929,12 @@ iwm_attach(device_t dev) } } + /* special-case 7265D, it has the same PCI IDs. */ + if (sc->cfg == &iwm7265_cfg && + (sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK) == IWM_CSR_HW_REV_TYPE_7265D) { + sc->cfg = &iwm7265d_cfg; + } + /* Allocate DMA memory for firmware transfers. */ if ((error = iwm_alloc_fwmem(sc)) != 0) { device_printf(dev, "could not allocate memory for firmware\n"); Modified: head/sys/dev/iwm/if_iwm_pcie_trans.c ============================================================================== --- head/sys/dev/iwm/if_iwm_pcie_trans.c Mon Feb 6 03:06:11 2017 (r313311) +++ head/sys/dev/iwm/if_iwm_pcie_trans.c Mon Feb 6 03:29:50 2017 (r313312) @@ -256,7 +256,7 @@ iwm_nic_lock(struct iwm_softc *sc) IWM_SETBITS(sc, IWM_CSR_GP_CNTRL, IWM_CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - if (sc->sc_device_family == IWM_DEVICE_FAMILY_8000) + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_8000) DELAY(2); if (iwm_poll_bit(sc, IWM_CSR_GP_CNTRL, @@ -425,7 +425,7 @@ iwm_apm_init(struct iwm_softc *sc) IWM_DPRINTF(sc, IWM_DEBUG_RESET, "iwm apm start\n"); /* Disable L0S exit timer (platform NMI Work/Around) */ - if (sc->sc_device_family != IWM_DEVICE_FAMILY_8000) { + if (sc->cfg->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); } @@ -476,7 +476,7 @@ iwm_apm_init(struct iwm_softc *sc) goto out; } - if (sc->host_interrupt_operation_mode) { + if (sc->cfg->host_interrupt_operation_mode) { /* * This is a bit of an abuse - This is needed for 7260 / 3160 * only check host_interrupt_operation_mode even if this is @@ -505,7 +505,7 @@ iwm_apm_init(struct iwm_softc *sc) * do not disable clocks. This preserves any hardware bits already * set by default in "CLK_CTRL_REG" after reset. */ - if (sc->sc_device_family == IWM_DEVICE_FAMILY_7000) { + if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) { iwm_write_prph(sc, IWM_APMG_CLK_EN_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT); DELAY(20); Modified: head/sys/dev/iwm/if_iwmvar.h ============================================================================== --- head/sys/dev/iwm/if_iwmvar.h Mon Feb 6 03:06:11 2017 (r313311) +++ head/sys/dev/iwm/if_iwmvar.h Mon Feb 6 03:29:50 2017 (r313312) @@ -362,6 +362,27 @@ struct iwm_node { #define IWM_ICT_COUNT (IWM_ICT_SIZE / sizeof (uint32_t)) #define IWM_ICT_PADDR_SHIFT 12 +enum iwm_device_family { + IWM_DEVICE_FAMILY_UNDEFINED, + IWM_DEVICE_FAMILY_7000, + IWM_DEVICE_FAMILY_8000, +}; + +/** + * struct iwm_cfg + * @fw_name: Firmware filename. + * @host_interrupt_operation_mode: device needs host interrupt operation + * mode set + * @nvm_hw_section_num: the ID of the HW NVM section + */ +struct iwm_cfg { + const char *fw_name; + uint16_t eeprom_size; + enum iwm_device_family device_family; + int host_interrupt_operation_mode; + uint8_t nvm_hw_section_num; +}; + struct iwm_softc { device_t sc_dev; uint32_t sc_debug; @@ -411,9 +432,6 @@ struct iwm_softc { int sc_hw_rev; int sc_hw_id; - int sc_device_family; -#define IWM_DEVICE_FAMILY_7000 1 -#define IWM_DEVICE_FAMILY_8000 2 struct iwm_dma_info kw_dma; struct iwm_dma_info fw_dma; @@ -445,12 +463,12 @@ struct iwm_softc { */ int sc_generation; - const char *sc_fwname; bus_size_t sc_fwdmasegsz; struct iwm_fw_info sc_fw; int sc_fw_phy_config; struct iwm_tlv_calib_ctrl sc_default_calib[IWM_UCODE_TYPE_MAX]; + const struct iwm_cfg *cfg; struct iwm_nvm_data *nvm_data; struct iwm_phy_db *sc_phy_db; @@ -481,17 +499,12 @@ struct iwm_softc { struct iwm_notif_statistics sc_stats; int sc_noise; - int host_interrupt_operation_mode; - caddr_t sc_drvbpf; struct iwm_rx_radiotap_header sc_rxtap; struct iwm_tx_radiotap_header sc_txtap; int sc_max_rssi; - - uint16_t eeprom_size; - uint8_t nvm_hw_section_num; }; #define IWM_LOCK_INIT(_sc) \