Index: sys/dev/sge/if_sgereg.h =================================================================== --- sys/dev/sge/if_sgereg.h (revision 228083) +++ sys/dev/sge/if_sgereg.h (working copy) @@ -72,11 +72,11 @@ #define GMIIControl 0x44 #define GMacIOCR 0x48 #define GMacIOCTL 0x4c -#define TxMacControl 0x50 +#define TXMAC_CTL 0x50 #define TxMacTimeLimit 0x54 #define RGMIIDelay 0x58 #define Reserved3 0x5c -#define RxMacControl 0x60 /* 1 WORD */ +#define RXMAC_CTL 0x60 /* 1 WORD */ #define RxMacAddr 0x62 /* 6x BYTE */ #define RxHashTable 0x68 /* 1 LONG */ #define RxHashTable2 0x6c /* 1 LONG */ @@ -117,30 +117,69 @@ #define RxRWT 0x00400000 /* - * RX_CTL Register Content + * RX control register */ -#define RX_CTL_POLL 0x00000010 +#define RX_CTL_FIFO_THRESH_128T 0x03000000 +#define RX_CTL_FIFO_THRESH_64T 0x02000000 +#define RX_CTL_FIFO_THRESH_32T 0x01000000 +#define RX_CTL_FIFO_THRESH_16T 0x00000000 +#define RX_CTL_ACCEPT_MAGIC_ENB 0x00040000 +#define RX_CTL_ACCEPT_PAUSE_ENB 0x00020000 +#define RX_CTL_DISCARD_ERR 0x00010000 +#define RX_CTL_DMA_BURST 0x00001000 +#define RX_CTL_DMA_8QW 0x00000C00 +#define RX_CTL_DMA_4QW 0x00000800 +#define RX_CTL_DMA_2QW 0x00000400 +#define RX_CTL_DMA_1QW 0x00000000 +#define RX_CTL_FIFO_WAIT_128QW 0x00000300 +#define RX_CTL_FIFO_WAIT_64QW 0x00000200 +#define RX_CTL_FIFO_WAIT_32QW 0x00000100 +#define RX_CTL_FIFO_WAIT_16QW 0x00000000 +#define RX_CTL_QUEUE_ENB 0x00000010 +#define RX_CTL_SUSPEND 0x00000002 #define RX_CTL_ENB 0x00000001 /* - * TX_CTL Register Content + * TX control register */ -#define TX_CTL_POLL 0x00000010 +#define TX_CTL_SEL_QUEUE1 0x00010000 +#define TX_CTL_SEL_QUEUE0 0x00000000 +#define TX_CTL_DMA_BURST 0x00001000 +#define TX_CTL_DMA_8QW 0x00000C00 +#define TX_CTL_DMA_4QW 0x00000800 +#define TX_CTL_DMA_2QW 0x00000400 +#define TX_CTL_DMA_1QW 0x00000000 +#define TX_CTL_FIFO_WAIT_16QW 0x00000300 +#define TX_CTL_FIFO_WAIT_12W 0x00000200 +#define TX_CTL_FIFO_WAIT_8QW 0x00000100 +#define TX_CTL_FIFO_WAIT_4QW 0x00000000 +#define TX_CTL_QUEUE1_ENB 0x00000020 +#define TX_CTL_QUEUE0_ENB 0x00000010 +#define TX_CTL_SUSPEND 0x00000002 #define TX_CTL_ENB 0x00000001 /* - * RxMacControl Register Content + * TX MAC control register */ -#define AcceptBroadcast 0x0800 -#define AcceptMulticast 0x0400 -#define AcceptMyPhys 0x0200 -#define AcceptAllPhys 0x0100 -#define AcceptErr 0x0020 -#define AcceptRunt 0x0010 +#define TXMAC_PAUSE_CRC 0x00000200 +#define TXMAC_PAUSE_AUTOPAD 0x00000100 +#define TXMAC_IFG2_DEF 0x00000040 +#define TXMAC_IFG1_DEF 0x00000020 +#define TXMAC_PAUSE_ENB 0x00000001 + +/* + * RX MAC control register + */ +#define RXMAC_BROADCAST 0x0800 +#define RXMAC_MULTICAST 0x0400 +#define RXMAC_UNICAST 0x0200 +#define RXMAC_PROMISC 0x0100 #define RXMAC_STRIP_VLAN 0x0020 #define RXMAC_STRIP_FCS 0x0010 +#define RXMAC_COL_DET 0x0008 #define RXMAC_PAD_ENB 0x0004 #define RXMAC_CSUM_ENB 0x0002 +#define RXMAC_PAUSE_ENB 0x0001 #define SGE_RX_PAD_BYTES 10 @@ -359,6 +398,8 @@ int sge_if_flags; int sge_intrcontrol; int sge_intrtimer; + uint32_t sge_rxctl; + uint32_t sge_txctl; struct mtx sge_mtx; }; Index: sys/dev/sge/if_sge.c =================================================================== --- sys/dev/sge/if_sge.c (revision 228083) +++ sys/dev/sge/if_sge.c (working copy) @@ -380,7 +380,7 @@ struct sge_softc *sc; struct mii_data *mii; struct ifnet *ifp; - uint32_t ctl, speed; + uint32_t ctl, rxmac, speed, txmac; sc = device_get_softc(dev); mii = device_get_softc(sc->sge_miibus); @@ -428,11 +428,24 @@ ctl |= 0x03000000; #endif ctl |= speed; + rxmac = CSR_READ_4(sc, RXMAC_CTL); + rxmac &= ~RXMAC_PAUSE_ENB; + txmac = CSR_READ_4(sc, TXMAC_CTL); + txmac &= ~TXMAC_PAUSE_ENB; if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { ctl |= SC_FDX; sc->sge_flags |= SGE_FLAG_FDX; - } else + rxmac &= ~RXMAC_COL_DET; + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0) + rxmac |= RXMAC_PAUSE_ENB; + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0) + txmac |= TXMAC_PAUSE_ENB; + } else { sc->sge_flags &= ~SGE_FLAG_FDX; + rxmac |= RXMAC_COL_DET; + } + CSR_WRITE_4(sc, RXMAC_CTL, rxmac); + CSR_WRITE_4(sc, TXMAC_CTL, txmac); CSR_WRITE_4(sc, StationControl, ctl); if ((sc->sge_flags & SGE_FLAG_RGMII) != 0) { CSR_WRITE_4(sc, RGMIIDelay, 0x0441); @@ -451,19 +464,19 @@ SGE_LOCK_ASSERT(sc); ifp = sc->sge_ifp; - rxfilt = CSR_READ_2(sc, RxMacControl); - rxfilt &= ~(AcceptBroadcast | AcceptAllPhys | AcceptMulticast); - rxfilt |= AcceptMyPhys; + rxfilt = CSR_READ_2(sc, RXMAC_CTL); + rxfilt &= ~(RXMAC_BROADCAST | RXMAC_PROMISC | RXMAC_MULTICAST); + rxfilt |= RXMAC_UNICAST; if ((ifp->if_flags & IFF_BROADCAST) != 0) - rxfilt |= AcceptBroadcast; + rxfilt |= RXMAC_BROADCAST; if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) { if ((ifp->if_flags & IFF_PROMISC) != 0) - rxfilt |= AcceptAllPhys; - rxfilt |= AcceptMulticast; + rxfilt |= RXMAC_PROMISC; + rxfilt |= RXMAC_MULTICAST; hashes[0] = 0xFFFFFFFF; hashes[1] = 0xFFFFFFFF; } else { - rxfilt |= AcceptMulticast; + rxfilt |= RXMAC_MULTICAST; hashes[0] = hashes[1] = 0; /* Now program new ones. */ if_maddr_rlock(ifp); @@ -476,7 +489,7 @@ } if_maddr_runlock(ifp); } - CSR_WRITE_2(sc, RxMacControl, rxfilt); + CSR_WRITE_2(sc, RXMAC_CTL, rxfilt); CSR_WRITE_4(sc, RxHashTable, hashes[0]); CSR_WRITE_4(sc, RxHashTable2, hashes[1]); } @@ -492,12 +505,12 @@ ifp = sc->sge_ifp; if ((ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) == 0) return; - rxfilt = CSR_READ_2(sc, RxMacControl); + rxfilt = CSR_READ_2(sc, RXMAC_CTL); if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) rxfilt |= RXMAC_STRIP_VLAN; else rxfilt &= ~RXMAC_STRIP_VLAN; - CSR_WRITE_2(sc, RxMacControl, rxfilt); + CSR_WRITE_2(sc, RXMAC_CTL, rxfilt); } static void @@ -512,14 +525,9 @@ CSR_READ_4(sc, IntrControl); DELAY(100); CSR_WRITE_4(sc, IntrControl, 0); - /* Stop MAC. */ - CSR_WRITE_4(sc, TX_CTL, 0x1a00); - CSR_WRITE_4(sc, RX_CTL, 0x1a00); CSR_WRITE_4(sc, IntrMask, 0); CSR_WRITE_4(sc, IntrStatus, 0xffffffff); - - CSR_WRITE_4(sc, GMIIControl, 0); } /* @@ -624,7 +632,8 @@ * Do MII setup. */ error = mii_attach(dev, &sc->sge_miibus, ifp, sge_ifmedia_upd, - sge_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, 0); + sge_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY, + MIIF_DOPAUSE); if (error != 0) { device_printf(dev, "attaching PHYs failed\n"); goto fail; @@ -1361,8 +1370,8 @@ sge_rxeof(sc); /* Wakeup Rx MAC. */ if ((status & INTR_RX_IDLE) != 0) - CSR_WRITE_4(sc, RX_CTL, - 0x1a00 | 0x000c | RX_CTL_POLL | RX_CTL_ENB); + CSR_WRITE_4(sc, RX_CTL, sc->sge_rxctl | + RX_CTL_ENB | RX_CTL_QUEUE_ENB); } if ((status & (INTR_TX_DONE | INTR_TX_IDLE)) != 0) sge_txeof(sc); @@ -1602,7 +1611,8 @@ bus_dmamap_sync(sc->sge_cdata.sge_tx_tag, sc->sge_cdata.sge_tx_dmamap, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - CSR_WRITE_4(sc, TX_CTL, 0x1a00 | TX_CTL_ENB | TX_CTL_POLL); + CSR_WRITE_4(sc, TX_CTL, sc->sge_txctl | TX_CTL_ENB | + TX_CTL_QUEUE0_ENB); sc->sge_timer = 5; } } @@ -1645,13 +1655,23 @@ } /* Init TX descriptors. */ sge_list_tx_init(sc); + + sc->sge_rxctl = RX_CTL_FIFO_THRESH_16T | RX_CTL_DISCARD_ERR | + RX_CTL_DMA_BURST | RX_CTL_DMA_8QW | RX_CTL_FIFO_WAIT_16QW; + CSR_WRITE_4(sc, RX_CTL, sc->sge_rxctl); + + sc->sge_txctl = TX_CTL_SEL_QUEUE0 | TX_CTL_DMA_BURST | + TX_CTL_DMA_8QW | TX_CTL_FIFO_WAIT_4QW; + CSR_WRITE_4(sc, TX_CTL, sc->sge_txctl); + /* * Load the address of the RX and TX lists. */ CSR_WRITE_4(sc, TX_DESC, SGE_ADDR_LO(sc->sge_ldata.sge_tx_paddr)); CSR_WRITE_4(sc, RX_DESC, SGE_ADDR_LO(sc->sge_ldata.sge_rx_paddr)); - CSR_WRITE_4(sc, TxMacControl, 0x60); + CSR_WRITE_4(sc, TXMAC_CTL, TXMAC_PAUSE_CRC | TXMAC_PAUSE_AUTOPAD | + TXMAC_IFG1_DEF | TXMAC_IFG2_DEF); CSR_WRITE_4(sc, RxWakeOnLan, 0); CSR_WRITE_4(sc, RxWakeOnLanData, 0); /* Allow receiving VLAN frames. */ @@ -1662,7 +1682,7 @@ CSR_WRITE_1(sc, RxMacAddr + i, IF_LLADDR(ifp)[i]); /* Configure RX MAC. */ rxfilt = RXMAC_STRIP_FCS | RXMAC_PAD_ENB | RXMAC_CSUM_ENB; - CSR_WRITE_2(sc, RxMacControl, rxfilt); + CSR_WRITE_2(sc, RXMAC_CTL, rxfilt); sge_rxfilter(sc); sge_setvlan(sc); @@ -1671,7 +1691,7 @@ sc->sge_flags |= SGE_FLAG_SPEED_1000; sc->sge_flags |= SGE_FLAG_FDX; if ((sc->sge_flags & SGE_FLAG_RGMII) != 0) - CSR_WRITE_4(sc, StationControl, 0x04008001); + CSR_WRITE_4(sc, StationControl, 0x04000001 | SC_RGMII); else CSR_WRITE_4(sc, StationControl, 0x04000001); /* @@ -1692,9 +1712,12 @@ CSR_WRITE_4(sc, IntrMask, SGE_INTRS); /* Enable receiver and transmitter. */ - CSR_WRITE_4(sc, TX_CTL, 0x1a00 | TX_CTL_ENB); - CSR_WRITE_4(sc, RX_CTL, 0x1a00 | 0x000c | RX_CTL_POLL | RX_CTL_ENB); + CSR_WRITE_4(sc, TX_CTL, sc->sge_txctl | TX_CTL_ENB); + CSR_WRITE_4(sc, RX_CTL, sc->sge_rxctl | RX_CTL_ENB); + /* Enable RX queue processing. */ + CSR_WRITE_4(sc, RX_CTL, sc->sge_rxctl | RX_CTL_ENB | RX_CTL_QUEUE_ENB); + ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -1877,6 +1900,7 @@ sge_stop(struct sge_softc *sc) { struct ifnet *ifp; + int i; ifp = sc->sge_ifp; @@ -1890,10 +1914,23 @@ CSR_READ_4(sc, IntrMask); CSR_WRITE_4(sc, IntrStatus, 0xffffffff); /* Stop TX/RX MAC. */ - CSR_WRITE_4(sc, TX_CTL, 0x1a00); - CSR_WRITE_4(sc, RX_CTL, 0x1a00); - /* XXX Can we assume active DMA cycles gone? */ - DELAY(2000); + CSR_WRITE_4(sc, TX_CTL, 0); + CSR_WRITE_4(sc, RX_CTL, 0); + for (i = SGE_TIMEOUT; i > 0; i--) { + if ((CSR_READ_4(sc, TX_CTL) & TX_CTL_ENB) == 0) + break; + DELAY(50); + } + if (i == 0) + device_printf(sc->sge_dev, "Stopping TX MAC timed out!\n"); + + for (i = SGE_TIMEOUT; i > 0; i--) { + if ((CSR_READ_4(sc, RX_CTL) & RX_CTL_ENB) == 0) + break; + DELAY(50); + } + if (i == 0) + device_printf(sc->sge_dev, "Stopping RX MAC timed out!\n"); CSR_WRITE_4(sc, IntrMask, 0); CSR_WRITE_4(sc, IntrStatus, 0xffffffff);