Subversion Repositories Kolibri OS

Rev

Rev 108 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 108 Rev 261
Line 34... Line 34...
34
;      ethernet_driver   called by stack_handler in stack.inc
34
;      ethernet_driver   called by stack_handler in stack.inc
35
;      eth_probe         called by app_stack_handler in stack.inc
35
;      eth_probe         called by app_stack_handler in stack.inc
36
;
36
;
37
;********************************************************************
37
;********************************************************************
Line -... Line 38...
-
 
38
 
-
 
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
 
38
 
54
 
Line 39... Line 55...
39
; Some useful information on data structures
55
; Some useful information on data structures
40
 
56
 
41
;     Ethernet Packet - ARP Request example
57
;     Ethernet Packet - ARP Request example
Line 73... Line 89...
73
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
89
;   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Line 74... Line 90...
74
 
90
 
75
; Include individual drivers source files at this point.
91
; Include individual drivers source files at this point.
Line 76... Line 92...
76
; If you create a new driver, include it below.
92
; If you create a new driver, include it below.
77
 
93
 
78
include "rtl8029.inc"
94
include "drivers/rtl8029.inc"
79
include "i8255x.inc"
95
include "drivers/i8255x.inc"
80
include "rtl8139.inc"
96
include "drivers/rtl8139.inc"
81
include "3c59x.inc"
97
include "drivers/3c59x.inc"
82
include "sis900.inc"
-
 
83
include "pcnet32.inc"
-
 
84
 
-
 
85
; DEBUGGING_STATE enables or disables output of received and transmitted
-
 
86
; data over the serial port
-
 
87
DEBUGGING_ENABLED           equ     1
-
 
Line 88... Line 98...
88
DEBUGGING_DISABLED          equ     0
98
include "drivers/sis900.inc"
89
DEBUGGING_STATE             equ     DEBUGGING_DISABLED
99
include "drivers/pcnet32.inc"
90
 
100
 
91
; PCICards
101
; PCICards
Line 171... Line 181...
171
; following card is untested
181
; following card is untested
172
dd  0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
182
dd  0x70161039, SIS900_probe, SIS900_reset, SIS900_poll, SIS900_transmit
173
dd  0,0,0,0,0  ; end of list marker, do not remove
183
dd  0,0,0,0,0  ; end of list marker, do not remove
174
endg
184
endg
Line 175... Line -...
175
 
-
 
176
; PCI Bus defines
-
 
177
PCI_HEADER_TYPE             equ     0x0e  ;8 bit
-
 
178
PCI_BASE_ADDRESS_0          equ     0x10  ;32 bit
-
 
179
PCI_BASE_ADDRESS_5          equ     0x24  ;32 bits
-
 
180
PCI_BASE_ADDRESS_SPACE_IO   equ     0x01
-
 
181
PCI_VENDOR_ID               equ     0x00  ;16 bit
-
 
182
PCI_BASE_ADDRESS_IO_MASK    equ     0xFFFFFFFC
-
 
183
 
-
 
184
ETHER_IP                    equ     0x0008      ; Reversed from 0800 for intel
-
 
185
ETHER_ARP                   equ     0x0608      ; Reversed from 0806 for intel
-
 
186
ETHER_RARP                  equ     0x3580
-
 
187
ARP_REQ_OPCODE              equ     0x0100
-
 
188
ARP_REP_OPCODE              equ     0x0200
-
 
189
 
185
 
190
uglobal
-
 
191
  arp_rx_count:       dd  0
-
 
192
  ip_rx_count:        dd  0
-
 
193
  dumped_rx_count:    dd  0
186
uglobal
194
  ip_tx_count:        dd  0
187
;Net-stack's interface's settings
-
 
188
  node_addr:          db  0,0,0,0,0,0
-
 
189
  gateway_ip:         db  0, 0, 0, 0
-
 
190
  dns_ip:             dd  0
195
  node_addr:          db  0,0,0,0,0,0
191
 
196
  eth_rx_data_len:    dw  0
192
  eth_rx_data_len:    dw  0
197
  eth_status:         dd  0
193
  eth_status:         dd  0
198
  io_addr:            dd  0
194
  io_addr:            dd  0
199
  hdrtype:            db  0
195
  hdrtype:            db  0
Line 206... Line 202...
206
  drvr_probe:         dd  0
202
  drvr_probe:         dd  0
207
  drvr_reset:         dd  0
203
  drvr_reset:         dd  0
208
  drvr_poll:          dd  0
204
  drvr_poll:          dd  0
209
  drvr_transmit:      dd  0
205
  drvr_transmit:      dd  0
Line 210... Line -...
210
 
-
 
211
  ; These hold the destination Host identity for ARP responses
-
 
212
  remote_ip_add:      dd  0
-
 
213
  remote_hw_add:      db  0, 0, 0, 0, 0, 0
206
 
Line 214... Line 207...
214
endg
207
endg
215
 
208
 
216
iglobal
209
iglobal
217
  broadcast_add:      db  0xff,0xff,0xff,0xff,0xff,0xff
-
 
218
  subnet_mask:        dd  0x00ffffff
-
 
219
endg
-
 
220
 
-
 
221
uglobal
-
 
222
  ; This is used by getMACfromIP
-
 
223
  MACAddress:         db  0,0,0,0,0,0
-
 
224
  gateway_ip:         db  0, 0, 0, 0
-
 
225
  dns_ip:             dd  0
-
 
226
endg
-
 
227
 
-
 
228
; The follow is the ARP Table.
-
 
229
; This table must be manually updated and the kernel recompilied if
-
 
230
; changes are made to it.
-
 
231
; ARP_TABLE_SIZE defines the size of the table
-
 
232
; ARP_TABLE_ENTRIES defines the number of entries in the table
-
 
233
; Each entry is 10 bytes: 4 Byte IP address, 6 byte MAC Address,
-
 
234
;                         2 bytes status, 2 bytes TTL ( in seconds )
-
 
235
; Empty entries are filled with zeros
-
 
236
; The TTL field is decremented every second, and is deleted when it
-
 
237
; reaches 0. It is refreshed every time a packet is received
-
 
238
; If the TTL field is 0xFFFF it is a permanent entry and is never deleted
-
 
239
; The status field can be the following values
-
 
240
; 0x0000  entry not used
-
 
241
; 0x0001  entry holds a valid mapping
-
 
242
; 0x0002  entry contains an IP address, awaiting ARP response
-
 
243
; 0x0003  No response received to ARP request.
-
 
244
; The last status value is provided to allow the network layer to delete
-
 
245
; a packet that is queued awaiting an ARP response
-
 
246
 
-
 
247
ARP_NO_ENTRY                equ 0
-
 
248
ARP_VALID_MAPPING           equ 1
-
 
249
ARP_AWAITING_RESPONSE       equ 2
-
 
250
ARP_RESPONSE_TIMEOUT        equ 3
-
 
251
 
-
 
252
ARP_ENTRY_SIZE              equ     14          ; Number of bytes per entry
-
 
253
ARP_TABLE_SIZE              equ     20          ; Size of table
-
 
254
ARP_TABLE_ENTRIES           equ     0           ; Inital, hardcoded entries
-
 
255
 
-
 
256
uglobal
-
 
257
  ARPTable:
-
 
258
  times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE  db 0
-
 
259
endg
-
 
260
 
-
 
261
iglobal
210
  broadcast_add:      db  0xff,0xff,0xff,0xff,0xff,0xff
Line 262... Line -...
262
  NumARP:        db    ARP_TABLE_ENTRIES
-
 
263
endg
-
 
264
 
-
 
265
;***************************************************************************
-
 
266
;   Function
-
 
267
;      eth_probe
-
 
268
;   Description
-
 
269
;      Searches for an ethernet card. If found, the card is enabled and
-
 
270
;      the ethernet -> IP link established
-
 
271
;
-
 
272
;      This function scans the PCI bus looking for a supported device.
211
  subnet_mask:        dd  0x00ffffff   ; 255.255.255.0
273
;      ISA bus is currently not supported.
-
 
274
;
-
 
275
;        eax is 0 if no hardware found
212
endg
276
;***************************************************************************
-
 
277
eth_probe:
-
 
278
    ; Find a card on the PCI bus, and get it's address
-
 
279
    call    scan_bus                    ; Find the ethernet cards PIC address
-
 
280
    xor     eax, eax
-
 
281
    cmp     [io_addr], eax
-
 
282
    je      ep_00x                      ; Return 0 in eax if no cards found
-
 
283
 
-
 
284
    call    dword [drvr_probe]          ; Call the drivers probe function
-
 
285
 
-
 
286
    mov     eax, [io_addr]              ; return a non zero value
-
 
287
 
-
 
288
ep_00x:
-
 
289
    ret
-
 
290
 
-
 
