15,8 → 15,6 |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
; TODO: test for RX-overrun |
|
format PE DLL native |
entry START |
|
24,8 → 22,6 |
COMPATIBLE_API = 0x0100 |
API_VERSION = (COMPATIBLE_API shl 16) + CURRENT_API |
|
; configureable area |
|
MAX_DEVICES = 16 |
|
RBLEN = 3 ; Receive buffer size: 0==8K 1==16k 2==32k 3==64k |
39,8 → 35,6 |
__DEBUG__ = 1 |
__DEBUG_LEVEL__ = 2 ; 1 = verbose, 2 = errors only |
|
; end configureable area |
|
section '.flat' readable writable executable |
|
include '../proc32.inc' |
645,13 → 639,13 |
;; Transmit ;; |
;; ;; |
;; In: pointer to device structure in ebx ;; |
;; Out: eax = 0 on success ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
align 16 |
|
proc transmit stdcall bufferptr |
|
spin_lock_irqsave |
pushf |
cli |
|
mov esi, [bufferptr] |
DEBUGF 1,"Transmitting packet, buffer:%x, size:%u\n", [bufferptr], [esi + NET_BUFF.length] |
662,9 → 656,9 |
[eax+13]:2,[eax+12]:2 |
|
cmp [esi + NET_BUFF.length], 1514 |
ja .error |
ja .fail |
cmp [esi + NET_BUFF.length], 60 |
jb .error |
jb .fail |
|
; check if we own the current discriptor |
set_io [ebx + device.io_addr], 0 |
674,8 → 668,9 |
add edx, ecx |
in eax, dx |
test eax, (1 shl BIT_OWN) |
jz .overrun |
jz .wait_to_send |
|
.send_packet: |
; Set the buffer address |
set_io [ebx + device.io_addr], REG_TSAD0 |
mov [ebx + device.TX_DESC+ecx], esi |
696,29 → 691,37 |
|
; Update stats |
inc [ebx + device.packets_tx] |
mov eax, [esi + NET_BUFF.length] |
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 |
|
spin_unlock_irqrestore |
DEBUGF 1, "Packet Sent!\n" |
popf |
xor eax, eax |
ret |
|
.error: |
DEBUGF 2, "TX packet error\n" |
inc [ebx + device.packets_tx_err] |
invoke NetFree, [bufferptr] |
.wait_to_send: |
DEBUGF 1, "Waiting for timeout\n" |
|
spin_unlock_irqrestore |
or eax, -1 |
ret |
push edx |
mov esi, 30 |
invoke Sleep |
pop edx |
|
.overrun: |
DEBUGF 2, "TX overrun\n" |
inc [ebx + device.packets_tx_ovr] |
in ax, dx |
test ax, (1 shl BIT_OWN) |
jnz .send_packet |
|
pusha |
call reset ; if chip hung, reset it |
popa |
|
jmp .send_packet |
|
.fail: |
DEBUGF 2, "transmit failed!\n" |
invoke NetFree, [bufferptr] |
|
spin_unlock_irqrestore |
popf |
or eax, -1 |
ret |
|
733,25 → 736,42 |
;; Interrupt handler ;; |
;; ;; |
;;;;;;;;;;;;;;;;;;;;;;; |
align 16 |
|
align 4 |
int_handler: |
|
push ebx esi edi |
|
mov ebx, [esp+4*4] |
DEBUGF 1,"INT for 0x%x\n", ebx |
DEBUGF 1, "INT\n" |
|
; TODO? if we are paranoid, we can check that the value from ebx is present in the current device_list |
; find pointer of device wich made IRQ occur |
mov ecx, [devices] |
test ecx, ecx |
jz .nothing |
mov esi, device_list |
.nextdevice: |
mov ebx, [esi] |
|
set_io [ebx + device.io_addr], 0 |
set_io [ebx + device.io_addr], REG_ISR |
in ax, dx ; Get interrupt status |
out dx, ax ; send it back to ACK |
test ax, ax |
jz .nothing |
jnz .got_it |
.continue: |
add esi, 4 |
dec ecx |
jnz .nextdevice |
.nothing: |
pop edi esi ebx |
xor eax, eax |
|
out dx, ax ; ACK interrupt |
DEBUGF 1, "Status: %x\n", ax |
ret ; If no device was found, abort (The irq was probably for a device, not registered to this driver) |
|
.got_it: |
|
DEBUGF 1, "Device: %x Status: %x\n", ebx, ax |
|
;---------------------------------------------------- |
; Received packet ok? |
|
864,10 → 884,10 |
|
.finish: |
pop ax |
@@: |
|
;---------------------------------------------------- |
; Transmit ok / Transmit error |
@@: |
test ax, ISR_TOK + ISR_TER |
jz @f |
|
924,10 → 944,10 |
sub ecx, 4 |
jae .txdescloop |
pop ax |
@@: |
|
;---------------------------------------------------- |
; Rx buffer overflow ? |
@@: |
test ax, ISR_RXOVW |
jz @f |
|
939,10 → 959,10 |
mov ax, ISR_FIFOOVW or ISR_RXOVW or ISR_ROK |
out dx, ax |
pop ax |
@@: |
|
;---------------------------------------------------- |
; Packet underrun? |
@@: |
test ax, ISR_PUN |
jz @f |
|
949,10 → 969,10 |
DEBUGF 1, "Packet underrun or link changed!\n" |
|
call link |
@@: |
|
;---------------------------------------------------- |
; Receive FIFO overflow ? |
@@: |
test ax, ISR_FIFOOVW |
jz @f |
|
964,18 → 984,18 |
mov ax, ISR_FIFOOVW or ISR_RXOVW or ISR_ROK |
out dx, ax |
pop ax |
@@: |
|
;---------------------------------------------------- |
; cable length changed ? |
@@: |
test ax, ISR_LENCHG |
jz @f |
jz .fail |
|
DEBUGF 2, "Cable length changed!\n" |
|
call link |
@@: |
|
.fail: |
pop edi esi ebx |
xor eax, eax |
inc eax |
982,14 → 1002,9 |
|
ret |
|
.nothing: |
pop edi esi ebx |
xor eax, eax |
|
ret |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;; |
;; ;; |
;; Check link status ;; |