Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.18-rc6 1315 lines 30 kB view raw
1/****************************************************************************** 2 * 3 * (C)Copyright 1998,1999 SysKonnect, 4 * a business unit of Schneider & Koch & Co. Datensysteme GmbH. 5 * 6 * See the file "skfddi.c" for further information. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * The information in this file is provided "AS IS" without warranty. 14 * 15 ******************************************************************************/ 16 17/* 18 * FBI board dependent Driver for SMT and LLC 19 */ 20 21#include "h/types.h" 22#include "h/fddi.h" 23#include "h/smc.h" 24#include "h/supern_2.h" 25#include "h/skfbiinc.h" 26 27#ifndef lint 28static const char ID_sccs[] = "@(#)drvfbi.c 1.63 99/02/11 (C) SK " ; 29#endif 30 31/* 32 * PCM active state 33 */ 34#define PC8_ACTIVE 8 35 36#define LED_Y_ON 0x11 /* Used for ring up/down indication */ 37#define LED_Y_OFF 0x10 38 39 40#define MS2BCLK(x) ((x)*12500L) 41 42/* 43 * valid configuration values are: 44 */ 45#ifdef ISA 46const int opt_ints[] = {8, 3, 4, 5, 9, 10, 11, 12, 15} ; 47const int opt_iops[] = {8, 48 0x100, 0x120, 0x180, 0x1a0, 0x220, 0x240, 0x320, 0x340}; 49const int opt_dmas[] = {4, 3, 5, 6, 7} ; 50const int opt_eproms[] = {15, 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 51 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc} ; 52#endif 53#ifdef EISA 54const int opt_ints[] = {5, 9, 10, 11} ; 55const int opt_dmas[] = {0, 5, 6, 7} ; 56const int opt_eproms[] = {0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 57 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc} ; 58#endif 59 60#ifdef MCA 61int opt_ints[] = {3, 11, 10, 9} ; /* FM1 */ 62int opt_eproms[] = {0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4, 0xd8, 0xdc} ; 63#endif /* MCA */ 64 65/* 66 * xPOS_ID:xxxx 67 * | \ / 68 * | \/ 69 * | --------------------- the patched POS_ID of the Adapter 70 * | xxxx = (Vendor ID low byte, 71 * | Vendor ID high byte, 72 * | Device ID low byte, 73 * | Device ID high byte) 74 * +------------------------------ the patched oem_id must be 75 * 'S' for SK or 'I' for IBM 76 * this is a short id for the driver. 77 */ 78#ifndef MULT_OEM 79#ifndef OEM_CONCEPT 80#ifndef MCA 81const u_char oem_id[] = "xPOS_ID:xxxx" ; 82#else 83const u_char oem_id[] = "xPOSID1:xxxx" ; /* FM1 card id. */ 84#endif 85#else /* OEM_CONCEPT */ 86#ifndef MCA 87const u_char oem_id[] = OEM_ID ; 88#else 89const u_char oem_id[] = OEM_ID1 ; /* FM1 card id. */ 90#endif /* MCA */ 91#endif /* OEM_CONCEPT */ 92#define ID_BYTE0 8 93#define OEMID(smc,i) oem_id[ID_BYTE0 + i] 94#else /* MULT_OEM */ 95const struct s_oem_ids oem_ids[] = { 96#include "oemids.h" 97{0} 98}; 99#define OEMID(smc,i) smc->hw.oem_id->oi_id[i] 100#endif /* MULT_OEM */ 101 102/* Prototypes of external functions */ 103#ifdef AIX 104extern int AIX_vpdReadByte() ; 105#endif 106 107 108/* Prototype of a local function. */ 109static void smt_stop_watchdog(struct s_smc *smc); 110 111#ifdef MCA 112static int read_card_id() ; 113static void DisableSlotAccess() ; 114static void EnableSlotAccess() ; 115#ifdef AIX 116extern int attach_POS_addr() ; 117extern int detach_POS_addr() ; 118extern u_char read_POS() ; 119extern void write_POS() ; 120extern int AIX_vpdReadByte() ; 121#else 122#define read_POS(smc,a1,a2) ((u_char) inp(a1)) 123#define write_POS(smc,a1,a2,a3) outp((a1),(a3)) 124#endif 125#endif /* MCA */ 126 127 128/* 129 * FDDI card reset 130 */ 131static void card_start(struct s_smc *smc) 132{ 133 int i ; 134#ifdef PCI 135 u_char rev_id ; 136 u_short word; 137#endif 138 139 smt_stop_watchdog(smc) ; 140 141#ifdef ISA 142 outpw(CSR_A,0) ; /* reset for all chips */ 143 for (i = 10 ; i ; i--) /* delay for PLC's */ 144 (void)inpw(ISR_A) ; 145 OUT_82c54_TIMER(3,COUNT(2) | RW_OP(3) | TMODE(2)) ; 146 /* counter 2, mode 2 */ 147 OUT_82c54_TIMER(2,97) ; /* LSB */ 148 OUT_82c54_TIMER(2,0) ; /* MSB ( 15.6 us ) */ 149 outpw(CSR_A,CS_CRESET) ; 150#endif 151#ifdef EISA 152 outpw(CSR_A,0) ; /* reset for all chips */ 153 for (i = 10 ; i ; i--) /* delay for PLC's */ 154 (void)inpw(ISR_A) ; 155 outpw(CSR_A,CS_CRESET) ; 156 smc->hw.led = (2<<6) ; 157 outpw(CSR_A,CS_CRESET | smc->hw.led) ; 158#endif 159#ifdef MCA 160 outp(ADDR(CARD_DIS),0) ; /* reset for all chips */ 161 for (i = 10 ; i ; i--) /* delay for PLC's */ 162 (void)inpw(ISR_A) ; 163 outp(ADDR(CARD_EN),0) ; 164 /* first I/O after reset must not be a access to FORMAC or PLC */ 165 166 /* 167 * bus timeout (MCA) 168 */ 169 OUT_82c54_TIMER(3,COUNT(2) | RW_OP(3) | TMODE(3)) ; 170 /* counter 2, mode 3 */ 171 OUT_82c54_TIMER(2,(2*24)) ; /* 3.9 us * 2 square wave */ 172 OUT_82c54_TIMER(2,0) ; /* MSB */ 173 174 /* POS 102 indicated an activ Check Line or Buss Error monitoring */ 175 if (inpw(CSA_A) & (POS_EN_CHKINT | POS_EN_BUS_ERR)) { 176 outp(ADDR(IRQ_CHCK_EN),0) ; 177 } 178 179 if (!((i = inpw(CSR_A)) & CS_SAS)) { 180 if (!(i & CS_BYSTAT)) { 181 outp(ADDR(BYPASS(STAT_INS)),0) ;/* insert station */ 182 } 183 } 184 outpw(LEDR_A,LED_1) ; /* yellow */ 185#endif /* MCA */ 186#ifdef PCI 187 /* 188 * make sure no transfer activity is pending 189 */ 190 outpw(FM_A(FM_MDREG1),FM_MINIT) ; 191 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ; 192 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ; 193 /* 194 * now reset everything 195 */ 196 outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */ 197 i = (int) inp(ADDR(B0_CTRL)) ; /* do dummy read */ 198 SK_UNUSED(i) ; /* Make LINT happy. */ 199 outp(ADDR(B0_CTRL), CTRL_RST_CLR) ; 200 201 /* 202 * Reset all bits in the PCI STATUS register 203 */ 204 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ; /* enable for writes */ 205 word = inpw(PCI_C(PCI_STATUS)) ; 206 outpw(PCI_C(PCI_STATUS), word | PCI_ERRBITS) ; 207 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ; /* disable writes */ 208 209 /* 210 * Release the reset of all the State machines 211 * Release Master_Reset 212 * Release HPI_SM_Reset 213 */ 214 outp(ADDR(B0_CTRL), CTRL_MRST_CLR|CTRL_HPI_CLR) ; 215 216 /* 217 * determine the adapter type 218 * Note: Do it here, because some drivers may call card_start() once 219 * at very first before any other initialization functions is 220 * executed. 221 */ 222 rev_id = inp(PCI_C(PCI_REV_ID)) ; 223 if ((rev_id & 0xf0) == SK_ML_ID_1 || (rev_id & 0xf0) == SK_ML_ID_2) { 224 smc->hw.hw_is_64bit = TRUE ; 225 } else { 226 smc->hw.hw_is_64bit = FALSE ; 227 } 228 229 /* 230 * Watermark initialization 231 */ 232 if (!smc->hw.hw_is_64bit) { 233 outpd(ADDR(B4_R1_F), RX_WATERMARK) ; 234 outpd(ADDR(B5_XA_F), TX_WATERMARK) ; 235 outpd(ADDR(B5_XS_F), TX_WATERMARK) ; 236 } 237 238 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* clear the reset chips */ 239 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_ON|LED_GB_OFF) ; /* ye LED on */ 240 241 /* init the timer value for the watch dog 2,5 minutes */ 242 outpd(ADDR(B2_WDOG_INI),0x6FC23AC0) ; 243 244 /* initialize the ISR mask */ 245 smc->hw.is_imask = ISR_MASK ; 246 smc->hw.hw_state = STOPPED ; 247#endif 248 GET_PAGE(0) ; /* necessary for BOOT */ 249} 250 251void card_stop(struct s_smc *smc) 252{ 253 smt_stop_watchdog(smc) ; 254 smc->hw.mac_ring_is_up = 0 ; /* ring down */ 255#ifdef ISA 256 outpw(CSR_A,0) ; /* reset for all chips */ 257#endif 258#ifdef EISA 259 outpw(CSR_A,0) ; /* reset for all chips */ 260#endif 261#ifdef MCA 262 outp(ADDR(CARD_DIS),0) ; /* reset for all chips */ 263#endif 264#ifdef PCI 265 /* 266 * make sure no transfer activity is pending 267 */ 268 outpw(FM_A(FM_MDREG1),FM_MINIT) ; 269 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ; 270 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ; 271 /* 272 * now reset everything 273 */ 274 outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */ 275 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* reset for all chips */ 276 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_OFF|LED_GB_OFF) ; /* all LEDs off */ 277 smc->hw.hw_state = STOPPED ; 278#endif 279} 280/*--------------------------- ISR handling ----------------------------------*/ 281 282void mac1_irq(struct s_smc *smc, u_short stu, u_short stl) 283{ 284 int restart_tx = 0 ; 285again: 286#ifndef PCI 287#ifndef ISA 288/* 289 * FORMAC+ bug modified the queue pointer if many read/write accesses happens!? 290 */ 291 if (stl & (FM_SPCEPDS | /* parit/coding err. syn.q.*/ 292 FM_SPCEPDA0 | /* parit/coding err. a.q.0 */ 293 FM_SPCEPDA1 | /* parit/coding err. a.q.1 */ 294 FM_SPCEPDA2)) { /* parit/coding err. a.q.2 */ 295 SMT_PANIC(smc,SMT_E0132, SMT_E0132_MSG) ; 296 } 297 if (stl & (FM_STBURS | /* tx buffer underrun syn.q.*/ 298 FM_STBURA0 | /* tx buffer underrun a.q.0 */ 299 FM_STBURA1 | /* tx buffer underrun a.q.1 */ 300 FM_STBURA2)) { /* tx buffer underrun a.q.2 */ 301 SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ; 302 } 303#endif 304 if ( (stu & (FM_SXMTABT | /* transmit abort */ 305#ifdef SYNC 306 FM_STXABRS | /* syn. tx abort */ 307#endif /* SYNC */ 308 FM_STXABRA0)) || /* asyn. tx abort */ 309 (stl & (FM_SQLCKS | /* lock for syn. q. */ 310 FM_SQLCKA0)) ) { /* lock for asyn. q. */ 311 formac_tx_restart(smc) ; /* init tx */ 312 restart_tx = 1 ; 313 stu = inpw(FM_A(FM_ST1U)) ; 314 stl = inpw(FM_A(FM_ST1L)) ; 315 stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ; 316 if (stu || stl) 317 goto again ; 318 } 319 320#ifndef SYNC 321 if (stu & (FM_STECFRMA0 | /* end of chain asyn tx */ 322 FM_STEFRMA0)) { /* end of frame asyn tx */ 323 /* free tx_queue */ 324 smc->hw.n_a_send = 0 ; 325 if (++smc->hw.fp.tx_free < smc->hw.fp.tx_max) { 326 start_next_send(smc); 327 } 328 restart_tx = 1 ; 329 } 330#else /* SYNC */ 331 if (stu & (FM_STEFRMA0 | /* end of asyn tx */ 332 FM_STEFRMS)) { /* end of sync tx */ 333 restart_tx = 1 ; 334 } 335#endif /* SYNC */ 336 if (restart_tx) 337 llc_restart_tx(smc) ; 338} 339#else /* PCI */ 340 341 /* 342 * parity error: note encoding error is not possible in tag mode 343 */ 344 if (stl & (FM_SPCEPDS | /* parity err. syn.q.*/ 345 FM_SPCEPDA0 | /* parity err. a.q.0 */ 346 FM_SPCEPDA1)) { /* parity err. a.q.1 */ 347 SMT_PANIC(smc,SMT_E0134, SMT_E0134_MSG) ; 348 } 349 /* 350 * buffer underrun: can only occur if a tx threshold is specified 351 */ 352 if (stl & (FM_STBURS | /* tx buffer underrun syn.q.*/ 353 FM_STBURA0 | /* tx buffer underrun a.q.0 */ 354 FM_STBURA1)) { /* tx buffer underrun a.q.2 */ 355 SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ; 356 } 357 358 if ( (stu & (FM_SXMTABT | /* transmit abort */ 359 FM_STXABRS | /* syn. tx abort */ 360 FM_STXABRA0)) || /* asyn. tx abort */ 361 (stl & (FM_SQLCKS | /* lock for syn. q. */ 362 FM_SQLCKA0)) ) { /* lock for asyn. q. */ 363 formac_tx_restart(smc) ; /* init tx */ 364 restart_tx = 1 ; 365 stu = inpw(FM_A(FM_ST1U)) ; 366 stl = inpw(FM_A(FM_ST1L)) ; 367 stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ; 368 if (stu || stl) 369 goto again ; 370 } 371 372 if (stu & (FM_STEFRMA0 | /* end of asyn tx */ 373 FM_STEFRMS)) { /* end of sync tx */ 374 restart_tx = 1 ; 375 } 376 377 if (restart_tx) 378 llc_restart_tx(smc) ; 379} 380#endif /* PCI */ 381/* 382 * interrupt source= plc1 383 * this function is called in nwfbisr.asm 384 */ 385void plc1_irq(struct s_smc *smc) 386{ 387 u_short st = inpw(PLC(PB,PL_INTR_EVENT)) ; 388 389#if (defined(ISA) || defined(EISA)) 390 /* reset PLC Int. bits */ 391 outpw(PLC1_I,inpw(PLC1_I)) ; 392#endif 393 plc_irq(smc,PB,st) ; 394} 395 396/* 397 * interrupt source= plc2 398 * this function is called in nwfbisr.asm 399 */ 400void plc2_irq(struct s_smc *smc) 401{ 402 u_short st = inpw(PLC(PA,PL_INTR_EVENT)) ; 403 404#if (defined(ISA) || defined(EISA)) 405 /* reset PLC Int. bits */ 406 outpw(PLC2_I,inpw(PLC2_I)) ; 407#endif 408 plc_irq(smc,PA,st) ; 409} 410 411 412/* 413 * interrupt source= timer 414 */ 415void timer_irq(struct s_smc *smc) 416{ 417 hwt_restart(smc); 418 smc->hw.t_stop = smc->hw.t_start; 419 smt_timer_done(smc) ; 420} 421 422/* 423 * return S-port (PA or PB) 424 */ 425int pcm_get_s_port(struct s_smc *smc) 426{ 427 SK_UNUSED(smc) ; 428 return(PS) ; 429} 430 431/* 432 * Station Label = "FDDI-XYZ" where 433 * 434 * X = connector type 435 * Y = PMD type 436 * Z = port type 437 */ 438#define STATION_LABEL_CONNECTOR_OFFSET 5 439#define STATION_LABEL_PMD_OFFSET 6 440#define STATION_LABEL_PORT_OFFSET 7 441 442void read_address(struct s_smc *smc, u_char *mac_addr) 443{ 444 char ConnectorType ; 445 char PmdType ; 446 int i ; 447 448 extern const u_char canonical[256] ; 449 450#if (defined(ISA) || defined(MCA)) 451 for (i = 0; i < 4 ;i++) { /* read mac address from board */ 452 smc->hw.fddi_phys_addr.a[i] = 453 canonical[(inpw(PR_A(i+SA_MAC))&0xff)] ; 454 } 455 for (i = 4; i < 6; i++) { 456 smc->hw.fddi_phys_addr.a[i] = 457 canonical[(inpw(PR_A(i+SA_MAC+PRA_OFF))&0xff)] ; 458 } 459#endif 460#ifdef EISA 461 /* 462 * Note: We get trouble on an Alpha machine if we make a inpw() 463 * instead of inp() 464 */ 465 for (i = 0; i < 4 ;i++) { /* read mac address from board */ 466 smc->hw.fddi_phys_addr.a[i] = 467 canonical[inp(PR_A(i+SA_MAC))] ; 468 } 469 for (i = 4; i < 6; i++) { 470 smc->hw.fddi_phys_addr.a[i] = 471 canonical[inp(PR_A(i+SA_MAC+PRA_OFF))] ; 472 } 473#endif 474#ifdef PCI 475 for (i = 0; i < 6; i++) { /* read mac address from board */ 476 smc->hw.fddi_phys_addr.a[i] = 477 canonical[inp(ADDR(B2_MAC_0+i))] ; 478 } 479#endif 480#ifndef PCI 481 ConnectorType = inpw(PR_A(SA_PMD_TYPE)) & 0xff ; 482 PmdType = inpw(PR_A(SA_PMD_TYPE+1)) & 0xff ; 483#else 484 ConnectorType = inp(ADDR(B2_CONN_TYP)) ; 485 PmdType = inp(ADDR(B2_PMD_TYP)) ; 486#endif 487 488 smc->y[PA].pmd_type[PMD_SK_CONN] = 489 smc->y[PB].pmd_type[PMD_SK_CONN] = ConnectorType ; 490 smc->y[PA].pmd_type[PMD_SK_PMD ] = 491 smc->y[PB].pmd_type[PMD_SK_PMD ] = PmdType ; 492 493 if (mac_addr) { 494 for (i = 0; i < 6 ;i++) { 495 smc->hw.fddi_canon_addr.a[i] = mac_addr[i] ; 496 smc->hw.fddi_home_addr.a[i] = canonical[mac_addr[i]] ; 497 } 498 return ; 499 } 500 smc->hw.fddi_home_addr = smc->hw.fddi_phys_addr ; 501 502 for (i = 0; i < 6 ;i++) { 503 smc->hw.fddi_canon_addr.a[i] = 504 canonical[smc->hw.fddi_phys_addr.a[i]] ; 505 } 506} 507 508/* 509 * FDDI card soft reset 510 */ 511void init_board(struct s_smc *smc, u_char *mac_addr) 512{ 513 card_start(smc) ; 514 read_address(smc,mac_addr) ; 515 516#ifndef PCI 517 if (inpw(CSR_A) & CS_SAS) 518#else 519 if (!(inp(ADDR(B0_DAS)) & DAS_AVAIL)) 520#endif 521 smc->s.sas = SMT_SAS ; /* Single att. station */ 522 else 523 smc->s.sas = SMT_DAS ; /* Dual att. station */ 524 525#ifndef PCI 526 if (inpw(CSR_A) & CS_BYSTAT) 527#else 528 if (!(inp(ADDR(B0_DAS)) & DAS_BYP_ST)) 529#endif 530 smc->mib.fddiSMTBypassPresent = 0 ; 531 /* without opt. bypass */ 532 else 533 smc->mib.fddiSMTBypassPresent = 1 ; 534 /* with opt. bypass */ 535} 536 537/* 538 * insert or deinsert optical bypass (called by ECM) 539 */ 540void sm_pm_bypass_req(struct s_smc *smc, int mode) 541{ 542#if (defined(ISA) || defined(EISA)) 543 int csra_v ; 544#endif 545 546 DB_ECMN(1,"ECM : sm_pm_bypass_req(%s)\n",(mode == BP_INSERT) ? 547 "BP_INSERT" : "BP_DEINSERT",0) ; 548 549 if (smc->s.sas != SMT_DAS) 550 return ; 551 552#if (defined(ISA) || defined(EISA)) 553 554 csra_v = inpw(CSR_A) & ~CS_BYPASS ; 555#ifdef EISA 556 csra_v |= smc->hw.led ; 557#endif 558 559 switch(mode) { 560 case BP_INSERT : 561 outpw(CSR_A,csra_v | CS_BYPASS) ; 562 break ; 563 case BP_DEINSERT : 564 outpw(CSR_A,csra_v) ; 565 break ; 566 } 567#endif /* ISA / EISA */ 568#ifdef MCA 569 switch(mode) { 570 case BP_INSERT : 571 outp(ADDR(BYPASS(STAT_INS)),0) ;/* insert station */ 572 break ; 573 case BP_DEINSERT : 574 outp(ADDR(BYPASS(STAT_BYP)),0) ; /* bypass station */ 575 break ; 576 } 577#endif 578#ifdef PCI 579 switch(mode) { 580 case BP_INSERT : 581 outp(ADDR(B0_DAS),DAS_BYP_INS) ; /* insert station */ 582 break ; 583 case BP_DEINSERT : 584 outp(ADDR(B0_DAS),DAS_BYP_RMV) ; /* bypass station */ 585 break ; 586 } 587#endif 588} 589 590/* 591 * check if bypass connected 592 */ 593int sm_pm_bypass_present(struct s_smc *smc) 594{ 595#ifndef PCI 596 return( (inpw(CSR_A) & CS_BYSTAT) ? FALSE : TRUE ) ; 597#else 598 return( (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE: FALSE) ; 599#endif 600} 601 602void plc_clear_irq(struct s_smc *smc, int p) 603{ 604 SK_UNUSED(p) ; 605 606#if (defined(ISA) || defined(EISA)) 607 switch (p) { 608 case PA : 609 /* reset PLC Int. bits */ 610 outpw(PLC2_I,inpw(PLC2_I)) ; 611 break ; 612 case PB : 613 /* reset PLC Int. bits */ 614 outpw(PLC1_I,inpw(PLC1_I)) ; 615 break ; 616 } 617#else 618 SK_UNUSED(smc) ; 619#endif 620} 621 622 623/* 624 * led_indication called by rmt_indication() and 625 * pcm_state_change() 626 * 627 * Input: 628 * smc: SMT context 629 * led_event: 630 * 0 Only switch green LEDs according to their respective PCM state 631 * LED_Y_OFF just switch yellow LED off 632 * LED_Y_ON just switch yello LED on 633 */ 634static void led_indication(struct s_smc *smc, int led_event) 635{ 636 /* use smc->hw.mac_ring_is_up == TRUE 637 * as indication for Ring Operational 638 */ 639 u_short led_state ; 640 struct s_phy *phy ; 641 struct fddi_mib_p *mib_a ; 642 struct fddi_mib_p *mib_b ; 643 644 phy = &smc->y[PA] ; 645 mib_a = phy->mib ; 646 phy = &smc->y[PB] ; 647 mib_b = phy->mib ; 648 649#ifdef EISA 650 /* Ring up = yellow led OFF*/ 651 if (led_event == LED_Y_ON) { 652 smc->hw.led |= CS_LED_1 ; 653 } 654 else if (led_event == LED_Y_OFF) { 655 smc->hw.led &= ~CS_LED_1 ; 656 } 657 else { 658 /* Link at Port A or B = green led ON */ 659 if (mib_a->fddiPORTPCMState == PC8_ACTIVE || 660 mib_b->fddiPORTPCMState == PC8_ACTIVE) { 661 smc->hw.led |= CS_LED_0 ; 662 } 663 else { 664 smc->hw.led &= ~CS_LED_0 ; 665 } 666 } 667#endif 668#ifdef MCA 669 led_state = inpw(LEDR_A) ; 670 671 /* Ring up = yellow led OFF*/ 672 if (led_event == LED_Y_ON) { 673 led_state |= LED_1 ; 674 } 675 else if (led_event == LED_Y_OFF) { 676 led_state &= ~LED_1 ; 677 } 678 else { 679 led_state &= ~(LED_2|LED_0) ; 680 681 /* Link at Port A = green led A ON */ 682 if (mib_a->fddiPORTPCMState == PC8_ACTIVE) { 683 led_state |= LED_2 ; 684 } 685 686 /* Link at Port B/S = green led B ON */ 687 if (mib_b->fddiPORTPCMState == PC8_ACTIVE) { 688 led_state |= LED_0 ; 689 } 690 } 691 692 outpw(LEDR_A, led_state) ; 693#endif /* MCA */ 694#ifdef PCI 695 led_state = 0 ; 696 697 /* Ring up = yellow led OFF*/ 698 if (led_event == LED_Y_ON) { 699 led_state |= LED_MY_ON ; 700 } 701 else if (led_event == LED_Y_OFF) { 702 led_state |= LED_MY_OFF ; 703 } 704 else { /* PCM state changed */ 705 /* Link at Port A/S = green led A ON */ 706 if (mib_a->fddiPORTPCMState == PC8_ACTIVE) { 707 led_state |= LED_GA_ON ; 708 } 709 else { 710 led_state |= LED_GA_OFF ; 711 } 712 713 /* Link at Port B = green led B ON */ 714 if (mib_b->fddiPORTPCMState == PC8_ACTIVE) { 715 led_state |= LED_GB_ON ; 716 } 717 else { 718 led_state |= LED_GB_OFF ; 719 } 720 } 721 722 outp(ADDR(B0_LED), led_state) ; 723#endif /* PCI */ 724 725} 726 727 728void pcm_state_change(struct s_smc *smc, int plc, int p_state) 729{ 730 /* 731 * the current implementation of pcm_state_change() in the driver 732 * parts must be renamed to drv_pcm_state_change() which will be called 733 * now after led_indication. 734 */ 735 DRV_PCM_STATE_CHANGE(smc,plc,p_state) ; 736 737 led_indication(smc,0) ; 738} 739 740 741void rmt_indication(struct s_smc *smc, int i) 742{ 743 /* Call a driver special function if defined */ 744 DRV_RMT_INDICATION(smc,i) ; 745 746 led_indication(smc, i ? LED_Y_OFF : LED_Y_ON) ; 747} 748 749 750/* 751 * llc_recover_tx called by init_tx (fplus.c) 752 */ 753void llc_recover_tx(struct s_smc *smc) 754{ 755#ifdef LOAD_GEN 756 extern int load_gen_flag ; 757 758 load_gen_flag = 0 ; 759#endif 760#ifndef SYNC 761 smc->hw.n_a_send= 0 ; 762#else 763 SK_UNUSED(smc) ; 764#endif 765} 766 767#ifdef MULT_OEM 768static int is_equal_num(char comp1[], char comp2[], int num) 769{ 770 int i ; 771 772 for (i = 0 ; i < num ; i++) { 773 if (comp1[i] != comp2[i]) 774 return (0) ; 775 } 776 return (1) ; 777} /* is_equal_num */ 778 779 780/* 781 * set the OEM ID defaults, and test the contents of the OEM data base 782 * The default OEM is the first ACTIVE entry in the OEM data base 783 * 784 * returns: 0 success 785 * 1 error in data base 786 * 2 data base empty 787 * 3 no active entry 788 */ 789int set_oi_id_def(struct s_smc *smc) 790{ 791 int sel_id ; 792 int i ; 793 int act_entries ; 794 795 i = 0 ; 796 sel_id = -1 ; 797 act_entries = FALSE ; 798 smc->hw.oem_id = 0 ; 799 smc->hw.oem_min_status = OI_STAT_ACTIVE ; 800 801 /* check OEM data base */ 802 while (oem_ids[i].oi_status) { 803 switch (oem_ids[i].oi_status) { 804 case OI_STAT_ACTIVE: 805 act_entries = TRUE ; /* we have active IDs */ 806 if (sel_id == -1) 807 sel_id = i ; /* save the first active ID */ 808 case OI_STAT_VALID: 809 case OI_STAT_PRESENT: 810 i++ ; 811 break ; /* entry ok */ 812 default: 813 return (1) ; /* invalid oi_status */ 814 } 815 } 816 817 if (i == 0) 818 return (2) ; 819 if (!act_entries) 820 return (3) ; 821 822 /* ok, we have a valid OEM data base with an active entry */ 823 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[sel_id] ; 824 return (0) ; 825} 826#endif /* MULT_OEM */ 827 828 829#ifdef MCA 830/************************ 831 * 832 * BEGIN_MANUAL_ENTRY() 833 * 834 * exist_board 835 * 836 * Check if an MCA board is present in the specified slot. 837 * 838 * int exist_board( 839 * struct s_smc *smc, 840 * int slot) ; 841 * In 842 * smc - A pointer to the SMT Context struct. 843 * 844 * slot - The number of the slot to inspect. 845 * Out 846 * 0 = No adapter present. 847 * 1 = Found FM1 adapter. 848 * 849 * Pseudo 850 * Read MCA ID 851 * for all valid OEM_IDs 852 * compare with ID read 853 * if equal, return 1 854 * return(0 855 * 856 * Note 857 * The smc pointer must be valid now. 858 * 859 * END_MANUAL_ENTRY() 860 * 861 ************************/ 862#define LONG_CARD_ID(lo, hi) ((((hi) & 0xff) << 8) | ((lo) & 0xff)) 863int exist_board(struct s_smc *smc, int slot) 864{ 865#ifdef MULT_OEM 866 SK_LOC_DECL(u_char,id[2]) ; 867 int idi ; 868#endif /* MULT_OEM */ 869 870 /* No longer valid. */ 871 if (smc == NULL) 872 return(0) ; 873 874#ifndef MULT_OEM 875 if (read_card_id(smc, slot) 876 == LONG_CARD_ID(OEMID(smc,0), OEMID(smc,1))) 877 return (1) ; /* Found FM adapter. */ 878 879#else /* MULT_OEM */ 880 idi = read_card_id(smc, slot) ; 881 id[0] = idi & 0xff ; 882 id[1] = idi >> 8 ; 883 884 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ; 885 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) { 886 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status) 887 continue ; 888 889 if (is_equal_num(&id[0],&OEMID(smc,0),2)) 890 return (1) ; 891 } 892#endif /* MULT_OEM */ 893 return (0) ; /* No adapter found. */ 894} 895 896/************************ 897 * 898 * read_card_id 899 * 900 * Read the MCA card id from the specified slot. 901 * In 902 * smc - A pointer to the SMT Context struct. 903 * CAVEAT: This pointer may be NULL and *must not* be used within this 904 * function. It's only purpose is for drivers that need some information 905 * for the inp() and outp() macros. 906 * 907 * slot - The number of the slot for which the card id is returned. 908 * Out 909 * Returns the card id read from the specified slot. If an illegal slot 910 * number is specified, the function returns zero. 911 * 912 ************************/ 913static int read_card_id(struct s_smc *smc, int slot) 914/* struct s_smc *smc ; Do not use. */ 915{ 916 int card_id ; 917 918 SK_UNUSED(smc) ; /* Make LINT happy. */ 919 if ((slot < 1) || (slot > 15)) /* max 16 slots, 0 = motherboard */ 920 return (0) ; /* Illegal slot number specified. */ 921 922 EnableSlotAccess(smc, slot) ; 923 924 card_id = ((read_POS(smc,POS_ID_HIGH,slot - 1) & 0xff) << 8) | 925 (read_POS(smc,POS_ID_LOW,slot - 1) & 0xff) ; 926 927 DisableSlotAccess(smc) ; 928 929 return (card_id) ; 930} 931 932/************************ 933 * 934 * BEGIN_MANUAL_ENTRY() 935 * 936 * get_board_para 937 * 938 * Get adapter configuration information. Fill all board specific 939 * parameters within the 'smc' structure. 940 * 941 * int get_board_para( 942 * struct s_smc *smc, 943 * int slot) ; 944 * In 945 * smc - A pointer to the SMT Context struct, to which this function will 946 * write some adapter configuration data. 947 * 948 * slot - The number of the slot, in which the adapter is installed. 949 * Out 950 * 0 = No adapter present. 951 * 1 = Ok. 952 * 2 = Adapter present, but card enable bit not set. 953 * 954 * END_MANUAL_ENTRY() 955 * 956 ************************/ 957int get_board_para(struct s_smc *smc, int slot) 958{ 959 int val ; 960 int i ; 961 962 /* Check if adapter present & get type of adapter. */ 963 switch (exist_board(smc, slot)) { 964 case 0: /* Adapter not present. */ 965 return (0) ; 966 case 1: /* FM Rev. 1 */ 967 smc->hw.rev = FM1_REV ; 968 smc->hw.VFullRead = 0x0a ; 969 smc->hw.VFullWrite = 0x05 ; 970 smc->hw.DmaWriteExtraBytes = 8 ; /* 2 extra words. */ 971 break ; 972 } 973 smc->hw.slot = slot ; 974 975 EnableSlotAccess(smc, slot) ; 976 977 if (!(read_POS(smc,POS_102, slot - 1) & POS_CARD_EN)) { 978 DisableSlotAccess(smc) ; 979 return (2) ; /* Card enable bit not set. */ 980 } 981 982 val = read_POS(smc,POS_104, slot - 1) ; /* I/O, IRQ */ 983 984#ifndef MEM_MAPPED_IO /* is defined by the operating system */ 985 i = val & POS_IOSEL ; /* I/O base addr. (0x0200 .. 0xfe00) */ 986 smc->hw.iop = (i + 1) * 0x0400 - 0x200 ; 987#endif 988 i = ((val & POS_IRQSEL) >> 6) & 0x03 ; /* IRQ <0, 1> */ 989 smc->hw.irq = opt_ints[i] ; 990 991 /* FPROM base addr. */ 992 i = ((read_POS(smc,POS_103, slot - 1) & POS_MSEL) >> 4) & 0x07 ; 993 smc->hw.eprom = opt_eproms[i] ; 994 995 DisableSlotAccess(smc) ; 996 997 /* before this, the smc->hw.iop must be set !!! */ 998 smc->hw.slot_32 = inpw(CSF_A) & SLOT_32 ; 999 1000 return (1) ; 1001} 1002 1003/* Enable access to specified MCA slot. */ 1004static void EnableSlotAccess(struct s_smc *smc, int slot) 1005{ 1006 SK_UNUSED(slot) ; 1007 1008#ifndef AIX 1009 SK_UNUSED(smc) ; 1010 1011 /* System mode. */ 1012 outp(POS_SYS_SETUP, POS_SYSTEM) ; 1013 1014 /* Select slot. */ 1015 outp(POS_CHANNEL_POS, POS_CHANNEL_BIT | (slot-1)) ; 1016#else 1017 attach_POS_addr (smc) ; 1018#endif 1019} 1020 1021/* Disable access to MCA slot formerly enabled via EnableSlotAccess(). */ 1022static void DisableSlotAccess(struct s_smc *smc) 1023{ 1024#ifndef AIX 1025 SK_UNUSED(smc) ; 1026 1027 outp(POS_CHANNEL_POS, 0) ; 1028#else 1029 detach_POS_addr (smc) ; 1030#endif 1031} 1032#endif /* MCA */ 1033 1034#ifdef EISA 1035#ifndef MEM_MAPPED_IO 1036#define SADDR(slot) (((slot)<<12)&0xf000) 1037#else /* MEM_MAPPED_IO */ 1038#define SADDR(slot) (smc->hw.iop) 1039#endif /* MEM_MAPPED_IO */ 1040 1041/************************ 1042 * 1043 * BEGIN_MANUAL_ENTRY() 1044 * 1045 * exist_board 1046 * 1047 * Check if an EISA board is present in the specified slot. 1048 * 1049 * int exist_board( 1050 * struct s_smc *smc, 1051 * int slot) ; 1052 * In 1053 * smc - A pointer to the SMT Context struct. 1054 * 1055 * slot - The number of the slot to inspect. 1056 * Out 1057 * 0 = No adapter present. 1058 * 1 = Found adapter. 1059 * 1060 * Pseudo 1061 * Read EISA ID 1062 * for all valid OEM_IDs 1063 * compare with ID read 1064 * if equal, return 1 1065 * return(0 1066 * 1067 * Note 1068 * The smc pointer must be valid now. 1069 * 1070 ************************/ 1071int exist_board(struct s_smc *smc, int slot) 1072{ 1073 int i ; 1074#ifdef MULT_OEM 1075 SK_LOC_DECL(u_char,id[4]) ; 1076#endif /* MULT_OEM */ 1077 1078 /* No longer valid. */ 1079 if (smc == NULL) 1080 return(0); 1081 1082 SK_UNUSED(slot) ; 1083 1084#ifndef MULT_OEM 1085 for (i = 0 ; i < 4 ; i++) { 1086 if (inp(SADDR(slot)+PRA(i)) != OEMID(smc,i)) 1087 return(0) ; 1088 } 1089 return(1) ; 1090#else /* MULT_OEM */ 1091 for (i = 0 ; i < 4 ; i++) 1092 id[i] = inp(SADDR(slot)+PRA(i)) ; 1093 1094 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ; 1095 1096 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) { 1097 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status) 1098 continue ; 1099 1100 if (is_equal_num(&id[0],&OEMID(smc,0),4)) 1101 return (1) ; 1102 } 1103 return (0) ; /* No adapter found. */ 1104#endif /* MULT_OEM */ 1105} 1106 1107 1108int get_board_para(struct s_smc *smc, int slot) 1109{ 1110 int i ; 1111 1112 if (!exist_board(smc,slot)) 1113 return(0) ; 1114 1115 smc->hw.slot = slot ; 1116#ifndef MEM_MAPPED_IO /* if defined by the operating system */ 1117 smc->hw.iop = SADDR(slot) ; 1118#endif 1119 1120 if (!(inp(C0_A(0))&CFG_CARD_EN)) { 1121 return(2) ; /* CFG_CARD_EN bit not set! */ 1122 } 1123 1124 smc->hw.irq = opt_ints[(inp(C1_A(0)) & CFG_IRQ_SEL)] ; 1125 smc->hw.dma = opt_dmas[((inp(C1_A(0)) & CFG_DRQ_SEL)>>3)] ; 1126 1127 if ((i = inp(C2_A(0)) & CFG_EPROM_SEL) != 0x0f) 1128 smc->hw.eprom = opt_eproms[i] ; 1129 else 1130 smc->hw.eprom = 0 ; 1131 1132 smc->hw.DmaWriteExtraBytes = 8 ; 1133 1134 return(1) ; 1135} 1136#endif /* EISA */ 1137 1138#ifdef ISA 1139#ifndef MULT_OEM 1140const u_char sklogo[6] = SKLOGO_STR ; 1141#define SIZE_SKLOGO(smc) sizeof(sklogo) 1142#define SKLOGO(smc,i) sklogo[i] 1143#else /* MULT_OEM */ 1144#define SIZE_SKLOGO(smc) smc->hw.oem_id->oi_logo_len 1145#define SKLOGO(smc,i) smc->hw.oem_id->oi_logo[i] 1146#endif /* MULT_OEM */ 1147 1148 1149int exist_board(struct s_smc *smc, HW_PTR port) 1150{ 1151 int i ; 1152#ifdef MULT_OEM 1153 int bytes_read ; 1154 u_char board_logo[15] ; 1155 SK_LOC_DECL(u_char,id[4]) ; 1156#endif /* MULT_OEM */ 1157 1158 /* No longer valid. */ 1159 if (smc == NULL) 1160 return(0); 1161 1162 SK_UNUSED(smc) ; 1163#ifndef MULT_OEM 1164 for (i = SADDRL ; i < (signed) (SADDRL+SIZE_SKLOGO(smc)) ; i++) { 1165 if ((u_char)inpw((PRA(i)+port)) != SKLOGO(smc,i-SADDRL)) { 1166 return(0) ; 1167 } 1168 } 1169 1170 /* check MAC address (S&K or other) */ 1171 for (i = 0 ; i < 3 ; i++) { 1172 if ((u_char)inpw((PRA(i)+port)) != OEMID(smc,i)) 1173 return(0) ; 1174 } 1175 return(1) ; 1176#else /* MULT_OEM */ 1177 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ; 1178 board_logo[0] = (u_char)inpw((PRA(SADDRL)+port)) ; 1179 bytes_read = 1 ; 1180 1181 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) { 1182 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status) 1183 continue ; 1184 1185 /* Test all read bytes with current OEM_entry */ 1186 /* for (i=0; (i<bytes_read) && (i < SIZE_SKLOGO(smc)); i++) { */ 1187 for (i = 0; i < bytes_read; i++) { 1188 if (board_logo[i] != SKLOGO(smc,i)) 1189 break ; 1190 } 1191 1192 /* If mismatch, switch to next OEM entry */ 1193 if ((board_logo[i] != SKLOGO(smc,i)) && (i < bytes_read)) 1194 continue ; 1195 1196 --i ; 1197 while (bytes_read < SIZE_SKLOGO(smc)) { 1198 // inpw next byte SK_Logo 1199 i++ ; 1200 board_logo[i] = (u_char)inpw((PRA(SADDRL+i)+port)) ; 1201 bytes_read++ ; 1202 if (board_logo[i] != SKLOGO(smc,i)) 1203 break ; 1204 } 1205 1206 for (i = 0 ; i < 3 ; i++) 1207 id[i] = (u_char)inpw((PRA(i)+port)) ; 1208 1209 if ((board_logo[i] == SKLOGO(smc,i)) 1210 && (bytes_read == SIZE_SKLOGO(smc))) { 1211 1212 if (is_equal_num(&id[0],&OEMID(smc,0),3)) 1213 return(1); 1214 } 1215 } /* for */ 1216 return(0) ; 1217#endif /* MULT_OEM */ 1218} 1219 1220int get_board_para(struct s_smc *smc, int slot) 1221{ 1222 SK_UNUSED(smc) ; 1223 SK_UNUSED(slot) ; 1224 return(0) ; /* for ISA not supported */ 1225} 1226#endif /* ISA */ 1227 1228#ifdef PCI 1229#ifdef USE_BIOS_FUN 1230int exist_board(struct s_smc *smc, int slot) 1231{ 1232 u_short dev_id ; 1233 u_short ven_id ; 1234 int found ; 1235 int i ; 1236 1237 found = FALSE ; /* make sure we returned with adatper not found*/ 1238 /* if an empty oemids.h was included */ 1239 1240#ifdef MULT_OEM 1241 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ; 1242 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) { 1243 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status) 1244 continue ; 1245#endif 1246 ven_id = OEMID(smc,0) + (OEMID(smc,1) << 8) ; 1247 dev_id = OEMID(smc,2) + (OEMID(smc,3) << 8) ; 1248 for (i = 0; i < slot; i++) { 1249 if (pci_find_device(i,&smc->hw.pci_handle, 1250 dev_id,ven_id) != 0) { 1251 1252 found = FALSE ; 1253 } else { 1254 found = TRUE ; 1255 } 1256 } 1257 if (found) { 1258 return(1) ; /* adapter was found */ 1259 } 1260#ifdef MULT_OEM 1261 } 1262#endif 1263 return(0) ; /* adapter was not found */ 1264} 1265#endif /* PCI */ 1266#endif /* USE_BIOS_FUNC */ 1267 1268void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr) 1269{ 1270 int i ; 1271 1272 extern const u_char canonical[256] ; 1273 1274 for (i = 0 ; i < 6 ; i++) { 1275 bia_addr->a[i] = canonical[smc->hw.fddi_phys_addr.a[i]] ; 1276 } 1277} 1278 1279void smt_start_watchdog(struct s_smc *smc) 1280{ 1281 SK_UNUSED(smc) ; /* Make LINT happy. */ 1282 1283#ifndef DEBUG 1284 1285#ifdef PCI 1286 if (smc->hw.wdog_used) { 1287 outpw(ADDR(B2_WDOG_CRTL),TIM_START) ; /* Start timer. */ 1288 } 1289#endif 1290 1291#endif /* DEBUG */ 1292} 1293 1294static void smt_stop_watchdog(struct s_smc *smc) 1295{ 1296 SK_UNUSED(smc) ; /* Make LINT happy. */ 1297#ifndef DEBUG 1298 1299#ifdef PCI 1300 if (smc->hw.wdog_used) { 1301 outpw(ADDR(B2_WDOG_CRTL),TIM_STOP) ; /* Stop timer. */ 1302 } 1303#endif 1304 1305#endif /* DEBUG */ 1306} 1307 1308#ifdef PCI 1309 1310void mac_do_pci_fix(struct s_smc *smc) 1311{ 1312 SK_UNUSED(smc) ; 1313} 1314#endif /* PCI */ 1315