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