291
;***************************************************************************
-
 
292
;   Function
-
 
293
;      ethernet_driver
-
 
294
;
-
 
295
;   Description
-
 
296
;       The ethernet RX and TX handler
-
 
297
;       This is a kernel function, called by stack_handler
-
 
298
;
-
 
299
;***************************************************************************
-
 
300
ethernet_driver:
-
 
301
    ; Do nothing if the driver is inactive
-
 
302
    cmp     [ethernet_active], byte 0
-
 
303
    je      eth_exit
-
 
Line 304... Line -...
304
 
-
 
305
    call    eth_rx
-
 
306
    call    eth_tx
-
 
307
 
-
 
308
eth_exit:
-
 
309
    ret
-
 
310
 
-
 
311
;***************************************************************************
-
 
312
;   Function
-
 
313
;      eth_rx
-
 
314
;
-
 
315
;   Description
-
 
316
;      Polls the ethernet card for received data. Extracts if present
-
 
317
;       Depending on the Protocol within the packet:
-
 
318
;         ARP : Pass to ARP_handler. This may result in an ARP reply
-
 
319
;               being tx'ed
-
 
320
;         IP  : Store in an IP buffer
-
 
321
;
-
 
322
;***************************************************************************
-
 
323
eth_rx:
-
 
324
    xor     ax, ax
-
 
325
    mov     [eth_rx_data_len], ax
-
 
326
    call    dword [drvr_poll]       ; Call the drivers poll function
-
 
327
 
-
 
328
    mov     ax, [eth_rx_data_len]
-
 
329
    cmp     ax, 0
-
 
330
    je      erx_exit
-
 
331
 
-
 
332
if DEBUGGING_STATE = DEBUGGING_ENABLED
-
 
333
    pusha
-
 
334
    mov     eax, 0                    ;Indicate that this is a received packet
-
 
335
    mov     cx, [eth_rx_data_len]
-
 
336
    mov     esi, Ether_buffer
-
 
337
    cmp     word [esi + 12], ETHER_IP
-
 
338
    jnz     erxd_done
-
 
339
;    cmp     byte [esi + 14 + 9], 0x06  ; TCP
-
 
340
;    jnz     erxd_done
-
 
341
    call    eth_dump
-
 
342
erxd_done:
-
 
343
    popa
-
 
344
end if
-
 
345
 
-
 
346
    ; Check the protocol. Call appropriate handler
-
 
347
    mov     eax, Ether_buffer
-
 
348
    add     eax, 12                  ; The address of the protocol word
-
 
349
 
-
 
350
    mov     ax, [eax]
-
 
351
 
-
 
352
    cmp     ax, ETHER_ARP
-
 
353
    je      erx_001                  ; It is ARP
-
 
354
 
-
 
355
    cmp     ax, ETHER_IP
-
 
356
    je      erx_002                  ; It's IP
-
 
357
 
-
 
358
;    inc     dword [dumped_rx_count]
-
 
359
 
-
 
360
    jmp     erx_exit               ; If not IP or ARP, ignore
-
 
361
 
-
 
362
erx_001:
-
 
363
    mov     eax, [arp_rx_count]
-
 
364
    inc     eax
-
 
365
    mov     [arp_rx_count], eax
-
 
366
 
-
 
367
    ; At this point, the packet is still in the Ether_buffer
-
 
368
    call    arp_handler
-
 
369
 
-
 
370
    jmp     erx_exit
-
 
371
 
-
 
372
erx_002:
-
 
373
    mov     eax, [ip_rx_count]
-
 
374
    inc     eax
-
 
375
    mov     [ip_rx_count], eax
-
 
376
 
-
 
377
    ; Check to see if the MAC address is in our arp table
-
 
378
    ; refresh the arp ttl if so
-
 
379
 
-
 
380
    mov     esi, Ether_buffer
-
 
381
    add     esi, 6
-
 
382
 
-
 
383
    call    refreshARP
-
 
384
 
-
 
385
    call    ether_IP_handler
-
 
386
 
-
 
Line 387... Line 213...
387
    jmp     erx_exit
213
 
388
 
214
include "arp.inc"    ;arp-protocol functions
389
erx_exit:
215
include "pci.inc"    ;PCI bus access functions
390
    ret
216
 
Line 401... Line 227...
401
;      Get the length of the data. Store that where the tx routine wants it
227
;      Get the length of the data. Store that where the tx routine wants it
402
;      Call tx
228
;      Call tx
403
;      Places buffer on empty queue when the tx routine finished
229
;      Places buffer on empty queue when the tx routine finished
404
;
230
;
405
;***************************************************************************
231
;***************************************************************************
-
 
232
proc eth_tx stdcall uses ebx esi edi
-
 
233
local MACAddress  dp  ?  ;allocate 6 bytes in the stack
406
eth_tx:
234
 
407
    ; Look for a buffer to tx
235
    ; Look for a buffer to tx
408
    mov     eax, NET1OUT_QUEUE
236
    mov     eax, NET1OUT_QUEUE
409
    call    dequeue
237
    call    dequeue
410
    cmp     ax, NO_BUFFER
238
    cmp     ax, NO_BUFFER
411
    je      eth_exit            ; Exit if no buffer available
239
    je      .exit            ; Exit if no buffer available
Line 412... Line 240...
412
 
240
 
Line 413... Line 241...
413
    push    eax
241
    push    eax  ;save buffer number
414
 
242
 
415
    ; convert buffer pointer eax to the absolute address
-
 
416
    mov     ecx, IPBUFFSIZE
243
    ; convert buffer pointer eax to the absolute address
Line 417... Line 244...
417
    mul     ecx
244
    imul    eax, IPBUFFSIZE
418
    add     eax, IPbuffs
245
    add     eax, IPbuffs
419
 
246
 
420
    ; Extract the destination IP
247
    ; Extract the destination IP
421
    ; find the destination IP in the ARP table, get MAC
248
    ; find the destination IP in the ARP table, get MAC
Line 422... Line 249...
422
    ; store this MAC in 'MACAddress'
249
    ; store this MAC in 'MACAddress'
423
    mov     ebx, eax               ; Save buffer address
250
    mov     ebx, eax               ; Save buffer address
-
 
251
    mov     edx, [ebx + 16]        ; get destination address
424
    mov     edx, [ebx + 16]        ; get destination address
252
 
425
 
253
    ; If the destination address is 255.255.255.255,
-
 
254
    ; set the MACAddress to all ones ( broadcast )
-
 
255
    cld
426
    ; If the destination address is 255.255.255.255,
256
    mov     esi, broadcast_add
427
    ; set the MACAddress to all ones ( broadcast )
257
    lea     edi, [MACAddress]
Line 428... Line 258...
428
    mov     [MACAddress], dword 0xffffffff
258
    movsd
-
 
259
    movsw
Line 429... Line 260...
429
    mov     [MACAddress + 4], word 0xffff
260
    cmp     edx, 0xffffffff
430
    cmp     edx, 0xffffffff
261
    je      .send                ; If it is broadcast, just send
Line 431... Line -...
431
    je      etx_send                ; If it is broadcast, just send
-
 
432
 
-
 
433
    call    getMACfromIP           ; Get the MAC address.
-
 
434
 
-
 
435
    cmp     eax, ARP_VALID_MAPPING
-
 
436
    jz      etx_send
-
 
437
 
-
 
438
    ; No valid entry. Are we waiting for a response?
-
 
439
    cmp     eax, ARP_AWAITING_RESPONSE
-
 
440
    jne     etx_001
-
 
441
 
-
 
442
    ; Re-queue the packet, and exit
262
 
443
    pop     ebx
263
    lea     eax, [MACAddress]    ;cause this is local variable
444
    mov     eax, NET1OUT_QUEUE
-
 
445
    call    queue
-
 
446
    jmp     etx_exit
-
 
447
 
264
    stdcall arp_table_manager, ARP_TABLE_IP_TO_MAC, edx, eax ;opcode,IP,MAC_ptr - Get the MAC address.
448
etx_001:
-
 
Line 449... Line -...
449
    ; HAs the request been sent, but timed out?
-
 
450
    cmp     eax, ARP_RESPONSE_TIMEOUT
265
 
451
    jne     etx_002
-
 
452
 
266
    cmp     eax, ARP_VALID_MAPPING
453
    pop     eax
-
 
454
    call    freeBuff
-
 
455
    jmp     etx_exit
267
    je      .send
456
 
-
 
457
etx_002:
-
 
458
    ; There is no entry. Re queue the request, and ask ARP to send a request
-
 
459
 
-
 
460
    ; IP address is in edx
-
 
461
    push    edx
-
 
462
    call    arp_request
-
 
463
    pop     ebx
-
 
464
 
-
 
465
    ; Add an entry in the ARP table, awaiting response
