1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include "h/types.h"
18#include "h/fddi.h"
19#include "h/smc.h"
20#include "h/supern_2.h"
21#include "h/skfbiinc.h"
22#include <linux/bitrev.h>
23#include <linux/pci.h>
24
25#ifndef lint
26static const char ID_sccs[] = "@(#)drvfbi.c 1.63 99/02/11 (C) SK " ;
27#endif
28
29
30
31
32#define PC8_ACTIVE 8
33
34#define LED_Y_ON 0x11
35#define LED_Y_OFF 0x10
36
37
38#define MS2BCLK(x) ((x)*12500L)
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57#ifndef MULT_OEM
58#ifndef OEM_CONCEPT
59const u_char oem_id[] = "xPOS_ID:xxxx" ;
60#else
61const u_char oem_id[] = OEM_ID ;
62#endif
63#define ID_BYTE0 8
64#define OEMID(smc,i) oem_id[ID_BYTE0 + i]
65#else
66const struct s_oem_ids oem_ids[] = {
67#include "oemids.h"
68{0}
69};
70#define OEMID(smc,i) smc->hw.oem_id->oi_id[i]
71#endif
72
73
74#ifdef AIX
75extern int AIX_vpdReadByte() ;
76#endif
77
78
79
80static void smt_stop_watchdog(struct s_smc *smc);
81
82
83
84
85static void card_start(struct s_smc *smc)
86{
87 int i ;
88#ifdef PCI
89 u_char rev_id ;
90 u_short word;
91#endif
92
93 smt_stop_watchdog(smc) ;
94
95#ifdef PCI
96
97
98
99 outpw(FM_A(FM_MDREG1),FM_MINIT) ;
100 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
101 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;
102
103
104
105 outp(ADDR(B0_CTRL),CTRL_RST_SET) ;
106 i = (int) inp(ADDR(B0_CTRL)) ;
107 SK_UNUSED(i) ;
108 outp(ADDR(B0_CTRL), CTRL_RST_CLR) ;
109
110
111
112
113 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ;
114 word = inpw(PCI_C(PCI_STATUS)) ;
115 outpw(PCI_C(PCI_STATUS), word | PCI_STATUS_ERROR_BITS);
116 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ;
117
118
119
120
121
122
123 outp(ADDR(B0_CTRL), CTRL_MRST_CLR|CTRL_HPI_CLR) ;
124
125
126
127
128
129
130
131 rev_id = inp(PCI_C(PCI_REVISION_ID)) ;
132 if ((rev_id & 0xf0) == SK_ML_ID_1 || (rev_id & 0xf0) == SK_ML_ID_2) {
133 smc->hw.hw_is_64bit = TRUE ;
134 } else {
135 smc->hw.hw_is_64bit = FALSE ;
136 }
137
138
139
140
141 if (!smc->hw.hw_is_64bit) {
142 outpd(ADDR(B4_R1_F), RX_WATERMARK) ;
143 outpd(ADDR(B5_XA_F), TX_WATERMARK) ;
144 outpd(ADDR(B5_XS_F), TX_WATERMARK) ;
145 }
146
147 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ;
148 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_ON|LED_GB_OFF) ;
149
150
151 outpd(ADDR(B2_WDOG_INI),0x6FC23AC0) ;
152
153
154 smc->hw.is_imask = ISR_MASK ;
155 smc->hw.hw_state = STOPPED ;
156#endif
157 GET_PAGE(0) ;
158}
159
160void card_stop(struct s_smc *smc)
161{
162 smt_stop_watchdog(smc) ;
163 smc->hw.mac_ring_is_up = 0 ;
164
165#ifdef PCI
166
167
168
169 outpw(FM_A(FM_MDREG1),FM_MINIT) ;
170 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
171 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;
172
173
174
175 outp(ADDR(B0_CTRL),CTRL_RST_SET) ;
176 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ;
177 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_OFF|LED_GB_OFF) ;
178 smc->hw.hw_state = STOPPED ;
179#endif
180}
181
182
183void mac1_irq(struct s_smc *smc, u_short stu, u_short stl)
184{
185 int restart_tx = 0 ;
186again:
187
188
189
190
191 if (stl & (FM_SPCEPDS |
192 FM_SPCEPDA0 |
193 FM_SPCEPDA1)) {
194 SMT_PANIC(smc,SMT_E0134, SMT_E0134_MSG) ;
195 }
196
197
198
199 if (stl & (FM_STBURS |
200 FM_STBURA0 |
201 FM_STBURA1)) {
202 SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ;
203 }
204
205 if ( (stu & (FM_SXMTABT |
206 FM_STXABRS |
207 FM_STXABRA0)) ||
208 (stl & (FM_SQLCKS |
209 FM_SQLCKA0)) ) {
210 formac_tx_restart(smc) ;
211 restart_tx = 1 ;
212 stu = inpw(FM_A(FM_ST1U)) ;
213 stl = inpw(FM_A(FM_ST1L)) ;
214 stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ;
215 if (stu || stl)
216 goto again ;
217 }
218
219 if (stu & (FM_STEFRMA0 |
220 FM_STEFRMS)) {
221 restart_tx = 1 ;
222 }
223
224 if (restart_tx)
225 llc_restart_tx(smc) ;
226}
227
228
229
230
231
232void plc1_irq(struct s_smc *smc)
233{
234 u_short st = inpw(PLC(PB,PL_INTR_EVENT)) ;
235
236 plc_irq(smc,PB,st) ;
237}
238
239
240
241
242
243void plc2_irq(struct s_smc *smc)
244{
245 u_short st = inpw(PLC(PA,PL_INTR_EVENT)) ;
246
247 plc_irq(smc,PA,st) ;
248}
249
250
251
252
253
254void timer_irq(struct s_smc *smc)
255{
256 hwt_restart(smc);
257 smc->hw.t_stop = smc->hw.t_start;
258 smt_timer_done(smc) ;
259}
260
261
262
263
264int pcm_get_s_port(struct s_smc *smc)
265{
266 SK_UNUSED(smc) ;
267 return PS;
268}
269
270
271
272
273
274
275
276
277#define STATION_LABEL_CONNECTOR_OFFSET 5
278#define STATION_LABEL_PMD_OFFSET 6
279#define STATION_LABEL_PORT_OFFSET 7
280
281void read_address(struct s_smc *smc, u_char *mac_addr)
282{
283 char ConnectorType ;
284 char PmdType ;
285 int i ;
286
287#ifdef PCI
288 for (i = 0; i < 6; i++) {
289 smc->hw.fddi_phys_addr.a[i] =
290 bitrev8(inp(ADDR(B2_MAC_0+i)));
291 }
292#endif
293
294 ConnectorType = inp(ADDR(B2_CONN_TYP)) ;
295 PmdType = inp(ADDR(B2_PMD_TYP)) ;
296
297 smc->y[PA].pmd_type[PMD_SK_CONN] =
298 smc->y[PB].pmd_type[PMD_SK_CONN] = ConnectorType ;
299 smc->y[PA].pmd_type[PMD_SK_PMD ] =
300 smc->y[PB].pmd_type[PMD_SK_PMD ] = PmdType ;
301
302 if (mac_addr) {
303 for (i = 0; i < 6 ;i++) {
304 smc->hw.fddi_canon_addr.a[i] = mac_addr[i] ;
305 smc->hw.fddi_home_addr.a[i] = bitrev8(mac_addr[i]);
306 }
307 return ;
308 }
309 smc->hw.fddi_home_addr = smc->hw.fddi_phys_addr ;
310
311 for (i = 0; i < 6 ;i++) {
312 smc->hw.fddi_canon_addr.a[i] =
313 bitrev8(smc->hw.fddi_phys_addr.a[i]);
314 }
315}
316
317
318
319
320void init_board(struct s_smc *smc, u_char *mac_addr)
321{
322 card_start(smc) ;
323 read_address(smc,mac_addr) ;
324
325 if (!(inp(ADDR(B0_DAS)) & DAS_AVAIL))
326 smc->s.sas = SMT_SAS ;
327 else
328 smc->s.sas = SMT_DAS ;
329
330 if (!(inp(ADDR(B0_DAS)) & DAS_BYP_ST))
331 smc->mib.fddiSMTBypassPresent = 0 ;
332
333 else
334 smc->mib.fddiSMTBypassPresent = 1 ;
335
336}
337
338
339
340
341void sm_pm_bypass_req(struct s_smc *smc, int mode)
342{
343 DB_ECMN(1, "ECM : sm_pm_bypass_req(%s)",
344 mode == BP_INSERT ? "BP_INSERT" : "BP_DEINSERT");
345
346 if (smc->s.sas != SMT_DAS)
347 return ;
348
349#ifdef PCI
350 switch(mode) {
351 case BP_INSERT :
352 outp(ADDR(B0_DAS),DAS_BYP_INS) ;
353 break ;
354 case BP_DEINSERT :
355 outp(ADDR(B0_DAS),DAS_BYP_RMV) ;
356 break ;
357 }
358#endif
359}
360
361
362
363
364int sm_pm_bypass_present(struct s_smc *smc)
365{
366 return (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE : FALSE;
367}
368
369void plc_clear_irq(struct s_smc *smc, int p)
370{
371 SK_UNUSED(p) ;
372
373 SK_UNUSED(smc) ;
374}
375
376
377
378
379
380
381
382
383
384
385
386
387
388static void led_indication(struct s_smc *smc, int led_event)
389{
390
391
392
393 u_short led_state ;
394 struct s_phy *phy ;
395 struct fddi_mib_p *mib_a ;
396 struct fddi_mib_p *mib_b ;
397
398 phy = &smc->y[PA] ;
399 mib_a = phy->mib ;
400 phy = &smc->y[PB] ;
401 mib_b = phy->mib ;
402
403#ifdef PCI
404 led_state = 0 ;
405
406
407 if (led_event == LED_Y_ON) {
408 led_state |= LED_MY_ON ;
409 }
410 else if (led_event == LED_Y_OFF) {
411 led_state |= LED_MY_OFF ;
412 }
413 else {
414
415 if (mib_a->fddiPORTPCMState == PC8_ACTIVE) {
416 led_state |= LED_GA_ON ;
417 }
418 else {
419 led_state |= LED_GA_OFF ;
420 }
421
422
423 if (mib_b->fddiPORTPCMState == PC8_ACTIVE) {
424 led_state |= LED_GB_ON ;
425 }
426 else {
427 led_state |= LED_GB_OFF ;
428 }
429 }
430
431 outp(ADDR(B0_LED), led_state) ;
432#endif
433
434}
435
436
437void pcm_state_change(struct s_smc *smc, int plc, int p_state)
438{
439
440
441
442
443
444 DRV_PCM_STATE_CHANGE(smc,plc,p_state) ;
445
446 led_indication(smc,0) ;
447}
448
449
450void rmt_indication(struct s_smc *smc, int i)
451{
452
453 DRV_RMT_INDICATION(smc,i) ;
454
455 led_indication(smc, i ? LED_Y_OFF : LED_Y_ON) ;
456}
457
458
459
460
461
462void llc_recover_tx(struct s_smc *smc)
463{
464#ifdef LOAD_GEN
465 extern int load_gen_flag ;
466
467 load_gen_flag = 0 ;
468#endif
469#ifndef SYNC
470 smc->hw.n_a_send= 0 ;
471#else
472 SK_UNUSED(smc) ;
473#endif
474}
475
476#ifdef MULT_OEM
477static int is_equal_num(char comp1[], char comp2[], int num)
478{
479 int i ;
480
481 for (i = 0 ; i < num ; i++) {
482 if (comp1[i] != comp2[i])
483 return 0;
484 }
485 return 1;
486}
487
488
489
490
491
492
493
494
495
496
497
498int set_oi_id_def(struct s_smc *smc)
499{
500 int sel_id ;
501 int i ;
502 int act_entries ;
503
504 i = 0 ;
505 sel_id = -1 ;
506 act_entries = FALSE ;
507 smc->hw.oem_id = 0 ;
508 smc->hw.oem_min_status = OI_STAT_ACTIVE ;
509
510
511 while (oem_ids[i].oi_status) {
512 switch (oem_ids[i].oi_status) {
513 case OI_STAT_ACTIVE:
514 act_entries = TRUE ;
515 if (sel_id == -1)
516 sel_id = i ;
517 case OI_STAT_VALID:
518 case OI_STAT_PRESENT:
519 i++ ;
520 break ;
521 default:
522 return 1;
523 }
524 }
525
526 if (i == 0)
527 return 2;
528 if (!act_entries)
529 return 3;
530
531
532 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[sel_id] ;
533 return 0;
534}
535#endif
536
537void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr)
538{
539 int i ;
540
541 for (i = 0 ; i < 6 ; i++)
542 bia_addr->a[i] = bitrev8(smc->hw.fddi_phys_addr.a[i]);
543}
544
545void smt_start_watchdog(struct s_smc *smc)
546{
547 SK_UNUSED(smc) ;
548
549#ifndef DEBUG
550
551#ifdef PCI
552 if (smc->hw.wdog_used) {
553 outpw(ADDR(B2_WDOG_CRTL),TIM_START) ;
554 }
555#endif
556
557#endif
558}
559
560static void smt_stop_watchdog(struct s_smc *smc)
561{
562 SK_UNUSED(smc) ;
563#ifndef DEBUG
564
565#ifdef PCI
566 if (smc->hw.wdog_used) {
567 outpw(ADDR(B2_WDOG_CRTL),TIM_STOP) ;
568 }
569#endif
570
571#endif
572}
573
574#ifdef PCI
575
576void mac_do_pci_fix(struct s_smc *smc)
577{
578 SK_UNUSED(smc) ;
579}
580#endif
581
582