Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/fddi/skfp/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 12 kB image not shown  

Quelle  drvfbi.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/******************************************************************************
 *
 * (C)Copyright 1998,1999 SysKonnect,
 * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
 *
 * See the file "skfddi.c" for further information.
 *
 * The information in this file is provided "AS IS" without warranty.
 *
 ******************************************************************************/


/*
 * FBI board dependent Driver for SMT and LLC
 */


#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#include "h/supern_2.h"
#include "h/skfbiinc.h"
#include <linux/bitrev.h>
#include <linux/pci.h>

/*
 * PCM active state
 */

#define PC8_ACTIVE 8

#define LED_Y_ON 0x11 /* Used for ring up/down indication */
#define LED_Y_OFF 0x10


#define MS2BCLK(x) ((x)*12500L)

/*
 * valid configuration values are:
 */


/*
 * xPOS_ID:xxxx
 * | \  /
 * |  \/
 * |   --------------------- the patched POS_ID of the Adapter
 * | xxxx = (Vendor ID low byte,
 * | Vendor ID high byte,
 * | Device ID low byte,
 * | Device ID high byte)
 * +------------------------------ the patched oem_id must be
 * 'S' for SK or 'I' for IBM
 * this is a short id for the driver.
 */

#ifndef MULT_OEM
#ifndef OEM_CONCEPT
const u_char oem_id[] = "xPOS_ID:xxxx" ;
#else /* OEM_CONCEPT */
const u_char oem_id[] = OEM_ID ;
#endif /* OEM_CONCEPT */
#define ID_BYTE0 8
#define OEMID(smc,i) oem_id[ID_BYTE0 + i]
#else /* MULT_OEM */
const struct s_oem_ids oem_ids[] = {
#include "oemids.h"
{0}
};
#define OEMID(smc,i) smc->hw.oem_id->oi_id[i]
#endif /* MULT_OEM */

/* Prototypes of external functions */
#ifdef AIX
extern int AIX_vpdReadByte() ;
#endif


/* Prototype of a local function. */
static void smt_stop_watchdog(struct s_smc *smc);

/*
 * FDDI card reset
 */

static void card_start(struct s_smc *smc)
{
 int i ;
#ifdef PCI
 u_char rev_id ;
 u_short word;
#endif

 smt_stop_watchdog(smc) ;

#ifdef PCI
 /*
 * make sure no transfer activity is pending
 */

 outpw(FM_A(FM_MDREG1),FM_MINIT) ;
 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;
 /*
 * now reset everything
 */

 outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */
 i = (int) inp(ADDR(B0_CTRL)) ;  /* do dummy read */
 SK_UNUSED(i) ;    /* Make LINT happy. */
 outp(ADDR(B0_CTRL), CTRL_RST_CLR) ;

 /*
 * Reset all bits in the PCI STATUS register
 */

 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ; /* enable for writes */
 word = inpw(PCI_C(PCI_STATUS)) ;
 outpw(PCI_C(PCI_STATUS), word | PCI_STATUS_ERROR_BITS);
 outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ; /* disable writes */

 /*
 * Release the reset of all the State machines
 * Release Master_Reset
 * Release HPI_SM_Reset
 */

 outp(ADDR(B0_CTRL), CTRL_MRST_CLR|CTRL_HPI_CLR) ;

 /*
 * determine the adapter type
 * Note: Do it here, because some drivers may call card_start() once
 *  at very first before any other initialization functions is
 *  executed.
 */

 rev_id = inp(PCI_C(PCI_REVISION_ID)) ;
 if ((rev_id & 0xf0) == SK_ML_ID_1 || (rev_id & 0xf0) == SK_ML_ID_2) {
  smc->hw.hw_is_64bit = TRUE ;
 } else {
  smc->hw.hw_is_64bit = FALSE ;
 }

 /*
 * Watermark initialization
 */

 if (!smc->hw.hw_is_64bit) {
  outpd(ADDR(B4_R1_F), RX_WATERMARK) ;
  outpd(ADDR(B5_XA_F), TX_WATERMARK) ;
  outpd(ADDR(B5_XS_F), TX_WATERMARK) ;
 }

 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* clear the reset chips */
 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_ON|LED_GB_OFF) ; /* ye LED on */

 /* init the timer value for the watch dog 2,5 minutes */
 outpd(ADDR(B2_WDOG_INI),0x6FC23AC0) ;

 /* initialize the ISR mask */
 smc->hw.is_imask = ISR_MASK ;
 smc->hw.hw_state = STOPPED ;
