/drivers/ethernet/RTL8169.asm |
---|
175,10 → 175,10 |
DSB_FSbit = 0x20000000 |
DSB_LSbit = 0x10000000 |
RX_BUF_SIZE = 1514 ; Rx Buffer size |
RX_BUF_SIZE = 1536 ; Rx Buffer size |
; max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4) |
MAX_ETH_FRAME_SIZE = 1514 |
MAX_ETH_FRAME_SIZE = 1536 |
TX_FIFO_THRESH = 256 ; In bytes |
200,7 → 200,7 |
ETH_HDR_LEN = 14 |
DEFAULT_MTU = 1500 |
DEFAULT_RX_BUF_LEN = 1514 |
DEFAULT_RX_BUF_LEN = 1536 |
;ifdef JUMBO_FRAME_SUPPORT |
662,9 → 662,6 |
DEBUGF 1,"resetting\n" |
call init_ring |
test eax, eax |
jnz .err |
call hw_start |
; clear packet/byte counters |
681,13 → 678,10 |
xor eax, eax |
ret |
.err: |
DEBUGF 2,"failed!\n" |
or eax, -1 |
ret |
align 4 |
PHY_config: |
806,12 → 800,9 |
mov ecx, NUM_RX_DESC |
.loop: |
push ecx |
invoke NetAlloc, RX_BUF_SIZE+NET_BUFF.data |
test eax, eax |
jz .err |
invoke KernelAlloc, RX_BUF_SIZE |
mov dword [edi + rx_desc.buf_soft_addr], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov dword [edi + rx_desc.buf_addr], eax |
mov [edi + rx_desc.status], DSB_OWNbit or RX_BUF_SIZE |
add edi, sizeof.rx_desc |
820,13 → 811,8 |
jnz .loop |
or [edi - sizeof.rx_desc + rx_desc.status], DSB_EORbit |
xor eax, eax |
ret |
.err: |
pop eax |
or eax, -1 |
ret |
align 4 |
hw_start: |
1004,22 → 990,21 |
; |
;*************************************************************************** |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
;---------------------------------- |
1041,9 → 1026,7 |
; Program the packet pointer |
mov eax, [bufferptr] |
mov ecx, [eax + NET_BUFF.length] |
mov [esi + tx_desc.buf_soft_addr], eax |
add eax, [eax + NET_BUFF.offset] |
invoke GetPhysAddr |
mov dword [esi + tx_desc.buf_addr], eax |
1050,7 → 1033,8 |
;------------------------ |
; Program the packet size |
mov eax, ecx |
mov eax, [buffersize] |
@@: |
or eax, DSB_OWNbit or DSB_FSbit or DSB_LSbit |
cmp [ebx + device.cur_tx], NUM_TX_DESC - 1 |
jne @f |
1076,7 → 1060,8 |
; Update stats |
inc [ebx + device.packets_tx] |
add dword [ebx + device.bytes_tx], ecx |
mov eax, [buffersize] |
add dword [ebx + device.bytes_tx], eax |
adc dword [ebx + device.bytes_tx + 4], 0 |
popf |
1087,7 → 1072,7 |
DEBUGF 2,"Descriptor is still in use!\n" |
.fail: |
DEBUGF 2,"Transmit failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
1154,27 → 1139,22 |
lea esi, [ebx + device.rx_ring + eax] |
DEBUGF 1,"RxDesc.status = 0x%x\n", [esi + rx_desc.status] |
mov ecx, [esi + rx_desc.status] |
test ecx, DSB_OWNbit ;;; |
jnz .rx_return |
mov eax, [esi + rx_desc.status] |
test eax, DSB_OWNbit ;;; |
jnz .no_own |
DEBUGF 1,"cur_rx = %u\n", [ebx + device.cur_rx] |
test ecx, SD_RxRES |
test eax, SD_RxRES |
jnz .rx_return ;;;;; RX error! |
push ebx |
push .check_more |
and ecx, 0x00001FFF |
add ecx, -4 ; we dont need CRC |
DEBUGF 1,"data length = %u\n", ecx |
mov eax, [esi + rx_desc.buf_soft_addr] |
and eax, 0x00001FFF |
add eax, -4 ; we dont need CRC |
push eax |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
DEBUGF 1,"data length = %u\n", ax |
;------------- |
; Update stats |
add dword [ebx + device.bytes_rx], eax |
1181,16 → 1161,15 |
adc dword [ebx + device.bytes_rx + 4], 0 |
inc [ebx + device.packets_rx] |
;---------------------- |
pushd [esi + rx_desc.buf_soft_addr] |
; Allocate a new buffer |
invoke NetAlloc, RX_BUF_SIZE+NET_BUFF.data |
invoke KernelAlloc, RX_BUF_SIZE |
mov [esi + rx_desc.buf_soft_addr], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov dword [esi + rx_desc.buf_addr], eax |
;--------------- |
; re set OWN bit |
mov eax, DSB_OWNbit or RX_BUF_SIZE |
1200,15 → 1179,15 |
@@: |
mov [esi + rx_desc.status], eax |
;-------------- |
; Update rx ptr |
inc [ebx + device.cur_rx] |
and [ebx + device.cur_rx], NUM_RX_DESC - 1 |
jmp [EthInput] |
jmp [Eth_input] |
.rx_return: |
DEBUGF 1,"RX error!\n" |
.no_own: |
pop ax |
.no_rx: |
1217,31 → 1196,30 |
test ax, ISB_TxOK or ISB_TxErr or ISB_TxDescUnavail |
jz .no_tx |
push ax |
DEBUGF 1,"TX done!\n" |
.txloop: |
mov esi, [ebx + device.last_tx] |
imul esi, sizeof.tx_desc |
lea esi, [ebx + device.tx_ring + esi] |
mov ecx, NUM_TX_DESC |
lea esi, [ebx + device.tx_ring] |
.txloop: |
cmp dword [esi + tx_desc.buf_soft_addr], 0 |
jz .maybenext |
je .no_tx |
test [esi + tx_desc.status], DSB_OWNbit |
jnz .maybenext |
jnz .no_tx |
push ecx |
DEBUGF 1,"Freeing up TX desc: %x\n", esi |
invoke NetFree, [esi + tx_desc.buf_soft_addr] |
pop ecx |
DEBUGF 1,"Freeing up TX desc: 0x%x\n", esi |
DEBUGF 1,"buff: 0x%x\n", [esi + tx_desc.buf_soft_addr] |
push eax |
push dword [esi + tx_desc.buf_soft_addr] |
and dword [esi + tx_desc.buf_soft_addr], 0 |
invoke KernelFree |
pop eax |
.maybenext: |
add esi, sizeof.tx_desc |
dec ecx |
jnz .txloop |
pop ax |
inc [ebx + device.last_tx] |
and [ebx + device.last_tx], NUM_TX_DESC-1 |
jmp .txloop |
.no_tx: |
test ax, ISB_LinkChg |
1355,10 → 1333,10 |
dd 0x7cf00000, 0x28a00000, 28, name_27 |
; 8168C family. |
dd 0x7cf00000, 0x3cb00000, 24, name_18 |
dd 0x7cf00000, 0x3c900000, 23, name_18 |
dd 0x7cf00000, 0x3cb00000, 24, name_23 |
dd 0x7cf00000, 0x3c900000, 23, name_23 |
dd 0x7cf00000, 0x3c800000, 18, name_18 |
dd 0x7c800000, 0x3c800000, 24, name_18 |
dd 0x7c800000, 0x3c800000, 24, name_23 |
dd 0x7cf00000, 0x3c000000, 19, name_19 |
dd 0x7cf00000, 0x3c200000, 20, name_19 |
dd 0x7cf00000, 0x3c300000, 21, name_19 |
1423,7 → 1401,7 |
;name_20 db "RTL8168c/8111c",0 |
;name_21 db "RTL8168c/8111c",0 |
;name_22 db "RTL8168c/8111c",0 |
;name_23 db "RTL8168cp/8111cp",0 |
name_23 db "RTL8168cp/8111cp",0 |
;name_24 db "RTL8168cp/8111cp",0 |
name_25 db "RTL8168d/8111d",0 |
;name_26 db "RTL8168d/8111d",0 |
/drivers/ethernet/3c59x.asm |
---|
289,7 → 289,9 |
RxBroadcast = 4 |
RxProm = 8 |
MAX_ETH_FRAME_SIZE = 1514 |
; RX/TX buffers sizes |
MAX_ETH_PKT_SIZE = 1536 ; max packet size |
MAX_ETH_FRAME_SIZE = 1520 ; size of ethernet frame + bytes alignment |
struct tx_desc |
804,9 → 806,6 |
call set_active_port |
call create_rx_ring |
test eax, eax |
jnz .err |
call rx_reset |
call tx_reset |
817,15 → 816,13 |
mov ecx, 6 |
rep stosd |
xor eax, eax |
ret |
.err: |
DEBUGF 2,"reset failed\n" |
or eax, -1 |
ret |
align 4 |
start_device: |
DEBUGF 1,"Starting the device\n" |
905,7 → 902,6 |
; Set link state to unknown |
mov [ebx + device.state], ETH_LINK_UNKNOWN |
xor eax, eax |
ret |
1001,13 → 997,10 |
mov [edx + rx_desc.next_ptr], edi |
push ecx edx |
invoke NetAlloc, MAX_ETH_FRAME_SIZE+NET_BUFF.data |
invoke KernelAlloc, MAX_ETH_FRAME_SIZE |
pop edx ecx |
test eax, eax |
jz .out_of_mem |
mov [esi + rx_desc.realaddr], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
invoke GetPgAddr |
mov [esi + rx_desc.frag_addr], eax |
and [esi + rx_desc.pkt_status], 0 |
mov [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) |
1021,15 → 1014,10 |
dec ecx |
jnz .loop |
xor eax, eax |
ret |
.out_of_mem: |
or eax, -1 |
ret |
;--------------------------------------------------------------------------- |
; Function |
; try_link_detect |
1051,14 → 1039,15 |
DEBUGF 1,"Trying to detect link\n" |
; create self-directed packet |
invoke NetAlloc, 20+NET_BUFF.data ; create a buffer for the self-directed packet |
invoke KernelAlloc, 20 ; create a buffer for the self-directed packet |
test eax, eax |
jz .fail |
push eax |
mov [eax + NET_BUFF.length], 20 |
pushd 20 ; Packet parameters for device.transmit |
push eax ; |
lea edi, [eax + NET_BUFF.data] |
mov edi, eax |
lea esi, [ebx + device.mac] |
movsw |
movsd |
1103,12 → 1092,10 |
jz @f |
or byte [ebx + device.internal_link+1], 100b |
@@: |
xor eax, eax |
ret |
.fail: |
DEBUGF 1,"No link detected!\n" |
or eax, -1 |
ret |
1148,7 → 1135,7 |
; wait for reset to complete |
mov esi, 2000 |
invoke Sleep ; 2s FIXME |
invoke Sleep ; 2s |
mov eax, [esp] |
call mdio_read ; returns with window #4 |
test ah, 0x80 |
1420,15 → 1407,14 |
call tx_reset |
; create self-directed packet |
invoke NetAlloc, 20 + NET_BUFF.data ; create a buffer for the self-directed packet |
invoke KernelAlloc, 20 ; create a buffer for the self-directed packet |
test eax, eax |
jz .fail |
push eax |
mov [eax + NET_BUFF.length], 20 |
; mov [eax + NET_BUFF.device], ebx |
pushd 20 ; Packet parameters for device.transmit |
push eax ; |
lea edi, [eax + NET_BUFF.data] |
mov edi, eax |
lea esi, [ebx + device.mac] |
movsw |
movsd |
1442,7 → 1428,7 |
call [ebx + device.transmit] |
; wait for 2s |
mov esi, 2000 ; FIXME |
mov esi, 2000 |
invoke Sleep |
; check if self-directed packet is received |
2138,26 → 2124,26 |
;; Transmit (vortex) ;; |
;; ;; |
;; In: buffer pointer in [esp+4] ;; |
;; size of buffer in [esp+8] ;; |
;; pointer to device structure in ebx ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc vortex_transmit stdcall bufferptr |
proc vortex_transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
call check_tx_status |
2167,25 → 2153,20 |
set_io [ebx + device.io_addr], REG_COMMAND |
mov ax, SELECT_REGISTER_WINDOW+7 |
out dx, ax |
; check for master operation in progress |
set_io [ebx + device.io_addr], REG_MASTER_STATUS |
in ax, dx |
test ah, 0x80 |
jnz .fail ; no DMA for sending |
; program frame address to be sent |
set_io [ebx + device.io_addr], REG_MASTER_ADDRESS |
mov eax, esi |
add eax, [eax + NET_BUFF.offset] |
mov eax, [bufferptr] |
invoke GetPhysAddr |
out dx, eax |
; program frame length |
set_io [ebx + device.io_addr], REG_MASTER_LEN |
mov eax, [esi + NET_BUFF.length] |
mov eax, [buffersize] |
out dx, ax |
; start DMA Down |
set_io [ebx + device.io_addr], REG_COMMAND |
mov ax, (10100b shl 11) + 1 ; StartDMADown |
2197,7 → 2178,7 |
.fail: |
DEBUGF 2,"Send failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
2209,38 → 2190,38 |
;; Transmit (boomerang) ;; |
;; ;; |
;; In: buffer pointer in [esp+4] ;; |
;; size of buffer in [esp+8] ;; |
;; pointer to device structure in ebx ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc boomerang_transmit stdcall bufferptr |
proc boomerang_transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
call check_tx_status ; Reset TX engine if needed |
; calculate descriptor address |
mov edi, [ebx + device.curr_tx] |
DEBUGF 1,"Previous TX desc: %x\n", edi |
add edi, sizeof.tx_desc |
mov esi, [ebx + device.curr_tx] |
DEBUGF 1,"Previous TX desc: %x\n", esi |
add esi, sizeof.tx_desc |
lea ecx, [ebx + device.tx_desc_buffer + (NUM_TX_DESC)*sizeof.tx_desc] |
cmp edi, ecx |
cmp esi, ecx |
jb @f |
lea edi, [ebx + device.tx_desc_buffer] ; Wrap if needed |
lea esi, [ebx + device.tx_desc_buffer] ; Wrap if needed |
@@: |
DEBUGF 1,"Using TX desc: %x\n", esi |
2258,32 → 2239,31 |
; update statistics |
inc [ebx + device.packets_tx] |
mov ecx, [esi + NET_BUFF.length] |
mov ecx, [buffersize] |
add dword [ebx + device.bytes_tx], ecx |
adc dword [ebx + device.bytes_tx + 4], 0 |
; program DPD |
and [edi + tx_desc.next_ptr], 0 |
and [esi + tx_desc.next_ptr], 0 |
mov eax, [bufferptr] |
mov [edi + tx_desc.realaddr], eax |
add eax, [eax + NET_BUFF.offset] |
mov [esi + tx_desc.realaddr], eax |
invoke GetPhysAddr |
mov [edi + tx_desc.frag_addr], eax |
;;; mov ecx, [buffersize] |
mov [esi + tx_desc.frag_addr], eax |
mov ecx, [buffersize] |
or ecx, 0x80000000 ; last fragment flag |
mov [edi + tx_desc.frag_len], ecx |
mov [esi + tx_desc.frag_len], ecx |
;;; mov ecx, [buffersize] ; packet size |
mov ecx, [buffersize] ; packet size |
or ecx, 0x80008000 ; set OWN bit + transmission complete notification flag |
; test byte [ebx + device.has_hwcksm], 0xff |
; jz @f |
; or ecx, (1 shl 26) ; set AddTcpChecksum |
;@@: |
mov [edi + tx_desc.frame_start_hdr], ecx |
DEBUGF 1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [edi+tx_desc.realaddr]:8, [edi+tx_desc.frag_addr]:8, [edi+tx_desc.frag_len]:8, [edi+tx_desc.frame_start_hdr]:8 |
mov [esi + tx_desc.frame_start_hdr], ecx |
DEBUGF 1,"TX desc: lin=%x phys=%x len=%x start hdr=%x\n", [esi+tx_desc.realaddr]:8, [esi+tx_desc.frag_addr]:8, [esi+tx_desc.frag_len]:8, [esi+tx_desc.frame_start_hdr]:8 |
; calculate physical address of tx descriptor |
mov eax, edi |
mov eax, esi |
invoke GetPhysAddr |
cmp [ebx + device.dn_list_ptr_cleared], 0 |
je .add_to_list |
2338,7 → 2318,7 |
out dx, ax |
.finish: |
mov [ebx + device.curr_tx], edi |
mov [ebx + device.curr_tx], esi |
popf |
xor eax, eax |
ret |
2345,7 → 2325,7 |
.fail: |
DEBUGF 2,"Send failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
2513,7 → 2493,7 |
.check_length: |
and eax, 0x1fff |
cmp eax, MAX_ETH_FRAME_SIZE |
cmp eax, MAX_ETH_PKT_SIZE |
ja .discard_frame ; frame is too long discard it |
.check_dma: |
2533,18 → 2513,15 |
.read_frame: |
; program buffer address to read in |
push ecx |
invoke NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data |
invoke KernelAlloc, MAX_ETH_FRAME_SIZE |
pop ecx |
test eax, eax |
jz .finish |
push .discard_frame |
push ecx |
push eax |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
; zero_to_dma eax |
set_io [ebx + device.io_addr], REG_MASTER_ADDRESS |
out dx, eax |
2566,7 → 2543,7 |
jnz .dma_loop |
; registrate the received packet to kernel |
jmp [EthInput] |
jmp Eth_input |
; discard the top frame received |
.discard_frame: |
2701,11 → 2678,8 |
DEBUGF 1, "Received %u bytes in buffer %x\n", ecx, [esi + rx_desc.realaddr]:8 |
push dword .loop ;.finish |
mov eax, [esi + rx_desc.realaddr] |
push eax |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
push ecx |
push [esi + rx_desc.realaddr] |
; update statistics |
inc [ebx + device.packets_rx] |
2713,10 → 2687,9 |
adc dword [ebx + device.bytes_rx + 4], 0 |
; update rx descriptor (Alloc new buffer for next packet) |
invoke NetAlloc, MAX_ETH_FRAME_SIZE + NET_BUFF.data |
invoke KernelAlloc, MAX_ETH_FRAME_SIZE |
mov [esi + rx_desc.realaddr], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [esi + rx_desc.frag_addr], eax |
and [esi + rx_desc.pkt_status], 0 |
mov [esi + rx_desc.frag_len], MAX_ETH_FRAME_SIZE or (1 shl 31) |
2731,7 → 2704,7 |
mov [ebx + device.curr_rx], esi |
DEBUGF 1, "Next RX desc: %x\n", esi |
jmp [EthInput] |
jmp [Eth_input] |
.loop: |
mov ebx, [esp] |
2769,7 → 2742,7 |
and [esi+tx_desc.frame_start_hdr], 0 |
push ecx |
invoke NetFree, [esi+tx_desc.realaddr] |
invoke KernelFree, [esi+tx_desc.realaddr] |
pop ecx |
.maybenext: |
/drivers/ethernet/R6040.asm |
---|
137,7 → 137,7 |
MAC_SM = 0xAC ; MAC status machine |
MAC_ID = 0xBE ; Identifier register |
MAX_BUF_SIZE = 1514 |
MAX_BUF_SIZE = 0x600 ; 1536 |
MBCR_DEFAULT = 0x012A ; MAC Bus Control Register |
MCAST_MAX = 3 ; Max number multicast addresses to filter |
396,11 → 396,12 |
; |
; - Stop the device |
; - Detach int handler |
; - Remove device from local list (device_list) |
; - Remove device from local list (RTL8139_LIST) |
; - call unregister function in kernel |
; - Remove all allocated structures and buffers the card used |
or eax, -1 |
ret |
451,7 → 452,6 |
cmp ax, 0xFFFF |
jne @f |
DEBUGF 2, "Failed to detect an attached PHY!\n" |
.err: |
mov eax, -1 |
ret |
@@: |
462,8 → 462,6 |
; Initialize and alloc RX/TX buffers |
call init_txbufs |
call init_rxbufs |
test eax, eax |
jnz .err |
; Read the PHY ID |
mov [ebx + device.phy_mode], MCR0_FD |
664,19 → 662,19 |
.next_desc: |
mov [esi + x_head.ndesc], edx |
push esi ecx edx |
invoke NetAlloc, MAX_BUF_SIZE+NET_BUFF.data |
invoke KernelAlloc, MAX_BUF_SIZE |
pop edx ecx esi |
test eax, eax |
jz .out_of_mem |
mov [esi + x_head.skb_ptr], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [esi + x_head.buf], eax |
mov [esi + x_head.status], DSC_OWNER_MAC |
add edx, sizeof.x_head |
add esi, sizeof.x_head |
dec ecx |
jnz .next_desc |
685,15 → 683,10 |
invoke GetPhysAddr |
mov dword[ebx + device.rx_ring + sizeof.x_head*(RX_RING_SIZE-1) + x_head.ndesc], eax |
xor eax, eax |
ret |
.out_of_mem: |
or eax, -1 |
ret |
align 4 |
phy_mode_chk: |
741,22 → 734,21 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
movzx edi, [ebx + device.cur_tx] |
772,12 → 764,11 |
.do_send: |
DEBUGF 1,"Sending now\n" |
mov [edi + x_head.skb_ptr], esi |
mov eax, esi |
add eax, [eax + NET_BUFF.offset] |
mov eax, [bufferptr] |
mov [edi + x_head.skb_ptr], eax |
invoke GetPhysAddr |
mov [edi + x_head.buf], eax |
mov ecx, [esi + NET_BUFF.length] |
mov ecx, [buffersize] |
mov [edi + x_head.len], cx |
mov [edi + x_head.status], DSC_OWNER_MAC |
792,7 → 783,7 |
; Update stats |
inc [ebx + device.packets_tx] |
mov eax, [esi + NET_BUFF.length] |
mov eax, [buffersize] |
add dword[ebx + device.bytes_tx], eax |
adc dword[ebx + device.bytes_tx + 4], 0 |
802,18 → 793,15 |
.wait_to_send: |
DEBUGF 1,"Waiting for TX buffer\n" |
invoke GetTimerTicks ; returns in eax |
lea edx, [eax + 100] |
.l2: |
mov esi, [bufferptr] |
test [edi + x_head.status], DSC_OWNER_MAC |
jz .do_send |
popf |
mov esi, 10 |
invoke Sleep |
invoke GetTimerTicks |
pushf |
cli |
cmp edx, eax |
jb .l2 |
820,7 → 808,7 |
DEBUGF 2,"Send timeout\n" |
.fail: |
DEBUGF 2,"Send failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
902,29 → 890,26 |
and ecx, 0xFFF |
sub ecx, 4 ; Do not count the CRC |
DEBUGF 1,"packet ptr=0x%x size=%u\n", [edx + x_head.skb_ptr], ecx |
; Update stats |
add dword[ebx + device.bytes_rx], ecx |
adc dword[ebx + device.bytes_rx + 4], 0 |
inc dword[ebx + device.packets_rx] |
; Push packet size and pointer, kernel will need it.. |
push ebx |
; Push packet ptr and return addr for Eth_input |
push .more_RX |
mov eax, [edx + x_head.skb_ptr] |
push eax |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
; reset the RX descriptor (alloc new buffer) |
push ecx |
push [edx + x_head.skb_ptr] |
DEBUGF 1,"packet ptr=0x%x\n", [edx + x_head.skb_ptr] |
; reset the RX descriptor |
push edx |
invoke NetAlloc, MAX_BUF_SIZE+NET_BUFF.data |
invoke KernelAlloc, MAX_BUF_SIZE |
pop edx |
mov [edx + x_head.skb_ptr], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [edx + x_head.buf], eax |
mov [edx + x_head.status], DSC_OWNER_MAC |
933,10 → 918,11 |
and [ebx + device.cur_rx], RX_RING_SIZE - 1 |
; At last, send packet to kernel |
jmp [EthInput] |
jmp [Eth_input] |
.no_RX: |
test word[esp], TX_FINISH |
jz .no_TX |
955,7 → 941,7 |
push [edi + x_head.skb_ptr] |
mov [edi + x_head.skb_ptr], 0 |
invoke NetFree |
invoke KernelFree |
inc [ebx + device.last_tx] |
and [ebx + device.last_tx], TX_RING_SIZE - 1 |
1120,13 → 1106,13 |
lea edi, [ebx + device.mac] |
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], MID_0L |
.loop: |
.mac: |
in ax, dx |
stosw |
inc dx |
inc dx |
dec cx |
jnz .loop |
jnz .mac |
DEBUGF 1,"%x-%x-%x-%x-%x-%x\n",\ |
[edi-6]:2, [edi-5]:2, [edi-4]:2, [edi-3]:2, [edi-2]:2, [edi-1]:2 |
/drivers/ethernet/RTL8029.asm |
---|
665,18 → 665,17 |
;*************************************************************************** |
; Function |
; transmit |
; buffer in [esp+4], pointer to device struct in ebx |
; buffer in [esp+4], size in [esp+8], pointer to device struct in ebx |
;*************************************************************************** |
proc transmit stdcall buffer_ptr |
proc transmit stdcall buffer_ptr, buffer_size |
pushf |
cli |
mov esi, [buffer_ptr] |
mov ecx, [esi + NET_BUFF.length] |
mov ecx, [buffer_size] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", esi, ecx |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1, "To: %x-%x-%x-%x-%x-%x From: %x-%x-%x-%x-%x-%x Type:%x%x\n",\ |
[esi+0]:2,[esi+1]:2,[esi+2]:2,[esi+3]:2,[esi+4]:2,[esi+5]:2,[esi+6]:2,[esi+7]:2,[esi+8]:2,[esi+9]:2,[esi+10]:2,[esi+11]:2,[esi+13]:2,[esi+12]:2 |
687,10 → 686,9 |
movzx edi, [ebx + device.tx_start] |
shl edi, 8 |
add esi, [esi + NET_BUFF.offset] |
push ecx |
push cx |
call PIO_write |
pop ecx |
pop cx |
set_io [ebx + device.io_addr], 0 |
; set_io [ebx + device.io_addr], P0_COMMAND |
716,10 → 714,11 |
DEBUGF 1, "Packet Sent!\n" |
inc [ebx + device.packets_tx] |
add dword[ebx + device.bytes_tx], ecx |
mov eax, [buffer_size] |
add dword[ebx + device.bytes_tx], eax |
adc dword[ebx + device.bytes_tx + 4], 0 |
invoke NetFree, [buffer_ptr] |
invoke KernelFree, [buffer_ptr] |
popf |
xor eax, eax |
ret |
726,7 → 725,7 |
.err: |
DEBUGF 2, "Transmit error!\n" |
invoke NetFree, [buffer_ptr] |
invoke KernelFree, [buffer_ptr] |
popf |
or eax, -1 |
ret |
786,15 → 785,14 |
jz .no_rx ; FIXME: Only PIO mode supported for now |
; allocate a buffer |
invoke NetAlloc, ETH_FRAME_LEN+NET_BUFF.data |
invoke KernelAlloc, ETH_FRAME_LEN |
test eax, eax |
jz .rx_fail_2 |
; Push return address and packet ptr to stack |
pushd .no_rx |
pushd 0 ; Reserve some space for the packet size |
push eax |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
; read offset for current packet from device |
set_io [ebx + device.io_addr], 0 |
828,8 → 826,8 |
movzx esi, ch ; we are using 256 byte pages |
shl esi, 8 ; esi now holds the offset for current packet |
; Write packet header to frame header size field |
push ecx |
; Get packet header in ecx |
push ecx ; reserve 4 bytes on stack to put packet header in |
mov edi, esp |
mov cx, 4 |
call PIO_read |
842,8 → 840,7 |
; calculate packet length in ecx |
shr ecx, 16 |
sub ecx, 4 ; CRC doesnt count as data byte |
mov edi, [esp+4] |
mov [edi + NET_BUFF.length], ecx |
mov [esp + 8], ecx |
; check if packet size is ok |
cmp ecx, ETH_ZLEN |
859,7 → 856,7 |
; update read and write pointers |
add esi, 4 |
add edi, NET_BUFF.data |
mov edi, [esp + 4] |
; now check if we can read all data at once (if we cross the end boundary, we need to wrap back to the beginning) |
xor eax, eax |
897,7 → 894,7 |
out dx, al |
; now send the data to the kernel |
jmp [EthInput] |
jmp [Eth_input] |
.rx_fail_3: |
add esp, 4 |
/drivers/ethernet/RTL8139.asm |
---|
404,6 → 404,7 |
; - Remove all allocated structures and buffers the card used |
or eax, -1 |
ret |
627,26 → 628,27 |
;; ;; |
;; Transmit ;; |
;; ;; |
;; In: pointer to device structure in ebx ;; |
;; In: buffer pointer in [esp+4] ;; |
;; size of buffer in [esp+8] ;; |
;; pointer to device structure in ebx ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
; check if we own the current discriptor |
660,30 → 662,29 |
jz .wait_to_send |
.send_packet: |
; get next descriptor |
inc [ebx + device.curr_tx_desc] |
and [ebx + device.curr_tx_desc], NUM_TX_DESC-1 |
; Update stats |
inc [ebx + device.packets_tx] |
mov eax, [buffersize] |
add dword [ebx + device.bytes_tx], eax |
adc dword [ebx + device.bytes_tx+4], 0 |
; Set the buffer address |
set_io [ebx + device.io_addr], REG_TSAD0 |
mov [ebx + device.TX_DESC+ecx], esi |
mov eax, esi |
add eax, [eax + NET_BUFF.offset] |
mov eax, [bufferptr] |
mov [ebx + device.TX_DESC+ecx], eax |
invoke GetPhysAddr |
out dx, eax |
; And the size of the buffer |
set_io [ebx + device.io_addr], REG_TSD0 |
mov eax, [esi + NET_BUFF.length] |
mov eax, [buffersize] |
or eax, (ERTXTH shl BIT_ERTXTH) ; Early threshold |
out dx, eax |
; get next descriptor |
inc [ebx + device.curr_tx_desc] |
and [ebx + device.curr_tx_desc], NUM_TX_DESC-1 |
; Update stats |
inc [ebx + device.packets_tx] |
mov ecx, [esi + NET_BUFF.length] |
add dword [ebx + device.bytes_tx], ecx |
adc dword [ebx + device.bytes_tx+4], 0 |
DEBUGF 1, "Packet Sent!\n" |
popf |
xor eax, eax |
709,7 → 710,7 |
.fail: |
DEBUGF 2, "transmit failed!\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
794,21 → 795,18 |
DEBUGF 1, "Received %u bytes\n", ecx |
push ebx eax ecx |
add ecx, NET_BUFF.data |
invoke NetAlloc, ecx ; Allocate a buffer to put packet into |
invoke KernelAlloc, ecx ; Allocate a buffer to put packet into |
pop ecx |
test eax, eax ; Test if we allocated succesfully |
jz .abort |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
lea edi, [eax + NET_BUFF.data] ; Where we will copy too |
mov edi, eax ; Where we will copy too |
mov esi, [esp] ; The buffer we will copy from |
add esi, 4 ; Dont copy CRC |
push .abort ; return addr for Eth_input |
push eax ; buffer ptr for Eth_input |
push dword .abort ; Kernel will return to this address after EthReceiver |
push ecx edi ; Save buffer pointer and size, to pass to kernel |
.copy: |
shr ecx, 1 |
823,7 → 821,7 |
rep movsd |
.nd: |
jmp [EthInput] ; Send it to kernel |
jmp [Eth_input] ; Send it to kernel |
.abort: |
pop eax ebx |
925,7 → 923,7 |
.no_tok: |
DEBUGF 1, "free transmit buffer 0x%x\n", [ebx + device.TX_DESC+ecx]:8 |
push ecx ebx |
invoke NetFree, [ebx + device.TX_DESC+ecx] |
invoke KernelFree, [ebx + device.TX_DESC+ecx] |
pop ebx ecx |
mov [ebx + device.TX_DESC+ecx], 0 |
/drivers/ethernet/dec21x4x.asm |
---|
594,6 → 594,8 |
@@: |
;;; Find connected mii xceivers? 993-1043 |
; Reset the xcvr interface and turn on heartbeat. |
cmp [ebx + device.id], DC21041 |
jne @f |
867,23 → 869,19 |
DEBUGF 1,"RX descriptor 0x%x\n", edi |
add edx, sizeof.desc |
mov [edi + desc.status], DES0_OWN |
mov [edi + desc.length], 1514 |
mov [edi + desc.length], 1536 |
push edx edi ecx |
invoke NetAlloc, 1514+NET_BUFF.data |
invoke KernelAlloc, 1536 |
pop ecx edi edx |
test eax, eax |
jz .out_of_mem |
mov [edi + RX_RING_SIZE*sizeof.desc], eax |
push edx |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
pop edx |
mov [edi + desc.buffer1], eax |
mov [edi + desc.buffer2], edx |
add edi, sizeof.desc |
dec ecx |
jnz .loop_rx_des |
; set last descriptor as LAST |
or [edi - sizeof.desc + desc.length], RDES1_RER ; EndOfRing |
pop [edi - sizeof.desc + desc.buffer2] ; point it to the first descriptor |
919,7 → 917,6 |
mov [ebx + device.last_tx], eax |
mov [ebx + device.cur_rx], eax |
; xor eax, eax |
ret |
.out_of_mem: |
1046,15 → 1043,13 |
DEBUGF 1,"Creating setup packet\n" |
invoke NetAlloc, 192 + NET_BUFF.data |
invoke KernelAlloc, 192 |
test eax, eax |
jz .err |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.length], 192 |
push eax |
lea edi, [eax + NET_BUFF.data] |
mov edi, eax |
xor eax, eax |
dec ax |
stosd |
1076,22 → 1071,18 |
DEBUGF 1, "attaching setup packet 0x%x to descriptor 0x%x\n", eax, edi |
mov [edi + TX_RING_SIZE*sizeof.desc], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [edi + desc.buffer1], eax |
mov [edi + desc.length], TDES1_SET or 192 ; size must be EXACTLY 192 bytes + TDES1_IC |
mov [edi + desc.length], TDES1_SET + 192 ; size must be EXACTLY 192 bytes + TDES1_IC |
mov [edi + desc.status], DES0_OWN |
DEBUGF 1, "descriptor 0x%x\n", edi |
; go to next descriptor |
inc [ebx + device.cur_tx] |
and [ebx + device.cur_tx], TX_RING_SIZE-1 |
xor eax, eax |
ret |
.err: |
DEBUGF 2, "Out of memory!\n" |
or eax, -1 |
ret |
1100,51 → 1091,50 |
;; ;; |
;; Transmit ;; |
;; ;; |
;; In: ebx = pointer to device structure ;; |
;; Out: eax = 0 on success ;; |
;; In: buffer pointer in [esp+4] ;; |
;; size of buffer in [esp+8] ;; |
;; pointer to device structure in ebx ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
jb .fail |
mov eax, [ebx + device.cur_tx] |
mov edx, sizeof.desc |
mul edx |
lea edi, [ebx + device.tx_ring + eax] |
test [edi + desc.status], DES0_OWN |
lea esi, [ebx + device.tx_ring + eax] |
test [esi + desc.status], DES0_OWN |
jnz .fail |
DEBUGF 1, "Descriptor is free\n" |
mov eax, [bufferptr] |
mov [edi + TX_RING_SIZE*sizeof.desc], eax |
add eax, [eax + NET_BUFF.offset] |
mov [esi + TX_RING_SIZE*sizeof.desc], eax |
invoke GetPhysAddr |
mov [edi + desc.buffer1], eax |
mov [esi + desc.buffer1], eax |
; set packet size |
mov eax, [edi + desc.length] |
mov eax, [esi + desc.length] |
and eax, TDES1_TER ; preserve 'End of Ring' bit |
or eax, [esi + NET_BUFF.length] ; set size |
or eax, [buffersize] ; set size |
or eax, TDES1_FS or TDES1_LS or TDES1_IC ; first descr, last descr, interrupt on complete |
mov [edi + desc.length], eax |
mov [esi + desc.length], eax |
; set descriptor status |
mov [edi + desc.status], DES0_OWN ; say it is now owned by the 21x4x |
mov [esi + desc.status], DES0_OWN ; say it is now owned by the 21x4x |
; Check if transmitter is running |
set_io [ebx + device.io_addr], 0 |
1165,8 → 1155,8 |
; Update stats |
inc [ebx + device.packets_tx] |
mov ecx, [esi + NET_BUFF.length] |
add dword [ebx + device.bytes_tx], ecx |
mov eax, [buffersize] |
add dword [ebx + device.bytes_tx], eax |
adc dword [ebx + device.bytes_tx + 4], 0 |
; go to next descriptor |
1179,8 → 1169,8 |
ret |
.fail: |
DEBUGF 1,"Transmit failed\n" |
invoke NetFree, [bufferptr] |
DEBUGF 2,"Transmit failed\n" |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
1251,7 → 1241,7 |
mov [eax + desc.buffer1], 0 |
DEBUGF 1, "Free buffer 0x%x\n", [eax + TX_RING_SIZE*sizeof.desc] |
invoke NetFree, [eax + TX_RING_SIZE*sizeof.desc] |
invoke KernelFree, [eax + TX_RING_SIZE*sizeof.desc] |
; advance to next descriptor |
inc [ebx + device.last_tx] |
1264,6 → 1254,7 |
;---------------------------------- |
; RX irq |
test eax, CSR5_RI |
jz .not_rx |
push eax esi ecx |
1280,7 → 1271,7 |
mul edx |
lea edi, [ebx + device.rx_ring + eax] |
; now check status |
; Check current RX descriptor status |
mov eax, [edi + desc.status] |
test eax, DES0_OWN |
1299,14 → 1290,11 |
sub ecx, 4 ; throw away the CRC |
DEBUGF 1,"got %u bytes\n", ecx |
; Push arguments for EthInput (and some more...) |
; Push arguments for Eth_input (and some more...) |
push ebx |
push .rx_loop ; return addr |
mov eax, dword[edi + RX_RING_SIZE*sizeof.desc] |
push eax |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
push ecx ; packet size |
push dword[edi + RX_RING_SIZE*sizeof.desc] ; packet ptr |
; update statistics |
inc [ebx + device.packets_rx] |
1315,12 → 1303,10 |
; Allocate new descriptor |
push edi ebx |
invoke NetAlloc, 1514 + NET_BUFF.data ; Allocate a buffer to put packet into |
invoke KernelAlloc, 1536 ; Allocate a buffer to put packet into |
pop ebx edi |
jz .fail |
mov [edi + RX_RING_SIZE*sizeof.desc], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [edi + desc.buffer1], eax |
mov [edi + desc.status], DES0_OWN ; mark descriptor as being free |
1328,10 → 1314,8 |
inc [ebx + device.cur_rx] ; next descriptor |
and [ebx + device.cur_rx], RX_RING_SIZE-1 |
jmp [EthInput] |
jmp [Eth_input] |
.end_rx: |
.fail: |
pop ecx esi eax |
.not_rx: |
pop edi esi ebx |
/drivers/ethernet/forcedeth.asm |
---|
35,7 → 35,7 |
MAX_DEVICES = 16 |
RBLEN = 0 ; Receive buffer size: 0=4K 1=8k 2=16k 3=32k 4=64k |
; FIXME: option 1 and 2 may allocate a non contiguous buffer causing data loss! |
; FIXME: option 1 and 2 will not allocate buffer correctly causing data loss! |
DEBUG = 1 |
__DEBUG__ = 1 |
1371,7 → 1371,7 |
init_ring: |
DEBUGF 1,"init rings\n" |
push esi ecx |
push eax esi ecx |
mov [ebx + device.cur_tx], 0 |
mov [ebx + device.last_tx], 0 |
1392,13 → 1392,10 |
lea esi, [ebx + device.rx_ring] |
.rx_loop: |
push ecx esi |
invoke NetAlloc, (4096 shl RBLEN) + NET_BUFF.data ; push/pop esi not needed, but just in case... |
invoke KernelAlloc, 4096 shl RBLEN ; push/pop esi not needed, but just in case... |
pop esi |
test eax, eax |
jz .out_of_mem |
mov [esi + RX_RING*sizeof.RxDesc], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [esi + RxDesc.PacketBuffer], eax |
mov [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL) |
add esi, sizeof.RxDesc |
1406,20 → 1403,14 |
dec ecx |
jnz .rx_loop |
pop ecx esi |
pop ecx esi eax |
xor eax, eax |
ret |
.out_of_mem: |
add esp, 12 |
or eax, -1 |
ret |
; Input: none |
; Output: none |
align 4 |
1790,42 → 1781,41 |
;; Transmit ;; |
;; ;; |
;; In: buffer pointer in [esp+4] ;; |
;; size of buffer in [esp+8] ;; |
;; pointer to device structure in ebx ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
; get the descriptor address |
mov eax, [ebx + device.cur_tx] |
shl eax, 3 ; TX descriptor is 8 bytes. |
lea edi, [ebx + device.tx_ring + eax] |
lea esi, [ebx + device.tx_ring + eax] |
mov eax, [bufferptr] |
mov [edi + TX_RING*sizeof.TxDesc], eax |
add eax, [eax + NET_BUFF.offset] |
mov [esi + TX_RING*sizeof.TxDesc], eax |
invoke GetPhysAddr ; Does not change esi/ebx :) |
mov [edi + TxDesc.PacketBuffer], eax |
mov [esi + TxDesc.PacketBuffer], eax |
mov ecx, [esi + NET_BUFF.length] |
or ecx, [ebx + device.txflags] |
mov [edi + TxDesc.FlagLen], ecx |
mov eax, [buffersize] |
or eax, [ebx + device.txflags] |
mov [esi + TxDesc.FlagLen], eax |
mov edi, [ebx + device.mmio_addr] |
mov eax, [ebx + device.desc_ver] |
1839,7 → 1829,8 |
; Update stats |
inc [ebx + device.packets_tx] |
add dword[ebx + device.bytes_tx], ecx |
mov eax, [buffersize] |
add dword[ebx + device.bytes_tx], eax |
adc dword[ebx + device.bytes_tx + 4], 0 |
popf |
1848,7 → 1839,7 |
.fail: |
DEBUGF 2,"Send failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
1905,33 → 1896,33 |
mov cx, sizeof.RxDesc |
mul cx |
lea esi, [ebx + device.rx_ring + eax] |
mov ecx, [esi + RxDesc.FlagLen] |
mov eax, [esi + RxDesc.FlagLen] |
test ecx, NV_RX_AVAIL ; still owned by hardware |
test eax, NV_RX_AVAIL ; still owned by hardware |
jnz .no_rx |
cmp [ebx + device.desc_ver], DESC_VER_1 |
jne @f |
test ecx, NV_RX_DESCRIPTORVALID |
test eax, NV_RX_DESCRIPTORVALID |
jz .no_rx |
jmp .next |
@@: |
test ecx, NV_RX2_DESCRIPTORVALID |
test eax, NV_RX2_DESCRIPTORVALID |
jz .no_rx |
.next: |
cmp dword[ebx + device.desc_ver], DESC_VER_1 |
jne @f |
and ecx, LEN_MASK_V1 |
and eax, LEN_MASK_V1 |
jmp .next2 |
@@: |
and ecx, LEN_MASK_V2 |
and eax, LEN_MASK_V2 |
.next2: |
DEBUGF 1,"Received %u bytes\n", ecx |
DEBUGF 1,"Received %u bytes\n", eax |
; Update stats |
add dword[ebx + device.bytes_rx], ecx |
add dword[ebx + device.bytes_rx], eax |
adc dword[ebx + device.bytes_rx + 4], 0 |
inc dword[ebx + device.packets_rx] |
1939,18 → 1930,14 |
push ebx |
push .more_rx |
mov eax, [esi + RX_RING*sizeof.RxDesc] |
push eax |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
push dword[esi + RX_RING*sizeof.RxDesc] |
DEBUGF 1,"packet ptr=0x%x\n", [esi + RX_RING*sizeof.RxDesc] |
; Allocate new buffer for this descriptor |
invoke NetAlloc, (4096 shl RBLEN) + NET_BUFF.data |
invoke KernelAlloc, 4096 shl RBLEN |
mov [esi + RX_RING*sizeof.RxDesc], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [esi + RxDesc.PacketBuffer], eax |
mov [esi + RxDesc.FlagLen], (4096 shl RBLEN or NV_RX_AVAIL) |
1958,7 → 1945,7 |
inc [ebx + device.cur_rx] |
and [ebx + device.cur_rx], (RX_RING-1) |
jmp [EthInput] |
jmp [Eth_input] |
.no_rx: |
test eax, IRQ_RX_ERROR |
2012,7 → 1999,7 |
DEBUGF 1,"Freeing buffer 0x%x\n", [esi + TX_RING*sizeof.TxDesc]:8 |
push dword[esi + TX_RING*sizeof.TxDesc] |
mov dword[esi + TX_RING*sizeof.TxDesc], 0 |
invoke NetFree |
invoke KernelFree |
inc [ebx + device.last_tx] |
and [ebx + device.last_tx], TX_RING - 1 |
/drivers/ethernet/i8254x.asm |
---|
472,6 → 472,7 |
; - Remove all allocated structures and buffers the card used |
or eax, -1 |
ret |
559,9 → 560,8 |
lea edi, [ebx + device.rx_desc] |
mov ecx, RX_RING_SIZE |
.loop: |
push ecx |
push edi |
invoke NetAlloc, MAX_PKT_SIZE+NET_BUFF.data |
push ecx edi |
invoke KernelAlloc, MAX_PKT_SIZE |
test eax, eax |
jz .out_of_mem |
DEBUGF 1,"RX buffer: 0x%x\n", eax |
570,7 → 570,6 |
push edi |
invoke GetPhysAddr |
pop edi |
add eax, NET_BUFF.data |
mov [edi + RDESC.addr_l], eax |
mov [edi + RDESC.addr_h], 0 |
mov [edi + RDESC.status_l], 0 |
708,27 → 707,25 |
;; ;; |
;; Transmit ;; |
;; ;; |
;; In: ebx = pointer to device structure ;; |
;; Out: eax = 0 on success ;; |
;; In: pointer to device structure in ebx ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
; Program the descriptor (use legacy mode) |
736,14 → 733,12 |
DEBUGF 1, "Using TX desc: %u\n", edi |
shl edi, 4 ; edi = edi * sizeof.TDESC |
lea edi, [ebx + device.tx_desc + edi] |
mov eax, esi |
mov dword[edi + TX_RING_SIZE*sizeof.TDESC], eax ; Store the data location (for driver) |
add eax, [eax + NET_BUFF.offset] |
invoke GetPhysAddr |
mov [edi + TDESC.addr_l], eax ; Data location (for hardware) |
mov [edi + TDESC.addr_h], 0 |
mov ecx, [esi + NET_BUFF.length] |
mov ecx, [buffersize] |
or ecx, TXDESC_EOP + TXDESC_IFCS + TXDESC_RS |
mov [edi + TDESC.length_cso_cmd], ecx |
mov [edi + TDESC.status], 0 |
758,7 → 753,7 |
; Update stats |
inc [ebx + device.packets_tx] |
mov eax, [esi + NET_BUFF.length] |
mov eax, [buffersize] |
add dword[ebx + device.bytes_tx], eax |
adc dword[ebx + device.bytes_tx + 4], 0 |
772,7 → 767,7 |
call clean_tx |
DEBUGF 2,"Send failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
838,11 → 833,8 |
push .retaddr |
movzx ecx, word[esi + 8] ; Get the packet length |
DEBUGF 1,"got %u bytes\n", ecx |
mov eax, [esi + RX_RING_SIZE*sizeof.RDESC] ; Get packet pointer |
push eax |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
push ecx |
push dword[esi + RX_RING_SIZE*sizeof.RDESC] ; Get packet pointer |
; Update stats |
add dword[ebx + device.bytes_rx], ecx |
851,13 → 843,12 |
; Allocate new descriptor |
push esi |
invoke NetAlloc, MAX_PKT_SIZE+NET_BUFF.data |
invoke KernelAlloc, MAX_PKT_SIZE |
pop esi |
test eax, eax |
jz .out_of_mem |
mov dword[esi + RX_RING_SIZE*sizeof.RDESC], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [esi + RDESC.addr_l], eax |
mov [esi + RDESC.status_l], 0 |
mov [esi + RDESC.status_h], 0 |
871,7 → 862,7 |
inc [ebx + device.cur_rx] |
and [ebx + device.cur_rx], RX_RING_SIZE-1 |
jmp [EthInput] |
jmp [Eth_input] |
.out_of_mem: |
DEBUGF 2,"Out of memory!\n" |
880,7 → 871,7 |
inc [ebx + device.cur_rx] |
and [ebx + device.cur_rx], RX_RING_SIZE-1 |
jmp [EthInput] |
jmp [Eth_input] |
.no_rx: |
;-------------- |
927,7 → 918,7 |
push ebx |
push dword[edi + TX_RING_SIZE*sizeof.TDESC] |
mov dword[edi + TX_RING_SIZE*sizeof.TDESC], 0 |
invoke NetFree |
invoke KernelFree |
pop ebx |
inc [ebx + device.last_tx] |
/drivers/ethernet/i8255x.asm |
---|
18,7 → 18,9 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; TODO: use separate descriptors in memory instead of placing them in front of packets! |
format PE DLL native |
entry START |
76,8 → 78,6 |
CmdTxFlex = 0x0008 |
Cmdsuspend = 0x4000 |
CmdRxFlex = 0x0008 |
reg_scb_status = 0 |
reg_scb_cmd = 2 |
reg_scb_ptr = 4 |
487,8 → 487,6 |
; Create RX and TX descriptors |
call create_ring |
test eax, eax |
jz .error |
; RX start |
496,7 → 494,6 |
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 |
mov ax, INT_MASK + RX_START |
583,11 → 580,7 |
xor eax, eax ; indicate that we have successfully reset the card |
ret |
.error: |
or eax, -1 |
ret |
align 4 |
create_ring: |
596,18 → 589,15 |
;--------------------- |
; build rxfd structure |
invoke NetAlloc, 2000 |
test eax, eax |
jz .out_of_mem |
invoke KernelAlloc, 2000 |
mov [ebx + device.rx_desc], eax |
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], 0x0000 |
mov [esi + sizeof.NET_BUFF + rxfd.link], eax |
mov [esi + sizeof.NET_BUFF + rxfd.count], 0 |
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 |
mov [esi + rxfd.status], 0x0000 |
mov [esi + rxfd.command], 0x0000 |
mov [esi + rxfd.link], eax |
mov [esi + rxfd.count], 0 |
mov [esi + rxfd.size], 1528 |
;----------------------- |
; build txfd structure |
620,8 → 610,6 |
invoke GetPhysAddr |
mov [ebx + device.txfd.desc_addr], eax |
.out_of_mem: |
ret |
634,37 → 622,33 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
;;; TODO: check if current descriptor is in use |
; fill in buffer address and size |
mov eax, [bufferptr] |
mov [ebx + device.last_tx_buffer], eax |
add eax, [eax + NET_BUFF.offset] |
invoke GetPhysAddr |
mov [ebx + device.txfd.buf_addr0], eax |
mov ecx, [bufferptr] |
mov ecx, [ecx + NET_BUFF.length] |
mov ecx, [buffersize] |
mov [ebx + device.txfd.buf_size0], ecx |
mov [ebx + device.txfd.status], 0 |
mov [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex ;+ 1 shl 15 ;;; EL bit |
mov [ebx + device.txfd.command], Cmdsuspend + CmdTx + CmdTxFlex + 1 shl 15 ;;; EL bit |
; mov [txfd.count], 0x02208000 ;;;;;;;;;;; |
; Inform device of the new/updated transmit descriptor |
682,6 → 666,7 |
; Update stats |
inc [ebx + device.packets_tx] |
mov ecx, [buffersize] |
add dword[ebx + device.bytes_tx], ecx |
adc dword[ebx + device.bytes_tx + 4], 0 |
691,7 → 676,7 |
ret |
.fail: |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
753,20 → 738,19 |
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) |
cmp [esi + rxfd.status], 0 ; we could also check bits C and OK (bit 15 and 13) |
je .nodata |
DEBUGF 1,"rxfd status=0x%x\n", [esi + sizeof.NET_BUFF + rxfd.status]:4 |
DEBUGF 1,"rxfd status=0x%x\n", [esi + rxfd.status]:4 |
movzx ecx, [esi + sizeof.NET_BUFF + rxfd.count] |
movzx ecx, [esi + rxfd.count] |
and ecx, 0x3fff |
push ebx |
push .rx_loop |
push ecx |
add esi, rxfd.packet |
push esi |
mov [esi + NET_BUFF.length], ecx |
mov [esi + NET_BUFF.device], ebx |
mov [esi + NET_BUFF.offset], NET_BUFF.data + rxfd.packet |
; Update stats |
add dword [ebx + device.bytes_rx], ecx |
775,16 → 759,15 |
; allocate new descriptor |
invoke NetAlloc, 2000 |
invoke KernelAlloc, 2000 |
mov [ebx + device.rx_desc], eax |
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.link], eax |
mov [esi + sizeof.NET_BUFF + rxfd.count], 0 |
mov [esi + sizeof.NET_BUFF + rxfd.size], 1528 |
mov [esi + rxfd.status], 0x0000 |
mov [esi + rxfd.command], 0xc000 ; End of list + Suspend |
mov [esi + rxfd.link], eax |
mov [esi + rxfd.count], 0 |
mov [esi + rxfd.size], 1528 |
; restart RX |
800,7 → 783,7 |
call cmd_wait |
; And give packet to kernel |
jmp [EthInput] |
jmp [Eth_input] |
.nodata: |
DEBUGF 1, "no more data\n" |
/drivers/ethernet/mtd80x.asm |
---|
473,6 → 473,7 |
; - Remove all allocated structures and buffers the card used |
or eax, -1 |
ret |
626,8 → 627,6 |
out dx, eax |
call init_ring |
test eax, eax |
jnz .err |
; Initialize other registers. |
; Configure the PCI bus bursts and FIFO thresholds. |
677,14 → 676,9 |
xor eax, eax |
ret |
.err: |
DEBUGF 2, "Error!\n" |
or eax, -1 |
ret |
align 4 |
init_ring: |
696,7 → 690,7 |
mov ecx, NUM_RX_DESC |
.rx_desc_loop: |
mov [esi + descriptor.status], RXOWN |
mov [esi + descriptor.control], 1514 shl RBSShift |
mov [esi + descriptor.control], 1536 shl RBSShift |
lea eax, [esi + sizeof.descriptor] |
mov [esi + descriptor.next_desc_logical], eax |
704,14 → 698,11 |
invoke GetPhysAddr |
mov [esi + descriptor.next_desc], eax |
invoke NetAlloc, 1514+NET_BUFF.data |
pop esi ecx |
test eax, eax |
jz .out_of_mem |
push ecx esi |
invoke KernelAlloc, 1536 |
pop esi |
push esi |
mov [esi + descriptor.skbuff], eax |
invoke GetPgAddr |
add eax, NET_BUFF.data |
pop esi ecx |
mov [esi + descriptor.buffer], eax |
759,14 → 750,9 |
set_io [ebx + device.io_addr], TXLBA |
out dx, eax |
xor eax, eax |
ret |
.out_of_mem: |
or eax, -1 |
ret |
align 4 |
set_rx_mode: |
938,25 → 924,25 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
mov esi, [ebx + device.cur_tx] |
test [esi + descriptor.status], TXOWN |
jnz .fail |
965,12 → 951,10 |
mov eax, [bufferptr] |
mov [esi + descriptor.skbuff], eax |
add eax, [eax + NET_BUFF.offset] |
invoke GetPhysAddr |
mov [esi + descriptor.buffer], eax |
mov eax, [bufferptr] |
mov eax, [eax + NET_BUFF.length] |
mov eax, [buffersize] |
mov ecx, eax |
shl eax, PKTSShift ; packet size |
shl ecx, TBSShift |
981,9 → 965,8 |
; Update stats |
inc [ebx + device.packets_tx] |
mov eax, [bufferptr] |
mov ecx, [eax + NET_BUFF.length] |
add dword[ebx + device.bytes_tx], ecx |
mov eax, [buffersize] |
add dword[ebx + device.bytes_tx], eax |
adc dword[ebx + device.bytes_tx + 4], 0 |
; TX Poll |
999,7 → 982,7 |
.fail: |
DEBUGF 2,"Transmit failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
1085,12 → 1068,8 |
mov ecx, [esi + descriptor.status] |
shr ecx, FLNGShift |
sub ecx, 4 ; we dont need CRC |
push ecx |
DEBUGF 1,"Received %u bytes\n", ecx |
mov eax, [esi + descriptor.skbuff] |
push eax |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
; Update stats |
add dword[ebx + device.bytes_rx], ecx |
1097,20 → 1076,18 |
adc dword[ebx + device.bytes_rx + 4], 0 |
inc [ebx + device.packets_rx] |
jmp [EthInput] |
push [esi + descriptor.skbuff] |
jmp [Eth_input] |
.rx_complete: |
pop ebx |
mov esi, [ebx + device.cur_rx] |
mov [esi + descriptor.control], 1514 shl RBSShift |
mov [esi + descriptor.control], 1536 shl RBSShift |
push esi |
invoke NetAlloc, 1514+NET_BUFF.data |
invoke KernelAlloc, 1536 |
pop esi |
; test eax, eax |
; jz .rx_loop |
mov [esi + descriptor.skbuff], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
invoke GetPgAddr |
mov [esi + descriptor.buffer], eax |
mov [esi + descriptor.status], RXOWN |
1145,7 → 1122,7 |
je .skip_this_one |
mov [esi + descriptor.skbuff], 0 |
DEBUGF 1,"freeing buffer: 0x%x\n", eax |
invoke NetFree, eax |
invoke KernelFree, eax |
.skip_this_one: |
mov esi, [esi + descriptor.next_desc_logical] |
loop .tx_loop |
/drivers/ethernet/pcnet32.asm |
---|
491,7 → 491,7 |
.destroy: |
; todo: reset device into virgin state |
add eax, NET_BUFF.data |
dec [devices] |
.err: |
DEBUGF 2,"Error, removing all data !\n" |
522,6 → 522,7 |
; - Remove all allocated structures and buffers the card used |
or eax, -1 |
ret |
867,8 → 868,6 |
movsw |
call init_ring |
test eax, eax |
jnz .fail |
mov edx, [ebx + device.io_addr] ; init ring destroys edx |
924,7 → 923,6 |
DEBUGF 1,"reset complete\n" |
xor eax, eax |
.fail: |
ret |
940,13 → 938,10 |
mov ecx, RX_RING_SIZE |
.rx_init: |
push ecx |
invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data |
invoke KernelAlloc, PKT_BUF_SZ |
pop ecx |
test eax, eax |
jz .out_of_mem |
mov [edi + descriptor.virtual], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [edi + descriptor.base], eax |
mov [edi + descriptor.length], - PKT_BUF_SZ |
mov [edi + descriptor.status], RXSTAT_OWN |
972,18 → 967,11 |
mov [ebx + device.last_tx], 0 |
mov [ebx + device.cur_rx], 0 |
xor eax, eax |
ret |
.out_of_mem: |
DEBUGF 2,"Out of memory!\n" |
or eax, -1 |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Transmit ;; |
992,40 → 980,38 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
; check descriptor |
lea edi, [ebx + device.tx_ring] |
movzx ecx, [ebx + device.cur_tx] |
shl ecx, 4 |
add edi, ecx |
movzx eax, [ebx + device.cur_tx] |
shl eax, 4 |
add edi, eax |
test [edi + descriptor.status], TXCTL_OWN |
jnz .fail |
; descriptor is free, use it |
mov [edi + descriptor.virtual], esi |
mov eax, esi |
add eax, [eax + NET_BUFF.offset] |
mov eax, [bufferptr] |
mov [edi + descriptor.virtual], eax |
invoke GetPhysAddr |
mov [edi + descriptor.base], eax |
; set length |
mov eax, [esi + NET_BUFF.length] |
mov eax, [buffersize] |
neg eax |
mov [edi + descriptor.length], ax |
; put to transfer queue |
1044,7 → 1030,7 |
; Update stats |
inc [ebx + device.packets_tx] |
mov eax, [esi + NET_BUFF.length] |
mov eax, [buffersize] |
add dword[ebx + device.bytes_tx], eax |
adc dword[ebx + device.bytes_tx + 4], 0 |
1055,7 → 1041,7 |
.fail: |
DEBUGF 2, "Send failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
1138,11 → 1124,8 |
push ebx |
push .rx_loop ; return address |
mov eax, [edi + descriptor.virtual] |
push eax ; packet address |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
push ecx ; packet size |
push [edi + descriptor.virtual] ; packet address |
; Update stats |
add dword[ebx + device.bytes_rx], ecx |
1150,12 → 1133,9 |
inc [ebx + device.packets_rx] |
; now allocate a new buffer |
invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data ; Allocate a buffer for the next packet |
test eax, eax |
jz .out_of_mem |
invoke KernelAlloc, PKT_BUF_SZ ; Allocate a buffer for the next packet |
mov [edi + descriptor.virtual], eax ; set virtual address |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [edi + descriptor.base], eax ; and physical address |
mov [edi + descriptor.status], RXSTAT_OWN ; give it back to PCnet controller |
1162,16 → 1142,8 |
inc [ebx + device.cur_rx] ; set next receive descriptor |
and [ebx + device.cur_rx], RX_RING_SIZE - 1 |
jmp [EthInput] |
jmp [Eth_input] |
.out_of_mem: |
DEBUGF 2,"Out of memory!\n" |
inc [ebx + device.cur_rx] ; set next receive descriptor |
and [ebx + device.cur_rx], RX_RING_SIZE - 1 |
jmp [EthInput] |
.not_receive: |
pop ax |
1195,7 → 1167,7 |
DEBUGF 1,"Removing packet %x from memory\n", eax |
invoke NetFree, eax |
invoke KernelFree, eax |
inc [ebx + device.last_tx] |
and [ebx + device.last_tx], TX_RING_SIZE - 1 |
/drivers/ethernet/rhine.asm |
---|
346,7 → 346,7 |
NIC_LB_INTERNAL = 0x01 |
NIC_LB_PHY = 0x02 ; MII or Internal-10BaseT loopback |
PKT_BUF_SZ = 1514 |
PKT_BUF_SZ = 1536 ; Size of each temporary Rx buffer. |
PCI_REG_MODE3 = 0x53 |
MODE3_MIION = 0x04 ; in PCI_REG_MOD3 OF PCI space |
929,7 → 929,11 |
DEBUGF 1,"Attaching int handler to irq %x\n", eax:1 |
invoke AttachIntHandler, eax, int_handler, ebx |
test eax, eax |
jz .err |
jnz @f |
DEBUGF 2,"Could not attach int handler!\n" |
or eax, -1 |
ret |
@@: |
; Soft reset the chip. |
set_io [ebx + device.io_addr], 0 |
941,8 → 945,6 |
; Initialize rings |
call init_ring |
test eax, eax |
jnz .err |
; Set Multicast |
call set_rx_mode |
966,6 → 968,7 |
out dx, al |
; Set Fulldupex |
call QueryAuto |
test eax, eax ; full duplex? |
jz @f |
1004,13 → 1007,8 |
xor eax, eax |
ret |
.err: |
DEBUGF 2,"Error!\n" |
or eax, -1 |
ret |
align 4 |
unload: |
1075,13 → 1073,10 |
mov [edi + rx_head.status], RX_SBITS_OWN_BIT |
mov [edi + rx_head.control], PKT_BUF_SZ |
push ecx |
invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data |
invoke KernelAlloc, PKT_BUF_SZ |
pop ecx |
test eax, eax |
jz .out_of_mem |
mov [edi + rx_head.buff_addr_virt], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [edi + rx_head.buff_addr], eax ; buffer ptr |
mov [edi + rx_head.next_desc], esi ; next head |
add edi, sizeof.rx_head |
1125,15 → 1120,9 |
mov [ebx + device.cur_tx], ax |
mov [ebx + device.last_tx], ax |
xor eax, eax |
ret |
.out_of_mem: |
add esp, 4 |
or eax, -1 |
ret |
align 4 |
QueryAuto: |
1360,8 → 1349,8 |
out dx, eax |
set_io [ebx + device.io_addr], byRCR |
mov al, 0x6C ; thresh or rx_mode |
out dx, al |
mov al, 0x6C ;rx_mode = 0x0C; |
out dx, al ;outb(0x60 /* thresh */ | rx_mode, byRCR ); |
ret |
1404,26 → 1393,26 |
;; Transmit ;; |
;; ;; |
;; In: buffer pointer in [esp+4] ;; |
;; size of buffer in [esp+8] ;; |
;; pointer to device structure in ebx ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 4 |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
movzx eax, [ebx + device.cur_tx] |
1435,12 → 1424,11 |
cmp [edi + tx_head.buff_addr_virt], 0 |
jne .fail |
mov eax, esi |
mov eax, [bufferptr] |
mov [edi + tx_head.buff_addr_virt], eax |
add eax, [eax + NET_BUFF.offset] |
invoke GetPhysAddr |
mov [edi + tx_head.buff_addr], eax |
mov ecx, [esi + NET_BUFF.length] |
mov ecx, [buffersize] |
and ecx, TX_CBITS_TX_BUF_SIZE |
or ecx, 0x00E08000 |
mov [edi + tx_head.control], ecx |
1459,7 → 1447,7 |
; Update stats |
inc [ebx + device.packets_tx] |
mov ecx, [esi + NET_BUFF.length] |
mov ecx, [buffersize] |
add dword [ebx + device.bytes_tx], ecx |
adc dword [ebx + device.bytes_tx + 4], 0 |
1470,7 → 1458,7 |
.fail: |
DEBUGF 2,"Transmit failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
1493,6 → 1481,7 |
DEBUGF 1,"INT\n" |
; Find pointer of device which made IRQ occur |
mov ecx, [devices] |
test ecx, ecx |
jz .nothing |
1517,7 → 1506,9 |
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) |
.got_it: |
DEBUGF 1, "status=0x%x\n", ax |
push ax |
1530,6 → 1521,7 |
pop ebx |
; Get the current descriptor pointer |
movzx eax, [ebx + device.cur_rx] |
mov ecx, sizeof.rx_head |
mul ecx |
1537,8 → 1529,9 |
add edi, eax |
; Check it's status |
test [edi + rx_head.status], RX_SBITS_OWN_BIT |
jnz .not_RX |
jnz .not_bit_own |
DEBUGF 1, "Packet status = 0x%x\n", [edi + rx_head.status] |
1545,6 → 1538,7 |
; TODO: check error bits |
; get length |
mov ecx, [edi + rx_head.status] |
and ecx, RX_SBITS_FRAME_LENGTH |
shr ecx, 16 |
1551,37 → 1545,41 |
sub ecx, 4 ; We dont want CRC |
; Update stats |
add dword [ebx + device.bytes_rx], ecx |
adc dword [ebx + device.bytes_rx + 4], 0 |
inc [ebx + device.packets_rx] |
; Push packet pointer, kernel will need it.. |
; Push packet size and pointer, kernel will need it.. |
push ebx |
push .more_RX ; return ptr |
mov eax, [edi + rx_head.buff_addr_virt] |
push eax |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
push ecx ; full packet size |
push [edi + rx_head.buff_addr_virt] |
; reset the RX descriptor |
push edi |
invoke NetAlloc, PKT_BUF_SZ+NET_BUFF.data |
invoke KernelAlloc, PKT_BUF_SZ |
pop edi |
mov [edi + rx_head.buff_addr_virt], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov [edi + rx_head.buff_addr], eax |
mov [edi + rx_head.status], RX_SBITS_OWN_BIT |
; Use next descriptor next time |
inc [ebx + device.cur_rx] |
and [ebx + device.cur_rx], RX_RING_SIZE - 1 |
; At last, send packet to kernel |
jmp [EthInput] |
jmp [Eth_input] |
.not_bit_own: |
.not_RX: |
pop ax |
test ax, IntrTxDone |
1604,7 → 1602,7 |
push [edi + tx_head.buff_addr_virt] |
mov [edi + tx_head.buff_addr_virt], 0 |
invoke NetFree |
invoke KernelFree |
inc [ebx + device.last_tx] |
and [ebx + device.last_tx], TX_RING_SIZE - 1 |
1615,12 → 1613,12 |
; On Rhine-II, Bit 3 indicates Tx descriptor write-back race. |
if 0 |
cmp [ebx + device.chip_id], 0x3065 |
cmp [ebx + device.chip_id], 0x3065 ;if (tp->chip_id == 0x3065) |
jne @f |
push ax |
xor eax, eax |
set_io [ebx + device.io_addr], IntrStatus2 |
in al, dx |
in al, dx ; intr_status |= inb(nic->ioaddr + IntrStatus2) << 16; |
shl eax, 16 |
pop ax |
@@: |
/drivers/ethernet/sis900.asm |
---|
414,6 → 414,7 |
; - Remove all allocated structures and buffers the card used |
or eax, -1 |
ret |
;*************************************************************************** |
611,13 → 612,12 |
mov dword [esi + 4], RX_BUFF_SZ ; size |
push ecx esi |
invoke NetAlloc, RX_BUFF_SZ+NET_BUFF.data |
invoke KernelAlloc, RX_BUFF_SZ |
pop esi ecx |
test eax, eax |
jz .fail |
mov dword [esi + 12], eax ; address |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov dword [esi + 8], eax ; real address |
add esi, 16 |
dec ecx |
1006,22 → 1006,21 |
;*************************************************************************** |
align 4 |
proc transmit stdcall bufferptr |
proc transmit stdcall bufferptr, buffersize |
pushf |
cli |
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
lea eax, [esi + NET_BUFF.data] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [buffersize] |
mov eax, [bufferptr] |
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 [esi + NET_BUFF.length], 1514 |
cmp [buffersize], 1514 |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
cmp [buffersize], 60 |
jb .fail |
movzx ecx, [ebx + device.cur_tx] |
1031,13 → 1030,12 |
test dword[ecx + 4], 0x80000000 ; card owns descriptor ? |
jnz .fail |
mov eax, esi |
mov eax, [bufferptr] |
mov dword[ecx + 12], eax |
add eax, [eax + NET_BUFF.offset] |
invoke GetPhysAddr |
mov dword[ecx + 8], eax ; buffer address |
mov eax, [esi + NET_BUFF.length] |
mov eax, [buffersize] |
and eax, DSIZE |
or eax, 0x80000000 ; card owns descriptor |
mov dword[ecx + 4], eax ; status field |
1052,7 → 1050,7 |
and [ebx + device.cur_tx], NUM_TX_DESC-1 |
; update stats |
mov ecx, [esi + NET_BUFF.length] |
mov ecx, [buffersize] |
inc [ebx + device.packets_tx] |
add dword [ebx + device.bytes_tx], ecx |
adc dword [ebx + device.bytes_tx + 4], 0 |
1064,7 → 1062,7 |
.fail: |
DEBUGF 2,"Transmit failed\n" |
invoke NetFree, [bufferptr] |
invoke KernelFree, [bufferptr] |
popf |
or eax, -1 |
ret |
1153,19 → 1151,16 |
adc dword [ebx + device.bytes_rx + 4], 0 |
push ebx |
push .return ; return addr |
mov eax, [ebx + device.rxd + eax + 12] |
push eax ; packet ptr |
mov [eax + NET_BUFF.length], ecx |
mov [eax + NET_BUFF.device], ebx |
mov [eax + NET_BUFF.offset], NET_BUFF.data |
push .return |
push ecx ; packet size |
pushd [ebx + device.rxd + eax + 12] ; packet ptr |
DEBUGF 1, "Packet received OK\n" |
jmp [EthInput] |
jmp [Eth_input] |
.return: |
pop ebx |
; Reset status, allow ethernet card access to descriptor |
invoke NetAlloc, RX_BUFF_SZ + NET_BUFF.data |
invoke KernelAlloc, RX_BUFF_SZ |
test eax, eax |
jz .fail |
movzx ecx, [ebx + device.cur_rx] |
1173,7 → 1168,6 |
lea ecx, [ebx + device.rxd + ecx] |
mov dword [ecx + 12], eax |
invoke GetPhysAddr |
add eax, NET_BUFF.data |
mov dword [ecx + 8], eax |
mov dword [ecx + 4], RX_BUFF_SZ |
1210,7 → 1204,7 |
DEBUGF 1, "Freeing packet = %x\n", [ecx + 12]:8 |
push dword[ecx + 12] |
mov dword[ecx + 12], 0 |
invoke NetFree |
invoke KernelFree |
inc [ebx + device.last_tx] |
and [ebx + device.last_tx], NUM_TX_DESC-1 |
/drivers/imports.inc |
---|
104,8 → 104,7 |
NetUnRegDev,\ |
NetPtrToNum,\ |
NetLinkChanged,\ |
NetAlloc,\ |
NetFree,\ |
EthInput,\ |
Eth_input,\ |
IPv4_input,\ |
\ |
GetPCIList |
/drivers/netdrv.inc |
---|
122,19 → 122,6 |
ends |
struct NET_BUFF |
NextPtr dd ? ; pointer to next frame in list |
PrevPtr dd ? ; pointer to previous frame in list |
device dd ? ; ptr to NET_DEVICE structure |
type dd ? ; data type (e.g. Ethernet) |
length dd ? ; data length |
offset dd ? ; offset to actual data (24 bytes for default frame) |
data rb 0 |
ends |
struct ETH_DEVICE NET_DEVICE |
mac dp ? |
/drivers/peimport.inc |
---|
155,9 → 155,8 |
NetUnRegDev,\ |
NetPtrToNum,\ |
NetLinkChanged,\ |
EthInput,\ |
NetAlloc,\ |
NetFree,\ |
Eth_input,\ |
IPv4_input,\ |
\ |
GetPCIList |
end data |