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