Date: Wed, 10 Dec 2008 17:44:40 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 154447 for review Message-ID: <200812101744.mBAHieHx083517@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=154447 Change 154447 by sam@sam_ebb on 2008/12/10 17:44:24 Sync updates in the continued pursuit of a working NPE-A on ixp435: o track MAC address/naming changes o remove macsize and miisize from the static config tables; these are always going to be 4K o fix NPE-A qid's (from clang@gateworks) o move phy probe to npe_activate so it can be done before hooking up the qmgr (seems to be a noop) o simplify mac/mii address override from hints; no more size parameter o split out mac reset logic for possible reuse o rearrange activate work to be more like linux (doesn't seem to matter) o add printfs to show MAC and MII addresses (to go under bootverbose) o add DELAY(1) when polling for MII cmd completion and up max tries to 1000 (~1ms total) Tested on Avila and Cambria boards w/o regression. Affected files ... .. //depot/projects/vap/sys/arm/xscale/ixp425/if_npe.c#11 edit Differences ... ==== //depot/projects/vap/sys/arm/xscale/ixp425/if_npe.c#11 (text+ko) ==== @@ -159,9 +159,7 @@ static const struct { uint32_t imageid; /* default fw image */ uint32_t macbase; - int macsize; uint32_t miibase; - int miisize; int phy; /* phy id */ uint8_t rx_qid; uint8_t rx_freeqid; @@ -171,21 +169,17 @@ [NPE_A] = { .imageid = IXP425_NPE_A_IMAGEID, .macbase = IXP435_MAC_A_HWBASE, - .macsize = IXP435_MAC_A_SIZE, - .miibase = IXP435_MAC_A_HWBASE, - .miisize = IXP435_MAC_A_SIZE, + .miibase = IXP425_MAC_C_HWBASE, .phy = 2, .rx_qid = 4, - .rx_freeqid = 27, - .tx_qid = 24, + .rx_freeqid = 26, + .tx_qid = 23, .tx_doneqid = 31 }, [NPE_B] = { .imageid = IXP425_NPE_B_IMAGEID, - .macbase = IXP425_MAC_A_HWBASE, - .macsize = IXP425_MAC_A_SIZE, - .miibase = IXP425_MAC_A_HWBASE, - .miisize = IXP425_MAC_A_SIZE, + .macbase = IXP425_MAC_B_HWBASE, + .miibase = IXP425_MAC_C_HWBASE, .phy = 0, .rx_qid = 4, .rx_freeqid = 27, @@ -194,10 +188,8 @@ }, [NPE_C] = { .imageid = IXP425_NPE_C_IMAGEID, - .macbase = IXP425_MAC_B_HWBASE, - .macsize = IXP425_MAC_B_SIZE, - .miibase = IXP425_MAC_A_HWBASE, - .miisize = IXP425_MAC_A_SIZE, + .macbase = IXP425_MAC_C_HWBASE, + .miibase = IXP425_MAC_C_HWBASE, .phy = 1, .rx_qid = 12, .rx_freeqid = 28, @@ -330,7 +322,7 @@ struct ixp425_softc *sa = device_get_softc(device_get_parent(dev)); struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev); struct sysctl_oid *tree = device_get_sysctl_tree(dev); - struct ifnet *ifp = NULL; + struct ifnet *ifp; int error; u_char eaddr[6]; @@ -341,31 +333,23 @@ sc->sc_debug = npe_debug; sc->sc_tickinterval = npe_tickinterval; - if (!override_npeid(dev, "npeid", &sc->sc_npeid)) - sc->sc_npeid = unit2npeid(device_get_unit(dev)); - sc->sc_npe = ixpnpe_attach(dev, sc->sc_npeid); - if (sc->sc_npe == NULL) { - device_printf(dev, "cannot attach ixpnpe.\n"); + ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + device_printf(dev, "cannot allocate ifnet\n"); error = EIO; /* XXX */ goto out; } + /* NB: must be setup prior to invoking mii code */ + sc->sc_ifp = ifp; error = npe_activate(dev); if (error) { - device_printf(dev, "cannot activate npe.\n"); + device_printf(dev, "cannot activate npe\n"); goto out; } npe_getmac(sc, eaddr); - /* NB: must be setup prior to invoking mii code */ - sc->sc_ifp = ifp = if_alloc(IFT_ETHER); - if (mii_phy_probe(dev, &sc->sc_mii, npe_ifmedia_update, npe_ifmedia_status)) { - device_printf(dev, "cannot find my PHY.\n"); - error = ENXIO; - 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; @@ -394,8 +378,6 @@ if_free(ifp); NPE_LOCK_DESTROY(sc); npe_deactivate(dev); - if (sc->sc_npe != NULL) - ixpnpe_detach(sc->sc_npe); return error; } @@ -416,8 +398,6 @@ } NPE_LOCK_DESTROY(sc); npe_deactivate(dev); - if (sc->sc_npe != NULL) - ixpnpe_detach(sc->sc_npe); return 0; } @@ -590,36 +570,8 @@ } static int -npe_macaddr(int npeid, int *base, int *size) +override_addr(device_t dev, const char *resname, int *base) { - if (npeid == NPE_A) { - if ((cpu_id() & CPU_ID_CPU_MASK) == CPU_ID_IXP435) { - *base = IXP435_MAC_A_HWBASE; - *size = IXP435_MAC_A_SIZE; - } else { - *base = IXP425_MAC_A_HWBASE; - *size = IXP425_MAC_A_SIZE; - } - return 0; - } else if (npeid == NPE_B) { - if ((cpu_id() & CPU_ID_CPU_MASK) != CPU_ID_IXP435) { - *base = IXP425_MAC_B_HWBASE; - *size = IXP425_MAC_B_SIZE; - return 0; - } - } else if (npeid == NPE_C) { - if ((cpu_id() & CPU_ID_CPU_MASK) == CPU_ID_IXP435) { - *base = IXP435_MAC_C_HWBASE; - *size = IXP435_MAC_C_SIZE; - return 0; - } - } - return EINVAL; -} - -static int -override_addr(device_t dev, const char *resname, int *base, int *size) -{ int unit = device_get_unit(dev); const char *resval; @@ -628,18 +580,15 @@ return 0; switch (resval[0]) { case 'A': - npe_macaddr(NPE_A, base, size); + *base = IXP435_MAC_A_HWBASE; break; case 'B': - if (npe_macaddr(NPE_B, base, size) != 0) - goto bad; + *base = IXP425_MAC_B_HWBASE; break; case 'C': - if (npe_macaddr(NPE_C, base, size) != 0) - goto bad; + *base = IXP425_MAC_C_HWBASE; break; default: - bad: device_printf(dev, "Warning, bad value %s for " "npe.%d.%s ignored\n", resval, unit, resname); return 0; @@ -711,14 +660,68 @@ return 1; } +static void +npe_mac_reset(struct npe_softc *sc) +{ + /* + * Reset MAC core. + */ + WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET); + DELAY(NPE_MAC_RESET_DELAY); + /* configure MAC to generate MDC clock */ + WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN); +} + static int npe_activate(device_t dev) { struct npe_softc * sc = device_get_softc(dev); - int error, i, macbase, macsize, miibase, miisize; + int error, i, macbase, miibase; uint32_t imageid, msg[2]; /* + * Setup NEP ID, MAC, and MII bindings. We allow override + * via hints to handle unexpected board configs. + */ + if (!override_npeid(dev, "npeid", &sc->sc_npeid)) + sc->sc_npeid = unit2npeid(device_get_unit(dev)); + sc->sc_npe = ixpnpe_attach(dev, sc->sc_npeid); + if (sc->sc_npe == NULL) { + device_printf(dev, "cannot attach ixpnpe\n"); + return EIO; /* XXX */ + } + + /* MAC */ + if (!override_addr(dev, "mac", &macbase)) + macbase = npeconfig[sc->sc_npeid].macbase; + device_printf(sc->sc_dev, "MAC at 0x%x\n", macbase); + if (bus_space_map(sc->sc_iot, macbase, IXP425_REG_SIZE, 0, &sc->sc_ioh)) { + device_printf(dev, "cannot map mac registers 0x%x:0x%x\n", + macbase, IXP425_REG_SIZE); + return ENOMEM; + } + + /* PHY */ + if (!override_unit(dev, "phy", &sc->sc_phy, 0, MII_NPHY-1)) + sc->sc_phy = npeconfig[sc->sc_npeid].phy; + if (!override_addr(dev, "mii", &miibase)) + miibase = npeconfig[sc->sc_npeid].miibase; + device_printf(sc->sc_dev, "MII at 0x%x\n", miibase); + if (miibase != macbase) { + /* + * PHY is mapped through a different MAC, setup an + * additional mapping for frobbing the PHY registers. + */ + if (bus_space_map(sc->sc_iot, miibase, IXP425_REG_SIZE, 0, &sc->sc_miih)) { + device_printf(dev, + "cannot map MII registers 0x%x:0x%x\n", + miibase, IXP425_REG_SIZE); + return ENOMEM; + } + } else + sc->sc_miih = sc->sc_ioh; + + /* * Load NPE firmware and start it running. We assume * that minor version bumps remain compatible so probe * the firmware image starting with the expected version @@ -744,38 +747,18 @@ } imageid++; } + /* NB: firmware should respond with a status msg */ if (ixpnpe_recvmsg_sync(sc->sc_npe, msg) != 0) { device_printf(dev, "firmware did not respond as expected\n"); return EIO; } - if (!override_addr(dev, "mac", &macbase, &macsize)) { - macbase = npeconfig[sc->sc_npeid].macbase; - macsize = npeconfig[sc->sc_npeid].macsize; + /* probe for PHY */ + if (mii_phy_probe(dev, &sc->sc_mii, npe_ifmedia_update, npe_ifmedia_status)) { + device_printf(dev, "cannot find PHY %d.\n", sc->sc_phy); + return ENXIO; } - if (bus_space_map(sc->sc_iot, macbase, macsize, 0, &sc->sc_ioh)) { - device_printf(dev, "cannot map mac registers 0x%x:0x%x\n", - macbase, macsize); - return ENOMEM; - } - if (!override_addr(dev, "mii", &miibase, &miisize)) { - miibase = npeconfig[sc->sc_npeid].miibase; - miisize = npeconfig[sc->sc_npeid].miisize; - } - if (miibase != macbase) { - /* - * PHY is mapped through a different MAC, setup an - * additional mapping for frobbing the PHY registers. - */ - if (bus_space_map(sc->sc_iot, miibase, miisize, 0, &sc->sc_miih)) { - device_printf(dev, - "cannot map MII registers 0x%x:0x%x\n", - miibase, miisize); - return ENOMEM; - } - } else - sc->sc_miih = sc->sc_ioh; error = npe_dma_setup(sc, &sc->txdma, "tx", npe_txbuf, NPE_MAXSEG); if (error != 0) return error; @@ -809,8 +792,6 @@ } sc->sc_stats_phys = sc->buf_phys; - /* XXX disable half-bridge LEARNING+FILTERING feature */ - /* * Setup h/w rx/tx queues. There are four q's: * rx inbound q of rx'd frames @@ -840,7 +821,7 @@ for (i = 0; i < 8; i++) npe_setrxqosentry(sc, i, 0, sc->rx_qid); - /* disable firewall mode just in case (should be off by default) */ + /* disable firewall mode just in case (should be off) */ npe_setfirewallmode(sc, 0); sc->tx_qid = npeconfig[sc->sc_npeid].tx_qid; @@ -852,13 +833,6 @@ tx_doneqid = sc->tx_doneqid; } - /* - * Setup phy port number. We allow override via hints - * to handle different board configs. - */ - if (!override_unit(dev, "phy", &sc->sc_phy, 0, MII_NPHY-1)) - sc->sc_phy = npeconfig[sc->sc_npeid].phy; - KASSERT(npes[sc->sc_npeid] == NULL, ("npe %u already setup", sc->sc_npeid)); npes[sc->sc_npeid] = sc; @@ -874,8 +848,10 @@ npes[sc->sc_npeid] = NULL; /* XXX disable q's */ - if (sc->sc_npe != NULL) + if (sc->sc_npe != NULL) { ixpnpe_stop(sc->sc_npe); + ixpnpe_detach(sc->sc_npe); + } if (sc->sc_stats != NULL) { bus_dmamap_unload(sc->sc_stats_tag, sc->sc_stats_map); bus_dmamem_free(sc->sc_stats_tag, sc->sc_stats, @@ -1256,10 +1232,7 @@ /* * Reset MAC core. */ - WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET); - DELAY(NPE_MAC_RESET_DELAY); - /* configure MAC to generate MDC clock */ - WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN); + npe_mac_reset(sc); /* disable transmitter and reciver in the MAC */ WR4(sc, NPE_MAC_RX_CNTRL1, @@ -1672,10 +1645,13 @@ /* * MII bus support routines. */ +#define MII_RD4(sc, reg) bus_space_read_4(sc->sc_iot, sc->sc_miih, reg) +#define MII_WR4(sc, reg, v) \ + bus_space_write_4(sc->sc_iot, sc->sc_miih, reg, v) + static uint32_t npe_mii_mdio_read(struct npe_softc *sc, int reg) { -#define MII_RD4(sc, reg) bus_space_read_4(sc->sc_iot, sc->sc_miih, reg) uint32_t v; /* NB: registers are known to be sequential */ @@ -1684,37 +1660,34 @@ v |= (MII_RD4(sc, reg+8) & 0xff) << 16; v |= (MII_RD4(sc, reg+12) & 0xff) << 24; return v; -#undef MII_RD4 } static void npe_mii_mdio_write(struct npe_softc *sc, int reg, uint32_t cmd) { -#define MII_WR4(sc, reg, v) \ - bus_space_write_4(sc->sc_iot, sc->sc_miih, reg, v) - /* NB: registers are known to be sequential */ MII_WR4(sc, reg+0, cmd & 0xff); MII_WR4(sc, reg+4, (cmd >> 8) & 0xff); MII_WR4(sc, reg+8, (cmd >> 16) & 0xff); MII_WR4(sc, reg+12, (cmd >> 24) & 0xff); -#undef MII_WR4 } static int npe_mii_mdio_wait(struct npe_softc *sc) { -#define MAXTRIES 100 /* XXX */ uint32_t v; int i; - for (i = 0; i < MAXTRIES; i++) { + /* NB: typically this takes 25-30 trips */ + for (i = 0; i < 1000; i++) { v = npe_mii_mdio_read(sc, NPE_MAC_MDIO_CMD); if ((v & NPE_MII_GO) == 0) return 1; + DELAY(1); } + device_printf(sc->sc_dev, "%s: timeout after ~1ms, cmd 0x%x\n", + __func__, v); return 0; /* NB: timeout */ -#undef MAXTRIES } static int @@ -1725,15 +1698,13 @@ if (phy != sc->sc_phy) /* XXX no auto-detect */ return 0xffff; - v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL) - | NPE_MII_GO; + v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL) | NPE_MII_GO; npe_mii_mdio_write(sc, NPE_MAC_MDIO_CMD, v); if (npe_mii_mdio_wait(sc)) v = npe_mii_mdio_read(sc, NPE_MAC_MDIO_STS); else v = 0xffff | NPE_MII_READ_FAIL; return (v & NPE_MII_READ_FAIL) ? 0xffff : (v & 0xffff); -#undef MAXTRIES } static void @@ -1742,7 +1713,7 @@ struct npe_softc *sc = device_get_softc(dev); uint32_t v; - if (phy != sc->sc_phy) /* XXX should not happen */ + if (phy != sc->sc_phy) /* XXX */ return; v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL) | data | NPE_MII_WRITE
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812101744.mBAHieHx083517>