-
 
466
 
-
 
467
    cmp     byte [NumARP], ARP_TABLE_SIZE
-
 
468
    je      etx_003            ; We cannot add a new entry in the table
-
 
469
 
-
 
470
    inc     byte [NumARP]
-
 
471
 
-
 
472
    movzx   eax, byte [NumARP]
-
 
473
    mov     ecx, ARP_ENTRY_SIZE
-
 
474
    mul     ecx
-
 
475
    sub     eax, ARP_ENTRY_SIZE
-
 
476
 
-
 
477
    mov     [eax + ARPTable], ebx
-
 
478
    xor     ebx, ebx
-
 
479
    mov     [eax + ARPTable + 4], ebx
-
 
480
    mov     [eax + ARPTable + 8], bx
-
 
481
 
-
 
482
    ; set the status field up - awaiting response
-
 
483
    mov     cl, 0x00
-
 
484
    mov     [eax + ARPTable + 10], cl
-
 
485
    mov     cl, 0x02
-
 
486
    mov     [eax + ARPTable + 11], cl
268
 
487
 
269
    ; No valid entry. Has the request been sent, but timed out?
488
    ; Initialise the time to live field - 10s
270
    cmp     eax, ARP_RESPONSE_TIMEOUT
Line 489... Line -...
489
    mov     cx, 0x000A
-
 
490
    mov     [eax + ARPTable + 12], cx
271
    je      .freebuf
491
 
272
 
492
etx_003:
273
  .wait_response:                   ;we wait arp-response
493
    pop     ebx                        ; Get the buffer back
-
 
494
    mov     eax, NET1OUT_QUEUE
-
 
495
    call    queue
-
 
496
    jmp     etx_exit
274
                                    ; Re-queue the packet, and exit
497
 
-
 
498
etx_send:
-
 
499
    xor     ecx, ecx
-
 
500
    mov     ch, [ebx+2]
-
 
501
    mov     cl, [ebx+3]          ; ; Size of IP packet to send
275
    pop     ebx
502
 
-
 
503
    mov     esi, ebx
-
 
504
 
-
 
505
    mov     edi, MACAddress
-
 
506
 
276
    mov     eax, NET1OUT_QUEUE
507
if DEBUGGING_STATE = DEBUGGING_ENABLED
277
    call    queue                        ; Get the buffer back
Line 508... Line 278...
508
    pusha
278
    jmp     .exit
509
    mov     cx, 42
279
 
Line 510... Line 280...
510
    mov     eax, 1                    ; Indicate that this is a tx packet
280
  .send:    ;if ARP_VALID_MAPPING then send the packet
-
 
281
    lea     edi, [MACAddress]     ; Pointer to 48 bit destination address
511
    call    eth_dump
282
    movzx   ecx, word[ebx+2]      ; Size of IP packet to send
512
    popa
283
    xchg    ch, cl                ; because mirror byte-order
Line 513... Line 284...
513
end if
284
    mov     esi, ebx              ; Pointer to packet data
514
 
285
    mov     bx, ETHER_IP          ; Type of packet
-
 
286
    call    dword [drvr_transmit] ; Call the drivers transmit function
Line 515... Line 287...
515
    mov     bx, ETHER_IP
287
 
516
    call    dword [drvr_transmit]       ; Call the drivers transmit function
288
    ; OK, we have sent a packet, so increment the count
517
 
289
    inc     dword [ip_tx_count]
518
    ; OK, we have sent a packet, so increment the count
290
 
Line 552... Line 324...
552
    add     eax, IPbuffs
324
    add     eax, IPbuffs
Line 553... Line 325...
553
 
325
 
Line 554... Line 326...
554
    mov     edi, eax
326
    mov     edi, eax
555
 
327
 
Line 556... Line 328...
556
    ; get a pointer to the start of the DATA
328
    ; get a pointer to the start of the DATA
557
    mov     esi, Ether_buffer + 14
329
    mov     esi, ETH_FRAME.Data
558
 
330
 
559
    ; Now store it all away
331
    ; Now store it all away
Line 569... Line 341...
569
 
341
 
570
eiph00x:
342
eiph00x:
Line 571... Line 343...
571
    ret
343
    ret
572
 
-
 
573
;***************************************************************************
-
 
574
;
-
 
575
;  ARP CODE FOLLOWS
-
 
576
;
-
 
577
;  The ARP code is used by ethernet drivers to translate an destination
-
 
578
;  IP address into an ethernet hardware address. Functions to broadcast
-
 
579
;  requests and handle response are (or will be) here.
-
 
580
;  The IP layer has no knowledge of ARP, as this is a network interface
-
 
581
;  issue
-
 
582
;
-
 
583
;***************************************************************************
-
 
584
 
-
 
585
;***************************************************************************
-
 
586
;   Function
-
 
587
;      arp_timer
-
 
588
;
-
 
589
;   Description
-
 
590
;      Called every 1s
-
 
591
;      It is responsible for removing expired routes
-
 
592
;      All registers may be destroyed
-
 
593
;
-
 
594
;***************************************************************************
-
 
595
arp_timer:
-
 
596
    ; loop through all the ARP entries, decrementing each one
-
 
597
    ; that doesn't have a TTL of 0xFFFF
-
 
598
    movzx   eax, byte [NumARP]
-
 
599
 
-
 
600
arp_001:
-
 
601
    cmp     eax, 0
-
 
602
    je      arp_003
-
 
603
 
-
 
604
    push    eax
-
 
605
    dec     eax
-
 
606
    mov     ecx, ARP_ENTRY_SIZE
-
 
607
    mul     ecx
-
 
608
    cmp     word [ eax + ARPTable + 12], 0xFFFF
-
 
609
    je      arp_002
-
 
610
 
-
 
611
    cmp     word [ eax + ARPTable + 12], 0
-
 
612
    je      arp_002
-
 
613
 
-
 
614
    dec     word [eax + ARPTable + 12]
-
 
615
 
-
 
616
arp_002:
-
 
617
    pop     eax
-
 
618
    dec     eax
-
 
619
    jmp     arp_001
-
 
620
 
-
 
621
    ; Now, look for entries with a TTL of 0
-
 
622
    ; Valid entries and response timeout entries get removed
-
 
623
    ; awaiting response gets converted into a response timeout, with a
-
 
624
    ; short life time - this allows queued packets to be flushed
-
 
625
arp_003:
-
 
626
    movzx   edx, byte [NumARP]
-
 
627
    cmp     edx, 0
-
 
628
    je      arp_exit
-
 
629
 
-
 
630
    ; EDX holds the # of entries to search through
-
 
631
    mov     eax, 0
-
 
632
 
-
 
633
arp_005:
-
 
634
    cmp     word [ eax + ARPTable + 12], 0
-
 
635
    jne     arp_004
-
 
636
 
-
 
637
    ; If it's status code is 0001 or 0003, delete the entry
-
 
638
    cmp     word [eax + ARPTable + 10], 0x0100
-
 
639
    je      arp_007
-
 
640
    cmp     word [eax + ARPTable + 10], 0x0300
-
 
641
    je      arp_007
-
 
642
 
-
 
643
    ; The only other valid code is 0002 - indicating a
-
 
644
    ; timeout while waiting for a response. Change the
-
 
645
    ; entry to response timed out
-
 
646
 
-
 
647
    mov     [eax + ARPTable + 10], word 0x0300
-
 
648
    mov     [eax + ARPTable + 12], word 0x000A
-
 
649
    jmp     arp_004
-
 
650
 
-
 
651
arp_007:
-
 
652
    ; Delete this entry
-
 
653
    mov     edi, ARPTable
-
 
654
    add     edi, eax
-
 
655
    mov     esi, edi
-
 
656
    add     esi, ARP_ENTRY_SIZE
-
 
657
 
-
 
658
    mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
-
 
659
    sub     ecx, eax
-
 
660
 
-
 
661
    rep     movsb
-
 
662
 
-
 
663
    dec     byte [NumARP]
-
 
664
    jmp     arp_006
-
 
665
 
-
 
666
arp_004:
-
 
667
    add     eax, ARP_ENTRY_SIZE
-
 
668
arp_006:
-
 
669
    dec     edx
-
 
670
    cmp     edx, 0
-
 
671
    jne     arp_005
-
 
672
 
-
 
673
arp_exit:
-
 
674
    ret
-
 
675
 
-
 
676
;***************************************************************************
-
 
677
;   Function
-
 
678
;      arp_request
-
 
679
;
-
 
680
;   Description
-
 
681
;      Sends an ARP request on the ethernet
-
 
682
;        The requested IP address is in edx
-
 
683
;      All registers may be destroyed
-
 
684
;
-
 
685
;***************************************************************************
-
 
686
arp_request:
-
 
687
    mov     ebx, Ether_buffer
