Index: head/sys/mips/rmi/dev/nlge/if_nlge.c =================================================================== --- head/sys/mips/rmi/dev/nlge/if_nlge.c (revision 287470) +++ head/sys/mips/rmi/dev/nlge/if_nlge.c (revision 287471) @@ -1,2564 +1,2564 @@ /*- * Copyright (c) 2003-2009 RMI Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of RMI Corporation, nor the names of its contributors, * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * RMI_BSD */ /* * The XLR device supports upto four 10/100/1000 Ethernet MACs and upto * two 10G Ethernet MACs (of XGMII). Alternatively, each 10G port can used * as a SPI-4 interface, with 8 ports per such interface. The MACs are * encapsulated in another hardware block referred to as network accelerator, * such that there are three instances of these in a XLR. One of them controls * the four 1G RGMII ports while one each of the others controls an XGMII port. * Enabling MACs requires configuring the corresponding network accelerator * and the individual port. * The XLS device supports upto 8 10/100/1000 Ethernet MACs or max 2 10G * Ethernet MACs. The 1G MACs are of SGMII and 10G MACs are of XAUI * interface. These ports are part of two network accelerators. * The nlge driver configures and initializes non-SPI4 Ethernet ports in the * XLR/XLS devices and enables data transfer on them. */ #include __FBSDID("$FreeBSD$"); #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_device_polling.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define __RMAN_RESOURCE_VISIBLE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for DELAY */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "miidevs.h" #include #include "miibus_if.h" #include MODULE_DEPEND(nlna, nlge, 1, 1, 1); MODULE_DEPEND(nlge, ether, 1, 1, 1); MODULE_DEPEND(nlge, miibus, 1, 1, 1); /* Network accelarator entry points */ static int nlna_probe(device_t); static int nlna_attach(device_t); static int nlna_detach(device_t); static int nlna_suspend(device_t); static int nlna_resume(device_t); static int nlna_shutdown(device_t); /* GMAC port entry points */ static int nlge_probe(device_t); static int nlge_attach(device_t); static int nlge_detach(device_t); static int nlge_suspend(device_t); static int nlge_resume(device_t); static void nlge_init(void *); static int nlge_ioctl(struct ifnet *, u_long, caddr_t); static int nlge_tx(struct ifnet *ifp, struct mbuf *m); static void nlge_rx(struct nlge_softc *sc, vm_paddr_t paddr, int len); static int nlge_mii_write(struct device *, int, int, int); static int nlge_mii_read(struct device *, int, int); static void nlge_mac_mii_statchg(device_t); static int nlge_mediachange(struct ifnet *ifp); static void nlge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr); /* Other internal/helper functions */ static void *get_buf(void); static void nlna_add_to_port_set(struct nlge_port_set *pset, struct nlge_softc *sc); static void nlna_config_pde(struct nlna_softc *); static void nlna_config_parser(struct nlna_softc *); static void nlna_config_classifier(struct nlna_softc *); static void nlna_config_fifo_spill_area(struct nlna_softc *sc); static void nlna_config_translate_table(struct nlna_softc *sc); static void nlna_config_common(struct nlna_softc *); static void nlna_disable_ports(struct nlna_softc *sc); static void nlna_enable_intr(struct nlna_softc *sc); static void nlna_disable_intr(struct nlna_softc *sc); static void nlna_enable_ports(struct nlna_softc *sc); static void nlna_get_all_softc(device_t iodi_dev, struct nlna_softc **sc_vec, uint32_t vec_sz); static void nlna_hw_init(struct nlna_softc *sc); static int nlna_is_last_active_na(struct nlna_softc *sc); static void nlna_media_specific_config(struct nlna_softc *sc); static void nlna_reset_ports(struct nlna_softc *sc, struct xlr_gmac_block_t *blk); static struct nlna_softc *nlna_sc_init(device_t dev, struct xlr_gmac_block_t *blk); static void nlna_setup_intr(struct nlna_softc *sc); static void nlna_smp_update_pde(void *dummy __unused); static void nlna_submit_rx_free_desc(struct nlna_softc *sc, uint32_t n_desc); static int nlge_gmac_config_speed(struct nlge_softc *, int quick); static void nlge_hw_init(struct nlge_softc *sc); static int nlge_if_init(struct nlge_softc *sc); static void nlge_intr(void *arg); static int nlge_irq_init(struct nlge_softc *sc); static void nlge_irq_fini(struct nlge_softc *sc); static void nlge_media_specific_init(struct nlge_softc *sc); static void nlge_mii_init(device_t dev, struct nlge_softc *sc); static int nlge_mii_read_internal(xlr_reg_t *mii_base, int phyaddr, int regidx); static void nlge_mii_write_internal(xlr_reg_t *mii_base, int phyaddr, int regidx, int regval); void nlge_msgring_handler(int bucket, int size, int code, int stid, struct msgrng_msg *msg, void *data); static void nlge_port_disable(struct nlge_softc *sc); static void nlge_port_enable(struct nlge_softc *sc); static void nlge_read_mac_addr(struct nlge_softc *sc); static void nlge_sc_init(struct nlge_softc *sc, device_t dev, struct xlr_gmac_port *port_info); static void nlge_set_mac_addr(struct nlge_softc *sc); static void nlge_set_port_attribs(struct nlge_softc *, struct xlr_gmac_port *); static void nlge_mac_set_rx_mode(struct nlge_softc *sc); static void nlge_sgmii_init(struct nlge_softc *sc); static int nlge_start_locked(struct ifnet *ifp, struct nlge_softc *sc, struct mbuf *m); static int prepare_fmn_message(struct nlge_softc *sc, struct msgrng_msg *msg, uint32_t *n_entries, struct mbuf *m_head, uint64_t fr_stid, struct nlge_tx_desc **tx_desc); static void release_tx_desc(vm_paddr_t phy_addr); static int send_fmn_msg_tx(struct nlge_softc *, struct msgrng_msg *, uint32_t n_entries); //#define DEBUG #ifdef DEBUG static int mac_debug = 1; #undef PDEBUG #define PDEBUG(fmt, args...) \ do {\ if (mac_debug) {\ printf("[%s@%d|%s]: cpu_%d: " fmt, \ __FILE__, __LINE__, __FUNCTION__, PCPU_GET(cpuid), ##args);\ }\ } while(0); /* Debug/dump functions */ static void dump_reg(xlr_reg_t *addr, uint32_t offset, char *name); static void dump_gmac_registers(struct nlge_softc *); static void dump_na_registers(xlr_reg_t *base, int port_id); static void dump_mac_stats(struct nlge_softc *sc); static void dump_mii_regs(struct nlge_softc *sc) __attribute__((used)); static void dump_mii_data(struct mii_data *mii) __attribute__((used)); static void dump_board_info(struct xlr_board_info *); static void dump_pcs_regs(struct nlge_softc *sc, int phy); #else #undef PDEBUG #define PDEBUG(fmt, args...) #define dump_reg(a, o, n) /* nop */ #define dump_gmac_registers(a) /* nop */ #define dump_na_registers(a, p) /* nop */ #define dump_board_info(b) /* nop */ #define dump_mac_stats(sc) /* nop */ #define dump_mii_regs(sc) /* nop */ #define dump_mii_data(mii) /* nop */ #define dump_pcs_regs(sc, phy) /* nop */ #endif /* Wrappers etc. to export the driver entry points. */ static device_method_t nlna_methods[] = { /* Device interface */ DEVMETHOD(device_probe, nlna_probe), DEVMETHOD(device_attach, nlna_attach), DEVMETHOD(device_detach, nlna_detach), DEVMETHOD(device_shutdown, nlna_shutdown), DEVMETHOD(device_suspend, nlna_suspend), DEVMETHOD(device_resume, nlna_resume), /* bus interface : TBD : what are these for ? */ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), DEVMETHOD_END }; static driver_t nlna_driver = { "nlna", nlna_methods, sizeof(struct nlna_softc) }; static devclass_t nlna_devclass; static device_method_t nlge_methods[] = { /* Device interface */ DEVMETHOD(device_probe, nlge_probe), DEVMETHOD(device_attach, nlge_attach), DEVMETHOD(device_detach, nlge_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, nlge_suspend), DEVMETHOD(device_resume, nlge_resume), /* MII interface */ DEVMETHOD(miibus_readreg, nlge_mii_read), DEVMETHOD(miibus_writereg, nlge_mii_write), DEVMETHOD(miibus_statchg, nlge_mac_mii_statchg), {0, 0} }; static driver_t nlge_driver = { "nlge", nlge_methods, sizeof(struct nlge_softc) }; static devclass_t nlge_devclass; DRIVER_MODULE(nlna, iodi, nlna_driver, nlna_devclass, 0, 0); DRIVER_MODULE(nlge, nlna, nlge_driver, nlge_devclass, 0, 0); DRIVER_MODULE(miibus, nlge, miibus_driver, miibus_devclass, 0, 0); static uma_zone_t nl_tx_desc_zone; /* Tunables. */ static int flow_classification = 0; TUNABLE_INT("hw.nlge.flow_classification", &flow_classification); #define NLGE_HW_CHKSUM 1 static __inline void atomic_incr_long(unsigned long *addr) { /* XXX: fix for 64 bit */ unsigned int *iaddr = (unsigned int *)addr; xlr_ldaddwu(1, iaddr); } static int nlna_probe(device_t dev) { return (BUS_PROBE_DEFAULT); } /* * Add all attached GMAC/XGMAC ports to the device tree. Port * configuration is spread in two regions - common configuration * for all ports in the NA and per-port configuration in MAC-specific * region. This function does the following: * - adds the ports to the device tree * - reset the ports * - do all the common initialization * - invoke bus_generic_attach for per-port configuration * - supply initial free rx descriptors to ports * - initialize s/w data structures * - finally, enable interrupts (only in the last NA). * * For reference, sample address space for common and per-port * registers is given below. * * The address map for RNA0 is: (typical value) * * XLR_IO_BASE +--------------------------------------+ 0xbef0_0000 * | | * | | * | | * | | * | | * | | * GMAC0 ---> +--------------------------------------+ 0xbef0_c000 * | | * | | * (common) -> |......................................| 0xbef0_c400 * | | * | (RGMII/SGMII: common registers) | * | | * GMAC1 ---> |--------------------------------------| 0xbef0_d000 * | | * | | * (common) -> |......................................| 0xbef0_d400 * | | * | (RGMII/SGMII: common registers) | * | | * |......................................| * and so on .... * * Ref: Figure 14-3 and Table 14-1 of XLR PRM */ static int nlna_attach(device_t dev) { struct xlr_gmac_block_t *block_info; device_t gmac_dev; struct nlna_softc *sc; int error; int i; int id; id = device_get_unit(dev); block_info = device_get_ivars(dev); if (!block_info->enabled) { return 0; } #ifdef DEBUG dump_board_info(&xlr_board_info); #endif /* Initialize nlna state in softc structure */ sc = nlna_sc_init(dev, block_info); /* Add device's for the ports controlled by this NA. */ if (block_info->type == XLR_GMAC) { KASSERT(id < 2, ("No GMACs supported with this network" "accelerator: %d", id)); for (i = 0; i < sc->num_ports; i++) { gmac_dev = device_add_child(dev, "nlge", -1); device_set_ivars(gmac_dev, &block_info->gmac_port[i]); } } else if (block_info->type == XLR_XGMAC) { KASSERT(id > 0 && id <= 2, ("No XGMACs supported with this" "network accelerator: %d", id)); gmac_dev = device_add_child(dev, "nlge", -1); device_set_ivars(gmac_dev, &block_info->gmac_port[0]); } else if (block_info->type == XLR_SPI4) { /* SPI4 is not supported here */ device_printf(dev, "Unsupported: NA with SPI4 type"); return (ENOTSUP); } nlna_reset_ports(sc, block_info); /* Initialize Network Accelarator registers. */ nlna_hw_init(sc); error = bus_generic_attach(dev); if (error) { device_printf(dev, "failed to attach port(s)\n"); goto fail; } /* Send out the initial pool of free-descriptors for the rx path */ nlna_submit_rx_free_desc(sc, MAX_FRIN_SPILL); /* S/w data structure initializations shared by all NA's. */ if (nl_tx_desc_zone == NULL) { /* Create a zone for allocating tx descriptors */ nl_tx_desc_zone = uma_zcreate("NL Tx Desc", sizeof(struct nlge_tx_desc), NULL, NULL, NULL, NULL, XLR_CACHELINE_SIZE, 0); } /* Enable NA interrupts */ nlna_setup_intr(sc); return (0); fail: return (error); } static int nlna_detach(device_t dev) { struct nlna_softc *sc; sc = device_get_softc(dev); if (device_is_alive(dev)) { nlna_disable_intr(sc); /* This will make sure that per-port detach is complete * and all traffic on the ports has been stopped. */ bus_generic_detach(dev); uma_zdestroy(nl_tx_desc_zone); } return (0); } static int nlna_suspend(device_t dev) { return (0); } static int nlna_resume(device_t dev) { return (0); } static int nlna_shutdown(device_t dev) { return (0); } /* GMAC port entry points */ static int nlge_probe(device_t dev) { struct nlge_softc *sc; struct xlr_gmac_port *port_info; int index; char *desc[] = { "RGMII", "SGMII", "RGMII/SGMII", "XGMAC", "XAUI", "Unknown"}; port_info = device_get_ivars(dev); index = (port_info->type < XLR_RGMII || port_info->type > XLR_XAUI) ? 5 : port_info->type; device_set_desc_copy(dev, desc[index]); sc = device_get_softc(dev); nlge_sc_init(sc, dev, port_info); nlge_port_disable(sc); return (0); } static int nlge_attach(device_t dev) { struct nlge_softc *sc; struct nlna_softc *nsc; int error; sc = device_get_softc(dev); nlge_if_init(sc); nlge_mii_init(dev, sc); error = nlge_irq_init(sc); if (error) return error; nlge_hw_init(sc); nsc = (struct nlna_softc *)device_get_softc(device_get_parent(dev)); nsc->child_sc[sc->instance] = sc; return (0); } static int nlge_detach(device_t dev) { struct nlge_softc *sc; struct ifnet *ifp; sc = device_get_softc(dev); ifp = sc->nlge_if; if (device_is_attached(dev)) { nlge_port_disable(sc); nlge_irq_fini(sc); ether_ifdetach(ifp); bus_generic_detach(dev); } if (ifp) if_free(ifp); return (0); } static int nlge_suspend(device_t dev) { return (0); } static int nlge_resume(device_t dev) { return (0); } static void nlge_init(void *addr) { struct nlge_softc *sc; struct ifnet *ifp; sc = (struct nlge_softc *)addr; ifp = sc->nlge_if; if (ifp->if_drv_flags & IFF_DRV_RUNNING) return; nlge_gmac_config_speed(sc, 1); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; nlge_port_enable(sc); if (sc->port_type == XLR_SGMII) { dump_pcs_regs(sc, 27); } dump_gmac_registers(sc); dump_mac_stats(sc); } static int nlge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { struct mii_data *mii; struct nlge_softc *sc; struct ifreq *ifr; int error; sc = ifp->if_softc; error = 0; ifr = (struct ifreq *)data; switch(command) { case SIOCSIFFLAGS: NLGE_LOCK(sc); if (ifp->if_flags & IFF_UP) { if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { nlge_init(sc); } if (ifp->if_flags & IFF_PROMISC && !(sc->if_flags & IFF_PROMISC)) { sc->if_flags |= IFF_PROMISC; nlge_mac_set_rx_mode(sc); } else if (!(ifp->if_flags & IFF_PROMISC) && sc->if_flags & IFF_PROMISC) { sc->if_flags &= IFF_PROMISC; nlge_mac_set_rx_mode(sc); } } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { nlge_port_disable(sc); } } sc->if_flags = ifp->if_flags; NLGE_UNLOCK(sc); error = 0; break; case SIOCSIFMEDIA: case SIOCGIFMEDIA: if (sc->mii_bus != NULL) { mii = (struct mii_data *)device_get_softc(sc->mii_bus); error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); } break; default: error = ether_ioctl(ifp, command, data); break; } return (error); } /* This function is called from an interrupt handler */ void nlge_msgring_handler(int bucket, int size, int code, int stid, struct msgrng_msg *msg, void *data) { struct nlna_softc *na_sc; struct nlge_softc *sc; struct ifnet *ifp; struct mbuf *m; vm_paddr_t phys_addr; uint32_t length; int ctrl; int tx_error; int port; int is_p2p; is_p2p = 0; tx_error = 0; length = (msg->msg0 >> 40) & 0x3fff; na_sc = (struct nlna_softc *)data; if (length == 0) { ctrl = CTRL_REG_FREE; phys_addr = msg->msg0 & 0xffffffffffULL; port = (msg->msg0 >> 54) & 0x0f; is_p2p = (msg->msg0 >> 62) & 0x1; tx_error = (msg->msg0 >> 58) & 0xf; } else { ctrl = CTRL_SNGL; phys_addr = msg->msg0 & 0xffffffffe0ULL; length = length - BYTE_OFFSET - MAC_CRC_LEN; port = msg->msg0 & 0x0f; } sc = na_sc->child_sc[port]; if (sc == NULL) { printf("Message (of %d len) with softc=NULL on %d port (type=%s)\n", length, port, (ctrl == CTRL_SNGL ? "Pkt rx" : "Freeback for tx packet")); return; } if (ctrl == CTRL_REG_FREE || ctrl == CTRL_JUMBO_FREE) { ifp = sc->nlge_if; if (!tx_error) { if (is_p2p) { release_tx_desc(phys_addr); } else { #ifdef __mips_n64 m = (struct mbuf *)(uintptr_t)xlr_paddr_ld(phys_addr); m->m_nextpkt = NULL; #else m = (struct mbuf *)(uintptr_t)phys_addr; #endif m_freem(m); } NLGE_LOCK(sc); if (ifp->if_drv_flags & IFF_DRV_OACTIVE){ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } NLGE_UNLOCK(sc); } else { printf("ERROR: Tx fb error (%d) on port %d\n", tx_error, port); } tx_error ? if_inc_counter(ifp, IFCOUNTER_OERRORS, 1) : if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); } else if (ctrl == CTRL_SNGL || ctrl == CTRL_START) { /* Rx Packet */ nlge_rx(sc, phys_addr, length); nlna_submit_rx_free_desc(na_sc, 1); /* return free descr to NA */ } else { printf("[%s]: unrecognized ctrl=%d!\n", __func__, ctrl); } } static int nlge_tx(struct ifnet *ifp, struct mbuf *m) { return (nlge_start_locked(ifp, ifp->if_softc, m)); } static int nlge_start_locked(struct ifnet *ifp, struct nlge_softc *sc, struct mbuf *m) { struct msgrng_msg msg; struct nlge_tx_desc *tx_desc; uint64_t fr_stid; uint32_t cpu; uint32_t n_entries; uint32_t tid; int error, ret; if (m == NULL) return (0); tx_desc = NULL; error = 0; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || ifp->if_drv_flags & IFF_DRV_OACTIVE) { error = ENXIO; goto fail; // note: mbuf will get free'd } cpu = xlr_core_id(); tid = xlr_thr_id(); /* H/w threads [0, 2] --> bucket 6 and [1, 3] --> bucket 7 */ fr_stid = cpu * 8 + 6 + (tid % 2); /* * First, remove some freeback messages before transmitting * any new packets. However, cap the number of messages * drained to permit this thread to continue with its * transmission. * * Mask for buckets {6, 7} is 0xc0 */ xlr_msgring_handler(0xc0, 4); ret = prepare_fmn_message(sc, &msg, &n_entries, m, fr_stid, &tx_desc); if (ret) { error = (ret == 2) ? ENOBUFS : ENOTSUP; goto fail; } ret = send_fmn_msg_tx(sc, &msg, n_entries); if (ret != 0) { error = EBUSY; goto fail; } return (0); fail: if (tx_desc != NULL) { uma_zfree(nl_tx_desc_zone, tx_desc); } if (m != NULL) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { NLGE_LOCK(sc); ifp->if_drv_flags |= IFF_DRV_OACTIVE; NLGE_UNLOCK(sc); } m_freem(m); if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); } return (error); } static void nlge_rx(struct nlge_softc *sc, vm_paddr_t paddr, int len) { struct ifnet *ifp; struct mbuf *m; uint64_t tm, mag; uint32_t sr; sr = xlr_enable_kx(); tm = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE); mag = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE + sizeof(uint64_t)); xlr_restore_kx(sr); m = (struct mbuf *)(intptr_t)tm; if (mag != 0xf00bad) { /* somebody else's packet. Error - FIXME in intialization */ printf("cpu %d: *ERROR* Not my packet paddr %jx\n", xlr_core_id(), (uintmax_t)paddr); return; } ifp = sc->nlge_if; #ifdef NLGE_HW_CHKSUM m->m_pkthdr.csum_flags = CSUM_IP_CHECKED; if (m->m_data[10] & 0x2) { m->m_pkthdr.csum_flags |= CSUM_IP_VALID; if (m->m_data[10] & 0x1) { m->m_pkthdr.csum_flags |= (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); m->m_pkthdr.csum_data = htons(0xffff); } } m->m_data += NLGE_PREPAD_LEN; len -= NLGE_PREPAD_LEN; #else m->m_pkthdr.csum_flags = 0; #endif /* align the data */ m->m_data += BYTE_OFFSET ; m->m_pkthdr.len = m->m_len = len; m->m_pkthdr.rcvif = ifp; if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); (*ifp->if_input)(ifp, m); } static int nlge_mii_write(struct device *dev, int phyaddr, int regidx, int regval) { struct nlge_softc *sc; sc = device_get_softc(dev); if (sc->port_type != XLR_XGMII) nlge_mii_write_internal(sc->mii_base, phyaddr, regidx, regval); return (0); } static int nlge_mii_read(struct device *dev, int phyaddr, int regidx) { struct nlge_softc *sc; int val; sc = device_get_softc(dev); val = (sc->port_type == XLR_XGMII) ? (0xffff) : nlge_mii_read_internal(sc->mii_base, phyaddr, regidx); return (val); } static void nlge_mac_mii_statchg(device_t dev) { } static int nlge_mediachange(struct ifnet *ifp) { return 0; } static void nlge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) { struct nlge_softc *sc; struct mii_data *md; md = NULL; sc = ifp->if_softc; if (sc->mii_bus) md = device_get_softc(sc->mii_bus); ifmr->ifm_status = IFM_AVALID; ifmr->ifm_active = IFM_ETHER; if (sc->link == xlr_mac_link_down) return; if (md != NULL) ifmr->ifm_active = md->mii_media.ifm_cur->ifm_media; ifmr->ifm_status |= IFM_ACTIVE; } static struct nlna_softc * nlna_sc_init(device_t dev, struct xlr_gmac_block_t *blk) { struct nlna_softc *sc; sc = device_get_softc(dev); memset(sc, 0, sizeof(*sc)); sc->nlna_dev = dev; sc->base = xlr_io_mmio(blk->baseaddr); sc->rfrbucket = blk->station_rfr; sc->station_id = blk->station_id; sc->na_type = blk->type; sc->mac_type = blk->mode; sc->num_ports = blk->num_ports; sc->mdio_set.port_vec = sc->mdio_sc; sc->mdio_set.vec_sz = XLR_MAX_MACS; return (sc); } /* * Do: * - Initialize common GMAC registers (index range 0x100-0x3ff). */ static void nlna_hw_init(struct nlna_softc *sc) { /* * Register message ring handler for the NA block, messages from * the GMAC will have source station id to the first bucket of the * NA FMN station, so register just that station id. */ if (register_msgring_handler(sc->station_id, sc->station_id + 1, nlge_msgring_handler, sc)) { panic("Couldn't register msgring handler\n"); } nlna_config_fifo_spill_area(sc); nlna_config_pde(sc); nlna_config_common(sc); nlna_config_parser(sc); nlna_config_classifier(sc); } /* * Enable interrupts on all the ports controlled by this NA. For now, we * only care about the MII interrupt and this has to be enabled only * on the port id0. * * This function is not in-sync with the regular way of doing things - it * executes only in the context of the last active network accelerator (and * thereby has some ugly accesses in the device tree). Though inelegant, it * is necessary to do it this way as the per-port interrupts can be * setup/enabled only after all the network accelerators have been * initialized. */ static void nlna_setup_intr(struct nlna_softc *sc) { struct nlna_softc *na_sc[XLR_MAX_NLNA]; struct nlge_port_set *pset; struct xlr_gmac_port *port_info; device_t iodi_dev; int i, j; if (!nlna_is_last_active_na(sc)) return ; /* Collect all nlna softc pointers */ memset(na_sc, 0, sizeof(*na_sc) * XLR_MAX_NLNA); iodi_dev = device_get_parent(sc->nlna_dev); nlna_get_all_softc(iodi_dev, na_sc, XLR_MAX_NLNA); /* Setup the MDIO interrupt lists. */ /* * MDIO interrupts are coarse - a single interrupt line provides * information about one of many possible ports. To figure out the * exact port on which action is to be taken, all of the ports * linked to an MDIO interrupt should be read. To enable this, * ports need to add themselves to port sets. */ for (i = 0; i < XLR_MAX_NLNA; i++) { if (na_sc[i] == NULL) continue; for (j = 0; j < na_sc[i]->num_ports; j++) { /* processing j-th port on i-th NA */ port_info = device_get_ivars( na_sc[i]->child_sc[j]->nlge_dev); pset = &na_sc[port_info->mdint_id]->mdio_set; nlna_add_to_port_set(pset, na_sc[i]->child_sc[j]); } } /* Enable interrupts */ for (i = 0; i < XLR_MAX_NLNA; i++) { if (na_sc[i] != NULL && na_sc[i]->na_type != XLR_XGMAC) { nlna_enable_intr(na_sc[i]); } } } static void nlna_add_to_port_set(struct nlge_port_set *pset, struct nlge_softc *sc) { int i; /* step past the non-NULL elements */ for (i = 0; i < pset->vec_sz && pset->port_vec[i] != NULL; i++) ; if (i < pset->vec_sz) pset->port_vec[i] = sc; else printf("warning: internal error: out-of-bounds for MDIO array"); } static void nlna_enable_intr(struct nlna_softc *sc) { int i; for (i = 0; i < sc->num_ports; i++) { if (sc->child_sc[i]->instance == 0) NLGE_WRITE(sc->child_sc[i]->base, R_INTMASK, (1 << O_INTMASK__MDInt)); } } static void nlna_disable_intr(struct nlna_softc *sc) { int i; for (i = 0; i < sc->num_ports; i++) { if (sc->child_sc[i]->instance == 0) NLGE_WRITE(sc->child_sc[i]->base, R_INTMASK, 0); } } static int nlna_is_last_active_na(struct nlna_softc *sc) { int id; id = device_get_unit(sc->nlna_dev); return (id == 2 || xlr_board_info.gmac_block[id + 1].enabled == 0); } static void nlna_submit_rx_free_desc(struct nlna_softc *sc, uint32_t n_desc) { struct msgrng_msg msg; void *ptr; uint32_t msgrng_flags; int i, n, stid, ret, code; if (n_desc > 1) { PDEBUG("Sending %d free-in descriptors to station=%d\n", n_desc, sc->rfrbucket); } stid = sc->rfrbucket; code = (sc->na_type == XLR_XGMAC) ? MSGRNG_CODE_XGMAC : MSGRNG_CODE_MAC; memset(&msg, 0, sizeof(msg)); for (i = 0; i < n_desc; i++) { ptr = get_buf(); if (!ptr) { ret = -ENOMEM; device_printf(sc->nlna_dev, "Cannot allocate mbuf\n"); break; } /* Send the free Rx desc to the MAC */ msg.msg0 = vtophys(ptr) & 0xffffffffe0ULL; n = 0; do { msgrng_flags = msgrng_access_enable(); ret = message_send(1, code, stid, &msg); msgrng_restore(msgrng_flags); KASSERT(n++ < 100000, ("Too many credit fails in rx path\n")); } while (ret != 0); } } static __inline__ void * nlna_config_spill(xlr_reg_t *base, int reg_start_0, int reg_start_1, int reg_size, int size) { void *spill; uint64_t phys_addr; uint32_t spill_size; spill_size = size; spill = contigmalloc((spill_size + XLR_CACHELINE_SIZE), M_DEVBUF, M_NOWAIT | M_ZERO, 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); if (spill == NULL || ((vm_offset_t) spill & (XLR_CACHELINE_SIZE - 1))) { panic("Unable to allocate memory for spill area!\n"); } phys_addr = vtophys(spill); PDEBUG("Allocated spill %d bytes at %llx\n", size, phys_addr); NLGE_WRITE(base, reg_start_0, (phys_addr >> 5) & 0xffffffff); NLGE_WRITE(base, reg_start_1, (phys_addr >> 37) & 0x07); NLGE_WRITE(base, reg_size, spill_size); return (spill); } /* * Configure the 6 FIFO's that are used by the network accelarator to * communicate with the rest of the XLx device. 4 of the FIFO's are for * packets from NA --> cpu (called Class FIFO's) and 2 are for feeding * the NA with free descriptors. */ static void nlna_config_fifo_spill_area(struct nlna_softc *sc) { sc->frin_spill = nlna_config_spill(sc->base, R_REG_FRIN_SPILL_MEM_START_0, R_REG_FRIN_SPILL_MEM_START_1, R_REG_FRIN_SPILL_MEM_SIZE, MAX_FRIN_SPILL * sizeof(struct fr_desc)); sc->frout_spill = nlna_config_spill(sc->base, R_FROUT_SPILL_MEM_START_0, R_FROUT_SPILL_MEM_START_1, R_FROUT_SPILL_MEM_SIZE, MAX_FROUT_SPILL * sizeof(struct fr_desc)); sc->class_0_spill = nlna_config_spill(sc->base, R_CLASS0_SPILL_MEM_START_0, R_CLASS0_SPILL_MEM_START_1, R_CLASS0_SPILL_MEM_SIZE, MAX_CLASS_0_SPILL * sizeof(union rx_tx_desc)); sc->class_1_spill = nlna_config_spill(sc->base, R_CLASS1_SPILL_MEM_START_0, R_CLASS1_SPILL_MEM_START_1, R_CLASS1_SPILL_MEM_SIZE, MAX_CLASS_1_SPILL * sizeof(union rx_tx_desc)); sc->class_2_spill = nlna_config_spill(sc->base, R_CLASS2_SPILL_MEM_START_0, R_CLASS2_SPILL_MEM_START_1, R_CLASS2_SPILL_MEM_SIZE, MAX_CLASS_2_SPILL * sizeof(union rx_tx_desc)); sc->class_3_spill = nlna_config_spill(sc->base, R_CLASS3_SPILL_MEM_START_0, R_CLASS3_SPILL_MEM_START_1, R_CLASS3_SPILL_MEM_SIZE, MAX_CLASS_3_SPILL * sizeof(union rx_tx_desc)); } /* Set the CPU buckets that receive packets from the NA class FIFOs. */ static void nlna_config_pde(struct nlna_softc *sc) { uint64_t bucket_map; uint32_t cpumask; int i, cpu, bucket; cpumask = 0x1; #ifdef SMP /* - * rge may be called before SMP start in a BOOTP/NFSROOT + * nlna may be called before SMP start in a BOOTP/NFSROOT * setup. we will distribute packets to other cpus only when * the SMP is started. */ if (smp_started) cpumask = xlr_hw_thread_mask; #endif bucket_map = 0; for (i = 0; i < 32; i++) { if (cpumask & (1 << i)) { cpu = i; /* use bucket 0 and 1 on every core for NA msgs */ bucket = cpu/4 * 8; bucket_map |= (3ULL << bucket); } } NLGE_WRITE(sc->base, R_PDE_CLASS_0, (bucket_map & 0xffffffff)); NLGE_WRITE(sc->base, R_PDE_CLASS_0 + 1, ((bucket_map >> 32) & 0xffffffff)); NLGE_WRITE(sc->base, R_PDE_CLASS_1, (bucket_map & 0xffffffff)); NLGE_WRITE(sc->base, R_PDE_CLASS_1 + 1, ((bucket_map >> 32) & 0xffffffff)); NLGE_WRITE(sc->base, R_PDE_CLASS_2, (bucket_map & 0xffffffff)); NLGE_WRITE(sc->base, R_PDE_CLASS_2 + 1, ((bucket_map >> 32) & 0xffffffff)); NLGE_WRITE(sc->base, R_PDE_CLASS_3, (bucket_map & 0xffffffff)); NLGE_WRITE(sc->base, R_PDE_CLASS_3 + 1, ((bucket_map >> 32) & 0xffffffff)); } /* * Update the network accelerator packet distribution engine for SMP. * On bootup, we have just the boot hw thread handling all packets, on SMP * start, we can start distributing packets across all the cores which are up. */ static void nlna_smp_update_pde(void *dummy __unused) { device_t iodi_dev; struct nlna_softc *na_sc[XLR_MAX_NLNA]; int i; printf("Updating packet distribution for SMP\n"); iodi_dev = devclass_get_device(devclass_find("iodi"), 0); nlna_get_all_softc(iodi_dev, na_sc, XLR_MAX_NLNA); for (i = 0; i < XLR_MAX_NLNA; i++) { if (na_sc[i] == NULL) continue; nlna_disable_ports(na_sc[i]); nlna_config_pde(na_sc[i]); nlna_config_translate_table(na_sc[i]); nlna_enable_ports(na_sc[i]); } } SYSINIT(nlna_smp_update_pde, SI_SUB_SMP, SI_ORDER_ANY, nlna_smp_update_pde, NULL); static void nlna_config_translate_table(struct nlna_softc *sc) { uint32_t cpu_mask; uint32_t val; int bkts[32]; /* one bucket is assumed for each cpu */ int b1, b2, c1, c2, i, j, k; int use_bkt; if (!flow_classification) return; use_bkt = 1; if (smp_started) cpu_mask = xlr_hw_thread_mask; else return; printf("Using %s-based distribution\n", (use_bkt) ? "bucket" : "class"); j = 0; for(i = 0; i < 32; i++) { if ((1 << i) & cpu_mask){ /* for each cpu, mark the 4+threadid bucket */ bkts[j] = ((i / 4) * 8) + (i % 4); j++; } } /*configure the 128 * 9 Translation table to send to available buckets*/ k = 0; c1 = 3; c2 = 0; for(i = 0; i < 64; i++) { /* Get the next 2 pairs of (class, bucket): (c1, b1), (c2, b2). c1, c2 limited to {0, 1, 2, 3} i.e, the 4 classes defined by h/w b1, b2 limited to { bkts[i], where 0 <= i < j} i.e, the set of buckets computed in the above loop. */ c1 = (c1 + 1) & 3; c2 = (c1 + 1) & 3; b1 = bkts[k]; k = (k + 1) % j; b2 = bkts[k]; k = (k + 1) % j; PDEBUG("Translation table[%d] b1=%d b2=%d c1=%d c2=%d\n", i, b1, b2, c1, c2); val = ((c1 << 23) | (b1 << 17) | (use_bkt << 16) | (c2 << 7) | (b2 << 1) | (use_bkt << 0)); NLGE_WRITE(sc->base, R_TRANSLATETABLE + i, val); c1 = c2; } } static void nlna_config_parser(struct nlna_softc *sc) { uint32_t val; /* * Mark it as ETHERNET type. */ NLGE_WRITE(sc->base, R_L2TYPE_0, 0x01); #ifndef NLGE_HW_CHKSUM if (!flow_classification) return; #endif /* Use 7bit CRChash for flow classification with 127 as CRC polynomial*/ NLGE_WRITE(sc->base, R_PARSERCONFIGREG, ((0x7f << 8) | (1 << 1))); /* configure the parser : L2 Type is configured in the bootloader */ /* extract IP: src, dest protocol */ NLGE_WRITE(sc->base, R_L3CTABLE, (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) | (0x0800 << 0)); NLGE_WRITE(sc->base, R_L3CTABLE + 1, (9 << 25) | (1 << 21) | (12 << 14) | (4 << 10) | (16 << 4) | 4); #ifdef NLGE_HW_CHKSUM device_printf(sc->nlna_dev, "Enabled h/w support to compute TCP/IP" " checksum\n"); #endif /* Configure to extract SRC port and Dest port for TCP and UDP pkts */ NLGE_WRITE(sc->base, R_L4CTABLE, 6); NLGE_WRITE(sc->base, R_L4CTABLE + 2, 17); val = ((0 << 21) | (2 << 17) | (2 << 11) | (2 << 7)); NLGE_WRITE(sc->base, R_L4CTABLE + 1, val); NLGE_WRITE(sc->base, R_L4CTABLE + 3, val); } static void nlna_config_classifier(struct nlna_softc *sc) { int i; if (sc->mac_type == XLR_XGMII) { /* TBD: XGMII init sequence */ /* xgmac translation table doesn't have sane values on reset */ for (i = 0; i < 64; i++) NLGE_WRITE(sc->base, R_TRANSLATETABLE + i, 0x0); /* * use upper 7 bits of the parser extract to index the * translate table */ NLGE_WRITE(sc->base, R_PARSERCONFIGREG, 0x0); } } /* * Complete a bunch of h/w register initializations that are common for all the * ports controlled by a NA. */ static void nlna_config_common(struct nlna_softc *sc) { struct xlr_gmac_block_t *block_info; struct stn_cc *gmac_cc_config; int i; block_info = device_get_ivars(sc->nlna_dev); gmac_cc_config = block_info->credit_config; for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { NLGE_WRITE(sc->base, R_CC_CPU0_0 + i, gmac_cc_config->counters[i >> 3][i & 0x07]); } NLGE_WRITE(sc->base, R_MSG_TX_THRESHOLD, 3); NLGE_WRITE(sc->base, R_DMACR0, 0xffffffff); NLGE_WRITE(sc->base, R_DMACR1, 0xffffffff); NLGE_WRITE(sc->base, R_DMACR2, 0xffffffff); NLGE_WRITE(sc->base, R_DMACR3, 0xffffffff); NLGE_WRITE(sc->base, R_FREEQCARVE, 0); nlna_media_specific_config(sc); } static void nlna_media_specific_config(struct nlna_softc *sc) { struct bucket_size *bucket_sizes; bucket_sizes = xlr_board_info.bucket_sizes; switch (sc->mac_type) { case XLR_RGMII: case XLR_SGMII: case XLR_XAUI: NLGE_WRITE(sc->base, R_GMAC_JFR0_BUCKET_SIZE, bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_0]); NLGE_WRITE(sc->base, R_GMAC_RFR0_BUCKET_SIZE, bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_0]); NLGE_WRITE(sc->base, R_GMAC_JFR1_BUCKET_SIZE, bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_1]); NLGE_WRITE(sc->base, R_GMAC_RFR1_BUCKET_SIZE, bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_1]); if (sc->mac_type == XLR_XAUI) { NLGE_WRITE(sc->base, R_TXDATAFIFO0, (224 << 16)); } break; case XLR_XGMII: NLGE_WRITE(sc->base, R_XGS_RFR_BUCKET_SIZE, bucket_sizes->bucket[sc->rfrbucket]); default: break; } } static void nlna_reset_ports(struct nlna_softc *sc, struct xlr_gmac_block_t *blk) { xlr_reg_t *addr; int i; uint32_t rx_ctrl; /* Refer Section 13.9.3 in the PRM for the reset sequence */ for (i = 0; i < sc->num_ports; i++) { addr = xlr_io_mmio(blk->gmac_port[i].base_addr); /* 1. Reset RxEnable in MAC_CONFIG */ switch (sc->mac_type) { case XLR_RGMII: case XLR_SGMII: NLGE_UPDATE(addr, R_MAC_CONFIG_1, 0, (1 << O_MAC_CONFIG_1__rxen)); break; case XLR_XAUI: case XLR_XGMII: NLGE_UPDATE(addr, R_RX_CONTROL, 0, (1 << O_RX_CONTROL__RxEnable)); break; default: printf("Error: Unsupported port_type=%d\n", sc->mac_type); } /* 1.1 Wait for RxControl.RxHalt to be set */ do { rx_ctrl = NLGE_READ(addr, R_RX_CONTROL); } while (!(rx_ctrl & 0x2)); /* 2. Set the soft reset bit in RxControl */ NLGE_UPDATE(addr, R_RX_CONTROL, (1 << O_RX_CONTROL__SoftReset), (1 << O_RX_CONTROL__SoftReset)); /* 2.1 Wait for RxControl.SoftResetDone to be set */ do { rx_ctrl = NLGE_READ(addr, R_RX_CONTROL); } while (!(rx_ctrl & 0x8)); /* 3. Clear the soft reset bit in RxControl */ NLGE_UPDATE(addr, R_RX_CONTROL, 0, (1 << O_RX_CONTROL__SoftReset)); /* Turn off tx/rx on the port. */ NLGE_UPDATE(addr, R_RX_CONTROL, 0, (1 << O_RX_CONTROL__RxEnable)); NLGE_UPDATE(addr, R_TX_CONTROL, 0, (1 << O_TX_CONTROL__TxEnable)); } } static void nlna_disable_ports(struct nlna_softc *sc) { int i; for (i = 0; i < sc->num_ports; i++) { if (sc->child_sc[i] != NULL) nlge_port_disable(sc->child_sc[i]); } } static void nlna_enable_ports(struct nlna_softc *sc) { device_t nlge_dev, *devlist; struct nlge_softc *port_sc; int i, numdevs; device_get_children(sc->nlna_dev, &devlist, &numdevs); for (i = 0; i < numdevs; i++) { nlge_dev = devlist[i]; if (nlge_dev == NULL) continue; port_sc = device_get_softc(nlge_dev); if (port_sc->nlge_if->if_drv_flags & IFF_DRV_RUNNING) nlge_port_enable(port_sc); } free(devlist, M_TEMP); } static void nlna_get_all_softc(device_t iodi_dev, struct nlna_softc **sc_vec, uint32_t vec_sz) { device_t na_dev; int i; for (i = 0; i < vec_sz; i++) { sc_vec[i] = NULL; na_dev = device_find_child(iodi_dev, "nlna", i); if (na_dev != NULL) sc_vec[i] = device_get_softc(na_dev); } } static void nlge_port_disable(struct nlge_softc *sc) { struct ifnet *ifp; xlr_reg_t *base; uint32_t rd; int id, port_type; id = sc->id; port_type = sc->port_type; base = sc->base; ifp = sc->nlge_if; NLGE_UPDATE(base, R_RX_CONTROL, 0x0, 1 << O_RX_CONTROL__RxEnable); do { rd = NLGE_READ(base, R_RX_CONTROL); } while (!(rd & (1 << O_RX_CONTROL__RxHalt))); NLGE_UPDATE(base, R_TX_CONTROL, 0, 1 << O_TX_CONTROL__TxEnable); do { rd = NLGE_READ(base, R_TX_CONTROL); } while (!(rd & (1 << O_TX_CONTROL__TxIdle))); switch (port_type) { case XLR_RGMII: case XLR_SGMII: NLGE_UPDATE(base, R_MAC_CONFIG_1, 0, ((1 << O_MAC_CONFIG_1__rxen) | (1 << O_MAC_CONFIG_1__txen))); break; case XLR_XGMII: case XLR_XAUI: NLGE_UPDATE(base, R_XGMAC_CONFIG_1, 0, ((1 << O_XGMAC_CONFIG_1__hsttfen) | (1 << O_XGMAC_CONFIG_1__hstrfen))); break; default: panic("Unknown MAC type on port %d\n", id); } if (ifp) { ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); } } static void nlge_port_enable(struct nlge_softc *sc) { struct xlr_gmac_port *self; xlr_reg_t *base; base = sc->base; self = device_get_ivars(sc->nlge_dev); if (xlr_board_info.is_xls && sc->port_type == XLR_RGMII) NLGE_UPDATE(base, R_RX_CONTROL, (1 << O_RX_CONTROL__RGMII), (1 << O_RX_CONTROL__RGMII)); NLGE_UPDATE(base, R_RX_CONTROL, (1 << O_RX_CONTROL__RxEnable), (1 << O_RX_CONTROL__RxEnable)); NLGE_UPDATE(base, R_TX_CONTROL, (1 << O_TX_CONTROL__TxEnable | RGE_TX_THRESHOLD_BYTES), (1 << O_TX_CONTROL__TxEnable | 0x3fff)); switch (sc->port_type) { case XLR_RGMII: case XLR_SGMII: NLGE_UPDATE(base, R_MAC_CONFIG_1, ((1 << O_MAC_CONFIG_1__rxen) | (1 << O_MAC_CONFIG_1__txen)), ((1 << O_MAC_CONFIG_1__rxen) | (1 << O_MAC_CONFIG_1__txen))); break; case XLR_XGMII: case XLR_XAUI: NLGE_UPDATE(base, R_XGMAC_CONFIG_1, ((1 << O_XGMAC_CONFIG_1__hsttfen) | (1 << O_XGMAC_CONFIG_1__hstrfen)), ((1 << O_XGMAC_CONFIG_1__hsttfen) | (1 << O_XGMAC_CONFIG_1__hstrfen))); break; default: panic("Unknown MAC type on port %d\n", sc->id); } } static void nlge_mac_set_rx_mode(struct nlge_softc *sc) { uint32_t regval; regval = NLGE_READ(sc->base, R_MAC_FILTER_CONFIG); if (sc->if_flags & IFF_PROMISC) { regval |= (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | (1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN); } else { regval &= ~((1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN)); } NLGE_WRITE(sc->base, R_MAC_FILTER_CONFIG, regval); } static void nlge_sgmii_init(struct nlge_softc *sc) { xlr_reg_t *mmio_gpio; int phy; if (sc->port_type != XLR_SGMII) return; nlge_mii_write_internal(sc->serdes_addr, 26, 0, 0x6DB0); nlge_mii_write_internal(sc->serdes_addr, 26, 1, 0xFFFF); nlge_mii_write_internal(sc->serdes_addr, 26, 2, 0xB6D0); nlge_mii_write_internal(sc->serdes_addr, 26, 3, 0x00FF); nlge_mii_write_internal(sc->serdes_addr, 26, 4, 0x0000); nlge_mii_write_internal(sc->serdes_addr, 26, 5, 0x0000); nlge_mii_write_internal(sc->serdes_addr, 26, 6, 0x0005); nlge_mii_write_internal(sc->serdes_addr, 26, 7, 0x0001); nlge_mii_write_internal(sc->serdes_addr, 26, 8, 0x0000); nlge_mii_write_internal(sc->serdes_addr, 26, 9, 0x0000); nlge_mii_write_internal(sc->serdes_addr, 26,10, 0x0000); /* program GPIO values for serdes init parameters */ DELAY(100); mmio_gpio = xlr_io_mmio(XLR_IO_GPIO_OFFSET); xlr_write_reg(mmio_gpio, 0x20, 0x7e6802); xlr_write_reg(mmio_gpio, 0x10, 0x7104); DELAY(100); /* * This kludge is needed to setup serdes (?) clock correctly on some * XLS boards */ if ((xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_XI || xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_XII) && xlr_boot1_info.board_minor_version == 4) { /* use 125 Mhz instead of 156.25Mhz ref clock */ DELAY(100); xlr_write_reg(mmio_gpio, 0x10, 0x7103); xlr_write_reg(mmio_gpio, 0x21, 0x7103); DELAY(100); } /* enable autoneg - more magic */ phy = sc->phy_addr % 4 + 27; nlge_mii_write_internal(sc->pcs_addr, phy, 0, 0x1000); DELAY(100000); nlge_mii_write_internal(sc->pcs_addr, phy, 0, 0x0200); DELAY(100000); } static void nlge_intr(void *arg) { struct nlge_port_set *pset; struct nlge_softc *sc; struct nlge_softc *port_sc; xlr_reg_t *base; uint32_t intreg; uint32_t intr_status; int i; sc = arg; if (sc == NULL) { printf("warning: No port registered for interrupt\n"); return; } base = sc->base; intreg = NLGE_READ(base, R_INTREG); if (intreg & (1 << O_INTREG__MDInt)) { pset = sc->mdio_pset; if (pset == NULL) { printf("warning: No ports for MDIO interrupt\n"); return; } for (i = 0; i < pset->vec_sz; i++) { port_sc = pset->port_vec[i]; if (port_sc == NULL) continue; /* Ack phy interrupt - clear on read*/ intr_status = nlge_mii_read_internal(port_sc->mii_base, port_sc->phy_addr, 26); PDEBUG("Phy_%d: int_status=0x%08x\n", port_sc->phy_addr, intr_status); if (!(intr_status & 0x8000)) { /* no interrupt for this port */ continue; } if (intr_status & 0x2410) { /* update link status for port */ nlge_gmac_config_speed(port_sc, 1); } else { printf("%s: Unsupported phy interrupt" " (0x%08x)\n", device_get_nameunit(port_sc->nlge_dev), intr_status); } } } /* Clear the NA interrupt */ xlr_write_reg(base, R_INTREG, 0xffffffff); return; } static int nlge_irq_init(struct nlge_softc *sc) { struct resource irq_res; struct nlna_softc *na_sc; struct xlr_gmac_block_t *block_info; device_t na_dev; int ret; int irq_num; na_dev = device_get_parent(sc->nlge_dev); block_info = device_get_ivars(na_dev); irq_num = block_info->baseirq + sc->instance; irq_res.__r_i = (struct resource_i *)(intptr_t) (irq_num); ret = bus_setup_intr(sc->nlge_dev, &irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, nlge_intr, sc, NULL); if (ret) { nlge_detach(sc->nlge_dev); device_printf(sc->nlge_dev, "couldn't set up irq: error=%d\n", ret); return (ENXIO); } PDEBUG("Setup intr for dev=%s, irq=%d\n", device_get_nameunit(sc->nlge_dev), irq_num); if (sc->instance == 0) { na_sc = device_get_softc(na_dev); sc->mdio_pset = &na_sc->mdio_set; } return (0); } static void nlge_irq_fini(struct nlge_softc *sc) { } static void nlge_hw_init(struct nlge_softc *sc) { struct xlr_gmac_port *port_info; xlr_reg_t *base; base = sc->base; port_info = device_get_ivars(sc->nlge_dev); sc->tx_bucket_id = port_info->tx_bucket_id; /* each packet buffer is 1536 bytes */ NLGE_WRITE(base, R_DESC_PACK_CTRL, (1 << O_DESC_PACK_CTRL__MaxEntry) | #ifdef NLGE_HW_CHKSUM (1 << O_DESC_PACK_CTRL__PrePadEnable) | #endif (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize)); NLGE_WRITE(base, R_STATCTRL, ((1 << O_STATCTRL__Sten) | (1 << O_STATCTRL__ClrCnt))); NLGE_WRITE(base, R_L2ALLOCCTRL, 0xffffffff); NLGE_WRITE(base, R_INTMASK, 0); nlge_set_mac_addr(sc); nlge_media_specific_init(sc); } static void nlge_sc_init(struct nlge_softc *sc, device_t dev, struct xlr_gmac_port *port_info) { memset(sc, 0, sizeof(*sc)); sc->nlge_dev = dev; sc->id = device_get_unit(dev); nlge_set_port_attribs(sc, port_info); } static void nlge_media_specific_init(struct nlge_softc *sc) { struct mii_data *media; struct bucket_size *bucket_sizes; bucket_sizes = xlr_board_info.bucket_sizes; switch (sc->port_type) { case XLR_RGMII: case XLR_SGMII: case XLR_XAUI: NLGE_UPDATE(sc->base, R_DESC_PACK_CTRL, (BYTE_OFFSET << O_DESC_PACK_CTRL__ByteOffset), (W_DESC_PACK_CTRL__ByteOffset << O_DESC_PACK_CTRL__ByteOffset)); NLGE_WRITE(sc->base, R_GMAC_TX0_BUCKET_SIZE + sc->instance, bucket_sizes->bucket[sc->tx_bucket_id]); if (sc->port_type != XLR_XAUI) { nlge_gmac_config_speed(sc, 1); if (sc->mii_bus) { media = (struct mii_data *)device_get_softc( sc->mii_bus); } } break; case XLR_XGMII: NLGE_WRITE(sc->base, R_BYTEOFFSET0, 0x2); NLGE_WRITE(sc->base, R_XGMACPADCALIBRATION, 0x30); NLGE_WRITE(sc->base, R_XGS_TX0_BUCKET_SIZE, bucket_sizes->bucket[sc->tx_bucket_id]); break; default: break; } } /* * Read the MAC address from the XLR boot registers. All port addresses * are identical except for the lowest octet. */ static void nlge_read_mac_addr(struct nlge_softc *sc) { int i, j; for (i = 0, j = 40; i < ETHER_ADDR_LEN && j >= 0; i++, j-= 8) sc->dev_addr[i] = (xlr_boot1_info.mac_addr >> j) & 0xff; sc->dev_addr[i - 1] += sc->id; /* last octet is port-specific */ } /* * Write the MAC address to the XLR MAC port. Also, set the address * masks and MAC filter configuration. */ static void nlge_set_mac_addr(struct nlge_softc *sc) { NLGE_WRITE(sc->base, R_MAC_ADDR0, ((sc->dev_addr[5] << 24) | (sc->dev_addr[4] << 16) | (sc->dev_addr[3] << 8) | (sc->dev_addr[2]))); NLGE_WRITE(sc->base, R_MAC_ADDR0 + 1, ((sc->dev_addr[1] << 24) | (sc-> dev_addr[0] << 16))); NLGE_WRITE(sc->base, R_MAC_ADDR_MASK2, 0xffffffff); NLGE_WRITE(sc->base, R_MAC_ADDR_MASK2 + 1, 0xffffffff); NLGE_WRITE(sc->base, R_MAC_ADDR_MASK3, 0xffffffff); NLGE_WRITE(sc->base, R_MAC_ADDR_MASK3 + 1, 0xffffffff); NLGE_WRITE(sc->base, R_MAC_FILTER_CONFIG, (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID)); if (sc->port_type == XLR_RGMII || sc->port_type == XLR_SGMII) { NLGE_UPDATE(sc->base, R_IPG_IFG, MAC_B2B_IPG, 0x7f); } } static int nlge_if_init(struct nlge_softc *sc) { struct ifnet *ifp; device_t dev; int error; error = 0; dev = sc->nlge_dev; NLGE_LOCK_INIT(sc, device_get_nameunit(dev)); ifp = sc->nlge_if = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); error = ENOSPC; goto fail; } ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_capabilities = 0; ifp->if_capenable = ifp->if_capabilities; ifp->if_ioctl = nlge_ioctl; ifp->if_init = nlge_init; ifp->if_hwassist = 0; ifp->if_snd.ifq_drv_maxlen = RGE_TX_Q_SIZE; IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); IFQ_SET_READY(&ifp->if_snd); ifmedia_init(&sc->nlge_mii.mii_media, 0, nlge_mediachange, nlge_mediastatus); ifmedia_add(&sc->nlge_mii.mii_media, IFM_ETHER | IFM_AUTO, 0, NULL); ifmedia_set(&sc->nlge_mii.mii_media, IFM_ETHER | IFM_AUTO); sc->nlge_mii.mii_media.ifm_media = sc->nlge_mii.mii_media.ifm_cur->ifm_media; nlge_read_mac_addr(sc); ether_ifattach(ifp, sc->dev_addr); /* override if_transmit : per ifnet(9), do it after if_attach */ ifp->if_transmit = nlge_tx; fail: return (error); } static void nlge_mii_init(device_t dev, struct nlge_softc *sc) { int error; if (sc->port_type != XLR_XAUI && sc->port_type != XLR_XGMII) { NLGE_WRITE(sc->mii_base, R_MII_MGMT_CONFIG, 0x07); } error = mii_attach(dev, &sc->mii_bus, sc->nlge_if, nlge_mediachange, nlge_mediastatus, BMSR_DEFCAPMASK, sc->phy_addr, MII_OFFSET_ANY, 0); if (error) { device_printf(dev, "attaching PHYs failed\n"); sc->mii_bus = NULL; } if (sc->mii_bus != NULL) { /* * Enable all MDIO interrupts in the phy. RX_ER bit seems to get * set about every 1 sec in GigE mode, ignore it for now... */ nlge_mii_write_internal(sc->mii_base, sc->phy_addr, 25, 0xfffffffe); } } /* * Read a PHY register. * * Input parameters: * mii_base - Base address of MII * phyaddr - PHY's address * regidx = index of register to read * * Return value: * value read, or 0 if an error occurred. */ static int nlge_mii_read_internal(xlr_reg_t *mii_base, int phyaddr, int regidx) { int i, val; /* setup the phy reg to be used */ NLGE_WRITE(mii_base, R_MII_MGMT_ADDRESS, (phyaddr << 8) | (regidx << 0)); /* Issue the read command */ NLGE_WRITE(mii_base, R_MII_MGMT_COMMAND, (1 << O_MII_MGMT_COMMAND__rstat)); /* poll for the read cycle to complete */ for (i = 0; i < PHY_STATUS_RETRIES; i++) { if (NLGE_READ(mii_base, R_MII_MGMT_INDICATORS) == 0) break; } /* clear the read cycle */ NLGE_WRITE(mii_base, R_MII_MGMT_COMMAND, 0); if (i == PHY_STATUS_RETRIES) { return (0xffffffff); } val = NLGE_READ(mii_base, R_MII_MGMT_STATUS); return (val); } /* * Write a value to a PHY register. * * Input parameters: * mii_base - Base address of MII * phyaddr - PHY to use * regidx - register within the PHY * regval - data to write to register * * Return value: * nothing */ static void nlge_mii_write_internal(xlr_reg_t *mii_base, int phyaddr, int regidx, int regval) { int i; NLGE_WRITE(mii_base, R_MII_MGMT_ADDRESS, (phyaddr << 8) | (regidx << 0)); /* Write the data which starts the write cycle */ NLGE_WRITE(mii_base, R_MII_MGMT_WRITE_DATA, regval); /* poll for the write cycle to complete */ for (i = 0; i < PHY_STATUS_RETRIES; i++) { if (NLGE_READ(mii_base, R_MII_MGMT_INDICATORS) == 0) break; } } /* * Function to optimize the use of p2d descriptors for the given PDU. * As it is on the fast-path (called during packet transmission), it * described in more detail than the initialization functions. * * Input: mbuf chain (MC), pointer to fmn message * Input constraints: None * Output: FMN message to transmit the data in MC * Return values: 0 - success * 1 - MC cannot be handled (see Limitations below) * 2 - MC cannot be handled presently (maybe worth re-trying) * Other output: Number of entries filled in the FMN message * * Output structure/constraints: * 1. Max 3 p2d's + 1 zero-len (ZL) p2d with virtual address of MC. * 2. 3 p2d's + 1 p2p with max 14 p2d's (ZL p2d not required in this case). * 3. Each p2d points to physically contiguous chunk of data (subject to * entire MC requiring max 17 p2d's). * Limitations: * 1. MC's that require more than 17 p2d's are not handled. * Benefits: MC's that require <= 3 p2d's avoid the overhead of allocating * the p2p structure. Small packets (which typically give low * performance) are expected to have a small MC that takes * advantage of this. */ static int prepare_fmn_message(struct nlge_softc *sc, struct msgrng_msg *fmn_msg, uint32_t *n_entries, struct mbuf *mbuf_chain, uint64_t fb_stn_id, struct nlge_tx_desc **tx_desc) { struct mbuf *m; struct nlge_tx_desc *p2p; uint64_t *cur_p2d; uint64_t fbpaddr; vm_offset_t buf; vm_paddr_t paddr; int msg_sz, p2p_sz, len, frag_sz; /* Num entries per FMN msg is 4 for XLR/XLS */ const int FMN_SZ = sizeof(*fmn_msg) / sizeof(uint64_t); msg_sz = p2p_sz = 0; p2p = NULL; cur_p2d = &fmn_msg->msg0; for (m = mbuf_chain; m != NULL; m = m->m_next) { buf = (vm_offset_t) m->m_data; len = m->m_len; while (len) { if (msg_sz == (FMN_SZ - 1)) { p2p = uma_zalloc(nl_tx_desc_zone, M_NOWAIT); if (p2p == NULL) { return (2); } /* * Save the virtual address in the descriptor, * it makes freeing easy. */ p2p->frag[XLR_MAX_TX_FRAGS] = (uint64_t)(vm_offset_t)p2p; cur_p2d = &p2p->frag[0]; } else if (msg_sz == (FMN_SZ - 2 + XLR_MAX_TX_FRAGS)) { uma_zfree(nl_tx_desc_zone, p2p); return (1); } paddr = vtophys(buf); frag_sz = PAGE_SIZE - (buf & PAGE_MASK); if (len < frag_sz) frag_sz = len; *cur_p2d++ = (127ULL << 54) | ((uint64_t)frag_sz << 40) | paddr; msg_sz++; if (p2p != NULL) p2p_sz++; len -= frag_sz; buf += frag_sz; } } if (msg_sz == 0) { printf("Zero-length mbuf chain ??\n"); *n_entries = msg_sz ; return (0); } /* set eop in most-recent p2d */ cur_p2d[-1] |= (1ULL << 63); #ifdef __mips_n64 /* * On n64, we cannot store our mbuf pointer(64 bit) in the freeback * message (40bit available), so we put the mbuf in m_nextpkt and * use the physical addr of that in freeback message. */ mbuf_chain->m_nextpkt = mbuf_chain; fbpaddr = vtophys(&mbuf_chain->m_nextpkt); #else /* Careful, don't sign extend when going to 64bit */ fbpaddr = (uint64_t)(uintptr_t)mbuf_chain; #endif *cur_p2d = (1ULL << 63) | ((uint64_t)fb_stn_id << 54) | fbpaddr; *tx_desc = p2p; if (p2p != NULL) { paddr = vtophys(p2p); p2p_sz++; fmn_msg->msg3 = (1ULL << 62) | ((uint64_t)fb_stn_id << 54) | ((uint64_t)(p2p_sz * 8) << 40) | paddr; *n_entries = FMN_SZ; } else { *n_entries = msg_sz + 1; } return (0); } static int send_fmn_msg_tx(struct nlge_softc *sc, struct msgrng_msg *msg, uint32_t n_entries) { uint32_t msgrng_flags; int ret; int i = 0; do { msgrng_flags = msgrng_access_enable(); ret = message_send(n_entries, MSGRNG_CODE_MAC, sc->tx_bucket_id, msg); msgrng_restore(msgrng_flags); if (ret == 0) return (0); i++; } while (i < 100000); device_printf(sc->nlge_dev, "Too many credit fails in tx path\n"); return (1); } static void release_tx_desc(vm_paddr_t paddr) { struct nlge_tx_desc *tx_desc; uint32_t sr; uint64_t vaddr; paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t)); sr = xlr_enable_kx(); vaddr = xlr_paddr_ld(paddr); xlr_restore_kx(sr); tx_desc = (struct nlge_tx_desc*)(intptr_t)vaddr; uma_zfree(nl_tx_desc_zone, tx_desc); } static void * get_buf(void) { struct mbuf *m_new; uint64_t *md; #ifdef INVARIANTS vm_paddr_t temp1, temp2; #endif if ((m_new = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR)) == NULL) return (NULL); m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; m_adj(m_new, XLR_CACHELINE_SIZE - ((uintptr_t)m_new->m_data & 0x1f)); md = (uint64_t *)m_new->m_data; md[0] = (intptr_t)m_new; /* Back Ptr */ md[1] = 0xf00bad; m_adj(m_new, XLR_CACHELINE_SIZE); #ifdef INVARIANTS temp1 = vtophys((vm_offset_t) m_new->m_data); temp2 = vtophys((vm_offset_t) m_new->m_data + 1536); if ((temp1 + 1536) != temp2) panic("ALLOCED BUFFER IS NOT CONTIGUOUS\n"); #endif return ((void *)m_new->m_data); } static int nlge_gmac_config_speed(struct nlge_softc *sc, int quick) { struct mii_data *md; xlr_reg_t *mmio; int bmsr, n_tries, max_tries; int core_ctl[] = { 0x2, 0x1, 0x0, 0x1 }; int sgmii_speed[] = { SGMII_SPEED_10, SGMII_SPEED_100, SGMII_SPEED_1000, SGMII_SPEED_100 }; /* default to 100Mbps */ char *speed_str[] = { "10", "100", "1000", "unknown, defaulting to 100" }; int link_state = LINK_STATE_DOWN; if (sc->port_type == XLR_XAUI || sc->port_type == XLR_XGMII) return 0; md = NULL; mmio = sc->base; if (sc->mii_base != NULL) { max_tries = (quick == 1) ? 100 : 4000; bmsr = 0; for (n_tries = 0; n_tries < max_tries; n_tries++) { bmsr = nlge_mii_read_internal(sc->mii_base, sc->phy_addr, MII_BMSR); if ((bmsr & BMSR_ACOMP) && (bmsr & BMSR_LINK)) break; /* Auto-negotiation is complete and link is up */ DELAY(1000); } bmsr &= BMSR_LINK; sc->link = (bmsr == 0) ? xlr_mac_link_down : xlr_mac_link_up; sc->speed = nlge_mii_read_internal(sc->mii_base, sc->phy_addr, 28); sc->speed = (sc->speed >> 3) & 0x03; if (sc->link == xlr_mac_link_up) { link_state = LINK_STATE_UP; nlge_sgmii_init(sc); } if (sc->mii_bus) md = (struct mii_data *)device_get_softc(sc->mii_bus); } if (sc->port_type != XLR_RGMII) NLGE_WRITE(mmio, R_INTERFACE_CONTROL, sgmii_speed[sc->speed]); if (sc->speed == xlr_mac_speed_10 || sc->speed == xlr_mac_speed_100 || sc->speed == xlr_mac_speed_rsvd) { NLGE_WRITE(mmio, R_MAC_CONFIG_2, 0x7117); } else if (sc->speed == xlr_mac_speed_1000) { NLGE_WRITE(mmio, R_MAC_CONFIG_2, 0x7217); if (md != NULL) { ifmedia_set(&md->mii_media, IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, md->mii_instance)); } } NLGE_WRITE(mmio, R_CORECONTROL, core_ctl[sc->speed]); if_link_state_change(sc->nlge_if, link_state); printf("%s: [%sMbps]\n", device_get_nameunit(sc->nlge_dev), speed_str[sc->speed]); return (0); } /* * This function is called for each port that was added to the device tree * and it initializes the following port attributes: * - type * - base (base address to access port-specific registers) * - mii_base * - phy_addr */ static void nlge_set_port_attribs(struct nlge_softc *sc, struct xlr_gmac_port *port_info) { sc->instance = port_info->instance % 4; /* TBD: will not work for SPI-4 */ sc->port_type = port_info->type; sc->base = xlr_io_mmio(port_info->base_addr); sc->mii_base = xlr_io_mmio(port_info->mii_addr); if (port_info->pcs_addr != 0) sc->pcs_addr = xlr_io_mmio(port_info->pcs_addr); if (port_info->serdes_addr != 0) sc->serdes_addr = xlr_io_mmio(port_info->serdes_addr); sc->phy_addr = port_info->phy_addr; PDEBUG("Port%d: base=%p, mii_base=%p, phy_addr=%d\n", sc->id, sc->base, sc->mii_base, sc->phy_addr); } /* ------------------------------------------------------------------------ */ /* Debug dump functions */ #ifdef DEBUG static void dump_reg(xlr_reg_t *base, uint32_t offset, char *name) { int val; val = NLGE_READ(base, offset); printf("%-30s: 0x%8x 0x%8x\n", name, offset, val); } #define STRINGIFY(x) #x static void dump_na_registers(xlr_reg_t *base_addr, int port_id) { PDEBUG("Register dump for NA (of port=%d)\n", port_id); dump_reg(base_addr, R_PARSERCONFIGREG, STRINGIFY(R_PARSERCONFIGREG)); PDEBUG("Tx bucket sizes\n"); dump_reg(base_addr, R_GMAC_JFR0_BUCKET_SIZE, STRINGIFY(R_GMAC_JFR0_BUCKET_SIZE)); dump_reg(base_addr, R_GMAC_RFR0_BUCKET_SIZE, STRINGIFY(R_GMAC_RFR0_BUCKET_SIZE)); dump_reg(base_addr, R_GMAC_TX0_BUCKET_SIZE, STRINGIFY(R_GMAC_TX0_BUCKET_SIZE)); dump_reg(base_addr, R_GMAC_TX1_BUCKET_SIZE, STRINGIFY(R_GMAC_TX1_BUCKET_SIZE)); dump_reg(base_addr, R_GMAC_TX2_BUCKET_SIZE, STRINGIFY(R_GMAC_TX2_BUCKET_SIZE)); dump_reg(base_addr, R_GMAC_TX3_BUCKET_SIZE, STRINGIFY(R_GMAC_TX3_BUCKET_SIZE)); dump_reg(base_addr, R_GMAC_JFR1_BUCKET_SIZE, STRINGIFY(R_GMAC_JFR1_BUCKET_SIZE)); dump_reg(base_addr, R_GMAC_RFR1_BUCKET_SIZE, STRINGIFY(R_GMAC_RFR1_BUCKET_SIZE)); dump_reg(base_addr, R_TXDATAFIFO0, STRINGIFY(R_TXDATAFIFO0)); dump_reg(base_addr, R_TXDATAFIFO1, STRINGIFY(R_TXDATAFIFO1)); } static void dump_gmac_registers(struct nlge_softc *sc) { xlr_reg_t *base_addr = sc->base; int port_id = sc->instance; PDEBUG("Register dump for port=%d\n", port_id); if (sc->port_type == XLR_RGMII || sc->port_type == XLR_SGMII) { dump_reg(base_addr, R_MAC_CONFIG_1, STRINGIFY(R_MAC_CONFIG_1)); dump_reg(base_addr, R_MAC_CONFIG_2, STRINGIFY(R_MAC_CONFIG_2)); dump_reg(base_addr, R_IPG_IFG, STRINGIFY(R_IPG_IFG)); dump_reg(base_addr, R_HALF_DUPLEX, STRINGIFY(R_HALF_DUPLEX)); dump_reg(base_addr, R_MAXIMUM_FRAME_LENGTH, STRINGIFY(R_MAXIMUM_FRAME_LENGTH)); dump_reg(base_addr, R_TEST, STRINGIFY(R_TEST)); dump_reg(base_addr, R_MII_MGMT_CONFIG, STRINGIFY(R_MII_MGMT_CONFIG)); dump_reg(base_addr, R_MII_MGMT_COMMAND, STRINGIFY(R_MII_MGMT_COMMAND)); dump_reg(base_addr, R_MII_MGMT_ADDRESS, STRINGIFY(R_MII_MGMT_ADDRESS)); dump_reg(base_addr, R_MII_MGMT_WRITE_DATA, STRINGIFY(R_MII_MGMT_WRITE_DATA)); dump_reg(base_addr, R_MII_MGMT_STATUS, STRINGIFY(R_MII_MGMT_STATUS)); dump_reg(base_addr, R_MII_MGMT_INDICATORS, STRINGIFY(R_MII_MGMT_INDICATORS)); dump_reg(base_addr, R_INTERFACE_CONTROL, STRINGIFY(R_INTERFACE_CONTROL)); dump_reg(base_addr, R_INTERFACE_STATUS, STRINGIFY(R_INTERFACE_STATUS)); } else if (sc->port_type == XLR_XAUI || sc->port_type == XLR_XGMII) { dump_reg(base_addr, R_XGMAC_CONFIG_0, STRINGIFY(R_XGMAC_CONFIG_0)); dump_reg(base_addr, R_XGMAC_CONFIG_1, STRINGIFY(R_XGMAC_CONFIG_1)); dump_reg(base_addr, R_XGMAC_CONFIG_2, STRINGIFY(R_XGMAC_CONFIG_2)); dump_reg(base_addr, R_XGMAC_CONFIG_3, STRINGIFY(R_XGMAC_CONFIG_3)); dump_reg(base_addr, R_XGMAC_STATION_ADDRESS_LS, STRINGIFY(R_XGMAC_STATION_ADDRESS_LS)); dump_reg(base_addr, R_XGMAC_STATION_ADDRESS_MS, STRINGIFY(R_XGMAC_STATION_ADDRESS_MS)); dump_reg(base_addr, R_XGMAC_MAX_FRAME_LEN, STRINGIFY(R_XGMAC_MAX_FRAME_LEN)); dump_reg(base_addr, R_XGMAC_REV_LEVEL, STRINGIFY(R_XGMAC_REV_LEVEL)); dump_reg(base_addr, R_XGMAC_MIIM_COMMAND, STRINGIFY(R_XGMAC_MIIM_COMMAND)); dump_reg(base_addr, R_XGMAC_MIIM_FILED, STRINGIFY(R_XGMAC_MIIM_FILED)); dump_reg(base_addr, R_XGMAC_MIIM_CONFIG, STRINGIFY(R_XGMAC_MIIM_CONFIG)); dump_reg(base_addr, R_XGMAC_MIIM_LINK_FAIL_VECTOR, STRINGIFY(R_XGMAC_MIIM_LINK_FAIL_VECTOR)); dump_reg(base_addr, R_XGMAC_MIIM_INDICATOR, STRINGIFY(R_XGMAC_MIIM_INDICATOR)); } dump_reg(base_addr, R_MAC_ADDR0, STRINGIFY(R_MAC_ADDR0)); dump_reg(base_addr, R_MAC_ADDR0 + 1, STRINGIFY(R_MAC_ADDR0+1)); dump_reg(base_addr, R_MAC_ADDR1, STRINGIFY(R_MAC_ADDR1)); dump_reg(base_addr, R_MAC_ADDR2, STRINGIFY(R_MAC_ADDR2)); dump_reg(base_addr, R_MAC_ADDR3, STRINGIFY(R_MAC_ADDR3)); dump_reg(base_addr, R_MAC_ADDR_MASK2, STRINGIFY(R_MAC_ADDR_MASK2)); dump_reg(base_addr, R_MAC_ADDR_MASK3, STRINGIFY(R_MAC_ADDR_MASK3)); dump_reg(base_addr, R_MAC_FILTER_CONFIG, STRINGIFY(R_MAC_FILTER_CONFIG)); dump_reg(base_addr, R_TX_CONTROL, STRINGIFY(R_TX_CONTROL)); dump_reg(base_addr, R_RX_CONTROL, STRINGIFY(R_RX_CONTROL)); dump_reg(base_addr, R_DESC_PACK_CTRL, STRINGIFY(R_DESC_PACK_CTRL)); dump_reg(base_addr, R_STATCTRL, STRINGIFY(R_STATCTRL)); dump_reg(base_addr, R_L2ALLOCCTRL, STRINGIFY(R_L2ALLOCCTRL)); dump_reg(base_addr, R_INTMASK, STRINGIFY(R_INTMASK)); dump_reg(base_addr, R_INTREG, STRINGIFY(R_INTREG)); dump_reg(base_addr, R_TXRETRY, STRINGIFY(R_TXRETRY)); dump_reg(base_addr, R_CORECONTROL, STRINGIFY(R_CORECONTROL)); dump_reg(base_addr, R_BYTEOFFSET0, STRINGIFY(R_BYTEOFFSET0)); dump_reg(base_addr, R_BYTEOFFSET1, STRINGIFY(R_BYTEOFFSET1)); dump_reg(base_addr, R_L2TYPE_0, STRINGIFY(R_L2TYPE_0)); dump_na_registers(base_addr, port_id); } static void dump_fmn_cpu_credits_for_gmac(struct xlr_board_info *board, int gmac_id) { struct stn_cc *cc; int gmac_bucket_ids[] = { 97, 98, 99, 100, 101, 103 }; int j, k, r, c; int n_gmac_buckets; n_gmac_buckets = sizeof (gmac_bucket_ids) / sizeof (gmac_bucket_ids[0]); for (j = 0; j < 8; j++) { // for each cpu cc = board->credit_configs[j]; printf("Credits for Station CPU_%d ---> GMAC buckets (tx path)\n", j); for (k = 0; k < n_gmac_buckets; k++) { r = gmac_bucket_ids[k] / 8; c = gmac_bucket_ids[k] % 8; printf (" --> gmac%d_bucket_%-3d: credits=%d\n", gmac_id, gmac_bucket_ids[k], cc->counters[r][c]); } } } static void dump_fmn_gmac_credits(struct xlr_board_info *board, int gmac_id) { struct stn_cc *cc; int j, k; cc = board->gmac_block[gmac_id].credit_config; printf("Credits for Station: GMAC_%d ---> CPU buckets (rx path)\n", gmac_id); for (j = 0; j < 8; j++) { // for each cpu printf(" ---> cpu_%d\n", j); for (k = 0; k < 8; k++) { // for each bucket in cpu printf(" ---> bucket_%d: credits=%d\n", j * 8 + k, cc->counters[j][k]); } } } static void dump_board_info(struct xlr_board_info *board) { struct xlr_gmac_block_t *gm; int i, k; printf("cpu=%x ", xlr_revision()); printf("board_version: major=%llx, minor=%llx\n", xlr_boot1_info.board_major_version, xlr_boot1_info.board_minor_version); printf("is_xls=%d, nr_cpus=%d, usb=%s, cfi=%s, ata=%s\npci_irq=%d," "gmac_ports=%d\n", board->is_xls, board->nr_cpus, board->usb ? "Yes" : "No", board->cfi ? "Yes": "No", board->ata ? "Yes" : "No", board->pci_irq, board->gmacports); printf("FMN: Core-station bucket sizes\n"); for (i = 0; i < 128; i++) { if (i && ((i % 16) == 0)) printf("\n"); printf ("b[%d] = %d ", i, board->bucket_sizes->bucket[i]); } printf("\n"); for (i = 0; i < 3; i++) { gm = &board->gmac_block[i]; printf("RNA_%d: type=%d, enabled=%s, mode=%d, station_id=%d," "station_txbase=%d, station_rfr=%d ", i, gm->type, gm->enabled ? "Yes" : "No", gm->mode, gm->station_id, gm->station_txbase, gm->station_rfr); printf("n_ports=%d, baseaddr=%p, baseirq=%d, baseinst=%d\n", gm->num_ports, (xlr_reg_t *)gm->baseaddr, gm->baseirq, gm->baseinst); } for (k = 0; k < 3; k++) { // for each NA dump_fmn_cpu_credits_for_gmac(board, k); dump_fmn_gmac_credits(board, k); } } static void dump_mac_stats(struct nlge_softc *sc) { xlr_reg_t *addr; uint32_t pkts_tx, pkts_rx; addr = sc->base; pkts_rx = NLGE_READ(sc->base, R_RPKT); pkts_tx = NLGE_READ(sc->base, R_TPKT); printf("[nlge_%d mac stats]: pkts_tx=%u, pkts_rx=%u\n", sc->id, pkts_tx, pkts_rx); if (pkts_rx > 0) { uint32_t r; /* dump all rx counters. we need this because pkts_rx includes bad packets. */ for (r = R_RFCS; r <= R_ROVR; r++) printf("[nlge_%d mac stats]: [0x%x]=%u\n", sc->id, r, NLGE_READ(sc->base, r)); } if (pkts_tx > 0) { uint32_t r; /* dump all tx counters. might be useful for debugging. */ for (r = R_TMCA; r <= R_TFRG; r++) { if ((r == (R_TNCL + 1)) || (r == (R_TNCL + 2))) continue; printf("[nlge_%d mac stats]: [0x%x]=%u\n", sc->id, r, NLGE_READ(sc->base, r)); } } } static void dump_mii_regs(struct nlge_softc *sc) { uint32_t mii_regs[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e}; int i, n_regs; if (sc->mii_base == NULL || sc->mii_bus == NULL) return; n_regs = sizeof (mii_regs) / sizeof (mii_regs[0]); for (i = 0; i < n_regs; i++) { printf("[mii_0x%x] = %x\n", mii_regs[i], nlge_mii_read_internal(sc->mii_base, sc->phy_addr, mii_regs[i])); } } static void dump_ifmedia(struct ifmedia *ifm) { printf("ifm_mask=%08x, ifm_media=%08x, cur=%p\n", ifm->ifm_mask, ifm->ifm_media, ifm->ifm_cur); if (ifm->ifm_cur != NULL) { printf("Cur attribs: ifmedia_entry.ifm_media=%08x," " ifmedia_entry.ifm_data=%08x\n", ifm->ifm_cur->ifm_media, ifm->ifm_cur->ifm_data); } } static void dump_mii_data(struct mii_data *mii) { dump_ifmedia(&mii->mii_media); printf("ifp=%p, mii_instance=%d, mii_media_status=%08x," " mii_media_active=%08x\n", mii->mii_ifp, mii->mii_instance, mii->mii_media_status, mii->mii_media_active); } static void dump_pcs_regs(struct nlge_softc *sc, int phy) { int i, val; printf("PCS regs from %p for phy=%d\n", sc->pcs_addr, phy); for (i = 0; i < 18; i++) { if (i == 2 || i == 3 || (i >= 9 && i <= 14)) continue; val = nlge_mii_read_internal(sc->pcs_addr, phy, i); printf("PHY:%d pcs[0x%x] is 0x%x\n", phy, i, val); } } #endif Index: head/sys/mips/rmi/dev/xlr/rge.c =================================================================== --- head/sys/mips/rmi/dev/xlr/rge.c (revision 287470) +++ head/sys/mips/rmi/dev/xlr/rge.c (nonexistent) @@ -1,2564 +0,0 @@ -/*- - * Copyright (c) 2003-2009 RMI Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of RMI Corporation, nor the names of its contributors, - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * RMI_BSD - */ - -#include -__FBSDID("$FreeBSD$"); - -#ifdef HAVE_KERNEL_OPTION_HEADERS -#include "opt_device_polling.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define __RMAN_RESOURCE_VISIBLE -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include /* for DELAY */ -#include -#include /* */ -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "miibus_if.h" - -MODULE_DEPEND(rge, ether, 1, 1, 1); -MODULE_DEPEND(rge, miibus, 1, 1, 1); - -/* #define DEBUG */ - -#define RGE_TX_THRESHOLD 1024 -#define RGE_TX_Q_SIZE 1024 - -#ifdef DEBUG -#undef dbg_msg -int mac_debug = 1; - -#define dbg_msg(fmt, args...) \ - do {\ - if (mac_debug) {\ - printf("[%s@%d|%s]: cpu_%d: " fmt, \ - __FILE__, __LINE__, __FUNCTION__, xlr_cpu_id(), ##args);\ - }\ - } while(0); - -#define DUMP_PACKETS -#else -#undef dbg_msg -#define dbg_msg(fmt, args...) -int mac_debug = 0; - -#endif - -#define MAC_B2B_IPG 88 - -/* frame sizes need to be cacheline aligned */ -#define MAX_FRAME_SIZE 1536 -#define MAX_FRAME_SIZE_JUMBO 9216 - -#define MAC_SKB_BACK_PTR_SIZE SMP_CACHE_BYTES -#define MAC_PREPAD 0 -#define BYTE_OFFSET 2 -#define XLR_RX_BUF_SIZE (MAX_FRAME_SIZE+BYTE_OFFSET+MAC_PREPAD+MAC_SKB_BACK_PTR_SIZE+SMP_CACHE_BYTES) -#define MAC_CRC_LEN 4 -#define MAX_NUM_MSGRNG_STN_CC 128 - -#define MAX_NUM_DESC 1024 -#define MAX_SPILL_SIZE (MAX_NUM_DESC + 128) - -#define MAC_FRIN_TO_BE_SENT_THRESHOLD 16 - -#define MAX_FRIN_SPILL (MAX_SPILL_SIZE << 2) -#define MAX_FROUT_SPILL (MAX_SPILL_SIZE << 2) -#define MAX_CLASS_0_SPILL (MAX_SPILL_SIZE << 2) -#define MAX_CLASS_1_SPILL (MAX_SPILL_SIZE << 2) -#define MAX_CLASS_2_SPILL (MAX_SPILL_SIZE << 2) -#define MAX_CLASS_3_SPILL (MAX_SPILL_SIZE << 2) - -/***************************************************************** - * Phoenix Generic Mac driver - *****************************************************************/ - -extern uint32_t cpu_ltop_map[32]; - -#ifdef ENABLED_DEBUG -static int port_counters[4][8] __aligned(XLR_CACHELINE_SIZE); - -#define port_inc_counter(port, counter) atomic_add_int(&port_counters[port][(counter)], 1) -#else -#define port_inc_counter(port, counter) /* Nothing */ -#endif - -int xlr_rge_tx_prepend[MAXCPU]; -int xlr_rge_tx_done[MAXCPU]; -int xlr_rge_get_p2d_failed[MAXCPU]; -int xlr_rge_msg_snd_failed[MAXCPU]; -int xlr_rge_tx_ok_done[MAXCPU]; -int xlr_rge_rx_done[MAXCPU]; -int xlr_rge_repl_done[MAXCPU]; - -/* #define mac_stats_add(x, val) ({(x) += (val);}) */ -#define mac_stats_add(x, val) xlr_ldaddwu(val, &x) - -#define XLR_MAX_CORE 8 -#define RGE_LOCK_INIT(_sc, _name) \ - mtx_init(&(_sc)->rge_mtx, _name, MTX_NETWORK_LOCK, MTX_DEF) -#define RGE_LOCK(_sc) mtx_lock(&(_sc)->rge_mtx) -#define RGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rge_mtx, MA_OWNED) -#define RGE_UNLOCK(_sc) mtx_unlock(&(_sc)->rge_mtx) -#define RGE_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rge_mtx) - -#define XLR_MAX_MACS 8 -#define XLR_MAX_TX_FRAGS 14 -#define MAX_P2D_DESC_PER_PORT 512 -struct p2d_tx_desc { - uint64_t frag[XLR_MAX_TX_FRAGS + 2]; -}; - -#define MAX_TX_RING_SIZE (XLR_MAX_MACS * MAX_P2D_DESC_PER_PORT * sizeof(struct p2d_tx_desc)) - -struct rge_softc *dev_mac[XLR_MAX_MACS]; -static int dev_mac_xgs0; -static int dev_mac_gmac0; - -static int gmac_common_init_done; - - -static int rge_probe(device_t); -static int rge_attach(device_t); -static int rge_detach(device_t); -static int rge_suspend(device_t); -static int rge_resume(device_t); -static void rge_release_resources(struct rge_softc *); -static void rge_rx(struct rge_softc *, vm_paddr_t paddr, int); -static void rge_intr(void *); -static void rge_start_locked(struct ifnet *, int); -static void rge_start(struct ifnet *); -static int rge_ioctl(struct ifnet *, u_long, caddr_t); -static void rge_init(void *); -static void rge_stop(struct rge_softc *); -static int rge_shutdown(device_t); -static void rge_reset(struct rge_softc *); - -static struct mbuf *get_mbuf(void); -static void free_buf(vm_paddr_t paddr); -static void *get_buf(void); - -static void xlr_mac_get_hwaddr(struct rge_softc *); -static void xlr_mac_setup_hwaddr(struct driver_data *); -static void rmi_xlr_mac_set_enable(struct driver_data *priv, int flag); -static void rmi_xlr_xgmac_init(struct driver_data *priv); -static void rmi_xlr_gmac_init(struct driver_data *priv); -static void mac_common_init(void); -static int rge_mii_write(device_t, int, int, int); -static int rge_mii_read(device_t, int, int); -static void rmi_xlr_mac_mii_statchg(device_t); -static int rmi_xlr_mac_mediachange(struct ifnet *); -static void rmi_xlr_mac_mediastatus(struct ifnet *, struct ifmediareq *); -static void xlr_mac_set_rx_mode(struct rge_softc *sc); -void -rmi_xlr_mac_msgring_handler(int bucket, int size, int code, - int stid, struct msgrng_msg *msg, - void *data); -static void mac_frin_replenish(void *); -static int rmi_xlr_mac_open(struct rge_softc *); -static int rmi_xlr_mac_close(struct rge_softc *); -static int -mac_xmit(struct mbuf *, struct rge_softc *, - struct driver_data *, int, struct p2d_tx_desc *); -static int rmi_xlr_mac_xmit(struct mbuf *, struct rge_softc *, int, struct p2d_tx_desc *); -static struct rge_softc_stats *rmi_xlr_mac_get_stats(struct rge_softc *sc); -static void rmi_xlr_mac_set_multicast_list(struct rge_softc *sc); -static int rmi_xlr_mac_change_mtu(struct rge_softc *sc, int new_mtu); -static int rmi_xlr_mac_fill_rxfr(struct rge_softc *sc); -static void rmi_xlr_config_spill_area(struct driver_data *priv); -static int rmi_xlr_mac_set_speed(struct driver_data *s, xlr_mac_speed_t speed); -static int -rmi_xlr_mac_set_duplex(struct driver_data *s, - xlr_mac_duplex_t duplex, xlr_mac_fc_t fc); -static void serdes_regs_init(struct driver_data *priv); -static int rmi_xlr_gmac_reset(struct driver_data *priv); - -/*Statistics...*/ -static int get_p2d_desc_failed = 0; -static int msg_snd_failed = 0; - -SYSCTL_INT(_hw, OID_AUTO, get_p2d_failed, CTLFLAG_RW, - &get_p2d_desc_failed, 0, "p2d desc failed"); -SYSCTL_INT(_hw, OID_AUTO, msg_snd_failed, CTLFLAG_RW, - &msg_snd_failed, 0, "msg snd failed"); - -struct callout xlr_tx_stop_bkp; - -static device_method_t rge_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, rge_probe), - DEVMETHOD(device_attach, rge_attach), - DEVMETHOD(device_detach, rge_detach), - DEVMETHOD(device_shutdown, rge_shutdown), - DEVMETHOD(device_suspend, rge_suspend), - DEVMETHOD(device_resume, rge_resume), - - /* MII interface */ - DEVMETHOD(miibus_readreg, rge_mii_read), - DEVMETHOD(miibus_statchg, rmi_xlr_mac_mii_statchg), - DEVMETHOD(miibus_writereg, rge_mii_write), - {0, 0} -}; - -static driver_t rge_driver = { - "rge", - rge_methods, - sizeof(struct rge_softc) -}; - -static devclass_t rge_devclass; - -DRIVER_MODULE(rge, iodi, rge_driver, rge_devclass, 0, 0); -DRIVER_MODULE(miibus, rge, miibus_driver, miibus_devclass, 0, 0); - -#ifndef __STR -#define __STR(x) #x -#endif -#ifndef STR -#define STR(x) __STR(x) -#endif - -void *xlr_tx_ring_mem; - -struct tx_desc_node { - struct p2d_tx_desc *ptr; - TAILQ_ENTRY(tx_desc_node) list; -}; - -#define XLR_MAX_TX_DESC_NODES (XLR_MAX_MACS * MAX_P2D_DESC_PER_PORT) -struct tx_desc_node tx_desc_nodes[XLR_MAX_TX_DESC_NODES]; -static volatile int xlr_tot_avail_p2d[XLR_MAX_CORE]; -static int xlr_total_active_core = 0; - -/* - * This should contain the list of all free tx frag desc nodes pointing to tx - * p2d arrays - */ -static -TAILQ_HEAD(, tx_desc_node) tx_frag_desc[XLR_MAX_CORE] = -{ - TAILQ_HEAD_INITIALIZER(tx_frag_desc[0]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[1]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[2]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[3]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[4]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[5]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[6]), - TAILQ_HEAD_INITIALIZER(tx_frag_desc[7]), -}; - -/* This contains a list of free tx frag node descriptors */ -static -TAILQ_HEAD(, tx_desc_node) free_tx_frag_desc[XLR_MAX_CORE] = -{ - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[0]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[1]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[2]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[3]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[4]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[5]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[6]), - TAILQ_HEAD_INITIALIZER(free_tx_frag_desc[7]), -}; - -static struct mtx tx_desc_lock[XLR_MAX_CORE]; - -static inline void -mac_make_desc_rfr(struct msgrng_msg *msg, - vm_paddr_t addr) -{ - msg->msg0 = (uint64_t) addr & 0xffffffffe0ULL; - msg->msg1 = msg->msg2 = msg->msg3 = 0; -} - -#define MAC_TX_DESC_ALIGNMENT (XLR_CACHELINE_SIZE - 1) - -static void -init_p2d_allocation(void) -{ - int active_core[8] = {0}; - int i = 0; - uint32_t cpumask; - int cpu; - - cpumask = xlr_hw_thread_mask; - - for (i = 0; i < 32; i++) { - if (cpumask & (1 << i)) { - cpu = i; - if (!active_core[cpu / 4]) { - active_core[cpu / 4] = 1; - xlr_total_active_core++; - } - } - } - for (i = 0; i < XLR_MAX_CORE; i++) { - if (active_core[i]) - xlr_tot_avail_p2d[i] = XLR_MAX_TX_DESC_NODES / xlr_total_active_core; - } - printf("Total Active Core %d\n", xlr_total_active_core); -} - - -static void -init_tx_ring(void) -{ - int i; - int j = 0; - struct tx_desc_node *start, *node; - struct p2d_tx_desc *tx_desc; - vm_paddr_t paddr; - vm_offset_t unmapped_addr; - - for (i = 0; i < XLR_MAX_CORE; i++) - mtx_init(&tx_desc_lock[i], "xlr tx_desc", NULL, MTX_SPIN); - - start = &tx_desc_nodes[0]; - /* TODO: try to get this from KSEG0 */ - xlr_tx_ring_mem = contigmalloc((MAX_TX_RING_SIZE + XLR_CACHELINE_SIZE), - M_DEVBUF, M_NOWAIT | M_ZERO, 0, - 0x10000000, XLR_CACHELINE_SIZE, 0); - - if (xlr_tx_ring_mem == NULL) { - panic("TX ring memory allocation failed"); - } - paddr = vtophys((vm_offset_t)xlr_tx_ring_mem); - - unmapped_addr = MIPS_PHYS_TO_KSEG0(paddr); - - - tx_desc = (struct p2d_tx_desc *)unmapped_addr; - - for (i = 0; i < XLR_MAX_TX_DESC_NODES; i++) { - node = start + i; - node->ptr = tx_desc; - tx_desc++; - TAILQ_INSERT_HEAD(&tx_frag_desc[j], node, list); - j = (i / (XLR_MAX_TX_DESC_NODES / xlr_total_active_core)); - } -} - -static inline struct p2d_tx_desc * -get_p2d_desc(void) -{ - struct tx_desc_node *node; - struct p2d_tx_desc *tx_desc = NULL; - int cpu = xlr_core_id(); - - mtx_lock_spin(&tx_desc_lock[cpu]); - node = TAILQ_FIRST(&tx_frag_desc[cpu]); - if (node) { - xlr_tot_avail_p2d[cpu]--; - TAILQ_REMOVE(&tx_frag_desc[cpu], node, list); - tx_desc = node->ptr; - TAILQ_INSERT_HEAD(&free_tx_frag_desc[cpu], node, list); - } else { - /* Increment p2d desc fail count */ - get_p2d_desc_failed++; - } - mtx_unlock_spin(&tx_desc_lock[cpu]); - return tx_desc; -} -static void -free_p2d_desc(struct p2d_tx_desc *tx_desc) -{ - struct tx_desc_node *node; - int cpu = xlr_core_id(); - - mtx_lock_spin(&tx_desc_lock[cpu]); - node = TAILQ_FIRST(&free_tx_frag_desc[cpu]); - KASSERT((node != NULL), ("Free TX frag node list is empty\n")); - - TAILQ_REMOVE(&free_tx_frag_desc[cpu], node, list); - node->ptr = tx_desc; - TAILQ_INSERT_HEAD(&tx_frag_desc[cpu], node, list); - xlr_tot_avail_p2d[cpu]++; - mtx_unlock_spin(&tx_desc_lock[cpu]); - -} - -static int -build_frag_list(struct mbuf *m_head, struct msgrng_msg *p2p_msg, struct p2d_tx_desc *tx_desc) -{ - struct mbuf *m; - vm_paddr_t paddr; - uint64_t p2d_len; - int nfrag; - vm_paddr_t p1, p2; - uint32_t len1, len2; - vm_offset_t taddr; - uint64_t fr_stid; - - fr_stid = (xlr_core_id() << 3) + xlr_thr_id() + 4; - - if (tx_desc == NULL) - return 1; - - nfrag = 0; - for (m = m_head; m != NULL; m = m->m_next) { - if ((nfrag + 1) >= XLR_MAX_TX_FRAGS) { - free_p2d_desc(tx_desc); - return 1; - } - if (m->m_len != 0) { - paddr = vtophys(mtod(m, vm_offset_t)); - p1 = paddr + m->m_len; - p2 = vtophys(((vm_offset_t)m->m_data + m->m_len)); - if (p1 != p2) { - len1 = (uint32_t) - (PAGE_SIZE - (paddr & PAGE_MASK)); - tx_desc->frag[nfrag] = (127ULL << 54) | - ((uint64_t) len1 << 40) | paddr; - nfrag++; - taddr = (vm_offset_t)m->m_data + len1; - p2 = vtophys(taddr); - len2 = m->m_len - len1; - if (len2 == 0) - continue; - if (nfrag >= XLR_MAX_TX_FRAGS) - panic("TX frags exceeded"); - - tx_desc->frag[nfrag] = (127ULL << 54) | - ((uint64_t) len2 << 40) | p2; - - taddr += len2; - p1 = vtophys(taddr); - - if ((p2 + len2) != p1) { - printf("p1 = %p p2 = %p\n", (void *)p1, (void *)p2); - printf("len1 = %x len2 = %x\n", len1, - len2); - printf("m_data %p\n", m->m_data); - DELAY(1000000); - panic("Multiple Mbuf segment discontiguous\n"); - } - } else { - tx_desc->frag[nfrag] = (127ULL << 54) | - ((uint64_t) m->m_len << 40) | paddr; - } - nfrag++; - } - } - /* set eop in the last tx p2d desc */ - tx_desc->frag[nfrag - 1] |= (1ULL << 63); - paddr = vtophys((vm_offset_t)tx_desc); - tx_desc->frag[nfrag] = (1ULL << 63) | (fr_stid << 54) | paddr; - nfrag++; - tx_desc->frag[XLR_MAX_TX_FRAGS] = (uint64_t)(intptr_t)tx_desc; - tx_desc->frag[XLR_MAX_TX_FRAGS + 1] = (uint64_t)(intptr_t)m_head; - - p2d_len = (nfrag * 8); - p2p_msg->msg0 = (1ULL << 63) | (1ULL << 62) | (127ULL << 54) | - (p2d_len << 40) | paddr; - - return 0; -} -static void -release_tx_desc(struct msgrng_msg *msg, int rel_buf) -{ - struct p2d_tx_desc *tx_desc, *chk_addr; - struct mbuf *m; - - tx_desc = (struct p2d_tx_desc *)MIPS_PHYS_TO_KSEG0(msg->msg0); - chk_addr = (struct p2d_tx_desc *)(intptr_t)tx_desc->frag[XLR_MAX_TX_FRAGS]; - if (tx_desc != chk_addr) { - printf("Address %p does not match with stored addr %p - we leaked a descriptor\n", - tx_desc, chk_addr); - return; - } - if (rel_buf) { - m = (struct mbuf *)(intptr_t)tx_desc->frag[XLR_MAX_TX_FRAGS + 1]; - m_freem(m); - } - free_p2d_desc(tx_desc); -} - - -static struct mbuf * -get_mbuf(void) -{ - struct mbuf *m_new = NULL; - - if ((m_new = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR)) == NULL) - return NULL; - - m_new->m_len = MCLBYTES; - m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; - return m_new; -} - -static void -free_buf(vm_paddr_t paddr) -{ - struct mbuf *m; - uint64_t mag; - uint32_t sr; - - sr = xlr_enable_kx(); - m = (struct mbuf *)(intptr_t)xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE); - mag = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE + sizeof(uint64_t)); - xlr_restore_kx(sr); - if (mag != 0xf00bad) { - printf("Something is wrong kseg:%lx found mag:%lx not 0xf00bad\n", - (u_long)paddr, (u_long)mag); - return; - } - if (m != NULL) - m_freem(m); -} - -static void * -get_buf(void) -{ - struct mbuf *m_new = NULL; - uint64_t *md; -#ifdef INVARIANTS - vm_paddr_t temp1, temp2; -#endif - - m_new = get_mbuf(); - if (m_new == NULL) - return NULL; - - m_adj(m_new, XLR_CACHELINE_SIZE - ((uintptr_t)m_new->m_data & 0x1f)); - md = (uint64_t *)m_new->m_data; - md[0] = (uintptr_t)m_new; /* Back Ptr */ - md[1] = 0xf00bad; - m_adj(m_new, XLR_CACHELINE_SIZE); - -#ifdef INVARIANTS - temp1 = vtophys((vm_offset_t)m_new->m_data); - temp2 = vtophys((vm_offset_t)m_new->m_data + 1536); - if ((temp1 + 1536) != temp2) - panic("ALLOCED BUFFER IS NOT CONTIGUOUS\n"); -#endif - return (void *)m_new->m_data; -} - -/********************************************************************** - **********************************************************************/ -static void -rmi_xlr_mac_set_enable(struct driver_data *priv, int flag) -{ - uint32_t regval; - int tx_threshold = 1518; - - if (flag) { - regval = xlr_read_reg(priv->mmio, R_TX_CONTROL); - regval |= (1 << O_TX_CONTROL__TxEnable) | - (tx_threshold << O_TX_CONTROL__TxThreshold); - - xlr_write_reg(priv->mmio, R_TX_CONTROL, regval); - - regval = xlr_read_reg(priv->mmio, R_RX_CONTROL); - regval |= 1 << O_RX_CONTROL__RxEnable; - if (priv->mode == XLR_PORT0_RGMII) - regval |= 1 << O_RX_CONTROL__RGMII; - xlr_write_reg(priv->mmio, R_RX_CONTROL, regval); - - regval = xlr_read_reg(priv->mmio, R_MAC_CONFIG_1); - regval |= (O_MAC_CONFIG_1__txen | O_MAC_CONFIG_1__rxen); - xlr_write_reg(priv->mmio, R_MAC_CONFIG_1, regval); - } else { - regval = xlr_read_reg(priv->mmio, R_TX_CONTROL); - regval &= ~((1 << O_TX_CONTROL__TxEnable) | - (tx_threshold << O_TX_CONTROL__TxThreshold)); - - xlr_write_reg(priv->mmio, R_TX_CONTROL, regval); - - regval = xlr_read_reg(priv->mmio, R_RX_CONTROL); - regval &= ~(1 << O_RX_CONTROL__RxEnable); - xlr_write_reg(priv->mmio, R_RX_CONTROL, regval); - - regval = xlr_read_reg(priv->mmio, R_MAC_CONFIG_1); - regval &= ~(O_MAC_CONFIG_1__txen | O_MAC_CONFIG_1__rxen); - xlr_write_reg(priv->mmio, R_MAC_CONFIG_1, regval); - } -} - -/********************************************************************** - **********************************************************************/ -static __inline__ int -xlr_mac_send_fr(struct driver_data *priv, - vm_paddr_t addr, int len) -{ - struct msgrng_msg msg; - int stid = priv->rfrbucket; - int code, ret; - uint32_t msgrng_flags; -#ifdef INVARIANTS - int i = 0; -#endif - - mac_make_desc_rfr(&msg, addr); - - /* Send the packet to MAC */ - dbg_msg("mac_%d: Sending free packet %lx to stid %d\n", - priv->instance, (u_long)addr, stid); - if (priv->type == XLR_XGMAC) - code = MSGRNG_CODE_XGMAC; /* WHY? */ - else - code = MSGRNG_CODE_MAC; - - do { - msgrng_flags = msgrng_access_enable(); - ret = message_send(1, code, stid, &msg); - msgrng_restore(msgrng_flags); - KASSERT(i++ < 100000, ("Too many credit fails\n")); - } while (ret != 0); - - return 0; -} - -/**************************************************************/ - -static void -xgmac_mdio_setup(volatile unsigned int *_mmio) -{ - int i; - uint32_t rd_data; - - for (i = 0; i < 4; i++) { - rd_data = xmdio_read(_mmio, 1, 0x8000 + i); - rd_data = rd_data & 0xffffdfff; /* clear isolate bit */ - xmdio_write(_mmio, 1, 0x8000 + i, rd_data); - } -} - -/********************************************************************** - * Init MII interface - * - * Input parameters: - * s - priv structure - ********************************************************************* */ -#define PHY_STATUS_RETRIES 25000 - -static void -rmi_xlr_mac_mii_init(struct driver_data *priv) -{ - xlr_reg_t *mii_mmio = priv->mii_mmio; - - /* use the lowest clock divisor - divisor 28 */ - xlr_write_reg(mii_mmio, R_MII_MGMT_CONFIG, 0x07); -} - -/********************************************************************** - * Read a PHY register. - * - * Input parameters: - * s - priv structure - * phyaddr - PHY's address - * regidx = index of register to read - * - * Return value: - * value read, or 0 if an error occurred. - ********************************************************************* */ - -static int -rge_mii_read_internal(xlr_reg_t * mii_mmio, int phyaddr, int regidx) -{ - int i = 0; - - /* setup the phy reg to be used */ - xlr_write_reg(mii_mmio, R_MII_MGMT_ADDRESS, - (phyaddr << 8) | (regidx << 0)); - /* Issue the read command */ - xlr_write_reg(mii_mmio, R_MII_MGMT_COMMAND, - (1 << O_MII_MGMT_COMMAND__rstat)); - - /* poll for the read cycle to complete */ - for (i = 0; i < PHY_STATUS_RETRIES; i++) { - if (xlr_read_reg(mii_mmio, R_MII_MGMT_INDICATORS) == 0) - break; - } - - /* clear the read cycle */ - xlr_write_reg(mii_mmio, R_MII_MGMT_COMMAND, 0); - - if (i == PHY_STATUS_RETRIES) { - return 0xffffffff; - } - /* Read the data back */ - return xlr_read_reg(mii_mmio, R_MII_MGMT_STATUS); -} - -static int -rge_mii_read(device_t dev, int phyaddr, int regidx) -{ - struct rge_softc *sc = device_get_softc(dev); - - return rge_mii_read_internal(sc->priv.mii_mmio, phyaddr, regidx); -} - -/********************************************************************** - * Set MII hooks to newly selected media - * - * Input parameters: - * ifp - Interface Pointer - * - * Return value: - * nothing - ********************************************************************* */ -static int -rmi_xlr_mac_mediachange(struct ifnet *ifp) -{ - struct rge_softc *sc = ifp->if_softc; - - if (ifp->if_flags & IFF_UP) - mii_mediachg(&sc->rge_mii); - - return 0; -} - -/********************************************************************** - * Get the current interface media status - * - * Input parameters: - * ifp - Interface Pointer - * ifmr - Interface media request ptr - * - * Return value: - * nothing - ********************************************************************* */ -static void -rmi_xlr_mac_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) -{ - struct rge_softc *sc = ifp->if_softc; - - /* Check whether this is interface is active or not. */ - ifmr->ifm_status = IFM_AVALID; - if (sc->link_up) { - ifmr->ifm_status |= IFM_ACTIVE; - } else { - ifmr->ifm_active = IFM_ETHER; - } -} - -/********************************************************************** - * Write a value to a PHY register. - * - * Input parameters: - * s - priv structure - * phyaddr - PHY to use - * regidx - register within the PHY - * regval - data to write to register - * - * Return value: - * nothing - ********************************************************************* */ -static void -rge_mii_write_internal(xlr_reg_t * mii_mmio, int phyaddr, int regidx, int regval) -{ - int i = 0; - - xlr_write_reg(mii_mmio, R_MII_MGMT_ADDRESS, - (phyaddr << 8) | (regidx << 0)); - - /* Write the data which starts the write cycle */ - xlr_write_reg(mii_mmio, R_MII_MGMT_WRITE_DATA, regval); - - /* poll for the write cycle to complete */ - for (i = 0; i < PHY_STATUS_RETRIES; i++) { - if (xlr_read_reg(mii_mmio, R_MII_MGMT_INDICATORS) == 0) - break; - } - - return; -} - -static int -rge_mii_write(device_t dev, int phyaddr, int regidx, int regval) -{ - struct rge_softc *sc = device_get_softc(dev); - - rge_mii_write_internal(sc->priv.mii_mmio, phyaddr, regidx, regval); - return (0); -} - -static void -rmi_xlr_mac_mii_statchg(struct device *dev) -{ -} - -static void -serdes_regs_init(struct driver_data *priv) -{ - xlr_reg_t *mmio_gpio = (xlr_reg_t *) (xlr_io_base + XLR_IO_GPIO_OFFSET); - - /* Initialize SERDES CONTROL Registers */ - rge_mii_write_internal(priv->serdes_mmio, 26, 0, 0x6DB0); - rge_mii_write_internal(priv->serdes_mmio, 26, 1, 0xFFFF); - rge_mii_write_internal(priv->serdes_mmio, 26, 2, 0xB6D0); - rge_mii_write_internal(priv->serdes_mmio, 26, 3, 0x00FF); - rge_mii_write_internal(priv->serdes_mmio, 26, 4, 0x0000); - rge_mii_write_internal(priv->serdes_mmio, 26, 5, 0x0000); - rge_mii_write_internal(priv->serdes_mmio, 26, 6, 0x0005); - rge_mii_write_internal(priv->serdes_mmio, 26, 7, 0x0001); - rge_mii_write_internal(priv->serdes_mmio, 26, 8, 0x0000); - rge_mii_write_internal(priv->serdes_mmio, 26, 9, 0x0000); - rge_mii_write_internal(priv->serdes_mmio, 26, 10, 0x0000); - - /* - * GPIO setting which affect the serdes - needs figuring out - */ - DELAY(100); - xlr_write_reg(mmio_gpio, 0x20, 0x7e6802); - xlr_write_reg(mmio_gpio, 0x10, 0x7104); - DELAY(100); - - /* - * This kludge is needed to setup serdes (?) clock correctly on some - * XLS boards - */ - if ((xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_XI || - xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_XII) && - xlr_boot1_info.board_minor_version == 4) { - /* use 125 Mhz instead of 156.25Mhz ref clock */ - DELAY(100); - xlr_write_reg(mmio_gpio, 0x10, 0x7103); - xlr_write_reg(mmio_gpio, 0x21, 0x7103); - DELAY(100); - } - - return; -} - -static void -serdes_autoconfig(struct driver_data *priv) -{ - int delay = 100000; - - /* Enable Auto negotiation in the PCS Layer */ - rge_mii_write_internal(priv->pcs_mmio, 27, 0, 0x1000); - DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 27, 0, 0x0200); - DELAY(delay); - - rge_mii_write_internal(priv->pcs_mmio, 28, 0, 0x1000); - DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 28, 0, 0x0200); - DELAY(delay); - - rge_mii_write_internal(priv->pcs_mmio, 29, 0, 0x1000); - DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 29, 0, 0x0200); - DELAY(delay); - - rge_mii_write_internal(priv->pcs_mmio, 30, 0, 0x1000); - DELAY(delay); - rge_mii_write_internal(priv->pcs_mmio, 30, 0, 0x0200); - DELAY(delay); - -} - -/***************************************************************** - * Initialize GMAC - *****************************************************************/ -static void -rmi_xlr_config_pde(struct driver_data *priv) -{ - int i = 0, cpu = 0, bucket = 0; - uint64_t bucket_map = 0; - - /* uint32_t desc_pack_ctrl = 0; */ - uint32_t cpumask; - - cpumask = 0x1; -#ifdef SMP - /* - * rge may be called before SMP start in a BOOTP/NFSROOT - * setup. we will distribute packets to other cpus only when - * the SMP is started. - */ - if (smp_started) - cpumask = xlr_hw_thread_mask; -#endif - - for (i = 0; i < MAXCPU; i++) { - if (cpumask & (1 << i)) { - cpu = i; - bucket = ((cpu >> 2) << 3); - bucket_map |= (3ULL << bucket); - } - } - printf("rmi_xlr_config_pde: bucket_map=%jx\n", (uintmax_t)bucket_map); - - /* bucket_map = 0x1; */ - xlr_write_reg(priv->mmio, R_PDE_CLASS_0, (bucket_map & 0xffffffff)); - xlr_write_reg(priv->mmio, R_PDE_CLASS_0 + 1, - ((bucket_map >> 32) & 0xffffffff)); - - xlr_write_reg(priv->mmio, R_PDE_CLASS_1, (bucket_map & 0xffffffff)); - xlr_write_reg(priv->mmio, R_PDE_CLASS_1 + 1, - ((bucket_map >> 32) & 0xffffffff)); - - xlr_write_reg(priv->mmio, R_PDE_CLASS_2, (bucket_map & 0xffffffff)); - xlr_write_reg(priv->mmio, R_PDE_CLASS_2 + 1, - ((bucket_map >> 32) & 0xffffffff)); - - xlr_write_reg(priv->mmio, R_PDE_CLASS_3, (bucket_map & 0xffffffff)); - xlr_write_reg(priv->mmio, R_PDE_CLASS_3 + 1, - ((bucket_map >> 32) & 0xffffffff)); -} - -static void -rge_smp_update_pde(void *dummy __unused) -{ - int i; - struct driver_data *priv; - struct rge_softc *sc; - - printf("Updating packet distribution for SMP\n"); - for (i = 0; i < XLR_MAX_MACS; i++) { - sc = dev_mac[i]; - if (!sc) - continue; - priv = &(sc->priv); - rmi_xlr_mac_set_enable(priv, 0); - rmi_xlr_config_pde(priv); - rmi_xlr_mac_set_enable(priv, 1); - } -} - -SYSINIT(rge_smp_update_pde, SI_SUB_SMP, SI_ORDER_ANY, rge_smp_update_pde, NULL); - - -static void -rmi_xlr_config_parser(struct driver_data *priv) -{ - /* - * Mark it as no classification The parser extract is gauranteed to - * be zero with no classfication - */ - xlr_write_reg(priv->mmio, R_L2TYPE_0, 0x00); - - xlr_write_reg(priv->mmio, R_L2TYPE_0, 0x01); - - /* configure the parser : L2 Type is configured in the bootloader */ - /* extract IP: src, dest protocol */ - xlr_write_reg(priv->mmio, R_L3CTABLE, - (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) | - (0x0800 << 0)); - xlr_write_reg(priv->mmio, R_L3CTABLE + 1, - (12 << 25) | (4 << 21) | (16 << 14) | (4 << 10)); - -} - -static void -rmi_xlr_config_classifier(struct driver_data *priv) -{ - int i = 0; - - if (priv->type == XLR_XGMAC) { - /* xgmac translation table doesn't have sane values on reset */ - for (i = 0; i < 64; i++) - xlr_write_reg(priv->mmio, R_TRANSLATETABLE + i, 0x0); - - /* - * use upper 7 bits of the parser extract to index the - * translate table - */ - xlr_write_reg(priv->mmio, R_PARSERCONFIGREG, 0x0); - } -} - -enum { - SGMII_SPEED_10 = 0x00000000, - SGMII_SPEED_100 = 0x02000000, - SGMII_SPEED_1000 = 0x04000000, -}; - -static void -rmi_xlr_gmac_config_speed(struct driver_data *priv) -{ - int phy_addr = priv->phy_addr; - xlr_reg_t *mmio = priv->mmio; - struct rge_softc *sc = priv->sc; - - priv->speed = rge_mii_read_internal(priv->mii_mmio, phy_addr, 28); - priv->link = rge_mii_read_internal(priv->mii_mmio, phy_addr, 1) & 0x4; - priv->speed = (priv->speed >> 3) & 0x03; - - if (priv->speed == xlr_mac_speed_10) { - if (priv->mode != XLR_RGMII) - xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_10); - xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7117); - xlr_write_reg(mmio, R_CORECONTROL, 0x02); - printf("%s: [10Mbps]\n", device_get_nameunit(sc->rge_dev)); - sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; - sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; - sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_10_T | IFM_FDX; - } else if (priv->speed == xlr_mac_speed_100) { - if (priv->mode != XLR_RGMII) - xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_100); - xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7117); - xlr_write_reg(mmio, R_CORECONTROL, 0x01); - printf("%s: [100Mbps]\n", device_get_nameunit(sc->rge_dev)); - sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; - sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; - sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; - } else { - if (priv->speed != xlr_mac_speed_1000) { - if (priv->mode != XLR_RGMII) - xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_100); - printf("PHY reported unknown MAC speed, defaulting to 100Mbps\n"); - xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7117); - xlr_write_reg(mmio, R_CORECONTROL, 0x01); - sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; - sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; - sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_100_TX | IFM_FDX; - } else { - if (priv->mode != XLR_RGMII) - xlr_write_reg(mmio, R_INTERFACE_CONTROL, SGMII_SPEED_1000); - xlr_write_reg(mmio, R_MAC_CONFIG_2, 0x7217); - xlr_write_reg(mmio, R_CORECONTROL, 0x00); - printf("%s: [1000Mbps]\n", device_get_nameunit(sc->rge_dev)); - sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_1000_T | IFM_FDX; - sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_1000_T | IFM_FDX; - sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_1000_T | IFM_FDX; - } - } - - if (!priv->link) { - sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER; - sc->link_up = 0; - } else { - sc->link_up = 1; - } -} - -/***************************************************************** - * Initialize XGMAC - *****************************************************************/ -static void -rmi_xlr_xgmac_init(struct driver_data *priv) -{ - int i = 0; - xlr_reg_t *mmio = priv->mmio; - int id = priv->instance; - struct rge_softc *sc = priv->sc; - volatile unsigned short *cpld; - - cpld = (volatile unsigned short *)0xBD840000; - - xlr_write_reg(priv->mmio, R_DESC_PACK_CTRL, - (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize) | (4 << 20)); - xlr_write_reg(priv->mmio, R_BYTEOFFSET0, BYTE_OFFSET); - rmi_xlr_config_pde(priv); - rmi_xlr_config_parser(priv); - rmi_xlr_config_classifier(priv); - - xlr_write_reg(priv->mmio, R_MSG_TX_THRESHOLD, 1); - - /* configure the XGMAC Registers */ - xlr_write_reg(mmio, R_XGMAC_CONFIG_1, 0x50000026); - - /* configure the XGMAC_GLUE Registers */ - xlr_write_reg(mmio, R_DMACR0, 0xffffffff); - xlr_write_reg(mmio, R_DMACR1, 0xffffffff); - xlr_write_reg(mmio, R_DMACR2, 0xffffffff); - xlr_write_reg(mmio, R_DMACR3, 0xffffffff); - xlr_write_reg(mmio, R_STATCTRL, 0x04); - xlr_write_reg(mmio, R_L2ALLOCCTRL, 0xffffffff); - - xlr_write_reg(mmio, R_XGMACPADCALIBRATION, 0x030); - xlr_write_reg(mmio, R_EGRESSFIFOCARVINGSLOTS, 0x0f); - xlr_write_reg(mmio, R_L2ALLOCCTRL, 0xffffffff); - xlr_write_reg(mmio, R_XGMAC_MIIM_CONFIG, 0x3e); - - /* - * take XGMII phy out of reset - */ - /* - * we are pulling everything out of reset because writing a 0 would - * reset other devices on the chip - */ - cpld[ATX_CPLD_RESET_1] = 0xffff; - cpld[ATX_CPLD_MISC_CTRL] = 0xffff; - cpld[ATX_CPLD_RESET_2] = 0xffff; - - xgmac_mdio_setup(mmio); - - rmi_xlr_config_spill_area(priv); - - if (id == 0) { - for (i = 0; i < 16; i++) { - xlr_write_reg(mmio, R_XGS_TX0_BUCKET_SIZE + i, - bucket_sizes. - bucket[MSGRNG_STNID_XGS0_TX + i]); - } - - xlr_write_reg(mmio, R_XGS_JFR_BUCKET_SIZE, - bucket_sizes.bucket[MSGRNG_STNID_XMAC0JFR]); - xlr_write_reg(mmio, R_XGS_RFR_BUCKET_SIZE, - bucket_sizes.bucket[MSGRNG_STNID_XMAC0RFR]); - - for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { - xlr_write_reg(mmio, R_CC_CPU0_0 + i, - cc_table_xgs_0. - counters[i >> 3][i & 0x07]); - } - } else if (id == 1) { - for (i = 0; i < 16; i++) { - xlr_write_reg(mmio, R_XGS_TX0_BUCKET_SIZE + i, - bucket_sizes. - bucket[MSGRNG_STNID_XGS1_TX + i]); - } - - xlr_write_reg(mmio, R_XGS_JFR_BUCKET_SIZE, - bucket_sizes.bucket[MSGRNG_STNID_XMAC1JFR]); - xlr_write_reg(mmio, R_XGS_RFR_BUCKET_SIZE, - bucket_sizes.bucket[MSGRNG_STNID_XMAC1RFR]); - - for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { - xlr_write_reg(mmio, R_CC_CPU0_0 + i, - cc_table_xgs_1. - counters[i >> 3][i & 0x07]); - } - } - sc->rge_mii.mii_media.ifm_media = IFM_ETHER | IFM_AUTO | IFM_10G_SR | IFM_FDX; - sc->rge_mii.mii_media.ifm_media |= (IFM_AVALID | IFM_ACTIVE); - sc->rge_mii.mii_media.ifm_cur->ifm_media = IFM_ETHER | IFM_AUTO | IFM_10G_SR | IFM_FDX; - sc->rge_mii.mii_media_active = IFM_ETHER | IFM_AUTO | IFM_10G_SR | IFM_FDX; - sc->rge_mii.mii_media.ifm_cur->ifm_media |= (IFM_AVALID | IFM_ACTIVE); - - priv->init_frin_desc = 1; -} - -/******************************************************* - * Initialization gmac - *******************************************************/ -static int -rmi_xlr_gmac_reset(struct driver_data *priv) -{ - volatile uint32_t val; - xlr_reg_t *mmio = priv->mmio; - int i, maxloops = 100; - - /* Disable MAC RX */ - val = xlr_read_reg(mmio, R_MAC_CONFIG_1); - val &= ~0x4; - xlr_write_reg(mmio, R_MAC_CONFIG_1, val); - - /* Disable Core RX */ - val = xlr_read_reg(mmio, R_RX_CONTROL); - val &= ~0x1; - xlr_write_reg(mmio, R_RX_CONTROL, val); - - /* wait for rx to halt */ - for (i = 0; i < maxloops; i++) { - val = xlr_read_reg(mmio, R_RX_CONTROL); - if (val & 0x2) - break; - DELAY(1000); - } - if (i == maxloops) - return -1; - - /* Issue a soft reset */ - val = xlr_read_reg(mmio, R_RX_CONTROL); - val |= 0x4; - xlr_write_reg(mmio, R_RX_CONTROL, val); - - /* wait for reset to complete */ - for (i = 0; i < maxloops; i++) { - val = xlr_read_reg(mmio, R_RX_CONTROL); - if (val & 0x8) - break; - DELAY(1000); - } - if (i == maxloops) - return -1; - - /* Clear the soft reset bit */ - val = xlr_read_reg(mmio, R_RX_CONTROL); - val &= ~0x4; - xlr_write_reg(mmio, R_RX_CONTROL, val); - return 0; -} - -static void -rmi_xlr_gmac_init(struct driver_data *priv) -{ - int i = 0; - xlr_reg_t *mmio = priv->mmio; - int id = priv->instance; - struct stn_cc *gmac_cc_config; - uint32_t value = 0; - int blk = id / 4, port = id % 4; - - rmi_xlr_mac_set_enable(priv, 0); - - rmi_xlr_config_spill_area(priv); - - xlr_write_reg(mmio, R_DESC_PACK_CTRL, - (BYTE_OFFSET << O_DESC_PACK_CTRL__ByteOffset) | - (1 << O_DESC_PACK_CTRL__MaxEntry) | - (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize)); - - rmi_xlr_config_pde(priv); - rmi_xlr_config_parser(priv); - rmi_xlr_config_classifier(priv); - - xlr_write_reg(mmio, R_MSG_TX_THRESHOLD, 3); - xlr_write_reg(mmio, R_MAC_CONFIG_1, 0x35); - xlr_write_reg(mmio, R_RX_CONTROL, (0x7 << 6)); - - if (priv->mode == XLR_PORT0_RGMII) { - printf("Port 0 set in RGMII mode\n"); - value = xlr_read_reg(mmio, R_RX_CONTROL); - value |= 1 << O_RX_CONTROL__RGMII; - xlr_write_reg(mmio, R_RX_CONTROL, value); - } - rmi_xlr_mac_mii_init(priv); - - -#if 0 - priv->advertising = ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half | - ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half | - ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | - ADVERTISED_MII; -#endif - - /* - * Enable all MDIO interrupts in the phy RX_ER bit seems to be get - * set about every 1 sec in GigE mode, ignore it for now... - */ - rge_mii_write_internal(priv->mii_mmio, priv->phy_addr, 25, 0xfffffffe); - - if (priv->mode != XLR_RGMII) { - serdes_regs_init(priv); - serdes_autoconfig(priv); - } - rmi_xlr_gmac_config_speed(priv); - - value = xlr_read_reg(mmio, R_IPG_IFG); - xlr_write_reg(mmio, R_IPG_IFG, ((value & ~0x7f) | MAC_B2B_IPG)); - xlr_write_reg(mmio, R_DMACR0, 0xffffffff); - xlr_write_reg(mmio, R_DMACR1, 0xffffffff); - xlr_write_reg(mmio, R_DMACR2, 0xffffffff); - xlr_write_reg(mmio, R_DMACR3, 0xffffffff); - xlr_write_reg(mmio, R_STATCTRL, 0x04); - xlr_write_reg(mmio, R_L2ALLOCCTRL, 0xffffffff); - xlr_write_reg(mmio, R_INTMASK, 0); - xlr_write_reg(mmio, R_FREEQCARVE, 0); - - xlr_write_reg(mmio, R_GMAC_TX0_BUCKET_SIZE + port, - xlr_board_info.bucket_sizes->bucket[priv->txbucket]); - xlr_write_reg(mmio, R_GMAC_JFR0_BUCKET_SIZE, - xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_0]); - xlr_write_reg(mmio, R_GMAC_RFR0_BUCKET_SIZE, - xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_0]); - xlr_write_reg(mmio, R_GMAC_JFR1_BUCKET_SIZE, - xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_1]); - xlr_write_reg(mmio, R_GMAC_RFR1_BUCKET_SIZE, - xlr_board_info.bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_1]); - - dbg_msg("Programming credit counter %d : %d -> %d\n", blk, R_GMAC_TX0_BUCKET_SIZE + port, - xlr_board_info.bucket_sizes->bucket[priv->txbucket]); - - gmac_cc_config = xlr_board_info.gmac_block[blk].credit_config; - for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) { - xlr_write_reg(mmio, R_CC_CPU0_0 + i, - gmac_cc_config->counters[i >> 3][i & 0x07]); - dbg_msg("%d: %d -> %d\n", priv->instance, - R_CC_CPU0_0 + i, gmac_cc_config->counters[i >> 3][i & 0x07]); - } - priv->init_frin_desc = 1; -} - -/********************************************************************** - * Set promiscuous mode - **********************************************************************/ -static void -xlr_mac_set_rx_mode(struct rge_softc *sc) -{ - struct driver_data *priv = &(sc->priv); - uint32_t regval; - - regval = xlr_read_reg(priv->mmio, R_MAC_FILTER_CONFIG); - - if (sc->flags & IFF_PROMISC) { - regval |= (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | - (1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | - (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | - (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN); - } else { - regval &= ~((1 << O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN) | - (1 << O_MAC_FILTER_CONFIG__ALL_UCAST_EN)); - } - - xlr_write_reg(priv->mmio, R_MAC_FILTER_CONFIG, regval); -} - -/********************************************************************** - * Configure LAN speed for the specified MAC. - ********************************************************************* */ -static int -rmi_xlr_mac_set_speed(struct driver_data *s, xlr_mac_speed_t speed) -{ - return 0; -} - -/********************************************************************** - * Set Ethernet duplex and flow control options for this MAC - ********************************************************************* */ -static int -rmi_xlr_mac_set_duplex(struct driver_data *s, - xlr_mac_duplex_t duplex, xlr_mac_fc_t fc) -{ - return 0; -} - -/***************************************************************** - * Kernel Net Stack <-> MAC Driver Interface - *****************************************************************/ -/********************************************************************** - **********************************************************************/ -#define MAC_TX_FAIL 2 -#define MAC_TX_PASS 0 -#define MAC_TX_RETRY 1 - -int xlr_dev_queue_xmit_hack = 0; - -static int -mac_xmit(struct mbuf *m, struct rge_softc *sc, - struct driver_data *priv, int len, struct p2d_tx_desc *tx_desc) -{ - struct msgrng_msg msg = {0,0,0,0}; - int stid = priv->txbucket; - uint32_t tx_cycles = 0; - uint32_t mflags; - int vcpu = xlr_cpu_id(); - int rv; - - tx_cycles = mips_rd_count(); - - if (build_frag_list(m, &msg, tx_desc) != 0) - return MAC_TX_FAIL; - - else { - mflags = msgrng_access_enable(); - if ((rv = message_send(1, MSGRNG_CODE_MAC, stid, &msg)) != 0) { - msg_snd_failed++; - msgrng_restore(mflags); - release_tx_desc(&msg, 0); - xlr_rge_msg_snd_failed[vcpu]++; - dbg_msg("Failed packet to cpu %d, rv = %d, stid %d, msg0=%jx\n", - vcpu, rv, stid, (uintmax_t)msg.msg0); - return MAC_TX_FAIL; - } - msgrng_restore(mflags); - port_inc_counter(priv->instance, PORT_TX); - } - - /* Send the packet to MAC */ - dbg_msg("Sent tx packet to stid %d, msg0=%jx, msg1=%jx \n", stid, - (uintmax_t)msg.msg0, (uintmax_t)msg.msg1); -#ifdef DUMP_PACKETS - { - int i = 0; - unsigned char *buf = (char *)m->m_data; - - printf("Tx Packet: length=%d\n", len); - for (i = 0; i < 64; i++) { - if (i && (i % 16) == 0) - printf("\n"); - printf("%02x ", buf[i]); - } - printf("\n"); - } -#endif - xlr_inc_counter(NETIF_TX); - return MAC_TX_PASS; -} - -static int -rmi_xlr_mac_xmit(struct mbuf *m, struct rge_softc *sc, int len, struct p2d_tx_desc *tx_desc) -{ - struct driver_data *priv = &(sc->priv); - int ret = -ENOSPC; - - dbg_msg("IN\n"); - - xlr_inc_counter(NETIF_STACK_TX); - -retry: - ret = mac_xmit(m, sc, priv, len, tx_desc); - - if (ret == MAC_TX_RETRY) - goto retry; - - dbg_msg("OUT, ret = %d\n", ret); - if (ret == MAC_TX_FAIL) { - /* FULL */ - dbg_msg("Msg Ring Full. Stopping upper layer Q\n"); - port_inc_counter(priv->instance, PORT_STOPQ); - } - return ret; -} - -static void -mac_frin_replenish(void *args /* ignored */ ) -{ - int cpu = xlr_core_id(); - int done = 0; - int i = 0; - - xlr_inc_counter(REPLENISH_ENTER); - /* - * xlr_set_counter(REPLENISH_ENTER_COUNT, - * atomic_read(frin_to_be_sent)); - */ - xlr_set_counter(REPLENISH_CPU, PCPU_GET(cpuid)); - - for (;;) { - - done = 0; - - for (i = 0; i < XLR_MAX_MACS; i++) { - /* int offset = 0; */ - void *m; - uint32_t cycles; - struct rge_softc *sc; - struct driver_data *priv; - int frin_to_be_sent; - - sc = dev_mac[i]; - if (!sc) - goto skip; - - priv = &(sc->priv); - frin_to_be_sent = priv->frin_to_be_sent[cpu]; - - /* if (atomic_read(frin_to_be_sent) < 0) */ - if (frin_to_be_sent < 0) { - panic("BUG?: [%s]: gmac_%d illegal value for frin_to_be_sent=%d\n", - __FUNCTION__, i, - frin_to_be_sent); - } - /* if (!atomic_read(frin_to_be_sent)) */ - if (!frin_to_be_sent) - goto skip; - - cycles = mips_rd_count(); - { - m = get_buf(); - if (!m) { - device_printf(sc->rge_dev, "No buffer\n"); - goto skip; - } - } - xlr_inc_counter(REPLENISH_FRIN); - if (xlr_mac_send_fr(priv, vtophys(m), MAX_FRAME_SIZE)) { - free_buf(vtophys(m)); - printf("[%s]: rx free message_send failed!\n", __FUNCTION__); - break; - } - xlr_set_counter(REPLENISH_CYCLES, - (read_c0_count() - cycles)); - atomic_subtract_int((&priv->frin_to_be_sent[cpu]), 1); - - continue; - skip: - done++; - } - if (done == XLR_MAX_MACS) - break; - } -} - -static volatile uint32_t g_tx_frm_tx_ok=0; - -static void -rge_tx_bkp_func(void *arg, int npending) -{ - int i = 0; - - for (i = 0; i < xlr_board_info.gmacports; i++) { - if (!dev_mac[i] || !dev_mac[i]->active) - continue; - rge_start_locked(dev_mac[i]->rge_ifp, RGE_TX_THRESHOLD); - } - atomic_subtract_int(&g_tx_frm_tx_ok, 1); -} - -/* This function is called from an interrupt handler */ -void -rmi_xlr_mac_msgring_handler(int bucket, int size, int code, - int stid, struct msgrng_msg *msg, - void *data /* ignored */ ) -{ - uint64_t phys_addr = 0; - unsigned long addr = 0; - uint32_t length = 0; - int ctrl = 0, port = 0; - struct rge_softc *sc = NULL; - struct driver_data *priv = 0; - struct ifnet *ifp; - int vcpu = xlr_cpu_id(); - int cpu = xlr_core_id(); - - dbg_msg("mac: bucket=%d, size=%d, code=%d, stid=%d, msg0=%jx msg1=%jx\n", - bucket, size, code, stid, (uintmax_t)msg->msg0, (uintmax_t)msg->msg1); - - phys_addr = (uint64_t) (msg->msg0 & 0xffffffffe0ULL); - length = (msg->msg0 >> 40) & 0x3fff; - if (length == 0) { - ctrl = CTRL_REG_FREE; - port = (msg->msg0 >> 54) & 0x0f; - addr = 0; - } else { - ctrl = CTRL_SNGL; - length = length - BYTE_OFFSET - MAC_CRC_LEN; - port = msg->msg0 & 0x0f; - addr = 0; - } - - if (xlr_board_info.is_xls) { - if (stid == MSGRNG_STNID_GMAC1) - port += 4; - sc = dev_mac[dev_mac_gmac0 + port]; - } else { - if (stid == MSGRNG_STNID_XGS0FR) - sc = dev_mac[dev_mac_xgs0]; - else if (stid == MSGRNG_STNID_XGS1FR) - sc = dev_mac[dev_mac_xgs0 + 1]; - else - sc = dev_mac[dev_mac_gmac0 + port]; - } - if (sc == NULL) - return; - priv = &(sc->priv); - - dbg_msg("msg0 = %jx, stid = %d, port = %d, addr=%lx, length=%d, ctrl=%d\n", - (uintmax_t)msg->msg0, stid, port, addr, length, ctrl); - - if (ctrl == CTRL_REG_FREE || ctrl == CTRL_JUMBO_FREE) { - xlr_rge_tx_ok_done[vcpu]++; - release_tx_desc(msg, 1); - ifp = sc->rge_ifp; - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - } - if (atomic_cmpset_int(&g_tx_frm_tx_ok, 0, 1)) - rge_tx_bkp_func(NULL, 0); - xlr_set_counter(NETIF_TX_COMPLETE_CYCLES, - (read_c0_count() - msgrng_msg_cycles)); - } else if (ctrl == CTRL_SNGL || ctrl == CTRL_START) { - /* Rx Packet */ - /* struct mbuf *m = 0; */ - /* int logical_cpu = 0; */ - - dbg_msg("Received packet, port = %d\n", port); - /* - * if num frins to be sent exceeds threshold, wake up the - * helper thread - */ - atomic_add_int(&(priv->frin_to_be_sent[cpu]), 1); - if ((priv->frin_to_be_sent[cpu]) > MAC_FRIN_TO_BE_SENT_THRESHOLD) { - mac_frin_replenish(NULL); - } - dbg_msg("gmac_%d: rx packet: phys_addr = %jx, length = %x\n", - priv->instance, (uintmax_t)phys_addr, length); - mac_stats_add(priv->stats.rx_packets, 1); - mac_stats_add(priv->stats.rx_bytes, length); - xlr_inc_counter(NETIF_RX); - xlr_set_counter(NETIF_RX_CYCLES, - (read_c0_count() - msgrng_msg_cycles)); - rge_rx(sc, phys_addr, length); - xlr_rge_rx_done[vcpu]++; - } else { - printf("[%s]: unrecognized ctrl=%d!\n", __FUNCTION__, ctrl); - } - -} - -/********************************************************************** - **********************************************************************/ -static int -rge_probe(dev) - device_t dev; -{ - device_set_desc(dev, "RMI Gigabit Ethernet"); - - /* Always return 0 */ - return 0; -} - -volatile unsigned long xlr_debug_enabled; -struct callout rge_dbg_count; -static void -xlr_debug_count(void *addr) -{ - struct driver_data *priv = &dev_mac[0]->priv; - - /* uint32_t crdt; */ - if (xlr_debug_enabled) { - printf("\nAvailRxIn %#x\n", xlr_read_reg(priv->mmio, 0x23e)); - } - callout_reset(&rge_dbg_count, hz, xlr_debug_count, NULL); -} - - -static void -xlr_tx_q_wakeup(void *addr) -{ - int i = 0; - int j = 0; - - for (i = 0; i < xlr_board_info.gmacports; i++) { - if (!dev_mac[i] || !dev_mac[i]->active) - continue; - if ((dev_mac[i]->rge_ifp->if_drv_flags) & IFF_DRV_OACTIVE) { - for (j = 0; j < XLR_MAX_CORE; j++) { - if (xlr_tot_avail_p2d[j]) { - dev_mac[i]->rge_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - break; - } - } - } - } - if (atomic_cmpset_int(&g_tx_frm_tx_ok, 0, 1)) - rge_tx_bkp_func(NULL, 0); - callout_reset(&xlr_tx_stop_bkp, 5 * hz, xlr_tx_q_wakeup, NULL); -} - -static int -rge_attach(device_t dev) -{ - struct ifnet *ifp; - struct rge_softc *sc; - struct driver_data *priv = 0; - int ret = 0; - struct xlr_gmac_block_t *gmac_conf = device_get_ivars(dev); - - sc = device_get_softc(dev); - sc->rge_dev = dev; - - /* Initialize mac's */ - sc->unit = device_get_unit(dev); - - if (sc->unit > XLR_MAX_MACS) { - ret = ENXIO; - goto out; - } - RGE_LOCK_INIT(sc, device_get_nameunit(dev)); - - priv = &(sc->priv); - priv->sc = sc; - - sc->flags = 0; /* TODO : fix me up later */ - - priv->id = sc->unit; - if (gmac_conf->type == XLR_GMAC) { - priv->instance = priv->id; - priv->mmio = (xlr_reg_t *) (xlr_io_base + gmac_conf->baseaddr + - 0x1000 * (sc->unit % 4)); - if ((ret = rmi_xlr_gmac_reset(priv)) == -1) - goto out; - } else if (gmac_conf->type == XLR_XGMAC) { - priv->instance = priv->id - xlr_board_info.gmacports; - priv->mmio = (xlr_reg_t *) (xlr_io_base + gmac_conf->baseaddr); - } - if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_VI || - (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_XI && - priv->instance >=4)) { - dbg_msg("Arizona board - offset 4 \n"); - priv->mii_mmio = (xlr_reg_t *) (xlr_io_base + XLR_IO_GMAC_4_OFFSET); - } else - priv->mii_mmio = (xlr_reg_t *) (xlr_io_base + XLR_IO_GMAC_0_OFFSET); - - priv->pcs_mmio = (xlr_reg_t *) (xlr_io_base + gmac_conf->baseaddr); - priv->serdes_mmio = (xlr_reg_t *) (xlr_io_base + XLR_IO_GMAC_0_OFFSET); - - sc->base_addr = (unsigned long)priv->mmio; - sc->mem_end = (unsigned long)priv->mmio + XLR_IO_SIZE - 1; - - sc->xmit = rge_start; - sc->stop = rge_stop; - sc->get_stats = rmi_xlr_mac_get_stats; - sc->ioctl = rge_ioctl; - - /* Initialize the device specific driver data */ - mtx_init(&priv->lock, "rge", NULL, MTX_SPIN); - - priv->type = gmac_conf->type; - - priv->mode = gmac_conf->mode; - if (xlr_board_info.is_xls == 0) { - /* TODO - check II and IIB boards */ - if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_II && - xlr_boot1_info.board_minor_version != 1) - priv->phy_addr = priv->instance - 2; - else - priv->phy_addr = priv->instance; - priv->mode = XLR_RGMII; - } else { - if (gmac_conf->mode == XLR_PORT0_RGMII && - priv->instance == 0) { - priv->mode = XLR_PORT0_RGMII; - priv->phy_addr = 0; - } else { - priv->mode = XLR_SGMII; - /* Board 11 has SGMII daughter cards with the XLS chips, in this case - the phy number is 0-3 for both GMAC blocks */ - if (xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_XI) - priv->phy_addr = priv->instance % 4 + 16; - else - priv->phy_addr = priv->instance + 16; - } - } - - priv->txbucket = gmac_conf->station_txbase + priv->instance % 4; - priv->rfrbucket = gmac_conf->station_rfr; - priv->spill_configured = 0; - - dbg_msg("priv->mmio=%p\n", priv->mmio); - - /* Set up ifnet structure */ - ifp = sc->rge_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(sc->rge_dev, "failed to if_alloc()\n"); - rge_release_resources(sc); - ret = ENXIO; - RGE_LOCK_DESTROY(sc); - goto out; - } - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_ioctl = rge_ioctl; - ifp->if_start = rge_start; - ifp->if_init = rge_init; - ifp->if_mtu = ETHERMTU; - ifp->if_snd.ifq_drv_maxlen = RGE_TX_Q_SIZE; - IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); - IFQ_SET_READY(&ifp->if_snd); - sc->active = 1; - ifp->if_hwassist = 0; - ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_HWTAGGING; - ifp->if_capenable = ifp->if_capabilities; - - /* Initialize the rge_softc */ - sc->irq = gmac_conf->baseirq + priv->instance % 4; - - /* Set the IRQ into the rid field */ - /* - * note this is a hack to pass the irq to the iodi interrupt setup - * routines - */ - sc->rge_irq.__r_i = (struct resource_i *)(intptr_t)sc->irq; - - ret = bus_setup_intr(dev, &sc->rge_irq, INTR_TYPE_NET | INTR_MPSAFE, - NULL, rge_intr, sc, &sc->rge_intrhand); - - if (ret) { - rge_detach(dev); - device_printf(sc->rge_dev, "couldn't set up irq\n"); - RGE_LOCK_DESTROY(sc); - goto out; - } - xlr_mac_get_hwaddr(sc); - xlr_mac_setup_hwaddr(priv); - - dbg_msg("MMIO %08lx, MII %08lx, PCS %08lx, base %08lx PHY %d IRQ %d\n", - (u_long)priv->mmio, (u_long)priv->mii_mmio, (u_long)priv->pcs_mmio, - (u_long)sc->base_addr, priv->phy_addr, sc->irq); - dbg_msg("HWADDR %02x:%02x tx %d rfr %d\n", (u_int)sc->dev_addr[4], - (u_int)sc->dev_addr[5], priv->txbucket, priv->rfrbucket); - - /* - * Set up ifmedia support. - */ - /* - * Initialize MII/media info. - */ - sc->rge_mii.mii_ifp = ifp; - sc->rge_mii.mii_readreg = rge_mii_read; - sc->rge_mii.mii_writereg = (mii_writereg_t) rge_mii_write; - sc->rge_mii.mii_statchg = rmi_xlr_mac_mii_statchg; - ifmedia_init(&sc->rge_mii.mii_media, 0, rmi_xlr_mac_mediachange, - rmi_xlr_mac_mediastatus); - ifmedia_add(&sc->rge_mii.mii_media, IFM_ETHER | IFM_AUTO, 0, NULL); - ifmedia_set(&sc->rge_mii.mii_media, IFM_ETHER | IFM_AUTO); - sc->rge_mii.mii_media.ifm_media = sc->rge_mii.mii_media.ifm_cur->ifm_media; - - /* - * Call MI attach routine. - */ - ether_ifattach(ifp, sc->dev_addr); - - if (priv->type == XLR_GMAC) { - rmi_xlr_gmac_init(priv); - } else if (priv->type == XLR_XGMAC) { - rmi_xlr_xgmac_init(priv); - } - dbg_msg("rge_%d: Phoenix Mac at 0x%p (mtu=%d)\n", - sc->unit, priv->mmio, sc->mtu); - dev_mac[sc->unit] = sc; - if (priv->type == XLR_XGMAC && priv->instance == 0) - dev_mac_xgs0 = sc->unit; - if (priv->type == XLR_GMAC && priv->instance == 0) - dev_mac_gmac0 = sc->unit; - - if (!gmac_common_init_done) { - mac_common_init(); - gmac_common_init_done = 1; - callout_init(&xlr_tx_stop_bkp, 1); - callout_reset(&xlr_tx_stop_bkp, hz, xlr_tx_q_wakeup, NULL); - callout_init(&rge_dbg_count, 1); - //callout_reset(&rge_dbg_count, hz, xlr_debug_count, NULL); - } - if ((ret = rmi_xlr_mac_open(sc)) == -1) { - RGE_LOCK_DESTROY(sc); - goto out; - } -out: - if (ret < 0) { - device_printf(dev, "error - skipping\n"); - } - return ret; -} - -static void -rge_reset(struct rge_softc *sc) -{ -} - -static int -rge_detach(dev) - device_t dev; -{ -#ifdef FREEBSD_MAC_NOT_YET - struct rge_softc *sc; - struct ifnet *ifp; - - sc = device_get_softc(dev); - ifp = sc->rge_ifp; - - RGE_LOCK(sc); - rge_stop(sc); - rge_reset(sc); - RGE_UNLOCK(sc); - - ether_ifdetach(ifp); - - if (sc->rge_tbi) { - ifmedia_removeall(&sc->rge_ifmedia); - } else { - bus_generic_detach(dev); - device_delete_child(dev, sc->rge_miibus); - } - - rge_release_resources(sc); - -#endif /* FREEBSD_MAC_NOT_YET */ - return (0); -} -static int -rge_suspend(device_t dev) -{ - struct rge_softc *sc; - - sc = device_get_softc(dev); - RGE_LOCK(sc); - rge_stop(sc); - RGE_UNLOCK(sc); - - return 0; -} - -static int -rge_resume(device_t dev) -{ - panic("rge_resume(): unimplemented\n"); - return 0; -} - -static void -rge_release_resources(struct rge_softc *sc) -{ - - if (sc->rge_ifp != NULL) - if_free(sc->rge_ifp); - - if (mtx_initialized(&sc->rge_mtx)) /* XXX */ - RGE_LOCK_DESTROY(sc); -} -uint32_t gmac_rx_fail[32]; -uint32_t gmac_rx_pass[32]; - -static void -rge_rx(struct rge_softc *sc, vm_paddr_t paddr, int len) -{ - struct mbuf *m; - struct ifnet *ifp = sc->rge_ifp; - uint64_t mag; - uint32_t sr; - /* - * On 32 bit machines we use XKPHYS to get the values stores with - * the mbuf, need to explicitly enable KX. Disable interrupts while - * KX is enabled to prevent this setting leaking to other code. - */ - sr = xlr_enable_kx(); - m = (struct mbuf *)(intptr_t)xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE); - mag = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE + sizeof(uint64_t)); - xlr_restore_kx(sr); - if (mag != 0xf00bad) { - /* somebody else packet Error - FIXME in intialization */ - printf("cpu %d: *ERROR* Not my packet paddr %p\n", - xlr_cpu_id(), (void *)paddr); - return; - } - /* align the data */ - m->m_data += BYTE_OFFSET; - m->m_pkthdr.len = m->m_len = len; - m->m_pkthdr.rcvif = ifp; - -#ifdef DUMP_PACKETS - { - int i = 0; - unsigned char *buf = (char *)m->m_data; - - printf("Rx Packet: length=%d\n", len); - for (i = 0; i < 64; i++) { - if (i && (i % 16) == 0) - printf("\n"); - printf("%02x ", buf[i]); - } - printf("\n"); - } -#endif - if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); - (*ifp->if_input) (ifp, m); -} - -static void -rge_intr(void *arg) -{ - struct rge_softc *sc = (struct rge_softc *)arg; - struct driver_data *priv = &(sc->priv); - xlr_reg_t *mmio = priv->mmio; - uint32_t intreg = xlr_read_reg(mmio, R_INTREG); - - if (intreg & (1 << O_INTREG__MDInt)) { - uint32_t phy_int_status = 0; - int i = 0; - - for (i = 0; i < XLR_MAX_MACS; i++) { - struct rge_softc *phy_dev = 0; - struct driver_data *phy_priv = 0; - - phy_dev = dev_mac[i]; - if (phy_dev == NULL) - continue; - - phy_priv = &phy_dev->priv; - - if (phy_priv->type == XLR_XGMAC) - continue; - - phy_int_status = rge_mii_read_internal(phy_priv->mii_mmio, - phy_priv->phy_addr, 26); - printf("rge%d: Phy addr %d, MII MMIO %lx status %x\n", phy_priv->instance, - (int)phy_priv->phy_addr, (u_long)phy_priv->mii_mmio, phy_int_status); - rmi_xlr_gmac_config_speed(phy_priv); - } - } else { - printf("[%s]: mac type = %d, instance %d error " - "interrupt: INTREG = 0x%08x\n", - __FUNCTION__, priv->type, priv->instance, intreg); - } - - /* clear all interrupts and hope to make progress */ - xlr_write_reg(mmio, R_INTREG, 0xffffffff); - - /* (not yet) on A0 and B0, xgmac interrupts are routed only to xgs_1 irq */ - if ((xlr_revision() < 2) && (priv->type == XLR_XGMAC)) { - struct rge_softc *xgs0_dev = dev_mac[dev_mac_xgs0]; - struct driver_data *xgs0_priv = &xgs0_dev->priv; - xlr_reg_t *xgs0_mmio = xgs0_priv->mmio; - uint32_t xgs0_intreg = xlr_read_reg(xgs0_mmio, R_INTREG); - - if (xgs0_intreg) { - printf("[%s]: mac type = %d, instance %d error " - "interrupt: INTREG = 0x%08x\n", - __FUNCTION__, xgs0_priv->type, xgs0_priv->instance, xgs0_intreg); - - xlr_write_reg(xgs0_mmio, R_INTREG, 0xffffffff); - } - } -} - -static void -rge_start_locked(struct ifnet *ifp, int threshold) -{ - struct rge_softc *sc = ifp->if_softc; - struct mbuf *m = NULL; - int prepend_pkt = 0; - int i = 0; - struct p2d_tx_desc *tx_desc = NULL; - int cpu = xlr_core_id(); - uint32_t vcpu = xlr_cpu_id(); - - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - return; - - for (i = 0; i < xlr_tot_avail_p2d[cpu]; i++) { - if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - return; - tx_desc = get_p2d_desc(); - if (!tx_desc) { - xlr_rge_get_p2d_failed[vcpu]++; - return; - } - /* Grab a packet off the queue. */ - IFQ_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) { - free_p2d_desc(tx_desc); - return; - } - prepend_pkt = rmi_xlr_mac_xmit(m, sc, 0, tx_desc); - - if (prepend_pkt) { - xlr_rge_tx_prepend[vcpu]++; - IF_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return; - } else { - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); - xlr_rge_tx_done[vcpu]++; - } - } -} - -static void -rge_start(struct ifnet *ifp) -{ - rge_start_locked(ifp, RGE_TX_Q_SIZE); -} - -static int -rge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct rge_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *)data; - int mask, error = 0; - - /* struct mii_data *mii; */ - switch (command) { - case SIOCSIFMTU: - ifp->if_mtu = ifr->ifr_mtu; - error = rmi_xlr_mac_change_mtu(sc, ifr->ifr_mtu); - break; - case SIOCSIFFLAGS: - - RGE_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - /* - * If only the state of the PROMISC flag changed, - * then just use the 'set promisc mode' command - * instead of reinitializing the entire NIC. Doing a - * full re-init means reloading the firmware and - * waiting for it to start up, which may take a - * second or two. Similarly for ALLMULTI. - */ - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->flags & IFF_PROMISC)) { - sc->flags |= IFF_PROMISC; - xlr_mac_set_rx_mode(sc); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->flags & IFF_PROMISC) { - sc->flags &= IFF_PROMISC; - xlr_mac_set_rx_mode(sc); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - (ifp->if_flags ^ sc->flags) & IFF_ALLMULTI) { - rmi_xlr_mac_set_multicast_list(sc); - } else - xlr_mac_set_rx_mode(sc); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - xlr_mac_set_rx_mode(sc); - } - } - sc->flags = ifp->if_flags; - RGE_UNLOCK(sc); - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - RGE_LOCK(sc); - rmi_xlr_mac_set_multicast_list(sc); - RGE_UNLOCK(sc); - error = 0; - } - break; - case SIOCSIFMEDIA: - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, - &sc->rge_mii.mii_media, command); - break; - case SIOCSIFCAP: - mask = ifr->ifr_reqcap ^ ifp->if_capenable; - ifp->if_hwassist = 0; - break; - default: - error = ether_ioctl(ifp, command, data); - break; - } - - return (error); -} - -static void -rge_init(void *addr) -{ - struct rge_softc *sc = (struct rge_softc *)addr; - struct ifnet *ifp; - struct driver_data *priv = &(sc->priv); - - ifp = sc->rge_ifp; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - return; - ifp->if_drv_flags |= IFF_DRV_RUNNING; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - rmi_xlr_mac_set_enable(priv, 1); -} - -static void -rge_stop(struct rge_softc *sc) -{ - rmi_xlr_mac_close(sc); -} - -static int -rge_shutdown(device_t dev) -{ - struct rge_softc *sc; - - sc = device_get_softc(dev); - - RGE_LOCK(sc); - rge_stop(sc); - rge_reset(sc); - RGE_UNLOCK(sc); - - return (0); -} - -static int -rmi_xlr_mac_open(struct rge_softc *sc) -{ - struct driver_data *priv = &(sc->priv); - int i; - - dbg_msg("IN\n"); - - if (rmi_xlr_mac_fill_rxfr(sc)) { - return -1; - } - mtx_lock_spin(&priv->lock); - - xlr_mac_set_rx_mode(sc); - - if (sc->unit == xlr_board_info.gmacports - 1) { - printf("Enabling MDIO interrupts\n"); - struct rge_softc *tmp = NULL; - - for (i = 0; i < xlr_board_info.gmacports; i++) { - tmp = dev_mac[i]; - if (tmp) - xlr_write_reg(tmp->priv.mmio, R_INTMASK, - ((tmp->priv.instance == 0) << O_INTMASK__MDInt)); - } - } - /* - * Configure the speed, duplex, and flow control - */ - rmi_xlr_mac_set_speed(priv, priv->speed); - rmi_xlr_mac_set_duplex(priv, priv->duplex, priv->flow_ctrl); - rmi_xlr_mac_set_enable(priv, 0); - - mtx_unlock_spin(&priv->lock); - - for (i = 0; i < 8; i++) { - priv->frin_to_be_sent[i] = 0; - } - - return 0; -} - -/********************************************************************** - **********************************************************************/ -static int -rmi_xlr_mac_close(struct rge_softc *sc) -{ - struct driver_data *priv = &(sc->priv); - - mtx_lock_spin(&priv->lock); - - /* - * There may have left over mbufs in the ring as well as in free in - * they will be reused next time open is called - */ - - rmi_xlr_mac_set_enable(priv, 0); - - xlr_inc_counter(NETIF_STOP_Q); - port_inc_counter(priv->instance, PORT_STOPQ); - - mtx_unlock_spin(&priv->lock); - - return 0; -} - -/********************************************************************** - **********************************************************************/ -static struct rge_softc_stats * -rmi_xlr_mac_get_stats(struct rge_softc *sc) -{ - struct driver_data *priv = &(sc->priv); - - /* unsigned long flags; */ - - mtx_lock_spin(&priv->lock); - - /* XXX update other stats here */ - - mtx_unlock_spin(&priv->lock); - - return &priv->stats; -} - -/********************************************************************** - **********************************************************************/ -static void -rmi_xlr_mac_set_multicast_list(struct rge_softc *sc) -{ -} - -/********************************************************************** - **********************************************************************/ -static int -rmi_xlr_mac_change_mtu(struct rge_softc *sc, int new_mtu) -{ - struct driver_data *priv = &(sc->priv); - - if ((new_mtu > 9500) || (new_mtu < 64)) { - return -EINVAL; - } - mtx_lock_spin(&priv->lock); - - sc->mtu = new_mtu; - - /* Disable MAC TX/RX */ - rmi_xlr_mac_set_enable(priv, 0); - - /* Flush RX FR IN */ - /* Flush TX IN */ - rmi_xlr_mac_set_enable(priv, 1); - - mtx_unlock_spin(&priv->lock); - return 0; -} - -/********************************************************************** - **********************************************************************/ -static int -rmi_xlr_mac_fill_rxfr(struct rge_softc *sc) -{ - struct driver_data *priv = &(sc->priv); - int i; - int ret = 0; - void *ptr; - - dbg_msg("\n"); - if (!priv->init_frin_desc) - return ret; - priv->init_frin_desc = 0; - - dbg_msg("\n"); - for (i = 0; i < MAX_NUM_DESC; i++) { - ptr = get_buf(); - if (!ptr) { - ret = -ENOMEM; - break; - } - /* Send the free Rx desc to the MAC */ - xlr_mac_send_fr(priv, vtophys(ptr), MAX_FRAME_SIZE); - } - - return ret; -} - -/********************************************************************** - **********************************************************************/ -static __inline__ void * -rmi_xlr_config_spill(xlr_reg_t * mmio, - int reg_start_0, int reg_start_1, - int reg_size, int size) -{ - uint32_t spill_size = size; - void *spill = NULL; - uint64_t phys_addr = 0; - - - spill = contigmalloc((spill_size + XLR_CACHELINE_SIZE), M_DEVBUF, - M_NOWAIT | M_ZERO, 0, 0xffffffff, XLR_CACHELINE_SIZE, 0); - if (!spill || ((vm_offset_t)spill & (XLR_CACHELINE_SIZE - 1))) { - panic("Unable to allocate memory for spill area!\n"); - } - phys_addr = vtophys(spill); - dbg_msg("Allocate spill %d bytes at %jx\n", size, (uintmax_t)phys_addr); - xlr_write_reg(mmio, reg_start_0, (phys_addr >> 5) & 0xffffffff); - xlr_write_reg(mmio, reg_start_1, (phys_addr >> 37) & 0x07); - xlr_write_reg(mmio, reg_size, spill_size); - - return spill; -} - -static void -rmi_xlr_config_spill_area(struct driver_data *priv) -{ - /* - * if driver initialization is done parallely on multiple cpus - * spill_configured needs synchronization - */ - if (priv->spill_configured) - return; - - if (priv->type == XLR_GMAC && priv->instance % 4 != 0) { - priv->spill_configured = 1; - return; - } - priv->spill_configured = 1; - - priv->frin_spill = - rmi_xlr_config_spill(priv->mmio, - R_REG_FRIN_SPILL_MEM_START_0, - R_REG_FRIN_SPILL_MEM_START_1, - R_REG_FRIN_SPILL_MEM_SIZE, - MAX_FRIN_SPILL * - sizeof(struct fr_desc)); - - priv->class_0_spill = - rmi_xlr_config_spill(priv->mmio, - R_CLASS0_SPILL_MEM_START_0, - R_CLASS0_SPILL_MEM_START_1, - R_CLASS0_SPILL_MEM_SIZE, - MAX_CLASS_0_SPILL * - sizeof(union rx_tx_desc)); - priv->class_1_spill = - rmi_xlr_config_spill(priv->mmio, - R_CLASS1_SPILL_MEM_START_0, - R_CLASS1_SPILL_MEM_START_1, - R_CLASS1_SPILL_MEM_SIZE, - MAX_CLASS_1_SPILL * - sizeof(union rx_tx_desc)); - - priv->frout_spill = - rmi_xlr_config_spill(priv->mmio, R_FROUT_SPILL_MEM_START_0, - R_FROUT_SPILL_MEM_START_1, - R_FROUT_SPILL_MEM_SIZE, - MAX_FROUT_SPILL * - sizeof(struct fr_desc)); - - priv->class_2_spill = - rmi_xlr_config_spill(priv->mmio, - R_CLASS2_SPILL_MEM_START_0, - R_CLASS2_SPILL_MEM_START_1, - R_CLASS2_SPILL_MEM_SIZE, - MAX_CLASS_2_SPILL * - sizeof(union rx_tx_desc)); - priv->class_3_spill = - rmi_xlr_config_spill(priv->mmio, - R_CLASS3_SPILL_MEM_START_0, - R_CLASS3_SPILL_MEM_START_1, - R_CLASS3_SPILL_MEM_SIZE, - MAX_CLASS_3_SPILL * - sizeof(union rx_tx_desc)); - priv->spill_configured = 1; -} - -/***************************************************************** - * Write the MAC address to the XLR registers - * All 4 addresses are the same for now - *****************************************************************/ -static void -xlr_mac_setup_hwaddr(struct driver_data *priv) -{ - struct rge_softc *sc = priv->sc; - - xlr_write_reg(priv->mmio, R_MAC_ADDR0, - ((sc->dev_addr[5] << 24) | (sc->dev_addr[4] << 16) - | (sc->dev_addr[3] << 8) | (sc->dev_addr[2])) - ); - - xlr_write_reg(priv->mmio, R_MAC_ADDR0 + 1, - ((sc->dev_addr[1] << 24) | (sc-> - dev_addr[0] << 16))); - - xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK2, 0xffffffff); - - xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK2 + 1, 0xffffffff); - - xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK3, 0xffffffff); - - xlr_write_reg(priv->mmio, R_MAC_ADDR_MASK3 + 1, 0xffffffff); - - xlr_write_reg(priv->mmio, R_MAC_FILTER_CONFIG, - (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) | - (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) | - (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID) - ); -} - -/***************************************************************** - * Read the MAC address from the XLR registers - * All 4 addresses are the same for now - *****************************************************************/ -static void -xlr_mac_get_hwaddr(struct rge_softc *sc) -{ - struct driver_data *priv = &(sc->priv); - - sc->dev_addr[0] = (xlr_boot1_info.mac_addr >> 40) & 0xff; - sc->dev_addr[1] = (xlr_boot1_info.mac_addr >> 32) & 0xff; - sc->dev_addr[2] = (xlr_boot1_info.mac_addr >> 24) & 0xff; - sc->dev_addr[3] = (xlr_boot1_info.mac_addr >> 16) & 0xff; - sc->dev_addr[4] = (xlr_boot1_info.mac_addr >> 8) & 0xff; - sc->dev_addr[5] = ((xlr_boot1_info.mac_addr >> 0) & 0xff) + priv->instance; -} - -/***************************************************************** - * Mac Module Initialization - *****************************************************************/ -static void -mac_common_init(void) -{ - init_p2d_allocation(); - init_tx_ring(); - - if (xlr_board_info.is_xls) { - if (register_msgring_handler(MSGRNG_STNID_GMAC, - MSGRNG_STNID_GMAC + 1, rmi_xlr_mac_msgring_handler, - NULL)) { - panic("Couldn't register msgring handler\n"); - } - if (register_msgring_handler(MSGRNG_STNID_GMAC1, - MSGRNG_STNID_GMAC1 + 1, rmi_xlr_mac_msgring_handler, - NULL)) { - panic("Couldn't register msgring handler\n"); - } - } else { - if (register_msgring_handler(MSGRNG_STNID_GMAC, - MSGRNG_STNID_GMAC + 1, rmi_xlr_mac_msgring_handler, - NULL)) { - panic("Couldn't register msgring handler\n"); - } - } - - /* - * Not yet if (xlr_board_atx_ii()) { if (register_msgring_handler - * (TX_STN_XGS_0, rmi_xlr_mac_msgring_handler, NULL)) { - * panic("Couldn't register msgring handler for TX_STN_XGS_0\n"); } - * if (register_msgring_handler (TX_STN_XGS_1, - * rmi_xlr_mac_msgring_handler, NULL)) { panic("Couldn't register - * msgring handler for TX_STN_XGS_1\n"); } } - */ -} Property changes on: head/sys/mips/rmi/dev/xlr/rge.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/mips/rmi/dev/xlr/rge.h =================================================================== --- head/sys/mips/rmi/dev/xlr/rge.h (revision 287470) +++ head/sys/mips/rmi/dev/xlr/rge.h (nonexistent) @@ -1,1098 +0,0 @@ -/*- - * Copyright (c) 2003-2009 RMI Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of RMI Corporation, nor the names of its contributors, - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * RMI_BSD */ -#ifndef _RMI_RGE_H_ -#define _RMI_RGE_H_ - -/* #define MAC_SPLIT_MODE */ - -#define MAC_SPACING 0x400 -#define XGMAC_SPACING 0x400 - -/* PE-MCXMAC register and bit field definitions */ -#define R_MAC_CONFIG_1 0x00 -#define O_MAC_CONFIG_1__srst 31 -#define O_MAC_CONFIG_1__simr 30 -#define O_MAC_CONFIG_1__hrrmc 18 -#define W_MAC_CONFIG_1__hrtmc 2 -#define O_MAC_CONFIG_1__hrrfn 16 -#define W_MAC_CONFIG_1__hrtfn 2 -#define O_MAC_CONFIG_1__intlb 8 -#define O_MAC_CONFIG_1__rxfc 5 -#define O_MAC_CONFIG_1__txfc 4 -#define O_MAC_CONFIG_1__srxen 3 -#define O_MAC_CONFIG_1__rxen 2 -#define O_MAC_CONFIG_1__stxen 1 -#define O_MAC_CONFIG_1__txen 0 -#define R_MAC_CONFIG_2 0x01 -#define O_MAC_CONFIG_2__prlen 12 -#define W_MAC_CONFIG_2__prlen 4 -#define O_MAC_CONFIG_2__speed 8 -#define W_MAC_CONFIG_2__speed 2 -#define O_MAC_CONFIG_2__hugen 5 -#define O_MAC_CONFIG_2__flchk 4 -#define O_MAC_CONFIG_2__crce 1 -#define O_MAC_CONFIG_2__fulld 0 -#define R_IPG_IFG 0x02 -#define O_IPG_IFG__ipgr1 24 -#define W_IPG_IFG__ipgr1 7 -#define O_IPG_IFG__ipgr2 16 -#define W_IPG_IFG__ipgr2 7 -#define O_IPG_IFG__mifg 8 -#define W_IPG_IFG__mifg 8 -#define O_IPG_IFG__ipgt 0 -#define W_IPG_IFG__ipgt 7 -#define R_HALF_DUPLEX 0x03 -#define O_HALF_DUPLEX__abebt 24 -#define W_HALF_DUPLEX__abebt 4 -#define O_HALF_DUPLEX__abebe 19 -#define O_HALF_DUPLEX__bpnb 18 -#define O_HALF_DUPLEX__nobo 17 -#define O_HALF_DUPLEX__edxsdfr 16 -#define O_HALF_DUPLEX__retry 12 -#define W_HALF_DUPLEX__retry 4 -#define O_HALF_DUPLEX__lcol 0 -#define W_HALF_DUPLEX__lcol 10 -#define R_MAXIMUM_FRAME_LENGTH 0x04 -#define O_MAXIMUM_FRAME_LENGTH__maxf 0 -#define W_MAXIMUM_FRAME_LENGTH__maxf 16 -#define R_TEST 0x07 -#define O_TEST__mbof 3 -#define O_TEST__rthdf 2 -#define O_TEST__tpause 1 -#define O_TEST__sstct 0 -#define R_MII_MGMT_CONFIG 0x08 -#define O_MII_MGMT_CONFIG__scinc 5 -#define O_MII_MGMT_CONFIG__spre 4 -#define O_MII_MGMT_CONFIG__clks 3 -#define W_MII_MGMT_CONFIG__clks 3 -#define R_MII_MGMT_COMMAND 0x09 -#define O_MII_MGMT_COMMAND__scan 1 -#define O_MII_MGMT_COMMAND__rstat 0 -#define R_MII_MGMT_ADDRESS 0x0A -#define O_MII_MGMT_ADDRESS__fiad 8 -#define W_MII_MGMT_ADDRESS__fiad 5 -#define O_MII_MGMT_ADDRESS__fgad 5 -#define W_MII_MGMT_ADDRESS__fgad 0 -#define R_MII_MGMT_WRITE_DATA 0x0B -#define O_MII_MGMT_WRITE_DATA__ctld 0 -#define W_MII_MGMT_WRITE_DATA__ctld 16 -#define R_MII_MGMT_STATUS 0x0C -#define R_MII_MGMT_INDICATORS 0x0D -#define O_MII_MGMT_INDICATORS__nvalid 2 -#define O_MII_MGMT_INDICATORS__scan 1 -#define O_MII_MGMT_INDICATORS__busy 0 -#define R_INTERFACE_CONTROL 0x0E -#define O_INTERFACE_CONTROL__hrstint 31 -#define O_INTERFACE_CONTROL__tbimode 27 -#define O_INTERFACE_CONTROL__ghdmode 26 -#define O_INTERFACE_CONTROL__lhdmode 25 -#define O_INTERFACE_CONTROL__phymod 24 -#define O_INTERFACE_CONTROL__hrrmi 23 -#define O_INTERFACE_CONTROL__rspd 16 -#define O_INTERFACE_CONTROL__hr100 15 -#define O_INTERFACE_CONTROL__frcq 10 -#define O_INTERFACE_CONTROL__nocfr 9 -#define O_INTERFACE_CONTROL__dlfct 8 -#define O_INTERFACE_CONTROL__enjab 0 -#define R_INTERFACE_STATUS 0x0F -#define O_INTERFACE_STATUS__xsdfr 9 -#define O_INTERFACE_STATUS__ssrr 8 -#define W_INTERFACE_STATUS__ssrr 5 -#define O_INTERFACE_STATUS__miilf 3 -#define O_INTERFACE_STATUS__locar 2 -#define O_INTERFACE_STATUS__sqerr 1 -#define O_INTERFACE_STATUS__jabber 0 -#define R_STATION_ADDRESS_LS 0x10 -#define R_STATION_ADDRESS_MS 0x11 - -/* A-XGMAC register and bit field definitions */ -#define R_XGMAC_CONFIG_0 0x00 -#define O_XGMAC_CONFIG_0__hstmacrst 31 -#define O_XGMAC_CONFIG_0__hstrstrctl 23 -#define O_XGMAC_CONFIG_0__hstrstrfn 22 -#define O_XGMAC_CONFIG_0__hstrsttctl 18 -#define O_XGMAC_CONFIG_0__hstrsttfn 17 -#define O_XGMAC_CONFIG_0__hstrstmiim 16 -#define O_XGMAC_CONFIG_0__hstloopback 8 -#define R_XGMAC_CONFIG_1 0x01 -#define O_XGMAC_CONFIG_1__hsttctlen 31 -#define O_XGMAC_CONFIG_1__hsttfen 30 -#define O_XGMAC_CONFIG_1__hstrctlen 29 -#define O_XGMAC_CONFIG_1__hstrfen 28 -#define O_XGMAC_CONFIG_1__tfen 26 -#define O_XGMAC_CONFIG_1__rfen 24 -#define O_XGMAC_CONFIG_1__hstrctlshrtp 12 -#define O_XGMAC_CONFIG_1__hstdlyfcstx 10 -#define W_XGMAC_CONFIG_1__hstdlyfcstx 2 -#define O_XGMAC_CONFIG_1__hstdlyfcsrx 8 -#define W_XGMAC_CONFIG_1__hstdlyfcsrx 2 -#define O_XGMAC_CONFIG_1__hstppen 7 -#define O_XGMAC_CONFIG_1__hstbytswp 6 -#define O_XGMAC_CONFIG_1__hstdrplt64 5 -#define O_XGMAC_CONFIG_1__hstprmscrx 4 -#define O_XGMAC_CONFIG_1__hstlenchk 3 -#define O_XGMAC_CONFIG_1__hstgenfcs 2 -#define O_XGMAC_CONFIG_1__hstpadmode 0 -#define W_XGMAC_CONFIG_1__hstpadmode 2 -#define R_XGMAC_CONFIG_2 0x02 -#define O_XGMAC_CONFIG_2__hsttctlfrcp 31 -#define O_XGMAC_CONFIG_2__hstmlnkflth 27 -#define O_XGMAC_CONFIG_2__hstalnkflth 26 -#define O_XGMAC_CONFIG_2__rflnkflt 24 -#define W_XGMAC_CONFIG_2__rflnkflt 2 -#define O_XGMAC_CONFIG_2__hstipgextmod 16 -#define W_XGMAC_CONFIG_2__hstipgextmod 5 -#define O_XGMAC_CONFIG_2__hstrctlfrcp 15 -#define O_XGMAC_CONFIG_2__hstipgexten 5 -#define O_XGMAC_CONFIG_2__hstmipgext 0 -#define W_XGMAC_CONFIG_2__hstmipgext 5 -#define R_XGMAC_CONFIG_3 0x03 -#define O_XGMAC_CONFIG_3__hstfltrfrm 31 -#define W_XGMAC_CONFIG_3__hstfltrfrm 16 -#define O_XGMAC_CONFIG_3__hstfltrfrmdc 15 -#define W_XGMAC_CONFIG_3__hstfltrfrmdc 16 -#define R_XGMAC_STATION_ADDRESS_LS 0x04 -#define O_XGMAC_STATION_ADDRESS_LS__hstmacadr0 0 -#define W_XGMAC_STATION_ADDRESS_LS__hstmacadr0 32 -#define R_XGMAC_STATION_ADDRESS_MS 0x05 -#define R_XGMAC_MAX_FRAME_LEN 0x08 -#define O_XGMAC_MAX_FRAME_LEN__hstmxfrmwctx 16 -#define W_XGMAC_MAX_FRAME_LEN__hstmxfrmwctx 14 -#define O_XGMAC_MAX_FRAME_LEN__hstmxfrmbcrx 0 -#define W_XGMAC_MAX_FRAME_LEN__hstmxfrmbcrx 16 -#define R_XGMAC_REV_LEVEL 0x0B -#define O_XGMAC_REV_LEVEL__revlvl 0 -#define W_XGMAC_REV_LEVEL__revlvl 15 -#define R_XGMAC_MIIM_COMMAND 0x10 -#define O_XGMAC_MIIM_COMMAND__hstldcmd 3 -#define O_XGMAC_MIIM_COMMAND__hstmiimcmd 0 -#define W_XGMAC_MIIM_COMMAND__hstmiimcmd 3 -#define R_XGMAC_MIIM_FILED 0x11 -#define O_XGMAC_MIIM_FILED__hststfield 30 -#define W_XGMAC_MIIM_FILED__hststfield 2 -#define O_XGMAC_MIIM_FILED__hstopfield 28 -#define W_XGMAC_MIIM_FILED__hstopfield 2 -#define O_XGMAC_MIIM_FILED__hstphyadx 23 -#define W_XGMAC_MIIM_FILED__hstphyadx 5 -#define O_XGMAC_MIIM_FILED__hstregadx 18 -#define W_XGMAC_MIIM_FILED__hstregadx 5 -#define O_XGMAC_MIIM_FILED__hsttafield 16 -#define W_XGMAC_MIIM_FILED__hsttafield 2 -#define O_XGMAC_MIIM_FILED__miimrddat 0 -#define W_XGMAC_MIIM_FILED__miimrddat 16 -#define R_XGMAC_MIIM_CONFIG 0x12 -#define O_XGMAC_MIIM_CONFIG__hstnopram 7 -#define O_XGMAC_MIIM_CONFIG__hstclkdiv 0 -#define W_XGMAC_MIIM_CONFIG__hstclkdiv 7 -#define R_XGMAC_MIIM_LINK_FAIL_VECTOR 0x13 -#define O_XGMAC_MIIM_LINK_FAIL_VECTOR__miimlfvec 0 -#define W_XGMAC_MIIM_LINK_FAIL_VECTOR__miimlfvec 32 -#define R_XGMAC_MIIM_INDICATOR 0x14 -#define O_XGMAC_MIIM_INDICATOR__miimphylf 4 -#define O_XGMAC_MIIM_INDICATOR__miimmoncplt 3 -#define O_XGMAC_MIIM_INDICATOR__miimmonvld 2 -#define O_XGMAC_MIIM_INDICATOR__miimmon 1 -#define O_XGMAC_MIIM_INDICATOR__miimbusy 0 - -/* Glue logic register and bit field definitions */ -#define R_MAC_ADDR0 0x50 -#define R_MAC_ADDR1 0x52 -#define R_MAC_ADDR2 0x54 -#define R_MAC_ADDR3 0x56 -#define R_MAC_ADDR_MASK2 0x58 -#define R_MAC_ADDR_MASK3 0x5A -#define R_MAC_FILTER_CONFIG 0x5C -#define O_MAC_FILTER_CONFIG__BROADCAST_EN 10 -#define O_MAC_FILTER_CONFIG__PAUSE_FRAME_EN 9 -#define O_MAC_FILTER_CONFIG__ALL_MCAST_EN 8 -#define O_MAC_FILTER_CONFIG__ALL_UCAST_EN 7 -#define O_MAC_FILTER_CONFIG__HASH_MCAST_EN 6 -#define O_MAC_FILTER_CONFIG__HASH_UCAST_EN 5 -#define O_MAC_FILTER_CONFIG__ADDR_MATCH_DISC 4 -#define O_MAC_FILTER_CONFIG__MAC_ADDR3_VALID 3 -#define O_MAC_FILTER_CONFIG__MAC_ADDR2_VALID 2 -#define O_MAC_FILTER_CONFIG__MAC_ADDR1_VALID 1 -#define O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID 0 -#define R_HASH_TABLE_VECTOR 0x30 -#define R_TX_CONTROL 0x0A0 -#define O_TX_CONTROL__Tx15Halt 31 -#define O_TX_CONTROL__Tx14Halt 30 -#define O_TX_CONTROL__Tx13Halt 29 -#define O_TX_CONTROL__Tx12Halt 28 -#define O_TX_CONTROL__Tx11Halt 27 -#define O_TX_CONTROL__Tx10Halt 26 -#define O_TX_CONTROL__Tx9Halt 25 -#define O_TX_CONTROL__Tx8Halt 24 -#define O_TX_CONTROL__Tx7Halt 23 -#define O_TX_CONTROL__Tx6Halt 22 -#define O_TX_CONTROL__Tx5Halt 21 -#define O_TX_CONTROL__Tx4Halt 20 -#define O_TX_CONTROL__Tx3Halt 19 -#define O_TX_CONTROL__Tx2Halt 18 -#define O_TX_CONTROL__Tx1Halt 17 -#define O_TX_CONTROL__Tx0Halt 16 -#define O_TX_CONTROL__TxIdle 15 -#define O_TX_CONTROL__TxEnable 14 -#define O_TX_CONTROL__TxThreshold 0 -#define W_TX_CONTROL__TxThreshold 14 -#define R_RX_CONTROL 0x0A1 -#define O_RX_CONTROL__RGMII 10 -#define O_RX_CONTROL__RxHalt 1 -#define O_RX_CONTROL__RxEnable 0 -#define R_DESC_PACK_CTRL 0x0A2 -#define O_DESC_PACK_CTRL__ByteOffset 17 -#define W_DESC_PACK_CTRL__ByteOffset 3 -#define O_DESC_PACK_CTRL__PrePadEnable 16 -#define O_DESC_PACK_CTRL__MaxEntry 14 -#define W_DESC_PACK_CTRL__MaxEntry 2 -#define O_DESC_PACK_CTRL__RegularSize 0 -#define W_DESC_PACK_CTRL__RegularSize 14 -#define R_STATCTRL 0x0A3 -#define O_STATCTRL__OverFlowEn 4 -#define O_STATCTRL__GIG 3 -#define O_STATCTRL__Sten 2 -#define O_STATCTRL__ClrCnt 1 -#define O_STATCTRL__AutoZ 0 -#define R_L2ALLOCCTRL 0x0A4 -#define O_L2ALLOCCTRL__TxL2Allocate 9 -#define W_L2ALLOCCTRL__TxL2Allocate 9 -#define O_L2ALLOCCTRL__RxL2Allocate 0 -#define W_L2ALLOCCTRL__RxL2Allocate 9 -#define R_INTMASK 0x0A5 -#define O_INTMASK__Spi4TxError 28 -#define O_INTMASK__Spi4RxError 27 -#define O_INTMASK__RGMIIHalfDupCollision 27 -#define O_INTMASK__Abort 26 -#define O_INTMASK__Underrun 25 -#define O_INTMASK__DiscardPacket 24 -#define O_INTMASK__AsyncFifoFull 23 -#define O_INTMASK__TagFull 22 -#define O_INTMASK__Class3Full 21 -#define O_INTMASK__C3EarlyFull 20 -#define O_INTMASK__Class2Full 19 -#define O_INTMASK__C2EarlyFull 18 -#define O_INTMASK__Class1Full 17 -#define O_INTMASK__C1EarlyFull 16 -#define O_INTMASK__Class0Full 15 -#define O_INTMASK__C0EarlyFull 14 -#define O_INTMASK__RxDataFull 13 -#define O_INTMASK__RxEarlyFull 12 -#define O_INTMASK__RFreeEmpty 9 -#define O_INTMASK__RFEarlyEmpty 8 -#define O_INTMASK__P2PSpillEcc 7 -#define O_INTMASK__FreeDescFull 5 -#define O_INTMASK__FreeEarlyFull 4 -#define O_INTMASK__TxFetchError 3 -#define O_INTMASK__StatCarry 2 -#define O_INTMASK__MDInt 1 -#define O_INTMASK__TxIllegal 0 -#define R_INTREG 0x0A6 -#define O_INTREG__Spi4TxError 28 -#define O_INTREG__Spi4RxError 27 -#define O_INTREG__RGMIIHalfDupCollision 27 -#define O_INTREG__Abort 26 -#define O_INTREG__Underrun 25 -#define O_INTREG__DiscardPacket 24 -#define O_INTREG__AsyncFifoFull 23 -#define O_INTREG__TagFull 22 -#define O_INTREG__Class3Full 21 -#define O_INTREG__C3EarlyFull 20 -#define O_INTREG__Class2Full 19 -#define O_INTREG__C2EarlyFull 18 -#define O_INTREG__Class1Full 17 -#define O_INTREG__C1EarlyFull 16 -#define O_INTREG__Class0Full 15 -#define O_INTREG__C0EarlyFull 14 -#define O_INTREG__RxDataFull 13 -#define O_INTREG__RxEarlyFull 12 -#define O_INTREG__RFreeEmpty 9 -#define O_INTREG__RFEarlyEmpty 8 -#define O_INTREG__P2PSpillEcc 7 -#define O_INTREG__FreeDescFull 5 -#define O_INTREG__FreeEarlyFull 4 -#define O_INTREG__TxFetchError 3 -#define O_INTREG__StatCarry 2 -#define O_INTREG__MDInt 1 -#define O_INTREG__TxIllegal 0 -#define R_TXRETRY 0x0A7 -#define O_TXRETRY__CollisionRetry 6 -#define O_TXRETRY__BusErrorRetry 5 -#define O_TXRETRY__UnderRunRetry 4 -#define O_TXRETRY__Retries 0 -#define W_TXRETRY__Retries 4 -#define R_CORECONTROL 0x0A8 -#define O_CORECONTROL__ErrorThread 4 -#define W_CORECONTROL__ErrorThread 7 -#define O_CORECONTROL__Shutdown 2 -#define O_CORECONTROL__Speed 0 -#define W_CORECONTROL__Speed 2 -#define R_BYTEOFFSET0 0x0A9 -#define R_BYTEOFFSET1 0x0AA -#define R_L2TYPE_0 0x0F0 -#define O_L2TYPE__ExtraHdrProtoSize 26 -#define W_L2TYPE__ExtraHdrProtoSize 5 -#define O_L2TYPE__ExtraHdrProtoOffset 20 -#define W_L2TYPE__ExtraHdrProtoOffset 6 -#define O_L2TYPE__ExtraHeaderSize 14 -#define W_L2TYPE__ExtraHeaderSize 6 -#define O_L2TYPE__ProtoOffset 8 -#define W_L2TYPE__ProtoOffset 6 -#define O_L2TYPE__L2HdrOffset 2 -#define W_L2TYPE__L2HdrOffset 6 -#define O_L2TYPE__L2Proto 0 -#define W_L2TYPE__L2Proto 2 -#define R_L2TYPE_1 0xF0 -#define R_L2TYPE_2 0xF0 -#define R_L2TYPE_3 0xF0 -#define R_PARSERCONFIGREG 0x100 -#define O_PARSERCONFIGREG__CRCHashPoly 8 -#define W_PARSERCONFIGREG__CRCHashPoly 7 -#define O_PARSERCONFIGREG__PrePadOffset 4 -#define W_PARSERCONFIGREG__PrePadOffset 4 -#define O_PARSERCONFIGREG__UseCAM 2 -#define O_PARSERCONFIGREG__UseHASH 1 -#define O_PARSERCONFIGREG__UseProto 0 -#define R_L3CTABLE 0x140 -#define O_L3CTABLE__Offset0 25 -#define W_L3CTABLE__Offset0 7 -#define O_L3CTABLE__Len0 21 -#define W_L3CTABLE__Len0 4 -#define O_L3CTABLE__Offset1 14 -#define W_L3CTABLE__Offset1 7 -#define O_L3CTABLE__Len1 10 -#define W_L3CTABLE__Len1 4 -#define O_L3CTABLE__Offset2 4 -#define W_L3CTABLE__Offset2 6 -#define O_L3CTABLE__Len2 0 -#define W_L3CTABLE__Len2 4 -#define O_L3CTABLE__L3HdrOffset 26 -#define W_L3CTABLE__L3HdrOffset 6 -#define O_L3CTABLE__L4ProtoOffset 20 -#define W_L3CTABLE__L4ProtoOffset 6 -#define O_L3CTABLE__IPChksumCompute 19 -#define O_L3CTABLE__L4Classify 18 -#define O_L3CTABLE__L2Proto 16 -#define W_L3CTABLE__L2Proto 2 -#define O_L3CTABLE__L3ProtoKey 0 -#define W_L3CTABLE__L3ProtoKey 16 -#define R_L4CTABLE 0x160 -#define O_L4CTABLE__Offset0 21 -#define W_L4CTABLE__Offset0 6 -#define O_L4CTABLE__Len0 17 -#define W_L4CTABLE__Len0 4 -#define O_L4CTABLE__Offset1 11 -#define W_L4CTABLE__Offset1 6 -#define O_L4CTABLE__Len1 7 -#define W_L4CTABLE__Len1 4 -#define O_L4CTABLE__TCPChksumEnable 0 -#define R_CAM4X128TABLE 0x172 -#define O_CAM4X128TABLE__ClassId 7 -#define W_CAM4X128TABLE__ClassId 2 -#define O_CAM4X128TABLE__BucketId 1 -#define W_CAM4X128TABLE__BucketId 6 -#define O_CAM4X128TABLE__UseBucket 0 -#define R_CAM4X128KEY 0x180 -#define R_TRANSLATETABLE 0x1A0 -#define R_DMACR0 0x200 -#define O_DMACR0__Data0WrMaxCr 27 -#define W_DMACR0__Data0WrMaxCr 3 -#define O_DMACR0__Data0RdMaxCr 24 -#define W_DMACR0__Data0RdMaxCr 3 -#define O_DMACR0__Data1WrMaxCr 21 -#define W_DMACR0__Data1WrMaxCr 3 -#define O_DMACR0__Data1RdMaxCr 18 -#define W_DMACR0__Data1RdMaxCr 3 -#define O_DMACR0__Data2WrMaxCr 15 -#define W_DMACR0__Data2WrMaxCr 3 -#define O_DMACR0__Data2RdMaxCr 12 -#define W_DMACR0__Data2RdMaxCr 3 -#define O_DMACR0__Data3WrMaxCr 9 -#define W_DMACR0__Data3WrMaxCr 3 -#define O_DMACR0__Data3RdMaxCr 6 -#define W_DMACR0__Data3RdMaxCr 3 -#define O_DMACR0__Data4WrMaxCr 3 -#define W_DMACR0__Data4WrMaxCr 3 -#define O_DMACR0__Data4RdMaxCr 0 -#define W_DMACR0__Data4RdMaxCr 3 -#define R_DMACR1 0x201 -#define O_DMACR1__Data5WrMaxCr 27 -#define W_DMACR1__Data5WrMaxCr 3 -#define O_DMACR1__Data5RdMaxCr 24 -#define W_DMACR1__Data5RdMaxCr 3 -#define O_DMACR1__Data6WrMaxCr 21 -#define W_DMACR1__Data6WrMaxCr 3 -#define O_DMACR1__Data6RdMaxCr 18 -#define W_DMACR1__Data6RdMaxCr 3 -#define O_DMACR1__Data7WrMaxCr 15 -#define W_DMACR1__Data7WrMaxCr 3 -#define O_DMACR1__Data7RdMaxCr 12 -#define W_DMACR1__Data7RdMaxCr 3 -#define O_DMACR1__Data8WrMaxCr 9 -#define W_DMACR1__Data8WrMaxCr 3 -#define O_DMACR1__Data8RdMaxCr 6 -#define W_DMACR1__Data8RdMaxCr 3 -#define O_DMACR1__Data9WrMaxCr 3 -#define W_DMACR1__Data9WrMaxCr 3 -#define O_DMACR1__Data9RdMaxCr 0 -#define W_DMACR1__Data9RdMaxCr 3 -#define R_DMACR2 0x202 -#define O_DMACR2__Data10WrMaxCr 27 -#define W_DMACR2__Data10WrMaxCr 3 -#define O_DMACR2__Data10RdMaxCr 24 -#define W_DMACR2__Data10RdMaxCr 3 -#define O_DMACR2__Data11WrMaxCr 21 -#define W_DMACR2__Data11WrMaxCr 3 -#define O_DMACR2__Data11RdMaxCr 18 -#define W_DMACR2__Data11RdMaxCr 3 -#define O_DMACR2__Data12WrMaxCr 15 -#define W_DMACR2__Data12WrMaxCr 3 -#define O_DMACR2__Data12RdMaxCr 12 -#define W_DMACR2__Data12RdMaxCr 3 -#define O_DMACR2__Data13WrMaxCr 9 -#define W_DMACR2__Data13WrMaxCr 3 -#define O_DMACR2__Data13RdMaxCr 6 -#define W_DMACR2__Data13RdMaxCr 3 -#define O_DMACR2__Data14WrMaxCr 3 -#define W_DMACR2__Data14WrMaxCr 3 -#define O_DMACR2__Data14RdMaxCr 0 -#define W_DMACR2__Data14RdMaxCr 3 -#define R_DMACR3 0x203 -#define O_DMACR3__Data15WrMaxCr 27 -#define W_DMACR3__Data15WrMaxCr 3 -#define O_DMACR3__Data15RdMaxCr 24 -#define W_DMACR3__Data15RdMaxCr 3 -#define O_DMACR3__SpClassWrMaxCr 21 -#define W_DMACR3__SpClassWrMaxCr 3 -#define O_DMACR3__SpClassRdMaxCr 18 -#define W_DMACR3__SpClassRdMaxCr 3 -#define O_DMACR3__JumFrInWrMaxCr 15 -#define W_DMACR3__JumFrInWrMaxCr 3 -#define O_DMACR3__JumFrInRdMaxCr 12 -#define W_DMACR3__JumFrInRdMaxCr 3 -#define O_DMACR3__RegFrInWrMaxCr 9 -#define W_DMACR3__RegFrInWrMaxCr 3 -#define O_DMACR3__RegFrInRdMaxCr 6 -#define W_DMACR3__RegFrInRdMaxCr 3 -#define O_DMACR3__FrOutWrMaxCr 3 -#define W_DMACR3__FrOutWrMaxCr 3 -#define O_DMACR3__FrOutRdMaxCr 0 -#define W_DMACR3__FrOutRdMaxCr 3 -#define R_REG_FRIN_SPILL_MEM_START_0 0x204 -#define O_REG_FRIN_SPILL_MEM_START_0__RegFrInSpillMemStart0 0 -#define W_REG_FRIN_SPILL_MEM_START_0__RegFrInSpillMemStart0 32 -#define R_REG_FRIN_SPILL_MEM_START_1 0x205 -#define O_REG_FRIN_SPILL_MEM_START_1__RegFrInSpillMemStart1 0 -#define W_REG_FRIN_SPILL_MEM_START_1__RegFrInSpillMemStart1 3 -#define R_REG_FRIN_SPILL_MEM_SIZE 0x206 -#define O_REG_FRIN_SPILL_MEM_SIZE__RegFrInSpillMemSize 0 -#define W_REG_FRIN_SPILL_MEM_SIZE__RegFrInSpillMemSize 32 -#define R_FROUT_SPILL_MEM_START_0 0x207 -#define O_FROUT_SPILL_MEM_START_0__FrOutSpillMemStart0 0 -#define W_FROUT_SPILL_MEM_START_0__FrOutSpillMemStart0 32 -#define R_FROUT_SPILL_MEM_START_1 0x208 -#define O_FROUT_SPILL_MEM_START_1__FrOutSpillMemStart1 0 -#define W_FROUT_SPILL_MEM_START_1__FrOutSpillMemStart1 3 -#define R_FROUT_SPILL_MEM_SIZE 0x209 -#define O_FROUT_SPILL_MEM_SIZE__FrOutSpillMemSize 0 -#define W_FROUT_SPILL_MEM_SIZE__FrOutSpillMemSize 32 -#define R_CLASS0_SPILL_MEM_START_0 0x20A -#define O_CLASS0_SPILL_MEM_START_0__Class0SpillMemStart0 0 -#define W_CLASS0_SPILL_MEM_START_0__Class0SpillMemStart0 32 -#define R_CLASS0_SPILL_MEM_START_1 0x20B -#define O_CLASS0_SPILL_MEM_START_1__Class0SpillMemStart1 0 -#define W_CLASS0_SPILL_MEM_START_1__Class0SpillMemStart1 3 -#define R_CLASS0_SPILL_MEM_SIZE 0x20C -#define O_CLASS0_SPILL_MEM_SIZE__Class0SpillMemSize 0 -#define W_CLASS0_SPILL_MEM_SIZE__Class0SpillMemSize 32 -#define R_JUMFRIN_SPILL_MEM_START_0 0x20D -#define O_JUMFRIN_SPILL_MEM_START_0__JumFrInSpillMemStar0 0 -#define W_JUMFRIN_SPILL_MEM_START_0__JumFrInSpillMemStar0 32 -#define R_JUMFRIN_SPILL_MEM_START_1 0x20E -#define O_JUMFRIN_SPILL_MEM_START_1__JumFrInSpillMemStart1 0 -#define W_JUMFRIN_SPILL_MEM_START_1__JumFrInSpillMemStart1 3 -#define R_JUMFRIN_SPILL_MEM_SIZE 0x20F -#define O_JUMFRIN_SPILL_MEM_SIZE__JumFrInSpillMemSize 0 -#define W_JUMFRIN_SPILL_MEM_SIZE__JumFrInSpillMemSize 32 -#define R_CLASS1_SPILL_MEM_START_0 0x210 -#define O_CLASS1_SPILL_MEM_START_0__Class1SpillMemStart0 0 -#define W_CLASS1_SPILL_MEM_START_0__Class1SpillMemStart0 32 -#define R_CLASS1_SPILL_MEM_START_1 0x211 -#define O_CLASS1_SPILL_MEM_START_1__Class1SpillMemStart1 0 -#define W_CLASS1_SPILL_MEM_START_1__Class1SpillMemStart1 3 -#define R_CLASS1_SPILL_MEM_SIZE 0x212 -#define O_CLASS1_SPILL_MEM_SIZE__Class1SpillMemSize 0 -#define W_CLASS1_SPILL_MEM_SIZE__Class1SpillMemSize 32 -#define R_CLASS2_SPILL_MEM_START_0 0x213 -#define O_CLASS2_SPILL_MEM_START_0__Class2SpillMemStart0 0 -#define W_CLASS2_SPILL_MEM_START_0__Class2SpillMemStart0 32 -#define R_CLASS2_SPILL_MEM_START_1 0x214 -#define O_CLASS2_SPILL_MEM_START_1__Class2SpillMemStart1 0 -#define W_CLASS2_SPILL_MEM_START_1__Class2SpillMemStart1 3 -#define R_CLASS2_SPILL_MEM_SIZE 0x215 -#define O_CLASS2_SPILL_MEM_SIZE__Class2SpillMemSize 0 -#define W_CLASS2_SPILL_MEM_SIZE__Class2SpillMemSize 32 -#define R_CLASS3_SPILL_MEM_START_0 0x216 -#define O_CLASS3_SPILL_MEM_START_0__Class3SpillMemStart0 0 -#define W_CLASS3_SPILL_MEM_START_0__Class3SpillMemStart0 32 -#define R_CLASS3_SPILL_MEM_START_1 0x217 -#define O_CLASS3_SPILL_MEM_START_1__Class3SpillMemStart1 0 -#define W_CLASS3_SPILL_MEM_START_1__Class3SpillMemStart1 3 -#define R_CLASS3_SPILL_MEM_SIZE 0x218 -#define O_CLASS3_SPILL_MEM_SIZE__Class3SpillMemSize 0 -#define W_CLASS3_SPILL_MEM_SIZE__Class3SpillMemSize 32 -#define R_REG_FRIN1_SPILL_MEM_START_0 0x219 -#define R_REG_FRIN1_SPILL_MEM_START_1 0x21a -#define R_REG_FRIN1_SPILL_MEM_SIZE 0x21b -#define R_SPIHNGY0 0x219 -#define O_SPIHNGY0__EG_HNGY_THRESH_0 24 -#define W_SPIHNGY0__EG_HNGY_THRESH_0 7 -#define O_SPIHNGY0__EG_HNGY_THRESH_1 16 -#define W_SPIHNGY0__EG_HNGY_THRESH_1 7 -#define O_SPIHNGY0__EG_HNGY_THRESH_2 8 -#define W_SPIHNGY0__EG_HNGY_THRESH_2 7 -#define O_SPIHNGY0__EG_HNGY_THRESH_3 0 -#define W_SPIHNGY0__EG_HNGY_THRESH_3 7 -#define R_SPIHNGY1 0x21A -#define O_SPIHNGY1__EG_HNGY_THRESH_4 24 -#define W_SPIHNGY1__EG_HNGY_THRESH_4 7 -#define O_SPIHNGY1__EG_HNGY_THRESH_5 16 -#define W_SPIHNGY1__EG_HNGY_THRESH_5 7 -#define O_SPIHNGY1__EG_HNGY_THRESH_6 8 -#define W_SPIHNGY1__EG_HNGY_THRESH_6 7 -#define O_SPIHNGY1__EG_HNGY_THRESH_7 0 -#define W_SPIHNGY1__EG_HNGY_THRESH_7 7 -#define R_SPIHNGY2 0x21B -#define O_SPIHNGY2__EG_HNGY_THRESH_8 24 -#define W_SPIHNGY2__EG_HNGY_THRESH_8 7 -#define O_SPIHNGY2__EG_HNGY_THRESH_9 16 -#define W_SPIHNGY2__EG_HNGY_THRESH_9 7 -#define O_SPIHNGY2__EG_HNGY_THRESH_10 8 -#define W_SPIHNGY2__EG_HNGY_THRESH_10 7 -#define O_SPIHNGY2__EG_HNGY_THRESH_11 0 -#define W_SPIHNGY2__EG_HNGY_THRESH_11 7 -#define R_SPIHNGY3 0x21C -#define O_SPIHNGY3__EG_HNGY_THRESH_12 24 -#define W_SPIHNGY3__EG_HNGY_THRESH_12 7 -#define O_SPIHNGY3__EG_HNGY_THRESH_13 16 -#define W_SPIHNGY3__EG_HNGY_THRESH_13 7 -#define O_SPIHNGY3__EG_HNGY_THRESH_14 8 -#define W_SPIHNGY3__EG_HNGY_THRESH_14 7 -#define O_SPIHNGY3__EG_HNGY_THRESH_15 0 -#define W_SPIHNGY3__EG_HNGY_THRESH_15 7 -#define R_SPISTRV0 0x21D -#define O_SPISTRV0__EG_STRV_THRESH_0 24 -#define W_SPISTRV0__EG_STRV_THRESH_0 7 -#define O_SPISTRV0__EG_STRV_THRESH_1 16 -#define W_SPISTRV0__EG_STRV_THRESH_1 7 -#define O_SPISTRV0__EG_STRV_THRESH_2 8 -#define W_SPISTRV0__EG_STRV_THRESH_2 7 -#define O_SPISTRV0__EG_STRV_THRESH_3 0 -#define W_SPISTRV0__EG_STRV_THRESH_3 7 -#define R_SPISTRV1 0x21E -#define O_SPISTRV1__EG_STRV_THRESH_4 24 -#define W_SPISTRV1__EG_STRV_THRESH_4 7 -#define O_SPISTRV1__EG_STRV_THRESH_5 16 -#define W_SPISTRV1__EG_STRV_THRESH_5 7 -#define O_SPISTRV1__EG_STRV_THRESH_6 8 -#define W_SPISTRV1__EG_STRV_THRESH_6 7 -#define O_SPISTRV1__EG_STRV_THRESH_7 0 -#define W_SPISTRV1__EG_STRV_THRESH_7 7 -#define R_SPISTRV2 0x21F -#define O_SPISTRV2__EG_STRV_THRESH_8 24 -#define W_SPISTRV2__EG_STRV_THRESH_8 7 -#define O_SPISTRV2__EG_STRV_THRESH_9 16 -#define W_SPISTRV2__EG_STRV_THRESH_9 7 -#define O_SPISTRV2__EG_STRV_THRESH_10 8 -#define W_SPISTRV2__EG_STRV_THRESH_10 7 -#define O_SPISTRV2__EG_STRV_THRESH_11 0 -#define W_SPISTRV2__EG_STRV_THRESH_11 7 -#define R_SPISTRV3 0x220 -#define O_SPISTRV3__EG_STRV_THRESH_12 24 -#define W_SPISTRV3__EG_STRV_THRESH_12 7 -#define O_SPISTRV3__EG_STRV_THRESH_13 16 -#define W_SPISTRV3__EG_STRV_THRESH_13 7 -#define O_SPISTRV3__EG_STRV_THRESH_14 8 -#define W_SPISTRV3__EG_STRV_THRESH_14 7 -#define O_SPISTRV3__EG_STRV_THRESH_15 0 -#define W_SPISTRV3__EG_STRV_THRESH_15 7 -#define R_TXDATAFIFO0 0x221 -#define O_TXDATAFIFO0__Tx0DataFifoStart 24 -#define W_TXDATAFIFO0__Tx0DataFifoStart 7 -#define O_TXDATAFIFO0__Tx0DataFifoSize 16 -#define W_TXDATAFIFO0__Tx0DataFifoSize 7 -#define O_TXDATAFIFO0__Tx1DataFifoStart 8 -#define W_TXDATAFIFO0__Tx1DataFifoStart 7 -#define O_TXDATAFIFO0__Tx1DataFifoSize 0 -#define W_TXDATAFIFO0__Tx1DataFifoSize 7 -#define R_TXDATAFIFO1 0x222 -#define O_TXDATAFIFO1__Tx2DataFifoStart 24 -#define W_TXDATAFIFO1__Tx2DataFifoStart 7 -#define O_TXDATAFIFO1__Tx2DataFifoSize 16 -#define W_TXDATAFIFO1__Tx2DataFifoSize 7 -#define O_TXDATAFIFO1__Tx3DataFifoStart 8 -#define W_TXDATAFIFO1__Tx3DataFifoStart 7 -#define O_TXDATAFIFO1__Tx3DataFifoSize 0 -#define W_TXDATAFIFO1__Tx3DataFifoSize 7 -#define R_TXDATAFIFO2 0x223 -#define O_TXDATAFIFO2__Tx4DataFifoStart 24 -#define W_TXDATAFIFO2__Tx4DataFifoStart 7 -#define O_TXDATAFIFO2__Tx4DataFifoSize 16 -#define W_TXDATAFIFO2__Tx4DataFifoSize 7 -#define O_TXDATAFIFO2__Tx5DataFifoStart 8 -#define W_TXDATAFIFO2__Tx5DataFifoStart 7 -#define O_TXDATAFIFO2__Tx5DataFifoSize 0 -#define W_TXDATAFIFO2__Tx5DataFifoSize 7 -#define R_TXDATAFIFO3 0x224 -#define O_TXDATAFIFO3__Tx6DataFifoStart 24 -#define W_TXDATAFIFO3__Tx6DataFifoStart 7 -#define O_TXDATAFIFO3__Tx6DataFifoSize 16 -#define W_TXDATAFIFO3__Tx6DataFifoSize 7 -#define O_TXDATAFIFO3__Tx7DataFifoStart 8 -#define W_TXDATAFIFO3__Tx7DataFifoStart 7 -#define O_TXDATAFIFO3__Tx7DataFifoSize 0 -#define W_TXDATAFIFO3__Tx7DataFifoSize 7 -#define R_TXDATAFIFO4 0x225 -#define O_TXDATAFIFO4__Tx8DataFifoStart 24 -#define W_TXDATAFIFO4__Tx8DataFifoStart 7 -#define O_TXDATAFIFO4__Tx8DataFifoSize 16 -#define W_TXDATAFIFO4__Tx8DataFifoSize 7 -#define O_TXDATAFIFO4__Tx9DataFifoStart 8 -#define W_TXDATAFIFO4__Tx9DataFifoStart 7 -#define O_TXDATAFIFO4__Tx9DataFifoSize 0 -#define W_TXDATAFIFO4__Tx9DataFifoSize 7 -#define R_TXDATAFIFO5 0x226 -#define O_TXDATAFIFO5__Tx10DataFifoStart 24 -#define W_TXDATAFIFO5__Tx10DataFifoStart 7 -#define O_TXDATAFIFO5__Tx10DataFifoSize 16 -#define W_TXDATAFIFO5__Tx10DataFifoSize 7 -#define O_TXDATAFIFO5__Tx11DataFifoStart 8 -#define W_TXDATAFIFO5__Tx11DataFifoStart 7 -#define O_TXDATAFIFO5__Tx11DataFifoSize 0 -#define W_TXDATAFIFO5__Tx11DataFifoSize 7 -#define R_TXDATAFIFO6 0x227 -#define O_TXDATAFIFO6__Tx12DataFifoStart 24 -#define W_TXDATAFIFO6__Tx12DataFifoStart 7 -#define O_TXDATAFIFO6__Tx12DataFifoSize 16 -#define W_TXDATAFIFO6__Tx12DataFifoSize 7 -#define O_TXDATAFIFO6__Tx13DataFifoStart 8 -#define W_TXDATAFIFO6__Tx13DataFifoStart 7 -#define O_TXDATAFIFO6__Tx13DataFifoSize 0 -#define W_TXDATAFIFO6__Tx13DataFifoSize 7 -#define R_TXDATAFIFO7 0x228 -#define O_TXDATAFIFO7__Tx14DataFifoStart 24 -#define W_TXDATAFIFO7__Tx14DataFifoStart 7 -#define O_TXDATAFIFO7__Tx14DataFifoSize 16 -#define W_TXDATAFIFO7__Tx14DataFifoSize 7 -#define O_TXDATAFIFO7__Tx15DataFifoStart 8 -#define W_TXDATAFIFO7__Tx15DataFifoStart 7 -#define O_TXDATAFIFO7__Tx15DataFifoSize 0 -#define W_TXDATAFIFO7__Tx15DataFifoSize 7 -#define R_RXDATAFIFO0 0x229 -#define O_RXDATAFIFO0__Rx0DataFifoStart 24 -#define W_RXDATAFIFO0__Rx0DataFifoStart 7 -#define O_RXDATAFIFO0__Rx0DataFifoSize 16 -#define W_RXDATAFIFO0__Rx0DataFifoSize 7 -#define O_RXDATAFIFO0__Rx1DataFifoStart 8 -#define W_RXDATAFIFO0__Rx1DataFifoStart 7 -#define O_RXDATAFIFO0__Rx1DataFifoSize 0 -#define W_RXDATAFIFO0__Rx1DataFifoSize 7 -#define R_RXDATAFIFO1 0x22A -#define O_RXDATAFIFO1__Rx2DataFifoStart 24 -#define W_RXDATAFIFO1__Rx2DataFifoStart 7 -#define O_RXDATAFIFO1__Rx2DataFifoSize 16 -#define W_RXDATAFIFO1__Rx2DataFifoSize 7 -#define O_RXDATAFIFO1__Rx3DataFifoStart 8 -#define W_RXDATAFIFO1__Rx3DataFifoStart 7 -#define O_RXDATAFIFO1__Rx3DataFifoSize 0 -#define W_RXDATAFIFO1__Rx3DataFifoSize 7 -#define R_RXDATAFIFO2 0x22B -#define O_RXDATAFIFO2__Rx4DataFifoStart 24 -#define W_RXDATAFIFO2__Rx4DataFifoStart 7 -#define O_RXDATAFIFO2__Rx4DataFifoSize 16 -#define W_RXDATAFIFO2__Rx4DataFifoSize 7 -#define O_RXDATAFIFO2__Rx5DataFifoStart 8 -#define W_RXDATAFIFO2__Rx5DataFifoStart 7 -#define O_RXDATAFIFO2__Rx5DataFifoSize 0 -#define W_RXDATAFIFO2__Rx5DataFifoSize 7 -#define R_RXDATAFIFO3 0x22C -#define O_RXDATAFIFO3__Rx6DataFifoStart 24 -#define W_RXDATAFIFO3__Rx6DataFifoStart 7 -#define O_RXDATAFIFO3__Rx6DataFifoSize 16 -#define W_RXDATAFIFO3__Rx6DataFifoSize 7 -#define O_RXDATAFIFO3__Rx7DataFifoStart 8 -#define W_RXDATAFIFO3__Rx7DataFifoStart 7 -#define O_RXDATAFIFO3__Rx7DataFifoSize 0 -#define W_RXDATAFIFO3__Rx7DataFifoSize 7 -#define R_RXDATAFIFO4 0x22D -#define O_RXDATAFIFO4__Rx8DataFifoStart 24 -#define W_RXDATAFIFO4__Rx8DataFifoStart 7 -#define O_RXDATAFIFO4__Rx8DataFifoSize 16 -#define W_RXDATAFIFO4__Rx8DataFifoSize 7 -#define O_RXDATAFIFO4__Rx9DataFifoStart 8 -#define W_RXDATAFIFO4__Rx9DataFifoStart 7 -#define O_RXDATAFIFO4__Rx9DataFifoSize 0 -#define W_RXDATAFIFO4__Rx9DataFifoSize 7 -#define R_RXDATAFIFO5 0x22E -#define O_RXDATAFIFO5__Rx10DataFifoStart 24 -#define W_RXDATAFIFO5__Rx10DataFifoStart 7 -#define O_RXDATAFIFO5__Rx10DataFifoSize 16 -#define W_RXDATAFIFO5__Rx10DataFifoSize 7 -#define O_RXDATAFIFO5__Rx11DataFifoStart 8 -#define W_RXDATAFIFO5__Rx11DataFifoStart 7 -#define O_RXDATAFIFO5__Rx11DataFifoSize 0 -#define W_RXDATAFIFO5__Rx11DataFifoSize 7 -#define R_RXDATAFIFO6 0x22F -#define O_RXDATAFIFO6__Rx12DataFifoStart 24 -#define W_RXDATAFIFO6__Rx12DataFifoStart 7 -#define O_RXDATAFIFO6__Rx12DataFifoSize 16 -#define W_RXDATAFIFO6__Rx12DataFifoSize 7 -#define O_RXDATAFIFO6__Rx13DataFifoStart 8 -#define W_RXDATAFIFO6__Rx13DataFifoStart 7 -#define O_RXDATAFIFO6__Rx13DataFifoSize 0 -#define W_RXDATAFIFO6__Rx13DataFifoSize 7 -#define R_RXDATAFIFO7 0x230 -#define O_RXDATAFIFO7__Rx14DataFifoStart 24 -#define W_RXDATAFIFO7__Rx14DataFifoStart 7 -#define O_RXDATAFIFO7__Rx14DataFifoSize 16 -#define W_RXDATAFIFO7__Rx14DataFifoSize 7 -#define O_RXDATAFIFO7__Rx15DataFifoStart 8 -#define W_RXDATAFIFO7__Rx15DataFifoStart 7 -#define O_RXDATAFIFO7__Rx15DataFifoSize 0 -#define W_RXDATAFIFO7__Rx15DataFifoSize 7 -#define R_XGMACPADCALIBRATION 0x231 -#define R_FREEQCARVE 0x233 -#define R_SPI4STATICDELAY0 0x240 -#define O_SPI4STATICDELAY0__DataLine7 28 -#define W_SPI4STATICDELAY0__DataLine7 4 -#define O_SPI4STATICDELAY0__DataLine6 24 -#define W_SPI4STATICDELAY0__DataLine6 4 -#define O_SPI4STATICDELAY0__DataLine5 20 -#define W_SPI4STATICDELAY0__DataLine5 4 -#define O_SPI4STATICDELAY0__DataLine4 16 -#define W_SPI4STATICDELAY0__DataLine4 4 -#define O_SPI4STATICDELAY0__DataLine3 12 -#define W_SPI4STATICDELAY0__DataLine3 4 -#define O_SPI4STATICDELAY0__DataLine2 8 -#define W_SPI4STATICDELAY0__DataLine2 4 -#define O_SPI4STATICDELAY0__DataLine1 4 -#define W_SPI4STATICDELAY0__DataLine1 4 -#define O_SPI4STATICDELAY0__DataLine0 0 -#define W_SPI4STATICDELAY0__DataLine0 4 -#define R_SPI4STATICDELAY1 0x241 -#define O_SPI4STATICDELAY1__DataLine15 28 -#define W_SPI4STATICDELAY1__DataLine15 4 -#define O_SPI4STATICDELAY1__DataLine14 24 -#define W_SPI4STATICDELAY1__DataLine14 4 -#define O_SPI4STATICDELAY1__DataLine13 20 -#define W_SPI4STATICDELAY1__DataLine13 4 -#define O_SPI4STATICDELAY1__DataLine12 16 -#define W_SPI4STATICDELAY1__DataLine12 4 -#define O_SPI4STATICDELAY1__DataLine11 12 -#define W_SPI4STATICDELAY1__DataLine11 4 -#define O_SPI4STATICDELAY1__DataLine10 8 -#define W_SPI4STATICDELAY1__DataLine10 4 -#define O_SPI4STATICDELAY1__DataLine9 4 -#define W_SPI4STATICDELAY1__DataLine9 4 -#define O_SPI4STATICDELAY1__DataLine8 0 -#define W_SPI4STATICDELAY1__DataLine8 4 -#define R_SPI4STATICDELAY2 0x242 -#define O_SPI4STATICDELAY0__TxStat1 8 -#define W_SPI4STATICDELAY0__TxStat1 4 -#define O_SPI4STATICDELAY0__TxStat0 4 -#define W_SPI4STATICDELAY0__TxStat0 4 -#define O_SPI4STATICDELAY0__RxControl 0 -#define W_SPI4STATICDELAY0__RxControl 4 -#define R_SPI4CONTROL 0x243 -#define O_SPI4CONTROL__StaticDelay 2 -#define O_SPI4CONTROL__LVDS_LVTTL 1 -#define O_SPI4CONTROL__SPI4Enable 0 -#define R_CLASSWATERMARKS 0x244 -#define O_CLASSWATERMARKS__Class0Watermark 24 -#define W_CLASSWATERMARKS__Class0Watermark 5 -#define O_CLASSWATERMARKS__Class1Watermark 16 -#define W_CLASSWATERMARKS__Class1Watermark 5 -#define O_CLASSWATERMARKS__Class3Watermark 0 -#define W_CLASSWATERMARKS__Class3Watermark 5 -#define R_RXWATERMARKS1 0x245 -#define O_RXWATERMARKS__Rx0DataWatermark 24 -#define W_RXWATERMARKS__Rx0DataWatermark 7 -#define O_RXWATERMARKS__Rx1DataWatermark 16 -#define W_RXWATERMARKS__Rx1DataWatermark 7 -#define O_RXWATERMARKS__Rx3DataWatermark 0 -#define W_RXWATERMARKS__Rx3DataWatermark 7 -#define R_RXWATERMARKS2 0x246 -#define O_RXWATERMARKS__Rx4DataWatermark 24 -#define W_RXWATERMARKS__Rx4DataWatermark 7 -#define O_RXWATERMARKS__Rx5DataWatermark 16 -#define W_RXWATERMARKS__Rx5DataWatermark 7 -#define O_RXWATERMARKS__Rx6DataWatermark 8 -#define W_RXWATERMARKS__Rx6DataWatermark 7 -#define O_RXWATERMARKS__Rx7DataWatermark 0 -#define W_RXWATERMARKS__Rx7DataWatermark 7 -#define R_RXWATERMARKS3 0x247 -#define O_RXWATERMARKS__Rx8DataWatermark 24 -#define W_RXWATERMARKS__Rx8DataWatermark 7 -#define O_RXWATERMARKS__Rx9DataWatermark 16 -#define W_RXWATERMARKS__Rx9DataWatermark 7 -#define O_RXWATERMARKS__Rx10DataWatermark 8 -#define W_RXWATERMARKS__Rx10DataWatermark 7 -#define O_RXWATERMARKS__Rx11DataWatermark 0 -#define W_RXWATERMARKS__Rx11DataWatermark 7 -#define R_RXWATERMARKS4 0x248 -#define O_RXWATERMARKS__Rx12DataWatermark 24 -#define W_RXWATERMARKS__Rx12DataWatermark 7 -#define O_RXWATERMARKS__Rx13DataWatermark 16 -#define W_RXWATERMARKS__Rx13DataWatermark 7 -#define O_RXWATERMARKS__Rx14DataWatermark 8 -#define W_RXWATERMARKS__Rx14DataWatermark 7 -#define O_RXWATERMARKS__Rx15DataWatermark 0 -#define W_RXWATERMARKS__Rx15DataWatermark 7 -#define R_FREEWATERMARKS 0x249 -#define O_FREEWATERMARKS__FreeOutWatermark 16 -#define W_FREEWATERMARKS__FreeOutWatermark 16 -#define O_FREEWATERMARKS__JumFrWatermark 8 -#define W_FREEWATERMARKS__JumFrWatermark 7 -#define O_FREEWATERMARKS__RegFrWatermark 0 -#define W_FREEWATERMARKS__RegFrWatermark 7 -#define R_EGRESSFIFOCARVINGSLOTS 0x24a - -#define CTRL_RES0 0 -#define CTRL_RES1 1 -#define CTRL_REG_FREE 2 -#define CTRL_JUMBO_FREE 3 -#define CTRL_CONT 4 -#define CTRL_EOP 5 -#define CTRL_START 6 -#define CTRL_SNGL 7 - -#define CTRL_B0_NOT_EOP 0 -#define CTRL_B0_EOP 1 - -#define R_ROUND_ROBIN_TABLE 0 -#define R_PDE_CLASS_0 0x300 -#define R_PDE_CLASS_1 0x302 -#define R_PDE_CLASS_2 0x304 -#define R_PDE_CLASS_3 0x306 - -#define R_MSG_TX_THRESHOLD 0x308 - -#define R_GMAC_JFR0_BUCKET_SIZE 0x320 -#define R_GMAC_RFR0_BUCKET_SIZE 0x321 -#define R_GMAC_TX0_BUCKET_SIZE 0x322 -#define R_GMAC_TX1_BUCKET_SIZE 0x323 -#define R_GMAC_TX2_BUCKET_SIZE 0x324 -#define R_GMAC_TX3_BUCKET_SIZE 0x325 -#define R_GMAC_JFR1_BUCKET_SIZE 0x326 -#define R_GMAC_RFR1_BUCKET_SIZE 0x327 - -#define R_XGS_TX0_BUCKET_SIZE 0x320 -#define R_XGS_TX1_BUCKET_SIZE 0x321 -#define R_XGS_TX2_BUCKET_SIZE 0x322 -#define R_XGS_TX3_BUCKET_SIZE 0x323 -#define R_XGS_TX4_BUCKET_SIZE 0x324 -#define R_XGS_TX5_BUCKET_SIZE 0x325 -#define R_XGS_TX6_BUCKET_SIZE 0x326 -#define R_XGS_TX7_BUCKET_SIZE 0x327 -#define R_XGS_TX8_BUCKET_SIZE 0x328 -#define R_XGS_TX9_BUCKET_SIZE 0x329 -#define R_XGS_TX10_BUCKET_SIZE 0x32A -#define R_XGS_TX11_BUCKET_SIZE 0x32B -#define R_XGS_TX12_BUCKET_SIZE 0x32C -#define R_XGS_TX13_BUCKET_SIZE 0x32D -#define R_XGS_TX14_BUCKET_SIZE 0x32E -#define R_XGS_TX15_BUCKET_SIZE 0x32F -#define R_XGS_JFR_BUCKET_SIZE 0x330 -#define R_XGS_RFR_BUCKET_SIZE 0x331 - -#define R_CC_CPU0_0 0x380 -#define R_CC_CPU1_0 0x388 -#define R_CC_CPU2_0 0x390 -#define R_CC_CPU3_0 0x398 -#define R_CC_CPU4_0 0x3a0 -#define R_CC_CPU5_0 0x3a8 -#define R_CC_CPU6_0 0x3b0 -#define R_CC_CPU7_0 0x3b8 - -typedef enum { - xlr_mac_speed_10, xlr_mac_speed_100, - xlr_mac_speed_1000, xlr_mac_speed_rsvd -} xlr_mac_speed_t; - -typedef enum { - xlr_mac_duplex_auto, xlr_mac_duplex_half, - xlr_mac_duplex_full -} xlr_mac_duplex_t; - -typedef enum { - xlr_mac_link_down, - xlr_mac_link_up, -} xlr_mac_link_t; - -typedef enum { - xlr_mac_fc_auto, xlr_mac_fc_disabled, xlr_mac_fc_frame, - xlr_mac_fc_collision, xlr_mac_fc_carrier -} xlr_mac_fc_t; - -/* static int mac_frin_to_be_sent_thr[8]; */ - -enum { - PORT_TX, - PORT_TX_COMPLETE, - PORT_STARTQ, - PORT_STOPQ, - PORT_START_DEV_STATE, - PORT_STOP_DEV_STATE, -}; - -struct rge_softc_stats { - unsigned int rx_frames; - unsigned int tx_frames; - unsigned int rx_packets; - unsigned int rx_bytes; - unsigned int tx_packets; - unsigned int tx_bytes; -}; - -struct driver_data { - - /* - * Let these be the first fields in this structure the structure is - * cacheline aligned when allocated in init_etherdev - */ - struct fr_desc *frin_spill; - struct fr_desc *frout_spill; - union rx_tx_desc *class_0_spill; - union rx_tx_desc *class_1_spill; - union rx_tx_desc *class_2_spill; - union rx_tx_desc *class_3_spill; - int spill_configured; - - struct rge_softc *sc; /* pointer to freebsd device soft-pointer */ - struct rge_softc_stats stats; - struct mtx lock; - - xlr_reg_t *mmio; - xlr_reg_t *mii_mmio; - xlr_reg_t *pcs_mmio; - xlr_reg_t *serdes_mmio; - - int txbucket; - int rfrbucket; - - int phy_oldbmsr; - int phy_oldanlpar; - int phy_oldk1stsr; - int phy_oldlinkstat; - unsigned char phys_addr[2]; - - xlr_mac_speed_t speed; /* current speed */ - xlr_mac_duplex_t duplex;/* current duplex */ - xlr_mac_link_t link; /* current link */ - xlr_mac_fc_t flow_ctrl; /* current flow control setting */ - int advertising; - - int id; - int type; - int mode; - int instance; - int phy_addr; - int frin_to_be_sent[8]; - int init_frin_desc; -}; - -struct rge_softc { - int unit; - int irq; - unsigned char dev_addr[6]; - unsigned long base_addr; - unsigned long mem_end; - struct ifnet *rge_ifp; /* interface info */ - device_t rge_dev; - int mtu; - int flags; - struct driver_data priv; - struct mtx rge_mtx; - device_t rge_miibus; - struct mii_data rge_mii;/* MII/media information */ - bus_space_handle_t rge_bhandle; - bus_space_tag_t rge_btag; - void *rge_intrhand; - struct resource rge_irq; - struct resource *rge_res; - struct ifmedia rge_ifmedia; /* TBI media info */ - int rge_if_flags; - int rge_link; /* link state */ - int rge_link_evt; /* pending link event */ - struct callout rge_stat_ch; - void (*xmit) (struct ifnet *); - void (*stop) (struct rge_softc *); - int (*ioctl) (struct ifnet *, u_long, caddr_t); - struct rge_softc_stats *(*get_stats) (struct rge_softc *); - int active; - int link_up; -}; - -struct size_1_desc { - uint64_t entry0; -}; - -struct size_2_desc { - uint64_t entry0; - uint64_t entry1; -}; - -struct size_3_desc { - uint64_t entry0; - uint64_t entry1; - uint64_t entry2; -}; - -struct size_4_desc { - uint64_t entry0; - uint64_t entry1; - uint64_t entry2; - uint64_t entry3; -}; - -struct fr_desc { - struct size_1_desc d1; -}; - -union rx_tx_desc { - struct size_2_desc d2; - /* struct size_3_desc d3; */ - /* struct size_4_desc d4; */ -}; - - -extern unsigned char xlr_base_mac_addr[]; - -#endif Property changes on: head/sys/mips/rmi/dev/xlr/rge.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/mips/rmi/files.xlr =================================================================== --- head/sys/mips/rmi/files.xlr (revision 287470) +++ head/sys/mips/rmi/files.xlr (revision 287471) @@ -1,26 +1,25 @@ # $FreeBSD$ #mips/rmi/xlr_boot1_console.c standard mips/rmi/xlr_machdep.c standard #mips/rmi/clock.c standard mips/rmi/tick.c standard mips/rmi/iodi.c standard mips/rmi/msgring.c standard mips/rmi/msgring_xls.c standard mips/rmi/board.c standard mips/rmi/fmn.c standard mips/rmi/intr_machdep.c standard mips/rmi/mpwait.S optional smp mips/rmi/xlr_i2c.c optional iic -mips/rmi/uart_bus_xlr_iodi.c optional uart -mips/rmi/uart_cpu_mips_xlr.c optional uart +mips/rmi/uart_bus_xlr_iodi.c optional uart +mips/rmi/uart_cpu_mips_xlr.c optional uart mips/rmi/xlr_pci.c optional pci mips/rmi/xlr_pcmcia.c optional ata mips/rmi/xls_ehci.c optional usb ehci mips/rmi/bus_space_rmi.c standard mips/rmi/bus_space_rmi_pci.c standard mips/rmi/dev/sec/rmisec.c optional rmisec mips/rmi/dev/sec/rmilib.c optional rmisec -mips/rmi/dev/xlr/rge.c optional rge mips/rmi/dev/nlge/if_nlge.c optional nlge -mips/rmi/dev/iic/max6657.c optional max6657 -mips/rmi/dev/iic/at24co2n.c optional at24co2n +mips/rmi/dev/iic/max6657.c optional max6657 +mips/rmi/dev/iic/at24co2n.c optional at24co2n Index: head/sys/mips/rmi/iodi.c =================================================================== --- head/sys/mips/rmi/iodi.c (revision 287470) +++ head/sys/mips/rmi/iodi.c (revision 287471) @@ -1,321 +1,276 @@ /*- * Copyright (c) 2003-2009 RMI Corporation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of RMI Corporation, nor the names of its contributors, * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * RMI_BSD */ #include __FBSDID("$FreeBSD$"); #define __RMAN_RESOURCE_VISIBLE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for DELAY */ #include #include #include #include #include #include #include #include #include extern bus_space_tag_t uart_bus_space_mem; static struct resource * iodi_alloc_resource(device_t, device_t, int, int *, u_long, u_long, u_long, u_int); static int iodi_activate_resource(device_t, device_t, int, int, struct resource *); static int iodi_setup_intr(device_t, device_t, struct resource *, int, driver_filter_t *, driver_intr_t *, void *, void **); struct iodi_softc *iodi_softc; /* There can be only one. */ /* * We will manage the Flash/PCMCIA devices in IODI for now. * The NOR flash, Compact flash etc. which can be connected on * various chip selects on the peripheral IO, should have a * separate bus later. */ static void bridge_pcmcia_ack(int irq) { xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_FLASH_OFFSET); xlr_write_reg(mmio, 0x60, 0xffffffff); } static int iodi_setup_intr(device_t dev, device_t child, struct resource *ires, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { const char *name = device_get_name(child); if (strcmp(name, "uart") == 0) { /* FIXME uart 1? */ cpu_establish_hardintr("uart", filt, intr, arg, PIC_UART_0_IRQ, flags, cookiep); pic_setup_intr(PIC_IRT_UART_0_INDEX, PIC_UART_0_IRQ, 0x1, 1); - } else if (strcmp(name, "rge") == 0 || strcmp(name, "nlge") == 0) { + } else if (strcmp(name, "nlge") == 0) { int irq; /* This is a hack to pass in the irq */ irq = (intptr_t)ires->__r_i; - cpu_establish_hardintr("rge", filt, intr, arg, irq, flags, + cpu_establish_hardintr("nlge", filt, intr, arg, irq, flags, cookiep); pic_setup_intr(irq - PIC_IRQ_BASE, irq, 0x1, 1); } else if (strcmp(name, "ehci") == 0) { cpu_establish_hardintr("ehci", filt, intr, arg, PIC_USB_IRQ, flags, cookiep); pic_setup_intr(PIC_USB_IRQ - PIC_IRQ_BASE, PIC_USB_IRQ, 0x1, 1); } else if (strcmp(name, "ata") == 0) { xlr_establish_intr("ata", filt, intr, arg, PIC_PCMCIA_IRQ, flags, cookiep, bridge_pcmcia_ack); pic_setup_intr(PIC_PCMCIA_IRQ - PIC_IRQ_BASE, PIC_PCMCIA_IRQ, 0x1, 1); } return (0); } static struct resource * iodi_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK); const char *name = device_get_name(child); int unit; #ifdef DEBUG switch (type) { case SYS_RES_IRQ: device_printf(bus, "IRQ resource - for %s %lx-%lx\n", device_get_nameunit(child), start, end); break; case SYS_RES_IOPORT: device_printf(bus, "IOPORT resource - for %s %lx-%lx\n", device_get_nameunit(child), start, end); break; case SYS_RES_MEMORY: device_printf(bus, "MEMORY resource - for %s %lx-%lx\n", device_get_nameunit(child), start, end); break; } #endif if (strcmp(name, "uart") == 0) { if ((unit = device_get_unit(child)) == 0) { /* uart 0 */ res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET); } else if (unit == 1) { res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET); } else printf("%s: Unknown uart unit\n", __FUNCTION__); res->r_bustag = uart_bus_space_mem; } else if (strcmp(name, "ehci") == 0) { res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1ef24000); res->r_bustag = rmi_pci_bus_space; } else if (strcmp(name, "cfi") == 0) { res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1c000000); res->r_bustag = 0; } else if (strcmp(name, "ata") == 0) { res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1d000000); res->r_bustag = rmi_pci_bus_space; /* byte swapping (not really PCI) */ } /* res->r_start = *rid; */ return (res); } static int iodi_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { return (0); } /* prototypes */ static int iodi_probe(device_t); static int iodi_attach(device_t); static int iodi_detach(device_t); static void iodi_identify(driver_t *, device_t); int iodi_probe(device_t dev) { return (BUS_PROBE_NOWILDCARD); } void iodi_identify(driver_t * driver, device_t parent) { BUS_ADD_CHILD(parent, 0, "iodi", 0); } int iodi_attach(device_t dev) { device_t tmpd; int i; /* * Attach each devices */ device_add_child(dev, "uart", 0); device_add_child(dev, "xlr_i2c", 0); device_add_child(dev, "xlr_i2c", 1); device_add_child(dev, "pcib", 0); device_add_child(dev, "rmisec", -1); if (xlr_board_info.usb) device_add_child(dev, "ehci", 0); if (xlr_board_info.cfi) device_add_child(dev, "cfi", 0); if (xlr_board_info.ata) device_add_child(dev, "ata", 0); - if (xlr_board_info.gmac_block[0].enabled) { - tmpd = device_add_child(dev, "rge", 0); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); - - tmpd = device_add_child(dev, "rge", 1); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); - - tmpd = device_add_child(dev, "rge", 2); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); - - tmpd = device_add_child(dev, "rge", 3); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[0]); - } - if (xlr_board_info.gmac_block[1].enabled) { - if (xlr_board_info.gmac_block[1].type == XLR_GMAC) { - tmpd = device_add_child(dev, "rge", 4); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); - - tmpd = device_add_child(dev, "rge", 5); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); - - if (xlr_board_info.gmac_block[1].enabled & 0x4) { - tmpd = device_add_child(dev, "rge", 6); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); - } - - if (xlr_board_info.gmac_block[1].enabled & 0x8) { - tmpd = device_add_child(dev, "rge", 7); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); - } - } else if (xlr_board_info.gmac_block[1].type == XLR_XGMAC) { -#if 0 /* XGMAC not yet */ - tmpd = device_add_child(dev, "rge", 4); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); - - tmpd = device_add_child(dev, "rge", 5); - device_set_ivars(tmpd, &xlr_board_info.gmac_block[1]); -#endif - } else - device_printf(dev, "Unknown type of gmac 1\n"); - } - - /* This is to add the new GMAC driver. The above adds the old driver, - which has been retained for now as the new driver is stabilized. - The new driver is enabled with "option nlge". Make sure that only - one of rge or nlge is enabled in the conf file. */ for (i = 0; i < 3; i++) { if (xlr_board_info.gmac_block[i].enabled == 0) continue; tmpd = device_add_child(dev, "nlna", i); device_set_ivars(tmpd, &xlr_board_info.gmac_block[i]); } + bus_generic_probe(dev); bus_generic_attach(dev); return 0; } int iodi_detach(device_t dev) { device_t nlna_dev; int error, i, ret; error = 0; ret = 0; for (i = 0; i < 3; i++) { nlna_dev = device_find_child(dev, "nlna", i); if (nlna_dev != NULL) error = bus_generic_detach(nlna_dev); if (error) ret = error; } return ret; } static device_method_t iodi_methods[] = { DEVMETHOD(device_probe, iodi_probe), DEVMETHOD(device_attach, iodi_attach), DEVMETHOD(device_detach, iodi_detach), DEVMETHOD(device_identify, iodi_identify), DEVMETHOD(bus_alloc_resource, iodi_alloc_resource), DEVMETHOD(bus_activate_resource, iodi_activate_resource), DEVMETHOD(bus_add_child, bus_generic_add_child), DEVMETHOD(bus_setup_intr, iodi_setup_intr), {0, 0}, }; static driver_t iodi_driver = { "iodi", iodi_methods, 1 /* no softc */ }; static devclass_t iodi_devclass; DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0);