| 1 | /* $Id: sunhme.h,v 1.33 2001/08/03 06:23:04 davem Exp $ |
| 2 | * sunhme.h: Definitions for Sparc HME/BigMac 10/100baseT ethernet driver. |
| 3 | * Also known as the "Happy Meal". |
| 4 | * |
| 5 | * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) |
| 6 | */ |
| 7 | |
| 8 | #ifndef _SUNHME_H |
| 9 | #define _SUNHME_H |
| 10 | |
| 11 | #include <linux/pci.h> |
| 12 | |
| 13 | /* Happy Meal global registers. */ |
| 14 | #define GREG_SWRESET 0x000UL /* Software Reset */ |
| 15 | #define GREG_CFG 0x004UL /* Config Register */ |
| 16 | #define GREG_STAT 0x108UL /* Status */ |
| 17 | #define GREG_IMASK 0x10cUL /* Interrupt Mask */ |
| 18 | #define GREG_REG_SIZE 0x110UL |
| 19 | |
| 20 | /* Global reset register. */ |
| 21 | #define GREG_RESET_ETX 0x01 |
| 22 | #define GREG_RESET_ERX 0x02 |
| 23 | #define GREG_RESET_ALL 0x03 |
| 24 | |
| 25 | /* Global config register. */ |
| 26 | #define GREG_CFG_BURSTMSK 0x03 |
| 27 | #define GREG_CFG_BURST16 0x00 |
| 28 | #define GREG_CFG_BURST32 0x01 |
| 29 | #define GREG_CFG_BURST64 0x02 |
| 30 | #define GREG_CFG_64BIT 0x04 |
| 31 | #define GREG_CFG_PARITY 0x08 |
| 32 | #define GREG_CFG_RESV 0x10 |
| 33 | |
| 34 | /* Global status register. */ |
| 35 | #define GREG_STAT_GOTFRAME 0x00000001 /* Received a frame */ |
| 36 | #define GREG_STAT_RCNTEXP 0x00000002 /* Receive frame counter expired */ |
| 37 | #define GREG_STAT_ACNTEXP 0x00000004 /* Align-error counter expired */ |
| 38 | #define GREG_STAT_CCNTEXP 0x00000008 /* CRC-error counter expired */ |
| 39 | #define GREG_STAT_LCNTEXP 0x00000010 /* Length-error counter expired */ |
| 40 | #define GREG_STAT_RFIFOVF 0x00000020 /* Receive FIFO overflow */ |
| 41 | #define GREG_STAT_CVCNTEXP 0x00000040 /* Code-violation counter expired */ |
| 42 | #define GREG_STAT_STSTERR 0x00000080 /* Test error in XIF for SQE */ |
| 43 | #define GREG_STAT_SENTFRAME 0x00000100 /* Transmitted a frame */ |
| 44 | #define GREG_STAT_TFIFO_UND 0x00000200 /* Transmit FIFO underrun */ |
| 45 | #define GREG_STAT_MAXPKTERR 0x00000400 /* Max-packet size error */ |
| 46 | #define GREG_STAT_NCNTEXP 0x00000800 /* Normal-collision counter expired */ |
| 47 | #define GREG_STAT_ECNTEXP 0x00001000 /* Excess-collision counter expired */ |
| 48 | #define GREG_STAT_LCCNTEXP 0x00002000 /* Late-collision counter expired */ |
| 49 | #define GREG_STAT_FCNTEXP 0x00004000 /* First-collision counter expired */ |
| 50 | #define GREG_STAT_DTIMEXP 0x00008000 /* Defer-timer expired */ |
| 51 | #define GREG_STAT_RXTOHOST 0x00010000 /* Moved from receive-FIFO to host memory */ |
| 52 | #define GREG_STAT_NORXD 0x00020000 /* No more receive descriptors */ |
| 53 | #define GREG_STAT_RXERR 0x00040000 /* Error during receive dma */ |
| 54 | #define GREG_STAT_RXLATERR 0x00080000 /* Late error during receive dma */ |
| 55 | #define GREG_STAT_RXPERR 0x00100000 /* Parity error during receive dma */ |
| 56 | #define GREG_STAT_RXTERR 0x00200000 /* Tag error during receive dma */ |
| 57 | #define GREG_STAT_EOPERR 0x00400000 /* Transmit descriptor did not have EOP set */ |
| 58 | #define GREG_STAT_MIFIRQ 0x00800000 /* MIF is signaling an interrupt condition */ |
| 59 | #define GREG_STAT_HOSTTOTX 0x01000000 /* Moved from host memory to transmit-FIFO */ |
| 60 | #define GREG_STAT_TXALL 0x02000000 /* Transmitted all packets in the tx-fifo */ |
| 61 | #define GREG_STAT_TXEACK 0x04000000 /* Error during transmit dma */ |
| 62 | #define GREG_STAT_TXLERR 0x08000000 /* Late error during transmit dma */ |
| 63 | #define GREG_STAT_TXPERR 0x10000000 /* Parity error during transmit dma */ |
| 64 | #define GREG_STAT_TXTERR 0x20000000 /* Tag error during transmit dma */ |
| 65 | #define GREG_STAT_SLVERR 0x40000000 /* PIO access got an error */ |
| 66 | #define GREG_STAT_SLVPERR 0x80000000 /* PIO access got a parity error */ |
| 67 | |
| 68 | /* All interesting error conditions. */ |
| 69 | #define GREG_STAT_ERRORS 0xfc7efefc |
| 70 | |
| 71 | /* Global interrupt mask register. */ |
| 72 | #define GREG_IMASK_GOTFRAME 0x00000001 /* Received a frame */ |
| 73 | #define GREG_IMASK_RCNTEXP 0x00000002 /* Receive frame counter expired */ |
| 74 | #define GREG_IMASK_ACNTEXP 0x00000004 /* Align-error counter expired */ |
| 75 | #define GREG_IMASK_CCNTEXP 0x00000008 /* CRC-error counter expired */ |
| 76 | #define GREG_IMASK_LCNTEXP 0x00000010 /* Length-error counter expired */ |
| 77 | #define GREG_IMASK_RFIFOVF 0x00000020 /* Receive FIFO overflow */ |
| 78 | #define GREG_IMASK_CVCNTEXP 0x00000040 /* Code-violation counter expired */ |
| 79 | #define GREG_IMASK_STSTERR 0x00000080 /* Test error in XIF for SQE */ |
| 80 | #define GREG_IMASK_SENTFRAME 0x00000100 /* Transmitted a frame */ |
| 81 | #define GREG_IMASK_TFIFO_UND 0x00000200 /* Transmit FIFO underrun */ |
| 82 | #define GREG_IMASK_MAXPKTERR 0x00000400 /* Max-packet size error */ |
| 83 | #define GREG_IMASK_NCNTEXP 0x00000800 /* Normal-collision counter expired */ |
| 84 | #define GREG_IMASK_ECNTEXP 0x00001000 /* Excess-collision counter expired */ |
| 85 | #define GREG_IMASK_LCCNTEXP 0x00002000 /* Late-collision counter expired */ |
| 86 | #define GREG_IMASK_FCNTEXP 0x00004000 /* First-collision counter expired */ |
| 87 | #define GREG_IMASK_DTIMEXP 0x00008000 /* Defer-timer expired */ |
| 88 | #define GREG_IMASK_RXTOHOST 0x00010000 /* Moved from receive-FIFO to host memory */ |
| 89 | #define GREG_IMASK_NORXD 0x00020000 /* No more receive descriptors */ |
| 90 | #define GREG_IMASK_RXERR 0x00040000 /* Error during receive dma */ |
| 91 | #define GREG_IMASK_RXLATERR 0x00080000 /* Late error during receive dma */ |
| 92 | #define GREG_IMASK_RXPERR 0x00100000 /* Parity error during receive dma */ |
| 93 | #define GREG_IMASK_RXTERR 0x00200000 /* Tag error during receive dma */ |
| 94 | #define GREG_IMASK_EOPERR 0x00400000 /* Transmit descriptor did not have EOP set */ |
| 95 | #define GREG_IMASK_MIFIRQ 0x00800000 /* MIF is signaling an interrupt condition */ |
| 96 | #define GREG_IMASK_HOSTTOTX 0x01000000 /* Moved from host memory to transmit-FIFO */ |
| 97 | #define GREG_IMASK_TXALL 0x02000000 /* Transmitted all packets in the tx-fifo */ |
| 98 | #define GREG_IMASK_TXEACK 0x04000000 /* Error during transmit dma */ |
| 99 | #define GREG_IMASK_TXLERR 0x08000000 /* Late error during transmit dma */ |
| 100 | #define GREG_IMASK_TXPERR 0x10000000 /* Parity error during transmit dma */ |
| 101 | #define GREG_IMASK_TXTERR 0x20000000 /* Tag error during transmit dma */ |
| 102 | #define GREG_IMASK_SLVERR 0x40000000 /* PIO access got an error */ |
| 103 | #define GREG_IMASK_SLVPERR 0x80000000 /* PIO access got a parity error */ |
| 104 | |
| 105 | /* Happy Meal external transmitter registers. */ |
| 106 | #define ETX_PENDING 0x00UL /* Transmit pending/wakeup register */ |
| 107 | #define ETX_CFG 0x04UL /* Transmit config register */ |
| 108 | #define ETX_RING 0x08UL /* Transmit ring pointer */ |
| 109 | #define ETX_BBASE 0x0cUL /* Transmit buffer base */ |
| 110 | #define ETX_BDISP 0x10UL /* Transmit buffer displacement */ |
| 111 | #define ETX_FIFOWPTR 0x14UL /* FIFO write ptr */ |
| 112 | #define ETX_FIFOSWPTR 0x18UL /* FIFO write ptr (shadow register) */ |
| 113 | #define ETX_FIFORPTR 0x1cUL /* FIFO read ptr */ |
| 114 | #define ETX_FIFOSRPTR 0x20UL /* FIFO read ptr (shadow register) */ |
| 115 | #define ETX_FIFOPCNT 0x24UL /* FIFO packet counter */ |
| 116 | #define ETX_SMACHINE 0x28UL /* Transmitter state machine */ |
| 117 | #define ETX_RSIZE 0x2cUL /* Ring descriptor size */ |
| 118 | #define ETX_BPTR 0x30UL /* Transmit data buffer ptr */ |
| 119 | #define ETX_REG_SIZE 0x34UL |
| 120 | |
| 121 | /* ETX transmit pending register. */ |
| 122 | #define ETX_TP_DMAWAKEUP 0x00000001 /* Restart transmit dma */ |
| 123 | |
| 124 | /* ETX config register. */ |
| 125 | #define ETX_CFG_DMAENABLE 0x00000001 /* Enable transmit dma */ |
| 126 | #define ETX_CFG_FIFOTHRESH 0x000003fe /* Transmit FIFO threshold */ |
| 127 | #define ETX_CFG_IRQDAFTER 0x00000400 /* Interrupt after TX-FIFO drained */ |
| 128 | #define ETX_CFG_IRQDBEFORE 0x00000000 /* Interrupt before TX-FIFO drained */ |
| 129 | |
| 130 | #define ETX_RSIZE_SHIFT 4 |
| 131 | |
| 132 | /* Happy Meal external receiver registers. */ |
| 133 | #define ERX_CFG 0x00UL /* Receiver config register */ |
| 134 | #define ERX_RING 0x04UL /* Receiver ring ptr */ |
| 135 | #define ERX_BPTR 0x08UL /* Receiver buffer ptr */ |
| 136 | #define ERX_FIFOWPTR 0x0cUL /* FIFO write ptr */ |
| 137 | #define ERX_FIFOSWPTR 0x10UL /* FIFO write ptr (shadow register) */ |
| 138 | #define ERX_FIFORPTR 0x14UL /* FIFO read ptr */ |
| 139 | #define ERX_FIFOSRPTR 0x18UL /* FIFO read ptr (shadow register) */ |
| 140 | #define ERX_SMACHINE 0x1cUL /* Receiver state machine */ |
| 141 | #define ERX_REG_SIZE 0x20UL |
| 142 | |
| 143 | /* ERX config register. */ |
| 144 | #define ERX_CFG_DMAENABLE 0x00000001 /* Enable receive DMA */ |
| 145 | #define ERX_CFG_RESV1 0x00000006 /* Unused... */ |
| 146 | #define ERX_CFG_BYTEOFFSET 0x00000038 /* Receive first byte offset */ |
| 147 | #define ERX_CFG_RESV2 0x000001c0 /* Unused... */ |
| 148 | #define ERX_CFG_SIZE32 0x00000000 /* Receive ring size == 32 */ |
| 149 | #define ERX_CFG_SIZE64 0x00000200 /* Receive ring size == 64 */ |
| 150 | #define ERX_CFG_SIZE128 0x00000400 /* Receive ring size == 128 */ |
| 151 | #define ERX_CFG_SIZE256 0x00000600 /* Receive ring size == 256 */ |
| 152 | #define ERX_CFG_RESV3 0x0000f800 /* Unused... */ |
| 153 | #define ERX_CFG_CSUMSTART 0x007f0000 /* Offset of checksum start, |
| 154 | * in halfwords. */ |
| 155 | |
| 156 | /* I'd like a Big Mac, small fries, small coke, and SparcLinux please. */ |
| 157 | #define BMAC_XIFCFG 0x0000UL /* XIF config register */ |
| 158 | /* 0x4-->0x204, reserved */ |
| 159 | #define BMAC_TXSWRESET 0x208UL /* Transmitter software reset */ |
| 160 | #define BMAC_TXCFG 0x20cUL /* Transmitter config register */ |
| 161 | #define BMAC_IGAP1 0x210UL /* Inter-packet gap 1 */ |
| 162 | #define BMAC_IGAP2 0x214UL /* Inter-packet gap 2 */ |
| 163 | #define BMAC_ALIMIT 0x218UL /* Transmit attempt limit */ |
| 164 | #define BMAC_STIME 0x21cUL /* Transmit slot time */ |
| 165 | #define BMAC_PLEN 0x220UL /* Size of transmit preamble */ |
| 166 | #define BMAC_PPAT 0x224UL /* Pattern for transmit preamble */ |
| 167 | #define BMAC_TXSDELIM 0x228UL /* Transmit delimiter */ |
| 168 | #define BMAC_JSIZE 0x22cUL /* Jam size */ |
| 169 | #define BMAC_TXMAX 0x230UL /* Transmit max pkt size */ |
| 170 | #define BMAC_TXMIN 0x234UL /* Transmit min pkt size */ |
| 171 | #define BMAC_PATTEMPT 0x238UL /* Count of transmit peak attempts */ |
| 172 | #define BMAC_DTCTR 0x23cUL /* Transmit defer timer */ |
| 173 | #define BMAC_NCCTR 0x240UL /* Transmit normal-collision counter */ |
| 174 | #define BMAC_FCCTR 0x244UL /* Transmit first-collision counter */ |
| 175 | #define BMAC_EXCTR 0x248UL /* Transmit excess-collision counter */ |
| 176 | #define BMAC_LTCTR 0x24cUL /* Transmit late-collision counter */ |
| 177 | #define BMAC_RSEED 0x250UL /* Transmit random number seed */ |
| 178 | #define BMAC_TXSMACHINE 0x254UL /* Transmit state machine */ |
| 179 | /* 0x258-->0x304, reserved */ |
| 180 | #define BMAC_RXSWRESET 0x308UL /* Receiver software reset */ |
| 181 | #define BMAC_RXCFG 0x30cUL /* Receiver config register */ |
| 182 | #define BMAC_RXMAX 0x310UL /* Receive max pkt size */ |
| 183 | #define BMAC_RXMIN 0x314UL /* Receive min pkt size */ |
| 184 | #define BMAC_MACADDR2 0x318UL /* Ether address register 2 */ |
| 185 | #define BMAC_MACADDR1 0x31cUL /* Ether address register 1 */ |
| 186 | #define BMAC_MACADDR0 0x320UL /* Ether address register 0 */ |
| 187 | #define BMAC_FRCTR 0x324UL /* Receive frame receive counter */ |
| 188 | #define BMAC_GLECTR 0x328UL /* Receive giant-length error counter */ |
| 189 | #define BMAC_UNALECTR 0x32cUL /* Receive unaligned error counter */ |
| 190 | #define BMAC_RCRCECTR 0x330UL /* Receive CRC error counter */ |
| 191 | #define BMAC_RXSMACHINE 0x334UL /* Receiver state machine */ |
| 192 | #define BMAC_RXCVALID 0x338UL /* Receiver code violation */ |
| 193 | /* 0x33c, reserved */ |
| 194 | #define BMAC_HTABLE3 0x340UL /* Hash table 3 */ |
| 195 | #define BMAC_HTABLE2 0x344UL /* Hash table 2 */ |
| 196 | #define BMAC_HTABLE1 0x348UL /* Hash table 1 */ |
| 197 | #define BMAC_HTABLE0 0x34cUL /* Hash table 0 */ |
| 198 | #define BMAC_AFILTER2 0x350UL /* Address filter 2 */ |
| 199 | #define BMAC_AFILTER1 0x354UL /* Address filter 1 */ |
| 200 | #define BMAC_AFILTER0 0x358UL /* Address filter 0 */ |
| 201 | #define BMAC_AFMASK 0x35cUL /* Address filter mask */ |
| 202 | #define BMAC_REG_SIZE 0x360UL |
| 203 | |
| 204 | /* BigMac XIF config register. */ |
| 205 | #define BIGMAC_XCFG_ODENABLE 0x00000001 /* Output driver enable */ |
| 206 | #define BIGMAC_XCFG_XLBACK 0x00000002 /* Loopback-mode XIF enable */ |
| 207 | #define BIGMAC_XCFG_MLBACK 0x00000004 /* Loopback-mode MII enable */ |
| 208 | #define BIGMAC_XCFG_MIIDISAB 0x00000008 /* MII receive buffer disable */ |
| 209 | #define BIGMAC_XCFG_SQENABLE 0x00000010 /* SQE test enable */ |
| 210 | #define BIGMAC_XCFG_SQETWIN 0x000003e0 /* SQE time window */ |
| 211 | #define BIGMAC_XCFG_LANCE 0x00000010 /* Lance mode enable */ |
| 212 | #define BIGMAC_XCFG_LIPG0 0x000003e0 /* Lance mode IPG0 */ |
| 213 | |
| 214 | /* BigMac transmit config register. */ |
| 215 | #define BIGMAC_TXCFG_ENABLE 0x00000001 /* Enable the transmitter */ |
| 216 | #define BIGMAC_TXCFG_SMODE 0x00000020 /* Enable slow transmit mode */ |
| 217 | #define BIGMAC_TXCFG_CIGN 0x00000040 /* Ignore transmit collisions */ |
| 218 | #define BIGMAC_TXCFG_FCSOFF 0x00000080 /* Do not emit FCS */ |
| 219 | #define BIGMAC_TXCFG_DBACKOFF 0x00000100 /* Disable backoff */ |
| 220 | #define BIGMAC_TXCFG_FULLDPLX 0x00000200 /* Enable full-duplex */ |
| 221 | #define BIGMAC_TXCFG_DGIVEUP 0x00000400 /* Don't give up on transmits */ |
| 222 | |
| 223 | /* BigMac receive config register. */ |
| 224 | #define BIGMAC_RXCFG_ENABLE 0x00000001 /* Enable the receiver */ |
| 225 | #define BIGMAC_RXCFG_PSTRIP 0x00000020 /* Pad byte strip enable */ |
| 226 | #define BIGMAC_RXCFG_PMISC 0x00000040 /* Enable promiscous mode */ |
| 227 | #define BIGMAC_RXCFG_DERR 0x00000080 /* Disable error checking */ |
| 228 | #define BIGMAC_RXCFG_DCRCS 0x00000100 /* Disable CRC stripping */ |
| 229 | #define BIGMAC_RXCFG_REJME 0x00000200 /* Reject packets addressed to me */ |
| 230 | #define BIGMAC_RXCFG_PGRP 0x00000400 /* Enable promisc group mode */ |
| 231 | #define BIGMAC_RXCFG_HENABLE 0x00000800 /* Enable the hash filter */ |
| 232 | #define BIGMAC_RXCFG_AENABLE 0x00001000 /* Enable the address filter */ |
| 233 | |
| 234 | /* These are the "Management Interface" (ie. MIF) registers of the transceiver. */ |
| 235 | #define TCVR_BBCLOCK 0x00UL /* Bit bang clock register */ |
| 236 | #define TCVR_BBDATA 0x04UL /* Bit bang data register */ |
| 237 | #define TCVR_BBOENAB 0x08UL /* Bit bang output enable */ |
| 238 | #define TCVR_FRAME 0x0cUL /* Frame control/data register */ |
| 239 | #define TCVR_CFG 0x10UL /* MIF config register */ |
| 240 | #define TCVR_IMASK 0x14UL /* MIF interrupt mask */ |
| 241 | #define TCVR_STATUS 0x18UL /* MIF status */ |
| 242 | #define TCVR_SMACHINE 0x1cUL /* MIF state machine */ |
| 243 | #define TCVR_REG_SIZE 0x20UL |
| 244 | |
| 245 | /* Frame commands. */ |
| 246 | #define FRAME_WRITE 0x50020000 |
| 247 | #define FRAME_READ 0x60020000 |
| 248 | |
| 249 | /* Transceiver config register */ |
| 250 | #define TCV_CFG_PSELECT 0x00000001 /* Select PHY */ |
| 251 | #define TCV_CFG_PENABLE 0x00000002 /* Enable MIF polling */ |
| 252 | #define TCV_CFG_BENABLE 0x00000004 /* Enable the "bit banger" oh baby */ |
| 253 | #define TCV_CFG_PREGADDR 0x000000f8 /* Address of poll register */ |
| 254 | #define TCV_CFG_MDIO0 0x00000100 /* MDIO zero, data/attached */ |
| 255 | #define TCV_CFG_MDIO1 0x00000200 /* MDIO one, data/attached */ |
| 256 | #define TCV_CFG_PDADDR 0x00007c00 /* Device PHY address polling */ |
| 257 | |
| 258 | /* Here are some PHY addresses. */ |
| 259 | #define TCV_PADDR_ETX 0 /* Internal transceiver */ |
| 260 | #define TCV_PADDR_ITX 1 /* External transceiver */ |
| 261 | |
| 262 | /* Transceiver status register */ |
| 263 | #define TCV_STAT_BASIC 0xffff0000 /* The "basic" part */ |
| 264 | #define TCV_STAT_NORMAL 0x0000ffff /* The "non-basic" part */ |
| 265 | |
| 266 | /* Inside the Happy Meal transceiver is the physical layer, they use an |
| 267 | * implementations for National Semiconductor, part number DP83840VCE. |
| 268 | * You can retrieve the data sheets and programming docs for this beast |
| 269 | * from http://www.national.com/ |
| 270 | * |
| 271 | * The DP83840 is capable of both 10 and 100Mbps ethernet, in both |
| 272 | * half and full duplex mode. It also supports auto negotiation. |
| 273 | * |
| 274 | * But.... THIS THING IS A PAIN IN THE ASS TO PROGRAM! |
| 275 | * Debugging eeprom burnt code is more fun than programming this chip! |
| 276 | */ |
| 277 | |
| 278 | /* Generic MII registers defined in linux/mii.h, these below |
| 279 | * are DP83840 specific. |
| 280 | */ |
| 281 | #define DP83840_CSCONFIG 0x17 /* CS configuration */ |
| 282 | |
| 283 | /* The Carrier Sense config register. */ |
| 284 | #define CSCONFIG_RESV1 0x0001 /* Unused... */ |
| 285 | #define CSCONFIG_LED4 0x0002 /* Pin for full-dplx LED4 */ |
| 286 | #define CSCONFIG_LED1 0x0004 /* Pin for conn-status LED1 */ |
| 287 | #define CSCONFIG_RESV2 0x0008 /* Unused... */ |
| 288 | #define CSCONFIG_TCVDISAB 0x0010 /* Turns off the transceiver */ |
| 289 | #define CSCONFIG_DFBYPASS 0x0020 /* Bypass disconnect function */ |
| 290 | #define CSCONFIG_GLFORCE 0x0040 /* Good link force for 100mbps */ |
| 291 | #define CSCONFIG_CLKTRISTATE 0x0080 /* Tristate 25m clock */ |
| 292 | #define CSCONFIG_RESV3 0x0700 /* Unused... */ |
| 293 | #define CSCONFIG_ENCODE 0x0800 /* 1=MLT-3, 0=binary */ |
| 294 | #define CSCONFIG_RENABLE 0x1000 /* Repeater mode enable */ |
| 295 | #define CSCONFIG_TCDISABLE 0x2000 /* Disable timeout counter */ |
| 296 | #define CSCONFIG_RESV4 0x4000 /* Unused... */ |
| 297 | #define CSCONFIG_NDISABLE 0x8000 /* Disable NRZI */ |
| 298 | |
| 299 | /* Happy Meal descriptor rings and such. |
| 300 | * All descriptor rings must be aligned on a 2K boundary. |
| 301 | * All receive buffers must be 64 byte aligned. |
| 302 | * Always write the address first before setting the ownership |
| 303 | * bits to avoid races with the hardware scanning the ring. |
| 304 | */ |
| 305 | typedef u32 __bitwise__ hme32; |
| 306 | |
| 307 | struct happy_meal_rxd { |
| 308 | hme32 rx_flags; |
| 309 | hme32 rx_addr; |
| 310 | }; |
| 311 | |
| 312 | #define RXFLAG_OWN 0x80000000 /* 1 = hardware, 0 = software */ |
| 313 | #define RXFLAG_OVERFLOW 0x40000000 /* 1 = buffer overflow */ |
| 314 | #define RXFLAG_SIZE 0x3fff0000 /* Size of the buffer */ |
| 315 | #define RXFLAG_CSUM 0x0000ffff /* HW computed checksum */ |
| 316 | |
| 317 | struct happy_meal_txd { |
| 318 | hme32 tx_flags; |
| 319 | hme32 tx_addr; |
| 320 | }; |
| 321 | |
| 322 | #define TXFLAG_OWN 0x80000000 /* 1 = hardware, 0 = software */ |
| 323 | #define TXFLAG_SOP 0x40000000 /* 1 = start of packet */ |
| 324 | #define TXFLAG_EOP 0x20000000 /* 1 = end of packet */ |
| 325 | #define TXFLAG_CSENABLE 0x10000000 /* 1 = enable hw-checksums */ |
| 326 | #define TXFLAG_CSLOCATION 0x0ff00000 /* Where to stick the csum */ |
| 327 | #define TXFLAG_CSBUFBEGIN 0x000fc000 /* Where to begin checksum */ |
| 328 | #define TXFLAG_SIZE 0x00003fff /* Size of the packet */ |
| 329 | |
| 330 | #define TX_RING_SIZE 32 /* Must be >16 and <255, multiple of 16 */ |
| 331 | #define RX_RING_SIZE 32 /* see ERX_CFG_SIZE* for possible values */ |
| 332 | |
| 333 | #if (TX_RING_SIZE < 16 || TX_RING_SIZE > 256 || (TX_RING_SIZE % 16) != 0) |
| 334 | #error TX_RING_SIZE holds illegal value |
| 335 | #endif |
| 336 | |
| 337 | #define TX_RING_MAXSIZE 256 |
| 338 | #define RX_RING_MAXSIZE 256 |
| 339 | |
| 340 | /* We use a 14 byte offset for checksum computation. */ |
| 341 | #if (RX_RING_SIZE == 32) |
| 342 | #define ERX_CFG_DEFAULT(off) (ERX_CFG_DMAENABLE|((off)<<3)|ERX_CFG_SIZE32|((14/2)<<16)) |
| 343 | #else |
| 344 | #if (RX_RING_SIZE == 64) |
| 345 | #define ERX_CFG_DEFAULT(off) (ERX_CFG_DMAENABLE|((off)<<3)|ERX_CFG_SIZE64|((14/2)<<16)) |
| 346 | #else |
| 347 | #if (RX_RING_SIZE == 128) |
| 348 | #define ERX_CFG_DEFAULT(off) (ERX_CFG_DMAENABLE|((off)<<3)|ERX_CFG_SIZE128|((14/2)<<16)) |
| 349 | #else |
| 350 | #if (RX_RING_SIZE == 256) |
| 351 | #define ERX_CFG_DEFAULT(off) (ERX_CFG_DMAENABLE|((off)<<3)|ERX_CFG_SIZE256|((14/2)<<16)) |
| 352 | #else |
| 353 | #error RX_RING_SIZE holds illegal value |
| 354 | #endif |
| 355 | #endif |
| 356 | #endif |
| 357 | #endif |
| 358 | |
| 359 | #define NEXT_RX(num) (((num) + 1) & (RX_RING_SIZE - 1)) |
| 360 | #define NEXT_TX(num) (((num) + 1) & (TX_RING_SIZE - 1)) |
| 361 | #define PREV_RX(num) (((num) - 1) & (RX_RING_SIZE - 1)) |
| 362 | #define PREV_TX(num) (((num) - 1) & (TX_RING_SIZE - 1)) |
| 363 | |
| 364 | #define TX_BUFFS_AVAIL(hp) \ |
| 365 | (((hp)->tx_old <= (hp)->tx_new) ? \ |
| 366 | (hp)->tx_old + (TX_RING_SIZE - 1) - (hp)->tx_new : \ |
| 367 | (hp)->tx_old - (hp)->tx_new - 1) |
| 368 | |
| 369 | #define RX_OFFSET 2 |
| 370 | #define RX_BUF_ALLOC_SIZE (1546 + RX_OFFSET + 64) |
| 371 | |
| 372 | #define RX_COPY_THRESHOLD 256 |
| 373 | |
| 374 | struct hmeal_init_block { |
| 375 | struct happy_meal_rxd happy_meal_rxd[RX_RING_MAXSIZE]; |
| 376 | struct happy_meal_txd happy_meal_txd[TX_RING_MAXSIZE]; |
| 377 | }; |
| 378 | |
| 379 | #define hblock_offset(mem, elem) \ |
| 380 | ((__u32)((unsigned long)(&(((struct hmeal_init_block *)0)->mem[elem])))) |
| 381 | |
| 382 | /* Now software state stuff. */ |
| 383 | enum happy_transceiver { |
| 384 | external = 0, |
| 385 | internal = 1, |
| 386 | none = 2, |
| 387 | }; |
| 388 | |
| 389 | /* Timer state engine. */ |
| 390 | enum happy_timer_state { |
| 391 | arbwait = 0, /* Waiting for auto negotiation to complete. */ |
| 392 | lupwait = 1, /* Auto-neg complete, awaiting link-up status. */ |
| 393 | ltrywait = 2, /* Forcing try of all modes, from fastest to slowest. */ |
| 394 | asleep = 3, /* Time inactive. */ |
| 395 | }; |
| 396 | |
| 397 | struct quattro; |
| 398 | |
| 399 | /* Happy happy, joy joy! */ |
| 400 | struct happy_meal { |
| 401 | void __iomem *gregs; /* Happy meal global registers */ |
| 402 | struct hmeal_init_block *happy_block; /* RX and TX descriptors (CPU addr) */ |
| 403 | |
| 404 | #if defined(CONFIG_SBUS) && defined(CONFIG_PCI) |
| 405 | u32 (*read_desc32)(hme32 *); |
| 406 | void (*write_txd)(struct happy_meal_txd *, u32, u32); |
| 407 | void (*write_rxd)(struct happy_meal_rxd *, u32, u32); |
| 408 | #endif |
| 409 | |
| 410 | /* This is either an of_device or a pci_dev. */ |
| 411 | void *happy_dev; |
| 412 | struct device *dma_dev; |
| 413 | |
| 414 | spinlock_t happy_lock; |
| 415 | |
| 416 | struct sk_buff *rx_skbs[RX_RING_SIZE]; |
| 417 | struct sk_buff *tx_skbs[TX_RING_SIZE]; |
| 418 | |
| 419 | int rx_new, tx_new, rx_old, tx_old; |
| 420 | |
| 421 | struct net_device_stats net_stats; /* Statistical counters */ |
| 422 | |
| 423 | #if defined(CONFIG_SBUS) && defined(CONFIG_PCI) |
| 424 | u32 (*read32)(void __iomem *); |
| 425 | void (*write32)(void __iomem *, u32); |
| 426 | #endif |
| 427 | |
| 428 | void __iomem *etxregs; /* External transmitter regs */ |
| 429 | void __iomem *erxregs; /* External receiver regs */ |
| 430 | void __iomem *bigmacregs; /* BIGMAC core regs */ |
| 431 | void __iomem *tcvregs; /* MIF transceiver regs */ |
| 432 | |
| 433 | dma_addr_t hblock_dvma; /* DVMA visible address happy block */ |
| 434 | unsigned int happy_flags; /* Driver state flags */ |
| 435 | enum happy_transceiver tcvr_type; /* Kind of transceiver in use */ |
| 436 | unsigned int happy_bursts; /* Get your mind out of the gutter */ |
| 437 | unsigned int paddr; /* PHY address for transceiver */ |
| 438 | unsigned short hm_revision; /* Happy meal revision */ |
| 439 | unsigned short sw_bmcr; /* SW copy of BMCR */ |
| 440 | unsigned short sw_bmsr; /* SW copy of BMSR */ |
| 441 | unsigned short sw_physid1; /* SW copy of PHYSID1 */ |
| 442 | unsigned short sw_physid2; /* SW copy of PHYSID2 */ |
| 443 | unsigned short sw_advertise; /* SW copy of ADVERTISE */ |
| 444 | unsigned short sw_lpa; /* SW copy of LPA */ |
| 445 | unsigned short sw_expansion; /* SW copy of EXPANSION */ |
| 446 | unsigned short sw_csconfig; /* SW copy of CSCONFIG */ |
| 447 | unsigned int auto_speed; /* Auto-nego link speed */ |
| 448 | unsigned int forced_speed; /* Force mode link speed */ |
| 449 | unsigned int poll_data; /* MIF poll data */ |
| 450 | unsigned int poll_flag; /* MIF poll flag */ |
| 451 | unsigned int linkcheck; /* Have we checked the link yet? */ |
| 452 | unsigned int lnkup; /* Is the link up as far as we know? */ |
| 453 | unsigned int lnkdown; /* Trying to force the link down? */ |
| 454 | unsigned int lnkcnt; /* Counter for link-up attempts. */ |
| 455 | struct timer_list happy_timer; /* To watch the link when coming up. */ |
| 456 | enum happy_timer_state timer_state; /* State of the auto-neg timer. */ |
| 457 | unsigned int timer_ticks; /* Number of clicks at each state. */ |
| 458 | |
| 459 | struct net_device *dev; /* Backpointer */ |
| 460 | struct quattro *qfe_parent; /* For Quattro cards */ |
| 461 | int qfe_ent; /* Which instance on quattro */ |
| 462 | }; |
| 463 | |
| 464 | /* Here are the happy flags. */ |
| 465 | #define HFLAG_POLL 0x00000001 /* We are doing MIF polling */ |
| 466 | #define HFLAG_FENABLE 0x00000002 /* The MII frame is enabled */ |
| 467 | #define HFLAG_LANCE 0x00000004 /* We are using lance-mode */ |
| 468 | #define HFLAG_RXENABLE 0x00000008 /* Receiver is enabled */ |
| 469 | #define HFLAG_AUTO 0x00000010 /* Using auto-negotiation, 0 = force */ |
| 470 | #define HFLAG_FULL 0x00000020 /* Full duplex enable */ |
| 471 | #define HFLAG_MACFULL 0x00000040 /* Using full duplex in the MAC */ |
| 472 | #define HFLAG_POLLENABLE 0x00000080 /* Actually try MIF polling */ |
| 473 | #define HFLAG_RXCV 0x00000100 /* XXX RXCV ENABLE */ |
| 474 | #define HFLAG_INIT 0x00000200 /* Init called at least once */ |
| 475 | #define HFLAG_LINKUP 0x00000400 /* 1 = Link is up */ |
| 476 | #define HFLAG_PCI 0x00000800 /* PCI based Happy Meal */ |
| 477 | #define HFLAG_QUATTRO 0x00001000 /* On QFE/Quattro card */ |
| 478 | |
| 479 | #define HFLAG_20_21 (HFLAG_POLLENABLE | HFLAG_FENABLE) |
| 480 | #define HFLAG_NOT_A0 (HFLAG_POLLENABLE | HFLAG_FENABLE | HFLAG_LANCE | HFLAG_RXCV) |
| 481 | |
| 482 | /* Support for QFE/Quattro cards. */ |
| 483 | struct quattro { |
| 484 | struct net_device *happy_meals[4]; |
| 485 | |
| 486 | /* This is either a sbus_dev or a pci_dev. */ |
| 487 | void *quattro_dev; |
| 488 | |
| 489 | struct quattro *next; |
| 490 | |
| 491 | /* PROM ranges, if any. */ |
| 492 | #ifdef CONFIG_SBUS |
| 493 | struct linux_prom_ranges ranges[8]; |
| 494 | #endif |
| 495 | int nranges; |
| 496 | }; |
| 497 | |
| 498 | /* We use this to acquire receive skb's that we can DMA directly into. */ |
| 499 | #define ALIGNED_RX_SKB_ADDR(addr) \ |
| 500 | ((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr)) |
| 501 | #define happy_meal_alloc_skb(__length, __gfp_flags) \ |
| 502 | ({ struct sk_buff *__skb; \ |
| 503 | __skb = alloc_skb((__length) + 64, (__gfp_flags)); \ |
| 504 | if(__skb) { \ |
| 505 | int __offset = (int) ALIGNED_RX_SKB_ADDR(__skb->data); \ |
| 506 | if(__offset) \ |
| 507 | skb_reserve(__skb, __offset); \ |
| 508 | } \ |
| 509 | __skb; \ |
| 510 | }) |
| 511 | |
| 512 | #endif /* !(_SUNHME_H) */ |