Subversion Repositories Kolibri OS

Rev

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

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