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 |
__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 |
public START |
public version |
|
|
virtual at ebx |
device: |
|
63,10 → 222,6 |
.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 |
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 |
|
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 |
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 |
|
; 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 [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 |
|
; 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 |
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,58 → 512,30 |
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 |
634,71 → 542,52 |
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 |
set_io rfcr |
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 |
|
; init RX descriptors |
DEBUGF 1, "Initialising RX Descriptors\n" |
|
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,95 → 595,24 |
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 |
DEBUGF 1, "setting RX mode\n" |
|
|
;*************************************************************************** |
; |
; 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" |
|
set_io 0 |
set_io cr |
in eax, dx ; Get current Command Register |
or eax, TxENA ; Enable Receive |
out dx, eax |
|
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 |
|
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: |
.rxfilterloop: |
set_io 0 |
set_io rfcr ; Receive Filter Control Reg offset |
mov eax, 4 ; determine table entry |
808,39 → 626,51 |
|
inc cl ; next entry |
cmp cl, [device.table_entries] |
jl .loop |
jb .rxfilterloop |
|
;------------------------------------ |
; Set Receive Filter Control Register |
|
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 |
;*************************************************************************** |
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 |
; 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 |
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 |
|
1129,8 → 960,79 |
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 |
; |
; handles received IRQs, which signal received packets |
1141,7 → 1043,6 |
;*************************************************************************** |
align 4 |
int_handler: |
DEBUGF 1, "Int!\n" |
|
; find pointer of device which made IRQ occur |
mov esi, device_list |
1160,6 → 1061,8 |
ret |
.got_it: |
|
DEBUGF 1,"IRQ! status=%x\n", ax |
|
test ax, RxOK |
jz .no_rx |
|
1167,7 → 1070,7 |
|
;----------- |
; Get Status |
movzx eax, [device.cur_rx] ; find current discriptor |
movzx eax, [device.cur_rx] ; find current descriptor |
shl eax, 4 ; * 16 |
mov ecx, dword[device.rxd+eax+4] ; get receive status |
|
1187,7 → 1090,7 |
; 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] |
1197,7 → 1100,7 |
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: |
1204,12 → 1107,12 |
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 |
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 |
1218,30 → 1121,21 |
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: |
.no_rx: |
test ax, TxOK |
jz .no_tx |
|
DEBUGF 1, "Packet error: %x\n", ecx |
jmp .fail |
DEBUGF 1, "TX ok!\n" |
|
.error_size: |
|
DEBUGF 1, "Packet too large/small\n" |
jmp .fail |
|
.no_rx: |
;; test ax, TxOk |
;; jz .no_tx |
|
;;; TODO: free all unused buffers |
;; stdcall KernelFree, eax |
|
1249,7 → 1143,14 |
|
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" |
jmp $ |
1256,59 → 1157,7 |
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 |
|
align 4 ; Place all initialised data here |