if_rl.c revision 178054
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 178054 2008-04-10 01:06:05Z yongari $"); 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" }, 169173948Sremko { PLANEX_VENDORID, PLANEX_DEVICEID_FNW3603TX, RL_8139, 170173948Sremko "Planex FNW-3603-TX" }, 171117388Swpaul { PLANEX_VENDORID, PLANEX_DEVICEID_FNW3800TX, RL_8139, 172112379Ssanpei "Planex FNW-3800-TX" }, 173117388Swpaul { CP_VENDORID, RT_DEVICEID_8139, RL_8139, 174117388Swpaul "Compaq HNE-300" }, 175117388Swpaul { LEVEL1_VENDORID, LEVEL1_DEVICEID_FPC0106TX, RL_8139, 176117388Swpaul "LevelOne FPC-0106TX" }, 177117388Swpaul { EDIMAX_VENDORID, EDIMAX_DEVICEID_EP4103DL, RL_8139, 178176757Syongari "Edimax EP-4103DL CardBus" } 17940516Swpaul}; 18040516Swpaul 181142407Simpstatic int rl_attach(device_t); 182142407Simpstatic int rl_detach(device_t); 183142407Simpstatic void rl_dma_map_rxbuf(void *, bus_dma_segment_t *, int, int); 184142407Simpstatic void rl_dma_map_txbuf(void *, bus_dma_segment_t *, int, int); 185142407Simpstatic void rl_eeprom_putbyte(struct rl_softc *, int); 186142407Simpstatic void rl_eeprom_getword(struct rl_softc *, int, uint16_t *); 187142407Simpstatic int rl_encap(struct rl_softc *, struct mbuf * ); 188142407Simpstatic int rl_list_tx_init(struct rl_softc *); 189142407Simpstatic int rl_ifmedia_upd(struct ifnet *); 190142407Simpstatic void rl_ifmedia_sts(struct ifnet *, struct ifmediareq *); 191142407Simpstatic int rl_ioctl(struct ifnet *, u_long, caddr_t); 192142407Simpstatic void rl_intr(void *); 193142407Simpstatic void rl_init(void *); 194142407Simpstatic void rl_init_locked(struct rl_softc *sc); 195142407Simpstatic void rl_mii_send(struct rl_softc *, uint32_t, int); 196142407Simpstatic void rl_mii_sync(struct rl_softc *); 197142407Simpstatic int rl_mii_readreg(struct rl_softc *, struct rl_mii_frame *); 198142407Simpstatic int rl_mii_writereg(struct rl_softc *, struct rl_mii_frame *); 199142407Simpstatic int rl_miibus_readreg(device_t, int, int); 200142407Simpstatic void rl_miibus_statchg(device_t); 201142407Simpstatic int rl_miibus_writereg(device_t, int, int, int); 202131841Sbms#ifdef DEVICE_POLLING 203150789Sglebiusstatic void rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); 204150789Sglebiusstatic void rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); 205131841Sbms#endif 206142407Simpstatic int rl_probe(device_t); 207142407Simpstatic void rl_read_eeprom(struct rl_softc *, uint8_t *, int, int, int); 208142407Simpstatic void rl_reset(struct rl_softc *); 209142407Simpstatic int rl_resume(device_t); 210142407Simpstatic void rl_rxeof(struct rl_softc *); 211142407Simpstatic void rl_setmulti(struct rl_softc *); 212173839Syongaristatic int rl_shutdown(device_t); 213142407Simpstatic void rl_start(struct ifnet *); 214142407Simpstatic void rl_start_locked(struct ifnet *); 215142407Simpstatic void rl_stop(struct rl_softc *); 216142407Simpstatic int rl_suspend(device_t); 217142407Simpstatic void rl_tick(void *); 218142407Simpstatic void rl_txeof(struct rl_softc *); 219164811Srustatic void rl_watchdog(struct rl_softc *); 22040516Swpaul 22150703Swpaul#ifdef RL_USEIOSPACE 22250703Swpaul#define RL_RES SYS_RES_IOPORT 22350703Swpaul#define RL_RID RL_PCI_LOIO 22450703Swpaul#else 22550703Swpaul#define RL_RES SYS_RES_MEMORY 22650703Swpaul#define RL_RID RL_PCI_LOMEM 22750703Swpaul#endif 22850703Swpaul 22950703Swpaulstatic device_method_t rl_methods[] = { 23050703Swpaul /* Device interface */ 23150703Swpaul DEVMETHOD(device_probe, rl_probe), 23250703Swpaul DEVMETHOD(device_attach, rl_attach), 23350703Swpaul DEVMETHOD(device_detach, rl_detach), 23486822Siwasaki DEVMETHOD(device_suspend, rl_suspend), 23586822Siwasaki DEVMETHOD(device_resume, rl_resume), 23650703Swpaul DEVMETHOD(device_shutdown, rl_shutdown), 23750703Swpaul 23850703Swpaul /* bus interface */ 23950703Swpaul DEVMETHOD(bus_print_child, bus_generic_print_child), 24050703Swpaul DEVMETHOD(bus_driver_added, bus_generic_driver_added), 24150703Swpaul 24250703Swpaul /* MII interface */ 24350703Swpaul DEVMETHOD(miibus_readreg, rl_miibus_readreg), 24450703Swpaul DEVMETHOD(miibus_writereg, rl_miibus_writereg), 24550703Swpaul DEVMETHOD(miibus_statchg, rl_miibus_statchg), 24650703Swpaul 24750703Swpaul { 0, 0 } 24850703Swpaul}; 24950703Swpaul 25050703Swpaulstatic driver_t rl_driver = { 25151455Swpaul "rl", 25250703Swpaul rl_methods, 25350703Swpaul sizeof(struct rl_softc) 25450703Swpaul}; 25550703Swpaul 25650703Swpaulstatic devclass_t rl_devclass; 25750703Swpaul 258113506SmdoddDRIVER_MODULE(rl, pci, rl_driver, rl_devclass, 0, 0); 259123019SimpDRIVER_MODULE(rl, cardbus, rl_driver, rl_devclass, 0, 0); 26051473SwpaulDRIVER_MODULE(miibus, rl, miibus_driver, miibus_devclass, 0, 0); 26150703Swpaul 26240516Swpaul#define EE_SET(x) \ 26340516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26440516Swpaul CSR_READ_1(sc, RL_EECMD) | x) 26540516Swpaul 26640516Swpaul#define EE_CLR(x) \ 26740516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26840516Swpaul CSR_READ_1(sc, RL_EECMD) & ~x) 26940516Swpaul 27081713Swpaulstatic void 271131605Sbmsrl_dma_map_rxbuf(void *arg, bus_dma_segment_t *segs, int nseg, int error) 27281713Swpaul{ 273131605Sbms struct rl_softc *sc = arg; 27481713Swpaul 27581713Swpaul CSR_WRITE_4(sc, RL_RXADDR, segs->ds_addr & 0xFFFFFFFF); 27681713Swpaul} 27781713Swpaul 27881713Swpaulstatic void 279131605Sbmsrl_dma_map_txbuf(void *arg, bus_dma_segment_t *segs, int nseg, int error) 28081713Swpaul{ 281131605Sbms struct rl_softc *sc = arg; 28281713Swpaul 28381713Swpaul CSR_WRITE_4(sc, RL_CUR_TXADDR(sc), segs->ds_addr & 0xFFFFFFFF); 28481713Swpaul} 28581713Swpaul 28640516Swpaul/* 28740516Swpaul * Send a read command and address to the EEPROM, check for ACK. 28840516Swpaul */ 289102335Salfredstatic void 290131605Sbmsrl_eeprom_putbyte(struct rl_softc *sc, int addr) 29140516Swpaul{ 29240516Swpaul register int d, i; 29340516Swpaul 29467931Swpaul d = addr | sc->rl_eecmd_read; 29540516Swpaul 29640516Swpaul /* 29755170Sbillf * Feed in each bit and strobe the clock. 29840516Swpaul */ 29940516Swpaul for (i = 0x400; i; i >>= 1) { 30040516Swpaul if (d & i) { 30140516Swpaul EE_SET(RL_EE_DATAIN); 30240516Swpaul } else { 30340516Swpaul EE_CLR(RL_EE_DATAIN); 30440516Swpaul } 30540516Swpaul DELAY(100); 30640516Swpaul EE_SET(RL_EE_CLK); 30740516Swpaul DELAY(150); 30840516Swpaul EE_CLR(RL_EE_CLK); 30940516Swpaul DELAY(100); 31040516Swpaul } 31140516Swpaul} 31240516Swpaul 31340516Swpaul/* 31440516Swpaul * Read a word of data stored in the EEPROM at address 'addr.' 31540516Swpaul */ 316102335Salfredstatic void 317131605Sbmsrl_eeprom_getword(struct rl_softc *sc, int addr, uint16_t *dest) 31840516Swpaul{ 31940516Swpaul register int i; 320131605Sbms uint16_t word = 0; 32140516Swpaul 32240516Swpaul /* Enter EEPROM access mode. */ 32340516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 32440516Swpaul 32540516Swpaul /* 32640516Swpaul * Send address of word we want to read. 32740516Swpaul */ 32840516Swpaul rl_eeprom_putbyte(sc, addr); 32940516Swpaul 33040516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 33140516Swpaul 33240516Swpaul /* 33340516Swpaul * Start reading bits from EEPROM. 33440516Swpaul */ 33540516Swpaul for (i = 0x8000; i; i >>= 1) { 33640516Swpaul EE_SET(RL_EE_CLK); 33740516Swpaul DELAY(100); 33840516Swpaul if (CSR_READ_1(sc, RL_EECMD) & RL_EE_DATAOUT) 33940516Swpaul word |= i; 34040516Swpaul EE_CLR(RL_EE_CLK); 34140516Swpaul DELAY(100); 34240516Swpaul } 34340516Swpaul 34440516Swpaul /* Turn off EEPROM access mode. */ 34540516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 34640516Swpaul 34740516Swpaul *dest = word; 34840516Swpaul} 34940516Swpaul 35040516Swpaul/* 35140516Swpaul * Read a sequence of words from the EEPROM. 35240516Swpaul */ 353102335Salfredstatic void 354131605Sbmsrl_read_eeprom(struct rl_softc *sc, uint8_t *dest, int off, int cnt, int swap) 35540516Swpaul{ 35640516Swpaul int i; 357131605Sbms uint16_t word = 0, *ptr; 35840516Swpaul 35940516Swpaul for (i = 0; i < cnt; i++) { 36040516Swpaul rl_eeprom_getword(sc, off + i, &word); 361131605Sbms ptr = (uint16_t *)(dest + (i * 2)); 36240516Swpaul if (swap) 36340516Swpaul *ptr = ntohs(word); 36440516Swpaul else 36540516Swpaul *ptr = word; 36640516Swpaul } 36740516Swpaul} 36840516Swpaul 36940516Swpaul/* 37040516Swpaul * MII access routines are provided for the 8129, which 37140516Swpaul * doesn't have a built-in PHY. For the 8139, we fake things 37240516Swpaul * up by diverting rl_phy_readreg()/rl_phy_writereg() to the 37340516Swpaul * direct access PHY registers. 37440516Swpaul */ 37540516Swpaul#define MII_SET(x) \ 37640516Swpaul CSR_WRITE_1(sc, RL_MII, \ 377105221Sphk CSR_READ_1(sc, RL_MII) | (x)) 37840516Swpaul 37940516Swpaul#define MII_CLR(x) \ 38040516Swpaul CSR_WRITE_1(sc, RL_MII, \ 381105221Sphk CSR_READ_1(sc, RL_MII) & ~(x)) 38240516Swpaul 38340516Swpaul/* 38440516Swpaul * Sync the PHYs by setting data bit and strobing the clock 32 times. 38540516Swpaul */ 386102335Salfredstatic void 387131605Sbmsrl_mii_sync(struct rl_softc *sc) 38840516Swpaul{ 38940516Swpaul register int i; 39040516Swpaul 39140516Swpaul MII_SET(RL_MII_DIR|RL_MII_DATAOUT); 39240516Swpaul 39340516Swpaul for (i = 0; i < 32; i++) { 39440516Swpaul MII_SET(RL_MII_CLK); 39540516Swpaul DELAY(1); 39640516Swpaul MII_CLR(RL_MII_CLK); 39740516Swpaul DELAY(1); 39840516Swpaul } 39940516Swpaul} 40040516Swpaul 40140516Swpaul/* 40240516Swpaul * Clock a series of bits through the MII. 40340516Swpaul */ 404102335Salfredstatic void 405131605Sbmsrl_mii_send(struct rl_softc *sc, uint32_t bits, int cnt) 40640516Swpaul{ 40740516Swpaul int i; 40840516Swpaul 40940516Swpaul MII_CLR(RL_MII_CLK); 41040516Swpaul 41140516Swpaul for (i = (0x1 << (cnt - 1)); i; i >>= 1) { 412109109Sdes if (bits & i) { 41340516Swpaul MII_SET(RL_MII_DATAOUT); 414109109Sdes } else { 41540516Swpaul MII_CLR(RL_MII_DATAOUT); 416109109Sdes } 41740516Swpaul DELAY(1); 41840516Swpaul MII_CLR(RL_MII_CLK); 41940516Swpaul DELAY(1); 42040516Swpaul MII_SET(RL_MII_CLK); 42140516Swpaul } 42240516Swpaul} 42340516Swpaul 42440516Swpaul/* 42540516Swpaul * Read an PHY register through the MII. 42640516Swpaul */ 427102335Salfredstatic int 428131605Sbmsrl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame) 42940516Swpaul{ 43067087Swpaul int i, ack; 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 499131605Sbms return (ack ? 1 : 0); 50040516Swpaul} 50140516Swpaul 50240516Swpaul/* 50340516Swpaul * Write to a PHY register through the MII. 50440516Swpaul */ 505102335Salfredstatic int 506131605Sbmsrl_mii_writereg(struct rl_softc *sc, struct rl_mii_frame *frame) 507131605Sbms{ 508109109Sdes 509131605Sbms /* Set up frame for TX. */ 51040516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 51140516Swpaul frame->mii_opcode = RL_MII_WRITEOP; 51240516Swpaul frame->mii_turnaround = RL_MII_TURNAROUND; 513109109Sdes 514131605Sbms /* Turn on data output. */ 51540516Swpaul MII_SET(RL_MII_DIR); 51640516Swpaul 51740516Swpaul rl_mii_sync(sc); 51840516Swpaul 51940516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 52040516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 52140516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 52240516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 52340516Swpaul rl_mii_send(sc, frame->mii_turnaround, 2); 52440516Swpaul rl_mii_send(sc, frame->mii_data, 16); 52540516Swpaul 52640516Swpaul /* Idle bit. */ 52740516Swpaul MII_SET(RL_MII_CLK); 52840516Swpaul DELAY(1); 52940516Swpaul MII_CLR(RL_MII_CLK); 53040516Swpaul DELAY(1); 53140516Swpaul 532131605Sbms /* Turn off xmit. */ 53340516Swpaul MII_CLR(RL_MII_DIR); 53440516Swpaul 535131605Sbms return (0); 53640516Swpaul} 53740516Swpaul 538102335Salfredstatic int 539131605Sbmsrl_miibus_readreg(device_t dev, int phy, int reg) 54050703Swpaul{ 54140516Swpaul struct rl_softc *sc; 54240516Swpaul struct rl_mii_frame frame; 543131605Sbms uint16_t rval = 0; 544131605Sbms uint16_t rl8139_reg = 0; 54540516Swpaul 54650703Swpaul sc = device_get_softc(dev); 54750703Swpaul 548119868Swpaul if (sc->rl_type == RL_8139) { 54950703Swpaul /* Pretend the internal PHY is only at address 0 */ 55067087Swpaul if (phy) { 551131605Sbms return (0); 55267087Swpaul } 553131605Sbms switch (reg) { 55450703Swpaul case MII_BMCR: 55540516Swpaul rl8139_reg = RL_BMCR; 55640516Swpaul break; 55750703Swpaul case MII_BMSR: 55840516Swpaul rl8139_reg = RL_BMSR; 55940516Swpaul break; 56050703Swpaul case MII_ANAR: 56140516Swpaul rl8139_reg = RL_ANAR; 56240516Swpaul break; 56350703Swpaul case MII_ANER: 56450703Swpaul rl8139_reg = RL_ANER; 56550703Swpaul break; 56650703Swpaul case MII_ANLPAR: 56740516Swpaul rl8139_reg = RL_LPAR; 56840516Swpaul break; 56950703Swpaul case MII_PHYIDR1: 57050703Swpaul case MII_PHYIDR2: 571131605Sbms return (0); 57294149Swpaul /* 57394149Swpaul * Allow the rlphy driver to read the media status 57494149Swpaul * register. If we have a link partner which does not 57594149Swpaul * support NWAY, this is the register which will tell 57694149Swpaul * us the results of parallel detection. 57794149Swpaul */ 57894149Swpaul case RL_MEDIASTAT: 57994149Swpaul rval = CSR_READ_1(sc, RL_MEDIASTAT); 580131605Sbms return (rval); 58140516Swpaul default: 582162315Sglebius device_printf(sc->rl_dev, "bad phy register\n"); 583131605Sbms return (0); 58440516Swpaul } 58540516Swpaul rval = CSR_READ_2(sc, rl8139_reg); 586131605Sbms return (rval); 58740516Swpaul } 58840516Swpaul 58940516Swpaul bzero((char *)&frame, sizeof(frame)); 59050703Swpaul frame.mii_phyaddr = phy; 59140516Swpaul frame.mii_regaddr = reg; 59240516Swpaul rl_mii_readreg(sc, &frame); 593131605Sbms 594131605Sbms return (frame.mii_data); 59540516Swpaul} 59640516Swpaul 597102335Salfredstatic int 598131605Sbmsrl_miibus_writereg(device_t dev, int phy, int reg, int data) 59950703Swpaul{ 60040516Swpaul struct rl_softc *sc; 60140516Swpaul struct rl_mii_frame frame; 602131605Sbms uint16_t rl8139_reg = 0; 60340516Swpaul 60450703Swpaul sc = device_get_softc(dev); 60550703Swpaul 606119868Swpaul if (sc->rl_type == RL_8139) { 60750703Swpaul /* Pretend the internal PHY is only at address 0 */ 60867087Swpaul if (phy) { 609131605Sbms return (0); 61067087Swpaul } 611131605Sbms switch (reg) { 61250703Swpaul case MII_BMCR: 61340516Swpaul rl8139_reg = RL_BMCR; 61440516Swpaul break; 61550703Swpaul case MII_BMSR: 61640516Swpaul rl8139_reg = RL_BMSR; 61740516Swpaul break; 61850703Swpaul case MII_ANAR: 61940516Swpaul rl8139_reg = RL_ANAR; 62040516Swpaul break; 62150703Swpaul case MII_ANER: 62250703Swpaul rl8139_reg = RL_ANER; 62350703Swpaul break; 62450703Swpaul case MII_ANLPAR: 62540516Swpaul rl8139_reg = RL_LPAR; 62640516Swpaul break; 62750703Swpaul case MII_PHYIDR1: 62850703Swpaul case MII_PHYIDR2: 629131605Sbms return (0); 63050703Swpaul break; 63140516Swpaul default: 632162315Sglebius device_printf(sc->rl_dev, "bad phy register\n"); 633131605Sbms return (0); 63440516Swpaul } 63540516Swpaul CSR_WRITE_2(sc, rl8139_reg, data); 636131605Sbms return (0); 63740516Swpaul } 63840516Swpaul 63940516Swpaul bzero((char *)&frame, sizeof(frame)); 64050703Swpaul frame.mii_phyaddr = phy; 64140516Swpaul frame.mii_regaddr = reg; 64240516Swpaul frame.mii_data = data; 64340516Swpaul rl_mii_writereg(sc, &frame); 64440516Swpaul 645131605Sbms return (0); 64650703Swpaul} 64750703Swpaul 648102335Salfredstatic void 649131605Sbmsrl_miibus_statchg(device_t dev) 65050703Swpaul{ 65140516Swpaul} 65240516Swpaul 65340516Swpaul/* 65440516Swpaul * Program the 64-bit multicast hash filter. 65540516Swpaul */ 656102335Salfredstatic void 657131605Sbmsrl_setmulti(struct rl_softc *sc) 65840516Swpaul{ 659147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 66040516Swpaul int h = 0; 661131605Sbms uint32_t hashes[2] = { 0, 0 }; 66240516Swpaul struct ifmultiaddr *ifma; 663131605Sbms uint32_t rxfilt; 66440516Swpaul int mcnt = 0; 66540516Swpaul 666131606Sbms RL_LOCK_ASSERT(sc); 667131606Sbms 66840516Swpaul rxfilt = CSR_READ_4(sc, RL_RXCFG); 66940516Swpaul 67043062Swpaul if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 67140516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 67240516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 67340516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF); 67440516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF); 67540516Swpaul return; 67640516Swpaul } 67740516Swpaul 67840516Swpaul /* first, zot all the existing hash bits */ 67940516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0); 68040516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0); 68140516Swpaul 68240516Swpaul /* now program new ones */ 683148654Srwatson IF_ADDR_LOCK(ifp); 68472084Sphk TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 68540516Swpaul if (ifma->ifma_addr->sa_family != AF_LINK) 68640516Swpaul continue; 687130270Snaddy h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 688130270Snaddy ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 68940516Swpaul if (h < 32) 69040516Swpaul hashes[0] |= (1 << h); 69140516Swpaul else 69240516Swpaul hashes[1] |= (1 << (h - 32)); 69340516Swpaul mcnt++; 69440516Swpaul } 695148654Srwatson IF_ADDR_UNLOCK(ifp); 69640516Swpaul 69740516Swpaul if (mcnt) 69840516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 69940516Swpaul else 70040516Swpaul rxfilt &= ~RL_RXCFG_RX_MULTI; 70140516Swpaul 70240516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 70340516Swpaul CSR_WRITE_4(sc, RL_MAR0, hashes[0]); 70440516Swpaul CSR_WRITE_4(sc, RL_MAR4, hashes[1]); 70540516Swpaul} 70640516Swpaul 707102335Salfredstatic void 708131605Sbmsrl_reset(struct rl_softc *sc) 70940516Swpaul{ 71040516Swpaul register int i; 71140516Swpaul 712131606Sbms RL_LOCK_ASSERT(sc); 713131606Sbms 71440516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RESET); 71540516Swpaul 71640516Swpaul for (i = 0; i < RL_TIMEOUT; i++) { 71740516Swpaul DELAY(10); 71840516Swpaul if (!(CSR_READ_1(sc, RL_COMMAND) & RL_CMD_RESET)) 71940516Swpaul break; 72040516Swpaul } 72140516Swpaul if (i == RL_TIMEOUT) 722162315Sglebius device_printf(sc->rl_dev, "reset never completed!\n"); 72340516Swpaul} 72440516Swpaul 72540516Swpaul/* 72640516Swpaul * Probe for a RealTek 8129/8139 chip. Check the PCI vendor and device 72740516Swpaul * IDs against our list and return a device name if we find a match. 72840516Swpaul */ 729102335Salfredstatic int 730131605Sbmsrl_probe(device_t dev) 73140516Swpaul{ 732176757Syongari struct rl_type *t; 733176757Syongari uint16_t devid, revid, vendor; 734176757Syongari int i; 735176757Syongari 736176757Syongari vendor = pci_get_vendor(dev); 737176757Syongari devid = pci_get_device(dev); 738176757Syongari revid = pci_get_revid(dev); 73940516Swpaul 740176757Syongari if (vendor == RT_VENDORID && devid == RT_DEVICEID_8139) { 741176757Syongari if (revid == 0x20) { 742176757Syongari /* 8139C+, let re(4) take care of this device. */ 743176757Syongari return (ENXIO); 744176757Syongari } 745176757Syongari } 746176757Syongari t = rl_devs; 747176757Syongari for (i = 0; i < sizeof(rl_devs) / sizeof(rl_devs[0]); i++, t++) { 748176757Syongari if (vendor == t->rl_vid && devid == t->rl_did) { 749119868Swpaul device_set_desc(dev, t->rl_name); 750142398Simp return (BUS_PROBE_DEFAULT); 75140516Swpaul } 75240516Swpaul } 75340516Swpaul 754131605Sbms return (ENXIO); 75540516Swpaul} 75640516Swpaul 75740516Swpaul/* 75840516Swpaul * Attach the interface. Allocate softc structures, do ifmedia 75940516Swpaul * setup and ethernet/BPF attach. 76040516Swpaul */ 761102335Salfredstatic int 762131605Sbmsrl_attach(device_t dev) 76340516Swpaul{ 764131605Sbms uint8_t eaddr[ETHER_ADDR_LEN]; 765131605Sbms uint16_t as[3]; 766131605Sbms struct ifnet *ifp; 76740516Swpaul struct rl_softc *sc; 768117388Swpaul struct rl_type *t; 769131605Sbms int error = 0, i, rid; 770131605Sbms int unit; 771131605Sbms uint16_t rl_did = 0; 77240516Swpaul 77350703Swpaul sc = device_get_softc(dev); 77450703Swpaul unit = device_get_unit(dev); 775162315Sglebius sc->rl_dev = dev; 77640516Swpaul 77793818Sjhb mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 778131606Sbms MTX_DEF); 779150720Sjhb callout_init_mtx(&sc->rl_stat_callout, &sc->rl_mtx, 0); 780131605Sbms 78172813Swpaul pci_enable_busmaster(dev); 78240516Swpaul 783131605Sbms /* Map control/status registers. */ 784109109Sdes rid = RL_RID; 785127135Snjl sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, RF_ACTIVE); 78650703Swpaul 78750703Swpaul if (sc->rl_res == NULL) { 788131605Sbms device_printf(dev, "couldn't map ports/memory\n"); 78950703Swpaul error = ENXIO; 79040516Swpaul goto fail; 79140516Swpaul } 79240516Swpaul 793117388Swpaul#ifdef notdef 794131605Sbms /* 795131605Sbms * Detect the Realtek 8139B. For some reason, this chip is very 79669127Sroger * unstable when left to autoselect the media 79769127Sroger * The best workaround is to set the device to the required 79869127Sroger * media type or to set it to the 10 Meg speed. 79969127Sroger */ 800131605Sbms if ((rman_get_end(sc->rl_res) - rman_get_start(sc->rl_res)) == 0xFF) 801131605Sbms device_printf(dev, 802131605Sbms"Realtek 8139B detected. Warning, this may be unstable in autoselect mode\n"); 803117388Swpaul#endif 80469127Sroger 80550703Swpaul sc->rl_btag = rman_get_bustag(sc->rl_res); 80650703Swpaul sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 80750703Swpaul 808112872Snjl /* Allocate interrupt */ 80950703Swpaul rid = 0; 810171560Syongari sc->rl_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 81150703Swpaul RF_SHAREABLE | RF_ACTIVE); 81250703Swpaul 813171560Syongari if (sc->rl_irq[0] == NULL) { 814131605Sbms device_printf(dev, "couldn't map interrupt\n"); 81550703Swpaul error = ENXIO; 81640516Swpaul goto fail; 81740516Swpaul } 81840516Swpaul 819131606Sbms /* 820131606Sbms * Reset the adapter. Only take the lock here as it's needed in 821131606Sbms * order to call rl_reset(). 822131606Sbms */ 823131606Sbms RL_LOCK(sc); 82440516Swpaul rl_reset(sc); 825131606Sbms RL_UNLOCK(sc); 826131606Sbms 82767931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_6BIT; 828131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, 0, 1, 0); 82968215Swpaul if (rl_did != 0x8129) 83067931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_8BIT; 83140516Swpaul 83240516Swpaul /* 83340516Swpaul * Get station address from the EEPROM. 83440516Swpaul */ 835131605Sbms rl_read_eeprom(sc, (uint8_t *)as, RL_EE_EADDR, 3, 0); 836108729Sjake for (i = 0; i < 3; i++) { 837108729Sjake eaddr[(i * 2) + 0] = as[i] & 0xff; 838108729Sjake eaddr[(i * 2) + 1] = as[i] >> 8; 839108729Sjake } 84040516Swpaul 84140516Swpaul /* 84240516Swpaul * Now read the exact device type from the EEPROM to find 84340516Swpaul * out if it's an 8129 or 8139. 84440516Swpaul */ 845131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, RL_EE_PCI_DID, 1, 0); 84640516Swpaul 847117388Swpaul t = rl_devs; 848119868Swpaul sc->rl_type = 0; 849117388Swpaul while(t->rl_name != NULL) { 850117388Swpaul if (rl_did == t->rl_did) { 851117388Swpaul sc->rl_type = t->rl_basetype; 852117388Swpaul break; 853117388Swpaul } 854117388Swpaul t++; 855117388Swpaul } 856119868Swpaul 857119868Swpaul if (sc->rl_type == 0) { 858131605Sbms device_printf(dev, "unknown device ID: %x\n", rl_did); 85950703Swpaul error = ENXIO; 86040516Swpaul goto fail; 86140516Swpaul } 86240516Swpaul 86381713Swpaul /* 86481713Swpaul * Allocate the parent bus DMA tag appropriate for PCI. 86581713Swpaul */ 86681713Swpaul#define RL_NSEG_NEW 32 867166165Smarius error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 86881713Swpaul 1, 0, /* alignment, boundary */ 86981713Swpaul BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 87081713Swpaul BUS_SPACE_MAXADDR, /* highaddr */ 87181713Swpaul NULL, NULL, /* filter, filterarg */ 87281713Swpaul MAXBSIZE, RL_NSEG_NEW, /* maxsize, nsegments */ 873109109Sdes BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 87481713Swpaul BUS_DMA_ALLOCNOW, /* flags */ 875117126Sscottl NULL, NULL, /* lockfunc, lockarg */ 87681713Swpaul &sc->rl_parent_tag); 877112872Snjl if (error) 878112872Snjl goto fail; 87940516Swpaul 88081713Swpaul /* 881119868Swpaul * Now allocate a tag for the DMA descriptor lists. 882119868Swpaul * All of our lists are allocated as a contiguous block 883119868Swpaul * of memory. 88481713Swpaul */ 885119868Swpaul error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */ 886119868Swpaul 1, 0, /* alignment, boundary */ 887119868Swpaul BUS_SPACE_MAXADDR, /* lowaddr */ 888119868Swpaul BUS_SPACE_MAXADDR, /* highaddr */ 889119868Swpaul NULL, NULL, /* filter, filterarg */ 890119868Swpaul RL_RXBUFLEN + 1518, 1, /* maxsize,nsegments */ 891119868Swpaul BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 892119868Swpaul BUS_DMA_ALLOCNOW, /* flags */ 893119868Swpaul NULL, NULL, /* lockfunc, lockarg */ 894119868Swpaul &sc->rl_tag); 895112872Snjl if (error) 896112872Snjl goto fail; 89781713Swpaul 898119868Swpaul /* 899119868Swpaul * Now allocate a chunk of DMA-able memory based on the 900119868Swpaul * tag we just created. 901119868Swpaul */ 902119868Swpaul error = bus_dmamem_alloc(sc->rl_tag, 903119868Swpaul (void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT | BUS_DMA_ZERO, 904119868Swpaul &sc->rl_cdata.rl_rx_dmamap); 905119868Swpaul if (error) { 906131605Sbms device_printf(dev, "no memory for list buffers!\n"); 907119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 908119868Swpaul sc->rl_tag = NULL; 909119868Swpaul goto fail; 910119868Swpaul } 911119868Swpaul 912119868Swpaul /* Leave a few bytes before the start of the RX ring buffer. */ 913119868Swpaul sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf; 914131605Sbms sc->rl_cdata.rl_rx_buf += sizeof(uint64_t); 915119868Swpaul 916147291Sbrooks ifp = sc->rl_ifp = if_alloc(IFT_ETHER); 917147291Sbrooks if (ifp == NULL) { 918147291Sbrooks device_printf(dev, "can not if_alloc()\n"); 919147291Sbrooks error = ENOSPC; 920147291Sbrooks goto fail; 921147291Sbrooks } 922147291Sbrooks 92350703Swpaul /* Do MII setup */ 92450703Swpaul if (mii_phy_probe(dev, &sc->rl_miibus, 92550703Swpaul rl_ifmedia_upd, rl_ifmedia_sts)) { 926131605Sbms device_printf(dev, "MII without any phy!\n"); 92750703Swpaul error = ENXIO; 92850703Swpaul goto fail; 92950703Swpaul } 93050703Swpaul 93140516Swpaul ifp->if_softc = sc; 932121816Sbrooks if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 93340516Swpaul ifp->if_mtu = ETHERMTU; 93440516Swpaul ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 93540516Swpaul ifp->if_ioctl = rl_ioctl; 936119868Swpaul ifp->if_start = rl_start; 93740516Swpaul ifp->if_init = rl_init; 938119976Swpaul ifp->if_capabilities = IFCAP_VLAN_MTU; 939150789Sglebius ifp->if_capenable = ifp->if_capabilities; 940128121Sru#ifdef DEVICE_POLLING 941128121Sru ifp->if_capabilities |= IFCAP_POLLING; 942128121Sru#endif 943131455Smlaier IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 944131455Smlaier ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 945131455Smlaier IFQ_SET_READY(&ifp->if_snd); 946131605Sbms 94740516Swpaul /* 94863090Sarchie * Call MI attach routine. 94940516Swpaul */ 950106936Ssam ether_ifattach(ifp, eaddr); 951106157Simp 952113609Snjl /* Hook interrupt last to avoid having to lock softc */ 953171560Syongari error = bus_setup_intr(dev, sc->rl_irq[0], INTR_TYPE_NET | INTR_MPSAFE, 954171560Syongari NULL, rl_intr, sc, &sc->rl_intrhand[0]); 955106157Simp if (error) { 956162315Sglebius device_printf(sc->rl_dev, "couldn't set up irq\n"); 957113609Snjl ether_ifdetach(ifp); 958106157Simp } 959106157Simp 96040516Swpaulfail: 961112872Snjl if (error) 962112872Snjl rl_detach(dev); 963112872Snjl 964110601Snjl return (error); 96540516Swpaul} 96640516Swpaul 967113609Snjl/* 968113609Snjl * Shutdown hardware and free up resources. This can be called any 969113609Snjl * time after the mutex has been initialized. It is called in both 970113609Snjl * the error case in attach and the normal detach case so it needs 971113609Snjl * to be careful about only freeing resources that have actually been 972113609Snjl * allocated. 973113609Snjl */ 974102335Salfredstatic int 975131605Sbmsrl_detach(device_t dev) 97650703Swpaul{ 97750703Swpaul struct rl_softc *sc; 97850703Swpaul struct ifnet *ifp; 97950703Swpaul 98050703Swpaul sc = device_get_softc(dev); 981147256Sbrooks ifp = sc->rl_ifp; 982131605Sbms 983112880Sjhb KASSERT(mtx_initialized(&sc->rl_mtx), ("rl mutex not initialized")); 984150720Sjhb 985150789Sglebius#ifdef DEVICE_POLLING 986150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 987150789Sglebius ether_poll_deregister(ifp); 988150789Sglebius#endif 989133403Sgreen /* These should only be active if attach succeeded */ 990150213Sru if (device_is_attached(dev)) { 991150126Sru RL_LOCK(sc); 992150126Sru rl_stop(sc); 993150126Sru RL_UNLOCK(sc); 994150720Sjhb callout_drain(&sc->rl_stat_callout); 995133403Sgreen ether_ifdetach(ifp); 996147256Sbrooks } 997131606Sbms#if 0 998131606Sbms sc->suspended = 1; 999131606Sbms#endif 1000113609Snjl if (sc->rl_miibus) 1001112872Snjl device_delete_child(dev, sc->rl_miibus); 1002113609Snjl bus_generic_detach(dev); 100350703Swpaul 1004171560Syongari if (sc->rl_intrhand[0]) 1005171560Syongari bus_teardown_intr(dev, sc->rl_irq[0], sc->rl_intrhand[0]); 1006171560Syongari if (sc->rl_irq[0]) 1007171560Syongari bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq[0]); 1008112872Snjl if (sc->rl_res) 1009112872Snjl bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 101050703Swpaul 1011151297Sru if (ifp) 1012151297Sru if_free(ifp); 1013151297Sru 1014119868Swpaul if (sc->rl_tag) { 1015119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 1016119868Swpaul bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf, 1017119868Swpaul sc->rl_cdata.rl_rx_dmamap); 1018119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 1019112872Snjl } 1020112872Snjl if (sc->rl_parent_tag) 1021112872Snjl bus_dma_tag_destroy(sc->rl_parent_tag); 102250703Swpaul 102367087Swpaul mtx_destroy(&sc->rl_mtx); 102450703Swpaul 1025131605Sbms return (0); 102650703Swpaul} 102750703Swpaul 102840516Swpaul/* 102940516Swpaul * Initialize the transmit descriptors. 103040516Swpaul */ 1031102335Salfredstatic int 1032131605Sbmsrl_list_tx_init(struct rl_softc *sc) 103340516Swpaul{ 103440516Swpaul struct rl_chain_data *cd; 103540516Swpaul int i; 103640516Swpaul 1037131606Sbms RL_LOCK_ASSERT(sc); 1038131606Sbms 103940516Swpaul cd = &sc->rl_cdata; 104040516Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 104145633Swpaul cd->rl_tx_chain[i] = NULL; 104248028Swpaul CSR_WRITE_4(sc, 1043131605Sbms RL_TXADDR0 + (i * sizeof(uint32_t)), 0x0000000); 104440516Swpaul } 104540516Swpaul 104645633Swpaul sc->rl_cdata.cur_tx = 0; 104745633Swpaul sc->rl_cdata.last_tx = 0; 104840516Swpaul 1049131605Sbms return (0); 105040516Swpaul} 105140516Swpaul 105240516Swpaul/* 105340516Swpaul * A frame has been uploaded: pass the resulting mbuf chain up to 105440516Swpaul * the higher level protocols. 105540516Swpaul * 105640516Swpaul * You know there's something wrong with a PCI bus-master chip design 105740516Swpaul * when you have to use m_devget(). 105840516Swpaul * 105940516Swpaul * The receive operation is badly documented in the datasheet, so I'll 106040516Swpaul * attempt to document it here. The driver provides a buffer area and 106140516Swpaul * places its base address in the RX buffer start address register. 106240516Swpaul * The chip then begins copying frames into the RX buffer. Each frame 106372645Sasmodai * is preceded by a 32-bit RX status word which specifies the length 106440516Swpaul * of the frame and certain other status bits. Each frame (starting with 106540516Swpaul * the status word) is also 32-bit aligned. The frame length is in the 106640516Swpaul * first 16 bits of the status word; the lower 15 bits correspond with 106740516Swpaul * the 'rx status register' mentioned in the datasheet. 106848028Swpaul * 106948028Swpaul * Note: to make the Alpha happy, the frame payload needs to be aligned 107078508Sbmilekic * on a 32-bit boundary. To achieve this, we pass RL_ETHER_ALIGN (2 bytes) 1071109109Sdes * as the offset argument to m_devget(). 107240516Swpaul */ 1073102335Salfredstatic void 1074131605Sbmsrl_rxeof(struct rl_softc *sc) 107540516Swpaul{ 1076109109Sdes struct mbuf *m; 1077147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1078131605Sbms uint8_t *rxbufpos; 107940516Swpaul int total_len = 0; 108040516Swpaul int wrap = 0; 1081131605Sbms uint32_t rxstat; 1082131605Sbms uint16_t cur_rx; 1083131605Sbms uint16_t limit; 1084131605Sbms uint16_t max_bytes, rx_bytes = 0; 108540516Swpaul 1086122689Ssam RL_LOCK_ASSERT(sc); 1087122689Ssam 108881713Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1089108729Sjake BUS_DMASYNC_POSTREAD); 109081713Swpaul 109140516Swpaul cur_rx = (CSR_READ_2(sc, RL_CURRXADDR) + 16) % RL_RXBUFLEN; 109240516Swpaul 109340516Swpaul /* Do not try to read past this point. */ 109440516Swpaul limit = CSR_READ_2(sc, RL_CURRXBUF) % RL_RXBUFLEN; 109540516Swpaul 109640516Swpaul if (limit < cur_rx) 109740516Swpaul max_bytes = (RL_RXBUFLEN - cur_rx) + limit; 109840516Swpaul else 109940516Swpaul max_bytes = limit - cur_rx; 110040516Swpaul 110142738Swpaul while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) { 110294883Sluigi#ifdef DEVICE_POLLING 1103150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) { 110494883Sluigi if (sc->rxcycles <= 0) 110594883Sluigi break; 110694883Sluigi sc->rxcycles--; 110794883Sluigi } 1108150789Sglebius#endif 110940516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx; 1110131605Sbms rxstat = le32toh(*(uint32_t *)rxbufpos); 111140516Swpaul 111240516Swpaul /* 111340516Swpaul * Here's a totally undocumented fact for you. When the 111440516Swpaul * RealTek chip is in the process of copying a packet into 111540516Swpaul * RAM for you, the length will be 0xfff0. If you spot a 111640516Swpaul * packet header with this value, you need to stop. The 111740516Swpaul * datasheet makes absolutely no mention of this and 111840516Swpaul * RealTek should be shot for this. 111940516Swpaul */ 1120178054Syongari total_len = rxstat >> 16; 1121178054Syongari if (total_len == RL_RXSTAT_UNFINISHED) 112240516Swpaul break; 1123109109Sdes 1124178054Syongari if (!(rxstat & RL_RXSTAT_RXOK) || 1125178054Syongari total_len < ETHER_MIN_LEN || 1126178054Syongari total_len > ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) { 112740516Swpaul ifp->if_ierrors++; 1128131841Sbms rl_init_locked(sc); 112950703Swpaul return; 113040516Swpaul } 113140516Swpaul 1132109109Sdes /* No errors; receive the packet. */ 113340516Swpaul rx_bytes += total_len + 4; 113440516Swpaul 113540516Swpaul /* 113642051Swpaul * XXX The RealTek chip includes the CRC with every 113742051Swpaul * received frame, and there's no way to turn this 113842051Swpaul * behavior off (at least, I can't find anything in 1139109109Sdes * the manual that explains how to do it) so we have 114042051Swpaul * to trim off the CRC manually. 114142051Swpaul */ 114242051Swpaul total_len -= ETHER_CRC_LEN; 114342051Swpaul 114442051Swpaul /* 114540516Swpaul * Avoid trying to read more bytes than we know 114640516Swpaul * the chip has prepared for us. 114740516Swpaul */ 114840516Swpaul if (rx_bytes > max_bytes) 114940516Swpaul break; 115040516Swpaul 115140516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + 1152131605Sbms ((cur_rx + sizeof(uint32_t)) % RL_RXBUFLEN); 115340516Swpaul if (rxbufpos == (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN)) 115440516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf; 115540516Swpaul 115640516Swpaul wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos; 115740516Swpaul if (total_len > wrap) { 115878508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 115978508Sbmilekic NULL); 116040516Swpaul if (m == NULL) { 116140516Swpaul ifp->if_ierrors++; 116252426Swpaul } else { 116340516Swpaul m_copyback(m, wrap, total_len - wrap, 116440516Swpaul sc->rl_cdata.rl_rx_buf); 116548028Swpaul } 116642051Swpaul cur_rx = (total_len - wrap + ETHER_CRC_LEN); 116740516Swpaul } else { 116878508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 116978508Sbmilekic NULL); 1170131605Sbms if (m == NULL) 117140516Swpaul ifp->if_ierrors++; 117242051Swpaul cur_rx += total_len + 4 + ETHER_CRC_LEN; 117340516Swpaul } 117440516Swpaul 1175131605Sbms /* Round up to 32-bit boundary. */ 117640516Swpaul cur_rx = (cur_rx + 3) & ~3; 117740516Swpaul CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16); 117840516Swpaul 117940516Swpaul if (m == NULL) 118040516Swpaul continue; 118140516Swpaul 118240516Swpaul ifp->if_ipackets++; 1183122689Ssam RL_UNLOCK(sc); 1184106936Ssam (*ifp->if_input)(ifp, m); 1185122689Ssam RL_LOCK(sc); 118640516Swpaul } 118740516Swpaul} 118840516Swpaul 118940516Swpaul/* 119040516Swpaul * A frame was downloaded to the chip. It's safe for us to clean up 119140516Swpaul * the list buffers. 119240516Swpaul */ 1193102335Salfredstatic void 1194131605Sbmsrl_txeof(struct rl_softc *sc) 119540516Swpaul{ 1196147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1197131605Sbms uint32_t txstat; 119840516Swpaul 1199131606Sbms RL_LOCK_ASSERT(sc); 1200131606Sbms 120140516Swpaul /* 120240516Swpaul * Go through our tx list and free mbufs for those 120340516Swpaul * frames that have been uploaded. 120440516Swpaul */ 120545633Swpaul do { 1206127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1207127783Sru break; 120845633Swpaul txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc)); 120945633Swpaul if (!(txstat & (RL_TXSTAT_TX_OK| 121045633Swpaul RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT))) 121140516Swpaul break; 121240516Swpaul 121345633Swpaul ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24; 121440516Swpaul 1215127783Sru bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1216127783Sru bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1217127783Sru m_freem(RL_LAST_TXMBUF(sc)); 1218127783Sru RL_LAST_TXMBUF(sc) = NULL; 1219141676Smlaier /* 1220141676Smlaier * If there was a transmit underrun, bump the TX threshold. 1221141676Smlaier * Make sure not to overflow the 63 * 32byte we can address 1222141676Smlaier * with the 6 available bit. 1223141676Smlaier */ 1224141676Smlaier if ((txstat & RL_TXSTAT_TX_UNDERRUN) && 1225141676Smlaier (sc->rl_txthresh < 2016)) 1226141676Smlaier sc->rl_txthresh += 32; 122745633Swpaul if (txstat & RL_TXSTAT_TX_OK) 122845633Swpaul ifp->if_opackets++; 122945633Swpaul else { 123052426Swpaul int oldthresh; 123145633Swpaul ifp->if_oerrors++; 123245633Swpaul if ((txstat & RL_TXSTAT_TXABRT) || 123345633Swpaul (txstat & RL_TXSTAT_OUTOFWIN)) 123445633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 123552426Swpaul oldthresh = sc->rl_txthresh; 123652426Swpaul /* error recovery */ 123752426Swpaul rl_reset(sc); 1238131841Sbms rl_init_locked(sc); 1239141676Smlaier /* restore original threshold */ 1240141676Smlaier sc->rl_txthresh = oldthresh; 124152426Swpaul return; 124245633Swpaul } 124345633Swpaul RL_INC(sc->rl_cdata.last_tx); 1244148887Srwatson ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 124545633Swpaul } while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx); 124640516Swpaul 1247127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1248164811Sru sc->rl_watchdog_timer = 0; 1249164811Sru else if (sc->rl_watchdog_timer == 0) 1250164811Sru sc->rl_watchdog_timer = 5; 125150703Swpaul} 125240516Swpaul 1253102335Salfredstatic void 1254131605Sbmsrl_tick(void *xsc) 125550703Swpaul{ 1256131605Sbms struct rl_softc *sc = xsc; 125750703Swpaul struct mii_data *mii; 125850703Swpaul 1259150720Sjhb RL_LOCK_ASSERT(sc); 126050703Swpaul mii = device_get_softc(sc->rl_miibus); 126150703Swpaul mii_tick(mii); 126250703Swpaul 1263164811Sru rl_watchdog(sc); 1264164811Sru 1265150720Sjhb callout_reset(&sc->rl_stat_callout, hz, rl_tick, sc); 126640516Swpaul} 126740516Swpaul 126894883Sluigi#ifdef DEVICE_POLLING 126994883Sluigistatic void 1270131841Sbmsrl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 127194883Sluigi{ 127294883Sluigi struct rl_softc *sc = ifp->if_softc; 127394883Sluigi 127494883Sluigi RL_LOCK(sc); 1275150789Sglebius if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1276150789Sglebius rl_poll_locked(ifp, cmd, count); 1277131841Sbms RL_UNLOCK(sc); 1278131841Sbms} 1279131605Sbms 1280131841Sbmsstatic void 1281131841Sbmsrl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) 1282131841Sbms{ 1283131841Sbms struct rl_softc *sc = ifp->if_softc; 1284131841Sbms 1285131841Sbms RL_LOCK_ASSERT(sc); 1286131841Sbms 128794883Sluigi sc->rxcycles = count; 1288119868Swpaul rl_rxeof(sc); 1289119868Swpaul rl_txeof(sc); 1290131605Sbms 1291131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1292131841Sbms rl_start_locked(ifp); 129394883Sluigi 1294131605Sbms if (cmd == POLL_AND_CHECK_STATUS) { 1295131605Sbms uint16_t status; 129694883Sluigi 1297131605Sbms /* We should also check the status register. */ 129894883Sluigi status = CSR_READ_2(sc, RL_ISR); 1299100957Sjhb if (status == 0xffff) 1300131841Sbms return; 1301131605Sbms if (status != 0) 130294883Sluigi CSR_WRITE_2(sc, RL_ISR, status); 130394883Sluigi 1304131605Sbms /* XXX We should check behaviour on receiver stalls. */ 130594883Sluigi 130694883Sluigi if (status & RL_ISR_SYSTEM_ERR) { 130794883Sluigi rl_reset(sc); 1308131841Sbms rl_init_locked(sc); 130994883Sluigi } 131094883Sluigi } 131194883Sluigi} 131294883Sluigi#endif /* DEVICE_POLLING */ 131394883Sluigi 1314102335Salfredstatic void 1315131605Sbmsrl_intr(void *arg) 131640516Swpaul{ 1317131605Sbms struct rl_softc *sc = arg; 1318147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1319131605Sbms uint16_t status; 132040516Swpaul 1321131606Sbms RL_LOCK(sc); 1322131606Sbms 1323131841Sbms if (sc->suspended) 1324131841Sbms goto done_locked; 132586822Siwasaki 132694883Sluigi#ifdef DEVICE_POLLING 1327150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 1328131841Sbms goto done_locked; 1329150789Sglebius#endif 1330131841Sbms 133140516Swpaul for (;;) { 133240516Swpaul status = CSR_READ_2(sc, RL_ISR); 1333131605Sbms /* If the card has gone away, the read returns 0xffff. */ 1334100957Sjhb if (status == 0xffff) 1335100957Sjhb break; 1336131605Sbms if (status != 0) 133740516Swpaul CSR_WRITE_2(sc, RL_ISR, status); 133840516Swpaul if ((status & RL_INTRS) == 0) 133940516Swpaul break; 134040516Swpaul if (status & RL_ISR_RX_OK) 134140516Swpaul rl_rxeof(sc); 134240516Swpaul if (status & RL_ISR_RX_ERR) 134340516Swpaul rl_rxeof(sc); 134445633Swpaul if ((status & RL_ISR_TX_OK) || (status & RL_ISR_TX_ERR)) 134540516Swpaul rl_txeof(sc); 134640516Swpaul if (status & RL_ISR_SYSTEM_ERR) { 134740516Swpaul rl_reset(sc); 1348131841Sbms rl_init_locked(sc); 134940516Swpaul } 135040516Swpaul } 135140516Swpaul 1352131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1353131841Sbms rl_start_locked(ifp); 1354131841Sbms 1355131841Sbmsdone_locked: 1356131606Sbms RL_UNLOCK(sc); 135740516Swpaul} 135840516Swpaul 135940516Swpaul/* 136040516Swpaul * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 136140516Swpaul * pointers to the fragment pointers. 136240516Swpaul */ 1363102335Salfredstatic int 1364131605Sbmsrl_encap(struct rl_softc *sc, struct mbuf *m_head) 136540516Swpaul{ 136641243Swpaul struct mbuf *m_new = NULL; 136740516Swpaul 1368131606Sbms RL_LOCK_ASSERT(sc); 1369131606Sbms 137040516Swpaul /* 137145633Swpaul * The RealTek is brain damaged and wants longword-aligned 137245633Swpaul * TX buffers, plus we can only have one fragment buffer 137345633Swpaul * per packet. We have to copy pretty much all the time. 137440516Swpaul */ 1375112839Ssilby m_new = m_defrag(m_head, M_DONTWAIT); 137640516Swpaul 1377113496Ssilby if (m_new == NULL) { 1378113496Ssilby m_freem(m_head); 1379131605Sbms return (1); 1380113496Ssilby } 138141243Swpaul m_head = m_new; 138240516Swpaul 138340516Swpaul /* Pad frames to at least 60 bytes. */ 138441243Swpaul if (m_head->m_pkthdr.len < RL_MIN_FRAMELEN) { 138555058Swpaul /* 138655058Swpaul * Make security concious people happy: zero out the 138755058Swpaul * bytes in the pad area, since we don't know what 138855058Swpaul * this mbuf cluster buffer's previous user might 138955058Swpaul * have left in it. 1390109109Sdes */ 139155058Swpaul bzero(mtod(m_head, char *) + m_head->m_pkthdr.len, 139255058Swpaul RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 139340516Swpaul m_head->m_pkthdr.len += 139452426Swpaul (RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 139541243Swpaul m_head->m_len = m_head->m_pkthdr.len; 139641243Swpaul } 139740516Swpaul 139845633Swpaul RL_CUR_TXMBUF(sc) = m_head; 139940516Swpaul 1400131605Sbms return (0); 140140516Swpaul} 140240516Swpaul 140340516Swpaul/* 140440516Swpaul * Main transmit routine. 140540516Swpaul */ 1406102335Salfredstatic void 1407131605Sbmsrl_start(struct ifnet *ifp) 140840516Swpaul{ 1409131605Sbms struct rl_softc *sc = ifp->if_softc; 141040516Swpaul 141167087Swpaul RL_LOCK(sc); 1412131841Sbms rl_start_locked(ifp); 1413131841Sbms RL_UNLOCK(sc); 1414131841Sbms} 141540516Swpaul 1416131841Sbmsstatic void 1417131841Sbmsrl_start_locked(struct ifnet *ifp) 1418131841Sbms{ 1419131841Sbms struct rl_softc *sc = ifp->if_softc; 1420131841Sbms struct mbuf *m_head = NULL; 1421131841Sbms 1422131841Sbms RL_LOCK_ASSERT(sc); 1423131841Sbms 1424131605Sbms while (RL_CUR_TXMBUF(sc) == NULL) { 1425131841Sbms 1426131455Smlaier IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); 1427131841Sbms 142840516Swpaul if (m_head == NULL) 142940516Swpaul break; 143040516Swpaul 1431131841Sbms if (rl_encap(sc, m_head)) 143258801Swpaul break; 143340516Swpaul 1434131605Sbms /* Pass a copy of this mbuf chain to the bpf subsystem. */ 1435106936Ssam BPF_MTAP(ifp, RL_CUR_TXMBUF(sc)); 143651583Swpaul 1437131605Sbms /* Transmit the frame. */ 143881713Swpaul bus_dmamap_create(sc->rl_tag, 0, &RL_CUR_DMAMAP(sc)); 143981713Swpaul bus_dmamap_load(sc->rl_tag, RL_CUR_DMAMAP(sc), 144081713Swpaul mtod(RL_CUR_TXMBUF(sc), void *), 1441119868Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len, rl_dma_map_txbuf, sc, 0); 144281713Swpaul bus_dmamap_sync(sc->rl_tag, RL_CUR_DMAMAP(sc), 144381713Swpaul BUS_DMASYNC_PREREAD); 144445633Swpaul CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc), 144552426Swpaul RL_TXTHRESH(sc->rl_txthresh) | 144652426Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len); 144745633Swpaul 144845633Swpaul RL_INC(sc->rl_cdata.cur_tx); 1449113237Ssilby 1450131605Sbms /* Set a timeout in case the chip goes out to lunch. */ 1451164811Sru sc->rl_watchdog_timer = 5; 145240516Swpaul } 145340516Swpaul 145440516Swpaul /* 145545633Swpaul * We broke out of the loop because all our TX slots are 145645633Swpaul * full. Mark the NIC as busy until it drains some of the 145745633Swpaul * packets from the queue. 145845633Swpaul */ 145945633Swpaul if (RL_CUR_TXMBUF(sc) != NULL) 1460148887Srwatson ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1461131841Sbms} 146245633Swpaul 1463131841Sbmsstatic void 1464131841Sbmsrl_init(void *xsc) 1465131841Sbms{ 1466131841Sbms struct rl_softc *sc = xsc; 1467131841Sbms 1468131841Sbms RL_LOCK(sc); 1469131841Sbms rl_init_locked(sc); 147067087Swpaul RL_UNLOCK(sc); 147140516Swpaul} 147240516Swpaul 1473102335Salfredstatic void 1474131841Sbmsrl_init_locked(struct rl_softc *sc) 147540516Swpaul{ 1476147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 147750703Swpaul struct mii_data *mii; 1478131605Sbms uint32_t rxcfg = 0; 1479165311Syongari uint32_t eaddr[2]; 148040516Swpaul 1481131841Sbms RL_LOCK_ASSERT(sc); 1482131841Sbms 148350703Swpaul mii = device_get_softc(sc->rl_miibus); 148440516Swpaul 148540516Swpaul /* 148640516Swpaul * Cancel pending I/O and free all RX/TX buffers. 148740516Swpaul */ 148840516Swpaul rl_stop(sc); 148940516Swpaul 1490117029Swpaul /* 1491117029Swpaul * Init our MAC address. Even though the chipset 1492117029Swpaul * documentation doesn't mention it, we need to enter "Config 1493117029Swpaul * register write enable" mode to modify the ID registers. 1494117029Swpaul */ 1495117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG); 1496165311Syongari bzero(eaddr, sizeof(eaddr)); 1497165311Syongari bcopy(IF_LLADDR(sc->rl_ifp), eaddr, ETHER_ADDR_LEN); 1498165311Syongari CSR_WRITE_STREAM_4(sc, RL_IDR0, eaddr[0]); 1499165311Syongari CSR_WRITE_STREAM_4(sc, RL_IDR4, eaddr[1]); 1500117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 150140516Swpaul 1502119868Swpaul /* Init the RX buffer pointer register. */ 1503119868Swpaul bus_dmamap_load(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1504119868Swpaul sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN, rl_dma_map_rxbuf, sc, 0); 1505119868Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1506119868Swpaul BUS_DMASYNC_PREWRITE); 150740516Swpaul 1508119868Swpaul /* Init TX descriptors. */ 1509119868Swpaul rl_list_tx_init(sc); 151040516Swpaul 151140516Swpaul /* 151240516Swpaul * Enable transmit and receive. 151340516Swpaul */ 151440516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 151540516Swpaul 151640516Swpaul /* 151745633Swpaul * Set the initial TX and RX configuration. 151840516Swpaul */ 151945633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 152040516Swpaul CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); 152140516Swpaul 152240516Swpaul /* Set the individual bit to receive frames for this host only. */ 152340516Swpaul rxcfg = CSR_READ_4(sc, RL_RXCFG); 152440516Swpaul rxcfg |= RL_RXCFG_RX_INDIV; 152540516Swpaul 152640516Swpaul /* If we want promiscuous mode, set the allframes bit. */ 152740516Swpaul if (ifp->if_flags & IFF_PROMISC) { 152840516Swpaul rxcfg |= RL_RXCFG_RX_ALLPHYS; 152940516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 153040516Swpaul } else { 153140516Swpaul rxcfg &= ~RL_RXCFG_RX_ALLPHYS; 153240516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 153340516Swpaul } 153440516Swpaul 1535131605Sbms /* Set capture broadcast bit to capture broadcast frames. */ 153640516Swpaul if (ifp->if_flags & IFF_BROADCAST) { 153740516Swpaul rxcfg |= RL_RXCFG_RX_BROAD; 153840516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 153940516Swpaul } else { 154040516Swpaul rxcfg &= ~RL_RXCFG_RX_BROAD; 154140516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 154240516Swpaul } 154340516Swpaul 1544131605Sbms /* Program the multicast filter, if necessary. */ 154540516Swpaul rl_setmulti(sc); 154640516Swpaul 154794883Sluigi#ifdef DEVICE_POLLING 1548131605Sbms /* Disable interrupts if we are polling. */ 1549150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 155094883Sluigi CSR_WRITE_2(sc, RL_IMR, 0); 1551131605Sbms else 1552150789Sglebius#endif 1553131605Sbms /* Enable interrupts. */ 1554119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 155540516Swpaul 155652426Swpaul /* Set initial TX threshold */ 155752426Swpaul sc->rl_txthresh = RL_TX_THRESH_INIT; 155852426Swpaul 155940516Swpaul /* Start RX/TX process. */ 156040516Swpaul CSR_WRITE_4(sc, RL_MISSEDPKT, 0); 1561119868Swpaul 156240516Swpaul /* Enable receiver and transmitter. */ 156340516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 156440516Swpaul 156550703Swpaul mii_mediachg(mii); 156640516Swpaul 156740516Swpaul CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); 156840516Swpaul 1569148887Srwatson ifp->if_drv_flags |= IFF_DRV_RUNNING; 1570148887Srwatson ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 157140516Swpaul 1572150720Sjhb callout_reset(&sc->rl_stat_callout, hz, rl_tick, sc); 157340516Swpaul} 157440516Swpaul 157540516Swpaul/* 157640516Swpaul * Set media options. 157740516Swpaul */ 1578102335Salfredstatic int 1579131605Sbmsrl_ifmedia_upd(struct ifnet *ifp) 158040516Swpaul{ 1581131605Sbms struct rl_softc *sc = ifp->if_softc; 158250703Swpaul struct mii_data *mii; 158340516Swpaul 158450703Swpaul mii = device_get_softc(sc->rl_miibus); 1585131605Sbms 1586150720Sjhb RL_LOCK(sc); 158750703Swpaul mii_mediachg(mii); 1588150720Sjhb RL_UNLOCK(sc); 158940516Swpaul 1590131605Sbms return (0); 159140516Swpaul} 159240516Swpaul 159340516Swpaul/* 159440516Swpaul * Report current media status. 159540516Swpaul */ 1596102335Salfredstatic void 1597131605Sbmsrl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 159840516Swpaul{ 1599131605Sbms struct rl_softc *sc = ifp->if_softc; 160050703Swpaul struct mii_data *mii; 160140516Swpaul 160250703Swpaul mii = device_get_softc(sc->rl_miibus); 160340516Swpaul 1604150720Sjhb RL_LOCK(sc); 160550703Swpaul mii_pollstat(mii); 1606150720Sjhb RL_UNLOCK(sc); 160750703Swpaul ifmr->ifm_active = mii->mii_media_active; 160850703Swpaul ifmr->ifm_status = mii->mii_media_status; 160940516Swpaul} 161040516Swpaul 1611102335Salfredstatic int 1612131605Sbmsrl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 161340516Swpaul{ 1614131605Sbms struct ifreq *ifr = (struct ifreq *)data; 1615131605Sbms struct mii_data *mii; 161640516Swpaul struct rl_softc *sc = ifp->if_softc; 161767087Swpaul int error = 0; 161840516Swpaul 1619131605Sbms switch (command) { 162040516Swpaul case SIOCSIFFLAGS: 1621131841Sbms RL_LOCK(sc); 162240516Swpaul if (ifp->if_flags & IFF_UP) { 1623131841Sbms rl_init_locked(sc); 162440516Swpaul } else { 1625148887Srwatson if (ifp->if_drv_flags & IFF_DRV_RUNNING) 162640516Swpaul rl_stop(sc); 162740516Swpaul } 1628131841Sbms RL_UNLOCK(sc); 162940516Swpaul error = 0; 163040516Swpaul break; 163140516Swpaul case SIOCADDMULTI: 163240516Swpaul case SIOCDELMULTI: 1633131606Sbms RL_LOCK(sc); 163440516Swpaul rl_setmulti(sc); 1635131606Sbms RL_UNLOCK(sc); 163640516Swpaul error = 0; 163740516Swpaul break; 163840516Swpaul case SIOCGIFMEDIA: 163940516Swpaul case SIOCSIFMEDIA: 164050703Swpaul mii = device_get_softc(sc->rl_miibus); 164150703Swpaul error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 164240516Swpaul break; 1643128121Sru case SIOCSIFCAP: 1644150789Sglebius#ifdef DEVICE_POLLING 1645150789Sglebius if (ifr->ifr_reqcap & IFCAP_POLLING && 1646150789Sglebius !(ifp->if_capenable & IFCAP_POLLING)) { 1647150789Sglebius error = ether_poll_register(rl_poll, ifp); 1648150789Sglebius if (error) 1649150789Sglebius return(error); 1650150789Sglebius RL_LOCK(sc); 1651150789Sglebius /* Disable interrupts */ 1652150789Sglebius CSR_WRITE_2(sc, RL_IMR, 0x0000); 1653150789Sglebius ifp->if_capenable |= IFCAP_POLLING; 1654150789Sglebius RL_UNLOCK(sc); 1655150789Sglebius return (error); 1656150789Sglebius 1657150789Sglebius } 1658150789Sglebius if (!(ifr->ifr_reqcap & IFCAP_POLLING) && 1659150789Sglebius ifp->if_capenable & IFCAP_POLLING) { 1660150789Sglebius error = ether_poll_deregister(ifp); 1661150789Sglebius /* Enable interrupts. */ 1662150789Sglebius RL_LOCK(sc); 1663150789Sglebius CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 1664150789Sglebius ifp->if_capenable &= ~IFCAP_POLLING; 1665150789Sglebius RL_UNLOCK(sc); 1666150789Sglebius return (error); 1667150789Sglebius } 1668150789Sglebius#endif /* DEVICE_POLLING */ 1669128121Sru break; 167040516Swpaul default: 1671106936Ssam error = ether_ioctl(ifp, command, data); 167240516Swpaul break; 167340516Swpaul } 167440516Swpaul 1675131605Sbms return (error); 167640516Swpaul} 167740516Swpaul 1678102335Salfredstatic void 1679164811Srurl_watchdog(struct rl_softc *sc) 168040516Swpaul{ 168140516Swpaul 1682164811Sru RL_LOCK_ASSERT(sc); 1683131605Sbms 1684164811Sru if (sc->rl_watchdog_timer == 0 || --sc->rl_watchdog_timer >0) 1685164811Sru return; 168650703Swpaul 1687164811Sru device_printf(sc->rl_dev, "watchdog timeout\n"); 1688164811Sru sc->rl_ifp->if_oerrors++; 1689164811Sru 1690119868Swpaul rl_txeof(sc); 1691119868Swpaul rl_rxeof(sc); 1692131841Sbms rl_init_locked(sc); 169340516Swpaul} 169440516Swpaul 169540516Swpaul/* 169640516Swpaul * Stop the adapter and free any mbufs allocated to the 169740516Swpaul * RX and TX lists. 169840516Swpaul */ 1699102335Salfredstatic void 1700131605Sbmsrl_stop(struct rl_softc *sc) 170140516Swpaul{ 170240516Swpaul register int i; 1703147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 170440516Swpaul 1705131606Sbms RL_LOCK_ASSERT(sc); 1706131606Sbms 1707164811Sru sc->rl_watchdog_timer = 0; 1708150720Sjhb callout_stop(&sc->rl_stat_callout); 1709148887Srwatson ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 171050703Swpaul 171140516Swpaul CSR_WRITE_1(sc, RL_COMMAND, 0x00); 171240516Swpaul CSR_WRITE_2(sc, RL_IMR, 0x0000); 1713119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 171440516Swpaul 1715119868Swpaul /* 1716119868Swpaul * Free the TX list buffers. 1717119868Swpaul */ 1718119868Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 1719119868Swpaul if (sc->rl_cdata.rl_tx_chain[i] != NULL) { 1720119868Swpaul bus_dmamap_unload(sc->rl_tag, 1721119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1722119868Swpaul bus_dmamap_destroy(sc->rl_tag, 1723119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1724119868Swpaul m_freem(sc->rl_cdata.rl_tx_chain[i]); 1725119868Swpaul sc->rl_cdata.rl_tx_chain[i] = NULL; 1726131605Sbms CSR_WRITE_4(sc, RL_TXADDR0 + (i * sizeof(uint32_t)), 1727124816Swpaul 0x0000000); 172840516Swpaul } 172940516Swpaul } 173040516Swpaul} 173140516Swpaul 173240516Swpaul/* 173386822Siwasaki * Device suspend routine. Stop the interface and save some PCI 173486822Siwasaki * settings in case the BIOS doesn't restore them properly on 173586822Siwasaki * resume. 173686822Siwasaki */ 1737102335Salfredstatic int 1738131605Sbmsrl_suspend(device_t dev) 173986822Siwasaki{ 174086822Siwasaki struct rl_softc *sc; 174186822Siwasaki 174286822Siwasaki sc = device_get_softc(dev); 1743131606Sbms 1744131606Sbms RL_LOCK(sc); 174586822Siwasaki rl_stop(sc); 174686822Siwasaki sc->suspended = 1; 1747131606Sbms RL_UNLOCK(sc); 174886822Siwasaki 174986822Siwasaki return (0); 175086822Siwasaki} 175186822Siwasaki 175286822Siwasaki/* 175386822Siwasaki * Device resume routine. Restore some PCI settings in case the BIOS 175486822Siwasaki * doesn't, re-enable busmastering, and restart the interface if 175586822Siwasaki * appropriate. 175686822Siwasaki */ 1757102335Salfredstatic int 1758131605Sbmsrl_resume(device_t dev) 175986822Siwasaki{ 176086822Siwasaki struct rl_softc *sc; 176186822Siwasaki struct ifnet *ifp; 176286822Siwasaki 176386822Siwasaki sc = device_get_softc(dev); 1764147256Sbrooks ifp = sc->rl_ifp; 176586822Siwasaki 1766131841Sbms RL_LOCK(sc); 1767131841Sbms 1768109109Sdes /* reinitialize interface if necessary */ 1769109109Sdes if (ifp->if_flags & IFF_UP) 1770131841Sbms rl_init_locked(sc); 177186822Siwasaki 177286822Siwasaki sc->suspended = 0; 1773131841Sbms 1774131606Sbms RL_UNLOCK(sc); 177586822Siwasaki 177686822Siwasaki return (0); 177786822Siwasaki} 177886822Siwasaki 177986822Siwasaki/* 178040516Swpaul * Stop all chip I/O so that the kernel's probe routines don't 178140516Swpaul * get confused by errant DMAs when rebooting. 178240516Swpaul */ 1783173839Syongaristatic int 1784131605Sbmsrl_shutdown(device_t dev) 178540516Swpaul{ 178650703Swpaul struct rl_softc *sc; 178740516Swpaul 178850703Swpaul sc = device_get_softc(dev); 1789131606Sbms 1790131606Sbms RL_LOCK(sc); 179140516Swpaul rl_stop(sc); 1792131606Sbms RL_UNLOCK(sc); 1793173839Syongari 1794173839Syongari return (0); 179540516Swpaul} 1796