-
 
688
    mov     ax, 0x0100
-
 
689
    mov     [ebx], ax
-
 
690
    add     ebx, 2
-
 
691
 
-
 
692
    mov     ax, 0x0008
-
 
693
    mov     [ebx], ax
-
 
694
    add     ebx, 2
-
 
695
 
-
 
696
    mov     ax, 0x0406
-
 
697
    mov     [ebx], ax
-
 
698
    add     ebx, 2
-
 
699
 
-
 
700
    mov     ax, 0x0100
-
 
701
    mov     [ebx], ax
-
 
702
    add     ebx, 2
-
 
703
 
-
 
704
    mov     ecx, node_addr
-
 
705
    mov     eax, [ecx]
-
 
706
    mov     [ebx], eax
-
 
707
    add     ecx, 4
-
 
708
    add     ebx, 4
-
 
709
    mov     ax, [ecx]
-
 
710
    mov     [ebx], ax
-
 
711
    add     ebx, 2
-
 
712
    mov     eax, [stack_ip]
-
 
713
    mov     [ebx], eax
-
 
714
    add     ebx, 4
-
 
715
 
-
 
716
    xor     eax, eax
-
 
717
    mov     [ebx], eax
-
 
718
    add     ebx, 4
-
 
719
    mov     [ebx], ax
-
 
720
 
-
 
721
    add     ebx, 2
-
 
722
    mov     [ebx], edx
-
 
723
 
-
 
724
    ; Now, send it!
-
 
725
 
-
 
726
    ; Pointer to 48 bit destination address in edi
-
 
727
    ; Type of packet in bx
-
 
728
    ; size of packet in ecx
-
 
729
    ; pointer to packet data in esi
-
 
730
    mov      edi, broadcast_add
-
 
731
 
-
 
732
;if DEBUGGING_STATE = DEBUGGING_ENABLED
-
 
733
;    pusha
-
 
734
;    mov     eax, 1                    ; Indicate that this is a tx packet
-
 
735
;    mov     ecx, 28
-
 
736
;   mov      esi, Ether_buffer
-
 
737
;    call    eth_dump
-
 
738
;    popa
-
 
739
;end if
-
 
740
 
-
 
741
    mov     bx, ETHER_ARP
-
 
742
    mov     ecx, 28
-
 
743
    mov     esi, Ether_buffer
-
 
744
    call    dword [drvr_transmit]       ; Call the drivers transmit function
-
 
745
    ret
-
 
746
 
-
 
747
;***************************************************************************
-
 
748
;   Function
-
 
749
;      arp_handler
-
 
750
;
-
 
751
;   Description
-
 
752
;      Called when an ARP packet is received on the ethernet
-
 
753
;      Header + Data is in Ether_buffer[]
-
 
754
;       It looks to see if the packet is a request to resolve this Hosts
-
 
755
;       IP address. If it is, send the ARP reply packet.
-
 
756
;      This Hosts IP address is in dword [stack_ip]  ( in network format )
-
 
757
;       This Hosts MAC address is in node_addr[6]
-
 
758
;      All registers may be destroyed
-
 
759
;
-
 
760
;***************************************************************************
-
 
761
arp_handler:
-
 
762
    ; Is this a REQUEST?
-
 
763
    ; Is this a request for My Host IP
-
 
764
    ; Yes - So construct a response message.
-
 
765
    ; Send this message to the ethernet card for transmission
-
 
766
 
-
 
767
    mov     ebx, Ether_buffer
-
 
768
 
-
 
769
    mov     edx, ebx
-
 
770
    add     edx, 20
-
 
771
    mov     ax, [edx]
-
 
772
    cmp     ax, ARP_REQ_OPCODE      ; Is this a request packet?
-
 
773
    jne     arph_resp            ; No - so test for response
-
 
774
 
-
 
775
    mov     edx, ebx
-
 
776
    add     edx, 38
-
 
777
    mov     eax, [edx]
-
 
778
 
-
 
779
    cmp     eax, [stack_ip]         ; Is it looking for my IP address?
-
 
780
    jne     arph_exit            ; No - so quit now
-
 
781
 
-
 
782
    ; OK, it is a request for my MAC address. Build the frame and send it
-
 
783
 
-
 
784
    ; Save the important data from the original packet
-
 
785
    ; remote MAC address first
-
 
786
    mov     ecx, remote_hw_add
-
 
787
    mov     edx, ebx
-
 
788
    add     edx, 22               ; edx points to Source h/w address
-
 
789
    mov     eax, [edx]
-
 
790
    mov     [ecx], eax
-
 
791
    add     edx, 4
-
 
792
    add     ecx, 4
-
 
793
    mov     ax, [edx]
-
 
794
    mov     [ecx],ax
-
 
795
 
-
 
796
    ; and also the remote IP address
-
 
797
    add     edx, 2
-
 
798
    mov     eax,[edx]
-
 
799
    mov     [remote_ip_add], eax
-
 
800
 
-
 
801
    ; So now we can reuse the packet. ebx still holds the address of
-
 
802
    ; the header + packet
-
 
803
    ; We dont need the header ( first 14 bytes )
-
 
804
 
-
 
805
    mov     edx, ebx
-
 
806
    add     edx, 20
-
 
807
    mov     ax, ARP_REP_OPCODE
-
 
808
    mov     [edx], ax
-
 
809
    add     edx, 2
-
 
810
 
-
 
811
    mov     ecx, node_addr
-
 
812
    mov     eax, [ecx]
-
 
813
    mov     [edx], eax
-
 
814
    add     ecx, 4
-
 
815
    add     edx, 4
-
 
816
    mov     ax, [ecx]
-
 
817
    mov     [edx], ax
-
 
818
    add     edx, 2
-
 
819
    mov     eax, [stack_ip]
-
 
820
    mov     [edx], eax
-
 
821
    add     edx, 4
-
 
822
    mov     ecx, remote_hw_add
-
 
823
    mov     eax, [ecx]
-
 
824
    mov     [edx], eax
-
 
825
    add     ecx, 4
-
 
826
    add     edx, 4
-
 
827
    mov     ax, [ecx]
-
 
828
    mov     [edx], ax
-
 
829
 
-
 
830
    add     edx, 2
-
 
831
    mov     eax, [remote_ip_add]
-
 
832
    mov     [edx], eax
-
 
833
 
-
 
834
    ; Now, send it!
-
 
835
 
-
 
836
    ; Pointer to 48 bit destination address in edi
-
 
837
    ; Type of packet in bx
-
 
838
    ; size of packet in ecx
-
 
839
    ; pointer to packet data in esi
-
 
840
    mov     edi, remote_hw_add
-
 
841
 
-
 
842
;if DEBUGGING_STATE = DEBUGGING_ENABLED
-
 
843
;    pusha
-
 
844
;    mov     eax, 1                    ; Indicate that this is a tx packet
-
 
845
;    mov     ecx, 28
-
 
846
;   mov      esi, Ether_buffer + 14
-
 
847
 ;   call    eth_dump
-
 
848
;    popa
-
 
849
;end if
-
 
850
 
-
 
851
    mov     bx, ETHER_ARP
-
 
852
    mov     ecx, 28
-
 
853
    mov     esi, Ether_buffer + 14
-
 
854
    call    dword [drvr_transmit]       ; Call the drivers transmit function
-
 
855
    jmp     arph_exit
-
 
856
 
-
 
857
arph_resp:
-
 
858
    cmp     ax, ARP_REP_OPCODE      ; Is this a replypacket?
-
 
859
    jne     arph_resp            ; No - so quit
-
 
860
 
-
 
861
    ; This was a reply, probably directed at me.
-
 
862
    ; save the remotes MAC & IP
-
 
863
    mov     ecx, remote_hw_add
-
 
864
    mov     edx, ebx
-
 
865
    add     edx, 22               ; edx points to Source h/w address
-
 
866
    mov     eax, [edx]
-
 
867
    mov     [ecx], eax
-
 
868
    add     edx, 4
-
 
869
    add     ecx, 4
-
 
870
    mov     ax, [edx]
-
 
871
    mov     [ecx],ax
-
 
872
 
-
 
873
    ; and also the remote IP address
-
 
874
    add     edx, 2
-
 
875
    mov     eax,[edx]
-
 
876
    mov     [remote_ip_add], eax
-
 
877
 
-
 
878
    ; Now, add an entry in the table for this IP address if it doesn't exist
-
 
879
 
-
 
880
    push    eax
-
 
881
    movzx   eax, byte [NumARP]
-
 
882
    mov     ecx, ARP_ENTRY_SIZE
-
 
883
    mul     ecx
-
 
884
    pop     edx
-
 
885
    movzx   ecx, byte [NumARP]
-
 
886
    cmp     ecx, 0
-
 
887
    je      arph_002
