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 */ 103extern void hwt_restart() ; 104#ifdef AIX 105extern int AIX_vpdReadByte() ; 106#endif 107 108 109/* Prototypes of local functions. */ 110void smt_stop_watchdog() ; 111 112#ifdef MCA 113static int read_card_id() ; 114static void DisableSlotAccess() ; 115static void EnableSlotAccess() ; 116#ifdef AIX 117extern int attach_POS_addr() ; 118extern int detach_POS_addr() ; 119extern u_char read_POS() ; 120extern void write_POS() ; 121extern int AIX_vpdReadByte() ; 122#else 123#define read_POS(smc,a1,a2) ((u_char) inp(a1)) 124#define write_POS(smc,a1,a2,a3) outp((a1),(a3)) 125#endif 126#endif /* MCA */ 127 128 129/* 130 * FDDI card reset 131 */ 132static void card_start(smc) 133struct s_smc *smc ; 134{ 135 int i ; 136#ifdef PCI 137 u_char rev_id ; 138 u_short word; 139#endif 140 141 smt_stop_watchdog(smc) ; 142 143#ifdef ISA 144 outpw(CSR_A,0) ; /* reset for all chips */ 145 for (i = 10 ; i ; i--) /* delay for PLC's */ 146 (void)inpw(ISR_A) ; 147 OUT_82c54_TIMER(3,COUNT(2) | RW_OP(3) | TMODE(2)) ; 148 /* counter 2, mode 2 */ 149 OUT_82c54_TIMER(2,97) ; /* LSB */ 150 OUT_82c54_TIMER(2,0) ; /* MSB ( 15.6 us ) */ 151 outpw(CSR_A,CS_CRESET) ; 152#endif 153#ifdef EISA 154 outpw(CSR_A,0) ; /* reset for all chips */ 155 for (i = 10 ; i ; i--) /* delay for PLC's */ 156 (void)inpw(ISR_A) ; 157 outpw(CSR_A,CS_CRESET) ; 158 smc->hw.led = (2<<6) ; 159 outpw(CSR_A,CS_CRESET | smc->hw.led) ; 160#endif 161#ifdef MCA 162 outp(ADDR(CARD_DIS),0) ; /* reset for all chips */ 163 for (i = 10 ; i ; i--) /* delay for PLC's */ 164 (void)inpw(ISR_A) ; 165 outp(ADDR(CARD_EN),0) ; 166 /* first I/O after reset must not be a access to FORMAC or PLC */ 167 168 /* 169 * bus timeout (MCA) 170 */ 171 OUT_82c54_TIMER(3,COUNT(2) | RW_OP(3) | TMODE(3)) ; 172 /* counter 2, mode 3 */ 173 OUT_82c54_TIMER(2,(2*24)) ; /* 3.9 us * 2 square wave */ 174 OUT_82c54_TIMER(2,0) ; /* MSB */ 175 176 /* POS 102 indicated an activ Check Line or Buss Error monitoring */ 177 if (inpw(CSA_A) & (POS_EN_CHKINT | POS_EN_BUS_ERR)) { 178 outp(ADDR(IRQ_CHCK_EN),0) ; 179 } 180 181 if (!((i = inpw(CSR_A)) & CS_SAS)) { 182 if (!(i & CS_BYSTAT)) { 183 outp(ADDR(BYPASS(STAT_INS)),0) ;/* insert station */ 184 } 185 } 186 outpw(LEDR_A,LED_1) ; /* yellow */ 187#endif /* MCA */ 188#ifdef PCI 189 /* 190 * make sure no transfer activity is pending 191 */ 192 outpw(FM_A(FM_MDREG1),FM_MINIT) ; 193 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ; 194 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ; 195 /* 196 * now reset everything 197 */ 198 outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */ 199 i = (int) inp(ADDR(B0_CTRL)) ; /* do dummy read */ 200 SK_UNUSED(i) ; /* Make LINT happy. */ 201 outp(ADDR(B0_CTRL), CTRL_RST_CLR) ; 202 203 /* 204 * Reset all bits in the PCI STATUS register 205 */ 206 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ; /* enable for writes */ 207 word = inpw(PCI_C(PCI_STATUS)) ; 208 outpw(PCI_C(PCI_STATUS), word | PCI_ERRBITS) ; 209 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ; /* disable writes */ 210 211 /* 212 * Release the reset of all the State machines 213 * Release Master_Reset 214 * Release HPI_SM_Reset 215 */ 216 outp(ADDR(B0_CTRL), CTRL_MRST_CLR|CTRL_HPI_CLR) ; 217 218 /* 219 * determine the adapter type 220 * Note: Do it here, because some drivers may call card_start() once 221 * at very first before any other initialization functions is 222 * executed. 223 */ 224 rev_id = inp(PCI_C(PCI_REV_ID)) ; 225 if ((rev_id & 0xf0) == SK_ML_ID_1 || (rev_id & 0xf0) == SK_ML_ID_2) { 226 smc->hw.hw_is_64bit = TRUE ; 227 } else { 228 smc->hw.hw_is_64bit = FALSE ; 229 } 230 231 /* 232 * Watermark initialization 233 */ 234 if (!smc->hw.hw_is_64bit) { 235 outpd(ADDR(B4_R1_F), RX_WATERMARK) ; 236 outpd(ADDR(B5_XA_F), TX_WATERMARK) ; 237 outpd(ADDR(B5_XS_F), TX_WATERMARK) ; 238 } 239 240 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* clear the reset chips */ 241 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_ON|LED_GB_OFF) ; /* ye LED on */ 242 243 /* init the timer value for the watch dog 2,5 minutes */ 244 outpd(ADDR(B2_WDOG_INI),0x6FC23AC0) ; 245 246 /* initialize the ISR mask */ 247 smc->hw.is_imask = ISR_MASK ; 248 smc->hw.hw_state = STOPPED ; 249#endif 250 GET_PAGE(0) ; /* necessary for BOOT */ 251} 252 253void card_stop(smc) 254struct s_smc *smc ; 255{ 256 smt_stop_watchdog(smc) ; 257 smc->hw.mac_ring_is_up = 0 ; /* ring down */ 258#ifdef ISA 259 outpw(CSR_A,0) ; /* reset for all chips */ 260#endif 261#ifdef EISA 262 outpw(CSR_A,0) ; /* reset for all chips */ 263#endif 264#ifdef MCA 265 outp(ADDR(CARD_DIS),0) ; /* reset for all chips */ 266#endif 267#ifdef PCI 268 /* 269 * make sure no transfer activity is pending 270 */ 271 outpw(FM_A(FM_MDREG1),FM_MINIT) ; 272 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ; 273 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ; 274 /* 275 * now reset everything 276 */ 277 outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */ 278 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* reset for all chips */ 279 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_OFF|LED_GB_OFF) ; /* all LEDs off */ 280 smc->hw.hw_state = STOPPED ; 281#endif 282} 283/*--------------------------- ISR handling ----------------------------------*/ 284 285#ifndef PCI 286void mac1_irq(smc,stu, stl) 287struct s_smc *smc ; 288u_short stu; 289u_short stl; 290{ 291 int restart_tx = 0 ; 292again: 293#ifndef ISA 294/* 295 * FORMAC+ bug modified the queue pointer if many read/write accesses happens!? 296 */ 297 if (stl & (FM_SPCEPDS | /* parit/coding err. syn.q.*/ 298 FM_SPCEPDA0 | /* parit/coding err. a.q.0 */ 299 FM_SPCEPDA1 | /* parit/coding err. a.q.1 */ 300 FM_SPCEPDA2)) { /* parit/coding err. a.q.2 */ 301 SMT_PANIC(smc,SMT_E0132, SMT_E0132_MSG) ; 302 } 303 if (stl & (FM_STBURS | /* tx buffer underrun syn.q.*/ 304 FM_STBURA0 | /* tx buffer underrun a.q.0 */ 305 FM_STBURA1 | /* tx buffer underrun a.q.1 */ 306 FM_STBURA2)) { /* tx buffer underrun a.q.2 */ 307 SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ; 308 } 309#endif 310 if ( (stu & (FM_SXMTABT | /* transmit abort */ 311#ifdef SYNC 312 FM_STXABRS | /* syn. tx abort */ 313#endif /* SYNC */ 314 FM_STXABRA0)) || /* asyn. tx abort */ 315 (stl & (FM_SQLCKS | /* lock for syn. q. */ 316 FM_SQLCKA0)) ) { /* lock for asyn. q. */ 317 formac_tx_restart(smc) ; /* init tx */ 318 restart_tx = 1 ; 319 stu = inpw(FM_A(FM_ST1U)) ; 320 stl = inpw(FM_A(FM_ST1L)) ; 321 stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ; 322 if (stu || stl) 323 goto again ; 324 } 325 326#ifndef SYNC 327 if (stu & (FM_STECFRMA0 | /* end of chain asyn tx */ 328 FM_STEFRMA0)) { /* end of frame asyn tx */ 329 /* free tx_queue */ 330 smc->hw.n_a_send = 0 ; 331 if (++smc->hw.fp.tx_free < smc->hw.fp.tx_max) { 332 start_next_send(smc); 333 } 334 restart_tx = 1 ; 335 } 336#else /* SYNC */ 337 if (stu & (FM_STEFRMA0 | /* end of asyn tx */ 338 FM_STEFRMS)) { /* end of sync tx */ 339 restart_tx = 1 ; 340 } 341#endif /* SYNC */ 342 if (restart_tx) 343 llc_restart_tx(smc) ; 344} 345#else /* PCI */ 346 347void mac1_irq(smc,stu, stl) 348struct s_smc *smc ; 349u_short stu; 350u_short stl; 351{ 352 int restart_tx = 0 ; 353again: 354 355 /* 356 * parity error: note encoding error is not possible in tag mode 357 */ 358 if (stl & (FM_SPCEPDS | /* parity err. syn.q.*/ 359 FM_SPCEPDA0 | /* parity err. a.q.0 */ 360 FM_SPCEPDA1)) { /* parity err. a.q.1 */ 361 SMT_PANIC(smc,SMT_E0134, SMT_E0134_MSG) ; 362 } 363 /* 364 * buffer underrun: can only occur if a tx threshold is specified 365 */ 366 if (stl & (FM_STBURS | /* tx buffer underrun syn.q.*/ 367 FM_STBURA0 | /* tx buffer underrun a.q.0 */ 368 FM_STBURA1)) { /* tx buffer underrun a.q.2 */ 369 SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ; 370 } 371 372 if ( (stu & (FM_SXMTABT | /* transmit abort */ 373 FM_STXABRS | /* syn. tx abort */ 374 FM_STXABRA0)) || /* asyn. tx abort */ 375 (stl & (FM_SQLCKS | /* lock for syn. q. */ 376 FM_SQLCKA0)) ) { /* lock for asyn. q. */ 377 formac_tx_restart(smc) ; /* init tx */ 378 restart_tx = 1 ; 379 stu = inpw(FM_A(FM_ST1U)) ; 380 stl = inpw(FM_A(FM_ST1L)) ; 381 stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ; 382 if (stu || stl) 383 goto again ; 384 } 385 386 if (stu & (FM_STEFRMA0 | /* end of asyn tx */ 387 FM_STEFRMS)) { /* end of sync tx */ 388 restart_tx = 1 ; 389 } 390 391 if (restart_tx) 392 llc_restart_tx(smc) ; 393} 394#endif /* PCI */ 395/* 396 * interrupt source= plc1 397 * this function is called in nwfbisr.asm 398 */ 399void plc1_irq(smc) 400struct s_smc *smc ; 401{ 402 u_short st = inpw(PLC(PB,PL_INTR_EVENT)) ; 403 404#if (defined(ISA) || defined(EISA)) 405 /* reset PLC Int. bits */ 406 outpw(PLC1_I,inpw(PLC1_I)) ; 407#endif 408 plc_irq(smc,PB,st) ; 409} 410 411/* 412 * interrupt source= plc2 413 * this function is called in nwfbisr.asm 414 */ 415void plc2_irq(smc) 416struct s_smc *smc ; 417{ 418 u_short st = inpw(PLC(PA,PL_INTR_EVENT)) ; 419 420#if (defined(ISA) || defined(EISA)) 421 /* reset PLC Int. bits */ 422 outpw(PLC2_I,inpw(PLC2_I)) ; 423#endif 424 plc_irq(smc,PA,st) ; 425} 426 427 428/* 429 * interrupt source= timer 430 */ 431void timer_irq(smc) 432struct s_smc *smc ; 433{ 434 hwt_restart(smc); 435 smc->hw.t_stop = smc->hw.t_start; 436 smt_timer_done(smc) ; 437} 438 439/* 440 * return S-port (PA or PB) 441 */ 442int pcm_get_s_port(smc) 443struct s_smc *smc ; 444{ 445 SK_UNUSED(smc) ; 446 return(PS) ; 447} 448 449/* 450 * Station Label = "FDDI-XYZ" where 451 * 452 * X = connector type 453 * Y = PMD type 454 * Z = port type 455 */ 456#define STATION_LABEL_CONNECTOR_OFFSET 5 457#define STATION_LABEL_PMD_OFFSET 6 458#define STATION_LABEL_PORT_OFFSET 7 459 460void read_address(smc,mac_addr) 461struct s_smc *smc ; 462u_char *mac_addr ; 463{ 464 char ConnectorType ; 465 char PmdType ; 466 int i ; 467 468 extern const u_char canonical[256] ; 469 470#if (defined(ISA) || defined(MCA)) 471 for (i = 0; i < 4 ;i++) { /* read mac address from board */ 472 smc->hw.fddi_phys_addr.a[i] = 473 canonical[(inpw(PR_A(i+SA_MAC))&0xff)] ; 474 } 475 for (i = 4; i < 6; i++) { 476 smc->hw.fddi_phys_addr.a[i] = 477 canonical[(inpw(PR_A(i+SA_MAC+PRA_OFF))&0xff)] ; 478 } 479#endif 480#ifdef EISA 481 /* 482 * Note: We get trouble on an Alpha machine if we make a inpw() 483 * instead of inp() 484 */ 485 for (i = 0; i < 4 ;i++) { /* read mac address from board */ 486 smc->hw.fddi_phys_addr.a[i] = 487 canonical[inp(PR_A(i+SA_MAC))] ; 488 } 489 for (i = 4; i < 6; i++) { 490 smc->hw.fddi_phys_addr.a[i] = 491 canonical[inp(PR_A(i+SA_MAC+PRA_OFF))] ; 492 } 493#endif 494#ifdef PCI 495 for (i = 0; i < 6; i++) { /* read mac address from board */ 496 smc->hw.fddi_phys_addr.a[i] = 497 canonical[inp(ADDR(B2_MAC_0+i))] ; 498 } 499#endif 500#ifndef PCI 501 ConnectorType = inpw(PR_A(SA_PMD_TYPE)) & 0xff ; 502 PmdType = inpw(PR_A(SA_PMD_TYPE+1)) & 0xff ; 503#else 504 ConnectorType = inp(ADDR(B2_CONN_TYP)) ; 505 PmdType = inp(ADDR(B2_PMD_TYP)) ; 506#endif 507 508 smc->y[PA].pmd_type[PMD_SK_CONN] = 509 smc->y[PB].pmd_type[PMD_SK_CONN] = ConnectorType ; 510 smc->y[PA].pmd_type[PMD_SK_PMD ] = 511 smc->y[PB].pmd_type[PMD_SK_PMD ] = PmdType ; 512 513 if (mac_addr) { 514 for (i = 0; i < 6 ;i++) { 515 smc->hw.fddi_canon_addr.a[i] = mac_addr[i] ; 516 smc->hw.fddi_home_addr.a[i] = canonical[mac_addr[i]] ; 517 } 518 return ; 519 } 520 smc->hw.fddi_home_addr = smc->hw.fddi_phys_addr ; 521 522 for (i = 0; i < 6 ;i++) { 523 smc->hw.fddi_canon_addr.a[i] = 524 canonical[smc->hw.fddi_phys_addr.a[i]] ; 525 } 526} 527 528/* 529 * FDDI card soft reset 530 */ 531void init_board(smc,mac_addr) 532struct s_smc *smc ; 533u_char *mac_addr ; 534{ 535 card_start(smc) ; 536 read_address(smc,mac_addr) ; 537 538#ifndef PCI 539 if (inpw(CSR_A) & CS_SAS) 540#else 541 if (!(inp(ADDR(B0_DAS)) & DAS_AVAIL)) 542#endif 543 smc->s.sas = SMT_SAS ; /* Single att. station */ 544 else 545 smc->s.sas = SMT_DAS ; /* Dual att. station */ 546 547#ifndef PCI 548 if (inpw(CSR_A) & CS_BYSTAT) 549#else 550 if (!(inp(ADDR(B0_DAS)) & DAS_BYP_ST)) 551#endif 552 smc->mib.fddiSMTBypassPresent = 0 ; 553 /* without opt. bypass */ 554 else 555 smc->mib.fddiSMTBypassPresent = 1 ; 556 /* with opt. bypass */ 557} 558 559/* 560 * insert or deinsert optical bypass (called by ECM) 561 */ 562void sm_pm_bypass_req(smc,mode) 563struct s_smc *smc ; 564int mode; 565{ 566#if (defined(ISA) || defined(EISA)) 567 int csra_v ; 568#endif 569 570 DB_ECMN(1,"ECM : sm_pm_bypass_req(%s)\n",(mode == BP_INSERT) ? 571 "BP_INSERT" : "BP_DEINSERT",0) ; 572 573 if (smc->s.sas != SMT_DAS) 574 return ; 575 576#if (defined(ISA) || defined(EISA)) 577 578 csra_v = inpw(CSR_A) & ~CS_BYPASS ; 579#ifdef EISA 580 csra_v |= smc->hw.led ; 581#endif 582 583 switch(mode) { 584 case BP_INSERT : 585 outpw(CSR_A,csra_v | CS_BYPASS) ; 586 break ; 587 case BP_DEINSERT : 588 outpw(CSR_A,csra_v) ; 589 break ; 590 } 591#endif /* ISA / EISA */ 592#ifdef MCA 593 switch(mode) { 594 case BP_INSERT : 595 outp(ADDR(BYPASS(STAT_INS)),0) ;/* insert station */ 596 break ; 597 case BP_DEINSERT : 598 outp(ADDR(BYPASS(STAT_BYP)),0) ; /* bypass station */ 599 break ; 600 } 601#endif 602#ifdef PCI 603 switch(mode) { 604 case BP_INSERT : 605 outp(ADDR(B0_DAS),DAS_BYP_INS) ; /* insert station */ 606 break ; 607 case BP_DEINSERT : 608 outp(ADDR(B0_DAS),DAS_BYP_RMV) ; /* bypass station */ 609 break ; 610 } 611#endif 612} 613 614/* 615 * check if bypass connected 616 */ 617int sm_pm_bypass_present(smc) 618struct s_smc *smc ; 619{ 620#ifndef PCI 621 return( (inpw(CSR_A) & CS_BYSTAT) ? FALSE : TRUE ) ; 622#else 623 return( (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE: FALSE) ; 624#endif 625} 626 627void plc_clear_irq(smc,p) 628struct s_smc *smc ; 629int p ; 630{ 631 SK_UNUSED(p) ; 632 633#if (defined(ISA) || defined(EISA)) 634 switch (p) { 635 case PA : 636 /* reset PLC Int. bits */ 637 outpw(PLC2_I,inpw(PLC2_I)) ; 638 break ; 639 case PB : 640 /* reset PLC Int. bits */ 641 outpw(PLC1_I,inpw(PLC1_I)) ; 642 break ; 643 } 644#else 645 SK_UNUSED(smc) ; 646#endif 647} 648 649 650/* 651 * led_indication called by rmt_indication() and 652 * pcm_state_change() 653 * 654 * Input: 655 * smc: SMT context 656 * led_event: 657 * 0 Only switch green LEDs according to their respective PCM state 658 * LED_Y_OFF just switch yellow LED off 659 * LED_Y_ON just switch yello LED on 660 */ 661void led_indication(smc,led_event) 662struct s_smc *smc ; 663int led_event; 664{ 665 /* use smc->hw.mac_ring_is_up == TRUE 666 * as indication for Ring Operational 667 */ 668 u_short led_state ; 669 struct s_phy *phy ; 670 struct fddi_mib_p *mib_a ; 671 struct fddi_mib_p *mib_b ; 672 673 phy = &smc->y[PA] ; 674 mib_a = phy->mib ; 675 phy = &smc->y[PB] ; 676 mib_b = phy->mib ; 677 678#ifdef EISA 679 /* Ring up = yellow led OFF*/ 680 if (led_event == LED_Y_ON) { 681 smc->hw.led |= CS_LED_1 ; 682 } 683 else if (led_event == LED_Y_OFF) { 684 smc->hw.led &= ~CS_LED_1 ; 685 } 686 else { 687 /* Link at Port A or B = green led ON */ 688 if (mib_a->fddiPORTPCMState == PC8_ACTIVE || 689 mib_b->fddiPORTPCMState == PC8_ACTIVE) { 690 smc->hw.led |= CS_LED_0 ; 691 } 692 else { 693 smc->hw.led &= ~CS_LED_0 ; 694 } 695 } 696#endif 697#ifdef MCA 698 led_state = inpw(LEDR_A) ; 699 700 /* Ring up = yellow led OFF*/ 701 if (led_event == LED_Y_ON) { 702 led_state |= LED_1 ; 703 } 704 else if (led_event == LED_Y_OFF) { 705 led_state &= ~LED_1 ; 706 } 707 else { 708 led_state &= ~(LED_2|LED_0) ; 709 710 /* Link at Port A = green led A ON */ 711 if (mib_a->fddiPORTPCMState == PC8_ACTIVE) { 712 led_state |= LED_2 ; 713 } 714 715 /* Link at Port B/S = green led B ON */ 716 if (mib_b->fddiPORTPCMState == PC8_ACTIVE) { 717 led_state |= LED_0 ; 718 } 719 } 720 721 outpw(LEDR_A, led_state) ; 722#endif /* MCA */ 723#ifdef PCI 724 led_state = 0 ; 725 726 /* Ring up = yellow led OFF*/ 727 if (led_event == LED_Y_ON) { 728 led_state |= LED_MY_ON ; 729 } 730 else if (led_event == LED_Y_OFF) { 731 led_state |= LED_MY_OFF ; 732 } 733 else { /* PCM state changed */ 734 /* Link at Port A/S = green led A ON */ 735 if (mib_a->fddiPORTPCMState == PC8_ACTIVE) { 736 led_state |= LED_GA_ON ; 737 } 738 else { 739 led_state |= LED_GA_OFF ; 740 } 741 742 /* Link at Port B = green led B ON */ 743 if (mib_b->fddiPORTPCMState == PC8_ACTIVE) { 744 led_state |= LED_GB_ON ; 745 } 746 else { 747 led_state |= LED_GB_OFF ; 748 } 749 } 750 751 outp(ADDR(B0_LED), led_state) ; 752#endif /* PCI */ 753 754} 755 756 757void pcm_state_change(smc,plc,p_state) 758struct s_smc *smc; 759int plc; 760int p_state; 761{ 762 /* 763 * the current implementation of pcm_state_change() in the driver 764 * parts must be renamed to drv_pcm_state_change() which will be called 765 * now after led_indication. 766 */ 767 DRV_PCM_STATE_CHANGE(smc,plc,p_state) ; 768 769 led_indication(smc,0) ; 770} 771 772 773void rmt_indication(smc,i) 774struct s_smc *smc ; 775int i; 776{ 777 /* Call a driver special function if defined */ 778 DRV_RMT_INDICATION(smc,i) ; 779 780 led_indication(smc, i ? LED_Y_OFF : LED_Y_ON) ; 781} 782 783 784/* 785 * llc_recover_tx called by init_tx (fplus.c) 786 */ 787void llc_recover_tx(smc) 788struct s_smc *smc ; 789{ 790#ifdef LOAD_GEN 791 extern int load_gen_flag ; 792 793 load_gen_flag = 0 ; 794#endif 795#ifndef SYNC 796 smc->hw.n_a_send= 0 ; 797#else 798 SK_UNUSED(smc) ; 799#endif 800} 801 802/*--------------------------- DMA init ----------------------------*/ 803#ifdef ISA 804 805/* 806 * init DMA 807 */ 808void init_dma(smc,dma) 809struct s_smc *smc; 810int dma; 811{ 812 SK_UNUSED(smc) ; 813 814 /* 815 * set cascade mode, 816 * clear mask bit (enable DMA cannal) 817 */ 818 if (dma > 3) { 819 outp(0xd6,(dma & 0x03) | 0xc0) ; 820 outp(0xd4, dma & 0x03) ; 821 } 822 else { 823 outp(0x0b,(dma & 0x03) | 0xc0) ; 824 outp(0x0a,dma & 0x03) ; 825 } 826} 827 828/* 829 * disable DMA 830 */ 831void dis_dma(smc,dma) 832struct s_smc *smc ; 833int dma; 834{ 835 SK_UNUSED(smc) ; 836 837 /* 838 * set mask bit (disable DMA cannal) 839 */ 840 if (dma > 3) { 841 outp(0xd4,(dma & 0x03) | 0x04) ; 842 } 843 else { 844 outp(0x0a,(dma & 0x03) | 0x04) ; 845 } 846} 847 848#endif /* ISA */ 849 850#ifdef EISA 851 852/*arrays with io addresses of dma controller length and address registers*/ 853static const int cntr[8] = { 0x001,0x003,0x005,0x007,0,0x0c6,0x0ca,0x0ce } ; 854static const int base[8] = { 0x000,0x002,0x004,0x006,0,0x0c4,0x0c8,0x0cc } ; 855static const int page[8] = { 0x087,0x083,0x081,0x082,0,0x08b,0x089,0x08a } ; 856 857void init_dma(smc,dma) 858struct s_smc *smc ; 859int dma; 860{ 861 /* 862 * extended mode register 863 * 32 bit IO 864 * type c 865 * TC output 866 * disable stop 867 */ 868 869 /* mode read (write) demand */ 870 smc->hw.dma_rmode = (dma & 3) | 0x08 | 0x0 ; 871 smc->hw.dma_wmode = (dma & 3) | 0x04 | 0x0 ; 872 873 /* 32 bit IO's, burst DMA mode (type "C") */ 874 smc->hw.dma_emode = (dma & 3) | 0x08 | 0x30 ; 875 876 outp((dma < 4) ? 0x40b : 0x4d6,smc->hw.dma_emode) ; 877 878 /* disable chaining */ 879 outp((dma < 4) ? 0x40a : 0x4d4,(dma&3)) ; 880 881 /*load dma controller addresses for fast access during set dma*/ 882 smc->hw.dma_base_word_count = cntr[smc->hw.dma]; 883 smc->hw.dma_base_address = base[smc->hw.dma]; 884 smc->hw.dma_base_address_page = page[smc->hw.dma]; 885 886} 887 888void dis_dma(smc,dma) 889struct s_smc *smc ; 890int dma; 891{ 892 SK_UNUSED(smc) ; 893 894 outp((dma < 4) ? 0x0a : 0xd4,(dma&3)|4) ;/* mask bit */ 895} 896#endif /* EISA */ 897 898#ifdef MCA 899void init_dma(smc,dma) 900struct s_smc *smc; 901int dma; 902{ 903 SK_UNUSED(smc) ; 904 SK_UNUSED(dma) ; 905} 906void dis_dma(smc,dma) 907struct s_smc *smc; 908int dma; 909{ 910 SK_UNUSED(smc) ; 911 SK_UNUSED(dma) ; 912} 913#endif 914 915#ifdef PCI 916void init_dma(smc,dma) 917struct s_smc *smc; 918int dma; 919{ 920 SK_UNUSED(smc) ; 921 SK_UNUSED(dma) ; 922} 923void dis_dma(smc,dma) 924struct s_smc *smc; 925int dma; 926{ 927 SK_UNUSED(smc) ; 928 SK_UNUSED(dma) ; 929} 930#endif 931 932#ifdef MULT_OEM 933static int is_equal_num(comp1,comp2,num) 934char comp1[] ; 935char comp2[] ; 936int num ; 937{ 938 int i ; 939 940 for (i = 0 ; i < num ; i++) { 941 if (comp1[i] != comp2[i]) 942 return (0) ; 943 } 944 return (1) ; 945} /* is_equal_num */ 946 947 948/* 949 * set the OEM ID defaults, and test the contents of the OEM data base 950 * The default OEM is the first ACTIVE entry in the OEM data base 951 * 952 * returns: 0 success 953 * 1 error in data base 954 * 2 data base empty 955 * 3 no active entry 956 */ 957int set_oi_id_def(smc) 958struct s_smc *smc ; 959{ 960 int sel_id ; 961 int i ; 962 int act_entries ; 963 964 i = 0 ; 965 sel_id = -1 ; 966 act_entries = FALSE ; 967 smc->hw.oem_id = 0 ; 968 smc->hw.oem_min_status = OI_STAT_ACTIVE ; 969 970 /* check OEM data base */ 971 while (oem_ids[i].oi_status) { 972 switch (oem_ids[i].oi_status) { 973 case OI_STAT_ACTIVE: 974 act_entries = TRUE ; /* we have active IDs */ 975 if (sel_id == -1) 976 sel_id = i ; /* save the first active ID */ 977 case OI_STAT_VALID: 978 case OI_STAT_PRESENT: 979 i++ ; 980 break ; /* entry ok */ 981 default: 982 return (1) ; /* invalid oi_status */ 983 } 984 } 985 986 if (i == 0) 987 return (2) ; 988 if (!act_entries) 989 return (3) ; 990 991 /* ok, we have a valid OEM data base with an active entry */ 992 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[sel_id] ; 993 return (0) ; 994} 995#endif /* MULT_OEM */ 996 997 998#ifdef MCA 999/************************ 1000 * 1001 * BEGIN_MANUAL_ENTRY() 1002 * 1003 * exist_board 1004 * 1005 * Check if an MCA board is present in the specified slot. 1006 * 1007 * int exist_board( 1008 * struct s_smc *smc, 1009 * int slot) ; 1010 * In 1011 * smc - A pointer to the SMT Context struct. 1012 * 1013 * slot - The number of the slot to inspect. 1014 * Out 1015 * 0 = No adapter present. 1016 * 1 = Found FM1 adapter. 1017 * 1018 * Pseudo 1019 * Read MCA ID 1020 * for all valid OEM_IDs 1021 * compare with ID read 1022 * if equal, return 1 1023 * return(0 1024 * 1025 * Note 1026 * The smc pointer must be valid now. 1027 * 1028 * END_MANUAL_ENTRY() 1029 * 1030 ************************/ 1031#define LONG_CARD_ID(lo, hi) ((((hi) & 0xff) << 8) | ((lo) & 0xff)) 1032int exist_board(smc,slot) 1033struct s_smc *smc ; 1034int slot ; 1035{ 1036#ifdef MULT_OEM 1037 SK_LOC_DECL(u_char,id[2]) ; 1038 int idi ; 1039#endif /* MULT_OEM */ 1040 1041 /* No longer valid. */ 1042 if (smc == NULL) 1043 return(0) ; 1044 1045#ifndef MULT_OEM 1046 if (read_card_id(smc, slot) 1047 == LONG_CARD_ID(OEMID(smc,0), OEMID(smc,1))) 1048 return (1) ; /* Found FM adapter. */ 1049 1050#else /* MULT_OEM */ 1051 idi = read_card_id(smc, slot) ; 1052 id[0] = idi & 0xff ; 1053 id[1] = idi >> 8 ; 1054 1055 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ; 1056 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) { 1057 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status) 1058 continue ; 1059 1060 if (is_equal_num(&id[0],&OEMID(smc,0),2)) 1061 return (1) ; 1062 } 1063#endif /* MULT_OEM */ 1064 return (0) ; /* No adapter found. */ 1065} 1066 1067/************************ 1068 * 1069 * read_card_id 1070 * 1071 * Read the MCA card id from the specified slot. 1072 * In 1073 * smc - A pointer to the SMT Context struct. 1074 * CAVEAT: This pointer may be NULL and *must not* be used within this 1075 * function. It's only purpose is for drivers that need some information 1076 * for the inp() and outp() macros. 1077 * 1078 * slot - The number of the slot for which the card id is returned. 1079 * Out 1080 * Returns the card id read from the specified slot. If an illegal slot 1081 * number is specified, the function returns zero. 1082 * 1083 ************************/ 1084static int read_card_id(smc,slot) 1085struct s_smc *smc ; /* Do not use. */ 1086int slot ; 1087{ 1088 int card_id ; 1089 1090 SK_UNUSED(smc) ; /* Make LINT happy. */ 1091 if ((slot < 1) || (slot > 15)) /* max 16 slots, 0 = motherboard */ 1092 return (0) ; /* Illegal slot number specified. */ 1093 1094 EnableSlotAccess(smc, slot) ; 1095 1096 card_id = ((read_POS(smc,POS_ID_HIGH,slot - 1) & 0xff) << 8) | 1097 (read_POS(smc,POS_ID_LOW,slot - 1) & 0xff) ; 1098 1099 DisableSlotAccess(smc) ; 1100 1101 return (card_id) ; 1102} 1103 1104/************************ 1105 * 1106 * BEGIN_MANUAL_ENTRY() 1107 * 1108 * get_board_para 1109 * 1110 * Get adapter configuration information. Fill all board specific 1111 * parameters within the 'smc' structure. 1112 * 1113 * int get_board_para( 1114 * struct s_smc *smc, 1115 * int slot) ; 1116 * In 1117 * smc - A pointer to the SMT Context struct, to which this function will 1118 * write some adapter configuration data. 1119 * 1120 * slot - The number of the slot, in which the adapter is installed. 1121 * Out 1122 * 0 = No adapter present. 1123 * 1 = Ok. 1124 * 2 = Adapter present, but card enable bit not set. 1125 * 1126 * END_MANUAL_ENTRY() 1127 * 1128 ************************/ 1129int get_board_para(smc,slot) 1130struct s_smc *smc ; 1131int slot ; 1132{ 1133 int val ; 1134 int i ; 1135 1136 /* Check if adapter present & get type of adapter. */ 1137 switch (exist_board(smc, slot)) { 1138 case 0: /* Adapter not present. */ 1139 return (0) ; 1140 case 1: /* FM Rev. 1 */ 1141 smc->hw.rev = FM1_REV ; 1142 smc->hw.VFullRead = 0x0a ; 1143 smc->hw.VFullWrite = 0x05 ; 1144 smc->hw.DmaWriteExtraBytes = 8 ; /* 2 extra words. */ 1145 break ; 1146 } 1147 smc->hw.slot = slot ; 1148 1149 EnableSlotAccess(smc, slot) ; 1150 1151 if (!(read_POS(smc,POS_102, slot - 1) & POS_CARD_EN)) { 1152 DisableSlotAccess(smc) ; 1153 return (2) ; /* Card enable bit not set. */ 1154 } 1155 1156 val = read_POS(smc,POS_104, slot - 1) ; /* I/O, IRQ */ 1157 1158#ifndef MEM_MAPPED_IO /* is defined by the operating system */ 1159 i = val & POS_IOSEL ; /* I/O base addr. (0x0200 .. 0xfe00) */ 1160 smc->hw.iop = (i + 1) * 0x0400 - 0x200 ; 1161#endif 1162 i = ((val & POS_IRQSEL) >> 6) & 0x03 ; /* IRQ <0, 1> */ 1163 smc->hw.irq = opt_ints[i] ; 1164 1165 /* FPROM base addr. */ 1166 i = ((read_POS(smc,POS_103, slot - 1) & POS_MSEL) >> 4) & 0x07 ; 1167 smc->hw.eprom = opt_eproms[i] ; 1168 1169 DisableSlotAccess(smc) ; 1170 1171 /* before this, the smc->hw.iop must be set !!! */ 1172 smc->hw.slot_32 = inpw(CSF_A) & SLOT_32 ; 1173 1174 return (1) ; 1175} 1176 1177/* Enable access to specified MCA slot. */ 1178static void EnableSlotAccess(smc,slot) 1179struct s_smc *smc ; 1180int slot ; 1181{ 1182 SK_UNUSED(slot) ; 1183 1184#ifndef AIX 1185 SK_UNUSED(smc) ; 1186 1187 /* System mode. */ 1188 outp(POS_SYS_SETUP, POS_SYSTEM) ; 1189 1190 /* Select slot. */ 1191 outp(POS_CHANNEL_POS, POS_CHANNEL_BIT | (slot-1)) ; 1192#else 1193 attach_POS_addr (smc) ; 1194#endif 1195} 1196 1197/* Disable access to MCA slot formerly enabled via EnableSlotAccess(). */ 1198static void DisableSlotAccess(smc) 1199struct s_smc *smc ; 1200{ 1201#ifndef AIX 1202 SK_UNUSED(smc) ; 1203 1204 outp(POS_CHANNEL_POS, 0) ; 1205#else 1206 detach_POS_addr (smc) ; 1207#endif 1208} 1209#endif /* MCA */ 1210 1211#ifdef EISA 1212#ifndef MEM_MAPPED_IO 1213#define SADDR(slot) (((slot)<<12)&0xf000) 1214#else /* MEM_MAPPED_IO */ 1215#define SADDR(slot) (smc->hw.iop) 1216#endif /* MEM_MAPPED_IO */ 1217 1218/************************ 1219 * 1220 * BEGIN_MANUAL_ENTRY() 1221 * 1222 * exist_board 1223 * 1224 * Check if an EISA board is present in the specified slot. 1225 * 1226 * int exist_board( 1227 * struct s_smc *smc, 1228 * int slot) ; 1229 * In 1230 * smc - A pointer to the SMT Context struct. 1231 * 1232 * slot - The number of the slot to inspect. 1233 * Out 1234 * 0 = No adapter present. 1235 * 1 = Found adapter. 1236 * 1237 * Pseudo 1238 * Read EISA ID 1239 * for all valid OEM_IDs 1240 * compare with ID read 1241 * if equal, return 1 1242 * return(0 1243 * 1244 * Note 1245 * The smc pointer must be valid now. 1246 * 1247 ************************/ 1248int exist_board(smc,slot) 1249struct s_smc *smc ; 1250int slot ; 1251{ 1252 int i ; 1253#ifdef MULT_OEM 1254 SK_LOC_DECL(u_char,id[4]) ; 1255#endif /* MULT_OEM */ 1256 1257 /* No longer valid. */ 1258 if (smc == NULL) 1259 return(0); 1260 1261 SK_UNUSED(slot) ; 1262 1263#ifndef MULT_OEM 1264 for (i = 0 ; i < 4 ; i++) { 1265 if (inp(SADDR(slot)+PRA(i)) != OEMID(smc,i)) 1266 return(0) ; 1267 } 1268 return(1) ; 1269#else /* MULT_OEM */ 1270 for (i = 0 ; i < 4 ; i++) 1271 id[i] = inp(SADDR(slot)+PRA(i)) ; 1272 1273 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ; 1274 1275 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) { 1276 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status) 1277 continue ; 1278 1279 if (is_equal_num(&id[0],&OEMID(smc,0),4)) 1280 return (1) ; 1281 } 1282 return (0) ; /* No adapter found. */ 1283#endif /* MULT_OEM */ 1284} 1285 1286 1287int get_board_para(smc,slot) 1288struct s_smc *smc ; 1289int slot ; 1290{ 1291 int i ; 1292 1293 if (!exist_board(smc,slot)) 1294 return(0) ; 1295 1296 smc->hw.slot = slot ; 1297#ifndef MEM_MAPPED_IO /* if defined by the operating system */ 1298 smc->hw.iop = SADDR(slot) ; 1299#endif 1300 1301 if (!(inp(C0_A(0))&CFG_CARD_EN)) { 1302 return(2) ; /* CFG_CARD_EN bit not set! */ 1303 } 1304 1305 smc->hw.irq = opt_ints[(inp(C1_A(0)) & CFG_IRQ_SEL)] ; 1306 smc->hw.dma = opt_dmas[((inp(C1_A(0)) & CFG_DRQ_SEL)>>3)] ; 1307 1308 if ((i = inp(C2_A(0)) & CFG_EPROM_SEL) != 0x0f) 1309 smc->hw.eprom = opt_eproms[i] ; 1310 else 1311 smc->hw.eprom = 0 ; 1312 1313 smc->hw.DmaWriteExtraBytes = 8 ; 1314 1315 return(1) ; 1316} 1317#endif /* EISA */ 1318 1319#ifdef ISA 1320#ifndef MULT_OEM 1321const u_char sklogo[6] = SKLOGO_STR ; 1322#define SIZE_SKLOGO(smc) sizeof(sklogo) 1323#define SKLOGO(smc,i) sklogo[i] 1324#else /* MULT_OEM */ 1325#define SIZE_SKLOGO(smc) smc->hw.oem_id->oi_logo_len 1326#define SKLOGO(smc,i) smc->hw.oem_id->oi_logo[i] 1327#endif /* MULT_OEM */ 1328 1329 1330int exist_board(smc,port) 1331struct s_smc *smc ; 1332HW_PTR port ; 1333{ 1334 int i ; 1335#ifdef MULT_OEM 1336 int bytes_read ; 1337 u_char board_logo[15] ; 1338 SK_LOC_DECL(u_char,id[4]) ; 1339#endif /* MULT_OEM */ 1340 1341 /* No longer valid. */ 1342 if (smc == NULL) 1343 return(0); 1344 1345 SK_UNUSED(smc) ; 1346#ifndef MULT_OEM 1347 for (i = SADDRL ; i < (signed) (SADDRL+SIZE_SKLOGO(smc)) ; i++) { 1348 if ((u_char)inpw((PRA(i)+port)) != SKLOGO(smc,i-SADDRL)) { 1349 return(0) ; 1350 } 1351 } 1352 1353 /* check MAC address (S&K or other) */ 1354 for (i = 0 ; i < 3 ; i++) { 1355 if ((u_char)inpw((PRA(i)+port)) != OEMID(smc,i)) 1356 return(0) ; 1357 } 1358 return(1) ; 1359#else /* MULT_OEM */ 1360 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ; 1361 board_logo[0] = (u_char)inpw((PRA(SADDRL)+port)) ; 1362 bytes_read = 1 ; 1363 1364 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) { 1365 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status) 1366 continue ; 1367 1368 /* Test all read bytes with current OEM_entry */ 1369 /* for (i=0; (i<bytes_read) && (i < SIZE_SKLOGO(smc)); i++) { */ 1370 for (i = 0; i < bytes_read; i++) { 1371 if (board_logo[i] != SKLOGO(smc,i)) 1372 break ; 1373 } 1374 1375 /* If mismatch, switch to next OEM entry */ 1376 if ((board_logo[i] != SKLOGO(smc,i)) && (i < bytes_read)) 1377 continue ; 1378 1379 --i ; 1380 while (bytes_read < SIZE_SKLOGO(smc)) { 1381 // inpw next byte SK_Logo 1382 i++ ; 1383 board_logo[i] = (u_char)inpw((PRA(SADDRL+i)+port)) ; 1384 bytes_read++ ; 1385 if (board_logo[i] != SKLOGO(smc,i)) 1386 break ; 1387 } 1388 1389 for (i = 0 ; i < 3 ; i++) 1390 id[i] = (u_char)inpw((PRA(i)+port)) ; 1391 1392 if ((board_logo[i] == SKLOGO(smc,i)) 1393 && (bytes_read == SIZE_SKLOGO(smc))) { 1394 1395 if (is_equal_num(&id[0],&OEMID(smc,0),3)) 1396 return(1); 1397 } 1398 } /* for */ 1399 return(0) ; 1400#endif /* MULT_OEM */ 1401} 1402 1403int get_board_para(smc,slot) 1404struct s_smc *smc ; 1405int slot ; 1406{ 1407 SK_UNUSED(smc) ; 1408 SK_UNUSED(slot) ; 1409 return(0) ; /* for ISA not supported */ 1410} 1411#endif /* ISA */ 1412 1413#ifdef PCI 1414#ifdef USE_BIOS_FUN 1415int exist_board(smc,slot) 1416struct s_smc *smc ; 1417int slot ; 1418{ 1419 u_short dev_id ; 1420 u_short ven_id ; 1421 int found ; 1422 int i ; 1423 1424 found = FALSE ; /* make sure we returned with adatper not found*/ 1425 /* if an empty oemids.h was included */ 1426 1427#ifdef MULT_OEM 1428 smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[0] ; 1429 for (; smc->hw.oem_id->oi_status != OI_STAT_LAST; smc->hw.oem_id++) { 1430 if (smc->hw.oem_id->oi_status < smc->hw.oem_min_status) 1431 continue ; 1432#endif 1433 ven_id = OEMID(smc,0) + (OEMID(smc,1) << 8) ; 1434 dev_id = OEMID(smc,2) + (OEMID(smc,3) << 8) ; 1435 for (i = 0; i < slot; i++) { 1436 if (pci_find_device(i,&smc->hw.pci_handle, 1437 dev_id,ven_id) != 0) { 1438 1439 found = FALSE ; 1440 } else { 1441 found = TRUE ; 1442 } 1443 } 1444 if (found) { 1445 return(1) ; /* adapter was found */ 1446 } 1447#ifdef MULT_OEM 1448 } 1449#endif 1450 return(0) ; /* adapter was not found */ 1451} 1452#endif /* PCI */ 1453#endif /* USE_BIOS_FUNC */ 1454 1455void driver_get_bia(smc, bia_addr) 1456struct s_smc *smc ; 1457struct fddi_addr *bia_addr ; 1458{ 1459 int i ; 1460 1461 extern const u_char canonical[256] ; 1462 1463 for (i = 0 ; i < 6 ; i++) { 1464 bia_addr->a[i] = canonical[smc->hw.fddi_phys_addr.a[i]] ; 1465 } 1466} 1467 1468void smt_start_watchdog(smc) 1469struct s_smc *smc ; 1470{ 1471 SK_UNUSED(smc) ; /* Make LINT happy. */ 1472 1473#ifndef DEBUG 1474 1475#ifdef PCI 1476 if (smc->hw.wdog_used) { 1477 outpw(ADDR(B2_WDOG_CRTL),TIM_START) ; /* Start timer. */ 1478 } 1479#endif 1480 1481#endif /* DEBUG */ 1482} 1483 1484void smt_stop_watchdog(smc) 1485struct s_smc *smc ; 1486{ 1487 SK_UNUSED(smc) ; /* Make LINT happy. */ 1488#ifndef DEBUG 1489 1490#ifdef PCI 1491 if (smc->hw.wdog_used) { 1492 outpw(ADDR(B2_WDOG_CRTL),TIM_STOP) ; /* Stop timer. */ 1493 } 1494#endif 1495 1496#endif /* DEBUG */ 1497} 1498 1499#ifdef PCI 1500static char get_rom_byte(smc,addr) 1501struct s_smc *smc ; 1502u_short addr ; 1503{ 1504 GET_PAGE(addr) ; 1505 return (READ_PROM(ADDR(B2_FDP))) ; 1506} 1507 1508/* 1509 * ROM image defines 1510 */ 1511#define ROM_SIG_1 0 1512#define ROM_SIG_2 1 1513#define PCI_DATA_1 0x18 1514#define PCI_DATA_2 0x19 1515 1516/* 1517 * PCI data structure defines 1518 */ 1519#define VPD_DATA_1 0x08 1520#define VPD_DATA_2 0x09 1521#define IMAGE_LEN_1 0x10 1522#define IMAGE_LEN_2 0x11 1523#define CODE_TYPE 0x14 1524#define INDICATOR 0x15 1525 1526/* 1527 * BEGIN_MANUAL_ENTRY(mac_drv_vpd_read) 1528 * mac_drv_vpd_read(smc,buf,size,image) 1529 * 1530 * function DOWNCALL (FDDIWARE) 1531 * reads the VPD data of the FPROM and writes it into the 1532 * buffer 1533 * 1534 * para buf points to the buffer for the VPD data 1535 * size size of the VPD data buffer 1536 * image boot image; code type of the boot image 1537 * image = 0 Intel x86, PC-AT compatible 1538 * 1 OPENBOOT standard for PCI 1539 * 2-FF reserved 1540 * 1541 * returns len number of VPD data bytes read form the FPROM 1542 * <0 number of read bytes 1543 * >0 error: data invalid 1544 * 1545 * END_MANUAL_ENTRY 1546 */ 1547int mac_drv_vpd_read(smc,buf,size,image) 1548struct s_smc *smc ; 1549char *buf ; 1550int size ; 1551char image ; 1552{ 1553 u_short ibase ; 1554 u_short pci_base ; 1555 u_short vpd ; 1556 int len ; 1557 1558 len = 0 ; 1559 ibase = 0 ; 1560 /* 1561 * as long images defined 1562 */ 1563 while (get_rom_byte(smc,ibase+ROM_SIG_1) == 0x55 && 1564 (u_char) get_rom_byte(smc,ibase+ROM_SIG_2) == 0xaa) { 1565 /* 1566 * get the pointer to the PCI data structure 1567 */ 1568 pci_base = ibase + get_rom_byte(smc,ibase+PCI_DATA_1) + 1569 (get_rom_byte(smc,ibase+PCI_DATA_2) << 8) ; 1570 1571 if (image == get_rom_byte(smc,pci_base+CODE_TYPE)) { 1572 /* 1573 * we have the right image, read the VPD data 1574 */ 1575 vpd = ibase + get_rom_byte(smc,pci_base+VPD_DATA_1) + 1576 (get_rom_byte(smc,pci_base+VPD_DATA_2) << 8) ; 1577 if (vpd == ibase) { 1578 break ; /* no VPD data */ 1579 } 1580 for (len = 0; len < size; len++,buf++,vpd++) { 1581 *buf = get_rom_byte(smc,vpd) ; 1582 } 1583 break ; 1584 } 1585 else { 1586 /* 1587 * try the next image 1588 */ 1589 if (get_rom_byte(smc,pci_base+INDICATOR) & 0x80) { 1590 break ; /* this was the last image */ 1591 } 1592 ibase = ibase + get_rom_byte(smc,ibase+IMAGE_LEN_1) + 1593 (get_rom_byte(smc,ibase+IMAGE_LEN_2) << 8) ; 1594 } 1595 } 1596 1597 return(len) ; 1598} 1599 1600void mac_drv_pci_fix(smc,fix_value) 1601struct s_smc *smc ; 1602u_long fix_value ; 1603{ 1604 smc->hw.pci_fix_value = fix_value ; 1605} 1606 1607void mac_do_pci_fix(smc) 1608struct s_smc *smc ; 1609{ 1610 SK_UNUSED(smc) ; 1611} 1612#endif /* PCI */ 1613