#endif
 GET_PAGE(0) ;  /* necessary for BOOT */
}

void card_stop(struct s_smc *smc)
{
 smt_stop_watchdog(smc) ;
 smc->hw.mac_ring_is_up = 0 ;  /* ring down */

#ifdef PCI
 /*
 * make sure no transfer activity is pending
 */

 outpw(FM_A(FM_MDREG1),FM_MINIT) ;
 outp(ADDR(B0_CTRL), CTRL_HPI_SET) ;
 hwt_wait_time(smc,hwt_quick_read(smc),MS2BCLK(10)) ;
 /*
 * now reset everything
 */

 outp(ADDR(B0_CTRL),CTRL_RST_SET) ; /* reset for all chips */
 outp(ADDR(B0_CTRL),CTRL_RST_CLR) ; /* reset for all chips */
 outp(ADDR(B0_LED),LED_GA_OFF|LED_MY_OFF|LED_GB_OFF) ; /* all LEDs off */
 smc->hw.hw_state = STOPPED ;
#endif
}
/*--------------------------- ISR handling ----------------------------------*/

void mac1_irq(struct s_smc *smc, u_short stu, u_short stl)
{
 int restart_tx = 0 ;
again:

 /*
 * parity error: note encoding error is not possible in tag mode
 */

 if (stl & (FM_SPCEPDS  | /* parity err. syn.q.*/
     FM_SPCEPDA0 | /* parity err. a.q.0 */
     FM_SPCEPDA1)) { /* parity err. a.q.1 */
  SMT_PANIC(smc,SMT_E0134, SMT_E0134_MSG) ;
 }
 /*
 * buffer underrun: can only occur if a tx threshold is specified
 */

 if (stl & (FM_STBURS  |  /* tx buffer underrun syn.q.*/
     FM_STBURA0 |  /* tx buffer underrun a.q.0 */
     FM_STBURA1)) { /* tx buffer underrun a.q.2 */
  SMT_PANIC(smc,SMT_E0133, SMT_E0133_MSG) ;
 }

 if ( (stu & (FM_SXMTABT |  /* transmit abort */
       FM_STXABRS |  /* syn. tx abort */
       FM_STXABRA0)) ||  /* asyn. tx abort */
      (stl & (FM_SQLCKS |  /* lock for syn. q. */
       FM_SQLCKA0)) ) {  /* lock for asyn. q. */
  formac_tx_restart(smc) ; /* init tx */
  restart_tx = 1 ;
  stu = inpw(FM_A(FM_ST1U)) ;
  stl = inpw(FM_A(FM_ST1L)) ;
  stu &= ~ (FM_STECFRMA0 | FM_STEFRMA0 | FM_STEFRMS) ;
  if (stu || stl)
   goto again ;
 }

 if (stu & (FM_STEFRMA0 | /* end of asyn tx */
      FM_STEFRMS)) { /* end of sync tx */
  restart_tx = 1 ;
 }

 if (restart_tx)
  llc_restart_tx(smc) ;
}

/*
 * interrupt source= plc1
 * this function is called in nwfbisr.asm
 */

void plc1_irq(struct s_smc *smc)
{
 u_short st = inpw(PLC(PB,PL_INTR_EVENT)) ;

 plc_irq(smc,PB,st) ;
}

/*
 * interrupt source= plc2
 * this function is called in nwfbisr.asm
 */

void plc2_irq(struct s_smc *smc)
{
 u_short st = inpw(PLC(PA,PL_INTR_EVENT)) ;

 plc_irq(smc,PA,st) ;
}


/*
 * interrupt source= timer
 */

void timer_irq(struct s_smc *smc)
{
 hwt_restart(smc);
 smc->hw.t_stop = smc->hw.t_start;
 smt_timer_done(smc) ;
}

/*
 * return S-port (PA or PB)
 */

int pcm_get_s_port(struct s_smc *smc)
{
 SK_UNUSED(smc) ;
 return PS;
}

/*
 * Station Label = "FDDI-XYZ" where
 *
 * X = connector type
 * Y = PMD type
 * Z = port type
 */

#define STATION_LABEL_CONNECTOR_OFFSET 5
#define STATION_LABEL_PMD_OFFSET 6
#define STATION_LABEL_PORT_OFFSET 7