-
 
888
 
-
 
889
arph_001:
-
 
890
    sub     eax, ARP_ENTRY_SIZE
-
 
891
    cmp     [eax + ARPTable], edx
-
 
892
    loopnz  arph_001                      ; Return back if non match
-
 
893
 
-
 
894
    jnz     arph_002                   ; None found, add to end
-
 
895
 
-
 
896
    mov     ecx, [remote_hw_add]
-
 
897
    mov     [eax + ARPTable + 4], ecx
-
 
898
    mov     cx, [remote_hw_add+4]
-
 
899
    mov     [eax + ARPTable + 8], cx
-
 
900
 
-
 
901
    ; specify the type - a valid entry
-
 
902
    mov     cl, 0x00
-
 
903
    mov     [eax + ARPTable + 10], cl
-
 
904
    mov     cl, 0x01
-
 
905
    mov     [eax + ARPTable + 11], cl
-
 
906
 
-
 
907
    ; Initialise the time to live field - 1 hour
-
 
908
    mov     cx, 0x0E10
-
 
909
    mov     [eax + ARPTable + 12], cx
-
 
910
    jmp     arph_exit
-
 
911
 
-
 
912
arph_002:
-
 
913
 
-
 
914
    cmp     byte [NumARP], ARP_TABLE_SIZE
-
 
915
    je      arph_exit
-
 
916
 
-
 
917
    inc     byte [NumARP]
-
 
918
 
-
 
919
    movzx   eax, byte [NumARP]
-
 
920
    mov     ecx, ARP_ENTRY_SIZE
-
 
921
    mul     ecx
-
 
922
    sub     eax, ARP_ENTRY_SIZE
-
 
923
 
-
 
924
    mov     ecx, [remote_ip_add]
-
 
925
    mov     [eax + ARPTable], ecx
-
 
926
    mov     ecx, [remote_hw_add]
-
 
927
    mov     [eax + ARPTable + 4], ecx
-
 
928
    mov     cx, [remote_hw_add+4]
-
 
929
    mov     [eax + ARPTable + 8], cx
-
 
930
 
-
 
931
    mov     cl, 0x00
-
 
932
    mov     [eax + ARPTable + 10], cl
-
 
933
    mov     cl, 0x01
-
 
934
    mov     [eax + ARPTable + 11], cl
-
 
935
 
-
 
936
    ; Initialise the time to live field - 1 hour
-
 
937
    mov     cx, 0x0E10
-
 
938
    mov     [eax + ARPTable + 12], cx
-
 
939
 
-
 
940
arph_exit:
-
 
941
    ret
-
 
942
 
-
 
943
; pointer to MAC in esi
-
 
944
refreshARP:
-
 
945
    mov     ebx, [esi]
-
 
946
    mov     dx, [esi+4]
-
 
947
    push    edx
-
 
948
    movzx   eax, byte [NumARP]
-
 
949
    mov     ecx, ARP_ENTRY_SIZE
-
 
950
    mul     ecx
-
 
951
    pop     edx
-
 
952
    movzx   ecx, byte [NumARP]
-
 
953
    cmp     ecx, 0
-
 
954
    je      rf_exit
-
 
955
 
-
 
956
rf_001:
-
 
957
    sub     eax, ARP_ENTRY_SIZE
-
 
958
    cmp     [eax + ARPTable+4], ebx
-
 
959
 
-
 
960
    je      rf_002
-
 
961
    loop    rf_001
-
 
962
    jmp     rf_exit
-
 
963
 
-
 
964
rf_002:
-
 
965
    cmp     [eax + ARPTable+8], dx
-
 
966
    je      rf_gotone
-
 
967
    loop    rf_001
-
 
968
    jmp     rf_exit
-
 
969
 
-
 
970
rf_gotone:
-
 
971
    ; Initialise the time to live field - 1 hour
-
 
972
    mov     cx, 0x0E10
-
 
973
    mov     [eax + ARPTable + 12], cx
-
 
974
 
-
 
975
rf_exit:
-
 
976
    ret
-
 
977
 
-
 
978
;***************************************************************************
-
 
979
;   Function
-
 
980
;      getMACfromIP
-
 
981
;
-
 
982
;   Description
-
 
983
;       Takes an IP address in edx and scans the ARP table for
-
 
984
;        a matching entry
-
 
985
;       If a match is found, it's MAC address is stored in MACAddress.
-
 
986
;      Otherwise the value 0 is writen to MACAddress
-
 
987
;      eax holds ARP table entry status code ( ARP_ )
-
 
988
;      ebx unchanged
-
 
989
;
-
 
990
;***************************************************************************
-
 
991
getMACfromIP:
-
 
992
    ; first, check destination IP to see if it is on 'this' network.
-
 
993
    ; The test is:
-
 
994
    ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
-
 
995
    ;   desitnation is local
-
 
996
    ; else
-
 
997
    ;  destination is remote, so pass to gateway
-
 
998
 
-
 
999
    mov     eax, edx
-
 
1000
    and     eax, [subnet_mask]
-
 
1001
    mov     ecx, [stack_ip]
-
 
1002
    and     ecx, [subnet_mask]
-
 
1003
    cmp     eax, ecx
-
 
1004
    je      gm0
-
 
1005
 
-
 
1006
    mov     edx, [gateway_ip]
-
 
1007
gm0:
-
 
1008
    push    edx
-
 
1009
    xor     eax, eax
-
 
1010
    mov     [MACAddress], eax
-
 
1011
    mov     [MACAddress + 4], ax
-
 
1012
 
-
 
1013
    movzx   eax, byte [NumARP]
-
 
1014
    mov     ecx, ARP_ENTRY_SIZE
-
 
1015
    mul     ecx
-
 
1016
 
-
 
1017
    pop     edx
-
 
1018
 
-
 
1019
    movzx   ecx, byte [NumARP]
-
 
1020
    cmp     ecx, 0
-
 
1021
    je      gm_none
-
 
1022
gm1:
-
 
1023
    sub     eax, ARP_ENTRY_SIZE
-
 
1024
    cmp     [eax + ARPTable], edx
-
 
1025
    loopnz  gm1                      ; Return back if non match
-
 
1026
    jnz     gm_none                   ; Quit if none found
-
 
1027
 
-
 
1028
    ; eax holds index
-
 
1029
    mov     ecx, [eax + ARPTable + 4]
-
 
1030
    mov     [MACAddress], ecx
-
 
1031
    mov     cx, [eax + ARPTable + 8]
-
 
1032
    mov     [MACAddress+4], cx
-
 
1033
 
-
 
1034
    ; Return the entry status in eax
-
 
1035
    mov     ch, [eax + ARPTable + 10]
-
 
1036
    mov     cl, [eax + ARPTable + 11]
-
 
1037
    movzx   eax, cx
-
 
1038
    jmp     gm_exit
-
 
1039
 
-
 
1040
gm_none:
-
 
1041
    mov     eax, ARP_NO_ENTRY
-
 
1042
 
-
 
1043
gm_exit:
-
 
1044
    ret
-
 
1045
 
-
 
1046
;***************************************************************************
-
 
1047
;
-
 
1048
;  PCI CODE FOLLOWS
-
 
1049
;
-
 
1050
;  the following functions provide access to the PCI interface.
-
 
1051
;  These functions are used by scan_bus, and also some ethernet drivers
-
 
1052
;
-
 
1053
;***************************************************************************
-
 
1054
 
344
 
1055
;***************************************************************************
-
 
1056
;   Function
-
 
1057
;      config_cmd
-
 
1058
;
-
 
1059
;   Description
-
 
1060
;       creates a command dword  for use with the PCI bus
345
;***************************************************************************
1061
;       bus # in ebx
-
 
1062
;      devfn in ecx
-
 
1063
;       where in edx
-
 
1064
;
-
 
1065
;      command dword returned in eax
-
 
1066
;       Only eax destroyed
-
 
1067
;***************************************************************************
-
 
1068
config_cmd:
-
 
1069
    push    ecx
-
 
1070
    mov     eax, ebx
-
 
1071
    shl     eax, 16
-
 
1072
    or      eax, 0x80000000
-
 
1073
    shl     ecx, 8
-
 
1074
    or      eax, ecx
-
 
1075
    pop     ecx
-
 
1076
    or      eax, edx
-
 
1077
    and     eax, 0xFFFFFFFC
-
 
1078
    ret
-
 
1079
 
-
 
1080
;***************************************************************************
-
 
1081
;   Function
-
 
1082
;      pcibios_read_config_byte
-
 
1083
;
-
 
1084
;   Description
-
 
1085
;       reads a byte from the PCI config space
-
 
1086
;       bus # in ebx
-
 
1087
;      devfn in ecx
-
 
1088
;       where in edx ( ls 16 bits significant )
-
 
