Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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