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

📄 hwmtm.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * *	(C)Copyright 1998,1999 SysKonnect, *	a business unit of Schneider & Koch & Co. Datensysteme GmbH. * *	See the file "skfddi.c" for further information. * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2 of the License, or *	(at your option) any later version. * *	The information in this file is provided "AS IS" without warranty. * ******************************************************************************/#ifndef	lintstatic char const ID_sccs[] = "@(#)hwmtm.c	1.40 99/05/31 (C) SK" ;#endif#define	HWMTM#ifndef FDDI#define	FDDI#endif#include "h/types.h"#include "h/fddi.h"#include "h/smc.h"#include "h/supern_2.h"#include "h/skfbiinc.h"/*	-------------------------------------------------------------	DOCUMENTATION	-------------------------------------------------------------	BEGIN_MANUAL_ENTRY(DOCUMENTATION)			T B D	END_MANUAL_ENTRY*//*	-------------------------------------------------------------	LOCAL VARIABLES:	-------------------------------------------------------------*/#ifdef COMMON_MB_POOLstatic	SMbuf *mb_start = 0 ;static	SMbuf *mb_free = 0 ;static	int mb_init = FALSE ;static	int call_count = 0 ;#endif/*	-------------------------------------------------------------	EXTERNE VARIABLES:	-------------------------------------------------------------*/#ifdef	DEBUG#ifndef	DEBUG_BRDextern	struct smt_debug	debug ;#endif#endif#ifdef	NDIS_OS2extern	u_char	offDepth ;extern	u_char	force_irq_pending ;#endif/*	-------------------------------------------------------------	LOCAL FUNCTIONS:	-------------------------------------------------------------*/static	void	queue_llc_rx(),		smt_to_llc(),		init_txd_ring(),	init_rxd_ring(),		queue_txd_mb() ;static	u_long	init_descr_ring(),	repair_txd_ring(),		repair_rxd_ring() ;static	SMbuf	*get_llc_rx(),		*get_txd_mb() ;/*	-------------------------------------------------------------	EXTERNAL FUNCTIONS:	-------------------------------------------------------------*//*	The external SMT functions are listed in cmtdef.h */extern	void	*mac_drv_get_space(),	*mac_drv_get_desc_mem(),		init_board(),		mac_drv_fill_rxd(),		plc1_irq(),		mac_drv_tx_complete(),		plc2_irq(),		mac1_irq(),		mac2_irq(),		mac3_irq(),		timer_irq(),		mac_drv_rx_complete(),		mac_drv_requeue_rxd(),	init_plc(),		mac_drv_clear_rxd(),	llc_restart_tx(),		ev_dispatcher(),	smt_force_irq() ;#ifdef	USE_OS_CPYextern	void	hwm_cpy_rxd2mb(),	hwm_cpy_txd2mb() ;#endif#ifdef	ALL_RX_COMPLETEextern	void	mac_drv_all_receives_complete() ;#endifextern	u_long	mac_drv_virt2phys(),	dma_master() ;#ifdef	NDIS_OS2extern	void	post_proc() ;#elseextern	void	dma_complete() ;#endifextern	int	init_fplus(),		mac_drv_rx_init() ;/*	-------------------------------------------------------------	PUBLIC FUNCTIONS:	-------------------------------------------------------------*/	void	process_receive(),	smt_send_mbuf(),		fddi_isr(),		mac_drv_clear_txd(),		smt_free_mbuf(),	init_driver_fplus(),		mac_drv_rx_mode(),	init_fddi_driver(),		mac_drv_clear_tx_queue(),		mac_drv_clear_rx_queue(),		hwm_tx_frag(),		hwm_rx_frag() ;	int	mac_drv_rx_frag(),	mac_drv_init(),		hwm_tx_init() ;	u_int	mac_drv_check_space() ;	SMbuf 	*smt_get_mbuf() ;#ifdef DEBUG	void	mac_drv_debug_lev() ;#endif/*	-------------------------------------------------------------	MACROS:	-------------------------------------------------------------*/#ifndef	UNUSED#ifdef	lint#define UNUSED(x)	(x) = (x)#else#define UNUSED(x)#endif#endif#ifdef	USE_CAN_ADDR#define MA		smc->hw.fddi_canon_addr.a#define	GROUP_ADDR_BIT	0x01#else#define	MA		smc->hw.fddi_home_addr.a#define	GROUP_ADDR_BIT	0x80#endif#define RXD_TXD_COUNT	(HWM_ASYNC_TXD_COUNT+HWM_SYNC_TXD_COUNT+\			SMT_R1_RXD_COUNT+SMT_R2_RXD_COUNT)#ifdef	MB_OUTSIDE_SMC#define	EXT_VIRT_MEM	((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd) +\			MAX_MBUF*sizeof(SMbuf))#define	EXT_VIRT_MEM_2	((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))#else#define	EXT_VIRT_MEM	((RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd))#endif	/*	 * define critical read for 16 Bit drivers	 */#if	defined(NDIS_OS2) || defined(ODI2)#define CR_READ(var)	((var) & 0xffff0000 | ((var) & 0xffff))#else#define CR_READ(var)	(u_long)(var)#endif#define IMASK_SLOW	(IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TOKEN | \			 IS_MINTR1 | IS_MINTR2 | IS_MINTR3 | IS_R1_P | \			 IS_R1_C | IS_XA_C | IS_XS_C)/*	-------------------------------------------------------------	INIT- AND SMT FUNCTIONS:	-------------------------------------------------------------*//* *	BEGIN_MANUAL_ENTRY(mac_drv_check_space) *	u_int mac_drv_check_space() * *	function	DOWNCALL	(drvsr.c) *			This function calculates the needed non virtual *			memory for MBufs, RxD and TxD descriptors etc. *			needed by the driver. * *	return		u_int	memory in bytes * *	END_MANUAL_ENTRY */u_int mac_drv_check_space(){#ifdef	MB_OUTSIDE_SMC#ifdef	COMMON_MB_POOL	call_count++ ;	if (call_count == 1) {		return(EXT_VIRT_MEM) ;	}	else {		return(EXT_VIRT_MEM_2) ;	}#else	return (EXT_VIRT_MEM) ;#endif#else	return (0) ;#endif}/* *	BEGIN_MANUAL_ENTRY(mac_drv_init) *	void mac_drv_init(smc) * *	function	DOWNCALL	(drvsr.c) *			In this function the hardware module allocates it's *			memory. *			The operating system dependent module should call *			mac_drv_init once, after the adatper is detected. *	END_MANUAL_ENTRY */int mac_drv_init(smc)struct s_smc *smc ;{	if (sizeof(struct s_smt_fp_rxd) % 16) {		SMT_PANIC(smc,HWM_E0001,HWM_E0001_MSG) ;	}	if (sizeof(struct s_smt_fp_txd) % 16) {		SMT_PANIC(smc,HWM_E0002,HWM_E0002_MSG) ;	}	/*	 * get the required memory for the RxDs and TxDs	 */	if (!(smc->os.hwm.descr_p = (union s_fp_descr volatile *)		mac_drv_get_desc_mem(smc,(u_int)		(RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd)))) {		return(1) ;	/* no space the hwm modul can't work */	}	/*	 * get the memory for the SMT MBufs	 */#ifndef	MB_OUTSIDE_SMC	smc->os.hwm.mbuf_pool.mb_start=(SMbuf *)(&smc->os.hwm.mbuf_pool.mb[0]) ;#else#ifndef	COMMON_MB_POOL	if (!(smc->os.hwm.mbuf_pool.mb_start = (SMbuf *) mac_drv_get_space(smc,		MAX_MBUF*sizeof(SMbuf)))) {		return(1) ;	/* no space the hwm modul can't work */	}#else	if (!mb_start) {		if (!(mb_start = (SMbuf *) mac_drv_get_space(smc,			MAX_MBUF*sizeof(SMbuf)))) {			return(1) ;	/* no space the hwm modul can't work */		}	}#endif#endif	return (0) ;}/* *	BEGIN_MANUAL_ENTRY(init_driver_fplus) *	init_driver_fplus(smc) * * Sets hardware modul specific values for the mode register 2 * (e.g. the byte alignment for the received frames, the position of the *	 least significant byte etc.) *	END_MANUAL_ENTRY */void init_driver_fplus(smc)struct s_smc *smc ;{	smc->hw.fp.mdr2init = FM_LSB | FM_BMMODE | FM_ENNPRQ | FM_ENHSRQ | 3 ;#ifdef	PCI	smc->hw.fp.mdr2init |= FM_CHKPAR | FM_PARITY ;#endif	smc->hw.fp.mdr3init = FM_MENRQAUNLCK | FM_MENRS ;#ifdef	USE_CAN_ADDR	/* enable address bit swapping */	smc->hw.fp.frselreg_init = FM_ENXMTADSWAP | FM_ENRCVADSWAP ;#endif}static u_long init_descr_ring(smc,start,count)struct s_smc *smc ;union s_fp_descr volatile *start;int count ;{	int i ;	union s_fp_descr volatile *d1 ;	union s_fp_descr volatile *d2 ;	u_long	phys ;	DB_GEN("descr ring starts at = %x ",(void *)start,0,3) ;	for (i=count-1, d1=start; i ; i--) {		d2 = d1 ;		d1++ ;		/* descr is owned by the host */		d2->r.rxd_rbctrl = AIX_REVERSE(BMU_CHECK) ;		d2->r.rxd_next = &d1->r ;		phys = mac_drv_virt2phys(smc,(void *)d1) ;		d2->r.rxd_nrdadr = AIX_REVERSE(phys) ;	}	DB_GEN("descr ring ends at = %x ",(void *)d1,0,3) ;	d1->r.rxd_rbctrl = AIX_REVERSE(BMU_CHECK) ;	d1->r.rxd_next = &start->r ;	phys = mac_drv_virt2phys(smc,(void *)start) ;	d1->r.rxd_nrdadr = AIX_REVERSE(phys) ;	for (i=count, d1=start; i ; i--) {		DRV_BUF_FLUSH(&d1->r,DDI_DMA_SYNC_FORDEV) ;		d1++;	}	return(phys) ;}static void init_txd_ring(smc)struct s_smc *smc ;{	struct s_smt_fp_txd volatile *ds ;	struct s_smt_tx_queue *queue ;	u_long	phys ;	/*	 * initialize the transmit descriptors	 */	ds = (struct s_smt_fp_txd volatile *) ((char *)smc->os.hwm.descr_p +		SMT_R1_RXD_COUNT*sizeof(struct s_smt_fp_rxd)) ;	queue = smc->hw.fp.tx[QUEUE_A0] ;	DB_GEN("Init async TxD ring, %d TxDs ",HWM_ASYNC_TXD_COUNT,0,3) ;	(void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,		HWM_ASYNC_TXD_COUNT) ;	phys = AIX_REVERSE(ds->txd_ntdadr) ;	ds++ ;	queue->tx_curr_put = queue->tx_curr_get = ds ;	ds-- ;	queue->tx_free = HWM_ASYNC_TXD_COUNT ;	queue->tx_used = 0 ;	outpd(ADDR(B5_XA_DA),phys) ;	ds = (struct s_smt_fp_txd volatile *) ((char *)ds +		HWM_ASYNC_TXD_COUNT*sizeof(struct s_smt_fp_txd)) ;	queue = smc->hw.fp.tx[QUEUE_S] ;	DB_GEN("Init sync TxD ring, %d TxDs ",HWM_SYNC_TXD_COUNT,0,3) ;	(void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,		HWM_SYNC_TXD_COUNT) ;	phys = AIX_REVERSE(ds->txd_ntdadr) ;	ds++ ;	queue->tx_curr_put = queue->tx_curr_get = ds ;	queue->tx_free = HWM_SYNC_TXD_COUNT ;	queue->tx_used = 0 ;	outpd(ADDR(B5_XS_DA),phys) ;}static void init_rxd_ring(smc)struct s_smc *smc ;{	struct s_smt_fp_rxd volatile *ds ;	struct s_smt_rx_queue *queue ;	u_long	phys ;	/*	 * initialize the receive descriptors	 */	ds = (struct s_smt_fp_rxd volatile *) smc->os.hwm.descr_p ;	queue = smc->hw.fp.rx[QUEUE_R1] ;	DB_GEN("Init RxD ring, %d RxDs ",SMT_R1_RXD_COUNT,0,3) ;	(void)init_descr_ring(smc,(union s_fp_descr volatile *)ds,		SMT_R1_RXD_COUNT) ;	phys = AIX_REVERSE(ds->rxd_nrdadr) ;	ds++ ;	queue->rx_curr_put = queue->rx_curr_get = ds ;	queue->rx_free = SMT_R1_RXD_COUNT ;	queue->rx_used = 0 ;	outpd(ADDR(B4_R1_DA),phys) ;}/* *	BEGIN_MANUAL_ENTRY(init_fddi_driver) *	void init_fddi_driver(smc,mac_addr) * * initializes the driver and it's variables * *	END_MANUAL_ENTRY */void init_fddi_driver(smc,mac_addr)struct	s_smc	*smc ;u_char		*mac_addr ;	/* canonical address */{	SMbuf	*mb ;	int	i ;	init_board(smc,mac_addr) ;	(void)init_fplus(smc) ;	/*	 * initialize the SMbufs for the SMT	 */#ifndef	COMMON_MB_POOL	mb = smc->os.hwm.mbuf_pool.mb_start ;	smc->os.hwm.mbuf_pool.mb_free = (SMbuf *)NULL ;	for (i = 0; i < MAX_MBUF; i++) {		mb->sm_use_count = 1 ;		smt_free_mbuf(smc,mb)	;		mb++ ;	}#else	mb = mb_start ;	if (!mb_init) {		mb_free = 0 ;		for (i = 0; i < MAX_MBUF; i++) {			mb->sm_use_count = 1 ;			smt_free_mbuf(smc,mb)	;			mb++ ;		}		mb_init = TRUE ;	}#endif	/*	 * initialize the other variables	 */	smc->os.hwm.llc_rx_pipe = smc->os.hwm.llc_rx_tail = (SMbuf *)NULL ;	smc->os.hwm.txd_tx_pipe = smc->os.hwm.txd_tx_tail = NULL ;	smc->os.hwm.pass_SMT = smc->os.hwm.pass_NSA = smc->os.hwm.pass_DB = 0 ;	smc->os.hwm.pass_llc_promisc = TRUE ;	smc->os.hwm.queued_rx_frames = smc->os.hwm.queued_txd_mb = 0 ;	smc->os.hwm.detec_count = 0 ;	smc->os.hwm.rx_break = 0 ;	smc->os.hwm.rx_len_error = 0 ;	smc->os.hwm.isr_flag = FALSE ;	/*	 * make sure that the start pointer is 16 byte aligned	 */	i = 16 - ((long)smc->os.hwm.descr_p & 0xf) ;	if (i != 16) {		DB_GEN("i = %d",i,0,3) ;		smc->os.hwm.descr_p = (union s_fp_descr volatile *)			((char *)smc->os.hwm.descr_p+i) ;	}	DB_GEN("pt to descr area = %x",(void *)smc->os.hwm.descr_p,0,3) ;	init_txd_ring(smc) ;	init_rxd_ring(smc) ;	mac_drv_fill_rxd(smc) ;	init_plc(smc) ;}SMbuf *smt_get_mbuf(smc)struct s_smc *smc ;{	register SMbuf	*mb ;#ifndef	COMMON_MB_POOL	mb = smc->os.hwm.mbuf_pool.mb_free ;#else	mb = mb_free ;#endif	if (mb) {#ifndef	COMMON_MB_POOL		smc->os.hwm.mbuf_pool.mb_free = mb->sm_next ;#else		mb_free = mb->sm_next ;#endif		mb->sm_off = 8 ;		mb->sm_use_count = 1 ;	}	DB_GEN("get SMbuf: mb = %x",(void *)mb,0,3) ;	return (mb) ;	/* May be NULL */}void smt_free_mbuf(smc, mb)struct s_smc	*smc ;SMbuf		*mb;{	if (mb) {		mb->sm_use_count-- ;		DB_GEN("free_mbuf: sm_use_count = %d",mb->sm_use_count,0,3) ;		/*		 * If the use_count is != zero the MBuf is queued		 * more than once and must not queued into the		 * free MBuf queue		 */		if (!mb->sm_use_count) {			DB_GEN("free SMbuf: mb = %x",(void *)mb,0,3) ;#ifndef	COMMON_MB_POOL			mb->sm_next = smc->os.hwm.mbuf_pool.mb_free ;			smc->os.hwm.mbuf_pool.mb_free = mb ;#else			mb->sm_next = mb_free ;			mb_free = mb ;#endif		}	}	else		SMT_PANIC(smc,HWM_E0003,HWM_E0003_MSG) ;}/* *	BEGIN_MANUAL_ENTRY(mac_drv_repair_descr) *	void mac_drv_repair_descr(smc) * * function	called from SMT	(HWM / hwmtm.c) *		The BMU is idle when this function is called. *		Mac_drv_repair_descr sets up the physical address *		for all receive and transmit queues where the BMU *		should continue. *		It may be that the BMU was reseted during a fragmented *		transfer. In this case there are some fragments which will *		never completed by the BMU. The OWN bit of this fragments *		must be switched to be owned by the host. * *		Give a start command to the receive BMU. *		Start the transmit BMUs if transmit frames pending. * *	END_MANUAL_ENTRY */void mac_drv_repair_descr(smc)struct s_smc *smc ;{	u_long	phys ;	if (smc->hw.hw_state != STOPPED) {		SK_BREAK() ;		SMT_PANIC(smc,HWM_E0013,HWM_E0013_MSG) ;		return ;	}	/*	 * repair tx queues: don't start	 */	phys = repair_txd_ring(smc,smc->hw.fp.tx[QUEUE_A0]) ;	outpd(ADDR(B5_XA_DA),phys) ;

⌨️ 快捷键说明

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