if_rl.c revision 131841
140516Swpaul/* 2119868Swpaul * Copyright (c) 1997, 1998 340516Swpaul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 440516Swpaul * 540516Swpaul * Redistribution and use in source and binary forms, with or without 640516Swpaul * modification, are permitted provided that the following conditions 740516Swpaul * are met: 840516Swpaul * 1. Redistributions of source code must retain the above copyright 940516Swpaul * notice, this list of conditions and the following disclaimer. 1040516Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1140516Swpaul * notice, this list of conditions and the following disclaimer in the 1240516Swpaul * documentation and/or other materials provided with the distribution. 1340516Swpaul * 3. All advertising materials mentioning features or use of this software 1440516Swpaul * must display the following acknowledgement: 1540516Swpaul * This product includes software developed by Bill Paul. 1640516Swpaul * 4. Neither the name of the author nor the names of any co-contributors 1740516Swpaul * may be used to endorse or promote products derived from this software 1840516Swpaul * without specific prior written permission. 1940516Swpaul * 2040516Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 2140516Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2240516Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2340516Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 2440516Swpaul * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2540516Swpaul * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2640516Swpaul * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2740516Swpaul * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2840516Swpaul * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2940516Swpaul * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3040516Swpaul * THE POSSIBILITY OF SUCH DAMAGE. 3140516Swpaul */ 3240516Swpaul 33122678Sobrien#include <sys/cdefs.h> 34122678Sobrien__FBSDID("$FreeBSD: head/sys/pci/if_rl.c 131841 2004-07-09 00:07:06Z bms $"); 35122678Sobrien 3640516Swpaul/* 37119868Swpaul * RealTek 8129/8139 PCI NIC driver 3840516Swpaul * 39119868Swpaul * Supports several extremely cheap PCI 10/100 adapters based on 40119868Swpaul * the RealTek chipset. Datasheets can be obtained from 4140516Swpaul * www.realtek.com.tw. 4240516Swpaul * 43119868Swpaul * Written by Bill Paul <wpaul@ctr.columbia.edu> 44119868Swpaul * Electrical Engineering Department 45119868Swpaul * Columbia University, New York City 4640516Swpaul */ 4740516Swpaul/* 4840516Swpaul * The RealTek 8139 PCI NIC redefines the meaning of 'low end.' This is 4940516Swpaul * probably the worst PCI ethernet controller ever made, with the possible 5040516Swpaul * exception of the FEAST chip made by SMC. The 8139 supports bus-master 5140516Swpaul * DMA, but it has a terrible interface that nullifies any performance 5240516Swpaul * gains that bus-master DMA usually offers. 5340516Swpaul * 5440516Swpaul * For transmission, the chip offers a series of four TX descriptor 5540516Swpaul * registers. Each transmit frame must be in a contiguous buffer, aligned 5641569Swpaul * on a longword (32-bit) boundary. This means we almost always have to 5740516Swpaul * do mbuf copies in order to transmit a frame, except in the unlikely 5840516Swpaul * case where a) the packet fits into a single mbuf, and b) the packet 5940516Swpaul * is 32-bit aligned within the mbuf's data area. The presence of only 6040516Swpaul * four descriptor registers means that we can never have more than four 6140516Swpaul * packets queued for transmission at any one time. 6240516Swpaul * 6340516Swpaul * Reception is not much better. The driver has to allocate a single large 6440516Swpaul * buffer area (up to 64K in size) into which the chip will DMA received 6540516Swpaul * frames. Because we don't know where within this region received packets 6640516Swpaul * will begin or end, we have no choice but to copy data from the buffer 6740516Swpaul * area into mbufs in order to pass the packets up to the higher protocol 6840516Swpaul * levels. 6940516Swpaul * 7040516Swpaul * It's impossible given this rotten design to really achieve decent 7140516Swpaul * performance at 100Mbps, unless you happen to have a 400Mhz PII or 7240516Swpaul * some equally overmuscled CPU to drive it. 7340516Swpaul * 7440516Swpaul * On the bright side, the 8139 does have a built-in PHY, although 7540516Swpaul * rather than using an MDIO serial interface like most other NICs, the 7640516Swpaul * PHY registers are directly accessible through the 8139's register 7740516Swpaul * space. The 8139 supports autonegotiation, as well as a 64-bit multicast 7840516Swpaul * filter. 7940516Swpaul * 8040516Swpaul * The 8129 chip is an older version of the 8139 that uses an external PHY 8140516Swpaul * chip. The 8129 has a serial MDIO interface for accessing the MII where 8240516Swpaul * the 8139 lets you directly access the on-board PHY registers. We need 8340516Swpaul * to select which interface to use depending on the chip type. 8440516Swpaul */ 8540516Swpaul 8640516Swpaul#include <sys/param.h> 87108729Sjake#include <sys/endian.h> 8840516Swpaul#include <sys/systm.h> 8940516Swpaul#include <sys/sockio.h> 9040516Swpaul#include <sys/mbuf.h> 9140516Swpaul#include <sys/malloc.h> 9240516Swpaul#include <sys/kernel.h> 93129878Sphk#include <sys/module.h> 9440516Swpaul#include <sys/socket.h> 9540516Swpaul 9640516Swpaul#include <net/if.h> 9740516Swpaul#include <net/if_arp.h> 9840516Swpaul#include <net/ethernet.h> 9940516Swpaul#include <net/if_dl.h> 10040516Swpaul#include <net/if_media.h> 10140516Swpaul 10240516Swpaul#include <net/bpf.h> 10340516Swpaul 10441569Swpaul#include <machine/bus_pio.h> 10541569Swpaul#include <machine/bus_memio.h> 10641569Swpaul#include <machine/bus.h> 10750703Swpaul#include <machine/resource.h> 10850703Swpaul#include <sys/bus.h> 10950703Swpaul#include <sys/rman.h> 11040516Swpaul 11150703Swpaul#include <dev/mii/mii.h> 11250703Swpaul#include <dev/mii/miivar.h> 11350703Swpaul 114119871Swpaul#include <dev/pci/pcireg.h> 115119871Swpaul#include <dev/pci/pcivar.h> 11640516Swpaul 117113506SmdoddMODULE_DEPEND(rl, pci, 1, 1, 1); 118113506SmdoddMODULE_DEPEND(rl, ether, 1, 1, 1); 11959758SpeterMODULE_DEPEND(rl, miibus, 1, 1, 1); 12059758Speter 12151089Speter/* "controller miibus0" required. See GENERIC if you get errors here. */ 12250703Swpaul#include "miibus_if.h" 12350703Swpaul 12440516Swpaul/* 12540516Swpaul * Default to using PIO access for this driver. On SMP systems, 12640516Swpaul * there appear to be problems with memory mapped mode: it looks like 12740516Swpaul * doing too many memory mapped access back to back in rapid succession 12840516Swpaul * can hang the bus. I'm inclined to blame this on crummy design/construction 12940516Swpaul * on the part of RealTek. Memory mapped mode does appear to work on 13040516Swpaul * uniprocessor systems though. 13140516Swpaul */ 13240516Swpaul#define RL_USEIOSPACE 13340516Swpaul 13440516Swpaul#include <pci/if_rlreg.h> 13540516Swpaul 13640516Swpaul/* 13740516Swpaul * Various supported device vendors/types and their names. 13840516Swpaul */ 13940516Swpaulstatic struct rl_type rl_devs[] = { 140117388Swpaul { RT_VENDORID, RT_DEVICEID_8129, RL_8129, 14140516Swpaul "RealTek 8129 10/100BaseTX" }, 142117388Swpaul { RT_VENDORID, RT_DEVICEID_8139, RL_8139, 14340516Swpaul "RealTek 8139 10/100BaseTX" }, 144117388Swpaul { RT_VENDORID, RT_DEVICEID_8138, RL_8139, 14567771Swpaul "RealTek 8139 10/100BaseTX CardBus" }, 146118978Swpaul { RT_VENDORID, RT_DEVICEID_8100, RL_8139, 147118978Swpaul "RealTek 8100 10/100BaseTX" }, 148117388Swpaul { ACCTON_VENDORID, ACCTON_DEVICEID_5030, RL_8139, 14941243Swpaul "Accton MPX 5030/5038 10/100BaseTX" }, 150117388Swpaul { DELTA_VENDORID, DELTA_DEVICEID_8139, RL_8139, 15144238Swpaul "Delta Electronics 8139 10/100BaseTX" }, 152117388Swpaul { ADDTRON_VENDORID, ADDTRON_DEVICEID_8139, RL_8139, 15344238Swpaul "Addtron Technolgy 8139 10/100BaseTX" }, 154117388Swpaul { DLINK_VENDORID, DLINK_DEVICEID_530TXPLUS, RL_8139, 15572813Swpaul "D-Link DFE-530TX+ 10/100BaseTX" }, 156117388Swpaul { DLINK_VENDORID, DLINK_DEVICEID_690TXD, RL_8139, 15796112Sjhb "D-Link DFE-690TXD 10/100BaseTX" }, 158117388Swpaul { NORTEL_VENDORID, ACCTON_DEVICEID_5030, RL_8139, 15994400Swpaul "Nortel Networks 10/100BaseTX" }, 160117388Swpaul { COREGA_VENDORID, COREGA_DEVICEID_FETHERCBTXD, RL_8139, 161103020Siwasaki "Corega FEther CB-TXD" }, 162117388Swpaul { COREGA_VENDORID, COREGA_DEVICEID_FETHERIICBTXD, RL_8139, 163109095Ssanpei "Corega FEtherII CB-TXD" }, 164117388Swpaul { PEPPERCON_VENDORID, PEPPERCON_DEVICEID_ROLF, RL_8139, 165111381Sdan "Peppercon AG ROL-F" }, 166117388Swpaul { PLANEX_VENDORID, PLANEX_DEVICEID_FNW3800TX, RL_8139, 167112379Ssanpei "Planex FNW-3800-TX" }, 168117388Swpaul { CP_VENDORID, RT_DEVICEID_8139, RL_8139, 169117388Swpaul "Compaq HNE-300" }, 170117388Swpaul { LEVEL1_VENDORID, LEVEL1_DEVICEID_FPC0106TX, RL_8139, 171117388Swpaul "LevelOne FPC-0106TX" }, 172117388Swpaul { EDIMAX_VENDORID, EDIMAX_DEVICEID_EP4103DL, RL_8139, 173117388Swpaul "Edimax EP-4103DL CardBus" }, 174123740Speter { 0, 0, 0, NULL } 17540516Swpaul}; 17640516Swpaul 17792739Salfredstatic int rl_attach (device_t); 17892739Salfredstatic int rl_detach (device_t); 179131605Sbmsstatic void rl_dma_map_rxbuf (void *, bus_dma_segment_t *, int, int); 180131605Sbmsstatic void rl_dma_map_txbuf (void *, bus_dma_segment_t *, int, int); 181131605Sbmsstatic void rl_eeprom_putbyte (struct rl_softc *, int); 182131605Sbmsstatic void rl_eeprom_getword (struct rl_softc *, int, uint16_t *); 183119868Swpaulstatic int rl_encap (struct rl_softc *, struct mbuf * ); 184131605Sbmsstatic int rl_list_tx_init (struct rl_softc *); 185131605Sbmsstatic int rl_ifmedia_upd (struct ifnet *); 186131605Sbmsstatic void rl_ifmedia_sts (struct ifnet *, struct ifmediareq *); 187131605Sbmsstatic int rl_ioctl (struct ifnet *, u_long, caddr_t); 18892739Salfredstatic void rl_intr (void *); 18992739Salfredstatic void rl_init (void *); 190131841Sbmsstatic void rl_init_locked (struct rl_softc *sc); 191131605Sbmsstatic void rl_mii_send (struct rl_softc *, uint32_t, int); 19292739Salfredstatic void rl_mii_sync (struct rl_softc *); 19392739Salfredstatic int rl_mii_readreg (struct rl_softc *, struct rl_mii_frame *); 19492739Salfredstatic int rl_mii_writereg (struct rl_softc *, struct rl_mii_frame *); 19592739Salfredstatic int rl_miibus_readreg (device_t, int, int); 196131605Sbmsstatic void rl_miibus_statchg (device_t); 19792739Salfredstatic int rl_miibus_writereg (device_t, int, int, int); 198131841Sbms#ifdef DEVICE_POLLING 199131841Sbmsstatic void rl_poll (struct ifnet *ifp, enum poll_cmd cmd, 200131841Sbms int count); 201131841Sbmsstatic void rl_poll_locked (struct ifnet *ifp, enum poll_cmd cmd, 202131841Sbms int count); 203131841Sbms#endif 204131605Sbmsstatic int rl_probe (device_t); 205131605Sbmsstatic void rl_read_eeprom (struct rl_softc *, uint8_t *, int, int, int); 206131605Sbmsstatic void rl_reset (struct rl_softc *); 207131605Sbmsstatic int rl_resume (device_t); 208131605Sbmsstatic void rl_rxeof (struct rl_softc *); 20992739Salfredstatic void rl_setmulti (struct rl_softc *); 210131605Sbmsstatic void rl_shutdown (device_t); 211131605Sbmsstatic void rl_start (struct ifnet *); 212131841Sbmsstatic void rl_start_locked (struct ifnet *); 213131605Sbmsstatic void rl_stop (struct rl_softc *); 214131605Sbmsstatic int rl_suspend (device_t); 215131605Sbmsstatic void rl_tick (void *); 216131605Sbmsstatic void rl_txeof (struct rl_softc *); 217131605Sbmsstatic void rl_watchdog (struct ifnet *); 21840516Swpaul 21950703Swpaul#ifdef RL_USEIOSPACE 22050703Swpaul#define RL_RES SYS_RES_IOPORT 22150703Swpaul#define RL_RID RL_PCI_LOIO 22250703Swpaul#else 22350703Swpaul#define RL_RES SYS_RES_MEMORY 22450703Swpaul#define RL_RID RL_PCI_LOMEM 22550703Swpaul#endif 22650703Swpaul 22750703Swpaulstatic device_method_t rl_methods[] = { 22850703Swpaul /* Device interface */ 22950703Swpaul DEVMETHOD(device_probe, rl_probe), 23050703Swpaul DEVMETHOD(device_attach, rl_attach), 23150703Swpaul DEVMETHOD(device_detach, rl_detach), 23286822Siwasaki DEVMETHOD(device_suspend, rl_suspend), 23386822Siwasaki DEVMETHOD(device_resume, rl_resume), 23450703Swpaul DEVMETHOD(device_shutdown, rl_shutdown), 23550703Swpaul 23650703Swpaul /* bus interface */ 23750703Swpaul DEVMETHOD(bus_print_child, bus_generic_print_child), 23850703Swpaul DEVMETHOD(bus_driver_added, bus_generic_driver_added), 23950703Swpaul 24050703Swpaul /* MII interface */ 24150703Swpaul DEVMETHOD(miibus_readreg, rl_miibus_readreg), 24250703Swpaul DEVMETHOD(miibus_writereg, rl_miibus_writereg), 24350703Swpaul DEVMETHOD(miibus_statchg, rl_miibus_statchg), 24450703Swpaul 24550703Swpaul { 0, 0 } 24650703Swpaul}; 24750703Swpaul 24850703Swpaulstatic driver_t rl_driver = { 24951455Swpaul "rl", 25050703Swpaul rl_methods, 25150703Swpaul sizeof(struct rl_softc) 25250703Swpaul}; 25350703Swpaul 25450703Swpaulstatic devclass_t rl_devclass; 25550703Swpaul 256113506SmdoddDRIVER_MODULE(rl, pci, rl_driver, rl_devclass, 0, 0); 257123019SimpDRIVER_MODULE(rl, cardbus, rl_driver, rl_devclass, 0, 0); 25851473SwpaulDRIVER_MODULE(miibus, rl, miibus_driver, miibus_devclass, 0, 0); 25950703Swpaul 26040516Swpaul#define EE_SET(x) \ 26140516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26240516Swpaul CSR_READ_1(sc, RL_EECMD) | x) 26340516Swpaul 26440516Swpaul#define EE_CLR(x) \ 26540516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26640516Swpaul CSR_READ_1(sc, RL_EECMD) & ~x) 26740516Swpaul 26881713Swpaulstatic void 269131605Sbmsrl_dma_map_rxbuf(void *arg, bus_dma_segment_t *segs, int nseg, int error) 27081713Swpaul{ 271131605Sbms struct rl_softc *sc = arg; 27281713Swpaul 27381713Swpaul CSR_WRITE_4(sc, RL_RXADDR, segs->ds_addr & 0xFFFFFFFF); 27481713Swpaul} 27581713Swpaul 27681713Swpaulstatic void 277131605Sbmsrl_dma_map_txbuf(void *arg, bus_dma_segment_t *segs, int nseg, int error) 27881713Swpaul{ 279131605Sbms struct rl_softc *sc = arg; 28081713Swpaul 28181713Swpaul CSR_WRITE_4(sc, RL_CUR_TXADDR(sc), segs->ds_addr & 0xFFFFFFFF); 28281713Swpaul} 28381713Swpaul 28440516Swpaul/* 28540516Swpaul * Send a read command and address to the EEPROM, check for ACK. 28640516Swpaul */ 287102335Salfredstatic void 288131605Sbmsrl_eeprom_putbyte(struct rl_softc *sc, int addr) 28940516Swpaul{ 29040516Swpaul register int d, i; 29140516Swpaul 29267931Swpaul d = addr | sc->rl_eecmd_read; 29340516Swpaul 29440516Swpaul /* 29555170Sbillf * Feed in each bit and strobe the clock. 29640516Swpaul */ 29740516Swpaul for (i = 0x400; i; i >>= 1) { 29840516Swpaul if (d & i) { 29940516Swpaul EE_SET(RL_EE_DATAIN); 30040516Swpaul } else { 30140516Swpaul EE_CLR(RL_EE_DATAIN); 30240516Swpaul } 30340516Swpaul DELAY(100); 30440516Swpaul EE_SET(RL_EE_CLK); 30540516Swpaul DELAY(150); 30640516Swpaul EE_CLR(RL_EE_CLK); 30740516Swpaul DELAY(100); 30840516Swpaul } 30940516Swpaul} 31040516Swpaul 31140516Swpaul/* 31240516Swpaul * Read a word of data stored in the EEPROM at address 'addr.' 31340516Swpaul */ 314102335Salfredstatic void 315131605Sbmsrl_eeprom_getword(struct rl_softc *sc, int addr, uint16_t *dest) 31640516Swpaul{ 31740516Swpaul register int i; 318131605Sbms uint16_t word = 0; 31940516Swpaul 32040516Swpaul /* Enter EEPROM access mode. */ 32140516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 32240516Swpaul 32340516Swpaul /* 32440516Swpaul * Send address of word we want to read. 32540516Swpaul */ 32640516Swpaul rl_eeprom_putbyte(sc, addr); 32740516Swpaul 32840516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 32940516Swpaul 33040516Swpaul /* 33140516Swpaul * Start reading bits from EEPROM. 33240516Swpaul */ 33340516Swpaul for (i = 0x8000; i; i >>= 1) { 33440516Swpaul EE_SET(RL_EE_CLK); 33540516Swpaul DELAY(100); 33640516Swpaul if (CSR_READ_1(sc, RL_EECMD) & RL_EE_DATAOUT) 33740516Swpaul word |= i; 33840516Swpaul EE_CLR(RL_EE_CLK); 33940516Swpaul DELAY(100); 34040516Swpaul } 34140516Swpaul 34240516Swpaul /* Turn off EEPROM access mode. */ 34340516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 34440516Swpaul 34540516Swpaul *dest = word; 34640516Swpaul} 34740516Swpaul 34840516Swpaul/* 34940516Swpaul * Read a sequence of words from the EEPROM. 35040516Swpaul */ 351102335Salfredstatic void 352131605Sbmsrl_read_eeprom(struct rl_softc *sc, uint8_t *dest, int off, int cnt, int swap) 35340516Swpaul{ 35440516Swpaul int i; 355131605Sbms uint16_t word = 0, *ptr; 35640516Swpaul 35740516Swpaul for (i = 0; i < cnt; i++) { 35840516Swpaul rl_eeprom_getword(sc, off + i, &word); 359131605Sbms ptr = (uint16_t *)(dest + (i * 2)); 36040516Swpaul if (swap) 36140516Swpaul *ptr = ntohs(word); 36240516Swpaul else 36340516Swpaul *ptr = word; 36440516Swpaul } 36540516Swpaul} 36640516Swpaul 36740516Swpaul/* 36840516Swpaul * MII access routines are provided for the 8129, which 36940516Swpaul * doesn't have a built-in PHY. For the 8139, we fake things 37040516Swpaul * up by diverting rl_phy_readreg()/rl_phy_writereg() to the 37140516Swpaul * direct access PHY registers. 37240516Swpaul */ 37340516Swpaul#define MII_SET(x) \ 37440516Swpaul CSR_WRITE_1(sc, RL_MII, \ 375105221Sphk CSR_READ_1(sc, RL_MII) | (x)) 37640516Swpaul 37740516Swpaul#define MII_CLR(x) \ 37840516Swpaul CSR_WRITE_1(sc, RL_MII, \ 379105221Sphk CSR_READ_1(sc, RL_MII) & ~(x)) 38040516Swpaul 38140516Swpaul/* 38240516Swpaul * Sync the PHYs by setting data bit and strobing the clock 32 times. 38340516Swpaul */ 384102335Salfredstatic void 385131605Sbmsrl_mii_sync(struct rl_softc *sc) 38640516Swpaul{ 38740516Swpaul register int i; 38840516Swpaul 38940516Swpaul MII_SET(RL_MII_DIR|RL_MII_DATAOUT); 39040516Swpaul 39140516Swpaul for (i = 0; i < 32; i++) { 39240516Swpaul MII_SET(RL_MII_CLK); 39340516Swpaul DELAY(1); 39440516Swpaul MII_CLR(RL_MII_CLK); 39540516Swpaul DELAY(1); 39640516Swpaul } 39740516Swpaul} 39840516Swpaul 39940516Swpaul/* 40040516Swpaul * Clock a series of bits through the MII. 40140516Swpaul */ 402102335Salfredstatic void 403131605Sbmsrl_mii_send(struct rl_softc *sc, uint32_t bits, int cnt) 40440516Swpaul{ 40540516Swpaul int i; 40640516Swpaul 40740516Swpaul MII_CLR(RL_MII_CLK); 40840516Swpaul 40940516Swpaul for (i = (0x1 << (cnt - 1)); i; i >>= 1) { 410109109Sdes if (bits & i) { 41140516Swpaul MII_SET(RL_MII_DATAOUT); 412109109Sdes } else { 41340516Swpaul MII_CLR(RL_MII_DATAOUT); 414109109Sdes } 41540516Swpaul DELAY(1); 41640516Swpaul MII_CLR(RL_MII_CLK); 41740516Swpaul DELAY(1); 41840516Swpaul MII_SET(RL_MII_CLK); 41940516Swpaul } 42040516Swpaul} 42140516Swpaul 42240516Swpaul/* 42340516Swpaul * Read an PHY register through the MII. 42440516Swpaul */ 425102335Salfredstatic int 426131605Sbmsrl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame) 42740516Swpaul{ 42867087Swpaul int i, ack; 42940516Swpaul 43067087Swpaul RL_LOCK(sc); 43140516Swpaul 432131605Sbms /* Set up frame for RX. */ 43340516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 43440516Swpaul frame->mii_opcode = RL_MII_READOP; 43540516Swpaul frame->mii_turnaround = 0; 43640516Swpaul frame->mii_data = 0; 437109109Sdes 43840516Swpaul CSR_WRITE_2(sc, RL_MII, 0); 43940516Swpaul 440131605Sbms /* Turn on data xmit. */ 44140516Swpaul MII_SET(RL_MII_DIR); 44240516Swpaul 44340516Swpaul rl_mii_sync(sc); 44440516Swpaul 445131605Sbms /* Send command/address info. */ 44640516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 44740516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 44840516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 44940516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 45040516Swpaul 45140516Swpaul /* Idle bit */ 45240516Swpaul MII_CLR((RL_MII_CLK|RL_MII_DATAOUT)); 45340516Swpaul DELAY(1); 45440516Swpaul MII_SET(RL_MII_CLK); 45540516Swpaul DELAY(1); 45640516Swpaul 45740516Swpaul /* Turn off xmit. */ 45840516Swpaul MII_CLR(RL_MII_DIR); 45940516Swpaul 46040516Swpaul /* Check for ack */ 46140516Swpaul MII_CLR(RL_MII_CLK); 46240516Swpaul DELAY(1); 463109058Smbr ack = CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN; 46440516Swpaul MII_SET(RL_MII_CLK); 46540516Swpaul DELAY(1); 46640516Swpaul 46740516Swpaul /* 46840516Swpaul * Now try reading data bits. If the ack failed, we still 46940516Swpaul * need to clock through 16 cycles to keep the PHY(s) in sync. 47040516Swpaul */ 47140516Swpaul if (ack) { 47240516Swpaul for(i = 0; i < 16; i++) { 47340516Swpaul MII_CLR(RL_MII_CLK); 47440516Swpaul DELAY(1); 47540516Swpaul MII_SET(RL_MII_CLK); 47640516Swpaul DELAY(1); 47740516Swpaul } 47840516Swpaul goto fail; 47940516Swpaul } 48040516Swpaul 48140516Swpaul for (i = 0x8000; i; i >>= 1) { 48240516Swpaul MII_CLR(RL_MII_CLK); 48340516Swpaul DELAY(1); 48440516Swpaul if (!ack) { 48540516Swpaul if (CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN) 48640516Swpaul frame->mii_data |= i; 48740516Swpaul DELAY(1); 48840516Swpaul } 48940516Swpaul MII_SET(RL_MII_CLK); 49040516Swpaul DELAY(1); 49140516Swpaul } 49240516Swpaul 49340516Swpaulfail: 49440516Swpaul MII_CLR(RL_MII_CLK); 49540516Swpaul DELAY(1); 49640516Swpaul MII_SET(RL_MII_CLK); 49740516Swpaul DELAY(1); 49840516Swpaul 49967087Swpaul RL_UNLOCK(sc); 50040516Swpaul 501131605Sbms return (ack ? 1 : 0); 50240516Swpaul} 50340516Swpaul 50440516Swpaul/* 50540516Swpaul * Write to a PHY register through the MII. 50640516Swpaul */ 507102335Salfredstatic int 508131605Sbmsrl_mii_writereg(struct rl_softc *sc, struct rl_mii_frame *frame) 509131605Sbms{ 510109109Sdes 51167087Swpaul RL_LOCK(sc); 51240516Swpaul 513131605Sbms /* Set up frame for TX. */ 51440516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 51540516Swpaul frame->mii_opcode = RL_MII_WRITEOP; 51640516Swpaul frame->mii_turnaround = RL_MII_TURNAROUND; 517109109Sdes 518131605Sbms /* Turn on data output. */ 51940516Swpaul MII_SET(RL_MII_DIR); 52040516Swpaul 52140516Swpaul rl_mii_sync(sc); 52240516Swpaul 52340516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 52440516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 52540516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 52640516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 52740516Swpaul rl_mii_send(sc, frame->mii_turnaround, 2); 52840516Swpaul rl_mii_send(sc, frame->mii_data, 16); 52940516Swpaul 53040516Swpaul /* Idle bit. */ 53140516Swpaul MII_SET(RL_MII_CLK); 53240516Swpaul DELAY(1); 53340516Swpaul MII_CLR(RL_MII_CLK); 53440516Swpaul DELAY(1); 53540516Swpaul 536131605Sbms /* Turn off xmit. */ 53740516Swpaul MII_CLR(RL_MII_DIR); 53840516Swpaul 53967087Swpaul RL_UNLOCK(sc); 54040516Swpaul 541131605Sbms return (0); 54240516Swpaul} 54340516Swpaul 544102335Salfredstatic int 545131605Sbmsrl_miibus_readreg(device_t dev, int phy, int reg) 54650703Swpaul{ 54740516Swpaul struct rl_softc *sc; 54840516Swpaul struct rl_mii_frame frame; 549131605Sbms uint16_t rval = 0; 550131605Sbms uint16_t rl8139_reg = 0; 55140516Swpaul 55250703Swpaul sc = device_get_softc(dev); 55350703Swpaul 554119868Swpaul if (sc->rl_type == RL_8139) { 55550703Swpaul /* Pretend the internal PHY is only at address 0 */ 55667087Swpaul if (phy) { 557131605Sbms return (0); 55867087Swpaul } 559131605Sbms switch (reg) { 56050703Swpaul case MII_BMCR: 56140516Swpaul rl8139_reg = RL_BMCR; 56240516Swpaul break; 56350703Swpaul case MII_BMSR: 56440516Swpaul rl8139_reg = RL_BMSR; 56540516Swpaul break; 56650703Swpaul case MII_ANAR: 56740516Swpaul rl8139_reg = RL_ANAR; 56840516Swpaul break; 56950703Swpaul case MII_ANER: 57050703Swpaul rl8139_reg = RL_ANER; 57150703Swpaul break; 57250703Swpaul case MII_ANLPAR: 57340516Swpaul rl8139_reg = RL_LPAR; 57440516Swpaul break; 57550703Swpaul case MII_PHYIDR1: 57650703Swpaul case MII_PHYIDR2: 577131605Sbms return (0); 57894149Swpaul /* 57994149Swpaul * Allow the rlphy driver to read the media status 58094149Swpaul * register. If we have a link partner which does not 58194149Swpaul * support NWAY, this is the register which will tell 58294149Swpaul * us the results of parallel detection. 58394149Swpaul */ 58494149Swpaul case RL_MEDIASTAT: 58594149Swpaul rval = CSR_READ_1(sc, RL_MEDIASTAT); 586131605Sbms return (rval); 58740516Swpaul default: 588131605Sbms if_printf(&sc->arpcom.ac_if, "bad phy register\n"); 589131605Sbms return (0); 59040516Swpaul } 59140516Swpaul rval = CSR_READ_2(sc, rl8139_reg); 592131605Sbms return (rval); 59340516Swpaul } 59440516Swpaul 59540516Swpaul bzero((char *)&frame, sizeof(frame)); 59650703Swpaul frame.mii_phyaddr = phy; 59740516Swpaul frame.mii_regaddr = reg; 59840516Swpaul rl_mii_readreg(sc, &frame); 599131605Sbms 600131605Sbms return (frame.mii_data); 60140516Swpaul} 60240516Swpaul 603102335Salfredstatic int 604131605Sbmsrl_miibus_writereg(device_t dev, int phy, int reg, int data) 60550703Swpaul{ 60640516Swpaul struct rl_softc *sc; 60740516Swpaul struct rl_mii_frame frame; 608131605Sbms uint16_t rl8139_reg = 0; 60940516Swpaul 61050703Swpaul sc = device_get_softc(dev); 61150703Swpaul 612119868Swpaul if (sc->rl_type == RL_8139) { 61350703Swpaul /* Pretend the internal PHY is only at address 0 */ 61467087Swpaul if (phy) { 615131605Sbms return (0); 61667087Swpaul } 617131605Sbms switch (reg) { 61850703Swpaul case MII_BMCR: 61940516Swpaul rl8139_reg = RL_BMCR; 62040516Swpaul break; 62150703Swpaul case MII_BMSR: 62240516Swpaul rl8139_reg = RL_BMSR; 62340516Swpaul break; 62450703Swpaul case MII_ANAR: 62540516Swpaul rl8139_reg = RL_ANAR; 62640516Swpaul break; 62750703Swpaul case MII_ANER: 62850703Swpaul rl8139_reg = RL_ANER; 62950703Swpaul break; 63050703Swpaul case MII_ANLPAR: 63140516Swpaul rl8139_reg = RL_LPAR; 63240516Swpaul break; 63350703Swpaul case MII_PHYIDR1: 63450703Swpaul case MII_PHYIDR2: 635131605Sbms return (0); 63650703Swpaul break; 63740516Swpaul default: 638131605Sbms if_printf(&sc->arpcom.ac_if, "bad phy register\n"); 639131605Sbms return (0); 64040516Swpaul } 64140516Swpaul CSR_WRITE_2(sc, rl8139_reg, data); 642131605Sbms return (0); 64340516Swpaul } 64440516Swpaul 64540516Swpaul bzero((char *)&frame, sizeof(frame)); 64650703Swpaul frame.mii_phyaddr = phy; 64740516Swpaul frame.mii_regaddr = reg; 64840516Swpaul frame.mii_data = data; 64940516Swpaul rl_mii_writereg(sc, &frame); 65040516Swpaul 651131605Sbms return (0); 65250703Swpaul} 65350703Swpaul 654102335Salfredstatic void 655131605Sbmsrl_miibus_statchg(device_t dev) 65650703Swpaul{ 65740516Swpaul} 65840516Swpaul 65940516Swpaul/* 66040516Swpaul * Program the 64-bit multicast hash filter. 66140516Swpaul */ 662102335Salfredstatic void 663131605Sbmsrl_setmulti(struct rl_softc *sc) 66440516Swpaul{ 665131605Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 66640516Swpaul int h = 0; 667131605Sbms uint32_t hashes[2] = { 0, 0 }; 66840516Swpaul struct ifmultiaddr *ifma; 669131605Sbms uint32_t rxfilt; 67040516Swpaul int mcnt = 0; 67140516Swpaul 672131606Sbms RL_LOCK_ASSERT(sc); 673131606Sbms 67440516Swpaul rxfilt = CSR_READ_4(sc, RL_RXCFG); 67540516Swpaul 67643062Swpaul if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 67740516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 67840516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 67940516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF); 68040516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF); 68140516Swpaul return; 68240516Swpaul } 68340516Swpaul 68440516Swpaul /* first, zot all the existing hash bits */ 68540516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0); 68640516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0); 68740516Swpaul 68840516Swpaul /* now program new ones */ 68972084Sphk TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 69040516Swpaul if (ifma->ifma_addr->sa_family != AF_LINK) 69140516Swpaul continue; 692130270Snaddy h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 693130270Snaddy ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 69440516Swpaul if (h < 32) 69540516Swpaul hashes[0] |= (1 << h); 69640516Swpaul else 69740516Swpaul hashes[1] |= (1 << (h - 32)); 69840516Swpaul mcnt++; 69940516Swpaul } 70040516Swpaul 70140516Swpaul if (mcnt) 70240516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 70340516Swpaul else 70440516Swpaul rxfilt &= ~RL_RXCFG_RX_MULTI; 70540516Swpaul 70640516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 70740516Swpaul CSR_WRITE_4(sc, RL_MAR0, hashes[0]); 70840516Swpaul CSR_WRITE_4(sc, RL_MAR4, hashes[1]); 70940516Swpaul} 71040516Swpaul 711102335Salfredstatic void 712131605Sbmsrl_reset(struct rl_softc *sc) 71340516Swpaul{ 71440516Swpaul register int i; 71540516Swpaul 716131606Sbms RL_LOCK_ASSERT(sc); 717131606Sbms 71840516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RESET); 71940516Swpaul 72040516Swpaul for (i = 0; i < RL_TIMEOUT; i++) { 72140516Swpaul DELAY(10); 72240516Swpaul if (!(CSR_READ_1(sc, RL_COMMAND) & RL_CMD_RESET)) 72340516Swpaul break; 72440516Swpaul } 72540516Swpaul if (i == RL_TIMEOUT) 726131605Sbms if_printf(&sc->arpcom.ac_if, "reset never completed!\n"); 72740516Swpaul} 72840516Swpaul 72940516Swpaul/* 73040516Swpaul * Probe for a RealTek 8129/8139 chip. Check the PCI vendor and device 73140516Swpaul * IDs against our list and return a device name if we find a match. 73240516Swpaul */ 733102335Salfredstatic int 734131605Sbmsrl_probe(device_t dev) 73540516Swpaul{ 736131605Sbms struct rl_softc *sc; 737131605Sbms struct rl_type *t = rl_devs; 738117388Swpaul int rid; 739131605Sbms uint32_t hwrev; 74040516Swpaul 741117388Swpaul sc = device_get_softc(dev); 74240516Swpaul 743131605Sbms while (t->rl_name != NULL) { 74450703Swpaul if ((pci_get_vendor(dev) == t->rl_vid) && 74550703Swpaul (pci_get_device(dev) == t->rl_did)) { 746117388Swpaul /* 747117388Swpaul * Temporarily map the I/O space 748117388Swpaul * so we can read the chip ID register. 749117388Swpaul */ 750117388Swpaul rid = RL_RID; 751127135Snjl sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, 752127135Snjl RF_ACTIVE); 753117388Swpaul if (sc->rl_res == NULL) { 754117388Swpaul device_printf(dev, 755117388Swpaul "couldn't map ports/memory\n"); 756131605Sbms return (ENXIO); 757117388Swpaul } 758117388Swpaul sc->rl_btag = rman_get_bustag(sc->rl_res); 759117388Swpaul sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 760131605Sbms 761119868Swpaul hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV; 762119868Swpaul bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 763131605Sbms 764119868Swpaul /* Don't attach to 8139C+ or 8169/8110 chips. */ 765119868Swpaul if (hwrev == RL_HWREV_8139CPLUS || 766124076Swpaul (hwrev == RL_HWREV_8169 && 767124076Swpaul t->rl_did == RT_DEVICEID_8169) || 768119954Swpaul hwrev == RL_HWREV_8169S || 769119954Swpaul hwrev == RL_HWREV_8110S) { 770119868Swpaul t++; 771119868Swpaul continue; 772119868Swpaul } 773119868Swpaul 774119868Swpaul device_set_desc(dev, t->rl_name); 775131605Sbms return (0); 77640516Swpaul } 77740516Swpaul t++; 77840516Swpaul } 77940516Swpaul 780131605Sbms return (ENXIO); 78140516Swpaul} 78240516Swpaul 78340516Swpaul/* 78440516Swpaul * Attach the interface. Allocate softc structures, do ifmedia 78540516Swpaul * setup and ethernet/BPF attach. 78640516Swpaul */ 787102335Salfredstatic int 788131605Sbmsrl_attach(device_t dev) 78940516Swpaul{ 790131605Sbms uint8_t eaddr[ETHER_ADDR_LEN]; 791131605Sbms uint16_t as[3]; 792131605Sbms struct ifnet *ifp; 79340516Swpaul struct rl_softc *sc; 794117388Swpaul struct rl_type *t; 795131605Sbms int error = 0, i, rid; 796131605Sbms int unit; 797131605Sbms uint16_t rl_did = 0; 79840516Swpaul 79950703Swpaul sc = device_get_softc(dev); 80050703Swpaul unit = device_get_unit(dev); 80140516Swpaul 80293818Sjhb mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 803131606Sbms MTX_DEF); 804131605Sbms 80572813Swpaul pci_enable_busmaster(dev); 80640516Swpaul 807131605Sbms /* Map control/status registers. */ 808109109Sdes rid = RL_RID; 809127135Snjl sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, RF_ACTIVE); 81050703Swpaul 81150703Swpaul if (sc->rl_res == NULL) { 812131605Sbms device_printf(dev, "couldn't map ports/memory\n"); 81350703Swpaul error = ENXIO; 81440516Swpaul goto fail; 81540516Swpaul } 81640516Swpaul 817117388Swpaul#ifdef notdef 818131605Sbms /* 819131605Sbms * Detect the Realtek 8139B. For some reason, this chip is very 82069127Sroger * unstable when left to autoselect the media 82169127Sroger * The best workaround is to set the device to the required 82269127Sroger * media type or to set it to the 10 Meg speed. 82369127Sroger */ 824131605Sbms if ((rman_get_end(sc->rl_res) - rman_get_start(sc->rl_res)) == 0xFF) 825131605Sbms device_printf(dev, 826131605Sbms"Realtek 8139B detected. Warning, this may be unstable in autoselect mode\n"); 827117388Swpaul#endif 82869127Sroger 82950703Swpaul sc->rl_btag = rman_get_bustag(sc->rl_res); 83050703Swpaul sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 83150703Swpaul 832112872Snjl /* Allocate interrupt */ 83350703Swpaul rid = 0; 834127135Snjl sc->rl_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 83550703Swpaul RF_SHAREABLE | RF_ACTIVE); 83650703Swpaul 83750703Swpaul if (sc->rl_irq == NULL) { 838131605Sbms device_printf(dev, "couldn't map interrupt\n"); 83950703Swpaul error = ENXIO; 84040516Swpaul goto fail; 84140516Swpaul } 84240516Swpaul 843131606Sbms /* 844131606Sbms * Reset the adapter. Only take the lock here as it's needed in 845131606Sbms * order to call rl_reset(). 846131606Sbms */ 847131606Sbms RL_LOCK(sc); 84840516Swpaul rl_reset(sc); 849131606Sbms RL_UNLOCK(sc); 850131606Sbms 85167931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_6BIT; 852131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, 0, 1, 0); 85368215Swpaul if (rl_did != 0x8129) 85467931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_8BIT; 85540516Swpaul 85640516Swpaul /* 85740516Swpaul * Get station address from the EEPROM. 85840516Swpaul */ 859131605Sbms rl_read_eeprom(sc, (uint8_t *)as, RL_EE_EADDR, 3, 0); 860108729Sjake for (i = 0; i < 3; i++) { 861108729Sjake eaddr[(i * 2) + 0] = as[i] & 0xff; 862108729Sjake eaddr[(i * 2) + 1] = as[i] >> 8; 863108729Sjake } 86440516Swpaul 86540516Swpaul sc->rl_unit = unit; 86640516Swpaul bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 86740516Swpaul 86840516Swpaul /* 86940516Swpaul * Now read the exact device type from the EEPROM to find 87040516Swpaul * out if it's an 8129 or 8139. 87140516Swpaul */ 872131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, RL_EE_PCI_DID, 1, 0); 87340516Swpaul 874117388Swpaul t = rl_devs; 875119868Swpaul sc->rl_type = 0; 876117388Swpaul while(t->rl_name != NULL) { 877117388Swpaul if (rl_did == t->rl_did) { 878117388Swpaul sc->rl_type = t->rl_basetype; 879117388Swpaul break; 880117388Swpaul } 881117388Swpaul t++; 882117388Swpaul } 883119868Swpaul 884119868Swpaul if (sc->rl_type == 0) { 885131605Sbms device_printf(dev, "unknown device ID: %x\n", rl_did); 88650703Swpaul error = ENXIO; 88740516Swpaul goto fail; 88840516Swpaul } 88940516Swpaul 89081713Swpaul /* 89181713Swpaul * Allocate the parent bus DMA tag appropriate for PCI. 89281713Swpaul */ 89381713Swpaul#define RL_NSEG_NEW 32 894109109Sdes error = bus_dma_tag_create(NULL, /* parent */ 89581713Swpaul 1, 0, /* alignment, boundary */ 89681713Swpaul BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 89781713Swpaul BUS_SPACE_MAXADDR, /* highaddr */ 89881713Swpaul NULL, NULL, /* filter, filterarg */ 89981713Swpaul MAXBSIZE, RL_NSEG_NEW, /* maxsize, nsegments */ 900109109Sdes BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 90181713Swpaul BUS_DMA_ALLOCNOW, /* flags */ 902117126Sscottl NULL, NULL, /* lockfunc, lockarg */ 90381713Swpaul &sc->rl_parent_tag); 904112872Snjl if (error) 905112872Snjl goto fail; 90640516Swpaul 90781713Swpaul /* 908119868Swpaul * Now allocate a tag for the DMA descriptor lists. 909119868Swpaul * All of our lists are allocated as a contiguous block 910119868Swpaul * of memory. 91181713Swpaul */ 912119868Swpaul error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */ 913119868Swpaul 1, 0, /* alignment, boundary */ 914119868Swpaul BUS_SPACE_MAXADDR, /* lowaddr */ 915119868Swpaul BUS_SPACE_MAXADDR, /* highaddr */ 916119868Swpaul NULL, NULL, /* filter, filterarg */ 917119868Swpaul RL_RXBUFLEN + 1518, 1, /* maxsize,nsegments */ 918119868Swpaul BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 919119868Swpaul BUS_DMA_ALLOCNOW, /* flags */ 920119868Swpaul NULL, NULL, /* lockfunc, lockarg */ 921119868Swpaul &sc->rl_tag); 922112872Snjl if (error) 923112872Snjl goto fail; 92481713Swpaul 925119868Swpaul /* 926119868Swpaul * Now allocate a chunk of DMA-able memory based on the 927119868Swpaul * tag we just created. 928119868Swpaul */ 929119868Swpaul error = bus_dmamem_alloc(sc->rl_tag, 930119868Swpaul (void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT | BUS_DMA_ZERO, 931119868Swpaul &sc->rl_cdata.rl_rx_dmamap); 932119868Swpaul if (error) { 933131605Sbms device_printf(dev, "no memory for list buffers!\n"); 934119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 935119868Swpaul sc->rl_tag = NULL; 936119868Swpaul goto fail; 937119868Swpaul } 938119868Swpaul 939119868Swpaul /* Leave a few bytes before the start of the RX ring buffer. */ 940119868Swpaul sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf; 941131605Sbms sc->rl_cdata.rl_rx_buf += sizeof(uint64_t); 942119868Swpaul 94350703Swpaul /* Do MII setup */ 94450703Swpaul if (mii_phy_probe(dev, &sc->rl_miibus, 94550703Swpaul rl_ifmedia_upd, rl_ifmedia_sts)) { 946131605Sbms device_printf(dev, "MII without any phy!\n"); 94750703Swpaul error = ENXIO; 94850703Swpaul goto fail; 94950703Swpaul } 95050703Swpaul 95140516Swpaul ifp = &sc->arpcom.ac_if; 95240516Swpaul ifp->if_softc = sc; 953121816Sbrooks if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 95440516Swpaul ifp->if_mtu = ETHERMTU; 95540516Swpaul ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 95640516Swpaul ifp->if_ioctl = rl_ioctl; 957119868Swpaul ifp->if_start = rl_start; 95840516Swpaul ifp->if_watchdog = rl_watchdog; 95940516Swpaul ifp->if_init = rl_init; 96040516Swpaul ifp->if_baudrate = 10000000; 961119976Swpaul ifp->if_capabilities = IFCAP_VLAN_MTU; 962128121Sru#ifdef DEVICE_POLLING 963128121Sru ifp->if_capabilities |= IFCAP_POLLING; 964128121Sru#endif 965119977Swpaul ifp->if_capenable = ifp->if_capabilities; 966131455Smlaier IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 967131455Smlaier ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 968131455Smlaier IFQ_SET_READY(&ifp->if_snd); 969131605Sbms 970112872Snjl callout_handle_init(&sc->rl_stat_ch); 971112872Snjl 97240516Swpaul /* 97363090Sarchie * Call MI attach routine. 97440516Swpaul */ 975106936Ssam ether_ifattach(ifp, eaddr); 976106157Simp 977113609Snjl /* Hook interrupt last to avoid having to lock softc */ 978131606Sbms error = bus_setup_intr(dev, sc->rl_irq, INTR_TYPE_NET | INTR_MPSAFE, 979119868Swpaul rl_intr, sc, &sc->rl_intrhand); 980106157Simp if (error) { 981131605Sbms if_printf(ifp, "couldn't set up irq\n"); 982113609Snjl ether_ifdetach(ifp); 983106157Simp } 984106157Simp 98540516Swpaulfail: 986112872Snjl if (error) 987112872Snjl rl_detach(dev); 988112872Snjl 989110601Snjl return (error); 99040516Swpaul} 99140516Swpaul 992113609Snjl/* 993113609Snjl * Shutdown hardware and free up resources. This can be called any 994113609Snjl * time after the mutex has been initialized. It is called in both 995113609Snjl * the error case in attach and the normal detach case so it needs 996113609Snjl * to be careful about only freeing resources that have actually been 997113609Snjl * allocated. 998113609Snjl */ 999102335Salfredstatic int 1000131605Sbmsrl_detach(device_t dev) 100150703Swpaul{ 100250703Swpaul struct rl_softc *sc; 100350703Swpaul struct ifnet *ifp; 100450703Swpaul 100550703Swpaul sc = device_get_softc(dev); 1006131605Sbms ifp = &sc->arpcom.ac_if; 1007131605Sbms 1008112880Sjhb KASSERT(mtx_initialized(&sc->rl_mtx), ("rl mutex not initialized")); 100967087Swpaul RL_LOCK(sc); 1010131606Sbms#if 0 1011131606Sbms sc->suspended = 1; 1012131606Sbms#endif 101350703Swpaul 1014113609Snjl /* These should only be active if attach succeeded */ 1015113812Simp if (device_is_attached(dev)) { 1016113609Snjl rl_stop(sc); 1017112872Snjl ether_ifdetach(ifp); 1018113609Snjl } 1019113609Snjl if (sc->rl_miibus) 1020112872Snjl device_delete_child(dev, sc->rl_miibus); 1021113609Snjl bus_generic_detach(dev); 102250703Swpaul 1023112872Snjl if (sc->rl_intrhand) 1024112872Snjl bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand); 1025112872Snjl if (sc->rl_irq) 1026112872Snjl bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1027112872Snjl if (sc->rl_res) 1028112872Snjl bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 102950703Swpaul 1030119868Swpaul if (sc->rl_tag) { 1031119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 1032119868Swpaul bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf, 1033119868Swpaul sc->rl_cdata.rl_rx_dmamap); 1034119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 1035112872Snjl } 1036112872Snjl if (sc->rl_parent_tag) 1037112872Snjl bus_dma_tag_destroy(sc->rl_parent_tag); 103850703Swpaul 103967087Swpaul RL_UNLOCK(sc); 104067087Swpaul mtx_destroy(&sc->rl_mtx); 104150703Swpaul 1042131605Sbms return (0); 104350703Swpaul} 104450703Swpaul 104540516Swpaul/* 104640516Swpaul * Initialize the transmit descriptors. 104740516Swpaul */ 1048102335Salfredstatic int 1049131605Sbmsrl_list_tx_init(struct rl_softc *sc) 105040516Swpaul{ 105140516Swpaul struct rl_chain_data *cd; 105240516Swpaul int i; 105340516Swpaul 1054131606Sbms RL_LOCK_ASSERT(sc); 1055131606Sbms 105640516Swpaul cd = &sc->rl_cdata; 105740516Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 105845633Swpaul cd->rl_tx_chain[i] = NULL; 105948028Swpaul CSR_WRITE_4(sc, 1060131605Sbms RL_TXADDR0 + (i * sizeof(uint32_t)), 0x0000000); 106140516Swpaul } 106240516Swpaul 106345633Swpaul sc->rl_cdata.cur_tx = 0; 106445633Swpaul sc->rl_cdata.last_tx = 0; 106540516Swpaul 1066131605Sbms return (0); 106740516Swpaul} 106840516Swpaul 106940516Swpaul/* 107040516Swpaul * A frame has been uploaded: pass the resulting mbuf chain up to 107140516Swpaul * the higher level protocols. 107240516Swpaul * 107340516Swpaul * You know there's something wrong with a PCI bus-master chip design 107440516Swpaul * when you have to use m_devget(). 107540516Swpaul * 107640516Swpaul * The receive operation is badly documented in the datasheet, so I'll 107740516Swpaul * attempt to document it here. The driver provides a buffer area and 107840516Swpaul * places its base address in the RX buffer start address register. 107940516Swpaul * The chip then begins copying frames into the RX buffer. Each frame 108072645Sasmodai * is preceded by a 32-bit RX status word which specifies the length 108140516Swpaul * of the frame and certain other status bits. Each frame (starting with 108240516Swpaul * the status word) is also 32-bit aligned. The frame length is in the 108340516Swpaul * first 16 bits of the status word; the lower 15 bits correspond with 108440516Swpaul * the 'rx status register' mentioned in the datasheet. 108548028Swpaul * 108648028Swpaul * Note: to make the Alpha happy, the frame payload needs to be aligned 108778508Sbmilekic * on a 32-bit boundary. To achieve this, we pass RL_ETHER_ALIGN (2 bytes) 1088109109Sdes * as the offset argument to m_devget(). 108940516Swpaul */ 1090102335Salfredstatic void 1091131605Sbmsrl_rxeof(struct rl_softc *sc) 109240516Swpaul{ 1093109109Sdes struct mbuf *m; 1094131605Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 1095131605Sbms uint8_t *rxbufpos; 109640516Swpaul int total_len = 0; 109740516Swpaul int wrap = 0; 1098131605Sbms uint32_t rxstat; 1099131605Sbms uint16_t cur_rx; 1100131605Sbms uint16_t limit; 1101131605Sbms uint16_t max_bytes, rx_bytes = 0; 110240516Swpaul 1103122689Ssam RL_LOCK_ASSERT(sc); 1104122689Ssam 110581713Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1106108729Sjake BUS_DMASYNC_POSTREAD); 110781713Swpaul 110840516Swpaul cur_rx = (CSR_READ_2(sc, RL_CURRXADDR) + 16) % RL_RXBUFLEN; 110940516Swpaul 111040516Swpaul /* Do not try to read past this point. */ 111140516Swpaul limit = CSR_READ_2(sc, RL_CURRXBUF) % RL_RXBUFLEN; 111240516Swpaul 111340516Swpaul if (limit < cur_rx) 111440516Swpaul max_bytes = (RL_RXBUFLEN - cur_rx) + limit; 111540516Swpaul else 111640516Swpaul max_bytes = limit - cur_rx; 111740516Swpaul 111842738Swpaul while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) { 111994883Sluigi#ifdef DEVICE_POLLING 1120102052Ssobomax if (ifp->if_flags & IFF_POLLING) { 112194883Sluigi if (sc->rxcycles <= 0) 112294883Sluigi break; 112394883Sluigi sc->rxcycles--; 112494883Sluigi } 112594883Sluigi#endif /* DEVICE_POLLING */ 112640516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx; 1127131605Sbms rxstat = le32toh(*(uint32_t *)rxbufpos); 112840516Swpaul 112940516Swpaul /* 113040516Swpaul * Here's a totally undocumented fact for you. When the 113140516Swpaul * RealTek chip is in the process of copying a packet into 113240516Swpaul * RAM for you, the length will be 0xfff0. If you spot a 113340516Swpaul * packet header with this value, you need to stop. The 113440516Swpaul * datasheet makes absolutely no mention of this and 113540516Swpaul * RealTek should be shot for this. 113640516Swpaul */ 1137131605Sbms if ((uint16_t)(rxstat >> 16) == RL_RXSTAT_UNFINISHED) 113840516Swpaul break; 1139109109Sdes 114040516Swpaul if (!(rxstat & RL_RXSTAT_RXOK)) { 114140516Swpaul ifp->if_ierrors++; 1142131841Sbms rl_init_locked(sc); 114350703Swpaul return; 114440516Swpaul } 114540516Swpaul 1146109109Sdes /* No errors; receive the packet. */ 114740516Swpaul total_len = rxstat >> 16; 114840516Swpaul rx_bytes += total_len + 4; 114940516Swpaul 115040516Swpaul /* 115142051Swpaul * XXX The RealTek chip includes the CRC with every 115242051Swpaul * received frame, and there's no way to turn this 115342051Swpaul * behavior off (at least, I can't find anything in 1154109109Sdes * the manual that explains how to do it) so we have 115542051Swpaul * to trim off the CRC manually. 115642051Swpaul */ 115742051Swpaul total_len -= ETHER_CRC_LEN; 115842051Swpaul 115942051Swpaul /* 116040516Swpaul * Avoid trying to read more bytes than we know 116140516Swpaul * the chip has prepared for us. 116240516Swpaul */ 116340516Swpaul if (rx_bytes > max_bytes) 116440516Swpaul break; 116540516Swpaul 116640516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + 1167131605Sbms ((cur_rx + sizeof(uint32_t)) % RL_RXBUFLEN); 116840516Swpaul if (rxbufpos == (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN)) 116940516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf; 117040516Swpaul 117140516Swpaul wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos; 117240516Swpaul if (total_len > wrap) { 117378508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 117478508Sbmilekic NULL); 117540516Swpaul if (m == NULL) { 117640516Swpaul ifp->if_ierrors++; 117752426Swpaul } else { 117840516Swpaul m_copyback(m, wrap, total_len - wrap, 117940516Swpaul sc->rl_cdata.rl_rx_buf); 118048028Swpaul } 118142051Swpaul cur_rx = (total_len - wrap + ETHER_CRC_LEN); 118240516Swpaul } else { 118378508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 118478508Sbmilekic NULL); 1185131605Sbms if (m == NULL) 118640516Swpaul ifp->if_ierrors++; 118742051Swpaul cur_rx += total_len + 4 + ETHER_CRC_LEN; 118840516Swpaul } 118940516Swpaul 1190131605Sbms /* Round up to 32-bit boundary. */ 119140516Swpaul cur_rx = (cur_rx + 3) & ~3; 119240516Swpaul CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16); 119340516Swpaul 119440516Swpaul if (m == NULL) 119540516Swpaul continue; 119640516Swpaul 119740516Swpaul ifp->if_ipackets++; 1198122689Ssam RL_UNLOCK(sc); 1199106936Ssam (*ifp->if_input)(ifp, m); 1200122689Ssam RL_LOCK(sc); 120140516Swpaul } 120240516Swpaul} 120340516Swpaul 120440516Swpaul/* 120540516Swpaul * A frame was downloaded to the chip. It's safe for us to clean up 120640516Swpaul * the list buffers. 120740516Swpaul */ 1208102335Salfredstatic void 1209131605Sbmsrl_txeof(struct rl_softc *sc) 121040516Swpaul{ 1211131605Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 1212131605Sbms uint32_t txstat; 121340516Swpaul 1214131606Sbms RL_LOCK_ASSERT(sc); 1215131606Sbms 121640516Swpaul /* 121740516Swpaul * Go through our tx list and free mbufs for those 121840516Swpaul * frames that have been uploaded. 121940516Swpaul */ 122045633Swpaul do { 1221127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1222127783Sru break; 122345633Swpaul txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc)); 122445633Swpaul if (!(txstat & (RL_TXSTAT_TX_OK| 122545633Swpaul RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT))) 122640516Swpaul break; 122740516Swpaul 122845633Swpaul ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24; 122940516Swpaul 1230127783Sru bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1231127783Sru bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1232127783Sru m_freem(RL_LAST_TXMBUF(sc)); 1233127783Sru RL_LAST_TXMBUF(sc) = NULL; 123445633Swpaul if (txstat & RL_TXSTAT_TX_OK) 123545633Swpaul ifp->if_opackets++; 123645633Swpaul else { 123752426Swpaul int oldthresh; 123845633Swpaul ifp->if_oerrors++; 123945633Swpaul if ((txstat & RL_TXSTAT_TXABRT) || 124045633Swpaul (txstat & RL_TXSTAT_OUTOFWIN)) 124145633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 124252426Swpaul oldthresh = sc->rl_txthresh; 124352426Swpaul /* error recovery */ 124452426Swpaul rl_reset(sc); 1245131841Sbms rl_init_locked(sc); 124652426Swpaul /* 124752426Swpaul * If there was a transmit underrun, 124852426Swpaul * bump the TX threshold. 124952426Swpaul */ 125052426Swpaul if (txstat & RL_TXSTAT_TX_UNDERRUN) 125152426Swpaul sc->rl_txthresh = oldthresh + 32; 125252426Swpaul return; 125345633Swpaul } 125445633Swpaul RL_INC(sc->rl_cdata.last_tx); 125545633Swpaul ifp->if_flags &= ~IFF_OACTIVE; 125645633Swpaul } while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx); 125740516Swpaul 1258127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1259127783Sru ifp->if_timer = 0; 1260127783Sru else if (ifp->if_timer == 0) 1261127783Sru ifp->if_timer = 5; 126250703Swpaul} 126340516Swpaul 1264102335Salfredstatic void 1265131605Sbmsrl_tick(void *xsc) 126650703Swpaul{ 1267131605Sbms struct rl_softc *sc = xsc; 126850703Swpaul struct mii_data *mii; 126950703Swpaul 127067087Swpaul RL_LOCK(sc); 127150703Swpaul mii = device_get_softc(sc->rl_miibus); 127250703Swpaul mii_tick(mii); 127350703Swpaul 127450703Swpaul sc->rl_stat_ch = timeout(rl_tick, sc, hz); 127567087Swpaul RL_UNLOCK(sc); 127640516Swpaul} 127740516Swpaul 127894883Sluigi#ifdef DEVICE_POLLING 127994883Sluigistatic void 1280131841Sbmsrl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 128194883Sluigi{ 128294883Sluigi struct rl_softc *sc = ifp->if_softc; 128394883Sluigi 128494883Sluigi RL_LOCK(sc); 1285131841Sbms rl_poll_locked(ifp, cmd, count); 1286131841Sbms RL_UNLOCK(sc); 1287131841Sbms} 1288131605Sbms 1289131841Sbmsstatic void 1290131841Sbmsrl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) 1291131841Sbms{ 1292131841Sbms struct rl_softc *sc = ifp->if_softc; 1293131841Sbms 1294131841Sbms RL_LOCK_ASSERT(sc); 1295131841Sbms 1296128121Sru if (!(ifp->if_capenable & IFCAP_POLLING)) { 1297128121Sru ether_poll_deregister(ifp); 1298128121Sru cmd = POLL_DEREGISTER; 1299128121Sru } 1300131605Sbms 1301131605Sbms if (cmd == POLL_DEREGISTER) { 1302131605Sbms /* Final call; enable interrupts. */ 1303119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 1304131841Sbms return; 130594883Sluigi } 130694883Sluigi 130794883Sluigi sc->rxcycles = count; 1308119868Swpaul rl_rxeof(sc); 1309119868Swpaul rl_txeof(sc); 1310131605Sbms 1311131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1312131841Sbms rl_start_locked(ifp); 131394883Sluigi 1314131605Sbms if (cmd == POLL_AND_CHECK_STATUS) { 1315131605Sbms uint16_t status; 131694883Sluigi 1317131605Sbms /* We should also check the status register. */ 131894883Sluigi status = CSR_READ_2(sc, RL_ISR); 1319100957Sjhb if (status == 0xffff) 1320131841Sbms return; 1321131605Sbms if (status != 0) 132294883Sluigi CSR_WRITE_2(sc, RL_ISR, status); 132394883Sluigi 1324131605Sbms /* XXX We should check behaviour on receiver stalls. */ 132594883Sluigi 132694883Sluigi if (status & RL_ISR_SYSTEM_ERR) { 132794883Sluigi rl_reset(sc); 1328131841Sbms rl_init_locked(sc); 132994883Sluigi } 133094883Sluigi } 133194883Sluigi} 133294883Sluigi#endif /* DEVICE_POLLING */ 133394883Sluigi 1334102335Salfredstatic void 1335131605Sbmsrl_intr(void *arg) 133640516Swpaul{ 1337131605Sbms struct rl_softc *sc = arg; 1338131606Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 1339131605Sbms uint16_t status; 134040516Swpaul 1341131606Sbms RL_LOCK(sc); 1342131606Sbms 1343131841Sbms if (sc->suspended) 1344131841Sbms goto done_locked; 134586822Siwasaki 134694883Sluigi#ifdef DEVICE_POLLING 1347131841Sbms if (ifp->if_flags & IFF_POLLING) 1348131841Sbms goto done_locked; 1349131841Sbms 1350128121Sru if ((ifp->if_capenable & IFCAP_POLLING) && 1351131605Sbms ether_poll_register(rl_poll, ifp)) { 1352131605Sbms /* Disable interrupts. */ 135394883Sluigi CSR_WRITE_2(sc, RL_IMR, 0x0000); 1354131841Sbms rl_poll_locked(ifp, 0, 1); 1355131841Sbms goto done_locked; 135694883Sluigi } 135794883Sluigi#endif /* DEVICE_POLLING */ 135840516Swpaul 135940516Swpaul for (;;) { 136040516Swpaul status = CSR_READ_2(sc, RL_ISR); 1361131605Sbms /* If the card has gone away, the read returns 0xffff. */ 1362100957Sjhb if (status == 0xffff) 1363100957Sjhb break; 1364131605Sbms if (status != 0) 136540516Swpaul CSR_WRITE_2(sc, RL_ISR, status); 136640516Swpaul if ((status & RL_INTRS) == 0) 136740516Swpaul break; 136840516Swpaul if (status & RL_ISR_RX_OK) 136940516Swpaul rl_rxeof(sc); 137040516Swpaul if (status & RL_ISR_RX_ERR) 137140516Swpaul rl_rxeof(sc); 137245633Swpaul if ((status & RL_ISR_TX_OK) || (status & RL_ISR_TX_ERR)) 137340516Swpaul rl_txeof(sc); 137440516Swpaul if (status & RL_ISR_SYSTEM_ERR) { 137540516Swpaul rl_reset(sc); 1376131841Sbms rl_init_locked(sc); 137740516Swpaul } 137840516Swpaul } 137940516Swpaul 1380131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1381131841Sbms rl_start_locked(ifp); 1382131841Sbms 1383131841Sbmsdone_locked: 1384131606Sbms RL_UNLOCK(sc); 138540516Swpaul} 138640516Swpaul 138740516Swpaul/* 138840516Swpaul * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 138940516Swpaul * pointers to the fragment pointers. 139040516Swpaul */ 1391102335Salfredstatic int 1392131605Sbmsrl_encap(struct rl_softc *sc, struct mbuf *m_head) 139340516Swpaul{ 139441243Swpaul struct mbuf *m_new = NULL; 139540516Swpaul 1396131606Sbms RL_LOCK_ASSERT(sc); 1397131606Sbms 139840516Swpaul /* 139945633Swpaul * The RealTek is brain damaged and wants longword-aligned 140045633Swpaul * TX buffers, plus we can only have one fragment buffer 140145633Swpaul * per packet. We have to copy pretty much all the time. 140240516Swpaul */ 1403112839Ssilby m_new = m_defrag(m_head, M_DONTWAIT); 140440516Swpaul 1405113496Ssilby if (m_new == NULL) { 1406113496Ssilby m_freem(m_head); 1407131605Sbms return (1); 1408113496Ssilby } 140941243Swpaul m_head = m_new; 141040516Swpaul 141140516Swpaul /* Pad frames to at least 60 bytes. */ 141241243Swpaul if (m_head->m_pkthdr.len < RL_MIN_FRAMELEN) { 141355058Swpaul /* 141455058Swpaul * Make security concious people happy: zero out the 141555058Swpaul * bytes in the pad area, since we don't know what 141655058Swpaul * this mbuf cluster buffer's previous user might 141755058Swpaul * have left in it. 1418109109Sdes */ 141955058Swpaul bzero(mtod(m_head, char *) + m_head->m_pkthdr.len, 142055058Swpaul RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 142140516Swpaul m_head->m_pkthdr.len += 142252426Swpaul (RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 142341243Swpaul m_head->m_len = m_head->m_pkthdr.len; 142441243Swpaul } 142540516Swpaul 142645633Swpaul RL_CUR_TXMBUF(sc) = m_head; 142740516Swpaul 1428131605Sbms return (0); 142940516Swpaul} 143040516Swpaul 143140516Swpaul/* 143240516Swpaul * Main transmit routine. 143340516Swpaul */ 1434102335Salfredstatic void 1435131605Sbmsrl_start(struct ifnet *ifp) 143640516Swpaul{ 1437131605Sbms struct rl_softc *sc = ifp->if_softc; 143840516Swpaul 143967087Swpaul RL_LOCK(sc); 1440131841Sbms rl_start_locked(ifp); 1441131841Sbms RL_UNLOCK(sc); 1442131841Sbms} 144340516Swpaul 1444131841Sbmsstatic void 1445131841Sbmsrl_start_locked(struct ifnet *ifp) 1446131841Sbms{ 1447131841Sbms struct rl_softc *sc = ifp->if_softc; 1448131841Sbms struct mbuf *m_head = NULL; 1449131841Sbms 1450131841Sbms RL_LOCK_ASSERT(sc); 1451131841Sbms 1452131605Sbms while (RL_CUR_TXMBUF(sc) == NULL) { 1453131841Sbms 1454131455Smlaier IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); 1455131841Sbms 145640516Swpaul if (m_head == NULL) 145740516Swpaul break; 145840516Swpaul 1459131841Sbms if (rl_encap(sc, m_head)) 146058801Swpaul break; 146140516Swpaul 1462131605Sbms /* Pass a copy of this mbuf chain to the bpf subsystem. */ 1463106936Ssam BPF_MTAP(ifp, RL_CUR_TXMBUF(sc)); 146451583Swpaul 1465131605Sbms /* Transmit the frame. */ 146681713Swpaul bus_dmamap_create(sc->rl_tag, 0, &RL_CUR_DMAMAP(sc)); 146781713Swpaul bus_dmamap_load(sc->rl_tag, RL_CUR_DMAMAP(sc), 146881713Swpaul mtod(RL_CUR_TXMBUF(sc), void *), 1469119868Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len, rl_dma_map_txbuf, sc, 0); 147081713Swpaul bus_dmamap_sync(sc->rl_tag, RL_CUR_DMAMAP(sc), 147181713Swpaul BUS_DMASYNC_PREREAD); 147245633Swpaul CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc), 147352426Swpaul RL_TXTHRESH(sc->rl_txthresh) | 147452426Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len); 147545633Swpaul 147645633Swpaul RL_INC(sc->rl_cdata.cur_tx); 1477113237Ssilby 1478131605Sbms /* Set a timeout in case the chip goes out to lunch. */ 1479113237Ssilby ifp->if_timer = 5; 148040516Swpaul } 148140516Swpaul 148240516Swpaul /* 148345633Swpaul * We broke out of the loop because all our TX slots are 148445633Swpaul * full. Mark the NIC as busy until it drains some of the 148545633Swpaul * packets from the queue. 148645633Swpaul */ 148745633Swpaul if (RL_CUR_TXMBUF(sc) != NULL) 148845633Swpaul ifp->if_flags |= IFF_OACTIVE; 1489131841Sbms} 149045633Swpaul 1491131841Sbmsstatic void 1492131841Sbmsrl_init(void *xsc) 1493131841Sbms{ 1494131841Sbms struct rl_softc *sc = xsc; 1495131841Sbms 1496131841Sbms RL_LOCK(sc); 1497131841Sbms rl_init_locked(sc); 149867087Swpaul RL_UNLOCK(sc); 149940516Swpaul} 150040516Swpaul 1501102335Salfredstatic void 1502131841Sbmsrl_init_locked(struct rl_softc *sc) 150340516Swpaul{ 150440516Swpaul struct ifnet *ifp = &sc->arpcom.ac_if; 150550703Swpaul struct mii_data *mii; 1506131605Sbms uint32_t rxcfg = 0; 150740516Swpaul 1508131841Sbms RL_LOCK_ASSERT(sc); 1509131841Sbms 151050703Swpaul mii = device_get_softc(sc->rl_miibus); 151140516Swpaul 151240516Swpaul /* 151340516Swpaul * Cancel pending I/O and free all RX/TX buffers. 151440516Swpaul */ 151540516Swpaul rl_stop(sc); 151640516Swpaul 1517117029Swpaul /* 1518117029Swpaul * Init our MAC address. Even though the chipset 1519117029Swpaul * documentation doesn't mention it, we need to enter "Config 1520117029Swpaul * register write enable" mode to modify the ID registers. 1521117029Swpaul */ 1522117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG); 1523119738Stmm CSR_WRITE_STREAM_4(sc, RL_IDR0, 1524131605Sbms *(uint32_t *)(&sc->arpcom.ac_enaddr[0])); 1525119738Stmm CSR_WRITE_STREAM_4(sc, RL_IDR4, 1526131605Sbms *(uint32_t *)(&sc->arpcom.ac_enaddr[4])); 1527117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 152840516Swpaul 1529119868Swpaul /* Init the RX buffer pointer register. */ 1530119868Swpaul bus_dmamap_load(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1531119868Swpaul sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN, rl_dma_map_rxbuf, sc, 0); 1532119868Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1533119868Swpaul BUS_DMASYNC_PREWRITE); 153440516Swpaul 1535119868Swpaul /* Init TX descriptors. */ 1536119868Swpaul rl_list_tx_init(sc); 153740516Swpaul 153840516Swpaul /* 153940516Swpaul * Enable transmit and receive. 154040516Swpaul */ 154140516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 154240516Swpaul 154340516Swpaul /* 154445633Swpaul * Set the initial TX and RX configuration. 154540516Swpaul */ 154645633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 154740516Swpaul CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); 154840516Swpaul 154940516Swpaul /* Set the individual bit to receive frames for this host only. */ 155040516Swpaul rxcfg = CSR_READ_4(sc, RL_RXCFG); 155140516Swpaul rxcfg |= RL_RXCFG_RX_INDIV; 155240516Swpaul 155340516Swpaul /* If we want promiscuous mode, set the allframes bit. */ 155440516Swpaul if (ifp->if_flags & IFF_PROMISC) { 155540516Swpaul rxcfg |= RL_RXCFG_RX_ALLPHYS; 155640516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 155740516Swpaul } else { 155840516Swpaul rxcfg &= ~RL_RXCFG_RX_ALLPHYS; 155940516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 156040516Swpaul } 156140516Swpaul 1562131605Sbms /* Set capture broadcast bit to capture broadcast frames. */ 156340516Swpaul if (ifp->if_flags & IFF_BROADCAST) { 156440516Swpaul rxcfg |= RL_RXCFG_RX_BROAD; 156540516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 156640516Swpaul } else { 156740516Swpaul rxcfg &= ~RL_RXCFG_RX_BROAD; 156840516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 156940516Swpaul } 157040516Swpaul 1571131605Sbms /* Program the multicast filter, if necessary. */ 157240516Swpaul rl_setmulti(sc); 157340516Swpaul 157494883Sluigi#ifdef DEVICE_POLLING 1575131605Sbms /* Disable interrupts if we are polling. */ 1576102052Ssobomax if (ifp->if_flags & IFF_POLLING) 157794883Sluigi CSR_WRITE_2(sc, RL_IMR, 0); 1578131605Sbms else 157994883Sluigi#endif /* DEVICE_POLLING */ 1580131605Sbms /* Enable interrupts. */ 1581119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 158240516Swpaul 158352426Swpaul /* Set initial TX threshold */ 158452426Swpaul sc->rl_txthresh = RL_TX_THRESH_INIT; 158552426Swpaul 158640516Swpaul /* Start RX/TX process. */ 158740516Swpaul CSR_WRITE_4(sc, RL_MISSEDPKT, 0); 1588119868Swpaul 158940516Swpaul /* Enable receiver and transmitter. */ 159040516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 159140516Swpaul 159250703Swpaul mii_mediachg(mii); 159340516Swpaul 159440516Swpaul CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); 159540516Swpaul 159640516Swpaul ifp->if_flags |= IFF_RUNNING; 159740516Swpaul ifp->if_flags &= ~IFF_OACTIVE; 159840516Swpaul 159950703Swpaul sc->rl_stat_ch = timeout(rl_tick, sc, hz); 160040516Swpaul} 160140516Swpaul 160240516Swpaul/* 160340516Swpaul * Set media options. 160440516Swpaul */ 1605102335Salfredstatic int 1606131605Sbmsrl_ifmedia_upd(struct ifnet *ifp) 160740516Swpaul{ 1608131605Sbms struct rl_softc *sc = ifp->if_softc; 160950703Swpaul struct mii_data *mii; 161040516Swpaul 161150703Swpaul mii = device_get_softc(sc->rl_miibus); 1612131605Sbms 161350703Swpaul mii_mediachg(mii); 161440516Swpaul 1615131605Sbms return (0); 161640516Swpaul} 161740516Swpaul 161840516Swpaul/* 161940516Swpaul * Report current media status. 162040516Swpaul */ 1621102335Salfredstatic void 1622131605Sbmsrl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 162340516Swpaul{ 1624131605Sbms struct rl_softc *sc = ifp->if_softc; 162550703Swpaul struct mii_data *mii; 162640516Swpaul 162750703Swpaul mii = device_get_softc(sc->rl_miibus); 162840516Swpaul 162950703Swpaul mii_pollstat(mii); 163050703Swpaul ifmr->ifm_active = mii->mii_media_active; 163150703Swpaul ifmr->ifm_status = mii->mii_media_status; 163240516Swpaul} 163340516Swpaul 1634102335Salfredstatic int 1635131605Sbmsrl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 163640516Swpaul{ 1637131605Sbms struct ifreq *ifr = (struct ifreq *)data; 1638131605Sbms struct mii_data *mii; 163940516Swpaul struct rl_softc *sc = ifp->if_softc; 164067087Swpaul int error = 0; 164140516Swpaul 1642131605Sbms switch (command) { 164340516Swpaul case SIOCSIFFLAGS: 1644131841Sbms RL_LOCK(sc); 164540516Swpaul if (ifp->if_flags & IFF_UP) { 1646131841Sbms rl_init_locked(sc); 164740516Swpaul } else { 164840516Swpaul if (ifp->if_flags & IFF_RUNNING) 164940516Swpaul rl_stop(sc); 165040516Swpaul } 1651131841Sbms RL_UNLOCK(sc); 165240516Swpaul error = 0; 165340516Swpaul break; 165440516Swpaul case SIOCADDMULTI: 165540516Swpaul case SIOCDELMULTI: 1656131606Sbms RL_LOCK(sc); 165740516Swpaul rl_setmulti(sc); 1658131606Sbms RL_UNLOCK(sc); 165940516Swpaul error = 0; 166040516Swpaul break; 166140516Swpaul case SIOCGIFMEDIA: 166240516Swpaul case SIOCSIFMEDIA: 166350703Swpaul mii = device_get_softc(sc->rl_miibus); 166450703Swpaul error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 166540516Swpaul break; 1666128121Sru case SIOCSIFCAP: 1667129633Syar ifp->if_capenable &= ~IFCAP_POLLING; 1668129633Syar ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING; 1669128121Sru break; 167040516Swpaul default: 1671106936Ssam error = ether_ioctl(ifp, command, data); 167240516Swpaul break; 167340516Swpaul } 167440516Swpaul 1675131605Sbms return (error); 167640516Swpaul} 167740516Swpaul 1678102335Salfredstatic void 1679131605Sbmsrl_watchdog(struct ifnet *ifp) 168040516Swpaul{ 1681131605Sbms struct rl_softc *sc = ifp->if_softc; 168240516Swpaul 168367087Swpaul RL_LOCK(sc); 1684131605Sbms 1685131605Sbms if_printf(ifp, "watchdog timeout\n"); 168640516Swpaul ifp->if_oerrors++; 168750703Swpaul 1688119868Swpaul rl_txeof(sc); 1689119868Swpaul rl_rxeof(sc); 1690131841Sbms rl_init_locked(sc); 1691131605Sbms 169267087Swpaul RL_UNLOCK(sc); 169340516Swpaul} 169440516Swpaul 169540516Swpaul/* 169640516Swpaul * Stop the adapter and free any mbufs allocated to the 169740516Swpaul * RX and TX lists. 169840516Swpaul */ 1699102335Salfredstatic void 1700131605Sbmsrl_stop(struct rl_softc *sc) 170140516Swpaul{ 170240516Swpaul register int i; 1703131605Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 170440516Swpaul 1705131606Sbms RL_LOCK_ASSERT(sc); 1706131606Sbms 170740516Swpaul ifp->if_timer = 0; 170850703Swpaul untimeout(rl_tick, sc, sc->rl_stat_ch); 170994883Sluigi ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 171094883Sluigi#ifdef DEVICE_POLLING 171194883Sluigi ether_poll_deregister(ifp); 171294883Sluigi#endif /* DEVICE_POLLING */ 171350703Swpaul 171440516Swpaul CSR_WRITE_1(sc, RL_COMMAND, 0x00); 171540516Swpaul CSR_WRITE_2(sc, RL_IMR, 0x0000); 1716119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 171740516Swpaul 1718119868Swpaul /* 1719119868Swpaul * Free the TX list buffers. 1720119868Swpaul */ 1721119868Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 1722119868Swpaul if (sc->rl_cdata.rl_tx_chain[i] != NULL) { 1723119868Swpaul bus_dmamap_unload(sc->rl_tag, 1724119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1725119868Swpaul bus_dmamap_destroy(sc->rl_tag, 1726119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1727119868Swpaul m_freem(sc->rl_cdata.rl_tx_chain[i]); 1728119868Swpaul sc->rl_cdata.rl_tx_chain[i] = NULL; 1729131605Sbms CSR_WRITE_4(sc, RL_TXADDR0 + (i * sizeof(uint32_t)), 1730124816Swpaul 0x0000000); 173140516Swpaul } 173240516Swpaul } 173340516Swpaul} 173440516Swpaul 173540516Swpaul/* 173686822Siwasaki * Device suspend routine. Stop the interface and save some PCI 173786822Siwasaki * settings in case the BIOS doesn't restore them properly on 173886822Siwasaki * resume. 173986822Siwasaki */ 1740102335Salfredstatic int 1741131605Sbmsrl_suspend(device_t dev) 174286822Siwasaki{ 174386822Siwasaki struct rl_softc *sc; 174486822Siwasaki 174586822Siwasaki sc = device_get_softc(dev); 1746131606Sbms 1747131606Sbms RL_LOCK(sc); 174886822Siwasaki rl_stop(sc); 174986822Siwasaki sc->suspended = 1; 1750131606Sbms RL_UNLOCK(sc); 175186822Siwasaki 175286822Siwasaki return (0); 175386822Siwasaki} 175486822Siwasaki 175586822Siwasaki/* 175686822Siwasaki * Device resume routine. Restore some PCI settings in case the BIOS 175786822Siwasaki * doesn't, re-enable busmastering, and restart the interface if 175886822Siwasaki * appropriate. 175986822Siwasaki */ 1760102335Salfredstatic int 1761131605Sbmsrl_resume(device_t dev) 176286822Siwasaki{ 176386822Siwasaki struct rl_softc *sc; 176486822Siwasaki struct ifnet *ifp; 176586822Siwasaki 176686822Siwasaki sc = device_get_softc(dev); 176786822Siwasaki ifp = &sc->arpcom.ac_if; 176886822Siwasaki 1769131841Sbms RL_LOCK(sc); 1770131841Sbms 1771109109Sdes /* reinitialize interface if necessary */ 1772109109Sdes if (ifp->if_flags & IFF_UP) 1773131841Sbms rl_init_locked(sc); 177486822Siwasaki 177586822Siwasaki sc->suspended = 0; 1776131841Sbms 1777131606Sbms RL_UNLOCK(sc); 177886822Siwasaki 177986822Siwasaki return (0); 178086822Siwasaki} 178186822Siwasaki 178286822Siwasaki/* 178340516Swpaul * Stop all chip I/O so that the kernel's probe routines don't 178440516Swpaul * get confused by errant DMAs when rebooting. 178540516Swpaul */ 1786102335Salfredstatic void 1787131605Sbmsrl_shutdown(device_t dev) 178840516Swpaul{ 178950703Swpaul struct rl_softc *sc; 179040516Swpaul 179150703Swpaul sc = device_get_softc(dev); 1792131606Sbms 1793131606Sbms RL_LOCK(sc); 179440516Swpaul rl_stop(sc); 1795131606Sbms RL_UNLOCK(sc); 179640516Swpaul} 1797