Rev 2434 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
261 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
2465 | Serge | 3 | ;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;; |
431 | serge | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
261 | hidnplayr | 6 | ;; RTL8139.INC ;; |
7 | ;; ;; |
||
8 | ;; Ethernet driver for Menuet OS ;; |
||
9 | ;; ;; |
||
10 | ;; Version 0.2 11 August 2003 ;; |
||
11 | ;; ;; |
||
12 | ;; Driver for chips of RealTek 8139 family ;; |
||
13 | ;; References: ;; |
||
14 | ;; www.realtek.com.hw - data sheets ;; |
||
15 | ;; rtl8139.c - linux driver ;; |
||
16 | ;; 8139too.c - linux driver ;; |
||
17 | ;; ethernet driver template by Mike Hibbett ;; |
||
18 | ;; ;; |
||
19 | ;; The copyright statement is ;; |
||
20 | ;; ;; |
||
21 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
22 | ;; Version 2, June 1991 ;; |
||
23 | ;; ;; |
||
24 | ;; Copyright 2003 Endre Kozma, ;; |
||
25 | ;; endre.kozma@axelero.hu ;; |
||
26 | ;; ;; |
||
27 | ;; See file COPYING for details ;; |
||
28 | ;; ;; |
||
330 | heavyiron | 29 | ;; 10.01.2007 Bugfix for l8139_transmit from Paolo Franchetti ;; |
261 | hidnplayr | 30 | ;; ;; |
31 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
593 | mikedld | 32 | |
33 | $Revision: 2465 $ |
||
34 | |||
35 | |||
2434 | Serge | 36 | ETH_ALEN equ 6 |
37 | ETH_HLEN equ (2 * ETH_ALEN + 2) |
||
38 | ETH_ZLEN equ 60 ; 60 + 4bytes auto payload for |
||
39 | ; mininmum 64bytes frame length |
||
261 | hidnplayr | 40 | |
2434 | Serge | 41 | PCI_REG_COMMAND equ 0x04 ; command register |
42 | PCI_BIT_PIO equ 0 ; bit0: io space control |
||
43 | PCI_BIT_MMIO equ 1 ; bit1: memory space control |
||
44 | PCI_BIT_MASTER equ 2 ; bit2: device acts as a PCI master |
||
261 | hidnplayr | 45 | |
2434 | Serge | 46 | RTL8139_REG_MAR0 equ 0x08 ; multicast filter register 0 |
47 | RTL8139_REG_MAR4 equ 0x0c ; multicast filter register 4 |
||
48 | RTL8139_REG_TSD0 equ 0x10 ; transmit status of descriptor |
||
49 | RTL8139_REG_TSAD0 equ 0x20 ; transmit start address of descriptor |
||
50 | RTL8139_REG_RBSTART equ 0x30 ; RxBuffer start address |
||
51 | RTL8139_REG_COMMAND equ 0x37 ; command register |
||
52 | RTL8139_REG_CAPR equ 0x38 ; current address of packet read |
||
53 | RTL8139_REG_IMR equ 0x3c ; interrupt mask register |
||
54 | RTL8139_REG_ISR equ 0x3e ; interrupt status register |
||
55 | RTL8139_REG_TXCONFIG equ 0x40 ; transmit configuration register |
||
56 | RTL8139_REG_TXCONFIG_0 equ 0x40 ; transmit configuration register 0 |
||
57 | RTL8139_REG_TXCONFIG_1 equ 0x41 ; transmit configuration register 1 |
||
58 | RTL8139_REG_TXCONFIG_2 equ 0x42 ; transmit configuration register 2 |
||
59 | RTL8139_REG_TXCONFIG_3 equ 0x43 ; transmit configuration register 3 |
||
60 | RTL8139_REG_RXCONFIG equ 0x44 ; receive configuration register 0 |
||
61 | RTL8139_REG_RXCONFIG_0 equ 0x44 ; receive configuration register 0 |
||
62 | RTL8139_REG_RXCONFIG_1 equ 0x45 ; receive configuration register 1 |
||
63 | RTL8139_REG_RXCONFIG_2 equ 0x46 ; receive configuration register 2 |
||
64 | RTL8139_REG_RXCONFIG_3 equ 0x47 ; receive configuration register 3 |
||
65 | RTL8139_REG_MPC equ 0x4c ; missed packet counter |
||
66 | RTL8139_REG_9346CR equ 0x50 ; serial eeprom 93C46 command register |
||
67 | RTL8139_REG_CONFIG1 equ 0x52 ; configuration register 1 |
||
68 | RTL8139_REG_CONFIG4 equ 0x5a ; configuration register 4 |
||
69 | RTL8139_REG_HLTCLK equ 0x5b ; undocumented halt clock register |
||
70 | RTL8139_REG_BMCR equ 0x62 ; basic mode control register |
||
71 | RTL8139_REG_ANAR equ 0x66 ; auto negotiation advertisement register |
||
261 | hidnplayr | 72 | |
73 | ; 5.1 packet header |
||
2434 | Serge | 74 | RTL8139_BIT_RUNT equ 4 ; total packet length < 64 bytes |
75 | RTL8139_BIT_LONG equ 3 ; total packet length > 4k |
||
76 | RTL8139_BIT_CRC equ 2 ; crc error occured |
||
77 | RTL8139_BIT_FAE equ 1 ; frame alignment error occured |
||
78 | RTL8139_BIT_ROK equ 0 ; received packet is ok |
||
261 | hidnplayr | 79 | ; 5.4 command register |
2434 | Serge | 80 | RTL8139_BIT_RST equ 4 ; reset bit |
81 | RTL8139_BIT_RE equ 3 ; receiver enabled |
||
82 | RTL8139_BIT_TE equ 2 ; transmitter enabled |
||
83 | RTL8139_BIT_BUFE equ 0 ; rx buffer is empty, no packet stored |
||
261 | hidnplayr | 84 | ; 5.6 interrupt status register |
2434 | Serge | 85 | RTL8139_BIT_ISR_TOK equ 2 ; transmit ok |
86 | RTL8139_BIT_ISR_RER equ 1 ; receive error interrupt |
||
87 | RTL8139_BIT_ISR_ROK equ 0 ; receive ok |
||
261 | hidnplayr | 88 | ; 5.7 transmit configyration register |
2434 | Serge | 89 | RTL8139_BIT_TX_MXDMA equ 8 ; Max DMA burst size per Tx DMA burst |
90 | RTL8139_BIT_TXRR equ 4 ; Tx Retry count 16+(TXRR*16) |
||
261 | hidnplayr | 91 | ; 5.8 receive configuration register |
2434 | Serge | 92 | RTL8139_BIT_RXFTH equ 13 ; Rx fifo threshold |
93 | RTL8139_BIT_RBLEN equ 11 ; Ring buffer length indicator |
||
94 | RTL8139_BIT_RX_MXDMA equ 8 ; Max DMA burst size per Rx DMA burst |
||
95 | RTL8139_BIT_NOWRAP equ 7 ; transfered data wrapping |
||
96 | RTL8139_BIT_9356SEL equ 6 ; eeprom selector 9346/9356 |
||
97 | RTL8139_BIT_AER equ 5 ; accept error packets |
||
98 | RTL8139_BIT_AR equ 4 ; accept runt packets |
||
99 | RTL8139_BIT_AB equ 3 ; accept broadcast packets |
||
100 | RTL8139_BIT_AM equ 2 ; accept multicast packets |
||
101 | RTL8139_BIT_APM equ 1 ; accept physical match packets |
||
102 | RTL8139_BIT_AAP equ 0 ; accept all packets |
||
261 | hidnplayr | 103 | ; 5.9 93C46/93C56 command register |
2434 | Serge | 104 | RTL8139_BIT_93C46_EEM1 equ 7 ; RTL8139 eeprom operating mode1 |
105 | RTL8139_BIT_93C46_EEM0 equ 6 ; RTL8139 eeprom operating mode0 |
||
106 | RTL8139_BIT_93C46_EECS equ 3 ; chip select |
||
107 | RTL8139_BIT_93C46_EESK equ 2 ; serial data clock |
||
108 | RTL8139_BIT_93C46_EEDI equ 1 ; serial data input |
||
109 | RTL8139_BIT_93C46_EEDO equ 0 ; serial data output |
||
261 | hidnplayr | 110 | ; 5.11 configuration register 1 |
2434 | Serge | 111 | RTL8139_BIT_LWACT equ 4 ; see RTL8139_REG_CONFIG1 |
112 | RTL8139_BIT_SLEEP equ 1 ; sleep bit at older chips |
||
113 | RTL8139_BIT_PWRDWN equ 0 ; power down bit at older chips |
||
114 | RTL8139_BIT_PMEn equ 0 ; power management enabled |
||
261 | hidnplayr | 115 | ; 5.14 configuration register 4 |
2434 | Serge | 116 | RTL8139_BIT_LWPTN equ 2 ; see RTL8139_REG_CONFIG4 |
261 | hidnplayr | 117 | ; 6.2 transmit status register |
2434 | Serge | 118 | RTL8139_BIT_ERTXTH equ 16 ; early TX threshold |
119 | RTL8139_BIT_TOK equ 15 ; transmit ok |
||
120 | RTL8139_BIT_OWN equ 13 ; tx DMA operation is completed |
||
261 | hidnplayr | 121 | ; 6.18 basic mode control register |
2434 | Serge | 122 | RTL8139_BIT_ANE equ 12 ; auto negotiation enable |
261 | hidnplayr | 123 | ; 6.20 auto negotiation advertisement register |
2434 | Serge | 124 | RTL8139_BIT_TXFD equ 8 ; 100base-T full duplex |
125 | RTL8139_BIT_TX equ 7 ; 100base-T |
||
126 | RTL8139_BIT_10FD equ 6 ; 10base-T full duplex |
||
127 | RTL8139_BIT_10 equ 5 ; 10base-T |
||
128 | RTL8139_BIT_SELECTOR equ 0 ; binary encoded selector CSMA/CD=00001 |
||
261 | hidnplayr | 129 | ; RX/TX buffer size |
2434 | Serge | 130 | RTL8139_RBLEN equ 0 ; 0==8K 1==16k 2==32k 3==64k |
131 | RTL8139_RX_BUFFER_SIZE equ (8192 shl RTL8139_RBLEN) |
||
132 | MAX_ETH_FRAME_SIZE equ 1516 ; exactly 1514 wthout CRC |
||
133 | RTL8139_NUM_TX_DESC equ 4 |
||
134 | RTL8139_TX_BUFFER_SIZE equ (MAX_ETH_FRAME_SIZE * RTL8139_NUM_TX_DESC) |
||
135 | RTL8139_TXRR equ 8 ; total retries = 16+(TXRR*16) |
||
136 | RTL8139_TX_MXDMA equ 6 ; 0==16 1==32 2==64 3==128 |
||
137 | ; 4==256 5==512 6==1024 7==2048 |
||
138 | RTL8139_ERTXTH equ 8 ; in unit of 32 bytes e.g:(8*32)=256 |
||
139 | RTL8139_RX_MXDMA equ 7 ; 0==16 1==32 2==64 3==128 |
||
140 | ; 4==256 5==512 6==1024 7==unlimited |
||
141 | RTL8139_RXFTH equ 7 ; 0==16 1==32 2==64 3==128 |
||
142 | ; 4==256 5==512 6==1024 7==no threshold |
||
143 | RTL8139_RX_CONFIG equ ((RTL8139_RBLEN shl RTL8139_BIT_RBLEN) \ |
||
144 | or (RTL8139_RX_MXDMA shl RTL8139_BIT_RX_MXDMA) \ |
||
145 | or (1 shl RTL8139_BIT_NOWRAP) \ |
||
146 | or (RTL8139_RXFTH shl RTL8139_BIT_RXFTH) \ |
||
147 | or (1 shl RTL8139_BIT_AB) or (1 shl RTL8139_BIT_APM) \ |
||
148 | or (1 shl RTL8139_BIT_AER) or (1 shl RTL8139_BIT_AR) \ |
||
149 | or (1 shl RTL8139_BIT_AM)) |
||
150 | RTL8139_TX_TIMEOUT equ 30 ; 300 milliseconds timeout |
||
261 | hidnplayr | 151 | |
2434 | Serge | 152 | EE_93C46_REG_ETH_ID equ 7 ; MAC offset |
153 | EE_93C46_READ_CMD equ (6 shl 6) ; 110b + 6bit address |
||
154 | EE_93C56_READ_CMD equ (6 shl 8) ; 110b + 8bit address |
||
155 | EE_93C46_CMD_LENGTH equ 9 ; start bit + cmd + 6bit address |
||
156 | EE_93C56_CMD_LENGTH equ 11 ; start bit + cmd + 8bit ddress |
||
261 | hidnplayr | 157 | |
2434 | Serge | 158 | VER_RTL8139 equ 1100000b |
159 | VER_RTL8139A equ 1110000b |
||
261 | hidnplayr | 160 | ; VER_RTL8139AG equ 1110100b |
2434 | Serge | 161 | VER_RTL8139B equ 1111000b |
162 | VER_RTL8130 equ VER_RTL8139B |
||
163 | VER_RTL8139C equ 1110100b |
||
164 | VER_RTL8100 equ 1111010b |
||
165 | VER_RTL8100B equ 1110101b |
||
166 | VER_RTL8139D equ VER_RTL8100B |
||
167 | VER_RTL8139CP equ 1110110b |
||
168 | VER_RTL8101 equ 1110111b |
||
261 | hidnplayr | 169 | |
2434 | Serge | 170 | IDX_RTL8139 equ 0 |
171 | IDX_RTL8139A equ 1 |
||
172 | IDX_RTL8139B equ 2 |
||
173 | IDX_RTL8139C equ 3 |
||
174 | IDX_RTL8100 equ 4 |
||
175 | IDX_RTL8139D equ 5 |
||
176 | IDX_RTL8139D equ 6 |
||
177 | IDX_RTL8101 equ 7 |
||
261 | hidnplayr | 178 | |
179 | |||
180 | ; These two must be 4 byte aligned ( which they are ) |
||
181 | rtl8139_rx_buff equ eth_data_start |
||
182 | rtl8139_tx_buff equ rtl8139_rx_buff + (RTL8139_RX_BUFFER_SIZE + MAX_ETH_FRAME_SIZE) |
||
183 | |||
184 | uglobal |
||
2434 | Serge | 185 | align 4 |
186 | rtl8139_rx_buff_offset: |
||
187 | dd 0 |
||
373 | mikedld | 188 | curr_tx_desc dd 0 |
261 | hidnplayr | 189 | endg |
190 | |||
191 | iglobal |
||
2434 | Serge | 192 | hw_ver_array: |
193 | db VER_RTL8139, VER_RTL8139A, VER_RTL8139B, VER_RTL8139C |
||
194 | db VER_RTL8100, VER_RTL8139D, VER_RTL8139CP, VER_RTL8101 |
||
261 | hidnplayr | 195 | HW_VER_ARRAY_SIZE = $-hw_ver_array |
196 | endg |
||
197 | |||
198 | uglobal |
||
2434 | Serge | 199 | hw_ver_id: |
200 | db 0 |
||
261 | hidnplayr | 201 | endg |
202 | |||
203 | ;*************************************************************************** |
||
204 | ; Function |
||
205 | ; rtl8139_probe |
||
206 | ; Description |
||
207 | ; Searches for an ethernet card, enables it and clears the rx buffer |
||
208 | ; If a card was found, it enables the ethernet -> TCPIP link |
||
209 | ; Destroyed registers |
||
210 | ; eax, ebx, ecx, edx |
||
211 | ; |
||
212 | ;*************************************************************************** |
||
213 | rtl8139_probe: |
||
214 | ; enable the device |
||
2434 | Serge | 215 | mov al, 2 |
216 | mov ah, [pci_bus] |
||
217 | mov bh, [pci_dev] |
||
218 | mov bl, PCI_REG_COMMAND |
||
219 | call pci_read_reg |
||
220 | mov cx, ax |
||
221 | or cl, (1 shl PCI_BIT_MASTER) or (1 shl PCI_BIT_PIO) |
||
222 | and cl, not (1 shl PCI_BIT_MMIO) |
||
223 | mov al, 2 |
||
224 | mov ah, [pci_bus] |
||
225 | mov bh, [pci_dev] |
||
226 | mov bl, PCI_REG_COMMAND |
||
227 | call pci_write_reg |
||
261 | hidnplayr | 228 | ; get chip version |
2434 | Serge | 229 | mov edx, [io_addr] |
230 | add edx, RTL8139_REG_TXCONFIG_2 |
||
231 | in ax, dx |
||
232 | shr ah, 2 |
||
233 | shr ax, 6 |
||
234 | and al, 01111111b |
||
235 | mov ecx, HW_VER_ARRAY_SIZE-1 |
||
261 | hidnplayr | 236 | .chip_ver_loop: |
2434 | Serge | 237 | cmp al, [hw_ver_array+ecx] |
238 | je .chip_ver_found |
||
239 | dec ecx |
||
240 | jns .chip_ver_loop |
||
241 | xor cl, cl ; default RTL8139 |
||
261 | hidnplayr | 242 | .chip_ver_found: |
2434 | Serge | 243 | mov [hw_ver_id], cl |
261 | hidnplayr | 244 | ; wake up the chip |
2434 | Serge | 245 | mov edx, [io_addr] |
246 | add edx, RTL8139_REG_HLTCLK |
||
247 | mov al, 'R' ; run the clock |
||
248 | out dx, al |
||
261 | hidnplayr | 249 | ; unlock config and BMCR registers |
2434 | Serge | 250 | add edx, RTL8139_REG_9346CR - RTL8139_REG_HLTCLK |
251 | mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) |
||
252 | out dx, al |
||
261 | hidnplayr | 253 | ; enable power management |
2434 | Serge | 254 | add edx, RTL8139_REG_CONFIG1 - RTL8139_REG_9346CR |
255 | in al, dx |
||
256 | cmp byte [hw_ver_id], IDX_RTL8139B |
||
257 | jl .old_chip |
||
261 | hidnplayr | 258 | ; set LWAKE pin to active high (default value). |
259 | ; it is for Wake-On-LAN functionality of some motherboards. |
||
260 | ; this signal is used to inform the motherboard to execute a wake-up process. |
||
261 | ; only at newer chips. |
||
2434 | Serge | 262 | or al, (1 shl RTL8139_BIT_PMEn) |
263 | and al, not (1 shl RTL8139_BIT_LWACT) |
||
264 | out dx, al |
||
265 | add edx, RTL8139_REG_CONFIG4 - RTL8139_REG_CONFIG1 |
||
266 | in al, dx |
||
267 | and al, not (1 shl RTL8139_BIT_LWPTN) |
||
268 | out dx, al |
||
269 | jmp .finish_wake_up |
||
261 | hidnplayr | 270 | .old_chip: |
271 | ; wake up older chips |
||
2434 | Serge | 272 | and al, not ((1 shl RTL8139_BIT_SLEEP) or (1 shl RTL8139_BIT_PWRDWN)) |
273 | out dx, al |
||
261 | hidnplayr | 274 | .finish_wake_up: |
275 | ; lock config and BMCR registers |
||
2434 | Serge | 276 | xor al, al |
277 | mov edx, [io_addr] |
||
278 | add edx, RTL8139_REG_9346CR |
||
279 | out dx, al |
||
261 | hidnplayr | 280 | ;*************************************************************************** |
281 | ; Function |
||
282 | ; rt8139_reset |
||
283 | ; Description |
||
284 | ; Place the chip (ie, the ethernet card) into a virgin state |
||
285 | ; Destroyed registers |
||
286 | ; eax, ebx, ecx, edx |
||
287 | ; |
||
288 | ;*************************************************************************** |
||
289 | rtl8139_reset: |
||
2434 | Serge | 290 | mov edx, [io_addr] |
291 | add edx, RTL8139_REG_COMMAND |
||
292 | mov al, 1 shl RTL8139_BIT_RST |
||
293 | out dx, al |
||
294 | mov cx, 1000 ; wait no longer for the reset |
||
261 | hidnplayr | 295 | .wait_for_reset: |
2434 | Serge | 296 | in al, dx |
297 | test al, 1 shl RTL8139_BIT_RST |
||
298 | jz .reset_completed ; RST remains 1 during reset |
||
299 | dec cx |
||
300 | jns .wait_for_reset |
||
261 | hidnplayr | 301 | .reset_completed: |
302 | ; get MAC (hardware address) |
||
2434 | Serge | 303 | mov ecx, 2 |
261 | hidnplayr | 304 | .mac_read_loop: |
2434 | Serge | 305 | lea eax, [EE_93C46_REG_ETH_ID+ecx] |
306 | push ecx |
||
307 | call rtl8139_read_eeprom |
||
308 | pop ecx |
||
309 | mov [node_addr+ecx*2], ax |
||
310 | dec ecx |
||
311 | jns .mac_read_loop |
||
261 | hidnplayr | 312 | ; unlock config and BMCR registers |
2434 | Serge | 313 | mov edx, [io_addr] |
314 | add edx, RTL8139_REG_9346CR |
||
315 | mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EEM0) |
||
316 | out dx, al |
||
261 | hidnplayr | 317 | ; initialize multicast registers (no filtering) |
2434 | Serge | 318 | mov eax, 0xffffffff |
319 | add edx, RTL8139_REG_MAR0 - RTL8139_REG_9346CR |
||
320 | out dx, eax |
||
321 | add edx, RTL8139_REG_MAR4 - RTL8139_REG_MAR0 |
||
322 | out dx, eax |
||
261 | hidnplayr | 323 | ; enable Rx/Tx |
2434 | Serge | 324 | mov al, (1 shl RTL8139_BIT_RE) or (1 shl RTL8139_BIT_TE) |
325 | add edx, RTL8139_REG_COMMAND - RTL8139_REG_MAR4 |
||
326 | out dx, al |
||
261 | hidnplayr | 327 | ; 32k Rxbuffer, unlimited dma burst, no wrapping, no rx threshold |
328 | ; accept broadcast packets, accept physical match packets |
||
2434 | Serge | 329 | mov eax, RTL8139_RX_CONFIG |
330 | add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND |
||
331 | out dx, eax |
||
261 | hidnplayr | 332 | ; 1024 bytes DMA burst, total retries = 16 + 8 * 16 = 144 |
2434 | Serge | 333 | mov eax, (RTL8139_TX_MXDMA shl RTL8139_BIT_TX_MXDMA) \ |
334 | or (RTL8139_TXRR shl RTL8139_BIT_TXRR) |
||
335 | add edx, RTL8139_REG_TXCONFIG - RTL8139_REG_RXCONFIG |
||
336 | out dx, eax |
||
261 | hidnplayr | 337 | ; enable auto negotiation |
2434 | Serge | 338 | add edx, RTL8139_REG_BMCR - RTL8139_REG_TXCONFIG |
339 | in ax, dx |
||
340 | or ax, (1 shl RTL8139_BIT_ANE) |
||
341 | out dx, ax |
||
261 | hidnplayr | 342 | ; set auto negotiation advertisement |
2434 | Serge | 343 | add edx, RTL8139_REG_ANAR - RTL8139_REG_BMCR |
344 | in ax, dx |
||
345 | or ax, (1 shl RTL8139_BIT_SELECTOR) or (1 shl RTL8139_BIT_10) \ |
||
346 | or (1 shl RTL8139_BIT_10FD) or (1 shl RTL8139_BIT_TX) \ |
||
347 | or (1 shl RTL8139_BIT_TXFD) |
||
348 | out dx, ax |
||
261 | hidnplayr | 349 | ; lock config and BMCR registers |
2434 | Serge | 350 | xor eax, eax |
351 | add edx, RTL8139_REG_9346CR - RTL8139_REG_ANAR |
||
352 | out dx, al |
||
261 | hidnplayr | 353 | ; init RX/TX pointers |
2434 | Serge | 354 | mov [rtl8139_rx_buff_offset], eax |
355 | mov [curr_tx_desc], eax |
||
261 | hidnplayr | 356 | ; clear missing packet counter |
2434 | Serge | 357 | add edx, RTL8139_REG_MPC - RTL8139_REG_9346CR |
358 | out dx, eax |
||
261 | hidnplayr | 359 | ; disable all interrupts |
2434 | Serge | 360 | add edx, RTL8139_REG_IMR - RTL8139_REG_MPC |
361 | out dx, ax |
||
261 | hidnplayr | 362 | ; set RxBuffer address, init RX buffer offset, init TX ring |
2434 | Serge | 363 | mov eax, rtl8139_rx_buff ; simba |
364 | sub eax, OS_BASE |
||
365 | add edx, RTL8139_REG_RBSTART - RTL8139_REG_IMR |
||
366 | out dx, eax |
||
261 | hidnplayr | 367 | ; Indicate that we have successfully reset the card |
2434 | Serge | 368 | mov eax, [pci_data] |
369 | mov [eth_status], eax |
||
370 | ret |
||
261 | hidnplayr | 371 | |
372 | ;*************************************************************************** |
||
373 | ; Function |
||
374 | ; rtl8139_read_eeprom |
||
375 | ; Description |
||
376 | ; reads eeprom type 93c46 and 93c56 |
||
377 | ; Parameters |
||
378 | ; al - word to be read (6bit in case of 93c46 and 8bit otherwise) |
||
379 | ; Return value |
||
380 | ; ax - word read in |
||
381 | ; Destroyed register(s) |
||
382 | ; eax, cx, ebx, edx |
||
383 | ; |
||
384 | ;*************************************************************************** |
||
385 | rtl8139_read_eeprom: |
||
2434 | Serge | 386 | movzx ebx, al |
387 | mov edx, [io_addr] |
||
388 | add edx, RTL8139_REG_RXCONFIG |
||
389 | in al, dx |
||
390 | test al, (1 shl RTL8139_BIT_9356SEL) |
||
391 | jz .type_93c46 |
||
261 | hidnplayr | 392 | ; and bl, 01111111b ; don't care first bit |
2434 | Serge | 393 | or bx, EE_93C56_READ_CMD ; it contains start bit |
394 | mov cx, EE_93C56_CMD_LENGTH-1 ; cmd_loop counter |
||
395 | jmp .read_eeprom |
||
261 | hidnplayr | 396 | .type_93c46: |
2434 | Serge | 397 | and bl, 00111111b |
398 | or bx, EE_93C46_READ_CMD ; it contains start bit |
||
399 | mov cx, EE_93C46_CMD_LENGTH-1 ; cmd_loop counter |
||
261 | hidnplayr | 400 | .read_eeprom: |
2434 | Serge | 401 | add edx, RTL8139_REG_9346CR - RTL8139_REG_RXCONFIG_0 |
261 | hidnplayr | 402 | ; mov al, (1 shl RTL8139_BIT_93C46_EEM1) |
403 | ; out dx, al |
||
2434 | Serge | 404 | mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
405 | or (1 shl RTL8139_BIT_93C46_EECS) ; wake up the eeprom |
||
406 | out dx, al |
||
261 | hidnplayr | 407 | .cmd_loop: |
2434 | Serge | 408 | mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) |
409 | bt bx, cx |
||
410 | jnc .zero_bit |
||
411 | or al, (1 shl RTL8139_BIT_93C46_EEDI) |
||
261 | hidnplayr | 412 | .zero_bit: |
2434 | Serge | 413 | out dx, al |
261 | hidnplayr | 414 | ; push eax |
415 | ; in eax, dx ; eeprom delay |
||
416 | ; pop eax |
||
2434 | Serge | 417 | or al, (1 shl RTL8139_BIT_93C46_EESK) |
418 | out dx, al |
||
261 | hidnplayr | 419 | ; in eax, dx ; eeprom delay |
2434 | Serge | 420 | dec cx |
421 | jns .cmd_loop |
||
261 | hidnplayr | 422 | ; in eax, dx ; eeprom delay |
2434 | Serge | 423 | mov al, (1 shl RTL8139_BIT_93C46_EEM1) or (1 shl RTL8139_BIT_93C46_EECS) |
424 | out dx, al |
||
425 | mov cl, 0xf |
||
261 | hidnplayr | 426 | .read_loop: |
2434 | Serge | 427 | shl ebx, 1 |
428 | mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
||
429 | or (1 shl RTL8139_BIT_93C46_EECS) \ |
||
430 | or (1 shl RTL8139_BIT_93C46_EESK) |
||
431 | out dx, al |
||
261 | hidnplayr | 432 | ; in eax, dx ; eeprom delay |
2434 | Serge | 433 | in al, dx |
434 | and al, (1 shl RTL8139_BIT_93C46_EEDO) |
||
435 | jz .dont_set |
||
436 | inc ebx |
||
261 | hidnplayr | 437 | .dont_set: |
2434 | Serge | 438 | mov al, (1 shl RTL8139_BIT_93C46_EEM1) \ |
439 | or (1 shl RTL8139_BIT_93C46_EECS) |
||
440 | out dx, al |
||
261 | hidnplayr | 441 | ; in eax, dx ; eeprom delay |
2434 | Serge | 442 | dec cl |
443 | jns .read_loop |
||
444 | xor al, al |
||
445 | out dx, al |
||
446 | mov ax, bx |
||
447 | ret |
||
261 | hidnplayr | 448 | |
449 | ;*************************************************************************** |
||
450 | ; Function |
||
451 | ; rtl8139_transmit |
||
452 | ; Description |
||
453 | ; Transmits a packet of data via the ethernet card |
||
454 | ; Pointer to 48 bit destination address in edi |
||
455 | ; Type of packet in bx |
||
373 | mikedld | 456 | ; Size of packet in ecx |
457 | ; Pointer to packet data in esi |
||
261 | hidnplayr | 458 | ; Destroyed registers |
459 | ; eax, edx, esi, edi |
||
460 | ; ToDo |
||
461 | ; for waiting of timeout the rtl8139 internal timer |
||
462 | ; should be used |
||
463 | ; |
||
464 | ;*************************************************************************** |
||
465 | rtl8139_transmit: |
||
2434 | Serge | 466 | cmp ecx, MAX_ETH_FRAME_SIZE |
467 | jg .finish ; packet is too long |
||
468 | push ecx |
||
261 | hidnplayr | 469 | ; check descriptor |
2434 | Serge | 470 | mov ecx, [curr_tx_desc] |
471 | mov edx, [io_addr] |
||
472 | lea edx, [edx+ecx*4+RTL8139_REG_TSD0] |
||
473 | push edx ebx |
||
474 | in ax, dx |
||
475 | test ax, 0x1fff ; or no size given |
||
476 | jz .send_packet |
||
477 | and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
||
478 | cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
||
479 | jz .send_packet |
||
261 | hidnplayr | 480 | ; wait for timeout |
2434 | Serge | 481 | mov ebx, RTL8139_TX_TIMEOUT |
482 | mov eax, 0x5 ; delay x/100 secs |
||
483 | int 0x40 |
||
484 | in ax, dx |
||
485 | and ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
||
486 | cmp ax, (1 shl RTL8139_BIT_TOK) or (1 shl RTL8139_BIT_OWN) |
||
487 | jz .send_packet |
||
261 | hidnplayr | 488 | ; chip hung, reset it |
2434 | Serge | 489 | call rtl8139_reset |
261 | hidnplayr | 490 | ; reset the card |
491 | .send_packet: |
||
492 | ; calculate tx_buffer address |
||
2434 | Serge | 493 | pop ebx |
494 | push esi |
||
495 | mov eax, MAX_ETH_FRAME_SIZE |
||
496 | mul dword [curr_tx_desc] |
||
497 | mov esi, edi |
||
498 | lea edi, [rtl8139_tx_buff+eax] |
||
499 | mov eax, edi |
||
500 | cld |
||
261 | hidnplayr | 501 | ; copy destination address |
2434 | Serge | 502 | movsd |
503 | movsw |
||
261 | hidnplayr | 504 | ; copy source address |
2434 | Serge | 505 | mov esi, node_addr |
506 | movsd |
||
507 | movsw |
||
261 | hidnplayr | 508 | ; copy packet type |
2434 | Serge | 509 | mov [edi], bx |
510 | add edi, 2 |
||
261 | hidnplayr | 511 | ; copy the packet data |
2434 | Serge | 512 | pop esi edx ecx |
513 | push ecx |
||
514 | shr ecx, 2 |
||
515 | rep movsd |
||
516 | pop ecx |
||
517 | push ecx |
||
518 | and ecx, 3 |
||
519 | rep movsb |
||
261 | hidnplayr | 520 | ; set address |
2434 | Serge | 521 | sub eax, OS_BASE |
522 | add edx, RTL8139_REG_TSAD0 - RTL8139_REG_TSD0 |
||
523 | out dx, eax |
||
261 | hidnplayr | 524 | ; set size and early threshold |
2434 | Serge | 525 | pop eax ; pick up the size |
526 | add eax, ETH_HLEN |
||
527 | cmp eax, ETH_ZLEN |
||
528 | jnc .no_pad |
||
529 | mov eax, ETH_ZLEN |
||
261 | hidnplayr | 530 | .no_pad: |
2434 | Serge | 531 | or eax, (RTL8139_ERTXTH shl RTL8139_BIT_ERTXTH) |
532 | add edx, RTL8139_REG_TSD0 - RTL8139_REG_TSAD0 |
||
533 | out dx, eax |
||
261 | hidnplayr | 534 | ; get next descriptor 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ... |
2434 | Serge | 535 | inc dword [curr_tx_desc] |
536 | and dword [curr_tx_desc], 3 |
||
261 | hidnplayr | 537 | .finish: |
2434 | Serge | 538 | ret |
261 | hidnplayr | 539 | |
540 | ;*************************************************************************** |
||
541 | ; Function |
||
542 | ; rtl8139_poll |
||
543 | ; |
||
544 | ; Description |
||
545 | ; Polls the ethernet card for a received packet |
||
546 | ; Received data, if any, ends up in Ether_buffer |
||
547 | ; Destroyed register(s) |
||
548 | ; eax, edx, ecx |
||
549 | ; |
||
550 | ;*************************************************************************** |
||
551 | rtl8139_poll: |
||
2434 | Serge | 552 | mov word [eth_rx_data_len], 0 |
553 | mov edx, [io_addr] |
||
554 | add edx, RTL8139_REG_COMMAND |
||
555 | in al, dx |
||
556 | test al, (1 shl RTL8139_BIT_BUFE) |
||
557 | jnz .finish |
||
261 | hidnplayr | 558 | ; new packet received copy it from rx_buffer into Ether_buffer |
2434 | Serge | 559 | mov eax, rtl8139_rx_buff |
560 | add eax, [rtl8139_rx_buff_offset] |
||
261 | hidnplayr | 561 | ; check if packet is ok |
2434 | Serge | 562 | test byte [eax], (1 shl RTL8139_BIT_ROK) |
563 | jz .reset_rx |
||
261 | hidnplayr | 564 | ; packet is ok copy it into the Ether_buffer |
2434 | Serge | 565 | movzx ecx, word [eax+2] ; packet length |
566 | sub ecx, 4 ; don't copy CRC |
||
567 | mov word [eth_rx_data_len], cx |
||
568 | push ecx |
||
569 | shr ecx, 2 ; first copy dword-wise |
||
570 | lea esi, [eax+4] ; don't copy the packet header |
||
571 | mov edi, Ether_buffer |
||
572 | cld |
||
573 | rep movsd ; copy the dwords |
||
574 | pop ecx |
||
575 | and ecx, 3 |
||
576 | rep movsb ; copy the rest bytes |
||
261 | hidnplayr | 577 | ; update rtl8139_rx_buff_offset |
2434 | Serge | 578 | movzx eax, word [eax+2] ; packet length |
579 | add eax, [rtl8139_rx_buff_offset] |
||
580 | add eax, 4+3 ; packet header is 4 bytes long + dword alignment |
||
581 | and eax, not 3 ; dword alignment |
||
582 | cmp eax, RTL8139_RX_BUFFER_SIZE |
||
583 | jl .no_wrap |
||
584 | sub eax, RTL8139_RX_BUFFER_SIZE |
||
261 | hidnplayr | 585 | .no_wrap: |
2434 | Serge | 586 | mov [rtl8139_rx_buff_offset], eax |
261 | hidnplayr | 587 | ; update CAPR register |
2434 | Serge | 588 | sub eax, 0x10 ; value 0x10 is a constant for CAPR |
589 | add edx, RTL8139_REG_CAPR - RTL8139_REG_COMMAND |
||
590 | out dx, ax |
||
261 | hidnplayr | 591 | .finish: |
592 | ; clear active interrupt sources |
||
2434 | Serge | 593 | mov edx, [io_addr] |
594 | add edx, RTL8139_REG_ISR |
||
595 | in ax, dx |
||
596 | out dx, ax |
||
597 | ret |
||
261 | hidnplayr | 598 | .reset_rx: |
2434 | Serge | 599 | in al, dx ; read command register |
600 | push eax |
||
601 | and al, not (1 shl RTL8139_BIT_RE) |
||
602 | out dx, al |
||
603 | pop eax |
||
604 | out dx, al |
||
605 | add edx, RTL8139_REG_RXCONFIG - RTL8139_REG_COMMAND |
||
606 | mov ax, RTL8139_RX_CONFIG |
||
607 | out dx, ax |
||
608 | ret |
||
302 | hidnplayr | 609 | |
610 | rtl8139_cable: |
||
2434 | Serge | 611 | pusha |
612 | mov edx, [io_addr] |
||
613 | add edx, 0x58 |
||
614 | in al, dx |
||
615 | test al, 1 SHL 2 |
||
616 | jnz .notconnected |
||
617 | popa |
||
618 | xor al, al |
||
619 | inc al |
||
620 | ret |
||
302 | hidnplayr | 621 | .notconnected: |
2434 | Serge | 622 | popa |
623 | xor al, al |
||
624 | ret> |