i8255x: Cleanup, Better handeling of received frames.

git-svn-id: svn://kolibrios.org@5562 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2015-05-29 19:12:25 +00:00
parent c9d8d9f37b
commit b754cb2eae

View File

@ -45,10 +45,10 @@ include '../netdrv.inc'
; Serial EEPROM ; Serial EEPROM
EE_SK = 1 shl 0 ; serial clock EE_SK = 1 shl 0 ; serial clock
EE_CS = 1 shl 1 ; chip select EE_CS = 1 shl 1 ; chip select
EE_DI = 1 shl 2 ; data in EE_DI = 1 shl 2 ; data in
EE_DO = 1 shl 3 ; data out EE_DO = 1 shl 3 ; data out
EE_MASK = EE_SK + EE_CS + EE_DI + EE_DO EE_MASK = EE_SK + EE_CS + EE_DI + EE_DO
; opcodes, first bit is start bit and must be 1 ; opcodes, first bit is start bit and must be 1
@ -73,45 +73,50 @@ RX_RESUMENR = 0x0007
INT_MASK = 0x0100 INT_MASK = 0x0100
DRVR_INT = 0x0200 ; Driver generated interrupt DRVR_INT = 0x0200 ; Driver generated interrupt
CmdIASetup = 0x0001 REG_SCB_STATUS = 0
CmdConfigure = 0x0002 REG_SCB_CMD = 2
CmdTx = 0x0004 REG_SCB_PTR = 4
CmdTxFlex = 0x0008 REG_PORT = 8
Cmdsuspend = 0x4000 REG_EEPROM = 14
REG_MDI_CTRL = 16
CmdRxFlex = 0x0008 PHY_100a = 0x000003E0
PHY_100c = 0x035002A8
PHY_82555_tx = 0x015002A8
PHY_nsc_tx = 0x5C002000
PHY_82562_et = 0x033002A8
PHY_82562_em = 0x032002A8
PHY_82562_ek = 0x031002A8
PHY_82562_eh = 0x017002A8
PHY_82552_v = 0xd061004d
PHY_unknown = 0xFFFFFFFF
reg_scb_status = 0 MAC_82557_D100_A = 0
reg_scb_cmd = 2 MAC_82557_D100_B = 1
reg_scb_ptr = 4 MAC_82557_D100_C = 2
reg_port = 8 MAC_82558_D101_A4 = 4
reg_eeprom = 14 MAC_82558_D101_B0 = 5
reg_mdi_ctrl = 16 MAC_82559_D101M = 8
MAC_82559_D101S = 9
MAC_82550_D102 = 12
MAC_82550_D102_C = 13
MAC_82551_E = 14
MAC_82551_F = 15
MAC_82551_10 = 16
MAC_unknown = 0xFF
phy_100a = 0x000003E0 SCB_STATUS_RUS = 111100b ; RU Status
phy_100c = 0x035002A8 RU_STATUS_IDLE = 0000b shl 2
phy_82555_tx = 0x015002A8 RU_STATUS_SUSPENDED = 0001b shl 2
phy_nsc_tx = 0x5C002000 RU_STATUS_NO_RESOURCES = 0010b shl 2
phy_82562_et = 0x033002A8 RU_STATUS_READY = 0100b shl 2
phy_82562_em = 0x032002A8 SCB_STATUS_FCP = 1 shl 8 ; Flow Control Pause
phy_82562_ek = 0x031002A8 SCB_STATUS_SWI = 1 shl 10 ; Software Interrupt
phy_82562_eh = 0x017002A8 SCB_STATUS_MDI = 1 shl 11 ; MDI read/write complete
phy_82552_v = 0xd061004d SCB_STATUS_RNR = 1 shl 12 ; Receiver Not Ready
phy_unknown = 0xFFFFFFFF SCB_STATUS_CNA = 1 shl 13 ; Command unit Not Active
SCB_STATUS_FR = 1 shl 14 ; Frame received
mac_82557_D100_A = 0 SCB_STATUS_CX_TNO = 1 shl 15 ; Command finished / Transmit Not Okay
mac_82557_D100_B = 1
mac_82557_D100_C = 2
mac_82558_D101_A4 = 4
mac_82558_D101_B0 = 5
mac_82559_D101M = 8
mac_82559_D101S = 9
mac_82550_D102 = 12
mac_82550_D102_C = 13
mac_82551_E = 14
mac_82551_F = 15
mac_82551_10 = 16
mac_unknown = 0xFF
struct rxfd struct rxfd
@ -125,6 +130,24 @@ struct rxfd
ends ends
RXFD_STATUS_RC = 1 shl 0 ; Receive collision
RXFD_STATUS_IA = 1 shl 1 ; IA mismatch
RXFD_STATUS_NA = 1 shl 2 ; No address match
RXFD_STATUS_RE = 1 shl 4 ; Receive Error
RXFD_STATUS_TL = 1 shl 5 ; Type/length
RXFD_STATUS_FS = 1 shl 7 ; Frame too short
RXFD_STATUS_DMA_FAIL = 1 shl 8 ; DMA overrun failure
RXFD_STATUS_NR = 1 shl 9 ; Out of buffer space; no resources
RXFD_STATUS_MISA = 1 shl 10 ; Alignment error
RXFD_STATUS_CRC_ERR = 1 shl 11 ; CRC error in aligned frame
RXFD_STATUS_OK = 1 shl 13 ; Frame received and stored
RXFD_STATUS_C = 1 shl 15 ; Completion of frame reception
RXFD_CMD_SF = 1 shl 3
RXFD_CMD_H = 1 shl 4 ; Header RFD
RXFD_CMD_SUSPEND = 1 shl 14 ; Suspends RU after receiving the frame
RXFD_CMD_EL = 1 shl 15 ; Last RFD in RFA
struct txfd struct txfd
status dw ? status dw ?
@ -140,6 +163,12 @@ struct txfd
ends ends
TXFD_CMD_IA = 1 shl 0
TXFD_CMD_CFG = 1 shl 1
TXFD_CMD_TX = 1 shl 2
TXFD_CMD_TX_FLEX = 1 shl 3
TXFD_CMD_SUSPEND = 1 shl 14
struc confcmd { struc confcmd {
.status dw ? .status dw ?
@ -455,7 +484,7 @@ reset:
; reset the card ; reset the card
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_port set_io [ebx + device.io_addr], REG_PORT
xor eax, eax ; Software Reset xor eax, eax ; Software Reset
out dx, eax out dx, eax
@ -468,10 +497,10 @@ reset:
lea eax, [ebx + device.lstats.tx_good_frames] ; lstats lea eax, [ebx + device.lstats.tx_good_frames] ; lstats
invoke GetPhysAddr invoke GetPhysAddr
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_scb_ptr set_io [ebx + device.io_addr], REG_SCB_PTR
out dx, eax out dx, eax
set_io [ebx + device.io_addr], reg_scb_cmd set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, CU_STATSADDR or INT_MASK mov ax, CU_STATSADDR or INT_MASK
out dx, ax out dx, ax
call cmd_wait call cmd_wait
@ -479,11 +508,11 @@ reset:
;------------------------ ;------------------------
; setup RX base addr to 0 ; setup RX base addr to 0
set_io [ebx + device.io_addr], reg_scb_ptr set_io [ebx + device.io_addr], REG_SCB_PTR
xor eax, eax xor eax, eax
out dx, eax out dx, eax
set_io [ebx + device.io_addr], reg_scb_cmd set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, RX_ADDR_LOAD or INT_MASK mov ax, RX_ADDR_LOAD or INT_MASK
out dx, ax out dx, ax
call cmd_wait call cmd_wait
@ -504,13 +533,13 @@ reset:
DEBUGF 1, "Starting RX" DEBUGF 1, "Starting RX"
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_scb_ptr set_io [ebx + device.io_addr], REG_SCB_PTR
mov eax, [ebx + device.rx_desc] mov eax, [ebx + device.rx_desc]
invoke GetPhysAddr invoke GetPhysAddr
add eax, NET_BUFF.data add eax, NET_BUFF.data
out dx, eax out dx, eax
set_io [ebx + device.io_addr], reg_scb_cmd set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, RX_START or INT_MASK mov ax, RX_START or INT_MASK
out dx, ax out dx, ax
call cmd_wait call cmd_wait
@ -518,11 +547,11 @@ reset:
;---------- ;----------
; Set-up TX ; Set-up TX
set_io [ebx + device.io_addr], reg_scb_ptr set_io [ebx + device.io_addr], REG_SCB_PTR
xor eax, eax xor eax, eax
out dx, eax out dx, eax
set_io [ebx + device.io_addr], reg_scb_cmd set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, CU_CMD_BASE or INT_MASK mov ax, CU_CMD_BASE or INT_MASK
out dx, ax out dx, ax
call cmd_wait call cmd_wait
@ -530,7 +559,7 @@ reset:
;------------------------- ;-------------------------
; Individual address setup ; Individual address setup
mov [ebx + device.confcmd.command], CmdIASetup + Cmdsuspend mov [ebx + device.confcmd.command], TXFD_CMD_IA + TXFD_CMD_SUSPEND
mov [ebx + device.confcmd.status], 0 mov [ebx + device.confcmd.status], 0
lea eax, [ebx + device.tx_ring] lea eax, [ebx + device.tx_ring]
invoke GetPhysAddr invoke GetPhysAddr
@ -540,12 +569,12 @@ reset:
movsd movsd
movsw movsw
set_io [ebx + device.io_addr], reg_scb_ptr set_io [ebx + device.io_addr], REG_SCB_PTR
lea eax, [ebx + device.confcmd.status] lea eax, [ebx + device.confcmd.status]
invoke GetPhysAddr invoke GetPhysAddr
out dx, eax out dx, eax
set_io [ebx + device.io_addr], reg_scb_cmd set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, CU_START or INT_MASK mov ax, CU_START or INT_MASK
out dx, ax out dx, ax
call cmd_wait call cmd_wait
@ -553,7 +582,7 @@ reset:
;------------- ;-------------
; Configure CU ; Configure CU
mov [ebx + device.confcmd.command], CmdConfigure + Cmdsuspend mov [ebx + device.confcmd.command], TXFD_CMD_CFG + TXFD_CMD_SUSPEND
mov [ebx + device.confcmd.status], 0 mov [ebx + device.confcmd.status], 0
lea eax, [ebx + device.confcmd.status] lea eax, [ebx + device.confcmd.status]
invoke GetPhysAddr invoke GetPhysAddr
@ -571,12 +600,12 @@ reset:
mov byte[ebx + device.confcmd.data + 19], 0x80 mov byte[ebx + device.confcmd.data + 19], 0x80
mov byte[ebx + device.confcmd.data + 21], 0x05 mov byte[ebx + device.confcmd.data + 21], 0x05
set_io [ebx + device.io_addr], reg_scb_ptr set_io [ebx + device.io_addr], REG_SCB_PTR
lea eax, [ebx + device.confcmd.status] lea eax, [ebx + device.confcmd.status]
invoke GetPhysAddr invoke GetPhysAddr
out dx, eax out dx, eax
set_io [ebx + device.io_addr], reg_scb_cmd set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, CU_START ; expect Interrupts from now on mov ax, CU_START ; expect Interrupts from now on
out dx, ax out dx, ax
call cmd_wait call cmd_wait
@ -610,8 +639,8 @@ init_rx_ring:
mov esi, eax mov esi, eax
invoke GetPhysAddr invoke GetPhysAddr
add eax, NET_BUFF.data add eax, NET_BUFF.data
mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000 mov [esi + sizeof.NET_BUFF + rxfd.status], 0
mov [esi + sizeof.NET_BUFF + rxfd.command], 0xc000 ; End of list + Suspend mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
mov [esi + sizeof.NET_BUFF + rxfd.link], eax mov [esi + sizeof.NET_BUFF + rxfd.link], eax
mov [esi + sizeof.NET_BUFF + rxfd.count], 0 mov [esi + sizeof.NET_BUFF + rxfd.count], 0
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
@ -693,7 +722,7 @@ proc transmit stdcall bufferptr
; Fill in status and command values ; Fill in status and command values
mov [edi + txfd.status], 0 mov [edi + txfd.status], 0
mov [edi + txfd.command], Cmdsuspend + CmdTx + CmdTxFlex ;;;+ 1 shl 15 ;;; EL bit mov [edi + txfd.command], TXFD_CMD_SUSPEND + TXFD_CMD_TX + TXFD_CMD_TX_FLEX
mov [edi + txfd.count], 0x01208000 mov [edi + txfd.count], 0x01208000
; Fill in buffer address and size ; Fill in buffer address and size
@ -711,11 +740,11 @@ proc transmit stdcall bufferptr
mov eax, edi mov eax, edi
invoke GetPhysAddr invoke GetPhysAddr
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_scb_ptr set_io [ebx + device.io_addr], REG_SCB_PTR
out dx, eax out dx, eax
; Start the transmit ; Start the transmit
set_io [ebx + device.io_addr], reg_scb_cmd set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, CU_START mov ax, CU_START
out dx, ax out dx, ax
@ -767,10 +796,10 @@ int_handler:
.nextdevice: .nextdevice:
mov ebx, [esi] mov ebx, [esi]
; set_io [ebx + device.io_addr], 0 ; reg_scb_status = 0 ; set_io [ebx + device.io_addr], 0 ; REG_SCB_STATUS = 0
set_io [ebx + device.io_addr], reg_scb_status set_io [ebx + device.io_addr], REG_SCB_STATUS
in ax, dx in ax, dx
out dx, ax ; send it back to ACK out dx, ax ; send it back to ACK
test ax, ax test ax, ax
jnz .got_it jnz .got_it
.continue: .continue:
@ -781,13 +810,13 @@ int_handler:
pop edi esi ebx pop edi esi ebx
xor eax, eax xor eax, eax
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver)
.got_it: .got_it:
DEBUGF 1,"Device: %x Status: %x\n", ebx, ax DEBUGF 1,"Device: %x Status: %x\n", ebx, ax
test ax, 1 shl 14 ; did we receive a frame? test ax, SCB_STATUS_FR ; did we receive a frame?
jz .no_rx jz .no_rx
push ax push ax
@ -799,8 +828,10 @@ int_handler:
pop ebx pop ebx
mov esi, [ebx + device.rx_desc] mov esi, [ebx + device.rx_desc]
cmp [esi + sizeof.NET_BUFF + rxfd.status], 0 ; we could also check bits C and OK (bit 15 and 13) test [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_C ; Completed?
je .nodata jz .no_rx_
test [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_OK ; OK?
jz .not_ok
DEBUGF 1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4 DEBUGF 1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4
@ -828,8 +859,8 @@ int_handler:
mov esi, eax mov esi, eax
invoke GetPhysAddr invoke GetPhysAddr
add eax, NET_BUFF.data add eax, NET_BUFF.data
mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000 mov [esi + sizeof.NET_BUFF + rxfd.status], 0
mov [esi + sizeof.NET_BUFF + rxfd.command], 0xc000 ; End of list + Suspend mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
mov [esi + sizeof.NET_BUFF + rxfd.link], eax mov [esi + sizeof.NET_BUFF + rxfd.link], eax
mov [esi + sizeof.NET_BUFF + rxfd.count], 0 mov [esi + sizeof.NET_BUFF + rxfd.count], 0
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
@ -837,28 +868,50 @@ int_handler:
; restart RX ; restart RX
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_scb_ptr set_io [ebx + device.io_addr], REG_SCB_PTR
; mov eax, [ebx + device.rx_desc] ; mov eax, [ebx + device.rx_desc]
; invoke GetPhysAddr ; invoke GetPhysAddr
; add eax, NET_BUFF.data ; add eax, NET_BUFF.data
out dx, eax out dx, eax
set_io [ebx + device.io_addr], reg_scb_cmd set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, RX_START mov ax, RX_START
out dx, ax out dx, ax
call cmd_wait call cmd_wait
.out_of_mem: .out_of_mem:
; And give packet to kernel ; Hand the frame over to the kernel
jmp [EthInput] jmp [EthInput]
.nodata: .not_ok:
; Reset the FD
mov [esi + sizeof.NET_BUFF + rxfd.status], 0
mov [esi + sizeof.NET_BUFF + rxfd.command], RXFD_CMD_EL or RXFD_CMD_SUSPEND
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
; Restart RX
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], REG_SCB_PTR
mov eax, esi
invoke GetPhysAddr
add eax, NET_BUFF.data
out dx, eax
set_io [ebx + device.io_addr], REG_SCB_CMD
mov ax, RX_START
out dx, ax
call cmd_wait
push ebx
jmp .rx_loop
.no_rx_:
DEBUGF 1, "no more data\n" DEBUGF 1, "no more data\n"
pop ax pop ax
.no_rx: .no_rx:
test ax, 1 shl 13 test ax, SCB_STATUS_CNA
jz .no_tx jz .no_tx
DEBUGF 1, "Command completed\n" DEBUGF 1, "Command completed\n"
@ -889,29 +942,11 @@ int_handler:
pop eax pop eax
.no_tx: .no_tx:
and ax, 00111100b test ax, RU_STATUS_NO_RESOURCES
cmp ax, 00001000b
jne .fail jne .fail
DEBUGF 2, "Out of resources!\n" DEBUGF 2, "Out of resources!\n"
; call init_rx_ring
; test eax, eax
; jz .fail
; restart RX
set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_scb_ptr
mov eax, [ebx + device.rx_desc]
invoke GetPhysAddr
add eax, NET_BUFF.data
out dx, eax
set_io [ebx + device.io_addr], reg_scb_cmd
mov ax, RX_START
out dx, ax
call cmd_wait
.fail: .fail:
pop edi esi ebx pop edi esi ebx
xor eax, eax xor eax, eax
@ -942,7 +977,7 @@ ee_read: ; esi = address to read
DEBUGF 1,"Eeprom read from 0x%x\n", esi DEBUGF 1,"Eeprom read from 0x%x\n", esi
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_eeprom set_io [ebx + device.io_addr], REG_EEPROM
;----------------------------------------------------- ;-----------------------------------------------------
; Prepend start bit + read opcode to the address field ; Prepend start bit + read opcode to the address field
@ -1020,7 +1055,7 @@ ee_write: ; esi = address to write to, di = data
DEBUGF 1,"Eeprom write 0x%x to 0x%x\n", di, esi DEBUGF 1,"Eeprom write 0x%x to 0x%x\n", di, esi
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_eeprom set_io [ebx + device.io_addr], REG_EEPROM
;----------------------------------------------------- ;-----------------------------------------------------
; Prepend start bit + write opcode to the address field ; Prepend start bit + write opcode to the address field
@ -1090,7 +1125,7 @@ align 4
ee_get_width: ee_get_width:
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_eeprom set_io [ebx + device.io_addr], REG_EEPROM
mov al, EE_CS ; activate eeprom mov al, EE_CS ; activate eeprom
out dx, al out dx, al
@ -1167,7 +1202,7 @@ mdio_read:
or eax, 10b shl 26 ; read opcode or eax, 10b shl 26 ; read opcode
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_mdi_ctrl set_io [ebx + device.io_addr], REG_MDI_CTRL
out dx, eax out dx, eax
.wait: .wait:
@ -1199,7 +1234,7 @@ mdio_write:
or eax, 01b shl 26 ; write opcode or eax, 01b shl 26 ; write opcode
set_io [ebx + device.io_addr], 0 set_io [ebx + device.io_addr], 0
set_io [ebx + device.io_addr], reg_mdi_ctrl set_io [ebx + device.io_addr], REG_MDI_CTRL
out dx, eax out dx, eax
.wait: .wait: