Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5561 → Rev 5562

/drivers/ethernet/i8255x.asm
73,46 → 73,51
INT_MASK = 0x0100
DRVR_INT = 0x0200 ; Driver generated interrupt
 
CmdIASetup = 0x0001
CmdConfigure = 0x0002
CmdTx = 0x0004
CmdTxFlex = 0x0008
Cmdsuspend = 0x4000
REG_SCB_STATUS = 0
REG_SCB_CMD = 2
REG_SCB_PTR = 4
REG_PORT = 8
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
reg_scb_cmd = 2
reg_scb_ptr = 4
reg_port = 8
reg_eeprom = 14
reg_mdi_ctrl = 16
MAC_82557_D100_A = 0
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
 
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
SCB_STATUS_RUS = 111100b ; RU Status
RU_STATUS_IDLE = 0000b shl 2
RU_STATUS_SUSPENDED = 0001b shl 2
RU_STATUS_NO_RESOURCES = 0010b shl 2
RU_STATUS_READY = 0100b shl 2
SCB_STATUS_FCP = 1 shl 8 ; Flow Control Pause
SCB_STATUS_SWI = 1 shl 10 ; Software Interrupt
SCB_STATUS_MDI = 1 shl 11 ; MDI read/write complete
SCB_STATUS_RNR = 1 shl 12 ; Receiver Not Ready
SCB_STATUS_CNA = 1 shl 13 ; Command unit Not Active
SCB_STATUS_FR = 1 shl 14 ; Frame received
SCB_STATUS_CX_TNO = 1 shl 15 ; Command finished / Transmit Not Okay
 
mac_82557_D100_A = 0
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
 
status dw ?
125,6 → 130,24
 
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
 
status dw ?
140,6 → 163,12
 
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 {
 
.status dw ?
455,7 → 484,7
; reset the card
 
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
out dx, eax
 
468,10 → 497,10
lea eax, [ebx + device.lstats.tx_good_frames] ; lstats
invoke GetPhysAddr
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
 
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
out dx, ax
call cmd_wait
479,11 → 508,11
;------------------------
; 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
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
out dx, ax
call cmd_wait
504,13 → 533,13
DEBUGF 1, "Starting RX"
 
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]
invoke GetPhysAddr
add eax, NET_BUFF.data
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
out dx, ax
call cmd_wait
518,11 → 547,11
;----------
; Set-up TX
 
set_io [ebx + device.io_addr], reg_scb_ptr
set_io [ebx + device.io_addr], REG_SCB_PTR
xor eax, 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
out dx, ax
call cmd_wait
530,7 → 559,7
;-------------------------
; 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
lea eax, [ebx + device.tx_ring]
invoke GetPhysAddr
540,12 → 569,12
movsd
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]
invoke GetPhysAddr
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
out dx, ax
call cmd_wait
553,7 → 582,7
;-------------
; 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
lea eax, [ebx + device.confcmd.status]
invoke GetPhysAddr
571,12 → 600,12
mov byte[ebx + device.confcmd.data + 19], 0x80
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]
invoke GetPhysAddr
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
out dx, ax
call cmd_wait
610,8 → 639,8
mov esi, eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000
mov [esi + sizeof.NET_BUFF + rxfd.command], 0xc000 ; End of list + Suspend
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.link], eax
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
693,7 → 722,7
 
; Fill in status and command values
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
 
; Fill in buffer address and size
711,11 → 740,11
mov eax, edi
invoke GetPhysAddr
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
 
; 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
out dx, ax
 
767,8 → 796,8
.nextdevice:
mov ebx, [esi]
 
; 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], 0 ; REG_SCB_STATUS = 0
set_io [ebx + device.io_addr], REG_SCB_STATUS
in ax, dx
out dx, ax ; send it back to ACK
test ax, ax
787,7 → 816,7
 
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
 
push ax
799,8 → 828,10
pop ebx
 
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)
je .nodata
test [esi + sizeof.NET_BUFF + rxfd.status], RXFD_STATUS_C ; Completed?
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
 
828,8 → 859,8
mov esi, eax
invoke GetPhysAddr
add eax, NET_BUFF.data
mov [esi + sizeof.NET_BUFF + rxfd.status], 0x0000
mov [esi + sizeof.NET_BUFF + rxfd.command], 0xc000 ; End of list + Suspend
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.link], eax
mov [esi + sizeof.NET_BUFF + rxfd.count], 0
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528
837,28 → 868,50
; restart RX
 
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]
; invoke GetPhysAddr
; add eax, NET_BUFF.data
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
out dx, ax
call cmd_wait
.out_of_mem:
 
; And give packet to kernel
; Hand the frame over to the kernel
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"
pop ax
 
.no_rx:
 
test ax, 1 shl 13
test ax, SCB_STATUS_CNA
jz .no_tx
DEBUGF 1, "Command completed\n"
 
889,29 → 942,11
pop eax
.no_tx:
 
and ax, 00111100b
cmp ax, 00001000b
test ax, RU_STATUS_NO_RESOURCES
jne .fail
 
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:
pop edi esi ebx
xor eax, eax
942,7 → 977,7
DEBUGF 1,"Eeprom read from 0x%x\n", esi
 
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
1020,7 → 1055,7
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], reg_eeprom
set_io [ebx + device.io_addr], REG_EEPROM
 
;-----------------------------------------------------
; Prepend start bit + write opcode to the address field
1090,7 → 1125,7
ee_get_width:
 
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
out dx, al
1167,7 → 1202,7
or eax, 10b shl 26 ; read opcode
 
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
 
.wait:
1199,7 → 1234,7
or eax, 01b shl 26 ; write opcode
 
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
 
.wait: