Subversion Repositories Kolibri OS

Rev

Rev 5006 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                    ;;
  3. ;; Copyright (C) KolibriOS team 2004-2014. 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. format PE DLL native
  27. entry START
  28.  
  29.         CURRENT_API             = 0x0200
  30.         COMPATIBLE_API          = 0x0100
  31.         API_VERSION             = (COMPATIBLE_API shl 16) + CURRENT_API
  32.  
  33.         NUM_RX_DESC             = 4             ; Number of RX descriptors
  34.         NUM_TX_DESC             = 4             ; Number of TX descriptors
  35.         RX_BUFF_SZ              = 1520          ; Buffer size for each Rx buffer
  36.  
  37.         MAX_DEVICES             = 16
  38.  
  39.         __DEBUG__               = 1
  40.         __DEBUG_LEVEL__         = 2             ; 1 = verbose, 2 = errors only
  41.  
  42.         DSIZE                   = 0x00000fff
  43.         CRC_SIZE                = 4
  44.         RFADDR_shift            = 16
  45.  
  46. ; If you are having problems sending/receiving packet try changing the
  47. ; Max DMA Burst, Possible settings are as follows:
  48. ;
  49. ; 0x00000000 = 512 bytes
  50. ; 0x00100000 = 4 bytes
  51. ; 0x00200000 = 8 bytes
  52. ; 0x00300000 = 16 bytes
  53. ; 0x00400000 = 32 bytes
  54. ; 0x00500000 = 64 bytes
  55. ; 0x00600000 = 128 bytes
  56. ; 0x00700000 = 256 bytes
  57.  
  58.         RX_DMA                  = 0x00600000
  59.         TX_DMA                  = 0x00600000
  60.  
  61. ;-------------------------------------------------------------------------------------------------
  62. ; Symbolic offsets to registers.
  63.         cr              = 0x0           ; Command Register
  64.         cfg             = 0x4           ; Configuration Register
  65.         mear            = 0x8           ; EEPROM Access Register
  66.         ptscr           = 0xc           ; PCI Test Control Register
  67.         isr             = 0x10          ; Interrupt Status Register
  68.         imr             = 0x14          ; Interrupt Mask Register
  69.         ier             = 0x18          ; Interrupt Enable Register
  70.         epar            = 0x18          ; Enhanced PHY Access Register
  71.         txdp            = 0x20          ; Transmit Descriptor Pointer Register
  72.         txcfg           = 0x24          ; Transmit Configuration Register
  73.         rxdp            = 0x30          ; Receive Descriptor Pointer Register
  74.         rxcfg           = 0x34          ; Receive Configuration Register
  75.         flctrl          = 0x38          ; Flow Control Register
  76.         rxlen           = 0x3c          ; Receive Packet Length Register
  77.         rfcr            = 0x48          ; Receive Filter Control Register
  78.         rfdr            = 0x4C          ; Receive Filter Data Register
  79.         pmctrl          = 0xB0          ; Power Management Control Register
  80.         pmer            = 0xB4          ; Power Management Wake-up Event Register
  81.  
  82. ; Command Register Bits
  83.         RELOAD          = 0x00000400
  84.         ACCESSMODE      = 0x00000200
  85.         RESET           = 0x00000100
  86.         SWI             = 0x00000080
  87.         RxRESET         = 0x00000020
  88.         TxRESET         = 0x00000010
  89.         RxDIS           = 0x00000008
  90.         RxENA           = 0x00000004
  91.         TxDIS           = 0x00000002
  92.         TxENA           = 0x00000001
  93.  
  94. ; Configuration Register Bits
  95.         DESCRFMT        = 0x00000100    ; 7016 specific
  96.         REQALG          = 0x00000080
  97.         SB              = 0x00000040
  98.         POW             = 0x00000020
  99.         EXD             = 0x00000010
  100.         PESEL           = 0x00000008
  101.         LPM             = 0x00000004
  102.         BEM             = 0x00000001
  103.         RND_CNT         = 0x00000400
  104.         FAIR_BACKOFF    = 0x00000200
  105.         EDB_MASTER_EN   = 0x00002000
  106.  
  107. ; Eeprom Access Reigster Bits
  108.         MDC             = 0x00000040
  109.         MDDIR           = 0x00000020
  110.         MDIO            = 0x00000010    ; 7016 specific
  111.         EECS            = 0x00000008
  112.         EECLK           = 0x00000004
  113.         EEDO            = 0x00000002
  114.         EEDI            = 0x00000001
  115.  
  116. ; TX Configuration Register Bits
  117.         ATP             = 0x10000000    ; Automatic Transmit Padding
  118.         MLB             = 0x20000000    ; Mac Loopback Enable
  119.         HBI             = 0x40000000    ; HeartBeat Ignore (Req for full-dup)
  120.         CSI             = 0x80000000    ; CarrierSenseIgnore (Req for full-du
  121.  
  122. ; RX Configuration Register Bits
  123.         AJAB            = 0x08000000    ;
  124.         ATX             = 0x10000000    ; Accept Transmit Packets
  125.         ARP             = 0x40000000    ; accept runt packets (<64bytes)
  126.         AEP             = 0x80000000    ; accept error packets
  127.  
  128. ; Interrupt Register Bits
  129.         WKEVT           = 0x10000000
  130.         TxPAUSEEND      = 0x08000000
  131.         TxPAUSE         = 0x04000000
  132.         TxRCMP          = 0x02000000    ; Transmit Reset Complete
  133.         RxRCMP          = 0x01000000    ; Receive Reset Complete
  134.         DPERR           = 0x00800000
  135.         SSERR           = 0x00400000
  136.         RMABT           = 0x00200000
  137.         RTABT           = 0x00100000
  138.         RxSOVR          = 0x00010000
  139.         HIBERR          = 0x00008000
  140.         SWINT           = 0x00001000
  141.         MIBINT          = 0x00000800
  142.         TxURN           = 0x00000400
  143.         TxIDLE          = 0x00000200
  144.         TxERR           = 0x00000100
  145.         TxDESC          = 0x00000080
  146.         TxOK            = 0x00000040
  147.         RxORN           = 0x00000020
  148.         RxIDLE          = 0x00000010
  149.         RxEARLY         = 0x00000008
  150.         RxERR           = 0x00000004
  151.         RxDESC          = 0x00000002
  152.         RxOK            = 0x00000001
  153.  
  154. ; Interrupt Enable Register Bits
  155.         IE              = RxOK + TxOK
  156.  
  157. ; Revision ID
  158.         SIS900B_900_REV         = 0x03
  159.         SIS630A_900_REV         = 0x80
  160.         SIS630E_900_REV         = 0x81
  161.         SIS630S_900_REV         = 0x82
  162.         SIS630EA1_900_REV       = 0x83
  163.         SIS630ET_900_REV        = 0x84
  164.         SIS635A_900_REV         = 0x90
  165.         SIS900_960_REV          = 0x91
  166.  
  167. ; Receive Filter Control Register Bits
  168.         RFEN            = 0x80000000            ; enable
  169.         RFAAB           = 0x40000000            ; accept all broadcasts
  170.         RFAAM           = 0x20000000            ; accept all multicasts
  171.         RFAAP           = 0x10000000            ; accept all packets
  172.  
  173. ; Reveive Filter Data Mask
  174.         RFDAT           = 0x0000FFFF
  175.  
  176. ; Eeprom Address
  177.         EEPROMSignature = 0x00
  178.         EEPROMVendorID  = 0x02
  179.         EEPROMDeviceID  = 0x03
  180.         EEPROMMACAddr   = 0x08
  181.         EEPROMChecksum  = 0x0b
  182.  
  183. ; The EEPROM commands include the alway-set leading bit.
  184.         EEread          = 0x0180
  185.         EEwrite         = 0x0140
  186.         EEerase         = 0x01C0
  187.         EEwriteEnable   = 0x0130
  188.         EEwriteDisable  = 0x0100
  189.         EEeraseAll      = 0x0120
  190.         EEwriteAll      = 0x0110
  191.         EEaddrMask      = 0x013F
  192.         EEcmdShift      = 16
  193.  
  194. ; For SiS962 or SiS963, request the eeprom software access
  195.         EEREQ           = 0x00000400
  196.         EEDONE          = 0x00000200
  197.         EEGNT           = 0x00000100
  198.  
  199. section '.flat' readable writable executable
  200.  
  201. include '../proc32.inc'
  202. include '../struct.inc'
  203. include '../macros.inc'
  204. include '../fdo.inc'
  205. include '../netdrv.inc'
  206.  
  207.  
  208. struct  device          ETH_DEVICE
  209.  
  210.         io_addr         dd ?
  211.         pci_bus         dd ?
  212.         pci_dev         dd ?
  213.         irq_line        db ?
  214.         cur_rx          db ?
  215.         cur_tx          db ?
  216.         last_tx         db ?
  217.         pci_revision    db ?
  218.         table_entries   db ?
  219.  
  220.         rb 0x100 - ($ and 0xff) ; align 256
  221.         txd             rd (4 * NUM_TX_DESC)
  222.         rxd             rd (4 * NUM_RX_DESC)
  223.  
  224. ends
  225.  
  226. macro   ee_delay {
  227.         push    eax
  228.         in      eax, dx
  229.         in      eax, dx
  230.         in      eax, dx
  231.         in      eax, dx
  232.         in      eax, dx
  233.         in      eax, dx
  234.         in      eax, dx
  235.         in      eax, dx
  236.         in      eax, dx
  237.         in      eax, dx
  238.         pop     eax
  239. }
  240.  
  241. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  242. ;;                        ;;
  243. ;; proc START             ;;
  244. ;;                        ;;
  245. ;; (standard driver proc) ;;
  246. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  247.  
  248. ; Driver entry point - register our service when the driver is loading.
  249. ; TODO: add needed operations when unloading
  250.  
  251. proc START c, reason:dword, cmdline:dword
  252.  
  253.         cmp     [reason], DRV_ENTRY
  254.         jne     .fail
  255.  
  256.         DEBUGF  2,"Loading driver\n"
  257.         invoke  RegService, my_service, service_proc
  258.         ret
  259.  
  260.   .fail:
  261.         xor     eax, eax
  262.         ret
  263.  
  264. endp
  265.  
  266.  
  267. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  268. ;;                        ;;
  269. ;; proc SERVICE_PROC      ;;
  270. ;;                        ;;
  271. ;; (standard driver proc) ;;
  272. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  273.  
  274. ; Service procedure for the driver - handle all I/O requests for the driver.
  275. ; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1.
  276. service_proc:
  277. ; 1. Get parameter from the stack: [esp+4] is the first parameter,
  278. ;       pointer to IOCTL structure.
  279.         mov     edx, [esp+4]    ; edx -> IOCTL
  280. ; 2. Get request code and select a handler for the code.
  281.         mov     eax, [edx + IOCTL.io_code]
  282.         test    eax, eax        ; check for SRV_GETVERSION
  283.         jnz     @f
  284. ; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION.
  285. ; 3a. Output size must be at least 4 bytes.
  286.         cmp     [edx + IOCTL.out_size], 4
  287.         jb      .fail
  288. ; 3b. Write result to the output buffer.
  289.         mov     eax, [edx + IOCTL.output]
  290.         mov     [eax], dword API_VERSION
  291. ; 3c. Return success.
  292.         xor     eax, eax
  293.         ret     4
  294.   @@:
  295.         dec     eax     ; check for SRV_HOOK
  296.         jnz     .fail
  297. ; 4. This is SRV_HOOK request, input defines the device to hook, no output.
  298. ; 4a. The driver works only with PCI devices,
  299. ;       so input must be at least 3 bytes long.
  300.         cmp     [edx + IOCTL.inp_size], 3
  301.         jb      .fail
  302. ; 4b. First byte of input is bus type, 1 stands for PCI.
  303.         mov     eax, [edx + IOCTL.input]
  304.         cmp     byte [eax], 1
  305.         jne     .fail
  306. ; 4c. Second and third bytes of the input define the device: bus and dev.
  307. ;       Word in bx holds both bytes.
  308.         mov     bx, [eax+1]
  309. ; 4d. Check if the device was already hooked,
  310. ;       scan through the list of known devices.
  311. ; check if the device is already listed
  312.         mov     esi, device_list
  313.         mov     ecx, [devices]
  314.         test    ecx, ecx
  315.         jz      .firstdevice
  316.  
  317. ;        mov     eax, [edx + IOCTL.input]                ; get the pci bus and device numbers
  318.         mov     ax, [eax+1]                             ;
  319.   .nextdevice:
  320.         mov     ebx, [esi]
  321.         cmp     al, byte[ebx + device.pci_bus]
  322.         jne     @f
  323.         cmp     ah, byte[ebx + device.pci_dev]
  324.         je      .find_devicenum                         ; Device is already loaded, let's find it's device number
  325.        @@:
  326.         add     esi, 4
  327.         loop    .nextdevice
  328. ; 4e. This device doesn't have its own eth_device structure yet, let's create one
  329.   .firstdevice:
  330. ; 4f. Check that we have place for new device.
  331.         cmp     [devices], MAX_DEVICES
  332.         jae     .fail
  333. ; 4g. Allocate memory for device descriptor and receive+transmit buffers.
  334. ; 4h. Zero the structure.
  335.         allocate_and_clear ebx, sizeof.device, .fail
  336. ; 4i. Save PCI coordinates
  337.         mov     eax, [edx + IOCTL.input]
  338.         movzx   ecx, byte[eax+1]
  339.         mov     [ebx + device.pci_bus], ecx
  340.         movzx   ecx, byte[eax+2]
  341.         mov     [ebx + device.pci_dev], ecx
  342. ; 4j. Fill in the direct call addresses into the struct.
  343.         mov     [ebx + device.reset], reset
  344.         mov     [ebx + device.transmit], transmit
  345.         mov     [ebx + device.unload], unload
  346.         mov     [ebx + device.name], my_service
  347.  
  348. ; 4k. Now, it's time to find the base io addres of the PCI device
  349. ; TODO: implement check if bus and dev exist on this machine
  350.  
  351. ; Now, it's time to find the base io addres of the PCI device
  352.         stdcall PCI_find_io, [ebx + device.pci_bus], [ebx + device.pci_dev]
  353.         mov     [ebx + device.io_addr], eax
  354.  
  355. ; We've found the io address, find IRQ now
  356.  
  357.         invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.interrupt_line
  358.         mov     [ebx + device.irq_line], al
  359.  
  360. ; 4m. Add new device to the list (required for int_handler).
  361.         mov     eax, [devices]
  362.         mov     [device_list+4*eax], ebx
  363.         inc     [devices]
  364.  
  365. ; 4m. Ok, the eth_device structure is ready, let's probe the device
  366.         call    probe
  367.         test    eax, eax
  368.         jnz     .destroy
  369. ; 4n. If device was successfully initialized, register it for the kernel.
  370.  
  371.         mov     [ebx + device.type], NET_TYPE_ETH
  372.         invoke  NetRegDev
  373.  
  374.         cmp     eax, -1
  375.         je      .destroy
  376.  
  377.         ret     4
  378.  
  379. ; 5. If the device was already loaded, find the device number and return it in eax
  380.  
  381.   .find_devicenum:
  382.         invoke  NetPtrToNum                             ; This kernel procedure converts a pointer to device struct in ebx
  383.                                                         ; into a device number in edi
  384.         mov     eax, edi                                ; Application wants it in eax instead
  385.         ret     4
  386.  
  387. ; If an error occured, remove all allocated data and exit (returning -1 in eax)
  388.  
  389.   .destroy:
  390.         dec     [devices]
  391.         ; todo: reset device into virgin state
  392.  
  393.   .err:
  394.         invoke  KernelFree, ebx
  395.  
  396.   .fail:
  397.         xor     eax, eax
  398.         ret     4
  399.  
  400.  
  401. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  402. ;;                                                                        ;;
  403. ;;        Actual Hardware dependent code starts here                      ;;
  404. ;;                                                                        ;;
  405. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  406.  
  407. unload:
  408.         ; TODO: (in this particular order)
  409.         ;
  410.         ; - Stop the device
  411.         ; - Detach int handler
  412.         ; - Remove device from local list
  413.         ; - call unregister function in kernel
  414.         ; - Remove all allocated structures and buffers the card used
  415.  
  416.         or      eax, -1
  417.  
  418. ret
  419.  
  420. ;***************************************************************************
  421. ;
  422. ; probe
  423. ;
  424. ; checks the card and enables it
  425. ;
  426. ; TODO: probe mii transceivers
  427. ;
  428. ;***************************************************************************
  429. align 4
  430. probe:
  431.         DEBUGF  1, "Probe\n"
  432.  
  433. ; wake up device
  434. ; TODO: check capabilities pointer instead of using hardcoded offset.
  435.         invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x40, 0
  436.  
  437. ; Make the device a bus master
  438.         invoke  PciRead32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command
  439.         or      al, PCI_CMD_MASTER
  440.         invoke  PciWrite32, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.command, eax
  441.  
  442. ; Adjust PCI latency to be at least 64
  443.         invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency
  444.         cmp     al, 64
  445.         jae     @f
  446.         mov     al, 64
  447.         invoke  PciWrite8, [ebx + device.pci_bus], [ebx + device.pci_dev], PCI_header00.max_latency, eax
  448.   @@:
  449.  
  450. ; Get Card Revision
  451.         invoke  PciRead8, [ebx + device.pci_bus], [ebx + device.pci_dev], 0x08
  452.         mov     [ebx + device.pci_revision], al         ; save the revision for later use
  453.  
  454. ; Look up through the specific_table
  455.         mov     esi, specific_table
  456.   .tableloop:
  457.         cmp     dword[esi], 0                           ; Check if we reached end of the list
  458.         je      .notsupported
  459.         cmp     al, [esi]                               ; Check if revision is OK
  460.         je      .ok
  461.         add     esi, 12                                 ; Advance to next entry
  462.         jmp     .tableloop
  463.   .ok:
  464.         call     dword[esi + 4]                         ; "get MAC" function
  465.  
  466. ; Set table entries
  467.         mov      [ebx + device.table_entries], 16
  468.         cmp      [ebx + device.pci_revision], SIS635A_900_REV
  469.         jae      @f
  470.         cmp      [ebx + device.pci_revision], SIS900B_900_REV
  471.         je       @f
  472.         mov      [ebx + device.table_entries], 8
  473.        @@:
  474.  
  475. ; TODO: Probe for mii transceiver
  476.         jmp     reset
  477.  
  478.   .notsupported:
  479.         DEBUGF  2, "Device not supported\n"
  480.         or      eax, -1
  481.  
  482.         ret
  483.  
  484. reset:
  485.  
  486.         DEBUGF  1, "reset\n"
  487.  
  488.         movzx   eax, [ebx + device.irq_line]
  489.         invoke  AttachIntHandler, eax, int_handler, ebx
  490.         test    eax, eax
  491.         jnz     @f
  492.         DEBUGF  2,"Could not attach int handler!\n"
  493.         or      eax, -1
  494.         ret
  495.        @@:  
  496.  
  497. ;--------------------------------------------
  498. ; Disable Interrupts and reset Receive Filter
  499.  
  500.         set_io  [ebx + device.io_addr], 0
  501.         set_io  [ebx + device.io_addr], ier
  502.         xor     eax, eax
  503.         out     dx, eax
  504.  
  505.         set_io  [ebx + device.io_addr], imr
  506.         out     dx, eax
  507.  
  508.         set_io  [ebx + device.io_addr], rfcr
  509.         out     dx, eax
  510.  
  511. ;-----------
  512. ; Reset Card
  513.  
  514.         set_io  [ebx + device.io_addr], cr
  515.         in      eax, dx                                 ; Get current Command Register
  516.         or      eax, RESET + RxRESET + TxRESET          ; set flags
  517.         out     dx, eax                                 ; Write new Command Register
  518.  
  519. ;----------
  520. ; Wait loop
  521.  
  522.         set_io  [ebx + device.io_addr], isr
  523.         mov     ecx, 1000
  524.   .loop:
  525.         dec     ecx
  526.         jz      .fail
  527.         in      eax, dx                                 ; read interrupt status
  528.         test    eax, TxRCMP + RxRCMP
  529.         jz      .loop
  530.         DEBUGF  1, "status=%x\n", eax
  531.  
  532. ;------------------------------------------------------
  533. ; Set Configuration Register depending on Card Revision
  534.  
  535.         set_io  [ebx + device.io_addr], cfg
  536.         mov     eax, PESEL                              ; Configuration Register Bit
  537.         cmp     [ebx + device.pci_revision], SIS635A_900_REV
  538.         je      .match
  539.         cmp     [ebx + device.pci_revision], SIS900B_900_REV ; Check card revision
  540.         jne     .done
  541.   .match:                                               ; Revision match
  542.         or      eax, RND_CNT                            ; Configuration Register Bit
  543.   .done:
  544.         out     dx, eax
  545.  
  546.         DEBUGF  1, "Initialising RX Filter\n"
  547.  
  548. ; Get Receive Filter Control Register
  549.         set_io  [ebx + device.io_addr], rfcr
  550.         in      eax, dx
  551.         push    eax
  552.  
  553. ; disable packet filtering before setting filter
  554.         and     eax, not RFEN
  555.         out     dx, eax
  556.  
  557. ; load MAC addr to filter data register
  558.         xor     ecx, ecx
  559.   .macloop:
  560.         mov     eax, ecx
  561.         set_io  [ebx + device.io_addr], 0
  562.         set_io  [ebx + device.io_addr], rfcr
  563.         shl     eax, 16                                 ; high word of eax tells card which mac byte to write
  564.         out     dx, eax                                 ;
  565.         set_io  [ebx + device.io_addr], rfdr
  566.         mov     ax, word [ebx + device.mac + ecx*2]     ; Get Mac ID word
  567.         out     dx, ax                                  ; Send Mac ID
  568.         inc     cl                                      ; send next word
  569.         cmp     cl, 3                                   ; more to send?
  570.         jne     .macloop
  571.  
  572. ; enable packet filtering
  573.         pop     eax                                     ; old register value
  574.         set_io  [ebx + device.io_addr], rfcr
  575.         or      eax, RFEN                               ; enable filtering
  576.         out     dx, eax                                 ; set register
  577.  
  578.         DEBUGF  1, "Initialising TX Descriptors\n"
  579.  
  580.         mov     ecx, NUM_TX_DESC
  581.         lea     esi, [ebx + device.txd]
  582.   .txdescloop:
  583.         lea     eax, [esi + 16]                         ; next ptr
  584.         invoke  GetPhysAddr
  585.         mov     dword[esi], eax                         ; link to next desc
  586.         mov     dword[esi + 4], 0                       ; status field
  587.         mov     dword[esi + 8], 0                       ; ptr to buffer
  588.         add     esi, 16
  589.         dec     ecx
  590.         jnz     .txdescloop
  591.  
  592.         lea     eax, [ebx + device.txd]
  593.         invoke  GetPhysAddr
  594.         mov     dword[esi - 16], eax                    ; correct last descriptor link ptr
  595.  
  596.         set_io  [ebx + device.io_addr], txdp            ; TX Descriptor Pointer
  597. ;        lea     eax, [ebx + device.txd]
  598. ;        invoke  GetPhysAddr
  599.         out     dx, eax
  600.  
  601.         mov     [ebx + device.cur_tx], 0                ; Set current tx descriptor to 0
  602.         mov     [ebx + device.last_tx], 0
  603.  
  604.         DEBUGF  1, "Initialising RX Descriptors\n"
  605.  
  606.         mov     ecx, NUM_RX_DESC
  607.         lea     esi, [ebx + device.rxd]
  608.   .rxdescloop:
  609.         lea     eax, [esi + 16]                         ; next ptr
  610.         invoke  GetPhysAddr
  611.         mov     dword [esi], eax
  612.         mov     dword [esi + 4], RX_BUFF_SZ             ; size
  613.  
  614.         push    ecx esi
  615.         invoke  KernelAlloc, RX_BUFF_SZ
  616.         pop     esi ecx
  617.         test    eax, eax
  618.         jz      .fail
  619.         mov     dword [esi + 12], eax                   ; address
  620.         invoke  GetPhysAddr
  621.         mov     dword [esi + 8], eax                    ; real address
  622.         add     esi, 16
  623.         dec     ecx
  624.         jnz     .rxdescloop
  625.  
  626.         lea     eax, [ebx + device.rxd]
  627.         invoke  GetPhysAddr
  628.         mov     dword [esi - 16], eax                   ; correct last descriptor link ptr
  629.  
  630.         set_io  [ebx + device.io_addr], 0
  631.         set_io  [ebx + device.io_addr], rxdp
  632. ;        lea     eax, [ebx + device.rxd]
  633. ;        invoke  GetPhysAddr
  634.         out     dx, eax
  635.  
  636.         mov     [ebx + device.cur_rx], 0                ; Set current rx descriptor to 0
  637.  
  638.         DEBUGF  1, "setting RX mode\n"
  639.  
  640.         xor     cl, cl
  641.   .rxfilterloop:
  642.         set_io  [ebx + device.io_addr], 0
  643.         set_io  [ebx + device.io_addr], rfcr            ; Receive Filter Control Reg offset
  644.         mov     eax, 4                                  ; determine table entry
  645.         add     al, cl
  646.         shl     eax, 16
  647.         out     dx, eax                                 ; tell card which entry to modify
  648.  
  649.         set_io  [ebx + device.io_addr], rfdr            ; Receive Filter Control Reg offset
  650.         mov     eax, 0xffff                             ; entry value
  651.         out     dx, ax                                  ; write value to table in card
  652.  
  653.         inc     cl                                      ; next entry
  654.         cmp     cl, [ebx + device.table_entries]
  655.         jb      .rxfilterloop
  656.  
  657.         set_io  [ebx + device.io_addr], rfcr            ; Receive Filter Control Register offset
  658.         mov     eax, RFAAB + RFAAM + RFAAP + RFEN
  659.         out     dx, eax
  660.  
  661.         set_io  [ebx + device.io_addr], rxcfg           ; Receive Config Register offset
  662.         mov     eax, ATX + RX_DMA + 2                   ; 0x2 : RX Drain Threshold = 8*8=64 bytes
  663.         out     dx, eax
  664.  
  665.         DEBUGF  1, "setting TX mode\n"
  666.  
  667.         set_io  [ebx + device.io_addr], txcfg           ; Transmit config Register offset
  668.         mov     eax, ATP + HBI + CSI + TX_DMA + 0x120   ; TX Fill threshold = 0x100
  669.                                                         ; TX Drain Threshold = 0x20
  670.         out     dx, eax
  671.  
  672.         DEBUGF  1, "Enabling interrupts\n"
  673.  
  674.         set_io  [ebx + device.io_addr], imr
  675.         mov     eax, IE                                 ; Interrupt enable mask
  676.         out     dx, eax
  677.  
  678.         set_io  [ebx + device.io_addr], cr
  679.         in      eax, dx
  680.         or      eax, RxENA                              ; Enable Receive
  681.         out     dx, eax
  682.  
  683.         set_io  [ebx + device.io_addr], ier             ; Interrupt enable
  684.         mov     eax, 1
  685.         out     dx, eax
  686.  
  687.         mov     [ebx + device.mtu], 1514
  688.  
  689. ; Set link state to unknown
  690.         mov     [ebx + device.state], ETH_LINK_UNKNOWN
  691.  
  692.         xor     eax, eax
  693.         ret
  694.  
  695.   .fail:
  696.         DEBUGF  2, "Resetting device failed\n"
  697.         or      eax, -1
  698.  
  699.         ret
  700.  
  701.  
  702. ;***************************************************************************
  703. ;
  704. ; SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
  705. ;
  706. ; SiS962 or SiS963 model, use EEPROM to store MAC address.
  707. ; EEPROM is shared by LAN and 1394.
  708. ; When access EEPROM, send EEREQ signal to hardware first, and wait for EEGNT.
  709. ; If EEGNT is ON, EEPROM is permitted to be accessed by LAN, otherwise is not.
  710. ; After MAC address is read from EEPROM, send
  711. ; EEDONE signal to refuse EEPROM access by LAN.
  712. ; The EEPROM map of SiS962 or SiS963 is different to SiS900.
  713. ; The signature field in SiS962 or SiS963 spec is meaningless.
  714. ;
  715. ; Return 0 is EAX = failure
  716. ;
  717. ;***************************************************************************
  718. align 4
  719. SIS960_get_mac_addr:
  720.         DEBUGF  1, "SIS960 - get mac:\n"
  721.  
  722. ;-------------------------------
  723. ; Send Request for eeprom access
  724.  
  725.         set_io  [ebx + device.io_addr], 0
  726.         set_io  [ebx + device.io_addr], mear            ; Eeprom access register
  727.         mov     eax, EEREQ                              ; Request access to eeprom
  728.         out     dx, eax                                 ; Send request
  729.  
  730. ;-----------------------------------------------------
  731. ; Loop 4000 times and if access not granted, error out
  732.  
  733.         mov     ecx, 4000
  734.   .loop:
  735.         in      eax, dx                                 ; get eeprom status
  736.         test    eax, EEGNT                              ; see if eeprom access granted flag is set
  737.         jnz     .got_access                             ; if it is, go access the eeprom
  738.         loop    .loop                                   ; else keep waiting
  739.  
  740.         DEBUGF  2, "Access to EEprom failed!\n", 0
  741.  
  742.         set_io  [ebx + device.io_addr], mear            ; Eeprom access register
  743.         mov     eax, EEDONE                             ; tell eeprom we are done
  744.         out     dx, eax
  745.  
  746.         or      eax, -1                                 ; error
  747.         ret
  748.  
  749.   .got_access:
  750.  
  751. ;------------------------------------------
  752. ; EEprom access granted, read MAC from card
  753.  
  754.     ; zero based so 3-16 bit reads will take place
  755.  
  756.         mov     ecx, 2
  757.   .read_loop:
  758.         mov     eax, EEPROMMACAddr                      ; Base Mac Address
  759.         add     eax, ecx                                ; Current Mac Byte Offset
  760.         push    ecx
  761.         call    read_eeprom                             ; try to read 16 bits
  762.         pop     ecx
  763.         mov     word [ebx + device.mac+ecx*2], ax       ; save 16 bits to the MAC ID varible
  764.         dec     ecx                                     ; one less word to read
  765.         jns     .read_loop                              ; if more read more
  766.         mov     eax, 1                                  ; return non-zero indicating success
  767.  
  768.         DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
  769.         [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
  770.  
  771. ;-------------------------------------
  772. ; Tell EEPROM We are Done Accessing It
  773.  
  774.   .done:
  775.         set_io  [ebx + device.io_addr], 0
  776.         set_io  [ebx + device.io_addr], mear            ; Eeprom access register
  777.         mov     eax, EEDONE                             ; tell eeprom we are done
  778.         out     dx, eax
  779.  
  780.         xor     eax, eax                                ; ok
  781.         ret
  782.  
  783.  
  784.  
  785.  
  786. ;***************************************************************************
  787. ;
  788. ; get_mac_addr: - Get MAC address for stand alone SiS900 model
  789. ;
  790. ; Older SiS900 and friends, use EEPROM to store MAC address.
  791. ;
  792. ;***************************************************************************
  793. align 4
  794. SIS900_get_mac_addr:
  795.         DEBUGF  1, "SIS900 - get mac:\n"
  796.  
  797. ;------------------------------------
  798. ; check to see if we have sane EEPROM
  799.  
  800.         mov     eax, EEPROMSignature                    ; Base Eeprom Signature
  801.         call    read_eeprom                             ; try to read 16 bits
  802.         cmp     ax, 0xffff
  803.         je      .err
  804.         test    ax, ax
  805.         je      .err
  806.  
  807. ;-----------
  808. ; Read MacID
  809.  
  810. ; zero based so 3-16 bit reads will take place
  811.  
  812.         mov     ecx, 2
  813.   .loop:
  814.         mov     eax, EEPROMMACAddr                      ; Base Mac Address
  815.         add     eax, ecx                                ; Current Mac Byte Offset
  816.         push    ecx
  817.         call    read_eeprom                             ; try to read 16 bits
  818.         pop     ecx
  819.         mov     word [ebx + device.mac+ecx*2], ax       ; save 16 bits to the MAC ID storage
  820.         dec     ecx                                     ; one less word to read
  821.         jns     .loop                                   ; if more read more
  822.  
  823.         DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
  824.         [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
  825.  
  826.         xor     eax, eax
  827.         ret
  828.  
  829.  
  830.   .err:
  831.         DEBUGF  1, "Access to EEprom failed!\n", 0
  832.  
  833.         or      eax, -1
  834.         ret
  835.  
  836.  
  837. ;***************************************************************************
  838. ;
  839. ; Get_Mac_SIS635_900_REV: - Get MAC address for model 635
  840. ;
  841. ;***************************************************************************
  842. align 4
  843. Get_Mac_SIS635_900_REV:
  844.         DEBUGF  1, "SIS635 - get mac:\n"
  845.  
  846.         set_io  [ebx + device.io_addr], 0
  847.         set_io  [ebx + device.io_addr], rfcr
  848.         in      eax, dx
  849.         mov     esi, eax
  850.  
  851.         set_io  [ebx + device.io_addr], cr
  852.         or      eax, RELOAD
  853.         out     dx, eax
  854.  
  855.         xor     eax, eax
  856.         out     dx, eax
  857.  
  858. ;-----------------------------------------------
  859. ; Disable packet filtering before setting filter
  860.  
  861.         set_io  [ebx + device.io_addr], rfcr
  862.         mov     eax, esi
  863.         and     eax, not RFEN
  864.         out     dx, eax
  865.  
  866. ;---------------------------------
  867. ; Load MAC to filter data register
  868.  
  869.         xor     ecx, ecx
  870.         lea     edi, [ebx + device.mac]
  871.   .loop:
  872.         set_io  [ebx + device.io_addr], 0
  873.         set_io  [ebx + device.io_addr], rfcr
  874.         mov     eax, ecx
  875.         shl     eax, RFADDR_shift
  876.         out     dx, eax
  877.  
  878.         set_io  [ebx + device.io_addr], rfdr
  879.         in      ax, dx
  880.         stosw
  881.         inc     ecx
  882.         cmp     ecx, 3
  883.         jb      .loop
  884.  
  885. ;------------------------
  886. ; Enable packet filtering
  887.  
  888.         set_io  [ebx + device.io_addr], rfcr
  889.         mov     eax, esi
  890.         or      eax, RFEN
  891.         out     dx, eax
  892.  
  893.         DEBUGF  1,"%x-%x-%x-%x-%x-%x\n",\
  894.         [ebx + device.mac]:2,[ebx + device.mac+1]:2,[ebx + device.mac+2]:2,[ebx + device.mac+3]:2,[ebx + device.mac+4]:2,[ebx + device.mac+5]:2
  895.  
  896.         xor     eax, eax
  897.         ret
  898.  
  899. ;***************************************************************************
  900. ;
  901. ; read_eeprom
  902. ;
  903. ; reads and returns a given location from EEPROM
  904. ;
  905. ; IN:  si = addr
  906. ; OUT: ax = data
  907. ;
  908. ;***************************************************************************
  909. align 4
  910. read_eeprom:
  911.  
  912.         set_io  [ebx + device.io_addr], 0
  913.         set_io  [ebx + device.io_addr], mear
  914.  
  915.         xor     eax, eax                                ; start send
  916.         out     dx, eax
  917.         ee_delay
  918.  
  919.         or      eax, EECLK
  920.         out     dx, eax
  921.         ee_delay
  922.  
  923. ;------------------------------------
  924. ; Send the read command
  925.  
  926.         or      esi, EEread
  927.         mov     ecx, 1 shl 9
  928.  
  929.   .loop:
  930.         mov     eax, EECS
  931.         test    esi, ecx
  932.         jz      @f
  933.         or      eax, EEDI
  934.        @@:
  935.         out     dx, eax
  936.         ee_delay
  937.  
  938.         or      eax, EECLK
  939.         out     dx, eax
  940.         ee_delay
  941.  
  942.         shr     esi, 1
  943.         jnc     .loop
  944.  
  945.         mov     eax, EECS
  946.         out     dx, eax
  947.         ee_delay
  948.  
  949. ;------------------------
  950. ; Read 16-bits of data in
  951.  
  952.         xor     esi, esi
  953.         mov     cx, 16
  954.   .loop2:
  955.         mov     eax, EECS
  956.         out     dx, eax
  957.         ee_delay
  958.  
  959.         or      eax, EECLK
  960.         out     dx, eax
  961.         ee_delay
  962.  
  963.         in      eax, dx
  964.         shl     esi, 1
  965.         test    eax, EEDO
  966.         jz      @f
  967.         inc     esi
  968.        @@:
  969.         loop    .loop2
  970.  
  971. ;----------------------------
  972. ; Terminate the EEPROM access
  973.  
  974.         xor     eax, eax
  975.         out     dx, eax
  976.         ee_delay
  977.  
  978.         mov     eax, EECLK
  979.         out     dx, eax
  980.         ee_delay
  981.  
  982.         movzx   eax, si
  983.  
  984.         ret
  985.  
  986.  
  987.  
  988. align 4
  989. write_mac:
  990.         DEBUGF  2,'Setting MAC is not supported for SIS900 card.\n'
  991.         add     esp, 6
  992.         ret
  993.  
  994.  
  995.  
  996.  
  997. ;***************************************************************************
  998. ;   Function
  999. ;      transmit
  1000. ;   Description
  1001. ;      Transmits a packet of data via the ethernet card
  1002. ;         buffer pointer in [esp+4]
  1003. ;         size of buffer in [esp+8]
  1004. ;         pointer to device structure in ebx
  1005. ;
  1006. ;***************************************************************************
  1007. align 4
  1008.  
  1009. proc transmit stdcall bufferptr, buffersize
  1010.  
  1011.         pushf
  1012.         cli
  1013.  
  1014.         DEBUGF  1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize]
  1015.         mov     eax, [bufferptr]
  1016.         DEBUGF  1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\
  1017.         [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\
  1018.         [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\
  1019.         [eax+13]:2,[eax+12]:2
  1020.  
  1021.         cmp     [buffersize], 1514
  1022.         ja      .fail
  1023.         cmp     [buffersize], 60
  1024.         jb      .fail
  1025.  
  1026.         movzx   ecx, [ebx + device.cur_tx]
  1027.         shl     ecx, 4                                  ; *16
  1028.         lea     ecx, [ebx + device.txd + ecx]
  1029.  
  1030.         test    dword[ecx + 4], 0x80000000              ; card owns descriptor ?
  1031.         jnz     .fail
  1032.  
  1033.         mov     eax, [bufferptr]
  1034.         mov     dword[ecx + 12], eax
  1035.         invoke  GetPhysAddr
  1036.         mov     dword[ecx + 8], eax                     ; buffer address
  1037.  
  1038.         mov     eax, [buffersize]
  1039.         and     eax, DSIZE
  1040.         or      eax, 0x80000000                         ; card owns descriptor
  1041.         mov     dword[ecx + 4], eax                     ; status field
  1042.  
  1043.         set_io  [ebx + device.io_addr], 0
  1044.         set_io  [ebx + device.io_addr], cr
  1045.         in      eax, dx
  1046.         or      eax, TxENA                              ; Enable the transmit state machine
  1047.         out     dx, eax
  1048.  
  1049.         inc     [ebx + device.cur_tx]
  1050.         and     [ebx + device.cur_tx], NUM_TX_DESC-1
  1051.  
  1052. ; update stats
  1053.         mov     ecx, [buffersize]
  1054.         inc     [ebx + device.packets_tx]
  1055.         add     dword [ebx + device.bytes_tx], ecx
  1056.         adc     dword [ebx + device.bytes_tx + 4], 0
  1057.  
  1058.         DEBUGF  1,"Transmit OK\n"
  1059.         popf
  1060.         xor     eax, eax
  1061.         ret
  1062.  
  1063.   .fail:
  1064.         DEBUGF  2,"Transmit failed\n"
  1065.         invoke  KernelFree, [bufferptr]
  1066.         popf
  1067.         or      eax, -1
  1068.         ret
  1069.  
  1070. endp
  1071.  
  1072.  
  1073. ;***************************************************************************
  1074. ;
  1075. ; int_handler
  1076. ;
  1077. ; handles received IRQs, which signal received packets
  1078. ;
  1079. ; Currently only supports one descriptor per packet, if packet is fragmented
  1080. ; between multiple descriptors you will lose part of the packet
  1081. ;
  1082. ;***************************************************************************
  1083.  
  1084. align 4
  1085. int_handler:
  1086.  
  1087.         push    ebx esi edi
  1088.  
  1089.         DEBUGF  1,"INT\n"
  1090.  
  1091. ; find pointer of device which made IRQ occur
  1092.  
  1093.         mov     ecx, [devices]
  1094.         test    ecx, ecx
  1095.         jz      .nothing
  1096.         mov     esi, device_list
  1097.   .nextdevice:
  1098.         mov     ebx, [esi]
  1099.  
  1100.         set_io  [ebx + device.io_addr], 0
  1101.         set_io  [ebx + device.io_addr], isr
  1102.         in      eax, dx                                 ; note that this clears all interrupts
  1103.         test    ax, IE
  1104.         jnz     .got_it
  1105.   .continue:
  1106.         add     esi, 4
  1107.         dec     ecx
  1108.         jnz     .nextdevice
  1109.   .nothing:
  1110.         pop     edi esi ebx
  1111.         xor     eax, eax
  1112.  
  1113.         ret
  1114.  
  1115.   .got_it:
  1116.  
  1117.         DEBUGF  1,"Device: %x Status: %x\n", ebx, ax
  1118.  
  1119.         test    ax, RxOK
  1120.         jz      .no_rx_
  1121.  
  1122.         push    ax
  1123.  
  1124.   .rx_loop:
  1125.  
  1126. ;-----------
  1127. ; Get Status
  1128.         movzx   eax, [ebx + device.cur_rx]              ; find current descriptor
  1129.         shl     eax, 4                                  ; * 16
  1130.         mov     ecx, dword[ebx + device.rxd + eax + 4]  ; get receive status
  1131.  
  1132. ;-------------------------------------------
  1133. ; Check RX_Status to see if packet is waiting
  1134.         test    ecx, 0x80000000
  1135.         jz      .no_rx
  1136.  
  1137. ;----------------------------------------------
  1138. ; There is a packet waiting check it for errors
  1139.         test    ecx, 0x67C0000                          ; see if there are any errors
  1140.         jnz     .error_status
  1141.  
  1142. ;---------------------
  1143. ; Check size of packet
  1144.         and     ecx, DSIZE                              ; get packet size minus CRC
  1145.         sub     ecx, CRC_SIZE                           ; make sure packet contains data
  1146.         jbe     .error_size
  1147.  
  1148. ; update statistics
  1149.         inc     dword [ebx + device.packets_rx]
  1150.         add     dword [ebx + device.bytes_rx], ecx
  1151.         adc     dword [ebx + device.bytes_rx + 4], 0
  1152.  
  1153.         push    ebx
  1154.         push    .return
  1155.         push    ecx                                     ; packet size
  1156.         pushd   [ebx + device.rxd + eax + 12]           ; packet ptr
  1157.         DEBUGF  1, "Packet received OK\n"
  1158.         jmp     [Eth_input]
  1159.   .return:
  1160.         pop     ebx
  1161.  
  1162. ; Reset status, allow ethernet card access to descriptor
  1163.         invoke  KernelAlloc, RX_BUFF_SZ
  1164.         test    eax, eax
  1165.         jz      .fail
  1166.         movzx   ecx, [ebx + device.cur_rx]
  1167.         shl     ecx, 4                                  ; *16
  1168.         lea     ecx, [ebx + device.rxd + ecx]
  1169.         mov     dword [ecx + 12], eax
  1170.         invoke  GetPhysAddr
  1171.         mov     dword [ecx + 8], eax
  1172.         mov     dword [ecx + 4], RX_BUFF_SZ
  1173.  
  1174.         inc     [ebx + device.cur_rx]                   ; get next descriptor
  1175.         and     [ebx + device.cur_rx], NUM_RX_DESC-1    ; only 4 descriptors 0-3
  1176.  
  1177.         jmp     .rx_loop
  1178.  
  1179.   .no_rx:
  1180.         set_io  [ebx + device.io_addr], 0
  1181.         set_io  [ebx + device.io_addr], cr
  1182.         in      eax, dx
  1183.         or      eax, RxENA                              ; Re-Enable the Receive state machine
  1184.         out     dx, eax
  1185.  
  1186.         pop     ax
  1187.  
  1188.   .no_rx_:
  1189.         test    ax, TxOK
  1190.         jz      .no_tx
  1191.  
  1192.         DEBUGF  1, "TX ok!\n"
  1193.  
  1194.   .tx_loop:
  1195.         movzx   ecx, [ebx + device.last_tx]
  1196.         shl     ecx, 4                  ; *16
  1197.         lea     ecx, [ebx + device.txd + ecx]
  1198.  
  1199.         test    dword[ecx + 4], 0x80000000              ; card owns descr
  1200.         jnz     .no_tx
  1201.         cmp     dword[ecx + 12], 0
  1202.         je      .no_tx
  1203.  
  1204.         DEBUGF  1, "Freeing packet = %x\n", [ecx + 12]:8
  1205.         push    dword[ecx + 12]
  1206.         mov     dword[ecx + 12], 0
  1207.         invoke  KernelFree
  1208.  
  1209.         inc     [ebx + device.last_tx]
  1210.         and     [ebx + device.last_tx], NUM_TX_DESC-1
  1211.         jmp     .tx_loop
  1212.  
  1213.   .no_tx:
  1214.   .fail:
  1215.         pop     edi esi ebx
  1216.         xor     eax, eax
  1217.         inc     eax
  1218.  
  1219.         ret
  1220.  
  1221.         ret
  1222.  
  1223.   .error_status:
  1224.         DEBUGF  2, "Packet error: %x\n", ecx
  1225.         jmp     .fail
  1226.  
  1227.   .error_size:
  1228.         DEBUGF  2, "Packet too large/small\n"
  1229.         jmp     .fail
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235. ; End of code
  1236.  
  1237. data fixups
  1238. end data
  1239.  
  1240. include '../peimport.inc'
  1241.  
  1242. my_service      db 'SIS900',0                           ; max 16 chars include zero
  1243.  
  1244. specific_table:
  1245. ;    dd SIS630A_900_REV, Get_Mac_SIS630A_900_REV, 0
  1246. ;    dd SIS630E_900_REV, Get_Mac_SIS630E_900_REV, 0
  1247.     dd SIS630S_900_REV, Get_Mac_SIS635_900_REV, 0
  1248.     dd SIS630EA1_900_REV, Get_Mac_SIS635_900_REV, 0
  1249.     dd SIS630ET_900_REV, Get_Mac_SIS635_900_REV, 0      ; SIS630ET_900_REV_SpecialFN
  1250.     dd SIS635A_900_REV, Get_Mac_SIS635_900_REV, 0
  1251.     dd SIS900_960_REV, SIS960_get_mac_addr, 0
  1252.     dd SIS900B_900_REV, SIS900_get_mac_addr, 0
  1253.     dd 0                                                ; end of list
  1254.  
  1255. include_debug_strings                                   ; All data wich FDO uses will be included here
  1256.  
  1257. align 4
  1258. devices         dd 0
  1259. device_list     rd MAX_DEVICES                          ; This list contains all pointers to device structures the driver is handling
  1260.  
  1261.