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

📄 fplustm.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
	set_int((char *) mac->mac_info+4,0) ;	set_int((char *) mac->mac_info+8,0) ;	copy_tx_mac(smc,td,(struct fddi_mac *)mac,		smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF,len) ;	/* end of claim/beacon queue */	outpw(FM_A(FM_EACB),smc->hw.fp.fifo.rx1_fifo_start-1) ;	outpw(FM_A(FM_WPXSF),0) ;	outpw(FM_A(FM_RPXSF),0) ;}static void formac_rcv_restart(struct s_smc *smc){	/* enable receive function */	SETMASK(FM_A(FM_MDREG1),smc->hw.fp.rx_mode,FM_ADDRX) ;	outpw(FM_A(FM_CMDREG1),FM_ICLLR) ;	/* clear receive lock */}void formac_tx_restart(struct s_smc *smc){	outpw(FM_A(FM_CMDREG1),FM_ICLLS) ;	/* clear s-frame lock */	outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ;	/* clear a-frame lock */}static void enable_formac(struct s_smc *smc){	/* set formac IMSK : 0 enables irq */	outpw(FM_A(FM_IMSK1U),~mac_imsk1u) ;	outpw(FM_A(FM_IMSK1L),~mac_imsk1l) ;	outpw(FM_A(FM_IMSK2U),~mac_imsk2u) ;	outpw(FM_A(FM_IMSK2L),~mac_imsk2l) ;	outpw(FM_A(FM_IMSK3U),~mac_imsk3u) ;	outpw(FM_A(FM_IMSK3L),~mac_imsk3l) ;}#if 0	/* Removed because the driver should use the ASICs TX complete IRQ. */	/* The FORMACs tx complete IRQ should be used any longer *//*	BEGIN_MANUAL_ENTRY(if,func;others;4)	void enable_tx_irq(smc, queue)	struct s_smc *smc ;	u_short	queue ;Function	DOWNCALL	(SMT, fplustm.c)		enable_tx_irq() enables the FORMACs transmit complete		interrupt of the queue.Para	queue	= QUEUE_S:	synchronous queue		= QUEUE_A0:	asynchronous queueNote	After any ring operational change the transmit complete	interrupts are disabled.	The operating system dependent module must enable	the transmit complete interrupt of a queue,		- when it queues the first frame,		  because of no transmit resources are beeing		  available and		- when it escapes from the function llc_restart_tx		  while some frames are still queued.	END_MANUAL_ENTRY */void enable_tx_irq(struct s_smc *smc, u_short queue)/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */{	u_short	imask ;	imask = ~(inpw(FM_A(FM_IMSK1U))) ;	if (queue == 0) {		outpw(FM_A(FM_IMSK1U),~(imask|FM_STEFRMS)) ;	}	if (queue == 1) {		outpw(FM_A(FM_IMSK1U),~(imask|FM_STEFRMA0)) ;	}}/*	BEGIN_MANUAL_ENTRY(if,func;others;4)	void disable_tx_irq(smc, queue)	struct s_smc *smc ;	u_short	queue ;Function	DOWNCALL	(SMT, fplustm.c)		disable_tx_irq disables the FORMACs transmit complete		interrupt of the queuePara	queue	= QUEUE_S:	synchronous queue		= QUEUE_A0:	asynchronous queueNote	The operating system dependent module should disable	the transmit complete interrupts if it escapes from the	function llc_restart_tx and no frames are queued.	END_MANUAL_ENTRY */void disable_tx_irq(struct s_smc *smc, u_short queue)/* u_short queue; 0 = synchronous queue, 1 = asynchronous queue 0 */{	u_short	imask ;	imask = ~(inpw(FM_A(FM_IMSK1U))) ;	if (queue == 0) {		outpw(FM_A(FM_IMSK1U),~(imask&~FM_STEFRMS)) ;	}	if (queue == 1) {		outpw(FM_A(FM_IMSK1U),~(imask&~FM_STEFRMA0)) ;	}}#endifstatic void disable_formac(struct s_smc *smc){	/* clear formac IMSK : 1 disables irq */	outpw(FM_A(FM_IMSK1U),MW) ;	outpw(FM_A(FM_IMSK1L),MW) ;	outpw(FM_A(FM_IMSK2U),MW) ;	outpw(FM_A(FM_IMSK2L),MW) ;	outpw(FM_A(FM_IMSK3U),MW) ;	outpw(FM_A(FM_IMSK3L),MW) ;}static void mac_ring_up(struct s_smc *smc, int up){	if (up) {		formac_rcv_restart(smc) ;	/* enable receive function */		smc->hw.mac_ring_is_up = TRUE ;		llc_restart_tx(smc) ;		/* TX queue */	}	else {		/* disable receive function */		SETMASK(FM_A(FM_MDREG1),FM_MDISRCV,FM_ADDET) ;		/* abort current transmit activity */		outpw(FM_A(FM_CMDREG2),FM_IACTR) ;		smc->hw.mac_ring_is_up = FALSE ;	}}/*--------------------------- ISR handling ----------------------------------*//* * mac1_irq is in drvfbi.c *//* * mac2_irq:	status bits for the receive queue 1, and ring status * 		ring status indication bits */void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l){	u_short	change_s2l ;	u_short	change_s2u ;	/* (jd) 22-Feb-1999	 * Restart 2_DMax Timer after end of claiming or beaconing	 */	if (code_s2u & (FM_SCLM|FM_SHICLM|FM_SBEC|FM_SOTRBEC)) {		queue_event(smc,EVENT_RMT,RM_TX_STATE_CHANGE) ;	}	else if (code_s2l & (FM_STKISS)) {		queue_event(smc,EVENT_RMT,RM_TX_STATE_CHANGE) ;	}	/*	 * XOR current st bits with the last to avoid useless RMT event queuing	 */	change_s2l = smc->hw.fp.s2l ^ code_s2l ;	change_s2u = smc->hw.fp.s2u ^ code_s2u ;	if ((change_s2l & FM_SRNGOP) ||		(!smc->hw.mac_ring_is_up && ((code_s2l & FM_SRNGOP)))) {		if (code_s2l & FM_SRNGOP) {			mac_ring_up(smc,1) ;			queue_event(smc,EVENT_RMT,RM_RING_OP) ;			smc->mib.m[MAC0].fddiMACRingOp_Ct++ ;		}		else {			mac_ring_up(smc,0) ;			queue_event(smc,EVENT_RMT,RM_RING_NON_OP) ;		}		goto mac2_end ;	}	if (code_s2l & FM_SMISFRM) {	/* missed frame */		smc->mib.m[MAC0].fddiMACNotCopied_Ct++ ;	}	if (code_s2u & (FM_SRCVOVR |	/* recv. FIFO overflow */			FM_SRBFL)) {	/* recv. buffer full */		smc->hw.mac_ct.mac_r_restart_counter++ ;/*		formac_rcv_restart(smc) ;	*/		smt_stat_counter(smc,1) ;/*		goto mac2_end ;			*/	}	if (code_s2u & FM_SOTRBEC)		queue_event(smc,EVENT_RMT,RM_OTHER_BEACON) ;	if (code_s2u & FM_SMYBEC)		queue_event(smc,EVENT_RMT,RM_MY_BEACON) ;	if (change_s2u & code_s2u & FM_SLOCLM) {		DB_RMTN(2,"RMT : lower claim received\n",0,0) ;	}	if ((code_s2u & FM_SMYCLM) && !(code_s2l & FM_SDUPCLM)) {		/*		 * This is my claim and that claim is not detected as a		 * duplicate one.		 */		queue_event(smc,EVENT_RMT,RM_MY_CLAIM) ;	}	if (code_s2l & FM_SDUPCLM) {		/*		 * If a duplicate claim frame (same SA but T_Bid != T_Req)		 * this flag will be set.		 * In the RMT state machine we need a RM_VALID_CLAIM event		 * to do the appropriate state change.		 * RM(34c)		 */		queue_event(smc,EVENT_RMT,RM_VALID_CLAIM) ;	}	if (change_s2u & code_s2u & FM_SHICLM) {		DB_RMTN(2,"RMT : higher claim received\n",0,0) ;	}	if ( (code_s2l & FM_STRTEXP) ||	     (code_s2l & FM_STRTEXR) )		queue_event(smc,EVENT_RMT,RM_TRT_EXP) ;	if (code_s2l & FM_SMULTDA) {		/*		 * The MAC has found a 2. MAC with the same address.		 * Signal dup_addr_test = failed to RMT state machine.		 * RM(25)		 */		smc->r.dup_addr_test = DA_FAILED ;		queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;	}	if (code_s2u & FM_SBEC)		smc->hw.fp.err_stats.err_bec_stat++ ;	if (code_s2u & FM_SCLM)		smc->hw.fp.err_stats.err_clm_stat++ ;	if (code_s2l & FM_STVXEXP)		smc->mib.m[MAC0].fddiMACTvxExpired_Ct++ ;	if ((code_s2u & (FM_SBEC|FM_SCLM))) {		if (!(change_s2l & FM_SRNGOP) && (smc->hw.fp.s2l & FM_SRNGOP)) {			mac_ring_up(smc,0) ;			queue_event(smc,EVENT_RMT,RM_RING_NON_OP) ;			mac_ring_up(smc,1) ;			queue_event(smc,EVENT_RMT,RM_RING_OP) ;			smc->mib.m[MAC0].fddiMACRingOp_Ct++ ;		}	}	if (code_s2l & FM_SPHINV)		smc->hw.fp.err_stats.err_phinv++ ;	if (code_s2l & FM_SSIFG)		smc->hw.fp.err_stats.err_sifg_det++ ;	if (code_s2l & FM_STKISS)		smc->hw.fp.err_stats.err_tkiss++ ;	if (code_s2l & FM_STKERR)		smc->hw.fp.err_stats.err_tkerr++ ;	if (code_s2l & FM_SFRMCTR)		smc->mib.m[MAC0].fddiMACFrame_Ct += 0x10000L ;	if (code_s2l & FM_SERRCTR)		smc->mib.m[MAC0].fddiMACError_Ct += 0x10000L ;	if (code_s2l & FM_SLSTCTR)		smc->mib.m[MAC0].fddiMACLost_Ct  += 0x10000L ;	if (code_s2u & FM_SERRSF) {		SMT_PANIC(smc,SMT_E0114, SMT_E0114_MSG) ;	}mac2_end:	/* notice old status */	smc->hw.fp.s2l = code_s2l ;	smc->hw.fp.s2u = code_s2u ;	outpw(FM_A(FM_IMSK2U),~mac_imsk2u) ;}/* * mac3_irq:	receive queue 2 bits and address detection bits */void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l){	UNUSED(code_s3l) ;	if (code_s3u & (FM_SRCVOVR2 |	/* recv. FIFO overflow */			FM_SRBFL2)) {	/* recv. buffer full */		smc->hw.mac_ct.mac_r_restart_counter++ ;		smt_stat_counter(smc,1);	}	if (code_s3u & FM_SRPERRQ2) {	/* parity error receive queue 2 */		SMT_PANIC(smc,SMT_E0115, SMT_E0115_MSG) ;	}	if (code_s3u & FM_SRPERRQ1) {	/* parity error receive queue 2 */		SMT_PANIC(smc,SMT_E0116, SMT_E0116_MSG) ;	}}/* * take formac offline */static void formac_offline(struct s_smc *smc){	outpw(FM_A(FM_CMDREG2),FM_IACTR) ;/* abort current transmit activity */	/* disable receive function */	SETMASK(FM_A(FM_MDREG1),FM_MDISRCV,FM_ADDET) ;	/* FORMAC+ 'Initialize Mode' */	SETMASK(FM_A(FM_MDREG1),FM_MINIT,FM_MMODE) ;	disable_formac(smc) ;	smc->hw.mac_ring_is_up = FALSE ;	smc->hw.hw_state = STOPPED ;}/* * bring formac online */static void formac_online(struct s_smc *smc){	enable_formac(smc) ;	SETMASK(FM_A(FM_MDREG1),FM_MONLINE | FM_SELRA | MDR1INIT |		smc->hw.fp.rx_mode, FM_MMODE | FM_SELRA | FM_ADDRX) ;}/* * FORMAC+ full init. (tx, rx, timer, counter, claim & beacon) */int init_fplus(struct s_smc *smc){	smc->hw.fp.nsa_mode = FM_MRNNSAFNMA ;	smc->hw.fp.rx_mode = FM_MDAMA ;	smc->hw.fp.group_addr = fddi_broadcast ;	smc->hw.fp.func_addr = 0 ;	smc->hw.fp.frselreg_init = 0 ;	init_driver_fplus(smc) ;	if (smc->s.sas == SMT_DAS)		smc->hw.fp.mdr3init |= FM_MENDAS ;	smc->hw.mac_ct.mac_nobuf_counter = 0 ;	smc->hw.mac_ct.mac_r_restart_counter = 0 ;	smc->hw.fp.fm_st1u = (HW_PTR) ADDR(B0_ST1U) ;	smc->hw.fp.fm_st1l = (HW_PTR) ADDR(B0_ST1L) ;	smc->hw.fp.fm_st2u = (HW_PTR) ADDR(B0_ST2U) ;	smc->hw.fp.fm_st2l = (HW_PTR) ADDR(B0_ST2L) ;	smc->hw.fp.fm_st3u = (HW_PTR) ADDR(B0_ST3U) ;	smc->hw.fp.fm_st3l = (HW_PTR) ADDR(B0_ST3L) ;	smc->hw.fp.s2l = smc->hw.fp.s2u = 0 ;	smc->hw.mac_ring_is_up = 0 ;	mac_counter_init(smc) ;	/* convert BCKL units to symbol time */	smc->hw.mac_pa.t_neg = (u_long)0 ;	smc->hw.mac_pa.t_pri = (u_long)0 ;	/* make sure all PCI settings are correct */	mac_do_pci_fix(smc) ;	return(init_mac(smc,1)) ;	/* enable_formac(smc) ; */}static int init_mac(struct s_smc *smc, int all){	u_short	t_max,x ;	u_long	time=0 ;	/*	 * clear memory	 */	outpw(FM_A(FM_MDREG1),FM_MINIT) ;	/* FORMAC+ init mode */	set_formac_addr(smc) ;	outpw(FM_A(FM_MDREG1),FM_MMEMACT) ;	/* FORMAC+ memory activ mode */	/* Note: Mode register 2 is set here, incase parity is enabled. */	outpw(FM_A(FM_MDREG2),smc->hw.fp.mdr2init) ;	if (all) {		init_ram(smc) ;	}	else {		/*		 * reset the HPI, the Master and the BMUs		 */		outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;		time = hwt_quick_read(smc) ;	}	/*	 * set all pointers, frames etc	 */	smt_split_up_fifo(smc) ;	init_tx(smc) ;	init_rx(smc) ;	init_rbc(smc) ;	build_claim_beacon(smc,smc->mib.m[MAC0].fddiMACT_Req) ;	/* set RX threshold */	/* see Errata #SN2 Phantom receive overflow */	outpw(FM_A(FM_FRMTHR),14<<12) ;		/* switch on */	/* set formac work mode */	outpw(FM_A(FM_MDREG1),MDR1INIT | FM_SELRA | smc->hw.fp.rx_mode) ;	outpw(FM_A(FM_MDREG2),smc->hw.fp.mdr2init) ;	outpw(FM_A(FM_MDREG3),smc->hw.fp.mdr3init) ;	outpw(FM_A(FM_FRSELREG),smc->hw.fp.frselreg_init) ;	/* set timer */	/*	 * errata #22 fplus:	 * T_MAX must not be FFFE	 * or one of FFDF, FFB8, FF91 (-0x27 etc..)	 */	t_max = (u_short)(smc->mib.m[MAC0].fddiMACT_Max/32) ;	x = t_max/0x27 ;	x *= 0x27 ;	if ((t_max == 0xfffe) || (t_max - x == 0x16))		t_max-- ;	outpw(FM_A(FM_TMAX),(u_short)t_max) ;	/* BugFix for report #10204 */	if (smc->mib.m[MAC0].fddiMACTvxValue < (u_long) (- US2BCLK(52))) {		outpw(FM_A(FM_TVX), (u_short) (- US2BCLK(52))/255 & MB) ;	} else {		outpw(FM_A(FM_TVX),			(u_short)((smc->mib.m[MAC0].fddiMACTvxValue/255) & MB)) ;	}	outpw(FM_A(FM_CMDREG1),FM_ICLLS) ;	/* clear s-frame lock */	outpw(FM_A(FM_CMDREG1),FM_ICLLA0) ;	/* clear a-frame lock */	outpw(FM_A(FM_CMDREG1),FM_ICLLR);	/* clear receive lock */	/* Auto unlock receice threshold for receive queue 1 and 2 */	outpw(FM_A(FM_UNLCKDLY),(0xff|(0xff<<8))) ;	rtm_init(smc) ;				/* RT-Monitor */	if (!all) {		/*		 * after 10ms, reset the BMUs and repair the rings		 */		hwt_wait_time(smc,time,MS2BCLK(10)) ;		outpd(ADDR(B0_R1_CSR),CSR_SET_RESET) ;		outpd(ADDR(B0_XA_CSR),CSR_SET_RESET) ;		outpd(ADDR(B0_XS_CSR),CSR_SET_RESET) ;		outp(ADDR(B0_CTRL), CTRL_HPI_CLR) ;		outpd(ADDR(B0_R1_CSR),CSR_CLR_RESET) ;		outpd(ADDR(B0_XA_CSR),CSR_CLR_RESET) ;		outpd(ADDR(B0_XS_CSR),CSR_CLR_RESET) ;		if (!smc->hw.hw_is_64bit) {			outpd(ADDR(B4_R1_F), RX_WATERMARK) ;			outpd(ADDR(B5_XA_F), TX_WATERMARK) ;			outpd(ADDR(B5_XS_F), TX_WATERMARK) ;		}		smc->hw.hw_state = STOPPED ;		mac_drv_repair_descr(smc) ;	}	smc->hw.hw_state = STARTED ;	return(0) ;}/* * called by CFM */void config_mux(struct s_smc *smc, int mux){	plc_config_mux(smc,mux) ;	SETMASK(FM_A(FM_MDREG1),FM_SELRA,FM_SELRA) ;}/* * called by RMT * enable CLAIM/BEACON interrupts * (only called if these events are of interest, e.g. in DETECT state * the interrupt must not be permanently enabled * RMT calls this function periodically (timer driven polling) */void sm_mac_check_beacon_claim(struct s_smc *smc){	/* set formac IMSK : 0 enables irq */	outpw(FM_A(FM_IMSK2U),~(mac_imsk2u | mac_beacon_imsk2u)) ;	/* the driver must receive the directed beacons */	formac_rcv_restart(smc) ;	process_receive(smc) ;}/*-------------------------- interface functions ----------------------------*//* * control MAC layer	(called by RMT) */void sm_ma_control(struct s_smc *smc, int mode){	switch(mode) {	case MA_OFFLINE :		/* Add to make the MAC offline in RM0_ISOLATED state */		formac_offline(smc) ;		break ;	case MA_RESET :		(void)init_mac(smc,0) ;		break ;	case MA_BEACON :		formac_online(smc) ;		break ;	case MA_DIRECTED :		directed_beacon(smc) ;		break ;	case MA_TREQ :

⌨️ 快捷键说明

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