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

📄 hwmtm.c

📁 linux-2.6.15.6
💻 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(struct s_smc *smc, SMbuf *mb);static void smt_to_llc(struct s_smc *smc, SMbuf *mb);static void init_txd_ring(struct s_smc *smc);static void init_rxd_ring(struct s_smc *smc);static void queue_txd_mb(struct s_smc *smc, SMbuf *mb);static u_long init_descr_ring(struct s_smc *smc, union s_fp_descr volatile *start,			      int count);static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue);static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue);static SMbuf* get_llc_rx(struct s_smc *smc);static SMbuf* get_txd_mb(struct s_smc *smc);static void mac_drv_clear_txd(struct s_smc *smc);/*	-------------------------------------------------------------	EXTERNAL FUNCTIONS:	-------------------------------------------------------------*//*	The external SMT functions are listed in cmtdef.h */extern void* mac_drv_get_space(struct s_smc *smc, unsigned int size);extern void* mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size);extern void init_board(struct s_smc *smc, u_char *mac_addr);extern void mac_drv_fill_rxd(struct s_smc *smc);extern void plc1_irq(struct s_smc *smc);extern void mac_drv_tx_complete(struct s_smc *smc,				volatile struct s_smt_fp_txd *txd);extern void plc2_irq(struct s_smc *smc);extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);extern void timer_irq(struct s_smc *smc);extern void mac_drv_rx_complete(struct s_smc *smc,				volatile struct s_smt_fp_rxd *rxd,				int frag_count, int len);extern void mac_drv_requeue_rxd(struct s_smc *smc, 				volatile struct s_smt_fp_rxd *rxd,				int frag_count);extern void init_plc(struct s_smc *smc);extern void mac_drv_clear_rxd(struct s_smc *smc,			      volatile struct s_smt_fp_rxd *rxd, int frag_count);#ifdef	USE_OS_CPYextern void hwm_cpy_rxd2mb(void);extern void hwm_cpy_txd2mb(void);#endif#ifdef	ALL_RX_COMPLETEextern void mac_drv_all_receives_complete(void);#endifextern u_long mac_drv_virt2phys(struct s_smc *smc, void *virt);extern u_long dma_master(struct s_smc *smc, void *virt, int len, int flag);#ifdef	NDIS_OS2extern void post_proc(void);#elseextern void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr,			 int flag);#endifextern int init_fplus(struct s_smc *smc);extern int mac_drv_rx_init(struct s_smc *smc, int len, int fc, char *look_ahead,			   int la_len);/*	-------------------------------------------------------------	PUBLIC FUNCTIONS:	-------------------------------------------------------------*/void process_receive(struct s_smc *smc);void fddi_isr(struct s_smc *smc);void smt_free_mbuf(struct s_smc *smc, SMbuf *mb);void init_driver_fplus(struct s_smc *smc);void mac_drv_rx_mode(struct s_smc *smc, int mode);void init_fddi_driver(struct s_smc *smc, u_char *mac_addr);void mac_drv_clear_tx_queue(struct s_smc *smc);void mac_drv_clear_rx_queue(struct s_smc *smc);void hwm_tx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,		 int frame_status);void hwm_rx_frag(struct s_smc *smc, char far *virt, u_long phys, int len,		 int frame_status);int mac_drv_init(struct s_smc *smc);int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len,		int frame_status);u_int mac_drv_check_space(void);SMbuf* smt_get_mbuf(struct s_smc *smc);#ifdef DEBUG	void mac_drv_debug_lev(void);#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(void){#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(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(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(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(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(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(struct s_smc *smc, u_char *mac_addr){	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(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(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)

⌨️ 快捷键说明

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