1 #ifndef __SIS190_H__ 2 #define __SIS190_H__ 3 4 FILE_LICENCE ( GPL_ANY ); 5 6 #include <stdint.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <stddef.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <assert.h> 13 #include <byteswap.h> 14 #include <errno.h> 15 #include <mii.h> 16 #include <gpxe/ethernet.h> 17 #include <gpxe/if_ether.h> 18 #include <gpxe/io.h> 19 #include <gpxe/iobuf.h> 20 #include <gpxe/malloc.h> 21 #include <gpxe/netdevice.h> 22 #include <gpxe/pci.h> 23 #include <gpxe/timer.h> 24 25 #define PCI_VENDOR_ID_SI 0x1039 26 27 #define PHY_MAX_ADDR 32 28 #define PHY_ID_ANY 0x1f 29 #define MII_REG_ANY 0x1f 30 31 #define DRV_VERSION "1.3" 32 #define DRV_NAME "sis190" 33 #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION 34 #define PFX DRV_NAME ": " 35 36 #define sis190_rx_quota(count, quota) count 37 38 #define NUM_TX_DESC 8 /* [8..1024] */ 39 #define NUM_RX_DESC 8 /* [8..8192] */ 40 #define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) 41 #define RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) 42 #define RX_BUF_SIZE 1536 43 #define RX_BUF_MASK 0xfff8 44 45 #define RING_ALIGNMENT 256 46 47 #define SIS190_REGS_SIZE 0x80 48 49 /* Enhanced PHY access register bit definitions */ 50 #define EhnMIIread 0x0000 51 #define EhnMIIwrite 0x0020 52 #define EhnMIIdataShift 16 53 #define EhnMIIpmdShift 6 /* 7016 only */ 54 #define EhnMIIregShift 11 55 #define EhnMIIreq 0x0010 56 #define EhnMIInotDone 0x0010 57 58 /* Write/read MMIO register */ 59 #define SIS_W8(reg, val) writeb ((val), ioaddr + (reg)) 60 #define SIS_W16(reg, val) writew ((val), ioaddr + (reg)) 61 #define SIS_W32(reg, val) writel ((val), ioaddr + (reg)) 62 #define SIS_R8(reg) readb (ioaddr + (reg)) 63 #define SIS_R16(reg) readw (ioaddr + (reg)) 64 #define SIS_R32(reg) readl (ioaddr + (reg)) 65 66 #define SIS_PCI_COMMIT() SIS_R32(IntrControl) 67 68 enum sis190_registers { 69 TxControl = 0x00, 70 TxDescStartAddr = 0x04, 71 rsv0 = 0x08, // reserved 72 TxSts = 0x0c, // unused (Control/Status) 73 RxControl = 0x10, 74 RxDescStartAddr = 0x14, 75 rsv1 = 0x18, // reserved 76 RxSts = 0x1c, // unused 77 IntrStatus = 0x20, 78 IntrMask = 0x24, 79 IntrControl = 0x28, 80 IntrTimer = 0x2c, // unused (Interupt Timer) 81 PMControl = 0x30, // unused (Power Mgmt Control/Status) 82 rsv2 = 0x34, // reserved 83 ROMControl = 0x38, 84 ROMInterface = 0x3c, 85 StationControl = 0x40, 86 GMIIControl = 0x44, 87 GIoCR = 0x48, // unused (GMAC IO Compensation) 88 GIoCtrl = 0x4c, // unused (GMAC IO Control) 89 TxMacControl = 0x50, 90 TxLimit = 0x54, // unused (Tx MAC Timer/TryLimit) 91 RGDelay = 0x58, // unused (RGMII Tx Internal Delay) 92 rsv3 = 0x5c, // reserved 93 RxMacControl = 0x60, 94 RxMacAddr = 0x62, 95 RxHashTable = 0x68, 96 // Undocumented = 0x6c, 97 RxWolCtrl = 0x70, 98 RxWolData = 0x74, // unused (Rx WOL Data Access) 99 RxMPSControl = 0x78, // unused (Rx MPS Control) 100 rsv4 = 0x7c, // reserved 101 }; 102 103 enum sis190_register_content { 104 /* IntrStatus */ 105 SoftInt = 0x40000000, // unused 106 Timeup = 0x20000000, // unused 107 PauseFrame = 0x00080000, // unused 108 MagicPacket = 0x00040000, // unused 109 WakeupFrame = 0x00020000, // unused 110 LinkChange = 0x00010000, 111 RxQEmpty = 0x00000080, 112 RxQInt = 0x00000040, 113 TxQ1Empty = 0x00000020, // unused 114 TxQ1Int = 0x00000010, 115 TxQ0Empty = 0x00000008, // unused 116 TxQ0Int = 0x00000004, 117 RxHalt = 0x00000002, 118 TxHalt = 0x00000001, 119 120 /* {Rx/Tx}CmdBits */ 121 CmdReset = 0x10, 122 CmdRxEnb = 0x08, // unused 123 CmdTxEnb = 0x01, 124 RxBufEmpty = 0x01, // unused 125 126 /* Cfg9346Bits */ 127 Cfg9346_Lock = 0x00, // unused 128 Cfg9346_Unlock = 0xc0, // unused 129 130 /* RxMacControl */ 131 AcceptErr = 0x20, // unused 132 AcceptRunt = 0x10, // unused 133 AcceptBroadcast = 0x0800, 134 AcceptMulticast = 0x0400, 135 AcceptMyPhys = 0x0200, 136 AcceptAllPhys = 0x0100, 137 138 /* RxConfigBits */ 139 RxCfgFIFOShift = 13, 140 RxCfgDMAShift = 8, // 0x1a in RxControl ? 141 142 /* TxConfigBits */ 143 TxInterFrameGapShift = 24, 144 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ 145 146 LinkStatus = 0x02, // unused 147 FullDup = 0x01, // unused 148 149 /* TBICSRBit */ 150 TBILinkOK = 0x02000000, // unused 151 }; 152 153 struct TxDesc { 154 volatile u32 PSize; 155 volatile u32 status; 156 volatile u32 addr; 157 volatile u32 size; 158 }; 159 160 struct RxDesc { 161 volatile u32 PSize; 162 volatile u32 status; 163 volatile u32 addr; 164 volatile u32 size; 165 }; 166 167 enum _DescStatusBit { 168 /* _Desc.status */ 169 OWNbit = 0x80000000, // RXOWN/TXOWN 170 INTbit = 0x40000000, // RXINT/TXINT 171 CRCbit = 0x00020000, // CRCOFF/CRCEN 172 PADbit = 0x00010000, // PREADD/PADEN 173 /* _Desc.size */ 174 RingEnd = 0x80000000, 175 /* TxDesc.status */ 176 LSEN = 0x08000000, // TSO ? -- FR 177 IPCS = 0x04000000, 178 TCPCS = 0x02000000, 179 UDPCS = 0x01000000, 180 BSTEN = 0x00800000, 181 EXTEN = 0x00400000, 182 DEFEN = 0x00200000, 183 BKFEN = 0x00100000, 184 CRSEN = 0x00080000, 185 COLEN = 0x00040000, 186 THOL3 = 0x30000000, 187 THOL2 = 0x20000000, 188 THOL1 = 0x10000000, 189 THOL0 = 0x00000000, 190 191 WND = 0x00080000, 192 TABRT = 0x00040000, 193 FIFO = 0x00020000, 194 LINK = 0x00010000, 195 ColCountMask = 0x0000ffff, 196 /* RxDesc.status */ 197 IPON = 0x20000000, 198 TCPON = 0x10000000, 199 UDPON = 0x08000000, 200 Wakup = 0x00400000, 201 Magic = 0x00200000, 202 Pause = 0x00100000, 203 DEFbit = 0x00200000, 204 BCAST = 0x000c0000, 205 MCAST = 0x00080000, 206 UCAST = 0x00040000, 207 /* RxDesc.PSize */ 208 TAGON = 0x80000000, 209 RxDescCountMask = 0x7f000000, // multi-desc pkt when > 1 ? -- FR 210 ABORT = 0x00800000, 211 SHORT = 0x00400000, 212 LIMIT = 0x00200000, 213 MIIER = 0x00100000, 214 OVRUN = 0x00080000, 215 NIBON = 0x00040000, 216 COLON = 0x00020000, 217 CRCOK = 0x00010000, 218 RxSizeMask = 0x0000ffff 219 /* 220 * The asic could apparently do vlan, TSO, jumbo (sis191 only) and 221 * provide two (unused with Linux) Tx queues. No publically 222 * available documentation alas. 223 */ 224 }; 225 226 enum sis190_eeprom_access_register_bits { 227 EECS = 0x00000001, // unused 228 EECLK = 0x00000002, // unused 229 EEDO = 0x00000008, // unused 230 EEDI = 0x00000004, // unused 231 EEREQ = 0x00000080, 232 EEROP = 0x00000200, 233 EEWOP = 0x00000100 // unused 234 }; 235 236 /* EEPROM Addresses */ 237 enum sis190_eeprom_address { 238 EEPROMSignature = 0x00, 239 EEPROMCLK = 0x01, // unused 240 EEPROMInfo = 0x02, 241 EEPROMMACAddr = 0x03 242 }; 243 244 enum sis190_feature { 245 F_HAS_RGMII = 1, 246 F_PHY_88E1111 = 2, 247 F_PHY_BCM5461 = 4 248 }; 249 250 struct sis190_private { 251 void *mmio_addr; 252 struct pci_device *pci_device; 253 struct net_device *dev; 254 u32 cur_rx; 255 u32 cur_tx; 256 u32 dirty_rx; 257 u32 dirty_tx; 258 u32 rx_dma; 259 u32 tx_dma; 260 struct RxDesc *RxDescRing; 261 struct TxDesc *TxDescRing; 262 struct io_buffer *Rx_iobuf[NUM_RX_DESC]; 263 struct io_buffer *Tx_iobuf[NUM_TX_DESC]; 264 struct mii_if_info mii_if; 265 struct list_head first_phy; 266 u32 features; 267 }; 268 269 struct sis190_phy { 270 struct list_head list; 271 int phy_id; 272 u16 id[2]; 273 u16 status; 274 u8 type; 275 }; 276 277 enum sis190_phy_type { 278 UNKNOWN = 0x00, 279 HOME = 0x01, 280 LAN = 0x02, 281 MIX = 0x03 282 }; 283 284 static struct mii_chip_info { 285 const char *name; 286 u16 id[2]; 287 unsigned int type; 288 u32 feature; 289 } mii_chip_table[] = { 290 { "Atheros PHY", { 0x004d, 0xd010 }, LAN, 0 }, 291 { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 }, 292 { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 }, 293 { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 }, 294 { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 }, 295 { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 }, 296 { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN, 0 }, 297 { NULL, { 0x00, 0x00 }, 0, 0 } 298 }; 299 300 static const struct { 301 const char *name; 302 } sis_chip_info[] = { 303 { "SiS 190 PCI Fast Ethernet adapter" }, 304 { "SiS 191 PCI Gigabit Ethernet adapter" }, 305 }; 306 307 static void sis190_phy_task(struct sis190_private *tp); 308 static void sis190_free(struct net_device *dev); 309 static inline void sis190_init_rxfilter(struct net_device *dev); 310 311 #endif 312