⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ir.asm

📁 dos下的网卡驱动程序。支持一般通用网卡
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;Licensed by Intel for distribution without complete source.
;History:1,1
;Tue Aug 21 12:54:06 2001 call setup_53040 on an 82555 as well.
;Wed Aug 01 22:00:25 2001 Add some calls to count_in_err
;Fri Aug 11 15:58:39 2000 Change the way the xmit routine works so we can implement IRQ chaining "right"

	include	options.inc
	include	chip.inc
	include	defs.asm

if	CHIP EQ INTEL_82596
	include	82596.inc
else
	include	82557.inc
endif

cgroup	group code, _text, init

code	segment para public 'code'
	assume	cs:cgroup, ds:cgroup
	
	include	timeout.asm

extrn ether_add_msg1 : word
extrn ether_add_msg2 : word
extrn their_timer : dword

	public mem_map_io
mem_map_io		dw	0,0		; Memory mapped I/O address from the command line

	public tx_buff_no, buff_ptrs
tx_buff_no		dw	?
old_buff_no		dw	?
buff_ptrs		dw	offset cgroup:cmd_buff1
				dw	offset cgroup:cmd_buff2

rbd_counter		db	0		; Used to guard against no EOF set

	align	4
	public cmd_buff1, cmd_buff2
cmd_buff1		db	GIANT + 10h dup (?)
	align	4
cmd_buff2		db	GIANT + 10h dup (?)

if	CHIP EQ INTEL_82557
timer_count	dw	0h			; Watchdog timer for the receiver lockup
endif

	public	base_addr, int_no
base_addr	dw 	0,0		; I/O address as located via the I/O scan
int_no		db	0,0,0,0		; must be four bytes long for get_number.

	public	driver_class, driver_type, driver_name
driver_class	db	BLUEBOOK,IEEE8023,0	;null terminated list of classes.
driver_type	db	255		;from the packet spec
driver_name	db	short_name, 0	;name of the driver.

	public	driver_function, parameter_list
driver_function	db	8 + 2	; Mix capability + packet status returned in DH