1089
;
-
 
1090
;      byte returned in al ( rest of eax zero )
-
 
1091
;       Only eax/edx destroyed
-
 
1092
;***************************************************************************
-
 
1093
pcibios_read_config_byte:
-
 
1094
    call    config_cmd
-
 
1095
    push    dx
-
 
1096
    mov     dx, 0xCF8
-
 
1097
    out     dx, eax
-
 
1098
    pop     dx
-
 
1099
 
-
 
1100
    xor     eax, eax
-
 
1101
    and     dx, 0x03
-
 
1102
    add     dx, 0xCFC
-
 
1103
;   and     dx, 0xFFC
-
 
1104
    in      al, dx
-
 
1105
    ret
-
 
1106
 
-
 
1107
;***************************************************************************
-
 
1108
;   Function
-
 
1109
;      pcibios_read_config_word
346
;   Function
1110
;
347
;      eth_probe
1111
;   Description
-
 
1112
;       reads a word from the PCI config space
-
 
1113
;       bus # in ebx
348
;   Description
1114
;      devfn in ecx
-
 
1115
;       where in edx ( ls 16 bits significant )
-
 
1116
;
-
 
1117
;      word returned in ax ( rest of eax zero )
-
 
1118
;       Only eax/edx destroyed
-
 
1119
;***************************************************************************
-
 
1120
pcibios_read_config_word:
-
 
1121
    call    config_cmd
-
 
1122
    push    dx
-
 
1123
    mov     dx, 0xCF8
-
 
1124
    out     dx, eax
-
 
1125
    pop     dx
-
 
1126
 
-
 
1127
    xor     eax, eax
-
 
1128
    and     dx, 0x02
-
 
1129
    add     dx, 0xCFC
-
 
1130
;   and     dx, 0xFFC
-
 
1131
    in      ax, dx
-
 
1132
    ret
-
 
1133
 
-
 
1134
;***************************************************************************
-
 
1135
;   Function
349
;      Searches for an ethernet card. If found, the card is enabled and
1136
;      pcibios_read_config_dword
-
 
1137
;
350
;      the ethernet -> IP link established
1138
;   Description
-
 
1139
;       reads a dword from the PCI config space
-
 
1140
;       bus # in ebx
351
;
1141
;      devfn in ecx
352
;      This function scans the PCI bus looking for a supported device.
1142
;       where in edx ( ls 16 bits significant )
-
 
1143
;
353
;      ISA bus is currently not supported.
1144
;      dword returned in eax
354
;
1145
;       Only eax/edx destroyed
-
 
1146
;***************************************************************************
355
;        eax is 0 if no hardware found
1147
pcibios_read_config_dword:
356
;***************************************************************************
1148
    push    edx
-
 
1149
    call    config_cmd
-
 
1150
    push    dx
357
eth_probe:
1151
    mov     dx, 0xCF8
-
 
1152
    out     dx, eax
358
    ; Find a card on the PCI bus, and get it's address
1153
    pop     dx
-
 
1154
    xor     eax, eax
-
 
1155
    mov     dx, 0xCFC
-
 
1156
    in      eax, dx
-
 
1157
    pop     edx
-
 
1158
    ret
-
 
1159
 
-
 
1160
;***************************************************************************
-
 
1161
;   Function
-
 
1162
;      pcibios_write_config_byte
-
 
1163
;
-
 
1164
;   Description
-
 
1165
;       write a byte in al to the PCI config space
-
 
1166
;       bus # in ebx
-
 
1167
;      devfn in ecx
-
 
1168
;       where in edx ( ls 16 bits significant )
-
 
1169
;
-
 
1170
;       Only eax/edx destroyed
-
 
1171
;***************************************************************************
-
 
1172
pcibios_write_config_byte:
-
 
1173
    push    ax
-
 
1174
    call    config_cmd
-
 
1175
    push    dx
-
 
1176
    mov     dx, 0xCF8
-
 
1177
    out     dx, eax
-
 
1178
    pop     dx
-
 
1179
    pop     ax
-
 
1180
 
-
 
1181
    and     dx, 0x03
-
 
1182
    add     dx, 0xCFC
-
 
1183
    out     dx, al
-
 
1184
    ret
-
 
1185
 
-
 
1186
;***************************************************************************
-
 
1187
;   Function
-
 
1188
;      pcibios_write_config_word
-
 
1189
;
-
 
1190
;   Description
-
 
1191
;       write a word in ax to the PCI config space
-
 
1192
;       bus # in ebx
-
 
1193
;      devfn in ecx
-
 
1194
;       where in edx ( ls 16 bits significant )
-
 
1195
;
-
 
1196
;       Only eax/edx destroyed
-
 
1197
;***************************************************************************
-
 
1198
pcibios_write_config_word:
-
 
1199
    push    ax
-
 
1200
    call    config_cmd
-
 
1201
    push    dx
359
    call    scan_bus                    ; Find the ethernet cards PIC address
1202
    mov     dx, 0xCF8
-
 
1203
    out     dx, eax
-
 
1204
    pop     dx
-
 
1205
    pop     ax
-
 
1206
 
-
 
1207
    and     dx, 0x02
-
 
1208
    add     dx, 0xCFC
-
 
1209
    out     dx, ax
-
 
1210
    ret
-
 
1211
 
-
 
1212
;***************************************************************************
-
 
1213
;   Function
-
 
1214
;      delay_us
-
 
1215
;
-
 
1216
;   Description
-
 
1217
;       delays for 30 to 60 us
-
 
1218
;
360
    xor     eax, eax
1219
;        I would prefer this routine to be able to delay for
-
 
1220
;       a selectable number of microseconds, but this works for now.
-
 
1221
;
-
 
1222
;       If you know a better way to do 2us delay, pleae tell me!
-
 
1223
;***************************************************************************
-
 
1224
delay_us:
-
 
1225
    push    eax
-
 
1226
    push    ecx
-
 
1227
 
-
 
1228
    mov     ecx,2
-
 
1229
 
-
 
1230
    in      al,0x61
-
 
1231
    and     al,0x10
-
 
1232
    mov     ah,al
-
 
1233
    cld
-
 
1234
 
-
 
1235
dcnt1:
-
 
1236
    in      al,0x61
-
 
1237
    and     al,0x10
-
 
Line 1238... Line -...
1238
    cmp     al,ah
-
 
1239
    jz      dcnt1
361
    cmp     [io_addr], eax
Line 1240... Line -...
1240
 
-
 
1241
    mov     ah,al
362
    je      ep_00x                      ; Return 0 in eax if no cards found
Line -... Line 363...
-
 
363
 
1242
    loop    dcnt1
364
    call    dword [drvr_probe]          ; Call the drivers probe function
Line 1243... Line 365...
1243
 
365
 
1244
    pop     ecx
366
    mov     eax, [io_addr]              ; return a non zero value
1245
    pop     eax
367
 
1246
 
368
ep_00x:
1247
    ret
369
    ret
1248
 
370
 
1249
;***************************************************************************
-
 
1250
;   Function
371
;***************************************************************************
1251
;      scan_bus
-
 
1252
;
-
 
1253
;   Description
-
 
1254
;       Scans the PCI bus for a supported device
-
 
1255
;        If a supported device is found, the drvr_ variables are initialised
-
 
1256
;       to that drivers functions ( as defined in the PCICards table)
-
 
1257
;
-
 
1258
;        io_addr   holds card I/O space. 32 bit, but only LS 16 bits valid
372
;   Function
1259
;        pci_data  holds the PCI vendor + device code
373
;      ethernet_driver
1260
;       pci_dev   holds PCI bus dev #
-
 
1261
;       pci_bus   holds PCI bus #
-
 
1262
;
-
 
1263
;        io_addr will be zero if no card found
-
 
1264
;
-
 
1265
;***************************************************************************
-
 
1266
scan_bus:
-
 
1267
    xor     eax, eax
-
 
1268
    mov     [hdrtype], al
-
 
1269
    mov     [pci_data], eax
-
 
1270
 
-
 
1271
    xor     ebx, ebx         ; ebx = bus# 0 .. 255
-
 
1272
 
-
 
1273
sb_bus_loop:
-
 
1274
    xor     ecx, ecx         ; ecx = devfn# 0 .. 254  ( not 255? )
-
 
1275
 
-
 
1276
sb_devf_loop:
-
 
1277
    mov     eax, ecx
-
 
1278
    and     eax, 0x07
-
 
1279
 
-
 
1280
    cmp     eax, 0
-
 
1281
    jne     sb_001
-
 
1282
 
-
 
1283
    mov     edx, PCI_HEADER_TYPE
-
 
1284
    call    pcibios_read_config_byte
-
 
1285
    mov     [hdrtype], al
-
 
1286
    jmp     sb_002
-
 
