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