From 5ae9070151d85b46e257017af80227e351b4603f Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Tue, 7 Aug 2012 20:22:07 +0000 Subject: [PATCH] SIS900: -refactoring -fixed SIS900-635 MAC read -fixed alignment issues -added multiple TX descriptor support TODO: clear sent packets from memory git-svn-id: svn://kolibrios.org@2910 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/branches/net/drivers/sis900.asm | 915 +++++++++++-------------- 1 file changed, 382 insertions(+), 533 deletions(-) diff --git a/kernel/branches/net/drivers/sis900.asm b/kernel/branches/net/drivers/sis900.asm index b1c41559ce..5ea622ebe6 100644 --- a/kernel/branches/net/drivers/sis900.asm +++ b/kernel/branches/net/drivers/sis900.asm @@ -25,10 +25,10 @@ format MS COFF - NUM_RX_DESC = 4 ;* Number of RX descriptors * - NUM_TX_DESC = 1 ;* Number of TX descriptors * - RX_BUFF_SZ = 1520 ;* Buffer size for each Rx buffer * - TX_BUFF_SZ = 1516 ;* Buffer size for each Tx buffer * + NUM_RX_DESC = 4 ; Number of RX descriptors + NUM_TX_DESC = 4 ; Number of TX descriptors + RX_BUFF_SZ = 1520 ; Buffer size for each Rx buffer + TX_BUFF_SZ = 1516 ; Buffer size for each Tx buffer MAX_ETH_FRAME_SIZE = 1516 API_VERSION = 0x01000100 @@ -40,6 +40,164 @@ format MS COFF __DEBUG__ = 1 __DEBUG_LEVEL__ = 1 + DSIZE = 0x00000fff + CRC_SIZE = 4 + RFADDR_shift = 16 + +; If you are having problems sending/receiving packet try changing the +; Max DMA Burst, Possible settings are as follows: +; +; 0x00000000 = 512 bytes +; 0x00100000 = 4 bytes +; 0x00200000 = 8 bytes +; 0x00300000 = 16 bytes +; 0x00400000 = 32 bytes +; 0x00500000 = 64 bytes +; 0x00600000 = 128 bytes +; 0x00700000 = 256 bytes + + RX_DMA = 0x00600000 + TX_DMA = 0x00600000 + +;------------------------------------------------------------------------------------------------- +; Symbolic offsets to registers. + cr = 0x0 ; Command Register + cfg = 0x4 ; Configuration Register + mear = 0x8 ; EEPROM Access Register + ptscr = 0xc ; PCI Test Control Register + isr = 0x10 ; Interrupt Status Register + imr = 0x14 ; Interrupt Mask Register + ier = 0x18 ; Interrupt Enable Register + epar = 0x18 ; Enhanced PHY Access Register + txdp = 0x20 ; Transmit Descriptor Pointer Register + txcfg = 0x24 ; Transmit Configuration Register + rxdp = 0x30 ; Receive Descriptor Pointer Register + rxcfg = 0x34 ; Receive Configuration Register + flctrl = 0x38 ; Flow Control Register + rxlen = 0x3c ; Receive Packet Length Register + rfcr = 0x48 ; Receive Filter Control Register + rfdr = 0x4C ; Receive Filter Data Register + pmctrl = 0xB0 ; Power Management Control Register + pmer = 0xB4 ; Power Management Wake-up Event Register + +; Command Register Bits + RELOAD = 0x00000400 + ACCESSMODE = 0x00000200 + RESET = 0x00000100 + SWI = 0x00000080 + RxRESET = 0x00000020 + TxRESET = 0x00000010 + RxDIS = 0x00000008 + RxENA = 0x00000004 + TxDIS = 0x00000002 + TxENA = 0x00000001 + +; Configuration Register Bits + DESCRFMT = 0x00000100 ; 7016 specific + REQALG = 0x00000080 + SB = 0x00000040 + POW = 0x00000020 + EXD = 0x00000010 + PESEL = 0x00000008 + LPM = 0x00000004 + BEM = 0x00000001 + RND_CNT = 0x00000400 + FAIR_BACKOFF = 0x00000200 + EDB_MASTER_EN = 0x00002000 + +; Eeprom Access Reigster Bits + MDC = 0x00000040 + MDDIR = 0x00000020 + MDIO = 0x00000010 ; 7016 specific + EECS = 0x00000008 + EECLK = 0x00000004 + EEDO = 0x00000002 + EEDI = 0x00000001 + +; TX Configuration Register Bits + ATP = 0x10000000 ; Automatic Transmit Padding + MLB = 0x20000000 ; Mac Loopback Enable + HBI = 0x40000000 ; HeartBeat Ignore (Req for full-dup) + CSI = 0x80000000 ; CarrierSenseIgnore (Req for full-du + +; RX Configuration Register Bits + AJAB = 0x08000000 ; + ATX = 0x10000000 ; Accept Transmit Packets + ARP = 0x40000000 ; accept runt packets (<64bytes) + AEP = 0x80000000 ; accept error packets + +; Interrupt Register Bits + WKEVT = 0x10000000 + TxPAUSEEND = 0x08000000 + TxPAUSE = 0x04000000 + TxRCMP = 0x02000000 ; Transmit Reset Complete + RxRCMP = 0x01000000 ; Receive Reset Complete + DPERR = 0x00800000 + SSERR = 0x00400000 + RMABT = 0x00200000 + RTABT = 0x00100000 + RxSOVR = 0x00010000 + HIBERR = 0x00008000 + SWINT = 0x00001000 + MIBINT = 0x00000800 + TxURN = 0x00000400 + TxIDLE = 0x00000200 + TxERR = 0x00000100 + TxDESC = 0x00000080 + TxOK = 0x00000040 + RxORN = 0x00000020 + RxIDLE = 0x00000010 + RxEARLY = 0x00000008 + RxERR = 0x00000004 + RxDESC = 0x00000002 + RxOK = 0x00000001 + +; Interrupt Enable Register Bits + IE = RxOK + TxOK + +; Revision ID + SIS900B_900_REV = 0x03 + SIS630A_900_REV = 0x80 + SIS630E_900_REV = 0x81 + SIS630S_900_REV = 0x82 + SIS630EA1_900_REV = 0x83 + SIS630ET_900_REV = 0x84 + SIS635A_900_REV = 0x90 + SIS900_960_REV = 0x91 + +; Receive Filter Control Register Bits + RFEN = 0x80000000 ; enable + RFAAB = 0x40000000 ; accept all broadcasts + RFAAM = 0x20000000 ; accept all multicasts + RFAAP = 0x10000000 ; accept all packets + +; Reveive Filter Data Mask + RFDAT = 0x0000FFFF + +; Eeprom Address + EEPROMSignature = 0x00 + EEPROMVendorID = 0x02 + EEPROMDeviceID = 0x03 + EEPROMMACAddr = 0x08 + EEPROMChecksum = 0x0b + +; The EEPROM commands include the alway-set leading bit. + EEread = 0x0180 + EEwrite = 0x0140 + EEerase = 0x01C0 + EEwriteEnable = 0x0130 + EEwriteDisable = 0x0100 + EEeraseAll = 0x0120 + EEwriteAll = 0x0110 + EEaddrMask = 0x013F + EEcmdShift = 16 + +; For SiS962 or SiS963, request the eeprom software access + EEREQ = 0x00000400 + EEDONE = 0x00000200 + EEGNT = 0x00000100 + + include 'proc32.inc' include 'imports.inc' include 'fdo.inc' @@ -48,6 +206,7 @@ include 'netdrv.inc' public START public version + virtual at ebx device: @@ -63,10 +222,6 @@ virtual at ebx .pci_revision db ? .table_entries db ? - dw ? ; align 4 - - .special_func dd ? - .txd rd (4 * NUM_TX_DESC) .rxd rd (4 * NUM_RX_DESC) @@ -170,9 +325,8 @@ service_proc: mov [device.pci_dev], cl ; 4j. Fill in the direct call addresses into the struct. ; Note that get_MAC pointer is filled in initialization by probe. - mov [device.reset], init + mov [device.reset], reset mov [device.transmit], transmit -; mov [device.get_MAC], read_mac mov [device.set_MAC], write_mac mov [device.unload], unload mov [device.name], my_service @@ -246,175 +400,11 @@ unload: ret -;******************************************************************** -; Comments: -; Known to work with the following SIS900 ethernet cards: -; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x91 -; - Device ID: 0x0900 Vendor ID: 0x1039 Revision: 0x90 -; -; If your card is not listed, try it and let me know if it -; functions properly and it will be aded to the list. If not -; we may be able to add support for it. -; -; ToDo: -; - Enable MII interface for reading speed -; and duplex settings. -; - Update receive routine to support packet fragmentation. -; - Add additional support for other sis900 based cards -; -;******************************************************************** - - ETH_ALEN = 6 ; Size of Ethernet address - ETH_HLEN = 14 ; Size of ethernet header - ETH_ZLEN = 60 ; Minimum packet length - DSIZE = 0x00000fff - CRC_SIZE = 4 - RFADDR_shift = 16 - -; Symbolic offsets to registers. - cr = 0x0 ; Command Register - cfg = 0x4 ; Configuration Register - mear = 0x8 ; EEPROM Access Register - ptscr = 0xc ; PCI Test Control Register - isr = 0x10 ; Interrupt Status Register - imr = 0x14 ; Interrupt Mask Register - ier = 0x18 ; Interrupt Enable Register - epar = 0x18 ; Enhanced PHY Access Register - txdp = 0x20 ; Transmit Descriptor Pointer Register - txcfg = 0x24 ; Transmit Configuration Register - rxdp = 0x30 ; Receive Descriptor Pointer Register - rxcfg = 0x34 ; Receive Configuration Register - flctrl = 0x38 ; Flow Control Register - rxlen = 0x3c ; Receive Packet Length Register - rfcr = 0x48 ; Receive Filter Control Register - rfdr = 0x4C ; Receive Filter Data Register - pmctrl = 0xB0 ; Power Management Control Register - pmer = 0xB4 ; Power Management Wake-up Event Register - -; Command Register Bits - RELOAD = 0x00000400 - ACCESSMODE = 0x00000200 - RESET = 0x00000100 - SWI = 0x00000080 - RxRESET = 0x00000020 - TxRESET = 0x00000010 - RxDIS = 0x00000008 - RxENA = 0x00000004 - TxDIS = 0x00000002 - TxENA = 0x00000001 - -; Configuration Register Bits - DESCRFMT = 0x00000100 ; 7016 specific - REQALG = 0x00000080 - SB = 0x00000040 - POW = 0x00000020 - EXD = 0x00000010 - PESEL = 0x00000008 - LPM = 0x00000004 - BEM = 0x00000001 - RND_CNT = 0x00000400 - FAIR_BACKOFF = 0x00000200 - EDB_MASTER_EN = 0x00002000 - -; Eeprom Access Reigster Bits - MDC = 0x00000040 - MDDIR = 0x00000020 - MDIO = 0x00000010 ; 7016 specific - EECS = 0x00000008 - EECLK = 0x00000004 - EEDO = 0x00000002 - EEDI = 0x00000001 - -; TX Configuration Register Bits - ATP = 0x10000000 ;Automatic Transmit Padding - MLB = 0x20000000 ;Mac Loopback Enable - HBI = 0x40000000 ;HeartBeat Ignore (Req for full-dup) - CSI = 0x80000000 ;CarrierSenseIgnore (Req for full-du - -; RX Configuration Register Bits - AJAB = 0x08000000 ; - ATX = 0x10000000 ;Accept Transmit Packets - ARP = 0x40000000 ;accept runt packets (<64bytes) - AEP = 0x80000000 ;accept error packets - -; Interrupt Reigster Bits - WKEVT = 0x10000000 - TxPAUSEEND = 0x08000000 - TxPAUSE = 0x04000000 - TxRCMP = 0x02000000 - RxRCMP = 0x01000000 - DPERR = 0x00800000 - SSERR = 0x00400000 - RMABT = 0x00200000 - RTABT = 0x00100000 - RxSOVR = 0x00010000 - HIBERR = 0x00008000 - SWINT = 0x00001000 - MIBINT = 0x00000800 - TxURN = 0x00000400 - TxIDLE = 0x00000200 - TxERR = 0x00000100 - TxDESC = 0x00000080 - TxOK = 0x00000040 - RxORN = 0x00000020 - RxIDLE = 0x00000010 - RxEARLY = 0x00000008 - RxERR = 0x00000004 - RxDESC = 0x00000002 - RxOK = 0x00000001 - -; Interrupt Enable Register Bits - IE = RxOK + TxOK - -; Revision ID - SIS900B_900_REV = 0x03 - SIS630A_900_REV = 0x80 - SIS630E_900_REV = 0x81 - SIS630S_900_REV = 0x82 - SIS630EA1_900_REV = 0x83 - SIS630ET_900_REV = 0x84 - SIS635A_900_REV = 0x90 - SIS900_960_REV = 0x91 - -; Receive Filter Control Register Bits - RFEN = 0x80000000 - RFAAB = 0x40000000 - RFAAM = 0x20000000 - RFAAP = 0x10000000 - RFPromiscuous = 0x70000000 - -; Reveive Filter Data Mask - RFDAT = 0x0000FFFF - -; Eeprom Address - EEPROMSignature = 0x00 - EEPROMVendorID = 0x02 - EEPROMDeviceID = 0x03 - EEPROMMACAddr = 0x08 - EEPROMChecksum = 0x0b - -;The EEPROM commands include the alway-set leading bit. - EEread = 0x0180 - EEwrite = 0x0140 - EEerase = 0x01C0 - EEwriteEnable = 0x0130 - EEwriteDisable = 0x0100 - EEeraseAll = 0x0120 - EEwriteAll = 0x0110 - EEaddrMask = 0x013F - EEcmdShift = 16 - -;For SiS962 or SiS963, request the eeprom software access - EEREQ = 0x00000400 - EEDONE = 0x00000200 - EEGNT = 0x00000100 - - ;*************************************************************************** ; ; probe ; -; Searches for an ethernet card, enables it and clears the rx buffer +; checks the card and enables it ; ; TODO: probe mii transceivers ; @@ -423,11 +413,13 @@ align 4 probe: DEBUGF 1, "Probe\n" +; wake up device CHECKME movzx eax, [device.pci_bus] movzx edx, [device.pci_dev] - stdcall PciWrite8, eax, edx, 0x40, 0 ; Wake Up Chip + stdcall PciWrite8, eax, edx, 0x40, 0 make_bus_master [device.pci_bus], [device.pci_dev] + adjust_latency [device.pci_bus], [device.pci_dev], 64 ; Get Card Revision movzx eax, [device.pci_bus] @@ -437,38 +429,21 @@ probe: ; Look up through the specific_table mov esi, specific_table - .loop: + .tableloop: cmp dword [esi], 0 ; Check if we reached end of the list - je .error + je .notsupported cmp al, [esi] ; Check if revision is OK je .ok add esi, 12 ; Advance to next entry - jmp .loop + jmp .tableloop - .error: - DEBUGF 1, "Device not supported!\n" - or eax, -1 - ret - -; Find Get Mac Function .ok: - mov eax, [esi + 4] ; Get pointer to "get MAC" function + mov eax, [esi + 4] ; Get pointer to "get MAC" function mov [device.get_MAC], eax - mov eax, [esi + 8] ; Get pointer to special initialization fn - mov [device.special_func], eax -; Get MAC call [device.get_MAC] -; Call special initialization fn if requested - - cmp [device.special_func], 0 - je @f - call [device.special_func] - @@: - ; Set table entries - mov [device.table_entries], 16 cmp [device.pci_revision], SIS635A_900_REV jae @f @@ -479,56 +454,16 @@ probe: ; TODO: Probe for mii transceiver + jmp reset -;*************************************************************************** -; -; init -; -; resets the ethernet controller chip and various -; data structures required for sending and receiving packets. -; -;*************************************************************************** -align 4 -init: - DEBUGF 1, "Init\n" + .notsupported: + DEBUGF 1, "Device not supported\n" + or eax, -1 - call reset - jnz .ret - call init_rxfilter - call init_txd - call init_rxd - call set_rx_mode - call set_tx_mode - ;call check_mode - -; enable interrupts on packet receive - - xor eax, eax - inc eax ; eax = 1 = RxOK - set_io 0 - set_io imr - out dx, eax - -; globally enable interrupts - - set_io ier - out dx, eax ; eax is still 1 - xor eax, eax - - mov [device.mtu], 1514 - - .ret: ret -;*************************************************************************** -; -; reset -; -; disables interrupts and soft resets the controller chip -; -;*************************************************************************** -align 4 reset: + DEBUGF 1, "reset\n" movzx eax, [device.irq_line] @@ -563,10 +498,11 @@ reset: mov ecx, 1000 .loop: dec ecx - jz .error - in eax, dx ; move interrup status to eax - test eax, 0x03000000 ; CHECKME + jz .fail + in eax, dx ; read interrupt status + test eax, TxRCMP + RxRCMP jz .loop + DEBUGF 1, "status=%x\n", eax ;------------------------------------------------------ ; Set Configuration Register depending on Card Revision @@ -576,129 +512,82 @@ reset: cmp [device.pci_revision], SIS635A_900_REV je .match cmp [device.pci_revision], SIS900B_900_REV ; Check card revision - je .match - out dx, eax ; no revision match - jmp .done - + jne .done .match: ; Revision match or eax, RND_CNT ; Configuration Register Bit + .done: out dx, eax - .done: - xor eax, eax - ret + DEBUGF 1, "Initialising RX Filter\n" - .error: - DEBUGF 1, "Reset failed!\n" - or eax, -1 - ret - - -;*************************************************************************** -; -; sis_init_rxfilter -; -; sets receive filter address to our MAC address -; -;*************************************************************************** -align 4 -init_rxfilter: - DEBUGF 1, "Init RxFilter\n" - -;------------------------------------ ; Get Receive Filter Control Register - - set_io 0 set_io rfcr in eax, dx push eax -;----------------------------------------------- ; disable packet filtering before setting filter - and eax, not RFEN out dx, eax -;-------------------------------------- ; load MAC addr to filter data register - xor ecx, ecx -RXINT_Mac_Write: ; high word of eax tells card which mac byte to write + .macloop: mov eax, ecx set_io 0 set_io rfcr - shl eax, 16 ; + shl eax, 16 ; high word of eax tells card which mac byte to write out dx, eax ; set_io rfdr - mov ax, word [device.mac+ecx*2] ; Get Mac ID word + mov ax, word [device.mac + ecx*2] ; Get Mac ID word out dx, ax ; Send Mac ID inc cl ; send next word cmp cl, 3 ; more to send? - jne RXINT_Mac_Write + jne .macloop -;------------------------ ; enable packet filtering - - pop eax ;old register value + pop eax ; old register value set_io rfcr - or eax, RFEN ;enable filtering - out dx, eax ;set register + or eax, RFEN ; enable filtering + out dx, eax ; set register - ret + DEBUGF 1, "Initialising TX Descriptors\n" -;*************************************************************************** -; -; init_txd -; -; initializes the Tx descriptor -; -;*************************************************************************** -align 4 -init_txd: - DEBUGF 1, "Init TxD\n" + mov ecx, NUM_TX_DESC + lea esi, [device.txd] + .txdescloop: + lea eax, [esi + 16] ; next ptr + GetRealAddr + mov dword [esi], eax ; link to next desc + mov dword [esi + 4], 0 ; status field + mov dword [esi + 8], 0 ; ptr to buffer + add esi, 16 + dec ecx + jnz .txdescloop -;------------------------- -; initialize TX descriptor - - mov dword [device.txd], 0 ; put link to next descriptor in link field - mov dword [device.txd + 4], 0 ; clear status field - mov dword [device.txd + 8], 0 ; ptr to buffer - -;---------------------------------- -; load Transmit Descriptor Register - - set_io 0 - set_io txdp ; TX Descriptor Pointer lea eax, [device.txd] GetRealAddr - out dx, eax ; move the pointer + mov dword [esi - 16], eax ; correct last descriptor link ptr - ret + set_io txdp ; TX Descriptor Pointer +; lea eax, [device.txd] +; GetRealAddr + out dx, eax -;*************************************************************************** -; -; init_rxd -; -; initializes the Rx descriptor ring -; -;*************************************************************************** -align 4 -init_rxd: - DEBUGF 1, "Init RxD\n" + mov [device.cur_tx], 0 ; Set current tx descriptor to 0 + + DEBUGF 1, "Initialising RX Descriptors\n" -; init RX descriptors mov ecx, NUM_RX_DESC lea esi, [device.rxd] - - .loop: + .rxdescloop: lea eax, [esi + 16] ; next ptr GetRealAddr mov dword [esi], eax mov dword [esi + 4], RX_BUFF_SZ ; size - push ecx + push ecx esi stdcall KernelAlloc, RX_BUFF_SZ - pop ecx + pop esi ecx test eax, eax jz .fail mov dword [esi + 12], eax ; address @@ -706,141 +595,82 @@ init_rxd: mov dword [esi + 8], eax ; real address add esi, 16 dec ecx - jnz .loop + jnz .rxdescloop lea eax, [device.rxd] GetRealAddr mov dword [esi - 16], eax ; correct last descriptor link ptr -; And output ptr to first desc, to device - set_io 0 set_io rxdp +; lea eax, [device.rxd] +; GetRealAddr out dx, eax - mov [device.cur_rx], 0 ; Set curent rx discriptor to 0 + mov [device.cur_rx], 0 ; Set current rx descriptor to 0 - .fail: ;;; TODO: abort instead! - ret - - -;*************************************************************************** -; -; set_tx_mode -; -; sets the transmit mode to allow for full duplex -; -; If you are having problems transmitting packet try changing the -; Max DMA Burst, Possible settings are as follows: -; -; 0x00000000 = 512 bytes -; 0x00100000 = 4 bytes -; 0x00200000 = 8 bytes -; 0x00300000 = 16 bytes -; 0x00400000 = 32 bytes -; 0x00500000 = 64 bytes -; 0x00600000 = 128 bytes -; 0x00700000 = 256 bytes -; -;*************************************************************************** -align 4 -set_tx_mode: - DEBUGF 1, "set TX mode\n" + DEBUGF 1, "setting RX mode\n" + xor cl, cl + .rxfilterloop: set_io 0 - set_io cr - in eax, dx ; Get current Command Register - or eax, TxENA ; Enable Receive - out dx, eax + set_io rfcr ; Receive Filter Control Reg offset + mov eax, 4 ; determine table entry + add al, cl + shl eax, 16 + out dx, eax ; tell card which entry to modify - set_io txcfg ; Transmit config Register offset - mov eax, ATP + HBI + CSI +0x00600120 - ; allow automatic padding - ; allow heartbeat ignore - ; allow carrier sense ignore - ; Max DMA Burst (128 bytes) - ; TX Fill Threshold - ; TX Drain Threshold - out dx, eax + set_io rfdr ; Receive Filter Control Reg offset + mov eax, 0xffff ; entry value + out dx, ax ; write value to table in card - ret - -;*************************************************************************** -; -; set_rx_mode -; -; sets the receive mode to accept all broadcast packets and packets -; with our MAC address, and reject all multicast packets. Also allows -; full-duplex -; -; If you are having problems receiving packet try changing the -; Max DMA Burst, Possible settings are as follows: -; -; 0x00000000 = 512 bytes -; 0x00100000 = 4 bytes -; 0x00200000 = 8 bytes -; 0x00300000 = 16 bytes -; 0x00400000 = 32 bytes -; 0x00500000 = 64 bytes -; 0x00600000 = 128 bytes -; 0x00700000 = 256 bytes -; -;*************************************************************************** -align 4 -set_rx_mode: - DEBUGF 1, "set RX mode\n" - -;---------------------------------------------- -; update Multicast Hash Table in Receive Filter - - xor cl, cl - .loop: - set_io 0 - set_io rfcr ; Receive Filter Control Reg offset - mov eax, 4 ; determine table entry - add al, cl - shl eax, 16 - out dx, eax ; tell card which entry to modify - - set_io rfdr ; Receive Filter Control Reg offset - mov eax, 0xffff ; entry value - out dx, ax ; write value to table in card - - inc cl ; next entry - cmp cl, [device.table_entries] - jl .loop - -;------------------------------------ -; Set Receive Filter Control Register + inc cl ; next entry + cmp cl, [device.table_entries] + jb .rxfilterloop set_io rfcr ; Receive Filter Control Register offset mov eax, RFAAB + RFAAM + RFAAP + RFEN - ; accecpt all broadcast packets - ; accept all multicast packets - ; Accept all packets - ; enable receiver filter out dx, eax -;---------------- -; Enable Receiver + + set_io rxcfg ; Receive Config Register offset + mov eax, ATX + RX_DMA + 2 ; 0x2 : RX Drain Threshold = 8*8=64 bytes + out dx, eax + + DEBUGF 1, "setting TX mode\n" + + set_io txcfg ; Transmit config Register offset + mov eax, ATP + HBI + CSI + TX_DMA + 0x120 + ; TX Fill threshold = 0x100 + ; TX Drain Threshold = 0x20 + out dx, eax + + DEBUGF 1, "Enabling interrupts\n" + + set_io imr + mov eax, IE ; Interrupt enable mask + out dx, eax set_io cr - in eax, dx ; Get current Command Register + in eax, dx or eax, RxENA ; Enable Receive out dx, eax -;------------------- -; Configure Receiver - - set_io rxcfg ; Receive Config Register offset - mov eax, ATX + 0x00600002 - ; Accept Transmit Packets - ; (Req for full-duplex and PMD Loopback) - ; Max DMA Burst - ; RX Drain Threshold, 8X8 bytes or 64bytes + set_io ier ; Interrupt enable + mov eax, 1 out dx, eax + mov [device.mtu], 1514 + xor eax, eax + ret + .fail: + DEBUGF 1, "Resetting device failed\n" + or eax, -1 + + ret + + ;*************************************************************************** ; ; SIS960_get_mac_addr: - Get MAC address for SiS962 or SiS963 model @@ -981,13 +811,12 @@ SIS900_get_mac_addr: ;*************************************************************************** align 4 Get_Mac_SIS635_900_REV: - DEBUGF 1, "SIS635 - get mac: " set_io 0 set_io rfcr in eax, dx - mov edi, eax ; EDI=rfcrSave + mov esi, eax set_io cr or eax, RELOAD @@ -1000,14 +829,14 @@ Get_Mac_SIS635_900_REV: ; Disable packet filtering before setting filter set_io rfcr - mov eax, edi - and edi, not RFEN + mov eax, esi + and eax, not RFEN out dx, eax ;--------------------------------- ; Load MAC to filter data register - mov ecx, 3 + xor ecx, ecx lea edi, [device.mac] .loop: set_io 0 @@ -1017,17 +846,19 @@ Get_Mac_SIS635_900_REV: out dx, eax set_io rfdr - in eax, dx + in ax, dx stosw - loop .loop + inc ecx + cmp ecx, 3 + jb .loop ;------------------------ ; Enable packet filtering -; set_io rfcr -; mov eax, edi -; or eax, RFEN -; out dx, eax + set_io rfcr + mov eax, esi + or eax, RFEN + out dx, eax DEBUGF 2,"%x-%x-%x-%x-%x-%x\n",[device.mac]:2,[device.mac+1]:2,[device.mac+2]:2,[device.mac+3]:2,[device.mac+4]:2,[device.mac+5]:2 @@ -1125,10 +956,81 @@ read_eeprom: align 4 write_mac: - DEBUGF 1,'Setting MAC is not supported for SIS900 card.\n' + DEBUGF 1,'Setting MAC is not supported for SIS900 card.\n' add esp, 6 ret + + + +;*************************************************************************** +; Function +; transmit +; Description +; Transmits a packet of data via the ethernet card +; buffer pointer in [esp+4] +; size of buffer in [esp+8] +; pointer to device structure in ebx +; +;*************************************************************************** +align 4 +transmit: + DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n",[esp+4],[esp+8] + mov eax, [esp+4] + DEBUGF 1,"To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ + [eax+00]:2,[eax+01]:2,[eax+02]:2,[eax+03]:2,[eax+04]:2,[eax+05]:2,\ + [eax+06]:2,[eax+07]:2,[eax+08]:2,[eax+09]:2,[eax+10]:2,[eax+11]:2,\ + [eax+13]:2,[eax+12]:2 + + cmp dword [esp + 8], MAX_ETH_FRAME_SIZE + ja .error + cmp dword [esp + 8], 60 + jb .error + + movzx ecx, [device.cur_tx] + shl ecx, 4 ; *16 + lea ecx, [device.txd + ecx] + +;; TODO: check if desc is empty (for example: check for eax, 0x6200000 at [ecx+4] +;;; or: count number of available descriptors + + mov eax, [esp + 4] + mov dword [ecx + 12], eax + GetRealAddr + mov dword [ecx + 8], eax ; buffer address + + mov eax, [esp + 8] + and eax, DSIZE + or eax, 0x80000000 ; card owns descriptor + mov dword [ecx + 4], eax ; status field + + set_io 0 + set_io cr + in eax, dx + or eax, TxENA ; Enable the transmit state machine + out dx, eax + + inc [device.cur_tx] + and [device.cur_tx], NUM_TX_DESC-1 + +; update stats + mov ecx, [esp + 8] + inc [device.packets_tx] + add dword [device.bytes_tx], ecx + adc dword [device.bytes_tx + 4], 0 + + .finish: + DEBUGF 1,"Packet sent!\n" + xor eax, eax + ret 8 + + .error: + DEBUGF 1,"ERROR!\n" + stdcall KernelFree, [esp+4] + or eax, -1 + ret 8 + + ;*************************************************************************** ; ; int_handler @@ -1141,24 +1043,25 @@ write_mac: ;*************************************************************************** align 4 int_handler: - DEBUGF 1, "Int!\n" ; find pointer of device which made IRQ occur mov esi, device_list mov ecx, [devices] test ecx, ecx jz .nothing -.nextdevice: + .nextdevice: mov ebx, [esi] set_io 0 set_io isr - in eax, dx ; note that this clears all interrupts + in eax, dx ; note that this clears all interrupts test ax, IE jnz .got_it loop .nextdevice -.nothing: + .nothing: ret -.got_it: + .got_it: + + DEBUGF 1,"IRQ! status=%x\n", ax test ax, RxOK jz .no_rx @@ -1167,9 +1070,9 @@ int_handler: ;----------- ; Get Status - movzx eax, [device.cur_rx] ; find current discriptor - shl eax, 4 ; * 16 - mov ecx, dword[device.rxd+eax+4] ; get receive status + movzx eax, [device.cur_rx] ; find current descriptor + shl eax, 4 ; * 16 + mov ecx, dword[device.rxd + eax + 4] ; get receive status ;------------------------------------------- ; Check RX_Status to see if packet is waiting @@ -1187,60 +1090,51 @@ int_handler: ; Check size of packet and ecx, DSIZE ; get packet size minus CRC sub ecx, CRC_SIZE ; make sure packet contains data - jle .error_size + jbe .error_size ; update statistics inc dword [device.packets_rx] add dword [device.bytes_rx], ecx - adc dword [device.bytes_rx+4], 0 + adc dword [device.bytes_rx + 4], 0 push ebx push .return push ecx ; packet size - push [device.rxd+eax+12] ; packet ptr + pushd [device.rxd + eax + 12] ; packet ptr DEBUGF 1, "Packet received OK\n" jmp EthReceiver .return: pop ebx ; Reset status, allow ethernet card access to descriptor - movzx ecx, [device.cur_rx] - shl ecx, 4 ; *16 - mov ecx, [device.rxd+ecx] stdcall KernelAlloc, RX_BUFF_SZ test eax, eax jz .fail - mov dword [ecx+12], eax + movzx ecx, [device.cur_rx] + shl ecx, 4 ; *16 + lea ecx, [device.rxd + ecx] + mov dword [ecx + 12], eax GetRealAddr - mov dword [ecx+8], eax - mov dword [ecx+4], RX_BUFF_SZ + mov dword [ecx + 8], eax + mov dword [ecx + 4], RX_BUFF_SZ inc [device.cur_rx] ; get next descriptor and [device.cur_rx], NUM_RX_DESC-1 ; only 4 descriptors 0-3 -; Enable Receiver - set_io 0 - set_io cr ; Command Register offset - in eax, dx ; Get current Command Register - or eax, RxENA ; Enable Receiver - out dx, eax +; Enable Receiver CHECKME +; set_io 0 +; set_io cr ; Command Register offset +; in eax, dx ; Get current Command Register +; or eax, RxENA ; Enable Receiver +; out dx, eax pop ax - jmp .no_rx - - .error_status: - - DEBUGF 1, "Packet error: %x\n", ecx - jmp .fail - - .error_size: - - DEBUGF 1, "Packet too large/small\n" - jmp .fail .no_rx: - ;; test ax, TxOk - ;; jz .no_tx + test ax, TxOK + jz .no_tx + + DEBUGF 1, "TX ok!\n" ;;; TODO: free all unused buffers ;; stdcall KernelFree, eax @@ -1249,6 +1143,13 @@ int_handler: ret + .error_status: + DEBUGF 1, "Packet error: %x\n", ecx + jmp .fail + + .error_size: + DEBUGF 1, "Packet too large/small\n" + jmp .fail .fail: DEBUGF 1, "FAILED\n" @@ -1256,58 +1157,6 @@ int_handler: ret -;*************************************************************************** -; Function -; transmit -; Description -; Transmits a packet of data via the ethernet card -; buffer pointer in [esp+4] -; size of buffer in [esp+8] -; pointer to device structure in ebx -; -; only one transmit descriptor is used -; -;*************************************************************************** -align 4 -transmit: - - cmp dword [esp+8], MAX_ETH_FRAME_SIZE - ja .error - - cmp dword [esp+8], 60 - jb .error - - movzx ecx, [device.cur_tx] - shl ecx, 4 - mov ecx, [device.txd+ecx] - -;; TODO: check if desc is empty (for example: check for eax, 0x6200000 at [ecx+4] -;;; or: count number of available descriptors - - mov eax, [esp+4] - mov dword [ecx + 12], eax - GetRealAddr - mov dword [ecx + 8], eax - - mov eax, [esp+8] - and eax, DSIZE - or eax, 0x80000000 ; card owns descriptor - mov dword [ecx + 4], eax - -; update stats - inc [device.packets_tx] - add dword [device.bytes_tx], ecx - adc dword [device.bytes_tx + 4], 0 - - .finish: - xor eax, eax - ret 8 - - .error: - stdcall KernelFree, [esp+4] - or eax, -1 - ret 8 - ; End of code