Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                    ;;
  3. ;; Copyright (C) KolibriOS team 2004-2009. All rights reserved.       ;;
  4. ;; Distributed under terms of the GNU General Public License          ;;
  5. ;;                                                                    ;;
  6. ;;  Ethernet driver for KolibriOS                                     ;;
  7. ;;  This is an adaptation of MenuetOS driver with minimal changes.    ;;
  8. ;;  Changes were made by CleverMouse. Original copyright follows.     ;;
  9. ;;                                                                    ;;
  10. ;;  This driver is based on the SIS900 driver from                    ;;
  11. ;;  the etherboot 5.0.6 project. The copyright statement is           ;;
  12. ;;                                                                    ;;
  13. ;;          GNU GENERAL PUBLIC LICENSE                                ;;
  14. ;;             Version 2, June 1991                                   ;;
  15. ;;                                                                    ;;
  16. ;;  remaining parts Copyright 2004 Jason Delozier,                    ;;
  17. ;;   cordata51@hotmail.com                                            ;;
  18. ;;                                                                    ;;
  19. ;;  See file COPYING for details                                      ;;
  20. ;;                                                                    ;;
  21. ;;  Updates:                                                          ;;
  22. ;;    Revision Look up table and SIS635 Mac Address by Jarek Pelczar  ;;
  23. ;;                                                                    ;;
  24. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  25.  
  26. ; $Revision: 1254 $
  27.  
  28. format MS COFF
  29.  
  30.         API_VERSION             equ 0x01000100
  31.  
  32.         DEBUG                   equ 1
  33.         __DEBUG__               equ 1
  34.         __DEBUG_LEVEL__         equ 1
  35.  
  36. include 'proc32.inc'
  37. include 'imports.inc'
  38. include 'fdo.inc'
  39.  
  40. public START
  41. public version
  42.  
  43. struc IOCTL {
  44.       .handle           dd ?
  45.       .io_code          dd ?
  46.       .input            dd ?
  47.       .inp_size         dd ?
  48.       .output           dd ?
  49.       .out_size         dd ?
  50. }
  51.  
  52. virtual at 0
  53.   IOCTL IOCTL
  54. end virtual
  55.  
  56. NUM_RX_DESC    equ    4               ;* Number of RX descriptors *
  57. NUM_TX_DESC    equ    1               ;* Number of TX descriptors *
  58. RX_BUFF_SZ          equ    1520            ;* Buffer size for each Rx buffer *
  59. TX_BUFF_SZ          equ    1516            ;* Buffer size for each Tx buffer *
  60. MAX_ETH_FRAME_SIZE  equ    1516
  61.  
  62. TOTAL_BUFFERS_SIZE equ NUM_RX_DESC*RX_BUFF_SZ + NUM_TX_DESC*TX_BUFF_SZ
  63.  
  64. struc ETH_DEVICE {
  65. ; pointers to procedures
  66.       .unload           dd ?
  67.       .reset            dd ?
  68.       .transmit         dd ?
  69.       .set_MAC          dd ?
  70.       .get_MAC          dd ?
  71.       .set_mode         dd ?
  72.       .get_mode         dd ?
  73. ; status & variables
  74.       .bytes_tx         dq ?
  75.       .bytes_rx         dq ?
  76.       .packets_tx       dd ?
  77.       .packets_rx       dd ?
  78.       .mode             dd ?  ; This dword contains cable status (10mbit/100mbit, full/half duplex, auto negotiation or not,..)
  79.       .name             dd ?
  80.       .mac              dp ?
  81. ; device specific
  82.       .io_addr          dd ?
  83.       .pci_bus          db ?
  84.       .pci_dev          db ?
  85.       .irq_line         db ?
  86.       .cur_rx           db ?
  87.       .pci_revision     db ?
  88.       .table_entries:   db ?
  89. align 4
  90.       .special_func:    dd 0
  91.       .txd: times (3 * NUM_TX_DESC) dd 0
  92.       .rxd: times (3 * NUM_RX_DESC) dd 0
  93.       .size:
  94. }
  95.  
  96. ; First page is designated to ETH_DEVICE, buffers start from second
  97. ALLOCATION_SIZE = ((device.size+0FFFh) and not 0FFFh) + TOTAL_BUFFERS_SIZE
  98. ; Note that buffers must be contiguous in the physical memory;
  99. ; because KernelAlloc allocates contiguous physical pages only in 8-pages blocks,
  100. ; align ALLOCATION_SIZE up to 8*(page size) = 8000h
  101. ALLOCATION_SIZE = (ALLOCATION_SIZE + 7FFFh) and not 7FFFh
  102.  
  103. MAX_DEVICES = 16        ; maximum number of devices which this driver can handle
  104.  
  105. virtual at 0
  106.   device ETH_DEVICE
  107. end virtual
  108.  
  109.         PCI_HEADER_TYPE               equ 0x0e  ;8 bit
  110.         PCI_BASE_ADDRESS_0            equ 0x10  ;32 bit
  111.         PCI_BASE_ADDRESS_5            equ 0x24  ;32 bits
  112.         PCI_BASE_ADDRESS_SPACE_IO     equ 0x01
  113.         PCI_VENDOR_ID                 equ 0x00  ;16 bit
  114.         PCI_BASE_ADDRESS_IO_MASK      equ 0xFFFFFFFC
  115.  
  116. section '.flat' code readable align 16
  117.  
  118. ; Driver entry point - register our service when the driver is loading.
  119. ; TODO: add needed operations when unloading
  120. START:
  121.         cmp     dword [esp+4], 1
  122.         jne     .exit
  123.         stdcall RegService, my_service, service_proc
  124.         ret     4
  125. .exit:
  126.         xor     eax, eax
  127.         ret     4
  128.  
  129. ; Service procedure for the driver - handle all I/O requests for the driver.
  130. ; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1.
  131. service_proc:
  132. ; 1. Get parameter from the stack: [esp+4] is the first parameter,
  133. ;       pointer to IOCTL structure.
  134.         mov     edx, [esp+4]    ; edx -> IOCTL
  135. ; 2. Get request code and select a handler for the code.
  136.         mov     eax, [ebx+IOCTL.io_code]
  137.         test    eax, eax        ; check for SRV_GETVERSION
  138.         jnz     @f
  139. ; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION.
  140. ; 3a. Output size must be at least 4 bytes.
  141.         cmp     [edx+IOCTL.out_size], 4
  142.         jl      .fail
  143. ; 3b. Write result to the output buffer.
  144.         mov     eax, [edx+IOCTL.output]
  145.         mov     [eax], dword API_VERSION
  146. ; 3c. Return success.
  147.         xor     eax, eax
  148.         ret     4
  149. @@:
  150.         dec     eax     ; check for SRV_HOOK
  151.         jnz     .fail
  152. ; 4. This is SRV_HOOK request, input defines the device to hook, no output.
  153. ; 4a. The driver works only with PCI devices,
  154. ;       so input must be at least 3 bytes long.
  155.         cmp     [edx + IOCTL.inp_size], 3
  156.         jl      .fail
  157. ; 4b. First byte of input is bus type, 1 stands for PCI.
  158.         mov     eax, [edx + IOCTL.input]
  159.         cmp     byte [eax], 1
  160.         jne     .fail
  161. ; 4c. Second and third bytes of the input define the device: bus and dev.
  162. ;       Word in bx holds both bytes.
  163.         mov     bx, [eax+1]
  164. ; 4d. Check if the device was already hooked,
  165. ;       scan through the list of known devices.
  166.         mov     esi, DEV_LIST
  167.         mov     ecx, [NUM_DEV]
  168.         test    ecx, ecx
  169.         jz      .firstdevice
  170.   .nextdevice:
  171.         lodsd
  172.         cmp     bx, word [eax + device.pci_bus]
  173.         je      .find_devicenum
  174.         loop    .nextdevice
  175. ; 4e. This device doesn't have its own eth_device structure yet, let's create one
  176.   .firstdevice:
  177. ; 4f. Check that we have place for new device.
  178.         cmp     [NUM_DEV], MAX_DEVICES
  179.         jge     .fail
  180. ; 4g. Allocate memory for device descriptor and receive+transmit buffers.
  181.         stdcall KernelAlloc, ALLOCATION_SIZE
  182.         test    eax, eax
  183.         jz      .fail
  184. ; 4h. Zero the structure.
  185.         push    eax
  186.         mov     edi, eax
  187.         mov     ecx, (device.size + 3) shr 2
  188.         xor     eax, eax
  189.         rep     stosd
  190.         pop     eax
  191. ; 4i. Save PCI coordinates, loaded to bx at 4c.
  192.         mov     word [eax+device.pci_bus], bx
  193.         mov     ebx, eax                                ; ebx is always used as a pointer to the structure (in driver, but also in kernel code)
  194. ; 4j. Fill in the direct call addresses into the struct.
  195. ; Note that get_MAC pointer is filled in initialization by SIS900_probe.
  196.         mov     dword [ebx+device.reset], sis900_init
  197.         mov     dword [ebx+device.transmit], transmit
  198. ;       mov     dword [ebx+device.get_MAC], read_mac
  199.         mov     dword [ebx+device.set_MAC], write_mac
  200.         mov     dword [ebx+device.unload], unload
  201.         mov     dword [ebx+device.name], my_service
  202.  
  203. ; 4k. Now, it's time to find the base io addres of the PCI device
  204. ; TODO: implement check if bus and dev exist on this machine
  205.  
  206.         mov     edx, PCI_BASE_ADDRESS_0
  207. .reg_check:
  208.         push    edx
  209.         stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], edx
  210.         pop     edx
  211.         test    al, PCI_BASE_ADDRESS_SPACE_IO
  212.         jz      .inc_reg
  213.         and     eax, PCI_BASE_ADDRESS_IO_MASK
  214.         jnz     .got_io
  215.  
  216.   .inc_reg:
  217.         add     edx, 4
  218.         cmp     edx, PCI_BASE_ADDRESS_5
  219.         jbe     .reg_check
  220.         jmp     .fail
  221.  
  222.   .got_io:
  223.         mov     [ebx+device.io_addr], eax
  224.  
  225. ; 4l. We've found the io address, find IRQ now
  226.         stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x3c
  227.         mov     byte [ebx+device.irq_line], al
  228.  
  229. ; 4m. Add new device to the list (required for int_handler).
  230.         mov     eax, [NUM_DEV]
  231.         mov     [DEV_LIST+4*eax], ebx
  232.         inc     [NUM_DEV]
  233.  
  234. ; 4m. Ok, the eth_device structure is ready, let's probe the device
  235.  
  236.         call    SIS900_probe
  237.         test    eax, eax
  238.         jnz     .destroy
  239. ; 4n. If device was successfully initialized, register it for the kernel.
  240.  
  241.         call    EthRegDev
  242.         cmp     eax, -1
  243.         je      .destroy
  244.  
  245.         ret     4
  246.  
  247. ; 5. If the device was already loaded, find the device number and return it in eax
  248.  
  249.   .find_devicenum:
  250.         mov     ebx, eax
  251.         call    EthStruc2Dev                                            ; This kernel procedure converts a pointer to device struct in ebx
  252.                                                                         ; into a device number in edi
  253.         mov     eax, edi                                                ; Application wants it in eax instead
  254.         ret     4
  255.  
  256. ; If an error occured, remove all allocated data and exit (returning -1 in eax)
  257.  
  258.   .destroy:
  259.         dec     [NUM_DEV]
  260.         ; todo: reset device into virgin state
  261.  
  262.   .err:
  263.         stdcall KernelFree, ebx
  264.  
  265.  
  266.   .fail:
  267.         xor     eax, eax
  268.         ret     4
  269.  
  270.  
  271. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  272. ;;                                                                        ;;
  273. ;;        Actual Hardware dependent code starts here                      ;;
  274. ;;                                                                        ;;
  275. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  276.  
  277. unload:
  278.         ; TODO: (in this particular order)
  279.         ;
  280.         ; - Stop the device
  281.         ; - Detach int handler
  282.         ; - Remove device from local list
  283.         ; - call unregister function in kernel
  284.         ; - Remove all allocated structures and buffers the card used
  285.  
  286.         or      eax,-1
  287.  
  288. ret
  289.  
  290. ;********************************************************************
  291. ;   Interface
  292. ;      SIS900_reset
  293. ;      SIS900_probe
  294. ;      SIS900_poll
  295. ;      SIS900_transmit
  296. ;
  297. ;********************************************************************
  298. ;********************************************************************
  299. ;  Comments:
  300. ;    Known to work with the following SIS900 ethernet cards:
  301. ;      -  Device ID: 0x0900   Vendor ID: 0x1039   Revision: 0x91
  302. ;      -  Device ID: 0x0900   Vendor ID: 0x1039   Revision: 0x90
  303. ;
  304. ;    If your card is not listed, try it and let me know if it
  305. ;    functions properly and it will be aded to the list.  If not
  306. ;    we may be able to add support for it.
  307. ;
  308. ;  ToDo:
  309. ;     -  Enable MII interface for reading speed
  310. ;        and duplex settings.
  311. ;
  312. ;     -  Update Poll routine to support packet fragmentation.
  313. ;
  314. ;     -  Add additional support for other sis900 based cards
  315. ;
  316. ;********************************************************************
  317.  
  318. ; comment the next line out if you don't want debug info printed
  319. ; on the debug board. This option adds a lot of bytes to the driver
  320. ; so it's worth to comment it out.
  321. ;        SIS900_DEBUG equ 1
  322.  
  323. SIS900_ETH_ALEN equ     6       ;* Size of Ethernet address *
  324. SIS900_ETH_HLEN equ     14      ;* Size of ethernet header *
  325. SIS900_ETH_ZLEN equ     60      ;* Minimum packet length *
  326. SIS900_DSIZE equ 0x00000fff
  327. SIS900_CRC_SIZE equ 4
  328. SIS900_RFADDR_shift equ 16
  329. ;SIS900 Symbolic offsets to registers.
  330.     SIS900_cr           equ     0x0               ; Command Register
  331.     SIS900_cfg          equ     0x4       ; Configuration Register
  332.     SIS900_mear     equ     0x8       ; EEPROM Access Register
  333.     SIS900_ptscr    equ     0xc       ; PCI Test Control Register
  334.     SIS900_isr          equ     0x10      ; Interrupt Status Register
  335.     SIS900_imr          equ     0x14      ; Interrupt Mask Register
  336.     SIS900_ier          equ     0x18      ; Interrupt Enable Register
  337.     SIS900_epar         equ     0x18      ; Enhanced PHY Access Register
  338.     SIS900_txdp     equ     0x20      ; Transmit Descriptor Pointer Register
  339.     SIS900_txcfg    equ     0x24      ; Transmit Configuration Register
  340.     SIS900_rxdp     equ     0x30      ; Receive Descriptor Pointer Register
  341.     SIS900_rxcfg    equ     0x34      ; Receive Configuration Register
  342.     SIS900_flctrl   equ     0x38      ; Flow Control Register
  343.     SIS900_rxlen    equ     0x3c      ; Receive Packet Length Register
  344.     SIS900_rfcr     equ     0x48      ; Receive Filter Control Register
  345.     SIS900_rfdr     equ     0x4C      ; Receive Filter Data Register
  346.     SIS900_pmctrl   equ     0xB0      ; Power Management Control Register
  347.     SIS900_pmer         equ     0xB4      ; Power Management Wake-up Event Register
  348. ;SIS900 Command Register Bits
  349.     SIS900_RELOAD       equ      0x00000400
  350.     SIS900_ACCESSMODE   equ      0x00000200
  351.     SIS900_RESET        equ      0x00000100
  352.     SIS900_SWI          equ      0x00000080
  353.     SIS900_RxRESET      equ      0x00000020
  354.     SIS900_TxRESET      equ      0x00000010
  355.     SIS900_RxDIS        equ      0x00000008
  356.     SIS900_RxENA        equ      0x00000004
  357.     SIS900_TxDIS        equ      0x00000002
  358.     SIS900_TxENA        equ      0x00000001
  359. ;SIS900 Configuration Register Bits
  360.     SIS900_DESCRFMT      equ    0x00000100 ; 7016 specific
  361.     SIS900_REQALG        equ    0x00000080
  362.     SIS900_SB            equ    0x00000040
  363.     SIS900_POW           equ    0x00000020
  364.     SIS900_EXD           equ    0x00000010
  365.     SIS900_PESEL         equ    0x00000008
  366.     SIS900_LPM           equ    0x00000004
  367.     SIS900_BEM           equ    0x00000001
  368.     SIS900_RND_CNT       equ    0x00000400
  369.     SIS900_FAIR_BACKOFF  equ    0x00000200
  370.     SIS900_EDB_MASTER_EN equ    0x00002000
  371. ;SIS900 Eeprom Access Reigster Bits
  372.     SIS900_MDC        equ      0x00000040
  373.     SIS900_MDDIR      equ      0x00000020
  374.     SIS900_MDIO       equ      0x00000010  ; 7016 specific
  375.     SIS900_EECS       equ      0x00000008
  376.     SIS900_EECLK      equ      0x00000004
  377.     SIS900_EEDO       equ      0x00000002
  378.     SIS900_EEDI       equ      0x00000001
  379. ;SIS900 TX Configuration Register Bits
  380.     SIS900_ATP        equ      0x10000000 ;Automatic Transmit Padding
  381.     SIS900_MLB        equ      0x20000000 ;Mac Loopback Enable
  382.     SIS900_HBI        equ      0x40000000 ;HeartBeat Ignore (Req for full-dup)
  383.     SIS900_CSI        equ      0x80000000 ;CarrierSenseIgnore (Req for full-du
  384. ;SIS900 RX Configuration Register Bits
  385.     SIS900_AJAB       equ      0x08000000 ;
  386.     SIS900_ATX        equ      0x10000000 ;Accept Transmit Packets
  387.     SIS900_ARP        equ      0x40000000 ;accept runt packets (<64bytes)
  388.     SIS900_AEP        equ      0x80000000 ;accept error packets
  389. ;SIS900 Interrupt Reigster Bits
  390.     SIS900_WKEVT           equ      0x10000000
  391.     SIS900_TxPAUSEEND      equ      0x08000000
  392.     SIS900_TxPAUSE         equ      0x04000000
  393.     SIS900_TxRCMP          equ      0x02000000
  394.     SIS900_RxRCMP          equ      0x01000000
  395.     SIS900_DPERR           equ      0x00800000
  396.     SIS900_SSERR           equ      0x00400000
  397.     SIS900_RMABT           equ      0x00200000
  398.     SIS900_RTABT           equ      0x00100000
  399.     SIS900_RxSOVR          equ      0x00010000
  400.     SIS900_HIBERR          equ      0x00008000
  401.     SIS900_SWINT           equ      0x00001000
  402.     SIS900_MIBINT          equ      0x00000800
  403.     SIS900_TxURN           equ      0x00000400
  404.     SIS900_TxIDLE          equ      0x00000200
  405.     SIS900_TxERR           equ      0x00000100
  406.     SIS900_TxDESC          equ      0x00000080
  407.     SIS900_TxOK            equ      0x00000040
  408.     SIS900_RxORN           equ      0x00000020
  409.     SIS900_RxIDLE          equ      0x00000010
  410.     SIS900_RxEARLY         equ      0x00000008
  411.     SIS900_RxERR           equ      0x00000004
  412.     SIS900_RxDESC          equ      0x00000002
  413.     SIS900_RxOK            equ      0x00000001
  414. ;SIS900 Interrupt Enable Reigster Bits
  415.     SIS900_IE      equ      0x00000001
  416. ;SIS900 Revision ID
  417.         SIS900B_900_REV       equ      0x03
  418.         SIS630A_900_REV       equ      0x80
  419.         SIS630E_900_REV       equ      0x81
  420.         SIS630S_900_REV       equ      0x82
  421.         SIS630EA1_900_REV     equ      0x83
  422.         SIS630ET_900_REV      equ      0x84
  423.         SIS635A_900_REV       equ      0x90
  424.         SIS900_960_REV        equ      0x91
  425. ;SIS900 Receive Filter Control Register Bits
  426.     SIS900_RFEN          equ 0x80000000
  427.     SIS900_RFAAB         equ 0x40000000
  428.     SIS900_RFAAM         equ 0x20000000
  429.     SIS900_RFAAP         equ 0x10000000
  430.     SIS900_RFPromiscuous equ 0x70000000
  431. ;SIS900 Reveive Filter Data Mask
  432.     SIS900_RFDAT equ  0x0000FFFF
  433. ;SIS900 Eeprom Address
  434.     SIS900_EEPROMSignature equ 0x00
  435.     SIS900_EEPROMVendorID  equ 0x02
  436.     SIS900_EEPROMDeviceID  equ 0x03
  437.     SIS900_EEPROMMACAddr   equ 0x08
  438.     SIS900_EEPROMChecksum  equ 0x0b
  439. ;The EEPROM commands include the alway-set leading bit.
  440. ;SIS900 Eeprom Command
  441.     SIS900_EEread          equ 0x0180
  442.     SIS900_EEwrite         equ 0x0140
  443.     SIS900_EEerase         equ 0x01C0
  444.     SIS900_EEwriteEnable   equ 0x0130
  445.     SIS900_EEwriteDisable  equ 0x0100
  446.     SIS900_EEeraseAll      equ 0x0120
  447.     SIS900_EEwriteAll      equ 0x0110
  448.     SIS900_EEaddrMask      equ 0x013F
  449.     SIS900_EEcmdShift      equ 16
  450. ;For SiS962 or SiS963, request the eeprom software access
  451.         SIS900_EEREQ    equ 0x00000400
  452.         SIS900_EEDONE   equ 0x00000200
  453.         SIS900_EEGNT    equ 0x00000100
  454.  
  455. SIS900_pci_revision equ ebx+device.pci_revision
  456. sis900_get_mac_func equ ebx+device.get_MAC
  457. sis900_special_func equ ebx+device.special_func
  458. sis900_table_entries equ ebx+device.table_entries
  459. cur_rx equ ebx+device.cur_rx
  460. sys_msg_board_str equ SysMsgBoardStr
  461. ;***************************************************************************
  462. ;   Function
  463. ;      SIS900_probe
  464. ;   Description
  465. ;      Searches for an ethernet card, enables it and clears the rx buffer
  466. ;      If a card was found, it enables the ethernet -> TCPIP link
  467. ;not done  - still need to probe mii transcievers
  468. ;***************************************************************************
  469. if defined SIS900_DEBUG
  470. SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0
  471. end if
  472. SIS900_probe:
  473. ;******Wake Up Chip*******
  474.    stdcall PciWrite8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x40, 0
  475. ;*******Set some PCI Settings*********
  476.    call    SIS900_adjust_pci_device
  477. ;*****Get Card Revision******
  478.    stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x08
  479.    mov [SIS900_pci_revision], al        ;save the revision for later use
  480. ;****** Look up through the sis900_specific_table
  481.    mov     esi,sis900_specific_table
  482. .probe_loop:
  483.    cmp     dword [esi],0                ; Check if we reached end of the list
  484.    je      .probe_loop_failed
  485.    cmp     al,[esi]                     ; Check if revision is OK
  486.    je      .probe_loop_ok
  487.    add     esi,12                       ; Advance to next entry
  488.    jmp     .probe_loop
  489. .probe_loop_failed:
  490.    jmp     SIS900_Probe_Unsupported
  491. ;*********Find Get Mac Function*********
  492. .probe_loop_ok:
  493.    mov      eax,[esi+4]         ; Get pointer to "get MAC" function
  494.    mov      [sis900_get_mac_func],eax
  495.    mov      eax,[esi+8]         ; Get pointer to special initialization fn
  496.    mov      [sis900_special_func],eax
  497. ;******** Get MAC ********
  498.    call     dword [sis900_get_mac_func]
  499. ;******** Call special initialization fn if requested ********
  500.    cmp      dword [sis900_special_func],0
  501.    je       .no_special_init
  502.    call     dword [sis900_special_func]
  503. .no_special_init:
  504. ;******** Set table entries ********
  505.    mov      al,[SIS900_pci_revision]
  506.    cmp      al,SIS635A_900_REV
  507.    jae      .ent16
  508.    cmp      al,SIS900B_900_REV
  509.    je       .ent16
  510.    mov      byte [sis900_table_entries],8
  511.    jmp      .ent8
  512. .ent16:
  513.    mov      byte [sis900_table_entries],16
  514. .ent8:
  515. ;*******Probe for mii transceiver*******
  516. ;TODO!!*********************
  517. ;*******Initialize Device*******
  518.    call sis900_init
  519.    ret
  520.  
  521. SIS900_Probe_Unsupported:
  522. if defined SIS900_DEBUG
  523.    mov     esi, SIS900_Debug_Str_Unsupported
  524.    call    sys_msg_board_str
  525. end if
  526.    or      eax, -1
  527.    ret
  528. ;***************************************************************************
  529. ; Function: sis900_init
  530. ;
  531. ; Description: resets the ethernet controller chip and various
  532. ;    data structures required for sending and receiving packets.
  533. ;
  534. ; Arguments:
  535. ;
  536. ; returns:   none
  537. ;not done
  538. ;***************************************************************************
  539. sis900_init:
  540.    call SIS900_reset               ;Done
  541.    call SIS900_init_rxfilter   ;Done
  542.    call SIS900_init_txd        ;Done
  543.    call SIS900_init_rxd            ;Done
  544.    call SIS900_set_rx_mode     ;done
  545.    call SIS900_set_tx_mode
  546.    ;call SIS900_check_mode
  547. ; enable interrupts on packet receive
  548.         xor     eax, eax
  549.         inc     eax     ; eax = 1 = SIS900_RxOK
  550.         mov     edx, [ebx+device.io_addr]
  551.         add     edx, SIS900_imr
  552.         out     dx, eax
  553. ; globally enable interrupts
  554.         add     edx, SIS900_ier-SIS900_imr
  555.         out     dx, eax ; eax is still 1
  556.         xor     eax, eax
  557.    ret
  558.  
  559. ;***************************************************************************
  560. ;   Function
  561. ;      SIS900_reset
  562. ;   Description
  563. ;      disables interrupts and soft resets the controller chip
  564. ;
  565. ;done+
  566. ;***************************************************************************
  567. if defined SIS900_DEBUG
  568.    SIS900_Debug_Reset_Failed db 'Reset Failed ',0
  569. end if
  570. SIS900_reset:
  571.         movzx   eax, [ebx+device.irq_line]
  572.         stdcall AttachIntHandler, eax, int_handler, 0
  573.    push     ebp
  574.    mov      ebp, [ebx+device.io_addr] ; base address
  575.    ;******Disable Interrupts and reset Receive Filter*******
  576.    xor      eax, eax            ; 0 to initialize
  577.    lea      edx,[ebp+SIS900_ier]
  578.    out      dx, eax                     ; Write 0 to location
  579.    lea      edx,[ebp+SIS900_imr]
  580.    out      dx, eax                     ; Write 0 to location
  581.    lea      edx,[ebp+SIS900_rfcr]
  582.    out      dx, eax                     ; Write 0 to location
  583.    ;*******Reset Card***********************************************
  584.    lea      edx,[ebp+SIS900_cr]
  585.    in       eax, dx                             ; Get current Command Register
  586.    or       eax, SIS900_RESET           ; set flags
  587.    or       eax, SIS900_RxRESET     ;
  588.    or           eax, SIS900_TxRESET         ;
  589.    out      dx, eax                             ; Write new Command Register
  590.    ;*******Wait Loop************************************************
  591.    push     ebx
  592.    lea      edx,[ebp+SIS900_isr]
  593.    mov      ecx, 0x03000000         ; Status we would like to see from card
  594.    mov      ebx, 2001               ; only loop 1000 times
  595. SIS900_Wait:
  596.    dec      ebx                                     ; 1 less loop
  597.    jz       SIS900_DoneWait_e           ; 1000 times yet?
  598.    in       eax, dx                                 ; move interrup status to eax
  599.    and      eax, ecx
  600.    xor      ecx, eax
  601.    jz       SIS900_DoneWait
  602.    jmp      SIS900_Wait
  603. SIS900_DoneWait_e:
  604. if defined SIS900_DEBUG
  605.    mov esi, SIS900_Debug_Reset_Failed
  606.    call sys_msg_board_str
  607. end if
  608. SIS900_DoneWait:
  609.    pop      ebx
  610.    ;*******Set Configuration Register depending on Card Revision********
  611.    lea      edx,[ebp+SIS900_cfg]
  612.    mov      eax, SIS900_PESEL               ; Configuration Register Bit
  613.    mov      cl, [SIS900_pci_revision]   ; card revision
  614.    cmp      cl, SIS635A_900_REV
  615.    je       SIS900_RevMatch
  616.    cmp      cl, SIS900B_900_REV         ; Check card revision
  617.    je       SIS900_RevMatch
  618.    out      dx, eax                                 ; no revision match
  619.    jmp      SIS900_Reset_Complete
  620. SIS900_RevMatch:                                        ; Revision match
  621.    or       eax, SIS900_RND_CNT         ; Configuration Register Bit
  622.    out      dx, eax
  623. SIS900_Reset_Complete:
  624.    xor      eax, eax
  625.    pop      ebp
  626.    ret
  627.  
  628. ;***************************************************************************
  629. ; Function: sis_init_rxfilter
  630. ;
  631. ; Description: sets receive filter address to our MAC address
  632. ;
  633. ; Arguments:
  634. ;
  635. ; returns:
  636. ;done+
  637. ;***************************************************************************
  638. SIS900_init_rxfilter:
  639.    push     ebp
  640.    mov      ebp, [ebx+device.io_addr]   ; base address
  641.    ;****Get Receive Filter Control Register ********
  642.    lea      edx,[ebp+SIS900_rfcr]
  643.    in       eax, dx                         ; get register
  644.    push     eax
  645.    ;****disable packet filtering before setting filter*******
  646.    mov      eax, SIS900_RFEN    ;move receive filter enable flag
  647.    not      eax                         ;1s complement
  648.    and      eax, [esp]                  ;disable receiver
  649.    out      dx, eax                     ;set receive disabled
  650.    ;********load MAC addr to filter data register*********
  651.    xor      ecx, ecx
  652. SIS900_RXINT_Mac_Write:
  653.    ;high word of eax tells card which mac byte to write
  654.    mov      eax, ecx
  655.    lea      edx,[ebp+SIS900_rfcr]
  656.    shl      eax, 16                                             ;
  657.    out      dx, eax                                             ;
  658.    lea      edx,[ebp+SIS900_rfdr]
  659.    mov      ax,  word [ebx+device.mac+ecx*2] ; Get Mac ID word
  660.    out      dx, ax                                              ; Send Mac ID
  661.    inc      cl                                                  ; send next word
  662.    cmp      cl, 3                                               ; more to send?
  663.    jne      SIS900_RXINT_Mac_Write
  664.    ;********enable packet filitering *****
  665.    pop      eax                             ;old register value
  666.    lea      edx,[ebp+SIS900_rfcr]
  667.    or       eax, SIS900_RFEN    ;enable filtering
  668.    out      dx, eax             ;set register
  669.    pop      ebp
  670.    ret
  671.  
  672. ;***************************************************************************
  673. ;*
  674. ;* Function: sis_init_txd
  675. ;*
  676. ;* Description: initializes the Tx descriptor
  677. ;*
  678. ;* Arguments:
  679. ;*
  680. ;* returns:
  681. ;*done
  682. ;***************************************************************************
  683. SIS900_init_txd:
  684.    ;********** initialize TX descriptor **************
  685.    mov     [ebx+device.txd], dword 0       ;put link to next descriptor in link field
  686.    mov     [ebx+device.txd+4],dword 0      ;clear status field
  687.    lea     eax, [ebx+0x1000]
  688.    call    GetPgAddr
  689.    mov     [ebx+device.txd+8], eax   ;save address to buffer ptr field
  690.    ;*************** load Transmit Descriptor Register ***************
  691.    mov     edx, [ebx+device.io_addr]        ; base address
  692.    add     edx, SIS900_txdp      ; TX Descriptor Pointer
  693.    add     eax, device.txd - 0x1000        ; First Descriptor
  694.    out     dx, eax                             ; move the pointer
  695.    ret
  696.  
  697. ;***************************************************************************
  698. ;* Function: sis_init_rxd
  699. ;*
  700. ;* Description: initializes the Rx descriptor ring
  701. ;*
  702. ;* Arguments:
  703. ;*
  704. ;* Returns:
  705. ;*done
  706. ;***************************************************************************
  707. SIS900_init_rxd:
  708.    xor      ecx,ecx
  709.    mov      [cur_rx], cl                                        ;Set cuurent rx discriptor to 0
  710.    mov      eax, ebx
  711.    call     GetPgAddr
  712.    mov      esi, eax
  713.    ;******** init RX descriptors ********
  714. SIS900_init_rxd_Loop:
  715.     mov     edx, ecx                                        ;current descriptor
  716.     imul    edx, 12                         ;
  717.     mov     eax, ecx                                        ;determine next link descriptor
  718.     inc     eax                             ;
  719.     cmp     eax, NUM_RX_DESC                ;
  720.     jne     SIS900_init_rxd_Loop_0          ;
  721.     xor     eax, eax                        ;
  722. SIS900_init_rxd_Loop_0:                    ;
  723.     imul    eax, 12                         ;
  724.     lea     eax, [eax+esi+device.rxd]
  725.     mov     [ebx+device.rxd+edx], eax                                      ;save link to next descriptor
  726.     mov     [ebx+device.rxd+edx+4],dword RX_BUFF_SZ        ;status bits init to buf size
  727.     mov     eax, ecx                                            ;find where the buf is located
  728.     imul    eax,RX_BUFF_SZ                  ;
  729.     lea     eax, [eax+esi+0x1000+NUM_TX_DESC*TX_BUFF_SZ]
  730.     mov     [ebx+device.rxd+edx+8], eax                            ;save buffer pointer
  731.     inc     ecx                                                     ;next descriptor
  732.     cmp     ecx, NUM_RX_DESC                ;
  733.     jne     SIS900_init_rxd_Loop            ;
  734.     ;********* load Receive Descriptor Register with address of first
  735.     ; descriptor*********
  736.     mov     edx, [ebx+device.io_addr]
  737.     add     edx, SIS900_rxdp
  738.     lea     eax, [esi+device.rxd]
  739.     out     dx, eax
  740.     ret
  741.  
  742. ;***************************************************************************
  743. ;* Function: sis900_set_tx_mode
  744. ;*
  745. ;* Description:
  746. ;*    sets the transmit mode to allow for full duplex
  747. ;*
  748. ;*
  749. ;* Arguments:
  750. ;*
  751. ;* Returns:
  752. ;*
  753. ;* Comments:
  754. ;*     If you are having problems transmitting packet try changing the
  755. ;*     Max DMA Burst, Possible settings are as follows:
  756. ;*         0x00000000 = 512 bytes
  757. ;*         0x00100000 = 4 bytes
  758. ;*         0x00200000 = 8 bytes
  759. ;*         0x00300000 = 16 bytes
  760. ;*         0x00400000 = 32 bytes
  761. ;*         0x00500000 = 64 bytes
  762. ;*         0x00600000 = 128 bytes
  763. ;*         0x00700000 = 256 bytes
  764. ;***************************************************************************
  765. SIS900_set_tx_mode:
  766.    push     ebp
  767.    mov      ebp,[ebx+device.io_addr]
  768.    lea      edx,[ebp+SIS900_cr]
  769.    in       eax, dx                         ; Get current Command Register
  770.    or       eax, SIS900_TxENA   ;Enable Receive
  771.    out      dx, eax
  772.    lea      edx,[ebp+SIS900_txcfg]; Transmit config Register offset
  773.    mov      eax, SIS900_ATP             ;allow automatic padding
  774.    or       eax, SIS900_HBI             ;allow heartbeat ignore
  775.    or       eax, SIS900_CSI             ;allow carrier sense ignore
  776.    or       eax, 0x00600000     ;Max DMA Burst
  777.    or       eax, 0x00000100     ;TX Fill Threshold
  778.    or       eax, 0x00000020     ;TX Drain Threshold
  779.    out      dx, eax
  780.    pop      ebp
  781.    ret
  782.  
  783. ;***************************************************************************
  784. ;* Function: sis900_set_rx_mode
  785. ;*
  786. ;* Description:
  787. ;*    sets the receive mode to accept all broadcast packets and packets
  788. ;*    with our MAC address, and reject all multicast packets.  Also allows
  789. ;*    full-duplex
  790. ;*
  791. ;* Arguments:
  792. ;*
  793. ;* Returns:
  794. ;*
  795. ;* Comments:
  796. ;*     If you are having problems receiving packet try changing the
  797. ;*     Max DMA Burst, Possible settings are as follows:
  798. ;*         0x00000000 = 512 bytes
  799. ;*         0x00100000 = 4 bytes
  800. ;*         0x00200000 = 8 bytes
  801. ;*         0x00300000 = 16 bytes
  802. ;*         0x00400000 = 32 bytes
  803. ;*         0x00500000 = 64 bytes
  804. ;*         0x00600000 = 128 bytes
  805. ;*         0x00700000 = 256 bytes
  806. ;***************************************************************************
  807. SIS900_set_rx_mode:
  808.    push     ebp
  809.    mov      ebp,[ebx+device.io_addr]
  810.     ;**************update Multicast Hash Table in Receive Filter
  811.    xor      cl, cl
  812. SIS900_set_rx_mode_Loop:
  813.    mov      eax, ecx
  814.    shl      eax, 1
  815.    lea      edx,[ebp+SIS900_rfcr]           ; Receive Filter Control Reg offset
  816.    mov      eax, 4                                          ;determine table entry
  817.    add      al, cl
  818.    shl      eax, 16
  819.    out      dx, eax                                         ;tell card which entry to modify
  820.    lea      edx,[ebp+SIS900_rfdr]           ; Receive Filter Control Reg offset
  821.    mov      eax, 0xffff                             ;entry value
  822.    out      dx, ax                                          ;write value to table in card
  823.    inc      cl                                              ;next entry
  824.    cmp      cl,[sis900_table_entries]   ;
  825.    jl       SIS900_set_rx_mode_Loop
  826.    ;*******Set Receive Filter Control Register*************
  827.    lea      edx,[ebp+SIS900_rfcr]       ; Receive Filter Control Register offset
  828.    mov      eax, SIS900_RFAAB           ;accecpt all broadcast packets
  829.    or       eax, SIS900_RFAAM           ;accept all multicast packets
  830.    or       eax, SIS900_RFAAP           ;Accept all packets
  831.    or       eax, SIS900_RFEN            ;enable receiver filter
  832.    out      dx, eax
  833.    ;******Enable Receiver************
  834.    lea      edx,[ebp+SIS900_cr] ; Command Register offset
  835.    in       eax, dx                         ; Get current Command Register
  836.    or       eax, SIS900_RxENA   ;Enable Receive
  837.    out      dx, eax
  838.    ;*********Set
  839.    lea      edx,[ebp+SIS900_rxcfg]      ; Receive Config Register offset
  840.    mov      eax, SIS900_ATX                     ;Accept Transmit Packets
  841.                                     ; (Req for full-duplex and PMD Loopback)
  842.    or       eax, 0x00600000                     ;Max DMA Burst
  843.    or       eax, 0x00000002                     ;RX Drain Threshold, 8X8 bytes or 64bytes
  844.    out      dx, eax                                     ;
  845.    pop      ebp
  846.    ret
  847.  
  848. ;***************************************************************************
  849. ; *     SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
  850. ; *     @pci_dev: the sis900 pci device
  851. ; *     @net_dev: the net device to get address for
  852. ; *
  853. ; *     SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
  854. ; *     is shared by
  855. ; *     LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
  856. ; *     and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
  857. ; *     by LAN, otherwise is not. After MAC address is read from EEPROM, send
  858. ; *     EEDONE signal to refuse EEPROM access by LAN.
  859. ; *     The EEPROM map of SiS962 or SiS963 is different to SiS900.
  860. ; *     The signature field in SiS962 or SiS963 spec is meaningless.
  861. ; *     MAC address is read into @net_dev->dev_addr.
  862. ; *done
  863. ;*
  864. ;* Return 0 is EAX = failure
  865. ;*Done+
  866. ;***************************************************************************
  867. if defined SIS900_DEBUG
  868. SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0
  869. SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0
  870. SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0
  871. SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0
  872. end if
  873. SIS960_get_mac_addr:
  874.    push     ebp
  875.    mov      ebp,[ebx+device.io_addr]
  876.    ;**********Send Request for eeprom access*********************
  877.    lea      edx,[ebp+SIS900_mear]               ; Eeprom access register
  878.    mov      eax, SIS900_EEREQ                   ; Request access to eeprom
  879.    out      dx, eax                                             ; Send request
  880.    xor      ecx,ecx                                             ;
  881.    ;******Loop 4000 times and if access not granted error out*****
  882. SIS96X_Get_Mac_Wait:
  883.    in       eax, dx                                     ;get eeprom status
  884.    and      eax, SIS900_EEGNT       ;see if eeprom access granted flag is set
  885.    jnz      SIS900_Got_EEP_Access       ;if it is, go access the eeprom
  886.    inc      ecx                                         ;else keep waiting
  887.    cmp      ecx, 4000                           ;have we tried 4000 times yet?
  888.    jl       SIS96X_Get_Mac_Wait     ;if not ask again
  889.    xor      eax, eax                ;return zero in eax indicating failure
  890.    ;*******Debug **********************
  891. if defined SIS900_DEBUG
  892.    mov esi,SIS900_Debug_Str_GetMac_Failed
  893.    call sys_msg_board_str
  894. end if
  895.    jmp SIS960_get_mac_addr_done
  896.    ;**********EEprom access granted, read MAC from card*************
  897. SIS900_Got_EEP_Access:
  898.     ; zero based so 3-16 bit reads will take place
  899.    mov      ecx, 2
  900. SIS96x_mac_read_loop:
  901.    mov      eax, SIS900_EEPROMMACAddr    ;Base Mac Address
  902.    add      eax, ecx                                 ;Current Mac Byte Offset
  903.    push     ecx
  904.    call     sis900_read_eeprom           ;try to read 16 bits
  905.    pop      ecx
  906.    mov      word [ebx+device.mac+ecx*2], ax        ;save 16 bits to the MAC ID varible
  907.    dec      ecx                          ;one less word to read
  908.    jns      SIS96x_mac_read_loop         ;if more read more
  909.    mov      eax, 1                       ;return non-zero indicating success
  910.    ;*******Debug Print MAC ID to debug window**********************
  911. if defined SIS900_DEBUG
  912.    mov esi,SIS900_Debug_Str_GetMac_Address2
  913.    call sys_msg_board_str
  914.    lea edx, [ebx+device.mac]
  915.    call Create_Mac_String
  916. end if
  917.    ;**********Tell EEPROM We are Done Accessing It*********************
  918. SIS960_get_mac_addr_done:
  919.    lea      edx,[ebp+SIS900_mear]               ; Eeprom access register
  920.    mov      eax, SIS900_EEDONE           ;tell eeprom we are done
  921.    out      dx,eax
  922.    pop      ebp
  923.    ret
  924. ;***************************************************************************
  925. ;*      sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
  926. ;*      @pci_dev: the sis900 pci device
  927. ;*      @net_dev: the net device to get address for
  928. ;*
  929. ;*      Older SiS900 and friends, use EEPROM to store MAC address.
  930. ;*      MAC address is read from read_eeprom() into @net_dev->dev_addr.
  931. ;* done/untested
  932. ;***************************************************************************
  933. SIS900_get_mac_addr:
  934.    ;*******Debug **********************
  935. if defined SIS900_DEBUG
  936.    mov esi,SIS900_Debug_Str_GetMac_Start
  937.    call sys_msg_board_str
  938. end if
  939.    ;******** check to see if we have sane EEPROM *******
  940.    mov      eax, SIS900_EEPROMSignature  ;Base Eeprom Signature
  941.    call     sis900_read_eeprom           ;try to read 16 bits
  942.    cmp ax, 0xffff
  943.    je SIS900_Bad_Eeprom
  944.    cmp ax, 0
  945.    je SIS900_Bad_Eeprom
  946.    ;**************Read MacID**************
  947.    ; zero based so 3-16 bit reads will take place
  948.    mov      ecx, 2
  949. SIS900_mac_read_loop:
  950.    mov      eax, SIS900_EEPROMMACAddr    ;Base Mac Address
  951.    add      eax, ecx                                 ;Current Mac Byte Offset
  952.    push     ecx
  953.    call     sis900_read_eeprom           ;try to read 16 bits
  954.    pop      ecx
  955.    mov      word [ebx+device.mac+ecx*2], ax        ;save 16 bits to the MAC ID storage
  956.    dec      ecx                          ;one less word to read
  957.    jns      SIS900_mac_read_loop         ;if more read more
  958.    mov      eax, 1                       ;return non-zero indicating success
  959.    ;*******Debug Print MAC ID to debug window**********************
  960. if defined SIS900_DEBUG
  961.    mov esi,SIS900_Debug_Str_GetMac_Address
  962.    call sys_msg_board_str
  963.    lea edx, [ebx+device.mac]
  964.    call Create_Mac_String
  965. end if
  966.    ret
  967.  
  968. SIS900_Bad_Eeprom:
  969.    xor eax, eax
  970.    ;*******Debug **********************
  971. if defined SIS900_DEBUG
  972.    mov esi,SIS900_Debug_Str_GetMac_Failed
  973.    call sys_msg_board_str
  974. end if
  975.    ret
  976. ;***************************************************************************
  977. ;*      Get_Mac_SIS635_900_REV: - Get MAC address for model 635
  978. ;*
  979. ;*
  980. ;***************************************************************************
  981. Get_Mac_SIS635_900_REV:
  982. if defined SIS900_DEBUG
  983.     mov     esi,SIS900_Debug_Str_GetMac_Start
  984.     call    sys_msg_board_str
  985. end if
  986.     push    ebp
  987.     mov     ebp,[ebx+device.io_addr]
  988.     lea     edx,[ebp+SIS900_rfcr]
  989.     in      eax,dx
  990.     mov     edi,eax ; EDI=rfcrSave
  991.     lea     edx,[ebp+SIS900_cr]
  992.     or      eax,SIS900_RELOAD
  993.     out     dx,eax
  994.     xor     eax,eax
  995.     out     dx,eax
  996.     ; Disable packet filtering before setting filter
  997.     lea     edx,[ebp+SIS900_rfcr]
  998.     mov     eax,edi
  999.     and     edi,not SIS900_RFEN
  1000.     out     dx,eax
  1001.     ; Load MAC to filter data register
  1002.     xor     ecx,ecx
  1003.     lea     esi,[ebx+device.mac]
  1004. .get_mac_loop:
  1005.     lea     edx,[ebp+SIS900_rfcr]
  1006.     mov     eax,ecx
  1007.     shl     eax,SIS900_RFADDR_shift
  1008.     out     dx,eax
  1009.     lea     edx,[ebp+SIS900_rfdr]
  1010.     in      eax,dx
  1011.     mov     [esi],ax
  1012.     add     esi,2
  1013.     inc     ecx
  1014.     cmp     ecx,3
  1015.     jne .get_mac_loop
  1016.     ; Enable packet filtering
  1017.     ;lea     edx,[ebp+SIS900_rfcr]
  1018.     ;mov     eax,edi
  1019.     ;or      eax,SIS900_RFEN
  1020.     ;out     dx, eax
  1021.    ;*******Debug Print MAC ID to debug window**********************
  1022. if defined SIS900_DEBUG
  1023.     mov     esi,SIS900_Debug_Str_GetMac_Address
  1024.     call    sys_msg_board_str
  1025.     lea     edx, [ebx+device.mac]
  1026.     call    Create_Mac_String
  1027. end if
  1028.     pop     ebp
  1029.     ret
  1030. ;***************************************************************************
  1031. ;* Function: sis900_read_eeprom
  1032. ;*
  1033. ;* Description: reads and returns a given location from EEPROM
  1034. ;*
  1035. ;* Arguments: eax - location:       requested EEPROM location
  1036. ;*
  1037. ;* Returns:   eax :                contents of requested EEPROM location
  1038. ;*
  1039. ; Read Serial EEPROM through EEPROM Access Register, Note that location is
  1040. ;   in word (16 bits) unit */
  1041. ;done+
  1042. ;***************************************************************************
  1043. sis900_read_eeprom:
  1044.    push      esi
  1045.    push      edx
  1046.    push      ecx
  1047.    push      ebx
  1048.    push      ebp
  1049.    mov       ebp,[ebx+device.io_addr]
  1050.    mov       ebx, eax              ;location of Mac byte to read
  1051.    or        ebx, SIS900_EEread    ;
  1052.    lea       edx,[ebp+SIS900_mear] ; Eeprom access register
  1053.    xor       eax, eax              ; start send
  1054.    out       dx,eax
  1055.    call      SIS900_Eeprom_Delay_1
  1056.    mov       eax, SIS900_EECLK
  1057.    out       dx, eax
  1058.    call      SIS900_Eeprom_Delay_1
  1059.     ;************ Shift the read command (9) bits out. *********
  1060.    mov       cl, 8                                      ;
  1061. sis900_read_eeprom_Send:
  1062.    mov       eax, 1
  1063.    shl       eax, cl
  1064.    and       eax, ebx
  1065.    jz SIS900_Read_Eeprom_8
  1066.    mov       eax, 9
  1067.    jmp       SIS900_Read_Eeprom_9
  1068. SIS900_Read_Eeprom_8:
  1069.    mov       eax, 8
  1070. SIS900_Read_Eeprom_9:
  1071.    out       dx, eax
  1072.    call      SIS900_Eeprom_Delay_1
  1073.    or        eax, SIS900_EECLK
  1074.    out       dx, eax
  1075.    call      SIS900_Eeprom_Delay_1
  1076.    cmp       cl, 0
  1077.    je        sis900_read_eeprom_Send_Done
  1078.    dec       cl
  1079.    jmp       sis900_read_eeprom_Send
  1080.    ;*********************
  1081. sis900_read_eeprom_Send_Done:
  1082.    mov       eax, SIS900_EECS           ;
  1083.    out       dx, eax
  1084.    call      SIS900_Eeprom_Delay_1
  1085.     ;********** Read 16-bits of data in ***************
  1086.     mov      cx, 16                             ;16 bits to read
  1087. sis900_read_eeprom_Send2:
  1088.     mov      eax, SIS900_EECS
  1089.     out      dx, eax
  1090.     call     SIS900_Eeprom_Delay_1
  1091.     or       eax, SIS900_EECLK
  1092.     out      dx, eax
  1093.     call     SIS900_Eeprom_Delay_1
  1094.     in       eax, dx
  1095.     shl      ebx, 1
  1096.     and      eax, SIS900_EEDO
  1097.     jz       SIS900_Read_Eeprom_0
  1098.     or       ebx, 1
  1099. SIS900_Read_Eeprom_0:
  1100.    dec       cx
  1101.    jnz       sis900_read_eeprom_Send2
  1102.    ;************** Terminate the EEPROM access. **************
  1103.    xor       eax, eax
  1104.    out       dx, eax
  1105.    call      SIS900_Eeprom_Delay_1
  1106.    mov       eax, SIS900_EECLK
  1107.    out       dx, eax
  1108.    mov       eax, ebx
  1109.    and       eax, 0x0000ffff                    ;return only 16 bits
  1110.    pop       ebp
  1111.    pop       ebx
  1112.    pop       ecx
  1113.    pop       edx
  1114.    pop       esi
  1115.    ret
  1116. ;***************************************************************************
  1117. ;   Function
  1118. ;      SIS900_Eeprom_Delay_1
  1119. ;   Description
  1120. ;
  1121. ;
  1122. ;
  1123. ;
  1124. ;***************************************************************************
  1125. SIS900_Eeprom_Delay_1:
  1126.    push eax
  1127.    in eax, dx
  1128.    pop eax
  1129.    ret
  1130.  
  1131. write_mac:
  1132.         DEBUGF 1,'Setting MAC is not supported for SIS900 card.\n'
  1133.         add     esp, 6
  1134.         ret
  1135.  
  1136. ;***************************************************************************
  1137. ;   Function
  1138. ;      int_handler
  1139. ;   Description
  1140. ;      handles received IRQs, which signal received packets
  1141. ;
  1142. ;  Currently only supports one descriptor per packet, if packet is fragmented
  1143. ;  between multiple descriptors you will lose part of the packet
  1144. ;***************************************************************************
  1145. if defined SIS900_DEBUG
  1146. SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0
  1147. SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0
  1148. SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0
  1149. end if
  1150. int_handler:
  1151. ; find pointer of device which made IRQ occur
  1152.         mov     esi, DEV_LIST
  1153.         mov     ecx, [NUM_DEV]
  1154.         test    ecx, ecx
  1155.         jz      .nothing
  1156. .nextdevice:
  1157.         mov     ebx, [esi]
  1158.         mov     edx, [ebx+device.io_addr]
  1159.         add     edx, SIS900_isr
  1160.         in      eax, dx ; note that this clears all interrupts
  1161.         test    al, SIS900_RxOK
  1162.         jnz     .got_it
  1163.         loop    .nextdevice
  1164. .nothing:
  1165.         ret
  1166. .got_it:
  1167.     ;**************Get Status **************
  1168.     movzx     eax, [ebx+device.cur_rx]          ;find current discriptor
  1169.     imul      eax, 12               ;
  1170.     mov       ecx, [ebx+device.rxd+eax+4]          ; get receive status
  1171.     ;**************Check Status **************
  1172.     ;Check RX_Status to see if packet is waiting
  1173.     test      ecx, 0x80000000
  1174.     jnz       SIS900_poll_IS_packet
  1175.     ret
  1176.    ;**********There is a packet waiting check it for errors**************
  1177. SIS900_poll_IS_packet:
  1178.     test      ecx, 0x67C0000            ;see if there are any errors
  1179.     jnz       SIS900_Poll_Error_Status
  1180.    ;**************Check size of packet*************
  1181.    and       ecx, SIS900_DSIZE                                  ;get packet size minus CRC
  1182.    cmp       ecx, SIS900_CRC_SIZE
  1183.    ;make sure packet contains data
  1184.    jle       SIS900_Poll_Error_Size
  1185.    ;*******Copy Good Packet to receive buffer******
  1186.    sub      ecx, SIS900_CRC_SIZE                             ;dont want crc
  1187.    ; update statistics
  1188.    inc      dword [ebx+device.packets_rx]
  1189.    add      dword [ebx+device.bytes_rx], ecx
  1190.    adc      dword [ebx+device.bytes_rx+4], 0
  1191.    push     ecx
  1192.    stdcall  KernelAlloc, ecx
  1193.    pop      ecx
  1194.    test     eax, eax
  1195.    jz       int_handler.nothing
  1196.    push     ebx
  1197.    push     .return ; return address for EthReceiver
  1198.    ;**********Continue copying packet****************
  1199.    push     ecx eax ; save buffer pointer and size for EthReceiver
  1200.    mov      edi, eax
  1201.    movzx    esi, byte [ebx+device.cur_rx]
  1202.    imul     esi, RX_BUFF_SZ
  1203.    lea      esi, [esi+ebx+0x1000+NUM_TX_DESC*TX_BUFF_SZ]
  1204.    ; first copy dword-wise, divide size by 4
  1205.    shr      ecx, 2
  1206.    rep      movsd                                                       ; copy the dwords
  1207.    mov      ecx, [esp+4]
  1208.    and      ecx, 3                                                  ;
  1209.    rep      movsb
  1210.    ;********Debug, tell user we have a good packet*************
  1211. if defined SIS900_DEBUG
  1212.    mov      esi, SIS900_Debug_Pull_Packet_good
  1213.    call     sys_msg_board_str
  1214. end if
  1215.    jmp      EthReceiver
  1216. .return:
  1217.    pop      ebx
  1218.    jmp      SIS900_Poll_Cnt
  1219.    ;*************Error occured let user know through debug window***********
  1220. SIS900_Poll_Error_Status:
  1221. if defined SIS900_DEBUG
  1222.                 mov      esi, SIS900_Debug_Pull_Bad_Packet_Status
  1223.                 call     sys_msg_board_str
  1224. end if
  1225.                 jmp      SIS900_Poll_Cnt
  1226. SIS900_Poll_Error_Size:
  1227. if defined SIS900_DEBUG
  1228.                 mov      esi, SIS900_Debug_Pull_Bad_Packet_Size
  1229.                 call     sys_msg_board_str
  1230. end if
  1231.    ;*************Increment to next available descriptor**************
  1232. SIS900_Poll_Cnt:
  1233.     ;Reset status, allow ethernet card access to descriptor
  1234.    movzx    eax, [ebx+device.cur_rx]
  1235.    lea      eax, [eax*3]
  1236.    mov      ecx, RX_BUFF_SZ
  1237.    mov      [ebx+device.rxd+eax*4+4], ecx                ;
  1238.    inc      [ebx+device.cur_rx]                          ;get next descriptor
  1239.    and      [ebx+device.cur_rx],NUM_RX_DESC-1            ;only 4 descriptors 0-3
  1240.    ;******Enable Receiver************
  1241.    mov      edx, [ebx+device.io_addr]
  1242.    add      edx, SIS900_cr ; Command Register offset
  1243.    in       eax, dx                         ; Get current Command Register
  1244.    or       eax, SIS900_RxENA   ;Enable Receive
  1245.    out      dx, eax
  1246.    ret
  1247. ;***************************************************************************
  1248. ;   Function
  1249. ;      transmit
  1250. ;   Description
  1251. ;      Transmits a packet of data via the ethernet card
  1252. ;         buffer pointer in [esp+4]
  1253. ;         size of buffer in [esp+8]
  1254. ;         pointer to device structure in ebx
  1255. ;
  1256. ;      only one transmit descriptor is used
  1257. ;
  1258. ;***************************************************************************
  1259. if defined SIS900_DEBUG
  1260. SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0
  1261. SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0
  1262. end if
  1263. str1 db 'Transmitting packet:',13,10,0
  1264. str2 db ' ',0
  1265. transmit:
  1266.    cmp      dword [esp+8], MAX_ETH_FRAME_SIZE
  1267.    jg       transmit_finish
  1268.    cmp      dword [esp+8], 60
  1269.    jl       transmit_finish
  1270.    push     ebp
  1271.    mov      ebp, [ebx+device.io_addr] ; Base Address
  1272.    ;******** Stop the transmitter ********
  1273.    lea      edx,[ebp+SIS900_cr] ; Command Register offset
  1274.    in       eax, dx                         ; Get current Command Register
  1275.    or       eax, SIS900_TxDIS   ; Disable Transmitter
  1276.    out      dx, eax
  1277.    ;*******load Transmit Descriptor Register *******
  1278.    lea      edx,[ebp+SIS900_txdp]
  1279.    mov      eax, ebx
  1280.    call     GetPgAddr
  1281.    add      eax, device.txd
  1282.    out      dx, eax
  1283.    ;******* copy packet to descriptor*******
  1284.    mov     esi, [esp+8]
  1285.    lea     edi, [ebx+0x1000]
  1286.    mov     ecx, [esp+12]
  1287.    mov     edx, ecx
  1288.    shr     ecx, 2
  1289.    and     edx, 3
  1290.    rep     movsd
  1291.    mov     ecx, edx
  1292.    rep     movsb
  1293.    ;**************set length tag**************
  1294.    mov     ecx, [esp+12]                  ;restore packet size
  1295.    and     ecx, SIS900_DSIZE     ;
  1296.    inc      [ebx+device.packets_tx]
  1297.    add      dword [ebx+device.bytes_tx], ecx
  1298.    adc      dword [ebx+device.bytes_tx+4], 0
  1299.    ;**************pad to minimum packet size **************not needed
  1300.    ;cmp       ecx, SIS900_ETH_ZLEN
  1301.    ;jge       SIS900_transmit_Size_Ok
  1302.    ;push      ecx
  1303.    ;mov       ebx, SIS900_ETH_ZLEN
  1304.    ;sub       ebx, ecx
  1305.    ;mov       ecx, ebx
  1306.    ;rep       movsb
  1307.    ;pop       ecx
  1308. SIS900_transmit_Size_Ok:
  1309.    or       ecx, 0x80000000                             ;card owns descriptor
  1310.    mov      [ebx+device.txd+4], ecx
  1311. if defined SIS900_DEBUG
  1312.    mov      esi, SIS900_Debug_Transmit_Packet
  1313.    call     sys_msg_board_str
  1314. end if
  1315.    ;***************restart the transmitter ********
  1316.    lea      edx,[ebp+SIS900_cr]
  1317.    in       eax, dx                         ; Get current Command Register
  1318.    or       eax, SIS900_TxENA   ; Enable Transmitter
  1319.    out      dx, eax
  1320.    ;****make sure packet transmitted successfully****
  1321. ;   mov      esi,10
  1322. ;   call     delay_ms
  1323.    mov      eax, [ebx+device.txd+4]
  1324.    and      eax, 0x6200000
  1325.    jz       SIS900_transmit_OK
  1326.    ;**************Tell user there was an error through debug window
  1327. if defined SIS900_DEBUG
  1328.    mov      esi, SIS900_Debug_Transmit_Packet_Err
  1329.    call     sys_msg_board_str
  1330. end if
  1331. SIS900_transmit_OK:
  1332.    pop      ebp
  1333. transmit_finish:
  1334.    ret
  1335.  
  1336. ;***************************************************************************
  1337. ;* Function: Create_Mac_String
  1338. ;*
  1339. ;* Description: Converts the 48 bit value to a string for display
  1340. ;*
  1341. ;* String Format: XX:XX:XX:XX:XX:XX
  1342. ;*
  1343. ;* Arguments: node_addr is location of 48 bit MAC ID
  1344. ;*
  1345. ;* Returns:   Prints string to general debug window
  1346. ;*
  1347. ;*
  1348. ;done
  1349. ;***************************************************************************
  1350. if defined SIS900_DEBUG
  1351.  
  1352. SIS900_Char_String    db '0','1','2','3','4','5','6','7','8','9'
  1353.                       db 'A','B','C','D','E','F'
  1354. Mac_str_build: times 20 db 0
  1355. Create_Mac_String:
  1356.    pusha
  1357.    xor ecx, ecx
  1358. Create_Mac_String_loop:
  1359.    mov al,byte [edx+ecx];[node_addr+ecx]
  1360.    push eax
  1361.    shr eax, 4
  1362.    and eax, 0x0f
  1363.    mov bl, byte [SIS900_Char_String+eax]
  1364.    mov [Mac_str_build+ecx*3], bl
  1365.    pop eax
  1366.    and eax, 0x0f
  1367.    mov bl, byte [SIS900_Char_String+eax]
  1368.    mov [Mac_str_build+1+ecx*3], bl
  1369.    cmp ecx, 5
  1370.    je Create_Mac_String_done
  1371.    mov bl, ':'
  1372.    mov [Mac_str_build+2+ecx*3], bl
  1373.    inc ecx
  1374.    jmp Create_Mac_String_loop
  1375. Create_Mac_String_done:                                 ;Insert CR and Zero Terminate
  1376.    mov [Mac_str_build+2+ecx*3],byte 13
  1377.    mov [Mac_str_build+3+ecx*3],byte 10
  1378.    mov [Mac_str_build+4+ecx*3],byte 0
  1379.    mov esi, Mac_str_build
  1380.    call sys_msg_board_str                               ;Print String to message board
  1381.    popa
  1382.    ret
  1383. end if
  1384. ;***************************************************************************
  1385. ;*      Set device to be a busmaster in case BIOS neglected to do so.
  1386. ;*      Also adjust PCI latency timer to a reasonable value, 64.
  1387. ;***************************************************************************
  1388. SIS900_adjust_pci_device:
  1389.    ;*******Get current setting************************
  1390.    stdcall PciRead16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x04
  1391.    ;******see if its already set as bus master********
  1392.    mov      cx, ax
  1393.    and      cx,5
  1394.    cmp      cx,5
  1395.    je       SIS900_adjust_pci_device_Latency
  1396.    ;******Make card a bus master*******
  1397.    mov      cx, ax                              ;value to write
  1398.    or       cx,5
  1399.    stdcall PciWrite16, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x04, ecx
  1400.    ;******Check latency setting***********
  1401. SIS900_adjust_pci_device_Latency:
  1402.    ;*******Get current latency setting************************
  1403.    stdcall PciRead8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x0D
  1404.    ;******see if its aat least 64 clocks********
  1405.    cmp      al,64
  1406.    jge      SIS900_adjust_pci_device_Done
  1407.    ;******Set latency to 32 clocks*******
  1408.    stdcall PciWrite8, dword [ebx+device.pci_bus], dword [ebx+device.pci_dev], 0x0D, 64
  1409.    ;******Check latency setting***********
  1410. SIS900_adjust_pci_device_Done:
  1411.    ret
  1412.  
  1413. ; End of code
  1414.  
  1415. align 4                                         ; Place all initialised data here
  1416.  
  1417. NUM_DEV   dd 0
  1418.  
  1419. sis900_specific_table:
  1420. ;    dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0
  1421. ;    dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0
  1422.     dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0
  1423.     dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0
  1424.     dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN
  1425.     dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0
  1426.     dd SIS900_960_REV,SIS960_get_mac_addr,0
  1427.     dd SIS900B_900_REV,SIS900_get_mac_addr,0
  1428.     dd 0,0,0,0 ; end of list
  1429.  
  1430. version       dd (5 shl 16) or (API_VERSION and 0xFFFF)
  1431. my_service    db 'SIS900',0                     ; max 16 chars include zero
  1432.  
  1433. include_debug_strings                           ; All data wich FDO uses will be included here
  1434.  
  1435. section '.data' data readable writable align 16 ; place all uninitialized data place here
  1436.  
  1437. DEV_LIST rd MAX_DEVICES                 ; This list contains all pointers to device structures the driver is handling
  1438.  
  1439.