if_rl.c revision 139825
1139825Simp/*- 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 139825 2005-01-07 02:29:27Z imp $"); 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; 1004133403Sgreen int attached; 100550703Swpaul 100650703Swpaul sc = device_get_softc(dev); 1007131605Sbms ifp = &sc->arpcom.ac_if; 1008131605Sbms 1009112880Sjhb KASSERT(mtx_initialized(&sc->rl_mtx), ("rl mutex not initialized")); 1010133403Sgreen attached = device_is_attached(dev); 1011133403Sgreen /* These should only be active if attach succeeded */ 1012133403Sgreen if (attached) 1013133403Sgreen ether_ifdetach(ifp); 101467087Swpaul RL_LOCK(sc); 1015131606Sbms#if 0 1016131606Sbms sc->suspended = 1; 1017131606Sbms#endif 1018133403Sgreen if (attached) 1019113609Snjl rl_stop(sc); 1020113609Snjl if (sc->rl_miibus) 1021112872Snjl device_delete_child(dev, sc->rl_miibus); 1022113609Snjl bus_generic_detach(dev); 102350703Swpaul 1024112872Snjl if (sc->rl_intrhand) 1025112872Snjl bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand); 1026112872Snjl if (sc->rl_irq) 1027112872Snjl bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1028112872Snjl if (sc->rl_res) 1029112872Snjl bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 103050703Swpaul 1031119868Swpaul if (sc->rl_tag) { 1032119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 1033119868Swpaul bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf, 1034119868Swpaul sc->rl_cdata.rl_rx_dmamap); 1035119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 1036112872Snjl } 1037112872Snjl if (sc->rl_parent_tag) 1038112872Snjl bus_dma_tag_destroy(sc->rl_parent_tag); 103950703Swpaul 104067087Swpaul RL_UNLOCK(sc); 104167087Swpaul mtx_destroy(&sc->rl_mtx); 104250703Swpaul 1043131605Sbms return (0); 104450703Swpaul} 104550703Swpaul 104640516Swpaul/* 104740516Swpaul * Initialize the transmit descriptors. 104840516Swpaul */ 1049102335Salfredstatic int 1050131605Sbmsrl_list_tx_init(struct rl_softc *sc) 105140516Swpaul{ 105240516Swpaul struct rl_chain_data *cd; 105340516Swpaul int i; 105440516Swpaul 1055131606Sbms RL_LOCK_ASSERT(sc); 1056131606Sbms 105740516Swpaul cd = &sc->rl_cdata; 105840516Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 105945633Swpaul cd->rl_tx_chain[i] = NULL; 106048028Swpaul CSR_WRITE_4(sc, 1061131605Sbms RL_TXADDR0 + (i * sizeof(uint32_t)), 0x0000000); 106240516Swpaul } 106340516Swpaul 106445633Swpaul sc->rl_cdata.cur_tx = 0; 106545633Swpaul sc->rl_cdata.last_tx = 0; 106640516Swpaul 1067131605Sbms return (0); 106840516Swpaul} 106940516Swpaul 107040516Swpaul/* 107140516Swpaul * A frame has been uploaded: pass the resulting mbuf chain up to 107240516Swpaul * the higher level protocols. 107340516Swpaul * 107440516Swpaul * You know there's something wrong with a PCI bus-master chip design 107540516Swpaul * when you have to use m_devget(). 107640516Swpaul * 107740516Swpaul * The receive operation is badly documented in the datasheet, so I'll 107840516Swpaul * attempt to document it here. The driver provides a buffer area and 107940516Swpaul * places its base address in the RX buffer start address register. 108040516Swpaul * The chip then begins copying frames into the RX buffer. Each frame 108172645Sasmodai * is preceded by a 32-bit RX status word which specifies the length 108240516Swpaul * of the frame and certain other status bits. Each frame (starting with 108340516Swpaul * the status word) is also 32-bit aligned. The frame length is in the 108440516Swpaul * first 16 bits of the status word; the lower 15 bits correspond with 108540516Swpaul * the 'rx status register' mentioned in the datasheet. 108648028Swpaul * 108748028Swpaul * Note: to make the Alpha happy, the frame payload needs to be aligned 108878508Sbmilekic * on a 32-bit boundary. To achieve this, we pass RL_ETHER_ALIGN (2 bytes) 1089109109Sdes * as the offset argument to m_devget(). 109040516Swpaul */ 1091102335Salfredstatic void 1092131605Sbmsrl_rxeof(struct rl_softc *sc) 109340516Swpaul{ 1094109109Sdes struct mbuf *m; 1095131605Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 1096131605Sbms uint8_t *rxbufpos; 109740516Swpaul int total_len = 0; 109840516Swpaul int wrap = 0; 1099131605Sbms uint32_t rxstat; 1100131605Sbms uint16_t cur_rx; 1101131605Sbms uint16_t limit; 1102131605Sbms uint16_t max_bytes, rx_bytes = 0; 110340516Swpaul 1104122689Ssam RL_LOCK_ASSERT(sc); 1105122689Ssam 110681713Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1107108729Sjake BUS_DMASYNC_POSTREAD); 110881713Swpaul 110940516Swpaul cur_rx = (CSR_READ_2(sc, RL_CURRXADDR) + 16) % RL_RXBUFLEN; 111040516Swpaul 111140516Swpaul /* Do not try to read past this point. */ 111240516Swpaul limit = CSR_READ_2(sc, RL_CURRXBUF) % RL_RXBUFLEN; 111340516Swpaul 111440516Swpaul if (limit < cur_rx) 111540516Swpaul max_bytes = (RL_RXBUFLEN - cur_rx) + limit; 111640516Swpaul else 111740516Swpaul max_bytes = limit - cur_rx; 111840516Swpaul 111942738Swpaul while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) { 112094883Sluigi#ifdef DEVICE_POLLING 1121102052Ssobomax if (ifp->if_flags & IFF_POLLING) { 112294883Sluigi if (sc->rxcycles <= 0) 112394883Sluigi break; 112494883Sluigi sc->rxcycles--; 112594883Sluigi } 112694883Sluigi#endif /* DEVICE_POLLING */ 112740516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx; 1128131605Sbms rxstat = le32toh(*(uint32_t *)rxbufpos); 112940516Swpaul 113040516Swpaul /* 113140516Swpaul * Here's a totally undocumented fact for you. When the 113240516Swpaul * RealTek chip is in the process of copying a packet into 113340516Swpaul * RAM for you, the length will be 0xfff0. If you spot a 113440516Swpaul * packet header with this value, you need to stop. The 113540516Swpaul * datasheet makes absolutely no mention of this and 113640516Swpaul * RealTek should be shot for this. 113740516Swpaul */ 1138131605Sbms if ((uint16_t)(rxstat >> 16) == RL_RXSTAT_UNFINISHED) 113940516Swpaul break; 1140109109Sdes 114140516Swpaul if (!(rxstat & RL_RXSTAT_RXOK)) { 114240516Swpaul ifp->if_ierrors++; 1143131841Sbms rl_init_locked(sc); 114450703Swpaul return; 114540516Swpaul } 114640516Swpaul 1147109109Sdes /* No errors; receive the packet. */ 114840516Swpaul total_len = rxstat >> 16; 114940516Swpaul rx_bytes += total_len + 4; 115040516Swpaul 115140516Swpaul /* 115242051Swpaul * XXX The RealTek chip includes the CRC with every 115342051Swpaul * received frame, and there's no way to turn this 115442051Swpaul * behavior off (at least, I can't find anything in 1155109109Sdes * the manual that explains how to do it) so we have 115642051Swpaul * to trim off the CRC manually. 115742051Swpaul */ 115842051Swpaul total_len -= ETHER_CRC_LEN; 115942051Swpaul 116042051Swpaul /* 116140516Swpaul * Avoid trying to read more bytes than we know 116240516Swpaul * the chip has prepared for us. 116340516Swpaul */ 116440516Swpaul if (rx_bytes > max_bytes) 116540516Swpaul break; 116640516Swpaul 116740516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + 1168131605Sbms ((cur_rx + sizeof(uint32_t)) % RL_RXBUFLEN); 116940516Swpaul if (rxbufpos == (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN)) 117040516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf; 117140516Swpaul 117240516Swpaul wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos; 117340516Swpaul if (total_len > wrap) { 117478508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 117578508Sbmilekic NULL); 117640516Swpaul if (m == NULL) { 117740516Swpaul ifp->if_ierrors++; 117852426Swpaul } else { 117940516Swpaul m_copyback(m, wrap, total_len - wrap, 118040516Swpaul sc->rl_cdata.rl_rx_buf); 118148028Swpaul } 118242051Swpaul cur_rx = (total_len - wrap + ETHER_CRC_LEN); 118340516Swpaul } else { 118478508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 118578508Sbmilekic NULL); 1186131605Sbms if (m == NULL) 118740516Swpaul ifp->if_ierrors++; 118842051Swpaul cur_rx += total_len + 4 + ETHER_CRC_LEN; 118940516Swpaul } 119040516Swpaul 1191131605Sbms /* Round up to 32-bit boundary. */ 119240516Swpaul cur_rx = (cur_rx + 3) & ~3; 119340516Swpaul CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16); 119440516Swpaul 119540516Swpaul if (m == NULL) 119640516Swpaul continue; 119740516Swpaul 119840516Swpaul ifp->if_ipackets++; 1199122689Ssam RL_UNLOCK(sc); 1200106936Ssam (*ifp->if_input)(ifp, m); 1201122689Ssam RL_LOCK(sc); 120240516Swpaul } 120340516Swpaul} 120440516Swpaul 120540516Swpaul/* 120640516Swpaul * A frame was downloaded to the chip. It's safe for us to clean up 120740516Swpaul * the list buffers. 120840516Swpaul */ 1209102335Salfredstatic void 1210131605Sbmsrl_txeof(struct rl_softc *sc) 121140516Swpaul{ 1212131605Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 1213131605Sbms uint32_t txstat; 121440516Swpaul 1215131606Sbms RL_LOCK_ASSERT(sc); 1216131606Sbms 121740516Swpaul /* 121840516Swpaul * Go through our tx list and free mbufs for those 121940516Swpaul * frames that have been uploaded. 122040516Swpaul */ 122145633Swpaul do { 1222127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1223127783Sru break; 122445633Swpaul txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc)); 122545633Swpaul if (!(txstat & (RL_TXSTAT_TX_OK| 122645633Swpaul RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT))) 122740516Swpaul break; 122840516Swpaul 122945633Swpaul ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24; 123040516Swpaul 1231127783Sru bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1232127783Sru bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1233127783Sru m_freem(RL_LAST_TXMBUF(sc)); 1234127783Sru RL_LAST_TXMBUF(sc) = NULL; 123545633Swpaul if (txstat & RL_TXSTAT_TX_OK) 123645633Swpaul ifp->if_opackets++; 123745633Swpaul else { 123852426Swpaul int oldthresh; 123945633Swpaul ifp->if_oerrors++; 124045633Swpaul if ((txstat & RL_TXSTAT_TXABRT) || 124145633Swpaul (txstat & RL_TXSTAT_OUTOFWIN)) 124245633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 124352426Swpaul oldthresh = sc->rl_txthresh; 124452426Swpaul /* error recovery */ 124552426Swpaul rl_reset(sc); 1246131841Sbms rl_init_locked(sc); 124752426Swpaul /* 124852426Swpaul * If there was a transmit underrun, 124952426Swpaul * bump the TX threshold. 125052426Swpaul */ 125152426Swpaul if (txstat & RL_TXSTAT_TX_UNDERRUN) 125252426Swpaul sc->rl_txthresh = oldthresh + 32; 125352426Swpaul return; 125445633Swpaul } 125545633Swpaul RL_INC(sc->rl_cdata.last_tx); 125645633Swpaul ifp->if_flags &= ~IFF_OACTIVE; 125745633Swpaul } while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx); 125840516Swpaul 1259127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1260127783Sru ifp->if_timer = 0; 1261127783Sru else if (ifp->if_timer == 0) 1262127783Sru ifp->if_timer = 5; 126350703Swpaul} 126440516Swpaul 1265102335Salfredstatic void 1266131605Sbmsrl_tick(void *xsc) 126750703Swpaul{ 1268131605Sbms struct rl_softc *sc = xsc; 126950703Swpaul struct mii_data *mii; 127050703Swpaul 127167087Swpaul RL_LOCK(sc); 127250703Swpaul mii = device_get_softc(sc->rl_miibus); 127350703Swpaul mii_tick(mii); 127450703Swpaul 127550703Swpaul sc->rl_stat_ch = timeout(rl_tick, sc, hz); 127667087Swpaul RL_UNLOCK(sc); 127740516Swpaul} 127840516Swpaul 127994883Sluigi#ifdef DEVICE_POLLING 128094883Sluigistatic void 1281131841Sbmsrl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 128294883Sluigi{ 128394883Sluigi struct rl_softc *sc = ifp->if_softc; 128494883Sluigi 128594883Sluigi RL_LOCK(sc); 1286131841Sbms rl_poll_locked(ifp, cmd, count); 1287131841Sbms RL_UNLOCK(sc); 1288131841Sbms} 1289131605Sbms 1290131841Sbmsstatic void 1291131841Sbmsrl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) 1292131841Sbms{ 1293131841Sbms struct rl_softc *sc = ifp->if_softc; 1294131841Sbms 1295131841Sbms RL_LOCK_ASSERT(sc); 1296131841Sbms 1297128121Sru if (!(ifp->if_capenable & IFCAP_POLLING)) { 1298128121Sru ether_poll_deregister(ifp); 1299128121Sru cmd = POLL_DEREGISTER; 1300128121Sru } 1301131605Sbms 1302131605Sbms if (cmd == POLL_DEREGISTER) { 1303131605Sbms /* Final call; enable interrupts. */ 1304119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 1305131841Sbms return; 130694883Sluigi } 130794883Sluigi 130894883Sluigi sc->rxcycles = count; 1309119868Swpaul rl_rxeof(sc); 1310119868Swpaul rl_txeof(sc); 1311131605Sbms 1312131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1313131841Sbms rl_start_locked(ifp); 131494883Sluigi 1315131605Sbms if (cmd == POLL_AND_CHECK_STATUS) { 1316131605Sbms uint16_t status; 131794883Sluigi 1318131605Sbms /* We should also check the status register. */ 131994883Sluigi status = CSR_READ_2(sc, RL_ISR); 1320100957Sjhb if (status == 0xffff) 1321131841Sbms return; 1322131605Sbms if (status != 0) 132394883Sluigi CSR_WRITE_2(sc, RL_ISR, status); 132494883Sluigi 1325131605Sbms /* XXX We should check behaviour on receiver stalls. */ 132694883Sluigi 132794883Sluigi if (status & RL_ISR_SYSTEM_ERR) { 132894883Sluigi rl_reset(sc); 1329131841Sbms rl_init_locked(sc); 133094883Sluigi } 133194883Sluigi } 133294883Sluigi} 133394883Sluigi#endif /* DEVICE_POLLING */ 133494883Sluigi 1335102335Salfredstatic void 1336131605Sbmsrl_intr(void *arg) 133740516Swpaul{ 1338131605Sbms struct rl_softc *sc = arg; 1339131606Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 1340131605Sbms uint16_t status; 134140516Swpaul 1342131606Sbms RL_LOCK(sc); 1343131606Sbms 1344131841Sbms if (sc->suspended) 1345131841Sbms goto done_locked; 134686822Siwasaki 134794883Sluigi#ifdef DEVICE_POLLING 1348131841Sbms if (ifp->if_flags & IFF_POLLING) 1349131841Sbms goto done_locked; 1350131841Sbms 1351128121Sru if ((ifp->if_capenable & IFCAP_POLLING) && 1352131605Sbms ether_poll_register(rl_poll, ifp)) { 1353131605Sbms /* Disable interrupts. */ 135494883Sluigi CSR_WRITE_2(sc, RL_IMR, 0x0000); 1355131841Sbms rl_poll_locked(ifp, 0, 1); 1356131841Sbms goto done_locked; 135794883Sluigi } 135894883Sluigi#endif /* DEVICE_POLLING */ 135940516Swpaul 136040516Swpaul for (;;) { 136140516Swpaul status = CSR_READ_2(sc, RL_ISR); 1362131605Sbms /* If the card has gone away, the read returns 0xffff. */ 1363100957Sjhb if (status == 0xffff) 1364100957Sjhb break; 1365131605Sbms if (status != 0) 136640516Swpaul CSR_WRITE_2(sc, RL_ISR, status); 136740516Swpaul if ((status & RL_INTRS) == 0) 136840516Swpaul break; 136940516Swpaul if (status & RL_ISR_RX_OK) 137040516Swpaul rl_rxeof(sc); 137140516Swpaul if (status & RL_ISR_RX_ERR) 137240516Swpaul rl_rxeof(sc); 137345633Swpaul if ((status & RL_ISR_TX_OK) || (status & RL_ISR_TX_ERR)) 137440516Swpaul rl_txeof(sc); 137540516Swpaul if (status & RL_ISR_SYSTEM_ERR) { 137640516Swpaul rl_reset(sc); 1377131841Sbms rl_init_locked(sc); 137840516Swpaul } 137940516Swpaul } 138040516Swpaul 1381131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1382131841Sbms rl_start_locked(ifp); 1383131841Sbms 1384131841Sbmsdone_locked: 1385131606Sbms RL_UNLOCK(sc); 138640516Swpaul} 138740516Swpaul 138840516Swpaul/* 138940516Swpaul * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 139040516Swpaul * pointers to the fragment pointers. 139140516Swpaul */ 1392102335Salfredstatic int 1393131605Sbmsrl_encap(struct rl_softc *sc, struct mbuf *m_head) 139440516Swpaul{ 139541243Swpaul struct mbuf *m_new = NULL; 139640516Swpaul 1397131606Sbms RL_LOCK_ASSERT(sc); 1398131606Sbms 139940516Swpaul /* 140045633Swpaul * The RealTek is brain damaged and wants longword-aligned 140145633Swpaul * TX buffers, plus we can only have one fragment buffer 140245633Swpaul * per packet. We have to copy pretty much all the time. 140340516Swpaul */ 1404112839Ssilby m_new = m_defrag(m_head, M_DONTWAIT); 140540516Swpaul 1406113496Ssilby if (m_new == NULL) { 1407113496Ssilby m_freem(m_head); 1408131605Sbms return (1); 1409113496Ssilby } 141041243Swpaul m_head = m_new; 141140516Swpaul 141240516Swpaul /* Pad frames to at least 60 bytes. */ 141341243Swpaul if (m_head->m_pkthdr.len < RL_MIN_FRAMELEN) { 141455058Swpaul /* 141555058Swpaul * Make security concious people happy: zero out the 141655058Swpaul * bytes in the pad area, since we don't know what 141755058Swpaul * this mbuf cluster buffer's previous user might 141855058Swpaul * have left in it. 1419109109Sdes */ 142055058Swpaul bzero(mtod(m_head, char *) + m_head->m_pkthdr.len, 142155058Swpaul RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 142240516Swpaul m_head->m_pkthdr.len += 142352426Swpaul (RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 142441243Swpaul m_head->m_len = m_head->m_pkthdr.len; 142541243Swpaul } 142640516Swpaul 142745633Swpaul RL_CUR_TXMBUF(sc) = m_head; 142840516Swpaul 1429131605Sbms return (0); 143040516Swpaul} 143140516Swpaul 143240516Swpaul/* 143340516Swpaul * Main transmit routine. 143440516Swpaul */ 1435102335Salfredstatic void 1436131605Sbmsrl_start(struct ifnet *ifp) 143740516Swpaul{ 1438131605Sbms struct rl_softc *sc = ifp->if_softc; 143940516Swpaul 144067087Swpaul RL_LOCK(sc); 1441131841Sbms rl_start_locked(ifp); 1442131841Sbms RL_UNLOCK(sc); 1443131841Sbms} 144440516Swpaul 1445131841Sbmsstatic void 1446131841Sbmsrl_start_locked(struct ifnet *ifp) 1447131841Sbms{ 1448131841Sbms struct rl_softc *sc = ifp->if_softc; 1449131841Sbms struct mbuf *m_head = NULL; 1450131841Sbms 1451131841Sbms RL_LOCK_ASSERT(sc); 1452131841Sbms 1453131605Sbms while (RL_CUR_TXMBUF(sc) == NULL) { 1454131841Sbms 1455131455Smlaier IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); 1456131841Sbms 145740516Swpaul if (m_head == NULL) 145840516Swpaul break; 145940516Swpaul 1460131841Sbms if (rl_encap(sc, m_head)) 146158801Swpaul break; 146240516Swpaul 1463131605Sbms /* Pass a copy of this mbuf chain to the bpf subsystem. */ 1464106936Ssam BPF_MTAP(ifp, RL_CUR_TXMBUF(sc)); 146551583Swpaul 1466131605Sbms /* Transmit the frame. */ 146781713Swpaul bus_dmamap_create(sc->rl_tag, 0, &RL_CUR_DMAMAP(sc)); 146881713Swpaul bus_dmamap_load(sc->rl_tag, RL_CUR_DMAMAP(sc), 146981713Swpaul mtod(RL_CUR_TXMBUF(sc), void *), 1470119868Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len, rl_dma_map_txbuf, sc, 0); 147181713Swpaul bus_dmamap_sync(sc->rl_tag, RL_CUR_DMAMAP(sc), 147281713Swpaul BUS_DMASYNC_PREREAD); 147345633Swpaul CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc), 147452426Swpaul RL_TXTHRESH(sc->rl_txthresh) | 147552426Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len); 147645633Swpaul 147745633Swpaul RL_INC(sc->rl_cdata.cur_tx); 1478113237Ssilby 1479131605Sbms /* Set a timeout in case the chip goes out to lunch. */ 1480113237Ssilby ifp->if_timer = 5; 148140516Swpaul } 148240516Swpaul 148340516Swpaul /* 148445633Swpaul * We broke out of the loop because all our TX slots are 148545633Swpaul * full. Mark the NIC as busy until it drains some of the 148645633Swpaul * packets from the queue. 148745633Swpaul */ 148845633Swpaul if (RL_CUR_TXMBUF(sc) != NULL) 148945633Swpaul ifp->if_flags |= IFF_OACTIVE; 1490131841Sbms} 149145633Swpaul 1492131841Sbmsstatic void 1493131841Sbmsrl_init(void *xsc) 1494131841Sbms{ 1495131841Sbms struct rl_softc *sc = xsc; 1496131841Sbms 1497131841Sbms RL_LOCK(sc); 1498131841Sbms rl_init_locked(sc); 149967087Swpaul RL_UNLOCK(sc); 150040516Swpaul} 150140516Swpaul 1502102335Salfredstatic void 1503131841Sbmsrl_init_locked(struct rl_softc *sc) 150440516Swpaul{ 150540516Swpaul struct ifnet *ifp = &sc->arpcom.ac_if; 150650703Swpaul struct mii_data *mii; 1507131605Sbms uint32_t rxcfg = 0; 150840516Swpaul 1509131841Sbms RL_LOCK_ASSERT(sc); 1510131841Sbms 151150703Swpaul mii = device_get_softc(sc->rl_miibus); 151240516Swpaul 151340516Swpaul /* 151440516Swpaul * Cancel pending I/O and free all RX/TX buffers. 151540516Swpaul */ 151640516Swpaul rl_stop(sc); 151740516Swpaul 1518117029Swpaul /* 1519117029Swpaul * Init our MAC address. Even though the chipset 1520117029Swpaul * documentation doesn't mention it, we need to enter "Config 1521117029Swpaul * register write enable" mode to modify the ID registers. 1522117029Swpaul */ 1523117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG); 1524119738Stmm CSR_WRITE_STREAM_4(sc, RL_IDR0, 1525131605Sbms *(uint32_t *)(&sc->arpcom.ac_enaddr[0])); 1526119738Stmm CSR_WRITE_STREAM_4(sc, RL_IDR4, 1527131605Sbms *(uint32_t *)(&sc->arpcom.ac_enaddr[4])); 1528117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 152940516Swpaul 1530119868Swpaul /* Init the RX buffer pointer register. */ 1531119868Swpaul bus_dmamap_load(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1532119868Swpaul sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN, rl_dma_map_rxbuf, sc, 0); 1533119868Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1534119868Swpaul BUS_DMASYNC_PREWRITE); 153540516Swpaul 1536119868Swpaul /* Init TX descriptors. */ 1537119868Swpaul rl_list_tx_init(sc); 153840516Swpaul 153940516Swpaul /* 154040516Swpaul * Enable transmit and receive. 154140516Swpaul */ 154240516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 154340516Swpaul 154440516Swpaul /* 154545633Swpaul * Set the initial TX and RX configuration. 154640516Swpaul */ 154745633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 154840516Swpaul CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); 154940516Swpaul 155040516Swpaul /* Set the individual bit to receive frames for this host only. */ 155140516Swpaul rxcfg = CSR_READ_4(sc, RL_RXCFG); 155240516Swpaul rxcfg |= RL_RXCFG_RX_INDIV; 155340516Swpaul 155440516Swpaul /* If we want promiscuous mode, set the allframes bit. */ 155540516Swpaul if (ifp->if_flags & IFF_PROMISC) { 155640516Swpaul rxcfg |= RL_RXCFG_RX_ALLPHYS; 155740516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 155840516Swpaul } else { 155940516Swpaul rxcfg &= ~RL_RXCFG_RX_ALLPHYS; 156040516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 156140516Swpaul } 156240516Swpaul 1563131605Sbms /* Set capture broadcast bit to capture broadcast frames. */ 156440516Swpaul if (ifp->if_flags & IFF_BROADCAST) { 156540516Swpaul rxcfg |= RL_RXCFG_RX_BROAD; 156640516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 156740516Swpaul } else { 156840516Swpaul rxcfg &= ~RL_RXCFG_RX_BROAD; 156940516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 157040516Swpaul } 157140516Swpaul 1572131605Sbms /* Program the multicast filter, if necessary. */ 157340516Swpaul rl_setmulti(sc); 157440516Swpaul 157594883Sluigi#ifdef DEVICE_POLLING 1576131605Sbms /* Disable interrupts if we are polling. */ 1577102052Ssobomax if (ifp->if_flags & IFF_POLLING) 157894883Sluigi CSR_WRITE_2(sc, RL_IMR, 0); 1579131605Sbms else 158094883Sluigi#endif /* DEVICE_POLLING */ 1581131605Sbms /* Enable interrupts. */ 1582119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 158340516Swpaul 158452426Swpaul /* Set initial TX threshold */ 158552426Swpaul sc->rl_txthresh = RL_TX_THRESH_INIT; 158652426Swpaul 158740516Swpaul /* Start RX/TX process. */ 158840516Swpaul CSR_WRITE_4(sc, RL_MISSEDPKT, 0); 1589119868Swpaul 159040516Swpaul /* Enable receiver and transmitter. */ 159140516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 159240516Swpaul 159350703Swpaul mii_mediachg(mii); 159440516Swpaul 159540516Swpaul CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); 159640516Swpaul 159740516Swpaul ifp->if_flags |= IFF_RUNNING; 159840516Swpaul ifp->if_flags &= ~IFF_OACTIVE; 159940516Swpaul 160050703Swpaul sc->rl_stat_ch = timeout(rl_tick, sc, hz); 160140516Swpaul} 160240516Swpaul 160340516Swpaul/* 160440516Swpaul * Set media options. 160540516Swpaul */ 1606102335Salfredstatic int 1607131605Sbmsrl_ifmedia_upd(struct ifnet *ifp) 160840516Swpaul{ 1609131605Sbms struct rl_softc *sc = ifp->if_softc; 161050703Swpaul struct mii_data *mii; 161140516Swpaul 161250703Swpaul mii = device_get_softc(sc->rl_miibus); 1613131605Sbms 161450703Swpaul mii_mediachg(mii); 161540516Swpaul 1616131605Sbms return (0); 161740516Swpaul} 161840516Swpaul 161940516Swpaul/* 162040516Swpaul * Report current media status. 162140516Swpaul */ 1622102335Salfredstatic void 1623131605Sbmsrl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 162440516Swpaul{ 1625131605Sbms struct rl_softc *sc = ifp->if_softc; 162650703Swpaul struct mii_data *mii; 162740516Swpaul 162850703Swpaul mii = device_get_softc(sc->rl_miibus); 162940516Swpaul 163050703Swpaul mii_pollstat(mii); 163150703Swpaul ifmr->ifm_active = mii->mii_media_active; 163250703Swpaul ifmr->ifm_status = mii->mii_media_status; 163340516Swpaul} 163440516Swpaul 1635102335Salfredstatic int 1636131605Sbmsrl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 163740516Swpaul{ 1638131605Sbms struct ifreq *ifr = (struct ifreq *)data; 1639131605Sbms struct mii_data *mii; 164040516Swpaul struct rl_softc *sc = ifp->if_softc; 164167087Swpaul int error = 0; 164240516Swpaul 1643131605Sbms switch (command) { 164440516Swpaul case SIOCSIFFLAGS: 1645131841Sbms RL_LOCK(sc); 164640516Swpaul if (ifp->if_flags & IFF_UP) { 1647131841Sbms rl_init_locked(sc); 164840516Swpaul } else { 164940516Swpaul if (ifp->if_flags & IFF_RUNNING) 165040516Swpaul rl_stop(sc); 165140516Swpaul } 1652131841Sbms RL_UNLOCK(sc); 165340516Swpaul error = 0; 165440516Swpaul break; 165540516Swpaul case SIOCADDMULTI: 165640516Swpaul case SIOCDELMULTI: 1657131606Sbms RL_LOCK(sc); 165840516Swpaul rl_setmulti(sc); 1659131606Sbms RL_UNLOCK(sc); 166040516Swpaul error = 0; 166140516Swpaul break; 166240516Swpaul case SIOCGIFMEDIA: 166340516Swpaul case SIOCSIFMEDIA: 166450703Swpaul mii = device_get_softc(sc->rl_miibus); 166550703Swpaul error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 166640516Swpaul break; 1667128121Sru case SIOCSIFCAP: 1668129633Syar ifp->if_capenable &= ~IFCAP_POLLING; 1669129633Syar ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING; 1670128121Sru break; 167140516Swpaul default: 1672106936Ssam error = ether_ioctl(ifp, command, data); 167340516Swpaul break; 167440516Swpaul } 167540516Swpaul 1676131605Sbms return (error); 167740516Swpaul} 167840516Swpaul 1679102335Salfredstatic void 1680131605Sbmsrl_watchdog(struct ifnet *ifp) 168140516Swpaul{ 1682131605Sbms struct rl_softc *sc = ifp->if_softc; 168340516Swpaul 168467087Swpaul RL_LOCK(sc); 1685131605Sbms 1686131605Sbms if_printf(ifp, "watchdog timeout\n"); 168740516Swpaul ifp->if_oerrors++; 168850703Swpaul 1689119868Swpaul rl_txeof(sc); 1690119868Swpaul rl_rxeof(sc); 1691131841Sbms rl_init_locked(sc); 1692131605Sbms 169367087Swpaul RL_UNLOCK(sc); 169440516Swpaul} 169540516Swpaul 169640516Swpaul/* 169740516Swpaul * Stop the adapter and free any mbufs allocated to the 169840516Swpaul * RX and TX lists. 169940516Swpaul */ 1700102335Salfredstatic void 1701131605Sbmsrl_stop(struct rl_softc *sc) 170240516Swpaul{ 170340516Swpaul register int i; 1704131605Sbms struct ifnet *ifp = &sc->arpcom.ac_if; 170540516Swpaul 1706131606Sbms RL_LOCK_ASSERT(sc); 1707131606Sbms 170840516Swpaul ifp->if_timer = 0; 170950703Swpaul untimeout(rl_tick, sc, sc->rl_stat_ch); 171094883Sluigi ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 171194883Sluigi#ifdef DEVICE_POLLING 171294883Sluigi ether_poll_deregister(ifp); 171394883Sluigi#endif /* DEVICE_POLLING */ 171450703Swpaul 171540516Swpaul CSR_WRITE_1(sc, RL_COMMAND, 0x00); 171640516Swpaul CSR_WRITE_2(sc, RL_IMR, 0x0000); 1717119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 171840516Swpaul 1719119868Swpaul /* 1720119868Swpaul * Free the TX list buffers. 1721119868Swpaul */ 1722119868Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 1723119868Swpaul if (sc->rl_cdata.rl_tx_chain[i] != NULL) { 1724119868Swpaul bus_dmamap_unload(sc->rl_tag, 1725119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1726119868Swpaul bus_dmamap_destroy(sc->rl_tag, 1727119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1728119868Swpaul m_freem(sc->rl_cdata.rl_tx_chain[i]); 1729119868Swpaul sc->rl_cdata.rl_tx_chain[i] = NULL; 1730131605Sbms CSR_WRITE_4(sc, RL_TXADDR0 + (i * sizeof(uint32_t)), 1731124816Swpaul 0x0000000); 173240516Swpaul } 173340516Swpaul } 173440516Swpaul} 173540516Swpaul 173640516Swpaul/* 173786822Siwasaki * Device suspend routine. Stop the interface and save some PCI 173886822Siwasaki * settings in case the BIOS doesn't restore them properly on 173986822Siwasaki * resume. 174086822Siwasaki */ 1741102335Salfredstatic int 1742131605Sbmsrl_suspend(device_t dev) 174386822Siwasaki{ 174486822Siwasaki struct rl_softc *sc; 174586822Siwasaki 174686822Siwasaki sc = device_get_softc(dev); 1747131606Sbms 1748131606Sbms RL_LOCK(sc); 174986822Siwasaki rl_stop(sc); 175086822Siwasaki sc->suspended = 1; 1751131606Sbms RL_UNLOCK(sc); 175286822Siwasaki 175386822Siwasaki return (0); 175486822Siwasaki} 175586822Siwasaki 175686822Siwasaki/* 175786822Siwasaki * Device resume routine. Restore some PCI settings in case the BIOS 175886822Siwasaki * doesn't, re-enable busmastering, and restart the interface if 175986822Siwasaki * appropriate. 176086822Siwasaki */ 1761102335Salfredstatic int 1762131605Sbmsrl_resume(device_t dev) 176386822Siwasaki{ 176486822Siwasaki struct rl_softc *sc; 176586822Siwasaki struct ifnet *ifp; 176686822Siwasaki 176786822Siwasaki sc = device_get_softc(dev); 176886822Siwasaki ifp = &sc->arpcom.ac_if; 176986822Siwasaki 1770131841Sbms RL_LOCK(sc); 1771131841Sbms 1772109109Sdes /* reinitialize interface if necessary */ 1773109109Sdes if (ifp->if_flags & IFF_UP) 1774131841Sbms rl_init_locked(sc); 177586822Siwasaki 177686822Siwasaki sc->suspended = 0; 1777131841Sbms 1778131606Sbms RL_UNLOCK(sc); 177986822Siwasaki 178086822Siwasaki return (0); 178186822Siwasaki} 178286822Siwasaki 178386822Siwasaki/* 178440516Swpaul * Stop all chip I/O so that the kernel's probe routines don't 178540516Swpaul * get confused by errant DMAs when rebooting. 178640516Swpaul */ 1787102335Salfredstatic void 1788131605Sbmsrl_shutdown(device_t dev) 178940516Swpaul{ 179050703Swpaul struct rl_softc *sc; 179140516Swpaul 179250703Swpaul sc = device_get_softc(dev); 1793131606Sbms 1794131606Sbms RL_LOCK(sc); 179540516Swpaul rl_stop(sc); 1796131606Sbms RL_UNLOCK(sc); 179740516Swpaul} 1798