Rev 5522 | Rev 5560 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5522 | Rev 5525 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;; i8255x (Intel eepro 100) driver for KolibriOS ;; |
6 | ;; i8255x (Intel eepro 100) driver for KolibriOS ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
8 | ;; Written by hidnplayr@kolibrios.org ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
10 | ;; GNU GENERAL PUBLIC LICENSE ;; |
11 | ;; Version 2, June 1991 ;; |
11 | ;; Version 2, June 1991 ;; |
12 | ;; ;; |
12 | ;; ;; |
13 | ;; Some parts of this driver are based on the code of eepro100.c ;; |
13 | ;; Some parts of this driver are based on the code of eepro100.c ;; |
14 | ;; from linux. ;; |
14 | ;; from linux. ;; |
15 | ;; ;; |
15 | ;; ;; |
16 | ;; Intel's programming manual for i8255x: ;; |
16 | ;; Intel's programming manual for i8255x: ;; |
17 | ;; http://www.intel.com/design/network/manuals/8255x_opensdm.htm ;; |
17 | ;; http://www.intel.com/design/network/manuals/8255x_opensdm.htm ;; |
18 | ;; ;; |
18 | ;; ;; |
19 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
19 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
20 | 20 | ||
21 | 21 | ||
22 | format PE DLL native |
22 | format PE DLL native |
23 | entry START |
23 | entry START |
24 | 24 | ||
25 | CURRENT_API = 0x0200 |
25 | CURRENT_API = 0x0200 |
26 | COMPATIBLE_API = 0x0100 |
26 | COMPATIBLE_API = 0x0100 |
27 | API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API |
27 | API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API |
28 | 28 | ||
29 | MAX_DEVICES = 16 |
29 | MAX_DEVICES = 16 |
- | 30 | ||
- | 31 | TX_RING_SIZE = 16 |
|
30 | 32 | ||
31 | DEBUG = 1 |
33 | DEBUG = 1 |
32 | __DEBUG__ = 1 |
34 | __DEBUG__ = 1 |
33 | __DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only |
35 | __DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only |
34 | 36 | ||
35 | section '.flat' readable writable executable |
37 | section '.flat' readable writable executable |
36 | 38 | ||
37 | include '../proc32.inc' |
39 | include '../proc32.inc' |
38 | include '../struct.inc' |
40 | include '../struct.inc' |
39 | include '../macros.inc' |
41 | include '../macros.inc' |
40 | include '../fdo.inc' |
42 | include '../fdo.inc' |
41 | include '../netdrv.inc' |
43 | include '../netdrv.inc' |
42 | 44 | ||
43 | ; Serial EEPROM |
45 | ; Serial EEPROM |
44 | 46 | ||
45 | EE_SK = 1 shl 0 ; serial clock |
47 | EE_SK = 1 shl 0 ; serial clock |
46 | EE_CS = 1 shl 1 ; chip select |
48 | EE_CS = 1 shl 1 ; chip select |
47 | EE_DI = 1 shl 2 ; data in |
49 | EE_DI = 1 shl 2 ; data in |
48 | EE_DO = 1 shl 3 ; data out |
50 | EE_DO = 1 shl 3 ; data out |
49 | EE_MASK = EE_SK + EE_CS + EE_DI + EE_DO |
51 | EE_MASK = EE_SK + EE_CS + EE_DI + EE_DO |
50 | 52 | ||
51 | ; opcodes, first bit is start bit and must be 1 |
53 | ; opcodes, first bit is start bit and must be 1 |
52 | EE_READ = 110b |
54 | EE_READ = 110b |
53 | EE_WRITE = 101b |
55 | EE_WRITE = 101b |
54 | EE_ERASE = 111b |
56 | EE_ERASE = 111b |
55 | 57 | ||
56 | ; The SCB accepts the following controls for the Tx and Rx units: |
58 | ; The SCB accepts the following controls for the Tx and Rx units: |
57 | 59 | ||
58 | CU_START = 0x0010 |
60 | CU_START = 0x0010 |
59 | CU_RESUME = 0x0020 |
61 | CU_RESUME = 0x0020 |
60 | CU_STATSADDR = 0x0040 |
62 | CU_STATSADDR = 0x0040 |
61 | CU_SHOWSTATS = 0x0050 ; Dump statistics counters. |
63 | CU_SHOWSTATS = 0x0050 ; Dump statistics counters. |
62 | CU_CMD_BASE = 0x0060 ; Base address to add CU commands. |
64 | CU_CMD_BASE = 0x0060 ; Base address to add CU commands. |
63 | CU_DUMPSTATS = 0x0070 ; Dump then reset stats counters. |
65 | CU_DUMPSTATS = 0x0070 ; Dump then reset stats counters. |
64 | 66 | ||
65 | RX_START = 0x0001 |
67 | RX_START = 0x0001 |
66 | RX_RESUME = 0x0002 |
68 | RX_RESUME = 0x0002 |
67 | RX_ABORT = 0x0004 |
69 | RX_ABORT = 0x0004 |
68 | RX_ADDR_LOAD = 0x0006 |
70 | RX_ADDR_LOAD = 0x0006 |
69 | RX_RESUMENR = 0x0007 |
71 | RX_RESUMENR = 0x0007 |
70 | INT_MASK = 0x0100 |
72 | INT_MASK = 0x0100 |
71 | DRVR_INT = 0x0200 ; Driver generated interrupt |
73 | DRVR_INT = 0x0200 ; Driver generated interrupt |
72 | 74 | ||
73 | CmdIASetup = 0x0001 |
75 | CmdIASetup = 0x0001 |
74 | CmdConfigure = 0x0002 |
76 | CmdConfigure = 0x0002 |
75 | CmdTx = 0x0004 |
77 | CmdTx = 0x0004 |
76 | CmdTxFlex = 0x0008 |
78 | CmdTxFlex = 0x0008 |
77 | Cmdsuspend = 0x4000 |
79 | Cmdsuspend = 0x4000 |
78 | 80 | ||
79 | CmdRxFlex = 0x0008 |
81 | CmdRxFlex = 0x0008 |
80 | 82 | ||
81 | reg_scb_status = 0 |
83 | reg_scb_status = 0 |
82 | reg_scb_cmd = 2 |
84 | reg_scb_cmd = 2 |
83 | reg_scb_ptr = 4 |
85 | reg_scb_ptr = 4 |
84 | reg_port = 8 |
86 | reg_port = 8 |
85 | reg_eeprom = 14 |
87 | reg_eeprom = 14 |
86 | reg_mdi_ctrl = 16 |
88 | reg_mdi_ctrl = 16 |
87 | 89 | ||
88 | phy_100a = 0x000003E0 |
90 | phy_100a = 0x000003E0 |
89 | phy_100c = 0x035002A8 |
91 | phy_100c = 0x035002A8 |
90 | phy_82555_tx = 0x015002A8 |
92 | phy_82555_tx = 0x015002A8 |
91 | phy_nsc_tx = 0x5C002000 |
93 | phy_nsc_tx = 0x5C002000 |
92 | phy_82562_et = 0x033002A8 |
94 | phy_82562_et = 0x033002A8 |
93 | phy_82562_em = 0x032002A8 |
95 | phy_82562_em = 0x032002A8 |
94 | phy_82562_ek = 0x031002A8 |
96 | phy_82562_ek = 0x031002A8 |
95 | phy_82562_eh = 0x017002A8 |
97 | phy_82562_eh = 0x017002A8 |
96 | phy_82552_v = 0xd061004d |
98 | phy_82552_v = 0xd061004d |
97 | phy_unknown = 0xFFFFFFFF |
99 | phy_unknown = 0xFFFFFFFF |
98 | 100 | ||
99 | mac_82557_D100_A = 0 |
101 | mac_82557_D100_A = 0 |
100 | mac_82557_D100_B = 1 |
102 | mac_82557_D100_B = 1 |
101 | mac_82557_D100_C = 2 |
103 | mac_82557_D100_C = 2 |
102 | mac_82558_D101_A4 = 4 |
104 | mac_82558_D101_A4 = 4 |
103 | mac_82558_D101_B0 = 5 |
105 | mac_82558_D101_B0 = 5 |
104 | mac_82559_D101M = 8 |
106 | mac_82559_D101M = 8 |
105 | mac_82559_D101S = 9 |
107 | mac_82559_D101S = 9 |
106 | mac_82550_D102 = 12 |
108 | mac_82550_D102 = 12 |
107 | mac_82550_D102_C = 13 |
109 | mac_82550_D102_C = 13 |
108 | mac_82551_E = 14 |
110 | mac_82551_E = 14 |
109 | mac_82551_F = 15 |
111 | mac_82551_F = 15 |
110 | mac_82551_10 = 16 |
112 | mac_82551_10 = 16 |
111 | mac_unknown = 0xFF |
113 | mac_unknown = 0xFF |
112 | 114 | ||
113 | struct rxfd |
115 | struct rxfd |
114 | 116 | ||
115 | status dw ? |
117 | status dw ? |
116 | command dw ? |
118 | command dw ? |
117 | link dd ? |
119 | link dd ? |
118 | rx_buf_addr dd ? |
120 | rx_buf_addr dd ? |
119 | count dw ? |
121 | count dw ? |
120 | size dw ? |
122 | size dw ? |
121 | packet rb 1500 |
123 | packet rb 1500 |
122 | 124 | ||
123 | ends |
125 | ends |
124 | 126 | ||
125 | struc txfd { |
127 | struct txfd |
126 | 128 | ||
127 | .status dw ? |
129 | status dw ? |
128 | .command dw ? |
130 | command dw ? |
129 | .link dd ? |
131 | link dd ? |
130 | .desc_addr dd ? |
132 | desc_addr dd ? |
131 | .count dd ? |
133 | count dd ? |
- | 134 | ||
- | 135 | buf_addr dd ? |
|
132 | 136 | buf_size dd ? |
|
133 | .buf_addr0 dd ? |
137 | virt_addr dd ? |
134 | .buf_size0 dd ? |
138 | dd ? ; alignment |
135 | 139 | ||
136 | } |
140 | ends |
137 | 141 | ||
138 | struc confcmd { |
142 | struc confcmd { |
139 | 143 | ||
140 | .status dw ? |
144 | .status dw ? |
141 | .command dw ? |
145 | .command dw ? |
142 | .link dd ? |
146 | .link dd ? |
143 | .data rb 64 |
147 | .data rb 64 |
144 | 148 | ||
145 | } |
149 | } |
146 | 150 | ||
147 | struc lstats { |
151 | struc lstats { |
148 | 152 | ||
149 | .tx_good_frames dd ? |
153 | .tx_good_frames dd ? |
150 | .tx_coll16_errs dd ? |
154 | .tx_coll16_errs dd ? |
151 | .tx_late_colls dd ? |
155 | .tx_late_colls dd ? |
152 | .tx_underruns dd ? |
156 | .tx_underruns dd ? |
153 | .tx_lost_carrier dd ? |
157 | .tx_lost_carrier dd ? |
154 | .tx_deferred dd ? |
158 | .tx_deferred dd ? |
155 | .tx_one_colls dd ? |
159 | .tx_one_colls dd ? |
156 | .tx_multi_colls dd ? |
160 | .tx_multi_colls dd ? |
157 | .tx_total_colls dd ? |
161 | .tx_total_colls dd ? |
158 | 162 | ||
159 | .rx_good_frames dd ? |
163 | .rx_good_frames dd ? |
160 | .rx_crc_errs dd ? |
164 | .rx_crc_errs dd ? |
161 | .rx_align_errs dd ? |
165 | .rx_align_errs dd ? |
162 | .rx_resource_errs dd ? |
166 | .rx_resource_errs dd ? |
163 | .rx_overrun_errs dd ? |
167 | .rx_overrun_errs dd ? |
164 | .rx_colls_errs dd ? |
168 | .rx_colls_errs dd ? |
165 | .rx_runt_errs dd ? |
169 | .rx_runt_errs dd ? |
166 | 170 | ||
167 | } |
171 | } |
168 | 172 | ||
169 | struct device ETH_DEVICE |
173 | struct device ETH_DEVICE |
170 | 174 | ||
171 | io_addr dd ? |
175 | io_addr dd ? |
172 | pci_bus dd ? |
176 | pci_bus dd ? |
173 | pci_dev dd ? |
177 | pci_dev dd ? |
174 | rx_desc dd ? |
178 | rx_desc dd ? |
- | 179 | cur_tx dd ? |
|
175 | last_tx_buffer dd ? |
180 | last_tx dd ? |
176 | ee_bus_width db ? |
181 | ee_bus_width db ? |
177 | irq_line db ? |
182 | irq_line db ? |
178 | 183 | ||
179 | rb 0x100 - ($ and 0xff) ; align 256 |
184 | rb 0x100 - ($ and 0xff) ; align 256 |
180 | txfd txfd |
185 | tx_ring rb TX_RING_SIZE*sizeof.txfd |
181 | 186 | ||
182 | rb 0x100 - ($ and 0xff) ; align 256 |
187 | rb 0x100 - ($ and 0xff) ; align 256 |
183 | confcmd confcmd |
188 | confcmd confcmd |
184 | 189 | ||
185 | rb 0x100 - ($ and 0xff) ; align 256 |
190 | rb 0x100 - ($ and 0xff) ; align 256 |
186 | lstats lstats |
191 | lstats lstats |
187 | 192 | ||
188 | ends |
193 | ends |
189 | 194 | ||
190 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
195 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
191 | ;; ;; |
196 | ;; ;; |
192 | ;; proc START ;; |
197 | ;; proc START ;; |
193 | ;; ;; |
198 | ;; ;; |
194 | ;; (standard driver proc) ;; |
199 | ;; (standard driver proc) ;; |
195 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
200 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
196 | 201 | ||
197 | proc START c, state:dword |
202 | proc START c, state:dword |
198 | 203 | ||
199 | cmp [state], 1 |
204 | cmp [state], 1 |
200 | jne .exit |
205 | jne .exit |
201 | 206 | ||
202 | .entry: |
207 | .entry: |
203 | 208 | ||
204 | DEBUGF 1,"Loading driver\n" |
209 | DEBUGF 1,"Loading driver\n" |
205 | invoke RegService, my_service, service_proc |
210 | invoke RegService, my_service, service_proc |
206 | ret |
211 | ret |
207 | 212 | ||
208 | .fail: |
213 | .fail: |
209 | .exit: |
214 | .exit: |
210 | xor eax, eax |
215 | xor eax, eax |
211 | ret |
216 | ret |
212 | 217 | ||
213 | endp |
218 | endp |
214 | 219 | ||
215 | 220 | ||
216 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
221 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
217 | ;; ;; |
222 | ;; ;; |
218 | ;; proc SERVICE_PROC ;; |
223 | ;; proc SERVICE_PROC ;; |
219 | ;; ;; |
224 | ;; ;; |
220 | ;; (standard driver proc) ;; |
225 | ;; (standard driver proc) ;; |
221 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
226 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
222 | 227 | ||
223 | align 4 |
228 | align 4 |
224 | proc service_proc stdcall, ioctl:dword |
229 | proc service_proc stdcall, ioctl:dword |
225 | 230 | ||
226 | mov edx, [ioctl] |
231 | mov edx, [ioctl] |
227 | mov eax, [edx + IOCTL.io_code] |
232 | mov eax, [edx + IOCTL.io_code] |
228 | 233 | ||
229 | ;------------------------------------------------------ |
234 | ;------------------------------------------------------ |
230 | 235 | ||
231 | cmp eax, 0 ;SRV_GETVERSION |
236 | cmp eax, 0 ;SRV_GETVERSION |
232 | jne @F |
237 | jne @F |
233 | 238 | ||
234 | cmp [edx + IOCTL.out_size], 4 |
239 | cmp [edx + IOCTL.out_size], 4 |
235 | jb .fail |
240 | jb .fail |
236 | mov eax, [edx + IOCTL.output] |
241 | mov eax, [edx + IOCTL.output] |
237 | mov [eax], dword API_VERSION |
242 | mov [eax], dword API_VERSION |
238 | 243 | ||
239 | xor eax, eax |
244 | xor eax, eax |
240 | ret |
245 | ret |
241 | 246 | ||
242 | ;------------------------------------------------------ |
247 | ;------------------------------------------------------ |
243 | @@: |
248 | @@: |
244 | cmp eax, 1 ;SRV_HOOK |
249 | cmp eax, 1 ;SRV_HOOK |
245 | jne .fail |
250 | jne .fail |
246 | 251 | ||
247 | cmp [edx + IOCTL.inp_size], 3 ; Data input must be at least 3 bytes |
252 | cmp [edx + IOCTL.inp_size], 3 ; Data input must be at least 3 bytes |
248 | jb .fail |
253 | jb .fail |
249 | 254 | ||
250 | mov eax, [edx + IOCTL.input] |
255 | mov eax, [edx + IOCTL.input] |
251 | cmp byte [eax], 1 ; 1 means device number and bus number (pci) are given |
256 | cmp byte [eax], 1 ; 1 means device number and bus number (pci) are given |
252 | jne .fail ; other types arent supported for this card yet |
257 | jne .fail ; other types arent supported for this card yet |
253 | 258 | ||
254 | ; check if the device is already listed |
259 | ; check if the device is already listed |
255 | 260 | ||
256 | mov esi, device_list |
261 | mov esi, device_list |
257 | mov ecx, [devices] |
262 | mov ecx, [devices] |
258 | test ecx, ecx |
263 | test ecx, ecx |
259 | jz .firstdevice |
264 | jz .firstdevice |
260 | 265 | ||
261 | ; mov eax, [edx + IOCTL.input] ; get the pci bus and device numbers |
266 | ; mov eax, [edx + IOCTL.input] ; get the pci bus and device numbers |
262 | mov ax , [eax+1] ; |
267 | mov ax , [eax+1] ; |
263 | .nextdevice: |
268 | .nextdevice: |
264 | mov ebx, [esi] |
269 | mov ebx, [esi] |
265 | cmp al, byte[ebx + device.pci_bus] |
270 | cmp al, byte[ebx + device.pci_bus] |
266 | jne @f |
271 | jne @f |
267 | cmp ah, byte[ebx + device.pci_dev] |
272 | cmp ah, byte[ebx + device.pci_dev] |
268 | je .find_devicenum ; Device is already loaded, let's find it's device number |
273 | je .find_devicenum ; Device is already loaded, let's find it's device number |
269 | @@: |
274 | @@: |
270 | add esi, 4 |
275 | add esi, 4 |
271 | loop .nextdevice |
276 | loop .nextdevice |
272 | 277 | ||
273 | 278 | ||
274 | ; This device doesnt have its own eth_device structure yet, lets create one |
279 | ; This device doesnt have its own eth_device structure yet, lets create one |
275 | .firstdevice: |
280 | .firstdevice: |
276 | cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card |
281 | cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card |
277 | jae .fail |
282 | jae .fail |
278 | 283 | ||
279 | allocate_and_clear ebx, sizeof.device, .fail ; Allocate the buffer for device structure |
284 | allocate_and_clear ebx, sizeof.device, .fail ; Allocate the buffer for device structure |
280 | 285 | ||
281 | ; Fill in the direct call addresses into the struct |
286 | ; Fill in the direct call addresses into the struct |
282 | 287 | ||
283 | mov [ebx + device.reset], reset |
288 | mov [ebx + device.reset], reset |
284 | mov [ebx + device.transmit], transmit |
289 | mov [ebx + device.transmit], transmit |
285 | mov [ebx + device.unload], unload |
290 | mov [ebx + device.unload], unload |
286 | mov [ebx + device.name], my_service |
291 | mov [ebx + device.name], my_service |
287 | 292 | ||
288 | ; save the pci bus and device numbers |
293 | ; save the pci bus and device numbers |
289 | 294 | ||
290 | mov eax, [edx + IOCTL.input] |
295 | mov eax, [edx + IOCTL.input] |
291 | movzx ecx, byte[eax+1] |
296 | movzx ecx, byte[eax+1] |
292 | mov [ebx + device.pci_bus], ecx |
297 | mov [ebx + device.pci_bus], ecx |
293 | movzx ecx, byte[eax+2] |
298 | movzx ecx, byte[eax+2] |
294 | mov [ebx + device.pci_dev], ecx |
299 | mov [ebx + device.pci_dev], ecx |
295 | 300 | ||
296 | ; Now, it's time to find the base io addres of the PCI device |
301 | ; Now, it's time to find the base io addres of the PCI device |
297 | 302 | ||
298 | stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev] |
303 | stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev] |
299 | mov [ebx + device.io_addr], eax |
304 | mov [ebx + device.io_addr], eax |
300 | 305 | ||
301 | ; We've found the io address, find IRQ now |
306 | ; We've found the io address, find IRQ now |
302 | 307 | ||
303 | invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line |
308 | invoke PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line |
304 | mov [ebx + device.irq_line], al |
309 | mov [ebx + device.irq_line], al |
305 | 310 | ||
306 | DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ |
311 | DEBUGF 1,"Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ |
307 | [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4 |
312 | [ebx + device.pci_dev]:1,[ebx + device.pci_bus]:1,[ebx + device.irq_line]:1,[ebx + device.io_addr]:4 |
308 | 313 | ||
309 | ; Ok, the eth_device structure is ready, let's probe the device |
314 | ; Ok, the eth_device structure is ready, let's probe the device |
310 | 315 | ||
311 | pushf |
316 | pushf |
312 | cli ; disable ints untilm initialisation is done |
317 | cli ; disable ints untilm initialisation is done |
313 | 318 | ||
314 | call probe ; this function will output in eax |
319 | call probe ; this function will output in eax |
315 | test eax, eax |
320 | test eax, eax |
316 | jnz .err ; If an error occured, exit |
321 | jnz .err ; If an error occured, exit |
317 | 322 | ||
318 | mov eax, [devices] ; Add the device structure to our device list |
323 | mov eax, [devices] ; Add the device structure to our device list |
319 | mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device) |
324 | mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device) |
320 | inc [devices] ; |
325 | inc [devices] ; |
321 | 326 | ||
322 | popf |
327 | popf |
323 | 328 | ||
324 | mov [ebx + device.type], NET_TYPE_ETH |
329 | mov [ebx + device.type], NET_TYPE_ETH |
325 | invoke NetRegDev |
330 | invoke NetRegDev |
326 | 331 | ||
327 | cmp eax, -1 |
332 | cmp eax, -1 |
328 | je .err |
333 | je .err |
329 | 334 | ||
330 | ret |
335 | ret |
331 | 336 | ||
332 | ; If the device was already loaded, find the device number and return it in eax |
337 | ; If the device was already loaded, find the device number and return it in eax |
333 | 338 | ||
334 | .find_devicenum: |
339 | .find_devicenum: |
335 | DEBUGF 2,"Trying to find device number of already registered device\n" |
340 | DEBUGF 2,"Trying to find device number of already registered device\n" |
336 | invoke NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx |
341 | invoke NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx |
337 | ; into a device number in edi |
342 | ; into a device number in edi |
338 | mov eax, edi ; Application wants it in eax instead |
343 | mov eax, edi ; Application wants it in eax instead |
339 | DEBUGF 2,"Kernel says: %u\n", eax |
344 | DEBUGF 2,"Kernel says: %u\n", eax |
340 | ret |
345 | ret |
341 | 346 | ||
342 | ; If an error occured, remove all allocated data and exit (returning -1 in eax) |
347 | ; If an error occured, remove all allocated data and exit (returning -1 in eax) |
343 | 348 | ||
344 | .err: |
349 | .err: |
345 | invoke KernelFree, ebx |
350 | invoke KernelFree, ebx |
346 | 351 | ||
347 | .fail: |
352 | .fail: |
348 | or eax, -1 |
353 | or eax, -1 |
349 | ret |
354 | ret |
350 | 355 | ||
351 | ;------------------------------------------------------ |
356 | ;------------------------------------------------------ |
352 | endp |
357 | endp |
353 | 358 | ||
354 | 359 | ||
355 | 360 | ||
356 | 361 | ||
357 | 362 | ||
358 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
363 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
359 | ;; ;; |
364 | ;; ;; |
360 | ;; Actual Hardware dependent code starts here ;; |
365 | ;; Actual Hardware dependent code starts here ;; |
361 | ;; ;; |
366 | ;; ;; |
362 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
367 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
363 | 368 | ||
364 | 369 | ||
365 | unload: |
370 | unload: |
366 | ; TODO: (in this particular order) |
371 | ; TODO: (in this particular order) |
367 | ; |
372 | ; |
368 | ; - Stop the device |
373 | ; - Stop the device |
369 | ; - Detach int handler |
374 | ; - Detach int handler |
370 | ; - Remove device from local list (device_list) |
375 | ; - Remove device from local list (device_list) |
371 | ; - call unregister function in kernel |
376 | ; - call unregister function in kernel |
372 | ; - Remove all allocated structures and buffers the card used |
377 | ; - Remove all allocated structures and buffers the card used |
373 | 378 | ||
374 | or eax,-1 |
379 | or eax,-1 |
375 | 380 | ||
376 | ret |
381 | ret |
377 | 382 | ||
378 | 383 | ||
379 | ;------------- |
384 | ;------------- |
380 | ; |
385 | ; |
381 | ; Probe |
386 | ; Probe |
382 | ; |
387 | ; |
383 | ;------------- |
388 | ;------------- |
384 | 389 | ||
385 | align 4 |
390 | align 4 |
386 | probe: |
391 | probe: |
387 | 392 | ||
388 | DEBUGF 1,"Probing\n" |
393 | DEBUGF 1,"Probing\n" |
389 | 394 | ||
390 | ; Make the device a bus master |
395 | ; Make the device a bus master |
391 | invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command |
396 | invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command |
392 | or al, PCI_CMD_MASTER |
397 | or al, PCI_CMD_MASTER |
393 | invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax |
398 | invoke PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax |
394 | 399 | ||
395 | ;--------------------------- |
400 | ;--------------------------- |
396 | ; First, identify the device |
401 | ; First, identify the device |
397 | 402 | ||
398 | invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.vendor_id ; get device/vendor id |
403 | invoke PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header.vendor_id ; get device/vendor id |
399 | 404 | ||
400 | DEBUGF 1,"Vendor_id=0x%x\n", ax |
405 | DEBUGF 1,"Vendor_id=0x%x\n", ax |
401 | 406 | ||
402 | cmp ax, 0x8086 |
407 | cmp ax, 0x8086 |
403 | jne .notfound |
408 | jne .notfound |
404 | shr eax, 16 |
409 | shr eax, 16 |
405 | 410 | ||
406 | DEBUGF 1,"Device_id=0x%x\n", ax |
411 | DEBUGF 1,"Device_id=0x%x\n", ax |
407 | 412 | ||
408 | mov ecx, DEVICE_IDs |
413 | mov ecx, DEVICE_IDs |
409 | mov edi, device_id_list |
414 | mov edi, device_id_list |
410 | repne scasw |
415 | repne scasw |
411 | jne .notfound |
416 | jne .notfound |
412 | jmp .found |
417 | jmp .found |
413 | 418 | ||
414 | .notfound: |
419 | .notfound: |
415 | DEBUGF 2,"Unsupported device!\n" |
420 | DEBUGF 2,"Unsupported device!\n" |
416 | or eax, -1 |
421 | or eax, -1 |
417 | ret |
422 | ret |
418 | 423 | ||
419 | .found: |
424 | .found: |
420 | 425 | ||
421 | call ee_get_width |
426 | call ee_get_width |
422 | call MAC_read_eeprom |
427 | call MAC_read_eeprom |
423 | 428 | ||
424 | ;;; TODO: detect phy |
429 | ;;; TODO: detect phy |
425 | 430 | ||
426 | 431 | ||
427 | 432 | ||
428 | ;---------- |
433 | ;---------- |
429 | ; |
434 | ; |
430 | ; Reset |
435 | ; Reset |
431 | ; |
436 | ; |
432 | ;---------- |
437 | ;---------- |
433 | 438 | ||
434 | align 4 |
439 | align 4 |
435 | reset: |
440 | reset: |
436 | 441 | ||
437 | movzx eax, [ebx + device.irq_line] |
442 | movzx eax, [ebx + device.irq_line] |
438 | DEBUGF 1,"Attaching int handler to irq %x\n", eax:1 |
443 | DEBUGF 1,"Attaching int handler to irq %x\n", eax:1 |
439 | invoke AttachIntHandler, eax, int_handler, ebx |
444 | invoke AttachIntHandler, eax, int_handler, ebx |
440 | test eax, eax |
445 | test eax, eax |
441 | jnz @f |
446 | jnz @f |
442 | DEBUGF 2,"Could not attach int handler!\n" |
447 | DEBUGF 2,"Could not attach int handler!\n" |
443 | or eax, -1 |
448 | or eax, -1 |
444 | ret |
449 | ret |
445 | @@: |
450 | @@: |
446 | 451 | ||
447 | DEBUGF 1,"Resetting\n" |
452 | DEBUGF 1,"Resetting\n" |
448 | 453 | ||
449 | ;--------------- |
454 | ;--------------- |
450 | ; reset the card |
455 | ; reset the card |
451 | 456 | ||
452 | set_io [ebx + device.io_addr], 0 |
457 | set_io [ebx + device.io_addr], 0 |
453 | set_io [ebx + device.io_addr], reg_port |
458 | set_io [ebx + device.io_addr], reg_port |
454 | xor eax, eax ; Software Reset |
459 | xor eax, eax ; Software Reset |
455 | out dx, eax |
460 | out dx, eax |
456 | 461 | ||
457 | mov esi, 10 |
462 | mov esi, 10 |
458 | invoke Sleep ; Give the card time to warm up. |
463 | invoke Sleep ; Give the card time to warm up. |
459 | 464 | ||
460 | ;--------------------------------- |
465 | ;--------------------------------- |
461 | ; Tell device where to store stats |
466 | ; Tell device where to store stats |
462 | 467 | ||
463 | lea eax, [ebx + device.lstats.tx_good_frames] ; lstats |
468 | lea eax, [ebx + device.lstats.tx_good_frames] ; lstats |
464 | invoke GetPhysAddr |
469 | invoke GetPhysAddr |
465 | set_io [ebx + device.io_addr], 0 |
470 | set_io [ebx + device.io_addr], 0 |
466 | set_io [ebx + device.io_addr], reg_scb_ptr |
471 | set_io [ebx + device.io_addr], reg_scb_ptr |
467 | out dx, eax |
472 | out dx, eax |
468 | - | ||
469 | mov ax, INT_MASK + CU_STATSADDR |
473 | |
- | 474 | set_io [ebx + device.io_addr], reg_scb_cmd |
|
470 | set_io [ebx + device.io_addr], reg_scb_cmd |
475 | mov ax, CU_STATSADDR or INT_MASK |
471 | out dx, ax |
476 | out dx, ax |
472 | call cmd_wait |
477 | call cmd_wait |
473 | 478 | ||
474 | ;----------------- |
479 | ;------------------------ |
475 | ; setup RX |
480 | ; setup RX base addr to 0 |
476 | 481 | ||
477 | set_io [ebx + device.io_addr], reg_scb_ptr |
482 | set_io [ebx + device.io_addr], reg_scb_ptr |
478 | xor eax, eax |
483 | xor eax, eax |
479 | out dx, eax |
484 | out dx, eax |
480 | 485 | ||
481 | set_io [ebx + device.io_addr], reg_scb_cmd |
486 | set_io [ebx + device.io_addr], reg_scb_cmd |
482 | mov ax, INT_MASK + RX_ADDR_LOAD |
487 | mov ax, RX_ADDR_LOAD or INT_MASK |
483 | out dx, ax |
488 | out dx, ax |
484 | call cmd_wait |
489 | call cmd_wait |
485 | 490 | ||
486 | ;----------------------------- |
491 | ;----------------------------- |
487 | ; Create RX and TX descriptors |
492 | ; Create RX and TX descriptors |
488 | 493 | ||
489 | call create_ring |
494 | call init_rx_ring |
490 | test eax, eax |
495 | test eax, eax |
491 | jz .error |
496 | jz .error |
- | 497 | ||
- | 498 | call init_tx_ring |
|
- | 499 | ||
- | 500 | ||
492 | 501 | ;--------- |
|
- | 502 | ; Start RX |
|
- | 503 | ||
493 | ; RX start |
504 | DEBUGF 1, "Starting RX" |
494 | 505 | ||
495 | set_io [ebx + device.io_addr], 0 |
506 | set_io [ebx + device.io_addr], 0 |
496 | set_io [ebx + device.io_addr], reg_scb_ptr |
507 | set_io [ebx + device.io_addr], reg_scb_ptr |
497 | mov eax, [ebx + device.rx_desc] |
508 | mov eax, [ebx + device.rx_desc] |
498 | invoke GetPhysAddr |
509 | invoke GetPhysAddr |
499 | add eax, NET_BUFF.data |
510 | add eax, NET_BUFF.data |
500 | out dx, eax |
511 | out dx, eax |
501 | - | ||
502 | mov ax, INT_MASK + RX_START |
512 | |
- | 513 | set_io [ebx + device.io_addr], reg_scb_cmd |
|
503 | set_io [ebx + device.io_addr], reg_scb_cmd |
514 | mov ax, RX_START or INT_MASK |
504 | out dx, ax |
515 | out dx, ax |
505 | call cmd_wait |
516 | call cmd_wait |
- | 517 | ||
506 | 518 | ;---------- |
|
507 | ; Set-up TX |
519 | ; Set-up TX |
508 | 520 | ||
509 | set_io [ebx + device.io_addr], reg_scb_ptr |
521 | set_io [ebx + device.io_addr], reg_scb_ptr |
510 | xor eax, eax |
522 | xor eax, eax |
511 | out dx, eax |
523 | out dx, eax |
512 | 524 | ||
513 | set_io [ebx + device.io_addr], reg_scb_cmd |
525 | set_io [ebx + device.io_addr], reg_scb_cmd |
- | 526 | mov ax, CU_CMD_BASE or INT_MASK |
|
- | 527 | out dx, ax |
|
- | 528 | call cmd_wait |
|
- | 529 | ||
- | 530 | ;------------------------- |
|
- | 531 | ; Individual address setup |
|
- | 532 | ||
- | 533 | mov [ebx + device.confcmd.command], CmdIASetup + Cmdsuspend |
|
- | 534 | mov [ebx + device.confcmd.status], 0 |
|
- | 535 | lea eax, [ebx + device.tx_ring] |
|
- | 536 | invoke GetPhysAddr |
|
- | 537 | mov [ebx + device.confcmd.link], eax |
|
- | 538 | lea edi, [ebx + device.confcmd.data] |
|
- | 539 | lea esi, [ebx + device.mac] |
|
- | 540 | movsd |
|
- | 541 | movsw |
|
- | 542 | ||
- | 543 | set_io [ebx + device.io_addr], reg_scb_ptr |
|
- | 544 | lea eax, [ebx + device.confcmd.status] |
|
- | 545 | invoke GetPhysAddr |
|
- | 546 | out dx, eax |
|
- | 547 | ||
- | 548 | set_io [ebx + device.io_addr], reg_scb_cmd |
|
514 | mov ax, INT_MASK + CU_CMD_BASE |
549 | mov ax, CU_START or INT_MASK |
515 | out dx, ax |
550 | out dx, ax |
516 | call cmd_wait |
551 | call cmd_wait |
517 | 552 | ||
- | 553 | ;------------- |
|
518 | ; -------------------- |
554 | ; Configure CU |
519 | 555 | ||
520 | mov [ebx + device.confcmd.command], CmdConfigure + Cmdsuspend |
556 | mov [ebx + device.confcmd.command], CmdConfigure + Cmdsuspend |
521 | mov [ebx + device.confcmd.status], 0 |
557 | mov [ebx + device.confcmd.status], 0 |
522 | lea eax, [ebx + device.txfd.status] |
558 | lea eax, [ebx + device.confcmd.status] |
523 | invoke GetPhysAddr |
559 | invoke GetPhysAddr |
524 | mov [ebx + device.confcmd.link], eax |
560 | mov [ebx + device.confcmd.link], eax |
525 | 561 | ||
526 | mov esi, confcmd_data |
562 | mov esi, confcmd_data |
527 | lea edi, [ebx + device.confcmd.data] |
563 | lea edi, [ebx + device.confcmd.data] |
528 | mov ecx, 22 |
564 | mov ecx, 22 |
529 | rep movsb |
565 | rep movsb |
530 | 566 | ||
531 | mov byte[ebx + device.confcmd.data + 1], 0x88 ; fifo of 8 each |
567 | mov byte[ebx + device.confcmd.data + 1], 0x88 ; fifo of 8 each |
532 | mov byte[ebx + device.confcmd.data + 4], 0 |
568 | mov byte[ebx + device.confcmd.data + 4], 0 |
533 | mov byte[ebx + device.confcmd.data + 5], 0x80 |
569 | mov byte[ebx + device.confcmd.data + 5], 0x80 |
534 | mov byte[ebx + device.confcmd.data + 15], 0x48 |
570 | mov byte[ebx + device.confcmd.data + 15], 0x48 |
535 | mov byte[ebx + device.confcmd.data + 19], 0x80 |
571 | mov byte[ebx + device.confcmd.data + 19], 0x80 |
536 | mov byte[ebx + device.confcmd.data + 21], 0x05 |
572 | mov byte[ebx + device.confcmd.data + 21], 0x05 |
537 | - | ||
538 | mov [ebx + device.txfd.command], CmdIASetup |
- | |
539 | mov [ebx + device.txfd.status], 0 |
- | |
540 | lea eax, [ebx + device.confcmd.status] |
- | |
541 | invoke GetPhysAddr |
- | |
542 | mov [ebx + device.txfd.link], eax |
- | |
543 | - | ||
544 | ;;; copy in our MAC |
- | |
545 | - | ||
546 | lea edi, [ebx + device.txfd.desc_addr] |
- | |
547 | lea esi, [ebx + device.mac] |
- | |
548 | movsd |
- | |
549 | movsw |
- | |
550 | 573 | ||
551 | set_io [ebx + device.io_addr], reg_scb_ptr |
574 | set_io [ebx + device.io_addr], reg_scb_ptr |
552 | lea eax, [ebx + device.txfd.status] |
575 | lea eax, [ebx + device.confcmd.status] |
553 | invoke GetPhysAddr |
576 | invoke GetPhysAddr |
554 | out dx, eax |
577 | out dx, eax |
555 | - | ||
556 | ; Start CU & enable ints |
- | |
557 | 578 | ||
558 | set_io [ebx + device.io_addr], reg_scb_cmd |
579 | set_io [ebx + device.io_addr], reg_scb_cmd |
559 | mov ax, CU_START |
580 | mov ax, CU_START ; expect Interrupts from now on |
560 | out dx, ax |
581 | out dx, ax |
561 | call cmd_wait |
582 | call cmd_wait |
562 | - | ||
563 | ;----------------------- |
- | |
564 | ; build txfd structure (again!) |
- | |
565 | - | ||
566 | lea eax, [ebx + device.txfd.status] |
- | |
567 | invoke GetPhysAddr |
- | |
568 | mov [ebx + device.txfd.link], eax |
- | |
569 | mov [ebx + device.txfd.count], 0x02208000 |
- | |
570 | lea eax, [ebx + device.txfd.buf_addr0] |
- | |
571 | invoke GetPhysAddr |
- | |
572 | mov [ebx + device.txfd.desc_addr], eax |
- | |
573 | - | ||
574 | ; Indicate that we have successfully reset the card |
- | |
575 | 583 | ||
576 | DEBUGF 1,"Reset complete\n" |
- | |
577 | 584 | DEBUGF 1,"Reset complete\n" |
|
578 | mov [ebx + device.mtu], 1514 |
585 | mov [ebx + device.mtu], 1514 |
579 | 586 | ||
580 | ; Set link state to unknown |
587 | ; Set link state to unknown |
581 | mov [ebx + device.state], ETH_LINK_UNKNOWN |
588 | mov [ebx + device.state], ETH_LINK_UNKNOWN |
582 | 589 | ||
583 | xor eax, eax ; indicate that we have successfully reset the card |
590 | xor eax, eax ; indicate that we have successfully reset the card |
584 | ret |
591 | ret |
585 | 592 | ||
586 | .error: |
593 | .error: |
587 | or eax, -1 |
594 | or eax, -1 |
588 | ret |
595 | ret |
589 | 596 | ||
590 | 597 | ||
591 | align 4 |
598 | align 4 |
592 | create_ring: |
599 | init_rx_ring: |
593 | 600 | ||
594 | DEBUGF 1,"Creating ring\n" |
601 | DEBUGF 1,"Creating ring\n" |
595 | 602 | ||
596 | ;--------------------- |
603 | ;--------------------- |
597 | ; build rxfd structure |
604 | ; build rxfd structure |
598 | 605 | ||
599 | invoke NetAlloc, 2000 |
606 | invoke NetAlloc, 2000 |
600 | test eax, eax |
607 | test eax, eax |
601 | jz .out_of_mem |
608 | jz .out_of_mem |
602 | mov [ebx + device.rx_desc], eax |
609 | mov [ebx + device.rx_desc], eax |
603 | mov esi, eax |
610 | mov esi, eax |
604 | invoke GetPhysAddr |
611 | invoke GetPhysAddr |
605 | add eax, NET_BUFF.data |
612 | add eax, NET_BUFF.data |
606 | mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000 |
613 | mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000 |
607 | mov [esi + sizeof.NET_BUFF + rxfd.command], 0x0000 |
614 | mov [esi + sizeof.NET_BUFF + rxfd.command], 0x0000 |
608 | mov [esi + sizeof.NET_BUFF + rxfd.link], eax |
615 | mov [esi + sizeof.NET_BUFF + rxfd.link], eax |
609 | mov [esi + sizeof.NET_BUFF + rxfd.count], 0 |
616 | mov [esi + sizeof.NET_BUFF + rxfd.count], 0 |
610 | mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 |
617 | mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 |
- | 618 | ||
- | 619 | ret |
|
611 | 620 | ||
- | 621 | .out_of_mem: |
|
612 | ;----------------------- |
622 | |
- | 623 | ret |
|
- | 624 | ||
- | 625 | ||
- | 626 | ||
- | 627 | ||
- | 628 | align 4 |
|
- | 629 | init_tx_ring: |
|
- | 630 | ||
613 | ; build txfd structure |
631 | DEBUGF 1,"Creating TX ring\n" |
- | 632 | ||
614 | 633 | lea esi, [ebx + device.tx_ring] |
|
- | 634 | mov eax, esi |
|
- | 635 | invoke GetPhysAddr |
|
615 | lea eax, [ebx + device.txfd.status] |
636 | mov ecx, TX_RING_SIZE |
616 | invoke GetPhysAddr |
637 | .next_desc: |
617 | mov [ebx + device.txfd.link], eax |
638 | mov [esi + txfd.status], 0 |
- | 639 | mov [esi + txfd.command], 0 |
|
- | 640 | lea edx, [eax + txfd.buf_addr] |
|
- | 641 | mov [esi + txfd.desc_addr], edx |
|
- | 642 | add eax, sizeof.txfd |
|
- | 643 | mov [esi + txfd.link], eax |
|
- | 644 | mov [esi + txfd.count], 0x01208000 ; One buffer, 0x20 bytes of transmit threshold, end of frame |
|
- | 645 | add esi, sizeof.txfd |
|
- | 646 | dec ecx |
|
- | 647 | jnz .next_desc |
|
618 | mov [ebx + device.txfd.count], 0x01208000 |
648 | |
619 | lea eax, [ebx + device.txfd.buf_addr0] |
649 | lea eax, [ebx + device.tx_ring] |
620 | invoke GetPhysAddr |
650 | invoke GetPhysAddr |
- | 651 | mov dword[ebx + device.tx_ring + sizeof.txfd*(TX_RING_SIZE-1) + txfd.link], eax |
|
621 | mov [ebx + device.txfd.desc_addr], eax |
652 | |
622 | 653 | mov [ebx + device.cur_tx], 0 |
|
623 | .out_of_mem: |
654 | mov [ebx + device.last_tx], 0 |
624 | 655 | ||
625 | ret |
656 | ret |
626 | 657 | ||
627 | - | ||
628 | 658 | ||
629 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
659 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
630 | ;; ;; |
660 | ;; ;; |
631 | ;; Transmit ;; |
661 | ;; Transmit ;; |
632 | ;; ;; |
662 | ;; ;; |
633 | ;; In: pointer to device structure in ebx ;; |
663 | ;; In: pointer to device structure in ebx ;; |
634 | ;; ;; |
664 | ;; ;; |
635 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
665 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
636 | 666 | ||
637 | proc transmit stdcall bufferptr |
667 | proc transmit stdcall bufferptr |
638 | 668 | ||
639 | pushf |
669 | pushf |
640 | cli |
670 | cli |
641 | 671 | ||
642 | mov esi, [bufferptr] |
672 | mov esi, [bufferptr] |
643 | DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
673 | DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
644 | lea eax, [esi + NET_BUFF.data] |
674 | lea eax, [esi + NET_BUFF.data] |
645 | DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ |
675 | DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ |
646 | [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ |
676 | [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ |
647 | [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ |
677 | [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ |
648 | [eax+13]:2,[eax+12]:2 |
678 | [eax+13]:2,[eax+12]:2 |
649 | 679 | ||
650 | cmp [esi + NET_BUFF.length], 1514 |
680 | cmp [esi + NET_BUFF.length], 1514 |
651 | ja .fail |
681 | ja .fail |
652 | cmp [esi + NET_BUFF.length], 60 |
682 | cmp [esi + NET_BUFF.length], 60 |
653 | jb .fail |
683 | jb .fail |
654 | 684 | ||
655 | ;;; TODO: check if current descriptor is in use |
685 | ; Get current TX descriptor |
656 | ; fill in buffer address and size |
686 | mov edi, [ebx + device.cur_tx] |
- | 687 | mov eax, sizeof.txfd |
|
657 | mov eax, [bufferptr] |
688 | mul edi |
- | 689 | lea edi, [ebx + device.tx_ring + eax] |
|
- | 690 | ||
658 | mov [ebx + device.last_tx_buffer], eax |
691 | ; Check if current descriptor is free or still in use |
659 | add eax, [eax + NET_BUFF.offset] |
692 | cmp [edi + txfd.status], 0 |
- | 693 | jne .fail |
|
660 | invoke GetPhysAddr |
694 | |
661 | mov [ebx + device.txfd.buf_addr0], eax |
695 | ; Fill in status and command values |
662 | mov ecx, [bufferptr] |
696 | mov [edi + txfd.status], 0 |
663 | mov ecx, [ecx + NET_BUFF.length] |
697 | mov [edi + txfd.command], Cmdsuspend + CmdTx + CmdTxFlex ;;;+ 1 shl 15 ;;; EL bit |
664 | mov [ebx + device.txfd.buf_size0], ecx |
698 | mov [edi + txfd.count], 0x01208000 |
- | 699 | ||
665 | 700 | ; Fill in buffer address and size |
|
- | 701 | mov [edi + txfd.virt_addr], esi |
|
- | 702 | mov eax, esi |
|
- | 703 | add eax, [esi + NET_BUFF.offset] |
|
- | 704 | push edi |
|
- | 705 | invoke GetPhysAddr |
|
666 | mov [ebx + device.txfd.status], 0 |
706 | pop edi |
- | 707 | mov [edi + txfd.buf_addr], eax |
|
667 | mov [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex ;+ 1 shl 15 ;;; EL bit |
708 | mov ecx, [esi + NET_BUFF.length] |
668 | ; mov [txfd.count], 0x02208000 ;;;;;;;;;;; |
709 | mov [edi + txfd.buf_size], ecx |
669 | 710 | ||
670 | ; Inform device of the new/updated transmit descriptor |
711 | ; Inform device of the new/updated transmit descriptor |
671 | lea eax, [ebx + device.txfd.status] |
712 | mov eax, edi |
672 | invoke GetPhysAddr |
713 | invoke GetPhysAddr |
673 | set_io [ebx + device.io_addr], 0 |
714 | set_io [ebx + device.io_addr], 0 |
674 | set_io [ebx + device.io_addr], reg_scb_ptr |
715 | set_io [ebx + device.io_addr], reg_scb_ptr |
675 | out dx, eax |
716 | out dx, eax |
676 | 717 | ||
677 | ; Start the transmit |
718 | ; Start the transmit |
678 | mov ax, CU_START |
- | |
679 | set_io [ebx + device.io_addr], reg_scb_cmd |
719 | set_io [ebx + device.io_addr], reg_scb_cmd |
- | 720 | mov ax, CU_START |
|
680 | out dx, ax |
721 | out dx, ax |
681 | call cmd_wait |
- | |
682 | 722 | ||
683 | ; Update stats |
723 | ; Update stats |
684 | inc [ebx + device.packets_tx] |
724 | inc [ebx + device.packets_tx] |
685 | add dword[ebx + device.bytes_tx], ecx |
725 | add dword[ebx + device.bytes_tx], ecx |
686 | adc dword[ebx + device.bytes_tx + 4], 0 |
726 | adc dword[ebx + device.bytes_tx + 4], 0 |
- | 727 | ||
- | 728 | ; Wait for command to complete |
|
- | 729 | call cmd_wait |
|
- | 730 | ||
- | 731 | inc [ebx + device.cur_tx] |
|
- | 732 | and [ebx + device.cur_tx], TX_RING_SIZE - 1 |
|
687 | 733 | ||
688 | DEBUGF 1,"Transmit OK\n" |
734 | DEBUGF 1,"Transmit OK\n" |
689 | popf |
735 | popf |
690 | xor eax, eax |
736 | xor eax, eax |
691 | ret |
737 | ret |
692 | 738 | ||
693 | .fail: |
739 | .fail: |
- | 740 | DEBUGF 2,"Transmit failed!\n" |
|
694 | invoke NetFree, [bufferptr] |
741 | invoke NetFree, [bufferptr] |
695 | popf |
742 | popf |
696 | or eax, -1 |
743 | or eax, -1 |
697 | ret |
744 | ret |
698 | 745 | ||
699 | endp |
746 | endp |
700 | 747 | ||
701 | 748 | ||
702 | ;;;;;;;;;;;;;;;;;;;;;;; |
749 | ;;;;;;;;;;;;;;;;;;;;;;; |
703 | ;; ;; |
750 | ;; ;; |
704 | ;; Interrupt handler ;; |
751 | ;; Interrupt handler ;; |
705 | ;; ;; |
752 | ;; ;; |
706 | ;;;;;;;;;;;;;;;;;;;;;;; |
753 | ;;;;;;;;;;;;;;;;;;;;;;; |
707 | 754 | ||
708 | align 4 |
755 | align 4 |
709 | int_handler: |
756 | int_handler: |
710 | 757 | ||
711 | push ebx esi edi |
758 | push ebx esi edi |
712 | 759 | ||
713 | DEBUGF 1,"INT\n" |
760 | DEBUGF 1,"INT\n" |
714 | 761 | ||
715 | ; find pointer of device wich made IRQ occur |
762 | ; find pointer of device wich made IRQ occur |
716 | 763 | ||
717 | mov ecx, [devices] |
764 | mov ecx, [devices] |
718 | test ecx, ecx |
765 | test ecx, ecx |
719 | jz .nothing |
766 | jz .nothing |
720 | mov esi, device_list |
767 | mov esi, device_list |
721 | .nextdevice: |
768 | .nextdevice: |
722 | mov ebx, [esi] |
769 | mov ebx, [esi] |
723 | 770 | ||
724 | ; set_io [ebx + device.io_addr], 0 ; reg_scb_status = 0 |
771 | ; set_io [ebx + device.io_addr], 0 ; reg_scb_status = 0 |
725 | set_io [ebx + device.io_addr], reg_scb_status |
772 | set_io [ebx + device.io_addr], reg_scb_status |
726 | in ax, dx |
773 | in ax, dx |
727 | out dx, ax ; send it back to ACK |
774 | out dx, ax ; send it back to ACK |
728 | test ax, ax |
775 | test ax, ax |
729 | jnz .got_it |
776 | jnz .got_it |
730 | .continue: |
777 | .continue: |
731 | add esi, 4 |
778 | add esi, 4 |
732 | dec ecx |
779 | dec ecx |
733 | jnz .nextdevice |
780 | jnz .nextdevice |
734 | .nothing: |
781 | .nothing: |
735 | pop edi esi ebx |
782 | pop edi esi ebx |
736 | xor eax, eax |
783 | xor eax, eax |
737 | 784 | ||
738 | ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) |
785 | ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) |
739 | 786 | ||
740 | .got_it: |
787 | .got_it: |
741 | 788 | ||
742 | DEBUGF 1,"Device: %x Status: %x\n", ebx, ax |
789 | DEBUGF 1,"Device: %x Status: %x\n", ebx, ax |
743 | 790 | ||
744 | test ax, 1 shl 14 ; did we receive a frame? |
791 | test ax, 1 shl 14 ; did we receive a frame? |
745 | jz .no_rx |
792 | jz .no_rx |
746 | 793 | ||
747 | push ax |
794 | push ax |
748 | 795 | ||
749 | DEBUGF 1,"Receiving\n" |
796 | DEBUGF 1,"Receiving\n" |
750 | 797 | ||
751 | push ebx |
798 | push ebx |
752 | .rx_loop: |
799 | .rx_loop: |
753 | pop ebx |
800 | pop ebx |
754 | 801 | ||
755 | mov esi, [ebx + device.rx_desc] |
802 | mov esi, [ebx + device.rx_desc] |
756 | cmp [esi + sizeof.NET_BUFF + rxfd.status], 0 ; we could also check bits C and OK (bit 15 and 13) |
803 | cmp [esi + sizeof.NET_BUFF + rxfd.status], 0 ; we could also check bits C and OK (bit 15 and 13) |
757 | je .nodata |
804 | je .nodata |
758 | 805 | ||
759 | DEBUGF 1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4 |
806 | DEBUGF 1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4 |
760 | 807 | ||
761 | movzx ecx, [esi + sizeof.NET_BUFF + rxfd.count] |
808 | movzx ecx, [esi + sizeof.NET_BUFF + rxfd.count] |
762 | and ecx, 0x3fff |
809 | and ecx, 0x3fff |
763 | 810 | ||
764 | push ebx |
811 | push ebx |
765 | push .rx_loop |
812 | push .rx_loop |
766 | push esi |
813 | push esi |
767 | mov [esi + NET_BUFF.length], ecx |
814 | mov [esi + NET_BUFF.length], ecx |
768 | mov [esi + NET_BUFF.device], ebx |
815 | mov [esi + NET_BUFF.device], ebx |
769 | mov [esi + NET_BUFF.offset], NET_BUFF.data + rxfd.packet |
816 | mov [esi + NET_BUFF.offset], NET_BUFF.data + rxfd.packet |
770 | 817 | ||
771 | ; Update stats |
818 | ; Update stats |
772 | add dword [ebx + device.bytes_rx], ecx |
819 | add dword [ebx + device.bytes_rx], ecx |
773 | adc dword [ebx + device.bytes_rx + 4], 0 |
820 | adc dword [ebx + device.bytes_rx + 4], 0 |
774 | inc dword [ebx + device.packets_rx] |
821 | inc dword [ebx + device.packets_rx] |
775 | 822 | ||
776 | ; allocate new descriptor |
823 | ; allocate new descriptor |
777 | 824 | ||
778 | invoke NetAlloc, 2000 |
825 | invoke NetAlloc, 2000 |
779 | mov [ebx + device.rx_desc], eax |
826 | mov [ebx + device.rx_desc], eax |
780 | mov esi, eax |
827 | mov esi, eax |
781 | invoke GetPhysAddr |
828 | invoke GetPhysAddr |
782 | add eax, NET_BUFF.data |
829 | add eax, NET_BUFF.data |
783 | mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000 |
830 | mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000 |
784 | mov [esi + sizeof.NET_BUFF + rxfd.command], 0xc000 ; End of list + Suspend |
831 | mov [esi + sizeof.NET_BUFF + rxfd.command], 0xc000 ; End of list + Suspend |
785 | mov [esi + sizeof.NET_BUFF + rxfd.link], eax |
832 | mov [esi + sizeof.NET_BUFF + rxfd.link], eax |
786 | mov [esi + sizeof.NET_BUFF + rxfd.count], 0 |
833 | mov [esi + sizeof.NET_BUFF + rxfd.count], 0 |
787 | mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 |
834 | mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 |
788 | 835 | ||
789 | ; restart RX |
836 | ; restart RX |
790 | 837 | ||
791 | set_io [ebx + device.io_addr], 0 |
838 | set_io [ebx + device.io_addr], 0 |
792 | set_io [ebx + device.io_addr], reg_scb_ptr |
839 | set_io [ebx + device.io_addr], reg_scb_ptr |
793 | ; lea eax, [ebx + device.rx_desc] |
840 | ; lea eax, [ebx + device.rx_desc] |
794 | ; invoke GetPhysAddr |
841 | ; invoke GetPhysAddr |
795 | out dx, eax |
842 | out dx, eax |
796 | 843 | ||
797 | set_io [ebx + device.io_addr], reg_scb_cmd |
844 | set_io [ebx + device.io_addr], reg_scb_cmd |
798 | mov ax, RX_START |
845 | mov ax, RX_START |
799 | out dx, ax |
846 | out dx, ax |
800 | call cmd_wait |
847 | call cmd_wait |
801 | 848 | ||
802 | ; And give packet to kernel |
849 | ; And give packet to kernel |
803 | jmp [EthInput] |
850 | jmp [EthInput] |
804 | 851 | ||
805 | .nodata: |
852 | .nodata: |
806 | DEBUGF 1, "no more data\n" |
853 | DEBUGF 1, "no more data\n" |
807 | pop ax |
854 | pop ax |
808 | 855 | ||
809 | .no_rx: |
856 | .no_rx: |
- | 857 | ||
- | 858 | test ax, 1 shl 13 |
|
- | 859 | jz .no_tx |
|
- | 860 | DEBUGF 1, "Command completed\n" |
|
810 | 861 | ||
- | 862 | push eax |
|
811 | ; Cleanup after TX |
863 | .loop_tx: |
- | 864 | mov edi, [ebx + device.last_tx] |
|
812 | cmp [ebx + device.txfd.status], 0 |
865 | mov eax, sizeof.txfd |
- | 866 | mul eax |
|
- | 867 | lea edi, [ebx + device.tx_ring + eax] |
|
813 | je .done |
868 | |
814 | cmp [ebx + device.last_tx_buffer], 0 |
869 | cmp [edi + txfd.status], 0 |
- | 870 | je .tx_done |
|
- | 871 | ||
815 | je .done |
872 | cmp [edi + txfd.virt_addr], 0 |
- | 873 | je .tx_done |
|
816 | push ax |
874 | |
- | 875 | DEBUGF 1,"Freeing buffer 0x%x\n", [edi + txfd.virt_addr] |
|
- | 876 | ||
- | 877 | push [edi + txfd.virt_addr] |
|
- | 878 | mov [edi + txfd.virt_addr], 0 |
|
- | 879 | invoke NetFree |
|
817 | DEBUGF 1, "Removing packet 0x%x from RAM!\n", [ebx + device.last_tx_buffer] |
880 | |
818 | invoke KernelFree, [ebx + device.last_tx_buffer] |
881 | inc [ebx + device.last_tx] |
- | 882 | and [ebx + device.last_tx], TX_RING_SIZE - 1 |
|
- | 883 | ||
- | 884 | jmp .loop_tx |
|
819 | mov [ebx + device.last_tx_buffer], 0 |
885 | .tx_done: |
- | 886 | pop eax |
|
820 | pop ax |
- | |
821 | 887 | .no_tx: |
|
822 | .done: |
888 | |
823 | and ax, 00111100b |
889 | and ax, 00111100b |
824 | cmp ax, 00001000b |
890 | cmp ax, 00001000b |
825 | jne .fail |
891 | jne .fail |
826 | 892 | ||
827 | DEBUGF 1, "out of resources!\n" |
893 | DEBUGF 1, "out of resources!\n" |
828 | ; Restart the RX |
894 | ; Restart the RX |
829 | 895 | ||
830 | ; allocate new descriptor |
896 | ; allocate new descriptor |
831 | 897 | ||
832 | invoke KernelAlloc, 2000 |
898 | invoke KernelAlloc, 2000 |
833 | mov [ebx + device.rx_desc], eax |
899 | mov [ebx + device.rx_desc], eax |
834 | mov esi, eax |
900 | mov esi, eax |
835 | invoke GetPhysAddr |
901 | invoke GetPhysAddr |
836 | mov [esi + rxfd.status], 0x0000 |
902 | mov [esi + rxfd.status], 0x0000 |
837 | mov [esi + rxfd.command], 0xc000 ; End of list + Suspend |
903 | mov [esi + rxfd.command], 0xc000 ; End of list + Suspend |
838 | mov [esi + rxfd.link], eax |
904 | mov [esi + rxfd.link], eax |
839 | mov [esi + rxfd.count], 0 |
905 | mov [esi + rxfd.count], 0 |
840 | mov [esi + rxfd.size], 1528 |
906 | mov [esi + rxfd.size], 1528 |
841 | 907 | ||
842 | ; restart RX |
908 | ; restart RX |
843 | 909 | ||
844 | set_io [ebx + device.io_addr], 0 |
910 | set_io [ebx + device.io_addr], 0 |
845 | set_io [ebx + device.io_addr], reg_scb_ptr |
911 | set_io [ebx + device.io_addr], reg_scb_ptr |
846 | ; lea eax, [ebx + device.rx_desc] |
912 | ; lea eax, [ebx + device.rx_desc] |
847 | ; invoke GetPhysAddr |
913 | ; invoke GetPhysAddr |
848 | out dx, eax |
914 | out dx, eax |
849 | 915 | ||
850 | set_io [ebx + device.io_addr], reg_scb_cmd |
916 | set_io [ebx + device.io_addr], reg_scb_cmd |
851 | mov ax, RX_START |
917 | mov ax, RX_START |
852 | out dx, ax |
918 | out dx, ax |
853 | call cmd_wait |
919 | call cmd_wait |
854 | 920 | ||
855 | .fail: |
921 | .fail: |
856 | pop edi esi ebx |
922 | pop edi esi ebx |
857 | xor eax, eax |
923 | xor eax, eax |
858 | inc eax |
924 | inc eax |
859 | 925 | ||
860 | ret |
926 | ret |
861 | 927 | ||
862 | 928 | ||
863 | 929 | ||
864 | 930 | ||
865 | align 4 |
931 | align 4 |
866 | cmd_wait: |
932 | cmd_wait: |
867 | 933 | ||
868 | in al, dx |
934 | in al, dx |
869 | test al, al |
935 | test al, al |
870 | jnz cmd_wait |
936 | jnz cmd_wait |
871 | 937 | ||
872 | ret |
938 | ret |
873 | 939 | ||
874 | 940 | ||
875 | 941 | ||
876 | 942 | ||
877 | 943 | ||
878 | 944 | ||
879 | align 4 |
945 | align 4 |
880 | ee_read: ; esi = address to read |
946 | ee_read: ; esi = address to read |
881 | 947 | ||
882 | DEBUGF 1,"Eeprom read from 0x%x\n", esi |
948 | DEBUGF 1,"Eeprom read from 0x%x\n", esi |
883 | 949 | ||
884 | set_io [ebx + device.io_addr], 0 |
950 | set_io [ebx + device.io_addr], 0 |
885 | set_io [ebx + device.io_addr], reg_eeprom |
951 | set_io [ebx + device.io_addr], reg_eeprom |
886 | 952 | ||
887 | ;----------------------------------------------------- |
953 | ;----------------------------------------------------- |
888 | ; Prepend start bit + read opcode to the address field |
954 | ; Prepend start bit + read opcode to the address field |
889 | ; and shift it to the very left bits of esi |
955 | ; and shift it to the very left bits of esi |
890 | 956 | ||
891 | mov cl, 29 |
957 | mov cl, 29 |
892 | sub cl, [ebx + device.ee_bus_width] |
958 | sub cl, [ebx + device.ee_bus_width] |
893 | shl esi, cl |
959 | shl esi, cl |
894 | or esi, EE_READ shl 29 |
960 | or esi, EE_READ shl 29 |
895 | 961 | ||
896 | movzx ecx, [ebx + device.ee_bus_width] |
962 | movzx ecx, [ebx + device.ee_bus_width] |
897 | add ecx, 3 |
963 | add ecx, 3 |
898 | 964 | ||
899 | mov al, EE_CS |
965 | mov al, EE_CS |
900 | out dx, al |
966 | out dx, al |
901 | call udelay |
967 | call udelay |
902 | 968 | ||
903 | ;----------------------- |
969 | ;----------------------- |
904 | ; Write this to the chip |
970 | ; Write this to the chip |
905 | 971 | ||
906 | .loop: |
972 | .loop: |
907 | mov al, EE_CS + EE_SK |
973 | mov al, EE_CS + EE_SK |
908 | shl esi, 1 |
974 | shl esi, 1 |
909 | jnc @f |
975 | jnc @f |
910 | or al, EE_DI |
976 | or al, EE_DI |
911 | @@: |
977 | @@: |
912 | out dx, al |
978 | out dx, al |
913 | call udelay |
979 | call udelay |
914 | 980 | ||
915 | and al, not EE_SK |
981 | and al, not EE_SK |
916 | out dx, al |
982 | out dx, al |
917 | call udelay |
983 | call udelay |
918 | 984 | ||
919 | loop .loop |
985 | loop .loop |
920 | 986 | ||
921 | ;------------------------------ |
987 | ;------------------------------ |
922 | ; Now read the data from eeprom |
988 | ; Now read the data from eeprom |
923 | 989 | ||
924 | xor esi, esi |
990 | xor esi, esi |
925 | mov ecx, 16 |
991 | mov ecx, 16 |
926 | 992 | ||
927 | .loop2: |
993 | .loop2: |
928 | shl esi, 1 |
994 | shl esi, 1 |
929 | mov al, EE_CS + EE_SK |
995 | mov al, EE_CS + EE_SK |
930 | out dx, al |
996 | out dx, al |
931 | call udelay |
997 | call udelay |
932 | 998 | ||
933 | in al, dx |
999 | in al, dx |
934 | test al, EE_DO |
1000 | test al, EE_DO |
935 | jz @f |
1001 | jz @f |
936 | inc esi |
1002 | inc esi |
937 | @@: |
1003 | @@: |
938 | 1004 | ||
939 | mov al, EE_CS |
1005 | mov al, EE_CS |
940 | out dx, al |
1006 | out dx, al |
941 | call udelay |
1007 | call udelay |
942 | 1008 | ||
943 | loop .loop2 |
1009 | loop .loop2 |
944 | 1010 | ||
945 | ;----------------------- |
1011 | ;----------------------- |
946 | ; de-activate the eeprom |
1012 | ; de-activate the eeprom |
947 | 1013 | ||
948 | xor ax, ax |
1014 | xor ax, ax |
949 | out dx, ax |
1015 | out dx, ax |
950 | 1016 | ||
951 | 1017 | ||
952 | DEBUGF 1,"0x%x\n", esi:4 |
1018 | DEBUGF 1,"0x%x\n", esi:4 |
953 | ret |
1019 | ret |
954 | 1020 | ||
955 | 1021 | ||
956 | 1022 | ||
957 | align 4 |
1023 | align 4 |
958 | ee_write: ; esi = address to write to, di = data |
1024 | ee_write: ; esi = address to write to, di = data |
959 | 1025 | ||
960 | DEBUGF 1,"Eeprom write 0x%x to 0x%x\n", di, esi |
1026 | DEBUGF 1,"Eeprom write 0x%x to 0x%x\n", di, esi |
961 | 1027 | ||
962 | set_io [ebx + device.io_addr], 0 |
1028 | set_io [ebx + device.io_addr], 0 |
963 | set_io [ebx + device.io_addr], reg_eeprom |
1029 | set_io [ebx + device.io_addr], reg_eeprom |
964 | 1030 | ||
965 | ;----------------------------------------------------- |
1031 | ;----------------------------------------------------- |
966 | ; Prepend start bit + write opcode to the address field |
1032 | ; Prepend start bit + write opcode to the address field |
967 | ; and shift it to the very left bits of esi |
1033 | ; and shift it to the very left bits of esi |
968 | 1034 | ||
969 | mov cl, 29 |
1035 | mov cl, 29 |
970 | sub cl, [ebx + device.ee_bus_width] |
1036 | sub cl, [ebx + device.ee_bus_width] |
971 | shl esi, cl |
1037 | shl esi, cl |
972 | or esi, EE_WRITE shl 29 |
1038 | or esi, EE_WRITE shl 29 |
973 | 1039 | ||
974 | movzx ecx, [ebx + device.ee_bus_width] |
1040 | movzx ecx, [ebx + device.ee_bus_width] |
975 | add ecx, 3 |
1041 | add ecx, 3 |
976 | 1042 | ||
977 | mov al, EE_CS ; enable chip |
1043 | mov al, EE_CS ; enable chip |
978 | out dx, al |
1044 | out dx, al |
979 | 1045 | ||
980 | ;----------------------- |
1046 | ;----------------------- |
981 | ; Write this to the chip |
1047 | ; Write this to the chip |
982 | 1048 | ||
983 | .loop: |
1049 | .loop: |
984 | mov al, EE_CS + EE_SK |
1050 | mov al, EE_CS + EE_SK |
985 | shl esi, 1 |
1051 | shl esi, 1 |
986 | jnc @f |
1052 | jnc @f |
987 | or al, EE_DI |
1053 | or al, EE_DI |
988 | @@: |
1054 | @@: |
989 | out dx, al |
1055 | out dx, al |
990 | call udelay |
1056 | call udelay |
991 | 1057 | ||
992 | and al, not EE_SK |
1058 | and al, not EE_SK |
993 | out dx, al |
1059 | out dx, al |
994 | call udelay |
1060 | call udelay |
995 | 1061 | ||
996 | loop .loop |
1062 | loop .loop |
997 | 1063 | ||
998 | ;----------------------------- |
1064 | ;----------------------------- |
999 | ; Now write the data to eeprom |
1065 | ; Now write the data to eeprom |
1000 | 1066 | ||
1001 | mov ecx, 16 |
1067 | mov ecx, 16 |
1002 | 1068 | ||
1003 | .loop2: |
1069 | .loop2: |
1004 | mov al, EE_CS + EE_SK |
1070 | mov al, EE_CS + EE_SK |
1005 | shl di, 1 |
1071 | shl di, 1 |
1006 | jnc @f |
1072 | jnc @f |
1007 | or al, EE_DI |
1073 | or al, EE_DI |
1008 | @@: |
1074 | @@: |
1009 | out dx, al |
1075 | out dx, al |
1010 | call udelay |
1076 | call udelay |
1011 | 1077 | ||
1012 | and al, not EE_SK |
1078 | and al, not EE_SK |
1013 | out dx, al |
1079 | out dx, al |
1014 | call udelay |
1080 | call udelay |
1015 | 1081 | ||
1016 | loop .loop2 |
1082 | loop .loop2 |
1017 | 1083 | ||
1018 | ;----------------------- |
1084 | ;----------------------- |
1019 | ; de-activate the eeprom |
1085 | ; de-activate the eeprom |
1020 | 1086 | ||
1021 | xor al, al |
1087 | xor al, al |
1022 | out dx, al |
1088 | out dx, al |
1023 | 1089 | ||
1024 | 1090 | ||
1025 | ret |
1091 | ret |
1026 | 1092 | ||
1027 | 1093 | ||
1028 | 1094 | ||
1029 | align 4 |
1095 | align 4 |
1030 | ee_get_width: |
1096 | ee_get_width: |
1031 | 1097 | ||
1032 | set_io [ebx + device.io_addr], 0 |
1098 | set_io [ebx + device.io_addr], 0 |
1033 | set_io [ebx + device.io_addr], reg_eeprom |
1099 | set_io [ebx + device.io_addr], reg_eeprom |
1034 | 1100 | ||
1035 | mov al, EE_CS ; activate eeprom |
1101 | mov al, EE_CS ; activate eeprom |
1036 | out dx, al |
1102 | out dx, al |
1037 | call udelay |
1103 | call udelay |
1038 | 1104 | ||
1039 | mov si, EE_READ shl 13 |
1105 | mov si, EE_READ shl 13 |
1040 | xor ecx, ecx |
1106 | xor ecx, ecx |
1041 | .loop: |
1107 | .loop: |
1042 | mov al, EE_CS + EE_SK |
1108 | mov al, EE_CS + EE_SK |
1043 | shl si, 1 |
1109 | shl si, 1 |
1044 | jnc @f |
1110 | jnc @f |
1045 | or al, EE_DI |
1111 | or al, EE_DI |
1046 | @@: |
1112 | @@: |
1047 | out dx, al |
1113 | out dx, al |
1048 | call udelay |
1114 | call udelay |
1049 | 1115 | ||
1050 | and al, not EE_SK |
1116 | and al, not EE_SK |
1051 | out dx, al |
1117 | out dx, al |
1052 | call udelay |
1118 | call udelay |
1053 | 1119 | ||
1054 | inc ecx |
1120 | inc ecx |
1055 | 1121 | ||
1056 | cmp ecx, 15 |
1122 | cmp ecx, 15 |
1057 | jae .give_up |
1123 | jae .give_up |
1058 | 1124 | ||
1059 | in al, dx |
1125 | in al, dx |
1060 | test al, EE_DO |
1126 | test al, EE_DO |
1061 | jnz .loop |
1127 | jnz .loop |
1062 | 1128 | ||
1063 | xor al, al |
1129 | xor al, al |
1064 | out dx, al ; de-activate eeprom |
1130 | out dx, al ; de-activate eeprom |
1065 | 1131 | ||
1066 | sub cl, 3 ; dont count the opcode bits |
1132 | sub cl, 3 ; dont count the opcode bits |
1067 | mov [ebx + device.ee_bus_width], cl |
1133 | mov [ebx + device.ee_bus_width], cl |
1068 | DEBUGF 1, "Eeprom width=%u bit\n", ecx |
1134 | DEBUGF 1, "Eeprom width=%u bit\n", ecx |
1069 | 1135 | ||
1070 | ret |
1136 | ret |
1071 | 1137 | ||
1072 | .give_up: |
1138 | .give_up: |
1073 | DEBUGF 2, "Eeprom not found!\n" |
1139 | DEBUGF 2, "Eeprom not found!\n" |
1074 | 1140 | ||
1075 | xor al, al |
1141 | xor al, al |
1076 | out dx, al ; de-activate eeprom |
1142 | out dx, al ; de-activate eeprom |
1077 | 1143 | ||
1078 | ret |
1144 | ret |
1079 | 1145 | ||
1080 | 1146 | ||
1081 | ; Wait a minimum of 2µs |
1147 | ; Wait a minimum of 2µs |
1082 | udelay: |
1148 | udelay: |
1083 | pusha |
1149 | pusha |
1084 | mov esi, 1 |
1150 | mov esi, 1 |
1085 | invoke Sleep |
1151 | invoke Sleep |
1086 | popa |
1152 | popa |
1087 | 1153 | ||
1088 | ret |
1154 | ret |
1089 | 1155 | ||
1090 | 1156 | ||
1091 | 1157 | ||
1092 | ; cx = phy addr |
1158 | ; cx = phy addr |
1093 | ; dx = phy reg addr |
1159 | ; dx = phy reg addr |
1094 | 1160 | ||
1095 | ; ax = data |
1161 | ; ax = data |
1096 | 1162 | ||
1097 | align 4 |
1163 | align 4 |
1098 | mdio_read: |
1164 | mdio_read: |
1099 | 1165 | ||
1100 | DEBUGF 1,"MDIO read\n" |
1166 | DEBUGF 1,"MDIO read\n" |
1101 | 1167 | ||
1102 | shl ecx, 21 ; PHY addr |
1168 | shl ecx, 21 ; PHY addr |
1103 | shl edx, 16 ; PHY reg addr |
1169 | shl edx, 16 ; PHY reg addr |
1104 | 1170 | ||
1105 | mov eax, ecx |
1171 | mov eax, ecx |
1106 | or eax, edx |
1172 | or eax, edx |
1107 | or eax, 10b shl 26 ; read opcode |
1173 | or eax, 10b shl 26 ; read opcode |
1108 | 1174 | ||
1109 | set_io [ebx + device.io_addr], 0 |
1175 | set_io [ebx + device.io_addr], 0 |
1110 | set_io [ebx + device.io_addr], reg_mdi_ctrl |
1176 | set_io [ebx + device.io_addr], reg_mdi_ctrl |
1111 | out dx, eax |
1177 | out dx, eax |
1112 | 1178 | ||
1113 | .wait: |
1179 | .wait: |
1114 | call udelay |
1180 | call udelay |
1115 | in eax, dx |
1181 | in eax, dx |
1116 | test eax, 1 shl 28 ; ready bit |
1182 | test eax, 1 shl 28 ; ready bit |
1117 | jz .wait |
1183 | jz .wait |
1118 | 1184 | ||
1119 | ret |
1185 | ret |
1120 | 1186 | ||
1121 | ; ax = data |
1187 | ; ax = data |
1122 | ; cx = phy addr |
1188 | ; cx = phy addr |
1123 | ; dx = phy reg addr |
1189 | ; dx = phy reg addr |
1124 | 1190 | ||
1125 | ; ax = data |
1191 | ; ax = data |
1126 | 1192 | ||
1127 | align 4 |
1193 | align 4 |
1128 | mdio_write: |
1194 | mdio_write: |
1129 | 1195 | ||
1130 | DEBUGF 1,"MDIO write\n" |
1196 | DEBUGF 1,"MDIO write\n" |
1131 | 1197 | ||
1132 | and eax, 0xffff |
1198 | and eax, 0xffff |
1133 | 1199 | ||
1134 | shl ecx, 21 ; PHY addr |
1200 | shl ecx, 21 ; PHY addr |
1135 | shl edx, 16 ; PHY reg addr |
1201 | shl edx, 16 ; PHY reg addr |
1136 | 1202 | ||
1137 | or eax, ecx |
1203 | or eax, ecx |
1138 | or eax, edx |
1204 | or eax, edx |
1139 | or eax, 01b shl 26 ; write opcode |
1205 | or eax, 01b shl 26 ; write opcode |
1140 | 1206 | ||
1141 | set_io [ebx + device.io_addr], 0 |
1207 | set_io [ebx + device.io_addr], 0 |
1142 | set_io [ebx + device.io_addr], reg_mdi_ctrl |
1208 | set_io [ebx + device.io_addr], reg_mdi_ctrl |
1143 | out dx, eax |
1209 | out dx, eax |
1144 | 1210 | ||
1145 | .wait: |
1211 | .wait: |
1146 | call udelay |
1212 | call udelay |
1147 | in eax, dx |
1213 | in eax, dx |
1148 | test eax, 1 shl 28 ; ready bit |
1214 | test eax, 1 shl 28 ; ready bit |
1149 | jz .wait |
1215 | jz .wait |
1150 | 1216 | ||
1151 | ret |
1217 | ret |
1152 | 1218 | ||
1153 | read_mac: |
1219 | read_mac: |
1154 | 1220 | ||
1155 | ret |
1221 | ret |
1156 | 1222 | ||
1157 | 1223 | ||
1158 | 1224 | ||
1159 | align 4 |
1225 | align 4 |
1160 | MAC_read_eeprom: |
1226 | MAC_read_eeprom: |
1161 | 1227 | ||
1162 | mov esi, 0 |
1228 | mov esi, 0 |
1163 | call ee_read |
1229 | call ee_read |
1164 | mov word[ebx + device.mac], si |
1230 | mov word[ebx + device.mac], si |
1165 | 1231 | ||
1166 | mov esi, 1 |
1232 | mov esi, 1 |
1167 | call ee_read |
1233 | call ee_read |
1168 | mov word[ebx + device.mac+2], si |
1234 | mov word[ebx + device.mac+2], si |
1169 | 1235 | ||
1170 | mov esi, 2 |
1236 | mov esi, 2 |
1171 | call ee_read |
1237 | call ee_read |
1172 | mov word[ebx + device.mac+4], si |
1238 | mov word[ebx + device.mac+4], si |
1173 | 1239 | ||
1174 | 1240 | ||
1175 | ret |
1241 | ret |
1176 | 1242 | ||
1177 | 1243 | ||
1178 | align 4 |
1244 | align 4 |
1179 | MAC_write: |
1245 | MAC_write: |
1180 | 1246 | ||
1181 | ;;;; |
1247 | ;;;; |
1182 | 1248 | ||
1183 | ret |
1249 | ret |
1184 | 1250 | ||
1185 | 1251 | ||
1186 | 1252 | ||
1187 | 1253 | ||
1188 | ; End of code |
1254 | ; End of code |
1189 | 1255 | ||
1190 | 1256 | ||
1191 | data fixups |
1257 | data fixups |
1192 | end data |
1258 | end data |
1193 | 1259 | ||
1194 | include '../peimport.inc' |
1260 | include '../peimport.inc' |
1195 | 1261 | ||
1196 | my_service db 'I8255X', 0 ; max 16 chars include zero |
1262 | my_service db 'I8255X', 0 ; max 16 chars include zero |
1197 | devicename db 'Intel Etherexpress pro/100', 0 |
1263 | devicename db 'Intel Etherexpress pro/100', 0 |
1198 | 1264 | ||
1199 | confcmd_data db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1 |
1265 | confcmd_data db 22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1 |
1200 | db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2 |
1266 | db 0, 0x2e, 0, 0x60, 0, 0xf2, 0x48, 0, 0x40, 0xf2 |
1201 | db 0x80, 0x3f, 0x05 ; 22 bytes total |
1267 | db 0x80, 0x3f, 0x05 ; 22 bytes total |
1202 | 1268 | ||
1203 | 1269 | ||
1204 | device_id_list: |
1270 | device_id_list: |
1205 | 1271 | ||
1206 | dw 0x1029 |
1272 | dw 0x1029 |
1207 | dw 0x1030 |
1273 | dw 0x1030 |
1208 | dw 0x1031 |
1274 | dw 0x1031 |
1209 | dw 0x1032 |
1275 | dw 0x1032 |
1210 | dw 0x1033 |
1276 | dw 0x1033 |
1211 | dw 0x1034 |
1277 | dw 0x1034 |
1212 | dw 0x1038 |
1278 | dw 0x1038 |
1213 | dw 0x1039 |
1279 | dw 0x1039 |
1214 | dw 0x103A |
1280 | dw 0x103A |
1215 | dw 0x103B |
1281 | dw 0x103B |
1216 | dw 0x103C |
1282 | dw 0x103C |
1217 | dw 0x103D |
1283 | dw 0x103D |
1218 | dw 0x103E |
1284 | dw 0x103E |
1219 | dw 0x1050 |
1285 | dw 0x1050 |
1220 | dw 0x1051 |
1286 | dw 0x1051 |
1221 | dw 0x1052 |
1287 | dw 0x1052 |
1222 | dw 0x1053 |
1288 | dw 0x1053 |
1223 | dw 0x1054 |
1289 | dw 0x1054 |
1224 | dw 0x1055 |
1290 | dw 0x1055 |
1225 | dw 0x1056 |
1291 | dw 0x1056 |
1226 | dw 0x1057 |
1292 | dw 0x1057 |
1227 | dw 0x1059 |
1293 | dw 0x1059 |
1228 | dw 0x1064 |
1294 | dw 0x1064 |
1229 | dw 0x1065 |
1295 | dw 0x1065 |
1230 | dw 0x1066 |
1296 | dw 0x1066 |
1231 | dw 0x1067 |
1297 | dw 0x1067 |
1232 | dw 0x1068 |
1298 | dw 0x1068 |
1233 | dw 0x1069 |
1299 | dw 0x1069 |
1234 | dw 0x106A |
1300 | dw 0x106A |
1235 | dw 0x106B |
1301 | dw 0x106B |
1236 | dw 0x1091 |
1302 | dw 0x1091 |
1237 | dw 0x1092 |
1303 | dw 0x1092 |
1238 | dw 0x1093 |
1304 | dw 0x1093 |
1239 | dw 0x1094 |
1305 | dw 0x1094 |
1240 | dw 0x1095 |
1306 | dw 0x1095 |
1241 | dw 0x10fe |
1307 | dw 0x10fe |
1242 | dw 0x1209 |
1308 | dw 0x1209 |
1243 | dw 0x1229 |
1309 | dw 0x1229 |
1244 | dw 0x2449 |
1310 | dw 0x2449 |
1245 | dw 0x2459 |
1311 | dw 0x2459 |
1246 | dw 0x245D |
1312 | dw 0x245D |
1247 | dw 0x27DC |
1313 | dw 0x27DC |
1248 | 1314 | ||
1249 | DEVICE_IDs = ($ - device_id_list) / 2 |
1315 | DEVICE_IDs = ($ - device_id_list) / 2 |
1250 | 1316 | ||
1251 | include_debug_strings ; All data wich FDO uses will be included here |
1317 | include_debug_strings ; All data wich FDO uses will be included here |
1252 | 1318 | ||
1253 | align 4 |
1319 | align 4 |
1254 | devices dd 0 ; number of currently running devices |
1320 | devices dd 0 ; number of currently running devices |
1255 | device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling |
1321 | device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling |