Subversion Repositories Kolibri OS

Rev

Rev 108 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ha 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;;  ETHERNET.INC                                                   ;;
4
;;                                                                 ;;
5
;;  Ethernet network layer for Menuet OS                           ;;
6
;;                                                                 ;;
7
;;  Version 0.4  22 September 2003                                 ;;
8
;;                                                                 ;;
9
;;  This file contains the following:                              ;;
10
;;      PCI bus scanning for valid devices                         ;;
11
;;      Table of supported ethernet drivers                        ;;
12
;;      Code to identify and activate a supported driver           ;;
13
;;      ARP handler                                                ;;
14
;;      Driver interface to the IP layer                           ;;
15
;;      Gateway support                                            ;;
16
;;                                                                 ;;
17
;;  Individual driver files are included here                      ;;
18
;;                                                                 ;;
19
;;  The PCI bus scanning code was ported from the etherboot        ;;
20
;;  5.0.6 project. The copyright statement for that code is        ;;
21
;;                                                                 ;;
22
;;          GNU GENERAL PUBLIC LICENSE                             ;;
23
;;             Version 2, June 1991                                ;;
24
;;                                                                 ;;
25
;;  remaining parts Copyright 2002 Mike Hibbett                    ;;
26
;;   mikeh@oceanfree.net                                           ;;
27
;;                                                                 ;;
28
;;  See file COPYING for details                                   ;;
29
;;                                                                 ;;
30
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31
 
32
;********************************************************************
33
;   Interface
34
;      ethernet_driver   called by stack_handler in stack.inc
35
;      eth_probe         called by app_stack_handler in stack.inc
36
;
37
;********************************************************************
38
 
261 hidnplayr 39
ETHER_IP                    equ     0x0008      ; Reversed from 0800 for intel
40
ETHER_ARP                   equ     0x0608      ; Reversed from 0806 for intel
41
ETHER_RARP                  equ     0x3580
42
 
43
struc ETH_FRAME
44
{  .DstMAC       dp   ?  ;destination MAC-address [6 bytes]
45
   .SrcMAC       dp   ?  ;source MAC-address [6 bytes]
46
   .Type         dw   ?  ;type of the upper-layer protocol [2 bytes]
47
   .Data         db   ?  ;data [46-1500 bytes]
48
}
49
 
50
virtual at Ether_buffer
51
  ETH_FRAME ETH_FRAME
52
end virtual
53
 
54
 
1 ha 55
; Some useful information on data structures
56
 
57
;     Ethernet Packet - ARP Request example
58
;
59
;   0                   1                   2                   3
60
;   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
61
;
62
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
;   |       Dest   H/W Address                                      |
64
;   |                    ( 14 byte header )                         |
65
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66
;   |                               |     Source     H/W Address    |
67
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68
;   |                                                               |
69
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
70
;   |    Protocol - ARP 08  06      |
71
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72
 
73
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74
;   |  H/W Type  00           01    |  Protocol Type   08 00        |
75
;   |                   ( ARP Request packet )                      |
76
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77
;   | HLen    0x06  | PLen    0x04  |    OpCode        00   01      |
78
;   |               ( 0001 for request, 0002 for reply )            |
79
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80
;   | Source Hardware Address ( MAC Address )                       |
81
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82
;   |                               |  Source IP Address            |
83
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84
;   |                               | Destination Hardware Address  |
85
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86
;   |                                                               |
87
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
88
;   | Destination IP Address                                        |
89
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90
 
91
; Include individual drivers source files at this point.
92
; If you create a new driver, include it below.
93
 
261 hidnplayr 94
include "drivers/rtl8029.inc"
95
include "drivers/i8255x.inc"
96
include "drivers/rtl8139.inc"
97
include "drivers/3c59x.inc"
98
include "drivers/sis900.inc"
99
include "drivers/pcnet32.inc"
1 ha 100
 
101
; PCICards
102
; ========
103
; PCI vendor and hardware types for hardware supported by the above drivers
104
; If you add a driver, ensure you update this datastructure, otherwise the
105
; card will not be probed.
106
; Each driver is defined by 4 double words. These are
107
;   PCIVendorDevice  probeFunction ResetFunction PollFunction transmitFunction
108
; The last entry must be kept at all zeros, to indicate the end of the list
109
; As a PCI driver may support more than one hardware implementation, there may
110
; be several lines which refer to the same functions.
111
; The first driver found on the PCI bus will be the one used.
112
 
