if_rl.c revision 148654
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 148654 2005-08-03 00:18:35Z rwatson $"); 35122678Sobrien 3640516Swpaul/* 37119868Swpaul * RealTek 8129/8139 PCI NIC driver 3840516Swpaul * 39119868Swpaul * Supports several extremely cheap PCI 10/100 adapters based on 40119868Swpaul * the RealTek chipset. Datasheets can be obtained from 4140516Swpaul * www.realtek.com.tw. 4240516Swpaul * 43119868Swpaul * Written by Bill Paul <wpaul@ctr.columbia.edu> 44119868Swpaul * Electrical Engineering Department 45119868Swpaul * Columbia University, New York City 4640516Swpaul */ 4740516Swpaul/* 4840516Swpaul * The RealTek 8139 PCI NIC redefines the meaning of 'low end.' This is 4940516Swpaul * probably the worst PCI ethernet controller ever made, with the possible 5040516Swpaul * exception of the FEAST chip made by SMC. The 8139 supports bus-master 5140516Swpaul * DMA, but it has a terrible interface that nullifies any performance 5240516Swpaul * gains that bus-master DMA usually offers. 5340516Swpaul * 5440516Swpaul * For transmission, the chip offers a series of four TX descriptor 5540516Swpaul * registers. Each transmit frame must be in a contiguous buffer, aligned 5641569Swpaul * on a longword (32-bit) boundary. This means we almost always have to 5740516Swpaul * do mbuf copies in order to transmit a frame, except in the unlikely 5840516Swpaul * case where a) the packet fits into a single mbuf, and b) the packet 5940516Swpaul * is 32-bit aligned within the mbuf's data area. The presence of only 6040516Swpaul * four descriptor registers means that we can never have more than four 6140516Swpaul * packets queued for transmission at any one time. 6240516Swpaul * 6340516Swpaul * Reception is not much better. The driver has to allocate a single large 6440516Swpaul * buffer area (up to 64K in size) into which the chip will DMA received 6540516Swpaul * frames. Because we don't know where within this region received packets 6640516Swpaul * will begin or end, we have no choice but to copy data from the buffer 6740516Swpaul * area into mbufs in order to pass the packets up to the higher protocol 6840516Swpaul * levels. 6940516Swpaul * 7040516Swpaul * It's impossible given this rotten design to really achieve decent 7140516Swpaul * performance at 100Mbps, unless you happen to have a 400Mhz PII or 7240516Swpaul * some equally overmuscled CPU to drive it. 7340516Swpaul * 7440516Swpaul * On the bright side, the 8139 does have a built-in PHY, although 7540516Swpaul * rather than using an MDIO serial interface like most other NICs, the 7640516Swpaul * PHY registers are directly accessible through the 8139's register 7740516Swpaul * space. The 8139 supports autonegotiation, as well as a 64-bit multicast 7840516Swpaul * filter. 7940516Swpaul * 8040516Swpaul * The 8129 chip is an older version of the 8139 that uses an external PHY 8140516Swpaul * chip. The 8129 has a serial MDIO interface for accessing the MII where 8240516Swpaul * the 8139 lets you directly access the on-board PHY registers. We need 8340516Swpaul * to select which interface to use depending on the chip type. 8440516Swpaul */ 8540516Swpaul 8640516Swpaul#include <sys/param.h> 87108729Sjake#include <sys/endian.h> 8840516Swpaul#include <sys/systm.h> 8940516Swpaul#include <sys/sockio.h> 9040516Swpaul#include <sys/mbuf.h> 9140516Swpaul#include <sys/malloc.h> 9240516Swpaul#include <sys/kernel.h> 93129878Sphk#include <sys/module.h> 9440516Swpaul#include <sys/socket.h> 9540516Swpaul 9640516Swpaul#include <net/if.h> 9740516Swpaul#include <net/if_arp.h> 9840516Swpaul#include <net/ethernet.h> 9940516Swpaul#include <net/if_dl.h> 10040516Swpaul#include <net/if_media.h> 101147256Sbrooks#include <net/if_types.h> 10240516Swpaul 10340516Swpaul#include <net/bpf.h> 10440516Swpaul 10541569Swpaul#include <machine/bus.h> 10650703Swpaul#include <machine/resource.h> 10750703Swpaul#include <sys/bus.h> 10850703Swpaul#include <sys/rman.h> 10940516Swpaul 11050703Swpaul#include <dev/mii/mii.h> 11150703Swpaul#include <dev/mii/miivar.h> 11250703Swpaul 113119871Swpaul#include <dev/pci/pcireg.h> 114119871Swpaul#include <dev/pci/pcivar.h> 11540516Swpaul 116113506SmdoddMODULE_DEPEND(rl, pci, 1, 1, 1); 117113506SmdoddMODULE_DEPEND(rl, ether, 1, 1, 1); 11859758SpeterMODULE_DEPEND(rl, miibus, 1, 1, 1); 11959758Speter 12051089Speter/* "controller miibus0" required. See GENERIC if you get errors here. */ 12150703Swpaul#include "miibus_if.h" 12250703Swpaul 12340516Swpaul/* 12440516Swpaul * Default to using PIO access for this driver. On SMP systems, 12540516Swpaul * there appear to be problems with memory mapped mode: it looks like 12640516Swpaul * doing too many memory mapped access back to back in rapid succession 12740516Swpaul * can hang the bus. I'm inclined to blame this on crummy design/construction 12840516Swpaul * on the part of RealTek. Memory mapped mode does appear to work on 12940516Swpaul * uniprocessor systems though. 13040516Swpaul */ 13140516Swpaul#define RL_USEIOSPACE 13240516Swpaul 13340516Swpaul#include <pci/if_rlreg.h> 13440516Swpaul 13540516Swpaul/* 13640516Swpaul * Various supported device vendors/types and their names. 13740516Swpaul */ 13840516Swpaulstatic struct rl_type rl_devs[] = { 139117388Swpaul { RT_VENDORID, RT_DEVICEID_8129, RL_8129, 14040516Swpaul "RealTek 8129 10/100BaseTX" }, 141117388Swpaul { RT_VENDORID, RT_DEVICEID_8139, RL_8139, 14240516Swpaul "RealTek 8139 10/100BaseTX" }, 143117388Swpaul { RT_VENDORID, RT_DEVICEID_8138, RL_8139, 14467771Swpaul "RealTek 8139 10/100BaseTX CardBus" }, 145118978Swpaul { RT_VENDORID, RT_DEVICEID_8100, RL_8139, 146118978Swpaul "RealTek 8100 10/100BaseTX" }, 147117388Swpaul { ACCTON_VENDORID, ACCTON_DEVICEID_5030, RL_8139, 14841243Swpaul "Accton MPX 5030/5038 10/100BaseTX" }, 149117388Swpaul { DELTA_VENDORID, DELTA_DEVICEID_8139, RL_8139, 15044238Swpaul "Delta Electronics 8139 10/100BaseTX" }, 151117388Swpaul { ADDTRON_VENDORID, ADDTRON_DEVICEID_8139, RL_8139, 15244238Swpaul "Addtron Technolgy 8139 10/100BaseTX" }, 153117388Swpaul { DLINK_VENDORID, DLINK_DEVICEID_530TXPLUS, RL_8139, 15472813Swpaul "D-Link DFE-530TX+ 10/100BaseTX" }, 155117388Swpaul { DLINK_VENDORID, DLINK_DEVICEID_690TXD, RL_8139, 15696112Sjhb "D-Link DFE-690TXD 10/100BaseTX" }, 157117388Swpaul { NORTEL_VENDORID, ACCTON_DEVICEID_5030, RL_8139, 15894400Swpaul "Nortel Networks 10/100BaseTX" }, 159117388Swpaul { COREGA_VENDORID, COREGA_DEVICEID_FETHERCBTXD, RL_8139, 160103020Siwasaki "Corega FEther CB-TXD" }, 161117388Swpaul { COREGA_VENDORID, COREGA_DEVICEID_FETHERIICBTXD, RL_8139, 162109095Ssanpei "Corega FEtherII CB-TXD" }, 163117388Swpaul { PEPPERCON_VENDORID, PEPPERCON_DEVICEID_ROLF, RL_8139, 164111381Sdan "Peppercon AG ROL-F" }, 165117388Swpaul { PLANEX_VENDORID, PLANEX_DEVICEID_FNW3800TX, RL_8139, 166112379Ssanpei "Planex FNW-3800-TX" }, 167117388Swpaul { CP_VENDORID, RT_DEVICEID_8139, RL_8139, 168117388Swpaul "Compaq HNE-300" }, 169117388Swpaul { LEVEL1_VENDORID, LEVEL1_DEVICEID_FPC0106TX, RL_8139, 170117388Swpaul "LevelOne FPC-0106TX" }, 171117388Swpaul { EDIMAX_VENDORID, EDIMAX_DEVICEID_EP4103DL, RL_8139, 172117388Swpaul "Edimax EP-4103DL CardBus" }, 173123740Speter { 0, 0, 0, NULL } 17440516Swpaul}; 17540516Swpaul 176142407Simpstatic int rl_attach(device_t); 177142407Simpstatic int rl_detach(device_t); 178142407Simpstatic void rl_dma_map_rxbuf(void *, bus_dma_segment_t *, int, int); 179142407Simpstatic void rl_dma_map_txbuf(void *, bus_dma_segment_t *, int, int); 180142407Simpstatic void rl_eeprom_putbyte(struct rl_softc *, int); 181142407Simpstatic void rl_eeprom_getword(struct rl_softc *, int, uint16_t *); 182142407Simpstatic int rl_encap(struct rl_softc *, struct mbuf * ); 183142407Simpstatic int rl_list_tx_init(struct rl_softc *); 184142407Simpstatic int rl_ifmedia_upd(struct ifnet *); 185142407Simpstatic void rl_ifmedia_sts(struct ifnet *, struct ifmediareq *); 186142407Simpstatic int rl_ioctl(struct ifnet *, u_long, caddr_t); 187142407Simpstatic void rl_intr(void *); 188142407Simpstatic void rl_init(void *); 189142407Simpstatic void rl_init_locked(struct rl_softc *sc); 190142407Simpstatic void rl_mii_send(struct rl_softc *, uint32_t, int); 191142407Simpstatic void rl_mii_sync(struct rl_softc *); 192142407Simpstatic int rl_mii_readreg(struct rl_softc *, struct rl_mii_frame *); 193142407Simpstatic int rl_mii_writereg(struct rl_softc *, struct rl_mii_frame *); 194142407Simpstatic int rl_miibus_readreg(device_t, int, int); 195142407Simpstatic void rl_miibus_statchg(device_t); 196142407Simpstatic int rl_miibus_writereg(device_t, int, int, int); 197131841Sbms#ifdef DEVICE_POLLING 198142407Simpstatic void rl_poll(struct ifnet *ifp, enum poll_cmd cmd, 199131841Sbms int count); 200142407Simpstatic void rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, 201131841Sbms int count); 202131841Sbms#endif 203142407Simpstatic int rl_probe(device_t); 204142407Simpstatic void rl_read_eeprom(struct rl_softc *, uint8_t *, int, int, int); 205142407Simpstatic void rl_reset(struct rl_softc *); 206142407Simpstatic int rl_resume(device_t); 207142407Simpstatic void rl_rxeof(struct rl_softc *); 208142407Simpstatic void rl_setmulti(struct rl_softc *); 209142407Simpstatic void rl_shutdown(device_t); 210142407Simpstatic void rl_start(struct ifnet *); 211142407Simpstatic void rl_start_locked(struct ifnet *); 212142407Simpstatic void rl_stop(struct rl_softc *); 213142407Simpstatic int rl_suspend(device_t); 214142407Simpstatic void rl_tick(void *); 215142407Simpstatic void rl_txeof(struct rl_softc *); 216142407Simpstatic void rl_watchdog(struct ifnet *); 21740516Swpaul 21850703Swpaul#ifdef RL_USEIOSPACE 21950703Swpaul#define RL_RES SYS_RES_IOPORT 22050703Swpaul#define RL_RID RL_PCI_LOIO 22150703Swpaul#else 22250703Swpaul#define RL_RES SYS_RES_MEMORY 22350703Swpaul#define RL_RID RL_PCI_LOMEM 22450703Swpaul#endif 22550703Swpaul 22650703Swpaulstatic device_method_t rl_methods[] = { 22750703Swpaul /* Device interface */ 22850703Swpaul DEVMETHOD(device_probe, rl_probe), 22950703Swpaul DEVMETHOD(device_attach, rl_attach), 23050703Swpaul DEVMETHOD(device_detach, rl_detach), 23186822Siwasaki DEVMETHOD(device_suspend, rl_suspend), 23286822Siwasaki DEVMETHOD(device_resume, rl_resume), 23350703Swpaul DEVMETHOD(device_shutdown, rl_shutdown), 23450703Swpaul 23550703Swpaul /* bus interface */ 23650703Swpaul DEVMETHOD(bus_print_child, bus_generic_print_child), 23750703Swpaul DEVMETHOD(bus_driver_added, bus_generic_driver_added), 23850703Swpaul 23950703Swpaul /* MII interface */ 24050703Swpaul DEVMETHOD(miibus_readreg, rl_miibus_readreg), 24150703Swpaul DEVMETHOD(miibus_writereg, rl_miibus_writereg), 24250703Swpaul DEVMETHOD(miibus_statchg, rl_miibus_statchg), 24350703Swpaul 24450703Swpaul { 0, 0 } 24550703Swpaul}; 24650703Swpaul 24750703Swpaulstatic driver_t rl_driver = { 24851455Swpaul "rl", 24950703Swpaul rl_methods, 25050703Swpaul sizeof(struct rl_softc) 25150703Swpaul}; 25250703Swpaul 25350703Swpaulstatic devclass_t rl_devclass; 25450703Swpaul 255113506SmdoddDRIVER_MODULE(rl, pci, rl_driver, rl_devclass, 0, 0); 256123019SimpDRIVER_MODULE(rl, cardbus, rl_driver, rl_devclass, 0, 0); 25751473SwpaulDRIVER_MODULE(miibus, rl, miibus_driver, miibus_devclass, 0, 0); 25850703Swpaul 25940516Swpaul#define EE_SET(x) \ 26040516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26140516Swpaul CSR_READ_1(sc, RL_EECMD) | x) 26240516Swpaul 26340516Swpaul#define EE_CLR(x) \ 26440516Swpaul CSR_WRITE_1(sc, RL_EECMD, \ 26540516Swpaul CSR_READ_1(sc, RL_EECMD) & ~x) 26640516Swpaul 26781713Swpaulstatic void 268131605Sbmsrl_dma_map_rxbuf(void *arg, bus_dma_segment_t *segs, int nseg, int error) 26981713Swpaul{ 270131605Sbms struct rl_softc *sc = arg; 27181713Swpaul 27281713Swpaul CSR_WRITE_4(sc, RL_RXADDR, segs->ds_addr & 0xFFFFFFFF); 27381713Swpaul} 27481713Swpaul 27581713Swpaulstatic void 276131605Sbmsrl_dma_map_txbuf(void *arg, bus_dma_segment_t *segs, int nseg, int error) 27781713Swpaul{ 278131605Sbms struct rl_softc *sc = arg; 27981713Swpaul 28081713Swpaul CSR_WRITE_4(sc, RL_CUR_TXADDR(sc), segs->ds_addr & 0xFFFFFFFF); 28181713Swpaul} 28281713Swpaul 28340516Swpaul/* 28440516Swpaul * Send a read command and address to the EEPROM, check for ACK. 28540516Swpaul */ 286102335Salfredstatic void 287131605Sbmsrl_eeprom_putbyte(struct rl_softc *sc, int addr) 28840516Swpaul{ 28940516Swpaul register int d, i; 29040516Swpaul 29167931Swpaul d = addr | sc->rl_eecmd_read; 29240516Swpaul 29340516Swpaul /* 29455170Sbillf * Feed in each bit and strobe the clock. 29540516Swpaul */ 29640516Swpaul for (i = 0x400; i; i >>= 1) { 29740516Swpaul if (d & i) { 29840516Swpaul EE_SET(RL_EE_DATAIN); 29940516Swpaul } else { 30040516Swpaul EE_CLR(RL_EE_DATAIN); 30140516Swpaul } 30240516Swpaul DELAY(100); 30340516Swpaul EE_SET(RL_EE_CLK); 30440516Swpaul DELAY(150); 30540516Swpaul EE_CLR(RL_EE_CLK); 30640516Swpaul DELAY(100); 30740516Swpaul } 30840516Swpaul} 30940516Swpaul 31040516Swpaul/* 31140516Swpaul * Read a word of data stored in the EEPROM at address 'addr.' 31240516Swpaul */ 313102335Salfredstatic void 314131605Sbmsrl_eeprom_getword(struct rl_softc *sc, int addr, uint16_t *dest) 31540516Swpaul{ 31640516Swpaul register int i; 317131605Sbms uint16_t word = 0; 31840516Swpaul 31940516Swpaul /* Enter EEPROM access mode. */ 32040516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 32140516Swpaul 32240516Swpaul /* 32340516Swpaul * Send address of word we want to read. 32440516Swpaul */ 32540516Swpaul rl_eeprom_putbyte(sc, addr); 32640516Swpaul 32740516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_PROGRAM|RL_EE_SEL); 32840516Swpaul 32940516Swpaul /* 33040516Swpaul * Start reading bits from EEPROM. 33140516Swpaul */ 33240516Swpaul for (i = 0x8000; i; i >>= 1) { 33340516Swpaul EE_SET(RL_EE_CLK); 33440516Swpaul DELAY(100); 33540516Swpaul if (CSR_READ_1(sc, RL_EECMD) & RL_EE_DATAOUT) 33640516Swpaul word |= i; 33740516Swpaul EE_CLR(RL_EE_CLK); 33840516Swpaul DELAY(100); 33940516Swpaul } 34040516Swpaul 34140516Swpaul /* Turn off EEPROM access mode. */ 34240516Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 34340516Swpaul 34440516Swpaul *dest = word; 34540516Swpaul} 34640516Swpaul 34740516Swpaul/* 34840516Swpaul * Read a sequence of words from the EEPROM. 34940516Swpaul */ 350102335Salfredstatic void 351131605Sbmsrl_read_eeprom(struct rl_softc *sc, uint8_t *dest, int off, int cnt, int swap) 35240516Swpaul{ 35340516Swpaul int i; 354131605Sbms uint16_t word = 0, *ptr; 35540516Swpaul 35640516Swpaul for (i = 0; i < cnt; i++) { 35740516Swpaul rl_eeprom_getword(sc, off + i, &word); 358131605Sbms ptr = (uint16_t *)(dest + (i * 2)); 35940516Swpaul if (swap) 36040516Swpaul *ptr = ntohs(word); 36140516Swpaul else 36240516Swpaul *ptr = word; 36340516Swpaul } 36440516Swpaul} 36540516Swpaul 36640516Swpaul/* 36740516Swpaul * MII access routines are provided for the 8129, which 36840516Swpaul * doesn't have a built-in PHY. For the 8139, we fake things 36940516Swpaul * up by diverting rl_phy_readreg()/rl_phy_writereg() to the 37040516Swpaul * direct access PHY registers. 37140516Swpaul */ 37240516Swpaul#define MII_SET(x) \ 37340516Swpaul CSR_WRITE_1(sc, RL_MII, \ 374105221Sphk CSR_READ_1(sc, RL_MII) | (x)) 37540516Swpaul 37640516Swpaul#define MII_CLR(x) \ 37740516Swpaul CSR_WRITE_1(sc, RL_MII, \ 378105221Sphk CSR_READ_1(sc, RL_MII) & ~(x)) 37940516Swpaul 38040516Swpaul/* 38140516Swpaul * Sync the PHYs by setting data bit and strobing the clock 32 times. 38240516Swpaul */ 383102335Salfredstatic void 384131605Sbmsrl_mii_sync(struct rl_softc *sc) 38540516Swpaul{ 38640516Swpaul register int i; 38740516Swpaul 38840516Swpaul MII_SET(RL_MII_DIR|RL_MII_DATAOUT); 38940516Swpaul 39040516Swpaul for (i = 0; i < 32; i++) { 39140516Swpaul MII_SET(RL_MII_CLK); 39240516Swpaul DELAY(1); 39340516Swpaul MII_CLR(RL_MII_CLK); 39440516Swpaul DELAY(1); 39540516Swpaul } 39640516Swpaul} 39740516Swpaul 39840516Swpaul/* 39940516Swpaul * Clock a series of bits through the MII. 40040516Swpaul */ 401102335Salfredstatic void 402131605Sbmsrl_mii_send(struct rl_softc *sc, uint32_t bits, int cnt) 40340516Swpaul{ 40440516Swpaul int i; 40540516Swpaul 40640516Swpaul MII_CLR(RL_MII_CLK); 40740516Swpaul 40840516Swpaul for (i = (0x1 << (cnt - 1)); i; i >>= 1) { 409109109Sdes if (bits & i) { 41040516Swpaul MII_SET(RL_MII_DATAOUT); 411109109Sdes } else { 41240516Swpaul MII_CLR(RL_MII_DATAOUT); 413109109Sdes } 41440516Swpaul DELAY(1); 41540516Swpaul MII_CLR(RL_MII_CLK); 41640516Swpaul DELAY(1); 41740516Swpaul MII_SET(RL_MII_CLK); 41840516Swpaul } 41940516Swpaul} 42040516Swpaul 42140516Swpaul/* 42240516Swpaul * Read an PHY register through the MII. 42340516Swpaul */ 424102335Salfredstatic int 425131605Sbmsrl_mii_readreg(struct rl_softc *sc, struct rl_mii_frame *frame) 42640516Swpaul{ 42767087Swpaul int i, ack; 42840516Swpaul 42967087Swpaul RL_LOCK(sc); 43040516Swpaul 431131605Sbms /* Set up frame for RX. */ 43240516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 43340516Swpaul frame->mii_opcode = RL_MII_READOP; 43440516Swpaul frame->mii_turnaround = 0; 43540516Swpaul frame->mii_data = 0; 436109109Sdes 43740516Swpaul CSR_WRITE_2(sc, RL_MII, 0); 43840516Swpaul 439131605Sbms /* Turn on data xmit. */ 44040516Swpaul MII_SET(RL_MII_DIR); 44140516Swpaul 44240516Swpaul rl_mii_sync(sc); 44340516Swpaul 444131605Sbms /* Send command/address info. */ 44540516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 44640516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 44740516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 44840516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 44940516Swpaul 45040516Swpaul /* Idle bit */ 45140516Swpaul MII_CLR((RL_MII_CLK|RL_MII_DATAOUT)); 45240516Swpaul DELAY(1); 45340516Swpaul MII_SET(RL_MII_CLK); 45440516Swpaul DELAY(1); 45540516Swpaul 45640516Swpaul /* Turn off xmit. */ 45740516Swpaul MII_CLR(RL_MII_DIR); 45840516Swpaul 45940516Swpaul /* Check for ack */ 46040516Swpaul MII_CLR(RL_MII_CLK); 46140516Swpaul DELAY(1); 462109058Smbr ack = CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN; 46340516Swpaul MII_SET(RL_MII_CLK); 46440516Swpaul DELAY(1); 46540516Swpaul 46640516Swpaul /* 46740516Swpaul * Now try reading data bits. If the ack failed, we still 46840516Swpaul * need to clock through 16 cycles to keep the PHY(s) in sync. 46940516Swpaul */ 47040516Swpaul if (ack) { 47140516Swpaul for(i = 0; i < 16; i++) { 47240516Swpaul MII_CLR(RL_MII_CLK); 47340516Swpaul DELAY(1); 47440516Swpaul MII_SET(RL_MII_CLK); 47540516Swpaul DELAY(1); 47640516Swpaul } 47740516Swpaul goto fail; 47840516Swpaul } 47940516Swpaul 48040516Swpaul for (i = 0x8000; i; i >>= 1) { 48140516Swpaul MII_CLR(RL_MII_CLK); 48240516Swpaul DELAY(1); 48340516Swpaul if (!ack) { 48440516Swpaul if (CSR_READ_2(sc, RL_MII) & RL_MII_DATAIN) 48540516Swpaul frame->mii_data |= i; 48640516Swpaul DELAY(1); 48740516Swpaul } 48840516Swpaul MII_SET(RL_MII_CLK); 48940516Swpaul DELAY(1); 49040516Swpaul } 49140516Swpaul 49240516Swpaulfail: 49340516Swpaul MII_CLR(RL_MII_CLK); 49440516Swpaul DELAY(1); 49540516Swpaul MII_SET(RL_MII_CLK); 49640516Swpaul DELAY(1); 49740516Swpaul 49867087Swpaul RL_UNLOCK(sc); 49940516Swpaul 500131605Sbms return (ack ? 1 : 0); 50140516Swpaul} 50240516Swpaul 50340516Swpaul/* 50440516Swpaul * Write to a PHY register through the MII. 50540516Swpaul */ 506102335Salfredstatic int 507131605Sbmsrl_mii_writereg(struct rl_softc *sc, struct rl_mii_frame *frame) 508131605Sbms{ 509109109Sdes 51067087Swpaul RL_LOCK(sc); 51140516Swpaul 512131605Sbms /* Set up frame for TX. */ 51340516Swpaul frame->mii_stdelim = RL_MII_STARTDELIM; 51440516Swpaul frame->mii_opcode = RL_MII_WRITEOP; 51540516Swpaul frame->mii_turnaround = RL_MII_TURNAROUND; 516109109Sdes 517131605Sbms /* Turn on data output. */ 51840516Swpaul MII_SET(RL_MII_DIR); 51940516Swpaul 52040516Swpaul rl_mii_sync(sc); 52140516Swpaul 52240516Swpaul rl_mii_send(sc, frame->mii_stdelim, 2); 52340516Swpaul rl_mii_send(sc, frame->mii_opcode, 2); 52440516Swpaul rl_mii_send(sc, frame->mii_phyaddr, 5); 52540516Swpaul rl_mii_send(sc, frame->mii_regaddr, 5); 52640516Swpaul rl_mii_send(sc, frame->mii_turnaround, 2); 52740516Swpaul rl_mii_send(sc, frame->mii_data, 16); 52840516Swpaul 52940516Swpaul /* Idle bit. */ 53040516Swpaul MII_SET(RL_MII_CLK); 53140516Swpaul DELAY(1); 53240516Swpaul MII_CLR(RL_MII_CLK); 53340516Swpaul DELAY(1); 53440516Swpaul 535131605Sbms /* Turn off xmit. */ 53640516Swpaul MII_CLR(RL_MII_DIR); 53740516Swpaul 53867087Swpaul RL_UNLOCK(sc); 53940516Swpaul 540131605Sbms return (0); 54140516Swpaul} 54240516Swpaul 543102335Salfredstatic int 544131605Sbmsrl_miibus_readreg(device_t dev, int phy, int reg) 54550703Swpaul{ 54640516Swpaul struct rl_softc *sc; 54740516Swpaul struct rl_mii_frame frame; 548131605Sbms uint16_t rval = 0; 549131605Sbms uint16_t rl8139_reg = 0; 55040516Swpaul 55150703Swpaul sc = device_get_softc(dev); 55250703Swpaul 553119868Swpaul if (sc->rl_type == RL_8139) { 55450703Swpaul /* Pretend the internal PHY is only at address 0 */ 55567087Swpaul if (phy) { 556131605Sbms return (0); 55767087Swpaul } 558131605Sbms switch (reg) { 55950703Swpaul case MII_BMCR: 56040516Swpaul rl8139_reg = RL_BMCR; 56140516Swpaul break; 56250703Swpaul case MII_BMSR: 56340516Swpaul rl8139_reg = RL_BMSR; 56440516Swpaul break; 56550703Swpaul case MII_ANAR: 56640516Swpaul rl8139_reg = RL_ANAR; 56740516Swpaul break; 56850703Swpaul case MII_ANER: 56950703Swpaul rl8139_reg = RL_ANER; 57050703Swpaul break; 57150703Swpaul case MII_ANLPAR: 57240516Swpaul rl8139_reg = RL_LPAR; 57340516Swpaul break; 57450703Swpaul case MII_PHYIDR1: 57550703Swpaul case MII_PHYIDR2: 576131605Sbms return (0); 57794149Swpaul /* 57894149Swpaul * Allow the rlphy driver to read the media status 57994149Swpaul * register. If we have a link partner which does not 58094149Swpaul * support NWAY, this is the register which will tell 58194149Swpaul * us the results of parallel detection. 58294149Swpaul */ 58394149Swpaul case RL_MEDIASTAT: 58494149Swpaul rval = CSR_READ_1(sc, RL_MEDIASTAT); 585131605Sbms return (rval); 58640516Swpaul default: 587147256Sbrooks if_printf(sc->rl_ifp, "bad phy register\n"); 588131605Sbms return (0); 58940516Swpaul } 59040516Swpaul rval = CSR_READ_2(sc, rl8139_reg); 591131605Sbms return (rval); 59240516Swpaul } 59340516Swpaul 59440516Swpaul bzero((char *)&frame, sizeof(frame)); 59550703Swpaul frame.mii_phyaddr = phy; 59640516Swpaul frame.mii_regaddr = reg; 59740516Swpaul rl_mii_readreg(sc, &frame); 598131605Sbms 599131605Sbms return (frame.mii_data); 60040516Swpaul} 60140516Swpaul 602102335Salfredstatic int 603131605Sbmsrl_miibus_writereg(device_t dev, int phy, int reg, int data) 60450703Swpaul{ 60540516Swpaul struct rl_softc *sc; 60640516Swpaul struct rl_mii_frame frame; 607131605Sbms uint16_t rl8139_reg = 0; 60840516Swpaul 60950703Swpaul sc = device_get_softc(dev); 61050703Swpaul 611119868Swpaul if (sc->rl_type == RL_8139) { 61250703Swpaul /* Pretend the internal PHY is only at address 0 */ 61367087Swpaul if (phy) { 614131605Sbms return (0); 61567087Swpaul } 616131605Sbms switch (reg) { 61750703Swpaul case MII_BMCR: 61840516Swpaul rl8139_reg = RL_BMCR; 61940516Swpaul break; 62050703Swpaul case MII_BMSR: 62140516Swpaul rl8139_reg = RL_BMSR; 62240516Swpaul break; 62350703Swpaul case MII_ANAR: 62440516Swpaul rl8139_reg = RL_ANAR; 62540516Swpaul break; 62650703Swpaul case MII_ANER: 62750703Swpaul rl8139_reg = RL_ANER; 62850703Swpaul break; 62950703Swpaul case MII_ANLPAR: 63040516Swpaul rl8139_reg = RL_LPAR; 63140516Swpaul break; 63250703Swpaul case MII_PHYIDR1: 63350703Swpaul case MII_PHYIDR2: 634131605Sbms return (0); 63550703Swpaul break; 63640516Swpaul default: 637147256Sbrooks if_printf(sc->rl_ifp, "bad phy register\n"); 638131605Sbms return (0); 63940516Swpaul } 64040516Swpaul CSR_WRITE_2(sc, rl8139_reg, data); 641131605Sbms return (0); 64240516Swpaul } 64340516Swpaul 64440516Swpaul bzero((char *)&frame, sizeof(frame)); 64550703Swpaul frame.mii_phyaddr = phy; 64640516Swpaul frame.mii_regaddr = reg; 64740516Swpaul frame.mii_data = data; 64840516Swpaul rl_mii_writereg(sc, &frame); 64940516Swpaul 650131605Sbms return (0); 65150703Swpaul} 65250703Swpaul 653102335Salfredstatic void 654131605Sbmsrl_miibus_statchg(device_t dev) 65550703Swpaul{ 65640516Swpaul} 65740516Swpaul 65840516Swpaul/* 65940516Swpaul * Program the 64-bit multicast hash filter. 66040516Swpaul */ 661102335Salfredstatic void 662131605Sbmsrl_setmulti(struct rl_softc *sc) 66340516Swpaul{ 664147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 66540516Swpaul int h = 0; 666131605Sbms uint32_t hashes[2] = { 0, 0 }; 66740516Swpaul struct ifmultiaddr *ifma; 668131605Sbms uint32_t rxfilt; 66940516Swpaul int mcnt = 0; 67040516Swpaul 671131606Sbms RL_LOCK_ASSERT(sc); 672131606Sbms 67340516Swpaul rxfilt = CSR_READ_4(sc, RL_RXCFG); 67440516Swpaul 67543062Swpaul if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { 67640516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 67740516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 67840516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0xFFFFFFFF); 67940516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0xFFFFFFFF); 68040516Swpaul return; 68140516Swpaul } 68240516Swpaul 68340516Swpaul /* first, zot all the existing hash bits */ 68440516Swpaul CSR_WRITE_4(sc, RL_MAR0, 0); 68540516Swpaul CSR_WRITE_4(sc, RL_MAR4, 0); 68640516Swpaul 68740516Swpaul /* now program new ones */ 688148654Srwatson IF_ADDR_LOCK(ifp); 68972084Sphk TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 69040516Swpaul if (ifma->ifma_addr->sa_family != AF_LINK) 69140516Swpaul continue; 692130270Snaddy h = ether_crc32_be(LLADDR((struct sockaddr_dl *) 693130270Snaddy ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; 69440516Swpaul if (h < 32) 69540516Swpaul hashes[0] |= (1 << h); 69640516Swpaul else 69740516Swpaul hashes[1] |= (1 << (h - 32)); 69840516Swpaul mcnt++; 69940516Swpaul } 700148654Srwatson IF_ADDR_UNLOCK(ifp); 70140516Swpaul 70240516Swpaul if (mcnt) 70340516Swpaul rxfilt |= RL_RXCFG_RX_MULTI; 70440516Swpaul else 70540516Swpaul rxfilt &= ~RL_RXCFG_RX_MULTI; 70640516Swpaul 70740516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxfilt); 70840516Swpaul CSR_WRITE_4(sc, RL_MAR0, hashes[0]); 70940516Swpaul CSR_WRITE_4(sc, RL_MAR4, hashes[1]); 71040516Swpaul} 71140516Swpaul 712102335Salfredstatic void 713131605Sbmsrl_reset(struct rl_softc *sc) 71440516Swpaul{ 71540516Swpaul register int i; 71640516Swpaul 717131606Sbms RL_LOCK_ASSERT(sc); 718131606Sbms 71940516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_RESET); 72040516Swpaul 72140516Swpaul for (i = 0; i < RL_TIMEOUT; i++) { 72240516Swpaul DELAY(10); 72340516Swpaul if (!(CSR_READ_1(sc, RL_COMMAND) & RL_CMD_RESET)) 72440516Swpaul break; 72540516Swpaul } 72640516Swpaul if (i == RL_TIMEOUT) 727147256Sbrooks if_printf(sc->rl_ifp, "reset never completed!\n"); 72840516Swpaul} 72940516Swpaul 73040516Swpaul/* 73140516Swpaul * Probe for a RealTek 8129/8139 chip. Check the PCI vendor and device 73240516Swpaul * IDs against our list and return a device name if we find a match. 73340516Swpaul */ 734102335Salfredstatic int 735131605Sbmsrl_probe(device_t dev) 73640516Swpaul{ 737131605Sbms struct rl_softc *sc; 738131605Sbms struct rl_type *t = rl_devs; 739117388Swpaul int rid; 740131605Sbms uint32_t hwrev; 74140516Swpaul 742117388Swpaul sc = device_get_softc(dev); 74340516Swpaul 744131605Sbms while (t->rl_name != NULL) { 74550703Swpaul if ((pci_get_vendor(dev) == t->rl_vid) && 74650703Swpaul (pci_get_device(dev) == t->rl_did)) { 747117388Swpaul /* 748117388Swpaul * Temporarily map the I/O space 749117388Swpaul * so we can read the chip ID register. 750117388Swpaul */ 751117388Swpaul rid = RL_RID; 752127135Snjl sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, 753127135Snjl RF_ACTIVE); 754117388Swpaul if (sc->rl_res == NULL) { 755117388Swpaul device_printf(dev, 756117388Swpaul "couldn't map ports/memory\n"); 757131605Sbms return (ENXIO); 758117388Swpaul } 759117388Swpaul sc->rl_btag = rman_get_bustag(sc->rl_res); 760117388Swpaul sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 761131605Sbms 762119868Swpaul hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV; 763119868Swpaul bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 764131605Sbms 765119868Swpaul /* Don't attach to 8139C+ or 8169/8110 chips. */ 766119868Swpaul if (hwrev == RL_HWREV_8139CPLUS || 767124076Swpaul (hwrev == RL_HWREV_8169 && 768124076Swpaul t->rl_did == RT_DEVICEID_8169) || 769119954Swpaul hwrev == RL_HWREV_8169S || 770119954Swpaul hwrev == RL_HWREV_8110S) { 771119868Swpaul t++; 772119868Swpaul continue; 773119868Swpaul } 774119868Swpaul 775119868Swpaul device_set_desc(dev, t->rl_name); 776142398Simp return (BUS_PROBE_DEFAULT); 77740516Swpaul } 77840516Swpaul t++; 77940516Swpaul } 78040516Swpaul 781131605Sbms return (ENXIO); 78240516Swpaul} 78340516Swpaul 78440516Swpaul/* 78540516Swpaul * Attach the interface. Allocate softc structures, do ifmedia 78640516Swpaul * setup and ethernet/BPF attach. 78740516Swpaul */ 788102335Salfredstatic int 789131605Sbmsrl_attach(device_t dev) 79040516Swpaul{ 791131605Sbms uint8_t eaddr[ETHER_ADDR_LEN]; 792131605Sbms uint16_t as[3]; 793131605Sbms struct ifnet *ifp; 79440516Swpaul struct rl_softc *sc; 795117388Swpaul struct rl_type *t; 796131605Sbms int error = 0, i, rid; 797131605Sbms int unit; 798131605Sbms uint16_t rl_did = 0; 79940516Swpaul 80050703Swpaul sc = device_get_softc(dev); 80150703Swpaul unit = device_get_unit(dev); 80240516Swpaul 80393818Sjhb mtx_init(&sc->rl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, 804131606Sbms MTX_DEF); 805131605Sbms 80672813Swpaul pci_enable_busmaster(dev); 80740516Swpaul 808131605Sbms /* Map control/status registers. */ 809109109Sdes rid = RL_RID; 810127135Snjl sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid, RF_ACTIVE); 81150703Swpaul 81250703Swpaul if (sc->rl_res == NULL) { 813131605Sbms device_printf(dev, "couldn't map ports/memory\n"); 81450703Swpaul error = ENXIO; 81540516Swpaul goto fail; 81640516Swpaul } 81740516Swpaul 818117388Swpaul#ifdef notdef 819131605Sbms /* 820131605Sbms * Detect the Realtek 8139B. For some reason, this chip is very 82169127Sroger * unstable when left to autoselect the media 82269127Sroger * The best workaround is to set the device to the required 82369127Sroger * media type or to set it to the 10 Meg speed. 82469127Sroger */ 825131605Sbms if ((rman_get_end(sc->rl_res) - rman_get_start(sc->rl_res)) == 0xFF) 826131605Sbms device_printf(dev, 827131605Sbms"Realtek 8139B detected. Warning, this may be unstable in autoselect mode\n"); 828117388Swpaul#endif 82969127Sroger 83050703Swpaul sc->rl_btag = rman_get_bustag(sc->rl_res); 83150703Swpaul sc->rl_bhandle = rman_get_bushandle(sc->rl_res); 83250703Swpaul 833112872Snjl /* Allocate interrupt */ 83450703Swpaul rid = 0; 835127135Snjl sc->rl_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 83650703Swpaul RF_SHAREABLE | RF_ACTIVE); 83750703Swpaul 83850703Swpaul if (sc->rl_irq == NULL) { 839131605Sbms device_printf(dev, "couldn't map interrupt\n"); 84050703Swpaul error = ENXIO; 84140516Swpaul goto fail; 84240516Swpaul } 84340516Swpaul 844131606Sbms /* 845131606Sbms * Reset the adapter. Only take the lock here as it's needed in 846131606Sbms * order to call rl_reset(). 847131606Sbms */ 848131606Sbms RL_LOCK(sc); 84940516Swpaul rl_reset(sc); 850131606Sbms RL_UNLOCK(sc); 851131606Sbms 85267931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_6BIT; 853131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, 0, 1, 0); 85468215Swpaul if (rl_did != 0x8129) 85567931Swpaul sc->rl_eecmd_read = RL_EECMD_READ_8BIT; 85640516Swpaul 85740516Swpaul /* 85840516Swpaul * Get station address from the EEPROM. 85940516Swpaul */ 860131605Sbms rl_read_eeprom(sc, (uint8_t *)as, RL_EE_EADDR, 3, 0); 861108729Sjake for (i = 0; i < 3; i++) { 862108729Sjake eaddr[(i * 2) + 0] = as[i] & 0xff; 863108729Sjake eaddr[(i * 2) + 1] = as[i] >> 8; 864108729Sjake } 86540516Swpaul 86640516Swpaul sc->rl_unit = unit; 86740516Swpaul 86840516Swpaul /* 86940516Swpaul * Now read the exact device type from the EEPROM to find 87040516Swpaul * out if it's an 8129 or 8139. 87140516Swpaul */ 872131605Sbms rl_read_eeprom(sc, (uint8_t *)&rl_did, RL_EE_PCI_DID, 1, 0); 87340516Swpaul 874117388Swpaul t = rl_devs; 875119868Swpaul sc->rl_type = 0; 876117388Swpaul while(t->rl_name != NULL) { 877117388Swpaul if (rl_did == t->rl_did) { 878117388Swpaul sc->rl_type = t->rl_basetype; 879117388Swpaul break; 880117388Swpaul } 881117388Swpaul t++; 882117388Swpaul } 883119868Swpaul 884119868Swpaul if (sc->rl_type == 0) { 885131605Sbms device_printf(dev, "unknown device ID: %x\n", rl_did); 88650703Swpaul error = ENXIO; 88740516Swpaul goto fail; 88840516Swpaul } 88940516Swpaul 89081713Swpaul /* 89181713Swpaul * Allocate the parent bus DMA tag appropriate for PCI. 89281713Swpaul */ 89381713Swpaul#define RL_NSEG_NEW 32 894109109Sdes error = bus_dma_tag_create(NULL, /* parent */ 89581713Swpaul 1, 0, /* alignment, boundary */ 89681713Swpaul BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 89781713Swpaul BUS_SPACE_MAXADDR, /* highaddr */ 89881713Swpaul NULL, NULL, /* filter, filterarg */ 89981713Swpaul MAXBSIZE, RL_NSEG_NEW, /* maxsize, nsegments */ 900109109Sdes BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 90181713Swpaul BUS_DMA_ALLOCNOW, /* flags */ 902117126Sscottl NULL, NULL, /* lockfunc, lockarg */ 90381713Swpaul &sc->rl_parent_tag); 904112872Snjl if (error) 905112872Snjl goto fail; 90640516Swpaul 90781713Swpaul /* 908119868Swpaul * Now allocate a tag for the DMA descriptor lists. 909119868Swpaul * All of our lists are allocated as a contiguous block 910119868Swpaul * of memory. 91181713Swpaul */ 912119868Swpaul error = bus_dma_tag_create(sc->rl_parent_tag, /* parent */ 913119868Swpaul 1, 0, /* alignment, boundary */ 914119868Swpaul BUS_SPACE_MAXADDR, /* lowaddr */ 915119868Swpaul BUS_SPACE_MAXADDR, /* highaddr */ 916119868Swpaul NULL, NULL, /* filter, filterarg */ 917119868Swpaul RL_RXBUFLEN + 1518, 1, /* maxsize,nsegments */ 918119868Swpaul BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 919119868Swpaul BUS_DMA_ALLOCNOW, /* flags */ 920119868Swpaul NULL, NULL, /* lockfunc, lockarg */ 921119868Swpaul &sc->rl_tag); 922112872Snjl if (error) 923112872Snjl goto fail; 92481713Swpaul 925119868Swpaul /* 926119868Swpaul * Now allocate a chunk of DMA-able memory based on the 927119868Swpaul * tag we just created. 928119868Swpaul */ 929119868Swpaul error = bus_dmamem_alloc(sc->rl_tag, 930119868Swpaul (void **)&sc->rl_cdata.rl_rx_buf, BUS_DMA_NOWAIT | BUS_DMA_ZERO, 931119868Swpaul &sc->rl_cdata.rl_rx_dmamap); 932119868Swpaul if (error) { 933131605Sbms device_printf(dev, "no memory for list buffers!\n"); 934119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 935119868Swpaul sc->rl_tag = NULL; 936119868Swpaul goto fail; 937119868Swpaul } 938119868Swpaul 939119868Swpaul /* Leave a few bytes before the start of the RX ring buffer. */ 940119868Swpaul sc->rl_cdata.rl_rx_buf_ptr = sc->rl_cdata.rl_rx_buf; 941131605Sbms sc->rl_cdata.rl_rx_buf += sizeof(uint64_t); 942119868Swpaul 943147291Sbrooks ifp = sc->rl_ifp = if_alloc(IFT_ETHER); 944147291Sbrooks if (ifp == NULL) { 945147291Sbrooks device_printf(dev, "can not if_alloc()\n"); 946147291Sbrooks error = ENOSPC; 947147291Sbrooks goto fail; 948147291Sbrooks } 949147291Sbrooks 95050703Swpaul /* Do MII setup */ 95150703Swpaul if (mii_phy_probe(dev, &sc->rl_miibus, 95250703Swpaul rl_ifmedia_upd, rl_ifmedia_sts)) { 953131605Sbms device_printf(dev, "MII without any phy!\n"); 95450703Swpaul error = ENXIO; 95550703Swpaul goto fail; 95650703Swpaul } 95750703Swpaul 95840516Swpaul ifp->if_softc = sc; 959121816Sbrooks if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 96040516Swpaul ifp->if_mtu = ETHERMTU; 96140516Swpaul ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 96240516Swpaul ifp->if_ioctl = rl_ioctl; 963119868Swpaul ifp->if_start = rl_start; 96440516Swpaul ifp->if_watchdog = rl_watchdog; 96540516Swpaul ifp->if_init = rl_init; 96640516Swpaul ifp->if_baudrate = 10000000; 967119976Swpaul ifp->if_capabilities = IFCAP_VLAN_MTU; 968128121Sru#ifdef DEVICE_POLLING 969128121Sru ifp->if_capabilities |= IFCAP_POLLING; 970128121Sru#endif 971119977Swpaul ifp->if_capenable = ifp->if_capabilities; 972131455Smlaier IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 973131455Smlaier ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 974131455Smlaier IFQ_SET_READY(&ifp->if_snd); 975131605Sbms 976112872Snjl callout_handle_init(&sc->rl_stat_ch); 977112872Snjl 97840516Swpaul /* 97963090Sarchie * Call MI attach routine. 98040516Swpaul */ 981106936Ssam ether_ifattach(ifp, eaddr); 982106157Simp 983113609Snjl /* Hook interrupt last to avoid having to lock softc */ 984131606Sbms error = bus_setup_intr(dev, sc->rl_irq, INTR_TYPE_NET | INTR_MPSAFE, 985119868Swpaul rl_intr, sc, &sc->rl_intrhand); 986106157Simp if (error) { 987131605Sbms if_printf(ifp, "couldn't set up irq\n"); 988113609Snjl ether_ifdetach(ifp); 989147256Sbrooks if_free(ifp); 990106157Simp } 991106157Simp 99240516Swpaulfail: 993112872Snjl if (error) 994112872Snjl rl_detach(dev); 995112872Snjl 996110601Snjl return (error); 99740516Swpaul} 99840516Swpaul 999113609Snjl/* 1000113609Snjl * Shutdown hardware and free up resources. This can be called any 1001113609Snjl * time after the mutex has been initialized. It is called in both 1002113609Snjl * the error case in attach and the normal detach case so it needs 1003113609Snjl * to be careful about only freeing resources that have actually been 1004113609Snjl * allocated. 1005113609Snjl */ 1006102335Salfredstatic int 1007131605Sbmsrl_detach(device_t dev) 100850703Swpaul{ 100950703Swpaul struct rl_softc *sc; 101050703Swpaul struct ifnet *ifp; 1011133403Sgreen int attached; 101250703Swpaul 101350703Swpaul sc = device_get_softc(dev); 1014147256Sbrooks ifp = sc->rl_ifp; 1015131605Sbms 1016112880Sjhb KASSERT(mtx_initialized(&sc->rl_mtx), ("rl mutex not initialized")); 1017133403Sgreen attached = device_is_attached(dev); 1018133403Sgreen /* These should only be active if attach succeeded */ 1019147256Sbrooks if (attached) { 1020133403Sgreen ether_ifdetach(ifp); 1021147256Sbrooks if_free(ifp); 1022147256Sbrooks } 102367087Swpaul RL_LOCK(sc); 1024131606Sbms#if 0 1025131606Sbms sc->suspended = 1; 1026131606Sbms#endif 1027133403Sgreen if (attached) 1028113609Snjl rl_stop(sc); 1029113609Snjl if (sc->rl_miibus) 1030112872Snjl device_delete_child(dev, sc->rl_miibus); 1031113609Snjl bus_generic_detach(dev); 103250703Swpaul 1033112872Snjl if (sc->rl_intrhand) 1034112872Snjl bus_teardown_intr(dev, sc->rl_irq, sc->rl_intrhand); 1035112872Snjl if (sc->rl_irq) 1036112872Snjl bus_release_resource(dev, SYS_RES_IRQ, 0, sc->rl_irq); 1037112872Snjl if (sc->rl_res) 1038112872Snjl bus_release_resource(dev, RL_RES, RL_RID, sc->rl_res); 103950703Swpaul 1040119868Swpaul if (sc->rl_tag) { 1041119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 1042119868Swpaul bus_dmamem_free(sc->rl_tag, sc->rl_cdata.rl_rx_buf, 1043119868Swpaul sc->rl_cdata.rl_rx_dmamap); 1044119868Swpaul bus_dma_tag_destroy(sc->rl_tag); 1045112872Snjl } 1046112872Snjl if (sc->rl_parent_tag) 1047112872Snjl bus_dma_tag_destroy(sc->rl_parent_tag); 104850703Swpaul 104967087Swpaul RL_UNLOCK(sc); 105067087Swpaul mtx_destroy(&sc->rl_mtx); 105150703Swpaul 1052131605Sbms return (0); 105350703Swpaul} 105450703Swpaul 105540516Swpaul/* 105640516Swpaul * Initialize the transmit descriptors. 105740516Swpaul */ 1058102335Salfredstatic int 1059131605Sbmsrl_list_tx_init(struct rl_softc *sc) 106040516Swpaul{ 106140516Swpaul struct rl_chain_data *cd; 106240516Swpaul int i; 106340516Swpaul 1064131606Sbms RL_LOCK_ASSERT(sc); 1065131606Sbms 106640516Swpaul cd = &sc->rl_cdata; 106740516Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 106845633Swpaul cd->rl_tx_chain[i] = NULL; 106948028Swpaul CSR_WRITE_4(sc, 1070131605Sbms RL_TXADDR0 + (i * sizeof(uint32_t)), 0x0000000); 107140516Swpaul } 107240516Swpaul 107345633Swpaul sc->rl_cdata.cur_tx = 0; 107445633Swpaul sc->rl_cdata.last_tx = 0; 107540516Swpaul 1076131605Sbms return (0); 107740516Swpaul} 107840516Swpaul 107940516Swpaul/* 108040516Swpaul * A frame has been uploaded: pass the resulting mbuf chain up to 108140516Swpaul * the higher level protocols. 108240516Swpaul * 108340516Swpaul * You know there's something wrong with a PCI bus-master chip design 108440516Swpaul * when you have to use m_devget(). 108540516Swpaul * 108640516Swpaul * The receive operation is badly documented in the datasheet, so I'll 108740516Swpaul * attempt to document it here. The driver provides a buffer area and 108840516Swpaul * places its base address in the RX buffer start address register. 108940516Swpaul * The chip then begins copying frames into the RX buffer. Each frame 109072645Sasmodai * is preceded by a 32-bit RX status word which specifies the length 109140516Swpaul * of the frame and certain other status bits. Each frame (starting with 109240516Swpaul * the status word) is also 32-bit aligned. The frame length is in the 109340516Swpaul * first 16 bits of the status word; the lower 15 bits correspond with 109440516Swpaul * the 'rx status register' mentioned in the datasheet. 109548028Swpaul * 109648028Swpaul * Note: to make the Alpha happy, the frame payload needs to be aligned 109778508Sbmilekic * on a 32-bit boundary. To achieve this, we pass RL_ETHER_ALIGN (2 bytes) 1098109109Sdes * as the offset argument to m_devget(). 109940516Swpaul */ 1100102335Salfredstatic void 1101131605Sbmsrl_rxeof(struct rl_softc *sc) 110240516Swpaul{ 1103109109Sdes struct mbuf *m; 1104147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1105131605Sbms uint8_t *rxbufpos; 110640516Swpaul int total_len = 0; 110740516Swpaul int wrap = 0; 1108131605Sbms uint32_t rxstat; 1109131605Sbms uint16_t cur_rx; 1110131605Sbms uint16_t limit; 1111131605Sbms uint16_t max_bytes, rx_bytes = 0; 111240516Swpaul 1113122689Ssam RL_LOCK_ASSERT(sc); 1114122689Ssam 111581713Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1116108729Sjake BUS_DMASYNC_POSTREAD); 111781713Swpaul 111840516Swpaul cur_rx = (CSR_READ_2(sc, RL_CURRXADDR) + 16) % RL_RXBUFLEN; 111940516Swpaul 112040516Swpaul /* Do not try to read past this point. */ 112140516Swpaul limit = CSR_READ_2(sc, RL_CURRXBUF) % RL_RXBUFLEN; 112240516Swpaul 112340516Swpaul if (limit < cur_rx) 112440516Swpaul max_bytes = (RL_RXBUFLEN - cur_rx) + limit; 112540516Swpaul else 112640516Swpaul max_bytes = limit - cur_rx; 112740516Swpaul 112842738Swpaul while((CSR_READ_1(sc, RL_COMMAND) & RL_CMD_EMPTY_RXBUF) == 0) { 112994883Sluigi#ifdef DEVICE_POLLING 1130102052Ssobomax if (ifp->if_flags & IFF_POLLING) { 113194883Sluigi if (sc->rxcycles <= 0) 113294883Sluigi break; 113394883Sluigi sc->rxcycles--; 113494883Sluigi } 113594883Sluigi#endif /* DEVICE_POLLING */ 113640516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + cur_rx; 1137131605Sbms rxstat = le32toh(*(uint32_t *)rxbufpos); 113840516Swpaul 113940516Swpaul /* 114040516Swpaul * Here's a totally undocumented fact for you. When the 114140516Swpaul * RealTek chip is in the process of copying a packet into 114240516Swpaul * RAM for you, the length will be 0xfff0. If you spot a 114340516Swpaul * packet header with this value, you need to stop. The 114440516Swpaul * datasheet makes absolutely no mention of this and 114540516Swpaul * RealTek should be shot for this. 114640516Swpaul */ 1147131605Sbms if ((uint16_t)(rxstat >> 16) == RL_RXSTAT_UNFINISHED) 114840516Swpaul break; 1149109109Sdes 115040516Swpaul if (!(rxstat & RL_RXSTAT_RXOK)) { 115140516Swpaul ifp->if_ierrors++; 1152131841Sbms rl_init_locked(sc); 115350703Swpaul return; 115440516Swpaul } 115540516Swpaul 1156109109Sdes /* No errors; receive the packet. */ 115740516Swpaul total_len = rxstat >> 16; 115840516Swpaul rx_bytes += total_len + 4; 115940516Swpaul 116040516Swpaul /* 116142051Swpaul * XXX The RealTek chip includes the CRC with every 116242051Swpaul * received frame, and there's no way to turn this 116342051Swpaul * behavior off (at least, I can't find anything in 1164109109Sdes * the manual that explains how to do it) so we have 116542051Swpaul * to trim off the CRC manually. 116642051Swpaul */ 116742051Swpaul total_len -= ETHER_CRC_LEN; 116842051Swpaul 116942051Swpaul /* 117040516Swpaul * Avoid trying to read more bytes than we know 117140516Swpaul * the chip has prepared for us. 117240516Swpaul */ 117340516Swpaul if (rx_bytes > max_bytes) 117440516Swpaul break; 117540516Swpaul 117640516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf + 1177131605Sbms ((cur_rx + sizeof(uint32_t)) % RL_RXBUFLEN); 117840516Swpaul if (rxbufpos == (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN)) 117940516Swpaul rxbufpos = sc->rl_cdata.rl_rx_buf; 118040516Swpaul 118140516Swpaul wrap = (sc->rl_cdata.rl_rx_buf + RL_RXBUFLEN) - rxbufpos; 118240516Swpaul if (total_len > wrap) { 118378508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 118478508Sbmilekic NULL); 118540516Swpaul if (m == NULL) { 118640516Swpaul ifp->if_ierrors++; 118752426Swpaul } else { 118840516Swpaul m_copyback(m, wrap, total_len - wrap, 118940516Swpaul sc->rl_cdata.rl_rx_buf); 119048028Swpaul } 119142051Swpaul cur_rx = (total_len - wrap + ETHER_CRC_LEN); 119240516Swpaul } else { 119378508Sbmilekic m = m_devget(rxbufpos, total_len, RL_ETHER_ALIGN, ifp, 119478508Sbmilekic NULL); 1195131605Sbms if (m == NULL) 119640516Swpaul ifp->if_ierrors++; 119742051Swpaul cur_rx += total_len + 4 + ETHER_CRC_LEN; 119840516Swpaul } 119940516Swpaul 1200131605Sbms /* Round up to 32-bit boundary. */ 120140516Swpaul cur_rx = (cur_rx + 3) & ~3; 120240516Swpaul CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16); 120340516Swpaul 120440516Swpaul if (m == NULL) 120540516Swpaul continue; 120640516Swpaul 120740516Swpaul ifp->if_ipackets++; 1208122689Ssam RL_UNLOCK(sc); 1209106936Ssam (*ifp->if_input)(ifp, m); 1210122689Ssam RL_LOCK(sc); 121140516Swpaul } 121240516Swpaul} 121340516Swpaul 121440516Swpaul/* 121540516Swpaul * A frame was downloaded to the chip. It's safe for us to clean up 121640516Swpaul * the list buffers. 121740516Swpaul */ 1218102335Salfredstatic void 1219131605Sbmsrl_txeof(struct rl_softc *sc) 122040516Swpaul{ 1221147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1222131605Sbms uint32_t txstat; 122340516Swpaul 1224131606Sbms RL_LOCK_ASSERT(sc); 1225131606Sbms 122640516Swpaul /* 122740516Swpaul * Go through our tx list and free mbufs for those 122840516Swpaul * frames that have been uploaded. 122940516Swpaul */ 123045633Swpaul do { 1231127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1232127783Sru break; 123345633Swpaul txstat = CSR_READ_4(sc, RL_LAST_TXSTAT(sc)); 123445633Swpaul if (!(txstat & (RL_TXSTAT_TX_OK| 123545633Swpaul RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT))) 123640516Swpaul break; 123740516Swpaul 123845633Swpaul ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24; 123940516Swpaul 1240127783Sru bus_dmamap_unload(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1241127783Sru bus_dmamap_destroy(sc->rl_tag, RL_LAST_DMAMAP(sc)); 1242127783Sru m_freem(RL_LAST_TXMBUF(sc)); 1243127783Sru RL_LAST_TXMBUF(sc) = NULL; 1244141676Smlaier /* 1245141676Smlaier * If there was a transmit underrun, bump the TX threshold. 1246141676Smlaier * Make sure not to overflow the 63 * 32byte we can address 1247141676Smlaier * with the 6 available bit. 1248141676Smlaier */ 1249141676Smlaier if ((txstat & RL_TXSTAT_TX_UNDERRUN) && 1250141676Smlaier (sc->rl_txthresh < 2016)) 1251141676Smlaier sc->rl_txthresh += 32; 125245633Swpaul if (txstat & RL_TXSTAT_TX_OK) 125345633Swpaul ifp->if_opackets++; 125445633Swpaul else { 125552426Swpaul int oldthresh; 125645633Swpaul ifp->if_oerrors++; 125745633Swpaul if ((txstat & RL_TXSTAT_TXABRT) || 125845633Swpaul (txstat & RL_TXSTAT_OUTOFWIN)) 125945633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 126052426Swpaul oldthresh = sc->rl_txthresh; 126152426Swpaul /* error recovery */ 126252426Swpaul rl_reset(sc); 1263131841Sbms rl_init_locked(sc); 1264141676Smlaier /* restore original threshold */ 1265141676Smlaier sc->rl_txthresh = oldthresh; 126652426Swpaul return; 126745633Swpaul } 126845633Swpaul RL_INC(sc->rl_cdata.last_tx); 126945633Swpaul ifp->if_flags &= ~IFF_OACTIVE; 127045633Swpaul } while (sc->rl_cdata.last_tx != sc->rl_cdata.cur_tx); 127140516Swpaul 1272127783Sru if (RL_LAST_TXMBUF(sc) == NULL) 1273127783Sru ifp->if_timer = 0; 1274127783Sru else if (ifp->if_timer == 0) 1275127783Sru ifp->if_timer = 5; 127650703Swpaul} 127740516Swpaul 1278102335Salfredstatic void 1279131605Sbmsrl_tick(void *xsc) 128050703Swpaul{ 1281131605Sbms struct rl_softc *sc = xsc; 128250703Swpaul struct mii_data *mii; 128350703Swpaul 128467087Swpaul RL_LOCK(sc); 128550703Swpaul mii = device_get_softc(sc->rl_miibus); 128650703Swpaul mii_tick(mii); 128750703Swpaul 128850703Swpaul sc->rl_stat_ch = timeout(rl_tick, sc, hz); 128967087Swpaul RL_UNLOCK(sc); 129040516Swpaul} 129140516Swpaul 129294883Sluigi#ifdef DEVICE_POLLING 129394883Sluigistatic void 1294131841Sbmsrl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 129594883Sluigi{ 129694883Sluigi struct rl_softc *sc = ifp->if_softc; 129794883Sluigi 129894883Sluigi RL_LOCK(sc); 1299131841Sbms rl_poll_locked(ifp, cmd, count); 1300131841Sbms RL_UNLOCK(sc); 1301131841Sbms} 1302131605Sbms 1303131841Sbmsstatic void 1304131841Sbmsrl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) 1305131841Sbms{ 1306131841Sbms struct rl_softc *sc = ifp->if_softc; 1307131841Sbms 1308131841Sbms RL_LOCK_ASSERT(sc); 1309131841Sbms 1310128121Sru if (!(ifp->if_capenable & IFCAP_POLLING)) { 1311128121Sru ether_poll_deregister(ifp); 1312128121Sru cmd = POLL_DEREGISTER; 1313128121Sru } 1314131605Sbms 1315131605Sbms if (cmd == POLL_DEREGISTER) { 1316131605Sbms /* Final call; enable interrupts. */ 1317119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 1318131841Sbms return; 131994883Sluigi } 132094883Sluigi 132194883Sluigi sc->rxcycles = count; 1322119868Swpaul rl_rxeof(sc); 1323119868Swpaul rl_txeof(sc); 1324131605Sbms 1325131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1326131841Sbms rl_start_locked(ifp); 132794883Sluigi 1328131605Sbms if (cmd == POLL_AND_CHECK_STATUS) { 1329131605Sbms uint16_t status; 133094883Sluigi 1331131605Sbms /* We should also check the status register. */ 133294883Sluigi status = CSR_READ_2(sc, RL_ISR); 1333100957Sjhb if (status == 0xffff) 1334131841Sbms return; 1335131605Sbms if (status != 0) 133694883Sluigi CSR_WRITE_2(sc, RL_ISR, status); 133794883Sluigi 1338131605Sbms /* XXX We should check behaviour on receiver stalls. */ 133994883Sluigi 134094883Sluigi if (status & RL_ISR_SYSTEM_ERR) { 134194883Sluigi rl_reset(sc); 1342131841Sbms rl_init_locked(sc); 134394883Sluigi } 134494883Sluigi } 134594883Sluigi} 134694883Sluigi#endif /* DEVICE_POLLING */ 134794883Sluigi 1348102335Salfredstatic void 1349131605Sbmsrl_intr(void *arg) 135040516Swpaul{ 1351131605Sbms struct rl_softc *sc = arg; 1352147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 1353131605Sbms uint16_t status; 135440516Swpaul 1355131606Sbms RL_LOCK(sc); 1356131606Sbms 1357131841Sbms if (sc->suspended) 1358131841Sbms goto done_locked; 135986822Siwasaki 136094883Sluigi#ifdef DEVICE_POLLING 1361131841Sbms if (ifp->if_flags & IFF_POLLING) 1362131841Sbms goto done_locked; 1363131841Sbms 1364128121Sru if ((ifp->if_capenable & IFCAP_POLLING) && 1365131605Sbms ether_poll_register(rl_poll, ifp)) { 1366131605Sbms /* Disable interrupts. */ 136794883Sluigi CSR_WRITE_2(sc, RL_IMR, 0x0000); 1368131841Sbms rl_poll_locked(ifp, 0, 1); 1369131841Sbms goto done_locked; 137094883Sluigi } 137194883Sluigi#endif /* DEVICE_POLLING */ 137240516Swpaul 137340516Swpaul for (;;) { 137440516Swpaul status = CSR_READ_2(sc, RL_ISR); 1375131605Sbms /* If the card has gone away, the read returns 0xffff. */ 1376100957Sjhb if (status == 0xffff) 1377100957Sjhb break; 1378131605Sbms if (status != 0) 137940516Swpaul CSR_WRITE_2(sc, RL_ISR, status); 138040516Swpaul if ((status & RL_INTRS) == 0) 138140516Swpaul break; 138240516Swpaul if (status & RL_ISR_RX_OK) 138340516Swpaul rl_rxeof(sc); 138440516Swpaul if (status & RL_ISR_RX_ERR) 138540516Swpaul rl_rxeof(sc); 138645633Swpaul if ((status & RL_ISR_TX_OK) || (status & RL_ISR_TX_ERR)) 138740516Swpaul rl_txeof(sc); 138840516Swpaul if (status & RL_ISR_SYSTEM_ERR) { 138940516Swpaul rl_reset(sc); 1390131841Sbms rl_init_locked(sc); 139140516Swpaul } 139240516Swpaul } 139340516Swpaul 1394131841Sbms if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) 1395131841Sbms rl_start_locked(ifp); 1396131841Sbms 1397131841Sbmsdone_locked: 1398131606Sbms RL_UNLOCK(sc); 139940516Swpaul} 140040516Swpaul 140140516Swpaul/* 140240516Swpaul * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data 140340516Swpaul * pointers to the fragment pointers. 140440516Swpaul */ 1405102335Salfredstatic int 1406131605Sbmsrl_encap(struct rl_softc *sc, struct mbuf *m_head) 140740516Swpaul{ 140841243Swpaul struct mbuf *m_new = NULL; 140940516Swpaul 1410131606Sbms RL_LOCK_ASSERT(sc); 1411131606Sbms 141240516Swpaul /* 141345633Swpaul * The RealTek is brain damaged and wants longword-aligned 141445633Swpaul * TX buffers, plus we can only have one fragment buffer 141545633Swpaul * per packet. We have to copy pretty much all the time. 141640516Swpaul */ 1417112839Ssilby m_new = m_defrag(m_head, M_DONTWAIT); 141840516Swpaul 1419113496Ssilby if (m_new == NULL) { 1420113496Ssilby m_freem(m_head); 1421131605Sbms return (1); 1422113496Ssilby } 142341243Swpaul m_head = m_new; 142440516Swpaul 142540516Swpaul /* Pad frames to at least 60 bytes. */ 142641243Swpaul if (m_head->m_pkthdr.len < RL_MIN_FRAMELEN) { 142755058Swpaul /* 142855058Swpaul * Make security concious people happy: zero out the 142955058Swpaul * bytes in the pad area, since we don't know what 143055058Swpaul * this mbuf cluster buffer's previous user might 143155058Swpaul * have left in it. 1432109109Sdes */ 143355058Swpaul bzero(mtod(m_head, char *) + m_head->m_pkthdr.len, 143455058Swpaul RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 143540516Swpaul m_head->m_pkthdr.len += 143652426Swpaul (RL_MIN_FRAMELEN - m_head->m_pkthdr.len); 143741243Swpaul m_head->m_len = m_head->m_pkthdr.len; 143841243Swpaul } 143940516Swpaul 144045633Swpaul RL_CUR_TXMBUF(sc) = m_head; 144140516Swpaul 1442131605Sbms return (0); 144340516Swpaul} 144440516Swpaul 144540516Swpaul/* 144640516Swpaul * Main transmit routine. 144740516Swpaul */ 1448102335Salfredstatic void 1449131605Sbmsrl_start(struct ifnet *ifp) 145040516Swpaul{ 1451131605Sbms struct rl_softc *sc = ifp->if_softc; 145240516Swpaul 145367087Swpaul RL_LOCK(sc); 1454131841Sbms rl_start_locked(ifp); 1455131841Sbms RL_UNLOCK(sc); 1456131841Sbms} 145740516Swpaul 1458131841Sbmsstatic void 1459131841Sbmsrl_start_locked(struct ifnet *ifp) 1460131841Sbms{ 1461131841Sbms struct rl_softc *sc = ifp->if_softc; 1462131841Sbms struct mbuf *m_head = NULL; 1463131841Sbms 1464131841Sbms RL_LOCK_ASSERT(sc); 1465131841Sbms 1466131605Sbms while (RL_CUR_TXMBUF(sc) == NULL) { 1467131841Sbms 1468131455Smlaier IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); 1469131841Sbms 147040516Swpaul if (m_head == NULL) 147140516Swpaul break; 147240516Swpaul 1473131841Sbms if (rl_encap(sc, m_head)) 147458801Swpaul break; 147540516Swpaul 1476131605Sbms /* Pass a copy of this mbuf chain to the bpf subsystem. */ 1477106936Ssam BPF_MTAP(ifp, RL_CUR_TXMBUF(sc)); 147851583Swpaul 1479131605Sbms /* Transmit the frame. */ 148081713Swpaul bus_dmamap_create(sc->rl_tag, 0, &RL_CUR_DMAMAP(sc)); 148181713Swpaul bus_dmamap_load(sc->rl_tag, RL_CUR_DMAMAP(sc), 148281713Swpaul mtod(RL_CUR_TXMBUF(sc), void *), 1483119868Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len, rl_dma_map_txbuf, sc, 0); 148481713Swpaul bus_dmamap_sync(sc->rl_tag, RL_CUR_DMAMAP(sc), 148581713Swpaul BUS_DMASYNC_PREREAD); 148645633Swpaul CSR_WRITE_4(sc, RL_CUR_TXSTAT(sc), 148752426Swpaul RL_TXTHRESH(sc->rl_txthresh) | 148852426Swpaul RL_CUR_TXMBUF(sc)->m_pkthdr.len); 148945633Swpaul 149045633Swpaul RL_INC(sc->rl_cdata.cur_tx); 1491113237Ssilby 1492131605Sbms /* Set a timeout in case the chip goes out to lunch. */ 1493113237Ssilby ifp->if_timer = 5; 149440516Swpaul } 149540516Swpaul 149640516Swpaul /* 149745633Swpaul * We broke out of the loop because all our TX slots are 149845633Swpaul * full. Mark the NIC as busy until it drains some of the 149945633Swpaul * packets from the queue. 150045633Swpaul */ 150145633Swpaul if (RL_CUR_TXMBUF(sc) != NULL) 150245633Swpaul ifp->if_flags |= IFF_OACTIVE; 1503131841Sbms} 150445633Swpaul 1505131841Sbmsstatic void 1506131841Sbmsrl_init(void *xsc) 1507131841Sbms{ 1508131841Sbms struct rl_softc *sc = xsc; 1509131841Sbms 1510131841Sbms RL_LOCK(sc); 1511131841Sbms rl_init_locked(sc); 151267087Swpaul RL_UNLOCK(sc); 151340516Swpaul} 151440516Swpaul 1515102335Salfredstatic void 1516131841Sbmsrl_init_locked(struct rl_softc *sc) 151740516Swpaul{ 1518147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 151950703Swpaul struct mii_data *mii; 1520131605Sbms uint32_t rxcfg = 0; 152140516Swpaul 1522131841Sbms RL_LOCK_ASSERT(sc); 1523131841Sbms 152450703Swpaul mii = device_get_softc(sc->rl_miibus); 152540516Swpaul 152640516Swpaul /* 152740516Swpaul * Cancel pending I/O and free all RX/TX buffers. 152840516Swpaul */ 152940516Swpaul rl_stop(sc); 153040516Swpaul 1531117029Swpaul /* 1532117029Swpaul * Init our MAC address. Even though the chipset 1533117029Swpaul * documentation doesn't mention it, we need to enter "Config 1534117029Swpaul * register write enable" mode to modify the ID registers. 1535117029Swpaul */ 1536117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_WRITECFG); 1537119738Stmm CSR_WRITE_STREAM_4(sc, RL_IDR0, 1538147256Sbrooks *(uint32_t *)(&IFP2ENADDR(sc->rl_ifp)[0])); 1539119738Stmm CSR_WRITE_STREAM_4(sc, RL_IDR4, 1540147256Sbrooks *(uint32_t *)(&IFP2ENADDR(sc->rl_ifp)[4])); 1541117029Swpaul CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); 154240516Swpaul 1543119868Swpaul /* Init the RX buffer pointer register. */ 1544119868Swpaul bus_dmamap_load(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1545119868Swpaul sc->rl_cdata.rl_rx_buf, RL_RXBUFLEN, rl_dma_map_rxbuf, sc, 0); 1546119868Swpaul bus_dmamap_sync(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap, 1547119868Swpaul BUS_DMASYNC_PREWRITE); 154840516Swpaul 1549119868Swpaul /* Init TX descriptors. */ 1550119868Swpaul rl_list_tx_init(sc); 155140516Swpaul 155240516Swpaul /* 155340516Swpaul * Enable transmit and receive. 155440516Swpaul */ 155540516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 155640516Swpaul 155740516Swpaul /* 155845633Swpaul * Set the initial TX and RX configuration. 155940516Swpaul */ 156045633Swpaul CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG); 156140516Swpaul CSR_WRITE_4(sc, RL_RXCFG, RL_RXCFG_CONFIG); 156240516Swpaul 156340516Swpaul /* Set the individual bit to receive frames for this host only. */ 156440516Swpaul rxcfg = CSR_READ_4(sc, RL_RXCFG); 156540516Swpaul rxcfg |= RL_RXCFG_RX_INDIV; 156640516Swpaul 156740516Swpaul /* If we want promiscuous mode, set the allframes bit. */ 156840516Swpaul if (ifp->if_flags & IFF_PROMISC) { 156940516Swpaul rxcfg |= RL_RXCFG_RX_ALLPHYS; 157040516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 157140516Swpaul } else { 157240516Swpaul rxcfg &= ~RL_RXCFG_RX_ALLPHYS; 157340516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 157440516Swpaul } 157540516Swpaul 1576131605Sbms /* Set capture broadcast bit to capture broadcast frames. */ 157740516Swpaul if (ifp->if_flags & IFF_BROADCAST) { 157840516Swpaul rxcfg |= RL_RXCFG_RX_BROAD; 157940516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 158040516Swpaul } else { 158140516Swpaul rxcfg &= ~RL_RXCFG_RX_BROAD; 158240516Swpaul CSR_WRITE_4(sc, RL_RXCFG, rxcfg); 158340516Swpaul } 158440516Swpaul 1585131605Sbms /* Program the multicast filter, if necessary. */ 158640516Swpaul rl_setmulti(sc); 158740516Swpaul 158894883Sluigi#ifdef DEVICE_POLLING 1589131605Sbms /* Disable interrupts if we are polling. */ 1590102052Ssobomax if (ifp->if_flags & IFF_POLLING) 159194883Sluigi CSR_WRITE_2(sc, RL_IMR, 0); 1592131605Sbms else 159394883Sluigi#endif /* DEVICE_POLLING */ 1594131605Sbms /* Enable interrupts. */ 1595119868Swpaul CSR_WRITE_2(sc, RL_IMR, RL_INTRS); 159640516Swpaul 159752426Swpaul /* Set initial TX threshold */ 159852426Swpaul sc->rl_txthresh = RL_TX_THRESH_INIT; 159952426Swpaul 160040516Swpaul /* Start RX/TX process. */ 160140516Swpaul CSR_WRITE_4(sc, RL_MISSEDPKT, 0); 1602119868Swpaul 160340516Swpaul /* Enable receiver and transmitter. */ 160440516Swpaul CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB); 160540516Swpaul 160650703Swpaul mii_mediachg(mii); 160740516Swpaul 160840516Swpaul CSR_WRITE_1(sc, RL_CFG1, RL_CFG1_DRVLOAD|RL_CFG1_FULLDUPLEX); 160940516Swpaul 161040516Swpaul ifp->if_flags |= IFF_RUNNING; 161140516Swpaul ifp->if_flags &= ~IFF_OACTIVE; 161240516Swpaul 161350703Swpaul sc->rl_stat_ch = timeout(rl_tick, sc, hz); 161440516Swpaul} 161540516Swpaul 161640516Swpaul/* 161740516Swpaul * Set media options. 161840516Swpaul */ 1619102335Salfredstatic int 1620131605Sbmsrl_ifmedia_upd(struct ifnet *ifp) 162140516Swpaul{ 1622131605Sbms struct rl_softc *sc = ifp->if_softc; 162350703Swpaul struct mii_data *mii; 162440516Swpaul 162550703Swpaul mii = device_get_softc(sc->rl_miibus); 1626131605Sbms 162750703Swpaul mii_mediachg(mii); 162840516Swpaul 1629131605Sbms return (0); 163040516Swpaul} 163140516Swpaul 163240516Swpaul/* 163340516Swpaul * Report current media status. 163440516Swpaul */ 1635102335Salfredstatic void 1636131605Sbmsrl_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 163740516Swpaul{ 1638131605Sbms struct rl_softc *sc = ifp->if_softc; 163950703Swpaul struct mii_data *mii; 164040516Swpaul 164150703Swpaul mii = device_get_softc(sc->rl_miibus); 164240516Swpaul 164350703Swpaul mii_pollstat(mii); 164450703Swpaul ifmr->ifm_active = mii->mii_media_active; 164550703Swpaul ifmr->ifm_status = mii->mii_media_status; 164640516Swpaul} 164740516Swpaul 1648102335Salfredstatic int 1649131605Sbmsrl_ioctl(struct ifnet *ifp, u_long command, caddr_t data) 165040516Swpaul{ 1651131605Sbms struct ifreq *ifr = (struct ifreq *)data; 1652131605Sbms struct mii_data *mii; 165340516Swpaul struct rl_softc *sc = ifp->if_softc; 165467087Swpaul int error = 0; 165540516Swpaul 1656131605Sbms switch (command) { 165740516Swpaul case SIOCSIFFLAGS: 1658131841Sbms RL_LOCK(sc); 165940516Swpaul if (ifp->if_flags & IFF_UP) { 1660131841Sbms rl_init_locked(sc); 166140516Swpaul } else { 166240516Swpaul if (ifp->if_flags & IFF_RUNNING) 166340516Swpaul rl_stop(sc); 166440516Swpaul } 1665131841Sbms RL_UNLOCK(sc); 166640516Swpaul error = 0; 166740516Swpaul break; 166840516Swpaul case SIOCADDMULTI: 166940516Swpaul case SIOCDELMULTI: 1670131606Sbms RL_LOCK(sc); 167140516Swpaul rl_setmulti(sc); 1672131606Sbms RL_UNLOCK(sc); 167340516Swpaul error = 0; 167440516Swpaul break; 167540516Swpaul case SIOCGIFMEDIA: 167640516Swpaul case SIOCSIFMEDIA: 167750703Swpaul mii = device_get_softc(sc->rl_miibus); 167850703Swpaul error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 167940516Swpaul break; 1680128121Sru case SIOCSIFCAP: 1681129633Syar ifp->if_capenable &= ~IFCAP_POLLING; 1682129633Syar ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING; 1683128121Sru break; 168440516Swpaul default: 1685106936Ssam error = ether_ioctl(ifp, command, data); 168640516Swpaul break; 168740516Swpaul } 168840516Swpaul 1689131605Sbms return (error); 169040516Swpaul} 169140516Swpaul 1692102335Salfredstatic void 1693131605Sbmsrl_watchdog(struct ifnet *ifp) 169440516Swpaul{ 1695131605Sbms struct rl_softc *sc = ifp->if_softc; 169640516Swpaul 169767087Swpaul RL_LOCK(sc); 1698131605Sbms 1699131605Sbms if_printf(ifp, "watchdog timeout\n"); 170040516Swpaul ifp->if_oerrors++; 170150703Swpaul 1702119868Swpaul rl_txeof(sc); 1703119868Swpaul rl_rxeof(sc); 1704131841Sbms rl_init_locked(sc); 1705131605Sbms 170667087Swpaul RL_UNLOCK(sc); 170740516Swpaul} 170840516Swpaul 170940516Swpaul/* 171040516Swpaul * Stop the adapter and free any mbufs allocated to the 171140516Swpaul * RX and TX lists. 171240516Swpaul */ 1713102335Salfredstatic void 1714131605Sbmsrl_stop(struct rl_softc *sc) 171540516Swpaul{ 171640516Swpaul register int i; 1717147256Sbrooks struct ifnet *ifp = sc->rl_ifp; 171840516Swpaul 1719131606Sbms RL_LOCK_ASSERT(sc); 1720131606Sbms 172140516Swpaul ifp->if_timer = 0; 172250703Swpaul untimeout(rl_tick, sc, sc->rl_stat_ch); 172394883Sluigi ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 172494883Sluigi#ifdef DEVICE_POLLING 172594883Sluigi ether_poll_deregister(ifp); 172694883Sluigi#endif /* DEVICE_POLLING */ 172750703Swpaul 172840516Swpaul CSR_WRITE_1(sc, RL_COMMAND, 0x00); 172940516Swpaul CSR_WRITE_2(sc, RL_IMR, 0x0000); 1730119868Swpaul bus_dmamap_unload(sc->rl_tag, sc->rl_cdata.rl_rx_dmamap); 173140516Swpaul 1732119868Swpaul /* 1733119868Swpaul * Free the TX list buffers. 1734119868Swpaul */ 1735119868Swpaul for (i = 0; i < RL_TX_LIST_CNT; i++) { 1736119868Swpaul if (sc->rl_cdata.rl_tx_chain[i] != NULL) { 1737119868Swpaul bus_dmamap_unload(sc->rl_tag, 1738119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1739119868Swpaul bus_dmamap_destroy(sc->rl_tag, 1740119868Swpaul sc->rl_cdata.rl_tx_dmamap[i]); 1741119868Swpaul m_freem(sc->rl_cdata.rl_tx_chain[i]); 1742119868Swpaul sc->rl_cdata.rl_tx_chain[i] = NULL; 1743131605Sbms CSR_WRITE_4(sc, RL_TXADDR0 + (i * sizeof(uint32_t)), 1744124816Swpaul 0x0000000); 174540516Swpaul } 174640516Swpaul } 174740516Swpaul} 174840516Swpaul 174940516Swpaul/* 175086822Siwasaki * Device suspend routine. Stop the interface and save some PCI 175186822Siwasaki * settings in case the BIOS doesn't restore them properly on 175286822Siwasaki * resume. 175386822Siwasaki */ 1754102335Salfredstatic int 1755131605Sbmsrl_suspend(device_t dev) 175686822Siwasaki{ 175786822Siwasaki struct rl_softc *sc; 175886822Siwasaki 175986822Siwasaki sc = device_get_softc(dev); 1760131606Sbms 1761131606Sbms RL_LOCK(sc); 176286822Siwasaki rl_stop(sc); 176386822Siwasaki sc->suspended = 1; 1764131606Sbms RL_UNLOCK(sc); 176586822Siwasaki 176686822Siwasaki return (0); 176786822Siwasaki} 176886822Siwasaki 176986822Siwasaki/* 177086822Siwasaki * Device resume routine. Restore some PCI settings in case the BIOS 177186822Siwasaki * doesn't, re-enable busmastering, and restart the interface if 177286822Siwasaki * appropriate. 177386822Siwasaki */ 1774102335Salfredstatic int 1775131605Sbmsrl_resume(device_t dev) 177686822Siwasaki{ 177786822Siwasaki struct rl_softc *sc; 177886822Siwasaki struct ifnet *ifp; 177986822Siwasaki 178086822Siwasaki sc = device_get_softc(dev); 1781147256Sbrooks ifp = sc->rl_ifp; 178286822Siwasaki 1783131841Sbms RL_LOCK(sc); 1784131841Sbms 1785109109Sdes /* reinitialize interface if necessary */ 1786109109Sdes if (ifp->if_flags & IFF_UP) 1787131841Sbms rl_init_locked(sc); 178886822Siwasaki 178986822Siwasaki sc->suspended = 0; 1790131841Sbms 1791131606Sbms RL_UNLOCK(sc); 179286822Siwasaki 179386822Siwasaki return (0); 179486822Siwasaki} 179586822Siwasaki 179686822Siwasaki/* 179740516Swpaul * Stop all chip I/O so that the kernel's probe routines don't 179840516Swpaul * get confused by errant DMAs when rebooting. 179940516Swpaul */ 1800102335Salfredstatic void 1801131605Sbmsrl_shutdown(device_t dev) 180240516Swpaul{ 180350703Swpaul struct rl_softc *sc; 180440516Swpaul 180550703Swpaul sc = device_get_softc(dev); 1806131606Sbms 1807131606Sbms RL_LOCK(sc); 180840516Swpaul rl_stop(sc); 1809131606Sbms RL_UNLOCK(sc); 181040516Swpaul} 1811