Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                    ;;
  3. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved.       ;;
  4. ;; Distributed under terms of the GNU General Public License          ;;
  5. ;;                                                                    ;;
  6. ;;  SIS900.INC                                                        ;;
  7. ;;                                                                    ;;
  8. ;;  Ethernet driver for Menuet OS                                     ;;
  9. ;;                                                                    ;;
  10. ;;  Version 0.4  26 April 2004                                        ;;
  11. ;;                                                                    ;;
  12. ;;  This driver is based on the SIS900 driver from                    ;;
  13. ;;  the etherboot 5.0.6 project. The copyright statement is           ;;
  14. ;;                                                                    ;;
  15. ;;          GNU GENERAL PUBLIC LICENSE                                ;;
  16. ;;             Version 2, June 1991                                   ;;
  17. ;;                                                                    ;;
  18. ;;  remaining parts Copyright 2004 Jason Delozier,                    ;;
  19. ;;   cordata51@hotmail.com                                            ;;
  20. ;;                                                                    ;;
  21. ;;  See file COPYING for details                                      ;;
  22. ;;                                                                    ;;
  23. ;;  Updates:                                                          ;;
  24. ;;    Revision Look up table and SIS635 Mac Address by Jarek Pelczar  ;;
  25. ;;                                                                    ;;
  26. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  27.  
  28. $Revision: 735 $
  29.  
  30.  
  31. ;********************************************************************
  32. ;   Interface
  33. ;      SIS900_reset
  34. ;      SIS900_probe
  35. ;      SIS900_poll
  36. ;      SIS900_transmit
  37. ;
  38. ;********************************************************************
  39. ;********************************************************************
  40. ;  Comments:
  41. ;    Known to work with the following SIS900 ethernet cards:
  42. ;      -  Device ID: 0x0900   Vendor ID: 0x1039   Revision: 0x91
  43. ;      -  Device ID: 0x0900   Vendor ID: 0x1039   Revision: 0x90
  44. ;
  45. ;    If your card is not listed, try it and let me know if it
  46. ;    functions properly and it will be aded to the list.  If not
  47. ;    we may be able to add support for it.
  48. ;
  49. ;  How To Use:
  50. ;    Add the following lines to Ethernet.inc in their appropriate locations
  51. ;
  52. ;         include "Sis900.INC"
  53. ;         dd  0x09001039, SIS900_probe, SIS900_reset, SIS900_poll,
  54. ; SIS900_transmit
  55. ;         dd  0x70161039, SIS900_probe, SIS900_reset, SIS900_poll,
  56. ; SIS900_transmit   ;untested
  57. ;
  58. ;  ToDo:
  59. ;     -  Enable MII interface for reading speed
  60. ;        and duplex settings.
  61. ;
  62. ;     -  Update Poll routine to support packet fragmentation.
  63. ;
  64. ;     -  Add additional support for other sis900 based cards
  65. ;
  66. ;********************************************************************
  67.  
  68. ; comment the next line out if you don't want debug info printed
  69. ; on the debug board. This option adds a lot of bytes to the driver
  70. ; so it's worth to comment it out.
  71. ;        SIS900_DEBUG equ 1
  72.  
  73.  
  74. ;* buffers and descriptors
  75. cur_rx  db  0
  76. NUM_RX_DESC    equ    4               ;* Number of RX descriptors *
  77. NUM_TX_DESC    equ    1               ;* Number of TX descriptors *
  78. RX_BUFF_SZ          equ    1520            ;* Buffer size for each Rx buffer *
  79. TX_BUFF_SZ          equ    1516            ;* Buffer size for each Tx buffer *
  80.  
  81. uglobal
  82. align   4
  83. txd: times (3 * NUM_TX_DESC) dd 0
  84. rxd: times (3 * NUM_RX_DESC) dd 0
  85. endg
  86.  
  87. txb equ eth_data_start
  88. rxb equ txb + (NUM_TX_DESC * TX_BUFF_SZ)
  89. SIS900_ETH_ALEN equ     6       ;* Size of Ethernet address *
  90. SIS900_ETH_HLEN equ     14      ;* Size of ethernet header *
  91. SIS900_ETH_ZLEN equ     60      ;* Minimum packet length *
  92. SIS900_DSIZE equ 0x00000fff
  93. SIS900_CRC_SIZE equ 4
  94. SIS900_RFADDR_shift equ 16
  95. ;SIS900 Symbolic offsets to registers.
  96.     SIS900_cr           equ     0x0               ; Command Register
  97.     SIS900_cfg          equ     0x4       ; Configuration Register
  98.     SIS900_mear     equ     0x8       ; EEPROM Access Register
  99.     SIS900_ptscr    equ     0xc       ; PCI Test Control Register
  100.     SIS900_isr          equ     0x10      ; Interrupt Status Register
  101.     SIS900_imr          equ     0x14      ; Interrupt Mask Register
  102.     SIS900_ier          equ     0x18      ; Interrupt Enable Register
  103.     SIS900_epar         equ     0x18      ; Enhanced PHY Access Register
  104.     SIS900_txdp     equ     0x20      ; Transmit Descriptor Pointer Register
  105.     SIS900_txcfg    equ     0x24      ; Transmit Configuration Register
  106.     SIS900_rxdp     equ     0x30      ; Receive Descriptor Pointer Register
  107.     SIS900_rxcfg    equ     0x34      ; Receive Configuration Register
  108.     SIS900_flctrl   equ     0x38      ; Flow Control Register
  109.     SIS900_rxlen    equ     0x3c      ; Receive Packet Length Register
  110.     SIS900_rfcr     equ     0x48      ; Receive Filter Control Register
  111.     SIS900_rfdr     equ     0x4C      ; Receive Filter Data Register
  112.     SIS900_pmctrl   equ     0xB0      ; Power Management Control Register
  113.     SIS900_pmer         equ     0xB4      ; Power Management Wake-up Event Register
  114. ;SIS900 Command Register Bits
  115.     SIS900_RELOAD       equ      0x00000400
  116.     SIS900_ACCESSMODE   equ      0x00000200
  117.     SIS900_RESET        equ      0x00000100
  118.     SIS900_SWI          equ      0x00000080
  119.     SIS900_RxRESET      equ      0x00000020
  120.     SIS900_TxRESET      equ      0x00000010
  121.     SIS900_RxDIS        equ      0x00000008
  122.     SIS900_RxENA        equ      0x00000004
  123.     SIS900_TxDIS        equ      0x00000002
  124.     SIS900_TxENA        equ      0x00000001
  125. ;SIS900 Configuration Register Bits
  126.     SIS900_DESCRFMT      equ    0x00000100 ; 7016 specific
  127.     SIS900_REQALG        equ    0x00000080
  128.     SIS900_SB            equ    0x00000040
  129.     SIS900_POW           equ    0x00000020
  130.     SIS900_EXD           equ    0x00000010
  131.     SIS900_PESEL         equ    0x00000008
  132.     SIS900_LPM           equ    0x00000004
  133.     SIS900_BEM           equ    0x00000001
  134.     SIS900_RND_CNT       equ    0x00000400
  135.     SIS900_FAIR_BACKOFF  equ    0x00000200
  136.     SIS900_EDB_MASTER_EN equ    0x00002000
  137. ;SIS900 Eeprom Access Reigster Bits
  138.     SIS900_MDC        equ      0x00000040
  139.     SIS900_MDDIR      equ      0x00000020
  140.     SIS900_MDIO       equ      0x00000010  ; 7016 specific
  141.     SIS900_EECS       equ      0x00000008
  142.     SIS900_EECLK      equ      0x00000004
  143.     SIS900_EEDO       equ      0x00000002
  144.     SIS900_EEDI       equ      0x00000001
  145. ;SIS900 TX Configuration Register Bits
  146.     SIS900_ATP        equ      0x10000000 ;Automatic Transmit Padding
  147.     SIS900_MLB        equ      0x20000000 ;Mac Loopback Enable
  148.     SIS900_HBI        equ      0x40000000 ;HeartBeat Ignore (Req for full-dup)
  149.     SIS900_CSI        equ      0x80000000 ;CarrierSenseIgnore (Req for full-du
  150. ;SIS900 RX Configuration Register Bits
  151.     SIS900_AJAB       equ      0x08000000 ;
  152.     SIS900_ATX        equ      0x10000000 ;Accept Transmit Packets
  153.     SIS900_ARP        equ      0x40000000 ;accept runt packets (<64bytes)
  154.     SIS900_AEP        equ      0x80000000 ;accept error packets
  155. ;SIS900 Interrupt Reigster Bits
  156.     SIS900_WKEVT           equ      0x10000000
  157.     SIS900_TxPAUSEEND      equ      0x08000000
  158.     SIS900_TxPAUSE         equ      0x04000000
  159.     SIS900_TxRCMP          equ      0x02000000
  160.     SIS900_RxRCMP          equ      0x01000000
  161.     SIS900_DPERR           equ      0x00800000
  162.     SIS900_SSERR           equ      0x00400000
  163.     SIS900_RMABT           equ      0x00200000
  164.     SIS900_RTABT           equ      0x00100000
  165.     SIS900_RxSOVR          equ      0x00010000
  166.     SIS900_HIBERR          equ      0x00008000
  167.     SIS900_SWINT           equ      0x00001000
  168.     SIS900_MIBINT          equ      0x00000800
  169.     SIS900_TxURN           equ      0x00000400
  170.     SIS900_TxIDLE          equ      0x00000200
  171.     SIS900_TxERR           equ      0x00000100
  172.     SIS900_TxDESC          equ      0x00000080
  173.     SIS900_TxOK            equ      0x00000040
  174.     SIS900_RxORN           equ      0x00000020
  175.     SIS900_RxIDLE          equ      0x00000010
  176.     SIS900_RxEARLY         equ      0x00000008
  177.     SIS900_RxERR           equ      0x00000004
  178.     SIS900_RxDESC          equ      0x00000002
  179.     SIS900_RxOK            equ      0x00000001
  180. ;SIS900 Interrupt Enable Reigster Bits
  181.     SIS900_IE      equ      0x00000001
  182. ;SIS900 Revision ID
  183.         SIS900B_900_REV       equ      0x03
  184.         SIS630A_900_REV       equ      0x80
  185.         SIS630E_900_REV       equ      0x81
  186.         SIS630S_900_REV       equ      0x82
  187.         SIS630EA1_900_REV     equ      0x83
  188.         SIS630ET_900_REV      equ      0x84
  189.         SIS635A_900_REV       equ      0x90
  190.         SIS900_960_REV        equ      0x91
  191. ;SIS900 Receive Filter Control Register Bits
  192.     SIS900_RFEN          equ 0x80000000
  193.     SIS900_RFAAB         equ 0x40000000
  194.     SIS900_RFAAM         equ 0x20000000
  195.     SIS900_RFAAP         equ 0x10000000
  196.     SIS900_RFPromiscuous equ 0x70000000
  197. ;SIS900 Reveive Filter Data Mask
  198.     SIS900_RFDAT equ  0x0000FFFF
  199. ;SIS900 Eeprom Address
  200.     SIS900_EEPROMSignature equ 0x00
  201.     SIS900_EEPROMVendorID  equ 0x02
  202.     SIS900_EEPROMDeviceID  equ 0x03
  203.     SIS900_EEPROMMACAddr   equ 0x08
  204.     SIS900_EEPROMChecksum  equ 0x0b
  205. ;The EEPROM commands include the alway-set leading bit.
  206. ;SIS900 Eeprom Command
  207.     SIS900_EEread          equ 0x0180
  208.     SIS900_EEwrite         equ 0x0140
  209.     SIS900_EEerase         equ 0x01C0
  210.     SIS900_EEwriteEnable   equ 0x0130
  211.     SIS900_EEwriteDisable  equ 0x0100
  212.     SIS900_EEeraseAll      equ 0x0120
  213.     SIS900_EEwriteAll      equ 0x0110
  214.     SIS900_EEaddrMask      equ 0x013F
  215.     SIS900_EEcmdShift      equ 16
  216. ;For SiS962 or SiS963, request the eeprom software access
  217.         SIS900_EEREQ    equ 0x00000400
  218.         SIS900_EEDONE   equ 0x00000200
  219.         SIS900_EEGNT    equ 0x00000100
  220. ;General Varibles
  221.         SIS900_pci_revision:     db       0
  222.         SIS900_Status                dd   0x03000000
  223. sis900_specific_table:
  224. ;    dd SIS630A_900_REV,Get_Mac_SIS630A_900_REV,0
  225. ;    dd SIS630E_900_REV,Get_Mac_SIS630E_900_REV,0
  226.     dd SIS630S_900_REV,Get_Mac_SIS635_900_REV,0
  227.     dd SIS630EA1_900_REV,Get_Mac_SIS635_900_REV,0
  228.     dd SIS630ET_900_REV,Get_Mac_SIS635_900_REV,0;SIS630ET_900_REV_SpecialFN
  229.     dd SIS635A_900_REV,Get_Mac_SIS635_900_REV,0
  230.     dd SIS900_960_REV,SIS960_get_mac_addr,0
  231.     dd SIS900B_900_REV,SIS900_get_mac_addr,0
  232.     dd 0,0,0,0 ; end of list
  233. sis900_get_mac_func:    dd 0
  234. sis900_special_func:    dd 0
  235. sis900_table_entries:   db 8
  236.  
  237. ;***************************************************************************
  238. ;   Function
  239. ;      SIS900_probe
  240. ;   Description
  241. ;      Searches for an ethernet card, enables it and clears the rx buffer
  242. ;      If a card was found, it enables the ethernet -> TCPIP link
  243. ;not done  - still need to probe mii transcievers
  244. ;***************************************************************************
  245. if defined SIS900_DEBUG
  246. SIS900_Debug_Str_Unsupported db 'Sorry your card is unsupported ',13,10,0
  247. end if
  248. SIS900_probe:
  249. ;******Wake Up Chip*******
  250.    mov     al, 4
  251.    mov     bh, [pci_dev]
  252.    mov     ecx, 0
  253.    mov     ah, [pci_bus]
  254.    mov     bl, 0x40
  255.    call    pci_write_reg
  256. ;*******Set some PCI Settings*********
  257.    call    SIS900_adjust_pci_device
  258. ;*****Get Card Revision******
  259.    mov     al, 1                                        ;one byte to read
  260.    mov     bh, [pci_dev]
  261.    mov     ah, [pci_bus]
  262.    mov     bl, 0x08                                 ;Revision Register
  263.    call    pci_read_reg
  264.    mov [SIS900_pci_revision], al        ;save the revision for later use
  265. ;****** Look up through the sis900_specific_table
  266.    mov     esi,sis900_specific_table
  267. .probe_loop:
  268.    cmp     dword [esi],0                ; Check if we reached end of the list
  269.    je      .probe_loop_failed
  270.    cmp     al,[esi]                     ; Check if revision is OK
  271.    je      .probe_loop_ok
  272.    add     esi,12                       ; Advance to next entry
  273.    jmp     .probe_loop
  274. .probe_loop_failed:
  275.    jmp     SIS900_Probe_Unsupported
  276. ;*********Find Get Mac Function*********
  277. .probe_loop_ok:
  278.    mov      eax,[esi+4]         ; Get pointer to "get MAC" function
  279.    mov      [sis900_get_mac_func],eax
  280.    mov      eax,[esi+8]         ; Get pointer to special initialization fn
  281.    mov      [sis900_special_func],eax
  282. ;******** Get MAC ********
  283.    call     dword [sis900_get_mac_func]
  284. ;******** Call special initialization fn if requested ********
  285.    cmp      dword [sis900_special_func],0
  286.    je       .no_special_init
  287.    call     dword [sis900_special_func]
  288. .no_special_init:
  289. ;******** Set table entries ********
  290.    mov      al,[SIS900_pci_revision]
  291.    cmp      al,SIS635A_900_REV
  292.    jae      .ent16
  293.    cmp      al,SIS900B_900_REV
  294.    je       .ent16
  295.    jmp      .ent8
  296. .ent16:
  297.    mov      byte [sis900_table_entries],16
  298. .ent8:
  299. ;*******Probe for mii transceiver*******
  300. ;TODO!!*********************
  301. ;*******Initialize Device*******
  302.    call sis900_init
  303.    ret
  304.  
  305. SIS900_Probe_Unsupported:
  306. if defined SIS900_DEBUG
  307.    mov     esi, SIS900_Debug_Str_Unsupported
  308.    call    sys_msg_board_str
  309. end if
  310.    ret
  311. ;***************************************************************************
  312. ; Function: sis900_init
  313. ;
  314. ; Description: resets the ethernet controller chip and various
  315. ;    data structures required for sending and receiving packets.
  316. ;
  317. ; Arguments:
  318. ;
  319. ; returns:   none
  320. ;not done
  321. ;***************************************************************************
  322. sis900_init:
  323.    call SIS900_reset               ;Done
  324.    call SIS900_init_rxfilter   ;Done
  325.    call SIS900_init_txd        ;Done
  326.    call SIS900_init_rxd            ;Done
  327.    call SIS900_set_rx_mode     ;done
  328.    call SIS900_set_tx_mode
  329.    ;call SIS900_check_mode
  330.    ret
  331.  
  332. ;***************************************************************************
  333. ;   Function
  334. ;      SIS900_reset
  335. ;   Description
  336. ;      disables interrupts and soft resets the controller chip
  337. ;
  338. ;done+
  339. ;***************************************************************************
  340. if defined SIS900_DEBUG
  341.    SIS900_Debug_Reset_Failed db 'Reset Failed ',0
  342. end if
  343. SIS900_reset:
  344.    ;******Disable Interrupts and reset Receive Filter*******
  345.    mov      ebp, [io_addr]      ; base address
  346.    xor      eax, eax            ; 0 to initialize
  347.    lea      edx,[ebp+SIS900_ier]
  348.    out      dx, eax                     ; Write 0 to location
  349.    lea      edx,[ebp+SIS900_imr]
  350.    out      dx, eax                     ; Write 0 to location
  351.    lea      edx,[ebp+SIS900_rfcr]
  352.    out      dx, eax                     ; Write 0 to location
  353.    ;*******Reset Card***********************************************
  354.    lea      edx,[ebp+SIS900_cr]
  355.    in       eax, dx                             ; Get current Command Register
  356.    or       eax, SIS900_RESET           ; set flags
  357.    or       eax, SIS900_RxRESET     ;
  358.    or           eax, SIS900_TxRESET         ;
  359.    out      dx, eax                             ; Write new Command Register
  360.    ;*******Wait Loop************************************************
  361.    lea      edx,[ebp+SIS900_isr]
  362.    mov      ecx, [SIS900_Status]    ; Status we would like to see from card
  363.    mov      ebx, 2001               ; only loop 1000 times
  364. SIS900_Wait:
  365.    dec      ebx                                     ; 1 less loop
  366.    jz       SIS900_DoneWait_e           ; 1000 times yet?
  367.    in       eax, dx                                 ; move interrup status to eax
  368.    and      eax, ecx
  369.    xor      ecx, eax
  370.    jz       SIS900_DoneWait
  371.    jmp      SIS900_Wait
  372. SIS900_DoneWait_e:
  373. if defined SIS900_DEBUG
  374.    mov esi, SIS900_Debug_Reset_Failed
  375.    call sys_msg_board_str
  376. end if
  377. SIS900_DoneWait:
  378.    ;*******Set Configuration Register depending on Card Revision********
  379.    lea      edx,[ebp+SIS900_cfg]
  380.    mov      eax, SIS900_PESEL               ; Configuration Register Bit
  381.    mov      bl, [SIS900_pci_revision]   ; card revision
  382.    mov      cl, SIS635A_900_REV         ; Check card revision
  383.    cmp      bl, cl
  384.    je       SIS900_RevMatch
  385.    mov      cl, SIS900B_900_REV         ; Check card revision
  386.    cmp      bl, cl
  387.    je       SIS900_RevMatch
  388.    out      dx, eax                                 ; no revision match
  389.    jmp      SIS900_Reset_Complete
  390. SIS900_RevMatch:                                        ; Revision match
  391.    or       eax, SIS900_RND_CNT         ; Configuration Register Bit
  392.    out      dx, eax
  393. SIS900_Reset_Complete:
  394.    mov      eax, [pci_data]
  395.    mov      [eth_status], eax
  396.    ret
  397.  
  398. ;***************************************************************************
  399. ; Function: sis_init_rxfilter
  400. ;
  401. ; Description: sets receive filter address to our MAC address
  402. ;
  403. ; Arguments:
  404. ;
  405. ; returns:
  406. ;done+
  407. ;***************************************************************************
  408. SIS900_init_rxfilter:
  409.    ;****Get Receive Filter Control Register ********
  410.    mov      ebp, [io_addr]          ; base address
  411.    lea      edx,[ebp+SIS900_rfcr]
  412.    in       eax, dx                         ; get register
  413.    push     eax
  414.    ;****disable packet filtering before setting filter*******
  415.    mov      eax, SIS900_RFEN    ;move receive filter enable flag
  416.    not      eax                         ;1s complement
  417.    pop      ebx                         ;and with our saved register
  418.    and      eax, ebx                    ;disable receiver
  419.    push     ebx                 ;save filter for another use
  420.    out      dx, eax                     ;set receive disabled
  421.    ;********load MAC addr to filter data register*********
  422.    xor      ecx, ecx
  423. SIS900_RXINT_Mac_Write:
  424.    ;high word of eax tells card which mac byte to write
  425.    mov      eax, ecx
  426.    lea      edx,[ebp+SIS900_rfcr]
  427.    shl      eax, 16                                             ;
  428.    out      dx, eax                                             ;
  429.    lea      edx,[ebp+SIS900_rfdr]
  430.    mov      ax,  word [node_addr+ecx*2] ; Get Mac ID word
  431.    out      dx, ax                                              ; Send Mac ID
  432.    inc      cl                                                  ; send next word
  433.    cmp      cl, 3                                               ; more to send?
  434.    jne      SIS900_RXINT_Mac_Write
  435.    ;********enable packet filitering *****
  436.    pop      eax                             ;old register value
  437.    lea      edx,[ebp+SIS900_rfcr]
  438.    or       eax, SIS900_RFEN    ;enable filtering
  439.    out      dx, eax             ;set register
  440.    ret
  441.  
  442. ;***************************************************************************
  443. ;*
  444. ;* Function: sis_init_txd
  445. ;*
  446. ;* Description: initializes the Tx descriptor
  447. ;*
  448. ;* Arguments:
  449. ;*
  450. ;* returns:
  451. ;*done
  452. ;***************************************************************************
  453. SIS900_init_txd:
  454.    ;********** initialize TX descriptor **************
  455.    mov     [txd], dword 0       ;put link to next descriptor in link field
  456.    mov     [txd+4],dword 0      ;clear status field
  457.    mov     [txd+8], dword txb - OS_BASE   ;save address to buffer ptr field
  458.    ;*************** load Transmit Descriptor Register ***************
  459.    mov     dx, [io_addr]            ; base address
  460.    add     dx, SIS900_txdp      ; TX Descriptor Pointer
  461.    mov     eax, txd - OS_BASE               ; First Descriptor
  462.    out     dx, eax                              ; move the pointer
  463.    ret
  464.  
  465. ;***************************************************************************
  466. ;* Function: sis_init_rxd
  467. ;*
  468. ;* Description: initializes the Rx descriptor ring
  469. ;*
  470. ;* Arguments:
  471. ;*
  472. ;* Returns:
  473. ;*done
  474. ;***************************************************************************
  475. SIS900_init_rxd:
  476.    xor      ecx,ecx
  477.    mov      [cur_rx], cl                                        ;Set cuurent rx discriptor to 0
  478.    ;******** init RX descriptors ********
  479. SIS900_init_rxd_Loop:
  480.     mov     eax, ecx                                        ;current descriptor
  481.     imul    eax, 12                         ;
  482.     mov     ebx, ecx                                        ;determine next link descriptor
  483.     inc     ebx                             ;
  484.     cmp     ebx, NUM_RX_DESC                ;
  485.     jne     SIS900_init_rxd_Loop_0          ;
  486.     xor     ebx, ebx                        ;
  487. SIS900_init_rxd_Loop_0:                    ;
  488.     imul    ebx, 12                         ;
  489.     add     ebx, rxd - OS_BASE              ;
  490.     mov     [rxd+eax], ebx                                      ;save link to next descriptor
  491.     mov     [rxd+eax+4],dword RX_BUFF_SZ        ;status bits init to buf size
  492.     mov     ebx, ecx                                            ;find where the buf is located
  493.     imul    ebx,RX_BUFF_SZ                  ;
  494.     add     ebx, rxb - OS_BASE              ;
  495.     mov     [rxd+eax+8], ebx                            ;save buffer pointer
  496.     inc     ecx                                                     ;next descriptor
  497.     cmp     ecx, NUM_RX_DESC                ;
  498.     jne     SIS900_init_rxd_Loop            ;
  499.     ;********* load Receive Descriptor Register with address of first
  500.     ; descriptor*********
  501.     mov     dx, [io_addr]
  502.     add     dx, SIS900_rxdp
  503.     mov     eax, rxd - OS_BASE
  504.     out     dx, eax
  505.     ret
  506.  
  507. ;***************************************************************************
  508. ;* Function: sis900_set_tx_mode
  509. ;*
  510. ;* Description:
  511. ;*    sets the transmit mode to allow for full duplex
  512. ;*
  513. ;*
  514. ;* Arguments:
  515. ;*
  516. ;* Returns:
  517. ;*
  518. ;* Comments:
  519. ;*     If you are having problems transmitting packet try changing the
  520. ;*     Max DMA Burst, Possible settings are as follows:
  521. ;*         0x00000000 = 512 bytes
  522. ;*         0x00100000 = 4 bytes
  523. ;*         0x00200000 = 8 bytes
  524. ;*         0x00300000 = 16 bytes
  525. ;*         0x00400000 = 32 bytes
  526. ;*         0x00500000 = 64 bytes
  527. ;*         0x00600000 = 128 bytes
  528. ;*         0x00700000 = 256 bytes
  529. ;***************************************************************************
  530. SIS900_set_tx_mode:
  531.    mov      ebp,[io_addr]
  532.    lea      edx,[ebp+SIS900_cr]
  533.    in       eax, dx                         ; Get current Command Register
  534.    or       eax, SIS900_TxENA   ;Enable Receive
  535.    out      dx, eax
  536.    lea      edx,[ebp+SIS900_txcfg]; Transmit config Register offset
  537.    mov      eax, SIS900_ATP             ;allow automatic padding
  538.    or       eax, SIS900_HBI             ;allow heartbeat ignore
  539.    or       eax, SIS900_CSI             ;allow carrier sense ignore
  540.    or       eax, 0x00600000     ;Max DMA Burst
  541.    or       eax, 0x00000100     ;TX Fill Threshold
  542.    or       eax, 0x00000020     ;TX Drain Threshold
  543.    out      dx, eax
  544.    ret
  545.  
  546. ;***************************************************************************
  547. ;* Function: sis900_set_rx_mode
  548. ;*
  549. ;* Description:
  550. ;*    sets the receive mode to accept all broadcast packets and packets
  551. ;*    with our MAC address, and reject all multicast packets.  Also allows
  552. ;*    full-duplex
  553. ;*
  554. ;* Arguments:
  555. ;*
  556. ;* Returns:
  557. ;*
  558. ;* Comments:
  559. ;*     If you are having problems receiving packet try changing the
  560. ;*     Max DMA Burst, Possible settings are as follows:
  561. ;*         0x00000000 = 512 bytes
  562. ;*         0x00100000 = 4 bytes
  563. ;*         0x00200000 = 8 bytes
  564. ;*         0x00300000 = 16 bytes
  565. ;*         0x00400000 = 32 bytes
  566. ;*         0x00500000 = 64 bytes
  567. ;*         0x00600000 = 128 bytes
  568. ;*         0x00700000 = 256 bytes
  569. ;***************************************************************************
  570. SIS900_mc_filter: times 16 dw 0
  571. SIS900_set_rx_mode:
  572.    mov      ebp,[io_addr]
  573.     ;**************update Multicast Hash Table in Receive Filter
  574.    mov      ebx, 0xffff
  575.    xor      cl, cl
  576. SIS900_set_rx_mode_Loop:
  577.    mov      eax, ecx
  578.    shl      eax, 1
  579.    mov      [SIS900_mc_filter+eax], bx
  580.    lea      edx,[ebp+SIS900_rfcr]           ; Receive Filter Control Reg offset
  581.    mov      eax, 4                                          ;determine table entry
  582.    add      al, cl
  583.    shl      eax, 16
  584.    out      dx, eax                                         ;tell card which entry to modify
  585.    lea      edx,[ebp+SIS900_rfdr]           ; Receive Filter Control Reg offset
  586.    mov      eax, ebx                                ;entry value
  587.    out      dx, ax                                          ;write value to table in card
  588.    inc      cl                                              ;next entry
  589.    cmp      cl,[sis900_table_entries]   ;
  590.    jl       SIS900_set_rx_mode_Loop
  591.    ;*******Set Receive Filter Control Register*************
  592.    lea      edx,[ebp+SIS900_rfcr]       ; Receive Filter Control Register offset
  593.    mov      eax, SIS900_RFAAB           ;accecpt all broadcast packets
  594.    or       eax, SIS900_RFAAM           ;accept all multicast packets
  595.    or       eax, SIS900_RFAAP           ;Accept all packets
  596.    or       eax, SIS900_RFEN            ;enable receiver filter
  597.    out      dx, eax
  598.    ;******Enable Receiver************
  599.    lea      edx,[ebp+SIS900_cr] ; Command Register offset
  600.    in       eax, dx                         ; Get current Command Register
  601.    or       eax, SIS900_RxENA   ;Enable Receive
  602.    out      dx, eax
  603.    ;*********Set
  604.    lea      edx,[ebp+SIS900_rxcfg]      ; Receive Config Register offset
  605.    mov      eax, SIS900_ATX                     ;Accept Transmit Packets
  606.                                     ; (Req for full-duplex and PMD Loopback)
  607.    or       eax, 0x00600000                     ;Max DMA Burst
  608.    or       eax, 0x00000002                     ;RX Drain Threshold, 8X8 bytes or 64bytes
  609.    out      dx, eax                                     ;
  610.    ret
  611.  
  612. ;***************************************************************************
  613. ; *     SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
  614. ; *     @pci_dev: the sis900 pci device
  615. ; *     @net_dev: the net device to get address for
  616. ; *
  617. ; *     SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
  618. ; *     is shared by
  619. ; *     LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
  620. ; *     and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
  621. ; *     by LAN, otherwise is not. After MAC address is read from EEPROM, send
  622. ; *     EEDONE signal to refuse EEPROM access by LAN.
  623. ; *     The EEPROM map of SiS962 or SiS963 is different to SiS900.
  624. ; *     The signature field in SiS962 or SiS963 spec is meaningless.
  625. ; *     MAC address is read into @net_dev->dev_addr.
  626. ; *done
  627. ;*
  628. ;* Return 0 is EAX = failure
  629. ;*Done+
  630. ;***************************************************************************
  631. if defined SIS900_DEBUG
  632. SIS900_Debug_Str_GetMac_Start db 'Attempting to get SIS900 Mac ID: ',13,10,0
  633. SIS900_Debug_Str_GetMac_Failed db 'Access to EEprom Failed',13,10,0
  634. SIS900_Debug_Str_GetMac_Address db 'Your Mac ID is: ',0
  635. SIS900_Debug_Str_GetMac_Address2 db 'Your SIS96x Mac ID is: ',0
  636. end if
  637. SIS960_get_mac_addr:
  638.    mov      ebp,[io_addr]
  639.    ;**********Send Request for eeprom access*********************
  640.    lea      edx,[ebp+SIS900_mear]               ; Eeprom access register
  641.    mov      eax, SIS900_EEREQ                   ; Request access to eeprom
  642.    out      dx, eax                                             ; Send request
  643.    xor      ebx,ebx                                             ;
  644.    ;******Loop 4000 times and if access not granted error out*****
  645. SIS96X_Get_Mac_Wait:
  646.    in       eax, dx                                     ;get eeprom status
  647.    and      eax, SIS900_EEGNT       ;see if eeprom access granted flag is set
  648.    jnz      SIS900_Got_EEP_Access       ;if it is, go access the eeprom
  649.    inc      ebx                                         ;else keep waiting
  650.    cmp      ebx, 4000                           ;have we tried 4000 times yet?
  651.    jl       SIS96X_Get_Mac_Wait     ;if not ask again
  652.    xor      eax, eax                ;return zero in eax indicating failure
  653.    ;*******Debug **********************
  654. if defined SIS900_DEBUG
  655.    mov esi,SIS900_Debug_Str_GetMac_Failed
  656.    call sys_msg_board_str
  657. end if
  658.    jmp SIS960_get_mac_addr_done
  659.    ;**********EEprom access granted, read MAC from card*************
  660. SIS900_Got_EEP_Access:
  661.     ; zero based so 3-16 bit reads will take place
  662.    mov      ecx, 2
  663. SIS96x_mac_read_loop:
  664.    mov      eax, SIS900_EEPROMMACAddr    ;Base Mac Address
  665.    add      eax, ecx                                 ;Current Mac Byte Offset
  666.    push     ecx
  667.    call     sis900_read_eeprom           ;try to read 16 bits
  668.    pop      ecx
  669.    mov      [node_addr+ecx*2], ax        ;save 16 bits to the MAC ID varible
  670.    dec      ecx                          ;one less word to read
  671.    jns      SIS96x_mac_read_loop         ;if more read more
  672.    mov      eax, 1                       ;return non-zero indicating success
  673.    ;*******Debug Print MAC ID to debug window**********************
  674. if defined SIS900_DEBUG
  675.    mov esi,SIS900_Debug_Str_GetMac_Address2
  676.    call sys_msg_board_str
  677.    mov edx, node_addr
  678.    call Create_Mac_String
  679. end if
  680.    ;**********Tell EEPROM We are Done Accessing It*********************
  681. SIS960_get_mac_addr_done:
  682.    lea      edx,[ebp+SIS900_mear]               ; Eeprom access register
  683.    mov      eax, SIS900_EEDONE           ;tell eeprom we are done
  684.    out      dx,eax
  685.    ret
  686. ;***************************************************************************
  687. ;*      sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
  688. ;*      @pci_dev: the sis900 pci device
  689. ;*      @net_dev: the net device to get address for
  690. ;*
  691. ;*      Older SiS900 and friends, use EEPROM to store MAC address.
  692. ;*      MAC address is read from read_eeprom() into @net_dev->dev_addr.
  693. ;* done/untested
  694. ;***************************************************************************
  695. SIS900_get_mac_addr:
  696.    ;*******Debug **********************
  697. if defined SIS900_DEBUG
  698.    mov esi,SIS900_Debug_Str_GetMac_Start
  699.    call sys_msg_board_str
  700. end if
  701.    ;******** check to see if we have sane EEPROM *******
  702.    mov      eax, SIS900_EEPROMSignature  ;Base Eeprom Signature
  703.    call     sis900_read_eeprom           ;try to read 16 bits
  704.    cmp ax, 0xffff
  705.    je SIS900_Bad_Eeprom
  706.    cmp ax, 0
  707.    je SIS900_Bad_Eeprom
  708.    ;**************Read MacID**************
  709.    ; zero based so 3-16 bit reads will take place
  710.    mov      ecx, 2
  711. SIS900_mac_read_loop:
  712.    mov      eax, SIS900_EEPROMMACAddr    ;Base Mac Address
  713.    add      eax, ecx                                 ;Current Mac Byte Offset
  714.    push     ecx
  715.    call     sis900_read_eeprom           ;try to read 16 bits
  716.    pop      ecx
  717.    mov      [node_addr+ecx*2], ax        ;save 16 bits to the MAC ID storage
  718.    dec      ecx                          ;one less word to read
  719.    jns      SIS900_mac_read_loop         ;if more read more
  720.    mov      eax, 1                       ;return non-zero indicating success
  721.    ;*******Debug Print MAC ID to debug window**********************
  722. if defined SIS900_DEBUG
  723.    mov esi,SIS900_Debug_Str_GetMac_Address
  724.    call sys_msg_board_str
  725.    mov edx, node_addr
  726.    call Create_Mac_String
  727. end if
  728.    ret
  729.  
  730. SIS900_Bad_Eeprom:
  731.    xor eax, eax
  732.    ;*******Debug **********************
  733. if defined SIS900_DEBUG
  734.    mov esi,SIS900_Debug_Str_GetMac_Failed
  735.    call sys_msg_board_str
  736. end if
  737.    ret
  738. ;***************************************************************************
  739. ;*      Get_Mac_SIS635_900_REV: - Get MAC address for model 635
  740. ;*
  741. ;*
  742. ;***************************************************************************
  743. Get_Mac_SIS635_900_REV:
  744. if defined SIS900_DEBUG
  745.     mov     esi,SIS900_Debug_Str_GetMac_Start
  746.     call    sys_msg_board_str
  747. end if
  748.     mov     ebp,[io_addr]
  749.     lea     edx,[ebp+SIS900_rfcr]
  750.     in      eax,dx
  751.     mov     edi,eax ; EDI=rfcrSave
  752.     lea     edx,[ebp+SIS900_cr]
  753.     or      eax,SIS900_RELOAD
  754.     out     dx,eax
  755.     xor     eax,eax
  756.     out     dx,eax
  757.     ; Disable packet filtering before setting filter
  758.     lea     edx,[ebp+SIS900_rfcr]
  759.     mov     eax,edi
  760.     and     edi,not SIS900_RFEN
  761.     out     dx,eax
  762.     ; Load MAC to filter data register
  763.     xor     ecx,ecx
  764.     mov     esi,node_addr
  765. .get_mac_loop:
  766.     lea     edx,[ebp+SIS900_rfcr]
  767.     mov     eax,ecx
  768.     shl     eax,SIS900_RFADDR_shift
  769.     out     dx,eax
  770.     lea     edx,[ebp+SIS900_rfdr]
  771.     in      eax,dx
  772.     mov     [esi],ax
  773.     add     esi,2
  774.     inc     ecx
  775.     cmp     ecx,3
  776.     jne .get_mac_loop
  777.     ; Enable packet filtering
  778.     ;lea     edx,[ebp+SIS900_rfcr]
  779.     ;mov     eax,edi
  780.     ;or      eax,SIS900_RFEN
  781.     ;out     dx, eax
  782.    ;*******Debug Print MAC ID to debug window**********************
  783. if defined SIS900_DEBUG
  784.     mov     esi,SIS900_Debug_Str_GetMac_Address
  785.     call    sys_msg_board_str
  786.     mov     edx, node_addr
  787.     call    Create_Mac_String
  788. end if
  789.     ret
  790. ;***************************************************************************
  791. ;* Function: sis900_read_eeprom
  792. ;*
  793. ;* Description: reads and returns a given location from EEPROM
  794. ;*
  795. ;* Arguments: eax - location:       requested EEPROM location
  796. ;*
  797. ;* Returns:   eax :                contents of requested EEPROM location
  798. ;*
  799. ; Read Serial EEPROM through EEPROM Access Register, Note that location is
  800. ;   in word (16 bits) unit */
  801. ;done+
  802. ;***************************************************************************
  803. sis900_read_eeprom:
  804.    push      esi
  805.    push      edx
  806.    push      ecx
  807.    push      ebx
  808.    mov       ebp,[io_addr]
  809.    mov       ebx, eax              ;location of Mac byte to read
  810.    or        ebx, SIS900_EEread    ;
  811.    lea       edx,[ebp+SIS900_mear] ; Eeprom access register
  812.    xor       eax, eax              ; start send
  813.    out       dx,eax
  814.    call      SIS900_Eeprom_Delay_1
  815.    mov       eax, SIS900_EECLK
  816.    out       dx, eax
  817.    call      SIS900_Eeprom_Delay_1
  818.     ;************ Shift the read command (9) bits out. *********
  819.    mov       cl, 8                                      ;
  820. sis900_read_eeprom_Send:
  821.    mov       eax, 1
  822.    shl       eax, cl
  823.    and       eax, ebx
  824.    jz SIS900_Read_Eeprom_8
  825.    mov       eax, 9
  826.    jmp       SIS900_Read_Eeprom_9
  827. SIS900_Read_Eeprom_8:
  828.    mov       eax, 8
  829. SIS900_Read_Eeprom_9:
  830.    out       dx, eax
  831.    call      SIS900_Eeprom_Delay_1
  832.    or        eax, SIS900_EECLK
  833.    out       dx, eax
  834.    call      SIS900_Eeprom_Delay_1
  835.    cmp       cl, 0
  836.    je        sis900_read_eeprom_Send_Done
  837.    dec       cl
  838.    jmp       sis900_read_eeprom_Send
  839.    ;*********************
  840. sis900_read_eeprom_Send_Done:
  841.    mov       eax, SIS900_EECS           ;
  842.    out       dx, eax
  843.    call      SIS900_Eeprom_Delay_1
  844.     ;********** Read 16-bits of data in ***************
  845.     mov      cx, 16                             ;16 bits to read
  846. sis900_read_eeprom_Send2:
  847.     mov      eax, SIS900_EECS
  848.     out      dx, eax
  849.     call     SIS900_Eeprom_Delay_1
  850.     or       eax, SIS900_EECLK
  851.     out      dx, eax
  852.     call     SIS900_Eeprom_Delay_1
  853.     in       eax, dx
  854.     shl      ebx, 1
  855.     and      eax, SIS900_EEDO
  856.     jz       SIS900_Read_Eeprom_0
  857.     or       ebx, 1
  858. SIS900_Read_Eeprom_0:
  859.    dec       cx
  860.    jnz       sis900_read_eeprom_Send2
  861.    ;************** Terminate the EEPROM access. **************
  862.    xor       eax, eax
  863.    out       dx, eax
  864.    call      SIS900_Eeprom_Delay_1
  865.    mov       eax, SIS900_EECLK
  866.    out       dx, eax
  867.    mov       eax, ebx
  868.    and       eax, 0x0000ffff                    ;return only 16 bits
  869.    pop       ebx
  870.    pop       ecx
  871.    pop       edx
  872.    pop       esi
  873.    ret
  874. ;***************************************************************************
  875. ;   Function
  876. ;      SIS900_Eeprom_Delay_1
  877. ;   Description
  878. ;
  879. ;
  880. ;
  881. ;
  882. ;***************************************************************************
  883. SIS900_Eeprom_Delay_1:
  884.    push eax
  885.    in eax, dx
  886.    pop eax
  887.    ret
  888.  
  889. ;***************************************************************************
  890. ;   Function
  891. ;      SIS900_poll
  892. ;   Description
  893. ;      polls card to see if there is a packet waiting
  894. ;
  895. ;  Currently only supports one descriptor per packet, if packet is fragmented
  896. ;  between multiple descriptors you will lose part of the packet
  897. ;***************************************************************************
  898. if defined SIS900_DEBUG
  899. SIS900_Debug_Pull_Packet_good db 'Good Packet Waiting: ',13,10,0
  900. SIS900_Debug_Pull_Bad_Packet_Status db 'Bad Packet Waiting: Status',13,10,0
  901. SIS900_Debug_Pull_Bad_Packet_Size db 'Bad Packet Waiting: Size',13,10,0
  902. end if
  903. SIS900_poll:
  904.     ;**************Get Status **************
  905.     xor       eax, eax                      ;get RX_Status
  906.     mov      [eth_rx_data_len], ax
  907.     mov       al, [cur_rx]          ;find current discriptor
  908.     imul      eax, 12               ;
  909.     mov       ecx, [rxd+eax+4]          ; get receive status
  910.     ;**************Check Status **************
  911.     mov       ebx, ecx                          ;move status
  912.     ;Check RX_Status to see if packet is waiting
  913.     and       ebx, 0x80000000
  914.     jnz       SIS900_poll_IS_packet
  915.     ret
  916.    ;**********There is a packet waiting check it for errors**************
  917. SIS900_poll_IS_packet:
  918.     mov       ebx, ecx                          ;move status
  919.     and       ebx, 0x67C0000            ;see if there are any errors
  920.     jnz       SIS900_Poll_Error_Status
  921.    ;**************Check size of packet*************
  922.    and       ecx, SIS900_DSIZE                                  ;get packet size minus CRC
  923.    cmp       cx, SIS900_CRC_SIZE
  924.    ;make sure packet contains data
  925.    jle       SIS900_Poll_Error_Size
  926.    ;*******Copy Good Packet to receive buffer******
  927.    sub      cx, SIS900_CRC_SIZE                             ;dont want crc
  928.    mov      word [eth_rx_data_len], cx          ;save size of packet
  929.    ;**********Continue copying packet****************
  930.    push     ecx
  931.    ; first copy dword-wise, divide size by 4
  932.    shr      ecx, 2
  933.    mov      esi, [rxd+eax+8]                            ; set source
  934.    add      esi, OS_BASE                        ; get linear address
  935.    mov      edi, Ether_buffer               ; set destination
  936.    cld                                                                          ; clear direction
  937.    rep      movsd                                                       ; copy the dwords
  938.    pop      ecx
  939.    and      ecx, 3                                                  ;
  940.    rep      movsb
  941.    ;********Debug, tell user we have a good packet*************
  942. if defined SIS900_DEBUG
  943.    mov      esi, SIS900_Debug_Pull_Packet_good
  944.    call     sys_msg_board_str
  945. end if
  946.    jmp SIS900_Poll_Cnt                      ;
  947.    ;*************Error occured let user know through debug window***********
  948. SIS900_Poll_Error_Status:
  949. if defined SIS900_DEBUG
  950.                 mov      esi, SIS900_Debug_Pull_Bad_Packet_Status
  951.                 call     sys_msg_board_str
  952. end if
  953.                 jmp      SIS900_Poll_Cnt
  954. SIS900_Poll_Error_Size:
  955. if defined SIS900_DEBUG
  956.                 mov      esi, SIS900_Debug_Pull_Bad_Packet_Size
  957.                 call     sys_msg_board_str
  958. end if
  959.    ;*************Increment to next available descriptor**************
  960. SIS900_Poll_Cnt:
  961.     ;Reset status, allow ethernet card access to descriptor
  962.    mov      ecx, RX_BUFF_SZ
  963.    mov      [rxd+eax+4], ecx                ;
  964.    inc      [cur_rx]                                            ;get next descriptor
  965.    and      [cur_rx],3                      ;only 4 descriptors 0-3
  966.    ;******Enable Receiver************
  967.    mov          ebp, [io_addr]      ; Base Address
  968.    lea      edx,[ebp+SIS900_cr] ; Command Register offset
  969.    in       eax, dx                         ; Get current Command Register
  970.    or       eax, SIS900_RxENA   ;Enable Receive
  971.    out      dx, eax
  972.    ret
  973. ;***************************************************************************
  974. ;   Function
  975. ;      SIS900_transmit
  976. ;   Description
  977. ;      Transmits a packet of data via the ethernet card
  978. ;         Pointer to 48 bit destination address in edi
  979. ;         Type of packet in bx
  980. ;         size of packet in ecx
  981. ;         pointer to packet data in esi
  982. ;
  983. ;      only one transmit descriptor is used
  984. ;
  985. ;***************************************************************************
  986. if defined SIS900_DEBUG
  987. SIS900_Debug_Transmit_Packet db 'Transmitting Packet: ',13,10,0
  988. SIS900_Debug_Transmit_Packet_Err db 'Transmitting Packet Error: ',13,10,0
  989. end if
  990. str1 db 'Transmitting packet:',13,10,0
  991. str2 db ' ',0
  992. SIS900_transmit:
  993.    mov          ebp, [io_addr]      ; Base Address
  994.    ;******** Stop the transmitter ********
  995.    lea      edx,[ebp+SIS900_cr] ; Command Register offset
  996.    in       eax, dx                         ; Get current Command Register
  997.    or       eax, SIS900_TxDIS   ; Disable Transmitter
  998.    out      dx, eax
  999.    ;*******load Transmit Descriptor Register *******
  1000.    lea      edx,[ebp+SIS900_txdp]
  1001.    mov      eax, txd - OS_BASE
  1002.    out      dx, eax
  1003.    ;******* copy packet to descriptor*******
  1004.    push    esi
  1005.    mov     esi, edi                ;copy destination addess
  1006.    mov     edi, txb
  1007.    cld
  1008.    movsd
  1009.    movsw
  1010.    mov     esi, node_addr  ;copy my mac address
  1011.    movsd
  1012.    movsw
  1013.    mov     [edi], bx       ;copy packet type
  1014.    add     edi, 2
  1015.    pop     esi             ;restore pointer to source of packet
  1016.    push    ecx             ;save packet size
  1017.    shr     ecx, 2          ;divide by 4, size in bytes send in dwords
  1018.    rep     movsd                   ;copy data to decriptor
  1019.    pop     ecx                     ;restore packet size
  1020.    push    ecx             ;save packet size
  1021.    and     ecx, 3          ;last three bytes if not a multiple of 4
  1022.    rep     movsb
  1023.    ;**************set length tag**************
  1024.    pop     ecx                           ;restore packet size
  1025.    add     ecx, SIS900_ETH_HLEN  ;add header to length
  1026.    and     ecx, SIS900_DSIZE     ;
  1027.    ;**************pad to minimum packet size **************not needed
  1028.    ;cmp       ecx, SIS900_ETH_ZLEN
  1029.    ;jge       SIS900_transmit_Size_Ok
  1030.    ;push      ecx
  1031.    ;mov       ebx, SIS900_ETH_ZLEN
  1032.    ;sub       ebx, ecx
  1033.    ;mov       ecx, ebx
  1034.    ;rep       movsb
  1035.    ;pop       ecx
  1036. SIS900_transmit_Size_Ok:
  1037.    mov      [txd+4], dword 0x80000000                   ;card owns descriptor
  1038.    or       [txd+4], ecx                                                ;set size of packet
  1039. if defined SIS900_DEBUG
  1040.    mov      esi, SIS900_Debug_Transmit_Packet
  1041.    call     sys_msg_board_str
  1042. end if
  1043.    ;***************restart the transmitter ********
  1044.    lea      edx,[ebp+SIS900_cr]
  1045.    in       eax, dx                         ; Get current Command Register
  1046.    or       eax, SIS900_TxENA   ; Enable Transmitter
  1047.    out      dx, eax
  1048.    ;****make sure packet transmitted successfully****
  1049. ;   mov      esi,10
  1050. ;   call     delay_ms
  1051.    mov      eax, [txd+4]
  1052.    and      eax, 0x6200000
  1053.    jz       SIS900_transmit_OK
  1054.    ;**************Tell user there was an error through debug window
  1055. if defined SIS900_DEBUG
  1056.    mov      esi, SIS900_Debug_Transmit_Packet_Err
  1057.    call     sys_msg_board_str
  1058. end if
  1059. SIS900_transmit_OK:
  1060.    ;******** Disable interrupts by clearing the interrupt mask. ********
  1061.    lea      edx,[ebp+SIS900_imr]            ; Interupt Mask Register
  1062.    xor      eax, eax
  1063.    out      dx,eax
  1064.    ret
  1065.  
  1066. ;***************************************************************************
  1067. ;* Function: Create_Mac_String
  1068. ;*
  1069. ;* Description: Converts the 48 bit value to a string for display
  1070. ;*
  1071. ;* String Format: XX:XX:XX:XX:XX:XX
  1072. ;*
  1073. ;* Arguments: node_addr is location of 48 bit MAC ID
  1074. ;*
  1075. ;* Returns:   Prints string to general debug window
  1076. ;*
  1077. ;*
  1078. ;done
  1079. ;***************************************************************************
  1080. if defined SIS900_DEBUG
  1081.  
  1082. SIS900_Char_String    db '0','1','2','3','4','5','6','7','8','9'
  1083.                       db 'A','B','C','D','E','F'
  1084. Mac_str_build: times 20 db 0
  1085. Create_Mac_String:
  1086.    pusha
  1087.    xor ecx, ecx
  1088. Create_Mac_String_loop:
  1089.    mov al,byte [edx+ecx];[node_addr+ecx]
  1090.    push eax
  1091.    shr eax, 4
  1092.    and eax, 0x0f
  1093.    mov bl, byte [SIS900_Char_String+eax]
  1094.    mov [Mac_str_build+ecx*3], bl
  1095.    pop eax
  1096.    and eax, 0x0f
  1097.    mov bl, byte [SIS900_Char_String+eax]
  1098.    mov [Mac_str_build+1+ecx*3], bl
  1099.    cmp ecx, 5
  1100.    je Create_Mac_String_done
  1101.    mov bl, ':'
  1102.    mov [Mac_str_build+2+ecx*3], bl
  1103.    inc ecx
  1104.    jmp Create_Mac_String_loop
  1105. Create_Mac_String_done:                                 ;Insert CR and Zero Terminate
  1106.    mov [Mac_str_build+2+ecx*3],byte 13
  1107.    mov [Mac_str_build+3+ecx*3],byte 10
  1108.    mov [Mac_str_build+4+ecx*3],byte 0
  1109.    mov esi, Mac_str_build
  1110.    call sys_msg_board_str                               ;Print String to message board
  1111.    popa
  1112.    ret
  1113. end if
  1114. ;***************************************************************************
  1115. ;*      Set device to be a busmaster in case BIOS neglected to do so.
  1116. ;*      Also adjust PCI latency timer to a reasonable value, 64.
  1117. ;***************************************************************************
  1118. SIS900_adjust_pci_device:
  1119.    ;*******Get current setting************************
  1120.    mov     al, 2                                        ;read a word
  1121.    mov     bh, [pci_dev]
  1122.    mov     ah, [pci_bus]
  1123.    mov     bl, 0x04                                 ;from command Register
  1124.    call    pci_read_reg
  1125.    ;******see if its already set as bus master********
  1126.    mov      bx, ax
  1127.    and      bx,5
  1128.    cmp      bx,5
  1129.    je       SIS900_adjust_pci_device_Latency
  1130.    ;******Make card a bus master*******
  1131.    mov      cx, ax                              ;value to write
  1132.    mov     bh, [pci_dev]
  1133.    mov     al, 2                                ;write a word
  1134.    or       cx,5
  1135.    mov     ah, [pci_bus]
  1136.    mov     bl, 0x04                             ;to command register
  1137.    call    pci_write_reg
  1138.    ;******Check latency setting***********
  1139. SIS900_adjust_pci_device_Latency:
  1140.    ;*******Get current latency setting************************
  1141.    mov     al, 1                                        ;read a byte
  1142.    mov     bh, [pci_dev]
  1143.    mov     ah, [pci_bus]
  1144.    mov     bl, 0x0D                                 ;from Lantency Timer Register
  1145.    call    pci_read_reg
  1146.    ;******see if its aat least 64 clocks********
  1147.    cmp      ax,64
  1148.    jge      SIS900_adjust_pci_device_Done
  1149.    ;******Set latency to 32 clocks*******
  1150.    mov     cx, 64                               ;value to write
  1151.    mov     bh, [pci_dev]
  1152.    mov     al, 1                                ;write a byte
  1153.    mov     ah, [pci_bus]
  1154.    mov     bl, 0x0D                             ;to Lantency Timer Register
  1155.    call    pci_write_reg
  1156.    ;******Check latency setting***********
  1157. SIS900_adjust_pci_device_Done:
  1158.    ret
  1159.