Subversion Repositories Kolibri OS

Rev

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