1
2
3
4#include <linux/if_ether.h>
5#include <linux/types.h>
6
7
8struct rx_header {
9 ushort pad;
10 ushort rx_count;
11 ushort rx_status;
12 ushort cur_addr;
13};
14
15#define PAR_DATA 0
16#define PAR_STATUS 1
17#define PAR_CONTROL 2
18
19enum chip_type { RTL8002, RTL8012 };
20
21#define Ctrl_LNibRead 0x08
22#define Ctrl_HNibRead 0
23#define Ctrl_LNibWrite 0x08
24#define Ctrl_HNibWrite 0
25#define Ctrl_SelData 0x04
26#define Ctrl_IRQEN 0x10
27
28#define EOW 0xE0
29#define EOC 0xE0
30#define WrAddr 0x40
31#define RdAddr 0xC0
32#define HNib 0x10
33
34enum page0_regs
35{
36
37 PAR0 = 0, PAR1 = 1, PAR2 = 2, PAR3 = 3, PAR4 = 4, PAR5 = 5,
38 TxCNT0 = 6, TxCNT1 = 7,
39 TxSTAT = 8, RxSTAT = 9,
40 ISR = 10, IMR = 11,
41 CMR1 = 12,
42 CMR2 = 13,
43 MODSEL = 14,
44 MAR = 14,
45 CMR2_h = 0x1d, };
46
47enum eepage_regs
48{ PROM_CMD = 6, PROM_DATA = 7 };
49
50
51#define ISR_TxOK 0x01
52#define ISR_RxOK 0x04
53#define ISR_TxErr 0x02
54#define ISRh_RxErr 0x11
55
56#define CMR1h_MUX 0x08
57#define CMR1h_RESET 0x04
58#define CMR1h_RxENABLE 0x02
59#define CMR1h_TxENABLE 0x01
60#define CMR1h_TxRxOFF 0x00
61#define CMR1_ReXmit 0x08
62#define CMR1_Xmit 0x04
63#define CMR1_IRQ 0x02
64#define CMR1_BufEnb 0x01
65#define CMR1_NextPkt 0x01
66
67#define CMR2_NULL 8
68#define CMR2_IRQOUT 9
69#define CMR2_RAMTEST 10
70#define CMR2_EEPROM 12
71
72#define CMR2h_OFF 0
73#define CMR2h_Physical 1
74#define CMR2h_Normal 2
75#define CMR2h_PROMISC 3
76
77
78
79static inline unsigned char inbyte(unsigned short port)
80{
81 unsigned char _v;
82 __asm__ __volatile__ ("inb %w1,%b0" :"=a" (_v):"d" (port));
83 return _v;
84}
85
86
87
88static inline unsigned char read_nibble(short port, unsigned char offset)
89{
90 unsigned char retval;
91 outb(EOC+offset, port + PAR_DATA);
92 outb(RdAddr+offset, port + PAR_DATA);
93 inbyte(port + PAR_STATUS);
94 retval = inbyte(port + PAR_STATUS);
95 outb(EOC+offset, port + PAR_DATA);
96
97 return retval;
98}
99
100
101
102static inline unsigned char read_byte_mode0(short ioaddr)
103{
104 unsigned char low_nib;
105
106 outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
107 inbyte(ioaddr + PAR_STATUS);
108 low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
109 outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
110 inbyte(ioaddr + PAR_STATUS);
111 inbyte(ioaddr + PAR_STATUS);
112 return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
113}
114
115
116static inline unsigned char read_byte_mode2(short ioaddr)
117{
118 unsigned char low_nib;
119
120 outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
121 inbyte(ioaddr + PAR_STATUS);
122 low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
123 outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
124 inbyte(ioaddr + PAR_STATUS);
125 return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
126}
127
128
129static inline unsigned char read_byte_mode4(short ioaddr)
130{
131 unsigned char low_nib;
132
133 outb(RdAddr | MAR, ioaddr + PAR_DATA);
134 low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
135 outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
136 return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
137}
138
139
140static inline unsigned char read_byte_mode6(short ioaddr)
141{
142 unsigned char low_nib;
143
144 outb(RdAddr | MAR, ioaddr + PAR_DATA);
145 inbyte(ioaddr + PAR_STATUS);
146 low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
147 outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
148 inbyte(ioaddr + PAR_STATUS);
149 return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
150}
151
152static inline void
153write_reg(short port, unsigned char reg, unsigned char value)
154{
155 unsigned char outval;
156 outb(EOC | reg, port + PAR_DATA);
157 outval = WrAddr | reg;
158 outb(outval, port + PAR_DATA);
159 outb(outval, port + PAR_DATA);
160
161 outval &= 0xf0;
162 outval |= value;
163 outb(outval, port + PAR_DATA);
164 outval &= 0x1f;
165 outb(outval, port + PAR_DATA);
166 outb(outval, port + PAR_DATA);
167
168 outb(EOC | outval, port + PAR_DATA);
169}
170
171static inline void
172write_reg_high(short port, unsigned char reg, unsigned char value)
173{
174 unsigned char outval = EOC | HNib | reg;
175
176 outb(outval, port + PAR_DATA);
177 outval &= WrAddr | HNib | 0x0f;
178 outb(outval, port + PAR_DATA);
179 outb(outval, port + PAR_DATA);
180
181 outval = WrAddr | HNib | value;
182 outb(outval, port + PAR_DATA);
183 outval &= HNib | 0x0f;
184 outb(outval, port + PAR_DATA);
185 outb(outval, port + PAR_DATA);
186
187 outb(EOC | HNib | outval, port + PAR_DATA);
188}
189
190
191static inline void
192write_reg_byte(short port, unsigned char reg, unsigned char value)
193{
194 unsigned char outval;
195 outb(EOC | reg, port + PAR_DATA);
196 outval = WrAddr | reg;
197 outb(outval, port + PAR_DATA);
198 outb(outval, port + PAR_DATA);
199
200 outb((outval & 0xf0) | (value & 0x0f), port + PAR_DATA);
201 outb(value & 0x0f, port + PAR_DATA);
202 value >>= 4;
203 outb(value, port + PAR_DATA);
204 outb(0x10 | value, port + PAR_DATA);
205 outb(0x10 | value, port + PAR_DATA);
206
207 outb(EOC | value, port + PAR_DATA);
208}
209
210
211
212
213
214
215
216
217static inline void write_byte_mode0(short ioaddr, unsigned char value)
218{
219 outb(value & 0x0f, ioaddr + PAR_DATA);
220 outb((value>>4) | 0x10, ioaddr + PAR_DATA);
221}
222
223static inline void write_byte_mode1(short ioaddr, unsigned char value)
224{
225 outb(value & 0x0f, ioaddr + PAR_DATA);
226 outb(Ctrl_IRQEN | Ctrl_LNibWrite, ioaddr + PAR_CONTROL);
227 outb((value>>4) | 0x10, ioaddr + PAR_DATA);
228 outb(Ctrl_IRQEN | Ctrl_HNibWrite, ioaddr + PAR_CONTROL);
229}
230
231
232static inline void write_word_mode0(short ioaddr, unsigned short value)
233{
234 outb(value & 0x0f, ioaddr + PAR_DATA);
235 value >>= 4;
236 outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
237 value >>= 4;
238 outb(value & 0x0f, ioaddr + PAR_DATA);
239 value >>= 4;
240 outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
241}
242
243
244#define EE_SHIFT_CLK 0x04
245#define EE_CS 0x02
246#define EE_CLK_HIGH 0x12
247#define EE_CLK_LOW 0x16
248#define EE_DATA_WRITE 0x01
249#define EE_DATA_READ 0x08
250
251
252#define eeprom_delay(ticks) \
253do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
254
255
256#define EE_WRITE_CMD(offset) (((5 << 6) + (offset)) << 17)
257#define EE_READ(offset) (((6 << 6) + (offset)) << 17)
258#define EE_ERASE(offset) (((7 << 6) + (offset)) << 17)
259#define EE_CMD_SIZE 27
260