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