113
PCICARDS_ENTRY_SIZE         equ     20    ; Size of each PCICARDS entry
114
 
115
iglobal
116
PCICards:
117
dd  0x12098086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
118
dd  0x10298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
119
dd  0x12298086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
120
dd  0x10308086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
121
dd  0x24498086, I8255x_probe, I8255x_reset, I8255x_poll, I8255x_transmit
122
dd  0x802910ec, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit
123
dd  0x12111113, rtl8029_probe, rtl8029_reset, rtl8029_poll, rtl8029_transmit
124
dd  0x813910ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
108 heavyiron 125
; /+/ Новые вендоры сетевых карт на базе rtl8139
126
dd  0x813810ec, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
127
dd  0x12111113, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
128
dd  0x13601500, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
129
dd  0x13604033, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
130
dd  0x13001186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
131
dd  0x13401186, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
132
dd  0xab0613d1, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
133
dd  0xa1171259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
134
dd  0xa11e1259, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
135
dd  0xab0614ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
136
dd  0xab0714ea, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
137
dd  0x123411db, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
138
dd  0x91301432, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
139
dd  0x101202ac, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
140
dd  0x0106018a, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
141
dd  0x1211126c, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
142
dd  0x81391743, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
143
dd  0x8139021b, rtl8139_probe, rtl8139_reset, rtl8139_poll, rtl8139_transmit
144
; /-/
1 ha 145
dd  0x590010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
146
dd  0x592010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
147
dd  0x597010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
148
dd  0x595010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
149
dd  0x595110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
150
dd  0x595210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
151
dd  0x900010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
152
dd  0x900110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
153
dd  0x900410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
154
dd  0x900510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
155
dd  0x900610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
156
dd  0x900A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
157
dd  0x905010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
158
dd  0x905110b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
159
dd  0x905510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
160
dd  0x905810b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
161
dd  0x905A10b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
162
dd  0x920010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
163
dd  0x980010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
164
dd  0x980510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
165
dd  0x764610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
166
dd  0x505510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
167
dd  0x605510b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
168
dd  0x605610b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
169
dd  0x5b5710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
170
dd  0x505710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
171
dd  0x515710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
172
dd  0x525710b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
173
dd  0x656010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
174
dd  0x656210b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
175
dd  0x656410b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
176
dd  0x450010b7, e3c59x_probe, e3c59x_reset, e3c59x_poll, e3c59x_transmit
177
dd  0x09001039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
178
dd  0x20001022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
179
dd  0x26251022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
180
dd  0x20011022, pcnet32_probe, pcnet32_reset, pcnet32_poll, pcnet32_xmit
181
; following card is untested
182
dd  0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
183
dd  0,0,0,0,0  ; end of list marker, do not remove
184
endg
185
 
186
uglobal
261 hidnplayr 187
;Net-stack's interface's settings
1 ha 188
  node_addr:          db  0,0,0,0,0,0
261 hidnplayr 189
  gateway_ip:         db  0, 0, 0, 0
190
  dns_ip:             dd  0
191
 
1 ha 192
  eth_rx_data_len:    dw  0
193
  eth_status:         dd  0
194
  io_addr:            dd  0
195
  hdrtype:            db  0
196
  vendor_device:      dd  0
197
  pci_data:           dd  0
198
  pci_dev:            dd  0
199
  pci_bus:            dd  0
200
 
201
  ; These will hold pointers to the selected driver functions
202
  drvr_probe:         dd  0
203
  drvr_reset:         dd  0
204
  drvr_poll:          dd  0
205
  drvr_transmit:      dd  0
206
 
207
endg
208
 
209
iglobal
210
  broadcast_add:      db  0xff,0xff,0xff,0xff,0xff,0xff
261 hidnplayr 211
  subnet_mask:        dd  0x00ffffff   ; 255.255.255.0
1 ha 212
endg
213
 
261 hidnplayr 214
include "arp.inc"    ;arp-protocol functions
215
include "pci.inc"    ;PCI bus access functions
1 ha 216
 
217
 
218
;***************************************************************************
219
;   Function
220
;      eth_tx
221
;
222
;   Description
223
;      Looks at the NET1OUT_QUEUE for data to send.
224
;      Stores that destination IP in a location used by the tx routine
225
;      Looks up the MAC address in the ARP table; stores that where
226
;      the tx routine can get it
227
;      Get the length of the data. Store that where the tx routine wants it
228
;      Call tx
229
;      Places buffer on empty queue when the tx routine finished
230
;
231
;***************************************************************************
261 hidnplayr 232
proc eth_tx stdcall uses ebx esi edi
233
local MACAddress  dp  ?  ;allocate 6 bytes in the stack
234
 
1 ha 235
    ; Look for a buffer to tx
236
    mov     eax, NET1OUT_QUEUE
237
    call    dequeue
238
    cmp     ax, NO_BUFFER
261 hidnplayr 239
    je      .exit            ; Exit if no buffer available
1 ha 240
 
261 hidnplayr 241
    push    eax  ;save buffer number
1 ha 242
 
243
    ; convert buffer pointer eax to the absolute address
261 hidnplayr 244
    imul    eax, IPBUFFSIZE
1 ha 245
    add     eax, IPbuffs
246
 
247
    ; Extract the destination IP
248
    ; find the destination IP in the ARP table, get MAC
249
    ; store this MAC in 'MACAddress'
250
    mov     ebx, eax               ; Save buffer address
251
    mov     edx, [ebx + 16]        ; get destination address
252
 
253
    ; If the destination address is 255.255.255.255,
254
    ; set the MACAddress to all ones ( broadcast )
261 hidnplayr 255
    cld
256
    mov     esi, broadcast_add
257
    lea     edi, [MACAddress]
258
    movsd
259
    movsw
1 ha 260
    cmp     edx, 0xffffffff
261 hidnplayr 261
    je      .send                ; If it is broadcast, just send
1 ha 262
 
261 hidnplayr 263
    lea     eax, [MACAddress]    ;cause this is local variable
264
    stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax ;opcode,IP,MAC_ptr - Get the MAC address.
1 ha 265
 
266
    cmp     eax, ARP_VALID_MAPPING
261 hidnplayr 267
    je      .send
1 ha 268
 
261 hidnplayr 269
    ; No valid entry. Has the request been sent, but timed out?
1 ha 270
    cmp     eax, ARP_RESPONSE_TIMEOUT
261 hidnplayr 271
    je      .freebuf
1 ha 272
 
261 hidnplayr 273
  .wait_response:                   ;we wait arp-response
274
                                    ; Re-queue the packet, and exit
1 ha 275
    pop     ebx
276
    mov     eax, NET1OUT_QUEUE
261 hidnplayr 277
    call    queue                        ; Get the buffer back
278
    jmp     .exit
1 ha 279
 
261 hidnplayr 280
  .send:    ;if ARP_VALID_MAPPING then send the packet
281
    lea     edi, [MACAddress]     ; Pointer to 48 bit destination address
282
    movzx   ecx, word[ebx+2]      ; Size of IP packet to send
283
    xchg    ch, cl                ; because mirror byte-order
284
    mov     esi, ebx              ; Pointer to packet data
285
    mov     bx, ETHER_IP          ; Type of packet
286
    call    dword [drvr_transmit] ; Call the drivers transmit function
1 ha 287
 
288
    ; OK, we have sent a packet, so increment the count
289
    inc     dword [ip_tx_count]
290
 
291
    ; And finally, return the buffer to the free queue
261 hidnplayr 292
  .freebuf:
1 ha 293
    pop     eax
294
    call    freeBuff
295
 
261 hidnplayr 296
  .exit:
1 ha 297
    ret
261 hidnplayr 298
endp
1 ha 299
 
300
;***************************************************************************
301
;   Function
302
;      ether_IP_handler
303
;
304
;   Description
305
;      Called when an IP ethernet packet is received on the ethernet
306
;      Header + Data is in Ether_buffer[]
307
;      We just need to get a buffer from the 'free' queue, and
308
;      store the packet in it, then insert the packet number into the
309
;      IPRX queue.
310
;      If no queue entry is available, the packet is silently discarded
311
;      All registers may be destroyed
312
;
313
;***************************************************************************
314
ether_IP_handler:
315
    mov     eax, EMPTY_QUEUE
316
    call    dequeue
317
    cmp     ax, NO_BUFFER
318
    je      eiph00x
319
 
320
    ; convert buffer pointer eax to the absolute address
321
    push    eax
322
    mov     ecx, IPBUFFSIZE
323
    mul     ecx
324
    add     eax, IPbuffs
325
 
