Hello Stefan, I tried to port the firmware detection and config values from iwlwifi.
On iwx_cfg_trans_params and iwx_cfg structs I ported only the fields iwx_attach was setting based on the iwx_device. With best regards, Iraklis Karagkiozoglou diff --git sys/dev/pci/if_iwx.c sys/dev/pci/if_iwx.c index 4c85ad108a8..571c6b0615e 100644 --- sys/dev/pci/if_iwx.c +++ sys/dev/pci/if_iwx.c @@ -486,6 +486,7 @@ int iwx_intr_msix(void *); int iwx_match(struct device *, void *, void *); int iwx_preinit(struct iwx_softc *); void iwx_attach_hook(struct device *); +int iwx_set_dev_info(struct iwx_softc *); void iwx_attach(struct device *, struct device *, void *); void iwx_init_task(void *); int iwx_activate(struct device *, int); @@ -865,7 +866,7 @@ iwx_ctxt_info_init(struct iwx_softc *sc, const struct iwx_fw_sects *fws) /* size is in DWs */ ctxt_info->version.size = htole16(sizeof(*ctxt_info) / 4); - if (sc->sc_device_family >= IWX_DEVICE_FAMILY_22560) + if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) rb_size = IWX_CTXT_INFO_RB_SIZE_2K; else rb_size = IWX_CTXT_INFO_RB_SIZE_4K; @@ -1019,6 +1020,7 @@ iwx_fw_info_free(struct iwx_fw_info *fw) int iwx_read_firmware(struct iwx_softc *sc) { + const struct iwx_cfg *cfg = sc->sc_cfg; struct iwx_fw_info *fw = &sc->sc_fw; struct iwx_tlv_ucode_header *uhdr; struct iwx_ucode_tlv tlv; @@ -1037,11 +1039,11 @@ iwx_read_firmware(struct iwx_softc *sc) if (fw->fw_rawdata != NULL) iwx_fw_info_free(fw); - err = loadfirmware(sc->sc_fwname, + err = loadfirmware(cfg->fw_name, (u_char **)&fw->fw_rawdata, &fw->fw_rawsize); if (err) { printf("%s: could not read firmware %s (error %d)\n", - DEVNAME(sc), sc->sc_fwname, err); + DEVNAME(sc), cfg->fw_name, err); goto out; } @@ -1055,7 +1057,7 @@ iwx_read_firmware(struct iwx_softc *sc) if (*(uint32_t *)fw->fw_rawdata != 0 || le32toh(uhdr->magic) != IWX_TLV_UCODE_MAGIC) { printf("%s: invalid firmware %s\n", - DEVNAME(sc), sc->sc_fwname); + DEVNAME(sc), cfg->fw_name); err = EINVAL; goto out; } @@ -9177,60 +9179,135 @@ static const struct pci_matchid iwx_devices[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_3 }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_4,}, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_5,}, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_6,}, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_7,}, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_8,}, }; -static const struct pci_matchid iwx_subsystem_id_ax201[] = { - { PCI_VENDOR_INTEL, 0x0070 }, - { PCI_VENDOR_INTEL, 0x0074 }, - { PCI_VENDOR_INTEL, 0x0078 }, - { PCI_VENDOR_INTEL, 0x007c }, - { PCI_VENDOR_INTEL, 0x0310 }, - { PCI_VENDOR_INTEL, 0x2074 }, - { PCI_VENDOR_INTEL, 0x4070 }, - /* TODO: There are more ax201 devices with "main" product ID 0x06f0 */ -}; int iwx_match(struct device *parent, iwx_match_t match __unused, void *aux) { struct pci_attach_args *pa = aux; - pcireg_t subid; - pci_vendor_id_t svid; - pci_product_id_t spid; - int i; - - if (!pci_matchbyid(pa, iwx_devices, nitems(iwx_devices))) - return 0; - - /* - * Some PCI product IDs are shared among devices which use distinct - * chips or firmware. We need to match the subsystem ID as well to - * ensure that we have in fact found a supported device. - */ - subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); - svid = PCI_VENDOR(subid); - spid = PCI_PRODUCT(subid); - - switch (PCI_PRODUCT(pa->pa_id)) { - case PCI_PRODUCT_INTEL_WL_22500_1: /* AX200 */ - return 1; /* match any device */ - case PCI_PRODUCT_INTEL_WL_22500_2: /* AX201 */ - case PCI_PRODUCT_INTEL_WL_22500_3: /* AX201 */ - case PCI_PRODUCT_INTEL_WL_22500_4: /* AX201 */ - case PCI_PRODUCT_INTEL_WL_22500_5: /* AX201 */ - for (i = 0; i < nitems(iwx_subsystem_id_ax201); i++) { - if (svid == iwx_subsystem_id_ax201[i].pm_vid && - spid == iwx_subsystem_id_ax201[i].pm_pid) - return 1; - - } - break; - default: - break; - } - - return 0; -} + return pci_matchbyid(pa, iwx_devices, nitems(iwx_devices)); +} + + +#define _IWX_DEV_INFO(_device, _subdevice, _mac_type, _mac_step, _rf_type, \ + _rf_id, _no_160, _cores, _cdb, _jacket, _cfg, _name) \ + { .device = (_device), .subdevice = (_subdevice), .cfg = &(_cfg), \ + .name = _name, .mac_type = _mac_type, .rf_type = _rf_type, \ + .no_160 = _no_160, .cores = _cores, .rf_id = _rf_id, \ + .mac_step = _mac_step, .cdb = _cdb, .jacket = _jacket } + +#define IWX_DEV_INFO(_device, _subdevice, _cfg, _name) \ + _IWX_DEV_INFO(_device, _subdevice, IWX_CFG_ANY, IWX_CFG_ANY, \ + IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_ANY, \ + IWX_CFG_ANY, IWX_CFG_ANY, _cfg, _name) + +static const struct iwx_dev_info iwx_dev_info_table[] = { +/* AX200 */ + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_1, IWX_CFG_ANY, iwx_ax200_cfg_cc, iwx_ax200_name), + +/* Qu with Hr */ + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_6, 0x0070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_6, 0x0074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_6, 0x0078, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_6, 0x007C, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_6, 0x2074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_6, 0x4070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_3, 0x0070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_3, 0x0074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_3, 0x0078, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_3, 0x007C, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_3, 0x0A10, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_3, 0x2074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_3, 0x4070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_3, 0x6074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_2, 0x0070, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_2, 0x0074, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_2, 0x6074, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_2, 0x0078, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_2, 0x007C, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_2, 0x0310, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_2, 0x2074, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_2, 0x4070, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_5, 0x0070, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_5, 0x0074, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_5, 0x0078, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_5, 0x007C, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_5, 0x0310, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_5, 0x2074, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_5, 0x4070, iwx_ax201_cfg_quz_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_4, 0x0070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_4, 0x0074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_4, 0x0078, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_4, 0x007C, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_4, 0x0310, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_4, 0x2074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_4, 0x4070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_7, 0x0070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_7, 0x0074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_7, 0x0078, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_7, 0x007C, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_7, 0x0310, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_7, 0x2074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_7, 0x4070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_8, 0x0070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_8, 0x0074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_8, 0x0078, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_8, 0x007C, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_8, 0x0310, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_8, 0x2074, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_8, 0x4070, iwx_ax201_cfg_qu_hr, NULL), + IWX_DEV_INFO(PCI_PRODUCT_INTEL_WL_22500_8, 0x6074, iwx_ax201_cfg_qu_hr, NULL), + +/* Qu with Hr */ + /* Qu B step */ + _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, + IWX_CFG_MAC_TYPE_QU, IWX_SILICON_B_STEP, + IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, + IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, + iwx_qu_b0_hr_b0, iwx_ax203_name), + + /* Qu C step */ + _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, + IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, + IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, + IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, + iwx_qu_c0_hr_b0, iwx_ax203_name), + _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, + IWX_CFG_MAC_TYPE_QU, IWX_SILICON_C_STEP, + IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, + IWX_CFG_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, + iwx_qu_c0_hr_b0, iwx_ax201_name), + + /* QuZ */ + _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, + IWX_CFG_MAC_TYPE_QUZ, IWX_SILICON_B_STEP, + IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, + IWX_CFG_NO_160, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, + iwx_cfg_quz_a0_hr_b0, iwx_ax203_name), + + /* QuZ */ + _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, + IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, + IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, + IWX_CFG_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, IWX_CFG_ANY, + iwx_9560_quz_a0_jf_b0_cfg, iwx_9560_160_name), + _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, + IWX_CFG_MAC_TYPE_QUZ, IWX_CFG_ANY, + IWX_CFG_RF_TYPE_JF2, IWX_CFG_RF_ID_JF, + IWX_CFG_NO_160, IWX_CFG_CORES_BT, IWX_CFG_NO_CDB, IWX_CFG_ANY, + iwx_9560_quz_a0_jf_b0_cfg, iwx_9560_name), + +/* SnJ with Hr */ + _IWX_DEV_INFO(IWX_CFG_ANY, IWX_CFG_ANY, + IWX_CFG_MAC_TYPE_SNJ, IWX_CFG_ANY, + IWX_CFG_RF_TYPE_HR2, IWX_CFG_ANY, + IWX_CFG_ANY, IWX_CFG_ANY, IWX_CFG_NO_CDB, IWX_CFG_ANY, + iwx_cfg_snj_hr_b0, iwx_ax201_name), +}; int iwx_preinit(struct iwx_softc *sc) @@ -9302,6 +9379,87 @@ iwx_attach_hook(struct device *self) iwx_preinit(sc); } +int +iwx_set_dev_info(struct iwx_softc *sc) +{ + pcireg_t sreg; + pci_product_id_t sdev_id; + uint16_t mac_type, rf_type; + uint8_t mac_step, cdb, jacket, rf_id, no_160, cores; + int num_devices, i; + const struct iwx_dev_info *dev_info; + + num_devices = nitems(iwx_dev_info_table); + + if (!num_devices) + return 1; + + sreg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_SUBSYS_ID_REG); + sdev_id = PCI_PRODUCT(sreg); + mac_type = IWX_CSR_HW_REV_TYPE(sc->sc_hw_rev); + mac_step = IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2); + rf_type = IWX_CSR_HW_RFID_TYPE(sc->sc_hw_rf_id); + cdb = IWX_CSR_HW_RFID_IS_CDB(sc->sc_hw_rf_id); + jacket = IWX_CSR_HW_RFID_IS_JACKET(sc->sc_hw_rf_id); + + rf_id = IWX_SUBDEVICE_RF_ID(sdev_id); + no_160 = IWX_SUBDEVICE_NO_160(sdev_id); + cores = IWX_SUBDEVICE_CORES(sdev_id); + + for (i = num_devices - 1; i >= 0; i--) { + dev_info = &iwx_dev_info_table[i]; + + if (dev_info->device != (uint16_t)IWX_CFG_ANY && + dev_info->device != sc->sc_pid) + continue; + + if (dev_info->subdevice != (uint16_t)IWX_CFG_ANY && + dev_info->subdevice != sdev_id) + continue; + + if (dev_info->mac_type != (uint16_t)IWX_CFG_ANY && + dev_info->mac_type != mac_type) + continue; + + if (dev_info->mac_step != (uint8_t)IWX_CFG_ANY && + dev_info->mac_step != mac_step) + continue; + + if (dev_info->rf_type != (uint16_t)IWX_CFG_ANY && + dev_info->rf_type != rf_type) + continue; + + if (dev_info->cdb != (uint8_t)IWX_CFG_ANY && + dev_info->cdb != cdb) + continue; + + if (dev_info->jacket != (uint8_t)IWX_CFG_ANY && + dev_info->jacket != jacket) + continue; + + if (dev_info->rf_id != (uint8_t)IWX_CFG_ANY && + dev_info->rf_id != rf_id) + continue; + + if (dev_info->no_160 != (uint8_t)IWX_CFG_ANY && + dev_info->no_160 != no_160) + continue; + + if (dev_info->cores != (uint8_t)IWX_CFG_ANY && + dev_info->cores != cores) + continue; + + sc->sc_dev_info = dev_info; + break; + } + + if(sc->sc_dev_info == NULL) + return 1; + + return 0; +} + + void iwx_attach(struct device *parent, struct device *self, void *aux) { @@ -9315,6 +9473,7 @@ iwx_attach(struct device *parent, struct device *self, void *aux) int err; int txq_i, i, j; + sc->sc_pid = pa->pa_id; sc->sc_pct = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; sc->sc_dmat = pa->pa_dmat; @@ -9384,6 +9543,7 @@ iwx_attach(struct device *parent, struct device *self, void *aux) IWX_WRITE(sc, IWX_CSR_FH_INT_STATUS, ~0); sc->sc_hw_rev = IWX_READ(sc, IWX_CSR_HW_REV); + sc->sc_hw_rf_id = IWX_READ(sc, IWX_CSR_HW_RF_ID); /* * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have @@ -9394,49 +9554,22 @@ iwx_attach(struct device *parent, struct device *self, void *aux) sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) | (IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2); - switch (PCI_PRODUCT(pa->pa_id)) { - case PCI_PRODUCT_INTEL_WL_22500_1: - sc->sc_fwname = "iwx-cc-a0-67"; - sc->sc_device_family = IWX_DEVICE_FAMILY_22000; - sc->sc_integrated = 0; - sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE; - sc->sc_low_latency_xtal = 0; - sc->sc_xtal_latency = 0; - sc->sc_tx_with_siso_diversity = 0; - sc->sc_uhb_supported = 0; - break; - case PCI_PRODUCT_INTEL_WL_22500_2: - case PCI_PRODUCT_INTEL_WL_22500_3: - case PCI_PRODUCT_INTEL_WL_22500_5: - if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) { - printf("%s: unsupported AX201 adapter\n", DEVNAME(sc)); - return; - } - - sc->sc_fwname = "iwx-QuZ-a0-hr-b0-67"; - sc->sc_device_family = IWX_DEVICE_FAMILY_22000; - sc->sc_integrated = 1; - sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_200; - sc->sc_low_latency_xtal = 0; - sc->sc_xtal_latency = 500; - sc->sc_tx_with_siso_diversity = 0; - sc->sc_uhb_supported = 0; - break; - case PCI_PRODUCT_INTEL_WL_22500_4: - sc->sc_fwname = "iwx-Qu-c0-hr-b0-63"; - sc->sc_device_family = IWX_DEVICE_FAMILY_22000; - sc->sc_integrated = 1; - sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820; - sc->sc_low_latency_xtal = 0; - sc->sc_xtal_latency = 1820; - sc->sc_tx_with_siso_diversity = 0; - sc->sc_uhb_supported = 0; - break; - default: + err = iwx_set_dev_info(sc); + if(err) { printf("%s: unknown adapter type\n", DEVNAME(sc)); return; } + sc->sc_cfg = sc->sc_dev_info->cfg; + sc->sc_device_family = sc->sc_cfg->trans.device_family; + sc->sc_integrated = sc->sc_cfg->trans.integrated; + sc->sc_ltr_delay = sc->sc_cfg->trans.ltr_delay; + sc->sc_low_latency_xtal = sc->sc_cfg->trans.low_latency_xtal; + sc->sc_xtal_latency = sc->sc_cfg->trans.xtal_latency; + sc->sc_tx_with_siso_diversity = sc->sc_cfg->tx_with_siso_diversity; + sc->sc_uhb_supported = sc->sc_cfg->uhb_supported; + + /* Allocate DMA memory for loading firmware. */ err = iwx_dma_contig_alloc(sc->sc_dmat, &sc->ctxt_info_dma, sizeof(struct iwx_context_info), 0); diff --git sys/dev/pci/if_iwxreg.h sys/dev/pci/if_iwxreg.h index 058e38dbcbd..1814ff21b20 100644 --- sys/dev/pci/if_iwxreg.h +++ sys/dev/pci/if_iwxreg.h @@ -271,6 +271,18 @@ struct iwx_context_info { */ #define IWX_CSR_HW_REV (0x028) +/* + * RF ID revision info + * Bit fields: + * 31:24: Reserved (set to 0x0) + * 23:12: Type + * 11:8: Step (A - 0x0, B - 0x1, etc) + * 7:4: Dash + * 3:0: Flavor + */ +#define IWX_CSR_HW_RF_ID (0x09c) + + #define IWX_CSR_GIO_REG (0x03C) /* @@ -423,10 +435,19 @@ struct iwx_context_info { /* HW REV */ #define IWX_CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0) #define IWX_CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2) +#define IWX_CSR_HW_REV_TYPE(_val) (((_val) & 0x000FFF0) >> 4) #define IWX_CSR_HW_REV_TYPE_MSK (0x000FFF0) #define IWX_CSR_HW_REV_TYPE_QUZ (0x0000354) +/* HW RFID */ +#define IWX_CSR_HW_RFID_FLAVOR(_val) (((_val) & 0x000000F) >> 0) +#define IWX_CSR_HW_RFID_DASH(_val) (((_val) & 0x00000F0) >> 4) +#define IWX_CSR_HW_RFID_STEP(_val) (((_val) & 0x0000F00) >> 8) +#define IWX_CSR_HW_RFID_TYPE(_val) (((_val) & 0x0FFF000) >> 12) +#define IWX_CSR_HW_RFID_IS_CDB(_val) (((_val) & 0x10000000) >> 28) +#define IWX_CSR_HW_RFID_IS_JACKET(_val) (((_val) & 0x20000000) >> 29) + /* CSR GIO */ #define IWX_CSR_GIO_REG_VAL_L0S_DISABLED (0x00000002) diff --git sys/dev/pci/if_iwxvar.h sys/dev/pci/if_iwxvar.h index f40dd20c64f..f4f7aa6394e 100644 --- sys/dev/pci/if_iwxvar.h +++ sys/dev/pci/if_iwxvar.h @@ -450,6 +450,274 @@ struct iwx_ba_task_data { uint32_t stop_tidmask; }; + +enum iwx_cfg_trans_ltr_delay { + IWX_CFG_TRANS_LTR_DELAY_NONE = 0, + IWX_CFG_TRANS_LTR_DELAY_200US = 1, + IWX_CFG_TRANS_LTR_DELAY_2500US = 2, + IWX_CFG_TRANS_LTR_DELAY_1820US = 3, +}; + + +enum iwx_device_family { + IWX_DEVICE_FAMILY_22000, + IWX_DEVICE_FAMILY_AX210, +}; + +/** + * struct iwx_cfg_trans - information needed to start the trans + * + * These values are specific to the device ID and do not change when + * multiple configs are used for a single device ID. They values are + * used, among other things, to boot the NIC so that the HW REV or + * RFID can be read before deciding the remaining parameters to use. + * + * @device_family: the device family + * @xtal_latency: power up latency to get the xtal stabilized + * @integrated: discrete or integrated + * @low_latency_xtal: use the low latency xtal if supported + * @ltr_delay: LTR delay parameter, &enum iwx_cfg_trans_ltr_delay. + */ +struct iwx_cfg_trans_params { + enum iwx_device_family device_family; + int integrated; + int ltr_delay; + int low_latency_xtal; + uint32_t xtal_latency; +}; + + +const struct iwx_cfg_trans_params iwx_qnj_trans_cfg = { + .device_family = IWX_DEVICE_FAMILY_22000 +}; + +const struct iwx_cfg_trans_params iwx_qu_trans_cfg = { + .device_family = IWX_DEVICE_FAMILY_22000, + .integrated = true, + .xtal_latency = 500, + .ltr_delay = IWX_CFG_TRANS_LTR_DELAY_200US, +}; + +const struct iwx_cfg_trans_params iwx_qu_medium_latency_trans_cfg = { + .device_family = IWX_DEVICE_FAMILY_22000, + .integrated = true, + .xtal_latency = 1820, + .ltr_delay = IWX_CFG_TRANS_LTR_DELAY_1820US, +}; + +const struct iwx_cfg_trans_params iwx_qu_long_latency_trans_cfg = { + .device_family = IWX_DEVICE_FAMILY_22000, + .integrated = true, + .xtal_latency = 12000, + .low_latency_xtal = true, + .ltr_delay = IWX_CFG_TRANS_LTR_DELAY_2500US, +}; + +const struct iwx_cfg_trans_params iwx_so_trans_cfg = { + .device_family = IWX_DEVICE_FAMILY_AX210, + .integrated = true, + /* TODO: the following values need to be checked */ + .xtal_latency = 500, + .ltr_delay = IWX_CFG_TRANS_LTR_DELAY_200US, +}; + +const struct iwx_cfg_trans_params iwx_so_long_latency_trans_cfg = { + .device_family = IWX_DEVICE_FAMILY_AX210, + .integrated = true, + .low_latency_xtal = true, + .xtal_latency = 12000, + .ltr_delay = IWX_CFG_TRANS_LTR_DELAY_2500US, +}; + +const struct iwx_cfg_trans_params iwx_ax200_trans_cfg = { + .device_family = IWX_DEVICE_FAMILY_22000, +}; + + + +/** + * struct iwx_cfg + * @trans: the trans-specific configuration part + * @name: Official name of the device + * @fw_name: Firmware filename prefix. The api version and extension + * (.ucode) will be added to filename before loading from disk. The + * filename is constructed as fw_name_pre<api>.ucode. + * @tx_with_siso_diversity: 1x1 device with tx antenna diversity + * @uhb_supported: ultra high band channels supported + * + * We enable the driver to be backward compatible wrt. hardware features. + * API differences in uCode shouldn't be handled here but through TLVs + * and/or the uCode API version instead. + */ +struct iwx_cfg { + struct iwx_cfg_trans_params trans; + /* params specific to an individual device within a device family */ + const char *name; + const char *fw_name; + int tx_with_siso_diversity; + int uhb_supported; +}; + +#define IWX_CC_A_FW "iwx-cc-a0-67" +#define IWX_QU_B_HR_B_FW "iwx-Qu-b0-hr-b0-63" +#define IWX_QNJ_B_HR_B_FW "iwx-QuQnj-b0-hr-b0-67" +#define IWX_QUZ_A_HR_B_FW "iwx-QuZ-a0-hr-b0-67" +#define IWX_QU_C_HR_B_FW "iwx-Qu-c0-hr-b0-67" +#define IWX_SNJ_A_HR_B_FW "iwx-SoSnj-a0-hr-b0-67" +#define IWX_QUZ_A_JF_B_FW "iwx-QuZ-a0-jf-b0-63" +#define IWX_SNJ_A_JF_B_FW "iwx-SoSnj-a0-jf-b0-63" +#define IWX_SO_A_HR_B_FW "iwx-so-a0-hr-b0-63" + +const char iwx_9560_name[] = "Intel(R) Wireless-AC 9560"; +const char iwx_9560_160_name[] = "Intel(R) Wireless-AC 9560 160MHz"; +const char iwx_ax200_name[] = "Intel(R) Wi-Fi 6 AX200 160MHz"; +const char iwx_ax201_name[] = "Intel(R) Wi-Fi 6 AX201 160MHz"; +const char iwx_ax203_name[] = "Intel(R) Wi-Fi 6 AX203"; + +#define IWX_DEVICE_22500 \ + .trans.device_family = IWX_DEVICE_FAMILY_22000 \ + +#define IWX_DEVICE_AX210 \ + .trans.device_family = IWX_DEVICE_FAMILY_AX210 \ + +/* + * All JF radio modules are part of the 9000 series, but the MAC part + * looks more like 22000. That's why this device is here, but called + * 9560 nevertheless. + */ + +const struct iwx_cfg iwx_9560_quz_a0_jf_b0_cfg = { + .fw_name = IWX_QUZ_A_JF_B_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_qu_b0_hr1_b0 = { + .fw_name = IWX_QU_B_HR_B_FW , + IWX_DEVICE_22500, + .tx_with_siso_diversity = true, +}; + +const struct iwx_cfg iwx_qu_b0_hr_b0 = { + .fw_name = IWX_QU_B_HR_B_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_ax201_cfg_qu_hr = { + .name = "Intel(R) Wi-Fi 6 AX201 160MHz", + .fw_name = IWX_QU_B_HR_B_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_qu_c0_hr1_b0 = { + .fw_name = IWX_QU_C_HR_B_FW, + IWX_DEVICE_22500, + .tx_with_siso_diversity = true, +}; + +const struct iwx_cfg iwx_qu_c0_hr_b0 = { + .fw_name = IWX_QU_C_HR_B_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_ax201_cfg_qu_c0_hr_b0 = { + .name = "Intel(R) Wi-Fi 6 AX201 160MHz", + .fw_name = IWX_QU_C_HR_B_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_quz_a0_hr1_b0 = { + .fw_name = IWX_QUZ_A_HR_B_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_ax201_cfg_quz_hr = { + .name = "Intel(R) Wi-Fi 6 AX201 160MHz", + .fw_name = IWX_QUZ_A_HR_B_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_ax200_cfg_cc = { + .fw_name = IWX_CC_A_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_qnj_b0_hr_b0_cfg = { + .fw_name = IWX_QNJ_B_HR_B_FW, + IWX_DEVICE_22500, +}; + +const struct iwx_cfg iwx_cfg_snj_hr_b0 = { + .fw_name = IWX_SNJ_A_HR_B_FW, + .uhb_supported = true, + IWX_DEVICE_AX210, +}; + +const struct iwx_cfg iwx_cfg_snj_a0_jf_b0 = { + .fw_name = IWX_SNJ_A_JF_B_FW , + .uhb_supported = true, + IWX_DEVICE_AX210, +}; + +const struct iwx_cfg iwx_cfg_so_a0_hr_a0 = { + .fw_name = IWX_SO_A_HR_B_FW, + IWX_DEVICE_AX210, +}; + +const struct iwx_cfg iwx_cfg_quz_a0_hr_b0 = { + .fw_name = IWX_QUZ_A_HR_B_FW, + IWX_DEVICE_22500, +}; + + +#define IWX_CFG_ANY (~0) + +#define IWX_CFG_MAC_TYPE_QU 0x33 +#define IWX_CFG_MAC_TYPE_QUZ 0x35 +#define IWX_CFG_MAC_TYPE_QNJ 0x36 +#define IWX_CFG_MAC_TYPE_SO 0x37 +#define IWX_CFG_MAC_TYPE_SNJ 0x42 +#define IWX_CFG_MAC_TYPE_SOF 0x43 + +#define IWX_CFG_RF_TYPE_JF2 0x105 +#define IWX_CFG_RF_TYPE_JF1 0x108 +#define IWX_CFG_RF_TYPE_HR2 0x10A + +#define IWX_CFG_RF_ID_JF 0x3 +#define IWX_CFG_RF_ID_JF1 0x6 + +#define IWX_CFG_NO_160 0x1 +#define IWX_CFG_160 0x0 + +#define IWX_CFG_CORES_BT 0x0 + +#define IWX_CFG_NO_CDB 0x0 + +#define IWX_SUBDEVICE_RF_ID(subdevice) ((uint16_t)((subdevice) & 0x00F0) >> 4) +#define IWX_SUBDEVICE_NO_160(subdevice) ((uint16_t)((subdevice) & 0x0200) >> 9) +#define IWX_SUBDEVICE_CORES(subdevice) ((uint16_t)((subdevice) & 0x1C00) >> 10) + +enum { + IWX_SILICON_A_STEP = 0, + IWX_SILICON_B_STEP, + IWX_SILICON_C_STEP, + IWX_SILICON_Z_STEP = 0xf, +}; + +struct iwx_dev_info { + uint16_t device; + uint16_t subdevice; + uint16_t mac_type; + uint16_t rf_type; + uint8_t mac_step; + uint8_t rf_id; + uint8_t no_160; + uint8_t cores; + uint8_t cdb; + uint8_t jacket; + const struct iwx_cfg *cfg; + const char *name; +}; + struct iwx_softc { struct device sc_dev; struct ieee80211com sc_ic; @@ -491,6 +759,7 @@ struct iwx_softc { bus_space_handle_t sc_sh; bus_size_t sc_sz; bus_dma_tag_t sc_dmat; + pci_product_id_t sc_pid; pci_chipset_tag_t sc_pct; pcitag_t sc_pcitag; const void *sc_ih; @@ -511,14 +780,11 @@ struct iwx_softc { int ict_cur; int sc_hw_rev; -#define IWX_SILICON_A_STEP 0 -#define IWX_SILICON_B_STEP 1 -#define IWX_SILICON_C_STEP 2 -#define IWX_SILICON_D_STEP 3 int sc_hw_id; + int sc_hw_rf_id; int sc_device_family; -#define IWX_DEVICE_FAMILY_22000 1 -#define IWX_DEVICE_FAMILY_22560 2 + const struct iwx_dev_info *sc_dev_info; + const struct iwx_cfg *sc_cfg; struct iwx_dma_info ctxt_info_dma; struct iwx_self_init_dram init_dram; @@ -554,7 +820,6 @@ struct iwx_softc { int sc_cap_off; /* PCIe caps */ - const char *sc_fwname; struct iwx_fw_info sc_fw; struct iwx_dma_info fw_mon; int sc_fw_phy_config; diff --git sys/dev/pci/pcidevs sys/dev/pci/pcidevs index e5eca2268d3..03f37866758 100644 --- sys/dev/pci/pcidevs +++ sys/dev/pci/pcidevs @@ -5302,6 +5302,7 @@ product INTEL E5_UNICAST 0x3ce8 E5 Unicast product INTEL E5_SAD_1 0x3cf4 E5 SAD product INTEL E5_BROADCAST 0x3cf5 E5 Broadcast product INTEL E5_SAD_2 0x3cf6 E5 SAD +product INTEL WL_22500_7 0x3df0 Wi-Fi 6 AX201 product INTEL CORE8G_S_D_HB_2C 0x3e0f Core 8G Host product INTEL CORE8G_H_HB_4C 0x3e10 Core 8G Host product INTEL CORE8G_S_W_HB_4C 0x3e18 Core 8G Host @@ -5456,6 +5457,7 @@ product INTEL 500SERIES_I2C_3 0x43eb 500 Series I2C product INTEL 500SERIES_XHCI 0x43ed 500 Series xHCI product INTEL 500SERIES_XDCI 0x43ee 500 Series xDCI product INTEL 500SERIES_SRAM 0x43ef 500 Series Shared SRAM +product INTEL WL_22500_6 0x43f0 Wi-Fi 6 AX201 product INTEL 500SERIES_GSPI_2 0x43fb 500 Series GSPI product INTEL 500SERIES_ISH 0x43fc 500 Series ISH product INTEL 500SERIES_GSPI_3 0x43fd 500 Series GSPI @@ -5510,6 +5512,7 @@ product INTEL RKL_GT_3 0x4c8b UHD Graphics product INTEL RKL_GT_4 0x4c8c UHD Graphics product INTEL RKL_GT_5 0x4c90 UHD Graphics product INTEL RKL_GT_6 0x4c9a UHD Graphics +product INTEL WL_22500_8 0x4df0 Wi-Fi 6 AX201 product INTEL JSL_GT_1 0x4e51 UHD Graphics product INTEL JSL_GT_2 0x4e55 UHD Graphics product INTEL JSL_GT_3 0x4e57 UHD Graphics diff --git sys/dev/pci/pcidevs.h sys/dev/pci/pcidevs.h index 2871a90f532..f5392ed5a36 100644 --- sys/dev/pci/pcidevs.h +++ sys/dev/pci/pcidevs.h @@ -5307,6 +5307,7 @@ #define PCI_PRODUCT_INTEL_E5_SAD_1 0x3cf4 /* E5 SAD */ #define PCI_PRODUCT_INTEL_E5_BROADCAST 0x3cf5 /* E5 Broadcast */ #define PCI_PRODUCT_INTEL_E5_SAD_2 0x3cf6 /* E5 SAD */ +#define PCI_PRODUCT_INTEL_WL_22500_7 0x3df0 /* Wi-Fi 6 AX201 */ #define PCI_PRODUCT_INTEL_CORE8G_S_D_HB_2C 0x3e0f /* Core 8G Host */ #define PCI_PRODUCT_INTEL_CORE8G_H_HB_4C 0x3e10 /* Core 8G Host */ #define PCI_PRODUCT_INTEL_CORE8G_S_W_HB_4C 0x3e18 /* Core 8G Host */ @@ -5461,6 +5462,7 @@ #define PCI_PRODUCT_INTEL_500SERIES_XHCI 0x43ed /* 500 Series xHCI */ #define PCI_PRODUCT_INTEL_500SERIES_XDCI 0x43ee /* 500 Series xDCI */ #define PCI_PRODUCT_INTEL_500SERIES_SRAM 0x43ef /* 500 Series Shared SRAM */ +#define PCI_PRODUCT_INTEL_WL_22500_6 0x43f0 /* Wi-Fi 6 AX201 */ #define PCI_PRODUCT_INTEL_500SERIES_GSPI_2 0x43fb /* 500 Series GSPI */ #define PCI_PRODUCT_INTEL_500SERIES_ISH 0x43fc /* 500 Series ISH */ #define PCI_PRODUCT_INTEL_500SERIES_GSPI_3 0x43fd /* 500 Series GSPI */ @@ -5515,6 +5517,7 @@ #define PCI_PRODUCT_INTEL_RKL_GT_4 0x4c8c /* UHD Graphics */ #define PCI_PRODUCT_INTEL_RKL_GT_5 0x4c90 /* UHD Graphics */ #define PCI_PRODUCT_INTEL_RKL_GT_6 0x4c9a /* UHD Graphics */ +#define PCI_PRODUCT_INTEL_WL_22500_8 0x4df0 /* Wi-Fi 6 AX201 */ #define PCI_PRODUCT_INTEL_JSL_GT_1 0x4e51 /* UHD Graphics */ #define PCI_PRODUCT_INTEL_JSL_GT_2 0x4e55 /* UHD Graphics */ #define PCI_PRODUCT_INTEL_JSL_GT_3 0x4e57 /* UHD Graphics */ diff --git sys/dev/pci/pcidevs_data.h sys/dev/pci/pcidevs_data.h index fc5c6c2473b..07930b27095 100644 --- sys/dev/pci/pcidevs_data.h +++ sys/dev/pci/pcidevs_data.h @@ -18615,6 +18615,10 @@ static const struct pci_known_product pci_known_products[] = { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_E5_SAD_2, "E5 SAD", }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_7, + "Wi-Fi 6 AX201", + }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE8G_S_D_HB_2C, "Core 8G Host", @@ -19231,6 +19235,10 @@ static const struct pci_known_product pci_known_products[] = { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_500SERIES_SRAM, "500 Series Shared SRAM", }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_6, + "Wi-Fi 6 AX201", + }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_500SERIES_GSPI_2, "500 Series GSPI", @@ -19447,6 +19455,10 @@ static const struct pci_known_product pci_known_products[] = { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_RKL_GT_6, "UHD Graphics", }, + { + PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_8, + "Wi-Fi 6 AX201", + }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_JSL_GT_1, "UHD Graphics",