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: |