1287
 
-
 
1288
sb_001:
-
 
1289
    mov     al, [hdrtype]
-
 
1290
    and     al, 0x80
-
 
1291
    cmp     al, 0x80
-
 
1292
    jne     sb_inc_devf
-
 
1293
 
-
 
1294
sb_002:
-
 
1295
    mov     edx, PCI_VENDOR_ID
-
 
1296
    call    pcibios_read_config_dword
-
 
1297
    mov     [vendor_device], eax
-
 
1298
    cmp     eax, 0xffffffff
-
 
1299
    je      sb_empty
-
 
1300
    cmp     eax, 0
-
 
1301
    jne     sb_check_vendor
374
;
1302
 
-
 
1303
sb_empty:
-
 
1304
    mov     [hdrtype], byte 0
-
 
1305
    jmp     sb_inc_devf
-
 
1306
 
-
 
1307
sb_check_vendor:
-
 
1308
    ; iterate though PCICards until end or match found
-
 
1309
    mov     esi, PCICards
-
 
1310
 
-
 
1311
sb_check:
-
 
1312
    cmp     [esi], dword 0
-
 
1313
    je      sb_inc_devf                ; Quit if at last entry
-
 
1314
    cmp     eax, [esi]
-
 
1315
    je      sb_got_card
-
 
1316
    add     esi, PCICARDS_ENTRY_SIZE
-
 
1317
    jmp     sb_check
-
 
1318
 
-
 
1319
sb_got_card:
375
;   Description
1320
    ; indicate that we have found the card
-
 
1321
    mov     [pci_data], eax
-
 
1322
    mov     [pci_dev], ecx
-
 
1323
    mov     [pci_bus], ebx
-
 
1324
 
-
 
1325
    ; Define the driver functions
-
 
1326
    push    eax
-
 
1327
    mov     eax, [esi+4]
-
 
1328
    mov     [drvr_probe], eax
376
;       The ethernet RX and TX handler
1329
    mov     eax, [esi+8]
-
 
1330
    mov     [drvr_reset], eax
-
 
1331
    mov     eax, [esi+12]
-
 
1332
    mov     [drvr_poll], eax
-
 
1333
    mov     eax, [esi+16]
-
 
1334
    mov     [drvr_transmit], eax
-
 
1335
    pop     eax
-
 
1336
 
-
 
1337
    mov     edx, PCI_BASE_ADDRESS_0
-
 
1338
 
-
 
1339
sb_reg_check:
-
 
1340
    call    pcibios_read_config_dword
-
 
1341
    mov     [io_addr], eax
-
 
1342
    and     eax, PCI_BASE_ADDRESS_IO_MASK
377
;       This is a kernel function, called by stack_handler
1343
    cmp     eax, 0
-
 
1344
    je      sb_inc_reg
-
 
1345
    mov     eax, [io_addr]
-
 
1346
    and     eax, PCI_BASE_ADDRESS_SPACE_IO
-
 
1347
    cmp     eax, 0
-
 
1348
    je      sb_inc_reg
-
 
1349
 
-
 
1350
    mov     eax, [io_addr]
-
 
1351
    and     eax, PCI_BASE_ADDRESS_IO_MASK
-
 
1352
    mov     [io_addr], eax
-
 
1353
 
-
 
1354
sb_exit1:
-
 
1355
    ret
-
 
1356
 
-
 
1357
sb_inc_reg:
-
 
1358
    add     edx, 4
-
 
1359
    cmp     edx, PCI_BASE_ADDRESS_5
-
 
1360
    jbe     sb_reg_check
-
 
1361
 
-
 
1362
sb_inc_devf:
-
 
Line 1363... Line -...
1363
    inc     ecx
-
 
1364
    cmp     ecx, 255
-
 
1365
    jb      sb_devf_loop
378
;
1366
    inc     ebx
379
;***************************************************************************
Line 1367... Line 380...
1367
    cmp     ebx, 256
380
ethernet_driver:
1368
    jb      sb_bus_loop
381
    ; Do nothing if the driver is inactive
Line 1369... Line 382...
1369
 
382
    cmp     [ethernet_active], byte 0
1370
    ; We get here if we didn't find our card
-
 
1371
    ; set io_addr to 0 as an indication
-
 
1372
    xor     eax, eax
-
 
1373
    mov     [io_addr], eax
-
 
1374
 
-
 
1375
sb_exit2:
-
 
1376
    ret
-
 
1377
 
-
 
1378
;***************************************************************************
-
 
1379
;
-
 
1380
;  DEBUGGING CODE FOLLOWS
-
 
1381
;
383
    je      eth_exit
1382
;  If debugging data output is not required, ALL code & data below may
384
 
1383
;  be removed.
385
    call    eth_rx
1384
;
386
    call    eth_tx
1385
;***************************************************************************
387
 
1386
 
388
eth_exit:
1387
if DEBUGGING_STATE = DEBUGGING_ENABLED
-
 
1388
 
-
 
1389
;***************************************************************************
-
 
1390
;   Function
389
    ret
1391
;      eth_dump
390
 
1392
;
391
;***************************************************************************
1393
;   Description
-
 
1394
;       Dumps a tx or rx ethernet packet over the rs232 link
392
;   Function
1395
;       This is a debugging routine that seriously slows down the stack.
393
;      eth_rx
1396
;       Use with caution.
394
;
1397
;
-
 
1398
;       Baud rate is 57600, 8n1  com1
-
 
1399
;         eax : type (0 == rx, 1 == tx )
-
 
1400
;          cx : # of bytes in buffer
-
 
1401
;         esi : address of buffer start
-
 
1402
;         edi : pointer to MACAddress ( tx only )
-
 
1403
;
-
 
1404
;***************************************************************************
-
 
1405
eth_dump:
-
 
1406
    pusha
-
 
1407
 
-
 
1408
    ; Set the port to the desired speed
-
 
1409
    mov     ebx, 0x3f8                     ; combase
-
 
1410
 
-
 
1411
    mov     edx, ebx
-
 
1412
    add     edx, 3                        ; data format register
-
 
1413
    mov     al, 0x80                    ; enable access to divisor latch
-
 
1414
    out     dx, al
-
 
1415
 
-
 
1416
    mov     edx, ebx
-
 
1417
    add     edx, 1                        ; interrupt enable register
-
 
1418
    mov     al, 0x00                    ; No interruts enabled
-
 
1419
    out     dx, al
-
 
1420
 
-
 
1421
    mov     edx, ebx
-
 
1422
    mov     al, 0x20 / 16                ; set baud rate to 57600 0x10 =115200
-
 
1423
    out     dx, al
-
 
1424
 
-
 
1425
    mov     edx, ebx
-
 
1426
    add     edx, 3                        ; data format register
-
 
1427
    mov     al, 0x03                    ; 8 data bits
-
 
1428
    out     dx, al
-
 
1429
 
-
 
1430
    mov     edx, ebx
-
 
1431
    add     edx, 4                        ; Modem control register
-
 
1432
    mov     al, 0x08                    ; out2 enabled. No handshaking.
-
 
1433
    out     dx, al
-
 
1434
 
-
 
1435
    mov     edx, ebx
-
 
1436
    add     edx, 1                        ; interrupt enable register
-
 
1437
    mov     al, 0x01                    ; Receive data interrupt enabled,
-
 
1438
    out     dx, al
-
 
1439
 
-
 
1440
    popa
-
 
1441
 
-
 
1442
    ; First, display the type of the buffer.
-
 
1443
    ; If it is a tx buffer, display the macaddress
-
 
1444
 
-
 
1445
    pusha
-
 
1446
 
-
 
1447
    cmp     eax, 0
-
 
1448
    jne     dd001
-
 
1449
 
-
 
1450
    mov     bl, 0x0a
-
 
1451
    call    tx_byted
-
 
1452
    mov     bl, 0x0d
-
 
1453
    call    tx_byted
-
 
1454
 
-
 
1455
    ; Output "RX:"
-
 
1456
    mov     bl, 'R'
-
 
1457
    call    tx_byted
-
 
1458
    mov     bl, 'X'
-
 
1459
    call    tx_byted
-
 
1460
    mov     bl, ':'
-
 
1461
    call    tx_byted
-
 
1462
    jmp     dump_data
-
 
1463
 
-
 
1464
dd001:
-
 
1465
    mov     bl, 0x0a
-
 
1466
    call    tx_byted
-
 
1467
    mov     bl, 0x0d
-
 
1468
    call    tx_byted
-
 
1469
 
-
 
1470
    ; Output TX: xxxxxxxxxxxx
-
 
1471
    mov     bl, 'T'
-
 
1472
    call    tx_byted
-
 
1473
    mov     bl, 'X'
-
 
1474
    call    tx_byted
-
 
1475
    mov     bl, ':'
