if_eqos_pci.c revision 1.1
11.1Smsaitoh/* $NetBSD: if_eqos_pci.c,v 1.1 2023/10/20 10:09:43 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.1Smsaitoh__KERNEL_RCSID(0, "$NetBSD: if_eqos_pci.c,v 1.1 2023/10/20 10:09:43 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.1Smsaitoh bus_space_tag_t memt; 1091.1Smsaitoh bus_space_handle_t memh; 1101.1Smsaitoh int counts[PCI_INTR_TYPE_SIZE]; 1111.1Smsaitoh char intrbuf[PCI_INTRSTR_LEN]; 1121.1Smsaitoh bus_size_t memsize; 1131.1Smsaitoh pcireg_t memtype; 1141.1Smsaitoh const char *intrstr; 1151.1Smsaitoh 1161.1Smsaitoh psc->sc_pc = pc; 1171.1Smsaitoh psc->sc_tag = tag; 1181.1Smsaitoh psc->sc_pcidevid = PCI_PRODUCT(pa->pa_id); 1191.1Smsaitoh 1201.1Smsaitoh memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_BAR0); 1211.1Smsaitoh if (pci_mapreg_map(pa, PCI_BAR0, memtype, 0, &memt, &memh, NULL, 1221.1Smsaitoh &memsize) != 0) { 1231.1Smsaitoh aprint_error(": can't map mem space\n"); 1241.1Smsaitoh return; 1251.1Smsaitoh } 1261.1Smsaitoh sc->sc_dev = self; 1271.1Smsaitoh sc->sc_bst = memt; 1281.1Smsaitoh sc->sc_bsh = memh; 1291.1Smsaitoh 1301.1Smsaitoh#if 0 /* I don't know why dmat64 doesn't work... */ 1311.1Smsaitoh if (pci_dma64_available(pa)) { 1321.1Smsaitoh aprint_verbose(", 64-bit DMA"); 1331.1Smsaitoh sc->sc_dmat = pa->pa_dmat64; 1341.1Smsaitoh } else { 1351.1Smsaitoh aprint_verbose(", 32-bit DMA"); 1361.1Smsaitoh sc->sc_dmat = pa->pa_dmat; 1371.1Smsaitoh } 1381.1Smsaitoh#else 1391.1Smsaitoh sc->sc_dmat = pa->pa_dmat; 1401.1Smsaitoh#endif 1411.1Smsaitoh sc->sc_phy_id = MII_PHY_ANY; 1421.1Smsaitoh switch (psc->sc_pcidevid) { 1431.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_ETH: 1441.1Smsaitoh sc->sc_csr_clock = 204800000; 1451.1Smsaitoh break; 1461.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_RGMII: 1471.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_RGMII: 1481.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_SGMII_1G: 1491.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_SGMII_1G: 1501.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_0_SGMII_2_5G: 1511.1Smsaitoh case PCI_PRODUCT_INTEL_EHL_PSE_ETH_1_SGMII_2_5G: 1521.1Smsaitoh sc->sc_csr_clock = 200000000; 1531.1Smsaitoh break; 1541.1Smsaitoh default: 1551.1Smsaitoh sc->sc_csr_clock = 200000000; /* XXX */ 1561.1Smsaitoh } 1571.1Smsaitoh if (eqos_attach(sc) != 0) { 1581.1Smsaitoh aprint_error_dev(sc->sc_dev, "failed in eqos_attach()\n"); 1591.1Smsaitoh return; 1601.1Smsaitoh } 1611.1Smsaitoh 1621.1Smsaitoh /* Allocation settings */ 1631.1Smsaitoh counts[PCI_INTR_TYPE_MSI] = 1; 1641.1Smsaitoh counts[PCI_INTR_TYPE_INTX] = 1; 1651.1Smsaitoh if (pci_intr_alloc(pa, &psc->sc_intrs, counts, PCI_INTR_TYPE_MSI) != 0) 1661.1Smsaitoh { 1671.1Smsaitoh aprint_error_dev(sc->sc_dev, "failed to allocate interrupt\n"); 1681.1Smsaitoh return; 1691.1Smsaitoh } 1701.1Smsaitoh intrstr = pci_intr_string(pc, psc->sc_intrs[0], intrbuf, 1711.1Smsaitoh sizeof(intrbuf)); 1721.1Smsaitoh pci_intr_setattr(pc, &psc->sc_intrs[0], PCI_INTR_MPSAFE, true); 1731.1Smsaitoh psc->sc_ihs[0] = pci_intr_establish_xname(pc, psc->sc_intrs[0], 1741.1Smsaitoh IPL_NET, eqos_intr, sc, device_xname(self)); 1751.1Smsaitoh 1761.1Smsaitoh aprint_normal_dev(self, "interrupting on %s\n", intrstr); 1771.1Smsaitoh 1781.1Smsaitoh if (pmf_device_register(self, NULL, NULL)) 1791.1Smsaitoh pmf_class_network_register(self, &sc->sc_ec.ec_if); 1801.1Smsaitoh else 1811.1Smsaitoh aprint_error_dev(self, "couldn't establish power handler\n"); 1821.1Smsaitoh} 183