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