Subversion Repositories Kolibri OS

Rev

Rev 3155 | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                    ;;
  3. ;; Copyright (C) KolibriOS team 2004-2013. 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__         =   1
  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.  
  201. include 'proc32.inc'
  202. include 'imports.inc'
  203. include 'fdo.inc'
  204. include 'netdrv.inc'
  205.  
  206. public START
  207. public version
  208.  
  209.  
  210. virtual at ebx
  211.         device:
  212.  
  213.         ETH_DEVICE
  214.  
  215.         .io_addr        dd ?
  216.         .pci_bus        dd ?
  217.         .pci_dev        dd ?
  218.         .irq_line       db ?
  219.         .cur_rx         db ?
  220.         .cur_tx         db ?
  221.         .last_tx        db ?
  222.         .pci_revision   db ?
  223.         .table_entries  db ?
  224.         rb 2    ; alignment
  225.  
  226.         .txd            rd (4 * NUM_TX_DESC)
  227.         .rxd            rd (4 * NUM_RX_DESC)
  228.  
  229.         .size = $ - device
  230.  
  231. end virtual
  232.  
  233. macro   ee_delay {
  234.         push    eax
  235.         in      eax, dx
  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.         pop     eax
  246. }
  247.  
  248.  
  249. section '.flat' code readable align 16
  250.  
  251. ; Driver entry point - register our service when the driver is loading.
  252. ; TODO: add needed operations when unloading
  253. START:
  254.         cmp     dword [esp+4], 1
  255.         jne     .exit
  256.         stdcall RegService, my_service, service_proc
  257.         ret     4
  258.   .exit:
  259.         xor     eax, eax
  260.         ret     4
  261.  
  262. ; Service procedure for the driver - handle all I/O requests for the driver.
  263. ; Currently handled requests are: SRV_GETVERSION = 0 and SRV_HOOK = 1.
  264. service_proc:
  265. ; 1. Get parameter from the stack: [esp+4] is the first parameter,
  266. ;       pointer to IOCTL structure.
  267.         mov     edx, [esp+4]    ; edx -> IOCTL
  268. ; 2. Get request code and select a handler for the code.
  269.         mov     eax, [IOCTL.io_code]
  270.         test    eax, eax        ; check for SRV_GETVERSION
  271.         jnz     @f
  272. ; 3. This is SRV_GETVERSION request, no input, 4 bytes output, API_VERSION.
  273. ; 3a. Output size must be at least 4 bytes.
  274.         cmp     [IOCTL.out_size], 4
  275.         jb      .fail
  276. ; 3b. Write result to the output buffer.
  277.         mov     eax, [IOCTL.output]
  278.         mov     [eax], dword API_VERSION
  279. ; 3c. Return success.
  280.         xor     eax, eax
  281.         ret     4
  282.   @@:
  283.         dec     eax     ; check for SRV_HOOK
  284.         jnz     .fail
  285. ; 4. This is SRV_HOOK request, input defines the device to hook, no output.
  286. ; 4a. The driver works only with PCI devices,
  287. ;       so input must be at least 3 bytes long.
  288.         cmp     [IOCTL.inp_size], 3
  289.         jb      .fail
  290. ; 4b. First byte of input is bus type, 1 stands for PCI.
  291.         mov     eax, [IOCTL.input]
  292.         cmp     byte [eax], 1
  293.         jne     .fail
  294. ; 4c. Second and third bytes of the input define the device: bus and dev.
  295. ;       Word in bx holds both bytes.
  296.         mov     bx, [eax+1]
  297. ; 4d. Check if the device was already hooked,
  298. ;       scan through the list of known devices.
  299. ; check if the device is already listed
  300.         mov     esi, device_list
  301.         mov     ecx, [devices]
  302.         test    ecx, ecx
  303.         jz      .firstdevice
  304.  
  305. ;        mov     eax, [IOCTL.input]                      ; get the pci bus and device numbers
  306.         mov     ax, [eax+1]                            ;
  307.   .nextdevice:
  308.         mov     ebx, [esi]
  309.         cmp     al, byte[device.pci_bus]
  310.         jne     @f
  311.         cmp     ah, byte[device.pci_dev]
  312.         je      .find_devicenum                         ; Device is already loaded, let's find it's device number
  313.        @@:
  314.         add     esi, 4
  315.         loop    .nextdevice
  316. ; 4e. This device doesn't have its own eth_device structure yet, let's create one
  317.   .firstdevice:
  318. ; 4f. Check that we have place for new device.
  319.         cmp     [devices], MAX_DEVICES
  320.         jae     .fail
  321. ; 4g. Allocate memory for device descriptor and receive+transmit buffers.
  322. ; 4h. Zero the structure.
  323.         allocate_and_clear ebx, device.size, .fail
  324. ; 4i. Save PCI coordinates
  325.         mov     eax, [IOCTL.input]
  326.         movzx   ecx, byte[eax+1]
  327.         mov     [device.pci_bus], ecx
  328.         movzx   ecx, byte[eax+2]
  329.         mov     [device.pci_dev], ecx
  330. ; 4j. Fill in the direct call addresses into the struct.
  331. ; Note that get_MAC pointer is filled in initialization by probe.
  332.         mov     [device.reset], reset
  333.         mov     [device.transmit], transmit
  334.         mov     [device.set_MAC], write_mac
  335.         mov     [device.unload], unload
  336.         mov     [device.name], my_service
  337.  
  338. ; 4k. Now, it's time to find the base io addres of the PCI device
  339. ; TODO: implement check if bus and dev exist on this machine
  340.  
  341. ; Now, it's time to find the base io addres of the PCI device
  342.         PCI_find_io
  343.  
  344. ; We've found the io address, find IRQ now
  345.         PCI_find_irq
  346.  
  347. ; 4m. Add new device to the list (required for int_handler).
  348.         mov     eax, [devices]
  349.         mov     [device_list+4*eax], ebx
  350.         inc     [devices]
  351.  
  352. ; 4m. Ok, the eth_device structure is ready, let's probe the device
  353.         call    probe
  354.         test    eax, eax
  355.         jnz     .destroy
  356. ; 4n. If device was successfully initialized, register it for the kernel.
  357.  
  358.         mov     [device.type], NET_TYPE_ETH
  359.         call    NetRegDev
  360.  
  361.         cmp     eax, -1
  362.         je      .destroy
  363.  
  364.         ret     4
  365.  
  366. ; 5. If the device was already loaded, find the device number and return it in eax
  367.  
  368.   .find_devicenum:
  369.         call    NetPtrToNum                                             ; This kernel procedure converts a pointer to device struct in ebx
  370.                                                                         ; into a device number in edi
  371.         mov     eax, edi                                                ; Application wants it in eax instead
  372.         ret     4
  373.  
  374. ; If an error occured, remove all allocated data and exit (returning -1 in eax)
  375.  
  376.   .destroy:
  377.         dec     [devices]
  378.         ; todo: reset device into virgin state
  379.  
  380.   .err:
  381.         stdcall KernelFree, ebx
  382.  
  383.   .fail:
  384.         xor     eax, eax
  385.         ret     4
  386.  
  387.  
  388. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  389. ;;                                                                        ;;
  390. ;;        Actual Hardware dependent code starts here                      ;;
  391. ;;                                                                        ;;
  392. ;;/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\;;
  393.  
  394. unload:
  395.         ; TODO: (in this particular order)
  396.         ;
  397.         ; - Stop the device
  398.         ; - Detach int handler
  399.         ; - Remove device from local list
  400.         ; - call unregister function in kernel
  401.         ; - Remove all allocated structures and buffers the card used
  402.  
  403.         or      eax,-1
  404.  
  405. ret
  406.  
  407. ;***************************************************************************
  408. ;
  409. ; probe
  410. ;
  411. ; checks the card and enables it
  412. ;
  413. ; TODO: probe mii transceivers
  414. ;
  415. ;***************************************************************************
  416. align 4
  417. probe:
  418.         DEBUGF  1, "Probe\n"
  419.  
  420. ; wake up device   CHECKME
  421.         stdcall PciWrite8, [device.pci_bus], [device.pci_dev], 0x40, 0
  422.  
  423.         PCI_make_bus_master
  424.  
  425.         PCI_adjust_latency 64
  426.  
  427. ; Get Card Revision
  428.         stdcall PciRead8, [device.pci_bus], [device.pci_dev], 0x08
  429.         mov     [device.pci_revision], al       ; save the revision for later use
  430.  
  431. ; Look up through the specific_table
  432.         mov     esi, specific_table
  433.   .tableloop:
  434.         cmp     dword [esi], 0                  ; Check if we reached end of the list
  435.         je      .notsupported
  436.         cmp     al, [esi]                       ; Check if revision is OK
  437.         je      .ok
  438.         add     esi, 12                         ; Advance to next entry
  439.         jmp     .tableloop
  440.  
  441.   .ok:
  442.         mov     eax, [esi + 4]                  ; Get pointer to "get MAC" function
  443.         mov     [device.get_MAC], eax
  444.  
  445.         call    [device.get_MAC]
  446.  
  447. ; Set table entries
  448.         mov      [device.table_entries], 16
  449.         cmp      [device.pci_revision], SIS635A_900_REV
  450.         jae      @f
  451.         cmp      [device.pci_revision], SIS900B_900_REV
  452.         je       @f
  453.         mov      [device.table_entries], 8
  454.        @@:
  455.  
  456. ; TODO: Probe for mii transceiver
  457.  
  458.         jmp     reset
  459.  
  460.   .notsupported:
  461.         DEBUGF  1, "Device not supported\n"
  462.         or      eax, -1
  463.  
  464.         ret
  465.  
  466. reset:
  467.  
  468.         DEBUGF  1, "reset\n"
  469.  
  470.         movzx   eax, [device.irq_line]
  471.         stdcall AttachIntHandler, eax, int_handler, 0
  472.  
  473. ;--------------------------------------------
  474. ; Disable Interrupts and reset Receive Filter
  475.  
  476.         set_io  0
  477.         set_io  ier
  478.         xor     eax, eax
  479.         out     dx, eax
  480.  
  481.         set_io  imr
  482.         out     dx, eax
  483.  
  484.         set_io  rfcr
  485.         out     dx, eax
  486.  
  487. ;-----------
  488. ; Reset Card
  489.  
  490.         set_io  cr
  491.         in      eax, dx                         ; Get current Command Register
  492.         or      eax, RESET + RxRESET + TxRESET  ; set flags
  493.         out     dx, eax                         ; Write new Command Register
  494.  
  495. ;----------
  496. ; Wait loop
  497.  
  498.         set_io  isr
  499.         mov     ecx, 1000
  500.   .loop:
  501.         dec     ecx
  502.         jz      .fail
  503.         in      eax, dx                         ; read interrupt status
  504.         test    eax, TxRCMP + RxRCMP
  505.         jz      .loop
  506.         DEBUGF  1, "status=%x\n", eax
  507.  
  508. ;------------------------------------------------------
  509. ; Set Configuration Register depending on Card Revision
  510.  
  511.         set_io  cfg
  512.         mov     eax, PESEL                      ; Configuration Register Bit
  513.         cmp     [device.pci_revision], SIS635A_900_REV
  514.         je      .match
  515.         cmp     [device.pci_revision], SIS900B_900_REV ; Check card revision
  516.         jne     .done
  517.   .match:                                       ; Revision match
  518.         or      eax, RND_CNT                    ; Configuration Register Bit
  519.   .done:
  520.         out     dx, eax
  521.  
  522.         DEBUGF  1, "Initialising RX Filter\n"
  523.  
  524. ; Get Receive Filter Control Register
  525.         set_io  rfcr
  526.         in      eax, dx
  527.         push    eax
  528.  
  529. ; disable packet filtering before setting filter
  530.         and     eax, not RFEN
  531.         out     dx, eax
  532.  
  533. ; load MAC addr to filter data register
  534.         xor     ecx, ecx
  535.   .macloop:
  536.         mov     eax, ecx
  537.         set_io  0
  538.         set_io  rfcr
  539.         shl     eax, 16                                             ; high word of eax tells card which mac byte to write
  540.         out     dx, eax                                             ;
  541.         set_io  rfdr
  542.         mov     ax, word [device.mac + ecx*2]                       ; Get Mac ID word
  543.         out     dx, ax                                              ; Send Mac ID
  544.         inc     cl                                                  ; send next word
  545.         cmp     cl, 3                                               ; more to send?
  546.         jne     .macloop
  547.  
  548. ; enable packet filtering
  549.         pop     eax                     ; old register value
  550.         set_io  rfcr
  551.         or      eax, RFEN               ; enable filtering
  552.         out     dx, eax                 ; set register
  553.  
  554.         DEBUGF  1, "Initialising TX Descriptors\n"
  555.  
  556.         mov     ecx, NUM_TX_DESC
  557.         lea     esi, [device.txd]
  558.   .txdescloop:
  559.         lea     eax, [esi + 16]                 ; next ptr
  560.         GetRealAddr
  561.         mov     dword [esi], eax                ; link to next desc
  562.         mov     dword [esi + 4], 0              ; status field
  563.         mov     dword [esi + 8], 0              ; ptr to buffer
  564.         add     esi, 16
  565.         dec     ecx
  566.         jnz     .txdescloop
  567.  
  568.         lea     eax, [device.txd]
  569.         GetRealAddr
  570.         mov     dword [esi - 16], eax           ; correct last descriptor link ptr
  571.  
  572.         set_io  txdp                            ; TX Descriptor Pointer
  573. ;        lea     eax, [device.txd]
  574. ;        GetRealAddr
  575.         out     dx, eax
  576.  
  577.         mov     [device.cur_tx], 0              ; Set current tx descriptor to 0
  578.         mov     [device.last_tx], 0
  579.  
  580.         DEBUGF  1, "Initialising RX Descriptors\n"
  581.  
  582.         mov     ecx, NUM_RX_DESC
  583.         lea     esi, [device.rxd]
  584.   .rxdescloop:
  585.         lea     eax, [esi + 16]                 ; next ptr
  586.         GetRealAddr
  587.         mov     dword [esi], eax
  588.         mov     dword [esi + 4], RX_BUFF_SZ     ; size
  589.  
  590.         push    ecx esi
  591.         stdcall KernelAlloc, RX_BUFF_SZ
  592.         pop     esi ecx
  593.         test    eax, eax
  594.         jz      .fail
  595.         mov     dword [esi + 12], eax           ; address
  596.         GetRealAddr
  597.         mov     dword [esi + 8], eax            ; real address
  598.         add     esi, 16
  599.         dec     ecx
  600.         jnz     .rxdescloop
  601.  
  602.         lea     eax, [device.rxd]
  603.         GetRealAddr
  604.         mov     dword [esi - 16], eax           ; correct last descriptor link ptr
  605.  
  606.         set_io  0
  607.         set_io  rxdp
  608. ;        lea     eax, [device.rxd]
  609. ;        GetRealAddr
  610.         out     dx, eax
  611.  
  612.         mov     [device.cur_rx], 0              ; Set current rx descriptor to 0
  613.  
  614.         DEBUGF  1, "setting RX mode\n"
  615.  
  616.         xor     cl, cl
  617.   .rxfilterloop:
  618.         set_io  0
  619.         set_io  rfcr                    ; Receive Filter Control Reg offset
  620.         mov     eax, 4                  ; determine table entry
  621.         add     al, cl
  622.         shl     eax, 16
  623.         out     dx, eax                 ; tell card which entry to modify
  624.  
  625.         set_io  rfdr                    ; Receive Filter Control Reg offset
  626.         mov     eax, 0xffff             ; entry value
  627.         out     dx, ax                  ; write value to table in card
  628.  
  629.         inc     cl                      ; next entry
  630.         cmp     cl, [device.table_entries]
  631.         jb      .rxfilterloop
  632.  
  633.         set_io  rfcr                    ; Receive Filter Control Register offset
  634.         mov     eax, RFAAB + RFAAM + RFAAP + RFEN
  635.         out     dx, eax
  636.  
  637.         set_io  rxcfg                   ; Receive Config Register offset
  638.         mov     eax, ATX + RX_DMA + 2   ; 0x2 : RX Drain Threshold = 8*8=64 bytes
  639.         out     dx, eax
  640.  
  641.         DEBUGF  1, "setting TX mode\n"
  642.  
  643.         set_io  txcfg                   ; Transmit config Register offset
  644.         mov     eax, ATP + HBI + CSI + TX_DMA + 0x120
  645.                                         ; TX Fill threshold = 0x100
  646.                                         ; TX Drain Threshold = 0x20
  647.         out     dx, eax
  648.  
  649.         DEBUGF  1, "Enabling interrupts\n"
  650.  
  651.         set_io  imr
  652.         mov     eax, IE                 ; Interrupt enable mask
  653.         out     dx, eax
  654.  
  655.         set_io  cr
  656.         in      eax, dx
  657.         or      eax, RxENA              ; Enable Receive
  658.         out     dx, eax
  659.  
  660.         set_io  ier                     ; Interrupt enable
  661.         mov     eax, 1
  662.         out     dx, eax
  663.  
  664.         mov     [device.mtu], 1514
  665.         xor     eax, eax
  666.  
  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.         DEBUGF  1,"\n%s int\n", my_service
  1051.  
  1052. ; find pointer of device which made IRQ occur
  1053.  
  1054.         mov     ecx, [devices]
  1055.         test    ecx, ecx
  1056.         jz      .nothing
  1057.         mov     esi, device_list
  1058.   .nextdevice:
  1059.         mov     ebx, [esi]
  1060.  
  1061.         set_io  0
  1062.         set_io  isr
  1063.         in      eax, dx                 ; note that this clears all interrupts
  1064.         test    ax, IE
  1065.         jnz     .got_it
  1066.   .continue:
  1067.         add     esi, 4
  1068.         dec     ecx
  1069.         jnz     .nextdevice
  1070.   .nothing:
  1071.         ret
  1072.  
  1073.   .got_it:
  1074.  
  1075.         DEBUGF  1,"Device: %x Status: %x ", ebx, ax
  1076.  
  1077.         test    ax, RxOK
  1078.         jz      .no_rx_
  1079.  
  1080.         push    ax
  1081.  
  1082.   .rx_loop:
  1083.  
  1084. ;-----------
  1085. ; Get Status
  1086.         movzx   eax, [device.cur_rx]                    ; find current descriptor
  1087.         shl     eax, 4                                  ; * 16
  1088.         mov     ecx, dword[device.rxd + eax + 4]        ; get receive status
  1089.  
  1090. ;-------------------------------------------
  1091. ; Check RX_Status to see if packet is waiting
  1092.         test    ecx, 0x80000000
  1093.         jz      .no_rx
  1094.  
  1095. ;----------------------------------------------
  1096. ; There is a packet waiting check it for errors
  1097.         test    ecx, 0x67C0000                  ; see if there are any errors
  1098.         jnz     .error_status
  1099.  
  1100. ;---------------------
  1101. ; Check size of packet
  1102.         and     ecx, DSIZE                      ; get packet size minus CRC
  1103.         sub     ecx, CRC_SIZE                   ; make sure packet contains data
  1104.         jbe     .error_size
  1105.  
  1106. ; update statistics
  1107.         inc     dword [device.packets_rx]
  1108.         add     dword [device.bytes_rx], ecx
  1109.         adc     dword [device.bytes_rx + 4], 0
  1110.  
  1111.         push    ebx
  1112.         push    .return
  1113.         push    ecx                             ; packet size
  1114.         pushd   [device.rxd + eax + 12]         ; packet ptr
  1115.         DEBUGF  1, "Packet received OK\n"
  1116.         jmp     Eth_input
  1117.   .return:
  1118.         pop     ebx
  1119.  
  1120. ; Reset status, allow ethernet card access to descriptor
  1121.         stdcall KernelAlloc, RX_BUFF_SZ
  1122.         test    eax, eax
  1123.         jz      .fail
  1124.         movzx   ecx, [device.cur_rx]
  1125.         shl     ecx, 4                          ; *16
  1126.         lea     ecx, [device.rxd + ecx]
  1127.         mov     dword [ecx + 12], eax
  1128.         GetRealAddr
  1129.         mov     dword [ecx + 8], eax
  1130.         mov     dword [ecx + 4], RX_BUFF_SZ
  1131.  
  1132.         inc     [device.cur_rx]                         ; get next descriptor
  1133.         and     [device.cur_rx], NUM_RX_DESC-1          ; only 4 descriptors 0-3
  1134.  
  1135.         jmp     .rx_loop
  1136.  
  1137.   .no_rx:
  1138.         set_io  0
  1139.         set_io  cr
  1140.         in      eax, dx
  1141.         or      eax, RxENA                              ; Re-Enable the Receive state machine
  1142.         out     dx, eax
  1143.  
  1144.         pop     ax
  1145.  
  1146.   .no_rx_:
  1147.         test    ax, TxOK
  1148.         jz      .no_tx
  1149.  
  1150.         DEBUGF  1, "TX ok!\n"
  1151.  
  1152.   .tx_loop:
  1153.         movzx   ecx, [device.last_tx]
  1154.         shl     ecx, 4                  ; *16
  1155.         lea     ecx, [device.txd + ecx]
  1156.  
  1157.         test    dword [ecx + 4], 0x80000000   ; card owns descr
  1158.         jnz     .no_tx
  1159.         cmp     dword [ecx + 12], 0
  1160.         je      .no_tx
  1161.  
  1162.         DEBUGF  1, "Freeing packet = %x\n", [ecx + 12]:8
  1163.         push    dword [ecx + 12]
  1164.         mov     dword [ecx + 12], 0
  1165.         call    KernelFree
  1166.  
  1167.         inc     [device.last_tx]
  1168.         and     [device.last_tx], NUM_TX_DESC-1
  1169.         jmp     .tx_loop
  1170.  
  1171.   .no_tx:
  1172.  
  1173.         ret
  1174.  
  1175.   .error_status:
  1176.         DEBUGF  1, "Packet error: %x\n", ecx
  1177.         jmp     .fail
  1178.  
  1179.   .error_size:
  1180.         DEBUGF  1, "Packet too large/small\n"
  1181.         jmp     .fail
  1182.  
  1183.   .fail:
  1184.         DEBUGF  1, "FAILED\n"
  1185.         jmp     $
  1186.         ret
  1187.  
  1188.  
  1189.  
  1190. ; End of code
  1191.  
  1192. align 4                                         ; Place all initialised data here
  1193.  
  1194. devices         dd 0
  1195.  
  1196. specific_table:
  1197. ;    dd SIS630A_900_REV, Get_Mac_SIS630A_900_REV, 0
  1198. ;    dd SIS630E_900_REV, Get_Mac_SIS630E_900_REV, 0
  1199.     dd SIS630S_900_REV, Get_Mac_SIS635_900_REV, 0
  1200.     dd SIS630EA1_900_REV, Get_Mac_SIS635_900_REV, 0
  1201.     dd SIS630ET_900_REV, Get_Mac_SIS635_900_REV, 0 ;SIS630ET_900_REV_SpecialFN
  1202.     dd SIS635A_900_REV, Get_Mac_SIS635_900_REV, 0
  1203.     dd SIS900_960_REV, SIS960_get_mac_addr, 0
  1204.     dd SIS900B_900_REV, SIS900_get_mac_addr, 0
  1205.     dd 0                                        ; end of list
  1206.  
  1207. version         dd (DRIVER_VERSION shl 16) or (API_VERSION and 0xFFFF)
  1208. my_service      db 'SIS900',0                  ; max 16 chars include zero
  1209.  
  1210. include_debug_strings                          ; All data wich FDO uses will be included here
  1211.  
  1212. section '.data' data readable writable align 16; place all uninitialized data place here
  1213.  
  1214. device_list     rd MAX_DEVICES                 ; This list contains all pointers to device structures the driver is handling
  1215.  
  1216.