Rev 3205 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3205 | Rev 3346 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2013. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2013. 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 | ;; Realtek 8139 driver for KolibriOS ;; |
6 | ;; Realtek 8139 driver for KolibriOS ;; |
7 | ;; ;; |
7 | ;; ;; |
8 | ;; based on RTL8139.asm driver for menuetos ;; |
8 | ;; based on RTL8139.asm driver for menuetos ;; |
9 | ;; and realtek8139.asm for SolarOS by Eugen Brasoveanu ;; |
9 | ;; and realtek8139.asm for SolarOS by Eugen Brasoveanu ;; |
10 | ;; ;; |
10 | ;; ;; |
11 | ;; Written by hidnplayr@kolibrios.org ;; |
11 | ;; Written by hidnplayr@kolibrios.org ;; |
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 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
16 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
17 | 17 | ||
18 | format MS COFF |
18 | format MS COFF |
19 | 19 | ||
20 | API_VERSION = 0x01000100 |
20 | API_VERSION = 0x01000100 |
21 | DRIVER_VERSION = 5 |
21 | DRIVER_VERSION = 5 |
22 | 22 | ||
23 | MAX_DEVICES = 16 |
23 | MAX_DEVICES = 16 |
24 | 24 | ||
25 | RBLEN = 3 ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k |
25 | RBLEN = 3 ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k |
26 | NUM_TX_DESC = 4 |
26 | NUM_TX_DESC = 4 |
27 | 27 | ||
28 | DEBUG = 1 |
28 | DEBUG = 1 |
29 | __DEBUG__ = 1 |
29 | __DEBUG__ = 1 |
30 | __DEBUG_LEVEL__ = 1 |
30 | __DEBUG_LEVEL__ = 1 |
31 | 31 | ||
32 | include 'proc32.inc' |
32 | include 'proc32.inc' |
33 | include 'imports.inc' |
33 | include 'imports.inc' |
34 | include 'fdo.inc' |
34 | include 'fdo.inc' |
35 | include '../struct.inc' |
- | |
36 | include 'netdrv.inc' |
35 | include 'netdrv.inc' |
37 | 36 | ||
38 | public START |
37 | public START |
39 | public service_proc |
38 | public service_proc |
40 | public version |
39 | public version |
41 | 40 | ||
42 | REG_IDR0 = 0x00 |
41 | REG_IDR0 = 0x00 |
43 | REG_MAR0 = 0x08 ; multicast filter register 0 |
42 | REG_MAR0 = 0x08 ; multicast filter register 0 |
44 | REG_MAR4 = 0x0c ; multicast filter register 4 |
43 | REG_MAR4 = 0x0c ; multicast filter register 4 |
45 | REG_TSD0 = 0x10 ; transmit status of descriptor |
44 | REG_TSD0 = 0x10 ; transmit status of descriptor |
46 | REG_TSAD0 = 0x20 ; transmit start address of descriptor |
45 | REG_TSAD0 = 0x20 ; transmit start address of descriptor |
47 | REG_RBSTART = 0x30 ; RxBuffer start address |
46 | REG_RBSTART = 0x30 ; RxBuffer start address |
48 | REG_COMMAND = 0x37 ; command register |
47 | REG_COMMAND = 0x37 ; command register |
49 | REG_CAPR = 0x38 ; current address of packet read (word) R/W |
48 | REG_CAPR = 0x38 ; current address of packet read (word) R/W |
50 | REG_IMR = 0x3c ; interrupt mask register |
49 | REG_IMR = 0x3c ; interrupt mask register |
51 | REG_ISR = 0x3e ; interrupt status register |
50 | REG_ISR = 0x3e ; interrupt status register |
52 | REG_TXCONFIG = 0x40 ; transmit configuration register |
51 | REG_TXCONFIG = 0x40 ; transmit configuration register |
53 | REG_RXCONFIG = 0x44 ; receive configuration register 0 |
52 | REG_RXCONFIG = 0x44 ; receive configuration register 0 |
54 | REG_MPC = 0x4c ; missed packet counter |
53 | REG_MPC = 0x4c ; missed packet counter |
55 | REG_9346CR = 0x50 ; serial eeprom 93C46 command register |
54 | REG_9346CR = 0x50 ; serial eeprom 93C46 command register |
56 | REG_CONFIG1 = 0x52 ; configuration register 1 |
55 | REG_CONFIG1 = 0x52 ; configuration register 1 |
57 | REG_MSR = 0x58 |
56 | REG_MSR = 0x58 |
58 | REG_CONFIG4 = 0x5a ; configuration register 4 |
57 | REG_CONFIG4 = 0x5a ; configuration register 4 |
59 | REG_HLTCLK = 0x5b ; undocumented halt clock register |
58 | REG_HLTCLK = 0x5b ; undocumented halt clock register |
60 | REG_BMCR = 0x62 ; basic mode control register |
59 | REG_BMCR = 0x62 ; basic mode control register |
61 | REG_ANAR = 0x66 ; auto negotiation advertisement register |
60 | REG_ANAR = 0x66 ; auto negotiation advertisement register |
62 | REG_9346CR_WE = 11b SHL 6 |
61 | REG_9346CR_WE = 11b shl 6 |
63 | 62 | ||
64 | BIT_RUNT = 4 ; total packet length < 64 bytes |
63 | BIT_RUNT = 4 ; total packet length < 64 bytes |
65 | BIT_LONG = 3 ; total packet length > 4k |
64 | BIT_LONG = 3 ; total packet length > 4k |
66 | BIT_CRC = 2 ; crc error occured |
65 | BIT_CRC = 2 ; crc error occured |
67 | BIT_FAE = 1 ; frame alignment error occured |
66 | BIT_FAE = 1 ; frame alignment error occured |
68 | BIT_ROK = 0 ; received packet is ok |
67 | BIT_ROK = 0 ; received packet is ok |
69 | 68 | ||
70 | BIT_RST = 4 ; reset bit |
69 | BIT_RST = 4 ; reset bit |
71 | BIT_RE = 3 ; receiver enabled |
70 | BIT_RE = 3 ; receiver enabled |
72 | BIT_TE = 2 ; transmitter enabled |
71 | BIT_TE = 2 ; transmitter enabled |
73 | BUFE = 1 ; rx buffer is empty, no packet stored |
72 | BUFE = 1 ; rx buffer is empty, no packet stored |
74 | 73 | ||
75 | BIT_ISR_TOK = 2 ; transmit ok |
74 | BIT_ISR_TOK = 2 ; transmit ok |
76 | BIT_ISR_RER = 1 ; receive error interrupt |
75 | BIT_ISR_RER = 1 ; receive error interrupt |
77 | BIT_ISR_ROK = 0 ; receive ok |
76 | BIT_ISR_ROK = 0 ; receive ok |
78 | 77 | ||
79 | BIT_TX_MXDMA = 8 ; Max DMA burst size per Tx DMA burst |
78 | BIT_TX_MXDMA = 8 ; Max DMA burst size per Tx DMA burst |
80 | BIT_TXRR = 4 ; Tx Retry count 16+(TXRR*16) |
79 | BIT_TXRR = 4 ; Tx Retry count 16+(TXRR*16) |
81 | 80 | ||
82 | BIT_RXFTH = 13 ; Rx fifo threshold |
81 | BIT_RXFTH = 13 ; Rx fifo threshold |
83 | BIT_RBLEN = 11 ; Ring buffer length indicator |
82 | BIT_RBLEN = 11 ; Ring buffer length indicator |
84 | BIT_RX_MXDMA = 8 ; Max DMA burst size per Rx DMA burst |
83 | BIT_RX_MXDMA = 8 ; Max DMA burst size per Rx DMA burst |
85 | BIT_NOWRAP = 7 ; transfered data wrapping |
84 | BIT_NOWRAP = 7 ; transfered data wrapping |
86 | BIT_9356SEL = 6 ; eeprom selector 9346/9356 |
85 | BIT_9356SEL = 6 ; eeprom selector 9346/9356 |
87 | BIT_AER = 5 ; accept error packets |
86 | BIT_AER = 5 ; accept error packets |
88 | BIT_AR = 4 ; accept runt packets |
87 | BIT_AR = 4 ; accept runt packets |
89 | BIT_AB = 3 ; accept broadcast packets |
88 | BIT_AB = 3 ; accept broadcast packets |
90 | BIT_AM = 2 ; accept multicast packets |
89 | BIT_AM = 2 ; accept multicast packets |
91 | BIT_APM = 1 ; accept physical match packets |
90 | BIT_APM = 1 ; accept physical match packets |
92 | BIT_AAP = 0 ; accept all packets |
91 | BIT_AAP = 0 ; accept all packets |
93 | 92 | ||
94 | BIT_93C46_EEM1 = 7 ; RTL8139 eeprom operating mode1 |
93 | BIT_93C46_EEM1 = 7 ; RTL8139 eeprom operating mode1 |
95 | BIT_93C46_EEM0 = 6 ; RTL8139 eeprom operating mode0 |
94 | BIT_93C46_EEM0 = 6 ; RTL8139 eeprom operating mode0 |
96 | BIT_93C46_EECS = 3 ; chip select |
95 | BIT_93C46_EECS = 3 ; chip select |
97 | BIT_93C46_EESK = 2 ; serial data clock |
96 | BIT_93C46_EESK = 2 ; serial data clock |
98 | BIT_93C46_EEDI = 1 ; serial data input |
97 | BIT_93C46_EEDI = 1 ; serial data input |
99 | BIT_93C46_EEDO = 0 ; serial data output |
98 | BIT_93C46_EEDO = 0 ; serial data output |
100 | 99 | ||
101 | BIT_LWACT = 4 ; see REG_CONFIG1 |
100 | BIT_LWACT = 4 ; see REG_CONFIG1 |
102 | BIT_SLEEP = 1 ; sleep bit at older chips |
101 | BIT_SLEEP = 1 ; sleep bit at older chips |
103 | BIT_PWRDWN = 0 ; power down bit at older chips |
102 | BIT_PWRDWN = 0 ; power down bit at older chips |
104 | BIT_PMEn = 0 ; power management enabled |
103 | BIT_PMEn = 0 ; power management enabled |
105 | 104 | ||
106 | BIT_LWPTN = 2 ; see REG_CONFIG4 |
105 | BIT_LWPTN = 2 ; see REG_CONFIG4 |
107 | 106 | ||
108 | BIT_ERTXTH = 16 ; early TX threshold |
107 | BIT_ERTXTH = 16 ; early TX threshold |
109 | BIT_TOK = 15 ; transmit ok |
108 | BIT_TOK = 15 ; transmit ok |
110 | BIT_OWN = 13 ; tx DMA operation is completed |
109 | BIT_OWN = 13 ; tx DMA operation is completed |
111 | 110 | ||
112 | BIT_ANE = 12 ; auto negotiation enable |
111 | BIT_ANE = 12 ; auto negotiation enable |
113 | 112 | ||
114 | BIT_TXFD = 8 ; 100base-T full duplex |
113 | BIT_TXFD = 8 ; 100base-T full duplex |
115 | BIT_TX = 7 ; 100base-T |
114 | BIT_TX = 7 ; 100base-T |
116 | BIT_10FD = 6 ; 10base-T full duplex |
115 | BIT_10FD = 6 ; 10base-T full duplex |
117 | BIT_10 = 5 ; 10base-T |
116 | BIT_10 = 5 ; 10base-T |
118 | BIT_SELECTOR = 0 ; binary encoded selector CSMA/CD=00001 |
117 | BIT_SELECTOR = 0 ; binary encoded selector CSMA/CD=00001 |
119 | 118 | ||
120 | BIT_IFG1 = 25 |
119 | BIT_IFG1 = 25 |
121 | BIT_IFG0 = 24 |
120 | BIT_IFG0 = 24 |
122 | 121 | ||
123 | TXRR = 8 ; total retries = 16+(TXRR*16) |
122 | TXRR = 8 ; total retries = 16+(TXRR*16) |
124 | TX_MXDMA = 6 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=2048 |
123 | TX_MXDMA = 6 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=2048 |
125 | ERTXTH = 8 ; in unit of 32 bytes e.g:(8*32)=256 |
124 | ERTXTH = 8 ; in unit of 32 bytes e.g:(8*32)=256 |
126 | RX_MXDMA = 7 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=unlimited |
125 | RX_MXDMA = 7 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=unlimited |
127 | RXFTH = 7 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=no threshold |
126 | RXFTH = 7 ; 0=16 1=32 2=64 3=128 4=256 5=512 6=1024 7=no threshold |
128 | 127 | ||
129 | RX_CONFIG = (RBLEN shl BIT_RBLEN) or \ |
128 | RX_CONFIG = (RBLEN shl BIT_RBLEN) or \ |
130 | (RX_MXDMA shl BIT_RX_MXDMA) or \ |
129 | (RX_MXDMA shl BIT_RX_MXDMA) or \ |
131 | (1 shl BIT_NOWRAP) or \ |
130 | (1 shl BIT_NOWRAP) or \ |
132 | (RXFTH shl BIT_RXFTH) or\ |
131 | (RXFTH shl BIT_RXFTH) or\ |
133 | (1 shl BIT_AB) or \ ; Accept broadcast packets |
132 | (1 shl BIT_AB) or \ ; Accept broadcast packets |
134 | (1 shl BIT_APM) or \ ; Accept physical match packets |
133 | (1 shl BIT_APM) or \ ; Accept physical match packets |
135 | (1 shl BIT_AER) or \ ; Accept error packets |
134 | (1 shl BIT_AER) or \ ; Accept error packets |
136 | (1 shl BIT_AR) or \ ; Accept Runt packets (smaller then 64 bytes) |
135 | (1 shl BIT_AR) or \ ; Accept Runt packets (smaller then 64 bytes) |
137 | (1 shl BIT_AM) ; Accept multicast packets |
136 | (1 shl BIT_AM) ; Accept multicast packets |
138 | 137 | ||
139 | RX_BUFFER_SIZE = (8192 shl RBLEN);+16 |
138 | RX_BUFFER_SIZE = (8192 shl RBLEN);+16 |
140 | MAX_ETH_FRAME_SIZE = 1514 |
139 | MAX_ETH_FRAME_SIZE = 1514 |
141 | 140 | ||
142 | EE_93C46_REG_ETH_ID = 7 ; MAC offset |
141 | EE_93C46_REG_ETH_ID = 7 ; MAC offset |
143 | EE_93C46_READ_CMD = (6 shl 6) ; 110b + 6bit address |
142 | EE_93C46_READ_CMD = (6 shl 6) ; 110b + 6bit address |
144 | EE_93C56_READ_CMD = (6 shl 8) ; 110b + 8bit address |
143 | EE_93C56_READ_CMD = (6 shl 8) ; 110b + 8bit address |
145 | EE_93C46_CMD_LENGTH = 9 ; start bit + cmd + 6bit address |
144 | EE_93C46_CMD_LENGTH = 9 ; start bit + cmd + 6bit address |
146 | EE_93C56_CMD_LENGTH = 11 ; start bit + cmd + 8bit ddress |
145 | EE_93C56_CMD_LENGTH = 11 ; start bit + cmd + 8bit ddress |
147 | 146 | ||
148 | VER_RTL8139 = 1100000b |
147 | VER_RTL8139 = 1100000b |
149 | VER_RTL8139A = 1110000b |
148 | VER_RTL8139A = 1110000b |
150 | VER_RTL8139AG = 1110100b |
149 | VER_RTL8139AG = 1110100b |
151 | VER_RTL8139B = 1111000b |
150 | VER_RTL8139B = 1111000b |
152 | VER_RTL8130 = VER_RTL8139B |
151 | VER_RTL8130 = VER_RTL8139B |
153 | VER_RTL8139C = 1110100b |
152 | VER_RTL8139C = 1110100b |
154 | VER_RTL8100 = 1111010b |
153 | VER_RTL8100 = 1111010b |
155 | VER_RTL8100B = 1110101b |
154 | VER_RTL8100B = 1110101b |
156 | VER_RTL8139D = VER_RTL8100B |
155 | VER_RTL8139D = VER_RTL8100B |
157 | VER_RTL8139CP = 1110110b |
156 | VER_RTL8139CP = 1110110b |
158 | VER_RTL8101 = 1110111b |
157 | VER_RTL8101 = 1110111b |
159 | 158 | ||
160 | IDX_RTL8139 = 0 |
159 | IDX_RTL8139 = 0 |
161 | IDX_RTL8139A = 1 |
160 | IDX_RTL8139A = 1 |
162 | IDX_RTL8139B = 2 |
161 | IDX_RTL8139B = 2 |
163 | IDX_RTL8139C = 3 |
162 | IDX_RTL8139C = 3 |
164 | IDX_RTL8100 = 4 |
163 | IDX_RTL8100 = 4 |
165 | IDX_RTL8139D = 5 |
164 | IDX_RTL8139D = 5 |
166 | IDX_RTL8139D = 6 |
165 | IDX_RTL8139D = 6 |
167 | IDX_RTL8101 = 7 |
166 | IDX_RTL8101 = 7 |
168 | 167 | ||
169 | ISR_SERR = 1 SHL 15 |
168 | ISR_SERR = 1 shl 15 |
170 | ISR_TIMEOUT = 1 SHL 14 |
169 | ISR_TIMEOUT = 1 shl 14 |
171 | ISR_LENCHG = 1 SHL 13 |
170 | ISR_LENCHG = 1 shl 13 |
172 | ISR_FIFOOVW = 1 SHL 6 |
171 | ISR_FIFOOVW = 1 shl 6 |
173 | ISR_PUN = 1 SHL 5 |
172 | ISR_PUN = 1 shl 5 |
174 | ISR_RXOVW = 1 SHL 4 |
173 | ISR_RXOVW = 1 shl 4 |
175 | ISR_TER = 1 SHL 3 |
174 | ISR_TER = 1 shl 3 |
176 | ISR_TOK = 1 SHL 2 |
175 | ISR_TOK = 1 shl 2 |
177 | ISR_RER = 1 SHL 1 |
176 | ISR_RER = 1 shl 1 |
178 | ISR_ROK = 1 SHL 0 |
177 | ISR_ROK = 1 shl 0 |
179 | 178 | ||
180 | INTERRUPT_MASK = ISR_ROK or \ |
179 | INTERRUPT_MASK = ISR_ROK or \ |
181 | ISR_RXOVW or \ |
180 | ISR_RXOVW or \ |
182 | ISR_PUN or \ |
181 | ISR_PUN or \ |
183 | ISR_FIFOOVW or \ |
182 | ISR_FIFOOVW or \ |
184 | ISR_LENCHG or \ |
183 | ISR_LENCHG or \ |
185 | ISR_TOK or \ |
184 | ISR_TOK or \ |
186 | ISR_TER |
185 | ISR_TER |
187 | 186 | ||
188 | TSR_OWN = 1 SHL 13 |
187 | TSR_OWN = 1 shl 13 |
189 | TSR_TUN = 1 SHL 14 |
188 | TSR_TUN = 1 shl 14 |
190 | TSR_TOK = 1 SHL 15 |
189 | TSR_TOK = 1 shl 15 |
191 | 190 | ||
192 | TSR_CDH = 1 SHL 28 |
191 | TSR_CDH = 1 shl 28 |
193 | TSR_OWC = 1 SHL 29 |
192 | TSR_OWC = 1 shl 29 |
194 | TSR_TABT = 1 SHL 30 |
193 | TSR_TABT = 1 shl 30 |
195 | TSR_CRS = 1 SHL 31 |
194 | TSR_CRS = 1 shl 31 |
196 | 195 | ||
197 | 196 | ||
198 | virtual at ebx |
197 | virtual at ebx |
199 | 198 | ||
200 | device: |
199 | device: |
201 | 200 | ||
202 | ETH_DEVICE |
201 | ETH_DEVICE |
203 | 202 | ||
204 | .rx_buffer dd ? |
203 | .rx_buffer dd ? |
205 | .tx_buffer dd ? |
- | |
206 | 204 | ||
207 | .rx_data_offset dd ? |
205 | .rx_data_offset dd ? |
208 | .io_addr dd ? |
206 | .io_addr dd ? |
209 | 207 | ||
210 | .curr_tx_desc db ? |
208 | .curr_tx_desc db ? |
211 | .pci_bus dd ? |
209 | .pci_bus dd ? |
212 | .pci_dev dd ? |
210 | .pci_dev dd ? |
213 | .irq_line db ? |
211 | .irq_line db ? |
214 | .hw_ver_id db ? |
212 | .hw_ver_id db ? |
215 | 213 | ||
216 | .TX_DESC rd NUM_TX_DESC |
214 | .TX_DESC rd NUM_TX_DESC |
217 | 215 | ||
218 | .size = $ - device |
216 | .size = $ - device |
219 | 217 | ||
220 | end virtual |
218 | end virtual |
221 | 219 | ||
222 | 220 | ||
223 | 221 | ||
224 | section '.flat' code readable align 16 |
222 | section '.flat' code readable align 16 |
225 | 223 | ||
226 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
224 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
227 | ;; ;; |
225 | ;; ;; |
228 | ;; proc START ;; |
226 | ;; proc START ;; |
229 | ;; ;; |
227 | ;; ;; |
230 | ;; (standard driver proc) ;; |
228 | ;; (standard driver proc) ;; |
231 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
229 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
232 | 230 | ||
233 | align 4 |
231 | align 4 |
234 | proc START stdcall, state:dword |
232 | proc START stdcall, state:dword |
235 | 233 | ||
236 | cmp [state], 1 |
234 | cmp [state], 1 |
237 | jne .exit |
235 | jne .exit |
238 | 236 | ||
239 | .entry: |
237 | .entry: |
240 | 238 | ||
241 | DEBUGF 2, "Loading %s driver\n", my_service |
239 | DEBUGF 2, "Loading %s driver\n", my_service |
242 | stdcall RegService, my_service, service_proc |
240 | stdcall RegService, my_service, service_proc |
243 | ret |
241 | ret |
244 | 242 | ||
245 | .fail: |
243 | .fail: |
246 | .exit: |
244 | .exit: |
247 | xor eax, eax |
245 | xor eax, eax |
248 | ret |
246 | ret |
249 | 247 | ||
250 | endp |
248 | endp |
251 | 249 | ||
252 | 250 | ||
253 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
251 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
254 | ;; ;; |
252 | ;; ;; |
255 | ;; proc SERVICE_PROC ;; |
253 | ;; proc SERVICE_PROC ;; |
256 | ;; ;; |
254 | ;; ;; |
257 | ;; (standard driver proc) ;; |
255 | ;; (standard driver proc) ;; |
258 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
256 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
259 | 257 | ||
260 | align 4 |
258 | align 4 |
261 | proc service_proc stdcall, ioctl:dword |
259 | proc service_proc stdcall, ioctl:dword |
262 | 260 | ||
263 | mov edx, [ioctl] |
261 | mov edx, [ioctl] |
264 | mov eax, [IOCTL.io_code] |
262 | mov eax, [IOCTL.io_code] |
265 | 263 | ||
266 | ;------------------------------------------------------ |
264 | ;------------------------------------------------------ |
267 | 265 | ||
268 | cmp eax, 0 ;SRV_GETVERSION |
266 | cmp eax, 0 ;SRV_GETVERSION |
269 | jne @F |
267 | jne @F |
270 | 268 | ||
271 | cmp [IOCTL.out_size], 4 |
269 | cmp [IOCTL.out_size], 4 |
272 | jb .fail |
270 | jb .fail |
273 | mov eax, [IOCTL.output] |
271 | mov eax, [IOCTL.output] |
274 | mov [eax], dword API_VERSION |
272 | mov [eax], dword API_VERSION |
275 | 273 | ||
276 | xor eax, eax |
274 | xor eax, eax |
277 | ret |
275 | ret |
278 | 276 | ||
279 | ;------------------------------------------------------ |
277 | ;------------------------------------------------------ |
280 | @@: |
278 | @@: |
281 | cmp eax, 1 ;SRV_HOOK |
279 | cmp eax, 1 ;SRV_HOOK |
282 | jne .fail |
280 | jne .fail |
283 | 281 | ||
284 | cmp [IOCTL.inp_size], 3 ; Data input must be at least 3 bytes |
282 | cmp [IOCTL.inp_size], 3 ; Data input must be at least 3 bytes |
285 | jb .fail |
283 | jb .fail |
286 | 284 | ||
287 | mov eax, [IOCTL.input] |
285 | mov eax, [IOCTL.input] |
288 | 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 |
289 | jne .fail ; other types arent supported for this card yet |
287 | jne .fail ; other types arent supported for this card yet |
290 | 288 | ||
291 | ; check if the device is already listed |
289 | ; check if the device is already listed |
292 | 290 | ||
293 | mov esi, device_list |
291 | mov esi, device_list |
294 | mov ecx, [devices] |
292 | mov ecx, [devices] |
295 | test ecx, ecx |
293 | test ecx, ecx |
296 | jz .firstdevice |
294 | jz .firstdevice |
297 | 295 | ||
298 | mov ax , [eax+1] ; get the pci bus and device numbers |
296 | mov ax, [eax+1] ; get the pci bus and device numbers |
299 | .nextdevice: |
297 | .nextdevice: |
300 | mov ebx, [esi] |
298 | mov ebx, [esi] |
301 | cmp al, byte[device.pci_bus] |
299 | cmp al, byte[device.pci_bus] |
302 | jne @f |
300 | jne @f |
303 | cmp ah, byte[device.pci_dev] |
301 | cmp ah, byte[device.pci_dev] |
304 | je .find_devicenum ; Device is already loaded, let's find it's device number |
302 | je .find_devicenum ; Device is already loaded, let's find it's device number |
305 | @@: |
303 | @@: |
306 | add esi, 4 |
304 | add esi, 4 |
307 | loop .nextdevice |
305 | loop .nextdevice |
308 | 306 | ||
309 | 307 | ||
310 | ; This device doesnt have its own eth_device structure yet, lets create one |
308 | ; This device doesnt have its own eth_device structure yet, lets create one |
311 | .firstdevice: |
309 | .firstdevice: |
312 | cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card |
310 | cmp [devices], MAX_DEVICES ; First check if the driver can handle one more card |
313 | jae .fail |
311 | jae .fail |
314 | 312 | ||
315 | allocate_and_clear ebx, device.size, .fail ; Allocate the buffer for device structure |
313 | allocate_and_clear ebx, device.size, .fail ; Allocate the buffer for device structure |
316 | 314 | ||
317 | ; Fill in the direct call addresses into the struct |
315 | ; Fill in the direct call addresses into the struct |
318 | 316 | ||
319 | mov [device.reset], reset |
317 | mov [device.reset], reset |
320 | mov [device.transmit], transmit |
318 | mov [device.transmit], transmit |
321 | mov [device.get_MAC], read_mac |
- | |
322 | mov [device.set_MAC], write_mac |
- | |
323 | mov [device.unload], unload |
319 | mov [device.unload], unload |
324 | mov [device.name], my_service |
320 | mov [device.name], my_service |
325 | 321 | ||
326 | ; save the pci bus and device numbers |
322 | ; save the pci bus and device numbers |
327 | 323 | ||
328 | mov eax, [IOCTL.input] |
324 | mov eax, [IOCTL.input] |
329 | movzx ecx, byte[eax+1] |
325 | movzx ecx, byte[eax+1] |
330 | mov [device.pci_bus], ecx |
326 | mov [device.pci_bus], ecx |
331 | movzx ecx, byte[eax+2] |
327 | movzx ecx, byte[eax+2] |
332 | mov [device.pci_dev], ecx |
328 | mov [device.pci_dev], ecx |
333 | 329 | ||
334 | ; Now, it's time to find the base io addres of the PCI device |
330 | ; Now, it's time to find the base io addres of the PCI device |
335 | 331 | ||
336 | PCI_find_io |
332 | PCI_find_io |
337 | 333 | ||
338 | ; We've found the io address, find IRQ now |
334 | ; We've found the io address, find IRQ now |
339 | 335 | ||
340 | PCI_find_irq |
336 | PCI_find_irq |
341 | 337 | ||
342 | DEBUGF 2, "Hooking into device, dev:%x, bus:%x, irq:%x, addr:%x\n",\ |
338 | DEBUGF 2, "Hooking into device, dev:%x, bus:%x, irq:%x, I/O addr:%x\n",\ |
343 | [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4 |
339 | [device.pci_dev]:1,[device.pci_bus]:1,[device.irq_line]:1,[device.io_addr]:4 |
344 | 340 | ||
345 | ; Allocate the receive buffer |
341 | ; Allocate the receive buffer |
346 | 342 | ||
347 | stdcall CreateRingBuffer, dword (RX_BUFFER_SIZE), dword PG_SW |
343 | stdcall CreateRingBuffer, dword (RX_BUFFER_SIZE), dword PG_SW |
348 | test eax, eax |
344 | test eax, eax |
349 | jz .err |
345 | jz .err |
350 | mov [device.rx_buffer], eax |
346 | mov [device.rx_buffer], eax |
351 | 347 | ||
352 | ; Ok, the eth_device structure is ready, let's probe the device |
348 | ; Ok, the eth_device structure is ready, let's probe the device |
353 | 349 | ||
354 | call probe ; this function will output in eax |
350 | call probe ; this function will output in eax |
355 | test eax, eax |
351 | test eax, eax |
356 | jnz .err ; If an error occured, exit |
352 | jnz .err ; If an error occured, exit |
357 | 353 | ||
358 | mov eax, [devices] ; Add the device structure to our device list |
354 | mov eax, [devices] ; Add the device structure to our device list |
359 | mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device) |
355 | mov [device_list+4*eax], ebx ; (IRQ handler uses this list to find device) |
360 | inc [devices] ; |
356 | inc [devices] ; |
361 | 357 | ||
362 | mov [device.type], NET_TYPE_ETH |
358 | mov [device.type], NET_TYPE_ETH |
363 | call NetRegDev |
359 | call NetRegDev |
364 | 360 | ||
365 | cmp eax, -1 |
361 | cmp eax, -1 |
366 | je .destroy |
362 | je .destroy |
367 | 363 | ||
368 | ret |
364 | ret |
369 | 365 | ||
370 | ; If the device was already loaded, find the device number and return it in eax |
366 | ; If the device was already loaded, find the device number and return it in eax |
371 | 367 | ||
372 | .find_devicenum: |
368 | .find_devicenum: |
373 | DEBUGF 2, "Trying to find device number of already registered device\n" |
369 | DEBUGF 2, "Trying to find device number of already registered device\n" |
374 | call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx |
370 | call NetPtrToNum ; This kernel procedure converts a pointer to device struct in ebx |
375 | ; into a device number in edi |
371 | ; into a device number in edi |
376 | mov eax, edi ; Application wants it in eax instead |
372 | mov eax, edi ; Application wants it in eax instead |
377 | DEBUGF 2, "Kernel says: %u\n", eax |
373 | DEBUGF 2, "Kernel says: %u\n", eax |
378 | ret |
374 | ret |
379 | 375 | ||
380 | ; If an error occured, remove all allocated data and exit (returning -1 in eax) |
376 | ; If an error occured, remove all allocated data and exit (returning -1 in eax) |
381 | 377 | ||
382 | .destroy: |
378 | .destroy: |
383 | ; todo: reset device into virgin state |
379 | ; todo: reset device into virgin state |
384 | 380 | ||
385 | .err: |
381 | .err: |
386 | stdcall KernelFree, [device.rx_buffer] |
382 | stdcall KernelFree, [device.rx_buffer] |
387 | stdcall KernelFree, ebx |
383 | stdcall KernelFree, ebx |
388 | 384 | ||
389 | .fail: |
385 | .fail: |
390 | or eax, -1 |
386 | or eax, -1 |
391 | ret |
387 | ret |
392 | 388 | ||
393 | ;------------------------------------------------------ |
389 | ;------------------------------------------------------ |
394 | endp |
390 | endp |
395 | 391 | ||
396 | 392 | ||
397 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
393 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
398 | ;; ;; |
394 | ;; ;; |
399 | ;; Actual Hardware dependent code starts here ;; |
395 | ;; Actual Hardware dependent code starts here ;; |
400 | ;; ;; |
396 | ;; ;; |
401 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
397 | ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;; |
402 | 398 | ||
403 | align 4 |
399 | align 4 |
404 | unload: |
400 | unload: |
405 | ; TODO: (in this particular order) |
401 | ; TODO: (in this particular order) |
406 | ; |
402 | ; |
407 | ; - Stop the device |
403 | ; - Stop the device |
408 | ; - Detach int handler |
404 | ; - Detach int handler |
409 | ; - Remove device from local list (RTL8139_LIST) |
405 | ; - Remove device from local list (RTL8139_LIST) |
410 | ; - call unregister function in kernel |
406 | ; - call unregister function in kernel |
411 | ; - Remove all allocated structures and buffers the card used |
407 | ; - Remove all allocated structures and buffers the card used |
412 | 408 | ||
413 | or eax, -1 |
409 | or eax, -1 |
414 | 410 | ||
415 | ret |
411 | ret |
416 | 412 | ||
417 | 413 | ||
418 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
414 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
419 | ;; |
415 | ;; |
420 | ;; probe: enables the device (if it really is RTL8139) |
416 | ;; probe: enables the device (if it really is RTL8139) |
421 | ;; |
417 | ;; |
422 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
418 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
423 | 419 | ||
424 | align 4 |
420 | align 4 |
425 | probe: |
421 | probe: |
426 | DEBUGF 2, "Probing %s device\n", my_service |
422 | DEBUGF 2, "Probing %s device\n", my_service |
427 | 423 | ||
428 | PCI_make_bus_master |
424 | PCI_make_bus_master |
429 | 425 | ||
430 | ; get chip version |
426 | ; get chip version |
431 | - | ||
432 | set_io 0 |
427 | set_io 0 |
433 | set_io REG_TXCONFIG + 2 |
428 | set_io REG_TXCONFIG + 2 |
434 | in ax, dx |
429 | in ax, dx |
435 | shr ah, 2 |
430 | shr ah, 2 |
436 | shr ax, 6 |
431 | shr ax, 6 |
437 | and al, 01111111b |
432 | and al, 01111111b |
- | 433 | ||
438 | 434 | ; now find it in our array |
|
439 | mov ecx, HW_VER_ARRAY_SIZE-1 |
435 | mov ecx, HW_VER_ARRAY_SIZE-1 |
440 | .chip_ver_loop: |
436 | .chip_ver_loop: |
441 | cmp al, [hw_ver_array + ecx] |
437 | cmp al, [hw_ver_array + ecx] |
442 | je .chip_ver_found |
438 | je .chip_ver_found |
443 | dec ecx |
439 | dec ecx |
444 | jns .chip_ver_loop |
440 | jns .chip_ver_loop |
445 | .unknown: |
441 | .unknown: |
446 | mov ecx, 8 |
442 | mov ecx, 8 |
447 | .chip_ver_found: |
443 | .chip_ver_found: |
448 | cmp ecx, 8 |
444 | cmp ecx, 8 |
449 | ja .unknown |
445 | ja .unknown |
450 | 446 | ||
451 | mov [device.hw_ver_id], cl |
447 | mov [device.hw_ver_id], cl |
452 | 448 | ||
453 | mov ecx, [crosslist+ecx*4] |
449 | mov ecx, [crosslist+ecx*4] |
454 | mov [device.name], ecx |
450 | mov [device.name], ecx |
455 | 451 | ||
456 | DEBUGF 2, "Chip version: %s\n", ecx |
452 | DEBUGF 2, "Chip version: %s\n", ecx |
457 | 453 | ||
458 | ; wake up the chip |
454 | ; wake up the chip |
459 | - | ||
460 | set_io 0 |
455 | set_io 0 |
461 | set_io REG_HLTCLK |
456 | set_io REG_HLTCLK |
462 | mov al, 'R' ; run the clock |
457 | mov al, 'R' ; run the clock |
463 | out dx, al |
458 | out dx, al |
464 | 459 | ||
465 | ; unlock config and BMCR registers |
460 | ; unlock config and BMCR registers |
466 | - | ||
467 | set_io REG_9346CR |
461 | set_io REG_9346CR |
468 | mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0) |
462 | mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0) |
469 | out dx, al |
463 | out dx, al |
470 | 464 | ||
471 | ; enable power management |
465 | ; enable power management |
472 | - | ||
473 | set_io REG_CONFIG1 |
466 | set_io REG_CONFIG1 |
474 | in al, dx |
467 | in al, dx |
475 | cmp [device.hw_ver_id], IDX_RTL8139B |
468 | cmp [device.hw_ver_id], IDX_RTL8139B |
476 | jb .old_chip |
469 | jae .new_chip |
- | 470 | ; wake up older chips |
|
- | 471 | and al, not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN)) |
|
- | 472 | out dx, al |
|
- | 473 | jmp .finish_wake_up |
|
477 | 474 | ||
478 | ; set LWAKE pin to active high (default value). |
475 | ; set LWAKE pin to active high (default value). |
479 | ; it is for Wake-On-LAN functionality of some motherboards. |
476 | ; it is for Wake-On-LAN functionality of some motherboards. |
480 | ; this signal is used to inform the motherboard to execute a wake-up process. |
477 | ; this signal is used to inform the motherboard to execute a wake-up process. |
481 | ; only at newer chips. |
478 | ; only at newer chips. |
482 | 479 | .new_chip: |
|
483 | or al, (1 shl BIT_PMEn) |
480 | or al, (1 shl BIT_PMEn) |
484 | and al, not (1 shl BIT_LWACT) |
481 | and al, not (1 shl BIT_LWACT) |
485 | out dx, al |
482 | out dx, al |
486 | 483 | ||
487 | set_io REG_CONFIG4 |
484 | set_io REG_CONFIG4 |
488 | in al, dx |
485 | in al, dx |
489 | and al, not (1 shl BIT_LWPTN) |
486 | and al, not (1 shl BIT_LWPTN) |
490 | out dx, al |
487 | out dx, al |
491 | - | ||
492 | jmp .finish_wake_up |
- | |
493 | .old_chip: |
- | |
494 | - | ||
495 | ; wake up older chips |
- | |
496 | - | ||
497 | and al, not ((1 shl BIT_SLEEP) or (1 shl BIT_PWRDWN)) |
- | |
498 | out dx, al |
- | |
499 | .finish_wake_up: |
- | |
500 | 488 | ||
501 | ; lock config and BMCR registers |
- | |
- | 489 | ; lock config and BMCR registers |
|
502 | 490 | .finish_wake_up: |
|
503 | xor al, al |
491 | xor al, al |
504 | set_io 0 |
492 | set_io 0 |
505 | set_io REG_9346CR |
493 | set_io REG_9346CR |
506 | out dx, al |
494 | out dx, al |
507 | DEBUGF 2, "done!\n" |
495 | DEBUGF 2, "done!\n" |
508 | 496 | ||
509 | 497 | ||
510 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
498 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
511 | ;; |
499 | ;; |
512 | ;; reset: Set up all registers and descriptors, clear some values |
500 | ;; reset: Set up all registers and descriptors, clear some values |
513 | ;; |
501 | ;; |
514 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
502 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
515 | 503 | ||
516 | reset: |
504 | reset: |
517 | DEBUGF 2, "Resetting\n" |
505 | DEBUGF 2, "Reset\n" |
518 | 506 | ||
519 | ; attach int handler |
- | |
520 | 507 | ; attach int handler |
|
521 | movzx eax, [device.irq_line] |
508 | movzx eax, [device.irq_line] |
522 | DEBUGF 1, "Attaching int handler to irq %x, ", eax:1 |
509 | DEBUGF 1, "Attaching int handler to irq %x\n", eax:1 |
523 | stdcall AttachIntHandler, eax, int_handler, dword 0 |
510 | stdcall AttachIntHandler, eax, int_handler, dword 0 |
524 | test eax, eax |
511 | test eax, eax |
525 | jnz @f |
512 | jnz @f |
526 | DEBUGF 1, "\nCould not attach int handler!\n" |
513 | DEBUGF 1, "\nCould not attach int handler!\n" |
527 | ; or eax, -1 |
514 | ; or eax, -1 |
528 | ; ret |
515 | ; ret |
529 | @@: |
516 | @@: |
530 | 517 | ||
531 | ; reset chip |
518 | ; reset chip |
532 | - | ||
533 | DEBUGF 1, "Resetting chip\n" |
519 | DEBUGF 1, "Resetting chip\n" |
534 | set_io 0 |
520 | set_io 0 |
535 | set_io REG_COMMAND |
521 | set_io REG_COMMAND |
536 | mov al , 1 shl BIT_RST |
522 | mov al, 1 shl BIT_RST |
537 | out dx , al |
523 | out dx, al |
538 | mov cx , 1000 ; wait no longer for the reset |
524 | mov cx, 1000 ; wait no longer for the reset |
539 | .wait_for_reset: |
525 | .wait_for_reset: |
540 | in al , dx |
526 | in al, dx |
541 | test al , 1 shl BIT_RST |
527 | test al, 1 shl BIT_RST |
542 | jz .reset_completed ; RST remains 1 during reset |
528 | jz .reset_completed ; RST remains 1 during reset |
543 | dec cx |
529 | dec cx |
544 | jns .wait_for_reset |
530 | jns .wait_for_reset |
- | 531 | DEBUGF 1, "Reset timeout!\n" |
|
545 | .reset_completed: |
532 | .reset_completed: |
546 | 533 | ||
547 | ; unlock config and BMCR registers |
534 | ; unlock config and BMCR registers |
548 | - | ||
549 | set_io REG_9346CR |
535 | set_io REG_9346CR |
550 | mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0) |
536 | mov al, (1 shl BIT_93C46_EEM1) or (1 shl BIT_93C46_EEM0) |
551 | out dx, al |
537 | out dx, al |
552 | 538 | ||
553 | ; initialize multicast registers (no filtering) |
539 | ; initialize multicast registers (no filtering) |
554 | - | ||
555 | mov eax, 0xffffffff |
540 | mov eax, 0xffffffff |
556 | set_io REG_MAR0 |
541 | set_io REG_MAR0 |
557 | out dx, eax |
542 | out dx, eax |
558 | set_io REG_MAR4 |
543 | set_io REG_MAR4 |
559 | out dx, eax |
544 | out dx, eax |
560 | - | ||
561 | ; enable Rx/Tx |
- | |
562 | - | ||
563 | mov al, (1 shl BIT_RE) or (1 shl BIT_TE) |
- | |
564 | set_io REG_COMMAND |
- | |
565 | out dx, al |
- | |
566 | 545 | ||
567 | ; Rxbuffer size, unlimited dma burst, no wrapping, no rx threshold |
546 | ; Rxbuffer size, unlimited dma burst, no wrapping, no rx threshold |
568 | ; accept broadcast packets, accept physical match packets |
- | |
569 | 547 | ; accept broadcast packets, accept physical match packets |
|
570 | mov ax, RX_CONFIG |
548 | mov ax, RX_CONFIG |
571 | set_io REG_RXCONFIG |
549 | set_io REG_RXCONFIG |
572 | out dx, ax |
550 | out dx, ax |
573 | - | ||
574 | 551 | ||
575 | ; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 |
- | |
576 | 552 | ; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 |
|
577 | mov eax, (TX_MXDMA shl BIT_TX_MXDMA) or (TXRR shl BIT_TXRR) or BIT_IFG1 or BIT_IFG0 |
553 | mov eax, (TX_MXDMA shl BIT_TX_MXDMA) or (TXRR shl BIT_TXRR) or BIT_IFG1 or BIT_IFG0 |
578 | set_io REG_TXCONFIG |
554 | set_io REG_TXCONFIG |
579 | out dx, eax |
555 | out dx, eax |
580 | 556 | ||
581 | ; enable auto negotiation |
557 | ; enable auto negotiation |
582 | - | ||
583 | set_io REG_BMCR |
558 | set_io REG_BMCR |
584 | in ax, dx |
559 | in ax, dx |
585 | or ax, (1 shl BIT_ANE) |
560 | or ax, (1 shl BIT_ANE) |
586 | out dx, ax |
561 | out dx, ax |
587 | 562 | ||
588 | ; set auto negotiation advertisement |
563 | ; set auto negotiation advertisement |
589 | - | ||
590 | set_io REG_ANAR |
564 | set_io REG_ANAR |
591 | in ax, dx |
565 | in ax, dx |
592 | or ax, (1 shl BIT_SELECTOR) or (1 shl BIT_10) or (1 shl BIT_10FD) or (1 shl BIT_TX) or (1 shl BIT_TXFD) |
566 | or ax, (1 shl BIT_SELECTOR) or (1 shl BIT_10) or (1 shl BIT_10FD) or (1 shl BIT_TX) or (1 shl BIT_TXFD) |
593 | out dx, ax |
567 | out dx, ax |
594 | 568 | ||
595 | ; lock config and BMCR registers |
569 | ; lock config and BMCR registers |
596 | - | ||
597 | xor eax, eax |
570 | xor eax, eax |
598 | set_io REG_9346CR |
571 | set_io REG_9346CR |
599 | out dx, al |
572 | out dx, al |
600 | 573 | ||
601 | ; init RX/TX pointers |
574 | ; init RX/TX pointers |
602 | - | ||
603 | mov [device.rx_data_offset], eax |
575 | mov [device.rx_data_offset], eax |
604 | mov [device.curr_tx_desc], al |
576 | mov [device.curr_tx_desc], al |
605 | - | ||
606 | ; set_io REG_CAPR |
577 | ; set_io REG_CAPR |
607 | ; out dx, ax |
578 | ; out dx, ax |
608 | 579 | ||
609 | ; clear packet/byte counters |
580 | ; clear packet/byte counters |
610 | - | ||
611 | lea edi, [device.bytes_tx] |
581 | lea edi, [device.bytes_tx] |
612 | mov ecx, 6 |
582 | mov ecx, 6 |
613 | rep stosd |
583 | rep stosd |
614 | 584 | ||
615 | ; clear missing packet counter |
585 | ; clear missing packet counter |
616 | - | ||
617 | set_io REG_MPC |
586 | set_io REG_MPC |
618 | out dx, eax |
587 | out dx, eax |
619 | 588 | ||
620 | ; set RxBuffer address, init RX buffer offset |
589 | ; set RxBuffer address, init RX buffer offset |
621 | - | ||
622 | mov eax, [device.rx_buffer] |
590 | mov eax, [device.rx_buffer] |
623 | mov dword[eax], 0 |
591 | mov dword[eax], 0 ; clear receive flags for first packet (really needed??) |
624 | DEBUGF 2, "RX buffer: %x\n", eax |
592 | DEBUGF 2, "RX buffer virtual addr=0x%x\n", eax |
625 | GetRealAddr |
593 | GetRealAddr |
626 | DEBUGF 2, "RX buffer: %x\n", eax |
594 | DEBUGF 2, "RX buffer real addr=0x%x\n", eax |
627 | set_io REG_RBSTART |
595 | set_io REG_RBSTART |
628 | out dx, eax |
596 | out dx, eax |
629 | 597 | ||
630 | ; Read MAC address |
598 | ; Read MAC address |
631 | - | ||
632 | call read_mac |
599 | call read_mac |
633 | 600 | ||
634 | ; enable interrupts |
- | |
635 | 601 | ; enable Rx/Tx |
|
- | 602 | set_io 0 |
|
- | 603 | mov al, (1 shl BIT_RE) or (1 shl BIT_TE) |
|
- | 604 | set_io REG_COMMAND |
|
- | 605 | out dx, al |
|
- | 606 | ||
636 | set_io 0 |
607 | ; enable interrupts |
637 | set_io REG_IMR |
608 | set_io REG_IMR |
638 | mov eax, INTERRUPT_MASK |
609 | mov ax, INTERRUPT_MASK |
639 | out dx , ax |
610 | out dx, ax |
640 | 611 | ||
641 | ; Set the mtu, kernel will be able to send now |
612 | ; Set the mtu, kernel will be able to send now |
642 | mov [device.mtu], 1514 |
613 | mov [device.mtu], 1514 |
643 | 614 | ||
644 | ; Indicate that we have successfully reset the card |
615 | call cable |
645 | 616 | ||
646 | DEBUGF 2, "Done!\n" |
- | |
647 | xor eax, eax |
617 | ; Indicate that we have successfully reset the card |
648 | 618 | xor eax, eax |
|
649 | ret |
619 | ret |
650 | 620 | ||
651 | 621 | ||
652 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
622 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
653 | ;; ;; |
623 | ;; ;; |
654 | ;; Transmit ;; |
624 | ;; Transmit ;; |
655 | ;; ;; |
625 | ;; ;; |
656 | ;; In: buffer pointer in [esp+4] ;; |
626 | ;; In: buffer pointer in [esp+4] ;; |
657 | ;; size of buffer in [esp+8] ;; |
627 | ;; size of buffer in [esp+8] ;; |
658 | ;; pointer to device structure in ebx ;; |
628 | ;; pointer to device structure in ebx ;; |
659 | ;; ;; |
629 | ;; ;; |
660 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
630 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
661 | align 4 |
631 | align 4 |
662 | transmit: |
632 | transmit: |
663 | DEBUGF 1, "\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8] |
633 | DEBUGF 1, "\nTransmitting packet, buffer:%x, size:%u\n", [esp+4], [esp+8] |
664 | mov eax, [esp+4] |
634 | mov eax, [esp+4] |
665 | DEBUGF 1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ |
635 | DEBUGF 1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ |
666 | [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ |
636 | [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ |
667 | [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ |
637 | [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ |
668 | [eax+13]:2,[eax+12]:2 |
638 | [eax+13]:2,[eax+12]:2 |
669 | 639 | ||
670 | cmp dword [esp+8], MAX_ETH_FRAME_SIZE |
640 | cmp dword [esp+8], MAX_ETH_FRAME_SIZE |
671 | ja .fail |
641 | ja .fail |
672 | cmp dword [esp+8], 60 |
642 | cmp dword [esp+8], 60 |
673 | jb .fail |
643 | jb .fail |
674 | 644 | ||
675 | ; check if we own the current discriptor |
645 | ; check if we own the current discriptor |
676 | set_io 0 |
646 | set_io 0 |
677 | set_io REG_TSD0 |
647 | set_io REG_TSD0 |
678 | movzx ecx, [device.curr_tx_desc] |
648 | movzx ecx, [device.curr_tx_desc] |
679 | shl ecx, 2 |
649 | shl ecx, 2 |
680 | add edx, ecx |
650 | add edx, ecx |
681 | in eax, dx |
651 | in eax, dx |
682 | test eax, (1 shl BIT_OWN) |
652 | test eax, (1 shl BIT_OWN) |
683 | jz .wait_to_send |
653 | jz .wait_to_send |
684 | 654 | ||
685 | .send_packet: |
655 | .send_packet: |
686 | ; get next descriptor |
656 | ; get next descriptor |
687 | inc [device.curr_tx_desc] |
657 | inc [device.curr_tx_desc] |
688 | and [device.curr_tx_desc], NUM_TX_DESC-1 |
658 | and [device.curr_tx_desc], NUM_TX_DESC-1 |
689 | 659 | ||
690 | ; Update stats |
660 | ; Update stats |
691 | inc [device.packets_tx] |
661 | inc [device.packets_tx] |
692 | mov eax, [esp+8] |
662 | mov eax, [esp+8] |
693 | add dword [device.bytes_tx], eax |
663 | add dword [device.bytes_tx], eax |
694 | adc dword [device.bytes_tx+4], 0 |
664 | adc dword [device.bytes_tx+4], 0 |
695 | 665 | ||
696 | ; Set the buffer address |
666 | ; Set the buffer address |
697 | set_io REG_TSAD0 |
667 | set_io REG_TSAD0 |
698 | mov eax, [esp+4] |
668 | mov eax, [esp+4] |
699 | mov [device.TX_DESC+ecx], eax |
669 | mov [device.TX_DESC+ecx], eax |
700 | GetRealAddr |
670 | GetRealAddr |
701 | out dx, eax |
671 | out dx, eax |
702 | 672 | ||
703 | ; And the size of the buffer |
673 | ; And the size of the buffer |
704 | set_io REG_TSD0 |
674 | set_io REG_TSD0 |
705 | mov eax, [esp+8] |
675 | mov eax, [esp+8] |
706 | or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold |
676 | or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold |
707 | out dx, eax |
677 | out dx, eax |
708 | 678 | ||
709 | DEBUGF 1, "Packet Sent!\n" |
679 | DEBUGF 1, "Packet Sent!\n" |
710 | xor eax, eax |
680 | xor eax, eax |
711 | ret 8 |
681 | ret 8 |
712 | 682 | ||
713 | .wait_to_send: |
683 | .wait_to_send: |
714 | DEBUGF 1, "Waiting for timeout\n" |
684 | DEBUGF 1, "Waiting for timeout\n" |
715 | 685 | ||
716 | push edx |
686 | push edx |
717 | mov esi, 30 |
687 | mov esi, 30 |
718 | stdcall Sleep |
688 | stdcall Sleep |
719 | pop edx |
689 | pop edx |
720 | 690 | ||
721 | in ax, dx |
691 | in ax, dx |
722 | test ax, (1 shl BIT_OWN) |
692 | test ax, (1 shl BIT_OWN) |
723 | jnz .send_packet |
693 | jnz .send_packet |
724 | 694 | ||
725 | pusha |
695 | pusha |
726 | call reset ; if chip hung, reset it |
696 | call reset ; if chip hung, reset it |
727 | popa |
697 | popa |
728 | 698 | ||
729 | jmp .send_packet |
699 | jmp .send_packet |
730 | 700 | ||
731 | .fail: |
701 | .fail: |
732 | DEBUGF 1, "failed!\n" |
702 | DEBUGF 1, "failed!\n" |
733 | stdcall KernelFree, [esp+4] |
703 | stdcall KernelFree, [esp+4] |
734 | or eax, -1 |
704 | or eax, -1 |
735 | ret 8 |
705 | ret 8 |
736 | 706 | ||
737 | 707 | ||
738 | 708 | ||
739 | 709 | ||
740 | 710 | ||
741 | ;;;;;;;;;;;;;;;;;;;;;;; |
711 | ;;;;;;;;;;;;;;;;;;;;;;; |
742 | ;; ;; |
712 | ;; ;; |
743 | ;; Interrupt handler ;; |
713 | ;; Interrupt handler ;; |
744 | ;; ;; |
714 | ;; ;; |
745 | ;;;;;;;;;;;;;;;;;;;;;;; |
715 | ;;;;;;;;;;;;;;;;;;;;;;; |
746 | 716 | ||
747 | align 4 |
717 | align 4 |
748 | int_handler: |
718 | int_handler: |
749 | 719 | ||
750 | DEBUGF 1, "\n%s int\n", my_service |
720 | DEBUGF 1, "\n%s int\n", my_service |
751 | 721 | ||
752 | ; find pointer of device wich made IRQ occur |
722 | ; find pointer of device wich made IRQ occur |
753 | - | ||
754 | mov ecx, [devices] |
723 | mov ecx, [devices] |
755 | test ecx, ecx |
724 | test ecx, ecx |
756 | jz .nothing |
725 | jz .nothing |
757 | mov esi, device_list |
726 | mov esi, device_list |
758 | .nextdevice: |
727 | .nextdevice: |
759 | mov ebx, [esi] |
728 | mov ebx, [esi] |
760 | 729 | ||
761 | set_io 0 |
730 | set_io 0 |
762 | set_io REG_ISR |
731 | set_io REG_ISR |
763 | in ax, dx |
732 | in ax, dx ; Get interrupt status |
764 | out dx, ax ; send it back to ACK |
733 | out dx, ax ; send it back to ACK |
765 | test ax, ax |
734 | test ax, ax |
766 | jnz .got_it |
735 | jnz .got_it |
767 | .continue: |
736 | .continue: |
768 | add esi, 4 |
737 | add esi, 4 |
769 | dec ecx |
738 | dec ecx |
770 | jnz .nextdevice |
739 | jnz .nextdevice |
771 | .nothing: |
740 | .nothing: |
772 | ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) |
741 | ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) |
773 | 742 | ||
774 | .got_it: |
743 | .got_it: |
775 | 744 | ||
776 | DEBUGF 1, "Device: %x Status: %x\n", ebx, ax |
745 | DEBUGF 1, "Device: %x Status: %x\n", ebx, ax |
777 | 746 | ||
778 | ;---------------------------------------------------- |
747 | ;---------------------------------------------------- |
779 | ; Received packet ok? |
748 | ; Received packet ok? |
780 | 749 | ||
781 | test ax, ISR_ROK |
750 | test ax, ISR_ROK |
782 | jz @f |
751 | jz @f |
783 | push ax |
752 | push ax |
784 | 753 | ||
785 | .receive: |
754 | .receive: |
786 | set_io 0 |
755 | set_io 0 |
787 | set_io REG_COMMAND |
756 | set_io REG_COMMAND |
788 | in al , dx |
757 | in al, dx |
789 | test al , BUFE ; test if RX buffer is empty |
758 | test al, BUFE ; test if RX buffer is empty |
790 | jnz .finish ; |
759 | jnz .finish |
791 | 760 | ||
792 | DEBUGF 1, "RX: " |
761 | DEBUGF 1, "RX: " |
793 | 762 | ||
794 | mov eax, [device.rx_buffer] |
763 | mov eax, [device.rx_buffer] |
795 | add eax, [device.rx_data_offset] |
764 | add eax, [device.rx_data_offset] |
796 | test byte [eax], (1 shl BIT_ROK) ; check if packet is ok |
765 | test byte [eax], (1 shl BIT_ROK) ; check if packet is ok |
797 | jz .reset_rx |
766 | jz .reset_rx |
798 | 767 | ||
799 | ; packet is ok, copy it |
768 | ; packet is ok, copy it |
800 | movzx ecx, word [eax+2] ; packet length |
769 | movzx ecx, word [eax+2] ; packet length |
801 | - | ||
802 | sub ecx, 4 ; don't copy CRC |
770 | sub cx, 4 ; don't copy CRC |
803 | 771 | ||
804 | ; Update stats |
772 | ; Update stats |
805 | add dword [device.bytes_rx], ecx |
773 | add dword [device.bytes_rx], ecx |
806 | adc dword [device.bytes_rx + 4], 0 |
774 | adc dword [device.bytes_rx + 4], 0 |
807 | inc dword [device.packets_rx] |
775 | inc [device.packets_rx] |
808 | 776 | ||
809 | DEBUGF 1, "Received %u bytes\n", ecx |
777 | DEBUGF 1, "Received %u bytes\n", ecx |
810 | 778 | ||
811 | push ebx eax ecx |
779 | push ebx eax ecx |
812 | stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into |
780 | stdcall KernelAlloc, ecx ; Allocate a buffer to put packet into |
813 | pop ecx |
781 | pop ecx |
814 | test eax, eax ; Test if we allocated succesfully |
782 | test eax, eax ; Test if we allocated succesfully |
815 | jz .abort |
783 | jz .abort |
816 | 784 | ||
817 | mov edi, eax ; Where we will copy too |
785 | mov edi, eax ; Where we will copy too |
818 | 786 | ||
819 | mov esi, [esp] ; The buffer we will copy from |
787 | mov esi, [esp] ; The buffer we will copy from |
820 | add esi, 4 ; Dont copy CRC |
788 | add esi, 4 ; Dont copy CRC |
821 | 789 | ||
822 | push dword .abort ; Kernel will return to this address after EthReceiver |
790 | push dword .abort ; Kernel will return to this address after EthReceiver |
823 | push ecx edi ; Save buffer pointer and size, to pass to kernel |
791 | push ecx edi ; Save buffer pointer and size, to pass to kernel |
824 | 792 | ||
825 | .copy: |
793 | .copy: |
826 | shr ecx, 1 |
794 | shr ecx, 1 |
827 | jnc .nb |
795 | jnc .nb |
828 | movsb |
796 | movsb |
829 | .nb: |
797 | .nb: |
830 | shr ecx, 1 |
798 | shr ecx, 1 |
831 | jnc .nw |
799 | jnc .nw |
832 | movsw |
800 | movsw |
833 | .nw: |
801 | .nw: |
834 | jz .nd |
802 | jz .nd |
835 | rep movsd |
803 | rep movsd |
836 | .nd: |
804 | .nd: |
837 | 805 | ||
838 | jmp Eth_input ; Send it to kernel |
806 | jmp Eth_input ; Send it to kernel |
839 | 807 | ||
840 | .abort: |
808 | .abort: |
841 | pop eax ebx |
809 | pop eax ebx |
842 | ; update eth_data_start_offset |
810 | ; update eth_data_start_offset |
843 | movzx eax, word [eax+2] ; packet length |
811 | movzx eax, word [eax+2] ; packet length |
844 | add eax, [device.rx_data_offset] |
812 | add eax, [device.rx_data_offset] |
845 | add eax, 4+3 ; packet header is 4 bytes long + dword alignment |
813 | add eax, 4+3 ; packet header is 4 bytes long + dword alignment |
846 | and eax, not 3 ; dword alignment |
814 | and eax, not 3 ; dword alignment |
847 | 815 | ||
848 | cmp eax, RX_BUFFER_SIZE |
816 | cmp eax, RX_BUFFER_SIZE |
849 | jb .no_wrap |
817 | jb .no_wrap |
850 | DEBUGF 2, "Wrapping" |
818 | DEBUGF 2, "Wrapping" |
851 | sub eax, RX_BUFFER_SIZE |
819 | sub eax, RX_BUFFER_SIZE |
852 | .no_wrap: |
820 | .no_wrap: |
853 | mov [device.rx_data_offset], eax |
821 | mov [device.rx_data_offset], eax |
854 | DEBUGF 1, "New RX ptr: %d\n", eax |
822 | DEBUGF 1, "New RX ptr: %d\n", eax |
855 | 823 | ||
856 | set_io 0 |
824 | set_io 0 |
857 | set_io REG_CAPR ; update 'Current Address of Packet Read register' |
825 | set_io REG_CAPR ; update 'Current Address of Packet Read register' |
858 | sub eax, 0x10 ; value 0x10 is a constant for CAPR |
826 | sub eax, 0x10 ; value 0x10 is a constant for CAPR |
859 | out dx , ax |
827 | out dx , ax |
860 | 828 | ||
861 | jmp .receive ; check for multiple packets |
829 | jmp .receive ; check for multiple packets |
862 | 830 | ||
863 | .reset_rx: |
831 | .reset_rx: |
864 | test byte [eax], (1 shl BIT_CRC) |
832 | test byte [eax], (1 shl BIT_CRC) |
865 | jz .no_crc_error |
833 | jz .no_crc_error |
866 | DEBUGF 2, "\nCRC error!\n" |
834 | DEBUGF 2, "\nCRC error!\n" |
867 | 835 | ||
868 | .no_crc_error: |
836 | .no_crc_error: |
869 | test byte [eax], (1 shl BIT_FAE) |
837 | test byte [eax], (1 shl BIT_FAE) |
870 | jz .no_fae_error |
838 | jz .no_fae_error |
871 | DEBUGF 1, "\nFrame alignment error!\n" |
839 | DEBUGF 1, "\nFrame alignment error!\n" |
872 | 840 | ||
873 | .no_fae_error: |
841 | .no_fae_error: |
874 | DEBUGF 1, "Reset RX\n" |
842 | DEBUGF 1, "Reset RX\n" |
875 | in al, dx ; read command register |
843 | in al, dx ; read command register |
876 | push ax |
844 | push ax |
877 | - | ||
878 | and al, not (1 shl BIT_RE) ; Clear the RE bit |
845 | and al, not (1 shl BIT_RE) ; Clear the RE bit |
879 | out dx, al |
846 | out dx, al |
880 | - | ||
881 | pop ax |
847 | pop ax |
882 | out dx, al ; write original command back |
848 | out dx, al ; write original command back |
883 | 849 | ||
884 | add edx, REG_RXCONFIG - REG_COMMAND ; Restore RX configuration |
850 | add edx, REG_RXCONFIG - REG_COMMAND ; Restore RX configuration |
885 | mov ax, RX_CONFIG |
851 | mov ax, RX_CONFIG |
886 | out dx, ax |
852 | out dx, ax |
887 | 853 | ||
888 | .finish: |
854 | .finish: |
889 | pop ax |
855 | pop ax |
890 | 856 | ||
891 | ;---------------------------------------------------- |
857 | ;---------------------------------------------------- |
892 | ; Transmit ok / Transmit error |
858 | ; Transmit ok / Transmit error |
893 | @@: |
859 | @@: |
894 | test ax, ISR_TOK + ISR_TER |
860 | test ax, ISR_TOK + ISR_TER |
895 | jz @f |
861 | jz @f |
896 | 862 | ||
897 | push ax |
863 | push ax |
898 | mov ecx, (NUM_TX_DESC-1)*4 |
864 | mov ecx, (NUM_TX_DESC-1)*4 |
899 | .txdescloop: |
865 | .txdescloop: |
900 | set_io 0 |
866 | set_io 0 |
901 | set_io REG_TSD0 |
867 | set_io REG_TSD0 |
902 | add edx, ecx |
868 | add edx, ecx |
903 | in eax, dx |
869 | in eax, dx |
904 | 870 | ||
905 | test eax, TSR_OWN ; DMA operation completed |
871 | test eax, TSR_OWN ; DMA operation completed |
906 | jz .notthisone |
872 | jz .notthisone |
907 | 873 | ||
908 | cmp [device.TX_DESC+ecx], 0 |
874 | cmp [device.TX_DESC+ecx], 0 |
909 | je .notthisone |
875 | je .notthisone |
910 | 876 | ||
911 | ; .notxd: |
877 | ; .notxd: |
912 | ; test eax, TSR_TUN |
878 | ; test eax, TSR_TUN |
913 | ; jz .nobun |
879 | ; jz .nobun |
914 | ; DEBUGF 2, "TX: FIFO Buffer underrun!\n" |
880 | ; DEBUGF 2, "TX: FIFO Buffer underrun!\n" |
915 | ; |
881 | ; |
916 | ; .nobun: |
882 | ; .nobun: |
917 | ; test eax, TSR_OWC |
883 | ; test eax, TSR_OWC |
918 | ; jz .noowc |
884 | ; jz .noowc |
919 | ; DEBUGF 2, "TX: OWC!\n" |
885 | ; DEBUGF 2, "TX: OWC!\n" |
920 | ; |
886 | ; |
921 | ; .noowc: |
887 | ; .noowc: |
922 | ; test eax, TSR_TABT |
888 | ; test eax, TSR_TABT |
923 | ; jz .notabt |
889 | ; jz .notabt |
924 | ; DEBUGF 2, "TX: TABT!\n" |
890 | ; DEBUGF 2, "TX: TABT!\n" |
925 | ; |
891 | ; |
926 | ; .notabt: |
892 | ; .notabt: |
927 | ; test eax, TSR_CRS |
893 | ; test eax, TSR_CRS |
928 | ; jz .nocsl |
894 | ; jz .nocsl |
929 | ; DEBUGF 2, "TX: Carrier Sense Lost!\n" |
895 | ; DEBUGF 2, "TX: Carrier Sense Lost!\n" |
930 | ; |
896 | ; |
931 | ; .nocsl: |
897 | ; .nocsl: |
932 | 898 | ||
933 | DEBUGF 1, "TX OK: free buffer %x\n", [device.TX_DESC+ecx]:8 |
899 | DEBUGF 1, "TX OK: free buffer %x\n", [device.TX_DESC+ecx]:8 |
934 | push ecx ebx |
900 | push ecx ebx |
935 | stdcall KernelFree, [device.TX_DESC+ecx] |
901 | stdcall KernelFree, [device.TX_DESC+ecx] |
936 | pop ebx ecx |
902 | pop ebx ecx |
937 | mov [device.TX_DESC+ecx], 0 |
903 | mov [device.TX_DESC+ecx], 0 |
938 | 904 | ||
939 | .notthisone: |
905 | .notthisone: |
940 | sub ecx, 4 |
906 | sub ecx, 4 |
941 | ja .txdescloop |
907 | ja .txdescloop |
942 | pop ax |
908 | pop ax |
943 | 909 | ||
944 | ;---------------------------------------------------- |
910 | ;---------------------------------------------------- |
945 | ; Rx buffer overflow ? |
911 | ; Rx buffer overflow ? |
946 | @@: |
912 | @@: |
947 | test ax, ISR_RXOVW |
913 | test ax, ISR_RXOVW |
948 | jz @f |
914 | jz @f |
949 | 915 | ||
950 | push ax |
916 | push ax |
951 | DEBUGF 2, "RX-buffer overflow!\n" |
917 | DEBUGF 2, "RX-buffer overflow!\n" |
952 | 918 | ||
953 | set_io 0 |
919 | set_io 0 |
954 | set_io REG_ISR |
920 | set_io REG_ISR |
955 | mov ax, ISR_FIFOOVW or ISR_RXOVW |
921 | mov ax, ISR_FIFOOVW or ISR_RXOVW |
956 | out dx, ax |
922 | out dx, ax |
957 | pop ax |
923 | pop ax |
958 | 924 | ||
959 | ;---------------------------------------------------- |
925 | ;---------------------------------------------------- |
960 | ; Packet underrun? |
926 | ; Packet underrun? |
961 | @@: |
927 | @@: |
962 | test ax, ISR_PUN |
928 | test ax, ISR_PUN |
963 | jz @f |
929 | jz @f |
964 | 930 | ||
965 | DEBUGF 2, "Packet underrun!\n" |
931 | DEBUGF 2, "Packet underrun!\n" |
966 | 932 | ||
967 | ;---------------------------------------------------- |
933 | ;---------------------------------------------------- |
968 | ; Receive FIFO overflow ? |
934 | ; Receive FIFO overflow ? |
969 | @@: |
935 | @@: |
970 | test ax, ISR_FIFOOVW |
936 | test ax, ISR_FIFOOVW |
971 | jz @f |
937 | jz @f |
972 | 938 | ||
973 | push ax |
939 | push ax |
974 | DEBUGF 2, "RX fifo overflow!\n" |
940 | DEBUGF 2, "RX fifo overflow!\n" |
975 | 941 | ||
976 | set_io 0 |
942 | set_io 0 |
977 | set_io REG_ISR |
943 | set_io REG_ISR |
978 | mov ax, ISR_FIFOOVW or ISR_RXOVW |
944 | mov ax, ISR_FIFOOVW or ISR_RXOVW |
979 | out dx, ax |
945 | out dx, ax |
980 | pop ax |
946 | pop ax |
981 | 947 | ||
982 | ;---------------------------------------------------- |
948 | ;---------------------------------------------------- |
983 | ; Something about Cable changed ? |
949 | ; Something about Cable changed ? |
984 | @@: |
950 | @@: |
985 | test ax, ISR_LENCHG |
951 | test ax, ISR_LENCHG |
986 | jz .fail |
952 | jz .fail |
987 | - | ||
988 | DEBUGF 2, "Cable changed!\n" |
953 | |
989 | call cable |
954 | call cable |
990 | 955 | ||
991 | .fail: |
956 | .fail: |
992 | DEBUGF 2, "\n" |
957 | DEBUGF 2, "\n" |
993 | ret |
958 | ret |
994 | 959 | ||
995 | 960 | ||
996 | 961 | ||
997 | 962 | ||
998 | ;;;;;;;;;;;;;;;;;;;;;;;;; |
963 | ;;;;;;;;;;;;;;;;;;;;;;;;; |
999 | ;; ;; |
964 | ;; ;; |
1000 | ;; Update Cable status ;; |
965 | ;; Update Cable status ;; |
1001 | ;; ;; |
966 | ;; ;; |
1002 | ;;;;;;;;;;;;;;;;;;;;;;;;; |
967 | ;;;;;;;;;;;;;;;;;;;;;;;;; |
1003 | 968 | ||
1004 | align 4 |
969 | align 4 |
1005 | cable: |
970 | cable: |
1006 | DEBUGF 1, "Checking Cable status: " |
971 | DEBUGF 1, "Updating Cable status\n" |
1007 | 972 | ||
1008 | mov edx, dword [device.io_addr] |
973 | set_io 0 |
1009 | add edx, REG_MSR |
974 | set_io REG_MSR |
1010 | in al , dx |
975 | in al, dx |
1011 | 976 | ||
1012 | ; test al , 1 SHL 2 ; 0 = link ok 1 = link fail |
977 | test al, 1 shl 2 ; 0 = link ok 1 = link fail |
1013 | ; jnz .notconnected |
978 | jnz .notconnected |
- | 979 | ||
- | 980 | test al, 1 shl 3 ; 0 = 100 Mbps 1 = 10 Mbps |
|
1014 | 981 | jnz .10mbps |
|
- | 982 | ||
- | 983 | .100mbps: |
|
- | 984 | mov [device.state], ETH_LINK_100M |
|
- | 985 | call NetLinkChanged |
|
- | 986 | ||
- | 987 | ret |
|
- | 988 | ||
- | 989 | .10mbps: |
|
- | 990 | mov [device.state], ETH_LINK_10M |
|
- | 991 | call NetLinkChanged |
|
- | 992 | ||
1015 | ; test al , 1 SHL 3 ; 0 = 100 Mbps 1 = 10 Mbps |
993 | ret |
1016 | ; jnz .10mbps |
- | |
1017 | - | ||
1018 | shr al, 2 |
994 | |
1019 | and al, 3 |
995 | .notconnected: |
1020 | 996 | mov [device.state], ETH_LINK_DOWN |
|
1021 | mov byte [device.mode+3], al |
997 | call NetLinkChanged |
1022 | DEBUGF 1, "Done!\n" |
998 | |
1023 | ret |
999 | ret |
1024 | 1000 | ||
1025 | 1001 | ||
1026 | 1002 | ||
1027 | ;;;;;;;;;;;;;;;;;;;;;;; |
1003 | ;;;;;;;;;;;;;;;;;;;;;;; |
1028 | ;; ;; |
1004 | ;; ;; |
1029 | ;; Write MAC address ;; |
1005 | ;; Write MAC address ;; |
1030 | ;; ;; |
1006 | ;; ;; |
1031 | ;;;;;;;;;;;;;;;;;;;;;;; |
1007 | ;;;;;;;;;;;;;;;;;;;;;;; |
1032 | 1008 | ||
1033 | align 4 |
1009 | align 4 |
1034 | write_mac: ; in: mac pushed onto stack (as 3 words) |
1010 | write_mac: ; in: mac pushed onto stack (as 3 words) |
1035 | 1011 | ||
1036 | DEBUGF 2, "Writing MAC: " |
1012 | DEBUGF 2, "Writing MAC: " |
1037 | 1013 | ||
1038 | ; disable all in command registers |
1014 | ; disable all in command registers |
1039 | - | ||
1040 | set_io 0 |
1015 | set_io 0 |
1041 | set_io REG_9346CR |
1016 | set_io REG_9346CR |
1042 | xor eax, eax |
1017 | xor eax, eax |
1043 | out dx, al |
1018 | out dx, al |
1044 | 1019 | ||
1045 | set_io REG_IMR |
1020 | set_io REG_IMR |
1046 | xor eax, eax |
1021 | xor eax, eax |
1047 | out dx, ax |
1022 | out dx, ax |
1048 | 1023 | ||
1049 | set_io REG_ISR |
1024 | set_io REG_ISR |
1050 | mov eax, -1 |
1025 | mov eax, -1 |
1051 | out dx, ax |
1026 | out dx, ax |
1052 | 1027 | ||
1053 | ; enable writing |
1028 | ; enable writing |
1054 | - | ||
1055 | set_io REG_9346CR |
1029 | set_io REG_9346CR |
1056 | mov eax, REG_9346CR_WE |
1030 | mov eax, REG_9346CR_WE |
1057 | out dx, al |
1031 | out dx, al |
1058 | 1032 | ||
1059 | ; write the mac ... |
1033 | ; write the mac ... |
1060 | - | ||
1061 | set_io REG_IDR0 |
1034 | set_io REG_IDR0 |
1062 | pop eax |
1035 | pop eax |
1063 | out dx, eax |
1036 | out dx, eax |
1064 | 1037 | ||
1065 | set_io REG_IDR0+4 |
1038 | set_io REG_IDR0+4 |
1066 | xor eax, eax |
1039 | xor eax, eax |
1067 | pop ax |
1040 | pop ax |
1068 | out dx, eax |
1041 | out dx, eax |
1069 | 1042 | ||
1070 | ; disable writing |
1043 | ; disable writing |
1071 | - | ||
1072 | set_io REG_9346CR |
1044 | set_io REG_9346CR |
1073 | xor eax, eax |
1045 | xor eax, eax |
1074 | out dx, al |
1046 | out dx, al |
1075 | 1047 | ||
1076 | DEBUGF 2, "ok!\n" |
1048 | DEBUGF 2, "ok!\n" |
1077 | 1049 | ||
1078 | ; Notice this procedure does not ret, but continues to read_mac instead. |
1050 | ; Notice this procedure does not ret, but continues to read_mac instead. |
1079 | 1051 | ||
1080 | 1052 | ||
1081 | ;;;;;;;;;;;;;;;;;;;;;; |
1053 | ;;;;;;;;;;;;;;;;;;;;;; |
1082 | ;; ;; |
1054 | ;; ;; |
1083 | ;; Read MAC address ;; |
1055 | ;; Read MAC address ;; |
1084 | ;; ;; |
1056 | ;; ;; |
1085 | ;;;;;;;;;;;;;;;;;;;;;; |
1057 | ;;;;;;;;;;;;;;;;;;;;;; |
1086 | 1058 | ||
1087 | read_mac: |
1059 | read_mac: |
1088 | DEBUGF 2, "Reading MAC: " |
1060 | DEBUGF 2, "Reading MAC: " |
1089 | 1061 | ||
1090 | set_io 0 |
1062 | set_io 0 |
1091 | lea edi, [device.mac] |
1063 | lea edi, [device.mac] |
1092 | in eax, dx |
1064 | in eax, dx |
1093 | stosd |
1065 | stosd |
1094 | add edx, 4 |
1066 | add edx, 4 |
1095 | in ax, dx |
1067 | in ax, dx |
1096 | stosw |
1068 | stosw |
1097 | 1069 | ||
1098 | DEBUGF 2, "%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2 |
1070 | DEBUGF 2, "%x-%x-%x-%x-%x-%x\n",[edi-6]:2,[edi-5]:2,[edi-4]:2,[edi-3]:2,[edi-2]:2,[edi-1]:2 |
1099 | 1071 | ||
1100 | ret |
1072 | ret |
1101 | 1073 | ||
1102 | 1074 | ||
1103 | ; End of code |
1075 | ; End of code |
1104 | 1076 | ||
1105 | section '.data' data readable writable align 16 ; place all uninitialized data place here |
1077 | section '.data' data readable writable align 16 ; place all uninitialized data place here |
1106 | align 4 ; Place all initialised data here |
1078 | align 4 ; Place all initialised data here |
1107 | 1079 | ||
1108 | devices dd 0 |
1080 | devices dd 0 |
1109 | version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) |
1081 | version dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF) |
1110 | my_service db 'RTL8139',0 ; max 16 chars include zero |
1082 | my_service db 'RTL8139',0 ; max 16 chars include zero |
1111 | 1083 | ||
1112 | device_1 db 'Realtek 8139',0 |
1084 | device_1 db 'Realtek 8139',0 |
1113 | device_2 db 'Realtek 8139A',0 |
1085 | device_2 db 'Realtek 8139A',0 |
1114 | device_3 db 'Realtek 8139B',0 |
1086 | device_3 db 'Realtek 8139B',0 |
1115 | device_4 db 'Realtek 8139C',0 |
1087 | device_4 db 'Realtek 8139C',0 |
1116 | device_5 db 'Realtek 8100',0 |
1088 | device_5 db 'Realtek 8100',0 |
1117 | device_6 db 'Realtek 8139D',0 |
1089 | device_6 db 'Realtek 8139D',0 |
1118 | device_7 db 'Realtek 8139CP',0 |
1090 | device_7 db 'Realtek 8139CP',0 |
1119 | device_8 db 'Realtek 8101',0 |
1091 | device_8 db 'Realtek 8101',0 |
1120 | device_unknown db 'Unknown RTL8139 clone', 0 |
1092 | device_unknown db 'Unknown RTL8139 clone', 0 |
1121 | 1093 | ||
1122 | crosslist: |
1094 | crosslist: |
1123 | dd device_1 |
1095 | dd device_1 |
1124 | dd device_2 |
1096 | dd device_2 |
1125 | dd device_3 |
1097 | dd device_3 |
1126 | dd device_4 |
1098 | dd device_4 |
1127 | dd device_5 |
1099 | dd device_5 |
1128 | dd device_6 |
1100 | dd device_6 |
1129 | dd device_7 |
1101 | dd device_7 |
1130 | dd device_8 |
1102 | dd device_8 |
1131 | dd device_unknown |
1103 | dd device_unknown |
1132 | 1104 | ||
1133 | hw_ver_array: ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with |
1105 | hw_ver_array: ; This array is used by the probe routine to find out wich version of the RTL8139 we are working with |
1134 | db VER_RTL8139 |
1106 | db VER_RTL8139 |
1135 | db VER_RTL8139A |
1107 | db VER_RTL8139A |
1136 | db VER_RTL8139B |
1108 | db VER_RTL8139B |
1137 | db VER_RTL8139C |
1109 | db VER_RTL8139C |
1138 | db VER_RTL8100 |
1110 | db VER_RTL8100 |
1139 | db VER_RTL8139D |
1111 | db VER_RTL8139D |
1140 | db VER_RTL8139CP |
1112 | db VER_RTL8139CP |
1141 | db VER_RTL8101 |
1113 | db VER_RTL8101 |
1142 | db 0 |
1114 | db 0 |
1143 | 1115 | ||
1144 | HW_VER_ARRAY_SIZE = $-hw_ver_array |
1116 | HW_VER_ARRAY_SIZE = $-hw_ver_array |
1145 | 1117 | ||
1146 | include_debug_strings ; All data wich FDO uses will be included here |
1118 | include_debug_strings ; All data wich FDO uses will be included here |
1147 | 1119 | ||
1148 | device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling> |
1120 | device_list rd MAX_DEVICES ; This list contains all pointers to device structures the driver is handling> |