parameter_list	label	byte
	db	1	;major rev of packet driver
	db	9	;minor rev of packet driver
	db	14	;length of parameter list
	db	EADDR_LEN	;length of MAC-layer address
	dw	GIANT	;MTU, including MAC headers
	dw	MAX_MULTICAST * EADDR_LEN	;buffer size of multicast addrs
	dw	0	;(# of back-to-back MTU rcvs) - 1
	dw	0	;(# of successive xmits) - 1

	public	int_num
int_num	dw	0	;Interrupt # to hook for post-EOI
			;processing, 0 == none,

;-> current address
	extrn	my_address: byte

received_ours	db	0
	public	rcv_modes
			;number of receive modes in our table.
rcv_modes	dw (offset cgroup:end_rcv_modes - offset cgroup:mode_zero)/2
mode_zero	dw	0               ;There is no mode zero
			dw	0
			dw	rcv_mode_2	; Individual address only
			dw	rcv_mode_3	; Mode 2 + Broadcast address
			dw	rcv_mode_4	; Mode 3 + Limited Multi-Cast addresses
			dw	rcv_mode_5	; Mode 4 + all Multi_Cast addresses
			dw	rcv_mode_6	; All packets - promiscuous mode
end_rcv_modes:

curr_rcv_mode	db	MATCH_BRDCAST		; The current receive mode
save_err	db	0		; Errors in last frame received (promiscuous mode only)

	ALIGN	4
config_start:
if	CHIP EQ INTEL_82596
; This structure needs to be 14 bytes long but is rounded up to 16 bytes in
; order to make use of DWORD transfers
	db	CB_CFIG_PREFETCH_BIT + (offset cgroup:true_config_end - offset cgroup:config_start)
	db	CB_CFIG_NO_MONITOR_MODE + DEFAULT_FIFO
	db	40h
	db	CB_CFIG_PREAMBLE_LEN + CB_CFIG_NO_SRCADR + CB_CFIG_ADDRESS_LEN
	db	0h
	db	CB_CFIG_IFS
	db	CB_CFIG_SLOTTIME_LOW
	db	CB_CFIG_MAX_RETRIES + CB_CFIG_SLOTTIME_HIGH
	db	0h
	db	0h
	db	RUNT
	db	CB_CFIG_NO_MONITOR_MODE + CB_CFIG_MCAST_DISABLE + CB_CFIG_NO_CDT_SAC + CB_CFIG_AUTO_RETX + CB_CFIG_NO_CRC_IN_MEM + CB_CFIG_LENGTH_DISABLE + CB_CFIG_PRECRS_DISABLE
	db	0h
	db	NOT (CB_CFIG_BACKOFF_DISABLE + CB_CFIG_MULTIIA_ENABLE)
else
	public	config_mii_mode, config_cdt, config_duplex
; This structure needs to be 22 bytes long but is rounded up to 24 bytes in
; order to make use of DWORD transfers
	db	offset cgroup:true_config_end - offset cgroup:config_start
	db	TX_FIFO_LMT +  RX_FIFO_LMT
	db	ADPATIVE_IFS
	db	0h
	db	RX_DMA_MAX
	db	DMBC_EN + TX_DMA_MAX
	db	CI_INT + LATE_SCB + 32h
	db	UNDR_RTRY_1 + DISC_SHORT
config_mii_mode:
	db	0h				 	;	For MII interface - db	MII_MODE
	db	0h
	db	PREAMBLE_LEN_7 + NSAI + 6h
	db	NRML_LINR_PRTY
; debug
;	db	DEF_IFS_SPACING
	db	0f0h ;- works 0a0h too small
	db	0h
	db	0f2h
config_cdt:
	db	CRS_CDT + 48h		;	For MII interface - db 48h
	db	0h
	db	40h
	db	PADDING_ENBL + STRIPPING_ENBL + 0F0h
config_duplex:
	db	0h					;  For full duplex set to FDX_PIN_ENBL
	db	3fh
	db	05h
endif
true_config_end:
	db	0				; 2 extra bytes to make config data
	db	0				; size be a a multiple of DWORDS
config_end:

temp_ru_status	dw	?
	
curs			dw 0

if	CHIP EQ INTEL_82557
	public	multicast_fix
multicast_fix	dw	?	; All drivers currently need fix - so this is ignored
endif


;this macro writes the given character to the given row and column on a CGA.
to_scrn	macro	r, c, ch
	local	di_ok,black,done,one_more
  if 0
jumps
  .8086
	push	bx
	push	es
	push	di
	mov		di, cs:curs
	cmp		di, 3200
	jb		short di_ok
	mov		di, 0
di_ok:
	mov		bx,0b800h
	mov		es,bx
	mov		bx,es:[di+r*160+c*2]
	test	bh,1
	jne		short black
	mov		bh,07h
	jmp		short done
black:
	mov		bh,70h
done:
	mov		bl,ch
	mov		es:[di+r*160+c*2],bx
	add		di, 2
	mov		cs:curs, di
	pop		di
	pop		es
	pop		bx
	.386
  endif
	endm

	.386					; Must have >= 386 for these routines to be called
	public	bad_command_intercept
bad_command_intercept:
;called with ah=command, unknown to the skeleton.
;exit with nc if okay, cy, dh=error if not.
	cmp		ah, 26
	jne		short bad_command_intercept_1
if	CHIP EQ INTEL_82596
	jmp		do_tdr
else
;	no tdr capability for the 82557
endif
bad_command_intercept_1:
	mov		dh, BAD_COMMAND
	stc
	ret

get_buffer	PROC	NEAR
; Get the next buffer address from the buff_ptr array
	mov		ax, cs
	mov		es, ax
	mov		ax, cs:tx_buff_no		; Get next buffer # to use
	mov		di, ax					; Save into di
	mov		cs:old_buff_no, ax		; Save buffer #
	inc		ax						; Advance the buffer #
	cmp		ax, 2					; Advanced too far ?
	jl		short count_ok			; No - the next count is ok
	xor		ax, ax					; Next count will be zero
count_ok:
	mov		cs:tx_buff_no, ax		; Store the updated buffer #
	sal		di, 1					; Make bx a word count
	mov		di, cs:buff_ptrs[di]	; Get the buffer address

	mov		ax, 1
	call	set_timeout
wait_cmd_to_complete:
	test	word ptr cs:[di], C_DONE_BIT
	jnz		short buff_finished_with
	to_scrn	2,0,'W'
	call	do_timeout				; Any more time left ?
	jnz		short wait_cmd_to_complete
	mov		ax, cs:old_buff_no		; Recover the original buffer #
	mov		cs:tx_buff_no, ax		; Store for next time
	stc
	ret

buff_finished_with:
	clc
	ret
get_buffer	ENDP

	public	as_send_pkt
; The Asynchronous Transmit Packet routine.
; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
;   interrupts possibly enabled.
; Exit with nc if ok, or else cy if error, dh set to error number.
;   es:di and interrupt enable flag preserved on exit.
as_send_pkt:
	ret

	public	drop_pkt
; Drop a packet from the queue.
; Enter with es:di -> iocb.
drop_pkt:
	assume	ds:nothing
	ret

	public	xmit
; Process a transmit interrupt with the least possible latency to achieve
;   back-to-back packet transmissions.
; May only use ax and dx.
; Return cy if we should abort the interrupt reception.
xmit:
	assume	ds:nothing
 	WAIT_CMD_ACCEPTED
	LOAD_PORT	SCB_STATUS
	in		ax, dx
	and		ax, SCB_STATUS_MASK
	clc
	jnz		short xmit_1
	stc
xmit_1:
	ret

	public	wait_scb_non_active
wait_scb_non_active	PROC	NEAR
	call	set_timeout				; AX previously set with the timeout
check_scb_again:
if	CHIP EQ INTEL_82596
	mov		ax, cs:scb_buff.scb_status ; Get the status bits
else
	in		ax, dx					; Get the status bits
endif
	and		ax, CU_STATUS_BITS		; Mask all but the cu status
	cmp		ax, CU_ACTIVE			; Is the cu active
	clc								; Clear carry for exit
	jne		short exit_wait_scb_non_active	; Jump if so
	call	do_timeout				; No - any more time left ?
	jnz		check_scb_again			; Continue to wait if so
	stc								; Otherwise exit with carry set
exit_wait_scb_non_active:
	ret
wait_scb_non_active	ENDP
	
	
	public  issue_cmd
issue_cmd	PROC	NEAR
	; di holds the start of the buffer for the command
cmd_accept_wait:
	WAIT_CMD_ACCEPTED 				; Wait for acceptance of last command
									; Now wait for that command to be completed
	mov		ax, 40h					; Wait, if necessary, for about 1 s
if	CHIP EQ INTEL_82557
	add		dx,	SCB_STATUS - SCB_CMD	; Get to the status port
endif
	call	wait_scb_non_active		; Can't issue a command if chip is active
	jc		short exit_issue_cmd	; Exit if still active
	pushf							; Save interrupt status
	cli								; Prevent the receiver from interrupting
if	CHIP EQ INTEL_82596
	cmp		cs:scb_buff.scb_command, 0	; Did the receiver interrupt earlier
else
	add		dx,	SCB_CMD - SCB_STATUS	; Get to the command port
	in		al, dx
	cmp		al, 0					; Did the receiver interrupt earlier
endif
	jz		short cmd_accepted		; No - safe to issue command
	popf							; Recover flags
	jmp		short cmd_accept_wait	; Need to wait again

cmd_accepted:
if	CHIP EQ INTEL_82596
	mov		cs:scb_buff.scb_command, CU_START
	mov		cs:scb_buff.scb_cbl_add, di
	STALL
	C_ATTENTION
	STALL
else
	add		dx,	SCB_GEN_PTR - SCB_CMD	; Get to the general pointer port
	xor		eax, eax
	mov		ax, di
	out		dx, eax					; Issue the address - upper word is low
	add		dx, SCB_CMD - SCB_GEN_PTR	; Get back to cmd port
	mov		al, CU_START
	out		dx, al					; Issue the command
endif

	popf							; Restore interrupt status
exit_issue_cmd_ok:
	clc
exit_issue_cmd:
	ret
issue_cmd	ENDP

send_problem:
	to_scrn	2,0,'P'
	mov		dh, CANT_SEND		; Indicate an error.
	stc
	ret

send_pkt_toobig:
	mov	dh,NO_SPACE
	stc
	ret

	public	send_pkt
send_pkt:
;enter with es:di->upcall routine, (0:0) if no upcall is desired.
;  (only if the high-performance bit is set in driver_function)
;enter with ds:si -> packet, cx = packet length.
;if we're a high-performance driver, es:di -> upcall.
;exit with nc if ok, or else cy if error, dh set to error number.
	assume	ds:nothing
	cmp		cx,GIANT			; Is this packet too large?
	ja		send_pkt_toobig

	cmp		cx, RUNT			; Minimum length for Ether
	jae		short oklen
	mov		cx, RUNT			; Make sure size at least RUNT
oklen:
	to_scrn	2,0,'T'
	mov		ax, cs
	mov		es, ax

	call	get_buffer
	jc		send_problem
	mov		bx, di				; Save the start of the buffer
	mov		eax, (EL_BIT + S_BIT + TRANSMIT)*10000h
	stosd						; Store the action command word + status word
if	CHIP EQ INTEL_82596
	mov		ax, -1
	stosw						; Write the address of the next command
	stosw						; Store the TBD array null pointer
	mov		eax, TX_EOF_BIT
else
	mov		eax, -1				; Write the address of the next command
	stosd						; Store the link address - next command
	stosd						; Store the TBD array null pointer
	mov		eax, TX_THRESHOLD*10000h + TX_EOF_BIT
endif
	or		ax, cx				; Include the length of the packet
	stosd
								; Memory copy routine
	mov		ax, cx				; Save byte count
	sar		cx, 2				; Convert to a DWORD count
	rep		movsd				; Copy DWORDS
	mov		cx, ax				; Recover byte count
	and		cx, 0003h			; Obtain count mod 4
	jz		short no_more
	rep		movsb				; Copy remaining bytes

no_more:
	mov		di, bx				; Recover the start of the buffer
	call	issue_cmd
	jc		send_problem
	ret


	public	set_address
set_address:
;enter with ds:si -> Ethernet address, CX = length of address.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -