Subversion Repositories Kolibri OS

Rev

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

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