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