4 FILE_LICENCE ( GPL_ANY );
16 #include <ipxe/ethernet.h>
17 #include <ipxe/if_ether.h>
19 #include <ipxe/iobuf.h>
20 #include <ipxe/malloc.h>
21 #include <ipxe/netdevice.h>
23 #include <ipxe/timer.h>
25 #define PCI_VENDOR_ID_SI 0x1039
27 #define PHY_MAX_ADDR 32
28 #define PHY_ID_ANY 0x1f
29 #define MII_REG_ANY 0x1f
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 ": "
36 #define sis190_rx_quota(count, quota) count
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
45 #define RING_ALIGNMENT 256
47 #define SIS190_REGS_SIZE 0x80
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
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))
66 #define SIS_PCI_COMMIT() SIS_R32(IntrControl)
68 enum sis190_registers {
70 TxDescStartAddr = 0x04,
71 rsv0 = 0x08, // reserved
72 TxSts = 0x0c, // unused (Control/Status)
74 RxDescStartAddr = 0x14,
75 rsv1 = 0x18, // reserved
76 RxSts = 0x1c, // unused
80 IntrTimer = 0x2c, // unused (Interrupt Timer)
81 PMControl = 0x30, // unused (Power Mgmt Control/Status)
82 rsv2 = 0x34, // reserved
85 StationControl = 0x40,
87 GIoCR = 0x48, // unused (GMAC IO Compensation)
88 GIoCtrl = 0x4c, // unused (GMAC IO Control)
90 TxLimit = 0x54, // unused (Tx MAC Timer/TryLimit)
91 RGDelay = 0x58, // unused (RGMII Tx Internal Delay)
92 rsv3 = 0x5c, // reserved
96 // Undocumented = 0x6c,
98 RxWolData = 0x74, // unused (Rx WOL Data Access)
99 RxMPSControl = 0x78, // unused (Rx MPS Control)
100 rsv4 = 0x7c, // reserved
103 enum sis190_register_content {
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,
113 TxQ1Empty = 0x00000020, // unused
114 TxQ1Int = 0x00000010,
115 TxQ0Empty = 0x00000008, // unused
116 TxQ0Int = 0x00000004,
122 CmdRxEnb = 0x08, // unused
124 RxBufEmpty = 0x01, // unused
127 Cfg9346_Lock = 0x00, // unused
128 Cfg9346_Unlock = 0xc0, // unused
131 AcceptErr = 0x20, // unused
132 AcceptRunt = 0x10, // unused
133 AcceptBroadcast = 0x0800,
134 AcceptMulticast = 0x0400,
135 AcceptMyPhys = 0x0200,
136 AcceptAllPhys = 0x0100,
140 RxCfgDMAShift = 8, // 0x1a in RxControl ?
143 TxInterFrameGapShift = 24,
144 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
146 LinkStatus = 0x02, // unused
147 FullDup = 0x01, // unused
150 TBILinkOK = 0x02000000, // unused
167 enum _DescStatusBit {
169 OWNbit = 0x80000000, // RXOWN/TXOWN
170 INTbit = 0x40000000, // RXINT/TXINT
171 CRCbit = 0x00020000, // CRCOFF/CRCEN
172 PADbit = 0x00010000, // PREADD/PADEN
174 RingEnd = 0x80000000,
176 LSEN = 0x08000000, // TSO ? -- FR
195 ColCountMask = 0x0000ffff,
209 RxDescCountMask = 0x7f000000, // multi-desc pkt when > 1 ? -- FR
218 RxSizeMask = 0x0000ffff
220 * The asic could apparently do vlan, TSO, jumbo (sis191 only) and
221 * provide two (unused with Linux) Tx queues. No publicly
222 * available documentation alas.
226 enum sis190_eeprom_access_register_bits {
227 EECS = 0x00000001, // unused
228 EECLK = 0x00000002, // unused
229 EEDO = 0x00000008, // unused
230 EEDI = 0x00000004, // unused
233 EEWOP = 0x00000100 // unused
236 /* EEPROM Addresses */
237 enum sis190_eeprom_address {
238 EEPROMSignature = 0x00,
239 EEPROMCLK = 0x01, // unused
244 enum sis190_feature {
250 struct sis190_private {
252 struct pci_device *pci_device;
253 struct net_device *dev;
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;
270 struct list_head list;
277 enum sis190_phy_type {
284 static struct mii_chip_info {
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 }
300 static const struct {
302 } sis_chip_info[] = {
303 { "SiS 190 PCI Fast Ethernet adapter" },
304 { "SiS 191 PCI Gigabit Ethernet adapter" },
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);