if_rl.c revision 184524
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 184524 2008-11-01 17:02:01Z imp $"); 35122678Sobrien 3640516Swpaul/* 37119868Swpaul * RealTek 8129/8139 PCI NIC driver 3840516Swpaul * 39119868Swpaul * Supports several extremely cheap PCI 10/100 adapters based on 40119868Swpaul * the RealTek chipset. Datasheets can be obtained from 4140516Swpaul * www.realtek.com.tw. 4240516Swpaul * 43119868Swpaul * Written by Bill Paul <wpaul@ctr.columbia.edu> 44119868Swpaul * Electrical Engineering Department 45119868Swpaul * Columbia University, New York City 4640516Swpaul */ 4740516Swpaul/* 4840516Swpaul * The RealTek 8139 PCI NIC redefines the meaning of 'low end.' This is 4940516Swpaul * probably the worst PCI ethernet controller ever made, with the possible 5040516Swpaul * exception of the FEAST chip made by SMC. The 8139 supports bus-master 5140516Swpaul * DMA, but it has a terrible interface that nullifies any performance 5240516Swpaul * gains that bus-master DMA usually offers. 5340516Swpaul * 5440516Swpaul * For transmission, the chip offers a series of four TX descriptor 5540516Swpaul * registers. Each transmit frame must be in a contiguous buffer, aligned 5641569Swpaul * on a longword (32-bit) boundary. This means we almost always have to 5740516Swpaul * do mbuf copies in order to transmit a frame, except in the unlikely 5840516Swpaul * case where a) the packet fits into a single mbuf, and b) the packet 5940516Swpaul * is 32-bit aligned within the mbuf's data area. The presence of only 6040516Swpaul * four descriptor registers means that we can never have more than four 6140516Swpaul * packets queued for transmission at any one time. 6240516Swpaul * 6340516Swpaul * Reception is not much better. The driver has to allocate a single large 6440516Swpaul * buffer area (up to 64K in size) into which the chip will DMA received 6540516Swpaul * frames. Because we don't know where within this region received packets 6640516Swpaul * will begin or end, we have no choice but to copy data from the buffer 6740516Swpaul * area into mbufs in order to pass the packets up to the higher protocol 6840516Swpaul * levels. 6940516Swpaul * 7040516Swpaul * It's impossible given this rotten design to really achieve decent 7140516Swpaul * performance at 100Mbps, unless you happen to have a 400Mhz PII or 7240516Swpaul * some equally overmuscled CPU to drive it. 7340516Swpaul * 7440516Swpaul * On the bright side, the 8139 does have a built-in PHY, although 7540516Swpaul * rather than using an MDIO serial interface like most other NICs, the 7640516Swpaul * PHY registers are directly accessible through the 8139's register 7740516Swpaul * space. The 8139 supports autonegotiation, as well as a 64-bit multicast 7840516Swpaul * filter. 7940516Swpaul * 8040516Swpaul * The 8129 chip is an older version of the 8139 that uses an external PHY 8140516Swpaul * chip. The 8129 has a serial MDIO interface for accessing the MII where 8240516Swpaul * the 8139 lets you directly access the on-board PHY registers. We need 8340516Swpaul * to select which interface to use depending on the chip type. 8440516Swpaul */ 8540516Swpaul 86150968Sglebius#ifdef HAVE_KERNEL_OPTION_HEADERS 87150968Sglebius#include "opt_device_polling.h" 88184515Simp#include "opt_rl.h" 89150968Sglebius#endif 90150968Sglebius 9140516Swpaul#include <sys/param.h> 92108729Sjake#include <sys/endian.h> 9340516Swpaul#include <sys/systm.h> 9440516Swpaul#include <sys/sockio.h> 9540516Swpaul#include <sys/mbuf.h> 9640516Swpaul#include <sys/malloc.h> 9740516Swpaul#include <sys/kernel.h> 98129878Sphk#include <sys/module.h> 9940516Swpaul#include <sys/socket.h> 10040516Swpaul 10140516Swpaul#include <net/if.h> 10240516Swpaul#include <net/if_arp.h> 10340516Swpaul#include <net/ethernet.h> 10440516Swpaul#include <net/if_dl.h> 10540516Swpaul#include <net/if_media.h> 106147256Sbrooks#include <net/if_types.h> 10740516Swpaul 10840516Swpaul#include <net/bpf.h> 10940516Swpaul 11041569Swpaul#include <machine/bus.h> 11150703Swpaul#include <machine/resource.h> 11250703Swpaul#include <sys/bus.h> 11350703Swpaul#include <sys/rman.h> 11440516Swpaul 11550703Swpaul#include <dev/mii/mii.h> 11650703Swpaul#include <dev/mii/miivar.h> 11750703Swpaul 118119871Swpaul#include <dev/pci/pcireg.h> 119119871Swpaul#include <dev/pci/pcivar.h> 12040516Swpaul 121113506SmdoddMODULE_DEPEND(rl, pci, 1, 1, 1); 122113506SmdoddMODULE_DEPEND(rl, ether, 1, 1, 1); 12359758SpeterMODULE_DEPEND(rl, miibus, 1, 1, 1); 12459758Speter 125151545Simp/* "device miibus" required. See GENERIC if you get errors here. */ 12650703Swpaul#include "miibus_if.h" 12750703Swpaul 12840516Swpaul/* 12940516Swpaul * Default to using PIO access for this driver. On SMP systems, 13040516Swpaul * there appear to be problems with memory mapped mode: it looks like 13140516Swpaul * doing too many memory mapped access back to back in rapid succession 13240516Swpaul * can hang the bus. I'm inclined to blame this on crummy design/construction 13340516Swpaul * on the part of RealTek. Memory mapped mode does appear to work on 13440516Swpaul * uniprocessor systems though. 13540516Swpaul */ 13640516Swpaul#define RL_USEIOSPACE 13740516Swpaul 13840516Swpaul#include <pci/if_rlreg.h> 13940516Swpaul 14040516Swpaul/* 14140516Swpaul * Various supported device vendors/types and their names. 14240516Swpaul */ 14340516Swpaulstatic struct rl_type rl_devs[] = { 144117388Swpaul { RT_VENDORID, RT_DEVICEID_8129, RL_8129, 14540516Swpaul "RealTek 8129 10/100BaseTX" }, 146117388Swpaul { RT_VENDORID, RT_DEVICEID_8139, RL_8139, 14740516Swpaul "RealTek 8139 10/100BaseTX" }, 148179831Sremko { RT_VENDORID, RT_DEVICEID_8139D, RL_8139, 149179831Sremko "RealTek 8139 10/100BaseTX" }, 150117388Swpaul { RT_VENDORID, RT_DEVICEID_8138, RL_8139, 15167771Swpaul "RealTek 8139 10/100BaseTX CardBus" }, 152118978Swpaul { RT_VENDORID, RT_DEVICEID_8100, RL_8139, 153118978Swpaul "RealTek 8100 10/100BaseTX" }, 154117388Swpaul { ACCTON_VENDORID, ACCTON_DEVICEID_5030, RL_8139, 15541243Swpaul "Accton MPX 5030/5038 10/100BaseTX" }, 156117388Swpaul { DELTA_VENDORID, DELTA_DEVICEID_8139, RL_8139, 15744238Swpaul "Delta Electronics 8139 10/100BaseTX" }, 158117388Swpaul { ADDTRON_VENDORID, ADDTRON_DEVICEID_8139, RL_8139, 159184524Simp "Addtron Technology 8139 10/100BaseTX" }, 160117388Swpaul { DLINK_VENDORID, DLINK_DEVICEID_530TXPLUS, RL_8139, 16172813Swpaul "D-Link DFE-530TX+ 10/100BaseTX" }, 162117388Swpaul { DLINK_VENDORID, DLINK_DEVICEID_690TXD, RL_8139, 16396112Sjhb "D-Link DFE-690TXD 10/100BaseTX" }, 164117388Swpaul { NORTEL_VENDORID, ACCTON_DEVICEID_5030, RL_8139, 16594400Swpaul "Nortel Networks 10/100BaseTX" }, 166117388Swpaul { COREGA_VENDORID, COREGA_DEVICEID_FETHERCBTXD, RL_8139, 167103020Siwasaki "Corega FEther CB-TXD" }, 168117388Swpaul { COREGA_VENDORID, COREGA_DEVICEID_FETHERIICBTXD, RL_8139, 169109095Ssanpei "Corega FEtherII CB-TXD" }, 170117388Swpaul { PEPPERCON_VENDORID, PEPPERCON_DEVICEID_ROLF, RL_8139, 171111381Sdan "Peppercon AG ROL-F" }, 172173948Sremko { PLANEX_VENDORID, PLANEX_DEVICEID_FNW3603TX, RL_8139, 173173948Sremko "Planex FNW-3603-TX" }, 174117388Swpaul { PLANEX_VENDORID, PLANEX_DEVICEID_FNW3800TX, RL_8139, 175112379Ssanpei "Planex FNW-3800-TX" }, 176117388Swpaul { CP_VENDORID, RT_DEVICEID_8139, RL_8139, 177117388Swpaul "Compaq HNE-300" }, 178117388Swpaul { LEVEL1_VENDORID, LEVEL1_DEVICEID_FPC0106TX, RL_8139, 179117388Swpaul "LevelOne FPC-0106TX" }, 180117388Swpaul { EDIMAX_VENDORID, EDIMAX_DEVICEID_EP4103DL, RL_8139, 181176757Syongari "Edimax EP-4103DL CardBus" } 18240516Swpaul}; 18340516Swpaul 184142407Simpstatic int rl_attach(device_t); 185142407Simpstatic int rl_detach(device_t); 186184240Syongaristatic void rl_dmamap_cb(void *, bus_dma_segment_t *, int, int); 187184240Syongaristatic int rl_dma_alloc(struct rl_softc *); 188184240Syongaristatic void rl_dma_free(struct rl_softc *); 189142407Simpstatic void rl_eeprom_putbyte(struct rl_softc *, int); 190142407Simpstatic void rl_eeprom_getword(struct rl_softc *, int, uint16_t *); 191184240Syongaristatic int rl_encap(struct rl_softc *, struct mbuf **); 192142407Simpstatic int rl_list_tx_init(struct rl_softc *); 193184240Syongaristatic int rl_list_rx_init(struct rl_softc *); 194142407Simpstatic int rl_ifmedia_upd(struct ifnet *); 195142407Simpstatic void rl_ifmedia_sts(struct ifnet *, struct ifmediareq *); 196142407Simpstatic int rl_ioctl(struct ifnet *, u_long, caddr_t); 197142407Simpstatic void rl_intr(void *); 198142407Simpstatic void rl_init(void *); 199142407Simpstatic void rl_init_locked(struct rl_softc *sc); 200142407Simpstatic void rl_mii_send(struct rl_softc *, uint32_t, int); 201142407Simpstatic void rl_mii_sync(struct rl_softc *); 202142407Simpstatic int rl_mii_readreg(struct rl_softc *, struct rl_mii_frame *); 203142407Simpstatic int rl_mii_writereg(struct rl_softc *, struct rl_mii_frame *); 204142407Simpstatic int rl_miibus_readreg(device_t, int, int); 205142407Simpstatic void rl_miibus_statchg(device_t); 206142407Simpstatic int rl_miibus_writereg(device_t, int, int, int); 207131841Sbms#ifdef DEVICE_POLLING 208150789Sglebiusstatic void rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); 209150789Sglebiusstatic void rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); 210131841Sbms#endif 211142407Simpstatic int rl_probe(device_t); 212142407Simpstatic void rl_read_eeprom(struct rl_softc *, uint8_t *, int, int, int); 213142407Simpstatic void rl_reset(struct rl_softc *); 214142407Simpstatic int rl_resume(device_t); 215142407Simpstatic void rl_rxeof(struct rl_softc *); 216142407Simpstatic void rl_setmulti(struct rl_softc *); 217173839Syongaristatic int rl_shutdown(device_t); 218142407Simpstatic void rl_start(struct ifnet *); 219142407Simpstatic void rl_start_locked(struct ifnet *); 220142407Simpstatic void rl_stop(struct rl_softc *); 221142407Simpstatic int rl_suspend(device_t); 222142407Simpstatic void rl_tick(void *); 223142407Simpstatic void rl_txeof(struct rl_softc *); 224164811Srustatic void rl_watchdog(struct rl_softc *); 22540516Swpaul 22650703Swpaul#ifdef RL_USEIOSPACE 22750703Swpaul#define RL_RES SYS_RES_IOPORT 22850703Swpaul#define RL_RID RL_PCI_LOIO 22950703Swpaul#else 23050703Swpaul#define RL_RES SYS_RES_MEMORY 23150703Swpaul#define RL_RID RL_PCI_LOMEM 23250703Swpaul#endif 23350703Swpaul 23450703Swpaulstatic device_method_t rl_methods[] = { 23550703Swpaul /* Device interface */ 23650703Swpaul DEVMETHOD(device_probe, rl_probe), 23750703Swpaul DEVMETHOD(device_attach, rl_attach), 23850703Swpaul DEVMETHOD(device_detach, rl_detach), 23986822Siwasaki DEVMETHOD(device_suspend, rl_suspend), 24086822Siwasaki DEVMETHOD(device_resume, rl_resume), 24150703Swpaul DEVMETHOD(device_shutdown, rl_shutdown), 24250703Swpaul 24350703Swpaul /* bus interface */ 24450703Swpaul DEVMETHOD(bus_print_child, bus_generic_print_child), 24550703Swpaul DEVMETHOD(bus_driver_added, bus_generic_driver_added), 24650703Swpaul 24750703Swpaul /* MII interface */ 24850703Swpaul DEVMETHOD(miibus_readreg, rl_miibus_readreg), 24950703Swpaul DEVMETHOD(miibus_writereg, rl_miibus_writereg), 25050703Swpaul DEVMETHOD(miibus_statchg, rl_miibus_statchg), 25150703Swpaul 25250703Swpaul { 0, 0 } 25350703Swpaul}; 25450703Swpaul 25550703Swpaulstatic driver_t rl_driver = { 25651455Swpaul "rl", 25750703Swpaul rl_methods, 25850703Swpaul sizeof(struct rl_softc) 25950703Swpaul}; 26050703Swpaul 26150703Swpaulstatic devclass_t rl_devclass; 26250703Swpaul 263113506SmdoddDRIVER_MODULE(rl, pci, rl_driver, rl_devclass, 0, 0); 264123019SimpDRIVER_MODULE(rl, cardbus, rl_driver, rl_devclass, 0, 0); 26551473SwpaulDRIVER_MODULE(miibus, rl, miibus_driver, miibus_devclass, 0, 0); 26650703Swpaul 26740516Swpaul#define EE_SET(x) \ 26840516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26940516Swpaul CSR_READ_1(sc, RL_EECMD) | x) 27040516Swpaul 27140516Swpaul#define EE_CLR(x) \ 27240516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 27340516Swpaul CSR_READ_1(sc, RL_EECMD) & ~x) 27440516Swpaul 27540516Swpaul/* 27640516Swpaul * Send a read command and address to the EEPROM, check for ACK. 27740516Swpaul */ 278102335Salfredstatic void 279131605Sbmsrl_eeprom_putbyte(struct rl_softc *sc, int addr) 28040516Swpaul{ 28140516Swpaul register int d, i; 28240516Swpaul 28367931Swpaul d = addr | sc->rl_eecmd_read; 28440516Swpaul 28540516Swpaul /* 28655170Sbillf * Feed in each bit and strobe the clock. 28740516Swpaul */ 28840516Swpaul for (i = 0x400; i; i >>= 1) { 28940516Swpaul if (d & i) { 29040516Swpaul EE_SET(RL_EE_DATAIN); 29140516Swpaul } else { 29240516Swpaul EE_CLR(RL_EE_DATAIN); 29340516Swpaul } 29440516Swpaul DELAY(100); 29540516Swpaul EE_SET(RL_EE_CLK); 29640516Swpaul DELAY(150); 29740516Swpaul EE_CLR(RL_EE_CLK); 29840516Swpaul DELAY(100); 29940516Swpaul } 30040516Swpaul} 30140516Swpaul 30240516Swpaul/* 30340516Swpaul * Read a word of data stored in the EEPROM at address 'addr.' 30440516Swpaul */ 305102335Salfredstatic void 306131605Sbmsrl_eeprom_getword(struct rl_softc *sc, int addr, uint16_t *dest) 30740516Swpaul{ 30840516Swpaul register int i; 309131605Sbms uint16_t word = 0; 31040516Swpaul 31140516Swpaul /* Enter EEPROM access mode. */ 31240516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 31340516Swpaul 31440516Swpaul /* 31540516Swpaul * Send address of word we want to read. 31640516Swpaul */ 31740516Swpaul rl_eeprom_putbyte(sc, addr); 31840516Swpaul 31940516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 32040516Swpaul 32140516Swpaul /* 32240516Swpaul * Start reading bits from EEPROM. 32340516Swpaul */ 32440516Swpaul for (i = 0x8000; i; i >>= 1) { 32540516Swpaul EE_SET(RL_EE_CLK); 32640516Swpaul DELAY(100); 32740516Swpaul if (CSR_READ_1(sc, RL_EECMD) & RL_EE_DATAOUT) 32840516Swpaul word |= i; 32940516Swpaul EE_CLR(RL_EE_CLK); 33040516Swpaul DELAY(100); 33140516Swpaul } 33240516Swpaul 33340516Swpaul /* Turn off EEPROM access mode. */ 33440516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 33540516Swpaul 33640516Swpaul *dest = word; 33740516Swpaul} 33840516Swpaul 33940516Swpaul/* 34040516Swpaul * Read a sequence of words from the EEPROM. 34140516Swpaul */ 342102335Salfredstatic void 343131605Sbmsrl_read_eeprom(struct rl_softc *sc, uint8_t *dest, int off, int cnt, int swap) 34440516Swpaul{ 34540516Swpaul int i; 346131605Sbms uint16_t word = 0, *ptr; 34740516Swpaul 34840516Swpaul for (i = 0; i < cnt; i++) { 34940516Swpaul rl_eeprom_getword(sc, off + i, &word); 350131605Sbms ptr = (uint16_t *)(dest + (i * 2)); 35140516Swpaul if (swap) 35240516Swpaul *ptr = ntohs(word); 35340516Swpaul else 35440516Swpaul *ptr = word; 35540516Swpaul } 35640516Swpaul} 35740516Swpaul 35840516Swpaul/* 35940516Swpaul * MII access routines are provided for the 8129, which 36040516Swpaul * doesn't have a built-in PHY. For the 8139, we fake things 36140516Swpaul * up by diverting rl_phy_readreg()/rl_phy_writereg() to the 36240516Swpaul * direct access PHY registers. 36340516Swpaul */ 36440516Swpaul#define MII_SET(x) \ 36540516Swpaul CSR_WRITE_1(sc, RL_MII, \ 366105221Sphk CSR_READ_1(sc, RL_MII) | (x)) 36740516Swpaul 36840516Swpaul#define MII_CLR(x) \ 36940516Swpaul CSR_WRITE_1(sc, RL_MII, \ 370105221Sphk CSR_READ_1(sc, RL_MII) & ~(x)) 37140516Swpaul 37240516Swpaul/* 37340516Swpaul * Sync the PHYs by setting data bit and strobing the clock 32 times. 37440516Swpaul */ 375102335Salfredstatic void 376131605Sbmsrl_mii_sync(struct rl_softc *sc) 37740516Swpaul{ 37840516Swpaul register int i; 37940516Swpaul 38040516Swpaul MII_SET(RL_MII_DIR|RL_MII_DATAOUT); 38140516Swpaul 38240516Swpaul for (i = 0; i < 32; i++) { 38340516Swpaul MII_SET(RL_MII_CLK); 38440516Swpaul DELAY(1); 38540516Swpaul MII_CLR(RL_MII_CLK); 38640516Swpaul DELAY(1); 38740516Swpaul } 38840516Swpaul} 38940516Swpaul 39040516Swpaul/* 39140516Swpaul * Clock a series of bits through the MII. 39240516Swpaul */ 393102335Salfredstatic void 394131605Sbmsrl_mii_send(struct rl_softc *sc, uint32_t bits, int cnt) 39540516Swpaul{ 39640516Swpaul int i; 39740516Swpaul 39840516Swpaul MII_CLR(RL_MII_CLK); 39940516Swpaul 40040516Swpaul for (i = (0x1 << (cnt - 1)); i; i >>= 1) { 401109109Sdes if (bits & i) { 40240516Swpaul MII_SET(RL_MII_DATAOUT); 403109109Sdes } else { 40440516Swpaul MII_CLR(RL_MII_DATAOUT); 405109109Sdes } 40640516Swpaul DELAY(1); 40740516Swpaul MII_CLR(RL_MII_CLK); 40840516Swpaul DELAY(1); 40940516Swpaul MII_SET(RL_MII_CLK); 41040516Swpaul } 41140516Swpaul} 41240516Swpaul 41340516Swpaul/* 41440516Swpaul * Read an PHY register through the MII. 41540516Swpaul */ 416102335Salfredstatic int 417131605Sbmsrl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame) 41840516Swpaul{ 41967087Swpaul int i, ack; 42040516Swpaul 421131605Sbms /* Set up frame for RX. */ 42240516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 42340516Swpaul frame->mii_opcode = RL_MII_READOP; 42440516Swpaul frame->mii_turnaround = 0; 42540516Swpaul frame->mii_data = 0; 426109109Sdes 42740516Swpaul CSR_WRITE_2(sc, RL_MII, 0); 42840516Swpaul 429131605Sbms /* Turn on data xmit. */ 43040516Swpaul MII_SET(RL_MII_DIR); 43140516Swpaul 43240516Swpaul rl_mii_sync(sc); 43340516Swpaul 434131605Sbms /* Send command/address info. */ 43540516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 43640516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 43740516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 43840516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 43940516Swpaul 44040516Swpaul /* Idle bit */ 44140516Swpaul MII_CLR((RL_MII_CLK|RL_MII_DATAOUT)); 44240516Swpaul DELAY(1); 44340516Swpaul MII_SET(RL_MII_CLK); 44440516Swpaul DELAY(1); 44540516Swpaul 44640516Swpaul /* Turn off xmit. */ 44740516Swpaul MII_CLR(RL_MII_DIR); 44840516Swpaul 44940516Swpaul /* Check for ack */ 45040516Swpaul MII_CLR(RL_MII_CLK); 45140516Swpaul DELAY(1); 452109058Smbr ack = CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN; 45340516Swpaul MII_SET(RL_MII_CLK); 45440516Swpaul DELAY(1); 45540516Swpaul 45640516Swpaul /* 45740516Swpaul * Now try reading data bits. If the ack failed, we still 45840516Swpaul * need to clock through 16 cycles to keep the PHY(s) in sync. 45940516Swpaul */ 46040516Swpaul if (ack) { 46140516Swpaul for(i = 0; i < 16; i++) { 46240516Swpaul MII_CLR(RL_MII_CLK); 46340516Swpaul DELAY(1); 46440516Swpaul MII_SET(RL_MII_CLK); 46540516Swpaul DELAY(1); 46640516Swpaul } 46740516Swpaul goto fail; 46840516Swpaul } 46940516Swpaul 47040516Swpaul for (i = 0x8000; i; i >>= 1) { 47140516Swpaul MII_CLR(RL_MII_CLK); 47240516Swpaul DELAY(1); 47340516Swpaul if (!ack) { 47440516Swpaul if (CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN) 47540516Swpaul frame->mii_data |= i; 47640516Swpaul DELAY(1); 47740516Swpaul } 47840516Swpaul MII_SET(RL_MII_CLK); 47940516Swpaul DELAY(1); 48040516Swpaul } 48140516Swpaul 48240516Swpaulfail: 48340516Swpaul MII_CLR(RL_MII_CLK); 48440516Swpaul DELAY(1); 48540516Swpaul MII_SET(RL_MII_CLK); 48640516Swpaul DELAY(1); 48740516Swpaul 488131605Sbms return (ack ? 1 : 0); 48940516Swpaul} 49040516Swpaul 49140516Swpaul/* 49240516Swpaul * Write to a PHY register through the MII. 49340516Swpaul */ 494102335Salfredstatic int 495131605Sbmsrl_mii_writereg(struct rl_softc *sc, struct rl_mii_frame *frame) 496131605Sbms{ 497109109Sdes 498131605Sbms /* Set up frame for TX. */ 49940516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 50040516Swpaul frame->mii_opcode = RL_MII_WRITEOP; 50140516Swpaul frame->mii_turnaround = RL_MII_TURNAROUND; 502109109Sdes 503131605Sbms /* Turn on data output. */ 50440516Swpaul MII_SET(RL_MII_DIR); 50540516Swpaul 50640516Swpaul rl_mii_sync(sc); 50740516Swpaul 50840516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 50940516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 51040516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 51140516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 51240516Swpaul rl_mii_send(sc, frame->mii_turnaround, 2); 51340516Swpaul rl_mii_send(sc, frame->mii_data, 16); 51440516Swpaul 51540516Swpaul /* Idle bit. */ 51640516Swpaul MII_SET(RL_MII_CLK); 51740516Swpaul DELAY(1); 51840516Swpaul MII_CLR(RL_MII_CLK); 51940516Swpaul DELAY(1); 52040516Swpaul 521131605Sbms /* Turn off xmit. */ 52240516Swpaul MII_CLR(RL_MII_DIR); 52340516Swpaul 524131605Sbms return (0); 52540516Swpaul} 52640516Swpaul 527102335Salfredstatic int 528131605Sbmsrl_miibus_readreg(device_t dev, int phy, int reg) 52950703Swpaul{ 53040516Swpaul struct rl_softc *sc; 53140516Swpaul struct rl_mii_frame frame; 532131605Sbms uint16_t rval = 0; 533131605Sbms uint16_t rl8139_reg = 0; 53440516Swpaul 53550703Swpaul sc = device_get_softc(dev); 53650703Swpaul 537119868Swpaul if (sc->rl_type == RL_8139) { 53850703Swpaul /* Pretend the internal PHY is only at address 0 */ 53967087Swpaul if (phy) { 540131605Sbms return (0); 54167087Swpaul } 542131605Sbms switch (reg) { 54350703Swpaul case MII_BMCR: 54440516Swpaul rl8139_reg = RL_BMCR; 54540516Swpaul break; 54650703Swpaul case MII_BMSR: 54740516Swpaul rl8139_reg = RL_BMSR; 54840516Swpaul break; 54950703Swpaul case MII_ANAR: 55040516Swpaul rl8139_reg = RL_ANAR; 55140516Swpaul break; 55250703Swpaul case MII_ANER: 55350703Swpaul rl8139_reg = RL_ANER; 55450703Swpaul break; 55550703Swpaul case MII_ANLPAR: 55640516Swpaul rl8139_reg = RL_LPAR; 55740516Swpaul break; 55850703Swpaul case MII_PHYIDR1: 55950703Swpaul case MII_PHYIDR2: 560131605Sbms return (0); 56194149Swpaul /* 56294149Swpaul * Allow the rlphy driver to read the media status 56394149Swpaul * register. If we have a link partner which does not 56494149Swpaul * support NWAY, this is the register which will tell 56594149Swpaul * us the results of parallel detection. 56694149Swpaul */ 56794149Swpaul case RL_MEDIASTAT: 56894149Swpaul rval = CSR_READ_1(sc, RL_MEDIASTAT); 569131605Sbms return (rval); 57040516Swpaul default: 571162315Sglebius device_printf(sc->rl_dev, "bad phy register\n"); 572131605Sbms return (0); 57340516Swpaul } 57440516Swpaul rval = CSR_READ_2(sc, rl8139_reg); 575131605Sbms return (rval); 57640516Swpaul } 57740516Swpaul 57840516Swpaul bzero((char *)&frame, sizeof(frame)); 57950703Swpaul frame.mii_phyaddr = phy; 58040516Swpaul frame.mii_regaddr = reg; 58140516Swpaul rl_mii_readreg(sc, &frame); 582131605Sbms 583131605Sbms return (frame.mii_data); 58440516Swpaul} 58540516Swpaul 586102335Salfredstatic int 587131605Sbmsrl_miibus_writereg(device_t dev, int phy, int reg, int data) 58850703Swpaul{ 58940516Swpaul struct rl_softc *sc; 59040516Swpaul struct rl_mii_frame frame; 591131605Sbms uint16_t rl8139_reg = 0; 59240516Swpaul 59350703Swpaul sc = device_get_softc(dev); 59450703Swpaul 595119868Swpaul if (sc->rl_type == RL_8139) { 59650703Swpaul /* Pretend the internal PHY is only at address 0 */ 59767087Swpaul if (phy) { 598131605Sbms return (0); 59967087Swpaul } 600131605Sbms switch (reg) { 60150703Swpaul case MII_BMCR: 60240516Swpaul rl8139_reg = RL_BMCR; 60340516Swpaul break; 60450703Swpaul case MII_BMSR: 60540516Swpaul rl8139_reg = RL_BMSR; 60640516Swpaul break; 60750703Swpaul case MII_ANAR: 60840516Swpaul rl8139_reg = RL_ANAR; 60940516Swpaul break; 61050703Swpaul case MII_ANER: 61150703Swpaul rl8139_reg = RL_ANER; 61250703Swpaul break; 61350703Swpaul case MII_ANLPAR: 61440516Swpaul rl8139_reg = RL_LPAR; 61540516Swpaul break; 61650703Swpaul case MII_PHYIDR1: 61750703Swpaul case MII_PHYIDR2: 618131605Sbms return (0); 61950703Swpaul break; 62040516Swpaul default: 621162315Sglebius device_printf(sc->rl_dev, "bad phy register\n"); 622131605Sbms return (0); 62340516Swpaul } 62440516Swpaul CSR_WRITE_2(sc, rl8139_reg, data); 625131605Sbms return (0); 62640516Swpaul } 62740516Swpaul 62840516Swpaul bzero((char *)&frame, sizeof(frame)); 62950703Swpaul frame.mii_phyaddr = phy; 63040516Swpaul frame.mii_regaddr = reg; 63140516Swpaul frame.mii_data = data; 63240516Swpaul rl_mii_writereg(sc, &frame); 63340516Swpaul 634131605Sbms return (0); 63550703Swpaul} 63650703Swpaul 637102335Salfredstatic void 638131605Sbmsrl_miibus_statchg(device_t dev) 63950703Swpaul{ 640184245Syongari struct rl_softc *sc; 641184245Syongari struct ifnet *ifp; 642184245Syongari struct mii_data *mii; 643184245Syongari 644184245Syongari sc = device_get_softc(dev); 645184245Syongari mii = device_get_softc(sc->rl_miibus); 646184245Syongari ifp = sc->rl_ifp; 647184245Syongari if (mii == NULL || ifp == NULL || 648184245Syongari (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 649184245Syongari return; 650184245Syongari 651184245Syongari sc->rl_flags &= ~RL_FLAG_LINK; 652184245Syongari if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == 653184245Syongari (IFM_ACTIVE | IFM_AVALID)) { 654184245Syongari switch (IFM_SUBTYPE(mii->mii_media_active)) { 655184245Syongari case IFM_10_T: 656184245Syongari case IFM_100_TX: 657184245Syongari sc->rl_flags |= RL_FLAG_LINK; 658184245Syongari break; 659184245Syongari default: 660184245Syongari break; 661184245Syongari } 662184245Syongari } 663184245Syongari /* 664184245Syongari * RealTek controllers do not provide any interface to 665184245Syongari * Tx/Rx MACs for resolved speed, duplex and flow-control 666184245Syongari * parameters. 667184245Syongari */ 66840516Swpaul} 66940516Swpaul 67040516Swpaul/* 67140516Swpaul * Program the 64-bit multicast hash filter. 67240516Swpaul */ 673102335Salfredstatic void 674131605Sbmsrl_setmulti(struct rl_softc *sc) 67540516Swpaul{ 676147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 67740516Swpaul int h = 0; 678131605Sbms uint32_t hashes[2] = { 0, 0 }; 67940516Swpaul struct ifmultiaddr *ifma; 680131605Sbms uint32_t rxfilt; 68140516Swpaul int mcnt = 0; 68240516Swpaul 683131606Sbms RL_LOCK_ASSERT(sc); 684131606Sbms 68540516Swpaul rxfilt = CSR_READ_4(sc, RL_RXCFG); 68640516Swpaul 68743062Swpaul if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 68840516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 68940516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 69040516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF); 69140516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF); 69240516Swpaul return; 69340516Swpaul } 69440516Swpaul 69540516Swpaul /* first, zot all the existing hash bits */ 69640516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0); 69740516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0); 69840516Swpaul 69940516Swpaul /* now program new ones */ 700148654Srwatson IF_ADDR_LOCK(ifp); 70172084Sphk TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 70240516Swpaul if (ifma->ifma_addr->sa_family != AF_LINK) 70340516Swpaul continue; 704130270Snaddy h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 705130270Snaddy ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 70640516Swpaul if (h < 32) 70740516Swpaul hashes[0] |= (1 << h); 70840516Swpaul else 70940516Swpaul hashes[1] |= (1 << (h - 32)); 71040516Swpaul mcnt++; 71140516Swpaul } 712148654Srwatson IF_ADDR_UNLOCK(ifp); 71340516Swpaul 71440516Swpaul if (mcnt) 71540516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 71640516Swpaul else 71740516Swpaul rxfilt &= ~RL_RXCFG_RX_MULTI; 71840516Swpaul 71940516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 72040516Swpaul CSR_WRITE_4(sc, RL_MAR0, hashes[0]); 72140516Swpaul CSR_WRITE_4(sc, RL_MAR4, hashes[1]); 72240516Swpaul} 72340516Swpaul 724102335Salfredstatic void 725131605Sbmsrl_reset(struct rl_softc *sc) 72640516Swpaul{ 72740516Swpaul register int i; 72840516Swpaul 729131606Sbms RL_LOCK_ASSERT(sc); 730131606Sbms 73140516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RESET); 73240516Swpaul 73340516Swpaul for (i = 0; i < RL_TIMEOUT; i++) { 73440516Swpaul DELAY(10); 73540516Swpaul if (!(CSR_READ_1(sc, RL_COMMAND) & RL_CMD_RESET)) 73640516Swpaul break; 73740516Swpaul } 73840516Swpaul if (i == RL_TIMEOUT) 739162315Sglebius device_printf(sc->rl_dev, "reset never completed!\n"); 74040516Swpaul} 74140516Swpaul 74240516Swpaul/* 74340516Swpaul * Probe for a RealTek 8129/8139 chip. Check the PCI vendor and device 74440516Swpaul * IDs against our list and return a device name if we find a match. 74540516Swpaul */ 746102335Salfredstatic int 747131605Sbmsrl_probe(device_t dev) 74840516Swpaul{ 749176757Syongari struct rl_type *t; 750176757Syongari uint16_t devid, revid, vendor; 751176757Syongari int i; 752176757Syongari 753176757Syongari vendor = pci_get_vendor(dev); 754176757Syongari devid = pci_get_device(dev); 755176757Syongari revid = pci_get_revid(dev); 75640516Swpaul 757176757Syongari if (vendor == RT_VENDORID && devid == RT_DEVICEID_8139) { 758176757Syongari if (revid == 0x20) { 759176757Syongari /* 8139C+, let re(4) take care of this device. */ 760176757Syongari return (ENXIO); 761176757Syongari } 762176757Syongari } 763176757Syongari t = rl_devs; 764176757Syongari for (i = 0; i < sizeof(rl_devs) / sizeof(rl_devs[0]); i++, t++) { 765176757Syongari if (vendor == t->rl_vid && devid == t->rl_did) { 766119868Swpaul device_set_desc(dev, t->rl_name); 767142398Simp return (BUS_PROBE_DEFAULT); 76840516Swpaul } 76940516Swpaul } 77040516Swpaul 771131605Sbms return (ENXIO); 77240516Swpaul} 77340516Swpaul 774184240Syongaristruct rl_dmamap_arg { 775184240Syongari bus_addr_t rl_busaddr; 776184240Syongari}; 777184240Syongari 778184240Syongaristatic void 779184240Syongarirl_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 780184240Syongari{ 781184240Syongari struct rl_dmamap_arg *ctx; 782184240Syongari 783184240Syongari if (error != 0) 784184240Syongari return; 785184240Syongari 786184240Syongari KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); 787184240Syongari 788184240Syongari ctx = (struct rl_dmamap_arg *)arg; 789184240Syongari ctx->rl_busaddr = segs[0].ds_addr; 790184240Syongari} 791184240Syongari 79240516Swpaul/* 79340516Swpaul * Attach the interface. Allocate softc structures, do ifmedia 79440516Swpaul * setup and ethernet/BPF attach. 79540516Swpaul */ 796102335Salfredstatic int 797131605Sbmsrl_attach(device_t dev) 79840516Swpaul{ 799131605Sbms uint8_t eaddr[ETHER_ADDR_LEN]; 800131605Sbms uint16_t as[3]; 801131605Sbms struct ifnet *ifp; 80240516Swpaul struct rl_softc *sc; 803117388Swpaul struct rl_type *t; 804131605Sbms int error = 0, i, rid; 805131605Sbms int unit; 806131605Sbms uint16_t rl_did = 0; 80740516Swpaul 80850703Swpaul sc = device_get_softc(dev); 80950703Swpaul unit = device_get_unit(dev); 810162315Sglebius sc->rl_dev = dev; 81140516Swpaul 81293818Sjhb mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 813131606Sbms MTX_DEF); 814150720Sjhb callout_init_mtx(&sc->rl_stat_callout, &sc->rl_mtx, 0); 815131605Sbms 81672813Swpaul pci_enable_busmaster(dev); 81740516Swpaul 818131605Sbms /* Map control/status registers. */ 819109109Sdes rid = RL_RID; 820127135Snjl sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, RF_ACTIVE); 82150703Swpaul 82250703Swpaul if (sc->rl_res == NULL) { 823131605Sbms device_printf(dev, "couldn't map ports/memory\n"); 82450703Swpaul error = ENXIO; 82540516Swpaul goto fail; 82640516Swpaul } 82740516Swpaul 828117388Swpaul#ifdef notdef 829131605Sbms /* 830131605Sbms * Detect the Realtek 8139B. For some reason, this chip is very 83169127Sroger * unstable when left to autoselect the media 83269127Sroger * The best workaround is to set the device to the required 83369127Sroger * media type or to set it to the 10 Meg speed. 83469127Sroger */ 835131605Sbms if ((rman_get_end(sc->rl_res) - rman_get_start(sc->rl_res)) == 0xFF) 836131605Sbms device_printf(dev, 837131605Sbms"Realtek 8139B detected. Warning, this may be unstable in autoselect mode\n"); 838117388Swpaul#endif 83969127Sroger 84050703Swpaul sc->rl_btag = rman_get_bustag(sc->rl_res); 84150703Swpaul sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 84250703Swpaul 843112872Snjl /* Allocate interrupt */ 84450703Swpaul rid = 0; 845171560Syongari sc->rl_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 84650703Swpaul RF_SHAREABLE | RF_ACTIVE); 84750703Swpaul 848171560Syongari if (sc->rl_irq[0] == NULL) { 849131605Sbms device_printf(dev, "couldn't map interrupt\n"); 85050703Swpaul error = ENXIO; 85140516Swpaul goto fail; 85240516Swpaul } 85340516Swpaul 854131606Sbms /* 855131606Sbms * Reset the adapter. Only take the lock here as it's needed in 856131606Sbms * order to call rl_reset(). 857131606Sbms */ 858131606Sbms RL_LOCK(sc); 85940516Swpaul rl_reset(sc); 860131606Sbms RL_UNLOCK(sc); 861131606Sbms 86267931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_6BIT; 863131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, 0, 1, 0); 86468215Swpaul if (rl_did != 0x8129) 86567931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_8BIT; 86640516Swpaul 86740516Swpaul /* 86840516Swpaul * Get station address from the EEPROM. 86940516Swpaul */ 870131605Sbms rl_read_eeprom(sc, (uint8_t *)as, RL_EE_EADDR, 3, 0); 871108729Sjake for (i = 0; i < 3; i++) { 872108729Sjake eaddr[(i * 2) + 0] = as[i] & 0xff; 873108729Sjake eaddr[(i * 2) + 1] = as[i] >> 8; 874108729Sjake } 87540516Swpaul 87640516Swpaul /* 87740516Swpaul * Now read the exact device type from the EEPROM to find 87840516Swpaul * out if it's an 8129 or 8139. 87940516Swpaul */ 880131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, RL_EE_PCI_DID, 1, 0); 88140516Swpaul 882117388Swpaul t = rl_devs; 883119868Swpaul sc->rl_type = 0; 884117388Swpaul while(t->rl_name != NULL) { 885117388Swpaul if (rl_did == t->rl_did) { 886117388Swpaul sc->rl_type = t->rl_basetype; 887117388Swpaul break; 888117388Swpaul } 889117388Swpaul t++; 890117388Swpaul } 891119868Swpaul 892119868Swpaul if (sc->rl_type == 0) { 893131605Sbms device_printf(dev, "unknown device ID: %x\n", rl_did); 89450703Swpaul error = ENXIO; 89540516Swpaul goto fail; 89640516Swpaul } 89740516Swpaul 898184240Syongari if ((error = rl_dma_alloc(sc)) != 0) 899112872Snjl goto fail; 90040516Swpaul 901147291Sbrooks ifp = sc->rl_ifp = if_alloc(IFT_ETHER); 902147291Sbrooks if (ifp == NULL) { 903147291Sbrooks device_printf(dev, "can not if_alloc()\n"); 904147291Sbrooks error = ENOSPC; 905147291Sbrooks goto fail; 906147291Sbrooks } 907147291Sbrooks 90850703Swpaul /* Do MII setup */ 90950703Swpaul if (mii_phy_probe(dev, &sc->rl_miibus, 91050703Swpaul rl_ifmedia_upd, rl_ifmedia_sts)) { 911131605Sbms device_printf(dev, "MII without any phy!\n"); 91250703Swpaul error = ENXIO; 91350703Swpaul goto fail; 91450703Swpaul } 91550703Swpaul 91640516Swpaul ifp->if_softc = sc; 917121816Sbrooks if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 91840516Swpaul ifp->if_mtu = ETHERMTU; 91940516Swpaul ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 92040516Swpaul ifp->if_ioctl = rl_ioctl; 921119868Swpaul ifp->if_start = rl_start; 92240516Swpaul ifp->if_init = rl_init; 923119976Swpaul ifp->if_capabilities = IFCAP_VLAN_MTU; 924150789Sglebius ifp->if_capenable = ifp->if_capabilities; 925128121Sru#ifdef DEVICE_POLLING 926128121Sru ifp->if_capabilities |= IFCAP_POLLING; 927128121Sru#endif 928131455Smlaier IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 929131455Smlaier ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 930131455Smlaier IFQ_SET_READY(&ifp->if_snd); 931131605Sbms 93240516Swpaul /* 93363090Sarchie * Call MI attach routine. 93440516Swpaul */ 935106936Ssam ether_ifattach(ifp, eaddr); 936106157Simp 937113609Snjl /* Hook interrupt last to avoid having to lock softc */ 938171560Syongari error = bus_setup_intr(dev, sc->rl_irq[0], INTR_TYPE_NET | INTR_MPSAFE, 939171560Syongari NULL, rl_intr, sc, &sc->rl_intrhand[0]); 940106157Simp if (error) { 941162315Sglebius device_printf(sc->rl_dev, "couldn't set up irq\n"); 942113609Snjl ether_ifdetach(ifp); 943106157Simp } 944106157Simp 94540516Swpaulfail: 946112872Snjl if (error) 947112872Snjl rl_detach(dev); 948112872Snjl 949110601Snjl return (error); 95040516Swpaul} 95140516Swpaul 952113609Snjl/* 953113609Snjl * Shutdown hardware and free up resources. This can be called any 954113609Snjl * time after the mutex has been initialized. It is called in both 955113609Snjl * the error case in attach and the normal detach case so it needs 956113609Snjl * to be careful about only freeing resources that have actually been 957113609Snjl * allocated. 958113609Snjl */ 959102335Salfredstatic int 960131605Sbmsrl_detach(device_t dev) 96150703Swpaul{ 96250703Swpaul struct rl_softc *sc; 96350703Swpaul struct ifnet *ifp; 96450703Swpaul 96550703Swpaul sc = device_get_softc(dev); 966147256Sbrooks ifp = sc->rl_ifp; 967131605Sbms 968112880Sjhb KASSERT(mtx_initialized(&sc->rl_mtx), ("rl mutex not initialized")); 969150720Sjhb 970150789Sglebius#ifdef DEVICE_POLLING 971150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 972150789Sglebius ether_poll_deregister(ifp); 973150789Sglebius#endif 974133403Sgreen /* These should only be active if attach succeeded */ 975150213Sru if (device_is_attached(dev)) { 976150126Sru RL_LOCK(sc); 977150126Sru rl_stop(sc); 978150126Sru RL_UNLOCK(sc); 979150720Sjhb callout_drain(&sc->rl_stat_callout); 980133403Sgreen ether_ifdetach(ifp); 981147256Sbrooks } 982131606Sbms#if 0 983131606Sbms sc->suspended = 1; 984131606Sbms#endif 985113609Snjl if (sc->rl_miibus) 986112872Snjl device_delete_child(dev, sc->rl_miibus); 987113609Snjl bus_generic_detach(dev); 98850703Swpaul 989171560Syongari if (sc->rl_intrhand[0]) 990171560Syongari bus_teardown_intr(dev, sc->rl_irq[0], sc->rl_intrhand[0]); 991171560Syongari if (sc->rl_irq[0]) 992171560Syongari bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq[0]); 993112872Snjl if (sc->rl_res) 994112872Snjl bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 99550703Swpaul 996151297Sru if (ifp) 997151297Sru if_free(ifp); 998151297Sru 999184240Syongari rl_dma_free(sc); 100050703Swpaul 100167087Swpaul mtx_destroy(&sc->rl_mtx); 100250703Swpaul 1003131605Sbms return (0); 100450703Swpaul} 100550703Swpaul 1006184240Syongaristatic int 1007184240Syongarirl_dma_alloc(struct rl_softc *sc) 1008184240Syongari{ 1009184240Syongari struct rl_dmamap_arg ctx; 1010184240Syongari int error, i; 1011184240Syongari 1012184240Syongari /* 1013184240Syongari * Allocate the parent bus DMA tag appropriate for PCI. 1014184240Syongari */ 1015184240Syongari error = bus_dma_tag_create(bus_get_dma_tag(sc->rl_dev), /* parent */ 1016184240Syongari 1, 0, /* alignment, boundary */ 1017184240Syongari BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 1018184240Syongari BUS_SPACE_MAXADDR, /* highaddr */ 1019184240Syongari NULL, NULL, /* filter, filterarg */ 1020184240Syongari BUS_SPACE_MAXSIZE_32BIT, 0, /* maxsize, nsegments */ 1021184240Syongari BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 1022184240Syongari 0, /* flags */ 1023184240Syongari NULL, NULL, /* lockfunc, lockarg */ 1024184240Syongari &sc->rl_parent_tag); 1025184240Syongari if (error) { 1026184240Syongari device_printf(sc->rl_dev, 1027184240Syongari "failed to create parent DMA tag.\n"); 1028184240Syongari goto fail; 1029184240Syongari } 1030184240Syongari /* Create DMA tag for Rx memory block. */ 1031184240Syongari error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */ 1032184240Syongari RL_RX_8139_BUF_ALIGN, 0, /* alignment, boundary */ 1033184240Syongari BUS_SPACE_MAXADDR, /* lowaddr */ 1034184240Syongari BUS_SPACE_MAXADDR, /* highaddr */ 1035184240Syongari NULL, NULL, /* filter, filterarg */ 1036184240Syongari RL_RXBUFLEN + RL_RX_8139_BUF_GUARD_SZ, 1, /* maxsize,nsegments */ 1037184240Syongari RL_RXBUFLEN + RL_RX_8139_BUF_GUARD_SZ, /* maxsegsize */ 1038184240Syongari 0, /* flags */ 1039184240Syongari NULL, NULL, /* lockfunc, lockarg */ 1040184240Syongari &sc->rl_cdata.rl_rx_tag); 1041184240Syongari if (error) { 1042184240Syongari device_printf(sc->rl_dev, 1043184240Syongari "failed to create Rx memory block DMA tag.\n"); 1044184240Syongari goto fail; 1045184240Syongari } 1046184240Syongari /* Create DMA tag for Tx buffer. */ 1047184240Syongari error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */ 1048184240Syongari RL_TX_8139_BUF_ALIGN, 0, /* alignment, boundary */ 1049184240Syongari BUS_SPACE_MAXADDR, /* lowaddr */ 1050184240Syongari BUS_SPACE_MAXADDR, /* highaddr */ 1051184240Syongari NULL, NULL, /* filter, filterarg */ 1052184240Syongari MCLBYTES, 1, /* maxsize, nsegments */ 1053184240Syongari MCLBYTES, /* maxsegsize */ 1054184240Syongari 0, /* flags */ 1055184240Syongari NULL, NULL, /* lockfunc, lockarg */ 1056184240Syongari &sc->rl_cdata.rl_tx_tag); 1057184240Syongari if (error) { 1058184240Syongari device_printf(sc->rl_dev, "failed to create Tx DMA tag.\n"); 1059184240Syongari goto fail; 1060184240Syongari } 1061184240Syongari 1062184240Syongari /* 1063184240Syongari * Allocate DMA'able memory and load DMA map for Rx memory block. 1064184240Syongari */ 1065184240Syongari error = bus_dmamem_alloc(sc->rl_cdata.rl_rx_tag, 1066184240Syongari (void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_WAITOK | 1067184240Syongari BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->rl_cdata.rl_rx_dmamap); 1068184240Syongari if (error != 0) { 1069184240Syongari device_printf(sc->rl_dev, 1070184240Syongari "failed to allocate Rx DMA memory block.\n"); 1071184240Syongari goto fail; 1072184240Syongari } 1073184240Syongari ctx.rl_busaddr = 0; 1074184240Syongari error = bus_dmamap_load(sc->rl_cdata.rl_rx_tag, 1075184240Syongari sc->rl_cdata.rl_rx_dmamap, sc->rl_cdata.rl_rx_buf, 1076184240Syongari RL_RXBUFLEN + RL_RX_8139_BUF_GUARD_SZ, rl_dmamap_cb, &ctx, 1077184240Syongari BUS_DMA_NOWAIT); 1078184240Syongari if (error != 0 || ctx.rl_busaddr == 0) { 1079184240Syongari device_printf(sc->rl_dev, 1080184240Syongari "could not load Rx DMA memory block.\n"); 1081184240Syongari goto fail; 1082184240Syongari } 1083184240Syongari sc->rl_cdata.rl_rx_buf_paddr = ctx.rl_busaddr; 1084184240Syongari 1085184240Syongari /* Create DMA maps for Tx buffers. */ 1086184240Syongari for (i = 0; i < RL_TX_LIST_CNT; i++) { 1087184240Syongari sc->rl_cdata.rl_tx_chain[i] = NULL; 1088184240Syongari sc->rl_cdata.rl_tx_dmamap[i] = NULL; 1089184240Syongari error = bus_dmamap_create(sc->rl_cdata.rl_tx_tag, 0, 1090184240Syongari &sc->rl_cdata.rl_tx_dmamap[i]); 1091184240Syongari if (error != 0) { 1092184240Syongari device_printf(sc->rl_dev, 1093184240Syongari "could not create Tx dmamap.\n"); 1094184240Syongari goto fail; 1095184240Syongari } 1096184240Syongari } 1097184240Syongari 1098184240Syongari /* Leave a few bytes before the start of the RX ring buffer. */ 1099184240Syongari sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf; 1100184240Syongari sc->rl_cdata.rl_rx_buf += RL_RX_8139_BUF_RESERVE; 1101184240Syongari 1102184240Syongarifail: 1103184240Syongari return (error); 1104184240Syongari} 1105184240Syongari 1106184240Syongaristatic void 1107184240Syongarirl_dma_free(struct rl_softc *sc) 1108184240Syongari{ 1109184240Syongari int i; 1110184240Syongari 1111184240Syongari /* Rx memory block. */ 1112184240Syongari if (sc->rl_cdata.rl_rx_tag != NULL) { 1113184240Syongari if (sc->rl_cdata.rl_rx_dmamap != NULL) 1114184240Syongari bus_dmamap_unload(sc->rl_cdata.rl_rx_tag, 1115184240Syongari sc->rl_cdata.rl_rx_dmamap); 1116184240Syongari if (sc->rl_cdata.rl_rx_dmamap != NULL && 1117184240Syongari sc->rl_cdata.rl_rx_buf_ptr != NULL) 1118184240Syongari bus_dmamem_free(sc->rl_cdata.rl_rx_tag, 1119184240Syongari sc->rl_cdata.rl_rx_buf_ptr, 1120184240Syongari sc->rl_cdata.rl_rx_dmamap); 1121184240Syongari sc->rl_cdata.rl_rx_buf_ptr = NULL; 1122184240Syongari sc->rl_cdata.rl_rx_buf = NULL; 1123184240Syongari sc->rl_cdata.rl_rx_dmamap = NULL; 1124184240Syongari bus_dma_tag_destroy(sc->rl_cdata.rl_rx_tag); 1125184240Syongari sc->rl_cdata.rl_tx_tag = NULL; 1126184240Syongari } 1127184240Syongari 1128184240Syongari /* Tx buffers. */ 1129184240Syongari if (sc->rl_cdata.rl_tx_tag != NULL) { 1130184240Syongari for (i = 0; i < RL_TX_LIST_CNT; i++) { 1131184240Syongari if (sc->rl_cdata.rl_tx_dmamap[i] != NULL) { 1132184240Syongari bus_dmamap_destroy( 1133184240Syongari sc->rl_cdata.rl_tx_tag, 1134184240Syongari sc->rl_cdata.rl_tx_dmamap[i]); 1135184240Syongari sc->rl_cdata.rl_tx_dmamap[i] = NULL; 1136184240Syongari } 1137184240Syongari bus_dma_tag_destroy(sc->rl_cdata.rl_tx_tag); 1138184240Syongari sc->rl_cdata.rl_tx_tag = NULL; 1139184240Syongari } 1140184240Syongari } 1141184240Syongari 1142184240Syongari if (sc->rl_parent_tag != NULL) { 1143184240Syongari bus_dma_tag_destroy(sc->rl_parent_tag); 1144184240Syongari sc->rl_parent_tag = NULL; 1145184240Syongari } 1146184240Syongari} 1147184240Syongari 114840516Swpaul/* 114940516Swpaul * Initialize the transmit descriptors. 115040516Swpaul */ 1151102335Salfredstatic int 1152131605Sbmsrl_list_tx_init(struct rl_softc *sc) 115340516Swpaul{ 115440516Swpaul struct rl_chain_data *cd; 115540516Swpaul int i; 115640516Swpaul 1157131606Sbms RL_LOCK_ASSERT(sc); 1158131606Sbms 115940516Swpaul cd = &sc->rl_cdata; 116040516Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 116145633Swpaul cd->rl_tx_chain[i] = NULL; 116248028Swpaul CSR_WRITE_4(sc, 1163131605Sbms RL_TXADDR0 + (i * sizeof(uint32_t)), 0x0000000); 116440516Swpaul } 116540516Swpaul 116645633Swpaul sc->rl_cdata.cur_tx = 0; 116745633Swpaul sc->rl_cdata.last_tx = 0; 116840516Swpaul 1169131605Sbms return (0); 117040516Swpaul} 117140516Swpaul 1172184240Syongaristatic int 1173184240Syongarirl_list_rx_init(struct rl_softc *sc) 1174184240Syongari{ 1175184240Syongari 1176184240Syongari RL_LOCK_ASSERT(sc); 1177184240Syongari 1178184240Syongari bzero(sc->rl_cdata.rl_rx_buf_ptr, 1179184240Syongari RL_RXBUFLEN + RL_RX_8139_BUF_GUARD_SZ); 1180184240Syongari bus_dmamap_sync(sc->rl_cdata.rl_tx_tag, sc->rl_cdata.rl_rx_dmamap, 1181184240Syongari BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1182184240Syongari 1183184240Syongari return (0); 1184184240Syongari} 1185184240Syongari 118640516Swpaul/* 118740516Swpaul * A frame has been uploaded: pass the resulting mbuf chain up to 118840516Swpaul * the higher level protocols. 118940516Swpaul * 119040516Swpaul * You know there's something wrong with a PCI bus-master chip design 119140516Swpaul * when you have to use m_devget(). 119240516Swpaul * 119340516Swpaul * The receive operation is badly documented in the datasheet, so I'll 119440516Swpaul * attempt to document it here. The driver provides a buffer area and 119540516Swpaul * places its base address in the RX buffer start address register. 119640516Swpaul * The chip then begins copying frames into the RX buffer. Each frame 119772645Sasmodai * is preceded by a 32-bit RX status word which specifies the length 119840516Swpaul * of the frame and certain other status bits. Each frame (starting with 119940516Swpaul * the status word) is also 32-bit aligned. The frame length is in the 120040516Swpaul * first 16 bits of the status word; the lower 15 bits correspond with 120140516Swpaul * the 'rx status register' mentioned in the datasheet. 120248028Swpaul * 120348028Swpaul * Note: to make the Alpha happy, the frame payload needs to be aligned 120478508Sbmilekic * on a 32-bit boundary. To achieve this, we pass RL_ETHER_ALIGN (2 bytes) 1205109109Sdes * as the offset argument to m_devget(). 120640516Swpaul */ 1207102335Salfredstatic void 1208131605Sbmsrl_rxeof(struct rl_softc *sc) 120940516Swpaul{ 1210109109Sdes struct mbuf *m; 1211147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1212131605Sbms uint8_t *rxbufpos; 121340516Swpaul int total_len = 0; 121440516Swpaul int wrap = 0; 1215131605Sbms uint32_t rxstat; 1216131605Sbms uint16_t cur_rx; 1217131605Sbms uint16_t limit; 1218131605Sbms uint16_t max_bytes, rx_bytes = 0; 121940516Swpaul 1220122689Ssam RL_LOCK_ASSERT(sc); 1221122689Ssam 1222184240Syongari bus_dmamap_sync(sc->rl_cdata.rl_rx_tag, sc->rl_cdata.rl_rx_dmamap, 1223184240Syongari BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 122481713Swpaul 122540516Swpaul cur_rx = (CSR_READ_2(sc, RL_CURRXADDR) + 16) % RL_RXBUFLEN; 122640516Swpaul 122740516Swpaul /* Do not try to read past this point. */ 122840516Swpaul limit = CSR_READ_2(sc, RL_CURRXBUF) % RL_RXBUFLEN; 122940516Swpaul 123040516Swpaul if (limit < cur_rx) 123140516Swpaul max_bytes = (RL_RXBUFLEN - cur_rx) + limit; 123240516Swpaul else 123340516Swpaul max_bytes = limit - cur_rx; 123440516Swpaul 123542738Swpaul while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) { 123694883Sluigi#ifdef DEVICE_POLLING 1237150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) { 123894883Sluigi if (sc->rxcycles <= 0) 123994883Sluigi break; 124094883Sluigi sc->rxcycles--; 124194883Sluigi } 1242150789Sglebius#endif 124340516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx; 1244131605Sbms rxstat = le32toh(*(uint32_t *)rxbufpos); 124540516Swpaul 124640516Swpaul /* 124740516Swpaul * Here's a totally undocumented fact for you. When the 124840516Swpaul * RealTek chip is in the process of copying a packet into 124940516Swpaul * RAM for you, the length will be 0xfff0. If you spot a 125040516Swpaul * packet header with this value, you need to stop. The 125140516Swpaul * datasheet makes absolutely no mention of this and 125240516Swpaul * RealTek should be shot for this. 125340516Swpaul */ 1254178054Syongari total_len = rxstat >> 16; 1255178054Syongari if (total_len == RL_RXSTAT_UNFINISHED) 125640516Swpaul break; 1257109109Sdes 1258178054Syongari if (!(rxstat & RL_RXSTAT_RXOK) || 1259178054Syongari total_len < ETHER_MIN_LEN || 1260178054Syongari total_len > ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) { 126140516Swpaul ifp->if_ierrors++; 1262131841Sbms rl_init_locked(sc); 126350703Swpaul return; 126440516Swpaul } 126540516Swpaul 1266109109Sdes /* No errors; receive the packet. */ 126740516Swpaul rx_bytes += total_len + 4; 126840516Swpaul 126940516Swpaul /* 127042051Swpaul * XXX The RealTek chip includes the CRC with every 127142051Swpaul * received frame, and there's no way to turn this 127242051Swpaul * behavior off (at least, I can't find anything in 1273109109Sdes * the manual that explains how to do it) so we have 127442051Swpaul * to trim off the CRC manually. 127542051Swpaul */ 127642051Swpaul total_len -= ETHER_CRC_LEN; 127742051Swpaul 127842051Swpaul /* 127940516Swpaul * Avoid trying to read more bytes than we know 128040516Swpaul * the chip has prepared for us. 128140516Swpaul */ 128240516Swpaul if (rx_bytes > max_bytes) 128340516Swpaul break; 128440516Swpaul 128540516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + 1286131605Sbms ((cur_rx + sizeof(uint32_t)) % RL_RXBUFLEN); 128740516Swpaul if (rxbufpos == (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN)) 128840516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf; 128940516Swpaul 129040516Swpaul wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos; 129140516Swpaul if (total_len > wrap) { 129278508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 129378508Sbmilekic NULL); 129440516Swpaul if (m == NULL) { 129540516Swpaul ifp->if_ierrors++; 129652426Swpaul } else { 129740516Swpaul m_copyback(m, wrap, total_len - wrap, 129840516Swpaul sc->rl_cdata.rl_rx_buf); 129948028Swpaul } 130042051Swpaul cur_rx = (total_len - wrap + ETHER_CRC_LEN); 130140516Swpaul } else { 130278508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 130378508Sbmilekic NULL); 1304131605Sbms if (m == NULL) 130540516Swpaul ifp->if_ierrors++; 130642051Swpaul cur_rx += total_len + 4 + ETHER_CRC_LEN; 130740516Swpaul } 130840516Swpaul 1309131605Sbms /* Round up to 32-bit boundary. */ 131040516Swpaul cur_rx = (cur_rx + 3) & ~3; 131140516Swpaul CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16); 131240516Swpaul 131340516Swpaul if (m == NULL) 131440516Swpaul continue; 131540516Swpaul 131640516Swpaul ifp->if_ipackets++; 1317122689Ssam RL_UNLOCK(sc); 1318106936Ssam (*ifp->if_input)(ifp, m); 1319122689Ssam RL_LOCK(sc); 132040516Swpaul } 1321184240Syongari 1322184524Simp /* No need to sync Rx memory block as we didn't modify it. */ 132340516Swpaul} 132440516Swpaul 132540516Swpaul/* 132640516Swpaul * A frame was downloaded to the chip. It's safe for us to clean up 132740516Swpaul * the list buffers. 132840516Swpaul */ 1329102335Salfredstatic void 1330131605Sbmsrl_txeof(struct rl_softc *sc) 133140516Swpaul{ 1332147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1333131605Sbms uint32_t txstat; 133440516Swpaul 1335131606Sbms RL_LOCK_ASSERT(sc); 1336131606Sbms 133740516Swpaul /* 133840516Swpaul * Go through our tx list and free mbufs for those 133940516Swpaul * frames that have been uploaded. 134040516Swpaul */ 134145633Swpaul do { 1342127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1343127783Sru break; 134445633Swpaul txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc)); 134545633Swpaul if (!(txstat & (RL_TXSTAT_TX_OK| 134645633Swpaul RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT))) 134740516Swpaul break; 134840516Swpaul 134945633Swpaul ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24; 135040516Swpaul 1351184240Syongari bus_dmamap_sync(sc->rl_cdata.rl_tx_tag, RL_LAST_DMAMAP(sc), 1352184240Syongari BUS_DMASYNC_POSTWRITE); 1353184240Syongari bus_dmamap_unload(sc->rl_cdata.rl_tx_tag, RL_LAST_DMAMAP(sc)); 1354127783Sru m_freem(RL_LAST_TXMBUF(sc)); 1355127783Sru RL_LAST_TXMBUF(sc) = NULL; 1356141676Smlaier /* 1357141676Smlaier * If there was a transmit underrun, bump the TX threshold. 1358141676Smlaier * Make sure not to overflow the 63 * 32byte we can address 1359141676Smlaier * with the 6 available bit. 1360141676Smlaier */ 1361141676Smlaier if ((txstat & RL_TXSTAT_TX_UNDERRUN) && 1362141676Smlaier (sc->rl_txthresh < 2016)) 1363141676Smlaier sc->rl_txthresh += 32; 136445633Swpaul if (txstat & RL_TXSTAT_TX_OK) 136545633Swpaul ifp->if_opackets++; 136645633Swpaul else { 136752426Swpaul int oldthresh; 136845633Swpaul ifp->if_oerrors++; 136945633Swpaul if ((txstat & RL_TXSTAT_TXABRT) || 137045633Swpaul (txstat & RL_TXSTAT_OUTOFWIN)) 137145633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 137252426Swpaul oldthresh = sc->rl_txthresh; 137352426Swpaul /* error recovery */ 1374131841Sbms rl_init_locked(sc); 1375141676Smlaier /* restore original threshold */ 1376141676Smlaier sc->rl_txthresh = oldthresh; 137752426Swpaul return; 137845633Swpaul } 137945633Swpaul RL_INC(sc->rl_cdata.last_tx); 1380148887Srwatson ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 138145633Swpaul } while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx); 138240516Swpaul 1383127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1384164811Sru sc->rl_watchdog_timer = 0; 138550703Swpaul} 138640516Swpaul 1387184515Simp#ifdef RL_TWISTER_ENABLE 1388102335Salfredstatic void 1389184515Simprl_twister_update(struct rl_softc *sc) 1390184515Simp{ 1391184515Simp uint16_t linktest; 1392184515Simp /* 1393184515Simp * Table provided by RealTek (Kinston <shangh@realtek.com.tw>) for 1394184515Simp * Linux driver. Values undocumented otherwise. 1395184515Simp */ 1396184515Simp static const uint32_t param[4][4] = { 1397184515Simp {0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43}, 1398184515Simp {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, 1399184515Simp {0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83}, 1400184515Simp {0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83} 1401184515Simp }; 1402184515Simp 1403184515Simp /* 1404184515Simp * Tune the so-called twister registers of the RTL8139. These 1405184524Simp * are used to compensate for impedance mismatches. The 1406184524Simp * method for tuning these registers is undocumented and the 1407184524Simp * following procedure is collected from public sources. 1408184515Simp */ 1409184515Simp switch (sc->rl_twister) 1410184515Simp { 1411184515Simp case CHK_LINK: 1412184515Simp /* 1413184524Simp * If we have a sufficient link, then we can proceed in 1414184515Simp * the state machine to the next stage. If not, then 1415184515Simp * disable further tuning after writing sane defaults. 1416184515Simp */ 1417184515Simp if (CSR_READ_2(sc, RL_CSCFG) & RL_CSCFG_LINK_OK) { 1418184515Simp CSR_WRITE_2(sc, RL_CSCFG, RL_CSCFG_LINK_DOWN_OFF_CMD); 1419184515Simp sc->rl_twister = FIND_ROW; 1420184515Simp } else { 1421184515Simp CSR_WRITE_2(sc, RL_CSCFG, RL_CSCFG_LINK_DOWN_CMD); 1422184515Simp CSR_WRITE_4(sc, RL_NWAYTST, RL_NWAYTST_CBL_TEST); 1423184515Simp CSR_WRITE_4(sc, RL_PARA78, RL_PARA78_DEF); 1424184515Simp CSR_WRITE_4(sc, RL_PARA7C, RL_PARA7C_DEF); 1425184515Simp sc->rl_twister = DONE; 1426184515Simp } 1427184515Simp break; 1428184515Simp case FIND_ROW: 1429184515Simp /* 1430184515Simp * Read how long it took to see the echo to find the tuning 1431184515Simp * row to use. 1432184515Simp */ 1433184515Simp linktest = CSR_READ_2(sc, RL_CSCFG) & RL_CSCFG_STATUS; 1434184515Simp if (linktest == RL_CSCFG_ROW3) 1435184515Simp sc->rl_twist_row = 3; 1436184515Simp else if (linktest == RL_CSCFG_ROW2) 1437184515Simp sc->rl_twist_row = 2; 1438184515Simp else if (linktest == RL_CSCFG_ROW1) 1439184515Simp sc->rl_twist_row = 1; 1440184515Simp else 1441184515Simp sc->rl_twist_row = 0; 1442184515Simp sc->rl_twist_col = 0; 1443184515Simp sc->rl_twister = SET_PARAM; 1444184515Simp break; 1445184515Simp case SET_PARAM: 1446184515Simp if (sc->rl_twist_col == 0) 1447184515Simp CSR_WRITE_4(sc, RL_NWAYTST, RL_NWAYTST_RESET); 1448184515Simp CSR_WRITE_4(sc, RL_PARA7C, 1449184515Simp param[sc->rl_twist_row][sc->rl_twist_col]); 1450184515Simp if (++sc->rl_twist_col == 4) { 1451184515Simp if (sc->rl_twist_row == 3) 1452184515Simp sc->rl_twister = RECHK_LONG; 1453184515Simp else 1454184515Simp sc->rl_twister = DONE; 1455184515Simp } 1456184515Simp break; 1457184515Simp case RECHK_LONG: 1458184515Simp /* 1459184515Simp * For long cables, we have to double check to make sure we 1460184515Simp * don't mistune. 1461184515Simp */ 1462184515Simp linktest = CSR_READ_2(sc, RL_CSCFG) & RL_CSCFG_STATUS; 1463184515Simp if (linktest == RL_CSCFG_ROW3) 1464184515Simp sc->rl_twister = DONE; 1465184515Simp else { 1466184515Simp CSR_WRITE_4(sc, RL_PARA7C, RL_PARA7C_RETUNE); 1467184515Simp sc->rl_twister = RETUNE; 1468184515Simp } 1469184515Simp break; 1470184515Simp case RETUNE: 1471184515Simp /* Retune for a shorter cable (try column 2) */ 1472184515Simp CSR_WRITE_4(sc, RL_NWAYTST, RL_NWAYTST_CBL_TEST); 1473184515Simp CSR_WRITE_4(sc, RL_PARA78, RL_PARA78_DEF); 1474184515Simp CSR_WRITE_4(sc, RL_PARA7C, RL_PARA7C_DEF); 1475184515Simp CSR_WRITE_4(sc, RL_NWAYTST, RL_NWAYTST_RESET); 1476184515Simp sc->rl_twist_row--; 1477184515Simp sc->rl_twist_col = 0; 1478184515Simp sc->rl_twister = SET_PARAM; 1479184515Simp break; 1480184515Simp 1481184515Simp case DONE: 1482184515Simp break; 1483184515Simp } 1484184515Simp 1485184515Simp} 1486184515Simp#endif 1487184515Simp 1488184515Simpstatic void 1489131605Sbmsrl_tick(void *xsc) 149050703Swpaul{ 1491131605Sbms struct rl_softc *sc = xsc; 149250703Swpaul struct mii_data *mii; 1493184515Simp int ticks; 149450703Swpaul 1495150720Sjhb RL_LOCK_ASSERT(sc); 1496184515Simp /* 1497184515Simp * If we're doing the twister cable calibration, then we need to defer 1498184515Simp * watchdog timeouts. This is a no-op in normal operations, but 1499184515Simp * can falsely trigger when the cable calibration takes a while and 1500184515Simp * there was traffic ready to go when rl was started. 1501184515Simp * 1502184515Simp * We don't defer mii_tick since that updates the mii status, which 1503184515Simp * helps the twister process, at least according to similar patches 1504184515Simp * for the Linux driver I found online while doing the fixes. Worst 1505184515Simp * case is a few extra mii reads during calibration. 1506184515Simp */ 150750703Swpaul mii = device_get_softc(sc->rl_miibus); 150850703Swpaul mii_tick(mii); 1509184515Simp#ifdef RL_TWISTER_ENABLE 1510184515Simp if (sc->rl_twister == DONE) 1511184515Simp rl_watchdog(sc); 1512184515Simp else 1513184515Simp rl_twister_update(sc); 1514184515Simp if (sc->rl_twister == DONE) 1515184515Simp ticks = hz; 1516184515Simp else 1517184515Simp ticks = hz / 10; 1518184515Simp#else 1519164811Sru rl_watchdog(sc); 1520184515Simp ticks = hz; 1521184515Simp#endif 1522164811Sru 1523184515Simp callout_reset(&sc->rl_stat_callout, ticks, rl_tick, sc); 152440516Swpaul} 152540516Swpaul 152694883Sluigi#ifdef DEVICE_POLLING 152794883Sluigistatic void 1528131841Sbmsrl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 152994883Sluigi{ 153094883Sluigi struct rl_softc *sc = ifp->if_softc; 153194883Sluigi 153294883Sluigi RL_LOCK(sc); 1533150789Sglebius if (ifp->if_drv_flags & IFF_DRV_RUNNING) 1534150789Sglebius rl_poll_locked(ifp, cmd, count); 1535131841Sbms RL_UNLOCK(sc); 1536131841Sbms} 1537131605Sbms 1538131841Sbmsstatic void 1539131841Sbmsrl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) 1540131841Sbms{ 1541131841Sbms struct rl_softc *sc = ifp->if_softc; 1542131841Sbms 1543131841Sbms RL_LOCK_ASSERT(sc); 1544131841Sbms 154594883Sluigi sc->rxcycles = count; 1546119868Swpaul rl_rxeof(sc); 1547119868Swpaul rl_txeof(sc); 1548131605Sbms 1549131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1550131841Sbms rl_start_locked(ifp); 155194883Sluigi 1552131605Sbms if (cmd == POLL_AND_CHECK_STATUS) { 1553131605Sbms uint16_t status; 155494883Sluigi 1555131605Sbms /* We should also check the status register. */ 155694883Sluigi status = CSR_READ_2(sc, RL_ISR); 1557100957Sjhb if (status == 0xffff) 1558131841Sbms return; 1559131605Sbms if (status != 0) 156094883Sluigi CSR_WRITE_2(sc, RL_ISR, status); 156194883Sluigi 1562131605Sbms /* XXX We should check behaviour on receiver stalls. */ 156394883Sluigi 1564184242Syongari if (status & RL_ISR_SYSTEM_ERR) 1565131841Sbms rl_init_locked(sc); 156694883Sluigi } 156794883Sluigi} 156894883Sluigi#endif /* DEVICE_POLLING */ 156994883Sluigi 1570102335Salfredstatic void 1571131605Sbmsrl_intr(void *arg) 157240516Swpaul{ 1573131605Sbms struct rl_softc *sc = arg; 1574147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1575131605Sbms uint16_t status; 157640516Swpaul 1577131606Sbms RL_LOCK(sc); 1578131606Sbms 1579131841Sbms if (sc->suspended) 1580131841Sbms goto done_locked; 158186822Siwasaki 158294883Sluigi#ifdef DEVICE_POLLING 1583150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 1584131841Sbms goto done_locked; 1585150789Sglebius#endif 1586131841Sbms 158740516Swpaul for (;;) { 158840516Swpaul status = CSR_READ_2(sc, RL_ISR); 1589131605Sbms /* If the card has gone away, the read returns 0xffff. */ 1590100957Sjhb if (status == 0xffff) 1591100957Sjhb break; 1592131605Sbms if (status != 0) 159340516Swpaul CSR_WRITE_2(sc, RL_ISR, status); 159440516Swpaul if ((status & RL_INTRS) == 0) 159540516Swpaul break; 159640516Swpaul if (status & RL_ISR_RX_OK) 159740516Swpaul rl_rxeof(sc); 159840516Swpaul if (status & RL_ISR_RX_ERR) 159940516Swpaul rl_rxeof(sc); 160045633Swpaul if ((status & RL_ISR_TX_OK) || (status & RL_ISR_TX_ERR)) 160140516Swpaul rl_txeof(sc); 1602184242Syongari if (status & RL_ISR_SYSTEM_ERR) 1603131841Sbms rl_init_locked(sc); 160440516Swpaul } 160540516Swpaul 1606131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1607131841Sbms rl_start_locked(ifp); 1608131841Sbms 1609131841Sbmsdone_locked: 1610131606Sbms RL_UNLOCK(sc); 161140516Swpaul} 161240516Swpaul 161340516Swpaul/* 161440516Swpaul * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 161540516Swpaul * pointers to the fragment pointers. 161640516Swpaul */ 1617102335Salfredstatic int 1618184240Syongarirl_encap(struct rl_softc *sc, struct mbuf **m_head) 161940516Swpaul{ 1620184240Syongari struct mbuf *m; 1621184240Syongari bus_dma_segment_t txsegs[1]; 1622184240Syongari int error, nsegs, padlen; 162340516Swpaul 1624131606Sbms RL_LOCK_ASSERT(sc); 1625131606Sbms 1626184240Syongari m = *m_head; 1627184240Syongari padlen = 0; 162840516Swpaul /* 1629184240Syongari * Hardware doesn't auto-pad, so we have to make sure 1630184240Syongari * pad short frames out to the minimum frame length. 1631184240Syongari */ 1632184240Syongari if (m->m_pkthdr.len < RL_MIN_FRAMELEN) 1633184240Syongari padlen = RL_MIN_FRAMELEN - m->m_pkthdr.len; 1634184240Syongari /* 163545633Swpaul * The RealTek is brain damaged and wants longword-aligned 163645633Swpaul * TX buffers, plus we can only have one fragment buffer 163745633Swpaul * per packet. We have to copy pretty much all the time. 163840516Swpaul */ 1639184240Syongari if (m->m_next != NULL || (mtod(m, uintptr_t) & 3) != 0 || 1640184240Syongari (padlen > 0 && M_TRAILINGSPACE(m) < padlen)) { 1641184240Syongari m = m_defrag(*m_head, M_DONTWAIT); 1642184240Syongari if (m == NULL) { 1643184240Syongari m_freem(*m_head); 1644184240Syongari *m_head = NULL; 1645184240Syongari return (ENOMEM); 1646184240Syongari } 1647113496Ssilby } 1648184240Syongari *m_head = m; 164940516Swpaul 1650184240Syongari if (padlen > 0) { 165155058Swpaul /* 1652184524Simp * Make security-conscious people happy: zero out the 165355058Swpaul * bytes in the pad area, since we don't know what 165455058Swpaul * this mbuf cluster buffer's previous user might 165555058Swpaul * have left in it. 1656109109Sdes */ 1657184240Syongari bzero(mtod(m, char *) + m->m_pkthdr.len, padlen); 1658184240Syongari m->m_pkthdr.len += padlen; 1659184240Syongari m->m_len = m->m_pkthdr.len; 166041243Swpaul } 166140516Swpaul 1662184240Syongari error = bus_dmamap_load_mbuf_sg(sc->rl_cdata.rl_tx_tag, 1663184240Syongari RL_CUR_DMAMAP(sc), m, txsegs, &nsegs, 0); 1664184240Syongari if (error != 0) 1665184240Syongari return (error); 1666184240Syongari if (nsegs == 0) { 1667184240Syongari m_freem(*m_head); 1668184240Syongari *m_head = NULL; 1669184240Syongari return (EIO); 1670184240Syongari } 167140516Swpaul 1672184240Syongari RL_CUR_TXMBUF(sc) = m; 1673184240Syongari bus_dmamap_sync(sc->rl_cdata.rl_tx_tag, RL_CUR_DMAMAP(sc), 1674184240Syongari BUS_DMASYNC_PREWRITE); 1675184240Syongari CSR_WRITE_4(sc, RL_CUR_TXADDR(sc), RL_ADDR_LO(txsegs[0].ds_addr)); 1676184240Syongari 1677131605Sbms return (0); 167840516Swpaul} 167940516Swpaul 168040516Swpaul/* 168140516Swpaul * Main transmit routine. 168240516Swpaul */ 1683102335Salfredstatic void 1684131605Sbmsrl_start(struct ifnet *ifp) 168540516Swpaul{ 1686131605Sbms struct rl_softc *sc = ifp->if_softc; 168740516Swpaul 168867087Swpaul RL_LOCK(sc); 1689131841Sbms rl_start_locked(ifp); 1690131841Sbms RL_UNLOCK(sc); 1691131841Sbms} 169240516Swpaul 1693131841Sbmsstatic void 1694131841Sbmsrl_start_locked(struct ifnet *ifp) 1695131841Sbms{ 1696131841Sbms struct rl_softc *sc = ifp->if_softc; 1697131841Sbms struct mbuf *m_head = NULL; 1698131841Sbms 1699131841Sbms RL_LOCK_ASSERT(sc); 1700131841Sbms 1701184245Syongari if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != 1702184245Syongari IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0) 1703184245Syongari return; 1704184245Syongari 1705131605Sbms while (RL_CUR_TXMBUF(sc) == NULL) { 1706131841Sbms 1707131455Smlaier IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); 1708131841Sbms 170940516Swpaul if (m_head == NULL) 171040516Swpaul break; 171140516Swpaul 1712184240Syongari if (rl_encap(sc, &m_head)) { 1713184240Syongari if (m_head == NULL) 1714184240Syongari break; 1715184240Syongari IFQ_DRV_PREPEND(&ifp->if_snd, m_head); 1716184240Syongari ifp->if_drv_flags |= IFF_DRV_OACTIVE; 171758801Swpaul break; 1718184240Syongari } 171940516Swpaul 1720131605Sbms /* Pass a copy of this mbuf chain to the bpf subsystem. */ 1721106936Ssam BPF_MTAP(ifp, RL_CUR_TXMBUF(sc)); 172251583Swpaul 1723131605Sbms /* Transmit the frame. */ 172445633Swpaul CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc), 172552426Swpaul RL_TXTHRESH(sc->rl_txthresh) | 172652426Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len); 172745633Swpaul 172845633Swpaul RL_INC(sc->rl_cdata.cur_tx); 1729113237Ssilby 1730131605Sbms /* Set a timeout in case the chip goes out to lunch. */ 1731164811Sru sc->rl_watchdog_timer = 5; 173240516Swpaul } 173340516Swpaul 173440516Swpaul /* 173545633Swpaul * We broke out of the loop because all our TX slots are 173645633Swpaul * full. Mark the NIC as busy until it drains some of the 173745633Swpaul * packets from the queue. 173845633Swpaul */ 173945633Swpaul if (RL_CUR_TXMBUF(sc) != NULL) 1740148887Srwatson ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1741131841Sbms} 174245633Swpaul 1743131841Sbmsstatic void 1744131841Sbmsrl_init(void *xsc) 1745131841Sbms{ 1746131841Sbms struct rl_softc *sc = xsc; 1747131841Sbms 1748131841Sbms RL_LOCK(sc); 1749131841Sbms rl_init_locked(sc); 175067087Swpaul RL_UNLOCK(sc); 175140516Swpaul} 175240516Swpaul 1753102335Salfredstatic void 1754131841Sbmsrl_init_locked(struct rl_softc *sc) 175540516Swpaul{ 1756147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 175750703Swpaul struct mii_data *mii; 1758131605Sbms uint32_t rxcfg = 0; 1759165311Syongari uint32_t eaddr[2]; 176040516Swpaul 1761131841Sbms RL_LOCK_ASSERT(sc); 1762131841Sbms 176350703Swpaul mii = device_get_softc(sc->rl_miibus); 176440516Swpaul 176540516Swpaul /* 176640516Swpaul * Cancel pending I/O and free all RX/TX buffers. 176740516Swpaul */ 176840516Swpaul rl_stop(sc); 176940516Swpaul 1770184242Syongari rl_reset(sc); 1771184515Simp#ifdef RL_TWISTER_ENABLE 1772184515Simp /* 1773184515Simp * Reset twister register tuning state. The twister registers 1774184515Simp * and their tuning are undocumented, but are necessary to cope 1775184515Simp * with bad links. rl_twister = DONE here will disable this entirely. 1776184515Simp */ 1777184515Simp sc->rl_twister = CHK_LINK; 1778184515Simp#endif 1779184242Syongari 1780117029Swpaul /* 1781117029Swpaul * Init our MAC address. Even though the chipset 1782117029Swpaul * documentation doesn't mention it, we need to enter "Config 1783117029Swpaul * register write enable" mode to modify the ID registers. 1784117029Swpaul */ 1785117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG); 1786165311Syongari bzero(eaddr, sizeof(eaddr)); 1787165311Syongari bcopy(IF_LLADDR(sc->rl_ifp), eaddr, ETHER_ADDR_LEN); 1788165311Syongari CSR_WRITE_STREAM_4(sc, RL_IDR0, eaddr[0]); 1789165311Syongari CSR_WRITE_STREAM_4(sc, RL_IDR4, eaddr[1]); 1790117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 179140516Swpaul 1792184240Syongari /* Init the RX memory block pointer register. */ 1793184240Syongari CSR_WRITE_4(sc, RL_RXADDR, sc->rl_cdata.rl_rx_buf_paddr + 1794184240Syongari RL_RX_8139_BUF_RESERVE); 1795119868Swpaul /* Init TX descriptors. */ 1796119868Swpaul rl_list_tx_init(sc); 1797184240Syongari /* Init Rx memory block. */ 1798184240Syongari rl_list_rx_init(sc); 179940516Swpaul 180040516Swpaul /* 180140516Swpaul * Enable transmit and receive. 180240516Swpaul */ 180340516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 180440516Swpaul 180540516Swpaul /* 180645633Swpaul * Set the initial TX and RX configuration. 180740516Swpaul */ 180845633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 180940516Swpaul CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); 181040516Swpaul 181140516Swpaul /* Set the individual bit to receive frames for this host only. */ 181240516Swpaul rxcfg = CSR_READ_4(sc, RL_RXCFG); 181340516Swpaul rxcfg |= RL_RXCFG_RX_INDIV; 181440516Swpaul 181540516Swpaul /* If we want promiscuous mode, set the allframes bit. */ 181640516Swpaul if (ifp->if_flags & IFF_PROMISC) { 181740516Swpaul rxcfg |= RL_RXCFG_RX_ALLPHYS; 181840516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 181940516Swpaul } else { 182040516Swpaul rxcfg &= ~RL_RXCFG_RX_ALLPHYS; 182140516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 182240516Swpaul } 182340516Swpaul 1824131605Sbms /* Set capture broadcast bit to capture broadcast frames. */ 182540516Swpaul if (ifp->if_flags & IFF_BROADCAST) { 182640516Swpaul rxcfg |= RL_RXCFG_RX_BROAD; 182740516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 182840516Swpaul } else { 182940516Swpaul rxcfg &= ~RL_RXCFG_RX_BROAD; 183040516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 183140516Swpaul } 183240516Swpaul 1833131605Sbms /* Program the multicast filter, if necessary. */ 183440516Swpaul rl_setmulti(sc); 183540516Swpaul 183694883Sluigi#ifdef DEVICE_POLLING 1837131605Sbms /* Disable interrupts if we are polling. */ 1838150789Sglebius if (ifp->if_capenable & IFCAP_POLLING) 183994883Sluigi CSR_WRITE_2(sc, RL_IMR, 0); 1840131605Sbms else 1841150789Sglebius#endif 1842131605Sbms /* Enable interrupts. */ 1843119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 184440516Swpaul 184552426Swpaul /* Set initial TX threshold */ 184652426Swpaul sc->rl_txthresh = RL_TX_THRESH_INIT; 184752426Swpaul 184840516Swpaul /* Start RX/TX process. */ 184940516Swpaul CSR_WRITE_4(sc, RL_MISSEDPKT, 0); 1850119868Swpaul 185140516Swpaul /* Enable receiver and transmitter. */ 185240516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 185340516Swpaul 1854184245Syongari sc->rl_flags &= ~RL_FLAG_LINK; 185550703Swpaul mii_mediachg(mii); 185640516Swpaul 185740516Swpaul CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); 185840516Swpaul 1859148887Srwatson ifp->if_drv_flags |= IFF_DRV_RUNNING; 1860148887Srwatson ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 186140516Swpaul 1862150720Sjhb callout_reset(&sc->rl_stat_callout, hz, rl_tick, sc); 186340516Swpaul} 186440516Swpaul 186540516Swpaul/* 186640516Swpaul * Set media options. 186740516Swpaul */ 1868102335Salfredstatic int 1869131605Sbmsrl_ifmedia_upd(struct ifnet *ifp) 187040516Swpaul{ 1871131605Sbms struct rl_softc *sc = ifp->if_softc; 187250703Swpaul struct mii_data *mii; 187340516Swpaul 187450703Swpaul mii = device_get_softc(sc->rl_miibus); 1875131605Sbms 1876150720Sjhb RL_LOCK(sc); 187750703Swpaul mii_mediachg(mii); 1878150720Sjhb RL_UNLOCK(sc); 187940516Swpaul 1880131605Sbms return (0); 188140516Swpaul} 188240516Swpaul 188340516Swpaul/* 188440516Swpaul * Report current media status. 188540516Swpaul */ 1886102335Salfredstatic void 1887131605Sbmsrl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 188840516Swpaul{ 1889131605Sbms struct rl_softc *sc = ifp->if_softc; 189050703Swpaul struct mii_data *mii; 189140516Swpaul 189250703Swpaul mii = device_get_softc(sc->rl_miibus); 189340516Swpaul 1894150720Sjhb RL_LOCK(sc); 189550703Swpaul mii_pollstat(mii); 1896150720Sjhb RL_UNLOCK(sc); 189750703Swpaul ifmr->ifm_active = mii->mii_media_active; 189850703Swpaul ifmr->ifm_status = mii->mii_media_status; 189940516Swpaul} 190040516Swpaul 1901102335Salfredstatic int 1902131605Sbmsrl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 190340516Swpaul{ 1904131605Sbms struct ifreq *ifr = (struct ifreq *)data; 1905131605Sbms struct mii_data *mii; 190640516Swpaul struct rl_softc *sc = ifp->if_softc; 190767087Swpaul int error = 0; 190840516Swpaul 1909131605Sbms switch (command) { 191040516Swpaul case SIOCSIFFLAGS: 1911131841Sbms RL_LOCK(sc); 191240516Swpaul if (ifp->if_flags & IFF_UP) { 1913131841Sbms rl_init_locked(sc); 191440516Swpaul } else { 1915148887Srwatson if (ifp->if_drv_flags & IFF_DRV_RUNNING) 191640516Swpaul rl_stop(sc); 191740516Swpaul } 1918131841Sbms RL_UNLOCK(sc); 191940516Swpaul error = 0; 192040516Swpaul break; 192140516Swpaul case SIOCADDMULTI: 192240516Swpaul case SIOCDELMULTI: 1923131606Sbms RL_LOCK(sc); 192440516Swpaul rl_setmulti(sc); 1925131606Sbms RL_UNLOCK(sc); 192640516Swpaul error = 0; 192740516Swpaul break; 192840516Swpaul case SIOCGIFMEDIA: 192940516Swpaul case SIOCSIFMEDIA: 193050703Swpaul mii = device_get_softc(sc->rl_miibus); 193150703Swpaul error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 193240516Swpaul break; 1933128121Sru case SIOCSIFCAP: 1934150789Sglebius#ifdef DEVICE_POLLING 1935150789Sglebius if (ifr->ifr_reqcap & IFCAP_POLLING && 1936150789Sglebius !(ifp->if_capenable & IFCAP_POLLING)) { 1937150789Sglebius error = ether_poll_register(rl_poll, ifp); 1938150789Sglebius if (error) 1939150789Sglebius return(error); 1940150789Sglebius RL_LOCK(sc); 1941150789Sglebius /* Disable interrupts */ 1942150789Sglebius CSR_WRITE_2(sc, RL_IMR, 0x0000); 1943150789Sglebius ifp->if_capenable |= IFCAP_POLLING; 1944150789Sglebius RL_UNLOCK(sc); 1945150789Sglebius return (error); 1946150789Sglebius 1947150789Sglebius } 1948150789Sglebius if (!(ifr->ifr_reqcap & IFCAP_POLLING) && 1949150789Sglebius ifp->if_capenable & IFCAP_POLLING) { 1950150789Sglebius error = ether_poll_deregister(ifp); 1951150789Sglebius /* Enable interrupts. */ 1952150789Sglebius RL_LOCK(sc); 1953150789Sglebius CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 1954150789Sglebius ifp->if_capenable &= ~IFCAP_POLLING; 1955150789Sglebius RL_UNLOCK(sc); 1956150789Sglebius return (error); 1957150789Sglebius } 1958150789Sglebius#endif /* DEVICE_POLLING */ 1959128121Sru break; 196040516Swpaul default: 1961106936Ssam error = ether_ioctl(ifp, command, data); 196240516Swpaul break; 196340516Swpaul } 196440516Swpaul 1965131605Sbms return (error); 196640516Swpaul} 196740516Swpaul 1968102335Salfredstatic void 1969164811Srurl_watchdog(struct rl_softc *sc) 197040516Swpaul{ 197140516Swpaul 1972164811Sru RL_LOCK_ASSERT(sc); 1973131605Sbms 1974164811Sru if (sc->rl_watchdog_timer == 0 || --sc->rl_watchdog_timer >0) 1975164811Sru return; 197650703Swpaul 1977164811Sru device_printf(sc->rl_dev, "watchdog timeout\n"); 1978164811Sru sc->rl_ifp->if_oerrors++; 1979164811Sru 1980119868Swpaul rl_txeof(sc); 1981119868Swpaul rl_rxeof(sc); 1982131841Sbms rl_init_locked(sc); 198340516Swpaul} 198440516Swpaul 198540516Swpaul/* 198640516Swpaul * Stop the adapter and free any mbufs allocated to the 198740516Swpaul * RX and TX lists. 198840516Swpaul */ 1989102335Salfredstatic void 1990131605Sbmsrl_stop(struct rl_softc *sc) 199140516Swpaul{ 199240516Swpaul register int i; 1993147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 199440516Swpaul 1995131606Sbms RL_LOCK_ASSERT(sc); 1996131606Sbms 1997164811Sru sc->rl_watchdog_timer = 0; 1998150720Sjhb callout_stop(&sc->rl_stat_callout); 1999148887Srwatson ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); 2000184245Syongari sc->rl_flags &= ~RL_FLAG_LINK; 200150703Swpaul 200240516Swpaul CSR_WRITE_1(sc, RL_COMMAND, 0x00); 200340516Swpaul CSR_WRITE_2(sc, RL_IMR, 0x0000); 2004184243Syongari for (i = 0; i < RL_TIMEOUT; i++) { 2005184243Syongari DELAY(10); 2006184243Syongari if ((CSR_READ_1(sc, RL_COMMAND) & 2007184243Syongari (RL_CMD_RX_ENB | RL_CMD_TX_ENB)) == 0) 2008184243Syongari break; 2009184243Syongari } 2010184243Syongari if (i == RL_TIMEOUT) 2011184243Syongari device_printf(sc->rl_dev, "Unable to stop Tx/Rx MAC\n"); 201240516Swpaul 2013119868Swpaul /* 2014119868Swpaul * Free the TX list buffers. 2015119868Swpaul */ 2016119868Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 2017119868Swpaul if (sc->rl_cdata.rl_tx_chain[i] != NULL) { 2018184240Syongari if (sc->rl_cdata.rl_tx_chain[i] != NULL) { 2019184240Syongari bus_dmamap_sync(sc->rl_cdata.rl_tx_tag, 2020184240Syongari sc->rl_cdata.rl_tx_dmamap[i], 2021184240Syongari BUS_DMASYNC_POSTWRITE); 2022184240Syongari bus_dmamap_unload(sc->rl_cdata.rl_tx_tag, 2023184240Syongari sc->rl_cdata.rl_tx_dmamap[i]); 2024184240Syongari m_freem(sc->rl_cdata.rl_tx_chain[i]); 2025184240Syongari sc->rl_cdata.rl_tx_chain[i] = NULL; 2026184240Syongari } 2027131605Sbms CSR_WRITE_4(sc, RL_TXADDR0 + (i * sizeof(uint32_t)), 2028124816Swpaul 0x0000000); 202940516Swpaul } 203040516Swpaul } 203140516Swpaul} 203240516Swpaul 203340516Swpaul/* 203486822Siwasaki * Device suspend routine. Stop the interface and save some PCI 203586822Siwasaki * settings in case the BIOS doesn't restore them properly on 203686822Siwasaki * resume. 203786822Siwasaki */ 2038102335Salfredstatic int 2039131605Sbmsrl_suspend(device_t dev) 204086822Siwasaki{ 204186822Siwasaki struct rl_softc *sc; 204286822Siwasaki 204386822Siwasaki sc = device_get_softc(dev); 2044131606Sbms 2045131606Sbms RL_LOCK(sc); 204686822Siwasaki rl_stop(sc); 204786822Siwasaki sc->suspended = 1; 2048131606Sbms RL_UNLOCK(sc); 204986822Siwasaki 205086822Siwasaki return (0); 205186822Siwasaki} 205286822Siwasaki 205386822Siwasaki/* 205486822Siwasaki * Device resume routine. Restore some PCI settings in case the BIOS 205586822Siwasaki * doesn't, re-enable busmastering, and restart the interface if 205686822Siwasaki * appropriate. 205786822Siwasaki */ 2058102335Salfredstatic int 2059131605Sbmsrl_resume(device_t dev) 206086822Siwasaki{ 206186822Siwasaki struct rl_softc *sc; 206286822Siwasaki struct ifnet *ifp; 206386822Siwasaki 206486822Siwasaki sc = device_get_softc(dev); 2065147256Sbrooks ifp = sc->rl_ifp; 206686822Siwasaki 2067131841Sbms RL_LOCK(sc); 2068131841Sbms 2069109109Sdes /* reinitialize interface if necessary */ 2070109109Sdes if (ifp->if_flags & IFF_UP) 2071131841Sbms rl_init_locked(sc); 207286822Siwasaki 207386822Siwasaki sc->suspended = 0; 2074131841Sbms 2075131606Sbms RL_UNLOCK(sc); 207686822Siwasaki 207786822Siwasaki return (0); 207886822Siwasaki} 207986822Siwasaki 208086822Siwasaki/* 208140516Swpaul * Stop all chip I/O so that the kernel's probe routines don't 208240516Swpaul * get confused by errant DMAs when rebooting. 208340516Swpaul */ 2084173839Syongaristatic int 2085131605Sbmsrl_shutdown(device_t dev) 208640516Swpaul{ 208750703Swpaul struct rl_softc *sc; 208840516Swpaul 208950703Swpaul sc = device_get_softc(dev); 2090131606Sbms 2091131606Sbms RL_LOCK(sc); 209240516Swpaul rl_stop(sc); 2093131606Sbms RL_UNLOCK(sc); 2094173839Syongari 2095173839Syongari return (0); 209640516Swpaul} 2097