void read_address(struct s_smc *smc, u_char *mac_addr)
{
 char ConnectorType ;
 char PmdType ;
 int i ;

#ifdef PCI
 for (i = 0; i < 6; i++) { /* read mac address from board */
  smc->hw.fddi_phys_addr.a[i] =
   bitrev8(inp(ADDR(B2_MAC_0+i)));
 }
#endif

 ConnectorType = inp(ADDR(B2_CONN_TYP)) ;
 PmdType = inp(ADDR(B2_PMD_TYP)) ;

 smc->y[PA].pmd_type[PMD_SK_CONN] =
 smc->y[PB].pmd_type[PMD_SK_CONN] = ConnectorType ;
 smc->y[PA].pmd_type[PMD_SK_PMD ] =
 smc->y[PB].pmd_type[PMD_SK_PMD ] = PmdType ;

 if (mac_addr) {
  for (i = 0; i < 6 ;i++) {
   smc->hw.fddi_canon_addr.a[i] = mac_addr[i] ;
   smc->hw.fddi_home_addr.a[i] = bitrev8(mac_addr[i]);
  }
  return ;
 }
 smc->hw.fddi_home_addr = smc->hw.fddi_phys_addr ;

 for (i = 0; i < 6 ;i++) {
  smc->hw.fddi_canon_addr.a[i] =
   bitrev8(smc->hw.fddi_phys_addr.a[i]);
 }
}

/*
 * FDDI card soft reset
 */

void init_board(struct s_smc *smc, u_char *mac_addr)
{
 card_start(smc) ;
 read_address(smc,mac_addr) ;

 if (!(inp(ADDR(B0_DAS)) & DAS_AVAIL))
  smc->s.sas = SMT_SAS ; /* Single att. station */
 else
  smc->s.sas = SMT_DAS ; /* Dual att. station */

 if (!(inp(ADDR(B0_DAS)) & DAS_BYP_ST))
  smc->mib.fddiSMTBypassPresent = 0 ;
  /* without opt. bypass */
 else
  smc->mib.fddiSMTBypassPresent = 1 ;
  /* with opt. bypass */
}

/*
 * insert or deinsert optical bypass (called by ECM)
 */

void sm_pm_bypass_req(struct s_smc *smc, int mode)
{
 DB_ECMN(1, "ECM : sm_pm_bypass_req(%s)",
  mode == BP_INSERT ? "BP_INSERT" : "BP_DEINSERT");

 if (smc->s.sas != SMT_DAS)
  return ;

#ifdef PCI
 switch(mode) {
 case BP_INSERT :
  outp(ADDR(B0_DAS),DAS_BYP_INS) ; /* insert station */
  break ;
 case BP_DEINSERT :
  outp(ADDR(B0_DAS),DAS_BYP_RMV) ; /* bypass station */
  break ;
 }
#endif
}

/*
 * check if bypass connected
 */

