1 /* $OpenBSD: if_dwqe_pci.c,v 1.3 2023/11/11 16:50:25 stsp Exp $ */ 2 3 /* 4 * Copyright (c) 2023 Stefan Sperling <stsp@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * Driver for the Intel Elkhart Lake ethernet controller. 21 */ 22 23 #include <sys/param.h> 24 #include <sys/systm.h> 25 #include <sys/device.h> 26 27 #include <dev/pci/pcireg.h> 28 #include <dev/pci/pcivar.h> 29 #include <dev/pci/pcidevs.h> 30 31 #include <net/if.h> 32 #include <net/if_media.h> 33 34 #include <netinet/in.h> 35 #include <netinet/if_ether.h> 36 37 #include <dev/mii/miivar.h> 38 39 #include <dev/ic/dwqereg.h> 40 #include <dev/ic/dwqevar.h> 41 42 static const struct pci_matchid dwqe_pci_devices[] = { 43 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE0_RGMII_1G }, 44 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE0_SGMII_1G }, 45 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE0_SGMII_2G }, 46 #if 0 47 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE1_RGMII_1G }, 48 #endif 49 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE1_SGMII_1G }, 50 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_EHL_PSE1_SGMII_2G }, 51 }; 52 53 struct dwqe_pci_softc { 54 struct dwqe_softc sc_sc; 55 pci_chipset_tag_t sc_pct; 56 pcitag_t sc_pcitag; 57 bus_size_t sc_mapsize; 58 }; 59 60 int 61 dwqe_pci_match(struct device *parent, void *cfdata, void *aux) 62 { 63 struct pci_attach_args *pa = aux; 64 return pci_matchbyid(pa, dwqe_pci_devices, nitems(dwqe_pci_devices)); 65 } 66 67 void 68 dwqe_pci_attach(struct device *parent, struct device *self, void *aux) 69 { 70 struct pci_attach_args *pa = aux; 71 struct dwqe_pci_softc *psc = (void *)self; 72 struct dwqe_softc *sc = &psc->sc_sc; 73 pci_intr_handle_t ih; 74 pcireg_t memtype; 75 int err; 76 const char *intrstr; 77 78 psc->sc_pct = pa->pa_pc; 79 psc->sc_pcitag = pa->pa_tag; 80 81 sc->sc_dmat = pa->pa_dmat; 82 83 memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, PCI_MAPREG_START); 84 err = pci_mapreg_map(pa, PCI_MAPREG_START, memtype, 0, 85 &sc->sc_iot, &sc->sc_ioh, NULL, &psc->sc_mapsize, 0); 86 if (err) { 87 printf("%s: can't map mem space\n", DEVNAME(sc)); 88 return; 89 } 90 91 if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) { 92 printf("%s: can't map interrupt\n", DEVNAME(sc)); 93 return; 94 } 95 96 intrstr = pci_intr_string(psc->sc_pct, ih); 97 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET | IPL_MPSAFE, 98 dwqe_intr, psc, sc->sc_dev.dv_xname); 99 if (sc->sc_ih == NULL) { 100 printf(": can't establish interrupt"); 101 if (intrstr != NULL) 102 printf(" at %s", intrstr); 103 printf("\n"); 104 return; 105 } 106 107 switch (PCI_PRODUCT(pa->pa_id)) { 108 case PCI_PRODUCT_INTEL_EHL_PSE0_RGMII_1G: 109 sc->sc_phy_mode = DWQE_PHY_MODE_RGMII_ID; 110 sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_250_300; 111 sc->sc_clkrate = 200000000; 112 break; 113 case PCI_PRODUCT_INTEL_EHL_PSE0_SGMII_1G: 114 case PCI_PRODUCT_INTEL_EHL_PSE0_SGMII_2G: 115 case PCI_PRODUCT_INTEL_EHL_PSE1_SGMII_1G: 116 case PCI_PRODUCT_INTEL_EHL_PSE1_SGMII_2G: 117 sc->sc_phy_mode = DWQE_PHY_MODE_SGMII; 118 sc->sc_clk = GMAC_MAC_MDIO_ADDR_CR_250_300; 119 sc->sc_clkrate = 200000000; 120 break; 121 default: 122 sc->sc_phy_mode = DWQE_PHY_MODE_UNKNOWN; 123 break; 124 } 125 126 sc->sc_phyloc = MII_PHY_ANY; 127 sc->sc_8xpbl = 1; 128 sc->sc_txpbl = 32; 129 sc->sc_rxpbl = 32; 130 sc->sc_txfifo_size = 32768; 131 sc->sc_rxfifo_size = 32768; 132 133 sc->sc_axi_config = 1; 134 sc->sc_wr_osr_lmt = 1; 135 sc->sc_rd_osr_lmt = 1; 136 sc->sc_blen[0] = 4; 137 sc->sc_blen[1] = 8; 138 sc->sc_blen[2] = 16; 139 140 dwqe_lladdr_read(sc, sc->sc_lladdr); 141 142 dwqe_reset(sc); 143 dwqe_attach(sc); 144 } 145 146 const struct cfattach dwqe_pci_ca = { 147 sizeof(struct dwqe_softc), dwqe_pci_match, dwqe_pci_attach 148 }; 149