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