int sm_pm_bypass_present(struct s_smc *smc)
{
 return (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE : FALSE;
}

void plc_clear_irq(struct s_smc *smc, int p)
{
 SK_UNUSED(p) ;

 SK_UNUSED(smc) ;
}


/*
 * led_indication called by rmt_indication() and
 * pcm_state_change()
 *
 * Input:
 * smc: SMT context
 * led_event:
 * 0 Only switch green LEDs according to their respective PCM state
 * LED_Y_OFF just switch yellow LED off
 * LED_Y_ON just switch yello LED on
 */

static void led_indication(struct s_smc *smc, int led_event)
{
 /* use smc->hw.mac_ring_is_up == TRUE 
 * as indication for Ring Operational
 */

 u_short   led_state ;
 struct s_phy  *phy ;
 struct fddi_mib_p *mib_a ;
 struct fddi_mib_p *mib_b ;

 phy = &smc->y[PA] ;
 mib_a = phy->mib ;
 phy = &smc->y[PB] ;
 mib_b = phy->mib ;

#ifdef PCI
        led_state = 0 ;
 
 /* Ring up = yellow led OFF*/
 if (led_event == LED_Y_ON) {
  led_state |= LED_MY_ON ;
 }
 else if (led_event == LED_Y_OFF) {
  led_state |= LED_MY_OFF ;
 }
 else { /* PCM state changed */
  /* Link at Port A/S = green led A ON */
  if (mib_a->fddiPORTPCMState == PC8_ACTIVE) { 
   led_state |= LED_GA_ON ;
  }
  else {
   led_state |= LED_GA_OFF ;
  }
  
  /* Link at Port B = green led B ON */
  if (mib_b->fddiPORTPCMState == PC8_ACTIVE) {
   led_state |= LED_GB_ON ;
  }
  else {
   led_state |= LED_GB_OFF ;
  }
 }

        outp(ADDR(B0_LED), led_state) ;
#endif /* PCI */

}


void pcm_state_change(struct s_smc *smc, int plc, int p_state)
{
 /*
 * the current implementation of pcm_state_change() in the driver
 * parts must be renamed to drv_pcm_state_change() which will be called
 * now after led_indication.
 */

 DRV_PCM_STATE_CHANGE(smc,plc,p_state) ;
 
 led_indication(smc,0) ;
}


void rmt_indication(struct s_smc *smc, int i)
{
 /* Call a driver special function if defined */
 DRV_RMT_INDICATION(smc,i) ;

        led_indication(smc, i ? LED_Y_OFF : LED_Y_ON) ;
}


/*
 * llc_recover_tx called by init_tx (fplus.c)
 */

void llc_recover_tx(struct s_smc *smc)
{
#ifdef LOAD_GEN
 extern int load_gen_flag ;

 load_gen_flag = 0 ;
#endif
#ifndef SYNC
 smc->hw.n_a_send= 0 ;
#else
 SK_UNUSED(smc) ;
#endif
}

#ifdef MULT_OEM
static int is_equal_num(char comp1[], char comp2[], int num)
{
 int i ;

 for (i = 0 ; i < num ; i++) {
  if (comp1[i] != comp2[i])
   return 0;
 }
  return 1;
/* is_equal_num */


/*
 * set the OEM ID defaults, and test the contents of the OEM data base
 * The default OEM is the first ACTIVE entry in the OEM data base 
 *
 * returns: 0 success
 * 1 error in data base
 * 2 data base empty
 * 3 no active entry
 */

int set_oi_id_def(struct s_smc *smc)
{
 int sel_id ;
 int i ;
 int act_entries ;

 i = 0 ;
 sel_id = -1 ;
 act_entries = FALSE ;
 smc->hw.oem_id = 0 ;
 smc->hw.oem_min_status = OI_STAT_ACTIVE ;
 
 /* check OEM data base */
 while (oem_ids[i].oi_status) {
  switch (oem_ids[i].oi_status) {
  case OI_STAT_ACTIVE:
   act_entries = TRUE ; /* we have active IDs */
   if (sel_id == -1)
    sel_id = i ; /* save the first active ID */
  case OI_STAT_VALID:
  case OI_STAT_PRESENT:
   i++ ;
   break ;   /* entry ok */
  default:
   return 1;  /* invalid oi_status */
  }
 }

 if (i == 0)
  return 2;
 if (!act_entries)
  return 3;

 /* ok, we have a valid OEM data base with an active entry */
 smc->hw.oem_id = (struct s_oem_ids *)  &oem_ids[sel_id] ;
 return 0;
}
#endif /* MULT_OEM */

void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr)
{
 int i ;

 for (i = 0 ; i < 6 ; i++)
  bia_addr->a[i] = bitrev8(smc->hw.fddi_phys_addr.a[i]);
}

void smt_start_watchdog(struct s_smc *smc)
{
 SK_UNUSED(smc) ; /* Make LINT happy. */

#ifndef DEBUG

#ifdef PCI
 if (smc->hw.wdog_used) {
  outpw(ADDR(B2_WDOG_CRTL),TIM_START) ; /* Start timer. */
 }
#endif

#endif /* DEBUG */
}

static void smt_stop_watchdog(struct s_smc *smc)
{
 SK_UNUSED(smc) ; /* Make LINT happy. */
#ifndef DEBUG

#ifdef PCI
 if (smc->hw.wdog_used) {
  outpw(ADDR(B2_WDOG_CRTL),TIM_STOP) ; /* Stop timer. */
 }
#endif

#endif /* DEBUG */
}

#ifdef PCI

void mac_do_pci_fix(struct s_smc *smc)
{
 SK_UNUSED(smc) ;
}
#endif /* PCI */


Messung V0.5
C=94 H=92 G=92

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.