326
    mov     edi, eax
327
 
328
    ; get a pointer to the start of the DATA
261 hidnplayr 329
    mov     esi, ETH_FRAME.Data
1 ha 330
 
331
    ; Now store it all away
332
    mov     ecx, IPBUFFSIZE / 4     ; Copy all of the available
333
                              ; data across - worse case
334
    cld
335
    rep     movsd
336
 
337
    ; And finally, place the buffer in the IPRX queue
338
    pop     ebx
339
    mov     eax, IPIN_QUEUE
340
    call    queue
341
 
342
eiph00x:
343
    ret
344
 
345
;***************************************************************************
346
;   Function
261 hidnplayr 347
;      eth_probe
1 ha 348
;   Description
261 hidnplayr 349
;      Searches for an ethernet card. If found, the card is enabled and
350
;      the ethernet -> IP link established
1 ha 351
;
261 hidnplayr 352
;      This function scans the PCI bus looking for a supported device.
353
;      ISA bus is currently not supported.
1 ha 354
;
261 hidnplayr 355
;        eax is 0 if no hardware found
1 ha 356
;***************************************************************************
261 hidnplayr 357
eth_probe:
358
    ; Find a card on the PCI bus, and get it's address
359
    call    scan_bus                    ; Find the ethernet cards PIC address
1 ha 360
    xor     eax, eax
261 hidnplayr 361
    cmp     [io_addr], eax
362
    je      ep_00x                      ; Return 0 in eax if no cards found
1 ha 363
 
261 hidnplayr 364
    call    dword [drvr_probe]          ; Call the drivers probe function
1 ha 365
 
261 hidnplayr 366
    mov     eax, [io_addr]              ; return a non zero value
1 ha 367
 
261 hidnplayr 368
ep_00x:
1 ha 369
    ret
370
 
371
;***************************************************************************
372
;   Function
261 hidnplayr 373
;      ethernet_driver
1 ha 374
;
375
;   Description
261 hidnplayr 376
;       The ethernet RX and TX handler
377
;       This is a kernel function, called by stack_handler
1 ha 378
;
379
;***************************************************************************
261 hidnplayr 380
ethernet_driver:
381
    ; Do nothing if the driver is inactive
382
    cmp     [ethernet_active], byte 0
383
    je      eth_exit
1 ha 384
 
261 hidnplayr 385
    call    eth_rx
386
    call    eth_tx
1 ha 387
 
261 hidnplayr 388
eth_exit:
1 ha 389
    ret
390
 
391
;***************************************************************************
392
;   Function
261 hidnplayr 393
;      eth_rx
1 ha 394
;
395
;   Description
261 hidnplayr 396
;      Polls the ethernet card for received data. Extracts if present
397
;       Depending on the Protocol within the packet:
398
;         ARP : Pass to ARP_handler. This may result in an ARP reply
399
;               being tx'ed
400
;         IP  : Store in an IP buffer
1 ha 401
;
402
;***************************************************************************
261 hidnplayr 403
eth_rx:
404
    xor     ax, ax
405
    mov     [eth_rx_data_len], ax
406
    call    dword [drvr_poll]       ; Call the drivers poll function
1 ha 407
 
261 hidnplayr 408
    mov     ax, [eth_rx_data_len]
409
    cmp     ax, 0
410
    je      .exit
1 ha 411
 
412
 
261 hidnplayr 413
    ; Check the protocol. Call appropriate handler
1 ha 414
 
261 hidnplayr 415
    mov     ax, [ETH_FRAME.Type]    ; The address of the protocol word
1 ha 416
 
261 hidnplayr 417
    cmp     ax, ETHER_IP
418
    je      .is_ip                   ; It's IP
1 ha 419
 
261 hidnplayr 420
    cmp     ax, ETHER_ARP
421
    je      .is_arp                  ; It is ARP
1 ha 422
 
261 hidnplayr 423
    jmp     .exit               ; If not IP or ARP, ignore
1 ha 424
 
261 hidnplayr 425
  .is_ip:
426
    inc     dword [ip_rx_count]
427
    call    ether_IP_handler
428
    jmp     .exit
1 ha 429
 
261 hidnplayr 430
  .is_arp:
1 ha 431
 
261 hidnplayr 432
    ; At this point, the packet is still in the Ether_buffer
433
    call    arp_handler
1 ha 434
 
261 hidnplayr 435
  .exit:
436
    ret