30f165e2d7
MFC after: 1 month Sponsored by: Mellanox Technologies
156 lines
5.0 KiB
ArmAsm
156 lines
5.0 KiB
ArmAsm
;
|
|
; This file requires NASM 0.97+ to assemble
|
|
;
|
|
; Currently used only for djgpp + DOS4GW targets
|
|
;
|
|
; these sizes MUST be equal to the sizes in PKTDRVR.H
|
|
;
|
|
%define ETH_MTU 1500 ; max data size on Ethernet
|
|
%define ETH_MIN 60 ; min/max total frame size
|
|
%define ETH_MAX (ETH_MTU+2*6+2) ; =1514
|
|
%define NUM_RX_BUF 32 ; # of RX element buffers
|
|
%define RX_SIZE (ETH_MAX+6) ; sizeof(RX_ELEMENT) = 1514+6
|
|
%idefine offset
|
|
|
|
struc RX_ELEMENT
|
|
.firstCount resw 1 ; # of bytes on 1st call
|
|
.secondCount resw 1 ; # of bytes on 2nd call
|
|
.handle resw 1 ; handle for upcall
|
|
; .timeStamp resw 4 ; 64-bit RDTSC value
|
|
.destinAdr resb 6 ; packet destination address
|
|
.sourceAdr resb 6 ; packet source address
|
|
.protocol resw 1 ; packet protocol number
|
|
.rxBuffer resb ETH_MTU ; RX buffer
|
|
endstruc
|
|
|
|
;-------------------------------------------
|
|
|
|
[org 0] ; assemble to .bin file
|
|
|
|
_rxOutOfs dw offset _pktRxBuf ; ring buffer offsets
|
|
_rxInOfs dw offset _pktRxBuf ; into _pktRxBuf
|
|
_pktDrop dw 0,0 ; packet drop counter
|
|
_pktTemp resb 20 ; temp work area
|
|
_pktTxBuf resb (ETH_MAX) ; TX buffer
|
|
_pktRxBuf resb (RX_SIZE*NUM_RX_BUF) ; RX structures
|
|
LAST_OFS equ $
|
|
|
|
screenSeg dw 0B800h
|
|
newInOffset dw 0
|
|
|
|
fanChars db '-\|/'
|
|
fanIndex dw 0
|
|
|
|
%macro SHOW_RX 0
|
|
push es
|
|
push bx
|
|
mov bx, [screenSeg]
|
|
mov es, bx ;; r-mode segment of colour screen
|
|
mov di, 158 ;; upper right corner - 1
|
|
mov bx, [fanIndex]
|
|
mov al, [fanChars+bx] ;; get write char
|
|
mov ah, 15 ;; and white colour
|
|
cld ;; Needed?
|
|
stosw ;; write to screen at ES:EDI
|
|
inc word [fanIndex] ;; update next index
|
|
and word [fanIndex], 3
|
|
pop bx
|
|
pop es
|
|
%endmacro
|
|
|
|
;PutTimeStamp
|
|
; rdtsc
|
|
; mov [si].timeStamp, eax
|
|
; mov [si+4].timeStamp, edx
|
|
; ret
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
;
|
|
; This routine gets called by the packet driver twice:
|
|
; 1st time (AX=0) it requests an address where to put the packet
|
|
;
|
|
; 2nd time (AX=1) the packet has been copied to this location (DS:SI)
|
|
; BX has client handle (stored in RX_ELEMENT.handle).
|
|
; CX has # of bytes in packet on both call. They should be equal.
|
|
; A test for equality is done by putting CX in _pktRxBuf [n].firstCount
|
|
; and _pktRxBuf[n].secondCount, and CL on first call in
|
|
; _pktRxBuf[n].rxBuffer[CX]. These values are checked in "PktReceive"
|
|
; (PKTDRVR.C)
|
|
;
|
|
;---------------------------------------------------------------------
|
|
|
|
_PktReceiver:
|
|
pushf
|
|
cli ; no distraction wanted !
|
|
push ds
|
|
push bx
|
|
mov bx, cs
|
|
mov ds, bx
|
|
mov es, bx ; ES = DS = CS or seg _DATA
|
|
pop bx ; restore handle
|
|
|
|
cmp ax, 0 ; first call? (AX=0)
|
|
jne @post ; AX=1: second call, do post process
|
|
|
|
%ifdef DEBUG
|
|
SHOW_RX ; show that a packet is received
|
|
%endif
|
|
|
|
cmp cx, ETH_MAX ; size OK ?
|
|
ja @skip ; no, too big
|
|
|
|
mov ax, [_rxInOfs]
|
|
add ax, RX_SIZE
|
|
cmp ax, LAST_OFS
|
|
jb @noWrap
|
|
mov ax, offset _pktRxBuf
|
|
@noWrap:
|
|
cmp ax, [_rxOutOfs]
|
|
je @dump
|
|
mov di, [_rxInOfs] ; ES:DI -> _pktRxBuf[n]
|
|
mov [newInOffset], ax
|
|
|
|
mov [di], cx ; remember firstCount.
|
|
mov [di+4], bx ; remember handle.
|
|
add di, 6 ; ES:DI -> _pktRxBuf[n].destinAdr
|
|
pop ds
|
|
popf
|
|
retf ; far return to driver with ES:DI
|
|
|
|
@dump: add word [_pktDrop+0], 1 ; discard the packet on 1st call
|
|
adc word [_pktDrop+2], 0 ; increment packets lost
|
|
|
|
@skip: xor di, di ; return ES:DI = NIL pointer
|
|
xor ax, ax
|
|
mov es, ax
|
|
pop ds
|
|
popf
|
|
retf
|
|
|
|
@post: or si, si ; DS:SI->_pktRxBuf[n][n].destinAdr
|
|
jz @discard ; make sure we don't use NULL-pointer
|
|
|
|
;
|
|
; push si
|
|
; call bpf_filter_match ; run the filter here some day
|
|
; pop si
|
|
; cmp ax, 0
|
|
; je @discard
|
|
|
|
mov [si-6+2], cx ; store _pktRxBuf[n].secondCount
|
|
mov ax, [newInOffset]
|
|
mov [_rxInOfs], ax ; update _pktRxBuf input offset
|
|
|
|
; call PutTimeStamp
|
|
|
|
@discard:
|
|
pop ds
|
|
popf
|
|
retf
|
|
|
|
_pktRxEnd db 0 ; marker for end of r-mode code/data
|
|
|
|
END
|
|
|