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

📄 drvfbi.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** * *	(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. * ******************************************************************************//* * FBI board dependent Driver for SMT and LLC */#include "h/types.h"#include "h/fddi.h"#include "h/smc.h"#include "h/supern_2.h"#include "h/skfbiinc.h"#ifndef	lintstatic const char ID_sccs[] = "@(#)drvfbi.c	1.63 99/02/11 (C) SK " ;#endif/* * PCM active state */#define PC8_ACTIVE	8#define	LED_Y_ON	0x11	/* Used for ring up/down indication */#define	LED_Y_OFF	0x10#define MS2BCLK(x)	((x)*12500L)/* * valid configuration values are: */#ifdef	ISAconst int opt_ints[] = {8,	3, 4, 5, 9, 10, 11, 12, 15} ;const int opt_iops[] = {8,	0x100, 0x120, 0x180, 0x1a0, 0x220, 0x240, 0x320, 0x340};const int opt_dmas[] = {4,	3, 5, 6, 7} ;const int opt_eproms[] = {15,	0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce,			0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc} ;#endif#ifdef	EISAconst int opt_ints[] = {5, 9, 10, 11} ;const int opt_dmas[] = {0, 5, 6, 7} ;const int opt_eproms[] = {0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce,				0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc} ;#endif#ifdef	MCAint	opt_ints[] = {3, 11, 10, 9} ;			/* FM1 */int	opt_eproms[] = {0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4, 0xd8, 0xdc} ;#endif	/* MCA *//* *	xPOS_ID:xxxx *	|	\  / *	|	 \/ *	|	  --------------------- the patched POS_ID of the Adapter *	|				xxxx = (Vendor ID low byte, *	|					Vendor ID high byte, *	|					Device ID low byte, *	|					Device ID high byte) *	+------------------------------ the patched oem_id must be *					'S' for SK or 'I' for IBM *					this is a short id for the driver. */#ifndef MULT_OEM#ifndef	OEM_CONCEPT#ifndef MCAconst u_char oem_id[] = "xPOS_ID:xxxx" ;#elseconst u_char oem_id[] = "xPOSID1:xxxx" ;	/* FM1 card id. */#endif#else	/* OEM_CONCEPT */#ifndef MCAconst u_char oem_id[] = OEM_ID ;#elseconst u_char oem_id[] = OEM_ID1 ;	/* FM1 card id. */#endif	/* MCA */#endif	/* OEM_CONCEPT */#define	ID_BYTE0	8#define	OEMID(smc,i)	oem_id[ID_BYTE0 + i]#else	/* MULT_OEM */const struct s_oem_ids oem_ids[] = {#include "oemids.h"{0}};#define	OEMID(smc,i)	smc->hw.oem_id->oi_id[i]#endif	/* MULT_OEM *//* Prototypes of external functions */#ifdef AIXextern int AIX_vpdReadByte() ;#endif/* Prototypes of local functions. */void smt_stop_watchdog(struct s_smc *smc);#ifdef MCAstatic int read_card_id() ;static void DisableSlotAccess() ;static void EnableSlotAccess() ;#ifdef AIXextern int attach_POS_addr() ;extern int detach_POS_addr() ;extern u_char read_POS() ;extern void write_POS() ;extern int AIX_vpdReadByte() ;#else#define	read_POS(smc,a1,a2)	((u_char) inp(a1))#define	write_POS(smc,a1,a2,a3)	outp((a1),(a3))#endif#endif	/* MCA *//* * FDDI card reset */static void card_start(struct s_smc *smc){	int i ;#ifdef	PCI	u_char	rev_id ;	u_short word;#endif	smt_stop_watchdog(smc) ;#ifdef	ISA	outpw(CSR_A,0) ;			/* reset for all chips */	for (i = 10 ; i ; i--)			/* delay for PLC's */		(void)inpw(ISR_A) ;	OUT_82c54_TIMER(3,COUNT(2) | RW_OP(3) | TMODE(2)) ;					/* counter 2, mode 2 */	OUT_82c54_TIMER(2,97) ;		/* LSB */	OUT_82c54_TIMER(2,0) ;		/* MSB ( 15.6 us ) */	outpw(CSR_A,CS_CRESET) ;#endif#ifdef	EISA	outpw(CSR_A,0) ;			/* reset for all chips */	for (i = 10 ; i ; i--)			/* delay for PLC's */		(void)inpw(ISR_A) ;	outpw(CSR_A,CS_CRESET) ;	smc->hw.led = (2<<6) ;	outpw(CSR_A,CS_CRESET | smc->hw.led) ;#endif#ifdef	MCA	outp(ADDR(CARD_DIS),0) ;		/* reset for all chips */	for (i = 10 ; i ; i--)			/* delay for PLC's */		(void)inpw(ISR_A) ;	outp(ADDR(CARD_EN),0) ;	/* first I/O after reset must not be a access to FORMAC or PLC */	/*	 * bus timeout (MCA)	 */	OUT_82c54_TIMER(3,COUNT(2) | RW_OP(3) | TMODE(3)) ;					/* counter 2, mode 3 */	OUT_82c54_TIMER(2,(2*24)) ;	/* 3.9 us * 2 square wave */	OUT_82c54_TIMER(2,0) ;		/* MSB */	/* POS 102 indicated an activ Check Line or Buss Error monitoring */	if (inpw(CSA_A) & (POS_EN_CHKINT | POS_EN_BUS_ERR)) {		outp(ADDR(IRQ_CHCK_EN),0) ;	}	if (!((i = inpw(CSR_A)) & CS_SAS)) {		if (!(i & CS_BYSTAT)) {			outp(ADDR(BYPASS(STAT_INS)),0) ;/* insert station */		}	}	outpw(LEDR_A,LED_1) ;	/* yellow */#endif	/* MCA */#ifdef	PCI	/*	 * make sure no transfer activity is pending	 */	outpw(FM_A(FM_MDREG1),FM_MINIT) ;	outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;	hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;	/*	 * now reset everything	 */	outp(ADDR(B0_CTRL),CTRL_RST_SET) ;	/* reset for all chips */	i = (int) inp(ADDR(B0_CTRL)) ;		/* do dummy read */	SK_UNUSED(i) ;				/* Make LINT happy. */	outp(ADDR(B0_CTRL), CTRL_RST_CLR) ;	/*	 * Reset all bits in the PCI STATUS register	 */	outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ;	/* enable for writes */	word = inpw(PCI_C(PCI_STATUS)) ;	outpw(PCI_C(PCI_STATUS), word | PCI_ERRBITS) ;	outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ;	/* disable writes */	/*	 * Release the reset of all the State machines	 * Release Master_Reset	 * Release HPI_SM_Reset	 */	outp(ADDR(B0_CTRL), CTRL_MRST_CLR|CTRL_HPI_CLR) ;	/*	 * determine the adapter type	 * Note: Do it here, because some drivers may call card_start() once	 *	 at very first before any other initialization functions is	 *	 executed.	 */	rev_id = inp(PCI_C(PCI_REV_ID)) ;	if ((rev_id & 0xf0) == SK_ML_ID_1 || (rev_id & 0xf0) == SK_ML_ID_2) {		smc->hw.hw_is_64bit = TRUE ;	} else {		smc->hw.hw_is_64bit = FALSE ;	}	/*	 * Watermark initialization	 */	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) ;	}	outp(ADDR(B0_CTRL),CTRL_RST_CLR) ;	/* clear the reset chips */	outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_ON|LED_GB_OFF) ; /* ye LED on */	/* init the timer value for the watch dog 2,5 minutes */	outpd(ADDR(B2_WDOG_INI),0x6FC23AC0) ;	/* initialize the ISR mask */	smc->hw.is_imask = ISR_MASK ;	smc->hw.hw_state = STOPPED ;#endif	GET_PAGE(0) ;		/* necessary for BOOT */}void card_stop(struct s_smc *smc){	smt_stop_watchdog(smc) ;	smc->hw.mac_ring_is_up = 0 ;		/* ring down */#ifdef	ISA	outpw(CSR_A,0) ;			/* reset for all chips */#endif#ifdef	EISA	outpw(CSR_A,0) ;			/* reset for all chips */#endif#ifdef	MCA	outp(ADDR(CARD_DIS),0) ;		/* reset for all chips */#endif#ifdef	PCI	/*	 * make sure no transfer activity is pending	 */	outpw(FM_A(FM_MDREG1),FM_MINIT) ;	outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;	hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;	/*	 * now reset everything	 */	outp(ADDR(B0_CTRL),CTRL_RST_SET) ;	/* reset for all chips */	outp(ADDR(B0_CTRL),CTRL_RST_CLR) ;	/* reset for all chips */	outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_OFF|LED_GB_OFF) ; /* all LEDs off */	smc->hw.hw_state = STOPPED ;#endif}/*--------------------------- ISR handling ----------------------------------*/void mac1_irq(struct s_smc *smc, u_short stu, u_short stl){	int	restart_tx = 0 ;again:#ifndef PCI#ifndef ISA/* * FORMAC+ bug modified the queue pointer if many read/write accesses happens!? */	if (stl & (FM_SPCEPDS  |	/* parit/coding err. syn.q.*/		   FM_SPCEPDA0 |	/* parit/coding err. a.q.0 */		   FM_SPCEPDA1 |	/* parit/coding err. a.q.1 */		   FM_SPCEPDA2)) {	/* parit/coding err. a.q.2 */		SMT_PANIC(smc,SMT_E0132, SMT_E0132_MSG) ;	}	if (stl & (FM_STBURS  |	/* tx buffer underrun syn.q.*/		   FM_STBURA0 |	/* tx buffer underrun a.q.0 */		   FM_STBURA1 |	/* tx buffer underrun a.q.1 */		   FM_STBURA2)) {	/* tx buffer underrun a.q.2 */		SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ;	}#endif	if ( (stu & (FM_SXMTABT |		/* transmit abort */#ifdef	SYNC		     FM_STXABRS |	/* syn. tx abort */#endif	/* SYNC */		     FM_STXABRA0)) ||	/* asyn. tx abort */	     (stl & (FM_SQLCKS |		/* lock for syn. q. */		     FM_SQLCKA0)) ) {	/* lock for asyn. q. */		formac_tx_restart(smc) ;		/* init tx */		restart_tx = 1 ;		stu = inpw(FM_A(FM_ST1U)) ;		stl = inpw(FM_A(FM_ST1L)) ;		stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ;		if (stu || stl)			goto again ;	}#ifndef	SYNC	if (stu & (FM_STECFRMA0 | /* end of chain asyn tx */		   FM_STEFRMA0)) { /* end of frame asyn tx */		/* free tx_queue */		smc->hw.n_a_send = 0 ;		if (++smc->hw.fp.tx_free < smc->hw.fp.tx_max) {			start_next_send(smc);		}		restart_tx = 1 ;	}#else	/* SYNC */	if (stu & (FM_STEFRMA0 |	/* end of asyn tx */		    FM_STEFRMS)) {	/* end of sync tx */		restart_tx = 1 ;	}#endif	/* SYNC */	if (restart_tx)		llc_restart_tx(smc) ;}#else	/* PCI */	/*	 * parity error: note encoding error is not possible in tag mode	 */	if (stl & (FM_SPCEPDS  |	/* parity err. syn.q.*/		   FM_SPCEPDA0 |	/* parity err. a.q.0 */		   FM_SPCEPDA1)) {	/* parity err. a.q.1 */		SMT_PANIC(smc,SMT_E0134, SMT_E0134_MSG) ;	}	/*	 * buffer underrun: can only occur if a tx threshold is specified	 */	if (stl & (FM_STBURS  |		/* tx buffer underrun syn.q.*/		   FM_STBURA0 |		/* tx buffer underrun a.q.0 */		   FM_STBURA1)) {	/* tx buffer underrun a.q.2 */		SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ;	}	if ( (stu & (FM_SXMTABT |		/* transmit abort */		     FM_STXABRS |		/* syn. tx abort */		     FM_STXABRA0)) ||		/* asyn. tx abort */	     (stl & (FM_SQLCKS |		/* lock for syn. q. */		     FM_SQLCKA0)) ) {		/* lock for asyn. q. */		formac_tx_restart(smc) ;	/* init tx */		restart_tx = 1 ;		stu = inpw(FM_A(FM_ST1U)) ;		stl = inpw(FM_A(FM_ST1L)) ;		stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ;		if (stu || stl)			goto again ;	}	if (stu & (FM_STEFRMA0 |	/* end of asyn tx */		    FM_STEFRMS)) {	/* end of sync tx */		restart_tx = 1 ;	}	if (restart_tx)		llc_restart_tx(smc) ;}#endif	/* PCI *//* * interrupt source= plc1 * this function is called in nwfbisr.asm */void plc1_irq(struct s_smc *smc){	u_short	st = inpw(PLC(PB,PL_INTR_EVENT)) ;#if	(defined(ISA) || defined(EISA))	/* reset PLC Int. bits */	outpw(PLC1_I,inpw(PLC1_I)) ;#endif	plc_irq(smc,PB,st) ;}/* * interrupt source= plc2 * this function is called in nwfbisr.asm */void plc2_irq(struct s_smc *smc){	u_short	st = inpw(PLC(PA,PL_INTR_EVENT)) ;#if	(defined(ISA) || defined(EISA))	/* reset PLC Int. bits */	outpw(PLC2_I,inpw(PLC2_I)) ;#endif	plc_irq(smc,PA,st) ;}/* * interrupt source= timer */void timer_irq(struct s_smc *smc){	hwt_restart(smc);	smc->hw.t_stop = smc->hw.t_start;	smt_timer_done(smc) ;}/* * return S-port (PA or PB) */int pcm_get_s_port(struct s_smc *smc){	SK_UNUSED(smc) ;	return(PS) ;}/* * Station Label = "FDDI-XYZ" where * *	X = connector type *	Y = PMD type *	Z = port type */#define STATION_LABEL_CONNECTOR_OFFSET	5#define STATION_LABEL_PMD_OFFSET	6#define STATION_LABEL_PORT_OFFSET	7void read_address(struct s_smc *smc, u_char *mac_addr){	char ConnectorType ;	char PmdType ;	int	i ;	extern const u_char canonical[256] ;#if	(defined(ISA) || defined(MCA))	for (i = 0; i < 4 ;i++) {	/* read mac address from board */		smc->hw.fddi_phys_addr.a[i] =			canonical[(inpw(PR_A(i+SA_MAC))&0xff)] ;	}	for (i = 4; i < 6; i++) {		smc->hw.fddi_phys_addr.a[i] =			canonical[(inpw(PR_A(i+SA_MAC+PRA_OFF))&0xff)] ;	}#endif#ifdef	EISA	/*	 * Note: We get trouble on an Alpha machine if we make a inpw()	 * instead of inp()	 */	for (i = 0; i < 4 ;i++) {	/* read mac address from board */		smc->hw.fddi_phys_addr.a[i] =			canonical[inp(PR_A(i+SA_MAC))] ;	}	for (i = 4; i < 6; i++) {		smc->hw.fddi_phys_addr.a[i] =			canonical[inp(PR_A(i+SA_MAC+PRA_OFF))] ;	}#endif#ifdef	PCI	for (i = 0; i < 6; i++) {	/* read mac address from board */		smc->hw.fddi_phys_addr.a[i] =			canonical[inp(ADDR(B2_MAC_0+i))] ;	}#endif#ifndef	PCI	ConnectorType = inpw(PR_A(SA_PMD_TYPE)) & 0xff ;	PmdType = inpw(PR_A(SA_PMD_TYPE+1)) & 0xff ;#else	ConnectorType = inp(ADDR(B2_CONN_TYP)) ;	PmdType = inp(ADDR(B2_PMD_TYP)) ;#endif	smc->y[PA].pmd_type[PMD_SK_CONN] =	smc->y[PB].pmd_type[PMD_SK_CONN] = ConnectorType ;	smc->y[PA].pmd_type[PMD_SK_PMD ] =	smc->y[PB].pmd_type[PMD_SK_PMD ] = PmdType ;	if (mac_addr) {		for (i = 0; i < 6 ;i++) {			smc->hw.fddi_canon_addr.a[i] = mac_addr[i] ;			smc->hw.fddi_home_addr.a[i] = canonical[mac_addr[i]] ;		}		return ;	}	smc->hw.fddi_home_addr = smc->hw.fddi_phys_addr ;	for (i = 0; i < 6 ;i++) {		smc->hw.fddi_canon_addr.a[i] =			canonical[smc->hw.fddi_phys_addr.a[i]] ;	}}/* * FDDI card soft reset */

⌨️ 快捷键说明

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