Rev 2913 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2913 | Rev 2935 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2012. 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 | ;; Ethernet driver for KolibriOS ;; |
6 | ;; Ethernet driver for KolibriOS ;; |
7 | ;; This is an adaptation of MenuetOS driver with minimal changes. ;; |
7 | ;; This is an adaptation of MenuetOS driver with minimal changes. ;; |
8 | ;; Changes were made by CleverMouse. Original copyright follows. ;; |
8 | ;; Changes were made by CleverMouse. Original copyright follows. ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; This driver is based on the SIS900 driver from ;; |
10 | ;; This driver is based on the SIS900 driver from ;; |
11 | ;; the etherboot 5.0.6 project. The copyright statement is ;; |
11 | ;; the etherboot 5.0.6 project. The copyright statement is ;; |
12 | ;; ;; |
12 | ;; ;; |
13 | ;; GNU GENERAL PUBLIC LICENSE ;; |
13 | ;; GNU GENERAL PUBLIC LICENSE ;; |
14 | ;; Version 2, June 1991 ;; |
14 | ;; Version 2, June 1991 ;; |
15 | ;; ;; |
15 | ;; ;; |
16 | ;; remaining parts Copyright 2004 Jason Delozier, ;; |
16 | ;; remaining parts Copyright 2004 Jason Delozier, ;; |
17 | ;; cordata51@hotmail.com ;; |
17 | ;; cordata51@hotmail.com ;; |
18 | ;; ;; |
18 | ;; ;; |
19 | ;; See file COPYING for details ;; |
19 | ;; See file COPYING for details ;; |
20 | ;; ;; |
20 | ;; ;; |
21 | ;; Updates: ;; |
21 | ;; Updates: ;; |
22 | ;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;; |
22 | ;; Revision Look up table and SIS635 Mac Address by Jarek Pelczar ;; |
23 | ;; ;; |
23 | ;; ;; |
24 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
24 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
25 | 25 | ||
26 | format MS COFF |
26 | format MS COFF |
27 | 27 | ||
28 | NUM_RX_DESC = 4 ; Number of RX descriptors |
28 | NUM_RX_DESC = 4 ; Number of RX descriptors |
29 | NUM_TX_DESC = 4 ; Number of TX descriptors |
29 | NUM_TX_DESC = 4 ; Number of TX descriptors |
30 | RX_BUFF_SZ = 1520 ; Buffer size for each Rx buffer |
30 | RX_BUFF_SZ = 1520 ; Buffer size for each Rx buffer |
31 | TX_BUFF_SZ = 1516 ; Buffer size for each Tx buffer |
31 | TX_BUFF_SZ = 1516 ; Buffer size for each Tx buffer |
32 | MAX_ETH_FRAME_SIZE = 1516 |
32 | MAX_ETH_FRAME_SIZE = 1516 |
33 | 33 | ||
34 | API_VERSION = 0x01000100 |
34 | API_VERSION = 0x01000100 |
35 | DRIVER_VERSION = 5 |
35 | DRIVER_VERSION = 5 |
36 | 36 | ||
37 | MAX_DEVICES = 16 |
37 | MAX_DEVICES = 16 |
38 | 38 | ||
39 | DEBUG = 1 |
39 | DEBUG = 1 |
40 | __DEBUG__ = 1 |
40 | __DEBUG__ = 1 |
41 | __DEBUG_LEVEL__ = 1 |
41 | __DEBUG_LEVEL__ = 1 |
42 | 42 | ||
43 | DSIZE = 0x00000fff |
43 | DSIZE = 0x00000fff |
44 | CRC_SIZE = 4 |
44 | CRC_SIZE = 4 |
45 | RFADDR_shift = 16 |
45 | RFADDR_shift = 16 |
46 | 46 | ||
47 | ; If you are having problems sending/receiving packet try changing the |
47 | ; If you are having problems sending/receiving packet try changing the |
48 | ; Max DMA Burst, Possible settings are as follows: |
48 | ; Max DMA Burst, Possible settings are as follows: |
49 | ; |
49 | ; |
50 | ; 0x00000000 = 512 bytes |
50 | ; 0x00000000 = 512 bytes |
51 | ; 0x00100000 = 4 bytes |
51 | ; 0x00100000 = 4 bytes |
52 | ; 0x00200000 = 8 bytes |
52 | ; 0x00200000 = 8 bytes |
53 | ; 0x00300000 = 16 bytes |
53 | ; 0x00300000 = 16 bytes |
54 | ; 0x00400000 = 32 bytes |
54 | ; 0x00400000 = 32 bytes |
55 | ; 0x00500000 = 64 bytes |
55 | ; 0x00500000 = 64 bytes |
56 | ; 0x00600000 = 128 bytes |
56 | ; 0x00600000 = 128 bytes |
57 | ; 0x00700000 = 256 bytes |
57 | ; 0x00700000 = 256 bytes |
58 | 58 | ||
59 | RX_DMA = 0x00600000 |
59 | RX_DMA = 0x00600000 |
60 | TX_DMA = 0x00600000 |
60 | TX_DMA = 0x00600000 |
61 | 61 | ||
62 | ;------------------------------------------------------------------------------------------------- |
62 | ;------------------------------------------------------------------------------------------------- |
63 | ; Symbolic offsets to registers. |
63 | ; Symbolic offsets to registers. |
64 | cr = 0x0 ; Command Register |
64 | cr = 0x0 ; Command Register |
65 | cfg = 0x4 ; Configuration Register |
65 | cfg = 0x4 ; Configuration Register |
66 | mear = 0x8 ; EEPROM Access Register |
66 | mear = 0x8 ; EEPROM Access Register |
67 | ptscr = 0xc ; PCI Test Control Register |
67 | ptscr = 0xc ; PCI Test Control Register |
68 | isr = 0x10 ; Interrupt Status Register |
68 | isr = 0x10 ; Interrupt Status Register |
69 | imr = 0x14 ; Interrupt Mask Register |
69 | imr = 0x14 ; Interrupt Mask Register |
70 | ier = 0x18 ; Interrupt Enable Register |
70 | ier = 0x18 ; Interrupt Enable Register |
71 | epar = 0x18 ; Enhanced PHY Access Register |
71 | epar = 0x18 ; Enhanced PHY Access Register |
72 | txdp = 0x20 ; Transmit Descriptor Pointer Register |
72 | txdp = 0x20 ; Transmit Descriptor Pointer Register |
73 | txcfg = 0x24 ; Transmit Configuration Register |
73 | txcfg = 0x24 ; Transmit Configuration Register |
74 | rxdp = 0x30 ; Receive Descriptor Pointer Register |
74 | rxdp = 0x30 ; Receive Descriptor Pointer Register |
75 | rxcfg = 0x34 ; Receive Configuration Register |
75 | rxcfg = 0x34 ; Receive Configuration Register |
76 | flctrl = 0x38 ; Flow Control Register |
76 | flctrl = 0x38 ; Flow Control Register |
77 | rxlen = 0x3c ; Receive Packet Length Register |
77 | rxlen = 0x3c ; Receive Packet Length Register |
78 | rfcr = 0x48 ; Receive Filter Control Register |
78 | rfcr = 0x48 ; Receive Filter Control Register |
79 | rfdr = 0x4C ; Receive Filter Data Register |
79 | rfdr = 0x4C ; Receive Filter Data Register |
80 | pmctrl = 0xB0 ; Power Management Control Register |
80 | pmctrl = 0xB0 ; Power Management Control Register |
81 | pmer = 0xB4 ; Power Management Wake-up Event Register |
81 | pmer = 0xB4 ; Power Management Wake-up Event Register |
82 | 82 | ||
83 | ; Command Register Bits |
83 | ; Command Register Bits |
84 | RELOAD = 0x00000400 |
84 | RELOAD = 0x00000400 |
85 | ACCESSMODE = 0x00000200 |
85 | ACCESSMODE = 0x00000200 |
86 | RESET = 0x00000100 |
86 | RESET = 0x00000100 |
87 | SWI = 0x00000080 |
87 | SWI = 0x00000080 |
88 | RxRESET = 0x00000020 |
88 | RxRESET = 0x00000020 |
89 | TxRESET = 0x00000010 |
89 | TxRESET = 0x00000010 |
90 | RxDIS = 0x00000008 |
90 | RxDIS = 0x00000008 |
91 | RxENA = 0x00000004 |
91 | RxENA = 0x00000004 |
92 | TxDIS = 0x00000002 |
92 | TxDIS = 0x00000002 |
93 | TxENA = 0x00000001 |
93 | TxENA = 0x00000001 |
94 | 94 | ||
95 | ; Configuration Register Bits |
95 | ; Configuration Register Bits |
96 | DESCRFMT = 0x00000100 ; 7016 specific |
96 | DESCRFMT = 0x00000100 ; 7016 specific |
97 | REQALG = 0x00000080 |
97 | REQALG = 0x00000080 |
98 | SB = 0x00000040 |
98 | SB = 0x00000040 |
99 | POW = 0x00000020 |
99 | POW = 0x00000020 |
100 | EXD = 0x00000010 |
100 | EXD = 0x00000010 |
101 | PESEL = 0x00000008 |
101 | PESEL = 0x00000008 |
102 | LPM = 0x00000004 |
102 | LPM = 0x00000004 |
103 | BEM = 0x00000001 |
103 | BEM = 0x00000001 |
104 | RND_CNT = 0x00000400 |
104 | RND_CNT = 0x00000400 |
105 | FAIR_BACKOFF = 0x00000200 |
105 | FAIR_BACKOFF = 0x00000200 |
106 | EDB_MASTER_EN = 0x00002000 |
106 | EDB_MASTER_EN = 0x00002000 |
107 | 107 | ||
108 | ; Eeprom Access Reigster Bits |
108 | ; Eeprom Access Reigster Bits |
109 | MDC = 0x00000040 |
109 | MDC = 0x00000040 |
110 | MDDIR = 0x00000020 |
110 | MDDIR = 0x00000020 |
111 | MDIO = 0x00000010 ; 7016 specific |
111 | MDIO = 0x00000010 ; 7016 specific |
112 | EECS = 0x00000008 |
112 | EECS = 0x00000008 |
113 | EECLK = 0x00000004 |
113 | EECLK = 0x00000004 |
114 | EEDO = 0x00000002 |
114 | EEDO = 0x00000002 |
115 | EEDI = 0x00000001 |
115 | EEDI = 0x00000001 |
116 | 116 | ||
117 | ; TX Configuration Register Bits |
117 | ; TX Configuration Register Bits |
118 | ATP = 0x10000000 ; Automatic Transmit Padding |
118 | ATP = 0x10000000 ; Automatic Transmit Padding |
119 | MLB = 0x20000000 ; Mac Loopback Enable |
119 | MLB = 0x20000000 ; Mac Loopback Enable |
120 | HBI = 0x40000000 ; HeartBeat Ignore (Req for full-dup) |
120 | HBI = 0x40000000 ; HeartBeat Ignore (Req for full-dup) |
121 | CSI = 0x80000000 ; CarrierSenseIgnore (Req for full-du |
121 | CSI = 0x80000000 ; CarrierSenseIgnore (Req for full-du |
122 | 122 | ||
123 | ; RX Configuration Register Bits |
123 | ; RX Configuration Register Bits |
124 | AJAB = 0x08000000 ; |
124 | AJAB = 0x08000000 ; |
125 | ATX = 0x10000000 ; Accept Transmit Packets |
125 | ATX = 0x10000000 ; Accept Transmit Packets |
126 | ARP = 0x40000000 ; accept runt packets (<64bytes) |
126 | ARP = 0x40000000 ; accept runt packets (<64bytes) |
127 | AEP = 0x80000000 ; accept error packets |
127 | AEP = 0x80000000 ; accept error packets |
128 | 128 | ||
129 | ; Interrupt Register Bits |
129 | ; Interrupt Register Bits |
130 | WKEVT = 0x10000000 |
130 | WKEVT = 0x10000000 |
131 | TxPAUSEEND = 0x08000000 |
131 | TxPAUSEEND = 0x08000000 |
132 | TxPAUSE = 0x04000000 |
132 | TxPAUSE = 0x04000000 |
133 | TxRCMP = 0x02000000 ; Transmit Reset Complete |
133 | TxRCMP = 0x02000000 ; Transmit Reset Complete |
134 | RxRCMP = 0x01000000 ; Receive Reset Complete |
134 | RxRCMP = 0x01000000 ; Receive Reset Complete |
135 | DPERR = 0x00800000 |
135 | DPERR = 0x00800000 |
136 | SSERR = 0x00400000 |
136 | SSERR = 0x00400000 |
137 | RMABT = 0x00200000 |
137 | RMABT = 0x00200000 |
138 | RTABT = 0x00100000 |
138 | RTABT = 0x00100000 |
139 | RxSOVR = 0x00010000 |
139 | RxSOVR = 0x00010000 |
140 | HIBERR = 0x00008000 |
140 | HIBERR = 0x00008000 |
141 | SWINT = 0x00001000 |
141 | SWINT = 0x00001000 |
142 | MIBINT = 0x00000800 |
142 | MIBINT = 0x00000800 |
143 | TxURN = 0x00000400 |
143 | TxURN = 0x00000400 |
144 | TxIDLE = 0x00000200 |
144 | TxIDLE = 0x00000200 |
145 | TxERR = 0x00000100 |
145 | TxERR = 0x00000100 |
146 | TxDESC = 0x00000080 |
146 | TxDESC = 0x00000080 |
147 | TxOK = 0x00000040 |
147 | TxOK = 0x00000040 |
148 | RxORN = 0x00000020 |
148 | RxORN = 0x00000020 |
149 | RxIDLE = 0x00000010 |
149 | RxIDLE = 0x00000010 |
150 | RxEARLY = 0x00000008 |
150 | RxEARLY = 0x00000008 |
151 | RxERR = 0x00000004 |
151 | RxERR = 0x00000004 |
152 | RxDESC = 0x00000002 |
152 | RxDESC = 0x00000002 |
153 | RxOK = 0x00000001 |
153 | RxOK = 0x00000001 |
154 | 154 | ||
155 | ; Interrupt Enable Register Bits |
155 | ; Interrupt Enable Register Bits |
156 | IE = RxOK + TxOK |
156 | IE = RxOK + TxOK |
157 | 157 | ||
158 | ; Revision ID |
158 | ; Revision ID |
159 | SIS900B_900_REV = 0x03 |
159 | SIS900B_900_REV = 0x03 |
160 | SIS630A_900_REV = 0x80 |
160 | SIS630A_900_REV = 0x80 |
161 | SIS630E_900_REV = 0x81 |
161 | SIS630E_900_REV = 0x81 |
162 | SIS630S_900_REV = 0x82 |
162 | SIS630S_900_REV = 0x82 |
163 | SIS630EA1_900_REV = 0x83 |
163 | SIS630EA1_900_REV = 0x83 |
164 | SIS630ET_900_REV = 0x84 |
164 | SIS630ET_900_REV = 0x84 |
165 | SIS635A_900_REV = 0x90 |
165 | SIS635A_900_REV = 0x90 |
166 | SIS900_960_REV = 0x91 |
166 | SIS900_960_REV = 0x91 |
167 | 167 | ||
168 | ; Receive Filter Control Register Bits |
168 | ; Receive Filter Control Register Bits |
169 | RFEN = 0x80000000 ; enable |
169 | RFEN = 0x80000000 ; enable |
170 | RFAAB = 0x40000000 ; accept all broadcasts |
170 | RFAAB = 0x40000000 ; accept all broadcasts |
171 | RFAAM = 0x20000000 ; accept all multicasts |
171 | RFAAM = 0x20000000 ; accept all multicasts |
172 | RFAAP = 0x10000000 ; accept all packets |
172 | RFAAP = 0x10000000 ; accept all packets |
173 | 173 | ||
174 | ; Reveive Filter Data Mask |
174 | ; Reveive Filter Data Mask |
175 | RFDAT = 0x0000FFFF |
175 | RFDAT = 0x0000FFFF |
176 | 176 | ||
177 | ; Eeprom Address |
177 | ; Eeprom Address |
178 | EEPROMSignature = 0x00 |
178 | EEPROMSignature = 0x00 |
179 | EEPROMVendorID = 0x02 |
179 | EEPROMVendorID = 0x02 |
180 | EEPROMDeviceID = 0x03 |
180 | EEPROMDeviceID = 0x03 |
181 | EEPROMMACAddr = 0x08 |
181 | EEPROMMACAddr = 0x08 |
182 | EEPROMChecksum = 0x0b |
182 | EEPROMChecksum = 0x0b |
183 | 183 | ||
184 | ; The EEPROM commands include the alway-set leading bit. |
184 | ; The EEPROM commands include the alway-set leading bit. |
185 | EEread = 0x0180 |
185 | EEread = 0x0180 |
186 | EEwrite = 0x0140 |
186 | EEwrite = 0x0140 |
187 | EEerase = 0x01C0 |
187 | EEerase = 0x01C0 |
188 | EEwriteEnable = 0x0130 |
188 | EEwriteEnable = 0x0130 |
189 | EEwriteDisable = 0x0100 |
189 | EEwriteDisable = 0x0100 |
190 | EEeraseAll = 0x0120 |
190 | EEeraseAll = 0x0120 |
191 | EEwriteAll = 0x0110 |
191 | EEwriteAll = 0x0110 |
192 | EEaddrMask = 0x013F |
192 | EEaddrMask = 0x013F |
193 | EEcmdShift = 16 |
193 | EEcmdShift = 16 |
194 | 194 | ||
195 | ; For SiS962 or SiS963, request the eeprom software access |
195 | ; For SiS962 or SiS963, request the eeprom software access |
196 | EEREQ = 0x00000400 |
196 | EEREQ = 0x00000400 |
197 | EEDONE = 0x00000200 |
197 | EEDONE = 0x00000200 |
198 | EEGNT = 0x00000100 |
198 | EEGNT = 0x00000100 |
199 | 199 | ||
200 | 200 | ||
201 | include 'proc32.inc' |
201 | include 'proc32.inc' |
202 | include 'imports.inc' |
202 | include 'imports.inc' |
203 | include 'fdo.inc' |
203 | include 'fdo.inc' |
204 | include 'netdrv.inc' |
204 | include 'netdrv.inc' |
205 | 205 | ||
206 | public START |
206 | public START |
207 | public version |
207 | public version |
208 | 208 | ||
209 | 209 | ||
210 | virtual at ebx |
210 | virtual at ebx |
211 | device: |
211 | device: |
212 | 212 | ||
213 | ETH_DEVICE |
213 | ETH_DEVICE |
214 | 214 | ||
215 | .io_addr dd ? |
215 | .io_addr dd ? |
216 | .pci_bus db ? |
216 | .pci_bus db ? |
217 | .pci_dev db ? |
217 | .pci_dev db ? |
218 | .irq_line db ? |
218 | .irq_line db ? |
219 | .cur_rx db ? |
219 | .cur_rx db ? |
220 | .cur_tx db ? |
220 | .cur_tx db ? |
221 | .last_tx db ? |
221 | .last_tx db ? |
222 | .pci_revision db ? |
222 | .pci_revision db ? |
223 | .table_entries db ? |
223 | .table_entries db ? |
224 | 224 | ||
225 | .txd rd (4 * NUM_TX_DESC) |
225 | .txd rd (4 * NUM_TX_DESC) |
226 | .rxd rd (4 * NUM_RX_DESC) |
226 | .rxd rd (4 * NUM_RX_DESC) |
227 | 227 | ||
228 | .size = $ - device |
228 | .size = $ - device |
229 | 229 | ||
230 | end virtual |
230 | end virtual |
231 | 231 | ||
232 | macro ee_delay { |
232 | macro ee_delay { |
233 | push eax |
233 | push eax |
234 | in eax, dx |
234 | in eax, dx |
235 | in eax, dx |
235 | in eax, dx |
236 | in eax, dx |
236 | in eax, dx |
237 | in eax, dx |
237 | in eax, dx |
238 | in eax, dx |
238 | in eax, dx |
239 | in eax, dx |
239 | in eax, dx |
240 | in eax, dx |
240 | in eax, dx |
241 | in eax, dx |
241 | in eax, dx |
242 | in eax, dx |
242 | in eax, dx |
243 | in eax, dx |
243 | in eax, dx |
244 | pop eax |
244 | pop eax |
245 | } |
245 | } |
246 | 246 | ||
247 | 247 | ||
248 | section '.flat' code readable align 16 |
248 | section '.flat' code readable align 16 |
249 | 249 | ||
250 | ; Driver entry point - register our service when the driver is loading. |
250 | ; Driver entry point - register our service when the driver is loading. |
251 | ; TODO: add needed operations when unloading |
251 | ; TODO: add needed operations when unloading |
252 | START: |
252 | START: |
253 | cmp dword [esp+4], 1 |
253 | cmp dword [esp+4], 1 |
254 | jne .exit |
254 | jne .exit |
255 | stdcall RegService, my_service, service_proc |
255 | stdcall RegService, my_service, service_proc |
256 | ret 4 |
256 | ret 4 |
257 | .exit: |
257 | .exit: |
258 | xor eax, eax |
258 | xor eax, eax |
259 | ret 4 |
259 | ret 4 |
260 | 260 | ||
261 | ; Service procedure for the driver - handle all I/O requests for the driver. |
261 | ; Service procedure for the driver - handle all I/O requests for the driver. |
262 | ; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1. |
262 | ; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1. |
263 | service_proc: |
263 | service_proc: |
264 | ; 1. Get parameter from the stack: [esp+4] is the first parameter, |
264 | ; 1. Get parameter from the stack: [esp+4] is the first parameter, |
265 | ; pointer to IOCTL structure. |
265 | ; pointer to IOCTL structure. |
266 | mov edx, [esp+4] ; edx -> IOCTL |
266 | mov edx, [esp+4] ; edx -> IOCTL |
267 | ; 2. Get request code and select a handler for the code. |
267 | ; 2. Get request code and select a handler for the code. |
268 | mov eax, [IOCTL.io_code] |
268 | mov eax, [IOCTL.io_code] |
269 | test eax, eax ; check for SRV_GETVERSION |
269 | test eax, eax ; check for SRV_GETVERSION |
270 | jnz @f |
270 | jnz @f |
271 | ; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION. |
271 | ; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION. |
272 | ; 3a. Output size must be at least 4 bytes. |
272 | ; 3a. Output size must be at least 4 bytes. |
273 | cmp [IOCTL.out_size], 4 |
273 | cmp [IOCTL.out_size], 4 |
274 | jl .fail |
274 | jl .fail |
275 | ; 3b. Write result to the output buffer. |
275 | ; 3b. Write result to the output buffer. |
276 | mov eax, [IOCTL.output] |
276 | mov eax, [IOCTL.output] |
277 | mov [eax], dword API_VERSION |
277 | mov [eax], dword API_VERSION |
278 | ; 3c. Return success. |
278 | ; 3c. Return success. |
279 | xor eax, eax |
279 | xor eax, eax |
280 | ret 4 |
280 | ret 4 |
281 | @@: |
281 | @@: |
282 | dec eax ; check for SRV_HOOK |
282 | dec eax ; check for SRV_HOOK |
283 | jnz .fail |
283 | jnz .fail |
284 | ; 4. This is SRV_HOOK request, input defines the device to hook, no output. |
284 | ; 4. This is SRV_HOOK request, input defines the device to hook, no output. |
285 | ; 4a. The driver works only with PCI devices, |
285 | ; 4a. The driver works only with PCI devices, |
286 | ; so input must be at least 3 bytes long. |
286 | ; so input must be at least 3 bytes long. |
287 | cmp [IOCTL.inp_size], 3 |
287 | cmp [IOCTL.inp_size], 3 |
288 | jl .fail |
288 | jl .fail |
289 | ; 4b. First byte of input is bus type, 1 stands for PCI. |
289 | ; 4b. First byte of input is bus type, 1 stands for PCI. |
290 | mov eax, [IOCTL.input] |
290 | mov eax, [IOCTL.input] |
291 | cmp byte [eax], 1 |
291 | cmp byte [eax], 1 |
292 | jne .fail |
292 | jne .fail |
293 | ; 4c. Second and third bytes of the input define the device: bus and dev. |
293 | ; 4c. Second and third bytes of the input define the device: bus and dev. |
294 | ; Word in bx holds both bytes. |
294 | ; Word in bx holds both bytes. |
295 | mov bx, [eax+1] |
295 | mov bx, [eax+1] |
296 | ; 4d. Check if the device was already hooked, |
296 | ; 4d. Check if the device was already hooked, |
297 | ; scan through the list of known devices. |
297 | ; scan through the list of known devices. |
298 | ; check if the device is already listed |
298 | ; check if the device is already listed |
299 | mov esi, device_list |
299 | mov esi, device_list |
300 | mov ecx, [devices] |
300 | mov ecx, [devices] |
301 | test ecx, ecx |
301 | test ecx, ecx |
302 | jz .firstdevice |
302 | jz .firstdevice |
303 | 303 | ||
304 | ; mov eax, [IOCTL.input] ; get the pci bus and device numbers |
304 | ; mov eax, [IOCTL.input] ; get the pci bus and device numbers |
305 | mov ax, [eax+1] ; |
305 | mov ax, [eax+1] ; |
306 | .nextdevice: |
306 | .nextdevice: |
307 | mov ebx, [esi] |
307 | mov ebx, [esi] |
308 | cmp ax, word [device.pci_bus] ; compare with pci and device num in device list (notice the usage of word instead of byte) |
308 | cmp ax, word [device.pci_bus] ; compare with pci and device num in device list (notice the usage of word instead of byte) |
309 | je .find_devicenum ; Device is already loaded, let's find it's device number |
309 | je .find_devicenum ; Device is already loaded, let's find it's device number |
310 | add esi, 4 |
310 | add esi, 4 |
311 | loop .nextdevice |
311 | loop .nextdevice |
312 | ; 4e. This device doesn't have its own eth_device structure yet, let's create one |
312 | ; 4e. This device doesn't have its own eth_device structure yet, let's create one |
313 | .firstdevice: |
313 | .firstdevice: |
314 | ; 4f. Check that we have place for new device. |
314 | ; 4f. Check that we have place for new device. |
315 | cmp [devices], MAX_DEVICES |
315 | cmp [devices], MAX_DEVICES |
316 | jge .fail |
316 | jge .fail |
317 | ; 4g. Allocate memory for device descriptor and receive+transmit buffers. |
317 | ; 4g. Allocate memory for device descriptor and receive+transmit buffers. |
318 | ; 4h. Zero the structure. |
318 | ; 4h. Zero the structure. |
319 | allocate_and_clear ebx, device.size, .fail |
319 | allocate_and_clear ebx, device.size, .fail |
320 | ; 4i. Save PCI coordinates |
320 | ; 4i. Save PCI coordinates |
321 | mov eax, [IOCTL.input] |
321 | mov eax, [IOCTL.input] |
322 | mov cl, [eax+1] |
322 | mov cl, [eax+1] |
323 | mov [device.pci_bus], cl |
323 | mov [device.pci_bus], cl |
324 | mov cl, [eax+2] |
324 | mov cl, [eax+2] |
325 | mov [device.pci_dev], cl |
325 | mov [device.pci_dev], cl |
326 | ; 4j. Fill in the direct call addresses into the struct. |
326 | ; 4j. Fill in the direct call addresses into the struct. |
327 | ; Note that get_MAC pointer is filled in initialization by probe. |
327 | ; Note that get_MAC pointer is filled in initialization by probe. |
328 | mov [device.reset], reset |
328 | mov [device.reset], reset |
329 | mov [device.transmit], transmit |
329 | mov [device.transmit], transmit |
330 | mov [device.set_MAC], write_mac |
330 | mov [device.set_MAC], write_mac |
331 | mov [device.unload], unload |
331 | mov [device.unload], unload |
332 | mov [device.name], my_service |
332 | mov [device.name], my_service |
333 | 333 | ||
334 | ; 4k. Now, it's time to find the base io addres of the PCI device |
334 | ; 4k. Now, it's time to find the base io addres of the PCI device |
335 | ; TODO: implement check if bus and dev exist on this machine |
335 | ; TODO: implement check if bus and dev exist on this machine |
336 | 336 | ||
337 | ; Now, it's time to find the base io addres of the PCI device |
337 | ; Now, it's time to find the base io addres of the PCI device |
338 | find_io [device.pci_bus], [device.pci_dev], [device.io_addr] |
338 | find_io [device.pci_bus], [device.pci_dev], [device.io_addr] |
339 | 339 | ||
340 | ; We've found the io address, find IRQ now |
340 | ; We've found the io address, find IRQ now |
341 | find_irq [device.pci_bus], [device.pci_dev], [device.irq_line] |
341 | find_irq [device.pci_bus], [device.pci_dev], [device.irq_line] |
342 | 342 | ||
343 | ; 4m. Add new device to the list (required for int_handler). |
343 | ; 4m. Add new device to the list (required for int_handler). |
344 | mov eax, [devices] |
344 | mov eax, [devices] |
345 | mov [device_list+4*eax], ebx |
345 | mov [device_list+4*eax], ebx |
346 | inc [devices] |
346 | inc [devices] |
347 | 347 | ||
348 | ; 4m. Ok, the eth_device structure is ready, let's probe the device |
348 | ; 4m. Ok, the eth_device structure is ready, let's probe the device |
349 | call probe |
349 | call probe |
350 | test eax, eax |
350 | test eax, eax |
351 | jnz .destroy |
351 | jnz .destroy |
352 | ; 4n. If device was successfully initialized, register it for the kernel. |
352 | ; 4n. If device was successfully initialized, register it for the kernel. |
353 | 353 | ||
354 | mov [device.type], NET_TYPE_ETH |
354 | mov [device.type], NET_TYPE_ETH |
355 | call NetRegDev |
355 | call NetRegDev |
356 | 356 | ||
357 | cmp eax, -1 |
357 | cmp eax, -1 |
358 | je .destroy |
358 | je .destroy |
359 | 359 | ||
360 | ret 4 |
360 | ret 4 |
361 | 361 | ||
362 | ; 5. If the device was already loaded, find the device number and return it in eax |
362 | ; 5. If the device was already loaded, find the device number and return it in eax |
363 | 363 | ||
364 | .find_devicenum: |
364 | .find_devicenum: |
365 | call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx |
365 | call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx |
366 | ; into a device number in edi |
366 | ; into a device number in edi |
367 | mov eax, edi ; Application wants it in eax instead |
367 | mov eax, edi ; Application wants it in eax instead |
368 | ret 4 |
368 | ret 4 |
369 | 369 | ||
370 | ; If an error occured, remove all allocated data and exit (returning -1 in eax) |
370 | ; If an error occured, remove all allocated data and exit (returning -1 in eax) |
371 | 371 | ||
372 | .destroy: |
372 | .destroy: |
373 | dec [devices] |
373 | dec [devices] |
374 | ; todo: reset device into virgin state |
374 | ; todo: reset device into virgin state |
375 | 375 | ||
376 | .err: |
376 | .err: |
377 | stdcall KernelFree, ebx |
377 | stdcall KernelFree, ebx |
378 | 378 | ||
379 | .fail: |
379 | .fail: |
380 | xor eax, eax |
380 | xor eax, eax |
381 | ret 4 |
381 | ret 4 |
382 | 382 | ||
383 | 383 | ||
384 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
384 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
385 | ;; ;; |
385 | ;; ;; |
386 | ;; Actual Hardware dependent code starts here ;; |
386 | ;; Actual Hardware dependent code starts here ;; |
387 | ;; ;; |
387 | ;; ;; |
388 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
388 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
389 | 389 | ||
390 | unload: |
390 | unload: |
391 | ; TODO: (in this particular order) |
391 | ; TODO: (in this particular order) |
392 | ; |
392 | ; |
393 | ; - Stop the device |
393 | ; - Stop the device |
394 | ; - Detach int handler |
394 | ; - Detach int handler |
395 | ; - Remove device from local list |
395 | ; - Remove device from local list |
396 | ; - call unregister function in kernel |
396 | ; - call unregister function in kernel |
397 | ; - Remove all allocated structures and buffers the card used |
397 | ; - Remove all allocated structures and buffers the card used |
398 | 398 | ||
399 | or eax,-1 |
399 | or eax,-1 |
400 | 400 | ||
401 | ret |
401 | ret |
402 | 402 | ||
403 | ;*************************************************************************** |
403 | ;*************************************************************************** |
404 | ; |
404 | ; |
405 | ; probe |
405 | ; probe |
406 | ; |
406 | ; |
407 | ; checks the card and enables it |
407 | ; checks the card and enables it |
408 | ; |
408 | ; |
409 | ; TODO: probe mii transceivers |
409 | ; TODO: probe mii transceivers |
410 | ; |
410 | ; |
411 | ;*************************************************************************** |
411 | ;*************************************************************************** |
412 | align 4 |
412 | align 4 |
413 | probe: |
413 | probe: |
414 | DEBUGF 1, "Probe\n" |
414 | DEBUGF 1, "Probe\n" |
415 | 415 | ||
416 | ; wake up device CHECKME |
416 | ; wake up device CHECKME |
417 | movzx eax, [device.pci_bus] |
417 | movzx eax, [device.pci_bus] |
418 | movzx edx, [device.pci_dev] |
418 | movzx edx, [device.pci_dev] |
419 | stdcall PciWrite8, eax, edx, 0x40, 0 |
419 | stdcall PciWrite8, eax, edx, 0x40, 0 |
420 | 420 | ||
421 | make_bus_master [device.pci_bus], [device.pci_dev] |
421 | make_bus_master [device.pci_bus], [device.pci_dev] |
422 | adjust_latency [device.pci_bus], [device.pci_dev], 64 |
422 | adjust_latency [device.pci_bus], [device.pci_dev], 64 |
423 | 423 | ||
424 | ; Get Card Revision |
424 | ; Get Card Revision |
425 | movzx eax, [device.pci_bus] |
425 | movzx eax, [device.pci_bus] |
426 | movzx edx, [device.pci_dev] |
426 | movzx edx, [device.pci_dev] |
427 | stdcall PciRead8, eax, edx, 0x08 |
427 | stdcall PciRead8, eax, edx, 0x08 |
428 | mov [device.pci_revision], al ; save the revision for later use |
428 | mov [device.pci_revision], al ; save the revision for later use |
429 | 429 | ||
430 | ; Look up through the specific_table |
430 | ; Look up through the specific_table |
431 | mov esi, specific_table |
431 | mov esi, specific_table |
432 | .tableloop: |
432 | .tableloop: |
433 | cmp dword [esi], 0 ; Check if we reached end of the list |
433 | cmp dword [esi], 0 ; Check if we reached end of the list |
434 | je .notsupported |
434 | je .notsupported |
435 | cmp al, [esi] ; Check if revision is OK |
435 | cmp al, [esi] ; Check if revision is OK |
436 | je .ok |
436 | je .ok |
437 | add esi, 12 ; Advance to next entry |
437 | add esi, 12 ; Advance to next entry |
438 | jmp .tableloop |
438 | jmp .tableloop |
439 | 439 | ||
440 | .ok: |
440 | .ok: |
441 | mov eax, [esi + 4] ; Get pointer to "get MAC" function |
441 | mov eax, [esi + 4] ; Get pointer to "get MAC" function |
442 | mov [device.get_MAC], eax |
442 | mov [device.get_MAC], eax |
443 | 443 | ||
444 | call [device.get_MAC] |
444 | call [device.get_MAC] |
445 | 445 | ||
446 | ; Set table entries |
446 | ; Set table entries |
447 | mov [device.table_entries], 16 |
447 | mov [device.table_entries], 16 |
448 | cmp [device.pci_revision], SIS635A_900_REV |
448 | cmp [device.pci_revision], SIS635A_900_REV |
449 | jae @f |
449 | jae @f |
450 | cmp [device.pci_revision], SIS900B_900_REV |
450 | cmp [device.pci_revision], SIS900B_900_REV |
451 | je @f |
451 | je @f |
452 | mov [device.table_entries], 8 |
452 | mov [device.table_entries], 8 |
453 | @@: |
453 | @@: |
454 | 454 | ||
455 | ; TODO: Probe for mii transceiver |
455 | ; TODO: Probe for mii transceiver |
456 | 456 | ||
457 | jmp reset |
457 | jmp reset |
458 | 458 | ||
459 | .notsupported: |
459 | .notsupported: |
460 | DEBUGF 1, "Device not supported\n" |
460 | DEBUGF 1, "Device not supported\n" |
461 | or eax, -1 |
461 | or eax, -1 |
462 | 462 | ||
463 | ret |
463 | ret |
464 | 464 | ||
465 | reset: |
465 | reset: |
466 | 466 | ||
467 | DEBUGF 1, "reset\n" |
467 | DEBUGF 1, "reset\n" |
468 | 468 | ||
469 | movzx eax, [device.irq_line] |
469 | movzx eax, [device.irq_line] |
470 | stdcall AttachIntHandler, eax, int_handler, 0 |
470 | stdcall AttachIntHandler, eax, int_handler, 0 |
471 | 471 | ||
472 | ;-------------------------------------------- |
472 | ;-------------------------------------------- |
473 | ; Disable Interrupts and reset Receive Filter |
473 | ; Disable Interrupts and reset Receive Filter |
474 | 474 | ||
475 | set_io 0 |
475 | set_io 0 |
476 | set_io ier |
476 | set_io ier |
477 | xor eax, eax |
477 | xor eax, eax |
478 | out dx, eax |
478 | out dx, eax |
479 | 479 | ||
480 | set_io imr |
480 | set_io imr |
481 | out dx, eax |
481 | out dx, eax |
482 | 482 | ||
483 | set_io rfcr |
483 | set_io rfcr |
484 | out dx, eax |
484 | out dx, eax |
485 | 485 | ||
486 | ;----------- |
486 | ;----------- |
487 | ; Reset Card |
487 | ; Reset Card |
488 | 488 | ||
489 | set_io cr |
489 | set_io cr |
490 | in eax, dx ; Get current Command Register |
490 | in eax, dx ; Get current Command Register |
491 | or eax, RESET + RxRESET + TxRESET ; set flags |
491 | or eax, RESET + RxRESET + TxRESET ; set flags |
492 | out dx, eax ; Write new Command Register |
492 | out dx, eax ; Write new Command Register |
493 | 493 | ||
494 | ;---------- |
494 | ;---------- |
495 | ; Wait loop |
495 | ; Wait loop |
496 | 496 | ||
497 | set_io isr |
497 | set_io isr |
498 | mov ecx, 1000 |
498 | mov ecx, 1000 |
499 | .loop: |
499 | .loop: |
500 | dec ecx |
500 | dec ecx |
501 | jz .fail |
501 | jz .fail |
502 | in eax, dx ; read interrupt status |
502 | in eax, dx ; read interrupt status |
503 | test eax, TxRCMP + RxRCMP |
503 | test eax, TxRCMP + RxRCMP |
504 | jz .loop |
504 | jz .loop |
505 | DEBUGF 1, "status=%x\n", eax |
505 | DEBUGF 1, "status=%x\n", eax |
506 | 506 | ||
507 | ;------------------------------------------------------ |
507 | ;------------------------------------------------------ |
508 | ; Set Configuration Register depending on Card Revision |
508 | ; Set Configuration Register depending on Card Revision |
509 | 509 | ||
510 | set_io cfg |
510 | set_io cfg |
511 | mov eax, PESEL ; Configuration Register Bit |
511 | mov eax, PESEL ; Configuration Register Bit |
512 | cmp [device.pci_revision], SIS635A_900_REV |
512 | cmp [device.pci_revision], SIS635A_900_REV |
513 | je .match |
513 | je .match |
514 | cmp [device.pci_revision], SIS900B_900_REV ; Check card revision |
514 | cmp [device.pci_revision], SIS900B_900_REV ; Check card revision |
515 | jne .done |
515 | jne .done |
516 | .match: ; Revision match |
516 | .match: ; Revision match |
517 | or eax, RND_CNT ; Configuration Register Bit |
517 | or eax, RND_CNT ; Configuration Register Bit |
518 | .done: |
518 | .done: |
519 | out dx, eax |
519 | out dx, eax |
520 | 520 | ||
521 | DEBUGF 1, "Initialising RX Filter\n" |
521 | DEBUGF 1, "Initialising RX Filter\n" |
522 | 522 | ||
523 | ; Get Receive Filter Control Register |
523 | ; Get Receive Filter Control Register |
524 | set_io rfcr |
524 | set_io rfcr |
525 | in eax, dx |
525 | in eax, dx |
526 | push eax |
526 | push eax |
527 | 527 | ||
528 | ; disable packet filtering before setting filter |
528 | ; disable packet filtering before setting filter |
529 | and eax, not RFEN |
529 | and eax, not RFEN |
530 | out dx, eax |
530 | out dx, eax |
531 | 531 | ||
532 | ; load MAC addr to filter data register |
532 | ; load MAC addr to filter data register |
533 | xor ecx, ecx |
533 | xor ecx, ecx |
534 | .macloop: |
534 | .macloop: |
535 | mov eax, ecx |
535 | mov eax, ecx |
536 | set_io 0 |
536 | set_io 0 |
537 | set_io rfcr |
537 | set_io rfcr |
538 | shl eax, 16 ; high word of eax tells card which mac byte to write |
538 | shl eax, 16 ; high word of eax tells card which mac byte to write |
539 | out dx, eax ; |
539 | out dx, eax ; |
540 | set_io rfdr |
540 | set_io rfdr |
541 | mov ax, word [device.mac + ecx*2] ; Get Mac ID word |
541 | mov ax, word [device.mac + ecx*2] ; Get Mac ID word |
542 | out dx, ax ; Send Mac ID |
542 | out dx, ax ; Send Mac ID |
543 | inc cl ; send next word |
543 | inc cl ; send next word |
544 | cmp cl, 3 ; more to send? |
544 | cmp cl, 3 ; more to send? |
545 | jne .macloop |
545 | jne .macloop |
546 | 546 | ||
547 | ; enable packet filtering |
547 | ; enable packet filtering |
548 | pop eax ; old register value |
548 | pop eax ; old register value |
549 | set_io rfcr |
549 | set_io rfcr |
550 | or eax, RFEN ; enable filtering |
550 | or eax, RFEN ; enable filtering |
551 | out dx, eax ; set register |
551 | out dx, eax ; set register |
552 | 552 | ||
553 | DEBUGF 1, "Initialising TX Descriptors\n" |
553 | DEBUGF 1, "Initialising TX Descriptors\n" |
554 | 554 | ||
555 | mov ecx, NUM_TX_DESC |
555 | mov ecx, NUM_TX_DESC |
556 | lea esi, [device.txd] |
556 | lea esi, [device.txd] |
557 | .txdescloop: |
557 | .txdescloop: |
558 | lea eax, [esi + 16] ; next ptr |
558 | lea eax, [esi + 16] ; next ptr |
559 | GetRealAddr |
559 | GetRealAddr |
560 | mov dword [esi], eax ; link to next desc |
560 | mov dword [esi], eax ; link to next desc |
561 | mov dword [esi + 4], 0 ; status field |
561 | mov dword [esi + 4], 0 ; status field |
562 | mov dword [esi + 8], 0 ; ptr to buffer |
562 | mov dword [esi + 8], 0 ; ptr to buffer |
563 | add esi, 16 |
563 | add esi, 16 |
564 | dec ecx |
564 | dec ecx |
565 | jnz .txdescloop |
565 | jnz .txdescloop |
566 | 566 | ||
567 | lea eax, [device.txd] |
567 | lea eax, [device.txd] |
568 | GetRealAddr |
568 | GetRealAddr |
569 | mov dword [esi - 16], eax ; correct last descriptor link ptr |
569 | mov dword [esi - 16], eax ; correct last descriptor link ptr |
570 | 570 | ||
571 | set_io txdp ; TX Descriptor Pointer |
571 | set_io txdp ; TX Descriptor Pointer |
572 | ; lea eax, [device.txd] |
572 | ; lea eax, [device.txd] |
573 | ; GetRealAddr |
573 | ; GetRealAddr |
574 | out dx, eax |
574 | out dx, eax |
575 | 575 | ||
576 | mov [device.cur_tx], 0 ; Set current tx descriptor to 0 |
576 | mov [device.cur_tx], 0 ; Set current tx descriptor to 0 |
577 | mov [device.last_tx], 0 |
577 | mov [device.last_tx], 0 |
578 | 578 | ||
579 | DEBUGF 1, "Initialising RX Descriptors\n" |
579 | DEBUGF 1, "Initialising RX Descriptors\n" |
580 | 580 | ||
581 | mov ecx, NUM_RX_DESC |
581 | mov ecx, NUM_RX_DESC |
582 | lea esi, [device.rxd] |
582 | lea esi, [device.rxd] |
583 | .rxdescloop: |
583 | .rxdescloop: |
584 | lea eax, [esi + 16] ; next ptr |
584 | lea eax, [esi + 16] ; next ptr |
585 | GetRealAddr |
585 | GetRealAddr |
586 | mov dword [esi], eax |
586 | mov dword [esi], eax |
587 | mov dword [esi + 4], RX_BUFF_SZ ; size |
587 | mov dword [esi + 4], RX_BUFF_SZ ; size |
588 | 588 | ||
589 | push ecx esi |
589 | push ecx esi |
590 | stdcall KernelAlloc, RX_BUFF_SZ |
590 | stdcall KernelAlloc, RX_BUFF_SZ |
591 | pop esi ecx |
591 | pop esi ecx |
592 | test eax, eax |
592 | test eax, eax |
593 | jz .fail |
593 | jz .fail |
594 | mov dword [esi + 12], eax ; address |
594 | mov dword [esi + 12], eax ; address |
595 | GetRealAddr |
595 | GetRealAddr |
596 | mov dword [esi + 8], eax ; real address |
596 | mov dword [esi + 8], eax ; real address |
597 | add esi, 16 |
597 | add esi, 16 |
598 | dec ecx |
598 | dec ecx |
599 | jnz .rxdescloop |
599 | jnz .rxdescloop |
600 | 600 | ||
601 | lea eax, [device.rxd] |
601 | lea eax, [device.rxd] |
602 | GetRealAddr |
602 | GetRealAddr |
603 | mov dword [esi - 16], eax ; correct last descriptor link ptr |
603 | mov dword [esi - 16], eax ; correct last descriptor link ptr |
604 | 604 | ||
605 | set_io 0 |
605 | set_io 0 |
606 | set_io rxdp |
606 | set_io rxdp |
607 | ; lea eax, [device.rxd] |
607 | ; lea eax, [device.rxd] |
608 | ; GetRealAddr |
608 | ; GetRealAddr |
609 | out dx, eax |
609 | out dx, eax |
610 | 610 | ||
611 | mov [device.cur_rx], 0 ; Set current rx descriptor to 0 |
611 | mov [device.cur_rx], 0 ; Set current rx descriptor to 0 |
612 | 612 | ||
613 | DEBUGF 1, "setting RX mode\n" |
613 | DEBUGF 1, "setting RX mode\n" |
614 | 614 | ||
615 | xor cl, cl |
615 | xor cl, cl |
616 | .rxfilterloop: |
616 | .rxfilterloop: |
617 | set_io 0 |
617 | set_io 0 |
618 | set_io rfcr ; Receive Filter Control Reg offset |
618 | set_io rfcr ; Receive Filter Control Reg offset |
619 | mov eax, 4 ; determine table entry |
619 | mov eax, 4 ; determine table entry |
620 | add al, cl |
620 | add al, cl |
621 | shl eax, 16 |
621 | shl eax, 16 |
622 | out dx, eax ; tell card which entry to modify |
622 | out dx, eax ; tell card which entry to modify |
623 | 623 | ||
624 | set_io rfdr ; Receive Filter Control Reg offset |
624 | set_io rfdr ; Receive Filter Control Reg offset |
625 | mov eax, 0xffff ; entry value |
625 | mov eax, 0xffff ; entry value |
626 | out dx, ax ; write value to table in card |
626 | out dx, ax ; write value to table in card |
627 | 627 | ||
628 | inc cl ; next entry |
628 | inc cl ; next entry |
629 | cmp cl, [device.table_entries] |
629 | cmp cl, [device.table_entries] |
630 | jb .rxfilterloop |
630 | jb .rxfilterloop |
631 | 631 | ||
632 | set_io rfcr ; Receive Filter Control Register offset |
632 | set_io rfcr ; Receive Filter Control Register offset |
633 | mov eax, RFAAB + RFAAM + RFAAP + RFEN |
633 | mov eax, RFAAB + RFAAM + RFAAP + RFEN |
634 | out dx, eax |
634 | out dx, eax |
635 | 635 | ||
636 | set_io rxcfg ; Receive Config Register offset |
636 | set_io rxcfg ; Receive Config Register offset |
637 | mov eax, ATX + RX_DMA + 2 ; 0x2 : RX Drain Threshold = 8*8=64 bytes |
637 | mov eax, ATX + RX_DMA + 2 ; 0x2 : RX Drain Threshold = 8*8=64 bytes |
638 | out dx, eax |
638 | out dx, eax |
639 | 639 | ||
640 | DEBUGF 1, "setting TX mode\n" |
640 | DEBUGF 1, "setting TX mode\n" |
641 | 641 | ||
642 | set_io txcfg ; Transmit config Register offset |
642 | set_io txcfg ; Transmit config Register offset |
643 | mov eax, ATP + HBI + CSI + TX_DMA + 0x120 |
643 | mov eax, ATP + HBI + CSI + TX_DMA + 0x120 |
644 | ; TX Fill threshold = 0x100 |
644 | ; TX Fill threshold = 0x100 |
645 | ; TX Drain Threshold = 0x20 |
645 | ; TX Drain Threshold = 0x20 |
646 | out dx, eax |
646 | out dx, eax |
647 | 647 | ||
648 | DEBUGF 1, "Enabling interrupts\n" |
648 | DEBUGF 1, "Enabling interrupts\n" |
649 | 649 | ||
650 | set_io imr |
650 | set_io imr |
651 | mov eax, IE ; Interrupt enable mask |
651 | mov eax, IE ; Interrupt enable mask |
652 | out dx, eax |
652 | out dx, eax |
653 | 653 | ||
654 | set_io cr |
654 | set_io cr |
655 | in eax, dx |
655 | in eax, dx |
656 | or eax, RxENA ; Enable Receive |
656 | or eax, RxENA ; Enable Receive |
657 | out dx, eax |
657 | out dx, eax |
658 | 658 | ||
659 | set_io ier ; Interrupt enable |
659 | set_io ier ; Interrupt enable |
660 | mov eax, 1 |
660 | mov eax, 1 |
661 | out dx, eax |
661 | out dx, eax |
662 | 662 | ||
663 | mov [device.mtu], 1514 |
663 | mov [device.mtu], 1514 |
664 | xor eax, eax |
664 | xor eax, eax |
665 | 665 | ||
666 | ret |
666 | ret |
667 | 667 | ||
668 | .fail: |
668 | .fail: |
669 | DEBUGF 1, "Resetting device failed\n" |
669 | DEBUGF 1, "Resetting device failed\n" |
670 | or eax, -1 |
670 | or eax, -1 |
671 | 671 | ||
672 | ret |
672 | ret |
673 | 673 | ||
674 | 674 | ||
675 | ;*************************************************************************** |
675 | ;*************************************************************************** |
676 | ; |
676 | ; |
677 | ; SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model |
677 | ; SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model |
678 | ; |
678 | ; |
679 | ; SiS962 or SiS963 model, use EEPROM to store MAC address. |
679 | ; SiS962 or SiS963 model, use EEPROM to store MAC address. |
680 | ; EEPROM is shared by LAN and 1394. |
680 | ; EEPROM is shared by LAN and 1394. |
681 | ; When access EEPROM, send EEREQ signal to hardware first, and wait for EEGNT. |
681 | ; When access EEPROM, send EEREQ signal to hardware first, and wait for EEGNT. |
682 | ; If EEGNT is ON, EEPROM is permitted to be accessed by LAN, otherwise is not. |
682 | ; If EEGNT is ON, EEPROM is permitted to be accessed by LAN, otherwise is not. |
683 | ; After MAC address is read from EEPROM, send |
683 | ; After MAC address is read from EEPROM, send |
684 | ; EEDONE signal to refuse EEPROM access by LAN. |
684 | ; EEDONE signal to refuse EEPROM access by LAN. |
685 | ; The EEPROM map of SiS962 or SiS963 is different to SiS900. |
685 | ; The EEPROM map of SiS962 or SiS963 is different to SiS900. |
686 | ; The signature field in SiS962 or SiS963 spec is meaningless. |
686 | ; The signature field in SiS962 or SiS963 spec is meaningless. |
687 | ; |
687 | ; |
688 | ; Return 0 is EAX = failure |
688 | ; Return 0 is EAX = failure |
689 | ; |
689 | ; |
690 | ;*************************************************************************** |
690 | ;*************************************************************************** |
691 | align 4 |
691 | align 4 |
692 | SIS960_get_mac_addr: |
692 | SIS960_get_mac_addr: |
693 | DEBUGF 1, "SIS960 - get mac: " |
693 | DEBUGF 1, "SIS960 - get mac: " |
694 | 694 | ||
695 | ;------------------------------- |
695 | ;------------------------------- |
696 | ; Send Request for eeprom access |
696 | ; Send Request for eeprom access |
697 | 697 | ||
698 | set_io 0 |
698 | set_io 0 |
699 | set_io mear ; Eeprom access register |
699 | set_io mear ; Eeprom access register |
700 | mov eax, EEREQ ; Request access to eeprom |
700 | mov eax, EEREQ ; Request access to eeprom |
701 | out dx, eax ; Send request |
701 | out dx, eax ; Send request |
702 | 702 | ||
703 | ;----------------------------------------------------- |
703 | ;----------------------------------------------------- |
704 | ; Loop 4000 times and if access not granted, error out |
704 | ; Loop 4000 times and if access not granted, error out |
705 | 705 | ||
706 | mov ecx, 4000 |
706 | mov ecx, 4000 |
707 | .loop: |
707 | .loop: |
708 | in eax, dx ; get eeprom status |
708 | in eax, dx ; get eeprom status |
709 | test eax, EEGNT ; see if eeprom access granted flag is set |
709 | test eax, EEGNT ; see if eeprom access granted flag is set |
710 | jnz .got_access ; if it is, go access the eeprom |
710 | jnz .got_access ; if it is, go access the eeprom |
711 | loop .loop ; else keep waiting |
711 | loop .loop ; else keep waiting |
712 | 712 | ||
713 | DEBUGF 1, "Access to EEprom failed!\n", 0 |
713 | DEBUGF 1, "Access to EEprom failed!\n", 0 |
714 | 714 | ||
715 | set_io mear ; Eeprom access register |
715 | set_io mear ; Eeprom access register |
716 | mov eax, EEDONE ; tell eeprom we are done |
716 | mov eax, EEDONE ; tell eeprom we are done |
717 | out dx, eax |
717 | out dx, eax |
718 | 718 | ||
719 | or eax, -1 ; error |
719 | or eax, -1 ; error |
720 | ret |
720 | ret |
721 | 721 | ||
722 | .got_access: |
722 | .got_access: |
723 | 723 | ||
724 | ;------------------------------------------ |
724 | ;------------------------------------------ |
725 | ; EEprom access granted, read MAC from card |
725 | ; EEprom access granted, read MAC from card |
726 | 726 | ||
727 | ; zero based so 3-16 bit reads will take place |
727 | ; zero based so 3-16 bit reads will take place |
728 | 728 | ||
729 | mov ecx, 2 |
729 | mov ecx, 2 |
730 | .read_loop: |
730 | .read_loop: |
731 | mov eax, EEPROMMACAddr ; Base Mac Address |
731 | mov eax, EEPROMMACAddr ; Base Mac Address |
732 | add eax, ecx ; Current Mac Byte Offset |
732 | add eax, ecx ; Current Mac Byte Offset |
733 | push ecx |
733 | push ecx |
734 | call read_eeprom ; try to read 16 bits |
734 | call read_eeprom ; try to read 16 bits |
735 | pop ecx |
735 | pop ecx |
736 | mov word [device.mac+ecx*2], ax ; save 16 bits to the MAC ID varible |
736 | mov word [device.mac+ecx*2], ax ; save 16 bits to the MAC ID varible |
737 | dec ecx ; one less word to read |
737 | dec ecx ; one less word to read |
738 | jns .read_loop ; if more read more |
738 | jns .read_loop ; if more read more |
739 | mov eax, 1 ; return non-zero indicating success |
739 | mov eax, 1 ; return non-zero indicating success |
740 | 740 | ||
741 | DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 |
741 | DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 |
742 | 742 | ||
743 | ;------------------------------------- |
743 | ;------------------------------------- |
744 | ; Tell EEPROM We are Done Accessing It |
744 | ; Tell EEPROM We are Done Accessing It |
745 | 745 | ||
746 | .done: |
746 | .done: |
747 | set_io 0 |
747 | set_io 0 |
748 | set_io mear ; Eeprom access register |
748 | set_io mear ; Eeprom access register |
749 | mov eax, EEDONE ; tell eeprom we are done |
749 | mov eax, EEDONE ; tell eeprom we are done |
750 | out dx, eax |
750 | out dx, eax |
751 | 751 | ||
752 | xor eax, eax ; ok |
752 | xor eax, eax ; ok |
753 | ret |
753 | ret |
754 | 754 | ||
755 | 755 | ||
756 | 756 | ||
757 | 757 | ||
758 | ;*************************************************************************** |
758 | ;*************************************************************************** |
759 | ; |
759 | ; |
760 | ; get_mac_addr: - Get MAC address for stand alone SiS900 model |
760 | ; get_mac_addr: - Get MAC address for stand alone SiS900 model |
761 | ; |
761 | ; |
762 | ; Older SiS900 and friends, use EEPROM to store MAC address. |
762 | ; Older SiS900 and friends, use EEPROM to store MAC address. |
763 | ; |
763 | ; |
764 | ;*************************************************************************** |
764 | ;*************************************************************************** |
765 | align 4 |
765 | align 4 |
766 | SIS900_get_mac_addr: |
766 | SIS900_get_mac_addr: |
767 | DEBUGF 1, "SIS900 - get mac: " |
767 | DEBUGF 1, "SIS900 - get mac: " |
768 | 768 | ||
769 | ;------------------------------------ |
769 | ;------------------------------------ |
770 | ; check to see if we have sane EEPROM |
770 | ; check to see if we have sane EEPROM |
771 | 771 | ||
772 | mov eax, EEPROMSignature ; Base Eeprom Signature |
772 | mov eax, EEPROMSignature ; Base Eeprom Signature |
773 | call read_eeprom ; try to read 16 bits |
773 | call read_eeprom ; try to read 16 bits |
774 | cmp ax, 0xffff |
774 | cmp ax, 0xffff |
775 | je .err |
775 | je .err |
776 | test ax, ax |
776 | test ax, ax |
777 | je .err |
777 | je .err |
778 | 778 | ||
779 | ;----------- |
779 | ;----------- |
780 | ; Read MacID |
780 | ; Read MacID |
781 | 781 | ||
782 | ; zero based so 3-16 bit reads will take place |
782 | ; zero based so 3-16 bit reads will take place |
783 | 783 | ||
784 | mov ecx, 2 |
784 | mov ecx, 2 |
785 | .loop: |
785 | .loop: |
786 | mov eax, EEPROMMACAddr ; Base Mac Address |
786 | mov eax, EEPROMMACAddr ; Base Mac Address |
787 | add eax, ecx ; Current Mac Byte Offset |
787 | add eax, ecx ; Current Mac Byte Offset |
788 | push ecx |
788 | push ecx |
789 | call read_eeprom ; try to read 16 bits |
789 | call read_eeprom ; try to read 16 bits |
790 | pop ecx |
790 | pop ecx |
791 | mov word [device.mac+ecx*2], ax ; save 16 bits to the MAC ID storage |
791 | mov word [device.mac+ecx*2], ax ; save 16 bits to the MAC ID storage |
792 | dec ecx ; one less word to read |
792 | dec ecx ; one less word to read |
793 | jns .loop ; if more read more |
793 | jns .loop ; if more read more |
794 | 794 | ||
795 | DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 |
795 | DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 |
796 | 796 | ||
797 | xor eax, eax |
797 | xor eax, eax |
798 | ret |
798 | ret |
799 | 799 | ||
800 | 800 | ||
801 | .err: |
801 | .err: |
802 | DEBUGF 1, "Access to EEprom failed!\n", 0 |
802 | DEBUGF 1, "Access to EEprom failed!\n", 0 |
803 | 803 | ||
804 | or eax, -1 |
804 | or eax, -1 |
805 | ret |
805 | ret |
806 | 806 | ||
807 | 807 | ||
808 | ;*************************************************************************** |
808 | ;*************************************************************************** |
809 | ; |
809 | ; |
810 | ; Get_Mac_SIS635_900_REV: - Get MAC address for model 635 |
810 | ; Get_Mac_SIS635_900_REV: - Get MAC address for model 635 |
811 | ; |
811 | ; |
812 | ;*************************************************************************** |
812 | ;*************************************************************************** |
813 | align 4 |
813 | align 4 |
814 | Get_Mac_SIS635_900_REV: |
814 | Get_Mac_SIS635_900_REV: |
815 | DEBUGF 1, "SIS635 - get mac: " |
815 | DEBUGF 1, "SIS635 - get mac: " |
816 | 816 | ||
817 | set_io 0 |
817 | set_io 0 |
818 | set_io rfcr |
818 | set_io rfcr |
819 | in eax, dx |
819 | in eax, dx |
820 | mov esi, eax |
820 | mov esi, eax |
821 | 821 | ||
822 | set_io cr |
822 | set_io cr |
823 | or eax, RELOAD |
823 | or eax, RELOAD |
824 | out dx, eax |
824 | out dx, eax |
825 | 825 | ||
826 | xor eax, eax |
826 | xor eax, eax |
827 | out dx, eax |
827 | out dx, eax |
828 | 828 | ||
829 | ;----------------------------------------------- |
829 | ;----------------------------------------------- |
830 | ; Disable packet filtering before setting filter |
830 | ; Disable packet filtering before setting filter |
831 | 831 | ||
832 | set_io rfcr |
832 | set_io rfcr |
833 | mov eax, esi |
833 | mov eax, esi |
834 | and eax, not RFEN |
834 | and eax, not RFEN |
835 | out dx, eax |
835 | out dx, eax |
836 | 836 | ||
837 | ;--------------------------------- |
837 | ;--------------------------------- |
838 | ; Load MAC to filter data register |
838 | ; Load MAC to filter data register |
839 | 839 | ||
840 | xor ecx, ecx |
840 | xor ecx, ecx |
841 | lea edi, [device.mac] |
841 | lea edi, [device.mac] |
842 | .loop: |
842 | .loop: |
843 | set_io 0 |
843 | set_io 0 |
844 | set_io rfcr |
844 | set_io rfcr |
845 | mov eax, ecx |
845 | mov eax, ecx |
846 | shl eax, RFADDR_shift |
846 | shl eax, RFADDR_shift |
847 | out dx, eax |
847 | out dx, eax |
848 | 848 | ||
849 | set_io rfdr |
849 | set_io rfdr |
850 | in ax, dx |
850 | in ax, dx |
851 | stosw |
851 | stosw |
852 | inc ecx |
852 | inc ecx |
853 | cmp ecx, 3 |
853 | cmp ecx, 3 |
854 | jb .loop |
854 | jb .loop |
855 | 855 | ||
856 | ;------------------------ |
856 | ;------------------------ |
857 | ; Enable packet filtering |
857 | ; Enable packet filtering |
858 | 858 | ||
859 | set_io rfcr |
859 | set_io rfcr |
860 | mov eax, esi |
860 | mov eax, esi |
861 | or eax, RFEN |
861 | or eax, RFEN |
862 | out dx, eax |
862 | out dx, eax |
863 | 863 | ||
864 | DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 |
864 | DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 |
865 | 865 | ||
866 | xor eax, eax |
866 | xor eax, eax |
867 | ret |
867 | ret |
868 | 868 | ||
869 | ;*************************************************************************** |
869 | ;*************************************************************************** |
870 | ; |
870 | ; |
871 | ; read_eeprom |
871 | ; read_eeprom |
872 | ; |
872 | ; |
873 | ; reads and returns a given location from EEPROM |
873 | ; reads and returns a given location from EEPROM |
874 | ; |
874 | ; |
875 | ; IN: si = addr |
875 | ; IN: si = addr |
876 | ; OUT: ax = data |
876 | ; OUT: ax = data |
877 | ; |
877 | ; |
878 | ;*************************************************************************** |
878 | ;*************************************************************************** |
879 | align 4 |
879 | align 4 |
880 | read_eeprom: |
880 | read_eeprom: |
881 | 881 | ||
882 | set_io 0 |
882 | set_io 0 |
883 | set_io mear |
883 | set_io mear |
884 | 884 | ||
885 | xor eax, eax ; start send |
885 | xor eax, eax ; start send |
886 | out dx, eax |
886 | out dx, eax |
887 | ee_delay |
887 | ee_delay |
888 | 888 | ||
889 | or eax, EECLK |
889 | or eax, EECLK |
890 | out dx, eax |
890 | out dx, eax |
891 | ee_delay |
891 | ee_delay |
892 | 892 | ||
893 | ;------------------------------------ |
893 | ;------------------------------------ |
894 | ; Send the read command |
894 | ; Send the read command |
895 | 895 | ||
896 | or esi, EEread |
896 | or esi, EEread |
897 | mov ecx, 1 shl 9 |
897 | mov ecx, 1 shl 9 |
898 | 898 | ||
899 | .loop: |
899 | .loop: |
900 | mov eax, EECS |
900 | mov eax, EECS |
901 | test esi, ecx |
901 | test esi, ecx |
902 | jz @f |
902 | jz @f |
903 | or eax, EEDI |
903 | or eax, EEDI |
904 | @@: |
904 | @@: |
905 | out dx, eax |
905 | out dx, eax |
906 | ee_delay |
906 | ee_delay |
907 | 907 | ||
908 | or eax, EECLK |
908 | or eax, EECLK |
909 | out dx, eax |
909 | out dx, eax |
910 | ee_delay |
910 | ee_delay |
911 | 911 | ||
912 | shr esi, 1 |
912 | shr esi, 1 |
913 | jnc .loop |
913 | jnc .loop |
914 | 914 | ||
915 | mov eax, EECS |
915 | mov eax, EECS |
916 | out dx, eax |
916 | out dx, eax |
917 | ee_delay |
917 | ee_delay |
918 | 918 | ||
919 | ;------------------------ |
919 | ;------------------------ |
920 | ; Read 16-bits of data in |
920 | ; Read 16-bits of data in |
921 | 921 | ||
922 | xor esi, esi |
922 | xor esi, esi |
923 | mov cx, 16 |
923 | mov cx, 16 |
924 | .loop2: |
924 | .loop2: |
925 | mov eax, EECS |
925 | mov eax, EECS |
926 | out dx, eax |
926 | out dx, eax |
927 | ee_delay |
927 | ee_delay |
928 | 928 | ||
929 | or eax, EECLK |
929 | or eax, EECLK |
930 | out dx, eax |
930 | out dx, eax |
931 | ee_delay |
931 | ee_delay |
932 | 932 | ||
933 | in eax, dx |
933 | in eax, dx |
934 | shl esi, 1 |
934 | shl esi, 1 |
935 | test eax, EEDO |
935 | test eax, EEDO |
936 | jz @f |
936 | jz @f |
937 | inc esi |
937 | inc esi |
938 | @@: |
938 | @@: |
939 | loop .loop2 |
939 | loop .loop2 |
940 | 940 | ||
941 | ;---------------------------- |
941 | ;---------------------------- |
942 | ; Terminate the EEPROM access |
942 | ; Terminate the EEPROM access |
943 | 943 | ||
944 | xor eax, eax |
944 | xor eax, eax |
945 | out dx, eax |
945 | out dx, eax |
946 | ee_delay |
946 | ee_delay |
947 | 947 | ||
948 | mov eax, EECLK |
948 | mov eax, EECLK |
949 | out dx, eax |
949 | out dx, eax |
950 | ee_delay |
950 | ee_delay |
951 | 951 | ||
952 | movzx eax, si |
952 | movzx eax, si |
953 | 953 | ||
954 | ret |
954 | ret |
955 | 955 | ||
956 | 956 | ||
957 | 957 | ||
958 | align 4 |
958 | align 4 |
959 | write_mac: |
959 | write_mac: |
960 | DEBUGF 1,'Setting MAC is not supported for SIS900 card.\n' |
960 | DEBUGF 1,'Setting MAC is not supported for SIS900 card.\n' |
961 | add esp, 6 |
961 | add esp, 6 |
962 | ret |
962 | ret |
963 | 963 | ||
964 | 964 | ||
965 | 965 | ||
966 | 966 | ||
967 | ;*************************************************************************** |
967 | ;*************************************************************************** |
968 | ; Function |
968 | ; Function |
969 | ; transmit |
969 | ; transmit |
970 | ; Description |
970 | ; Description |
971 | ; Transmits a packet of data via the ethernet card |
971 | ; Transmits a packet of data via the ethernet card |
972 | ; buffer pointer in [esp+4] |
972 | ; buffer pointer in [esp+4] |
973 | ; size of buffer in [esp+8] |
973 | ; size of buffer in [esp+8] |
974 | ; pointer to device structure in ebx |
974 | ; pointer to device structure in ebx |
975 | ; |
975 | ; |
976 | ;*************************************************************************** |
976 | ;*************************************************************************** |
977 | align 4 |
977 | align 4 |
978 | transmit: |
978 | transmit: |
979 | DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8] |
979 | DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8] |
980 | mov eax, [esp+4] |
980 | mov eax, [esp+4] |
981 | DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ |
981 | DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ |
982 | [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ |
982 | [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ |
983 | [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ |
983 | [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ |
984 | [eax+13]:2,[eax+12]:2 |
984 | [eax+13]:2,[eax+12]:2 |
985 | 985 | ||
986 | cmp dword [esp + 8], MAX_ETH_FRAME_SIZE |
986 | cmp dword [esp + 8], MAX_ETH_FRAME_SIZE |
987 | ja .error |
987 | ja .error |
988 | cmp dword [esp + 8], 60 |
988 | cmp dword [esp + 8], 60 |
989 | jb .error |
989 | jb .error |
990 | 990 | ||
991 | movzx ecx, [device.cur_tx] |
991 | movzx ecx, [device.cur_tx] |
992 | shl ecx, 4 ; *16 |
992 | shl ecx, 4 ; *16 |
993 | lea ecx, [device.txd + ecx] |
993 | lea ecx, [device.txd + ecx] |
994 | 994 | ||
995 | test dword [ecx + 4], 0x80000000 ; card owns descriptor ? |
995 | test dword [ecx + 4], 0x80000000 ; card owns descriptor ? |
996 | jnz .error |
996 | jnz .error |
997 | 997 | ||
998 | mov eax, [esp + 4] |
998 | mov eax, [esp + 4] |
999 | mov dword [ecx + 12], eax |
999 | mov dword [ecx + 12], eax |
1000 | GetRealAddr |
1000 | GetRealAddr |
1001 | mov dword [ecx + 8], eax ; buffer address |
1001 | mov dword [ecx + 8], eax ; buffer address |
1002 | 1002 | ||
1003 | mov eax, [esp + 8] |
1003 | mov eax, [esp + 8] |
1004 | and eax, DSIZE |
1004 | and eax, DSIZE |
1005 | or eax, 0x80000000 ; card owns descriptor |
1005 | or eax, 0x80000000 ; card owns descriptor |
1006 | mov dword [ecx + 4], eax ; status field |
1006 | mov dword [ecx + 4], eax ; status field |
1007 | 1007 | ||
1008 | set_io 0 |
1008 | set_io 0 |
1009 | set_io cr |
1009 | set_io cr |
1010 | in eax, dx |
1010 | in eax, dx |
1011 | or eax, TxENA ; Enable the transmit state machine |
1011 | or eax, TxENA ; Enable the transmit state machine |
1012 | out dx, eax |
1012 | out dx, eax |
1013 | 1013 | ||
1014 | inc [device.cur_tx] |
1014 | inc [device.cur_tx] |
1015 | and [device.cur_tx], NUM_TX_DESC-1 |
1015 | and [device.cur_tx], NUM_TX_DESC-1 |
1016 | 1016 | ||
1017 | ; update stats |
1017 | ; update stats |
1018 | mov ecx, [esp + 8] |
1018 | mov ecx, [esp + 8] |
1019 | inc [device.packets_tx] |
1019 | inc [device.packets_tx] |
1020 | add dword [device.bytes_tx], ecx |
1020 | add dword [device.bytes_tx], ecx |
1021 | adc dword [device.bytes_tx + 4], 0 |
1021 | adc dword [device.bytes_tx + 4], 0 |
1022 | 1022 | ||
1023 | .finish: |
1023 | .finish: |
1024 | DEBUGF 1,"Packet sent!\n" |
1024 | DEBUGF 1,"Packet sent!\n" |
1025 | xor eax, eax |
1025 | xor eax, eax |
1026 | ret 8 |
1026 | ret 8 |
1027 | 1027 | ||
1028 | .error: |
1028 | .error: |
1029 | DEBUGF 1,"ERROR!\n" |
1029 | DEBUGF 1,"ERROR!\n" |
1030 | stdcall KernelFree, [esp+4] |
1030 | stdcall KernelFree, [esp+4] |
1031 | or eax, -1 |
1031 | or eax, -1 |
1032 | ret 8 |
1032 | ret 8 |
1033 | 1033 | ||
1034 | 1034 | ||
1035 | ;*************************************************************************** |
1035 | ;*************************************************************************** |
1036 | ; |
1036 | ; |
1037 | ; int_handler |
1037 | ; int_handler |
1038 | ; |
1038 | ; |
1039 | ; handles received IRQs, which signal received packets |
1039 | ; handles received IRQs, which signal received packets |
1040 | ; |
1040 | ; |
1041 | ; Currently only supports one descriptor per packet, if packet is fragmented |
1041 | ; Currently only supports one descriptor per packet, if packet is fragmented |
1042 | ; between multiple descriptors you will lose part of the packet |
1042 | ; between multiple descriptors you will lose part of the packet |
1043 | ; |
1043 | ; |
1044 | ;*************************************************************************** |
1044 | ;*************************************************************************** |
- | 1045 | ||
1045 | align 4 |
1046 | align 4 |
1046 | int_handler: |
1047 | int_handler: |
- | 1048 | ||
- | 1049 | DEBUGF 1,"\n%s int\n", my_service |
|
1047 | 1050 | ||
1048 | ; find pointer of device which made IRQ occur |
- | |
- | 1051 | ; find pointer of device which made IRQ occur |
|
1049 | mov esi, device_list |
1052 | |
1050 | mov ecx, [devices] |
1053 | mov ecx, [devices] |
1051 | test ecx, ecx |
1054 | test ecx, ecx |
1052 | jz .nothing |
1055 | jz .nothing |
- | 1056 | mov esi, device_list |
|
1053 | .nextdevice: |
1057 | .nextdevice: |
1054 | mov ebx, [esi] |
1058 | mov ebx, [esi] |
- | 1059 | ||
1055 | set_io 0 |
1060 | set_io 0 |
1056 | set_io isr |
1061 | set_io isr |
1057 | in eax, dx ; note that this clears all interrupts |
1062 | in eax, dx ; note that this clears all interrupts |
1058 | test ax, IE |
1063 | test ax, IE |
1059 | jnz .got_it |
1064 | jnz .got_it |
- | 1065 | .continue: |
|
- | 1066 | add esi, 4 |
|
- | 1067 | dec ecx |
|
1060 | loop .nextdevice |
1068 | jnz .nextdevice |
1061 | .nothing: |
1069 | .nothing: |
1062 | ret |
1070 | ret |
- | 1071 | ||
1063 | .got_it: |
1072 | .got_it: |
1064 | 1073 | ||
1065 | DEBUGF 1,"IRQ! status=%x\n", ax |
1074 | DEBUGF 1,"Device: %x Status: %x ", ebx, ax |
1066 | 1075 | ||
1067 | test ax, RxOK |
1076 | test ax, RxOK |
1068 | jz .no_rx_ |
1077 | jz .no_rx_ |
1069 | 1078 | ||
1070 | push ax |
1079 | push ax |
1071 | 1080 | ||
1072 | .rx_loop: |
1081 | .rx_loop: |
1073 | 1082 | ||
1074 | ;----------- |
1083 | ;----------- |
1075 | ; Get Status |
1084 | ; Get Status |
1076 | movzx eax, [device.cur_rx] ; find current descriptor |
1085 | movzx eax, [device.cur_rx] ; find current descriptor |
1077 | shl eax, 4 ; * 16 |
1086 | shl eax, 4 ; * 16 |
1078 | mov ecx, dword[device.rxd + eax + 4] ; get receive status |
1087 | mov ecx, dword[device.rxd + eax + 4] ; get receive status |
1079 | 1088 | ||
1080 | ;------------------------------------------- |
1089 | ;------------------------------------------- |
1081 | ; Check RX_Status to see if packet is waiting |
1090 | ; Check RX_Status to see if packet is waiting |
1082 | test ecx, 0x80000000 |
1091 | test ecx, 0x80000000 |
1083 | jz .no_rx |
1092 | jz .no_rx |
1084 | 1093 | ||
1085 | ;---------------------------------------------- |
1094 | ;---------------------------------------------- |
1086 | ; There is a packet waiting check it for errors |
1095 | ; There is a packet waiting check it for errors |
1087 | test ecx, 0x67C0000 ; see if there are any errors |
1096 | test ecx, 0x67C0000 ; see if there are any errors |
1088 | jnz .error_status |
1097 | jnz .error_status |
1089 | 1098 | ||
1090 | ;--------------------- |
1099 | ;--------------------- |
1091 | ; Check size of packet |
1100 | ; Check size of packet |
1092 | and ecx, DSIZE ; get packet size minus CRC |
1101 | and ecx, DSIZE ; get packet size minus CRC |
1093 | sub ecx, CRC_SIZE ; make sure packet contains data |
1102 | sub ecx, CRC_SIZE ; make sure packet contains data |
1094 | jbe .error_size |
1103 | jbe .error_size |
1095 | 1104 | ||
1096 | ; update statistics |
1105 | ; update statistics |
1097 | inc dword [device.packets_rx] |
1106 | inc dword [device.packets_rx] |
1098 | add dword [device.bytes_rx], ecx |
1107 | add dword [device.bytes_rx], ecx |
1099 | adc dword [device.bytes_rx + 4], 0 |
1108 | adc dword [device.bytes_rx + 4], 0 |
1100 | 1109 | ||
1101 | push ebx |
1110 | push ebx |
1102 | push .return |
1111 | push .return |
1103 | push ecx ; packet size |
1112 | push ecx ; packet size |
1104 | pushd [device.rxd + eax + 12] ; packet ptr |
1113 | pushd [device.rxd + eax + 12] ; packet ptr |
1105 | DEBUGF 1, "Packet received OK\n" |
1114 | DEBUGF 1, "Packet received OK\n" |
1106 | jmp EthReceiver |
1115 | jmp EthReceiver |
1107 | .return: |
1116 | .return: |
1108 | pop ebx |
1117 | pop ebx |
1109 | 1118 | ||
1110 | ; Reset status, allow ethernet card access to descriptor |
1119 | ; Reset status, allow ethernet card access to descriptor |
1111 | stdcall KernelAlloc, RX_BUFF_SZ |
1120 | stdcall KernelAlloc, RX_BUFF_SZ |
1112 | test eax, eax |
1121 | test eax, eax |
1113 | jz .fail |
1122 | jz .fail |
1114 | movzx ecx, [device.cur_rx] |
1123 | movzx ecx, [device.cur_rx] |
1115 | shl ecx, 4 ; *16 |
1124 | shl ecx, 4 ; *16 |
1116 | lea ecx, [device.rxd + ecx] |
1125 | lea ecx, [device.rxd + ecx] |
1117 | mov dword [ecx + 12], eax |
1126 | mov dword [ecx + 12], eax |
1118 | GetRealAddr |
1127 | GetRealAddr |
1119 | mov dword [ecx + 8], eax |
1128 | mov dword [ecx + 8], eax |
1120 | mov dword [ecx + 4], RX_BUFF_SZ |
1129 | mov dword [ecx + 4], RX_BUFF_SZ |
1121 | 1130 | ||
1122 | inc [device.cur_rx] ; get next descriptor |
1131 | inc [device.cur_rx] ; get next descriptor |
1123 | and [device.cur_rx], NUM_RX_DESC-1 ; only 4 descriptors 0-3 |
1132 | and [device.cur_rx], NUM_RX_DESC-1 ; only 4 descriptors 0-3 |
1124 | 1133 | ||
1125 | jmp .rx_loop |
1134 | jmp .rx_loop |
1126 | 1135 | ||
1127 | .no_rx: |
1136 | .no_rx: |
1128 | set_io 0 |
1137 | set_io 0 |
1129 | set_io cr |
1138 | set_io cr |
1130 | in eax, dx |
1139 | in eax, dx |
1131 | or eax, RxENA ; Re-Enable the Receive state machine |
1140 | or eax, RxENA ; Re-Enable the Receive state machine |
1132 | out dx, eax |
1141 | out dx, eax |
1133 | 1142 | ||
1134 | pop ax |
1143 | pop ax |
1135 | 1144 | ||
1136 | .no_rx_: |
1145 | .no_rx_: |
1137 | test ax, TxOK |
1146 | test ax, TxOK |
1138 | jz .no_tx |
1147 | jz .no_tx |
1139 | 1148 | ||
1140 | DEBUGF 1, "TX ok!\n" |
1149 | DEBUGF 1, "TX ok!\n" |
1141 | 1150 | ||
1142 | .tx_loop: |
1151 | .tx_loop: |
1143 | movzx ecx, [device.last_tx] |
1152 | movzx ecx, [device.last_tx] |
1144 | shl ecx, 4 ; *16 |
1153 | shl ecx, 4 ; *16 |
1145 | lea ecx, [device.txd + ecx] |
1154 | lea ecx, [device.txd + ecx] |
1146 | 1155 | ||
1147 | test dword [ecx + 4], 0x80000000 ; card owns descr |
1156 | test dword [ecx + 4], 0x80000000 ; card owns descr |
1148 | jnz .no_tx |
1157 | jnz .no_tx |
1149 | cmp dword [ecx + 12], 0 |
1158 | cmp dword [ecx + 12], 0 |
1150 | je .no_tx |
1159 | je .no_tx |
1151 | 1160 | ||
1152 | DEBUGF 1, "Freeing packet = %x\n", [ecx + 12]:8 |
1161 | DEBUGF 1, "Freeing packet = %x\n", [ecx + 12]:8 |
1153 | push dword [ecx + 12] |
1162 | push dword [ecx + 12] |
1154 | mov dword [ecx + 12], 0 |
1163 | mov dword [ecx + 12], 0 |
1155 | call KernelFree |
1164 | call KernelFree |
1156 | 1165 | ||
1157 | inc [device.last_tx] |
1166 | inc [device.last_tx] |
1158 | and [device.last_tx], NUM_TX_DESC-1 |
1167 | and [device.last_tx], NUM_TX_DESC-1 |
1159 | jmp .tx_loop |
1168 | jmp .tx_loop |
1160 | 1169 | ||
1161 | .no_tx: |
1170 | .no_tx: |
1162 | 1171 | ||
1163 | ret |
1172 | ret |
1164 | 1173 | ||
1165 | .error_status: |
1174 | .error_status: |
1166 | DEBUGF 1, "Packet error: %x\n", ecx |
1175 | DEBUGF 1, "Packet error: %x\n", ecx |
1167 | jmp .fail |
1176 | jmp .fail |
1168 | 1177 | ||
1169 | .error_size: |
1178 | .error_size: |
1170 | DEBUGF 1, "Packet too large/small\n" |
1179 | DEBUGF 1, "Packet too large/small\n" |
1171 | jmp .fail |
1180 | jmp .fail |
1172 | 1181 | ||
1173 | .fail: |
1182 | .fail: |
1174 | DEBUGF 1, "FAILED\n" |
1183 | DEBUGF 1, "FAILED\n" |
1175 | jmp $ |
1184 | jmp $ |
1176 | ret |
1185 | ret |
1177 | 1186 | ||
1178 | 1187 | ||
1179 | 1188 | ||
1180 | ; End of code |
1189 | ; End of code |
1181 | 1190 | ||
1182 | align 4 ; Place all initialised data here |
1191 | align 4 ; Place all initialised data here |
1183 | 1192 | ||
1184 | devices dd 0 |
1193 | devices dd 0 |
1185 | 1194 | ||
1186 | specific_table: |
1195 | specific_table: |
1187 | ; dd SIS630A_900_REV, Get_Mac_SIS630A_900_REV, 0 |
1196 | ; dd SIS630A_900_REV, Get_Mac_SIS630A_900_REV, 0 |
1188 | ; dd SIS630E_900_REV, Get_Mac_SIS630E_900_REV, 0 |
1197 | ; dd SIS630E_900_REV, Get_Mac_SIS630E_900_REV, 0 |
1189 | dd SIS630S_900_REV, Get_Mac_SIS635_900_REV, 0 |
1198 | dd SIS630S_900_REV, Get_Mac_SIS635_900_REV, 0 |
1190 | dd SIS630EA1_900_REV, Get_Mac_SIS635_900_REV, 0 |
1199 | dd SIS630EA1_900_REV, Get_Mac_SIS635_900_REV, 0 |
1191 | dd SIS630ET_900_REV, Get_Mac_SIS635_900_REV, 0 ;SIS630ET_900_REV_SpecialFN |
1200 | dd SIS630ET_900_REV, Get_Mac_SIS635_900_REV, 0 ;SIS630ET_900_REV_SpecialFN |
1192 | dd SIS635A_900_REV, Get_Mac_SIS635_900_REV, 0 |
1201 | dd SIS635A_900_REV, Get_Mac_SIS635_900_REV, 0 |
1193 | dd SIS900_960_REV, SIS960_get_mac_addr, 0 |
1202 | dd SIS900_960_REV, SIS960_get_mac_addr, 0 |
1194 | dd SIS900B_900_REV, SIS900_get_mac_addr, 0 |
1203 | dd SIS900B_900_REV, SIS900_get_mac_addr, 0 |
1195 | dd 0 ; end of list |
1204 | dd 0 ; end of list |
1196 | 1205 | ||
1197 | version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) |
1206 | version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) |
1198 | my_service db 'SIS900',0 ; max 16 chars include zero |
1207 | my_service db 'SIS900',0 ; max 16 chars include zero |
1199 | 1208 | ||
1200 | include_debug_strings ; All data wich FDO uses will be included here |
1209 | include_debug_strings ; All data wich FDO uses will be included here |
1201 | 1210 | ||
1202 | section '.data' data readable writable align 16; place all uninitialized data place here |
1211 | section '.data' data readable writable align 16; place all uninitialized data place here |
1203 | 1212 | ||
1204 | device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling64bytes) |
1213 | device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling64bytes) |
1205 | > |
1214 | > |