-
 
1476
    call    tx_byted
-
 
1477
    mov     bl, ' '
-
 
1478
    call    tx_byted
-
 
1479
 
-
 
1480
    ; Display MAC address
-
 
1481
    xor     eax, eax
-
 
1482
    mov     al, [edi]
-
 
1483
    shr     al, 4
-
 
1484
    mov     bl, [eax + hexchars]
-
 
1485
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1486
 
-
 
1487
    xor     eax, eax
-
 
1488
    mov     al, [edi]
-
 
1489
    and     al, 0x0f
-
 
1490
    mov     bl, [eax + hexchars]
-
 
1491
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1492
 
-
 
1493
    inc     edi
-
 
1494
    xor     eax, eax
-
 
1495
    mov     al, [edi]
-
 
1496
    shr     al, 4
-
 
1497
    mov     bl, [eax + hexchars]
-
 
1498
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1499
 
-
 
1500
    xor     eax, eax
-
 
1501
    mov     al, [edi]
-
 
1502
    and     al, 0x0f
-
 
1503
    mov     bl, [eax + hexchars]
-
 
1504
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1505
 
-
 
1506
    inc     edi
-
 
1507
    xor     eax, eax
-
 
1508
    mov     al, [edi]
-
 
1509
    shr     al, 4
-
 
1510
    mov     bl, [eax + hexchars]
-
 
1511
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1512
 
-
 
1513
    xor     eax, eax
-
 
1514
    mov     al, [edi]
-
 
1515
    and     al, 0x0f
-
 
1516
    mov     bl, [eax + hexchars]
-
 
1517
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1518
 
-
 
1519
    inc     edi
-
 
1520
    xor     eax, eax
-
 
1521
    mov     al, [edi]
-
 
1522
    shr     al, 4
-
 
1523
    mov     bl, [eax + hexchars]
-
 
1524
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1525
 
-
 
1526
    xor     eax, eax
-
 
1527
    mov     al, [edi]
-
 
1528
    and     al, 0x0f
-
 
1529
    mov     bl, [eax + hexchars]
-
 
1530
    call    tx_byted ; byte in bl eax ebx edx destroyed
395
;   Description
1531
 
-
 
1532
    inc     edi
-
 
1533
    xor     eax, eax
396
;      Polls the ethernet card for received data. Extracts if present
1534
    mov     al, [edi]
-
 
1535
    shr     al, 4
-
 
1536
    mov     bl, [eax + hexchars]
-
 
1537
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1538
 
-
 
1539
    xor     eax, eax
-
 
1540
    mov     al, [edi]
-
 
1541
    and     al, 0x0f
-
 
1542
    mov     bl, [eax + hexchars]
-
 
1543
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1544
 
-
 
1545
    inc     edi
-
 
1546
    xor     eax, eax
-
 
1547
    mov     al, [edi]
-
 
1548
    shr     al, 4
-
 
1549
    mov     bl, [eax + hexchars]
-
 
1550
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1551
 
-
 
1552
    xor     eax, eax
-
 
1553
    mov     al, [edi]
-
 
1554
    and     al, 0x0f
-
 
1555
    mov     bl, [eax + hexchars]
-
 
1556
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1557
 
-
 
1558
dump_data:
-
 
1559
    popa
-
 
1560
 
-
 
1561
    ; OK, we come in here with
-
 
1562
    ; cx == number of byte to send
-
 
1563
    ; esi == buffer start
-
 
1564
    ;
-
 
1565
dd_000:
-
 
1566
    mov     bl, 0x0a
-
 
1567
    call    tx_byted
-
 
1568
    mov     bl, 0x0d
-
 
1569
    call    tx_byted
-
 
1570
 
-
 
1571
    mov     eax, 16        ; Number of characters on the line
-
 
1572
    mov     edi, esi    ; Save first byte position for later
-
 
1573
 
-
 
1574
    push    ecx
-
 
1575
 
-
 
1576
dd_001:
-
 
1577
    push    eax
-
 
1578
 
-
 
1579
    ; Print a byte, and a space
-
 
1580
    xor     eax, eax
-
 
1581
    mov     al, [esi]
-
 
1582
    shr     al, 4
-
 
1583
    mov     bl, [eax + hexchars]
-
 
1584
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1585
 
-
 
1586
    xor     eax, eax
-
 
1587
    mov     al, [esi]
-
 
1588
    and     al, 0x0f
-
 
1589
    mov     bl, [eax + hexchars]
-
 
1590
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1591
 
397
;       Depending on the Protocol within the packet:
1592
    mov     bl, ' '
-
 
1593
    call    tx_byted
-
 
1594
 
-
 
1595
    pop     eax
-
 
1596
 
-
 
1597
    inc     esi
-
 
1598
    dec     ecx
-
 
1599
    cmp     ecx, 0
-
 
1600
    je      dd_0011            ; Print the ASCII format
-
 
1601
 
-
 
1602
    dec     eax
-
 
1603
 
-
 
1604
    cmp     eax, 0
-
 
1605
    je      dd_002            ; Print the ASCII format
-
 
1606
    jmp     dd_001            ; Print rest of line
-
 
1607
 
-
 
1608
dd_0011:
-
 
1609
    ; First, complete the 16 bytes of data, by printing spaces
-
 
1610
    dec     eax
-
 
1611
    cmp     eax, 0
-
 
1612
    je      dd_002
-
 
1613
 
-
 
1614
    push    eax
-
 
1615
    mov     bl, ' '
-
 
1616
    call    tx_byted
-
 
1617
    mov     bl, ' '
-
 
1618
    call    tx_byted
-
 
1619
    mov     bl, ' '
-
 
1620
    call    tx_byted
-
 
1621
    pop     eax
-
 
1622
    jmp     dd_0011
-
 
1623
 
-
 
1624
dd_002:
-
 
1625
    pop     ecx
-
 
1626
    mov     esi, edi        ; Go back to the start of the line data
-
 
Line 1627... Line 398...
1627
 
398
;         ARP : Pass to ARP_handler. This may result in an ARP reply
1628
    mov     eax, 16
-
 
1629
 
399
;               being tx'ed
1630
outLineAscii:
400
;         IP  : Store in an IP buffer
Line 1631... Line -...
1631
    push    eax
-
 
Line 1632... Line -...
1632
 
-
 
1633
    xor     eax, eax
401
;
Line 1634... Line -...
1634
    mov     al, [esi]
-
 
1635
    mov     bl, '.'
-
 
1636
 
-
 
1637
    cmp     al, 0x1F
-
 
1638
    jle     outAscii
-
 
1639
    cmp     al, 0x7e
-
 
1640
    jge     outAscii
-
 
1641
 
-
 
1642
    mov     bl, al
-
 
1643
 
402
;***************************************************************************
1644
outAscii:
-
 
1645
    call    tx_byted ; byte in bl eax ebx edx destroyed
-
 
1646
 
-
 
1647
    pop     eax
-
 
1648
    dec     ecx
-
 
Line 1649... Line -...
1649
    inc     esi
-
 
1650
    cmp     ecx, 0
403
eth_rx:
-
 
404
    xor     ax, ax
Line 1651... Line -...
1651
    je      dd_003
-
 
1652
 
-
 
1653
    dec     eax
-
 
1654
    cmp     eax, 0
-
 
1655
    je      dd_003
-
 
1656
    jmp     outLineAscii
-
 
1657
 
405
    mov     [eth_rx_data_len], ax
1658
dd_003:
-
 
1659
    cmp     ecx, 0
-
 
1660
    je      dd_004
-
 
1661
    jmp     dd_000
406
    call    dword [drvr_poll]       ; Call the drivers poll function
Line 1662... Line 407...
1662
 
407
 
Line -... Line 408...
-
 
408
    mov     ax, [eth_rx_data_len]
1663
dd_004:
409
    cmp     ax, 0
-
 
410
    je      .exit
-
 
411
 
Line 1664... Line -...
1664
    ret
-
 
1665
 
412
 
Line 1666... Line -...
1666
;***************************************************************************
-
 
1667
;   Function
413
    ; Check the protocol. Call appropriate handler
1668
;      tx_byte
-
 
1669
;
414
 
1670
;   Description
-
 
Line 1671... Line -...
1671
;       Send a byte in bl out of the com port 1
-
 
1672
;       destroys eax, edx
-
 
1673
;
415
    mov     ax, [ETH_FRAME.Type]    ; The address of the protocol word
1674
;***************************************************************************
416
 
1675
tx_byted:
-
 
1676
    push    ebx                     ; Save the byte
-
 
1677
 
-
 
1678
    mov     ebx, 0x3f8            ; get the com port address
-
 
1679
 
-
 
1680
    ; Wait for transmit buffer to empty. This could take 1ms @ 9600baud
-
 
1681
 
-