if_eqos_pci.c revision 1.3
11.3Smsaitoh/* $NetBSD: if_eqos_pci.c,v 1.3 2023/10/31 13:57:08 msaitoh Exp $ */ 21.1Smsaitoh 31.1Smsaitoh/*- 41.1Smsaitoh * Copyright (c) 2023 Masanobu SAITOH <msaitoh@netbsd.org> 51.1Smsaitoh * All rights reserved. 61.1Smsaitoh * 71.1Smsaitoh * Redistribution and use in source and binary forms, with or without 81.1Smsaitoh * modification, are permitted provided that the following conditions 91.1Smsaitoh * are met: 101.1Smsaitoh * 1. Redistributions of source code must retain the above copyright 111.1Smsaitoh * notice, this list of conditions and the following disclaimer. 121.1Smsaitoh * 2. Redistributions in binary form must reproduce the above copyright 131.1Smsaitoh * notice, this list of conditions and the following disclaimer in the 141.1Smsaitoh * documentation and/or other materials provided with the distribution. 151.1Smsaitoh * 161.1Smsaitoh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 171.1Smsaitoh * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 181.1Smsaitoh * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 191.1Smsaitoh * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 201.1Smsaitoh * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 211.1Smsaitoh * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 221.1Smsaitoh * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 231.1Smsaitoh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 241.1Smsaitoh * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 251.1Smsaitoh * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Smsaitoh * POSSIBILITY OF SUCH DAMAGE. 271.1Smsaitoh */ 281.1Smsaitoh 291.1Smsaitoh/* 301.1Smsaitoh * TODO: 311.1Smsaitoh * Use multi vector MSI to support multiqueue. 321.1Smsaitoh * 331.1Smsaitoh */ 341.1Smsaitoh 351.1Smsaitoh#include "opt_net_mpsafe.h" 361.1Smsaitoh 371.1Smsaitoh#include <sys/cdefs.h> 381.3Smsaitoh__KERNEL_RCSID(0, "$NetBSD: if_eqos_pci.c,v 1.3 2023/10/31 13:57:08 msaitoh Exp $"); 391.1Smsaitoh 401.1Smsaitoh#include <sys/param.h> 411.1Smsaitoh#include <sys/bus.h> 421.1Smsaitoh#include <sys/device.h> 431.1Smsaitoh#include <sys/rndsource.h> 441.1Smsaitoh 451.1Smsaitoh#include <net/if_ether.h> 461.1Smsaitoh#include <net/if_media.h> 471.1Smsaitoh 481.1Smsaitoh#include <dev/pci/pcireg.h> 491.1Smsaitoh#include <dev/pci/pcivar.h> 501.1Smsaitoh#include <dev/pci/pcidevs.h> 511.1Smsaitoh 521.1Smsaitoh#include <dev/mii/miivar.h> 531.1Smsaitoh#include <dev/ic/dwc_eqos_var.h> 541.1Smsaitoh 551.1Smsaitoh#define EQOS_PCI_MAX_INTR 1 561.1Smsaitoh 571.1Smsaitohstatic int eqos_pci_match(device_t, cfdata_t, void *); 581.1Smsaitohstatic void eqos_pci_attach(device_t, device_t, void *); 591.1Smsaitoh 601.1Smsaitohstruct eqos_pci_softc { 611.1Smsaitoh struct eqos_softc sc_eqos; 621.1Smsaitoh pci_chipset_tag_t sc_pc; 631.1Smsaitoh pcitag_t sc_tag; 641.1Smsaitoh void *sc_ihs[EQOS_PCI_MAX_INTR]; 651.1Smsaitoh pci_intr_handle_t *sc_intrs; 661.1Smsaitoh uint16_t sc_pcidevid; 671.1Smsaitoh}; 681.1Smsaitoh 691.1Smsaitohstatic const struct device_compatible_entry compat_data[] = { 701.1Smsaitoh { .id = PCI_ID_CODE(PCI_VENDOR_INTEL, 711.1Smsaitoh PCI_PRODUCT_INTEL_EHL_ETH) }, 721.1Smsaitoh { .id = PCI_ID_CODE(PCI_VENDOR_INTEL, 731.1Smsaitoh PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_RGMII) }, 741.1Smsaitoh { .id = PCI_ID_CODE(PCI_VENDOR_INTEL, 751.1Smsaitoh PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_RGMII) }, 761.1Smsaitoh { .id = PCI_ID_CODE(PCI_VENDOR_INTEL, 771.1Smsaitoh PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_SGMII_1G) }, 781.1Smsaitoh { .id = PCI_ID_CODE(PCI_VENDOR_INTEL, 791.1Smsaitoh PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_SGMII_1G) }, 801.1Smsaitoh { .id = PCI_ID_CODE(PCI_VENDOR_INTEL, 811.1Smsaitoh PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_SGMII_2_5G) }, 821.1Smsaitoh { .id = PCI_ID_CODE(PCI_VENDOR_INTEL, 831.1Smsaitoh PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_SGMII_2_5G) }, 841.1Smsaitoh 851.1Smsaitoh PCI_COMPAT_EOL 861.1Smsaitoh}; 871.1Smsaitoh 881.1SmsaitohCFATTACH_DECL3_NEW(eqos_pci, sizeof(struct eqos_pci_softc), 891.1Smsaitoh eqos_pci_match, eqos_pci_attach, NULL, NULL, NULL, NULL, 901.1Smsaitoh 0); 911.1Smsaitoh 921.1Smsaitohstatic int 931.1Smsaitoheqos_pci_match(device_t parent, cfdata_t match, void *aux) 941.1Smsaitoh{ 951.1Smsaitoh struct pci_attach_args *pa =aux; 961.1Smsaitoh 971.1Smsaitoh return pci_compatible_match(pa, compat_data); 981.1Smsaitoh} 991.1Smsaitoh 1001.1Smsaitohstatic void 1011.1Smsaitoheqos_pci_attach(device_t parent, device_t self, void *aux) 1021.1Smsaitoh{ 1031.1Smsaitoh struct eqos_pci_softc * const psc = device_private(self); 1041.1Smsaitoh struct eqos_softc * const sc = &psc->sc_eqos; 1051.1Smsaitoh struct pci_attach_args *pa =aux; 1061.1Smsaitoh const pci_chipset_tag_t pc = pa->pa_pc; 1071.1Smsaitoh const pcitag_t tag = pa->pa_tag; 1081.2Smsaitoh prop_dictionary_t prop; 1091.1Smsaitoh bus_space_tag_t memt; 1101.1Smsaitoh bus_space_handle_t memh; 1111.1Smsaitoh int counts[PCI_INTR_TYPE_SIZE]; 1121.1Smsaitoh char intrbuf[PCI_INTRSTR_LEN]; 1131.1Smsaitoh bus_size_t memsize; 1141.1Smsaitoh pcireg_t memtype; 1151.1Smsaitoh const char *intrstr; 1161.2Smsaitoh uint32_t dma_pbl = 0; 1171.1Smsaitoh 1181.1Smsaitoh psc->sc_pc = pc; 1191.1Smsaitoh psc->sc_tag = tag; 1201.1Smsaitoh psc->sc_pcidevid = PCI_PRODUCT(pa->pa_id); 1211.1Smsaitoh 1221.1Smsaitoh memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_BAR0); 1231.1Smsaitoh if (pci_mapreg_map(pa, PCI_BAR0, memtype, 0, &memt, &memh, NULL, 1241.1Smsaitoh &memsize) != 0) { 1251.1Smsaitoh aprint_error(": can't map mem space\n"); 1261.1Smsaitoh return; 1271.1Smsaitoh } 1281.1Smsaitoh sc->sc_dev = self; 1291.1Smsaitoh sc->sc_bst = memt; 1301.1Smsaitoh sc->sc_bsh = memh; 1311.2Smsaitoh prop = device_properties(sc->sc_dev); 1321.1Smsaitoh 1331.3Smsaitoh if (pci_dma64_available(pa)) 1341.1Smsaitoh sc->sc_dmat = pa->pa_dmat64; 1351.3Smsaitoh else 1361.1Smsaitoh sc->sc_dmat = pa->pa_dmat; 1371.3Smsaitoh 1381.1Smsaitoh sc->sc_phy_id = MII_PHY_ANY; 1391.1Smsaitoh switch (psc->sc_pcidevid) { 1401.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_ETH: 1411.1Smsaitoh sc->sc_csr_clock = 204800000; 1421.2Smsaitoh dma_pbl = 32; 1431.1Smsaitoh break; 1441.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_RGMII: 1451.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_RGMII: 1461.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_SGMII_1G: 1471.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_SGMII_1G: 1481.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_SGMII_2_5G: 1491.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_SGMII_2_5G: 1501.3Smsaitoh sc->sc_dmat = pa->pa_dmat; /* 32bit DMA only */ 1511.1Smsaitoh sc->sc_csr_clock = 200000000; 1521.2Smsaitoh dma_pbl = 32; 1531.1Smsaitoh break; 1541.2Smsaitoh#if 0 1551.2Smsaitoh case PCI_PRODUCT_INTEL_QUARTK_ETH: 1561.2Smsaitoh dma_pbl = 16; 1571.2Smsaitoh#endif 1581.1Smsaitoh default: 1591.1Smsaitoh sc->sc_csr_clock = 200000000; /* XXX */ 1601.1Smsaitoh } 1611.3Smsaitoh 1621.3Smsaitoh if (sc->sc_dmat == pa->pa_dmat64) 1631.3Smsaitoh aprint_verbose(", 64-bit DMA"); 1641.3Smsaitoh else 1651.3Smsaitoh aprint_verbose(", 32-bit DMA"); 1661.3Smsaitoh 1671.2Smsaitoh /* Defaults */ 1681.2Smsaitoh if (dma_pbl != 0) { 1691.2Smsaitoh prop = device_properties(sc->sc_dev); 1701.2Smsaitoh prop_dictionary_set_uint32(prop, "snps,pbl", dma_pbl); 1711.2Smsaitoh } 1721.2Smsaitoh 1731.1Smsaitoh if (eqos_attach(sc) != 0) { 1741.1Smsaitoh aprint_error_dev(sc->sc_dev, "failed in eqos_attach()\n"); 1751.1Smsaitoh return; 1761.1Smsaitoh } 1771.1Smsaitoh 1781.1Smsaitoh /* Allocation settings */ 1791.1Smsaitoh counts[PCI_INTR_TYPE_MSI] = 1; 1801.1Smsaitoh counts[PCI_INTR_TYPE_INTX] = 1; 1811.1Smsaitoh if (pci_intr_alloc(pa, &psc->sc_intrs, counts, PCI_INTR_TYPE_MSI) != 0) 1821.1Smsaitoh { 1831.1Smsaitoh aprint_error_dev(sc->sc_dev, "failed to allocate interrupt\n"); 1841.1Smsaitoh return; 1851.1Smsaitoh } 1861.1Smsaitoh intrstr = pci_intr_string(pc, psc->sc_intrs[0], intrbuf, 1871.1Smsaitoh sizeof(intrbuf)); 1881.1Smsaitoh pci_intr_setattr(pc, &psc->sc_intrs[0], PCI_INTR_MPSAFE, true); 1891.1Smsaitoh psc->sc_ihs[0] = pci_intr_establish_xname(pc, psc->sc_intrs[0], 1901.1Smsaitoh IPL_NET, eqos_intr, sc, device_xname(self)); 1911.1Smsaitoh 1921.1Smsaitoh aprint_normal_dev(self, "interrupting on %s\n", intrstr); 1931.1Smsaitoh 1941.1Smsaitoh if (pmf_device_register(self, NULL, NULL)) 1951.1Smsaitoh pmf_class_network_register(self, &sc->sc_ec.ec_if); 1961.1Smsaitoh else 1971.1Smsaitoh aprint_error_dev(self, "couldn't establish power handler\n"); 1981.1Smsaitoh} 199