if_rl.c revision 162315
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 162315 2006-09-15 10:40:54Z glebius $"); 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 86150968Sglebius#ifdef HAVE_KERNEL_OPTION_HEADERS 87150968Sglebius#include "opt_device_polling.h" 88150968Sglebius#endif 89150968Sglebius 9040516Swpaul#include <sys/param.h> 91108729Sjake#include <sys/endian.h> 9240516Swpaul#include <sys/systm.h> 9340516Swpaul#include <sys/sockio.h> 9440516Swpaul#include <sys/mbuf.h> 9540516Swpaul#include <sys/malloc.h> 9640516Swpaul#include <sys/kernel.h> 97129878Sphk#include <sys/module.h> 9840516Swpaul#include <sys/socket.h> 9940516Swpaul 10040516Swpaul#include <net/if.h> 10140516Swpaul#include <net/if_arp.h> 10240516Swpaul#include <net/ethernet.h> 10340516Swpaul#include <net/if_dl.h> 10440516Swpaul#include <net/if_media.h> 105147256Sbrooks#include <net/if_types.h> 10640516Swpaul 10740516Swpaul#include <net/bpf.h> 10840516Swpaul 10941569Swpaul#include <machine/bus.h> 11050703Swpaul#include <machine/resource.h> 11150703Swpaul#include <sys/bus.h> 11250703Swpaul#include <sys/rman.h> 11340516Swpaul 11450703Swpaul#include <dev/mii/mii.h> 11550703Swpaul#include <dev/mii/miivar.h> 11650703Swpaul 117119871Swpaul#include <dev/pci/pcireg.h> 118119871Swpaul#include <dev/pci/pcivar.h> 11940516Swpaul 120113506SmdoddMODULE_DEPEND(rl, pci, 1, 1, 1); 121113506SmdoddMODULE_DEPEND(rl, ether, 1, 1, 1); 12259758SpeterMODULE_DEPEND(rl, miibus, 1, 1, 1); 12359758Speter 124151545Simp/* "device miibus" required. See GENERIC if you get errors here. */ 12550703Swpaul#include "miibus_if.h" 12650703Swpaul 12740516Swpaul/* 12840516Swpaul * Default to using PIO access for this driver. On SMP systems, 12940516Swpaul * there appear to be problems with memory mapped mode: it looks like 13040516Swpaul * doing too many memory mapped access back to back in rapid succession 13140516Swpaul * can hang the bus. I'm inclined to blame this on crummy design/construction 13240516Swpaul * on the part of RealTek. Memory mapped mode does appear to work on 13340516Swpaul * uniprocessor systems though. 13440516Swpaul */ 13540516Swpaul#define RL_USEIOSPACE 13640516Swpaul 13740516Swpaul#include <pci/if_rlreg.h> 13840516Swpaul 13940516Swpaul/* 14040516Swpaul * Various supported device vendors/types and their names. 14140516Swpaul */ 14240516Swpaulstatic struct rl_type rl_devs[] = { 143117388Swpaul { RT_VENDORID, RT_DEVICEID_8129, RL_8129, 14440516Swpaul "RealTek 8129 10/100BaseTX" }, 145117388Swpaul { RT_VENDORID, RT_DEVICEID_8139, RL_8139, 14640516Swpaul "RealTek 8139 10/100BaseTX" }, 147117388Swpaul { RT_VENDORID, RT_DEVICEID_8138, RL_8139, 14867771Swpaul "RealTek 8139 10/100BaseTX CardBus" }, 149118978Swpaul { RT_VENDORID, RT_DEVICEID_8100, RL_8139, 150118978Swpaul "RealTek 8100 10/100BaseTX" }, 151117388Swpaul { ACCTON_VENDORID, ACCTON_DEVICEID_5030, RL_8139, 15241243Swpaul "Accton MPX 5030/5038 10/100BaseTX" }, 153117388Swpaul { DELTA_VENDORID, DELTA_DEVICEID_8139, RL_8139, 15444238Swpaul "Delta Electronics 8139 10/100BaseTX" }, 155117388Swpaul { ADDTRON_VENDORID, ADDTRON_DEVICEID_8139, RL_8139, 15644238Swpaul "Addtron Technolgy 8139 10/100BaseTX" }, 157117388Swpaul { DLINK_VENDORID, DLINK_DEVICEID_530TXPLUS, RL_8139, 15872813Swpaul "D-Link DFE-530TX+ 10/100BaseTX" }, 159117388Swpaul { DLINK_VENDORID, DLINK_DEVICEID_690TXD, RL_8139, 16096112Sjhb "D-Link DFE-690TXD 10/100BaseTX" }, 161117388Swpaul { NORTEL_VENDORID, ACCTON_DEVICEID_5030, RL_8139, 16294400Swpaul "Nortel Networks 10/100BaseTX" }, 163117388Swpaul { COREGA_VENDORID, COREGA_DEVICEID_FETHERCBTXD, RL_8139, 164103020Siwasaki "Corega FEther CB-TXD" }, 165117388Swpaul { COREGA_VENDORID, COREGA_DEVICEID_FETHERIICBTXD, RL_8139, 166109095Ssanpei "Corega FEtherII CB-TXD" }, 167117388Swpaul { PEPPERCON_VENDORID, PEPPERCON_DEVICEID_ROLF, RL_8139, 168111381Sdan "Peppercon AG ROL-F" }, 169117388Swpaul { PLANEX_VENDORID, PLANEX_DEVICEID_FNW3800TX, RL_8139, 170112379Ssanpei "Planex FNW-3800-TX" }, 171117388Swpaul { CP_VENDORID, RT_DEVICEID_8139, RL_8139, 172117388Swpaul "Compaq HNE-300" }, 173117388Swpaul { LEVEL1_VENDORID, LEVEL1_DEVICEID_FPC0106TX, RL_8139, 174117388Swpaul "LevelOne FPC-0106TX" }, 175117388Swpaul { EDIMAX_VENDORID, EDIMAX_DEVICEID_EP4103DL, RL_8139, 176117388Swpaul "Edimax EP-4103DL CardBus" }, 177123740Speter { 0, 0, 0, NULL } 17840516Swpaul}; 17940516Swpaul 180142407Simpstatic int rl_attach(device_t); 181142407Simpstatic int rl_detach(device_t); 182142407Simpstatic void rl_dma_map_rxbuf(void *, bus_dma_segment_t *, int, int); 183142407Simpstatic void rl_dma_map_txbuf(void *, bus_dma_segment_t *, int, int); 184142407Simpstatic void rl_eeprom_putbyte(struct rl_softc *, int); 185142407Simpstatic void rl_eeprom_getword(struct rl_softc *, int, uint16_t *); 186142407Simpstatic int rl_encap(struct rl_softc *, struct mbuf * ); 187142407Simpstatic int rl_list_tx_init(struct rl_softc *); 188142407Simpstatic int rl_ifmedia_upd(struct ifnet *); 189142407Simpstatic void rl_ifmedia_sts(struct ifnet *, struct ifmediareq *); 190142407Simpstatic int rl_ioctl(struct ifnet *, u_long, caddr_t); 191142407Simpstatic void rl_intr(void *); 192142407Simpstatic void rl_init(void *); 193142407Simpstatic void rl_init_locked(struct rl_softc *sc); 194142407Simpstatic void rl_mii_send(struct rl_softc *, uint32_t, int); 195142407Simpstatic void rl_mii_sync(struct rl_softc *); 196142407Simpstatic int rl_mii_readreg(struct rl_softc *, struct rl_mii_frame *); 197142407Simpstatic int rl_mii_writereg(struct rl_softc *, struct rl_mii_frame *); 198142407Simpstatic int rl_miibus_readreg(device_t, int, int); 199142407Simpstatic void rl_miibus_statchg(device_t); 200142407Simpstatic int rl_miibus_writereg(device_t, int, int, int); 201131841Sbms#ifdef DEVICE_POLLING 202150789Sglebiusstatic void rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); 203150789Sglebiusstatic void rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); 204131841Sbms#endif 205142407Simpstatic int rl_probe(device_t); 206142407Simpstatic void rl_read_eeprom(struct rl_softc *, uint8_t *, int, int, int); 207142407Simpstatic void rl_reset(struct rl_softc *); 208142407Simpstatic int rl_resume(device_t); 209142407Simpstatic void rl_rxeof(struct rl_softc *); 210142407Simpstatic void rl_setmulti(struct rl_softc *); 211142407Simpstatic void rl_shutdown(device_t); 212142407Simpstatic void rl_start(struct ifnet *); 213142407Simpstatic void rl_start_locked(struct ifnet *); 214142407Simpstatic void rl_stop(struct rl_softc *); 215142407Simpstatic int rl_suspend(device_t); 216142407Simpstatic void rl_tick(void *); 217142407Simpstatic void rl_txeof(struct rl_softc *); 218142407Simpstatic void rl_watchdog(struct ifnet *); 21940516Swpaul 22050703Swpaul#ifdef RL_USEIOSPACE 22150703Swpaul#define RL_RES SYS_RES_IOPORT 22250703Swpaul#define RL_RID RL_PCI_LOIO 22350703Swpaul#else 22450703Swpaul#define RL_RES SYS_RES_MEMORY 22550703Swpaul#define RL_RID RL_PCI_LOMEM 22650703Swpaul#endif 22750703Swpaul 22850703Swpaulstatic device_method_t rl_methods[] = { 22950703Swpaul /* Device interface */ 23050703Swpaul DEVMETHOD(device_probe, rl_probe), 23150703Swpaul DEVMETHOD(device_attach, rl_attach), 23250703Swpaul DEVMETHOD(device_detach, rl_detach), 23386822Siwasaki DEVMETHOD(device_suspend, rl_suspend), 23486822Siwasaki DEVMETHOD(device_resume, rl_resume), 23550703Swpaul DEVMETHOD(device_shutdown, rl_shutdown), 23650703Swpaul 23750703Swpaul /* bus interface */ 23850703Swpaul DEVMETHOD(bus_print_child, bus_generic_print_child), 23950703Swpaul DEVMETHOD(bus_driver_added, bus_generic_driver_added), 24050703Swpaul 24150703Swpaul /* MII interface */ 24250703Swpaul DEVMETHOD(miibus_readreg, rl_miibus_readreg), 24350703Swpaul DEVMETHOD(miibus_writereg, rl_miibus_writereg), 24450703Swpaul DEVMETHOD(miibus_statchg, rl_miibus_statchg), 24550703Swpaul 24650703Swpaul { 0, 0 } 24750703Swpaul}; 24850703Swpaul 24950703Swpaulstatic driver_t rl_driver = { 25051455Swpaul "rl", 25150703Swpaul rl_methods, 25250703Swpaul sizeof(struct rl_softc) 25350703Swpaul}; 25450703Swpaul 25550703Swpaulstatic devclass_t rl_devclass; 25650703Swpaul 257113506SmdoddDRIVER_MODULE(rl, pci, rl_driver, rl_devclass, 0, 0); 258123019SimpDRIVER_MODULE(rl, cardbus, rl_driver, rl_devclass, 0, 0); 25951473SwpaulDRIVER_MODULE(miibus, rl, miibus_driver, miibus_devclass, 0, 0); 26050703Swpaul 26140516Swpaul#define EE_SET(x) \ 26240516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26340516Swpaul CSR_READ_1(sc, RL_EECMD) | x) 26440516Swpaul 26540516Swpaul#define EE_CLR(x) \ 26640516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26740516Swpaul CSR_READ_1(sc, RL_EECMD) & ~x) 26840516Swpaul 26981713Swpaulstatic void 270131605Sbmsrl_dma_map_rxbuf(void *arg, bus_dma_segment_t *segs, int nseg, int error) 27181713Swpaul{ 272131605Sbms struct rl_softc *sc = arg; 27381713Swpaul 27481713Swpaul CSR_WRITE_4(sc, RL_RXADDR, segs->ds_addr & 0xFFFFFFFF); 27581713Swpaul} 27681713Swpaul 27781713Swpaulstatic void 278131605Sbmsrl_dma_map_txbuf(void *arg, bus_dma_segment_t *segs, int nseg, int error) 27981713Swpaul{ 280131605Sbms struct rl_softc *sc = arg; 28181713Swpaul 28281713Swpaul CSR_WRITE_4(sc, RL_CUR_TXADDR(sc), segs->ds_addr & 0xFFFFFFFF); 28381713Swpaul} 28481713Swpaul 28540516Swpaul/* 28640516Swpaul * Send a read command and address to the EEPROM, check for ACK. 28740516Swpaul */ 288102335Salfredstatic void 289131605Sbmsrl_eeprom_putbyte(struct rl_softc *sc, int addr) 29040516Swpaul{ 29140516Swpaul register int d, i; 29240516Swpaul 29367931Swpaul d = addr | sc->rl_eecmd_read; 29440516Swpaul 29540516Swpaul /* 29655170Sbillf * Feed in each bit and strobe the clock. 29740516Swpaul */ 29840516Swpaul for (i = 0x400; i; i >>= 1) { 29940516Swpaul if (d & i) { 30040516Swpaul EE_SET(RL_EE_DATAIN); 30140516Swpaul } else { 30240516Swpaul EE_CLR(RL_EE_DATAIN); 30340516Swpaul } 30440516Swpaul DELAY(100); 30540516Swpaul EE_SET(RL_EE_CLK); 30640516Swpaul DELAY(150); 30740516Swpaul EE_CLR(RL_EE_CLK); 30840516Swpaul DELAY(100); 30940516Swpaul } 31040516Swpaul} 31140516Swpaul 31240516Swpaul/* 31340516Swpaul * Read a word of data stored in the EEPROM at address 'addr.' 31440516Swpaul */ 315102335Salfredstatic void 316131605Sbmsrl_eeprom_getword(struct rl_softc *sc, int addr, uint16_t *dest) 31740516Swpaul{ 31840516Swpaul register int i; 319131605Sbms uint16_t word = 0; 32040516Swpaul 32140516Swpaul /* Enter EEPROM access mode. */ 32240516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 32340516Swpaul 32440516Swpaul /* 32540516Swpaul * Send address of word we want to read. 32640516Swpaul */ 32740516Swpaul rl_eeprom_putbyte(sc, addr); 32840516Swpaul 32940516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 33040516Swpaul 33140516Swpaul /* 33240516Swpaul * Start reading bits from EEPROM. 33340516Swpaul */ 33440516Swpaul for (i = 0x8000; i; i >>= 1) { 33540516Swpaul EE_SET(RL_EE_CLK); 33640516Swpaul DELAY(100); 33740516Swpaul if (CSR_READ_1(sc, RL_EECMD) & RL_EE_DATAOUT) 33840516Swpaul word |= i; 33940516Swpaul EE_CLR(RL_EE_CLK); 34040516Swpaul DELAY(100); 34140516Swpaul } 34240516Swpaul 34340516Swpaul /* Turn off EEPROM access mode. */ 34440516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 34540516Swpaul 34640516Swpaul *dest = word; 34740516Swpaul} 34840516Swpaul 34940516Swpaul/* 35040516Swpaul * Read a sequence of words from the EEPROM. 35140516Swpaul */ 352102335Salfredstatic void 353131605Sbmsrl_read_eeprom(struct rl_softc *sc, uint8_t *dest, int off, int cnt, int swap) 35440516Swpaul{ 35540516Swpaul int i; 356131605Sbms uint16_t word = 0, *ptr; 35740516Swpaul 35840516Swpaul for (i = 0; i < cnt; i++) { 35940516Swpaul rl_eeprom_getword(sc, off + i, &word); 360131605Sbms ptr = (uint16_t *)(dest + (i * 2)); 36140516Swpaul if (swap) 36240516Swpaul *ptr = ntohs(word); 36340516Swpaul else 36440516Swpaul *ptr = word; 36540516Swpaul } 36640516Swpaul} 36740516Swpaul 36840516Swpaul/* 36940516Swpaul * MII access routines are provided for the 8129, which 37040516Swpaul * doesn't have a built-in PHY. For the 8139, we fake things 37140516Swpaul * up by diverting rl_phy_readreg()/rl_phy_writereg() to the 37240516Swpaul * direct access PHY registers. 37340516Swpaul */ 37440516Swpaul#define MII_SET(x) \ 37540516Swpaul CSR_WRITE_1(sc, RL_MII, \ 376105221Sphk CSR_READ_1(sc, RL_MII) | (x)) 37740516Swpaul 37840516Swpaul#define MII_CLR(x) \ 37940516Swpaul CSR_WRITE_1(sc, RL_MII, \ 380105221Sphk CSR_READ_1(sc, RL_MII) & ~(x)) 38140516Swpaul 38240516Swpaul/* 38340516Swpaul * Sync the PHYs by setting data bit and strobing the clock 32 times. 38440516Swpaul */ 385102335Salfredstatic void 386131605Sbmsrl_mii_sync(struct rl_softc *sc) 38740516Swpaul{ 38840516Swpaul register int i; 38940516Swpaul 39040516Swpaul MII_SET(RL_MII_DIR|RL_MII_DATAOUT); 39140516Swpaul 39240516Swpaul for (i = 0; i < 32; i++) { 39340516Swpaul MII_SET(RL_MII_CLK); 39440516Swpaul DELAY(1); 39540516Swpaul MII_CLR(RL_MII_CLK); 39640516Swpaul DELAY(1); 39740516Swpaul } 39840516Swpaul} 39940516Swpaul 40040516Swpaul/* 40140516Swpaul * Clock a series of bits through the MII. 40240516Swpaul */ 403102335Salfredstatic void 404131605Sbmsrl_mii_send(struct rl_softc *sc, uint32_t bits, int cnt) 40540516Swpaul{ 40640516Swpaul int i; 40740516Swpaul 40840516Swpaul MII_CLR(RL_MII_CLK); 40940516Swpaul 41040516Swpaul for (i = (0x1 << (cnt - 1)); i; i >>= 1) { 411109109Sdes if (bits & i) { 41240516Swpaul MII_SET(RL_MII_DATAOUT); 413109109Sdes } else { 41440516Swpaul MII_CLR(RL_MII_DATAOUT); 415109109Sdes } 41640516Swpaul DELAY(1); 41740516Swpaul MII_CLR(RL_MII_CLK); 41840516Swpaul DELAY(1); 41940516Swpaul MII_SET(RL_MII_CLK); 42040516Swpaul } 42140516Swpaul} 42240516Swpaul 42340516Swpaul/* 42440516Swpaul * Read an PHY register through the MII. 42540516Swpaul */ 426102335Salfredstatic int 427131605Sbmsrl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame) 42840516Swpaul{ 42967087Swpaul int i, ack; 43040516Swpaul 431131605Sbms /* Set up frame for RX. */ 43240516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 43340516Swpaul frame->mii_opcode = RL_MII_READOP; 43440516Swpaul frame->mii_turnaround = 0; 43540516Swpaul frame->mii_data = 0; 436109109Sdes 43740516Swpaul CSR_WRITE_2(sc, RL_MII, 0); 43840516Swpaul 439131605Sbms /* Turn on data xmit. */ 44040516Swpaul MII_SET(RL_MII_DIR); 44140516Swpaul 44240516Swpaul rl_mii_sync(sc); 44340516Swpaul 444131605Sbms /* Send command/address info. */ 44540516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 44640516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 44740516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 44840516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 44940516Swpaul 45040516Swpaul /* Idle bit */ 45140516Swpaul MII_CLR((RL_MII_CLK|RL_MII_DATAOUT)); 45240516Swpaul DELAY(1); 45340516Swpaul MII_SET(RL_MII_CLK); 45440516Swpaul DELAY(1); 45540516Swpaul 45640516Swpaul /* Turn off xmit. */ 45740516Swpaul MII_CLR(RL_MII_DIR); 45840516Swpaul 45940516Swpaul /* Check for ack */ 46040516Swpaul MII_CLR(RL_MII_CLK); 46140516Swpaul DELAY(1); 462109058Smbr ack = CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN; 46340516Swpaul MII_SET(RL_MII_CLK); 46440516Swpaul DELAY(1); 46540516Swpaul 46640516Swpaul /* 46740516Swpaul * Now try reading data bits. If the ack failed, we still 46840516Swpaul * need to clock through 16 cycles to keep the PHY(s) in sync. 46940516Swpaul */ 47040516Swpaul if (ack) { 47140516Swpaul for(i = 0; i < 16; i++) { 47240516Swpaul MII_CLR(RL_MII_CLK); 47340516Swpaul DELAY(1); 47440516Swpaul MII_SET(RL_MII_CLK); 47540516Swpaul DELAY(1); 47640516Swpaul } 47740516Swpaul goto fail; 47840516Swpaul } 47940516Swpaul 48040516Swpaul for (i = 0x8000; i; i >>= 1) { 48140516Swpaul MII_CLR(RL_MII_CLK); 48240516Swpaul DELAY(1); 48340516Swpaul if (!ack) { 48440516Swpaul if (CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN) 48540516Swpaul frame->mii_data |= i; 48640516Swpaul DELAY(1); 48740516Swpaul } 48840516Swpaul MII_SET(RL_MII_CLK); 48940516Swpaul DELAY(1); 49040516Swpaul } 49140516Swpaul 49240516Swpaulfail: 49340516Swpaul MII_CLR(RL_MII_CLK); 49440516Swpaul DELAY(1); 49540516Swpaul MII_SET(RL_MII_CLK); 49640516Swpaul DELAY(1); 49740516Swpaul 498131605Sbms return (ack ? 1 : 0); 49940516Swpaul} 50040516Swpaul 50140516Swpaul/* 50240516Swpaul * Write to a PHY register through the MII. 50340516Swpaul */ 504102335Salfredstatic int 505131605Sbmsrl_mii_writereg(struct rl_softc *sc, struct rl_mii_frame *frame) 506131605Sbms{ 507109109Sdes 508131605Sbms /* Set up frame for TX. */ 50940516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 51040516Swpaul frame->mii_opcode = RL_MII_WRITEOP; 51140516Swpaul frame->mii_turnaround = RL_MII_TURNAROUND; 512109109Sdes 513131605Sbms /* Turn on data output. */ 51440516Swpaul MII_SET(RL_MII_DIR); 51540516Swpaul 51640516Swpaul rl_mii_sync(sc); 51740516Swpaul 51840516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 51940516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 52040516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 52140516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 52240516Swpaul rl_mii_send(sc, frame->mii_turnaround, 2); 52340516Swpaul rl_mii_send(sc, frame->mii_data, 16); 52440516Swpaul 52540516Swpaul /* Idle bit. */ 52640516Swpaul MII_SET(RL_MII_CLK); 52740516Swpaul DELAY(1); 52840516Swpaul MII_CLR(RL_MII_CLK); 52940516Swpaul DELAY(1); 53040516Swpaul 531131605Sbms /* Turn off xmit. */ 53240516Swpaul MII_CLR(RL_MII_DIR); 53340516Swpaul 534131605Sbms return (0); 53540516Swpaul} 53640516Swpaul 537102335Salfredstatic int 538131605Sbmsrl_miibus_readreg(device_t dev, int phy, int reg) 53950703Swpaul{ 54040516Swpaul struct rl_softc *sc; 54140516Swpaul struct rl_mii_frame frame; 542131605Sbms uint16_t rval = 0; 543131605Sbms uint16_t rl8139_reg = 0; 54440516Swpaul 54550703Swpaul sc = device_get_softc(dev); 54650703Swpaul 547119868Swpaul if (sc->rl_type == RL_8139) { 54850703Swpaul /* Pretend the internal PHY is only at address 0 */ 54967087Swpaul if (phy) { 550131605Sbms return (0); 55167087Swpaul } 552131605Sbms switch (reg) { 55350703Swpaul case MII_BMCR: 55440516Swpaul rl8139_reg = RL_BMCR; 55540516Swpaul break; 55650703Swpaul case MII_BMSR: 55740516Swpaul rl8139_reg = RL_BMSR; 55840516Swpaul break; 55950703Swpaul case MII_ANAR: 56040516Swpaul rl8139_reg = RL_ANAR; 56140516Swpaul break; 56250703Swpaul case MII_ANER: 56350703Swpaul rl8139_reg = RL_ANER; 56450703Swpaul break; 56550703Swpaul case MII_ANLPAR: 56640516Swpaul rl8139_reg = RL_LPAR; 56740516Swpaul break; 56850703Swpaul case MII_PHYIDR1: 56950703Swpaul case MII_PHYIDR2: 570131605Sbms return (0); 57194149Swpaul /* 57294149Swpaul * Allow the rlphy driver to read the media status 57394149Swpaul * register. If we have a link partner which does not 57494149Swpaul * support NWAY, this is the register which will tell 57594149Swpaul * us the results of parallel detection. 57694149Swpaul */ 57794149Swpaul case RL_MEDIASTAT: 57894149Swpaul rval = CSR_READ_1(sc, RL_MEDIASTAT); 579131605Sbms return (rval); 58040516Swpaul default: 581162315Sglebius device_printf(sc->rl_dev, "bad phy register\n"); 582131605Sbms return (0); 58340516Swpaul } 58440516Swpaul rval = CSR_READ_2(sc, rl8139_reg); 585131605Sbms return (rval); 58640516Swpaul } 58740516Swpaul 58840516Swpaul bzero((char *)&frame, sizeof(frame)); 58950703Swpaul frame.mii_phyaddr = phy; 59040516Swpaul frame.mii_regaddr = reg; 59140516Swpaul rl_mii_readreg(sc, &frame); 592131605Sbms 593131605Sbms return (frame.mii_data); 59440516Swpaul} 59540516Swpaul 596102335Salfredstatic int 597131605Sbmsrl_miibus_writereg(device_t dev, int phy, int reg, int data) 59850703Swpaul{ 59940516Swpaul struct rl_softc *sc; 60040516Swpaul struct rl_mii_frame frame; 601131605Sbms uint16_t rl8139_reg = 0; 60240516Swpaul 60350703Swpaul sc = device_get_softc(dev); 60450703Swpaul 605119868Swpaul if (sc->rl_type == RL_8139) { 60650703Swpaul /* Pretend the internal PHY is only at address 0 */ 60767087Swpaul if (phy) { 608131605Sbms return (0); 60967087Swpaul } 610131605Sbms switch (reg) { 61150703Swpaul case MII_BMCR: 61240516Swpaul rl8139_reg = RL_BMCR; 61340516Swpaul break; 61450703Swpaul case MII_BMSR: 61540516Swpaul rl8139_reg = RL_BMSR; 61640516Swpaul break; 61750703Swpaul case MII_ANAR: 61840516Swpaul rl8139_reg = RL_ANAR; 61940516Swpaul break; 62050703Swpaul case MII_ANER: 62150703Swpaul rl8139_reg = RL_ANER; 62250703Swpaul break; 62350703Swpaul case MII_ANLPAR: 62440516Swpaul rl8139_reg = RL_LPAR; 62540516Swpaul break; 62650703Swpaul case MII_PHYIDR1: 62750703Swpaul case MII_PHYIDR2: 628131605Sbms return (0); 62950703Swpaul break; 63040516Swpaul default: 631162315Sglebius device_printf(sc->rl_dev, "bad phy register\n"); 632131605Sbms return (0); 63340516Swpaul } 63440516Swpaul CSR_WRITE_2(sc, rl8139_reg, data); 635131605Sbms return (0); 63640516Swpaul } 63740516Swpaul 63840516Swpaul bzero((char *)&frame, sizeof(frame)); 63950703Swpaul frame.mii_phyaddr = phy; 64040516Swpaul frame.mii_regaddr = reg; 64140516Swpaul frame.mii_data = data; 64240516Swpaul rl_mii_writereg(sc, &frame); 64340516Swpaul 644131605Sbms return (0); 64550703Swpaul} 64650703Swpaul 647102335Salfredstatic void 648131605Sbmsrl_miibus_statchg(device_t dev) 64950703Swpaul{ 65040516Swpaul} 65140516Swpaul 65240516Swpaul/* 65340516Swpaul * Program the 64-bit multicast hash filter. 65440516Swpaul */ 655102335Salfredstatic void 656131605Sbmsrl_setmulti(struct rl_softc *sc) 65740516Swpaul{ 658147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 65940516Swpaul int h = 0; 660131605Sbms uint32_t hashes[2] = { 0, 0 }; 66140516Swpaul struct ifmultiaddr *ifma; 662131605Sbms uint32_t rxfilt; 66340516Swpaul int mcnt = 0; 66440516Swpaul 665131606Sbms RL_LOCK_ASSERT(sc); 666131606Sbms 66740516Swpaul rxfilt = CSR_READ_4(sc, RL_RXCFG); 66840516Swpaul 66943062Swpaul if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 67040516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 67140516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 67240516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF); 67340516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF); 67440516Swpaul return; 67540516Swpaul } 67640516Swpaul 67740516Swpaul /* first, zot all the existing hash bits */ 67840516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0); 67940516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0); 68040516Swpaul 68140516Swpaul /* now program new ones */ 682148654Srwatson IF_ADDR_LOCK(ifp); 68372084Sphk TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 68440516Swpaul if (ifma->ifma_addr->sa_family != AF_LINK) 68540516Swpaul continue; 686130270Snaddy h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 687130270Snaddy ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 68840516Swpaul if (h < 32) 68940516Swpaul hashes[0] |= (1 << h); 69040516Swpaul else 69140516Swpaul hashes[1] |= (1 << (h - 32)); 69240516Swpaul mcnt++; 69340516Swpaul } 694148654Srwatson IF_ADDR_UNLOCK(ifp); 69540516Swpaul 69640516Swpaul if (mcnt) 69740516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 69840516Swpaul else 69940516Swpaul rxfilt &= ~RL_RXCFG_RX_MULTI; 70040516Swpaul 70140516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 70240516Swpaul CSR_WRITE_4(sc, RL_MAR0, hashes[0]); 70340516Swpaul CSR_WRITE_4(sc, RL_MAR4, hashes[1]); 70440516Swpaul} 70540516Swpaul 706102335Salfredstatic void 707131605Sbmsrl_reset(struct rl_softc *sc) 70840516Swpaul{ 70940516Swpaul register int i; 71040516Swpaul 711131606Sbms RL_LOCK_ASSERT(sc); 712131606Sbms 71340516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RESET); 71440516Swpaul 71540516Swpaul for (i = 0; i < RL_TIMEOUT; i++) { 71640516Swpaul DELAY(10); 71740516Swpaul if (!(CSR_READ_1(sc, RL_COMMAND) & RL_CMD_RESET)) 71840516Swpaul break; 71940516Swpaul } 72040516Swpaul if (i == RL_TIMEOUT) 721162315Sglebius device_printf(sc->rl_dev, "reset never completed!\n"); 72240516Swpaul} 72340516Swpaul 72440516Swpaul/* 72540516Swpaul * Probe for a RealTek 8129/8139 chip. Check the PCI vendor and device 72640516Swpaul * IDs against our list and return a device name if we find a match. 72740516Swpaul */ 728102335Salfredstatic int 729131605Sbmsrl_probe(device_t dev) 73040516Swpaul{ 731131605Sbms struct rl_softc *sc; 732131605Sbms struct rl_type *t = rl_devs; 733117388Swpaul int rid; 734131605Sbms uint32_t hwrev; 73540516Swpaul 736117388Swpaul sc = device_get_softc(dev); 73740516Swpaul 738131605Sbms while (t->rl_name != NULL) { 73950703Swpaul if ((pci_get_vendor(dev) == t->rl_vid) && 74050703Swpaul (pci_get_device(dev) == t->rl_did)) { 741117388Swpaul /* 742117388Swpaul * Temporarily map the I/O space 743117388Swpaul * so we can read the chip ID register. 744117388Swpaul */ 745117388Swpaul rid = RL_RID; 746127135Snjl sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, 747127135Snjl RF_ACTIVE); 748117388Swpaul if (sc->rl_res == NULL) { 749117388Swpaul device_printf(dev, 750117388Swpaul "couldn't map ports/memory\n"); 751131605Sbms return (ENXIO); 752117388Swpaul } 753117388Swpaul sc->rl_btag = rman_get_bustag(sc->rl_res); 754117388Swpaul sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 755131605Sbms 756119868Swpaul hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV; 757119868Swpaul bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 758131605Sbms 759119868Swpaul /* Don't attach to 8139C+ or 8169/8110 chips. */ 760119868Swpaul if (hwrev == RL_HWREV_8139CPLUS || 761124076Swpaul (hwrev == RL_HWREV_8169 && 762124076Swpaul t->rl_did == RT_DEVICEID_8169) || 763119954Swpaul hwrev == RL_HWREV_8169S || 764119954Swpaul hwrev == RL_HWREV_8110S) { 765119868Swpaul t++; 766119868Swpaul continue; 767119868Swpaul } 768119868Swpaul 769119868Swpaul device_set_desc(dev, t->rl_name); 770142398Simp return (BUS_PROBE_DEFAULT); 77140516Swpaul } 77240516Swpaul t++; 77340516Swpaul } 77440516Swpaul 775131605Sbms return (ENXIO); 77640516Swpaul} 77740516Swpaul 77840516Swpaul/* 77940516Swpaul * Attach the interface. Allocate softc structures, do ifmedia 78040516Swpaul * setup and ethernet/BPF attach. 78140516Swpaul */ 782102335Salfredstatic int 783131605Sbmsrl_attach(device_t dev) 78440516Swpaul{ 785131605Sbms uint8_t eaddr[ETHER_ADDR_LEN]; 786131605Sbms uint16_t as[3]; 787131605Sbms struct ifnet *ifp; 78840516Swpaul struct rl_softc *sc; 789117388Swpaul struct rl_type *t; 790131605Sbms int error = 0, i, rid; 791131605Sbms int unit; 792131605Sbms uint16_t rl_did = 0; 79340516Swpaul 79450703Swpaul sc = device_get_softc(dev); 79550703Swpaul unit = device_get_unit(dev); 796162315Sglebius sc->rl_dev = dev; 79740516Swpaul 79893818Sjhb mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 799131606Sbms MTX_DEF); 800150720Sjhb callout_init_mtx(&sc->rl_stat_callout, &sc->rl_mtx, 0); 801131605Sbms 80272813Swpaul pci_enable_busmaster(dev); 80340516Swpaul 804131605Sbms /* Map control/status registers. */ 805109109Sdes rid = RL_RID; 806127135Snjl sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, RF_ACTIVE); 80750703Swpaul 80850703Swpaul if (sc->rl_res == NULL) { 809131605Sbms device_printf(dev, "couldn't map ports/memory\n"); 81050703Swpaul error = ENXIO; 81140516Swpaul goto fail; 81240516Swpaul } 81340516Swpaul 814117388Swpaul#ifdef notdef 815131605Sbms /* 816131605Sbms * Detect the Realtek 8139B. For some reason, this chip is very 81769127Sroger * unstable when left to autoselect the media 81869127Sroger * The best workaround is to set the device to the required 81969127Sroger * media type or to set it to the 10 Meg speed. 82069127Sroger */ 821131605Sbms if ((rman_get_end(sc->rl_res) - rman_get_start(sc->rl_res)) == 0xFF) 822131605Sbms device_printf(dev, 823131605Sbms"Realtek 8139B detected. Warning, this may be unstable in autoselect mode\n"); 824117388Swpaul#endif 82569127Sroger 82650703Swpaul sc->rl_btag = rman_get_bustag(sc->rl_res); 82750703Swpaul sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 82850703Swpaul 829112872Snjl /* Allocate interrupt */ 83050703Swpaul rid = 0; 831127135Snjl sc->rl_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 83250703Swpaul RF_SHAREABLE | RF_ACTIVE); 83350703Swpaul 83450703Swpaul if (sc->rl_irq == NULL) { 835131605Sbms device_printf(dev, "couldn't map interrupt\n"); 83650703Swpaul error = ENXIO; 83740516Swpaul goto fail; 83840516Swpaul } 83940516Swpaul 840131606Sbms /* 841131606Sbms * Reset the adapter. Only take the lock here as it's needed in 842131606Sbms * order to call rl_reset(). 843131606Sbms */ 844131606Sbms RL_LOCK(sc); 84540516Swpaul rl_reset(sc); 846131606Sbms RL_UNLOCK(sc); 847131606Sbms 84867931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_6BIT; 849131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, 0, 1, 0); 85068215Swpaul if (rl_did != 0x8129) 85167931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_8BIT; 85240516Swpaul 85340516Swpaul /* 85440516Swpaul * Get station address from the EEPROM. 85540516Swpaul */ 856131605Sbms rl_read_eeprom(sc, (uint8_t *)as, RL_EE_EADDR, 3, 0); 857108729Sjake for (i = 0; i < 3; i++) { 858108729Sjake eaddr[(i * 2) + 0] = as[i] & 0xff; 859108729Sjake eaddr[(i * 2) + 1] = as[i] >> 8; 860108729Sjake } 86140516Swpaul 86240516Swpaul /* 86340516Swpaul * Now read the exact device type from the EEPROM to find 86440516Swpaul * out if it's an 8129 or 8139. 86540516Swpaul */ 866131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, RL_EE_PCI_DID, 1, 0); 86740516Swpaul 868117388Swpaul t = rl_devs; 869119868Swpaul sc->rl_type = 0; 870117388Swpaul while(t->rl_name != NULL) { 871117388Swpaul if (rl_did == t->rl_did) { 872117388Swpaul sc->rl_type = t->rl_basetype; 873117388Swpaul break; 874117388Swpaul } 875117388Swpaul t++; 876117388Swpaul } 877119868Swpaul 878119868Swpaul if (sc->rl_type == 0) { 879131605Sbms device_printf(dev, "unknown device ID: %x\n", rl_did); 88050703Swpaul error = ENXIO; 88140516Swpaul goto fail; 88240516Swpaul } 88340516Swpaul 88481713Swpaul /* 88581713Swpaul * Allocate the parent bus DMA tag appropriate for PCI. 88681713Swpaul */ 88781713Swpaul#define RL_NSEG_NEW 32 888109109Sdes error = bus_dma_tag_create(NULL, /* parent */ 88981713Swpaul 1, 0, /* alignment, boundary */ 89081713Swpaul BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 89181713Swpaul BUS_SPACE_MAXADDR, /* highaddr */ 89281713Swpaul NULL, NULL, /* filter, filterarg */ 89381713Swpaul MAXBSIZE, RL_NSEG_NEW, /* maxsize, nsegments */ 894109109Sdes BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 89581713Swpaul BUS_DMA_ALLOCNOW, /* flags */ 896117126Sscottl NULL, NULL, /* lockfunc, lockarg */ 89781713Swpaul &sc->rl_parent_tag); 898112872Snjl if (error) 899112872Snjl goto fail; 90040516Swpaul 90181713Swpaul /* 902119868Swpaul * Now allocate a tag for the DMA descriptor lists. 903119868Swpaul * All of our lists are allocated as a contiguous block 904119868Swpaul * of memory. 90581713Swpaul */ 906119868Swpaul error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */ 907119868Swpaul 1, 0, /* alignment, boundary */ 908119868Swpaul BUS_SPACE_MAXADDR, /* lowaddr */ 909119868Swpaul BUS_SPACE_MAXADDR, /* highaddr */ 910119868Swpaul NULL, NULL, /* filter, filterarg */ 911119868Swpaul RL_RXBUFLEN + 1518, 1, /* maxsize,nsegments */ 912119868Swpaul BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 913119868Swpaul BUS_DMA_ALLOCNOW, /* flags */ 914119868Swpaul NULL, NULL, /* lockfunc, lockarg */ 915119868Swpaul &sc->rl_tag); 916112872Snjl if (error) 917112872Snjl goto fail; 91881713Swpaul 919119868Swpaul /* 920119868Swpaul * Now allocate a chunk of DMA-able memory based on the 921119868Swpaul * tag we just created. 922119868Swpaul */ 923119868Swpaul error = bus_dmamem_alloc(sc->rl_tag, 924119868Swpaul (void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT | BUS_DMA_ZERO, 925119868Swpaul &sc->rl_cdata.rl_rx_dmamap); 926119868Swpaul if (error) { 927131605Sbms device_printf(dev, "no memory for list buffers!\n"); 928119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 929119868Swpaul sc->rl_tag = NULL; 930119868Swpaul goto fail; 931119868Swpaul } 932119868Swpaul 933119868Swpaul /* Leave a few bytes before the start of the RX ring buffer. */ 934119868Swpaul sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf; 935131605Sbms sc->rl_cdata.rl_rx_buf += sizeof(uint64_t); 936119868Swpaul 937147291Sbrooks ifp = sc->rl_ifp = if_alloc(IFT_ETHER); 938147291Sbrooks if (ifp == NULL) { 939147291Sbrooks device_printf(dev, "can not if_alloc()\n"); 940147291Sbrooks error = ENOSPC; 941147291Sbrooks goto fail; 942147291Sbrooks } 943147291Sbrooks 94450703Swpaul /* Do MII setup */ 94550703Swpaul if (mii_phy_probe(dev, &sc->rl_miibus, 94650703Swpaul rl_ifmedia_upd, rl_ifmedia_sts)) { 947131605Sbms device_printf(dev, "MII without any phy!\n"); 94850703Swpaul error = ENXIO; 94950703Swpaul goto fail; 95050703Swpaul } 95150703Swpaul 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; 960119976Swpaul ifp->if_capabilities = IFCAP_VLAN_MTU; 961150789Sglebius ifp->if_capenable = ifp->if_capabilities; 962128121Sru#ifdef DEVICE_POLLING 963128121Sru ifp->if_capabilities |= IFCAP_POLLING; 964128121Sru#endif 965131455Smlaier IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 966131455Smlaier ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 967131455Smlaier IFQ_SET_READY(&ifp->if_snd); 968131605Sbms 96940516Swpaul /* 97063090Sarchie * Call MI attach routine. 97140516Swpaul */ 972106936Ssam ether_ifattach(ifp, eaddr); 973106157Simp 974113609Snjl /* Hook interrupt last to avoid having to lock softc */ 975131606Sbms error = bus_setup_intr(dev, sc->rl_irq, INTR_TYPE_NET | INTR_MPSAFE, 976119868Swpaul rl_intr, sc, &sc->rl_intrhand); 977106157Simp if (error) { 978162315Sglebius device_printf(sc->rl_dev, "couldn't set up irq\n"); 979113609Snjl ether_ifdetach(ifp); 980106157Simp } 981106157Simp 98240516Swpaulfail: 983112872Snjl if (error) 984112872Snjl rl_detach(dev); 985112872Snjl 986110601Snjl return (error); 98740516Swpaul} 98840516Swpaul 989113609Snjl/* 990113609Snjl * Shutdown hardware and free up resources. This can be called any 991113609Snjl * time after the mutex has been initialized. It is called in both 992113609Snjl * the error case in attach and the normal detach case so it needs 993113609Snjl * to be careful about only freeing resources that have actually been 994113609Snjl * allocated. 995113609Snjl */ 996102335Salfredstatic int 997131605Sbmsrl_detach(device_t dev) 99850703Swpaul{ 99950703Swpaul struct rl_softc *sc; 100050703Swpaul struct ifnet *ifp; 100150703Swpaul 100250703Swpaul sc = device_get_softc(dev); 1003147256Sbrooks ifp = sc->rl_ifp; 1004131605Sbms 1005112880Sjhb KASSERT(mtx_initialized(&sc->rl_mtx), ("rl mutex not initialized")); 1006150720Sjhb 1007150789Sglebius#ifdef DEVICE_POLLING 1008150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 1009150789Sglebius ether_poll_deregister(ifp); 1010150789Sglebius#endif 1011133403Sgreen /* These should only be active if attach succeeded */ 1012150213Sru if (device_is_attached(dev)) { 1013150126Sru RL_LOCK(sc); 1014150126Sru rl_stop(sc); 1015150126Sru RL_UNLOCK(sc); 1016150720Sjhb callout_drain(&sc->rl_stat_callout); 1017133403Sgreen ether_ifdetach(ifp); 1018147256Sbrooks } 1019131606Sbms#if 0 1020131606Sbms sc->suspended = 1; 1021131606Sbms#endif 1022113609Snjl if (sc->rl_miibus) 1023112872Snjl device_delete_child(dev, sc->rl_miibus); 1024113609Snjl bus_generic_detach(dev); 102550703Swpaul 1026112872Snjl if (sc->rl_intrhand) 1027112872Snjl bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand); 1028112872Snjl if (sc->rl_irq) 1029112872Snjl bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1030112872Snjl if (sc->rl_res) 1031112872Snjl bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 103250703Swpaul 1033151297Sru if (ifp) 1034151297Sru if_free(ifp); 1035151297Sru 1036119868Swpaul if (sc->rl_tag) { 1037119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 1038119868Swpaul bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf, 1039119868Swpaul sc->rl_cdata.rl_rx_dmamap); 1040119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 1041112872Snjl } 1042112872Snjl if (sc->rl_parent_tag) 1043112872Snjl bus_dma_tag_destroy(sc->rl_parent_tag); 104450703Swpaul 104567087Swpaul mtx_destroy(&sc->rl_mtx); 104650703Swpaul 1047131605Sbms return (0); 104850703Swpaul} 104950703Swpaul 105040516Swpaul/* 105140516Swpaul * Initialize the transmit descriptors. 105240516Swpaul */ 1053102335Salfredstatic int 1054131605Sbmsrl_list_tx_init(struct rl_softc *sc) 105540516Swpaul{ 105640516Swpaul struct rl_chain_data *cd; 105740516Swpaul int i; 105840516Swpaul 1059131606Sbms RL_LOCK_ASSERT(sc); 1060131606Sbms 106140516Swpaul cd = &sc->rl_cdata; 106240516Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 106345633Swpaul cd->rl_tx_chain[i] = NULL; 106448028Swpaul CSR_WRITE_4(sc, 1065131605Sbms RL_TXADDR0 + (i * sizeof(uint32_t)), 0x0000000); 106640516Swpaul } 106740516Swpaul 106845633Swpaul sc->rl_cdata.cur_tx = 0; 106945633Swpaul sc->rl_cdata.last_tx = 0; 107040516Swpaul 1071131605Sbms return (0); 107240516Swpaul} 107340516Swpaul 107440516Swpaul/* 107540516Swpaul * A frame has been uploaded: pass the resulting mbuf chain up to 107640516Swpaul * the higher level protocols. 107740516Swpaul * 107840516Swpaul * You know there's something wrong with a PCI bus-master chip design 107940516Swpaul * when you have to use m_devget(). 108040516Swpaul * 108140516Swpaul * The receive operation is badly documented in the datasheet, so I'll 108240516Swpaul * attempt to document it here. The driver provides a buffer area and 108340516Swpaul * places its base address in the RX buffer start address register. 108440516Swpaul * The chip then begins copying frames into the RX buffer. Each frame 108572645Sasmodai * is preceded by a 32-bit RX status word which specifies the length 108640516Swpaul * of the frame and certain other status bits. Each frame (starting with 108740516Swpaul * the status word) is also 32-bit aligned. The frame length is in the 108840516Swpaul * first 16 bits of the status word; the lower 15 bits correspond with 108940516Swpaul * the 'rx status register' mentioned in the datasheet. 109048028Swpaul * 109148028Swpaul * Note: to make the Alpha happy, the frame payload needs to be aligned 109278508Sbmilekic * on a 32-bit boundary. To achieve this, we pass RL_ETHER_ALIGN (2 bytes) 1093109109Sdes * as the offset argument to m_devget(). 109440516Swpaul */ 1095102335Salfredstatic void 1096131605Sbmsrl_rxeof(struct rl_softc *sc) 109740516Swpaul{ 1098109109Sdes struct mbuf *m; 1099147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1100131605Sbms uint8_t *rxbufpos; 110140516Swpaul int total_len = 0; 110240516Swpaul int wrap = 0; 1103131605Sbms uint32_t rxstat; 1104131605Sbms uint16_t cur_rx; 1105131605Sbms uint16_t limit; 1106131605Sbms uint16_t max_bytes, rx_bytes = 0; 110740516Swpaul 1108122689Ssam RL_LOCK_ASSERT(sc); 1109122689Ssam 111081713Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1111108729Sjake BUS_DMASYNC_POSTREAD); 111281713Swpaul 111340516Swpaul cur_rx = (CSR_READ_2(sc, RL_CURRXADDR) + 16) % RL_RXBUFLEN; 111440516Swpaul 111540516Swpaul /* Do not try to read past this point. */ 111640516Swpaul limit = CSR_READ_2(sc, RL_CURRXBUF) % RL_RXBUFLEN; 111740516Swpaul 111840516Swpaul if (limit < cur_rx) 111940516Swpaul max_bytes = (RL_RXBUFLEN - cur_rx) + limit; 112040516Swpaul else 112140516Swpaul max_bytes = limit - cur_rx; 112240516Swpaul 112342738Swpaul while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) { 112494883Sluigi#ifdef DEVICE_POLLING 1125150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) { 112694883Sluigi if (sc->rxcycles <= 0) 112794883Sluigi break; 112894883Sluigi sc->rxcycles--; 112994883Sluigi } 1130150789Sglebius#endif 113140516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx; 1132131605Sbms rxstat = le32toh(*(uint32_t *)rxbufpos); 113340516Swpaul 113440516Swpaul /* 113540516Swpaul * Here's a totally undocumented fact for you. When the 113640516Swpaul * RealTek chip is in the process of copying a packet into 113740516Swpaul * RAM for you, the length will be 0xfff0. If you spot a 113840516Swpaul * packet header with this value, you need to stop. The 113940516Swpaul * datasheet makes absolutely no mention of this and 114040516Swpaul * RealTek should be shot for this. 114140516Swpaul */ 1142131605Sbms if ((uint16_t)(rxstat >> 16) == RL_RXSTAT_UNFINISHED) 114340516Swpaul break; 1144109109Sdes 114540516Swpaul if (!(rxstat & RL_RXSTAT_RXOK)) { 114640516Swpaul ifp->if_ierrors++; 1147131841Sbms rl_init_locked(sc); 114850703Swpaul return; 114940516Swpaul } 115040516Swpaul 1151109109Sdes /* No errors; receive the packet. */ 115240516Swpaul total_len = rxstat >> 16; 115340516Swpaul rx_bytes += total_len + 4; 115440516Swpaul 115540516Swpaul /* 115642051Swpaul * XXX The RealTek chip includes the CRC with every 115742051Swpaul * received frame, and there's no way to turn this 115842051Swpaul * behavior off (at least, I can't find anything in 1159109109Sdes * the manual that explains how to do it) so we have 116042051Swpaul * to trim off the CRC manually. 116142051Swpaul */ 116242051Swpaul total_len -= ETHER_CRC_LEN; 116342051Swpaul 116442051Swpaul /* 116540516Swpaul * Avoid trying to read more bytes than we know 116640516Swpaul * the chip has prepared for us. 116740516Swpaul */ 116840516Swpaul if (rx_bytes > max_bytes) 116940516Swpaul break; 117040516Swpaul 117140516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + 1172131605Sbms ((cur_rx + sizeof(uint32_t)) % RL_RXBUFLEN); 117340516Swpaul if (rxbufpos == (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN)) 117440516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf; 117540516Swpaul 117640516Swpaul wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos; 117740516Swpaul if (total_len > wrap) { 117878508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 117978508Sbmilekic NULL); 118040516Swpaul if (m == NULL) { 118140516Swpaul ifp->if_ierrors++; 118252426Swpaul } else { 118340516Swpaul m_copyback(m, wrap, total_len - wrap, 118440516Swpaul sc->rl_cdata.rl_rx_buf); 118548028Swpaul } 118642051Swpaul cur_rx = (total_len - wrap + ETHER_CRC_LEN); 118740516Swpaul } else { 118878508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 118978508Sbmilekic NULL); 1190131605Sbms if (m == NULL) 119140516Swpaul ifp->if_ierrors++; 119242051Swpaul cur_rx += total_len + 4 + ETHER_CRC_LEN; 119340516Swpaul } 119440516Swpaul 1195131605Sbms /* Round up to 32-bit boundary. */ 119640516Swpaul cur_rx = (cur_rx + 3) & ~3; 119740516Swpaul CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16); 119840516Swpaul 119940516Swpaul if (m == NULL) 120040516Swpaul continue; 120140516Swpaul 120240516Swpaul ifp->if_ipackets++; 1203122689Ssam RL_UNLOCK(sc); 1204106936Ssam (*ifp->if_input)(ifp, m); 1205122689Ssam RL_LOCK(sc); 120640516Swpaul } 120740516Swpaul} 120840516Swpaul 120940516Swpaul/* 121040516Swpaul * A frame was downloaded to the chip. It's safe for us to clean up 121140516Swpaul * the list buffers. 121240516Swpaul */ 1213102335Salfredstatic void 1214131605Sbmsrl_txeof(struct rl_softc *sc) 121540516Swpaul{ 1216147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1217131605Sbms uint32_t txstat; 121840516Swpaul 1219131606Sbms RL_LOCK_ASSERT(sc); 1220131606Sbms 122140516Swpaul /* 122240516Swpaul * Go through our tx list and free mbufs for those 122340516Swpaul * frames that have been uploaded. 122440516Swpaul */ 122545633Swpaul do { 1226127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1227127783Sru break; 122845633Swpaul txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc)); 122945633Swpaul if (!(txstat & (RL_TXSTAT_TX_OK| 123045633Swpaul RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT))) 123140516Swpaul break; 123240516Swpaul 123345633Swpaul ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24; 123440516Swpaul 1235127783Sru bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1236127783Sru bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1237127783Sru m_freem(RL_LAST_TXMBUF(sc)); 1238127783Sru RL_LAST_TXMBUF(sc) = NULL; 1239141676Smlaier /* 1240141676Smlaier * If there was a transmit underrun, bump the TX threshold. 1241141676Smlaier * Make sure not to overflow the 63 * 32byte we can address 1242141676Smlaier * with the 6 available bit. 1243141676Smlaier */ 1244141676Smlaier if ((txstat & RL_TXSTAT_TX_UNDERRUN) && 1245141676Smlaier (sc->rl_txthresh < 2016)) 1246141676Smlaier sc->rl_txthresh += 32; 124745633Swpaul if (txstat & RL_TXSTAT_TX_OK) 124845633Swpaul ifp->if_opackets++; 124945633Swpaul else { 125052426Swpaul int oldthresh; 125145633Swpaul ifp->if_oerrors++; 125245633Swpaul if ((txstat & RL_TXSTAT_TXABRT) || 125345633Swpaul (txstat & RL_TXSTAT_OUTOFWIN)) 125445633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 125552426Swpaul oldthresh = sc->rl_txthresh; 125652426Swpaul /* error recovery */ 125752426Swpaul rl_reset(sc); 1258131841Sbms rl_init_locked(sc); 1259141676Smlaier /* restore original threshold */ 1260141676Smlaier sc->rl_txthresh = oldthresh; 126152426Swpaul return; 126245633Swpaul } 126345633Swpaul RL_INC(sc->rl_cdata.last_tx); 1264148887Srwatson ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 126545633Swpaul } while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx); 126640516Swpaul 1267127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1268127783Sru ifp->if_timer = 0; 1269127783Sru else if (ifp->if_timer == 0) 1270127783Sru ifp->if_timer = 5; 127150703Swpaul} 127240516Swpaul 1273102335Salfredstatic void 1274131605Sbmsrl_tick(void *xsc) 127550703Swpaul{ 1276131605Sbms struct rl_softc *sc = xsc; 127750703Swpaul struct mii_data *mii; 127850703Swpaul 1279150720Sjhb RL_LOCK_ASSERT(sc); 128050703Swpaul mii = device_get_softc(sc->rl_miibus); 128150703Swpaul mii_tick(mii); 128250703Swpaul 1283150720Sjhb callout_reset(&sc->rl_stat_callout, hz, rl_tick, sc); 128440516Swpaul} 128540516Swpaul 128694883Sluigi#ifdef DEVICE_POLLING 128794883Sluigistatic void 1288131841Sbmsrl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 128994883Sluigi{ 129094883Sluigi struct rl_softc *sc = ifp->if_softc; 129194883Sluigi 129294883Sluigi RL_LOCK(sc); 1293150789Sglebius if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1294150789Sglebius rl_poll_locked(ifp, cmd, count); 1295131841Sbms RL_UNLOCK(sc); 1296131841Sbms} 1297131605Sbms 1298131841Sbmsstatic void 1299131841Sbmsrl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) 1300131841Sbms{ 1301131841Sbms struct rl_softc *sc = ifp->if_softc; 1302131841Sbms 1303131841Sbms RL_LOCK_ASSERT(sc); 1304131841Sbms 130594883Sluigi sc->rxcycles = count; 1306119868Swpaul rl_rxeof(sc); 1307119868Swpaul rl_txeof(sc); 1308131605Sbms 1309131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1310131841Sbms rl_start_locked(ifp); 131194883Sluigi 1312131605Sbms if (cmd == POLL_AND_CHECK_STATUS) { 1313131605Sbms uint16_t status; 131494883Sluigi 1315131605Sbms /* We should also check the status register. */ 131694883Sluigi status = CSR_READ_2(sc, RL_ISR); 1317100957Sjhb if (status == 0xffff) 1318131841Sbms return; 1319131605Sbms if (status != 0) 132094883Sluigi CSR_WRITE_2(sc, RL_ISR, status); 132194883Sluigi 1322131605Sbms /* XXX We should check behaviour on receiver stalls. */ 132394883Sluigi 132494883Sluigi if (status & RL_ISR_SYSTEM_ERR) { 132594883Sluigi rl_reset(sc); 1326131841Sbms rl_init_locked(sc); 132794883Sluigi } 132894883Sluigi } 132994883Sluigi} 133094883Sluigi#endif /* DEVICE_POLLING */ 133194883Sluigi 1332102335Salfredstatic void 1333131605Sbmsrl_intr(void *arg) 133440516Swpaul{ 1335131605Sbms struct rl_softc *sc = arg; 1336147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1337131605Sbms uint16_t status; 133840516Swpaul 1339131606Sbms RL_LOCK(sc); 1340131606Sbms 1341131841Sbms if (sc->suspended) 1342131841Sbms goto done_locked; 134386822Siwasaki 134494883Sluigi#ifdef DEVICE_POLLING 1345150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 1346131841Sbms goto done_locked; 1347150789Sglebius#endif 1348131841Sbms 134940516Swpaul for (;;) { 135040516Swpaul status = CSR_READ_2(sc, RL_ISR); 1351131605Sbms /* If the card has gone away, the read returns 0xffff. */ 1352100957Sjhb if (status == 0xffff) 1353100957Sjhb break; 1354131605Sbms if (status != 0) 135540516Swpaul CSR_WRITE_2(sc, RL_ISR, status); 135640516Swpaul if ((status & RL_INTRS) == 0) 135740516Swpaul break; 135840516Swpaul if (status & RL_ISR_RX_OK) 135940516Swpaul rl_rxeof(sc); 136040516Swpaul if (status & RL_ISR_RX_ERR) 136140516Swpaul rl_rxeof(sc); 136245633Swpaul if ((status & RL_ISR_TX_OK) || (status & RL_ISR_TX_ERR)) 136340516Swpaul rl_txeof(sc); 136440516Swpaul if (status & RL_ISR_SYSTEM_ERR) { 136540516Swpaul rl_reset(sc); 1366131841Sbms rl_init_locked(sc); 136740516Swpaul } 136840516Swpaul } 136940516Swpaul 1370131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1371131841Sbms rl_start_locked(ifp); 1372131841Sbms 1373131841Sbmsdone_locked: 1374131606Sbms RL_UNLOCK(sc); 137540516Swpaul} 137640516Swpaul 137740516Swpaul/* 137840516Swpaul * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 137940516Swpaul * pointers to the fragment pointers. 138040516Swpaul */ 1381102335Salfredstatic int 1382131605Sbmsrl_encap(struct rl_softc *sc, struct mbuf *m_head) 138340516Swpaul{ 138441243Swpaul struct mbuf *m_new = NULL; 138540516Swpaul 1386131606Sbms RL_LOCK_ASSERT(sc); 1387131606Sbms 138840516Swpaul /* 138945633Swpaul * The RealTek is brain damaged and wants longword-aligned 139045633Swpaul * TX buffers, plus we can only have one fragment buffer 139145633Swpaul * per packet. We have to copy pretty much all the time. 139240516Swpaul */ 1393112839Ssilby m_new = m_defrag(m_head, M_DONTWAIT); 139440516Swpaul 1395113496Ssilby if (m_new == NULL) { 1396113496Ssilby m_freem(m_head); 1397131605Sbms return (1); 1398113496Ssilby } 139941243Swpaul m_head = m_new; 140040516Swpaul 140140516Swpaul /* Pad frames to at least 60 bytes. */ 140241243Swpaul if (m_head->m_pkthdr.len < RL_MIN_FRAMELEN) { 140355058Swpaul /* 140455058Swpaul * Make security concious people happy: zero out the 140555058Swpaul * bytes in the pad area, since we don't know what 140655058Swpaul * this mbuf cluster buffer's previous user might 140755058Swpaul * have left in it. 1408109109Sdes */ 140955058Swpaul bzero(mtod(m_head, char *) + m_head->m_pkthdr.len, 141055058Swpaul RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 141140516Swpaul m_head->m_pkthdr.len += 141252426Swpaul (RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 141341243Swpaul m_head->m_len = m_head->m_pkthdr.len; 141441243Swpaul } 141540516Swpaul 141645633Swpaul RL_CUR_TXMBUF(sc) = m_head; 141740516Swpaul 1418131605Sbms return (0); 141940516Swpaul} 142040516Swpaul 142140516Swpaul/* 142240516Swpaul * Main transmit routine. 142340516Swpaul */ 1424102335Salfredstatic void 1425131605Sbmsrl_start(struct ifnet *ifp) 142640516Swpaul{ 1427131605Sbms struct rl_softc *sc = ifp->if_softc; 142840516Swpaul 142967087Swpaul RL_LOCK(sc); 1430131841Sbms rl_start_locked(ifp); 1431131841Sbms RL_UNLOCK(sc); 1432131841Sbms} 143340516Swpaul 1434131841Sbmsstatic void 1435131841Sbmsrl_start_locked(struct ifnet *ifp) 1436131841Sbms{ 1437131841Sbms struct rl_softc *sc = ifp->if_softc; 1438131841Sbms struct mbuf *m_head = NULL; 1439131841Sbms 1440131841Sbms RL_LOCK_ASSERT(sc); 1441131841Sbms 1442131605Sbms while (RL_CUR_TXMBUF(sc) == NULL) { 1443131841Sbms 1444131455Smlaier IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); 1445131841Sbms 144640516Swpaul if (m_head == NULL) 144740516Swpaul break; 144840516Swpaul 1449131841Sbms if (rl_encap(sc, m_head)) 145058801Swpaul break; 145140516Swpaul 1452131605Sbms /* Pass a copy of this mbuf chain to the bpf subsystem. */ 1453106936Ssam BPF_MTAP(ifp, RL_CUR_TXMBUF(sc)); 145451583Swpaul 1455131605Sbms /* Transmit the frame. */ 145681713Swpaul bus_dmamap_create(sc->rl_tag, 0, &RL_CUR_DMAMAP(sc)); 145781713Swpaul bus_dmamap_load(sc->rl_tag, RL_CUR_DMAMAP(sc), 145881713Swpaul mtod(RL_CUR_TXMBUF(sc), void *), 1459119868Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len, rl_dma_map_txbuf, sc, 0); 146081713Swpaul bus_dmamap_sync(sc->rl_tag, RL_CUR_DMAMAP(sc), 146181713Swpaul BUS_DMASYNC_PREREAD); 146245633Swpaul CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc), 146352426Swpaul RL_TXTHRESH(sc->rl_txthresh) | 146452426Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len); 146545633Swpaul 146645633Swpaul RL_INC(sc->rl_cdata.cur_tx); 1467113237Ssilby 1468131605Sbms /* Set a timeout in case the chip goes out to lunch. */ 1469113237Ssilby ifp->if_timer = 5; 147040516Swpaul } 147140516Swpaul 147240516Swpaul /* 147345633Swpaul * We broke out of the loop because all our TX slots are 147445633Swpaul * full. Mark the NIC as busy until it drains some of the 147545633Swpaul * packets from the queue. 147645633Swpaul */ 147745633Swpaul if (RL_CUR_TXMBUF(sc) != NULL) 1478148887Srwatson ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1479131841Sbms} 148045633Swpaul 1481131841Sbmsstatic void 1482131841Sbmsrl_init(void *xsc) 1483131841Sbms{ 1484131841Sbms struct rl_softc *sc = xsc; 1485131841Sbms 1486131841Sbms RL_LOCK(sc); 1487131841Sbms rl_init_locked(sc); 148867087Swpaul RL_UNLOCK(sc); 148940516Swpaul} 149040516Swpaul 1491102335Salfredstatic void 1492131841Sbmsrl_init_locked(struct rl_softc *sc) 149340516Swpaul{ 1494147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 149550703Swpaul struct mii_data *mii; 1496131605Sbms uint32_t rxcfg = 0; 149740516Swpaul 1498131841Sbms RL_LOCK_ASSERT(sc); 1499131841Sbms 150050703Swpaul mii = device_get_softc(sc->rl_miibus); 150140516Swpaul 150240516Swpaul /* 150340516Swpaul * Cancel pending I/O and free all RX/TX buffers. 150440516Swpaul */ 150540516Swpaul rl_stop(sc); 150640516Swpaul 1507117029Swpaul /* 1508117029Swpaul * Init our MAC address. Even though the chipset 1509117029Swpaul * documentation doesn't mention it, we need to enter "Config 1510117029Swpaul * register write enable" mode to modify the ID registers. 1511117029Swpaul */ 1512117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG); 1513119738Stmm CSR_WRITE_STREAM_4(sc, RL_IDR0, 1514152315Sru *(uint32_t *)(&IF_LLADDR(sc->rl_ifp)[0])); 1515119738Stmm CSR_WRITE_STREAM_4(sc, RL_IDR4, 1516152315Sru *(uint32_t *)(&IF_LLADDR(sc->rl_ifp)[4])); 1517117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 151840516Swpaul 1519119868Swpaul /* Init the RX buffer pointer register. */ 1520119868Swpaul bus_dmamap_load(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1521119868Swpaul sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN, rl_dma_map_rxbuf, sc, 0); 1522119868Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1523119868Swpaul BUS_DMASYNC_PREWRITE); 152440516Swpaul 1525119868Swpaul /* Init TX descriptors. */ 1526119868Swpaul rl_list_tx_init(sc); 152740516Swpaul 152840516Swpaul /* 152940516Swpaul * Enable transmit and receive. 153040516Swpaul */ 153140516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 153240516Swpaul 153340516Swpaul /* 153445633Swpaul * Set the initial TX and RX configuration. 153540516Swpaul */ 153645633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 153740516Swpaul CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); 153840516Swpaul 153940516Swpaul /* Set the individual bit to receive frames for this host only. */ 154040516Swpaul rxcfg = CSR_READ_4(sc, RL_RXCFG); 154140516Swpaul rxcfg |= RL_RXCFG_RX_INDIV; 154240516Swpaul 154340516Swpaul /* If we want promiscuous mode, set the allframes bit. */ 154440516Swpaul if (ifp->if_flags & IFF_PROMISC) { 154540516Swpaul rxcfg |= RL_RXCFG_RX_ALLPHYS; 154640516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 154740516Swpaul } else { 154840516Swpaul rxcfg &= ~RL_RXCFG_RX_ALLPHYS; 154940516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 155040516Swpaul } 155140516Swpaul 1552131605Sbms /* Set capture broadcast bit to capture broadcast frames. */ 155340516Swpaul if (ifp->if_flags & IFF_BROADCAST) { 155440516Swpaul rxcfg |= RL_RXCFG_RX_BROAD; 155540516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 155640516Swpaul } else { 155740516Swpaul rxcfg &= ~RL_RXCFG_RX_BROAD; 155840516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 155940516Swpaul } 156040516Swpaul 1561131605Sbms /* Program the multicast filter, if necessary. */ 156240516Swpaul rl_setmulti(sc); 156340516Swpaul 156494883Sluigi#ifdef DEVICE_POLLING 1565131605Sbms /* Disable interrupts if we are polling. */ 1566150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 156794883Sluigi CSR_WRITE_2(sc, RL_IMR, 0); 1568131605Sbms else 1569150789Sglebius#endif 1570131605Sbms /* Enable interrupts. */ 1571119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 157240516Swpaul 157352426Swpaul /* Set initial TX threshold */ 157452426Swpaul sc->rl_txthresh = RL_TX_THRESH_INIT; 157552426Swpaul 157640516Swpaul /* Start RX/TX process. */ 157740516Swpaul CSR_WRITE_4(sc, RL_MISSEDPKT, 0); 1578119868Swpaul 157940516Swpaul /* Enable receiver and transmitter. */ 158040516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 158140516Swpaul 158250703Swpaul mii_mediachg(mii); 158340516Swpaul 158440516Swpaul CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); 158540516Swpaul 1586148887Srwatson ifp->if_drv_flags |= IFF_DRV_RUNNING; 1587148887Srwatson ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 158840516Swpaul 1589150720Sjhb callout_reset(&sc->rl_stat_callout, hz, rl_tick, sc); 159040516Swpaul} 159140516Swpaul 159240516Swpaul/* 159340516Swpaul * Set media options. 159440516Swpaul */ 1595102335Salfredstatic int 1596131605Sbmsrl_ifmedia_upd(struct ifnet *ifp) 159740516Swpaul{ 1598131605Sbms struct rl_softc *sc = ifp->if_softc; 159950703Swpaul struct mii_data *mii; 160040516Swpaul 160150703Swpaul mii = device_get_softc(sc->rl_miibus); 1602131605Sbms 1603150720Sjhb RL_LOCK(sc); 160450703Swpaul mii_mediachg(mii); 1605150720Sjhb RL_UNLOCK(sc); 160640516Swpaul 1607131605Sbms return (0); 160840516Swpaul} 160940516Swpaul 161040516Swpaul/* 161140516Swpaul * Report current media status. 161240516Swpaul */ 1613102335Salfredstatic void 1614131605Sbmsrl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 161540516Swpaul{ 1616131605Sbms struct rl_softc *sc = ifp->if_softc; 161750703Swpaul struct mii_data *mii; 161840516Swpaul 161950703Swpaul mii = device_get_softc(sc->rl_miibus); 162040516Swpaul 1621150720Sjhb RL_LOCK(sc); 162250703Swpaul mii_pollstat(mii); 1623150720Sjhb RL_UNLOCK(sc); 162450703Swpaul ifmr->ifm_active = mii->mii_media_active; 162550703Swpaul ifmr->ifm_status = mii->mii_media_status; 162640516Swpaul} 162740516Swpaul 1628102335Salfredstatic int 1629131605Sbmsrl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 163040516Swpaul{ 1631131605Sbms struct ifreq *ifr = (struct ifreq *)data; 1632131605Sbms struct mii_data *mii; 163340516Swpaul struct rl_softc *sc = ifp->if_softc; 163467087Swpaul int error = 0; 163540516Swpaul 1636131605Sbms switch (command) { 163740516Swpaul case SIOCSIFFLAGS: 1638131841Sbms RL_LOCK(sc); 163940516Swpaul if (ifp->if_flags & IFF_UP) { 1640131841Sbms rl_init_locked(sc); 164140516Swpaul } else { 1642148887Srwatson if (ifp->if_drv_flags & IFF_DRV_RUNNING) 164340516Swpaul rl_stop(sc); 164440516Swpaul } 1645131841Sbms RL_UNLOCK(sc); 164640516Swpaul error = 0; 164740516Swpaul break; 164840516Swpaul case SIOCADDMULTI: 164940516Swpaul case SIOCDELMULTI: 1650131606Sbms RL_LOCK(sc); 165140516Swpaul rl_setmulti(sc); 1652131606Sbms RL_UNLOCK(sc); 165340516Swpaul error = 0; 165440516Swpaul break; 165540516Swpaul case SIOCGIFMEDIA: 165640516Swpaul case SIOCSIFMEDIA: 165750703Swpaul mii = device_get_softc(sc->rl_miibus); 165850703Swpaul error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 165940516Swpaul break; 1660128121Sru case SIOCSIFCAP: 1661150789Sglebius#ifdef DEVICE_POLLING 1662150789Sglebius if (ifr->ifr_reqcap & IFCAP_POLLING && 1663150789Sglebius !(ifp->if_capenable & IFCAP_POLLING)) { 1664150789Sglebius error = ether_poll_register(rl_poll, ifp); 1665150789Sglebius if (error) 1666150789Sglebius return(error); 1667150789Sglebius RL_LOCK(sc); 1668150789Sglebius /* Disable interrupts */ 1669150789Sglebius CSR_WRITE_2(sc, RL_IMR, 0x0000); 1670150789Sglebius ifp->if_capenable |= IFCAP_POLLING; 1671150789Sglebius RL_UNLOCK(sc); 1672150789Sglebius return (error); 1673150789Sglebius 1674150789Sglebius } 1675150789Sglebius if (!(ifr->ifr_reqcap & IFCAP_POLLING) && 1676150789Sglebius ifp->if_capenable & IFCAP_POLLING) { 1677150789Sglebius error = ether_poll_deregister(ifp); 1678150789Sglebius /* Enable interrupts. */ 1679150789Sglebius RL_LOCK(sc); 1680150789Sglebius CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 1681150789Sglebius ifp->if_capenable &= ~IFCAP_POLLING; 1682150789Sglebius RL_UNLOCK(sc); 1683150789Sglebius return (error); 1684150789Sglebius } 1685150789Sglebius#endif /* DEVICE_POLLING */ 1686128121Sru break; 168740516Swpaul default: 1688106936Ssam error = ether_ioctl(ifp, command, data); 168940516Swpaul break; 169040516Swpaul } 169140516Swpaul 1692131605Sbms return (error); 169340516Swpaul} 169440516Swpaul 1695102335Salfredstatic void 1696131605Sbmsrl_watchdog(struct ifnet *ifp) 169740516Swpaul{ 1698131605Sbms struct rl_softc *sc = ifp->if_softc; 169940516Swpaul 170067087Swpaul RL_LOCK(sc); 1701131605Sbms 1702131605Sbms if_printf(ifp, "watchdog timeout\n"); 170340516Swpaul ifp->if_oerrors++; 170450703Swpaul 1705119868Swpaul rl_txeof(sc); 1706119868Swpaul rl_rxeof(sc); 1707131841Sbms rl_init_locked(sc); 1708131605Sbms 170967087Swpaul RL_UNLOCK(sc); 171040516Swpaul} 171140516Swpaul 171240516Swpaul/* 171340516Swpaul * Stop the adapter and free any mbufs allocated to the 171440516Swpaul * RX and TX lists. 171540516Swpaul */ 1716102335Salfredstatic void 1717131605Sbmsrl_stop(struct rl_softc *sc) 171840516Swpaul{ 171940516Swpaul register int i; 1720147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 172140516Swpaul 1722131606Sbms RL_LOCK_ASSERT(sc); 1723131606Sbms 172440516Swpaul ifp->if_timer = 0; 1725150720Sjhb callout_stop(&sc->rl_stat_callout); 1726148887Srwatson ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 172750703Swpaul 172840516Swpaul CSR_WRITE_1(sc, RL_COMMAND, 0x00); 172940516Swpaul CSR_WRITE_2(sc, RL_IMR, 0x0000); 1730119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 173140516Swpaul 1732119868Swpaul /* 1733119868Swpaul * Free the TX list buffers. 1734119868Swpaul */ 1735119868Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 1736119868Swpaul if (sc->rl_cdata.rl_tx_chain[i] != NULL) { 1737119868Swpaul bus_dmamap_unload(sc->rl_tag, 1738119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1739119868Swpaul bus_dmamap_destroy(sc->rl_tag, 1740119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1741119868Swpaul m_freem(sc->rl_cdata.rl_tx_chain[i]); 1742119868Swpaul sc->rl_cdata.rl_tx_chain[i] = NULL; 1743131605Sbms CSR_WRITE_4(sc, RL_TXADDR0 + (i * sizeof(uint32_t)), 1744124816Swpaul 0x0000000); 174540516Swpaul } 174640516Swpaul } 174740516Swpaul} 174840516Swpaul 174940516Swpaul/* 175086822Siwasaki * Device suspend routine. Stop the interface and save some PCI 175186822Siwasaki * settings in case the BIOS doesn't restore them properly on 175286822Siwasaki * resume. 175386822Siwasaki */ 1754102335Salfredstatic int 1755131605Sbmsrl_suspend(device_t dev) 175686822Siwasaki{ 175786822Siwasaki struct rl_softc *sc; 175886822Siwasaki 175986822Siwasaki sc = device_get_softc(dev); 1760131606Sbms 1761131606Sbms RL_LOCK(sc); 176286822Siwasaki rl_stop(sc); 176386822Siwasaki sc->suspended = 1; 1764131606Sbms RL_UNLOCK(sc); 176586822Siwasaki 176686822Siwasaki return (0); 176786822Siwasaki} 176886822Siwasaki 176986822Siwasaki/* 177086822Siwasaki * Device resume routine. Restore some PCI settings in case the BIOS 177186822Siwasaki * doesn't, re-enable busmastering, and restart the interface if 177286822Siwasaki * appropriate. 177386822Siwasaki */ 1774102335Salfredstatic int 1775131605Sbmsrl_resume(device_t dev) 177686822Siwasaki{ 177786822Siwasaki struct rl_softc *sc; 177886822Siwasaki struct ifnet *ifp; 177986822Siwasaki 178086822Siwasaki sc = device_get_softc(dev); 1781147256Sbrooks ifp = sc->rl_ifp; 178286822Siwasaki 1783131841Sbms RL_LOCK(sc); 1784131841Sbms 1785109109Sdes /* reinitialize interface if necessary */ 1786109109Sdes if (ifp->if_flags & IFF_UP) 1787131841Sbms rl_init_locked(sc); 178886822Siwasaki 178986822Siwasaki sc->suspended = 0; 1790131841Sbms 1791131606Sbms RL_UNLOCK(sc); 179286822Siwasaki 179386822Siwasaki return (0); 179486822Siwasaki} 179586822Siwasaki 179686822Siwasaki/* 179740516Swpaul * Stop all chip I/O so that the kernel's probe routines don't 179840516Swpaul * get confused by errant DMAs when rebooting. 179940516Swpaul */ 1800102335Salfredstatic void 1801131605Sbmsrl_shutdown(device_t dev) 180240516Swpaul{ 180350703Swpaul struct rl_softc *sc; 180440516Swpaul 180550703Swpaul sc = device_get_softc(dev); 1806131606Sbms 1807131606Sbms RL_LOCK(sc); 180840516Swpaul rl_stop(sc); 1809131606Sbms RL_UNLOCK(sc); 181040516Swpaul} 1811