From e89da24b3dc8a5985ebb1a749c1fa4682d70c012 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 11 Apr 2009 04:30:38 +0000 Subject: [PATCH] Two refinements to the 3c1 support: 1) Flag it and only access that command on the 3c1 2) The TX PLL appears to power down when not in use, so we have to power it back up when we've been idle. Do this at the start of ifstart. Otherwise we fall off the net. --- sys/dev/ep/if_ep.c | 9 +++++++-- sys/dev/ep/if_ep_pccard.c | 15 +++++++++------ sys/dev/ep/if_epvar.h | 1 + 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/sys/dev/ep/if_ep.c b/sys/dev/ep/if_ep.c index b6aac055eb9..c56639d8940 100644 --- a/sys/dev/ep/if_ep.c +++ b/sys/dev/ep/if_ep.c @@ -435,7 +435,8 @@ epinit_locked(struct ep_softc *sc) if (!sc->epb.mii_trans) ep_ifmedia_upd(ifp); - CSR_WRITE_2(sc, EP_COMMAND, TX_PLL_ENABLE); + if (sc->stat & F_HAS_TX_PLL) + CSR_WRITE_2(sc, EP_COMMAND, TX_PLL_ENABLE); CSR_WRITE_2(sc, EP_COMMAND, RX_ENABLE); CSR_WRITE_2(sc, EP_COMMAND, TX_ENABLE); @@ -474,7 +475,7 @@ epstart_locked(struct ifnet *ifp) struct ep_softc *sc; u_int len; struct mbuf *m, *m0; - int pad; + int pad, started; sc = ifp->if_softc; if (sc->gone) @@ -483,11 +484,15 @@ epstart_locked(struct ifnet *ifp) EP_BUSY_WAIT(sc); if (ifp->if_drv_flags & IFF_DRV_OACTIVE) return; + started = 0; startagain: /* Sneak a peek at the next packet */ IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); if (m0 == NULL) return; + if (!started && (sc->stat & F_HAS_TX_PLL)) + CSR_WRITE_2(sc, EP_COMMAND, TX_PLL_ENABLE); + started++; for (len = 0, m = m0; m != NULL; m = m->m_next) len += m->m_len; diff --git a/sys/dev/ep/if_ep_pccard.c b/sys/dev/ep/if_ep_pccard.c index 430935804bb..98ebaf4e08d 100644 --- a/sys/dev/ep/if_ep_pccard.c +++ b/sys/dev/ep/if_ep_pccard.c @@ -68,9 +68,10 @@ struct ep_pccard_product #define EP_CHIP_589 1 /* Classic 3c5x9 chipset */ #define EP_CHIP_574 2 /* Roadrunner */ +#define EP_CHIP_C1 3 /* 3c1 */ static const struct ep_pccard_product ep_pccard_products[] = { - { PCMCIA_CARD(3COM, 3C1), EP_CHIP_589 }, + { PCMCIA_CARD(3COM, 3C1), EP_CHIP_C1 }, { PCMCIA_CARD(3COM, 3C562), EP_CHIP_589 }, { PCMCIA_CARD(3COM, 3C589), EP_CHIP_589 }, { PCMCIA_CARD(3COM, 3CXEM556), EP_CHIP_589 }, @@ -144,19 +145,21 @@ ep_pccard_attach(device_t dev) if ((pp = ep_pccard_lookup(dev)) == NULL) panic("ep_pccard_attach: can't find product in attach."); - if (pp->chipset == EP_CHIP_589) { - sc->epb.mii_trans = 0; - sc->epb.cmd_off = 0; - } else { + if (pp->chipset == EP_CHIP_574) { sc->epb.mii_trans = 1; sc->epb.cmd_off = 2; + } else { + sc->epb.mii_trans = 0; + sc->epb.cmd_off = 0; } - if ((error = ep_alloc(dev))) { device_printf(dev, "ep_alloc() failed! (%d)\n", error); goto bad; } + if (pp->chipset == EP_CHIP_C1) + sc->stat |= F_HAS_TX_PLL; + /* ROM size = 0, ROM base = 0 */ /* For now, ignore AUTO SELECT feature of 3C589B and later. */ error = ep_get_e(sc, EEPROM_ADDR_CFG, &result); diff --git a/sys/dev/ep/if_epvar.h b/sys/dev/ep/if_epvar.h index 704fe025406..922a264620b 100644 --- a/sys/dev/ep/if_epvar.h +++ b/sys/dev/ep/if_epvar.h @@ -57,6 +57,7 @@ struct ep_softc { #define F_ENADDR_SKIP 0x002 #define F_PROMISC 0x008 #define F_ACCESS_32_BITS 0x100 +#define F_HAS_TX_PLL 0x200 int gone; /* adapter is not present (for PCCARD) */ struct ep_board epb;