void nfe_attach(struct device *parent, struct device *self, void *aux) { struct nfe_softc *sc = (struct nfe_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr; struct ifnet *ifp; bus_size_t memsize; pcireg_t memtype; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA); if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt, &sc->sc_memh, NULL, &memsize, 0)) { printf(": can't map mem space\n"); return; } if (pci_intr_map(pa, &ih) != 0) { printf(": can't map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nfe_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": could not establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s", intrstr); sc->sc_dmat = pa->pa_dmat; sc->sc_flags = 0; switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_NVIDIA_NFORCE3_LAN2: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN3: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN4: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN5: sc->sc_flags |= NFE_JUMBO_SUP | NFE_HW_CSUM; break; case PCI_PRODUCT_NVIDIA_MCP51_LAN1: case PCI_PRODUCT_NVIDIA_MCP51_LAN2: sc->sc_flags |= NFE_40BIT_ADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP61_LAN1: case PCI_PRODUCT_NVIDIA_MCP61_LAN2: case PCI_PRODUCT_NVIDIA_MCP61_LAN3: case PCI_PRODUCT_NVIDIA_MCP61_LAN4: case PCI_PRODUCT_NVIDIA_MCP67_LAN1: case PCI_PRODUCT_NVIDIA_MCP67_LAN2: case PCI_PRODUCT_NVIDIA_MCP67_LAN3: case PCI_PRODUCT_NVIDIA_MCP67_LAN4: case PCI_PRODUCT_NVIDIA_MCP73_LAN1: case PCI_PRODUCT_NVIDIA_MCP73_LAN2: case PCI_PRODUCT_NVIDIA_MCP73_LAN3: case PCI_PRODUCT_NVIDIA_MCP73_LAN4: sc->sc_flags |= NFE_40BIT_ADDR | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP77_LAN1: case PCI_PRODUCT_NVIDIA_MCP77_LAN2: case PCI_PRODUCT_NVIDIA_MCP77_LAN3: case PCI_PRODUCT_NVIDIA_MCP77_LAN4: sc->sc_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP79_LAN1: case PCI_PRODUCT_NVIDIA_MCP79_LAN2: case PCI_PRODUCT_NVIDIA_MCP79_LAN3: case PCI_PRODUCT_NVIDIA_MCP79_LAN4: case PCI_PRODUCT_NVIDIA_MCP89_LAN: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_CK804_LAN1: case PCI_PRODUCT_NVIDIA_CK804_LAN2: case PCI_PRODUCT_NVIDIA_MCP04_LAN1: case PCI_PRODUCT_NVIDIA_MCP04_LAN2: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM; break; case PCI_PRODUCT_NVIDIA_MCP65_LAN1: case PCI_PRODUCT_NVIDIA_MCP65_LAN2: case PCI_PRODUCT_NVIDIA_MCP65_LAN3: case PCI_PRODUCT_NVIDIA_MCP65_LAN4: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_CORRECT_MACADDR | NFE_PWR_MGMT; break; case PCI_PRODUCT_NVIDIA_MCP55_LAN1: case PCI_PRODUCT_NVIDIA_MCP55_LAN2: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_HW_VLAN | NFE_PWR_MGMT; break; } if (sc->sc_flags & NFE_PWR_MGMT) { NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_RESET | NFE_RXTX_BIT2); NFE_WRITE(sc, NFE_MAC_RESET, NFE_MAC_RESET_MAGIC); DELAY(100); NFE_WRITE(sc, NFE_MAC_RESET, 0); DELAY(100); NFE_WRITE(sc, NFE_RXTX_CTL, NFE_RXTX_BIT2); NFE_WRITE(sc, NFE_PWR2_CTL, NFE_READ(sc, NFE_PWR2_CTL) & ~NFE_PWR2_WAKEUP_MASK); } nfe_get_macaddr(sc, sc->sc_arpcom.ac_enaddr); printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); /* * Allocate Tx and Rx rings. */ if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) { printf("%s: could not allocate Tx ring\n", sc->sc_dev.dv_xname); return; } if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) { printf("%s: could not allocate Rx ring\n", sc->sc_dev.dv_xname); nfe_free_tx_ring(sc, &sc->txq); return; } ifp = &sc->sc_arpcom.ac_if; ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = nfe_ioctl; ifp->if_start = nfe_start; ifp->if_watchdog = nfe_watchdog; IFQ_SET_MAXLEN(&ifp->if_snd, NFE_IFQ_MAXLEN); IFQ_SET_READY(&ifp->if_snd); strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); ifp->if_capabilities = IFCAP_VLAN_MTU; #ifndef SMALL_KERNEL ifp->if_capabilities |= IFCAP_WOL; ifp->if_wol = nfe_wol; nfe_wol(ifp, 0); #endif #if NVLAN > 0 if (sc->sc_flags & NFE_HW_VLAN) ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; #endif if (sc->sc_flags & NFE_HW_CSUM) { ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4; } sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = nfe_miibus_readreg; sc->sc_mii.mii_writereg = nfe_miibus_writereg; sc->sc_mii.mii_statchg = nfe_miibus_statchg; ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd, nfe_ifmedia_sts); mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 0, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL); } else ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO); if_attach(ifp); ether_ifattach(ifp); timeout_set(&sc->sc_tick_ch, nfe_tick, sc); }
void nfe_attach(struct device *parent, struct device *self, void *aux) { struct nfe_softc *sc = (struct nfe_softc *)self; struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pci_intr_handle_t ih; const char *intrstr; struct ifnet *ifp; bus_size_t memsize; pcireg_t memtype; memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, NFE_PCI_BA); switch (memtype) { case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT: if (pci_mapreg_map(pa, NFE_PCI_BA, memtype, 0, &sc->sc_memt, &sc->sc_memh, NULL, &memsize, 0) == 0) break; /* FALLTHROUGH */ default: printf(": could not map mem space\n"); return; } if (pci_intr_map(pa, &ih) != 0) { printf(": could not map interrupt\n"); return; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, nfe_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": could not establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); return; } printf(": %s", intrstr); sc->sc_dmat = pa->pa_dmat; nfe_get_macaddr(sc, sc->sc_arpcom.ac_enaddr); printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); sc->sc_flags = 0; switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_NVIDIA_NFORCE3_LAN2: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN3: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN4: case PCI_PRODUCT_NVIDIA_NFORCE3_LAN5: sc->sc_flags |= NFE_JUMBO_SUP | NFE_HW_CSUM; break; case PCI_PRODUCT_NVIDIA_MCP51_LAN1: case PCI_PRODUCT_NVIDIA_MCP51_LAN2: case PCI_PRODUCT_NVIDIA_MCP61_LAN1: case PCI_PRODUCT_NVIDIA_MCP61_LAN2: case PCI_PRODUCT_NVIDIA_MCP61_LAN3: case PCI_PRODUCT_NVIDIA_MCP61_LAN4: case PCI_PRODUCT_NVIDIA_MCP67_LAN1: case PCI_PRODUCT_NVIDIA_MCP67_LAN2: case PCI_PRODUCT_NVIDIA_MCP67_LAN3: case PCI_PRODUCT_NVIDIA_MCP67_LAN4: sc->sc_flags |= NFE_40BIT_ADDR; break; case PCI_PRODUCT_NVIDIA_CK804_LAN1: case PCI_PRODUCT_NVIDIA_CK804_LAN2: case PCI_PRODUCT_NVIDIA_MCP04_LAN1: case PCI_PRODUCT_NVIDIA_MCP04_LAN2: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM; break; case PCI_PRODUCT_NVIDIA_MCP65_LAN1: case PCI_PRODUCT_NVIDIA_MCP65_LAN2: case PCI_PRODUCT_NVIDIA_MCP65_LAN3: case PCI_PRODUCT_NVIDIA_MCP65_LAN4: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR; break; case PCI_PRODUCT_NVIDIA_MCP55_LAN1: case PCI_PRODUCT_NVIDIA_MCP55_LAN2: sc->sc_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_HW_VLAN; break; } /* enable jumbo frames for adapters that support it */ if (sc->sc_flags & NFE_JUMBO_SUP) sc->sc_flags |= NFE_USE_JUMBO; /* * Allocate Tx and Rx rings. */ if (nfe_alloc_tx_ring(sc, &sc->txq) != 0) { printf("%s: could not allocate Tx ring\n", sc->sc_dev.dv_xname); return; } if (nfe_alloc_rx_ring(sc, &sc->rxq) != 0) { printf("%s: could not allocate Rx ring\n", sc->sc_dev.dv_xname); nfe_free_tx_ring(sc, &sc->txq); return; } ifp = &sc->sc_arpcom.ac_if; ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = nfe_ioctl; ifp->if_start = nfe_start; ifp->if_watchdog = nfe_watchdog; ifp->if_init = nfe_init; ifp->if_baudrate = IF_Gbps(1); IFQ_SET_MAXLEN(&ifp->if_snd, NFE_IFQ_MAXLEN); IFQ_SET_READY(&ifp->if_snd); strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); ifp->if_capabilities = IFCAP_VLAN_MTU; if (sc->sc_flags & NFE_USE_JUMBO) ifp->if_hardmtu = NFE_JUMBO_MTU; #if NVLAN > 0 if (sc->sc_flags & NFE_HW_VLAN) ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; #endif if (sc->sc_flags & NFE_HW_CSUM) { ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4; } sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = nfe_miibus_readreg; sc->sc_mii.mii_writereg = nfe_miibus_writereg; sc->sc_mii.mii_statchg = nfe_miibus_statchg; ifmedia_init(&sc->sc_mii.mii_media, 0, nfe_ifmedia_upd, nfe_ifmedia_sts); mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL); } else ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO); if_attach(ifp); ether_ifattach(ifp); timeout_set(&sc->sc_tick_ch, nfe_tick, sc); sc->sc_powerhook = powerhook_establish(nfe_power, sc); }