xref: /OK3568_Linux_fs/kernel/drivers/net/fddi/skfp/drvfbi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  *	(C)Copyright 1998,1999 SysKonnect,
5*4882a593Smuzhiyun  *	a business unit of Schneider & Koch & Co. Datensysteme GmbH.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  *	See the file "skfddi.c" for further information.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  *	The information in this file is provided "AS IS" without warranty.
10*4882a593Smuzhiyun  *
11*4882a593Smuzhiyun  ******************************************************************************/
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun /*
14*4882a593Smuzhiyun  * FBI board dependent Driver for SMT and LLC
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include "h/types.h"
18*4882a593Smuzhiyun #include "h/fddi.h"
19*4882a593Smuzhiyun #include "h/smc.h"
20*4882a593Smuzhiyun #include "h/supern_2.h"
21*4882a593Smuzhiyun #include "h/skfbiinc.h"
22*4882a593Smuzhiyun #include <linux/bitrev.h>
23*4882a593Smuzhiyun #include <linux/pci.h>
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #ifndef	lint
26*4882a593Smuzhiyun static const char ID_sccs[] = "@(#)drvfbi.c	1.63 99/02/11 (C) SK " ;
27*4882a593Smuzhiyun #endif
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /*
30*4882a593Smuzhiyun  * PCM active state
31*4882a593Smuzhiyun  */
32*4882a593Smuzhiyun #define PC8_ACTIVE	8
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #define	LED_Y_ON	0x11	/* Used for ring up/down indication */
35*4882a593Smuzhiyun #define	LED_Y_OFF	0x10
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #define MS2BCLK(x)	((x)*12500L)
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /*
41*4882a593Smuzhiyun  * valid configuration values are:
42*4882a593Smuzhiyun  */
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun /*
45*4882a593Smuzhiyun  *	xPOS_ID:xxxx
46*4882a593Smuzhiyun  *	|	\  /
47*4882a593Smuzhiyun  *	|	 \/
48*4882a593Smuzhiyun  *	|	  --------------------- the patched POS_ID of the Adapter
49*4882a593Smuzhiyun  *	|				xxxx = (Vendor ID low byte,
50*4882a593Smuzhiyun  *	|					Vendor ID high byte,
51*4882a593Smuzhiyun  *	|					Device ID low byte,
52*4882a593Smuzhiyun  *	|					Device ID high byte)
53*4882a593Smuzhiyun  *	+------------------------------ the patched oem_id must be
54*4882a593Smuzhiyun  *					'S' for SK or 'I' for IBM
55*4882a593Smuzhiyun  *					this is a short id for the driver.
56*4882a593Smuzhiyun  */
57*4882a593Smuzhiyun #ifndef MULT_OEM
58*4882a593Smuzhiyun #ifndef	OEM_CONCEPT
59*4882a593Smuzhiyun const u_char oem_id[] = "xPOS_ID:xxxx" ;
60*4882a593Smuzhiyun #else	/* OEM_CONCEPT */
61*4882a593Smuzhiyun const u_char oem_id[] = OEM_ID ;
62*4882a593Smuzhiyun #endif	/* OEM_CONCEPT */
63*4882a593Smuzhiyun #define	ID_BYTE0	8
64*4882a593Smuzhiyun #define	OEMID(smc,i)	oem_id[ID_BYTE0 + i]
65*4882a593Smuzhiyun #else	/* MULT_OEM */
66*4882a593Smuzhiyun const struct s_oem_ids oem_ids[] = {
67*4882a593Smuzhiyun #include "oemids.h"
68*4882a593Smuzhiyun {0}
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun #define	OEMID(smc,i)	smc->hw.oem_id->oi_id[i]
71*4882a593Smuzhiyun #endif	/* MULT_OEM */
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /* Prototypes of external functions */
74*4882a593Smuzhiyun #ifdef AIX
75*4882a593Smuzhiyun extern int AIX_vpdReadByte() ;
76*4882a593Smuzhiyun #endif
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /* Prototype of a local function. */
80*4882a593Smuzhiyun static void smt_stop_watchdog(struct s_smc *smc);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /*
83*4882a593Smuzhiyun  * FDDI card reset
84*4882a593Smuzhiyun  */
card_start(struct s_smc * smc)85*4882a593Smuzhiyun static void card_start(struct s_smc *smc)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	int i ;
88*4882a593Smuzhiyun #ifdef	PCI
89*4882a593Smuzhiyun 	u_char	rev_id ;
90*4882a593Smuzhiyun 	u_short word;
91*4882a593Smuzhiyun #endif
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	smt_stop_watchdog(smc) ;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun #ifdef	PCI
96*4882a593Smuzhiyun 	/*
97*4882a593Smuzhiyun 	 * make sure no transfer activity is pending
98*4882a593Smuzhiyun 	 */
99*4882a593Smuzhiyun 	outpw(FM_A(FM_MDREG1),FM_MINIT) ;
100*4882a593Smuzhiyun 	outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
101*4882a593Smuzhiyun 	hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;
102*4882a593Smuzhiyun 	/*
103*4882a593Smuzhiyun 	 * now reset everything
104*4882a593Smuzhiyun 	 */
105*4882a593Smuzhiyun 	outp(ADDR(B0_CTRL),CTRL_RST_SET) ;	/* reset for all chips */
106*4882a593Smuzhiyun 	i = (int) inp(ADDR(B0_CTRL)) ;		/* do dummy read */
107*4882a593Smuzhiyun 	SK_UNUSED(i) ;				/* Make LINT happy. */
108*4882a593Smuzhiyun 	outp(ADDR(B0_CTRL), CTRL_RST_CLR) ;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	/*
111*4882a593Smuzhiyun 	 * Reset all bits in the PCI STATUS register
112*4882a593Smuzhiyun 	 */
113*4882a593Smuzhiyun 	outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ;	/* enable for writes */
114*4882a593Smuzhiyun 	word = inpw(PCI_C(PCI_STATUS)) ;
115*4882a593Smuzhiyun 	outpw(PCI_C(PCI_STATUS), word | PCI_STATUS_ERROR_BITS);
116*4882a593Smuzhiyun 	outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ;	/* disable writes */
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	/*
119*4882a593Smuzhiyun 	 * Release the reset of all the State machines
120*4882a593Smuzhiyun 	 * Release Master_Reset
121*4882a593Smuzhiyun 	 * Release HPI_SM_Reset
122*4882a593Smuzhiyun 	 */
123*4882a593Smuzhiyun 	outp(ADDR(B0_CTRL), CTRL_MRST_CLR|CTRL_HPI_CLR) ;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	/*
126*4882a593Smuzhiyun 	 * determine the adapter type
127*4882a593Smuzhiyun 	 * Note: Do it here, because some drivers may call card_start() once
128*4882a593Smuzhiyun 	 *	 at very first before any other initialization functions is
129*4882a593Smuzhiyun 	 *	 executed.
130*4882a593Smuzhiyun 	 */
131*4882a593Smuzhiyun 	rev_id = inp(PCI_C(PCI_REVISION_ID)) ;
132*4882a593Smuzhiyun 	if ((rev_id & 0xf0) == SK_ML_ID_1 || (rev_id & 0xf0) == SK_ML_ID_2) {
133*4882a593Smuzhiyun 		smc->hw.hw_is_64bit = TRUE ;
134*4882a593Smuzhiyun 	} else {
135*4882a593Smuzhiyun 		smc->hw.hw_is_64bit = FALSE ;
136*4882a593Smuzhiyun 	}
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	/*
139*4882a593Smuzhiyun 	 * Watermark initialization
140*4882a593Smuzhiyun 	 */
141*4882a593Smuzhiyun 	if (!smc->hw.hw_is_64bit) {
142*4882a593Smuzhiyun 		outpd(ADDR(B4_R1_F), RX_WATERMARK) ;
143*4882a593Smuzhiyun 		outpd(ADDR(B5_XA_F), TX_WATERMARK) ;
144*4882a593Smuzhiyun 		outpd(ADDR(B5_XS_F), TX_WATERMARK) ;
145*4882a593Smuzhiyun 	}
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	outp(ADDR(B0_CTRL),CTRL_RST_CLR) ;	/* clear the reset chips */
148*4882a593Smuzhiyun 	outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_ON|LED_GB_OFF) ; /* ye LED on */
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	/* init the timer value for the watch dog 2,5 minutes */
151*4882a593Smuzhiyun 	outpd(ADDR(B2_WDOG_INI),0x6FC23AC0) ;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	/* initialize the ISR mask */
154*4882a593Smuzhiyun 	smc->hw.is_imask = ISR_MASK ;
155*4882a593Smuzhiyun 	smc->hw.hw_state = STOPPED ;
156*4882a593Smuzhiyun #endif
157*4882a593Smuzhiyun 	GET_PAGE(0) ;		/* necessary for BOOT */
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
card_stop(struct s_smc * smc)160*4882a593Smuzhiyun void card_stop(struct s_smc *smc)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun 	smt_stop_watchdog(smc) ;
163*4882a593Smuzhiyun 	smc->hw.mac_ring_is_up = 0 ;		/* ring down */
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun #ifdef	PCI
166*4882a593Smuzhiyun 	/*
167*4882a593Smuzhiyun 	 * make sure no transfer activity is pending
168*4882a593Smuzhiyun 	 */
169*4882a593Smuzhiyun 	outpw(FM_A(FM_MDREG1),FM_MINIT) ;
170*4882a593Smuzhiyun 	outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
171*4882a593Smuzhiyun 	hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;
172*4882a593Smuzhiyun 	/*
173*4882a593Smuzhiyun 	 * now reset everything
174*4882a593Smuzhiyun 	 */
175*4882a593Smuzhiyun 	outp(ADDR(B0_CTRL),CTRL_RST_SET) ;	/* reset for all chips */
176*4882a593Smuzhiyun 	outp(ADDR(B0_CTRL),CTRL_RST_CLR) ;	/* reset for all chips */
177*4882a593Smuzhiyun 	outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_OFF|LED_GB_OFF) ; /* all LEDs off */
178*4882a593Smuzhiyun 	smc->hw.hw_state = STOPPED ;
179*4882a593Smuzhiyun #endif
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun /*--------------------------- ISR handling ----------------------------------*/
182*4882a593Smuzhiyun 
mac1_irq(struct s_smc * smc,u_short stu,u_short stl)183*4882a593Smuzhiyun void mac1_irq(struct s_smc *smc, u_short stu, u_short stl)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun 	int	restart_tx = 0 ;
186*4882a593Smuzhiyun again:
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	/*
189*4882a593Smuzhiyun 	 * parity error: note encoding error is not possible in tag mode
190*4882a593Smuzhiyun 	 */
191*4882a593Smuzhiyun 	if (stl & (FM_SPCEPDS  |	/* parity err. syn.q.*/
192*4882a593Smuzhiyun 		   FM_SPCEPDA0 |	/* parity err. a.q.0 */
193*4882a593Smuzhiyun 		   FM_SPCEPDA1)) {	/* parity err. a.q.1 */
194*4882a593Smuzhiyun 		SMT_PANIC(smc,SMT_E0134, SMT_E0134_MSG) ;
195*4882a593Smuzhiyun 	}
196*4882a593Smuzhiyun 	/*
197*4882a593Smuzhiyun 	 * buffer underrun: can only occur if a tx threshold is specified
198*4882a593Smuzhiyun 	 */
199*4882a593Smuzhiyun 	if (stl & (FM_STBURS  |		/* tx buffer underrun syn.q.*/
200*4882a593Smuzhiyun 		   FM_STBURA0 |		/* tx buffer underrun a.q.0 */
201*4882a593Smuzhiyun 		   FM_STBURA1)) {	/* tx buffer underrun a.q.2 */
202*4882a593Smuzhiyun 		SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ;
203*4882a593Smuzhiyun 	}
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	if ( (stu & (FM_SXMTABT |		/* transmit abort */
206*4882a593Smuzhiyun 		     FM_STXABRS |		/* syn. tx abort */
207*4882a593Smuzhiyun 		     FM_STXABRA0)) ||		/* asyn. tx abort */
208*4882a593Smuzhiyun 	     (stl & (FM_SQLCKS |		/* lock for syn. q. */
209*4882a593Smuzhiyun 		     FM_SQLCKA0)) ) {		/* lock for asyn. q. */
210*4882a593Smuzhiyun 		formac_tx_restart(smc) ;	/* init tx */
211*4882a593Smuzhiyun 		restart_tx = 1 ;
212*4882a593Smuzhiyun 		stu = inpw(FM_A(FM_ST1U)) ;
213*4882a593Smuzhiyun 		stl = inpw(FM_A(FM_ST1L)) ;
214*4882a593Smuzhiyun 		stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ;
215*4882a593Smuzhiyun 		if (stu || stl)
216*4882a593Smuzhiyun 			goto again ;
217*4882a593Smuzhiyun 	}
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	if (stu & (FM_STEFRMA0 |	/* end of asyn tx */
220*4882a593Smuzhiyun 		    FM_STEFRMS)) {	/* end of sync tx */
221*4882a593Smuzhiyun 		restart_tx = 1 ;
222*4882a593Smuzhiyun 	}
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	if (restart_tx)
225*4882a593Smuzhiyun 		llc_restart_tx(smc) ;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun /*
229*4882a593Smuzhiyun  * interrupt source= plc1
230*4882a593Smuzhiyun  * this function is called in nwfbisr.asm
231*4882a593Smuzhiyun  */
plc1_irq(struct s_smc * smc)232*4882a593Smuzhiyun void plc1_irq(struct s_smc *smc)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun 	u_short	st = inpw(PLC(PB,PL_INTR_EVENT)) ;
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	plc_irq(smc,PB,st) ;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun /*
240*4882a593Smuzhiyun  * interrupt source= plc2
241*4882a593Smuzhiyun  * this function is called in nwfbisr.asm
242*4882a593Smuzhiyun  */
plc2_irq(struct s_smc * smc)243*4882a593Smuzhiyun void plc2_irq(struct s_smc *smc)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	u_short	st = inpw(PLC(PA,PL_INTR_EVENT)) ;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	plc_irq(smc,PA,st) ;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun /*
252*4882a593Smuzhiyun  * interrupt source= timer
253*4882a593Smuzhiyun  */
timer_irq(struct s_smc * smc)254*4882a593Smuzhiyun void timer_irq(struct s_smc *smc)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun 	hwt_restart(smc);
257*4882a593Smuzhiyun 	smc->hw.t_stop = smc->hw.t_start;
258*4882a593Smuzhiyun 	smt_timer_done(smc) ;
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun /*
262*4882a593Smuzhiyun  * return S-port (PA or PB)
263*4882a593Smuzhiyun  */
pcm_get_s_port(struct s_smc * smc)264*4882a593Smuzhiyun int pcm_get_s_port(struct s_smc *smc)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun 	SK_UNUSED(smc) ;
267*4882a593Smuzhiyun 	return PS;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun /*
271*4882a593Smuzhiyun  * Station Label = "FDDI-XYZ" where
272*4882a593Smuzhiyun  *
273*4882a593Smuzhiyun  *	X = connector type
274*4882a593Smuzhiyun  *	Y = PMD type
275*4882a593Smuzhiyun  *	Z = port type
276*4882a593Smuzhiyun  */
277*4882a593Smuzhiyun #define STATION_LABEL_CONNECTOR_OFFSET	5
278*4882a593Smuzhiyun #define STATION_LABEL_PMD_OFFSET	6
279*4882a593Smuzhiyun #define STATION_LABEL_PORT_OFFSET	7
280*4882a593Smuzhiyun 
read_address(struct s_smc * smc,u_char * mac_addr)281*4882a593Smuzhiyun void read_address(struct s_smc *smc, u_char *mac_addr)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun 	char ConnectorType ;
284*4882a593Smuzhiyun 	char PmdType ;
285*4882a593Smuzhiyun 	int	i ;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun #ifdef	PCI
288*4882a593Smuzhiyun 	for (i = 0; i < 6; i++) {	/* read mac address from board */
289*4882a593Smuzhiyun 		smc->hw.fddi_phys_addr.a[i] =
290*4882a593Smuzhiyun 			bitrev8(inp(ADDR(B2_MAC_0+i)));
291*4882a593Smuzhiyun 	}
292*4882a593Smuzhiyun #endif
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	ConnectorType = inp(ADDR(B2_CONN_TYP)) ;
295*4882a593Smuzhiyun 	PmdType = inp(ADDR(B2_PMD_TYP)) ;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	smc->y[PA].pmd_type[PMD_SK_CONN] =
298*4882a593Smuzhiyun 	smc->y[PB].pmd_type[PMD_SK_CONN] = ConnectorType ;
299*4882a593Smuzhiyun 	smc->y[PA].pmd_type[PMD_SK_PMD ] =
300*4882a593Smuzhiyun 	smc->y[PB].pmd_type[PMD_SK_PMD ] = PmdType ;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	if (mac_addr) {
303*4882a593Smuzhiyun 		for (i = 0; i < 6 ;i++) {
304*4882a593Smuzhiyun 			smc->hw.fddi_canon_addr.a[i] = mac_addr[i] ;
305*4882a593Smuzhiyun 			smc->hw.fddi_home_addr.a[i] = bitrev8(mac_addr[i]);
306*4882a593Smuzhiyun 		}
307*4882a593Smuzhiyun 		return ;
308*4882a593Smuzhiyun 	}
309*4882a593Smuzhiyun 	smc->hw.fddi_home_addr = smc->hw.fddi_phys_addr ;
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	for (i = 0; i < 6 ;i++) {
312*4882a593Smuzhiyun 		smc->hw.fddi_canon_addr.a[i] =
313*4882a593Smuzhiyun 			bitrev8(smc->hw.fddi_phys_addr.a[i]);
314*4882a593Smuzhiyun 	}
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun /*
318*4882a593Smuzhiyun  * FDDI card soft reset
319*4882a593Smuzhiyun  */
init_board(struct s_smc * smc,u_char * mac_addr)320*4882a593Smuzhiyun void init_board(struct s_smc *smc, u_char *mac_addr)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun 	card_start(smc) ;
323*4882a593Smuzhiyun 	read_address(smc,mac_addr) ;
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	if (!(inp(ADDR(B0_DAS)) & DAS_AVAIL))
326*4882a593Smuzhiyun 		smc->s.sas = SMT_SAS ;	/* Single att. station */
327*4882a593Smuzhiyun 	else
328*4882a593Smuzhiyun 		smc->s.sas = SMT_DAS ;	/* Dual att. station */
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	if (!(inp(ADDR(B0_DAS)) & DAS_BYP_ST))
331*4882a593Smuzhiyun 		smc->mib.fddiSMTBypassPresent = 0 ;
332*4882a593Smuzhiyun 		/* without opt. bypass */
333*4882a593Smuzhiyun 	else
334*4882a593Smuzhiyun 		smc->mib.fddiSMTBypassPresent = 1 ;
335*4882a593Smuzhiyun 		/* with opt. bypass */
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun /*
339*4882a593Smuzhiyun  * insert or deinsert optical bypass (called by ECM)
340*4882a593Smuzhiyun  */
sm_pm_bypass_req(struct s_smc * smc,int mode)341*4882a593Smuzhiyun void sm_pm_bypass_req(struct s_smc *smc, int mode)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun 	DB_ECMN(1, "ECM : sm_pm_bypass_req(%s)",
344*4882a593Smuzhiyun 		mode == BP_INSERT ? "BP_INSERT" : "BP_DEINSERT");
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	if (smc->s.sas != SMT_DAS)
347*4882a593Smuzhiyun 		return ;
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun #ifdef	PCI
350*4882a593Smuzhiyun 	switch(mode) {
351*4882a593Smuzhiyun 	case BP_INSERT :
352*4882a593Smuzhiyun 		outp(ADDR(B0_DAS),DAS_BYP_INS) ;	/* insert station */
353*4882a593Smuzhiyun 		break ;
354*4882a593Smuzhiyun 	case BP_DEINSERT :
355*4882a593Smuzhiyun 		outp(ADDR(B0_DAS),DAS_BYP_RMV) ;	/* bypass station */
356*4882a593Smuzhiyun 		break ;
357*4882a593Smuzhiyun 	}
358*4882a593Smuzhiyun #endif
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun /*
362*4882a593Smuzhiyun  * check if bypass connected
363*4882a593Smuzhiyun  */
sm_pm_bypass_present(struct s_smc * smc)364*4882a593Smuzhiyun int sm_pm_bypass_present(struct s_smc *smc)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun 	return (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE : FALSE;
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun 
plc_clear_irq(struct s_smc * smc,int p)369*4882a593Smuzhiyun void plc_clear_irq(struct s_smc *smc, int p)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun 	SK_UNUSED(p) ;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	SK_UNUSED(smc) ;
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun /*
378*4882a593Smuzhiyun  * led_indication called by rmt_indication() and
379*4882a593Smuzhiyun  * pcm_state_change()
380*4882a593Smuzhiyun  *
381*4882a593Smuzhiyun  * Input:
382*4882a593Smuzhiyun  *	smc:	SMT context
383*4882a593Smuzhiyun  *	led_event:
384*4882a593Smuzhiyun  *	0	Only switch green LEDs according to their respective PCM state
385*4882a593Smuzhiyun  *	LED_Y_OFF	just switch yellow LED off
386*4882a593Smuzhiyun  *	LED_Y_ON	just switch yello LED on
387*4882a593Smuzhiyun  */
led_indication(struct s_smc * smc,int led_event)388*4882a593Smuzhiyun static void led_indication(struct s_smc *smc, int led_event)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 	/* use smc->hw.mac_ring_is_up == TRUE
391*4882a593Smuzhiyun 	 * as indication for Ring Operational
392*4882a593Smuzhiyun 	 */
393*4882a593Smuzhiyun 	u_short			led_state ;
394*4882a593Smuzhiyun 	struct s_phy		*phy ;
395*4882a593Smuzhiyun 	struct fddi_mib_p	*mib_a ;
396*4882a593Smuzhiyun 	struct fddi_mib_p	*mib_b ;
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	phy = &smc->y[PA] ;
399*4882a593Smuzhiyun 	mib_a = phy->mib ;
400*4882a593Smuzhiyun 	phy = &smc->y[PB] ;
401*4882a593Smuzhiyun 	mib_b = phy->mib ;
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun #ifdef	PCI
404*4882a593Smuzhiyun         led_state = 0 ;
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	/* Ring up = yellow led OFF*/
407*4882a593Smuzhiyun 	if (led_event == LED_Y_ON) {
408*4882a593Smuzhiyun 		led_state |= LED_MY_ON ;
409*4882a593Smuzhiyun 	}
410*4882a593Smuzhiyun 	else if (led_event == LED_Y_OFF) {
411*4882a593Smuzhiyun 		led_state |= LED_MY_OFF ;
412*4882a593Smuzhiyun 	}
413*4882a593Smuzhiyun 	else {	/* PCM state changed */
414*4882a593Smuzhiyun 		/* Link at Port A/S = green led A ON */
415*4882a593Smuzhiyun 		if (mib_a->fddiPORTPCMState == PC8_ACTIVE) {
416*4882a593Smuzhiyun 			led_state |= LED_GA_ON ;
417*4882a593Smuzhiyun 		}
418*4882a593Smuzhiyun 		else {
419*4882a593Smuzhiyun 			led_state |= LED_GA_OFF ;
420*4882a593Smuzhiyun 		}
421*4882a593Smuzhiyun 
422*4882a593Smuzhiyun 		/* Link at Port B = green led B ON */
423*4882a593Smuzhiyun 		if (mib_b->fddiPORTPCMState == PC8_ACTIVE) {
424*4882a593Smuzhiyun 			led_state |= LED_GB_ON ;
425*4882a593Smuzhiyun 		}
426*4882a593Smuzhiyun 		else {
427*4882a593Smuzhiyun 			led_state |= LED_GB_OFF ;
428*4882a593Smuzhiyun 		}
429*4882a593Smuzhiyun 	}
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun         outp(ADDR(B0_LED), led_state) ;
432*4882a593Smuzhiyun #endif	/* PCI */
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 
pcm_state_change(struct s_smc * smc,int plc,int p_state)437*4882a593Smuzhiyun void pcm_state_change(struct s_smc *smc, int plc, int p_state)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun 	/*
440*4882a593Smuzhiyun 	 * the current implementation of pcm_state_change() in the driver
441*4882a593Smuzhiyun 	 * parts must be renamed to drv_pcm_state_change() which will be called
442*4882a593Smuzhiyun 	 * now after led_indication.
443*4882a593Smuzhiyun 	 */
444*4882a593Smuzhiyun 	DRV_PCM_STATE_CHANGE(smc,plc,p_state) ;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	led_indication(smc,0) ;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 
rmt_indication(struct s_smc * smc,int i)450*4882a593Smuzhiyun void rmt_indication(struct s_smc *smc, int i)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun 	/* Call a driver special function if defined */
453*4882a593Smuzhiyun 	DRV_RMT_INDICATION(smc,i) ;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun         led_indication(smc, i ? LED_Y_OFF : LED_Y_ON) ;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun /*
460*4882a593Smuzhiyun  * llc_recover_tx called by init_tx (fplus.c)
461*4882a593Smuzhiyun  */
llc_recover_tx(struct s_smc * smc)462*4882a593Smuzhiyun void llc_recover_tx(struct s_smc *smc)
463*4882a593Smuzhiyun {
464*4882a593Smuzhiyun #ifdef	LOAD_GEN
465*4882a593Smuzhiyun 	extern	int load_gen_flag ;
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	load_gen_flag = 0 ;
468*4882a593Smuzhiyun #endif
469*4882a593Smuzhiyun #ifndef	SYNC
470*4882a593Smuzhiyun 	smc->hw.n_a_send= 0 ;
471*4882a593Smuzhiyun #else
472*4882a593Smuzhiyun 	SK_UNUSED(smc) ;
473*4882a593Smuzhiyun #endif
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun #ifdef MULT_OEM
is_equal_num(char comp1[],char comp2[],int num)477*4882a593Smuzhiyun static int is_equal_num(char comp1[], char comp2[], int num)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun 	int i ;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	for (i = 0 ; i < num ; i++) {
482*4882a593Smuzhiyun 		if (comp1[i] != comp2[i])
483*4882a593Smuzhiyun 			return 0;
484*4882a593Smuzhiyun 	}
485*4882a593Smuzhiyun 		return 1;
486*4882a593Smuzhiyun }	/* is_equal_num */
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun /*
490*4882a593Smuzhiyun  * set the OEM ID defaults, and test the contents of the OEM data base
491*4882a593Smuzhiyun  * The default OEM is the first ACTIVE entry in the OEM data base
492*4882a593Smuzhiyun  *
493*4882a593Smuzhiyun  * returns:	0	success
494*4882a593Smuzhiyun  *		1	error in data base
495*4882a593Smuzhiyun  *		2	data base empty
496*4882a593Smuzhiyun  *		3	no active entry
497*4882a593Smuzhiyun  */
set_oi_id_def(struct s_smc * smc)498*4882a593Smuzhiyun int set_oi_id_def(struct s_smc *smc)
499*4882a593Smuzhiyun {
500*4882a593Smuzhiyun 	int sel_id ;
501*4882a593Smuzhiyun 	int i ;
502*4882a593Smuzhiyun 	int act_entries ;
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	i = 0 ;
505*4882a593Smuzhiyun 	sel_id = -1 ;
506*4882a593Smuzhiyun 	act_entries = FALSE ;
507*4882a593Smuzhiyun 	smc->hw.oem_id = 0 ;
508*4882a593Smuzhiyun 	smc->hw.oem_min_status = OI_STAT_ACTIVE ;
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	/* check OEM data base */
511*4882a593Smuzhiyun 	while (oem_ids[i].oi_status) {
512*4882a593Smuzhiyun 		switch (oem_ids[i].oi_status) {
513*4882a593Smuzhiyun 		case OI_STAT_ACTIVE:
514*4882a593Smuzhiyun 			act_entries = TRUE ;	/* we have active IDs */
515*4882a593Smuzhiyun 			if (sel_id == -1)
516*4882a593Smuzhiyun 				sel_id = i ;	/* save the first active ID */
517*4882a593Smuzhiyun 		case OI_STAT_VALID:
518*4882a593Smuzhiyun 		case OI_STAT_PRESENT:
519*4882a593Smuzhiyun 			i++ ;
520*4882a593Smuzhiyun 			break ;			/* entry ok */
521*4882a593Smuzhiyun 		default:
522*4882a593Smuzhiyun 			return 1;		/* invalid oi_status */
523*4882a593Smuzhiyun 		}
524*4882a593Smuzhiyun 	}
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	if (i == 0)
527*4882a593Smuzhiyun 		return 2;
528*4882a593Smuzhiyun 	if (!act_entries)
529*4882a593Smuzhiyun 		return 3;
530*4882a593Smuzhiyun 
531*4882a593Smuzhiyun 	/* ok, we have a valid OEM data base with an active entry */
532*4882a593Smuzhiyun 	smc->hw.oem_id = (struct s_oem_ids *)  &oem_ids[sel_id] ;
533*4882a593Smuzhiyun 	return 0;
534*4882a593Smuzhiyun }
535*4882a593Smuzhiyun #endif	/* MULT_OEM */
536*4882a593Smuzhiyun 
driver_get_bia(struct s_smc * smc,struct fddi_addr * bia_addr)537*4882a593Smuzhiyun void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr)
538*4882a593Smuzhiyun {
539*4882a593Smuzhiyun 	int i ;
540*4882a593Smuzhiyun 
541*4882a593Smuzhiyun 	for (i = 0 ; i < 6 ; i++)
542*4882a593Smuzhiyun 		bia_addr->a[i] = bitrev8(smc->hw.fddi_phys_addr.a[i]);
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun 
smt_start_watchdog(struct s_smc * smc)545*4882a593Smuzhiyun void smt_start_watchdog(struct s_smc *smc)
546*4882a593Smuzhiyun {
547*4882a593Smuzhiyun 	SK_UNUSED(smc) ;	/* Make LINT happy. */
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun #ifndef	DEBUG
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun #ifdef	PCI
552*4882a593Smuzhiyun 	if (smc->hw.wdog_used) {
553*4882a593Smuzhiyun 		outpw(ADDR(B2_WDOG_CRTL),TIM_START) ;	/* Start timer. */
554*4882a593Smuzhiyun 	}
555*4882a593Smuzhiyun #endif
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun #endif	/* DEBUG */
558*4882a593Smuzhiyun }
559*4882a593Smuzhiyun 
smt_stop_watchdog(struct s_smc * smc)560*4882a593Smuzhiyun static void smt_stop_watchdog(struct s_smc *smc)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	SK_UNUSED(smc) ;	/* Make LINT happy. */
563*4882a593Smuzhiyun #ifndef	DEBUG
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun #ifdef	PCI
566*4882a593Smuzhiyun 	if (smc->hw.wdog_used) {
567*4882a593Smuzhiyun 		outpw(ADDR(B2_WDOG_CRTL),TIM_STOP) ;	/* Stop timer. */
568*4882a593Smuzhiyun 	}
569*4882a593Smuzhiyun #endif
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun #endif	/* DEBUG */
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun #ifdef	PCI
575*4882a593Smuzhiyun 
mac_do_pci_fix(struct s_smc * smc)576*4882a593Smuzhiyun void mac_do_pci_fix(struct s_smc *smc)
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun 	SK_UNUSED(smc) ;
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun #endif	/* PCI */
581*4882a593Smuzhiyun 
582