if_nge.c revision 122625
1145479Smp/* 259243Sobrien * Copyright (c) 2001 Wind River Systems 359243Sobrien * Copyright (c) 1997, 1998, 1999, 2000, 2001 459243Sobrien * Bill Paul <wpaul@bsdi.com>. All rights reserved. 559243Sobrien * 659243Sobrien * Redistribution and use in source and binary forms, with or without 759243Sobrien * modification, are permitted provided that the following conditions 859243Sobrien * are met: 959243Sobrien * 1. Redistributions of source code must retain the above copyright 1059243Sobrien * notice, this list of conditions and the following disclaimer. 1159243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1259243Sobrien * notice, this list of conditions and the following disclaimer in the 1359243Sobrien * documentation and/or other materials provided with the distribution. 1459243Sobrien * 3. All advertising materials mentioning features or use of this software 1559243Sobrien * must display the following acknowledgement: 1659243Sobrien * This product includes software developed by Bill Paul. 1759243Sobrien * 4. Neither the name of the author nor the names of any co-contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 1959243Sobrien * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 2559243Sobrien * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2659243Sobrien * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2759243Sobrien * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2859243Sobrien * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2959243Sobrien * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3059243Sobrien * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3159243Sobrien * THE POSSIBILITY OF SUCH DAMAGE. 3259243Sobrien */ 3359243Sobrien 3459243Sobrien#include <sys/cdefs.h> 3559243Sobrien__FBSDID("$FreeBSD: head/sys/dev/nge/if_nge.c 122625 2003-11-13 20:55:53Z obrien $"); 3659243Sobrien 3759243Sobrien/* 3859243Sobrien * National Semiconductor DP83820/DP83821 gigabit ethernet driver 3959243Sobrien * for FreeBSD. Datasheets are available from: 4059243Sobrien * 4159243Sobrien * http://www.national.com/ds/DP/DP83820.pdf 4259243Sobrien * http://www.national.com/ds/DP/DP83821.pdf 4359243Sobrien * 4459243Sobrien * These chips are used on several low cost gigabit ethernet NICs 4559243Sobrien * sold by D-Link, Addtron, SMC and Asante. Both parts are 4659243Sobrien * virtually the same, except the 83820 is a 64-bit/32-bit part, 4759243Sobrien * while the 83821 is 32-bit only. 4859243Sobrien * 4959243Sobrien * Many cards also use National gigE transceivers, such as the 5059243Sobrien * DP83891, DP83861 and DP83862 gigPHYTER parts. The DP83861 datasheet 5159243Sobrien * contains a full register description that applies to all of these 5259243Sobrien * components: 5359243Sobrien * 5459243Sobrien * http://www.national.com/ds/DP/DP83861.pdf 5559243Sobrien * 5659243Sobrien * Written by Bill Paul <wpaul@bsdi.com> 5759243Sobrien * BSDi Open Source Solutions 5859243Sobrien */ 5959243Sobrien 6059243Sobrien/* 6159243Sobrien * The NatSemi DP83820 and 83821 controllers are enhanced versions 6259243Sobrien * of the NatSemi MacPHYTER 10/100 devices. They support 10, 100 6359243Sobrien * and 1000Mbps speeds with 1000baseX (ten bit interface), MII and GMII 6459243Sobrien * ports. Other features include 8K TX FIFO and 32K RX FIFO, TCP/IP 6559243Sobrien * hardware checksum offload (IPv4 only), VLAN tagging and filtering, 6659243Sobrien * priority TX and RX queues, a 2048 bit multicast hash filter, 4 RX pattern 6759243Sobrien * matching buffers, one perfect address filter buffer and interrupt 6859243Sobrien * moderation. The 83820 supports both 64-bit and 32-bit addressing 6959243Sobrien * and data transfers: the 64-bit support can be toggled on or off 7059243Sobrien * via software. This affects the size of certain fields in the DMA 7159243Sobrien * descriptors. 7259243Sobrien * 73100616Smp * There are two bugs/misfeatures in the 83820/83821 that I have 7459243Sobrien * discovered so far: 7559243Sobrien * 7659243Sobrien * - Receive buffers must be aligned on 64-bit boundaries, which means 7759243Sobrien * you must resort to copying data in order to fix up the payload 7859243Sobrien * alignment. 7959243Sobrien * 8059243Sobrien * - In order to transmit jumbo frames larger than 8170 bytes, you have 8159243Sobrien * to turn off transmit checksum offloading, because the chip can't 8259243Sobrien * compute the checksum on an outgoing frame unless it fits entirely 8359243Sobrien * within the TX FIFO, which is only 8192 bytes in size. If you have 8459243Sobrien * TX checksum offload enabled and you transmit attempt to transmit a 8559243Sobrien * frame larger than 8170 bytes, the transmitter will wedge. 8659243Sobrien * 8759243Sobrien * To work around the latter problem, TX checksum offload is disabled 8859243Sobrien * if the user selects an MTU larger than 8152 (8170 - 18). 8959243Sobrien */ 9059243Sobrien 91145479Smp#include <sys/cdefs.h> 9259243Sobrien__FBSDID("$FreeBSD: head/sys/dev/nge/if_nge.c 122625 2003-11-13 20:55:53Z obrien $"); 9359243Sobrien 9459243Sobrien#include <sys/param.h> 9559243Sobrien#include <sys/systm.h> 9659243Sobrien#include <sys/sockio.h> 9759243Sobrien#include <sys/mbuf.h> 9859243Sobrien#include <sys/malloc.h> 9959243Sobrien#include <sys/kernel.h> 10059243Sobrien#include <sys/socket.h> 10159243Sobrien 10259243Sobrien#include <net/if.h> 10359243Sobrien#include <net/if_arp.h> 10459243Sobrien#include <net/ethernet.h> 10559243Sobrien#include <net/if_dl.h> 10659243Sobrien#include <net/if_media.h> 10759243Sobrien#include <net/if_types.h> 10859243Sobrien#include <net/if_vlan_var.h> 10959243Sobrien 11059243Sobrien#include <net/bpf.h> 11159243Sobrien 11259243Sobrien#include <vm/vm.h> /* for vtophys */ 11359243Sobrien#include <vm/pmap.h> /* for vtophys */ 11459243Sobrien#include <machine/clock.h> /* for DELAY */ 11559243Sobrien#include <machine/bus_pio.h> 11659243Sobrien#include <machine/bus_memio.h> 11759243Sobrien#include <machine/bus.h> 11859243Sobrien#include <machine/resource.h> 11959243Sobrien#include <sys/bus.h> 12059243Sobrien#include <sys/rman.h> 12159243Sobrien 12259243Sobrien#include <dev/mii/mii.h> 12359243Sobrien#include <dev/mii/miivar.h> 12459243Sobrien 12559243Sobrien#include <dev/pci/pcireg.h> 12659243Sobrien#include <dev/pci/pcivar.h> 12759243Sobrien 12859243Sobrien#define NGE_USEIOSPACE 12959243Sobrien 13059243Sobrien#include <dev/nge/if_ngereg.h> 13159243Sobrien 13259243SobrienMODULE_DEPEND(nge, pci, 1, 1, 1); 13359243SobrienMODULE_DEPEND(nge, ether, 1, 1, 1); 13459243SobrienMODULE_DEPEND(nge, miibus, 1, 1, 1); 13559243Sobrien 13659243Sobrien/* "controller miibus0" required. See GENERIC if you get errors here. */ 13759243Sobrien#include "miibus_if.h" 13859243Sobrien 13959243Sobrien#define NGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) 14059243Sobrien 14159243Sobrien/* 14259243Sobrien * Various supported device vendors/types and their names. 14359243Sobrien */ 14459243Sobrienstatic struct nge_type nge_devs[] = { 14559243Sobrien { NGE_VENDORID, NGE_DEVICEID, 14659243Sobrien "National Semiconductor Gigabit Ethernet" }, 14759243Sobrien { 0, 0, NULL } 14859243Sobrien}; 14959243Sobrien 15059243Sobrienstatic int nge_probe(device_t); 15159243Sobrienstatic int nge_attach(device_t); 15259243Sobrienstatic int nge_detach(device_t); 15359243Sobrien 15459243Sobrienstatic int nge_alloc_jumbo_mem(struct nge_softc *); 15559243Sobrienstatic void nge_free_jumbo_mem(struct nge_softc *); 15659243Sobrienstatic void *nge_jalloc(struct nge_softc *); 15759243Sobrienstatic void nge_jfree(void *, void *); 15859243Sobrien 15959243Sobrienstatic int nge_newbuf(struct nge_softc *, struct nge_desc *, struct mbuf *); 16059243Sobrienstatic int nge_encap(struct nge_softc *, struct mbuf *, u_int32_t *); 16159243Sobrienstatic void nge_rxeof(struct nge_softc *); 16259243Sobrienstatic void nge_txeof(struct nge_softc *); 16359243Sobrienstatic void nge_intr(void *); 16459243Sobrienstatic void nge_tick(void *); 16559243Sobrienstatic void nge_start(struct ifnet *); 16659243Sobrienstatic int nge_ioctl(struct ifnet *, u_long, caddr_t); 16759243Sobrienstatic void nge_init(void *); 16859243Sobrienstatic void nge_stop(struct nge_softc *); 16959243Sobrienstatic void nge_watchdog(struct ifnet *); 17059243Sobrienstatic void nge_shutdown(device_t); 17159243Sobrienstatic int nge_ifmedia_upd(struct ifnet *); 17259243Sobrienstatic void nge_ifmedia_sts(struct ifnet *, struct ifmediareq *); 17359243Sobrien 17459243Sobrienstatic void nge_delay(struct nge_softc *); 17559243Sobrienstatic void nge_eeprom_idle(struct nge_softc *); 17659243Sobrienstatic void nge_eeprom_putbyte(struct nge_softc *, int); 17759243Sobrienstatic void nge_eeprom_getword(struct nge_softc *, int, u_int16_t *); 17859243Sobrienstatic void nge_read_eeprom(struct nge_softc *, caddr_t, int, int, int); 17959243Sobrien 18059243Sobrienstatic void nge_mii_sync(struct nge_softc *); 18159243Sobrienstatic void nge_mii_send(struct nge_softc *, u_int32_t, int); 18259243Sobrienstatic int nge_mii_readreg(struct nge_softc *, struct nge_mii_frame *); 18359243Sobrienstatic int nge_mii_writereg(struct nge_softc *, struct nge_mii_frame *); 18459243Sobrien 18559243Sobrienstatic int nge_miibus_readreg(device_t, int, int); 18659243Sobrienstatic int nge_miibus_writereg(device_t, int, int, int); 18759243Sobrienstatic void nge_miibus_statchg(device_t); 18859243Sobrien 18959243Sobrienstatic void nge_setmulti(struct nge_softc *); 19059243Sobrienstatic u_int32_t nge_mchash(caddr_t); 19159243Sobrienstatic void nge_reset(struct nge_softc *); 19259243Sobrienstatic int nge_list_rx_init(struct nge_softc *); 19359243Sobrienstatic int nge_list_tx_init(struct nge_softc *); 19459243Sobrien 19559243Sobrien#ifdef NGE_USEIOSPACE 19659243Sobrien#define NGE_RES SYS_RES_IOPORT 19759243Sobrien#define NGE_RID NGE_PCI_LOIO 19859243Sobrien#else 19959243Sobrien#define NGE_RES SYS_RES_MEMORY 20059243Sobrien#define NGE_RID NGE_PCI_LOMEM 20159243Sobrien#endif 20259243Sobrien 20359243Sobrienstatic device_method_t nge_methods[] = { 20459243Sobrien /* Device interface */ 20559243Sobrien DEVMETHOD(device_probe, nge_probe), 20659243Sobrien DEVMETHOD(device_attach, nge_attach), 20759243Sobrien DEVMETHOD(device_detach, nge_detach), 20859243Sobrien DEVMETHOD(device_shutdown, nge_shutdown), 20959243Sobrien 21059243Sobrien /* bus interface */ 21159243Sobrien DEVMETHOD(bus_print_child, bus_generic_print_child), 21259243Sobrien DEVMETHOD(bus_driver_added, bus_generic_driver_added), 21359243Sobrien 21459243Sobrien /* MII interface */ 21559243Sobrien DEVMETHOD(miibus_readreg, nge_miibus_readreg), 21659243Sobrien DEVMETHOD(miibus_writereg, nge_miibus_writereg), 21759243Sobrien DEVMETHOD(miibus_statchg, nge_miibus_statchg), 21859243Sobrien 21959243Sobrien { 0, 0 } 22059243Sobrien}; 22159243Sobrien 22259243Sobrienstatic driver_t nge_driver = { 22359243Sobrien "nge", 22459243Sobrien nge_methods, 22559243Sobrien sizeof(struct nge_softc) 22659243Sobrien}; 22759243Sobrien 22859243Sobrienstatic devclass_t nge_devclass; 22959243Sobrien 23059243SobrienDRIVER_MODULE(nge, pci, nge_driver, nge_devclass, 0, 0); 23159243SobrienDRIVER_MODULE(miibus, nge, miibus_driver, miibus_devclass, 0, 0); 23259243Sobrien 23359243Sobrien#define NGE_SETBIT(sc, reg, x) \ 23459243Sobrien CSR_WRITE_4(sc, reg, \ 23559243Sobrien CSR_READ_4(sc, reg) | (x)) 23659243Sobrien 23759243Sobrien#define NGE_CLRBIT(sc, reg, x) \ 23859243Sobrien CSR_WRITE_4(sc, reg, \ 23959243Sobrien CSR_READ_4(sc, reg) & ~(x)) 24059243Sobrien 24159243Sobrien#define SIO_SET(x) \ 24259243Sobrien CSR_WRITE_4(sc, NGE_MEAR, CSR_READ_4(sc, NGE_MEAR) | (x)) 24359243Sobrien 24459243Sobrien#define SIO_CLR(x) \ 24559243Sobrien CSR_WRITE_4(sc, NGE_MEAR, CSR_READ_4(sc, NGE_MEAR) & ~(x)) 24659243Sobrien 24759243Sobrienstatic void 24859243Sobriennge_delay(sc) 24959243Sobrien struct nge_softc *sc; 25059243Sobrien{ 25159243Sobrien int idx; 25259243Sobrien 25359243Sobrien for (idx = (300 / 33) + 1; idx > 0; idx--) 25459243Sobrien CSR_READ_4(sc, NGE_CSR); 25559243Sobrien 25659243Sobrien return; 25759243Sobrien} 25859243Sobrien 25959243Sobrienstatic void 26059243Sobriennge_eeprom_idle(sc) 26159243Sobrien struct nge_softc *sc; 26259243Sobrien{ 26359243Sobrien register int i; 26459243Sobrien 26559243Sobrien SIO_SET(NGE_MEAR_EE_CSEL); 26659243Sobrien nge_delay(sc); 26759243Sobrien SIO_SET(NGE_MEAR_EE_CLK); 26859243Sobrien nge_delay(sc); 26959243Sobrien 27059243Sobrien for (i = 0; i < 25; i++) { 27159243Sobrien SIO_CLR(NGE_MEAR_EE_CLK); 27259243Sobrien nge_delay(sc); 27359243Sobrien SIO_SET(NGE_MEAR_EE_CLK); 27459243Sobrien nge_delay(sc); 27559243Sobrien } 27659243Sobrien 27759243Sobrien SIO_CLR(NGE_MEAR_EE_CLK); 27859243Sobrien nge_delay(sc); 27959243Sobrien SIO_CLR(NGE_MEAR_EE_CSEL); 28059243Sobrien nge_delay(sc); 28159243Sobrien CSR_WRITE_4(sc, NGE_MEAR, 0x00000000); 28259243Sobrien 28359243Sobrien return; 28459243Sobrien} 28559243Sobrien 28659243Sobrien/* 28759243Sobrien * Send a read command and address to the EEPROM, check for ACK. 28859243Sobrien */ 28959243Sobrienstatic void 29059243Sobriennge_eeprom_putbyte(sc, addr) 29159243Sobrien struct nge_softc *sc; 29259243Sobrien int addr; 29359243Sobrien{ 29459243Sobrien register int d, i; 29559243Sobrien 29659243Sobrien d = addr | NGE_EECMD_READ; 29759243Sobrien 29859243Sobrien /* 29959243Sobrien * Feed in each bit and stobe the clock. 30059243Sobrien */ 30159243Sobrien for (i = 0x400; i; i >>= 1) { 30259243Sobrien if (d & i) { 30359243Sobrien SIO_SET(NGE_MEAR_EE_DIN); 30459243Sobrien } else { 30559243Sobrien SIO_CLR(NGE_MEAR_EE_DIN); 30659243Sobrien } 30759243Sobrien nge_delay(sc); 30859243Sobrien SIO_SET(NGE_MEAR_EE_CLK); 30959243Sobrien nge_delay(sc); 31059243Sobrien SIO_CLR(NGE_MEAR_EE_CLK); 31159243Sobrien nge_delay(sc); 31259243Sobrien } 31359243Sobrien 31459243Sobrien return; 31559243Sobrien} 31659243Sobrien 31759243Sobrien/* 31859243Sobrien * Read a word of data stored in the EEPROM at address 'addr.' 31959243Sobrien */ 32059243Sobrienstatic void 32159243Sobriennge_eeprom_getword(sc, addr, dest) 32259243Sobrien struct nge_softc *sc; 32359243Sobrien int addr; 32459243Sobrien u_int16_t *dest; 32559243Sobrien{ 32659243Sobrien register int i; 32759243Sobrien u_int16_t word = 0; 32859243Sobrien 32959243Sobrien /* Force EEPROM to idle state. */ 33059243Sobrien nge_eeprom_idle(sc); 33159243Sobrien 33259243Sobrien /* Enter EEPROM access mode. */ 33359243Sobrien nge_delay(sc); 33459243Sobrien SIO_CLR(NGE_MEAR_EE_CLK); 33559243Sobrien nge_delay(sc); 33659243Sobrien SIO_SET(NGE_MEAR_EE_CSEL); 33759243Sobrien nge_delay(sc); 33859243Sobrien 33959243Sobrien /* 34059243Sobrien * Send address of word we want to read. 34159243Sobrien */ 34259243Sobrien nge_eeprom_putbyte(sc, addr); 34359243Sobrien 34459243Sobrien /* 34559243Sobrien * Start reading bits from EEPROM. 34659243Sobrien */ 34759243Sobrien for (i = 0x8000; i; i >>= 1) { 34859243Sobrien SIO_SET(NGE_MEAR_EE_CLK); 34959243Sobrien nge_delay(sc); 35059243Sobrien if (CSR_READ_4(sc, NGE_MEAR) & NGE_MEAR_EE_DOUT) 35159243Sobrien word |= i; 35259243Sobrien nge_delay(sc); 35359243Sobrien SIO_CLR(NGE_MEAR_EE_CLK); 35459243Sobrien nge_delay(sc); 35559243Sobrien } 35659243Sobrien 35759243Sobrien /* Turn off EEPROM access mode. */ 35859243Sobrien nge_eeprom_idle(sc); 35959243Sobrien 36059243Sobrien *dest = word; 36159243Sobrien 36259243Sobrien return; 36359243Sobrien} 36459243Sobrien 36559243Sobrien/* 36659243Sobrien * Read a sequence of words from the EEPROM. 36759243Sobrien */ 36859243Sobrienstatic void 36959243Sobriennge_read_eeprom(sc, dest, off, cnt, swap) 37059243Sobrien struct nge_softc *sc; 37159243Sobrien caddr_t dest; 37259243Sobrien int off; 37359243Sobrien int cnt; 37459243Sobrien int swap; 37559243Sobrien{ 37659243Sobrien int i; 37759243Sobrien u_int16_t word = 0, *ptr; 37859243Sobrien 37959243Sobrien for (i = 0; i < cnt; i++) { 38059243Sobrien nge_eeprom_getword(sc, off + i, &word); 38159243Sobrien ptr = (u_int16_t *)(dest + (i * 2)); 38259243Sobrien if (swap) 38359243Sobrien *ptr = ntohs(word); 38459243Sobrien else 38559243Sobrien *ptr = word; 38659243Sobrien } 38759243Sobrien 38859243Sobrien return; 38959243Sobrien} 39059243Sobrien 39159243Sobrien/* 39259243Sobrien * Sync the PHYs by setting data bit and strobing the clock 32 times. 39359243Sobrien */ 39459243Sobrienstatic void 39559243Sobriennge_mii_sync(sc) 39659243Sobrien struct nge_softc *sc; 39759243Sobrien{ 39859243Sobrien register int i; 39959243Sobrien 40059243Sobrien SIO_SET(NGE_MEAR_MII_DIR|NGE_MEAR_MII_DATA); 40159243Sobrien 40259243Sobrien for (i = 0; i < 32; i++) { 40359243Sobrien SIO_SET(NGE_MEAR_MII_CLK); 40459243Sobrien DELAY(1); 40559243Sobrien SIO_CLR(NGE_MEAR_MII_CLK); 40659243Sobrien DELAY(1); 40759243Sobrien } 40859243Sobrien 40959243Sobrien return; 41059243Sobrien} 41159243Sobrien 41259243Sobrien/* 41359243Sobrien * Clock a series of bits through the MII. 41459243Sobrien */ 41559243Sobrienstatic void 41659243Sobriennge_mii_send(sc, bits, cnt) 41759243Sobrien struct nge_softc *sc; 41859243Sobrien u_int32_t bits; 41959243Sobrien int cnt; 42059243Sobrien{ 42159243Sobrien int i; 42259243Sobrien 42359243Sobrien SIO_CLR(NGE_MEAR_MII_CLK); 42459243Sobrien 42559243Sobrien for (i = (0x1 << (cnt - 1)); i; i >>= 1) { 42659243Sobrien if (bits & i) { 42759243Sobrien SIO_SET(NGE_MEAR_MII_DATA); 42859243Sobrien } else { 42959243Sobrien SIO_CLR(NGE_MEAR_MII_DATA); 43059243Sobrien } 43159243Sobrien DELAY(1); 43259243Sobrien SIO_CLR(NGE_MEAR_MII_CLK); 43359243Sobrien DELAY(1); 43459243Sobrien SIO_SET(NGE_MEAR_MII_CLK); 43559243Sobrien } 43659243Sobrien} 43759243Sobrien 43859243Sobrien/* 43959243Sobrien * Read an PHY register through the MII. 44059243Sobrien */ 44159243Sobrienstatic int 44259243Sobriennge_mii_readreg(sc, frame) 44359243Sobrien struct nge_softc *sc; 44459243Sobrien struct nge_mii_frame *frame; 44559243Sobrien 44659243Sobrien{ 44759243Sobrien int i, ack, s; 44859243Sobrien 44959243Sobrien s = splimp(); 45059243Sobrien 45159243Sobrien /* 45259243Sobrien * Set up frame for RX. 45359243Sobrien */ 45459243Sobrien frame->mii_stdelim = NGE_MII_STARTDELIM; 45559243Sobrien frame->mii_opcode = NGE_MII_READOP; 45659243Sobrien frame->mii_turnaround = 0; 45759243Sobrien frame->mii_data = 0; 45859243Sobrien 45959243Sobrien CSR_WRITE_4(sc, NGE_MEAR, 0); 46059243Sobrien 46159243Sobrien /* 46259243Sobrien * Turn on data xmit. 46359243Sobrien */ 46459243Sobrien SIO_SET(NGE_MEAR_MII_DIR); 46559243Sobrien 46659243Sobrien nge_mii_sync(sc); 46759243Sobrien 46859243Sobrien /* 46959243Sobrien * Send command/address info. 47059243Sobrien */ 47159243Sobrien nge_mii_send(sc, frame->mii_stdelim, 2); 47259243Sobrien nge_mii_send(sc, frame->mii_opcode, 2); 47359243Sobrien nge_mii_send(sc, frame->mii_phyaddr, 5); 47459243Sobrien nge_mii_send(sc, frame->mii_regaddr, 5); 47559243Sobrien 47659243Sobrien /* Idle bit */ 47759243Sobrien SIO_CLR((NGE_MEAR_MII_CLK|NGE_MEAR_MII_DATA)); 47859243Sobrien DELAY(1); 47959243Sobrien SIO_SET(NGE_MEAR_MII_CLK); 48059243Sobrien DELAY(1); 48159243Sobrien 48259243Sobrien /* Turn off xmit. */ 48359243Sobrien SIO_CLR(NGE_MEAR_MII_DIR); 48459243Sobrien /* Check for ack */ 48559243Sobrien SIO_CLR(NGE_MEAR_MII_CLK); 48659243Sobrien DELAY(1); 48759243Sobrien ack = CSR_READ_4(sc, NGE_MEAR) & NGE_MEAR_MII_DATA; 48859243Sobrien SIO_SET(NGE_MEAR_MII_CLK); 48959243Sobrien DELAY(1); 49059243Sobrien 49159243Sobrien /* 49259243Sobrien * Now try reading data bits. If the ack failed, we still 49359243Sobrien * need to clock through 16 cycles to keep the PHY(s) in sync. 49459243Sobrien */ 49559243Sobrien if (ack) { 49659243Sobrien for(i = 0; i < 16; i++) { 49759243Sobrien SIO_CLR(NGE_MEAR_MII_CLK); 49859243Sobrien DELAY(1); 49959243Sobrien SIO_SET(NGE_MEAR_MII_CLK); 50059243Sobrien DELAY(1); 50159243Sobrien } 50259243Sobrien goto fail; 50359243Sobrien } 50459243Sobrien 50559243Sobrien for (i = 0x8000; i; i >>= 1) { 50659243Sobrien SIO_CLR(NGE_MEAR_MII_CLK); 50759243Sobrien DELAY(1); 50859243Sobrien if (!ack) { 50959243Sobrien if (CSR_READ_4(sc, NGE_MEAR) & NGE_MEAR_MII_DATA) 51059243Sobrien frame->mii_data |= i; 51159243Sobrien DELAY(1); 51259243Sobrien } 51359243Sobrien SIO_SET(NGE_MEAR_MII_CLK); 51459243Sobrien DELAY(1); 51559243Sobrien } 51659243Sobrien 51759243Sobrienfail: 51859243Sobrien 51959243Sobrien SIO_CLR(NGE_MEAR_MII_CLK); 52059243Sobrien DELAY(1); 52159243Sobrien SIO_SET(NGE_MEAR_MII_CLK); 52259243Sobrien DELAY(1); 52359243Sobrien 52459243Sobrien splx(s); 52559243Sobrien 52659243Sobrien if (ack) 52759243Sobrien return(1); 52859243Sobrien return(0); 52959243Sobrien} 53059243Sobrien 53159243Sobrien/* 53259243Sobrien * Write to a PHY register through the MII. 53359243Sobrien */ 53459243Sobrienstatic int 53559243Sobriennge_mii_writereg(sc, frame) 53659243Sobrien struct nge_softc *sc; 53759243Sobrien struct nge_mii_frame *frame; 53859243Sobrien 53959243Sobrien{ 54059243Sobrien int s; 54159243Sobrien 54259243Sobrien s = splimp(); 54359243Sobrien /* 54459243Sobrien * Set up frame for TX. 54559243Sobrien */ 54659243Sobrien 54759243Sobrien frame->mii_stdelim = NGE_MII_STARTDELIM; 54859243Sobrien frame->mii_opcode = NGE_MII_WRITEOP; 54959243Sobrien frame->mii_turnaround = NGE_MII_TURNAROUND; 55059243Sobrien 55159243Sobrien /* 55259243Sobrien * Turn on data output. 55359243Sobrien */ 55459243Sobrien SIO_SET(NGE_MEAR_MII_DIR); 55559243Sobrien 55659243Sobrien nge_mii_sync(sc); 55759243Sobrien 55859243Sobrien nge_mii_send(sc, frame->mii_stdelim, 2); 55959243Sobrien nge_mii_send(sc, frame->mii_opcode, 2); 56059243Sobrien nge_mii_send(sc, frame->mii_phyaddr, 5); 56159243Sobrien nge_mii_send(sc, frame->mii_regaddr, 5); 56259243Sobrien nge_mii_send(sc, frame->mii_turnaround, 2); 56359243Sobrien nge_mii_send(sc, frame->mii_data, 16); 56459243Sobrien 56559243Sobrien /* Idle bit. */ 56659243Sobrien SIO_SET(NGE_MEAR_MII_CLK); 56759243Sobrien DELAY(1); 56859243Sobrien SIO_CLR(NGE_MEAR_MII_CLK); 56959243Sobrien DELAY(1); 57059243Sobrien 57159243Sobrien /* 57259243Sobrien * Turn off xmit. 57359243Sobrien */ 57459243Sobrien SIO_CLR(NGE_MEAR_MII_DIR); 57559243Sobrien 57659243Sobrien splx(s); 57759243Sobrien 57859243Sobrien return(0); 57959243Sobrien} 58059243Sobrien 58159243Sobrienstatic int 58259243Sobriennge_miibus_readreg(dev, phy, reg) 58359243Sobrien device_t dev; 58459243Sobrien int phy, reg; 58559243Sobrien{ 58659243Sobrien struct nge_softc *sc; 58759243Sobrien struct nge_mii_frame frame; 58859243Sobrien 58959243Sobrien sc = device_get_softc(dev); 59059243Sobrien 59159243Sobrien bzero((char *)&frame, sizeof(frame)); 59259243Sobrien 59359243Sobrien frame.mii_phyaddr = phy; 59459243Sobrien frame.mii_regaddr = reg; 595145479Smp nge_mii_readreg(sc, &frame); 59659243Sobrien 59759243Sobrien return(frame.mii_data); 59859243Sobrien} 59959243Sobrien 60059243Sobrienstatic int 60159243Sobriennge_miibus_writereg(dev, phy, reg, data) 60259243Sobrien device_t dev; 60359243Sobrien int phy, reg, data; 60459243Sobrien{ 60559243Sobrien struct nge_softc *sc; 60659243Sobrien struct nge_mii_frame frame; 60759243Sobrien 60859243Sobrien sc = device_get_softc(dev); 60959243Sobrien 61059243Sobrien bzero((char *)&frame, sizeof(frame)); 61159243Sobrien 61259243Sobrien frame.mii_phyaddr = phy; 61359243Sobrien frame.mii_regaddr = reg; 61459243Sobrien frame.mii_data = data; 61559243Sobrien nge_mii_writereg(sc, &frame); 61659243Sobrien 61759243Sobrien return(0); 61859243Sobrien} 61959243Sobrien 62059243Sobrienstatic void 62159243Sobriennge_miibus_statchg(dev) 62259243Sobrien device_t dev; 62359243Sobrien{ 62459243Sobrien int status; 62559243Sobrien struct nge_softc *sc; 62659243Sobrien struct mii_data *mii; 62759243Sobrien 62859243Sobrien sc = device_get_softc(dev); 62959243Sobrien if (sc->nge_tbi) { 63059243Sobrien if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) 63169408Sache == IFM_AUTO) { 63259243Sobrien status = CSR_READ_4(sc, NGE_TBI_ANLPAR); 63359243Sobrien if (status == 0 || status & NGE_TBIANAR_FDX) { 63459243Sobrien NGE_SETBIT(sc, NGE_TX_CFG, 63559243Sobrien (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 63659243Sobrien NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 63769408Sache } else { 63859243Sobrien NGE_CLRBIT(sc, NGE_TX_CFG, 63959243Sobrien (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 64059243Sobrien NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 64159243Sobrien } 64259243Sobrien 64359243Sobrien } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) 64459243Sobrien != IFM_FDX) { 64559243Sobrien NGE_CLRBIT(sc, NGE_TX_CFG, 64659243Sobrien (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 64759243Sobrien NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 64859243Sobrien } else { 64959243Sobrien NGE_SETBIT(sc, NGE_TX_CFG, 65059243Sobrien (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 65159243Sobrien NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 65259243Sobrien } 65359243Sobrien } else { 65459243Sobrien mii = device_get_softc(sc->nge_miibus); 65559243Sobrien 65669408Sache if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { 65759243Sobrien NGE_SETBIT(sc, NGE_TX_CFG, 65859243Sobrien (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 65959243Sobrien NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 66059243Sobrien } else { 66159243Sobrien NGE_CLRBIT(sc, NGE_TX_CFG, 66259243Sobrien (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 66359243Sobrien NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 66459243Sobrien } 66559243Sobrien 66659243Sobrien /* If we have a 1000Mbps link, set the mode_1000 bit. */ 66759243Sobrien if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T || 66859243Sobrien IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) { 66959243Sobrien NGE_SETBIT(sc, NGE_CFG, NGE_CFG_MODE_1000); 67059243Sobrien } else { 67159243Sobrien NGE_CLRBIT(sc, NGE_CFG, NGE_CFG_MODE_1000); 67259243Sobrien } 67359243Sobrien } 67459243Sobrien return; 67559243Sobrien} 67659243Sobrien 67759243Sobrienstatic u_int32_t 678145479Smpnge_mchash(addr) 67959243Sobrien caddr_t addr; 68059243Sobrien{ 68159243Sobrien u_int32_t crc, carry; 68259243Sobrien int idx, bit; 68359243Sobrien u_int8_t data; 68459243Sobrien 68559243Sobrien /* Compute CRC for the address value. */ 68659243Sobrien crc = 0xFFFFFFFF; /* initial value */ 68759243Sobrien 68859243Sobrien for (idx = 0; idx < 6; idx++) { 689145479Smp for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1) { 69059243Sobrien carry = ((crc & 0x80000000) ? 1 : 0) ^ (data & 0x01); 69159243Sobrien crc <<= 1; 69259243Sobrien if (carry) 69359243Sobrien crc = (crc ^ 0x04c11db6) | carry; 69459243Sobrien } 69559243Sobrien } 69659243Sobrien 69759243Sobrien /* 69859243Sobrien * return the filter bit position 69959243Sobrien */ 70059243Sobrien 70159243Sobrien return((crc >> 21) & 0x00000FFF); 70259243Sobrien} 70359243Sobrien 70459243Sobrienstatic void 70559243Sobriennge_setmulti(sc) 70659243Sobrien struct nge_softc *sc; 70759243Sobrien{ 70859243Sobrien struct ifnet *ifp; 70959243Sobrien struct ifmultiaddr *ifma; 71059243Sobrien u_int32_t h = 0, i, filtsave; 71159243Sobrien int bit, index; 71259243Sobrien 71359243Sobrien ifp = &sc->arpcom.ac_if; 71459243Sobrien 71559243Sobrien if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 71659243Sobrien NGE_CLRBIT(sc, NGE_RXFILT_CTL, 71759243Sobrien NGE_RXFILTCTL_MCHASH|NGE_RXFILTCTL_UCHASH); 71883098Smp NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLMULTI); 71983098Smp return; 72083098Smp } 72159243Sobrien 72259243Sobrien /* 72359243Sobrien * We have to explicitly enable the multicast hash table 72459243Sobrien * on the NatSemi chip if we want to use it, which we do. 72559243Sobrien * We also have to tell it that we don't want to use the 72659243Sobrien * hash table for matching unicast addresses. 72759243Sobrien */ 72859243Sobrien NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_MCHASH); 72959243Sobrien NGE_CLRBIT(sc, NGE_RXFILT_CTL, 730145479Smp NGE_RXFILTCTL_ALLMULTI|NGE_RXFILTCTL_UCHASH); 731145479Smp 73259243Sobrien filtsave = CSR_READ_4(sc, NGE_RXFILT_CTL); 73359243Sobrien 73459243Sobrien /* first, zot all the existing hash bits */ 73559243Sobrien for (i = 0; i < NGE_MCAST_FILTER_LEN; i += 2) { 73659243Sobrien CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_MCAST_LO + i); 73759243Sobrien CSR_WRITE_4(sc, NGE_RXFILT_DATA, 0); 73859243Sobrien } 73959243Sobrien 74059243Sobrien /* 74159243Sobrien * From the 11 bits returned by the crc routine, the top 7 74259243Sobrien * bits represent the 16-bit word in the mcast hash table 74359243Sobrien * that needs to be updated, and the lower 4 bits represent 74459243Sobrien * which bit within that byte needs to be set. 74559243Sobrien */ 74669408Sache TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 74759243Sobrien if (ifma->ifma_addr->sa_family != AF_LINK) 74859243Sobrien continue; 74959243Sobrien h = nge_mchash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); 75059243Sobrien index = (h >> 4) & 0x7F; 75159243Sobrien bit = h & 0xF; 75259243Sobrien CSR_WRITE_4(sc, NGE_RXFILT_CTL, 75359243Sobrien NGE_FILTADDR_MCAST_LO + (index * 2)); 75459243Sobrien NGE_SETBIT(sc, NGE_RXFILT_DATA, (1 << bit)); 75559243Sobrien } 75659243Sobrien 75759243Sobrien CSR_WRITE_4(sc, NGE_RXFILT_CTL, filtsave); 75859243Sobrien 75959243Sobrien return; 76059243Sobrien} 76159243Sobrien 76259243Sobrienstatic void 76369408Sachenge_reset(sc) 76459243Sobrien struct nge_softc *sc; 76569408Sache{ 76659243Sobrien register int i; 76759243Sobrien 76859243Sobrien NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RESET); 76959243Sobrien 77069408Sache for (i = 0; i < NGE_TIMEOUT; i++) { 77159243Sobrien if (!(CSR_READ_4(sc, NGE_CSR) & NGE_CSR_RESET)) 77259243Sobrien break; 77359243Sobrien } 77459243Sobrien 77559243Sobrien if (i == NGE_TIMEOUT) 77659243Sobrien printf("nge%d: reset never completed\n", sc->nge_unit); 77759243Sobrien 77859243Sobrien /* Wait a little while for the chip to get its brains in order. */ 77959243Sobrien DELAY(1000); 78059243Sobrien 78159243Sobrien /* 78259243Sobrien * If this is a NetSemi chip, make sure to clear 78359243Sobrien * PME mode. 78459243Sobrien */ 78559243Sobrien CSR_WRITE_4(sc, NGE_CLKRUN, NGE_CLKRUN_PMESTS); 78659243Sobrien CSR_WRITE_4(sc, NGE_CLKRUN, 0); 78759243Sobrien 78859243Sobrien return; 78959243Sobrien} 79059243Sobrien 79169408Sache/* 79259243Sobrien * Probe for a NatSemi chip. Check the PCI vendor and device 79369408Sache * IDs against our list and return a device name if we find a match. 79459243Sobrien */ 79569408Sachestatic int 79659243Sobriennge_probe(dev) 79759243Sobrien device_t dev; 79859243Sobrien{ 79959243Sobrien struct nge_type *t; 80069408Sache 80159243Sobrien t = nge_devs; 80259243Sobrien 80359243Sobrien while(t->nge_name != NULL) { 80459243Sobrien if ((pci_get_vendor(dev) == t->nge_vid) && 80559243Sobrien (pci_get_device(dev) == t->nge_did)) { 80669408Sache device_set_desc(dev, t->nge_name); 80759243Sobrien return(0); 80859243Sobrien } 80959243Sobrien t++; 81059243Sobrien } 81159243Sobrien 81259243Sobrien return(ENXIO); 81359243Sobrien} 81459243Sobrien 81559243Sobrien/* 81659243Sobrien * Attach the interface. Allocate softc structures, do ifmedia 81759243Sobrien * setup and ethernet/BPF attach. 81859243Sobrien */ 81959243Sobrienstatic int 82069408Sachenge_attach(dev) 82159243Sobrien device_t dev; 82259243Sobrien{ 82359243Sobrien int s; 82459243Sobrien u_char eaddr[ETHER_ADDR_LEN]; 82559243Sobrien struct nge_softc *sc; 826145479Smp struct ifnet *ifp; 827145479Smp int unit, error = 0, rid; 82859243Sobrien const char *sep = ""; 82959243Sobrien 83059243Sobrien s = splimp(); 83159243Sobrien 83259243Sobrien sc = device_get_softc(dev); 83359243Sobrien unit = device_get_unit(dev); 83459243Sobrien bzero(sc, sizeof(struct nge_softc)); 83559243Sobrien 83669408Sache mtx_init(&sc->nge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 83759243Sobrien MTX_DEF | MTX_RECURSE); 83869408Sache#ifndef BURN_BRIDGES 83959243Sobrien /* 84069408Sache * Handle power management nonsense. 84159243Sobrien */ 84259243Sobrien if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { 84359243Sobrien u_int32_t iobase, membase, irq; 844 845 /* Save important PCI config data. */ 846 iobase = pci_read_config(dev, NGE_PCI_LOIO, 4); 847 membase = pci_read_config(dev, NGE_PCI_LOMEM, 4); 848 irq = pci_read_config(dev, NGE_PCI_INTLINE, 4); 849 850 /* Reset the power state. */ 851 printf("nge%d: chip is in D%d power mode " 852 "-- setting to D0\n", unit, 853 pci_get_powerstate(dev)); 854 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 855 856 /* Restore PCI config data. */ 857 pci_write_config(dev, NGE_PCI_LOIO, iobase, 4); 858 pci_write_config(dev, NGE_PCI_LOMEM, membase, 4); 859 pci_write_config(dev, NGE_PCI_INTLINE, irq, 4); 860 } 861#endif 862 /* 863 * Map control/status registers. 864 */ 865 pci_enable_busmaster(dev); 866 867 rid = NGE_RID; 868 sc->nge_res = bus_alloc_resource(dev, NGE_RES, &rid, 869 0, ~0, 1, RF_ACTIVE); 870 871 if (sc->nge_res == NULL) { 872 printf("nge%d: couldn't map ports/memory\n", unit); 873 error = ENXIO; 874 goto fail; 875 } 876 877 sc->nge_btag = rman_get_bustag(sc->nge_res); 878 sc->nge_bhandle = rman_get_bushandle(sc->nge_res); 879 880 /* Allocate interrupt */ 881 rid = 0; 882 sc->nge_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, 883 RF_SHAREABLE | RF_ACTIVE); 884 885 if (sc->nge_irq == NULL) { 886 printf("nge%d: couldn't map interrupt\n", unit); 887 bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res); 888 error = ENXIO; 889 goto fail; 890 } 891 892 error = bus_setup_intr(dev, sc->nge_irq, INTR_TYPE_NET, 893 nge_intr, sc, &sc->nge_intrhand); 894 895 if (error) { 896 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq); 897 bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res); 898 printf("nge%d: couldn't set up irq\n", unit); 899 goto fail; 900 } 901 902 /* Reset the adapter. */ 903 nge_reset(sc); 904 905 /* 906 * Get station address from the EEPROM. 907 */ 908 nge_read_eeprom(sc, (caddr_t)&eaddr[4], NGE_EE_NODEADDR, 1, 0); 909 nge_read_eeprom(sc, (caddr_t)&eaddr[2], NGE_EE_NODEADDR + 1, 1, 0); 910 nge_read_eeprom(sc, (caddr_t)&eaddr[0], NGE_EE_NODEADDR + 2, 1, 0); 911 912 /* 913 * A NatSemi chip was detected. Inform the world. 914 */ 915 printf("nge%d: Ethernet address: %6D\n", unit, eaddr, ":"); 916 917 sc->nge_unit = unit; 918 bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 919 920 sc->nge_ldata = contigmalloc(sizeof(struct nge_list_data), M_DEVBUF, 921 M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); 922 923 if (sc->nge_ldata == NULL) { 924 printf("nge%d: no memory for list buffers!\n", unit); 925 bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand); 926 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq); 927 bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res); 928 error = ENXIO; 929 goto fail; 930 } 931 bzero(sc->nge_ldata, sizeof(struct nge_list_data)); 932 933 /* Try to allocate memory for jumbo buffers. */ 934 if (nge_alloc_jumbo_mem(sc)) { 935 printf("nge%d: jumbo buffer allocation failed\n", 936 sc->nge_unit); 937 contigfree(sc->nge_ldata, 938 sizeof(struct nge_list_data), M_DEVBUF); 939 bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand); 940 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq); 941 bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res); 942 error = ENXIO; 943 goto fail; 944 } 945 946 ifp = &sc->arpcom.ac_if; 947 ifp->if_softc = sc; 948 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 949 ifp->if_mtu = ETHERMTU; 950 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 951 ifp->if_ioctl = nge_ioctl; 952 ifp->if_output = ether_output; 953 ifp->if_start = nge_start; 954 ifp->if_watchdog = nge_watchdog; 955 ifp->if_init = nge_init; 956 ifp->if_baudrate = 1000000000; 957 ifp->if_snd.ifq_maxlen = NGE_TX_LIST_CNT - 1; 958 ifp->if_hwassist = NGE_CSUM_FEATURES; 959 ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING; 960 ifp->if_capenable = ifp->if_capabilities; 961 962 /* 963 * Do MII setup. 964 */ 965 if (mii_phy_probe(dev, &sc->nge_miibus, 966 nge_ifmedia_upd, nge_ifmedia_sts)) { 967 if (CSR_READ_4(sc, NGE_CFG) & NGE_CFG_TBI_EN) { 968 sc->nge_tbi = 1; 969 device_printf(dev, "Using TBI\n"); 970 971 sc->nge_miibus = dev; 972 973 ifmedia_init(&sc->nge_ifmedia, 0, nge_ifmedia_upd, 974 nge_ifmedia_sts); 975#define ADD(m, c) ifmedia_add(&sc->nge_ifmedia, (m), (c), NULL) 976#define PRINT(s) printf("%s%s", sep, s); sep = ", " 977 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, 0), 0); 978 device_printf(dev, " "); 979 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0, 0), 0); 980 PRINT("1000baseSX"); 981 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, 0),0); 982 PRINT("1000baseSX-FDX"); 983 ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0), 0); 984 PRINT("auto"); 985 986 printf("\n"); 987#undef ADD 988#undef PRINT 989 ifmedia_set(&sc->nge_ifmedia, 990 IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0)); 991 992 CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) 993 | NGE_GPIO_GP4_OUT 994 | NGE_GPIO_GP1_OUTENB | NGE_GPIO_GP2_OUTENB 995 | NGE_GPIO_GP3_OUTENB 996 | NGE_GPIO_GP3_IN | NGE_GPIO_GP4_IN); 997 998 } else { 999 printf("nge%d: MII without any PHY!\n", sc->nge_unit); 1000 nge_free_jumbo_mem(sc); 1001 bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand); 1002 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq); 1003 bus_release_resource(dev, NGE_RES, NGE_RID, 1004 sc->nge_res); 1005 error = ENXIO; 1006 goto fail; 1007 } 1008 } 1009 1010 /* 1011 * Call MI attach routine. 1012 */ 1013 ether_ifattach(ifp, eaddr); 1014 callout_handle_init(&sc->nge_stat_ch); 1015 1016fail: 1017 1018 splx(s); 1019 mtx_destroy(&sc->nge_mtx); 1020 return(error); 1021} 1022 1023static int 1024nge_detach(dev) 1025 device_t dev; 1026{ 1027 struct nge_softc *sc; 1028 struct ifnet *ifp; 1029 int s; 1030 1031 s = splimp(); 1032 1033 sc = device_get_softc(dev); 1034 ifp = &sc->arpcom.ac_if; 1035 1036 nge_reset(sc); 1037 nge_stop(sc); 1038 ether_ifdetach(ifp); 1039 1040 bus_generic_detach(dev); 1041 if (!sc->nge_tbi) { 1042 device_delete_child(dev, sc->nge_miibus); 1043 } 1044 bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand); 1045 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq); 1046 bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res); 1047 1048 contigfree(sc->nge_ldata, sizeof(struct nge_list_data), M_DEVBUF); 1049 nge_free_jumbo_mem(sc); 1050 1051 splx(s); 1052 mtx_destroy(&sc->nge_mtx); 1053 1054 return(0); 1055} 1056 1057/* 1058 * Initialize the transmit descriptors. 1059 */ 1060static int 1061nge_list_tx_init(sc) 1062 struct nge_softc *sc; 1063{ 1064 struct nge_list_data *ld; 1065 struct nge_ring_data *cd; 1066 int i; 1067 1068 cd = &sc->nge_cdata; 1069 ld = sc->nge_ldata; 1070 1071 for (i = 0; i < NGE_TX_LIST_CNT; i++) { 1072 if (i == (NGE_TX_LIST_CNT - 1)) { 1073 ld->nge_tx_list[i].nge_nextdesc = 1074 &ld->nge_tx_list[0]; 1075 ld->nge_tx_list[i].nge_next = 1076 vtophys(&ld->nge_tx_list[0]); 1077 } else { 1078 ld->nge_tx_list[i].nge_nextdesc = 1079 &ld->nge_tx_list[i + 1]; 1080 ld->nge_tx_list[i].nge_next = 1081 vtophys(&ld->nge_tx_list[i + 1]); 1082 } 1083 ld->nge_tx_list[i].nge_mbuf = NULL; 1084 ld->nge_tx_list[i].nge_ptr = 0; 1085 ld->nge_tx_list[i].nge_ctl = 0; 1086 } 1087 1088 cd->nge_tx_prod = cd->nge_tx_cons = cd->nge_tx_cnt = 0; 1089 1090 return(0); 1091} 1092 1093 1094/* 1095 * Initialize the RX descriptors and allocate mbufs for them. Note that 1096 * we arrange the descriptors in a closed ring, so that the last descriptor 1097 * points back to the first. 1098 */ 1099static int 1100nge_list_rx_init(sc) 1101 struct nge_softc *sc; 1102{ 1103 struct nge_list_data *ld; 1104 struct nge_ring_data *cd; 1105 int i; 1106 1107 ld = sc->nge_ldata; 1108 cd = &sc->nge_cdata; 1109 1110 for (i = 0; i < NGE_RX_LIST_CNT; i++) { 1111 if (nge_newbuf(sc, &ld->nge_rx_list[i], NULL) == ENOBUFS) 1112 return(ENOBUFS); 1113 if (i == (NGE_RX_LIST_CNT - 1)) { 1114 ld->nge_rx_list[i].nge_nextdesc = 1115 &ld->nge_rx_list[0]; 1116 ld->nge_rx_list[i].nge_next = 1117 vtophys(&ld->nge_rx_list[0]); 1118 } else { 1119 ld->nge_rx_list[i].nge_nextdesc = 1120 &ld->nge_rx_list[i + 1]; 1121 ld->nge_rx_list[i].nge_next = 1122 vtophys(&ld->nge_rx_list[i + 1]); 1123 } 1124 } 1125 1126 cd->nge_rx_prod = 0; 1127 1128 return(0); 1129} 1130 1131/* 1132 * Initialize an RX descriptor and attach an MBUF cluster. 1133 */ 1134static int 1135nge_newbuf(sc, c, m) 1136 struct nge_softc *sc; 1137 struct nge_desc *c; 1138 struct mbuf *m; 1139{ 1140 struct mbuf *m_new = NULL; 1141 caddr_t *buf = NULL; 1142 1143 if (m == NULL) { 1144 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 1145 if (m_new == NULL) { 1146 printf("nge%d: no memory for rx list " 1147 "-- packet dropped!\n", sc->nge_unit); 1148 return(ENOBUFS); 1149 } 1150 1151 /* Allocate the jumbo buffer */ 1152 buf = nge_jalloc(sc); 1153 if (buf == NULL) { 1154#ifdef NGE_VERBOSE 1155 printf("nge%d: jumbo allocation failed " 1156 "-- packet dropped!\n", sc->nge_unit); 1157#endif 1158 m_freem(m_new); 1159 return(ENOBUFS); 1160 } 1161 /* Attach the buffer to the mbuf */ 1162 m_new->m_data = (void *)buf; 1163 m_new->m_len = m_new->m_pkthdr.len = NGE_JUMBO_FRAMELEN; 1164 MEXTADD(m_new, buf, NGE_JUMBO_FRAMELEN, nge_jfree, 1165 (struct nge_softc *)sc, 0, EXT_NET_DRV); 1166 } else { 1167 m_new = m; 1168 m_new->m_len = m_new->m_pkthdr.len = NGE_JUMBO_FRAMELEN; 1169 m_new->m_data = m_new->m_ext.ext_buf; 1170 } 1171 1172 m_adj(m_new, sizeof(u_int64_t)); 1173 1174 c->nge_mbuf = m_new; 1175 c->nge_ptr = vtophys(mtod(m_new, caddr_t)); 1176 c->nge_ctl = m_new->m_len; 1177 c->nge_extsts = 0; 1178 1179 return(0); 1180} 1181 1182static int 1183nge_alloc_jumbo_mem(sc) 1184 struct nge_softc *sc; 1185{ 1186 caddr_t ptr; 1187 register int i; 1188 struct nge_jpool_entry *entry; 1189 1190 /* Grab a big chunk o' storage. */ 1191 sc->nge_cdata.nge_jumbo_buf = contigmalloc(NGE_JMEM, M_DEVBUF, 1192 M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0); 1193 1194 if (sc->nge_cdata.nge_jumbo_buf == NULL) { 1195 printf("nge%d: no memory for jumbo buffers!\n", sc->nge_unit); 1196 return(ENOBUFS); 1197 } 1198 1199 SLIST_INIT(&sc->nge_jfree_listhead); 1200 SLIST_INIT(&sc->nge_jinuse_listhead); 1201 1202 /* 1203 * Now divide it up into 9K pieces and save the addresses 1204 * in an array. 1205 */ 1206 ptr = sc->nge_cdata.nge_jumbo_buf; 1207 for (i = 0; i < NGE_JSLOTS; i++) { 1208 sc->nge_cdata.nge_jslots[i] = ptr; 1209 ptr += NGE_JLEN; 1210 entry = malloc(sizeof(struct nge_jpool_entry), 1211 M_DEVBUF, M_NOWAIT); 1212 if (entry == NULL) { 1213 printf("nge%d: no memory for jumbo " 1214 "buffer queue!\n", sc->nge_unit); 1215 return(ENOBUFS); 1216 } 1217 entry->slot = i; 1218 SLIST_INSERT_HEAD(&sc->nge_jfree_listhead, 1219 entry, jpool_entries); 1220 } 1221 1222 return(0); 1223} 1224 1225static void 1226nge_free_jumbo_mem(sc) 1227 struct nge_softc *sc; 1228{ 1229 register int i; 1230 struct nge_jpool_entry *entry; 1231 1232 for (i = 0; i < NGE_JSLOTS; i++) { 1233 entry = SLIST_FIRST(&sc->nge_jfree_listhead); 1234 SLIST_REMOVE_HEAD(&sc->nge_jfree_listhead, jpool_entries); 1235 free(entry, M_DEVBUF); 1236 } 1237 1238 contigfree(sc->nge_cdata.nge_jumbo_buf, NGE_JMEM, M_DEVBUF); 1239 1240 return; 1241} 1242 1243/* 1244 * Allocate a jumbo buffer. 1245 */ 1246static void * 1247nge_jalloc(sc) 1248 struct nge_softc *sc; 1249{ 1250 struct nge_jpool_entry *entry; 1251 1252 entry = SLIST_FIRST(&sc->nge_jfree_listhead); 1253 1254 if (entry == NULL) { 1255#ifdef NGE_VERBOSE 1256 printf("nge%d: no free jumbo buffers\n", sc->nge_unit); 1257#endif 1258 return(NULL); 1259 } 1260 1261 SLIST_REMOVE_HEAD(&sc->nge_jfree_listhead, jpool_entries); 1262 SLIST_INSERT_HEAD(&sc->nge_jinuse_listhead, entry, jpool_entries); 1263 return(sc->nge_cdata.nge_jslots[entry->slot]); 1264} 1265 1266/* 1267 * Release a jumbo buffer. 1268 */ 1269static void 1270nge_jfree(buf, args) 1271 void *buf; 1272 void *args; 1273{ 1274 struct nge_softc *sc; 1275 int i; 1276 struct nge_jpool_entry *entry; 1277 1278 /* Extract the softc struct pointer. */ 1279 sc = args; 1280 1281 if (sc == NULL) 1282 panic("nge_jfree: can't find softc pointer!"); 1283 1284 /* calculate the slot this buffer belongs to */ 1285 i = ((vm_offset_t)buf 1286 - (vm_offset_t)sc->nge_cdata.nge_jumbo_buf) / NGE_JLEN; 1287 1288 if ((i < 0) || (i >= NGE_JSLOTS)) 1289 panic("nge_jfree: asked to free buffer that we don't manage!"); 1290 1291 entry = SLIST_FIRST(&sc->nge_jinuse_listhead); 1292 if (entry == NULL) 1293 panic("nge_jfree: buffer not in use!"); 1294 entry->slot = i; 1295 SLIST_REMOVE_HEAD(&sc->nge_jinuse_listhead, jpool_entries); 1296 SLIST_INSERT_HEAD(&sc->nge_jfree_listhead, entry, jpool_entries); 1297 1298 return; 1299} 1300/* 1301 * A frame has been uploaded: pass the resulting mbuf chain up to 1302 * the higher level protocols. 1303 */ 1304static void 1305nge_rxeof(sc) 1306 struct nge_softc *sc; 1307{ 1308 struct mbuf *m; 1309 struct ifnet *ifp; 1310 struct nge_desc *cur_rx; 1311 int i, total_len = 0; 1312 u_int32_t rxstat; 1313 1314 ifp = &sc->arpcom.ac_if; 1315 i = sc->nge_cdata.nge_rx_prod; 1316 1317 while(NGE_OWNDESC(&sc->nge_ldata->nge_rx_list[i])) { 1318 struct mbuf *m0 = NULL; 1319 u_int32_t extsts; 1320 1321#ifdef DEVICE_POLLING 1322 if (ifp->if_ipending & IFF_POLLING) { 1323 if (sc->rxcycles <= 0) 1324 break; 1325 sc->rxcycles--; 1326 } 1327#endif /* DEVICE_POLLING */ 1328 1329 cur_rx = &sc->nge_ldata->nge_rx_list[i]; 1330 rxstat = cur_rx->nge_rxstat; 1331 extsts = cur_rx->nge_extsts; 1332 m = cur_rx->nge_mbuf; 1333 cur_rx->nge_mbuf = NULL; 1334 total_len = NGE_RXBYTES(cur_rx); 1335 NGE_INC(i, NGE_RX_LIST_CNT); 1336 /* 1337 * If an error occurs, update stats, clear the 1338 * status word and leave the mbuf cluster in place: 1339 * it should simply get re-used next time this descriptor 1340 * comes up in the ring. 1341 */ 1342 if (!(rxstat & NGE_CMDSTS_PKT_OK)) { 1343 ifp->if_ierrors++; 1344 nge_newbuf(sc, cur_rx, m); 1345 continue; 1346 } 1347 1348 /* 1349 * Ok. NatSemi really screwed up here. This is the 1350 * only gigE chip I know of with alignment constraints 1351 * on receive buffers. RX buffers must be 64-bit aligned. 1352 */ 1353#ifdef __i386__ 1354 /* 1355 * By popular demand, ignore the alignment problems 1356 * on the Intel x86 platform. The performance hit 1357 * incurred due to unaligned accesses is much smaller 1358 * than the hit produced by forcing buffer copies all 1359 * the time, especially with jumbo frames. We still 1360 * need to fix up the alignment everywhere else though. 1361 */ 1362 if (nge_newbuf(sc, cur_rx, NULL) == ENOBUFS) { 1363#endif 1364 m0 = m_devget(mtod(m, char *), total_len, 1365 ETHER_ALIGN, ifp, NULL); 1366 nge_newbuf(sc, cur_rx, m); 1367 if (m0 == NULL) { 1368 printf("nge%d: no receive buffers " 1369 "available -- packet dropped!\n", 1370 sc->nge_unit); 1371 ifp->if_ierrors++; 1372 continue; 1373 } 1374 m = m0; 1375#ifdef __i386__ 1376 } else { 1377 m->m_pkthdr.rcvif = ifp; 1378 m->m_pkthdr.len = m->m_len = total_len; 1379 } 1380#endif 1381 1382 ifp->if_ipackets++; 1383 1384 /* Do IP checksum checking. */ 1385 if (extsts & NGE_RXEXTSTS_IPPKT) 1386 m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; 1387 if (!(extsts & NGE_RXEXTSTS_IPCSUMERR)) 1388 m->m_pkthdr.csum_flags |= CSUM_IP_VALID; 1389 if ((extsts & NGE_RXEXTSTS_TCPPKT && 1390 !(extsts & NGE_RXEXTSTS_TCPCSUMERR)) || 1391 (extsts & NGE_RXEXTSTS_UDPPKT && 1392 !(extsts & NGE_RXEXTSTS_UDPCSUMERR))) { 1393 m->m_pkthdr.csum_flags |= 1394 CSUM_DATA_VALID|CSUM_PSEUDO_HDR; 1395 m->m_pkthdr.csum_data = 0xffff; 1396 } 1397 1398 /* 1399 * If we received a packet with a vlan tag, pass it 1400 * to vlan_input() instead of ether_input(). 1401 */ 1402 if (extsts & NGE_RXEXTSTS_VLANPKT) { 1403 VLAN_INPUT_TAG(ifp, m, 1404 extsts & NGE_RXEXTSTS_VTCI, continue); 1405 } 1406 1407 (*ifp->if_input)(ifp, m); 1408 } 1409 1410 sc->nge_cdata.nge_rx_prod = i; 1411 1412 return; 1413} 1414 1415/* 1416 * A frame was downloaded to the chip. It's safe for us to clean up 1417 * the list buffers. 1418 */ 1419 1420static void 1421nge_txeof(sc) 1422 struct nge_softc *sc; 1423{ 1424 struct nge_desc *cur_tx = NULL; 1425 struct ifnet *ifp; 1426 u_int32_t idx; 1427 1428 ifp = &sc->arpcom.ac_if; 1429 1430 /* Clear the timeout timer. */ 1431 ifp->if_timer = 0; 1432 1433 /* 1434 * Go through our tx list and free mbufs for those 1435 * frames that have been transmitted. 1436 */ 1437 idx = sc->nge_cdata.nge_tx_cons; 1438 while (idx != sc->nge_cdata.nge_tx_prod) { 1439 cur_tx = &sc->nge_ldata->nge_tx_list[idx]; 1440 1441 if (NGE_OWNDESC(cur_tx)) 1442 break; 1443 1444 if (cur_tx->nge_ctl & NGE_CMDSTS_MORE) { 1445 sc->nge_cdata.nge_tx_cnt--; 1446 NGE_INC(idx, NGE_TX_LIST_CNT); 1447 continue; 1448 } 1449 1450 if (!(cur_tx->nge_ctl & NGE_CMDSTS_PKT_OK)) { 1451 ifp->if_oerrors++; 1452 if (cur_tx->nge_txstat & NGE_TXSTAT_EXCESSCOLLS) 1453 ifp->if_collisions++; 1454 if (cur_tx->nge_txstat & NGE_TXSTAT_OUTOFWINCOLL) 1455 ifp->if_collisions++; 1456 } 1457 1458 ifp->if_collisions += 1459 (cur_tx->nge_txstat & NGE_TXSTAT_COLLCNT) >> 16; 1460 1461 ifp->if_opackets++; 1462 if (cur_tx->nge_mbuf != NULL) { 1463 m_freem(cur_tx->nge_mbuf); 1464 cur_tx->nge_mbuf = NULL; 1465 } 1466 1467 sc->nge_cdata.nge_tx_cnt--; 1468 NGE_INC(idx, NGE_TX_LIST_CNT); 1469 ifp->if_timer = 0; 1470 } 1471 1472 sc->nge_cdata.nge_tx_cons = idx; 1473 1474 if (cur_tx != NULL) 1475 ifp->if_flags &= ~IFF_OACTIVE; 1476 1477 return; 1478} 1479 1480static void 1481nge_tick(xsc) 1482 void *xsc; 1483{ 1484 struct nge_softc *sc; 1485 struct mii_data *mii; 1486 struct ifnet *ifp; 1487 int s; 1488 1489 s = splimp(); 1490 1491 sc = xsc; 1492 ifp = &sc->arpcom.ac_if; 1493 1494 if (sc->nge_tbi) { 1495 if (!sc->nge_link) { 1496 if (CSR_READ_4(sc, NGE_TBI_BMSR) 1497 & NGE_TBIBMSR_ANEG_DONE) { 1498 printf("nge%d: gigabit link up\n", 1499 sc->nge_unit); 1500 nge_miibus_statchg(sc->nge_miibus); 1501 sc->nge_link++; 1502 if (ifp->if_snd.ifq_head != NULL) 1503 nge_start(ifp); 1504 } 1505 } 1506 } else { 1507 mii = device_get_softc(sc->nge_miibus); 1508 mii_tick(mii); 1509 1510 if (!sc->nge_link) { 1511 if (mii->mii_media_status & IFM_ACTIVE && 1512 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 1513 sc->nge_link++; 1514 if (IFM_SUBTYPE(mii->mii_media_active) 1515 == IFM_1000_T) 1516 printf("nge%d: gigabit link up\n", 1517 sc->nge_unit); 1518 if (ifp->if_snd.ifq_head != NULL) 1519 nge_start(ifp); 1520 } 1521 } 1522 } 1523 sc->nge_stat_ch = timeout(nge_tick, sc, hz); 1524 1525 splx(s); 1526 1527 return; 1528} 1529 1530#ifdef DEVICE_POLLING 1531static poll_handler_t nge_poll; 1532 1533static void 1534nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 1535{ 1536 struct nge_softc *sc = ifp->if_softc; 1537 1538 if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */ 1539 CSR_WRITE_4(sc, NGE_IER, 1); 1540 return; 1541 } 1542 1543 /* 1544 * On the nge, reading the status register also clears it. 1545 * So before returning to intr mode we must make sure that all 1546 * possible pending sources of interrupts have been served. 1547 * In practice this means run to completion the *eof routines, 1548 * and then call the interrupt routine 1549 */ 1550 sc->rxcycles = count; 1551 nge_rxeof(sc); 1552 nge_txeof(sc); 1553 if (ifp->if_snd.ifq_head != NULL) 1554 nge_start(ifp); 1555 1556 if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) { 1557 u_int32_t status; 1558 1559 /* Reading the ISR register clears all interrupts. */ 1560 status = CSR_READ_4(sc, NGE_ISR); 1561 1562 if (status & (NGE_ISR_RX_ERR|NGE_ISR_RX_OFLOW)) 1563 nge_rxeof(sc); 1564 1565 if (status & (NGE_ISR_RX_IDLE)) 1566 NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE); 1567 1568 if (status & NGE_ISR_SYSERR) { 1569 nge_reset(sc); 1570 nge_init(sc); 1571 } 1572 } 1573} 1574#endif /* DEVICE_POLLING */ 1575 1576static void 1577nge_intr(arg) 1578 void *arg; 1579{ 1580 struct nge_softc *sc; 1581 struct ifnet *ifp; 1582 u_int32_t status; 1583 1584 sc = arg; 1585 ifp = &sc->arpcom.ac_if; 1586 1587#ifdef DEVICE_POLLING 1588 if (ifp->if_ipending & IFF_POLLING) 1589 return; 1590 if (ether_poll_register(nge_poll, ifp)) { /* ok, disable interrupts */ 1591 CSR_WRITE_4(sc, NGE_IER, 0); 1592 nge_poll(ifp, 0, 1); 1593 return; 1594 } 1595#endif /* DEVICE_POLLING */ 1596 1597 /* Supress unwanted interrupts */ 1598 if (!(ifp->if_flags & IFF_UP)) { 1599 nge_stop(sc); 1600 return; 1601 } 1602 1603 /* Disable interrupts. */ 1604 CSR_WRITE_4(sc, NGE_IER, 0); 1605 1606 /* Data LED on for TBI mode */ 1607 if(sc->nge_tbi) 1608 CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) 1609 | NGE_GPIO_GP3_OUT); 1610 1611 for (;;) { 1612 /* Reading the ISR register clears all interrupts. */ 1613 status = CSR_READ_4(sc, NGE_ISR); 1614 1615 if ((status & NGE_INTRS) == 0) 1616 break; 1617 1618 if ((status & NGE_ISR_TX_DESC_OK) || 1619 (status & NGE_ISR_TX_ERR) || 1620 (status & NGE_ISR_TX_OK) || 1621 (status & NGE_ISR_TX_IDLE)) 1622 nge_txeof(sc); 1623 1624 if ((status & NGE_ISR_RX_DESC_OK) || 1625 (status & NGE_ISR_RX_ERR) || 1626 (status & NGE_ISR_RX_OFLOW) || 1627 (status & NGE_ISR_RX_FIFO_OFLOW) || 1628 (status & NGE_ISR_RX_IDLE) || 1629 (status & NGE_ISR_RX_OK)) 1630 nge_rxeof(sc); 1631 1632 if ((status & NGE_ISR_RX_IDLE)) 1633 NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE); 1634 1635 if (status & NGE_ISR_SYSERR) { 1636 nge_reset(sc); 1637 ifp->if_flags &= ~IFF_RUNNING; 1638 nge_init(sc); 1639 } 1640 1641#if 0 1642 /* 1643 * XXX: nge_tick() is not ready to be called this way 1644 * it screws up the aneg timeout because mii_tick() is 1645 * only to be called once per second. 1646 */ 1647 if (status & NGE_IMR_PHY_INTR) { 1648 sc->nge_link = 0; 1649 nge_tick(sc); 1650 } 1651#endif 1652 } 1653 1654 /* Re-enable interrupts. */ 1655 CSR_WRITE_4(sc, NGE_IER, 1); 1656 1657 if (ifp->if_snd.ifq_head != NULL) 1658 nge_start(ifp); 1659 1660 /* Data LED off for TBI mode */ 1661 1662 if(sc->nge_tbi) 1663 CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) 1664 & ~NGE_GPIO_GP3_OUT); 1665 1666 return; 1667} 1668 1669/* 1670 * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 1671 * pointers to the fragment pointers. 1672 */ 1673static int 1674nge_encap(sc, m_head, txidx) 1675 struct nge_softc *sc; 1676 struct mbuf *m_head; 1677 u_int32_t *txidx; 1678{ 1679 struct nge_desc *f = NULL; 1680 struct mbuf *m; 1681 int frag, cur, cnt = 0; 1682 struct m_tag *mtag; 1683 1684 /* 1685 * Start packing the mbufs in this chain into 1686 * the fragment pointers. Stop when we run out 1687 * of fragments or hit the end of the mbuf chain. 1688 */ 1689 m = m_head; 1690 cur = frag = *txidx; 1691 1692 for (m = m_head; m != NULL; m = m->m_next) { 1693 if (m->m_len != 0) { 1694 if ((NGE_TX_LIST_CNT - 1695 (sc->nge_cdata.nge_tx_cnt + cnt)) < 2) 1696 return(ENOBUFS); 1697 f = &sc->nge_ldata->nge_tx_list[frag]; 1698 f->nge_ctl = NGE_CMDSTS_MORE | m->m_len; 1699 f->nge_ptr = vtophys(mtod(m, vm_offset_t)); 1700 if (cnt != 0) 1701 f->nge_ctl |= NGE_CMDSTS_OWN; 1702 cur = frag; 1703 NGE_INC(frag, NGE_TX_LIST_CNT); 1704 cnt++; 1705 } 1706 } 1707 1708 if (m != NULL) 1709 return(ENOBUFS); 1710 1711 sc->nge_ldata->nge_tx_list[*txidx].nge_extsts = 0; 1712 if (m_head->m_pkthdr.csum_flags) { 1713 if (m_head->m_pkthdr.csum_flags & CSUM_IP) 1714 sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |= 1715 NGE_TXEXTSTS_IPCSUM; 1716 if (m_head->m_pkthdr.csum_flags & CSUM_TCP) 1717 sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |= 1718 NGE_TXEXTSTS_TCPCSUM; 1719 if (m_head->m_pkthdr.csum_flags & CSUM_UDP) 1720 sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |= 1721 NGE_TXEXTSTS_UDPCSUM; 1722 } 1723 1724 mtag = VLAN_OUTPUT_TAG(&sc->arpcom.ac_if, m); 1725 if (mtag != NULL) { 1726 sc->nge_ldata->nge_tx_list[cur].nge_extsts |= 1727 (NGE_TXEXTSTS_VLANPKT|VLAN_TAG_VALUE(mtag)); 1728 } 1729 1730 sc->nge_ldata->nge_tx_list[cur].nge_mbuf = m_head; 1731 sc->nge_ldata->nge_tx_list[cur].nge_ctl &= ~NGE_CMDSTS_MORE; 1732 sc->nge_ldata->nge_tx_list[*txidx].nge_ctl |= NGE_CMDSTS_OWN; 1733 sc->nge_cdata.nge_tx_cnt += cnt; 1734 *txidx = frag; 1735 1736 return(0); 1737} 1738 1739/* 1740 * Main transmit routine. To avoid having to do mbuf copies, we put pointers 1741 * to the mbuf data regions directly in the transmit lists. We also save a 1742 * copy of the pointers since the transmit list fragment pointers are 1743 * physical addresses. 1744 */ 1745 1746static void 1747nge_start(ifp) 1748 struct ifnet *ifp; 1749{ 1750 struct nge_softc *sc; 1751 struct mbuf *m_head = NULL; 1752 u_int32_t idx; 1753 1754 sc = ifp->if_softc; 1755 1756 if (!sc->nge_link) 1757 return; 1758 1759 idx = sc->nge_cdata.nge_tx_prod; 1760 1761 if (ifp->if_flags & IFF_OACTIVE) 1762 return; 1763 1764 while(sc->nge_ldata->nge_tx_list[idx].nge_mbuf == NULL) { 1765 IF_DEQUEUE(&ifp->if_snd, m_head); 1766 if (m_head == NULL) 1767 break; 1768 1769 if (nge_encap(sc, m_head, &idx)) { 1770 IF_PREPEND(&ifp->if_snd, m_head); 1771 ifp->if_flags |= IFF_OACTIVE; 1772 break; 1773 } 1774 1775 /* 1776 * If there's a BPF listener, bounce a copy of this frame 1777 * to him. 1778 */ 1779 BPF_MTAP(ifp, m_head); 1780 1781 } 1782 1783 /* Transmit */ 1784 sc->nge_cdata.nge_tx_prod = idx; 1785 NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_ENABLE); 1786 1787 /* 1788 * Set a timeout in case the chip goes out to lunch. 1789 */ 1790 ifp->if_timer = 5; 1791 1792 return; 1793} 1794 1795static void 1796nge_init(xsc) 1797 void *xsc; 1798{ 1799 struct nge_softc *sc = xsc; 1800 struct ifnet *ifp = &sc->arpcom.ac_if; 1801 struct mii_data *mii; 1802 int s; 1803 1804 if (ifp->if_flags & IFF_RUNNING) 1805 return; 1806 1807 s = splimp(); 1808 1809 /* 1810 * Cancel pending I/O and free all RX/TX buffers. 1811 */ 1812 nge_stop(sc); 1813 1814 if (sc->nge_tbi) { 1815 mii = NULL; 1816 } else { 1817 mii = device_get_softc(sc->nge_miibus); 1818 } 1819 1820 /* Set MAC address */ 1821 CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR0); 1822 CSR_WRITE_4(sc, NGE_RXFILT_DATA, 1823 ((u_int16_t *)sc->arpcom.ac_enaddr)[0]); 1824 CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR1); 1825 CSR_WRITE_4(sc, NGE_RXFILT_DATA, 1826 ((u_int16_t *)sc->arpcom.ac_enaddr)[1]); 1827 CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR2); 1828 CSR_WRITE_4(sc, NGE_RXFILT_DATA, 1829 ((u_int16_t *)sc->arpcom.ac_enaddr)[2]); 1830 1831 /* Init circular RX list. */ 1832 if (nge_list_rx_init(sc) == ENOBUFS) { 1833 printf("nge%d: initialization failed: no " 1834 "memory for rx buffers\n", sc->nge_unit); 1835 nge_stop(sc); 1836 (void)splx(s); 1837 return; 1838 } 1839 1840 /* 1841 * Init tx descriptors. 1842 */ 1843 nge_list_tx_init(sc); 1844 1845 /* 1846 * For the NatSemi chip, we have to explicitly enable the 1847 * reception of ARP frames, as well as turn on the 'perfect 1848 * match' filter where we store the station address, otherwise 1849 * we won't receive unicasts meant for this host. 1850 */ 1851 NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ARP); 1852 NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_PERFECT); 1853 1854 /* If we want promiscuous mode, set the allframes bit. */ 1855 if (ifp->if_flags & IFF_PROMISC) { 1856 NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLPHYS); 1857 } else { 1858 NGE_CLRBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLPHYS); 1859 } 1860 1861 /* 1862 * Set the capture broadcast bit to capture broadcast frames. 1863 */ 1864 if (ifp->if_flags & IFF_BROADCAST) { 1865 NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_BROAD); 1866 } else { 1867 NGE_CLRBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_BROAD); 1868 } 1869 1870 /* 1871 * Load the multicast filter. 1872 */ 1873 nge_setmulti(sc); 1874 1875 /* Turn the receive filter on */ 1876 NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ENABLE); 1877 1878 /* 1879 * Load the address of the RX and TX lists. 1880 */ 1881 CSR_WRITE_4(sc, NGE_RX_LISTPTR, 1882 vtophys(&sc->nge_ldata->nge_rx_list[0])); 1883 CSR_WRITE_4(sc, NGE_TX_LISTPTR, 1884 vtophys(&sc->nge_ldata->nge_tx_list[0])); 1885 1886 /* Set RX configuration */ 1887 CSR_WRITE_4(sc, NGE_RX_CFG, NGE_RXCFG); 1888 /* 1889 * Enable hardware checksum validation for all IPv4 1890 * packets, do not reject packets with bad checksums. 1891 */ 1892 CSR_WRITE_4(sc, NGE_VLAN_IP_RXCTL, NGE_VIPRXCTL_IPCSUM_ENB); 1893 1894 /* 1895 * Tell the chip to detect and strip VLAN tag info from 1896 * received frames. The tag will be provided in the extsts 1897 * field in the RX descriptors. 1898 */ 1899 NGE_SETBIT(sc, NGE_VLAN_IP_RXCTL, 1900 NGE_VIPRXCTL_TAG_DETECT_ENB|NGE_VIPRXCTL_TAG_STRIP_ENB); 1901 1902 /* Set TX configuration */ 1903 CSR_WRITE_4(sc, NGE_TX_CFG, NGE_TXCFG); 1904 1905 /* 1906 * Enable TX IPv4 checksumming on a per-packet basis. 1907 */ 1908 CSR_WRITE_4(sc, NGE_VLAN_IP_TXCTL, NGE_VIPTXCTL_CSUM_PER_PKT); 1909 1910 /* 1911 * Tell the chip to insert VLAN tags on a per-packet basis as 1912 * dictated by the code in the frame encapsulation routine. 1913 */ 1914 NGE_SETBIT(sc, NGE_VLAN_IP_TXCTL, NGE_VIPTXCTL_TAG_PER_PKT); 1915 1916 /* Set full/half duplex mode. */ 1917 if (sc->nge_tbi) { 1918 if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) 1919 == IFM_FDX) { 1920 NGE_SETBIT(sc, NGE_TX_CFG, 1921 (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 1922 NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 1923 } else { 1924 NGE_CLRBIT(sc, NGE_TX_CFG, 1925 (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 1926 NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 1927 } 1928 } else { 1929 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { 1930 NGE_SETBIT(sc, NGE_TX_CFG, 1931 (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 1932 NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 1933 } else { 1934 NGE_CLRBIT(sc, NGE_TX_CFG, 1935 (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 1936 NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 1937 } 1938 } 1939 1940 nge_tick(sc); 1941 1942 /* 1943 * Enable the delivery of PHY interrupts based on 1944 * link/speed/duplex status changes. Also enable the 1945 * extsts field in the DMA descriptors (needed for 1946 * TCP/IP checksum offload on transmit). 1947 */ 1948 NGE_SETBIT(sc, NGE_CFG, NGE_CFG_PHYINTR_SPD| 1949 NGE_CFG_PHYINTR_LNK|NGE_CFG_PHYINTR_DUP|NGE_CFG_EXTSTS_ENB); 1950 1951 /* 1952 * Configure interrupt holdoff (moderation). We can 1953 * have the chip delay interrupt delivery for a certain 1954 * period. Units are in 100us, and the max setting 1955 * is 25500us (0xFF x 100us). Default is a 100us holdoff. 1956 */ 1957 CSR_WRITE_4(sc, NGE_IHR, 0x01); 1958 1959 /* 1960 * Enable interrupts. 1961 */ 1962 CSR_WRITE_4(sc, NGE_IMR, NGE_INTRS); 1963#ifdef DEVICE_POLLING 1964 /* 1965 * ... only enable interrupts if we are not polling, make sure 1966 * they are off otherwise. 1967 */ 1968 if (ifp->if_ipending & IFF_POLLING) 1969 CSR_WRITE_4(sc, NGE_IER, 0); 1970 else 1971#endif /* DEVICE_POLLING */ 1972 CSR_WRITE_4(sc, NGE_IER, 1); 1973 1974 /* Enable receiver and transmitter. */ 1975 NGE_CLRBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE); 1976 NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE); 1977 1978 nge_ifmedia_upd(ifp); 1979 1980 ifp->if_flags |= IFF_RUNNING; 1981 ifp->if_flags &= ~IFF_OACTIVE; 1982 1983 (void)splx(s); 1984 1985 return; 1986} 1987 1988/* 1989 * Set media options. 1990 */ 1991static int 1992nge_ifmedia_upd(ifp) 1993 struct ifnet *ifp; 1994{ 1995 struct nge_softc *sc; 1996 struct mii_data *mii; 1997 1998 sc = ifp->if_softc; 1999 2000 if (sc->nge_tbi) { 2001 if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) 2002 == IFM_AUTO) { 2003 CSR_WRITE_4(sc, NGE_TBI_ANAR, 2004 CSR_READ_4(sc, NGE_TBI_ANAR) 2005 | NGE_TBIANAR_HDX | NGE_TBIANAR_FDX 2006 | NGE_TBIANAR_PS1 | NGE_TBIANAR_PS2); 2007 CSR_WRITE_4(sc, NGE_TBI_BMCR, NGE_TBIBMCR_ENABLE_ANEG 2008 | NGE_TBIBMCR_RESTART_ANEG); 2009 CSR_WRITE_4(sc, NGE_TBI_BMCR, NGE_TBIBMCR_ENABLE_ANEG); 2010 } else if ((sc->nge_ifmedia.ifm_cur->ifm_media 2011 & IFM_GMASK) == IFM_FDX) { 2012 NGE_SETBIT(sc, NGE_TX_CFG, 2013 (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 2014 NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 2015 2016 CSR_WRITE_4(sc, NGE_TBI_ANAR, 0); 2017 CSR_WRITE_4(sc, NGE_TBI_BMCR, 0); 2018 } else { 2019 NGE_CLRBIT(sc, NGE_TX_CFG, 2020 (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); 2021 NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); 2022 2023 CSR_WRITE_4(sc, NGE_TBI_ANAR, 0); 2024 CSR_WRITE_4(sc, NGE_TBI_BMCR, 0); 2025 } 2026 2027 CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) 2028 & ~NGE_GPIO_GP3_OUT); 2029 } else { 2030 mii = device_get_softc(sc->nge_miibus); 2031 sc->nge_link = 0; 2032 if (mii->mii_instance) { 2033 struct mii_softc *miisc; 2034 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL; 2035 miisc = LIST_NEXT(miisc, mii_list)) 2036 mii_phy_reset(miisc); 2037 } 2038 mii_mediachg(mii); 2039 } 2040 2041 return(0); 2042} 2043 2044/* 2045 * Report current media status. 2046 */ 2047static void 2048nge_ifmedia_sts(ifp, ifmr) 2049 struct ifnet *ifp; 2050 struct ifmediareq *ifmr; 2051{ 2052 struct nge_softc *sc; 2053 struct mii_data *mii; 2054 2055 sc = ifp->if_softc; 2056 2057 if (sc->nge_tbi) { 2058 ifmr->ifm_status = IFM_AVALID; 2059 ifmr->ifm_active = IFM_ETHER; 2060 2061 if (CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) { 2062 ifmr->ifm_status |= IFM_ACTIVE; 2063 } 2064 if (CSR_READ_4(sc, NGE_TBI_BMCR) & NGE_TBIBMCR_LOOPBACK) 2065 ifmr->ifm_active |= IFM_LOOP; 2066 if (!CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) { 2067 ifmr->ifm_active |= IFM_NONE; 2068 ifmr->ifm_status = 0; 2069 return; 2070 } 2071 ifmr->ifm_active |= IFM_1000_SX; 2072 if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) 2073 == IFM_AUTO) { 2074 ifmr->ifm_active |= IFM_AUTO; 2075 if (CSR_READ_4(sc, NGE_TBI_ANLPAR) 2076 & NGE_TBIANAR_FDX) { 2077 ifmr->ifm_active |= IFM_FDX; 2078 }else if (CSR_READ_4(sc, NGE_TBI_ANLPAR) 2079 & NGE_TBIANAR_HDX) { 2080 ifmr->ifm_active |= IFM_HDX; 2081 } 2082 } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) 2083 == IFM_FDX) 2084 ifmr->ifm_active |= IFM_FDX; 2085 else 2086 ifmr->ifm_active |= IFM_HDX; 2087 2088 } else { 2089 mii = device_get_softc(sc->nge_miibus); 2090 mii_pollstat(mii); 2091 ifmr->ifm_active = mii->mii_media_active; 2092 ifmr->ifm_status = mii->mii_media_status; 2093 } 2094 2095 return; 2096} 2097 2098static int 2099nge_ioctl(ifp, command, data) 2100 struct ifnet *ifp; 2101 u_long command; 2102 caddr_t data; 2103{ 2104 struct nge_softc *sc = ifp->if_softc; 2105 struct ifreq *ifr = (struct ifreq *) data; 2106 struct mii_data *mii; 2107 int s, error = 0; 2108 2109 s = splimp(); 2110 2111 switch(command) { 2112 case SIOCSIFMTU: 2113 if (ifr->ifr_mtu > NGE_JUMBO_MTU) 2114 error = EINVAL; 2115 else { 2116 ifp->if_mtu = ifr->ifr_mtu; 2117 /* 2118 * Workaround: if the MTU is larger than 2119 * 8152 (TX FIFO size minus 64 minus 18), turn off 2120 * TX checksum offloading. 2121 */ 2122 if (ifr->ifr_mtu >= 8152) 2123 ifp->if_hwassist = 0; 2124 else 2125 ifp->if_hwassist = NGE_CSUM_FEATURES; 2126 } 2127 break; 2128 case SIOCSIFFLAGS: 2129 if (ifp->if_flags & IFF_UP) { 2130 if (ifp->if_flags & IFF_RUNNING && 2131 ifp->if_flags & IFF_PROMISC && 2132 !(sc->nge_if_flags & IFF_PROMISC)) { 2133 NGE_SETBIT(sc, NGE_RXFILT_CTL, 2134 NGE_RXFILTCTL_ALLPHYS| 2135 NGE_RXFILTCTL_ALLMULTI); 2136 } else if (ifp->if_flags & IFF_RUNNING && 2137 !(ifp->if_flags & IFF_PROMISC) && 2138 sc->nge_if_flags & IFF_PROMISC) { 2139 NGE_CLRBIT(sc, NGE_RXFILT_CTL, 2140 NGE_RXFILTCTL_ALLPHYS); 2141 if (!(ifp->if_flags & IFF_ALLMULTI)) 2142 NGE_CLRBIT(sc, NGE_RXFILT_CTL, 2143 NGE_RXFILTCTL_ALLMULTI); 2144 } else { 2145 ifp->if_flags &= ~IFF_RUNNING; 2146 nge_init(sc); 2147 } 2148 } else { 2149 if (ifp->if_flags & IFF_RUNNING) 2150 nge_stop(sc); 2151 } 2152 sc->nge_if_flags = ifp->if_flags; 2153 error = 0; 2154 break; 2155 case SIOCADDMULTI: 2156 case SIOCDELMULTI: 2157 nge_setmulti(sc); 2158 error = 0; 2159 break; 2160 case SIOCGIFMEDIA: 2161 case SIOCSIFMEDIA: 2162 if (sc->nge_tbi) { 2163 error = ifmedia_ioctl(ifp, ifr, &sc->nge_ifmedia, 2164 command); 2165 } else { 2166 mii = device_get_softc(sc->nge_miibus); 2167 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, 2168 command); 2169 } 2170 break; 2171 default: 2172 error = ether_ioctl(ifp, command, data); 2173 break; 2174 } 2175 2176 (void)splx(s); 2177 2178 return(error); 2179} 2180 2181static void 2182nge_watchdog(ifp) 2183 struct ifnet *ifp; 2184{ 2185 struct nge_softc *sc; 2186 2187 sc = ifp->if_softc; 2188 2189 ifp->if_oerrors++; 2190 printf("nge%d: watchdog timeout\n", sc->nge_unit); 2191 2192 nge_stop(sc); 2193 nge_reset(sc); 2194 ifp->if_flags &= ~IFF_RUNNING; 2195 nge_init(sc); 2196 2197 if (ifp->if_snd.ifq_head != NULL) 2198 nge_start(ifp); 2199 2200 return; 2201} 2202 2203/* 2204 * Stop the adapter and free any mbufs allocated to the 2205 * RX and TX lists. 2206 */ 2207static void 2208nge_stop(sc) 2209 struct nge_softc *sc; 2210{ 2211 register int i; 2212 struct ifnet *ifp; 2213 struct mii_data *mii; 2214 2215 ifp = &sc->arpcom.ac_if; 2216 ifp->if_timer = 0; 2217 if (sc->nge_tbi) { 2218 mii = NULL; 2219 } else { 2220 mii = device_get_softc(sc->nge_miibus); 2221 } 2222 2223 untimeout(nge_tick, sc, sc->nge_stat_ch); 2224#ifdef DEVICE_POLLING 2225 ether_poll_deregister(ifp); 2226#endif 2227 CSR_WRITE_4(sc, NGE_IER, 0); 2228 CSR_WRITE_4(sc, NGE_IMR, 0); 2229 NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE); 2230 DELAY(1000); 2231 CSR_WRITE_4(sc, NGE_TX_LISTPTR, 0); 2232 CSR_WRITE_4(sc, NGE_RX_LISTPTR, 0); 2233 2234 if (!sc->nge_tbi) 2235 mii_down(mii); 2236 2237 sc->nge_link = 0; 2238 2239 /* 2240 * Free data in the RX lists. 2241 */ 2242 for (i = 0; i < NGE_RX_LIST_CNT; i++) { 2243 if (sc->nge_ldata->nge_rx_list[i].nge_mbuf != NULL) { 2244 m_freem(sc->nge_ldata->nge_rx_list[i].nge_mbuf); 2245 sc->nge_ldata->nge_rx_list[i].nge_mbuf = NULL; 2246 } 2247 } 2248 bzero((char *)&sc->nge_ldata->nge_rx_list, 2249 sizeof(sc->nge_ldata->nge_rx_list)); 2250 2251 /* 2252 * Free the TX list buffers. 2253 */ 2254 for (i = 0; i < NGE_TX_LIST_CNT; i++) { 2255 if (sc->nge_ldata->nge_tx_list[i].nge_mbuf != NULL) { 2256 m_freem(sc->nge_ldata->nge_tx_list[i].nge_mbuf); 2257 sc->nge_ldata->nge_tx_list[i].nge_mbuf = NULL; 2258 } 2259 } 2260 2261 bzero((char *)&sc->nge_ldata->nge_tx_list, 2262 sizeof(sc->nge_ldata->nge_tx_list)); 2263 2264 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2265 2266 return; 2267} 2268 2269/* 2270 * Stop all chip I/O so that the kernel's probe routines don't 2271 * get confused by errant DMAs when rebooting. 2272 */ 2273static void 2274nge_shutdown(dev) 2275 device_t dev; 2276{ 2277 struct nge_softc *sc; 2278 2279 sc = device_get_softc(dev); 2280 2281 nge_reset(sc); 2282 nge_stop(sc); 2283 2284 return; 2285} 2286