diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/skfp |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/net/skfp')
41 files changed, 25870 insertions, 0 deletions
diff --git a/drivers/net/skfp/Makefile b/drivers/net/skfp/Makefile new file mode 100644 index 00000000000..6cfccfb7889 --- /dev/null +++ b/drivers/net/skfp/Makefile @@ -0,0 +1,20 @@ +# +# Makefile for the SysKonnect FDDI PCI adapter driver +# + +obj-$(CONFIG_SKFP) += skfp.o + +skfp-objs := skfddi.o hwmtm.o fplustm.o smt.o cfm.o \ + ecm.o pcmplc.o pmf.o queue.o rmt.o \ + smtdef.o smtinit.o smttimer.o srf.o lnkstat.o \ + smtparse.o hwt.o drvfbi.o ess.o + +# NOTE: +# Compiling this driver produces some warnings (and some more are +# switched off below), but I did not fix this, because the Hardware +# Module source (see skfddi.c for details) is used for different +# drivers, and fixing it for Linux might bring problems on other +# projects. To keep the source common for all those drivers (and +# thus simplify fixes to it), please do not clean it up! + +EXTRA_CFLAGS += -Idrivers/net/skfp -DPCI -DMEM_MAPPED_IO -Wno-strict-prototypes diff --git a/drivers/net/skfp/can.c b/drivers/net/skfp/can.c new file mode 100644 index 00000000000..8a49abce796 --- /dev/null +++ b/drivers/net/skfp/can.c @@ -0,0 +1,83 @@ +/****************************************************************************** + * + * (C)Copyright 1998,1999 SysKonnect, + * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * + * See the file "skfddi.c" for further information. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +#ifndef lint +static const char xID_sccs[] = "@(#)can.c 1.5 97/04/07 (C) SK " ; +#endif + +/* + * canonical bit order + */ +const u_char canonical[256] = { + 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0, + 0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0, + 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8, + 0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8, + 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4, + 0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4, + 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec, + 0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc, + 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2, + 0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2, + 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea, + 0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa, + 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6, + 0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6, + 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee, + 0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe, + 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1, + 0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1, + 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9, + 0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9, + 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5, + 0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5, + 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed, + 0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd, + 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3, + 0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3, + 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb, + 0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb, + 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7, + 0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7, + 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef, + 0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff +} ; + +#ifdef MAKE_TABLE +int byte_reverse(x) +int x ; +{ + int y = 0 ; + + if (x & 0x01) + y |= 0x80 ; + if (x & 0x02) + y |= 0x40 ; + if (x & 0x04) + y |= 0x20 ; + if (x & 0x08) + y |= 0x10 ; + if (x & 0x10) + y |= 0x08 ; + if (x & 0x20) + y |= 0x04 ; + if (x & 0x40) + y |= 0x02 ; + if (x & 0x80) + y |= 0x01 ; + return(y) ; +} +#endif diff --git a/drivers/net/skfp/cfm.c b/drivers/net/skfp/cfm.c new file mode 100644 index 00000000000..4c8aaa76233 --- /dev/null +++ b/drivers/net/skfp/cfm.c @@ -0,0 +1,627 @@ +/****************************************************************************** + * + * (C)Copyright 1998,1999 SysKonnect, + * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * + * See the file "skfddi.c" for further information. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +/* + SMT CFM + Configuration Management + DAS with single MAC +*/ + +/* + * Hardware independent state machine implemantation + * The following external SMT functions are referenced : + * + * queue_event() + * + * The following external HW dependent functions are referenced : + * config_mux() + * + * The following HW dependent events are required : + * NONE + */ + +#include "h/types.h" +#include "h/fddi.h" +#include "h/smc.h" + +#define KERNEL +#include "h/smtstate.h" + +#ifndef lint +static const char ID_sccs[] = "@(#)cfm.c 2.18 98/10/06 (C) SK " ; +#endif + +/* + * FSM Macros + */ +#define AFLAG 0x10 +#define GO_STATE(x) (smc->mib.fddiSMTCF_State = (x)|AFLAG) +#define ACTIONS_DONE() (smc->mib.fddiSMTCF_State &= ~AFLAG) +#define ACTIONS(x) (x|AFLAG) + +#ifdef DEBUG +/* + * symbolic state names + */ +static const char * const cfm_states[] = { + "SC0_ISOLATED","CF1","CF2","CF3","CF4", + "SC1_WRAP_A","SC2_WRAP_B","SC5_TRHU_B","SC7_WRAP_S", + "SC9_C_WRAP_A","SC10_C_WRAP_B","SC11_C_WRAP_S","SC4_THRU_A" +} ; + +/* + * symbolic event names + */ +static const char * const cfm_events[] = { + "NONE","CF_LOOP_A","CF_LOOP_B","CF_JOIN_A","CF_JOIN_B" +} ; +#endif + +/* + * map from state to downstream port type + */ +static const u_char cf_to_ptype[] = { + TNONE,TNONE,TNONE,TNONE,TNONE, + TNONE,TB,TB,TS, + TA,TB,TS,TB +} ; + +/* + * CEM port states + */ +#define CEM_PST_DOWN 0 +#define CEM_PST_UP 1 +#define CEM_PST_HOLD 2 +/* define portstate array only for A and B port */ +/* Do this within the smc structure (use in multiple cards) */ + +/* + * all Globals are defined in smc.h + * struct s_cfm + */ + +/* + * function declarations + */ +static void cfm_fsm(struct s_smc *smc, int cmd); + +/* + init CFM state machine + clear all CFM vars and flags +*/ +void cfm_init(struct s_smc *smc) +{ + smc->mib.fddiSMTCF_State = ACTIONS(SC0_ISOLATED) ; + smc->r.rm_join = 0 ; + smc->r.rm_loop = 0 ; + smc->y[PA].scrub = 0 ; + smc->y[PB].scrub = 0 ; + smc->y[PA].cem_pst = CEM_PST_DOWN ; + smc->y[PB].cem_pst = CEM_PST_DOWN ; +} + +/* Some terms conditions used by the selection criteria */ +#define THRU_ENABLED(smc) (smc->y[PA].pc_mode != PM_TREE && \ + smc->y[PB].pc_mode != PM_TREE) +/* Selection criteria for the ports */ +static void selection_criteria (struct s_smc *smc, struct s_phy *phy) +{ + + switch (phy->mib->fddiPORTMy_Type) { + case TA: + if ( !THRU_ENABLED(smc) && smc->y[PB].cf_join ) { + phy->wc_flag = TRUE ; + } else { + phy->wc_flag = FALSE ; + } + + break; + case TB: + /* take precedence over PA */ + phy->wc_flag = FALSE ; + break; + case TS: + phy->wc_flag = FALSE ; + break; + case TM: + phy->wc_flag = FALSE ; + break; + } + +} + +void all_selection_criteria(struct s_smc *smc) +{ + struct s_phy *phy ; + int p ; + + for ( p = 0,phy = smc->y ; p < NUMPHYS; p++, phy++ ) { + /* Do the selection criteria */ + selection_criteria (smc,phy); + } +} + +static void cem_priv_state(struct s_smc *smc, int event) +/* State machine for private PORT states: used to optimize dual homing */ +{ + int np; /* Number of the port */ + int i; + + /* Do this only in a DAS */ + if (smc->s.sas != SMT_DAS ) + return ; + + np = event - CF_JOIN; + + if (np != PA && np != PB) { + return ; + } + /* Change the port state according to the event (portnumber) */ + if (smc->y[np].cf_join) { + smc->y[np].cem_pst = CEM_PST_UP ; + } else if (!smc->y[np].wc_flag) { + /* set the port to done only if it is not withheld */ + smc->y[np].cem_pst = CEM_PST_DOWN ; + } + + /* Don't set an hold port to down */ + + /* Check all ports of restart conditions */ + for (i = 0 ; i < 2 ; i ++ ) { + /* Check all port for PORT is on hold and no withhold is done */ + if ( smc->y[i].cem_pst == CEM_PST_HOLD && !smc->y[i].wc_flag ) { + smc->y[i].cem_pst = CEM_PST_DOWN; + queue_event(smc,(int)(EVENT_PCM+i),PC_START) ; + } + if ( smc->y[i].cem_pst == CEM_PST_UP && smc->y[i].wc_flag ) { + smc->y[i].cem_pst = CEM_PST_HOLD; + queue_event(smc,(int)(EVENT_PCM+i),PC_START) ; + } + if ( smc->y[i].cem_pst == CEM_PST_DOWN && smc->y[i].wc_flag ) { + /* + * The port must be restarted when the wc_flag + * will be reset. So set the port on hold. + */ + smc->y[i].cem_pst = CEM_PST_HOLD; + } + } + return ; +} + +/* + CFM state machine + called by dispatcher + + do + display state change + process event + until SM is stable +*/ +void cfm(struct s_smc *smc, int event) +{ + int state ; /* remember last state */ + int cond ; + int oldstate ; + + /* We will do the following: */ + /* - compute the variable WC_Flag for every port (This is where */ + /* we can extend the requested path checking !!) */ + /* - do the old (SMT 6.2 like) state machine */ + /* - do the resulting station states */ + + all_selection_criteria (smc); + + /* We will check now whether a state transition is allowed or not */ + /* - change the portstates */ + cem_priv_state (smc, event); + + oldstate = smc->mib.fddiSMTCF_State ; + do { + DB_CFM("CFM : state %s%s", + (smc->mib.fddiSMTCF_State & AFLAG) ? "ACTIONS " : "", + cfm_states[smc->mib.fddiSMTCF_State & ~AFLAG]) ; + DB_CFM(" event %s\n",cfm_events[event],0) ; + state = smc->mib.fddiSMTCF_State ; + cfm_fsm(smc,event) ; + event = 0 ; + } while (state != smc->mib.fddiSMTCF_State) ; + +#ifndef SLIM_SMT + /* + * check peer wrap condition + */ + cond = FALSE ; + if ( (smc->mib.fddiSMTCF_State == SC9_C_WRAP_A && + smc->y[PA].pc_mode == PM_PEER) || + (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B && + smc->y[PB].pc_mode == PM_PEER) || + (smc->mib.fddiSMTCF_State == SC11_C_WRAP_S && + smc->y[PS].pc_mode == PM_PEER && + smc->y[PS].mib->fddiPORTNeighborType != TS ) ) { + cond = TRUE ; + } + if (cond != smc->mib.fddiSMTPeerWrapFlag) + smt_srf_event(smc,SMT_COND_SMT_PEER_WRAP,0,cond) ; + +#if 0 + /* + * Don't send ever MAC_PATH_CHANGE events. Our MAC is hard-wired + * to the primary path. + */ + /* + * path change + */ + if (smc->mib.fddiSMTCF_State != oldstate) { + smt_srf_event(smc,SMT_EVENT_MAC_PATH_CHANGE,INDEX_MAC,0) ; + } +#endif +#endif /* no SLIM_SMT */ + + /* + * set MAC port type + */ + smc->mib.m[MAC0].fddiMACDownstreamPORTType = + cf_to_ptype[smc->mib.fddiSMTCF_State] ; + cfm_state_change(smc,(int)smc->mib.fddiSMTCF_State) ; +} + +/* + process CFM event +*/ +/*ARGSUSED1*/ +static void cfm_fsm(struct s_smc *smc, int cmd) +{ + switch(smc->mib.fddiSMTCF_State) { + case ACTIONS(SC0_ISOLATED) : + smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_ISOLATED ; + smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_ISOLATED ; + smc->mib.p[PA].fddiPORTMACPlacement = 0 ; + smc->mib.p[PB].fddiPORTMACPlacement = 0 ; + smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ; + config_mux(smc,MUX_ISOLATE) ; /* configure PHY Mux */ + smc->r.rm_loop = FALSE ; + smc->r.rm_join = FALSE ; + queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */ + /* Don't do the WC-Flag changing here */ + ACTIONS_DONE() ; + DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ; + break; + case SC0_ISOLATED : + /*SC07*/ + /*SAS port can be PA or PB ! */ + if (smc->s.sas && (smc->y[PA].cf_join || smc->y[PA].cf_loop || + smc->y[PB].cf_join || smc->y[PB].cf_loop)) { + GO_STATE(SC11_C_WRAP_S) ; + break ; + } + /*SC01*/ + if ((smc->y[PA].cem_pst == CEM_PST_UP && smc->y[PA].cf_join && + !smc->y[PA].wc_flag) || smc->y[PA].cf_loop) { + GO_STATE(SC9_C_WRAP_A) ; + break ; + } + /*SC02*/ + if ((smc->y[PB].cem_pst == CEM_PST_UP && smc->y[PB].cf_join && + !smc->y[PB].wc_flag) || smc->y[PB].cf_loop) { + GO_STATE(SC10_C_WRAP_B) ; + break ; + } + break ; + case ACTIONS(SC9_C_WRAP_A) : + smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ; + smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_ISOLATED ; + smc->mib.p[PA].fddiPORTMACPlacement = INDEX_MAC ; + smc->mib.p[PB].fddiPORTMACPlacement = 0 ; + smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ; + config_mux(smc,MUX_WRAPA) ; /* configure PHY mux */ + if (smc->y[PA].cf_loop) { + smc->r.rm_join = FALSE ; + smc->r.rm_loop = TRUE ; + queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */ + } + if (smc->y[PA].cf_join) { + smc->r.rm_loop = FALSE ; + smc->r.rm_join = TRUE ; + queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */ + } + ACTIONS_DONE() ; + DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ; + break ; + case SC9_C_WRAP_A : + /*SC10*/ + if ( (smc->y[PA].wc_flag || !smc->y[PA].cf_join) && + !smc->y[PA].cf_loop ) { + GO_STATE(SC0_ISOLATED) ; + break ; + } + /*SC12*/ + else if ( (smc->y[PB].cf_loop && smc->y[PA].cf_join && + smc->y[PA].cem_pst == CEM_PST_UP) || + ((smc->y[PB].cf_loop || + (smc->y[PB].cf_join && + smc->y[PB].cem_pst == CEM_PST_UP)) && + (smc->y[PA].pc_mode == PM_TREE || + smc->y[PB].pc_mode == PM_TREE))) { + smc->y[PA].scrub = TRUE ; + GO_STATE(SC10_C_WRAP_B) ; + break ; + } + /*SC14*/ + else if (!smc->s.attach_s && + smc->y[PA].cf_join && + smc->y[PA].cem_pst == CEM_PST_UP && + smc->y[PA].pc_mode == PM_PEER && smc->y[PB].cf_join && + smc->y[PB].cem_pst == CEM_PST_UP && + smc->y[PB].pc_mode == PM_PEER) { + smc->y[PA].scrub = TRUE ; + smc->y[PB].scrub = TRUE ; + GO_STATE(SC4_THRU_A) ; + break ; + } + /*SC15*/ + else if ( smc->s.attach_s && + smc->y[PA].cf_join && + smc->y[PA].cem_pst == CEM_PST_UP && + smc->y[PA].pc_mode == PM_PEER && + smc->y[PB].cf_join && + smc->y[PB].cem_pst == CEM_PST_UP && + smc->y[PB].pc_mode == PM_PEER) { + smc->y[PA].scrub = TRUE ; + smc->y[PB].scrub = TRUE ; + GO_STATE(SC5_THRU_B) ; + break ; + } + break ; + case ACTIONS(SC10_C_WRAP_B) : + smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_ISOLATED ; + smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ; + smc->mib.p[PA].fddiPORTMACPlacement = 0 ; + smc->mib.p[PB].fddiPORTMACPlacement = INDEX_MAC ; + smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ; + config_mux(smc,MUX_WRAPB) ; /* configure PHY mux */ + if (smc->y[PB].cf_loop) { + smc->r.rm_join = FALSE ; + smc->r.rm_loop = TRUE ; + queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */ + } + if (smc->y[PB].cf_join) { + smc->r.rm_loop = FALSE ; + smc->r.rm_join = TRUE ; + queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */ + } + ACTIONS_DONE() ; + DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ; + break ; + case SC10_C_WRAP_B : + /*SC20*/ + if ( !smc->y[PB].cf_join && !smc->y[PB].cf_loop ) { + GO_STATE(SC0_ISOLATED) ; + break ; + } + /*SC21*/ + else if ( smc->y[PA].cf_loop && smc->y[PA].pc_mode == PM_PEER && + smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) { + smc->y[PB].scrub = TRUE ; + GO_STATE(SC9_C_WRAP_A) ; + break ; + } + /*SC24*/ + else if (!smc->s.attach_s && + smc->y[PA].cf_join && smc->y[PA].pc_mode == PM_PEER && + smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) { + smc->y[PA].scrub = TRUE ; + smc->y[PB].scrub = TRUE ; + GO_STATE(SC4_THRU_A) ; + break ; + } + /*SC25*/ + else if ( smc->s.attach_s && + smc->y[PA].cf_join && smc->y[PA].pc_mode == PM_PEER && + smc->y[PB].cf_join && smc->y[PB].pc_mode == PM_PEER) { + smc->y[PA].scrub = TRUE ; + smc->y[PB].scrub = TRUE ; + GO_STATE(SC5_THRU_B) ; + break ; + } + break ; + case ACTIONS(SC4_THRU_A) : + smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_THRU ; + smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_THRU ; + smc->mib.p[PA].fddiPORTMACPlacement = 0 ; + smc->mib.p[PB].fddiPORTMACPlacement = INDEX_MAC ; + smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_THRU ; + config_mux(smc,MUX_THRUA) ; /* configure PHY mux */ + smc->r.rm_loop = FALSE ; + smc->r.rm_join = TRUE ; + queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */ + ACTIONS_DONE() ; + DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ; + break ; + case SC4_THRU_A : + /*SC41*/ + if (smc->y[PB].wc_flag || !smc->y[PB].cf_join) { + smc->y[PA].scrub = TRUE ; + GO_STATE(SC9_C_WRAP_A) ; + break ; + } + /*SC42*/ + else if (!smc->y[PA].cf_join || smc->y[PA].wc_flag) { + smc->y[PB].scrub = TRUE ; + GO_STATE(SC10_C_WRAP_B) ; + break ; + } + /*SC45*/ + else if (smc->s.attach_s) { + smc->y[PB].scrub = TRUE ; + GO_STATE(SC5_THRU_B) ; + break ; + } + break ; + case ACTIONS(SC5_THRU_B) : + smc->mib.p[PA].fddiPORTCurrentPath = MIB_PATH_THRU ; + smc->mib.p[PB].fddiPORTCurrentPath = MIB_PATH_THRU ; + smc->mib.p[PA].fddiPORTMACPlacement = INDEX_MAC ; + smc->mib.p[PB].fddiPORTMACPlacement = 0 ; + smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_THRU ; + config_mux(smc,MUX_THRUB) ; /* configure PHY mux */ + smc->r.rm_loop = FALSE ; + smc->r.rm_join = TRUE ; + queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */ + ACTIONS_DONE() ; + DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ; + break ; + case SC5_THRU_B : + /*SC51*/ + if (!smc->y[PB].cf_join || smc->y[PB].wc_flag) { + smc->y[PA].scrub = TRUE ; + GO_STATE(SC9_C_WRAP_A) ; + break ; + } + /*SC52*/ + else if (!smc->y[PA].cf_join || smc->y[PA].wc_flag) { + smc->y[PB].scrub = TRUE ; + GO_STATE(SC10_C_WRAP_B) ; + break ; + } + /*SC54*/ + else if (!smc->s.attach_s) { + smc->y[PA].scrub = TRUE ; + GO_STATE(SC4_THRU_A) ; + break ; + } + break ; + case ACTIONS(SC11_C_WRAP_S) : + smc->mib.p[PS].fddiPORTCurrentPath = MIB_PATH_CONCATENATED ; + smc->mib.p[PS].fddiPORTMACPlacement = INDEX_MAC ; + smc->mib.fddiSMTStationStatus = MIB_SMT_STASTA_CON ; + config_mux(smc,MUX_WRAPS) ; /* configure PHY mux */ + if (smc->y[PA].cf_loop || smc->y[PB].cf_loop) { + smc->r.rm_join = FALSE ; + smc->r.rm_loop = TRUE ; + queue_event(smc,EVENT_RMT,RM_LOOP) ;/* signal RMT */ + } + if (smc->y[PA].cf_join || smc->y[PB].cf_join) { + smc->r.rm_loop = FALSE ; + smc->r.rm_join = TRUE ; + queue_event(smc,EVENT_RMT,RM_JOIN) ;/* signal RMT */ + } + ACTIONS_DONE() ; + DB_CFMN(1,"CFM : %s\n",cfm_states[smc->mib.fddiSMTCF_State],0) ; + break ; + case SC11_C_WRAP_S : + /*SC70*/ + if ( !smc->y[PA].cf_join && !smc->y[PA].cf_loop && + !smc->y[PB].cf_join && !smc->y[PB].cf_loop) { + GO_STATE(SC0_ISOLATED) ; + break ; + } + break ; + default: + SMT_PANIC(smc,SMT_E0106, SMT_E0106_MSG) ; + break; + } +} + +/* + * get MAC's input Port + * return : + * PA or PB + */ +int cfm_get_mac_input(struct s_smc *smc) +{ + return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || + smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA) ; +} + +/* + * get MAC's output Port + * return : + * PA or PB + */ +int cfm_get_mac_output(struct s_smc *smc) +{ + return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || + smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA) ; +} + +static char path_iso[] = { + 0,0, 0,RES_PORT, 0,PA + INDEX_PORT, 0,PATH_ISO, + 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_ISO, + 0,0, 0,RES_PORT, 0,PB + INDEX_PORT, 0,PATH_ISO +} ; + +static char path_wrap_a[] = { + 0,0, 0,RES_PORT, 0,PA + INDEX_PORT, 0,PATH_PRIM, + 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_PRIM, + 0,0, 0,RES_PORT, 0,PB + INDEX_PORT, 0,PATH_ISO +} ; + +static char path_wrap_b[] = { + 0,0, 0,RES_PORT, 0,PB + INDEX_PORT, 0,PATH_PRIM, + 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_PRIM, + 0,0, 0,RES_PORT, 0,PA + INDEX_PORT, 0,PATH_ISO +} ; + +static char path_thru[] = { + 0,0, 0,RES_PORT, 0,PA + INDEX_PORT, 0,PATH_PRIM, + 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_PRIM, + 0,0, 0,RES_PORT, 0,PB + INDEX_PORT, 0,PATH_PRIM +} ; + +static char path_wrap_s[] = { + 0,0, 0,RES_PORT, 0,PS + INDEX_PORT, 0,PATH_PRIM, + 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_PRIM, +} ; + +static char path_iso_s[] = { + 0,0, 0,RES_PORT, 0,PS + INDEX_PORT, 0,PATH_ISO, + 0,0, 0,RES_MAC, 0,INDEX_MAC, 0,PATH_ISO, +} ; + +int cem_build_path(struct s_smc *smc, char *to, int path_index) +{ + char *path ; + int len ; + + switch (smc->mib.fddiSMTCF_State) { + default : + case SC0_ISOLATED : + path = smc->s.sas ? path_iso_s : path_iso ; + len = smc->s.sas ? sizeof(path_iso_s) : sizeof(path_iso) ; + break ; + case SC9_C_WRAP_A : + path = path_wrap_a ; + len = sizeof(path_wrap_a) ; + break ; + case SC10_C_WRAP_B : + path = path_wrap_b ; + len = sizeof(path_wrap_b) ; + break ; + case SC4_THRU_A : + path = path_thru ; + len = sizeof(path_thru) ; + break ; + case SC11_C_WRAP_S : + path = path_wrap_s ; + len = sizeof(path_wrap_s) ; + break ; + } + memcpy(to,path,len) ; + + LINT_USE(path_index); + + return(len) ; +} diff --git a/drivers/net/skfp/drvfbi.c b/drivers/net/skfp/drvfbi.c new file mode 100644 index 00000000000..052e841ba18 --- /dev/null +++ b/drivers/net/skfp/drvfbi.c @@ -0,0 +1,1529 @@ +/****************************************************************************** + * + * (C)Copyright 1998,1999 SysKonnect, + * a business unit of Schneider & Koch & Co. Datensysteme GmbH. + * + * See the file "skfddi.c" for further information. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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" + +#ifndef lint +static const char ID_sccs[] = "@(#)drvfbi.c 1.63 99/02/11 (C) SK " ; +#endif + +/* + * 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: + */ +#ifdef ISA +const int opt_ints[] = {8, 3, 4, 5, 9, 10, 11, 12, 15} ; +const int opt_iops[] = {8, + 0x100, 0x120, 0x180, 0x1a0, 0x220, 0x240, 0x320, 0x340}; +const int opt_dmas[] = {4, 3, 5, 6, 7} ; +const int opt_eproms[] = {15, 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, + 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc} ; +#endif +#ifdef EISA +const int opt_ints[] = {5, 9, 10, 11} ; +const int opt_dmas[] = {0, 5, 6, 7} ; +const int opt_eproms[] = {0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, |