Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

77
drivers/net/fddi/Kconfig Normal file
View file

@ -0,0 +1,77 @@
#
# FDDI network device configuration
#
config FDDI
tristate "FDDI driver support"
depends on PCI || EISA || TC
---help---
Fiber Distributed Data Interface is a high speed local area network
design; essentially a replacement for high speed Ethernet. FDDI can
run over copper or fiber. If you are connected to such a network and
want a driver for the FDDI card in your computer, say Y here (and
then also Y to the driver for your FDDI card, below). Most people
will say N.
if FDDI
config DEFXX
tristate "Digital DEFTA/DEFEA/DEFPA adapter support"
depends on FDDI && (PCI || EISA || TC)
---help---
This is support for the DIGITAL series of TURBOchannel (DEFTA),
EISA (DEFEA) and PCI (DEFPA) controllers which can connect you
to a local FDDI network.
To compile this driver as a module, choose M here: the module
will be called defxx. If unsure, say N.
config DEFXX_MMIO
bool
prompt "Use MMIO instead of PIO" if PCI || EISA
depends on DEFXX
default n if PCI || EISA
default y
---help---
This instructs the driver to use EISA or PCI memory-mapped I/O
(MMIO) as appropriate instead of programmed I/O ports (PIO).
Enabling this gives an improvement in processing time in parts
of the driver, but it may cause problems with EISA (DEFEA)
adapters. TURBOchannel does not have the concept of I/O ports,
so MMIO is always used for these (DEFTA) adapters.
If unsure, say N.
config SKFP
tristate "SysKonnect FDDI PCI support"
depends on FDDI && PCI
select BITREVERSE
---help---
Say Y here if you have a SysKonnect FDDI PCI adapter.
The following adapters are supported by this driver:
- SK-5521 (SK-NET FDDI-UP)
- SK-5522 (SK-NET FDDI-UP DAS)
- SK-5541 (SK-NET FDDI-FP)
- SK-5543 (SK-NET FDDI-LP)
- SK-5544 (SK-NET FDDI-LP DAS)
- SK-5821 (SK-NET FDDI-UP64)
- SK-5822 (SK-NET FDDI-UP64 DAS)
- SK-5841 (SK-NET FDDI-FP64)
- SK-5843 (SK-NET FDDI-LP64)
- SK-5844 (SK-NET FDDI-LP64 DAS)
- Netelligent 100 FDDI DAS Fibre SC
- Netelligent 100 FDDI SAS Fibre SC
- Netelligent 100 FDDI DAS UTP
- Netelligent 100 FDDI SAS UTP
- Netelligent 100 FDDI SAS Fibre MIC
Read <file:Documentation/networking/skfp.txt> for information about
the driver.
Questions concerning this driver can be addressed to:
<linux@syskonnect.de>
To compile this driver as a module, choose M here: the module
will be called skfp. This is recommended.
endif # FDDI

View file

@ -0,0 +1,6 @@
#
# Makefile for the Linux FDDI network device drivers.
#
obj-$(CONFIG_DEFXX) += defxx.o
obj-$(CONFIG_SKFP) += skfp/

3788
drivers/net/fddi/defxx.c Normal file

File diff suppressed because it is too large Load diff

1801
drivers/net/fddi/defxx.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -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 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!
ccflags-y := -Idrivers/net/skfp -DPCI -DMEM_MAPPED_IO -Wno-strict-prototypes

627
drivers/net/fddi/skfp/cfm.c Normal file
View file

@ -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 unsigned 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;
}

View file

@ -0,0 +1,584 @@
/******************************************************************************
*
* (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"
#include <linux/bitrev.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:
*/
/*
* 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_ERRBITS) ;
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_REV_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)\n",(mode == BP_INSERT) ?
"BP_INSERT" : "BP_DEINSERT",0) ;
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 */

536
drivers/net/fddi/skfp/ecm.c Normal file
View file

@ -0,0 +1,536 @@
/******************************************************************************
*
* (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 ECM
Entity Coordination Management
Hardware independent state machine
*/
/*
* Hardware independent state machine implemantation
* The following external SMT functions are referenced :
*
* queue_event()
* smt_timer_start()
* smt_timer_stop()
*
* The following external HW dependent functions are referenced :
* sm_pm_bypass_req()
* sm_pm_ls_latch()
* sm_pm_get_ls()
*
* 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[] = "@(#)ecm.c 2.7 99/08/05 (C) SK " ;
#endif
/*
* FSM Macros
*/
#define AFLAG 0x10
#define GO_STATE(x) (smc->mib.fddiSMTECMState = (x)|AFLAG)
#define ACTIONS_DONE() (smc->mib.fddiSMTECMState &= ~AFLAG)
#define ACTIONS(x) (x|AFLAG)
#define EC0_OUT 0 /* not inserted */
#define EC1_IN 1 /* inserted */
#define EC2_TRACE 2 /* tracing */
#define EC3_LEAVE 3 /* leaving the ring */
#define EC4_PATH_TEST 4 /* performing path test */
#define EC5_INSERT 5 /* bypass being turned on */
#define EC6_CHECK 6 /* checking bypass */
#define EC7_DEINSERT 7 /* bypass being turnde off */
#ifdef DEBUG
/*
* symbolic state names
*/
static const char * const ecm_states[] = {
"EC0_OUT","EC1_IN","EC2_TRACE","EC3_LEAVE","EC4_PATH_TEST",
"EC5_INSERT","EC6_CHECK","EC7_DEINSERT"
} ;
/*
* symbolic event names
*/
static const char * const ecm_events[] = {
"NONE","EC_CONNECT","EC_DISCONNECT","EC_TRACE_PROP","EC_PATH_TEST",
"EC_TIMEOUT_TD","EC_TIMEOUT_TMAX",
"EC_TIMEOUT_IMAX","EC_TIMEOUT_INMAX","EC_TEST_DONE"
} ;
#endif
/*
* all Globals are defined in smc.h
* struct s_ecm
*/
/*
* function declarations
*/
static void ecm_fsm(struct s_smc *smc, int cmd);
static void start_ecm_timer(struct s_smc *smc, u_long value, int event);
static void stop_ecm_timer(struct s_smc *smc);
static void prop_actions(struct s_smc *smc);
/*
init ECM state machine
clear all ECM vars and flags
*/
void ecm_init(struct s_smc *smc)
{
smc->e.path_test = PT_PASSED ;
smc->e.trace_prop = 0 ;
smc->e.sb_flag = 0 ;
smc->mib.fddiSMTECMState = ACTIONS(EC0_OUT) ;
smc->e.ecm_line_state = FALSE ;
}
/*
ECM state machine
called by dispatcher
do
display state change
process event
until SM is stable
*/
void ecm(struct s_smc *smc, int event)
{
int state ;
do {
DB_ECM("ECM : state %s%s",
(smc->mib.fddiSMTECMState & AFLAG) ? "ACTIONS " : "",
ecm_states[smc->mib.fddiSMTECMState & ~AFLAG]) ;
DB_ECM(" event %s\n",ecm_events[event],0) ;
state = smc->mib.fddiSMTECMState ;
ecm_fsm(smc,event) ;
event = 0 ;
} while (state != smc->mib.fddiSMTECMState) ;
ecm_state_change(smc,(int)smc->mib.fddiSMTECMState) ;
}
/*
process ECM event
*/
static void ecm_fsm(struct s_smc *smc, int cmd)
{
int ls_a ; /* current line state PHY A */
int ls_b ; /* current line state PHY B */
int p ; /* ports */
smc->mib.fddiSMTBypassPresent = sm_pm_bypass_present(smc) ;
if (cmd == EC_CONNECT)
smc->mib.fddiSMTRemoteDisconnectFlag = FALSE ;
/* For AIX event notification: */
/* Is a disconnect command remotely issued ? */
if (cmd == EC_DISCONNECT &&
smc->mib.fddiSMTRemoteDisconnectFlag == TRUE)
AIX_EVENT (smc, (u_long) CIO_HARD_FAIL, (u_long)
FDDI_REMOTE_DISCONNECT, smt_get_event_word(smc),
smt_get_error_word(smc) );
/*jd 05-Aug-1999 Bug #10419 "Port Disconnect fails at Dup MAc Cond."*/
if (cmd == EC_CONNECT) {
smc->e.DisconnectFlag = FALSE ;
}
else if (cmd == EC_DISCONNECT) {
smc->e.DisconnectFlag = TRUE ;
}
switch(smc->mib.fddiSMTECMState) {
case ACTIONS(EC0_OUT) :
/*
* We do not perform a path test
*/
smc->e.path_test = PT_PASSED ;
smc->e.ecm_line_state = FALSE ;
stop_ecm_timer(smc) ;
ACTIONS_DONE() ;
break ;
case EC0_OUT:
/*EC01*/
if (cmd == EC_CONNECT && !smc->mib.fddiSMTBypassPresent
&& smc->e.path_test==PT_PASSED) {
GO_STATE(EC1_IN) ;
break ;
}
/*EC05*/
else if (cmd == EC_CONNECT && (smc->e.path_test==PT_PASSED) &&
smc->mib.fddiSMTBypassPresent &&
(smc->s.sas == SMT_DAS)) {
GO_STATE(EC5_INSERT) ;
break ;
}
break;
case ACTIONS(EC1_IN) :
stop_ecm_timer(smc) ;
smc->e.trace_prop = 0 ;
sm_ma_control(smc,MA_TREQ) ;
for (p = 0 ; p < NUMPHYS ; p++)
if (smc->mib.p[p].fddiPORTHardwarePresent)
queue_event(smc,EVENT_PCMA+p,PC_START) ;
ACTIONS_DONE() ;
break ;
case EC1_IN:
/*EC12*/
if (cmd == EC_TRACE_PROP) {
prop_actions(smc) ;
GO_STATE(EC2_TRACE) ;
break ;
}
/*EC13*/
else if (cmd == EC_DISCONNECT) {
GO_STATE(EC3_LEAVE) ;
break ;
}
break;
case ACTIONS(EC2_TRACE) :
start_ecm_timer(smc,MIB2US(smc->mib.fddiSMTTrace_MaxExpiration),
EC_TIMEOUT_TMAX) ;
ACTIONS_DONE() ;
break ;
case EC2_TRACE :
/*EC22*/
if (cmd == EC_TRACE_PROP) {
prop_actions(smc) ;
GO_STATE(EC2_TRACE) ;
break ;
}
/*EC23a*/
else if (cmd == EC_DISCONNECT) {
smc->e.path_test = PT_EXITING ;
GO_STATE(EC3_LEAVE) ;
break ;
}
/*EC23b*/
else if (smc->e.path_test == PT_PENDING) {
GO_STATE(EC3_LEAVE) ;
break ;
}
/*EC23c*/
else if (cmd == EC_TIMEOUT_TMAX) {
/* Trace_Max is expired */
/* -> send AIX_EVENT */
AIX_EVENT(smc, (u_long) FDDI_RING_STATUS,
(u_long) FDDI_SMT_ERROR, (u_long)
FDDI_TRACE_MAX, smt_get_error_word(smc));
smc->e.path_test = PT_PENDING ;
GO_STATE(EC3_LEAVE) ;
break ;
}
break ;
case ACTIONS(EC3_LEAVE) :
start_ecm_timer(smc,smc->s.ecm_td_min,EC_TIMEOUT_TD) ;
for (p = 0 ; p < NUMPHYS ; p++)
queue_event(smc,EVENT_PCMA+p,PC_STOP) ;
ACTIONS_DONE() ;
break ;
case EC3_LEAVE:
/*EC30*/
if (cmd == EC_TIMEOUT_TD && !smc->mib.fddiSMTBypassPresent &&
(smc->e.path_test != PT_PENDING)) {
GO_STATE(EC0_OUT) ;
break ;
}
/*EC34*/
else if (cmd == EC_TIMEOUT_TD &&
(smc->e.path_test == PT_PENDING)) {
GO_STATE(EC4_PATH_TEST) ;
break ;
}
/*EC31*/
else if (cmd == EC_CONNECT && smc->e.path_test == PT_PASSED) {
GO_STATE(EC1_IN) ;
break ;
}
/*EC33*/
else if (cmd == EC_DISCONNECT &&
smc->e.path_test == PT_PENDING) {
smc->e.path_test = PT_EXITING ;
/*
* stay in state - state will be left via timeout
*/
}
/*EC37*/
else if (cmd == EC_TIMEOUT_TD &&
smc->mib.fddiSMTBypassPresent &&
smc->e.path_test != PT_PENDING) {
GO_STATE(EC7_DEINSERT) ;
break ;
}
break ;
case ACTIONS(EC4_PATH_TEST) :
stop_ecm_timer(smc) ;
smc->e.path_test = PT_TESTING ;
start_ecm_timer(smc,smc->s.ecm_test_done,EC_TEST_DONE) ;
/* now perform path test ... just a simulation */
ACTIONS_DONE() ;
break ;
case EC4_PATH_TEST :
/* path test done delay */
if (cmd == EC_TEST_DONE)
smc->e.path_test = PT_PASSED ;
if (smc->e.path_test == PT_FAILED)
RS_SET(smc,RS_PATHTEST) ;
/*EC40a*/
if (smc->e.path_test == PT_FAILED &&
!smc->mib.fddiSMTBypassPresent) {
GO_STATE(EC0_OUT) ;
break ;
}
/*EC40b*/
else if (cmd == EC_DISCONNECT &&
!smc->mib.fddiSMTBypassPresent) {
GO_STATE(EC0_OUT) ;
break ;
}
/*EC41*/
else if (smc->e.path_test == PT_PASSED) {
GO_STATE(EC1_IN) ;
break ;
}
/*EC47a*/
else if (smc->e.path_test == PT_FAILED &&
smc->mib.fddiSMTBypassPresent) {
GO_STATE(EC7_DEINSERT) ;
break ;
}
/*EC47b*/
else if (cmd == EC_DISCONNECT &&
smc->mib.fddiSMTBypassPresent) {
GO_STATE(EC7_DEINSERT) ;
break ;
}
break ;
case ACTIONS(EC5_INSERT) :
sm_pm_bypass_req(smc,BP_INSERT);
start_ecm_timer(smc,smc->s.ecm_in_max,EC_TIMEOUT_INMAX) ;
ACTIONS_DONE() ;
break ;
case EC5_INSERT :
/*EC56*/
if (cmd == EC_TIMEOUT_INMAX) {
GO_STATE(EC6_CHECK) ;
break ;
}
/*EC57*/
else if (cmd == EC_DISCONNECT) {
GO_STATE(EC7_DEINSERT) ;
break ;
}
break ;
case ACTIONS(EC6_CHECK) :
/*
* in EC6_CHECK, we *POLL* the line state !
* check whether both bypass switches have switched.
*/
start_ecm_timer(smc,smc->s.ecm_check_poll,0) ;
smc->e.ecm_line_state = TRUE ; /* flag to pcm: report Q/HLS */
(void) sm_pm_ls_latch(smc,PA,1) ; /* enable line state latch */
(void) sm_pm_ls_latch(smc,PB,1) ; /* enable line state latch */
ACTIONS_DONE() ;
break ;
case EC6_CHECK :
ls_a = sm_pm_get_ls(smc,PA) ;
ls_b = sm_pm_get_ls(smc,PB) ;
/*EC61*/
if (((ls_a == PC_QLS) || (ls_a == PC_HLS)) &&
((ls_b == PC_QLS) || (ls_b == PC_HLS)) ) {
smc->e.sb_flag = FALSE ;
smc->e.ecm_line_state = FALSE ;
GO_STATE(EC1_IN) ;
break ;
}
/*EC66*/
else if (!smc->e.sb_flag &&
(((ls_a == PC_ILS) && (ls_b == PC_QLS)) ||
((ls_a == PC_QLS) && (ls_b == PC_ILS)))){
smc->e.sb_flag = TRUE ;
DB_ECMN(1,"ECM : EC6_CHECK - stuck bypass\n",0,0) ;
AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
FDDI_SMT_ERROR, (u_long) FDDI_BYPASS_STUCK,
smt_get_error_word(smc));
}
/*EC67*/
else if (cmd == EC_DISCONNECT) {
smc->e.ecm_line_state = FALSE ;
GO_STATE(EC7_DEINSERT) ;
break ;
}
else {
/*
* restart poll
*/
start_ecm_timer(smc,smc->s.ecm_check_poll,0) ;
}
break ;
case ACTIONS(EC7_DEINSERT) :
sm_pm_bypass_req(smc,BP_DEINSERT);
start_ecm_timer(smc,smc->s.ecm_i_max,EC_TIMEOUT_IMAX) ;
ACTIONS_DONE() ;
break ;
case EC7_DEINSERT:
/*EC70*/
if (cmd == EC_TIMEOUT_IMAX) {
GO_STATE(EC0_OUT) ;
break ;
}
/*EC75*/
else if (cmd == EC_CONNECT && smc->e.path_test == PT_PASSED) {
GO_STATE(EC5_INSERT) ;
break ;
}
break;
default:
SMT_PANIC(smc,SMT_E0107, SMT_E0107_MSG) ;
break;
}
}
#ifndef CONCENTRATOR
/*
* trace propagation actions for SAS & DAS
*/
static void prop_actions(struct s_smc *smc)
{
int port_in = 0 ;
int port_out = 0 ;
RS_SET(smc,RS_EVENT) ;
switch (smc->s.sas) {
case SMT_SAS :
port_in = port_out = pcm_get_s_port(smc) ;
break ;
case SMT_DAS :
port_in = cfm_get_mac_input(smc) ; /* PA or PB */
port_out = cfm_get_mac_output(smc) ; /* PA or PB */
break ;
case SMT_NAC :
SMT_PANIC(smc,SMT_E0108, SMT_E0108_MSG) ;
return ;
}
DB_ECM("ECM : prop_actions - trace_prop %d\n", smc->e.trace_prop,0) ;
DB_ECM("ECM : prop_actions - in %d out %d\n", port_in,port_out) ;
if (smc->e.trace_prop & ENTITY_BIT(ENTITY_MAC)) {
/* trace initiatior */
DB_ECM("ECM : initiate TRACE on PHY %c\n",'A'+port_in-PA,0) ;
queue_event(smc,EVENT_PCM+port_in,PC_TRACE) ;
}
else if ((smc->e.trace_prop & ENTITY_BIT(ENTITY_PHY(PA))) &&
port_out != PA) {
/* trace propagate upstream */
DB_ECM("ECM : propagate TRACE on PHY B\n",0,0) ;
queue_event(smc,EVENT_PCMB,PC_TRACE) ;
}
else if ((smc->e.trace_prop & ENTITY_BIT(ENTITY_PHY(PB))) &&
port_out != PB) {
/* trace propagate upstream */
DB_ECM("ECM : propagate TRACE on PHY A\n",0,0) ;
queue_event(smc,EVENT_PCMA,PC_TRACE) ;
}
else {
/* signal trace termination */
DB_ECM("ECM : TRACE terminated\n",0,0) ;
smc->e.path_test = PT_PENDING ;
}
smc->e.trace_prop = 0 ;
}
#else
/*
* trace propagation actions for Concentrator
*/
static void prop_actions(struct s_smc *smc)
{
int initiator ;
int upstream ;
int p ;
RS_SET(smc,RS_EVENT) ;
while (smc->e.trace_prop) {
DB_ECM("ECM : prop_actions - trace_prop %d\n",
smc->e.trace_prop,0) ;
if (smc->e.trace_prop & ENTITY_BIT(ENTITY_MAC)) {
initiator = ENTITY_MAC ;
smc->e.trace_prop &= ~ENTITY_BIT(ENTITY_MAC) ;
DB_ECM("ECM: MAC initiates trace\n",0,0) ;
}
else {
for (p = NUMPHYS-1 ; p >= 0 ; p--) {
if (smc->e.trace_prop &
ENTITY_BIT(ENTITY_PHY(p)))
break ;
}
initiator = ENTITY_PHY(p) ;
smc->e.trace_prop &= ~ENTITY_BIT(ENTITY_PHY(p)) ;
}
upstream = cem_get_upstream(smc,initiator) ;
if (upstream == ENTITY_MAC) {
/* signal trace termination */
DB_ECM("ECM : TRACE terminated\n",0,0) ;
smc->e.path_test = PT_PENDING ;
}
else {
/* trace propagate upstream */
DB_ECM("ECM : propagate TRACE on PHY %d\n",upstream,0) ;
queue_event(smc,EVENT_PCM+upstream,PC_TRACE) ;
}
}
}
#endif
/*
* SMT timer interface
* start ECM timer
*/
static void start_ecm_timer(struct s_smc *smc, u_long value, int event)
{
smt_timer_start(smc,&smc->e.ecm_timer,value,EV_TOKEN(EVENT_ECM,event));
}
/*
* SMT timer interface
* stop ECM timer
*/
static void stop_ecm_timer(struct s_smc *smc)
{
if (smc->e.ecm_timer.tm_active)
smt_timer_stop(smc,&smc->e.ecm_timer) ;
}

720
drivers/net/fddi/skfp/ess.c Normal file
View file

@ -0,0 +1,720 @@
/******************************************************************************
*
* (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.
*
******************************************************************************/
/*
* *******************************************************************
* This SBA code implements the Synchronous Bandwidth Allocation
* functions described in the "FDDI Synchronous Forum Implementer's
* Agreement" dated December 1th, 1993.
* *******************************************************************
*
* PURPOSE: The purpose of this function is to control
* synchronous allocations on a single FDDI segment.
* Allocations are limited to the primary FDDI ring.
* The SBM provides recovery mechanisms to recover
* unused bandwidth also resolves T_Neg and
* reconfiguration changes. Many of the SBM state
* machine inputs are sourced by the underlying
* FDDI sub-system supporting the SBA application.
*
* *******************************************************************
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#include "h/smt_p.h"
#ifndef SLIM_SMT
#ifdef ESS
#ifndef lint
static const char ID_sccs[] = "@(#)ess.c 1.10 96/02/23 (C) SK" ;
#define LINT_USE(x)
#else
#define LINT_USE(x) (x)=(x)
#endif
#define MS2BCLK(x) ((x)*12500L)
/*
-------------------------------------------------------------
LOCAL VARIABLES:
-------------------------------------------------------------
*/
static const u_short plist_raf_alc_res[] = { SMT_P0012, SMT_P320B, SMT_P320F,
SMT_P3210, SMT_P0019, SMT_P001A,
SMT_P001D, 0 } ;
static const u_short plist_raf_chg_req[] = { SMT_P320B, SMT_P320F, SMT_P3210,
SMT_P001A, 0 } ;
static const struct fddi_addr smt_sba_da = {{0x80,0x01,0x43,0x00,0x80,0x0C}} ;
static const struct fddi_addr null_addr = {{0,0,0,0,0,0}} ;
/*
-------------------------------------------------------------
GLOBAL VARIABLES:
-------------------------------------------------------------
*/
/*
-------------------------------------------------------------
LOCAL FUNCTIONS:
-------------------------------------------------------------
*/
static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
int sba_cmd);
static void ess_config_fifo(struct s_smc *smc);
static void ess_send_alc_req(struct s_smc *smc);
static void ess_send_frame(struct s_smc *smc, SMbuf *mb);
/*
-------------------------------------------------------------
EXTERNAL FUNCTIONS:
-------------------------------------------------------------
*/
/*
-------------------------------------------------------------
PUBLIC FUNCTIONS:
-------------------------------------------------------------
*/
void ess_timer_poll(struct s_smc *smc);
void ess_para_change(struct s_smc *smc);
int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
int fs);
static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead);
/*
* --------------------------------------------------------------------------
* End Station Support (ESS)
* --------------------------------------------------------------------------
*/
/*
* evaluate the RAF frame
*/
int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
int fs)
{
void *p ; /* universal pointer */
struct smt_p_0016 *cmd ; /* para: command for the ESS */
SMbuf *db ;
u_long msg_res_type ; /* recource type */
u_long payload, overhead ;
int local ;
int i ;
/*
* Message Processing Code
*/
local = ((fs & L_INDICATOR) != 0) ;
/*
* get the resource type
*/
if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) {
DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ;
return fs;
}
msg_res_type = ((struct smt_p_0015 *)p)->res_type ;
/*
* get the pointer to the ESS command
*/
if (!(cmd = (struct smt_p_0016 *) sm_to_para(smc,sm,SMT_P0016))) {
/*
* error in frame: para ESS command was not found
*/
DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0);
return fs;
}
DB_ESSN(2,"fc %x ft %x\n",sm->smt_class,sm->smt_type) ;
DB_ESSN(2,"ver %x tran %lx\n",sm->smt_version,sm->smt_tid) ;
DB_ESSN(2,"stn_id %s\n",addr_to_string(&sm->smt_source),0) ;
DB_ESSN(2,"infolen %x res %x\n",sm->smt_len, msg_res_type) ;
DB_ESSN(2,"sbacmd %x\n",cmd->sba_cmd,0) ;
/*
* evaluate the ESS command
*/
switch (cmd->sba_cmd) {
/*
* Process an ESS Allocation Request
*/
case REQUEST_ALLOCATION :
/*
* check for an RAF Request (Allocation Request)
*/
if (sm->smt_type == SMT_REQUEST) {
/*
* process the Allocation request only if the frame is
* local and no static allocation is used
*/
if (!local || smc->mib.fddiESSPayload)
return fs;
p = (void *) sm_to_para(smc,sm,SMT_P0019) ;
for (i = 0; i < 5; i++) {
if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) {
return fs;
}
}
/*
* Note: The Application should send a LAN_LOC_FRAME.
* The ESS do not send the Frame to the network!
*/
smc->ess.alloc_trans_id = sm->smt_tid ;
DB_ESS("ESS: save Alloc Req Trans ID %lx\n",sm->smt_tid,0);
p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
((struct smt_p_320f *)p)->mib_payload =
smc->mib.a[PATH0].fddiPATHSbaPayload ;
p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
((struct smt_p_3210 *)p)->mib_overhead =
smc->mib.a[PATH0].fddiPATHSbaOverhead ;
sm->smt_dest = smt_sba_da ;
if (smc->ess.local_sba_active)
return fs | I_INDICATOR;
if (!(db = smt_get_mbuf(smc)))
return fs;
db->sm_len = mb->sm_len ;
db->sm_off = mb->sm_off ;
memcpy(((char *)(db->sm_data+db->sm_off)),(char *)sm,
(int)db->sm_len) ;
dump_smt(smc,
(struct smt_header *)(db->sm_data+db->sm_off),
"RAF") ;
smt_send_frame(smc,db,FC_SMT_INFO,0) ;
return fs;
}
/*
* The RAF frame is an Allocation Response !
* check the parameters
*/
if (smt_check_para(smc,sm,plist_raf_alc_res)) {
DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
return fs;
}
/*
* VERIFY THE FRAME IS WELL BUILT:
*
* 1. path index = primary ring only
* 2. resource type = sync bw only
* 3. trans action id = alloc_trans_id
* 4. reason code = success
*
* If any are violated, discard the RAF frame
*/
if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
!= PRIMARY_RING) ||
(msg_res_type != SYNC_BW) ||
(((struct smt_p_reason *)sm_to_para(smc,sm,SMT_P0012))->rdf_reason
!= SMT_RDF_SUCCESS) ||
(sm->smt_tid != smc->ess.alloc_trans_id)) {
DB_ESS("ESS: Allocation Response not accepted\n",0,0) ;
return fs;
}
/*
* Extract message parameters
*/
p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
if (!p) {
printk(KERN_ERR "ESS: sm_to_para failed");
return fs;
}
payload = ((struct smt_p_320f *)p)->mib_payload ;
p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
if (!p) {
printk(KERN_ERR "ESS: sm_to_para failed");
return fs;
}
overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
DB_ESSN(2,"payload= %lx overhead= %lx\n",payload,overhead) ;
/*
* process the bandwidth allocation
*/
(void)process_bw_alloc(smc,(long)payload,(long)overhead) ;
return fs;
/* end of Process Allocation Request */
/*
* Process an ESS Change Request
*/
case CHANGE_ALLOCATION :
/*
* except only replies
*/
if (sm->smt_type != SMT_REQUEST) {
DB_ESS("ESS: Do not process Change Responses\n",0,0) ;
return fs;
}
/*
* check the para for the Change Request
*/
if (smt_check_para(smc,sm,plist_raf_chg_req)) {
DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ;
return fs;
}
/*
* Verify the path index and resource
* type are correct. If any of
* these are false, don't process this
* change request frame.
*/
if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index
!= PRIMARY_RING) || (msg_res_type != SYNC_BW)) {
DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ;
return fs;
}
/*
* Extract message queue parameters
*/
p = (void *) sm_to_para(smc,sm,SMT_P320F) ;
payload = ((struct smt_p_320f *)p)->mib_payload ;
p = (void *) sm_to_para(smc,sm,SMT_P3210) ;
overhead = ((struct smt_p_3210 *)p)->mib_overhead ;
DB_ESSN(2,"ESS: Change Request from %s\n",
addr_to_string(&sm->smt_source),0) ;
DB_ESSN(2,"payload= %lx overhead= %lx\n",payload,overhead) ;
/*
* process the bandwidth allocation
*/
if(!process_bw_alloc(smc,(long)payload,(long)overhead))
return fs;
/*
* send an RAF Change Reply
*/
ess_send_response(smc,sm,CHANGE_ALLOCATION) ;
return fs;
/* end of Process Change Request */
/*
* Process Report Response
*/
case REPORT_ALLOCATION :
/*
* except only requests
*/
if (sm->smt_type != SMT_REQUEST) {
DB_ESS("ESS: Do not process a Report Reply\n",0,0) ;
return fs;
}
DB_ESSN(2,"ESS: Report Request from %s\n",
addr_to_string(&(sm->smt_source)),0) ;
/*
* verify that the resource type is sync bw only
*/
if (msg_res_type != SYNC_BW) {
DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ;
return fs;
}
/*
* send an RAF Change Reply
*/
ess_send_response(smc,sm,REPORT_ALLOCATION) ;
return fs;
/* end of Process Report Request */
default:
/*
* error in frame
*/
DB_ESS("ESS: ignoring RAF with bad sba_cmd\n",0,0) ;
break ;
}
return fs;
}
/*
* determines the synchronous bandwidth, set the TSYNC register and the
* mib variables SBAPayload, SBAOverhead and fddiMACT-NEG.
*/
static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhead)
{
/*
* determine the synchronous bandwidth (sync_bw) in bytes per T-NEG,
* if the payload is greater than zero.
* For the SBAPayload and the SBAOverhead we have the following
* unite quations
* _ _
* | bytes |
* SBAPayload = | 8000 ------ |
* | s |
* - -
* _ _
* | bytes |
* SBAOverhead = | ------ |
* | T-NEG |
* - -
*
* T-NEG is described by the equation:
*
* (-) fddiMACT-NEG
* T-NEG = -------------------
* 12500000 1/s
*
* The number of bytes we are able to send is the payload
* plus the overhead.
*
* bytes T-NEG SBAPayload 8000 bytes/s
* sync_bw = SBAOverhead ------ + -----------------------------
* T-NEG T-NEG
*
*
* 1
* sync_bw = SBAOverhead + ---- (-)fddiMACT-NEG * SBAPayload
* 1562
*
*/
/*
* set the mib attributes fddiPATHSbaOverhead, fddiPATHSbaPayload
*/
/* if (smt_set_obj(smc,SMT_P320F,payload,S_SET)) {
DB_ESS("ESS: SMT does not accept the payload value\n",0,0) ;
return FALSE;
}
if (smt_set_obj(smc,SMT_P3210,overhead,S_SET)) {
DB_ESS("ESS: SMT does not accept the overhead value\n",0,0) ;
return FALSE;
} */
/* premliminary */
if (payload > MAX_PAYLOAD || overhead > 5000) {
DB_ESS("ESS: payload / overhead not accepted\n",0,0) ;
return FALSE;
}
/*
* start the iterative allocation process if the payload or the overhead
* are smaller than the parsed values
*/
if (smc->mib.fddiESSPayload &&
((u_long)payload != smc->mib.fddiESSPayload ||
(u_long)overhead != smc->mib.fddiESSOverhead)) {
smc->ess.raf_act_timer_poll = TRUE ;
smc->ess.timer_count = 0 ;
}
/*
* evulate the Payload
*/
if (payload) {
DB_ESSN(2,"ESS: turn SMT_ST_SYNC_SERVICE bit on\n",0,0) ;
smc->ess.sync_bw_available = TRUE ;
smc->ess.sync_bw = overhead -
(long)smc->mib.m[MAC0].fddiMACT_Neg *
payload / 1562 ;
}
else {
DB_ESSN(2,"ESS: turn SMT_ST_SYNC_SERVICE bit off\n",0,0) ;
smc->ess.sync_bw_available = FALSE ;
smc->ess.sync_bw = 0 ;
overhead = 0 ;
}
smc->mib.a[PATH0].fddiPATHSbaPayload = payload ;
smc->mib.a[PATH0].fddiPATHSbaOverhead = overhead ;
DB_ESSN(2,"tsync = %lx\n",smc->ess.sync_bw,0) ;
ess_config_fifo(smc) ;
set_formac_tsync(smc,smc->ess.sync_bw) ;
return TRUE;
}
static void ess_send_response(struct s_smc *smc, struct smt_header *sm,
int sba_cmd)
{
struct smt_sba_chg *chg ;
SMbuf *mb ;
void *p ;
/*
* get and initialize the response frame
*/
if (sba_cmd == CHANGE_ALLOCATION) {
if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
sizeof(struct smt_sba_chg))))
return ;
}
else {
if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REPLY,
sizeof(struct smt_sba_rep_res))))
return ;
}
chg = smtod(mb,struct smt_sba_chg *) ;
chg->smt.smt_tid = sm->smt_tid ;
chg->smt.smt_dest = sm->smt_source ;
/* set P15 */
chg->s_type.para.p_type = SMT_P0015 ;
chg->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
chg->s_type.res_type = SYNC_BW ;
/* set P16 */
chg->cmd.para.p_type = SMT_P0016 ;
chg->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
chg->cmd.sba_cmd = sba_cmd ;
/* set P320B */
chg->path.para.p_type = SMT_P320B ;
chg->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
chg->path.mib_index = SBAPATHINDEX ;
chg->path.path_pad = 0;
chg->path.path_index = PRIMARY_RING ;
/* set P320F */
chg->payload.para.p_type = SMT_P320F ;
chg->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
chg->payload.mib_index = SBAPATHINDEX ;
chg->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;
/* set P3210 */
chg->overhead.para.p_type = SMT_P3210 ;
chg->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
chg->overhead.mib_index = SBAPATHINDEX ;
chg->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;
if (sba_cmd == CHANGE_ALLOCATION) {
/* set P1A */
chg->cat.para.p_type = SMT_P001A ;
chg->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
p = (void *) sm_to_para(smc,sm,SMT_P001A) ;
chg->cat.category = ((struct smt_p_001a *)p)->category ;
}
dump_smt(smc,(struct smt_header *)chg,"RAF") ;
ess_send_frame(smc,mb) ;
}
void ess_timer_poll(struct s_smc *smc)
{
if (!smc->ess.raf_act_timer_poll)
return ;
DB_ESSN(2,"ESS: timer_poll\n",0,0) ;
smc->ess.timer_count++ ;
if (smc->ess.timer_count == 10) {
smc->ess.timer_count = 0 ;
ess_send_alc_req(smc) ;
}
}
static void ess_send_alc_req(struct s_smc *smc)
{
struct smt_sba_alc_req *req ;
SMbuf *mb ;
/*
* send never allocation request where the requested payload and
* overhead is zero or deallocate bandwidth when no bandwidth is
* parsed
*/
if (!smc->mib.fddiESSPayload) {
smc->mib.fddiESSOverhead = 0 ;
}
else {
if (!smc->mib.fddiESSOverhead)
smc->mib.fddiESSOverhead = DEFAULT_OV ;
}
if (smc->mib.fddiESSOverhead ==
smc->mib.a[PATH0].fddiPATHSbaOverhead &&
smc->mib.fddiESSPayload ==
smc->mib.a[PATH0].fddiPATHSbaPayload){
smc->ess.raf_act_timer_poll = FALSE ;
smc->ess.timer_count = 7 ; /* next RAF alc req after 3 s */
return ;
}
/*
* get and initialize the response frame
*/
if (!(mb=smt_build_frame(smc,SMT_RAF,SMT_REQUEST,
sizeof(struct smt_sba_alc_req))))
return ;
req = smtod(mb,struct smt_sba_alc_req *) ;
req->smt.smt_tid = smc->ess.alloc_trans_id = smt_get_tid(smc) ;
req->smt.smt_dest = smt_sba_da ;
/* set P15 */
req->s_type.para.p_type = SMT_P0015 ;
req->s_type.para.p_len = sizeof(struct smt_p_0015) - PARA_LEN ;
req->s_type.res_type = SYNC_BW ;
/* set P16 */
req->cmd.para.p_type = SMT_P0016 ;
req->cmd.para.p_len = sizeof(struct smt_p_0016) - PARA_LEN ;
req->cmd.sba_cmd = REQUEST_ALLOCATION ;
/*
* set the parameter type and parameter length of all used
* parameters
*/
/* set P320B */
req->path.para.p_type = SMT_P320B ;
req->path.para.p_len = sizeof(struct smt_p_320b) - PARA_LEN ;
req->path.mib_index = SBAPATHINDEX ;
req->path.path_pad = 0;
req->path.path_index = PRIMARY_RING ;
/* set P0017 */
req->pl_req.para.p_type = SMT_P0017 ;
req->pl_req.para.p_len = sizeof(struct smt_p_0017) - PARA_LEN ;
req->pl_req.sba_pl_req = smc->mib.fddiESSPayload -
smc->mib.a[PATH0].fddiPATHSbaPayload ;
/* set P0018 */
req->ov_req.para.p_type = SMT_P0018 ;
req->ov_req.para.p_len = sizeof(struct smt_p_0018) - PARA_LEN ;
req->ov_req.sba_ov_req = smc->mib.fddiESSOverhead -
smc->mib.a[PATH0].fddiPATHSbaOverhead ;
/* set P320F */
req->payload.para.p_type = SMT_P320F ;
req->payload.para.p_len = sizeof(struct smt_p_320f) - PARA_LEN ;
req->payload.mib_index = SBAPATHINDEX ;
req->payload.mib_payload = smc->mib.a[PATH0].fddiPATHSbaPayload ;
/* set P3210 */
req->overhead.para.p_type = SMT_P3210 ;
req->overhead.para.p_len = sizeof(struct smt_p_3210) - PARA_LEN ;
req->overhead.mib_index = SBAPATHINDEX ;
req->overhead.mib_overhead = smc->mib.a[PATH0].fddiPATHSbaOverhead ;
/* set P19 */
req->a_addr.para.p_type = SMT_P0019 ;
req->a_addr.para.p_len = sizeof(struct smt_p_0019) - PARA_LEN ;
req->a_addr.sba_pad = 0;
req->a_addr.alloc_addr = null_addr ;
/* set P1A */
req->cat.para.p_type = SMT_P001A ;
req->cat.para.p_len = sizeof(struct smt_p_001a) - PARA_LEN ;
req->cat.category = smc->mib.fddiESSCategory ;
/* set P1B */
req->tneg.para.p_type = SMT_P001B ;
req->tneg.para.p_len = sizeof(struct smt_p_001b) - PARA_LEN ;
req->tneg.max_t_neg = smc->mib.fddiESSMaxTNeg ;
/* set P1C */
req->segm.para.p_type = SMT_P001C ;
req->segm.para.p_len = sizeof(struct smt_p_001c) - PARA_LEN ;
req->segm.min_seg_siz = smc->mib.fddiESSMinSegmentSize ;
dump_smt(smc,(struct smt_header *)req,"RAF") ;
ess_send_frame(smc,mb) ;
}
static void ess_send_frame(struct s_smc *smc, SMbuf *mb)
{
/*
* check if the frame must be send to the own ESS
*/
if (smc->ess.local_sba_active) {
/*
* Send the Change Reply to the local SBA
*/
DB_ESS("ESS:Send to the local SBA\n",0,0) ;
if (!smc->ess.sba_reply_pend)
smc->ess.sba_reply_pend = mb ;
else {
DB_ESS("Frame is lost - another frame was pending\n",0,0);
smt_free_mbuf(smc,mb) ;
}
}
else {
/*
* Send the SBA RAF Change Reply to the network
*/
DB_ESS("ESS:Send to the network\n",0,0) ;
smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
}
}
void ess_para_change(struct s_smc *smc)
{
(void)process_bw_alloc(smc,(long)smc->mib.a[PATH0].fddiPATHSbaPayload,
(long)smc->mib.a[PATH0].fddiPATHSbaOverhead) ;
}
static void ess_config_fifo(struct s_smc *smc)
{
/*
* if nothing to do exit
*/
if (smc->mib.a[PATH0].fddiPATHSbaPayload) {
if (smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON &&
(smc->hw.fp.fifo.fifo_config_mode&SEND_ASYNC_AS_SYNC) ==
smc->mib.fddiESSSynchTxMode) {
return ;
}
}
else {
if (!(smc->hw.fp.fifo.fifo_config_mode & SYNC_TRAFFIC_ON)) {
return ;
}
}
/*
* split up the FIFO and reinitialize the queues
*/
formac_reinit_tx(smc) ;
}
#endif /* ESS */
#endif /* no SLIM_SMT */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,756 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 _CMTDEF_
#define _CMTDEF_
/* **************************************************************** */
/*
* implementation specific constants
* MODIIFY THE FOLLOWING THREE DEFINES
*/
#define AMDPLC /* if Amd PLC chip used */
#ifdef CONC
#define NUMPHYS 12 /* 2 for SAS or DAS, more for Concentrator */
#else
#ifdef CONC_II
#define NUMPHYS 24 /* 2 for SAS or DAS, more for Concentrator */
#else
#define NUMPHYS 2 /* 2 for SAS or DAS, more for Concentrator */
#endif
#endif
#define NUMMACS 1 /* only 1 supported at the moment */
#define NUMPATHS 2 /* primary and secondary path supported */
/*
* DO NOT MODIFY BEYOND THIS POINT
*/
/* **************************************************************** */
#if NUMPHYS > 2
#define CONCENTRATOR
#endif
/*
* Definitions for comfortable LINT usage
*/
#ifdef lint
#define LINT_USE(x) (x)=(x)
#else
#define LINT_USE(x)
#endif
#ifdef DEBUG
#define DB_PR(flag,a,b,c) { if (flag) printf(a,b,c) ; }
#else
#define DB_PR(flag,a,b,c)
#endif
#ifdef DEBUG_BRD
#define DB_ECM(a,b,c) DB_PR((smc->debug.d_smt&1),a,b,c)
#define DB_ECMN(n,a,b,c) DB_PR((smc->debug.d_ecm >=(n)),a,b,c)
#define DB_RMT(a,b,c) DB_PR((smc->debug.d_smt&2),a,b,c)
#define DB_RMTN(n,a,b,c) DB_PR((smc->debug.d_rmt >=(n)),a,b,c)
#define DB_CFM(a,b,c) DB_PR((smc->debug.d_smt&4),a,b,c)
#define DB_CFMN(n,a,b,c) DB_PR((smc->debug.d_cfm >=(n)),a,b,c)
#define DB_PCM(a,b,c) DB_PR((smc->debug.d_smt&8),a,b,c)
#define DB_PCMN(n,a,b,c) DB_PR((smc->debug.d_pcm >=(n)),a,b,c)
#define DB_SMT(a,b,c) DB_PR((smc->debug.d_smtf),a,b,c)
#define DB_SMTN(n,a,b,c) DB_PR((smc->debug.d_smtf >=(n)),a,b,c)
#define DB_SBA(a,b,c) DB_PR((smc->debug.d_sba),a,b,c)
#define DB_SBAN(n,a,b,c) DB_PR((smc->debug.d_sba >=(n)),a,b,c)
#define DB_ESS(a,b,c) DB_PR((smc->debug.d_ess),a,b,c)
#define DB_ESSN(n,a,b,c) DB_PR((smc->debug.d_ess >=(n)),a,b,c)
#else
#define DB_ECM(a,b,c) DB_PR((debug.d_smt&1),a,b,c)
#define DB_ECMN(n,a,b,c) DB_PR((debug.d_ecm >=(n)),a,b,c)
#define DB_RMT(a,b,c) DB_PR((debug.d_smt&2),a,b,c)
#define DB_RMTN(n,a,b,c) DB_PR((debug.d_rmt >=(n)),a,b,c)
#define DB_CFM(a,b,c) DB_PR((debug.d_smt&4),a,b,c)
#define DB_CFMN(n,a,b,c) DB_PR((debug.d_cfm >=(n)),a,b,c)
#define DB_PCM(a,b,c) DB_PR((debug.d_smt&8),a,b,c)
#define DB_PCMN(n,a,b,c) DB_PR((debug.d_pcm >=(n)),a,b,c)
#define DB_SMT(a,b,c) DB_PR((debug.d_smtf),a,b,c)
#define DB_SMTN(n,a,b,c) DB_PR((debug.d_smtf >=(n)),a,b,c)
#define DB_SBA(a,b,c) DB_PR((debug.d_sba),a,b,c)
#define DB_SBAN(n,a,b,c) DB_PR((debug.d_sba >=(n)),a,b,c)
#define DB_ESS(a,b,c) DB_PR((debug.d_ess),a,b,c)
#define DB_ESSN(n,a,b,c) DB_PR((debug.d_ess >=(n)),a,b,c)
#endif
#ifndef SS_NOT_DS
#define SK_LOC_DECL(type,var) type var
#else
#define SK_LOC_DECL(type,var) static type var
#endif
/*
* PHYs and PORTS
* Note: Don't touch the definition of PA and PB. Those might be used
* by some "for" loops.
*/
#define PA 0
#define PB 1
#if defined(SUPERNET_3) || defined(CONC_II)
/*
* The port indices have to be different,
* because the MAC output goes through the 2. PLC
* Conc II: It has to be the first port in the row.
*/
#define PS 0 /* Internal PLC which is the same as PA */
#else
#define PS 1
#endif
#define PM 2 /* PM .. PA+NUM_PHYS-1 */
/*
* PHY types - as in path descriptor 'fddiPHYType'
*/
#define TA 0 /* A port */
#define TB 1 /* B port */
#define TS 2 /* S port */
#define TM 3 /* M port */
#define TNONE 4
/*
* indexes in MIB
*/
#define INDEX_MAC 1
#define INDEX_PATH 1
#define INDEX_PORT 1
/*
* policies
*/
#define POLICY_AA (1<<0) /* reject AA */
#define POLICY_AB (1<<1) /* reject AB */
#define POLICY_AS (1<<2) /* reject AS */
#define POLICY_AM (1<<3) /* reject AM */
#define POLICY_BA (1<<4) /* reject BA */
#define POLICY_BB (1<<5) /* reject BB */
#define POLICY_BS (1<<6) /* reject BS */
#define POLICY_BM (1<<7) /* reject BM */
#define POLICY_SA (1<<8) /* reject SA */
#define POLICY_SB (1<<9) /* reject SB */
#define POLICY_SS (1<<10) /* reject SS */
#define POLICY_SM (1<<11) /* reject SM */
#define POLICY_MA (1<<12) /* reject MA */
#define POLICY_MB (1<<13) /* reject MB */
#define POLICY_MS (1<<14) /* reject MS */
#define POLICY_MM (1<<15) /* reject MM */
/*
* commands
*/
/*
* EVENTS
* event classes
*/
#define EVENT_ECM 1 /* event class ECM */
#define EVENT_CFM 2 /* event class CFM */
#define EVENT_RMT 3 /* event class RMT */
#define EVENT_SMT 4 /* event class SMT */
#define EVENT_PCM 5 /* event class PCM */
#define EVENT_PCMA 5 /* event class PCMA */
#define EVENT_PCMB 6 /* event class PCMB */
/* WARNING :
* EVENT_PCM* must be last in the above list
* if more than two ports are used, EVENT_PCM .. EVENT_PCMA+NUM_PHYS-1
* are used !
*/
#define EV_TOKEN(class,event) (((u_long)(class)<<16L)|((u_long)(event)))
#define EV_T_CLASS(token) ((int)((token)>>16)&0xffff)
#define EV_T_EVENT(token) ((int)(token)&0xffff)
/*
* ECM events
*/
#define EC_CONNECT 1 /* connect request */
#define EC_DISCONNECT 2 /* disconnect request */
#define EC_TRACE_PROP 3 /* trace propagation */
#define EC_PATH_TEST 4 /* path test */
#define EC_TIMEOUT_TD 5 /* timer TD_min */
#define EC_TIMEOUT_TMAX 6 /* timer trace_max */
#define EC_TIMEOUT_IMAX 7 /* timer I_max */
#define EC_TIMEOUT_INMAX 8 /* timer IN_max */
#define EC_TEST_DONE 9 /* path test done */
/*
* CFM events
*/
#define CF_LOOP 1 /* cf_loop flag from PCM */
#define CF_LOOP_A 1 /* cf_loop flag from PCM */
#define CF_LOOP_B 2 /* cf_loop flag from PCM */
#define CF_JOIN 3 /* cf_join flag from PCM */
#define CF_JOIN_A 3 /* cf_join flag from PCM */
#define CF_JOIN_B 4 /* cf_join flag from PCM */
/*
* PCM events
*/
#define PC_START 1
#define PC_STOP 2
#define PC_LOOP 3
#define PC_JOIN 4
#define PC_SIGNAL 5
#define PC_REJECT 6
#define PC_MAINT 7
#define PC_TRACE 8
#define PC_PDR 9
#define PC_ENABLE 10
#define PC_DISABLE 11
/*
* must be ordered as in LineStateType
*/
#define PC_QLS 12
#define PC_ILS 13
#define PC_MLS 14
#define PC_HLS 15
#define PC_LS_PDR 16
#define PC_LS_NONE 17
#define LS2MIB(x) ((x)-PC_QLS)
#define MIB2LS(x) ((x)+PC_QLS)
#define PC_TIMEOUT_TB_MAX 18 /* timer TB_max */
#define PC_TIMEOUT_TB_MIN 19 /* timer TB_min */
#define PC_TIMEOUT_C_MIN 20 /* timer C_Min */
#define PC_TIMEOUT_T_OUT 21 /* timer T_Out */
#define PC_TIMEOUT_TL_MIN 22 /* timer TL_Min */
#define PC_TIMEOUT_T_NEXT 23 /* timer t_next[] */
#define PC_TIMEOUT_LCT 24
#define PC_NSE 25 /* NOISE hardware timer */
#define PC_LEM 26 /* LEM done */
/*
* RMT events meaning from
*/
#define RM_RING_OP 1 /* ring operational MAC */
#define RM_RING_NON_OP 2 /* ring not operational MAC */
#define RM_MY_BEACON 3 /* recvd my beacon MAC */
#define RM_OTHER_BEACON 4 /* recvd other beacon MAC */
#define RM_MY_CLAIM 5 /* recvd my claim MAC */
#define RM_TRT_EXP 6 /* TRT exp MAC */
#define RM_VALID_CLAIM 7 /* claim from dup addr MAC */
#define RM_JOIN 8 /* signal rm_join CFM */
#define RM_LOOP 9 /* signal rm_loop CFM */
#define RM_DUP_ADDR 10 /* dup_addr_test hange SMT-NIF */
#define RM_ENABLE_FLAG 11 /* enable flag */
#define RM_TIMEOUT_NON_OP 12 /* timeout T_Non_OP */
#define RM_TIMEOUT_T_STUCK 13 /* timeout T_Stuck */
#define RM_TIMEOUT_ANNOUNCE 14 /* timeout T_Announce */
#define RM_TIMEOUT_T_DIRECT 15 /* timeout T_Direct */
#define RM_TIMEOUT_D_MAX 16 /* timeout D_Max */
#define RM_TIMEOUT_POLL 17 /* claim/beacon poller */
#define RM_TX_STATE_CHANGE 18 /* To restart timer for D_Max */
/*
* SMT events
*/
#define SM_TIMER 1 /* timer */
#define SM_FAST 2 /* smt_force_irq */
/* PC modes */
#define PM_NONE 0
#define PM_PEER 1
#define PM_TREE 2
/*
* PCM withhold codes
* MIB PC-WithholdType ENUM
*/
#define PC_WH_NONE 0 /* ok */
#define PC_WH_M_M 1 /* M to M */
#define PC_WH_OTHER 2 /* other incompatible phys */
#define PC_WH_PATH 3 /* path not available */
/*
* LCT duration
*/
#define LC_SHORT 1 /* short LCT */
#define LC_MEDIUM 2 /* medium LCT */
#define LC_LONG 3 /* long LCT */
#define LC_EXTENDED 4 /* extended LCT */
/*
* path_test values
*/
#define PT_NONE 0
#define PT_TESTING 1 /* test is running */
#define PT_PASSED 2 /* test passed */
#define PT_FAILED 3 /* test failed */
#define PT_PENDING 4 /* path test follows */
#define PT_EXITING 5 /* disconnected while in trace/leave */
/*
* duplicate address test
* MIB DupAddressTest ENUM
*/
#define DA_NONE 0 /* */
#define DA_PASSED 1 /* test passed */
#define DA_FAILED 2 /* test failed */
/*
* optical bypass
*/
#define BP_DEINSERT 0 /* disable bypass */
#define BP_INSERT 1 /* enable bypass */
/*
* ODL enable/disable
*/
#define PM_TRANSMIT_DISABLE 0 /* disable xmit */
#define PM_TRANSMIT_ENABLE 1 /* enable xmit */
/*
* parameter for config_mux
* note : number is index in config_endec table !
*/
#define MUX_THRUA 0 /* through A */
#define MUX_THRUB 1 /* through B */
#define MUX_WRAPA 2 /* wrap A */
#define MUX_WRAPB 3 /* wrap B */
#define MUX_ISOLATE 4 /* isolated */
#define MUX_WRAPS 5 /* SAS */
/*
* MAC control
*/
#define MA_RESET 0
#define MA_BEACON 1
#define MA_CLAIM 2
#define MA_DIRECTED 3 /* directed beacon */
#define MA_TREQ 4 /* change T_Req */
#define MA_OFFLINE 5 /* switch MAC to offline */
/*
* trace prop
* bit map for trace propagation
*/
#define ENTITY_MAC (NUMPHYS)
#define ENTITY_PHY(p) (p)
#define ENTITY_BIT(m) (1<<(m))
/*
* Resource Tag Types
*/
#define PATH_ISO 0 /* isolated */
#define PATH_PRIM 3 /* primary path */
#define PATH_THRU 5 /* through path */
#define RES_MAC 2 /* resource type MAC */
#define RES_PORT 4 /* resource type PORT */
/*
* CFM state
* oops: MUST MATCH CF-StateType in SMT7.2 !
*/
#define SC0_ISOLATED 0 /* isolated */
#define SC1_WRAP_A 5 /* wrap A (not used) */
#define SC2_WRAP_B 6 /* wrap B (not used) */
#define SC4_THRU_A 12 /* through A */
#define SC5_THRU_B 7 /* through B (used in SMT 6.2) */
#define SC7_WRAP_S 8 /* SAS (not used) */
#define SC9_C_WRAP_A 9 /* c wrap A */
#define SC10_C_WRAP_B 10 /* c wrap B */
#define SC11_C_WRAP_S 11 /* c wrap S */
/*
* convert MIB time in units of 80nS to uS
*/
#define MIB2US(t) ((t)/12)
#define SEC2MIB(s) ((s)*12500000L)
/*
* SMT timer
*/
struct smt_timer {
struct smt_timer *tm_next ; /* linked list */
struct s_smc *tm_smc ; /* pointer to context */
u_long tm_delta ; /* delta time */
u_long tm_token ; /* token value */
u_short tm_active ; /* flag : active/inactive */
u_short tm_pad ; /* pad field */
} ;
/*
* communication structures
*/
struct mac_parameter {
u_long t_neg ; /* T_Neg parameter */
u_long t_pri ; /* T_Pri register in MAC */
} ;
/*
* MAC counters
*/
struct mac_counter {
u_long mac_nobuf_counter ; /* MAC SW counter: no buffer */
u_long mac_r_restart_counter ; /* MAC SW counter: rx restarted */
} ;
/*
* para struct context for SMT parameters
*/
struct s_pcon {
int pc_len ;
int pc_err ;
int pc_badset ;
void *pc_p ;
} ;
/*
* link error monitor
*/
#define LEM_AVG 5
struct lem_counter {
#ifdef AM29K
int lem_on ;
u_long lem_errors ;
u_long lem_symbols ;
u_long lem_tsymbols ;
int lem_s_count ;
int lem_n_s ;
int lem_values ;
int lem_index ;
int lem_avg_ber[LEM_AVG] ;
int lem_sum ;
#else
u_short lem_float_ber ; /* 10E-nn bit error rate */
u_long lem_errors ; /* accumulated error count */
u_short lem_on ;
#endif
} ;
#define NUMBITS 10
#ifdef AMDPLC
/*
* PLC state table
*/
struct s_plc {
u_short p_state ; /* current state */
u_short p_bits ; /* number of bits to send */
u_short p_start ; /* first bit pos */
u_short p_pad ; /* padding for alignment */
u_long soft_err ; /* error counter */
u_long parity_err ; /* error counter */
u_long ebuf_err ; /* error counter */
u_long ebuf_cont ; /* continuous error counter */
u_long phyinv ; /* error counter */
u_long vsym_ctr ; /* error counter */
u_long mini_ctr ; /* error counter */
u_long tpc_exp ; /* error counter */
u_long np_err ; /* error counter */
u_long b_pcs ; /* error counter */
u_long b_tpc ; /* error counter */
u_long b_tne ; /* error counter */
u_long b_qls ; /* error counter */
u_long b_ils ; /* error counter */
u_long b_hls ; /* error counter */
} ;
#endif
#ifdef PROTOTYP_INC
#include "fddi/driver.pro"
#else /* PROTOTYP_INC */
/*
* function prototypes
*/
#include "mbuf.h" /* Type definitions for MBUFs */
#include "smtstate.h" /* struct smt_state */
void hwt_restart(struct s_smc *smc); /* hwt.c */
SMbuf *smt_build_frame(struct s_smc *smc, int class, int type,
int length); /* smt.c */
SMbuf *smt_get_mbuf(struct s_smc *smc); /* drvsr.c */
void *sm_to_para(struct s_smc *smc, struct smt_header *sm,
int para); /* smt.c */
#ifndef SK_UNUSED
#define SK_UNUSED(var) (void)(var)
#endif
void queue_event(struct s_smc *smc, int class, int event);
void ecm(struct s_smc *smc, int event);
void ecm_init(struct s_smc *smc);
void rmt(struct s_smc *smc, int event);
void rmt_init(struct s_smc *smc);
void pcm(struct s_smc *smc, const int np, int event);
void pcm_init(struct s_smc *smc);
void cfm(struct s_smc *smc, int event);
void cfm_init(struct s_smc *smc);
void smt_timer_start(struct s_smc *smc, struct smt_timer *timer, u_long time,
u_long token);
void smt_timer_stop(struct s_smc *smc, struct smt_timer *timer);
void pcm_status_state(struct s_smc *smc, int np, int *type, int *state,
int *remote, int *mac);
void plc_config_mux(struct s_smc *smc, int mux);
void sm_lem_evaluate(struct s_smc *smc);
void mac_update_counter(struct s_smc *smc);
void sm_pm_ls_latch(struct s_smc *smc, int phy, int on_off);
void sm_ma_control(struct s_smc *smc, int mode);
void sm_mac_check_beacon_claim(struct s_smc *smc);
void config_mux(struct s_smc *smc, int mux);
void smt_agent_init(struct s_smc *smc);
void smt_timer_init(struct s_smc *smc);
void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs);
void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para,
int index, int local);
void smt_swap_para(struct smt_header *sm, int len, int direction);
void ev_init(struct s_smc *smc);
void hwt_init(struct s_smc *smc);
u_long hwt_read(struct s_smc *smc);
void hwt_stop(struct s_smc *smc);
void hwt_start(struct s_smc *smc, u_long time);
void smt_send_mbuf(struct s_smc *smc, SMbuf *mb, int fc);
void smt_free_mbuf(struct s_smc *smc, SMbuf *mb);
void sm_pm_bypass_req(struct s_smc *smc, int mode);
void rmt_indication(struct s_smc *smc, int i);
void cfm_state_change(struct s_smc *smc, int c_state);
#if defined(DEBUG) || !defined(NO_SMT_PANIC)
void smt_panic(struct s_smc *smc, char *text);
#else
#define smt_panic(smc,text)
#endif /* DEBUG || !NO_SMT_PANIC */
void smt_stat_counter(struct s_smc *smc, int stat);
void smt_timer_poll(struct s_smc *smc);
u_long smt_get_time(void);
u_long smt_get_tid(struct s_smc *smc);
void smt_timer_done(struct s_smc *smc);
void smt_fixup_mib(struct s_smc *smc);
void smt_reset_defaults(struct s_smc *smc, int level);
void smt_agent_task(struct s_smc *smc);
int smt_check_para(struct s_smc *smc, struct smt_header *sm,
const u_short list[]);
void driver_get_bia(struct s_smc *smc, struct fddi_addr *bia_addr);
#ifdef SUPERNET_3
void drv_reset_indication(struct s_smc *smc);
#endif /* SUPERNET_3 */
void smt_start_watchdog(struct s_smc *smc);
void smt_event(struct s_smc *smc, int event);
void timer_event(struct s_smc *smc, u_long token);
void ev_dispatcher(struct s_smc *smc);
void pcm_get_state(struct s_smc *smc, struct smt_state *state);
void ecm_state_change(struct s_smc *smc, int e_state);
int sm_pm_bypass_present(struct s_smc *smc);
void pcm_state_change(struct s_smc *smc, int plc, int p_state);
void rmt_state_change(struct s_smc *smc, int r_state);
int sm_pm_get_ls(struct s_smc *smc, int phy);
int pcm_get_s_port(struct s_smc *smc);
int pcm_rooted_station(struct s_smc *smc);
int cfm_get_mac_input(struct s_smc *smc);
int cfm_get_mac_output(struct s_smc *smc);
int cem_build_path(struct s_smc *smc, char *to, int path_index);
int sm_mac_get_tx_state(struct s_smc *smc);
char *get_pcmstate(struct s_smc *smc, int np);
int smt_action(struct s_smc *smc, int class, int code, int index);
u_short smt_online(struct s_smc *smc, int on);
void smt_force_irq(struct s_smc *smc);
void smt_pmf_received_pack(struct s_smc *smc, SMbuf *mb, int local);
void smt_send_frame(struct s_smc *smc, SMbuf *mb, int fc, int local);
void smt_set_timestamp(struct s_smc *smc, u_char *p);
void mac_set_rx_mode(struct s_smc *smc, int mode);
int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can);
void mac_update_multicast(struct s_smc *smc);
void mac_clear_multicast(struct s_smc *smc);
void set_formac_tsync(struct s_smc *smc, long sync_bw);
void formac_reinit_tx(struct s_smc *smc);
void formac_tx_restart(struct s_smc *smc);
void process_receive(struct s_smc *smc);
void init_driver_fplus(struct s_smc *smc);
void rtm_irq(struct s_smc *smc);
void rtm_set_timer(struct s_smc *smc);
void ring_status_indication(struct s_smc *smc, u_long status);
void llc_recover_tx(struct s_smc *smc);
void llc_restart_tx(struct s_smc *smc);
void plc_clear_irq(struct s_smc *smc, int p);
void plc_irq(struct s_smc *smc, int np, unsigned int cmd);
int smt_set_mac_opvalues(struct s_smc *smc);
#ifdef TAG_MODE
void mac_do_pci_fix(struct s_smc *smc);
void mac_drv_clear_tx_queue(struct s_smc *smc);
void mac_drv_repair_descr(struct s_smc *smc);
u_long hwt_quick_read(struct s_smc *smc);
void hwt_wait_time(struct s_smc *smc, u_long start, long duration);
#endif
#ifdef SMT_PNMI
int pnmi_init(struct s_smc* smc);
int pnmi_process_ndis_id(struct s_smc *smc, u_long ndis_oid, void *buf, int len,
int *BytesAccessed, int *BytesNeeded, u_char action);
#endif
#ifdef SBA
#ifndef _H2INC
void sba();
#endif
void sba_raf_received_pack();
void sba_timer_poll();
void smt_init_sba();
#endif
#ifdef ESS
int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm,
int fs);
void ess_timer_poll(struct s_smc *smc);
void ess_para_change(struct s_smc *smc);
#endif
#ifndef BOOT
void smt_init_evc(struct s_smc *smc);
void smt_srf_event(struct s_smc *smc, int code, int index, int cond);
#else
#define smt_init_evc(smc)
#define smt_srf_event(smc,code,index,cond)
#endif
#ifndef SMT_REAL_TOKEN_CT
void smt_emulate_token_ct(struct s_smc *smc, int mac_index);
#endif
#if defined(DEBUG) && !defined(BOOT)
void dump_smt(struct s_smc *smc, struct smt_header *sm, char *text);
#else
#define dump_smt(smc,sm,text)
#endif
#ifdef DEBUG
char* addr_to_string(struct fddi_addr *addr);
void dump_hex(char *p, int len);
#endif
#endif /* PROTOTYP_INC */
/* PNMI default defines */
#ifndef PNMI_INIT
#define PNMI_INIT(smc) /* Nothing */
#endif
#ifndef PNMI_GET_ID
#define PNMI_GET_ID( smc, ndis_oid, buf, len, BytesWritten, BytesNeeded ) \
( 1 ? (-1) : (-1) )
#endif
#ifndef PNMI_SET_ID
#define PNMI_SET_ID( smc, ndis_oid, buf, len, BytesRead, BytesNeeded, \
set_type) ( 1 ? (-1) : (-1) )
#endif
/*
* SMT_PANIC defines
*/
#ifndef SMT_PANIC
#define SMT_PANIC(smc,nr,msg) smt_panic (smc, msg)
#endif
#ifndef SMT_ERR_LOG
#define SMT_ERR_LOG(smc,nr,msg) SMT_PANIC (smc, nr, msg)
#endif
#ifndef SMT_EBASE
#define SMT_EBASE 100
#endif
#define SMT_E0100 SMT_EBASE + 0
#define SMT_E0100_MSG "cfm FSM: invalid ce_type"
#define SMT_E0101 SMT_EBASE + 1
#define SMT_E0101_MSG "CEM: case ???"
#define SMT_E0102 SMT_EBASE + 2
#define SMT_E0102_MSG "CEM A: invalid state"
#define SMT_E0103 SMT_EBASE + 3
#define SMT_E0103_MSG "CEM B: invalid state"
#define SMT_E0104 SMT_EBASE + 4
#define SMT_E0104_MSG "CEM M: invalid state"
#define SMT_E0105 SMT_EBASE + 5
#define SMT_E0105_MSG "CEM S: invalid state"
#define SMT_E0106 SMT_EBASE + 6
#define SMT_E0106_MSG "CFM : invalid state"
#define SMT_E0107 SMT_EBASE + 7
#define SMT_E0107_MSG "ECM : invalid state"
#define SMT_E0108 SMT_EBASE + 8
#define SMT_E0108_MSG "prop_actions : NAC in DAS CFM"
#define SMT_E0109 SMT_EBASE + 9
#define SMT_E0109_MSG "ST2U.FM_SERRSF error in special frame"
#define SMT_E0110 SMT_EBASE + 10
#define SMT_E0110_MSG "ST2U.FM_SRFRCTOV recv. count. overflow"
#define SMT_E0111 SMT_EBASE + 11
#define SMT_E0111_MSG "ST2U.FM_SNFSLD NP & FORMAC simult. load"
#define SMT_E0112 SMT_EBASE + 12
#define SMT_E0112_MSG "ST2U.FM_SRCVFRM single-frame recv.-mode"
#define SMT_E0113 SMT_EBASE + 13
#define SMT_E0113_MSG "FPLUS: Buffer Memory Error"
#define SMT_E0114 SMT_EBASE + 14
#define SMT_E0114_MSG "ST2U.FM_SERRSF error in special frame"
#define SMT_E0115 SMT_EBASE + 15
#define SMT_E0115_MSG "ST3L: parity error in receive queue 2"
#define SMT_E0116 SMT_EBASE + 16
#define SMT_E0116_MSG "ST3L: parity error in receive queue 1"
#define SMT_E0117 SMT_EBASE + 17
#define SMT_E0117_MSG "E_SMT_001: RxD count for receive queue 1 = 0"
#define SMT_E0118 SMT_EBASE + 18
#define SMT_E0118_MSG "PCM : invalid state"
#define SMT_E0119 SMT_EBASE + 19
#define SMT_E0119_MSG "smt_add_para"
#define SMT_E0120 SMT_EBASE + 20
#define SMT_E0120_MSG "smt_set_para"
#define SMT_E0121 SMT_EBASE + 21
#define SMT_E0121_MSG "invalid event in dispatcher"
#define SMT_E0122 SMT_EBASE + 22
#define SMT_E0122_MSG "RMT : invalid state"
#define SMT_E0123 SMT_EBASE + 23
#define SMT_E0123_MSG "SBA: state machine has invalid state"
#define SMT_E0124 SMT_EBASE + 24
#define SMT_E0124_MSG "sba_free_session() called with NULL pointer"
#define SMT_E0125 SMT_EBASE + 25
#define SMT_E0125_MSG "SBA : invalid session pointer"
#define SMT_E0126 SMT_EBASE + 26
#define SMT_E0126_MSG "smt_free_mbuf() called with NULL pointer\n"
#define SMT_E0127 SMT_EBASE + 27
#define SMT_E0127_MSG "sizeof evcs"
#define SMT_E0128 SMT_EBASE + 28
#define SMT_E0128_MSG "evc->evc_cond_state = 0"
#define SMT_E0129 SMT_EBASE + 29
#define SMT_E0129_MSG "evc->evc_multiple = 0"
#define SMT_E0130 SMT_EBASE + 30
#define SMT_E0130_MSG write_mdr_warning
#define SMT_E0131 SMT_EBASE + 31
#define SMT_E0131_MSG cam_warning
#define SMT_E0132 SMT_EBASE + 32
#define SMT_E0132_MSG "ST1L.FM_SPCEPDx parity/coding error"
#define SMT_E0133 SMT_EBASE + 33
#define SMT_E0133_MSG "ST1L.FM_STBURx tx buffer underrun"
#define SMT_E0134 SMT_EBASE + 34
#define SMT_E0134_MSG "ST1L.FM_SPCEPDx parity error"
#define SMT_E0135 SMT_EBASE + 35
#define SMT_E0135_MSG "RMT: duplicate MAC address detected. Ring left!"
#define SMT_E0136 SMT_EBASE + 36
#define SMT_E0136_MSG "Elasticity Buffer hang-up"
#define SMT_E0137 SMT_EBASE + 37
#define SMT_E0137_MSG "SMT: queue overrun"
#define SMT_E0138 SMT_EBASE + 38
#define SMT_E0138_MSG "RMT: duplicate MAC address detected. Ring NOT left!"
#endif /* _CMTDEF_ */

View file

@ -0,0 +1,69 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 _FDDI_
#define _FDDI_
struct fddi_addr {
u_char a[6] ;
} ;
#define GROUP_ADDR 0x80 /* MSB in a[0] */
struct fddi_mac {
struct fddi_addr mac_dest ;
struct fddi_addr mac_source ;
u_char mac_info[4478] ;
} ;
#define FDDI_MAC_SIZE (12)
#define FDDI_RAW_MTU (4500-5) /* exl. Pr,SD, ED/FS */
#define FDDI_RAW (4500)
/*
* FC values
*/
#define FC_VOID 0x40 /* void frame */
#define FC_TOKEN 0x80 /* token */
#define FC_RES_TOKEN 0xc0 /* restricted token */
#define FC_SMT_INFO 0x41 /* SMT Info frame */
/*
* FC_SMT_LAN_LOC && FC_SMT_LOC are SK specific !
*/
#define FC_SMT_LAN_LOC 0x42 /* local SMT Info frame */
#define FC_SMT_LOC 0x43 /* local SMT Info frame */
#define FC_SMT_NSA 0x4f /* SMT NSA frame */
#define FC_MAC 0xc0 /* MAC frame */
#define FC_BEACON 0xc2 /* MAC beacon frame */
#define FC_CLAIM 0xc3 /* MAC claim frame */
#define FC_SYNC_LLC 0xd0 /* sync. LLC frame */
#define FC_ASYNC_LLC 0x50 /* async. LLC frame */
#define FC_SYNC_BIT 0x80 /* sync. bit in FC */
#define FC_LLC_PRIOR 0x07 /* priority bits */
#define BEACON_INFO 0 /* beacon type */
#define DBEACON_INFO 1 /* beacon type DIRECTED */
/*
* indicator bits
*/
#define C_INDICATOR (1<<0)
#define A_INDICATOR (1<<1)
#define E_INDICATOR (1<<2)
#define I_INDICATOR (1<<6) /* SK specific */
#define L_INDICATOR (1<<7) /* SK specific */
#endif /* _FDDI_ */

View file

@ -0,0 +1,349 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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.
*
******************************************************************************/
/*
* FDDI MIB
*/
/*
* typedefs
*/
typedef u_long Counter ;
typedef u_char TimeStamp[8] ;
typedef struct fddi_addr LongAddr ;
typedef u_long Timer_2 ;
typedef u_long Timer ;
typedef u_short ResId ;
typedef u_short SMTEnum ;
typedef u_char SMTFlag ;
typedef struct {
Counter count ;
TimeStamp timestamp ;
} SetCountType ;
/*
* bits for bit string "available_path"
*/
#define MIB_PATH_P (1<<0)
#define MIB_PATH_S (1<<1)
#define MIB_PATH_L (1<<2)
/*
* bits for bit string PermittedPaths & RequestedPaths (SIZE(8))
*/
#define MIB_P_PATH_LOCAL (1<<0)
#define MIB_P_PATH_SEC_ALTER (1<<1)
#define MIB_P_PATH_PRIM_ALTER (1<<2)
#define MIB_P_PATH_CON_ALTER (1<<3)
#define MIB_P_PATH_SEC_PREFER (1<<4)
#define MIB_P_PATH_PRIM_PREFER (1<<5)
#define MIB_P_PATH_CON_PREFER (1<<6)
#define MIB_P_PATH_THRU (1<<7)
/*
* enum current path
*/
#define MIB_PATH_ISOLATED 0
#define MIB_PATH_LOCAL 1
#define MIB_PATH_SECONDARY 2
#define MIB_PATH_PRIMARY 3
#define MIB_PATH_CONCATENATED 4
#define MIB_PATH_THRU 5
/*
* enum PMDClass
*/
#define MIB_PMDCLASS_MULTI 0
#define MIB_PMDCLASS_SINGLE1 1
#define MIB_PMDCLASS_SINGLE2 2
#define MIB_PMDCLASS_SONET 3
#define MIB_PMDCLASS_LCF 4
#define MIB_PMDCLASS_TP 5
#define MIB_PMDCLASS_UNKNOWN 6
#define MIB_PMDCLASS_UNSPEC 7
/*
* enum SMTStationStatus
*/
#define MIB_SMT_STASTA_CON 0
#define MIB_SMT_STASTA_SEPA 1
#define MIB_SMT_STASTA_THRU 2
struct fddi_mib {
/*
* private
*/
u_char fddiPRPMFPasswd[8] ;
struct smt_sid fddiPRPMFStation ;
#ifdef ESS
/*
* private variables for static allocation of the
* End Station Support
*/
u_long fddiESSPayload ; /* payload for static alloc */
u_long fddiESSOverhead ; /* frame ov for static alloc */
u_long fddiESSMaxTNeg ; /* maximum of T-NEG */
u_long fddiESSMinSegmentSize ; /* min size of the sync frames */
u_long fddiESSCategory ; /* category for the Alloc req */
short fddiESSSynchTxMode ; /* send all LLC frames as sync */
#endif /* ESS */
#ifdef SBA
/*
* private variables for the Synchronous Bandwidth Allocator
*/
char fddiSBACommand ; /* holds the parsed SBA cmd */
u_char fddiSBAAvailable ; /* SBA allocatable value */
#endif /* SBA */
/*
* SMT standard mib
*/
struct smt_sid fddiSMTStationId ;
u_short fddiSMTOpVersionId ;
u_short fddiSMTHiVersionId ;
u_short fddiSMTLoVersionId ;
u_char fddiSMTManufacturerData[32] ;
u_char fddiSMTUserData[32] ;
u_short fddiSMTMIBVersionId ;
/*
* ConfigGrp
*/
u_char fddiSMTMac_Ct ;
u_char fddiSMTNonMaster_Ct ;
u_char fddiSMTMaster_Ct ;
u_char fddiSMTAvailablePaths ;
u_short fddiSMTConfigCapabilities ;
u_short fddiSMTConfigPolicy ;
u_short fddiSMTConnectionPolicy ;
u_short fddiSMTTT_Notify ;
u_char fddiSMTStatRptPolicy ;
u_long fddiSMTTrace_MaxExpiration ;
u_short fddiSMTPORTIndexes[NUMPHYS] ;
u_short fddiSMTMACIndexes ;
u_char fddiSMTBypassPresent ;
/*
* StatusGrp
*/
SMTEnum fddiSMTECMState ;
SMTEnum fddiSMTCF_State ;
SMTEnum fddiSMTStationStatus ;
u_char fddiSMTRemoteDisconnectFlag ;
u_char fddiSMTPeerWrapFlag ;
/*
* MIBOperationGrp
*/
TimeStamp fddiSMTTimeStamp ;
TimeStamp fddiSMTTransitionTimeStamp ;
SetCountType fddiSMTSetCount ;
struct smt_sid fddiSMTLastSetStationId ;
struct fddi_mib_m {
u_short fddiMACFrameStatusFunctions ;
Timer_2 fddiMACT_MaxCapabilitiy ;
Timer_2 fddiMACTVXCapabilitiy ;
/* ConfigGrp */
u_char fddiMACMultiple_N ; /* private */
u_char fddiMACMultiple_P ; /* private */
u_char fddiMACDuplicateAddressCond ;/* private */
u_char fddiMACAvailablePaths ;
u_short fddiMACCurrentPath ;
LongAddr fddiMACUpstreamNbr ;
LongAddr fddiMACDownstreamNbr ;
LongAddr fddiMACOldUpstreamNbr ;
LongAddr fddiMACOldDownstreamNbr ;
SMTEnum fddiMACDupAddressTest ;
u_short fddiMACRequestedPaths ;
SMTEnum fddiMACDownstreamPORTType ;
ResId fddiMACIndex ;
/* AddressGrp */
LongAddr fddiMACSMTAddress ;
/* OperationGrp */
Timer_2 fddiMACT_Min ; /* private */
Timer_2 fddiMACT_ReqMIB ;
Timer_2 fddiMACT_Req ; /* private */
Timer_2 fddiMACT_Neg ;
Timer_2 fddiMACT_MaxMIB ;
Timer_2 fddiMACT_Max ; /* private */
Timer_2 fddiMACTvxValueMIB ;
Timer_2 fddiMACTvxValue ; /* private */
Timer_2 fddiMACT_Pri0 ;
Timer_2 fddiMACT_Pri1 ;
Timer_2 fddiMACT_Pri2 ;
Timer_2 fddiMACT_Pri3 ;
Timer_2 fddiMACT_Pri4 ;
Timer_2 fddiMACT_Pri5 ;
Timer_2 fddiMACT_Pri6 ;
/* CountersGrp */
Counter fddiMACFrame_Ct ;
Counter fddiMACCopied_Ct ;
Counter fddiMACTransmit_Ct ;
Counter fddiMACToken_Ct ;
Counter fddiMACError_Ct ;
Counter fddiMACLost_Ct ;
Counter fddiMACTvxExpired_Ct ;
Counter fddiMACNotCopied_Ct ;
Counter fddiMACRingOp_Ct ;
Counter fddiMACSMTCopied_Ct ; /* private */
Counter fddiMACSMTTransmit_Ct ; /* private */
/* private for delta ratio */
Counter fddiMACOld_Frame_Ct ;
Counter fddiMACOld_Copied_Ct ;
Counter fddiMACOld_Error_Ct ;
Counter fddiMACOld_Lost_Ct ;
Counter fddiMACOld_NotCopied_Ct ;
/* FrameErrorConditionGrp */
u_short fddiMACFrameErrorThreshold ;
u_short fddiMACFrameErrorRatio ;
/* NotCopiedConditionGrp */
u_short fddiMACNotCopiedThreshold ;
u_short fddiMACNotCopiedRatio ;
/* StatusGrp */
SMTEnum fddiMACRMTState ;
SMTFlag fddiMACDA_Flag ;
SMTFlag fddiMACUNDA_Flag ;
SMTFlag fddiMACFrameErrorFlag ;
SMTFlag fddiMACNotCopiedFlag ;
SMTFlag fddiMACMA_UnitdataAvailable ;
SMTFlag fddiMACHardwarePresent ;
SMTFlag fddiMACMA_UnitdataEnable ;
} m[NUMMACS] ;
#define MAC0 0
struct fddi_mib_a {
ResId fddiPATHIndex ;
u_long fddiPATHSbaPayload ;
u_long fddiPATHSbaOverhead ;
/* fddiPATHConfiguration is built on demand */
/* u_long fddiPATHConfiguration ; */
Timer fddiPATHT_Rmode ;
u_long fddiPATHSbaAvailable ;
Timer_2 fddiPATHTVXLowerBound ;
Timer_2 fddiPATHT_MaxLowerBound ;
Timer_2 fddiPATHMaxT_Req ;
} a[NUMPATHS] ;
#define PATH0 0
struct fddi_mib_p {
/* ConfigGrp */
SMTEnum fddiPORTMy_Type ;
SMTEnum fddiPORTNeighborType ;
u_char fddiPORTConnectionPolicies ;
struct {
u_char T_val ;
u_char R_val ;
} fddiPORTMacIndicated ;
SMTEnum fddiPORTCurrentPath ;
/* must be 4: is 32 bit in SMT format
* indices :
* 1 none
* 2 tree
* 3 peer
*/
u_char fddiPORTRequestedPaths[4] ;
u_short fddiPORTMACPlacement ;
u_char fddiPORTAvailablePaths ;
u_char fddiPORTConnectionCapabilities ;
SMTEnum fddiPORTPMDClass ;
ResId fddiPORTIndex ;
/* OperationGrp */
SMTEnum fddiPORTMaint_LS ;
SMTEnum fddiPORTPC_LS ;
u_char fddiPORTBS_Flag ;
/* ErrorCtrsGrp */
Counter fddiPORTLCTFail_Ct ;
Counter fddiPORTEBError_Ct ;
Counter fddiPORTOldEBError_Ct ;
/* LerGrp */
Counter fddiPORTLem_Reject_Ct ;
Counter fddiPORTLem_Ct ;
u_char fddiPORTLer_Estimate ;
u_char fddiPORTLer_Cutoff ;
u_char fddiPORTLer_Alarm ;
/* StatusGrp */
SMTEnum fddiPORTConnectState ;
SMTEnum fddiPORTPCMState ; /* real value */
SMTEnum fddiPORTPCMStateX ; /* value for MIB */
SMTEnum fddiPORTPC_Withhold ;
SMTFlag fddiPORTHardwarePresent ;
u_char fddiPORTLerFlag ;
u_char fddiPORTMultiple_U ; /* private */
u_char fddiPORTMultiple_P ; /* private */
u_char fddiPORTEB_Condition ; /* private */
} p[NUMPHYS] ;
struct {
Counter fddiPRIVECF_Req_Rx ; /* ECF req received */
Counter fddiPRIVECF_Reply_Rx ; /* ECF repl received */
Counter fddiPRIVECF_Req_Tx ; /* ECF req transm */
Counter fddiPRIVECF_Reply_Tx ; /* ECF repl transm */
Counter fddiPRIVPMF_Get_Rx ; /* PMF Get rec */
Counter fddiPRIVPMF_Set_Rx ; /* PMF Set rec */
Counter fddiPRIVRDF_Rx ; /* RDF received */
Counter fddiPRIVRDF_Tx ; /* RDF transmitted */
} priv ;
} ;
/*
* OIDs for statistics
*/
#define SMT_OID_CF_STATE 1 /* fddiSMTCF_State */
#define SMT_OID_PCM_STATE_A 2 /* fddiPORTPCMState port A */
#define SMT_OID_PCM_STATE_B 17 /* fddiPORTPCMState port B */
#define SMT_OID_RMT_STATE 3 /* fddiMACRMTState */
#define SMT_OID_UNA 4 /* fddiMACUpstreamNbr */
#define SMT_OID_DNA 5 /* fddiMACOldDownstreamNbr */
#define SMT_OID_ERROR_CT 6 /* fddiMACError_Ct */
#define SMT_OID_LOST_CT 7 /* fddiMACLost_Ct */
#define SMT_OID_LEM_CT 8 /* fddiPORTLem_Ct */
#define SMT_OID_LEM_CT_A 11 /* fddiPORTLem_Ct port A */
#define SMT_OID_LEM_CT_B 12 /* fddiPORTLem_Ct port B */
#define SMT_OID_LCT_FAIL_CT 9 /* fddiPORTLCTFail_Ct */
#define SMT_OID_LCT_FAIL_CT_A 13 /* fddiPORTLCTFail_Ct port A */
#define SMT_OID_LCT_FAIL_CT_B 14 /* fddiPORTLCTFail_Ct port B */
#define SMT_OID_LEM_REJECT_CT 10 /* fddiPORTLem_Reject_Ct */
#define SMT_OID_LEM_REJECT_CT_A 15 /* fddiPORTLem_Reject_Ct port A */
#define SMT_OID_LEM_REJECT_CT_B 16 /* fddiPORTLem_Reject_Ct port B */
/*
* SK MIB
*/
#define SMT_OID_ECF_REQ_RX 20 /* ECF requests received */
#define SMT_OID_ECF_REPLY_RX 21 /* ECF replies received */
#define SMT_OID_ECF_REQ_TX 22 /* ECF requests transmitted */
#define SMT_OID_ECF_REPLY_TX 23 /* ECF replies transmitted */
#define SMT_OID_PMF_GET_RX 24 /* PMF get requests received */
#define SMT_OID_PMF_SET_RX 25 /* PMF set requests received */
#define SMT_OID_RDF_RX 26 /* RDF received */
#define SMT_OID_RDF_TX 27 /* RDF transmitted */

View file

@ -0,0 +1,274 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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.
*
******************************************************************************/
/*
* AMD Fplus in tag mode data structs
* defs for fplustm.c
*/
#ifndef _FPLUS_
#define _FPLUS_
#ifndef HW_PTR
#define HW_PTR void __iomem *
#endif
/*
* fplus error statistic structure
*/
struct err_st {
u_long err_valid ; /* memory status valid */
u_long err_abort ; /* memory status receive abort */
u_long err_e_indicator ; /* error indicator */
u_long err_crc ; /* error detected (CRC or length) */
u_long err_llc_frame ; /* LLC frame */
u_long err_mac_frame ; /* MAC frame */
u_long err_smt_frame ; /* SMT frame */
u_long err_imp_frame ; /* implementer frame */
u_long err_no_buf ; /* no buffer available */
u_long err_too_long ; /* longer than max. buffer */
u_long err_bec_stat ; /* beacon state entered */
u_long err_clm_stat ; /* claim state entered */
u_long err_sifg_det ; /* short interframe gap detect */
u_long err_phinv ; /* PHY invalid */
u_long err_tkiss ; /* token issued */
u_long err_tkerr ; /* token error */
} ;
/*
* Transmit Descriptor struct
*/
struct s_smt_fp_txd {
__le32 txd_tbctrl ; /* transmit buffer control */
__le32 txd_txdscr ; /* transmit frame status word */
__le32 txd_tbadr ; /* physical tx buffer address */
__le32 txd_ntdadr ; /* physical pointer to the next TxD */
#ifdef ENA_64BIT_SUP
__le32 txd_tbadr_hi ; /* physical tx buffer addr (high dword)*/
#endif
char far *txd_virt ; /* virtual pointer to the data frag */
/* virt pointer to the next TxD */
struct s_smt_fp_txd volatile far *txd_next ;
struct s_txd_os txd_os ; /* OS - specific struct */
} ;
/*
* Receive Descriptor struct
*/
struct s_smt_fp_rxd {
__le32 rxd_rbctrl ; /* receive buffer control */
__le32 rxd_rfsw ; /* receive frame status word */
__le32 rxd_rbadr ; /* physical rx buffer address */
__le32 rxd_nrdadr ; /* physical pointer to the next RxD */
#ifdef ENA_64BIT_SUP
__le32 rxd_rbadr_hi ; /* physical tx buffer addr (high dword)*/
#endif
char far *rxd_virt ; /* virtual pointer to the data frag */
/* virt pointer to the next RxD */
struct s_smt_fp_rxd volatile far *rxd_next ;
struct s_rxd_os rxd_os ; /* OS - specific struct */
} ;
/*
* Descriptor Union Definition
*/
union s_fp_descr {
struct s_smt_fp_txd t ; /* pointer to the TxD */
struct s_smt_fp_rxd r ; /* pointer to the RxD */
} ;
/*
* TxD Ring Control struct
*/
struct s_smt_tx_queue {
struct s_smt_fp_txd volatile *tx_curr_put ; /* next free TxD */
struct s_smt_fp_txd volatile *tx_prev_put ; /* shadow put pointer */
struct s_smt_fp_txd volatile *tx_curr_get ; /* next TxD to release*/
u_short tx_free ; /* count of free TxD's */
u_short tx_used ; /* count of used TxD's */
HW_PTR tx_bmu_ctl ; /* BMU addr for tx start */
HW_PTR tx_bmu_dsc ; /* BMU addr for curr dsc. */
} ;
/*
* RxD Ring Control struct
*/
struct s_smt_rx_queue {
struct s_smt_fp_rxd volatile *rx_curr_put ; /* next RxD to queue into */
struct s_smt_fp_rxd volatile *rx_prev_put ; /* shadow put pointer */
struct s_smt_fp_rxd volatile *rx_curr_get ; /* next RxD to fill */
u_short rx_free ; /* count of free RxD's */
u_short rx_used ; /* count of used RxD's */
HW_PTR rx_bmu_ctl ; /* BMU addr for rx start */
HW_PTR rx_bmu_dsc ; /* BMU addr for curr dsc. */
} ;
#define VOID_FRAME_OFF 0x00
#define CLAIM_FRAME_OFF 0x08
#define BEACON_FRAME_OFF 0x10
#define DBEACON_FRAME_OFF 0x18
#define RX_FIFO_OFF 0x21 /* to get a prime number for */
/* the RX_FIFO_SPACE */
#define RBC_MEM_SIZE 0x8000
#define SEND_ASYNC_AS_SYNC 0x1
#define SYNC_TRAFFIC_ON 0x2
/* big FIFO memory */
#define RX_FIFO_SPACE 0x4000 - RX_FIFO_OFF
#define TX_FIFO_SPACE 0x4000
#define TX_SMALL_FIFO 0x0900
#define TX_MEDIUM_FIFO TX_FIFO_SPACE / 2
#define TX_LARGE_FIFO TX_FIFO_SPACE - TX_SMALL_FIFO
#define RX_SMALL_FIFO 0x0900
#define RX_LARGE_FIFO RX_FIFO_SPACE - RX_SMALL_FIFO
struct s_smt_fifo_conf {
u_short rbc_ram_start ; /* FIFO start address */
u_short rbc_ram_end ; /* FIFO size */
u_short rx1_fifo_start ; /* rx queue start address */
u_short rx1_fifo_size ; /* rx queue size */
u_short rx2_fifo_start ; /* rx queue start address */
u_short rx2_fifo_size ; /* rx queue size */
u_short tx_s_start ; /* sync queue start address */
u_short tx_s_size ; /* sync queue size */
u_short tx_a0_start ; /* async queue A0 start address */
u_short tx_a0_size ; /* async queue A0 size */
u_short fifo_config_mode ; /* FIFO configuration mode */
} ;
#define FM_ADDRX (FM_ADDET|FM_EXGPA0|FM_EXGPA1)
struct s_smt_fp {
u_short mdr2init ; /* mode register 2 init value */
u_short mdr3init ; /* mode register 3 init value */
u_short frselreg_init ; /* frame selection register init val */
u_short rx_mode ; /* address mode broad/multi/promisc */
u_short nsa_mode ;
u_short rx_prom ;
u_short exgpa ;
struct err_st err_stats ; /* error statistics */
/*
* MAC buffers
*/
struct fddi_mac_sf { /* special frame build buffer */
u_char mac_fc ;
struct fddi_addr mac_dest ;
struct fddi_addr mac_source ;
u_char mac_info[0x20] ;
} mac_sfb ;
/*
* queues
*/
#define QUEUE_S 0
#define QUEUE_A0 1
#define QUEUE_R1 0
#define QUEUE_R2 1
#define USED_QUEUES 2
/*
* queue pointers; points to the queue dependent variables
*/
struct s_smt_tx_queue *tx[USED_QUEUES] ;
struct s_smt_rx_queue *rx[USED_QUEUES] ;
/*
* queue dependent variables
*/
struct s_smt_tx_queue tx_q[USED_QUEUES] ;
struct s_smt_rx_queue rx_q[USED_QUEUES] ;
/*
* FIFO configuration struct
*/
struct s_smt_fifo_conf fifo ;
/* last formac status */
u_short s2u ;
u_short s2l ;
/* calculated FORMAC+ reg.addr. */
HW_PTR fm_st1u ;
HW_PTR fm_st1l ;
HW_PTR fm_st2u ;
HW_PTR fm_st2l ;
HW_PTR fm_st3u ;
HW_PTR fm_st3l ;
/*
* multicast table
*/
#define FPMAX_MULTICAST 32
#define SMT_MAX_MULTI 4
struct {
struct s_fpmc {
struct fddi_addr a ; /* mc address */
u_char n ; /* usage counter */
u_char perm ; /* flag: permanent */
} table[FPMAX_MULTICAST] ;
} mc ;
struct fddi_addr group_addr ;
u_long func_addr ; /* functional address */
int smt_slots_used ; /* count of table entries for the SMT */
int os_slots_used ; /* count of table entries */
/* used by the os-specific module */
} ;
/*
* modes for mac_set_rx_mode()
*/
#define RX_ENABLE_ALLMULTI 1 /* enable all multicasts */
#define RX_DISABLE_ALLMULTI 2 /* disable "enable all multicasts" */
#define RX_ENABLE_PROMISC 3 /* enable promiscuous */
#define RX_DISABLE_PROMISC 4 /* disable promiscuous */
#define RX_ENABLE_NSA 5 /* enable reception of NSA frames */
#define RX_DISABLE_NSA 6 /* disable reception of NSA frames */
/*
* support for byte reversal in AIX
* (descriptors and pointers must be byte reversed in memory
* CPU is big endian; M-Channel is little endian)
*/
#ifdef AIX
#define MDR_REV
#define AIX_REVERSE(x) ((((x)<<24L)&0xff000000L) + \
(((x)<< 8L)&0x00ff0000L) + \
(((x)>> 8L)&0x0000ff00L) + \
(((x)>>24L)&0x000000ffL))
#else
#ifndef AIX_REVERSE
#define AIX_REVERSE(x) (x)
#endif
#endif
#ifdef MDR_REV
#define MDR_REVERSE(x) ((((x)<<24L)&0xff000000L) + \
(((x)<< 8L)&0x00ff0000L) + \
(((x)>> 8L)&0x0000ff00L) + \
(((x)>>24L)&0x000000ffL))
#else
#ifndef MDR_REVERSE
#define MDR_REVERSE(x) (x)
#endif
#endif
#endif

View file

@ -0,0 +1,399 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 _HWM_
#define _HWM_
#include "mbuf.h"
/*
* MACRO for DMA synchronization:
* The descriptor 'desc' is flushed for the device 'flag'.
* Devices are the CPU (DDI_DMA_SYNC_FORCPU) and the
* adapter (DDI_DMA_SYNC_FORDEV).
*
* 'desc' Pointer to a Rx or Tx descriptor.
* 'flag' Flag for direction (view for CPU or DEVICE) that
* should be synchronized.
*
* Empty macros and defines are specified here. The real macro
* is os-specific and should be defined in osdef1st.h.
*/
#ifndef DRV_BUF_FLUSH
#define DRV_BUF_FLUSH(desc,flag)
#define DDI_DMA_SYNC_FORCPU
#define DDI_DMA_SYNC_FORDEV
#endif
/*
* hardware modul dependent receive modes
*/
#define RX_ENABLE_PASS_SMT 21
#define RX_DISABLE_PASS_SMT 22
#define RX_ENABLE_PASS_NSA 23
#define RX_DISABLE_PASS_NSA 24
#define RX_ENABLE_PASS_DB 25
#define RX_DISABLE_PASS_DB 26
#define RX_DISABLE_PASS_ALL 27
#define RX_DISABLE_LLC_PROMISC 28
#define RX_ENABLE_LLC_PROMISC 29
#ifndef DMA_RD
#define DMA_RD 1 /* memory -> hw */
#endif
#ifndef DMA_WR
#define DMA_WR 2 /* hw -> memory */
#endif
#define SMT_BUF 0x80
/*
* bits of the frame status byte
*/
#define EN_IRQ_EOF 0x02 /* get IRQ after end of frame transmission */
#define LOC_TX 0x04 /* send frame to the local SMT */
#define LAST_FRAG 0x08 /* last TxD of the frame */
#define FIRST_FRAG 0x10 /* first TxD of the frame */
#define LAN_TX 0x20 /* send frame to network if set */
#define RING_DOWN 0x40 /* error: unable to send, ring down */
#define OUT_OF_TXD 0x80 /* error: not enough TxDs available */
#ifndef NULL
#define NULL 0
#endif
#ifdef LITTLE_ENDIAN
#define HWM_REVERSE(x) (x)
#else
#define HWM_REVERSE(x) ((((x)<<24L)&0xff000000L) + \
(((x)<< 8L)&0x00ff0000L) + \
(((x)>> 8L)&0x0000ff00L) + \
(((x)>>24L)&0x000000ffL))
#endif
#define C_INDIC (1L<<25)
#define A_INDIC (1L<<26)
#define RD_FS_LOCAL 0x80
/*
* DEBUG FLAGS
*/
#define DEBUG_SMTF 1
#define DEBUG_SMT 2
#define DEBUG_ECM 3
#define DEBUG_RMT 4
#define DEBUG_CFM 5
#define DEBUG_PCM 6
#define DEBUG_SBA 7
#define DEBUG_ESS 8
#define DB_HWM_RX 10
#define DB_HWM_TX 11
#define DB_HWM_GEN 12
struct s_mbuf_pool {
#ifndef MB_OUTSIDE_SMC
SMbuf mb[MAX_MBUF] ; /* mbuf pool */
#endif
SMbuf *mb_start ; /* points to the first mb */
SMbuf *mb_free ; /* free queue */
} ;
struct hwm_r {
/*
* hardware modul specific receive variables
*/
u_int len ; /* length of the whole frame */
char *mb_pos ; /* SMbuf receive position */
} ;
struct hw_modul {
/*
* All hardware modul specific variables
*/
struct s_mbuf_pool mbuf_pool ;
struct hwm_r r ;
union s_fp_descr volatile *descr_p ; /* points to the desriptor area */
u_short pass_SMT ; /* pass SMT frames */
u_short pass_NSA ; /* pass all NSA frames */
u_short pass_DB ; /* pass Direct Beacon Frames */
u_short pass_llc_promisc ; /* pass all llc frames (default ON) */
SMbuf *llc_rx_pipe ; /* points to the first queued llc fr */
SMbuf *llc_rx_tail ; /* points to the last queued llc fr */
int queued_rx_frames ; /* number of queued frames */
SMbuf *txd_tx_pipe ; /* points to first mb in the txd ring */
SMbuf *txd_tx_tail ; /* points to last mb in the txd ring */
int queued_txd_mb ; /* number of SMT MBufs in txd ring */
int rx_break ; /* rev. was breaked because ind. off */
int leave_isr ; /* leave fddi_isr immedeately if set */
int isr_flag ; /* set, when HWM is entered from isr */
/*
* variables for the current transmit frame
*/
struct s_smt_tx_queue *tx_p ; /* pointer to the transmit queue */
u_long tx_descr ; /* tx descriptor for FORMAC+ */
int tx_len ; /* tx frame length */
SMbuf *tx_mb ; /* SMT tx MBuf pointer */
char *tx_data ; /* data pointer to the SMT tx Mbuf */
int detec_count ; /* counter for out of RxD condition */
u_long rx_len_error ; /* rx len FORMAC != sum of fragments */
} ;
/*
* DEBUG structs and macros
*/
#ifdef DEBUG
struct os_debug {
int hwm_rx ;
int hwm_tx ;
int hwm_gen ;
} ;
#endif
#ifdef DEBUG
#ifdef DEBUG_BRD
#define DB_P smc->debug
#else
#define DB_P debug
#endif
#define DB_RX(a,b,c,lev) if (DB_P.d_os.hwm_rx >= (lev)) printf(a,b,c)
#define DB_TX(a,b,c,lev) if (DB_P.d_os.hwm_tx >= (lev)) printf(a,b,c)
#define DB_GEN(a,b,c,lev) if (DB_P.d_os.hwm_gen >= (lev)) printf(a,b,c)
#else /* DEBUG */
#define DB_RX(a,b,c,lev)
#define DB_TX(a,b,c,lev)
#define DB_GEN(a,b,c,lev)
#endif /* DEBUG */
#ifndef SK_BREAK
#define SK_BREAK()
#endif
/*
* HWM Macros
*/
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_TX_PHYS)
* u_long HWM_GET_TX_PHYS(txd)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to read
* the physical address of the specified TxD.
*
* para txd pointer to the TxD
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_TX_PHYS(txd) (u_long)AIX_REVERSE((txd)->txd_tbadr)
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_TX_LEN)
* int HWM_GET_TX_LEN(txd)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to read
* the fragment length of the specified TxD
*
* para rxd pointer to the TxD
*
* return the length of the fragment in bytes
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_TX_LEN(txd) ((int)AIX_REVERSE((txd)->txd_tbctrl)& RD_LENGTH)
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_TX_USED)
* txd *HWM_GET_TX_USED(smc,queue)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to get the
* number of used TxDs for the queue, specified by the index.
*
* para queue the number of the send queue: Can be specified by
* QUEUE_A0, QUEUE_S or (frame_status & QUEUE_A0)
*
* return number of used TxDs for this send queue
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_TX_USED(smc,queue) (int) (smc)->hw.fp.tx_q[queue].tx_used
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_CURR_TXD)
* txd *HWM_GET_CURR_TXD(smc,queue)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to get the
* pointer to the TxD which points to the current queue put
* position.
*
* para queue the number of the send queue: Can be specified by
* QUEUE_A0, QUEUE_S or (frame_status & QUEUE_A0)
*
* return pointer to the current TxD
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_CURR_TXD(smc,queue) (struct s_smt_fp_txd volatile *)\
(smc)->hw.fp.tx_q[queue].tx_curr_put
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_RX_FRAG_LEN)
* int HWM_GET_RX_FRAG_LEN(rxd)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to read
* the fragment length of the specified RxD
*
* para rxd pointer to the RxD
*
* return the length of the fragment in bytes
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_RX_FRAG_LEN(rxd) ((int)AIX_REVERSE((rxd)->rxd_rbctrl)& \
RD_LENGTH)
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_RX_PHYS)
* u_long HWM_GET_RX_PHYS(rxd)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to read
* the physical address of the specified RxD.
*
* para rxd pointer to the RxD
*
* return the RxD's physical pointer to the data fragment
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_RX_PHYS(rxd) (u_long)AIX_REVERSE((rxd)->rxd_rbadr)
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_RX_USED)
* int HWM_GET_RX_USED(smc)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to get
* the count of used RXDs in receive queue 1.
*
* return the used RXD count of receive queue 1
*
* NOTE: Remember, because of an ASIC bug at least one RXD should be unused
* in the descriptor ring !
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_RX_USED(smc) ((int)(smc)->hw.fp.rx_q[QUEUE_R1].rx_used)
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_RX_FREE)
* int HWM_GET_RX_FREE(smc)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to get
* the rxd_free count of receive queue 1.
*
* return the rxd_free count of receive queue 1
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_RX_FREE(smc) ((int)(smc)->hw.fp.rx_q[QUEUE_R1].rx_free-1)
/*
* BEGIN_MANUAL_ENTRY(HWM_GET_CURR_RXD)
* rxd *HWM_GET_CURR_RXD(smc)
*
* function MACRO (hardware module, hwmtm.h)
* This macro may be invoked by the OS-specific module to get the
* pointer to the RxD which points to the current queue put
* position.
*
* return pointer to the current RxD
*
* END_MANUAL_ENTRY
*/
#define HWM_GET_CURR_RXD(smc) (struct s_smt_fp_rxd volatile *)\
(smc)->hw.fp.rx_q[QUEUE_R1].rx_curr_put
/*
* BEGIN_MANUAL_ENTRY(HWM_RX_CHECK)
* void HWM_RX_CHECK(smc,low_water)
*
* function MACRO (hardware module, hwmtm.h)
* This macro is invoked by the OS-specific before it left the
* function mac_drv_rx_complete. This macro calls mac_drv_fill_rxd
* if the number of used RxDs is equal or lower than the
* the given low water mark.
*
* para low_water low water mark of used RxD's
*
* END_MANUAL_ENTRY
*/
#ifndef HWM_NO_FLOW_CTL
#define HWM_RX_CHECK(smc,low_water) {\
if ((low_water) >= (smc)->hw.fp.rx_q[QUEUE_R1].rx_used) {\
mac_drv_fill_rxd(smc) ;\
}\
}
#else
#define HWM_RX_CHECK(smc,low_water) mac_drv_fill_rxd(smc)
#endif
#ifndef HWM_EBASE
#define HWM_EBASE 500
#endif
#define HWM_E0001 HWM_EBASE + 1
#define HWM_E0001_MSG "HWM: Wrong size of s_rxd_os struct"
#define HWM_E0002 HWM_EBASE + 2
#define HWM_E0002_MSG "HWM: Wrong size of s_txd_os struct"
#define HWM_E0003 HWM_EBASE + 3
#define HWM_E0003_MSG "HWM: smt_free_mbuf() called with NULL pointer"
#define HWM_E0004 HWM_EBASE + 4
#define HWM_E0004_MSG "HWM: Parity error rx queue 1"
#define HWM_E0005 HWM_EBASE + 5
#define HWM_E0005_MSG "HWM: Encoding error rx queue 1"
#define HWM_E0006 HWM_EBASE + 6
#define HWM_E0006_MSG "HWM: Encoding error async tx queue"
#define HWM_E0007 HWM_EBASE + 7
#define HWM_E0007_MSG "HWM: Encoding error sync tx queue"
#define HWM_E0008 HWM_EBASE + 8
#define HWM_E0008_MSG ""
#define HWM_E0009 HWM_EBASE + 9
#define HWM_E0009_MSG "HWM: Out of RxD condition detected"
#define HWM_E0010 HWM_EBASE + 10
#define HWM_E0010_MSG "HWM: A protocol layer has tried to send a frame with an invalid frame control"
#define HWM_E0011 HWM_EBASE + 11
#define HWM_E0011_MSG "HWM: mac_drv_clear_tx_queue was called although the hardware wasn't stopped"
#define HWM_E0012 HWM_EBASE + 12
#define HWM_E0012_MSG "HWM: mac_drv_clear_rx_queue was called although the hardware wasn't stopped"
#define HWM_E0013 HWM_EBASE + 13
#define HWM_E0013_MSG "HWM: mac_drv_repair_descr was called although the hardware wasn't stopped"
#endif

View file

@ -0,0 +1,50 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 _MBUF_
#define _MBUF_
#define M_SIZE 4504
#ifndef MAX_MBUF
#define MAX_MBUF 4
#endif
#ifndef NO_STD_MBUF
#define sm_next m_next
#define sm_off m_off
#define sm_len m_len
#define sm_data m_data
#define SMbuf Mbuf
#define mtod smtod
#define mtodoff smtodoff
#endif
struct s_mbuf {
struct s_mbuf *sm_next ; /* low level linked list */
short sm_off ; /* offset in m_data */
u_int sm_len ; /* len of data */
#ifdef PCI
int sm_use_count ;
#endif
char sm_data[M_SIZE] ;
} ;
typedef struct s_mbuf SMbuf ;
/* mbuf head, to typed data */
#define smtod(x,t) ((t)((x)->sm_data + (x)->sm_off))
#define smtodoff(x,t,o) ((t)((x)->sm_data + (o)))
#endif /* _MBUF_ */

View file

@ -0,0 +1,125 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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.
*
******************************************************************************/
/*
* Operating system-dependent definitions that have to be defined
* before any other header files are included.
*/
// HWM (HardWare Module) Definitions
// -----------------------
#include <asm/byteorder.h>
#ifdef __LITTLE_ENDIAN
#define LITTLE_ENDIAN
#else
#define BIG_ENDIAN
#endif
// this is set in the makefile
// #define PCI /* only PCI adapters supported by this driver */
// #define MEM_MAPPED_IO /* use memory mapped I/O */
#define USE_CAN_ADDR /* DA and SA in MAC header are canonical. */
#define MB_OUTSIDE_SMC /* SMT Mbufs outside of smc struct. */
// -----------------------
// SMT Definitions
// -----------------------
#define SYNC /* allow synchronous frames */
// #define SBA /* Synchronous Bandwidth Allocator support */
/* not available as free source */
#define ESS /* SBA End Station Support */
#define SMT_PANIC(smc, nr, msg) printk(KERN_INFO "SMT PANIC: code: %d, msg: %s\n",nr,msg)
#ifdef DEBUG
#define printf(s,args...) printk(KERN_INFO s, ## args)
#endif
// #define HW_PTR u_long
// -----------------------
// HWM and OS-specific buffer definitions
// -----------------------
// default number of receive buffers.
#define NUM_RECEIVE_BUFFERS 10
// default number of transmit buffers.
#define NUM_TRANSMIT_BUFFERS 10
// Number of SMT buffers (Mbufs).
#define NUM_SMT_BUF 4
// Number of TXDs for asynchronous transmit queue.
#define HWM_ASYNC_TXD_COUNT (NUM_TRANSMIT_BUFFERS + NUM_SMT_BUF)
// Number of TXDs for synchronous transmit queue.
#define HWM_SYNC_TXD_COUNT HWM_ASYNC_TXD_COUNT
// Number of RXDs for receive queue #1.
// Note: Workaround for ASIC Errata #7: One extra RXD is required.
#if (NUM_RECEIVE_BUFFERS > 100)
#define SMT_R1_RXD_COUNT (1 + 100)
#else
#define SMT_R1_RXD_COUNT (1 + NUM_RECEIVE_BUFFERS)
#endif
// Number of RXDs for receive queue #2.
#define SMT_R2_RXD_COUNT 0 // Not used.
// -----------------------
/*
* OS-specific part of the transmit/receive descriptor structure (TXD/RXD).
*
* Note: The size of these structures must follow this rule:
*
* sizeof(struct) + 2*sizeof(void*) == n * 16, n >= 1
*
* We use the dma_addr fields under Linux to keep track of the
* DMA address of the packet data, for later pci_unmap_single. -DaveM
*/
struct s_txd_os { // os-specific part of transmit descriptor
struct sk_buff *skb;
dma_addr_t dma_addr;
} ;
struct s_rxd_os { // os-specific part of receive descriptor
struct sk_buff *skb;
dma_addr_t dma_addr;
} ;
/*
* So we do not need to make too many modifications to the generic driver
* parts, we take advantage of the AIX byte swapping macro interface.
*/
#define AIX_REVERSE(x) ((u32)le32_to_cpu((u32)(x)))
#define MDR_REVERSE(x) ((u32)le32_to_cpu((u32)(x)))

View file

@ -0,0 +1,142 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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.
*
******************************************************************************/
/*
* Synchronous Bandwidth Allocation (SBA) structs
*/
#ifndef _SBA_
#define _SBA_
#include "mbuf.h"
#include "sba_def.h"
#ifdef SBA
/* Timer Cell Template */
struct timer_cell {
struct timer_cell *next_ptr ;
struct timer_cell *prev_ptr ;
u_long start_time ;
struct s_sba_node_vars *node_var ;
} ;
/*
* Node variables
*/
struct s_sba_node_vars {
u_char change_resp_flag ;
u_char report_resp_flag ;
u_char change_req_flag ;
u_char report_req_flag ;
long change_amount ;
long node_overhead ;
long node_payload ;
u_long node_status ;
u_char deallocate_status ;
u_char timer_state ;
u_short report_cnt ;
long lastrep_req_tranid ;
struct fddi_addr mac_address ;
struct s_sba_sessions *node_sessions ;
struct timer_cell timer ;
} ;
/*
* Session variables
*/
struct s_sba_sessions {
u_long deallocate_status ;
long session_overhead ;
u_long min_segment_size ;
long session_payload ;
u_long session_status ;
u_long sba_category ;
long lastchg_req_tranid ;
u_short session_id ;
u_char class ;
u_char fddi2 ;
u_long max_t_neg ;
struct s_sba_sessions *next_session ;
} ;
struct s_sba {
struct s_sba_node_vars node[MAX_NODES] ;
struct s_sba_sessions session[MAX_SESSIONS] ;
struct s_sba_sessions *free_session ; /* points to the first */
/* free session */
struct timer_cell *tail_timer ; /* points to the last timer cell */
/*
* variables for allocation actions
*/
long total_payload ; /* Total Payload */
long total_overhead ; /* Total Overhead */
long sba_allocatable ; /* allocatable sync bandwidth */
/*
* RAF message receive parameters
*/
long msg_path_index ; /* Path Type */
long msg_sba_pl_req ; /* Payload Request */
long msg_sba_ov_req ; /* Overhead Request */
long msg_mib_pl ; /* Current Payload for this Path */
long msg_mib_ov ; /* Current Overhead for this Path*/
long msg_category ; /* Category of the Allocation */
u_long msg_max_t_neg ; /* longest T_Neg acceptable */
u_long msg_min_seg_siz ; /* minimum segement size */
struct smt_header *sm ; /* points to the rec message */
struct fddi_addr *msg_alloc_addr ; /* Allocation Address */
/*
* SBA variables
*/
u_long sba_t_neg ; /* holds the last T_NEG */
long sba_max_alloc ; /* the parsed value of SBAAvailable */
/*
* SBA state machine variables
*/
short sba_next_state ; /* the next state of the SBA */
char sba_command ; /* holds the execuded SBA cmd */
u_char sba_available ; /* parsed value after possible check */
} ;
#endif /* SBA */
/*
* variables for the End Station Support
*/
struct s_ess {
/*
* flags and counters
*/
u_char sync_bw_available ; /* is set if sync bw is allocated */
u_char local_sba_active ; /* set when a local sba is available */
char raf_act_timer_poll ; /* activate the timer to send allc req */
char timer_count ; /* counts every timer function call */
SMbuf *sba_reply_pend ; /* local reply for the sba is pending */
/*
* variables for the ess bandwidth control
*/
long sync_bw ; /* holds the allocaed sync bw */
u_long alloc_trans_id ; /* trans id of the last alloc req */
} ;
#endif

View file

@ -0,0 +1,76 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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.
*
******************************************************************************/
#define PHYS 0 /* physical addr */
#define PERM_ADDR 0x80 /* permanet address */
#define SB_STATIC 0x00000001
#define MAX_PAYLOAD 1562
#define PRIMARY_RING 0x00000001
#ifndef NULL
#define NULL 0x00
#endif
/*********************** SB_Input Variable Values ***********************/
/* may be needed when ever the SBA state machine is called */
#define UNKNOWN_SYNC_SOURCE 0x0001
#define REQ_ALLOCATION 0x0002
#define REPORT_RESP 0x0003
#define CHANGE_RESP 0x0004
#define TNEG 0x0005
#define NIF 0x0006
#define SB_STOP 0x0007
#define SB_START 0x0008
#define REPORT_TIMER 0x0009
#define CHANGE_REQUIRED 0x000A
#define DEFAULT_OV 50
#ifdef SBA
/**************************** SBA STATES *****************************/
#define SBA_STANDBY 0x00000000
#define SBA_ACTIVE 0x00000001
#define SBA_RECOVERY 0x00000002
#define SBA_REPORT 0x00000003
#define SBA_CHANGE 0x00000004
/**************************** OTHERS *********************************/
#define FIFTY_PERCENT 50 /* bytes per second */
#define MAX_SESSIONS 150
#define TWO_MINUTES 13079 /* 9.175 ms/tick */
#define FIFTY_BYTES 50
#define SBA_DENIED 0x0000000D
#define I_NEED_ONE 0x00000000
#define MAX_NODES 50
/*#define T_REPORT 0x59682F00L*/ /* 120s/80ns in Hex */
#define TWO_MIN 120 /* seconds */
#define SBA_ST_UNKNOWN 0x00000002
#define SBA_ST_ACTIVE 0x00000001
#define S_CLEAR 0x00000000L
#define ZERO 0x00000000
#define FULL 0x00000000 /* old: 0xFFFFFFFFF */
#define S_SET 0x00000001L
#define LOW_PRIO 0x02 /* ??????? */
#define OK 0x01 /* ??????? */
#define NOT_OK 0x00 /* ??????? */
/****************************************/
/* deallocate_status[ni][si] values */
/****************************************/
#define TX_CHANGE 0X00000001L
#define PENDING 0x00000002L
#define NONE 0X00000000L
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,97 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 _SKFBIINC_
#define _SKFBIINC_
#include "supern_2.h"
/*
* special defines for use into .asm files
*/
#define ERR_FLAGS (FS_MSRABT | FS_SEAC2 | FS_SFRMERR | FS_SFRMTY1)
#ifdef PCI
#define IMASK_FAST (IS_PLINT1 | IS_PLINT2 | IS_TIMINT | IS_TOKEN | \
IS_MINTR2 | IS_MINTR3 | IS_R1_P | \
IS_R1_C | IS_XA_C | IS_XS_C)
#endif
#ifdef PCI
#define ISR_MASK (IS_MINTR1 | IS_R1_F | IS_XS_F| IS_XA_F | IMASK_FAST)
#else
#define ISR_MASK (IS_MINTR1 | IS_MINTR2 | IMASK_FAST)
#endif
#define FMA_FM_CMDREG1 FMA(FM_CMDREG1)
#define FMA_FM_CMDREG2 FMA(FM_CMDREG2)
#define FMA_FM_STMCHN FMA(FM_STMCHN)
#define FMA_FM_RPR FMA(FM_RPR)
#define FMA_FM_WPXA0 FMA(FM_WPXA0)
#define FMA_FM_WPXA2 FMA(FM_WPXA2)
#define FMA_FM_MARR FMA(FM_MARR)
#define FMA_FM_MARW FMA(FM_MARW)
#define FMA_FM_MDRU FMA(FM_MDRU)
#define FMA_FM_MDRL FMA(FM_MDRL)
#define FMA_ST1L FMA(FM_ST1L)
#define FMA_ST1U FMA(FM_ST1U)
#define FMA_ST2L FMA(FM_ST2L)
#define FMA_ST2U FMA(FM_ST2U)
#ifdef SUPERNET_3
#define FMA_ST3L FMA(FM_ST3L)
#define FMA_ST3U FMA(FM_ST3U)
#endif
#define TMODE_RRQ RQ_RRQ
#define TMODE_WAQ2 RQ_WA2
#define HSRA HSR(0)
#define FMA_FM_ST1L FMA_ST1L
#define FMA_FM_ST1U FMA_ST1U
#define FMA_FM_ST2L FMA_ST2L
#define FMA_FM_ST2U FMA_ST2U
#ifdef SUPERNET_3
#define FMA_FM_ST3L FMA_ST3L
#define FMA_FM_ST3U FMA_ST3U
#endif
#define FMA_FM_SWPR FMA(FM_SWPR)
#define FMA_FM_RPXA0 FMA(FM_RPXA0)
#define FMA_FM_RPXS FMA(FM_RPXS)
#define FMA_FM_WPXS FMA(FM_WPXS)
#define FMA_FM_IMSK1U FMA(FM_IMSK1U)
#define FMA_FM_IMSK1L FMA(FM_IMSK1L)
#define FMA_FM_EAS FMA(FM_EAS)
#define FMA_FM_EAA0 FMA(FM_EAA0)
#define TMODE_WAQ0 RQ_WA0
#define TMODE_WSQ RQ_WSQ
/* Define default for DRV_PCM_STATE_CHANGE */
#ifndef DRV_PCM_STATE_CHANGE
#define DRV_PCM_STATE_CHANGE(smc,plc,p_state) /* nothing */
#endif
/* Define default for DRV_RMT_INDICATION */
#ifndef DRV_RMT_INDICATION
#define DRV_RMT_INDICATION(smc,i) /* nothing */
#endif
#endif /* n_SKFBIINC_ */

View file

@ -0,0 +1,488 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 _SCMECM_
#define _SCMECM_
#if defined(PCI) && !defined(OSDEF)
/*
* In the case of the PCI bus the file osdef1st.h must be present
*/
#define OSDEF
#endif
#ifdef PCI
#ifndef SUPERNET_3
#define SUPERNET_3
#endif
#ifndef TAG_MODE
#define TAG_MODE
#endif
#endif
/*
* include all other files in required order
* the following files must have been included before:
* types.h
* fddi.h
*/
#ifdef OSDEF
#include "osdef1st.h"
#endif /* OSDEF */
#ifdef OEM_CONCEPT
#include "oemdef.h"
#endif /* OEM_CONCEPT */
#include "smt.h"
#include "cmtdef.h"
#include "fddimib.h"
#include "targethw.h" /* all target hw dependencies */
#include "targetos.h" /* all target os dependencies */
#ifdef ESS
#include "sba.h"
#endif
/*
* Event Queue
* queue.c
* events are class/value pairs
* class is addressee, e.g. RMT, PCM etc.
* value is command, e.g. line state change, ring op change etc.
*/
struct event_queue {
u_short class ; /* event class */
u_short event ; /* event value */
} ;
/*
* define event queue as circular buffer
*/
#ifdef CONCENTRATOR
#define MAX_EVENT 128
#else /* nCONCENTRATOR */
#define MAX_EVENT 64
#endif /* nCONCENTRATOR */
struct s_queue {
struct event_queue ev_queue[MAX_EVENT];
struct event_queue *ev_put ;
struct event_queue *ev_get ;
} ;
/*
* ECM - Entity Coordination Management
* ecm.c
*/
struct s_ecm {
u_char path_test ; /* ECM path test variable */
u_char sb_flag ; /* ECM stuck bypass */
u_char DisconnectFlag ; /* jd 05-Aug-1999 Bug #10419
* ECM disconnected */
u_char ecm_line_state ; /* flag to dispatcher : line states */
u_long trace_prop ; /* ECM Trace_Prop flag >= 16 bits !! */
/* NUMPHYS note:
* this variable must have enough bits to hold all entiies in
* the station. So NUMPHYS may not be greater than 31.
*/
char ec_pad[2] ;
struct smt_timer ecm_timer ; /* timer */
} ;
/*
* RMT - Ring Management
* rmt.c
*/
struct s_rmt {
u_char dup_addr_test ; /* state of dupl. addr. test */
u_char da_flag ; /* flag : duplicate address det. */
u_char loop_avail ; /* flag : MAC available for loopback */
u_char sm_ma_avail ; /* flag : MAC available for SMT */
u_char no_flag ; /* flag : ring not operational */
u_char bn_flag ; /* flag : MAC reached beacon state */
u_char jm_flag ; /* flag : jamming in NON_OP_DUP */
u_char rm_join ; /* CFM flag RM_Join */
u_char rm_loop ; /* CFM flag RM_Loop */
long fast_rm_join ; /* bit mask of active ports */
/*
* timer and flags
*/
struct smt_timer rmt_timer0 ; /* timer 0 */
struct smt_timer rmt_timer1 ; /* timer 1 */
struct smt_timer rmt_timer2 ; /* timer 2 */
u_char timer0_exp ; /* flag : timer 0 expired */
u_char timer1_exp ; /* flag : timer 1 expired */
u_char timer2_exp ; /* flag : timer 2 expired */
u_char rm_pad1[1] ;
} ;
/*
* CFM - Configuration Management
* cfm.c
* used for SAS and DAS
*/
struct s_cfm {
u_char cf_state; /* CFM state machine current state */
u_char cf_pad[3] ;
} ;
/*
* CEM - Configuration Element Management
* cem.c
* used for Concentrator
*/
#ifdef CONCENTRATOR
struct s_cem {
int ce_state ; /* CEM state */
int ce_port ; /* PA PB PM PM+1 .. */
int ce_type ; /* TA TB TS TM */
} ;
/*
* linked list of CCEs in current token path
*/
struct s_c_ring {
struct s_c_ring *c_next ;
char c_entity ;
} ;
struct mib_path_config {
u_long fddimibPATHConfigSMTIndex;
u_long fddimibPATHConfigPATHIndex;
u_long fddimibPATHConfigTokenOrder;
u_long fddimibPATHConfigResourceType;
#define SNMP_RES_TYPE_MAC 2 /* Resource is a MAC */
#define SNMP_RES_TYPE_PORT 4 /* Resource is a PORT */
u_long fddimibPATHConfigResourceIndex;
u_long fddimibPATHConfigCurrentPath;
#define SNMP_PATH_ISOLATED 1 /* Current path is isolated */
#define SNMP_PATH_LOCAL 2 /* Current path is local */
#define SNMP_PATH_SECONDARY 3 /* Current path is secondary */
#define SNMP_PATH_PRIMARY 4 /* Current path is primary */
#define SNMP_PATH_CONCATENATED 5 /* Current path is concatenated */
#define SNMP_PATH_THRU 6 /* Current path is thru */
};
#endif
/*
* PCM connect states
*/
#define PCM_DISABLED 0
#define PCM_CONNECTING 1
#define PCM_STANDBY 2
#define PCM_ACTIVE 3
struct s_pcm {
u_char pcm_pad[3] ;
} ;
/*
* PHY struct
* one per physical port
*/
struct s_phy {
/* Inter Module Globals */
struct fddi_mib_p *mib ;
u_char np ; /* index 0 .. NUMPHYS */
u_char cf_join ;
u_char cf_loop ;
u_char wc_flag ; /* withhold connection flag */
u_char pc_mode ; /* Holds the negotiated mode of the PCM */
u_char pc_lem_fail ; /* flag : LCT failed */
u_char lc_test ;
u_char scrub ; /* CFM flag Scrub -> PCM */
char phy_name ;
u_char pmd_type[2] ; /* SK connector/transceiver type codes */
#define PMD_SK_CONN 0 /* pmd_type[PMD_SK_CONN] = Connector */
#define PMD_SK_PMD 1 /* pmd_type[PMD_SK_PMD] = Xver */
u_char pmd_scramble ; /* scrambler on/off */
/* inner Module Globals */
u_char curr_ls ; /* current line state */
u_char ls_flag ;
u_char rc_flag ;
u_char tc_flag ;
u_char td_flag ;
u_char bitn ;
u_char tr_flag ; /* trace recvd while in active */
u_char twisted ; /* flag to indicate an A-A or B-B connection */
u_char t_val[NUMBITS] ; /* transmit bits for signaling */
u_char r_val[NUMBITS] ; /* receive bits for signaling */
u_long t_next[NUMBITS] ;
struct smt_timer pcm_timer0 ;
struct smt_timer pcm_timer1 ;
struct smt_timer pcm_timer2 ;
u_char timer0_exp ;
u_char timer1_exp ;
u_char timer2_exp ;
u_char pcm_pad1[1] ;
int cem_pst ; /* CEM privae state; used for dual homing */
struct lem_counter lem ;
#ifdef AMDPLC
struct s_plc plc ;
#endif
} ;
/*
* timer package
* smttimer.c
*/
struct s_timer {
struct smt_timer *st_queue ;
struct smt_timer st_fast ;
} ;
/*
* SRF types and data
*/
#define SMT_EVENT_BASE 1
#define SMT_EVENT_MAC_PATH_CHANGE (SMT_EVENT_BASE+0)
#define SMT_EVENT_MAC_NEIGHBOR_CHANGE (SMT_EVENT_BASE+1)
#define SMT_EVENT_PORT_PATH_CHANGE (SMT_EVENT_BASE+2)
#define SMT_EVENT_PORT_CONNECTION (SMT_EVENT_BASE+3)
#define SMT_IS_CONDITION(x) ((x)>=SMT_COND_BASE)
#define SMT_COND_BASE (SMT_EVENT_PORT_CONNECTION+1)
#define SMT_COND_SMT_PEER_WRAP (SMT_COND_BASE+0)
#define SMT_COND_SMT_HOLD (SMT_COND_BASE+1)
#define SMT_COND_MAC_FRAME_ERROR (SMT_COND_BASE+2)
#define SMT_COND_MAC_DUP_ADDR (SMT_COND_BASE+3)
#define SMT_COND_MAC_NOT_COPIED (SMT_COND_BASE+4)
#define SMT_COND_PORT_EB_ERROR (SMT_COND_BASE+5)
#define SMT_COND_PORT_LER (SMT_COND_BASE+6)
#define SR0_WAIT 0
#define SR1_HOLDOFF 1
#define SR2_DISABLED 2
struct s_srf {
u_long SRThreshold ; /* threshold value */
u_char RT_Flag ; /* report transmitted flag */
u_char sr_state ; /* state-machine */
u_char any_report ; /* any report required */
u_long TSR ; /* timer */
u_short ring_status ; /* IBM ring status */
} ;
/*
* IBM token ring status
*/
#define RS_RES15 (1<<15) /* reserved */
#define RS_HARDERROR (1<<14) /* ring down */
#define RS_SOFTERROR (1<<13) /* sent SRF */
#define RS_BEACON (1<<12) /* transmitted beacon */
#define RS_PATHTEST (1<<11) /* path test failed */
#define RS_SELFTEST (1<<10) /* selftest required */
#define RS_RES9 (1<< 9) /* reserved */
#define RS_DISCONNECT (1<< 8) /* remote disconnect */
#define RS_RES7 (1<< 7) /* reserved */
#define RS_DUPADDR (1<< 6) /* duplicate address */
#define RS_NORINGOP (1<< 5) /* no ring op */
#define RS_VERSION (1<< 4) /* SMT version mismatch */
#define RS_STUCKBYPASSS (1<< 3) /* stuck bypass */
#define RS_EVENT (1<< 2) /* FDDI event occurred */
#define RS_RINGOPCHANGE (1<< 1) /* ring op changed */
#define RS_RES0 (1<< 0) /* reserved */
#define RS_SET(smc,bit) \
ring_status_indication(smc,smc->srf.ring_status |= bit)
#define RS_CLEAR(smc,bit) \
ring_status_indication(smc,smc->srf.ring_status &= ~bit)
#define RS_CLEAR_EVENT (0xffff & ~(RS_NORINGOP))
/* Define the AIX-event-Notification as null function if it isn't defined */
/* in the targetos.h file */
#ifndef AIX_EVENT
#define AIX_EVENT(smc,opt0,opt1,opt2,opt3) /* nothing */
#endif
struct s_srf_evc {
u_char evc_code ; /* event code type */
u_char evc_index ; /* index for mult. instances */
u_char evc_rep_required ; /* report required */
u_short evc_para ; /* SMT Para Number */
u_char *evc_cond_state ; /* condition state */
u_char *evc_multiple ; /* multiple occurrence */
} ;
/*
* Values used by frame based services
* smt.c
*/
#define SMT_MAX_TEST 5
#define SMT_TID_NIF 0 /* pending NIF request */
#define SMT_TID_NIF_TEST 1 /* pending NIF test */
#define SMT_TID_ECF_UNA 2 /* pending ECF UNA test */
#define SMT_TID_ECF_DNA 3 /* pending ECF DNA test */
#define SMT_TID_ECF 4 /* pending ECF test */
struct smt_values {
u_long smt_tvu ; /* timer valid una */
u_long smt_tvd ; /* timer valid dna */
u_long smt_tid ; /* transaction id */
u_long pend[SMT_MAX_TEST] ; /* TID of requests */
u_long uniq_time ; /* unique time stamp */
u_short uniq_ticks ; /* unique time stamp */
u_short please_reconnect ; /* flag : reconnect */
u_long smt_last_lem ;
u_long smt_last_notify ;
struct smt_timer smt_timer ; /* SMT NIF timer */
u_long last_tok_time[NUMMACS]; /* token cnt emulation */
} ;
/*
* SMT/CMT configurable parameters
*/
#define SMT_DAS 0 /* dual attach */
#define SMT_SAS 1 /* single attach */
#define SMT_NAC 2 /* null attach concentrator */
struct smt_config {
u_char attach_s ; /* CFM attach to secondary path */
u_char sas ; /* SMT_DAS/SAS/NAC */
u_char build_ring_map ; /* build ringmap if TRUE */
u_char numphys ; /* number of active phys */
u_char sc_pad[1] ;
u_long pcm_tb_min ; /* PCM : TB_Min timer value */
u_long pcm_tb_max ; /* PCM : TB_Max timer value */
u_long pcm_c_min ; /* PCM : C_Min timer value */
u_long pcm_t_out ; /* PCM : T_Out timer value */
u_long pcm_tl_min ; /* PCM : TL_min timer value */
u_long pcm_lc_short ; /* PCM : LC_Short timer value */
u_long pcm_lc_medium ; /* PCM : LC_Medium timer value */
u_long pcm_lc_long ; /* PCM : LC_Long timer value */
u_long pcm_lc_extended ; /* PCM : LC_Extended timer value */
u_long pcm_t_next_9 ; /* PCM : T_Next[9] timer value */
u_long pcm_ns_max ; /* PCM : NS_Max timer value */
u_long ecm_i_max ; /* ECM : I_Max timer value */
u_long ecm_in_max ; /* ECM : IN_Max timer value */
u_long ecm_td_min ; /* ECM : TD_Min timer */
u_long ecm_test_done ; /* ECM : path test done timer */
u_long ecm_check_poll ; /* ECM : check bypass poller */
u_long rmt_t_non_op ; /* RMT : T_Non_OP timer value */
u_long rmt_t_stuck ; /* RMT : T_Stuck timer value */
u_long rmt_t_direct ; /* RMT : T_Direct timer value */
u_long rmt_t_jam ; /* RMT : T_Jam timer value */
u_long rmt_t_announce ; /* RMT : T_Announce timer value */
u_long rmt_t_poll ; /* RMT : claim/beacon poller */
u_long rmt_dup_mac_behavior ; /* Flag for the beavior of SMT if
* a Duplicate MAC Address was detected.
* FALSE: SMT will leave finally the ring
* TRUE: SMT will reinstert into the ring
*/
u_long mac_d_max ; /* MAC : D_Max timer value */
u_long lct_short ; /* LCT : error threshold */
u_long lct_medium ; /* LCT : error threshold */
u_long lct_long ; /* LCT : error threshold */
u_long lct_extended ; /* LCT : error threshold */
} ;
#ifdef DEBUG
/*
* Debugging struct sometimes used in smc
*/
struct smt_debug {
int d_smtf ;
int d_smt ;
int d_ecm ;
int d_rmt ;
int d_cfm ;
int d_pcm ;
int d_plc ;
#ifdef ESS
int d_ess ;
#endif
#ifdef SBA
int d_sba ;
#endif
struct os_debug d_os; /* Include specific OS DEBUG struct */
} ;
#ifndef DEBUG_BRD
/* all boards shall be debugged with one debug struct */
extern struct smt_debug debug; /* Declaration of debug struct */
#endif /* DEBUG_BRD */
#endif /* DEBUG */
/*
* the SMT Context Struct SMC
* this struct contains ALL global variables of SMT
*/
struct s_smc {
struct s_smt_os os ; /* os specific */
struct s_smt_hw hw ; /* hardware */
/*
* NOTE: os and hw MUST BE the first two structs
* anything beyond hw WILL BE SET TO ZERO in smt_set_defaults()
*/
struct smt_config s ; /* smt constants */
struct smt_values sm ; /* smt variables */
struct s_ecm e ; /* ecm */
struct s_rmt r ; /* rmt */
struct s_cfm cf ; /* cfm/cem */
#ifdef CONCENTRATOR
struct s_cem ce[NUMPHYS] ; /* cem */
struct s_c_ring cr[NUMPHYS+NUMMACS] ;
#endif
struct s_pcm p ; /* pcm */
struct s_phy y[NUMPHYS] ; /* phy */
struct s_queue q ; /* queue */
struct s_timer t ; /* timer */
struct s_srf srf ; /* SRF */
struct s_srf_evc evcs[6+NUMPHYS*4] ;
struct fddi_mib mib ; /* __THE_MIB__ */
#ifdef SBA
struct s_sba sba ; /* SBA variables */
#endif
#ifdef ESS
struct s_ess ess ; /* Ess variables */
#endif
#if defined(DEBUG) && defined(DEBUG_BRD)
/* If you want all single board to be debugged separately */
struct smt_debug debug; /* Declaration of debug struct */
#endif /* DEBUG_BRD && DEBUG */
} ;
extern const struct fddi_addr fddi_broadcast;
void all_selection_criteria(struct s_smc *smc);
void card_stop(struct s_smc *smc);
void init_board(struct s_smc *smc, u_char *mac_addr);
int init_fplus(struct s_smc *smc);
void init_plc(struct s_smc *smc);
int init_smt(struct s_smc *smc, u_char *mac_addr);
void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
int pcm_status_twisted(struct s_smc *smc);
void plc1_irq(struct s_smc *smc);
void plc2_irq(struct s_smc *smc);
void read_address(struct s_smc *smc, u_char *mac_addr);
void timer_irq(struct s_smc *smc);
#endif /* _SCMECM_ */

View file

@ -0,0 +1,882 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 7.2 frame definitions
*/
#ifndef _SMT_
#define _SMT_
/* #define SMT5_10 */
#define SMT6_10
#define SMT7_20
#define OPT_PMF /* if parameter management is supported */
#define OPT_SRF /* if status report is supported */
/*
* SMT frame version 5.1
*/
#define SMT_VID 0x0001 /* V 5.1 .. 6.1 */
#define SMT_VID_2 0x0002 /* V 7.2 */
struct smt_sid {
u_char sid_oem[2] ; /* implementation spec. */
struct fddi_addr sid_node ; /* node address */
} ;
typedef u_char t_station_id[8] ;
/*
* note on alignment :
* sizeof(struct smt_header) = 32
* all parameters are long aligned
* if struct smt_header starts at offset 0, all longs are aligned correctly
* (FC starts at offset 3)
*/
_packed struct smt_header {
struct fddi_addr smt_dest ; /* destination address */
struct fddi_addr smt_source ; /* source address */
u_char smt_class ; /* NIF, SIF ... */
u_char smt_type ; /* req., response .. */
u_short smt_version ; /* version id */
u_int smt_tid ; /* transaction ID */
struct smt_sid smt_sid ; /* station ID */
u_short smt_pad ; /* pad with 0 */
u_short smt_len ; /* length of info field */
} ;
#define SWAP_SMTHEADER "662sl8ss"
#if 0
/*
* MAC FC values
*/
#define FC_SMT_INFO 0x41 /* SMT info */
#define FC_SMT_NSA 0x4f /* SMT Next Station Addressing */
#endif
/*
* type codes
*/
#define SMT_ANNOUNCE 0x01 /* announcement */
#define SMT_REQUEST 0x02 /* request */
#define SMT_REPLY 0x03 /* reply */
/*
* class codes
*/
#define SMT_NIF 0x01 /* neighbor information frames */
#define SMT_SIF_CONFIG 0x02 /* station information configuration */
#define SMT_SIF_OPER 0x03 /* station information operation */
#define SMT_ECF 0x04 /* echo frames */
#define SMT_RAF 0x05 /* resource allocation */
#define SMT_RDF 0x06 /* request denied */
#define SMT_SRF 0x07 /* status report */
#define SMT_PMF_GET 0x08 /* parameter management get */
#define SMT_PMF_SET 0x09 /* parameter management set */
#define SMT_ESF 0xff /* extended service */
#define SMT_MAX_ECHO_LEN 4458 /* max length of SMT Echo */
#if defined(CONC) || defined(CONC_II)
#define SMT_TEST_ECHO_LEN 50 /* test length of SMT Echo */
#else
#define SMT_TEST_ECHO_LEN SMT_MAX_ECHO_LEN /* test length */
#endif
#define SMT_MAX_INFO_LEN (4352-20) /* max length for SMT info */
/*
* parameter types
*/
struct smt_para {
u_short p_type ; /* type */
u_short p_len ; /* length of parameter */
} ;
#define PARA_LEN (sizeof(struct smt_para))
#define SMTSETPARA(p,t) (p)->para.p_type = (t),\
(p)->para.p_len = sizeof(*(p)) - PARA_LEN
/*
* P01 : Upstream Neighbor Address, UNA
*/
#define SMT_P_UNA 0x0001 /* upstream neighbor address */
#define SWAP_SMT_P_UNA "s6"
struct smt_p_una {
struct smt_para para ; /* generic parameter header */
u_short una_pad ;
struct fddi_addr una_node ; /* node address, zero if unknown */
} ;
/*
* P02 : Station Descriptor
*/
#define SMT_P_SDE 0x0002 /* station descriptor */
#define SWAP_SMT_P_SDE "1111"
#define SMT_SDE_STATION 0 /* end node */
#define SMT_SDE_CONCENTRATOR 1 /* concentrator */
struct smt_p_sde {
struct smt_para para ; /* generic parameter header */
u_char sde_type ; /* station type */
u_char sde_mac_count ; /* number of MACs */
u_char sde_non_master ; /* number of A,B or S ports */
u_char sde_master ; /* number of S ports on conc. */
} ;
/*
* P03 : Station State
*/
#define SMT_P_STATE 0x0003 /* station state */
#define SWAP_SMT_P_STATE "scc"
struct smt_p_state {
struct smt_para para ; /* generic parameter header */
u_short st_pad ;
u_char st_topology ; /* topology */
u_char st_dupl_addr ; /* duplicate address detected */
} ;
#define SMT_ST_WRAPPED (1<<0) /* station wrapped */
#define SMT_ST_UNATTACHED (1<<1) /* unattached concentrator */
#define SMT_ST_TWISTED_A (1<<2) /* A-A connection, twisted ring */
#define SMT_ST_TWISTED_B (1<<3) /* B-B connection, twisted ring */
#define SMT_ST_ROOTED_S (1<<4) /* rooted station */
#define SMT_ST_SRF (1<<5) /* SRF protocol supported */
#define SMT_ST_SYNC_SERVICE (1<<6) /* use synchronous bandwidth */
#define SMT_ST_MY_DUPA (1<<0) /* my station detected dupl. */
#define SMT_ST_UNA_DUPA (1<<1) /* my UNA detected duplicate */
/*
* P04 : timestamp
*/
#define SMT_P_TIMESTAMP 0x0004 /* time stamp */
#define SWAP_SMT_P_TIMESTAMP "8"
struct smt_p_timestamp {
struct smt_para para ; /* generic parameter header */
u_char ts_time[8] ; /* time, resolution 80nS, unique */
} ;
/*
* P05 : station policies
*/
#define SMT_P_POLICY 0x0005 /* station policies */
#define SWAP_SMT_P_POLICY "ss"
struct smt_p_policy {
struct smt_para para ; /* generic parameter header */
u_short pl_config ;
u_short pl_connect ; /* bit string POLICY_AA ... */
} ;
#define SMT_PL_HOLD 1 /* hold policy supported (Dual MAC) */
/*
* P06 : latency equivalent
*/
#define SMT_P_LATENCY 0x0006 /* latency */
#define SWAP_SMT_P_LATENCY "ssss"
/*
* note: latency has two phy entries by definition
* for a SAS, the 2nd one is null
*/
struct smt_p_latency {
struct smt_para para ; /* generic parameter header */
u_short lt_phyout_idx1 ; /* index */
u_short lt_latency1 ; /* latency , unit : byte clock */
u_short lt_phyout_idx2 ; /* 0 if SAS */
u_short lt_latency2 ; /* 0 if SAS */
} ;
/*
* P07 : MAC neighbors
*/
#define SMT_P_NEIGHBORS 0x0007 /* MAC neighbor description */
#define SWAP_SMT_P_NEIGHBORS "ss66"
struct smt_p_neighbor {
struct smt_para para ; /* generic parameter header */
u_short nb_mib_index ; /* MIB index */
u_short nb_mac_index ; /* n+1 .. n+m, m = #MACs, n = #PHYs */
struct fddi_addr nb_una ; /* UNA , 0 for unknown */
struct fddi_addr nb_dna ; /* DNA , 0 for unknown */
} ;
/*
* PHY record
*/
#define SMT_PHY_A 0 /* A port */
#define SMT_PHY_B 1 /* B port */
#define SMT_PHY_S 2 /* slave port */
#define SMT_PHY_M 3 /* master port */
#define SMT_CS_DISABLED 0 /* connect state : disabled */
#define SMT_CS_CONNECTING 1 /* connect state : connecting */
#define SMT_CS_STANDBY 2 /* connect state : stand by */
#define SMT_CS_ACTIVE 3 /* connect state : active */
#define SMT_RM_NONE 0
#define SMT_RM_MAC 1
struct smt_phy_rec {
u_short phy_mib_index ; /* MIB index */
u_char phy_type ; /* A/B/S/M */
u_char phy_connect_state ; /* disabled/connecting/active */
u_char phy_remote_type ; /* A/B/S/M */
u_char phy_remote_mac ; /* none/remote */
u_short phy_resource_idx ; /* 1 .. n */
} ;
/*
* MAC record
*/
struct smt_mac_rec {
struct fddi_addr mac_addr ; /* MAC address */
u_short mac_resource_idx ; /* n+1 .. n+m */
} ;
/*
* P08 : path descriptors
* should be really an array ; however our environment has a fixed number of
* PHYs and MACs
*/
#define SMT_P_PATH 0x0008 /* path descriptor */
#define SWAP_SMT_P_PATH "[6s]"
struct smt_p_path {
struct smt_para para ; /* generic parameter header */
struct smt_phy_rec pd_phy[2] ; /* PHY A */
struct smt_mac_rec pd_mac ; /* MAC record */
} ;
/*
* P09 : MAC status
*/
#define SMT_P_MAC_STATUS 0x0009 /* MAC status */
#define SWAP_SMT_P_MAC_STATUS "sslllllllll"
struct smt_p_mac_status {
struct smt_para para ; /* generic parameter header */
u_short st_mib_index ; /* MIB index */
u_short st_mac_index ; /* n+1 .. n+m */
u_int st_t_req ; /* T_Req */
u_int st_t_neg ; /* T_Neg */
u_int st_t_max ; /* T_Max */
u_int st_tvx_value ; /* TVX_Value */
u_int st_t_min ; /* T_Min */
u_int st_sba ; /* synchr. bandwidth alloc */
u_int st_frame_ct ; /* frame counter */
u_int st_error_ct ; /* error counter */
u_int st_lost_ct ; /* lost frames counter */
} ;
/*
* P0A : PHY link error rate monitoring
*/
#define SMT_P_LEM 0x000a /* link error monitor */
#define SWAP_SMT_P_LEM "ssccccll"
/*
* units of lem_cutoff,lem_alarm,lem_estimate : 10**-x
*/
struct smt_p_lem {
struct smt_para para ; /* generic parameter header */
u_short lem_mib_index ; /* MIB index */
u_short lem_phy_index ; /* 1 .. n */
u_char lem_pad2 ; /* be nice and make it even . */
u_char lem_cutoff ; /* 0x4 .. 0xf, default 0x7 */
u_char lem_alarm ; /* 0x4 .. 0xf, default 0x8 */
u_char lem_estimate ; /* 0x0 .. 0xff */
u_int lem_reject_ct ; /* 0x00000000 .. 0xffffffff */
u_int lem_ct ; /* 0x00000000 .. 0xffffffff */
} ;
/*
* P0B : MAC frame counters
*/
#define SMT_P_MAC_COUNTER 0x000b /* MAC frame counters */
#define SWAP_SMT_P_MAC_COUNTER "ssll"
struct smt_p_mac_counter {
struct smt_para para ; /* generic parameter header */
u_short mc_mib_index ; /* MIB index */
u_short mc_index ; /* mac index */
u_int mc_receive_ct ; /* receive counter */
u_int mc_transmit_ct ; /* transmit counter */
} ;
/*
* P0C : MAC frame not copied counter
*/
#define SMT_P_MAC_FNC 0x000c /* MAC frame not copied counter */
#define SWAP_SMT_P_MAC_FNC "ssl"
struct smt_p_mac_fnc {
struct smt_para para ; /* generic parameter header */
u_short nc_mib_index ; /* MIB index */
u_short nc_index ; /* mac index */
u_int nc_counter ; /* not copied counter */
} ;
/*
* P0D : MAC priority values
*/
#define SMT_P_PRIORITY 0x000d /* MAC priority values */
#define SWAP_SMT_P_PRIORITY "ssl"
struct smt_p_priority {
struct smt_para para ; /* generic parameter header */
u_short pr_mib_index ; /* MIB index */
u_short pr_index ; /* mac index */
u_int pr_priority[7] ; /* priority values */
} ;
/*
* P0E : PHY elasticity buffer status
*/
#define SMT_P_EB 0x000e /* PHY EB status */
#define SWAP_SMT_P_EB "ssl"
struct smt_p_eb {
struct smt_para para ; /* generic parameter header */
u_short eb_mib_index ; /* MIB index */
u_short eb_index ; /* phy index */
u_int eb_error_ct ; /* # of eb overflows */
} ;
/*
* P0F : manufacturer field
*/
#define SMT_P_MANUFACTURER 0x000f /* manufacturer field */
#define SWAP_SMT_P_MANUFACTURER ""
struct smp_p_manufacturer {
struct smt_para para ; /* generic parameter header */
u_char mf_data[32] ; /* OUI + arbitrary data */
} ;
/*
* P10 : user field
*/
#define SMT_P_USER 0x0010 /* manufacturer field */
#define SWAP_SMT_P_USER ""
struct smp_p_user {
struct smt_para para ; /* generic parameter header */
u_char us_data[32] ; /* arbitrary data */
} ;
/*
* P11 : echo data
*/
#define SMT_P_ECHODATA 0x0011 /* echo data */
#define SWAP_SMT_P_ECHODATA ""
struct smt_p_echo {
struct smt_para para ; /* generic parameter header */
u_char ec_data[SMT_MAX_ECHO_LEN-4] ; /* echo data */
} ;
/*
* P12 : reason code
*/
#define SMT_P_REASON 0x0012 /* reason code */
#define SWAP_SMT_P_REASON "l"
struct smt_p_reason {
struct smt_para para ; /* generic parameter header */
u_int rdf_reason ; /* CLASS/VERSION */
} ;
#define SMT_RDF_CLASS 0x00000001 /* class not supported */
#define SMT_RDF_VERSION 0x00000002 /* version not supported */
#define SMT_RDF_SUCCESS 0x00000003 /* success (PMF) */
#define SMT_RDF_BADSET 0x00000004 /* bad set count (PMF) */
#define SMT_RDF_ILLEGAL 0x00000005 /* read only (PMF) */
#define SMT_RDF_NOPARAM 0x6 /* parameter not supported (PMF) */
#define SMT_RDF_RANGE 0x8 /* out of range */
#define SMT_RDF_AUTHOR 0x9 /* not autohorized */
#define SMT_RDF_LENGTH 0x0a /* length error */
#define SMT_RDF_TOOLONG 0x0b /* length error */
#define SMT_RDF_SBA 0x0d /* SBA denied */
/*
* P13 : refused frame beginning
*/
#define SMT_P_REFUSED 0x0013 /* refused frame beginning */
#define SWAP_SMT_P_REFUSED "l"
struct smt_p_refused {
struct smt_para para ; /* generic parameter header */
u_int ref_fc ; /* 3 bytes 0 + FC */
struct smt_header ref_header ; /* refused header */
} ;
/*
* P14 : supported SMT versions
*/
#define SMT_P_VERSION 0x0014 /* SMT supported versions */
#define SWAP_SMT_P_VERSION "sccss"
struct smt_p_version {
struct smt_para para ; /* generic parameter header */
u_short v_pad ;
u_char v_n ; /* 1 .. 0xff, #versions */
u_char v_index ; /* 1 .. 0xff, index of op. v. */
u_short v_version[1] ; /* list of min. 1 version */
u_short v_pad2 ; /* pad if necessary */
} ;
/*
* P15 : Resource Type
*/
#define SWAP_SMT_P0015 "l"
struct smt_p_0015 {
struct smt_para para ; /* generic parameter header */
u_int res_type ; /* recsource type */
} ;
#define SYNC_BW 0x00000001L /* Synchronous Bandwidth */
/*
* P16 : SBA Command
*/
#define SWAP_SMT_P0016 "l"
struct smt_p_0016 {
struct smt_para para ; /* generic parameter header */
u_int sba_cmd ; /* command for the SBA */
} ;
#define REQUEST_ALLOCATION 0x1 /* req allocation of sync bandwidth */
#define REPORT_ALLOCATION 0x2 /* rep of sync bandwidth allocation */
#define CHANGE_ALLOCATION 0x3 /* forces a station using sync band-*/
/* width to change its current allo-*/
/* cation */
/*
* P17 : SBA Payload Request
*/
#define SWAP_SMT_P0017 "l"
struct smt_p_0017 {
struct smt_para para ; /* generic parameter header */
int sba_pl_req ; /* total sync bandwidth measured in */
} ; /* bytes per 125 us */
/*
* P18 : SBA Overhead Request
*/
#define SWAP_SMT_P0018 "l"
struct smt_p_0018 {
struct smt_para para ; /* generic parameter header */
int sba_ov_req ; /* total sync bandwidth req for overhead*/
} ; /* measuered in bytes per T_Neg */
/*
* P19 : SBA Allocation Address
*/
#define SWAP_SMT_P0019 "s6"
struct smt_p_0019 {
struct smt_para para ; /* generic parameter header */
u_short sba_pad ;
struct fddi_addr alloc_addr ; /* Allocation Address */
} ;
/*
* P1A : SBA Category
*/
#define SWAP_SMT_P001A "l"
struct smt_p_001a {
struct smt_para para ; /* generic parameter header */
u_int category ; /* Allocator defined classification */
} ;
/*
* P1B : Maximum T_Neg
*/
#define SWAP_SMT_P001B "l"
struct smt_p_001b {
struct smt_para para ; /* generic parameter header */
u_int max_t_neg ; /* longest T_NEG for the sync service*/
} ;
/*
* P1C : Minimum SBA Segment Size
*/
#define SWAP_SMT_P001C "l"
struct smt_p_001c {
struct smt_para para ; /* generic parameter header */
u_int min_seg_siz ; /* smallest number of bytes per frame*/
} ;
/*
* P1D : SBA Allocatable
*/
#define SWAP_SMT_P001D "l"
struct smt_p_001d {
struct smt_para para ; /* generic parameter header */
u_int allocatable ; /* total sync bw available for alloc */
} ;
/*
* P20 0B : frame status capabilities
* NOTE: not in swap table, is used by smt.c AND PMF table
*/
#define SMT_P_FSC 0x200b
/* #define SWAP_SMT_P_FSC "ssss" */
struct smt_p_fsc {
struct smt_para para ; /* generic parameter header */
u_short fsc_pad0 ;
u_short fsc_mac_index ; /* mac index 1 .. ff */
u_short fsc_pad1 ;
u_short fsc_value ; /* FSC_TYPE[0-2] */
} ;
#define FSC_TYPE0 0 /* "normal" node (A/C handling) */
#define FSC_TYPE1 1 /* Special A/C indicator forwarding */
#define FSC_TYPE2 2 /* Special A/C indicator forwarding */
/*
* P00 21 : user defined authoriziation (see pmf.c)
*/
#define SMT_P_AUTHOR 0x0021
/*
* notification parameters
*/
#define SWAP_SMT_P1048 "ll"
struct smt_p_1048 {
u_int p1048_flag ;
u_int p1048_cf_state ;
} ;
/*
* NOTE: all 2xxx 3xxx and 4xxx must include the INDEX in the swap string,
* even so the INDEX is NOT part of the struct.
* INDEX is already swapped in pmf.c, format in string is '4'
*/
#define SWAP_SMT_P208C "4lss66"
struct smt_p_208c {
u_int p208c_flag ;
u_short p208c_pad ;
u_short p208c_dupcondition ;
struct fddi_addr p208c_fddilong ;
struct fddi_addr p208c_fddiunalong ;
} ;
#define SWAP_SMT_P208D "4lllll"
struct smt_p_208d {
u_int p208d_flag ;
u_int p208d_frame_ct ;
u_int p208d_error_ct ;
u_int p208d_lost_ct ;
u_int p208d_ratio ;
} ;
#define SWAP_SMT_P208E "4llll"
struct smt_p_208e {
u_int p208e_flag ;
u_int p208e_not_copied ;
u_int p208e_copied ;
u_int p208e_not_copied_ratio ;
} ;
#define SWAP_SMT_P208F "4ll6666s6"
struct smt_p_208f {
u_int p208f_multiple ;
u_int p208f_nacondition ;
struct fddi_addr p208f_old_una ;
struct fddi_addr p208f_new_una ;
struct fddi_addr p208f_old_dna ;
struct fddi_addr p208f_new_dna ;
u_short p208f_curren_path ;
struct fddi_addr p208f_smt_address ;
} ;
#define SWAP_SMT_P2090 "4lssl"
struct smt_p_2090 {
u_int p2090_multiple ;
u_short p2090_availablepaths ;
u_short p2090_currentpath ;
u_int p2090_requestedpaths ;
} ;
/*
* NOTE:
* special kludge for parameters 320b,320f,3210
* these parameters are part of RAF frames
* RAF frames are parsed in SBA.C and must be swapped
* PMF.C has special code to avoid double swapping
*/
#ifdef LITTLE_ENDIAN
#define SBAPATHINDEX (0x01000000L)
#else
#define SBAPATHINDEX (0x01L)
#endif
#define SWAP_SMT_P320B "42s"
struct smt_p_320b {
struct smt_para para ; /* generic parameter header */
u_int mib_index ;
u_short path_pad ;
u_short path_index ;
} ;
#define SWAP_SMT_P320F "4l"
struct smt_p_320f {
struct smt_para para ; /* generic parameter header */
u_int mib_index ;
u_int mib_payload ;
} ;
#define SWAP_SMT_P3210 "4l"
struct smt_p_3210 {
struct smt_para para ; /* generic parameter header */
u_int mib_index ;
u_int mib_overhead ;
} ;
#define SWAP_SMT_P4050 "4l1111ll"
struct smt_p_4050 {
u_int p4050_flag ;
u_char p4050_pad ;
u_char p4050_cutoff ;
u_char p4050_alarm ;
u_char p4050_estimate ;
u_int p4050_reject_ct ;
u_int p4050_ct ;
} ;
#define SWAP_SMT_P4051 "4lssss"
struct smt_p_4051 {
u_int p4051_multiple ;
u_short p4051_porttype ;
u_short p4051_connectstate ;
u_short p4051_pc_neighbor ;
u_short p4051_pc_withhold ;
} ;
#define SWAP_SMT_P4052 "4ll"
struct smt_p_4052 {
u_int p4052_flag ;
u_int p4052_eberrorcount ;
} ;
#define SWAP_SMT_P4053 "4lsslss"
struct smt_p_4053 {
u_int p4053_multiple ;
u_short p4053_availablepaths ;
u_short p4053_currentpath ;
u_int p4053_requestedpaths ;
u_short p4053_mytype ;
u_short p4053_neighbortype ;
} ;
#define SMT_P_SETCOUNT 0x1035
#define SWAP_SMT_P_SETCOUNT "l8"
struct smt_p_setcount {
struct smt_para para ; /* generic parameter header */
u_int count ;
u_char timestamp[8] ;
} ;
/*
* SMT FRAMES
*/
/*
* NIF : neighbor information frames
*/
struct smt_nif {
struct smt_header smt ; /* generic header */
struct smt_p_una una ; /* UNA */
struct smt_p_sde sde ; /* station descriptor */
struct smt_p_state state ; /* station state */
#ifdef SMT6_10
struct smt_p_fsc fsc ; /* frame status cap. */
#endif
} ;
/*
* SIF : station information frames
*/
struct smt_sif_config {
struct smt_header smt ; /* generic header */
struct smt_p_timestamp ts ; /* time stamp */
struct smt_p_sde sde ; /* station descriptor */
struct smt_p_version version ; /* supported versions */
struct smt_p_state state ; /* station state */
struct smt_p_policy policy ; /* station policy */
struct smt_p_latency latency ; /* path latency */
struct smt_p_neighbor neighbor ; /* neighbors, we have only one*/
#ifdef OPT_PMF
struct smt_p_setcount setcount ; /* Set Count mandatory */
#endif
/* WARNING : path MUST BE LAST FIELD !!! (see smt.c:smt_fill_path) */
struct smt_p_path path ; /* path descriptor */
} ;
#define SIZEOF_SMT_SIF_CONFIG (sizeof(struct smt_sif_config)- \
sizeof(struct smt_p_path))
struct smt_sif_operation {
struct smt_header smt ; /* generic header */
struct smt_p_timestamp ts ; /* time stamp */
struct smt_p_mac_status status ; /* mac status */
struct smt_p_mac_counter mc ; /* MAC counter */
struct smt_p_mac_fnc fnc ; /* MAC frame not copied */
struct smp_p_manufacturer man ; /* manufacturer field */
struct smp_p_user user ; /* user field */
#ifdef OPT_PMF
struct smt_p_setcount setcount ; /* Set Count mandatory */
#endif
/* must be last */
struct smt_p_lem lem[1] ; /* phy lem status */
} ;
#define SIZEOF_SMT_SIF_OPERATION (sizeof(struct smt_sif_operation)- \
sizeof(struct smt_p_lem))
/*
* ECF : echo frame
*/
struct smt_ecf {
struct smt_header smt ; /* generic header */
struct smt_p_echo ec_echo ; /* echo parameter */
} ;
#define SMT_ECF_LEN (sizeof(struct smt_header)+sizeof(struct smt_para))
/*
* RDF : request denied frame
*/
struct smt_rdf {
struct smt_header smt ; /* generic header */
struct smt_p_reason reason ; /* reason code */
struct smt_p_version version ; /* supported versions */
struct smt_p_refused refused ; /* refused frame fragment */
} ;
/*
* SBA Request Allocation Response Frame
*/
struct smt_sba_alc_res {
struct smt_header smt ; /* generic header */
struct smt_p_0015 s_type ; /* resource type */
struct smt_p_0016 cmd ; /* SBA command */
struct smt_p_reason reason ; /* reason code */
struct smt_p_320b path ; /* path type */
struct smt_p_320f payload ; /* current SBA payload */
struct smt_p_3210 overhead ; /* current SBA overhead */
struct smt_p_0019 a_addr ; /* Allocation Address */
struct smt_p_001a cat ; /* Category - from the request */
struct smt_p_001d alloc ; /* SBA Allocatable */
} ;
/*
* SBA Request Allocation Request Frame
*/
struct smt_sba_alc_req {
struct smt_header smt ; /* generic header */
struct smt_p_0015 s_type ; /* resource type */
struct smt_p_0016 cmd ; /* SBA command */
struct smt_p_320b path ; /* path type */
struct smt_p_0017 pl_req ; /* requested payload */
struct smt_p_0018 ov_req ; /* requested SBA overhead */
struct smt_p_320f payload ; /* current SBA payload */
struct smt_p_3210 overhead ; /* current SBA overhead */
struct smt_p_0019 a_addr ; /* Allocation Address */
struct smt_p_001a cat ; /* Category - from the request */
struct smt_p_001b tneg ; /* max T-NEG */
struct smt_p_001c segm ; /* minimum segment size */
} ;
/*
* SBA Change Allocation Request Frame
*/
struct smt_sba_chg {
struct smt_header smt ; /* generic header */
struct smt_p_0015 s_type ; /* resource type */
struct smt_p_0016 cmd ; /* SBA command */
struct smt_p_320b path ; /* path type */
struct smt_p_320f payload ; /* current SBA payload */
struct smt_p_3210 overhead ; /* current SBA overhead */
struct smt_p_001a cat ; /* Category - from the request */
} ;
/*
* SBA Report Allocation Request Frame
*/
struct smt_sba_rep_req {
struct smt_header smt ; /* generic header */
struct smt_p_0015 s_type ; /* resource type */
struct smt_p_0016 cmd ; /* SBA command */
} ;
/*
* SBA Report Allocation Response Frame
*/
struct smt_sba_rep_res {
struct smt_header smt ; /* generic header */
struct smt_p_0015 s_type ; /* resource type */
struct smt_p_0016 cmd ; /* SBA command */
struct smt_p_320b path ; /* path type */
struct smt_p_320f payload ; /* current SBA payload */
struct smt_p_3210 overhead ; /* current SBA overhead */
} ;
/*
* actions
*/
#define SMT_STATION_ACTION 1
#define SMT_STATION_ACTION_CONNECT 0
#define SMT_STATION_ACTION_DISCONNECT 1
#define SMT_STATION_ACTION_PATHTEST 2
#define SMT_STATION_ACTION_SELFTEST 3
#define SMT_STATION_ACTION_DISABLE_A 4
#define SMT_STATION_ACTION_DISABLE_B 5
#define SMT_STATION_ACTION_DISABLE_M 6
#define SMT_PORT_ACTION 2
#define SMT_PORT_ACTION_MAINT 0
#define SMT_PORT_ACTION_ENABLE 1
#define SMT_PORT_ACTION_DISABLE 2
#define SMT_PORT_ACTION_START 3
#define SMT_PORT_ACTION_STOP 4
#endif /* _SMT_ */

View file

@ -0,0 +1,326 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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.
*
******************************************************************************/
/*
* defines for all SMT attributes
*/
/*
* this boring file was produced by perl
* thanks Larry !
*/
#define SMT_P0012 0x0012
#define SMT_P0015 0x0015
#define SMT_P0016 0x0016
#define SMT_P0017 0x0017
#define SMT_P0018 0x0018
#define SMT_P0019 0x0019
#define SMT_P001A 0x001a
#define SMT_P001B 0x001b
#define SMT_P001C 0x001c
#define SMT_P001D 0x001d
#define SMT_P100A 0x100a
#define SMT_P100B 0x100b
#define SMT_P100C 0x100c
#define SMT_P100D 0x100d
#define SMT_P100E 0x100e
#define SMT_P100F 0x100f
#define SMT_P1010 0x1010
#define SMT_P1011 0x1011
#define SMT_P1012 0x1012
#define SMT_P1013 0x1013
#define SMT_P1014 0x1014
#define SMT_P1015 0x1015
#define SMT_P1016 0x1016
#define SMT_P1017 0x1017
#define SMT_P1018 0x1018
#define SMT_P1019 0x1019
#define SMT_P101A 0x101a
#define SMT_P101B 0x101b
#define SMT_P101C 0x101c
#define SMT_P101D 0x101d
#define SMT_P101E 0x101e
#define SMT_P101F 0x101f
#define SMT_P1020 0x1020
#define SMT_P1021 0x1021
#define SMT_P1022 0x1022
#define SMT_P1023 0x1023
#define SMT_P1024 0x1024
#define SMT_P1025 0x1025
#define SMT_P1026 0x1026
#define SMT_P1027 0x1027
#define SMT_P1028 0x1028
#define SMT_P1029 0x1029
#define SMT_P102A 0x102a
#define SMT_P102B 0x102b
#define SMT_P102C 0x102c
#define SMT_P102D 0x102d
#define SMT_P102E 0x102e
#define SMT_P102F 0x102f
#define SMT_P1030 0x1030
#define SMT_P1031 0x1031
#define SMT_P1032 0x1032
#define SMT_P1033 0x1033
#define SMT_P1034 0x1034
#define SMT_P1035 0x1035
#define SMT_P1036 0x1036
#define SMT_P1037 0x1037
#define SMT_P1038 0x1038
#define SMT_P1039 0x1039
#define SMT_P103A 0x103a
#define SMT_P103B 0x103b
#define SMT_P103C 0x103c
#define SMT_P103D 0x103d
#define SMT_P103E 0x103e
#define SMT_P103F 0x103f
#define SMT_P1040 0x1040
#define SMT_P1041 0x1041
#define SMT_P1042 0x1042
#define SMT_P1043 0x1043
#define SMT_P1044 0x1044
#define SMT_P1045 0x1045
#define SMT_P1046 0x1046
#define SMT_P1047 0x1047
#define SMT_P1048 0x1048
#define SMT_P1049 0x1049
#define SMT_P104A 0x104a
#define SMT_P104B 0x104b
#define SMT_P104C 0x104c
#define SMT_P104D 0x104d
#define SMT_P104E 0x104e
#define SMT_P104F 0x104f
#define SMT_P1050 0x1050
#define SMT_P1051 0x1051
#define SMT_P1052 0x1052
#define SMT_P1053 0x1053
#define SMT_P1054 0x1054
#define SMT_P10F0 0x10f0
#define SMT_P10F1 0x10f1
#ifdef ESS
#define SMT_P10F2 0x10f2
#define SMT_P10F3 0x10f3
#define SMT_P10F4 0x10f4
#define SMT_P10F5 0x10f5
#define SMT_P10F6 0x10f6
#define SMT_P10F7 0x10f7
#endif
#ifdef SBA
#define SMT_P10F8 0x10f8
#define SMT_P10F9 0x10f9
#endif
#define SMT_P200A 0x200a
#define SMT_P200B 0x200b
#define SMT_P200C 0x200c
#define SMT_P200D 0x200d
#define SMT_P200E 0x200e
#define SMT_P200F 0x200f
#define SMT_P2010 0x2010
#define SMT_P2011 0x2011
#define SMT_P2012 0x2012
#define SMT_P2013 0x2013
#define SMT_P2014 0x2014
#define SMT_P2015 0x2015
#define SMT_P2016 0x2016
#define SMT_P2017 0x2017
#define SMT_P2018 0x2018
#define SMT_P2019 0x2019
#define SMT_P201A 0x201a
#define SMT_P201B 0x201b
#define SMT_P201C 0x201c
#define SMT_P201D 0x201d
#define SMT_P201E 0x201e
#define SMT_P201F 0x201f
#define SMT_P2020 0x2020
#define SMT_P2021 0x2021
#define SMT_P2022 0x2022
#define SMT_P2023 0x2023
#define SMT_P2024 0x2024
#define SMT_P2025 0x2025
#define SMT_P2026 0x2026
#define SMT_P2027 0x2027
#define SMT_P2028 0x2028
#define SMT_P2029 0x2029
#define SMT_P202A 0x202a
#define SMT_P202B 0x202b
#define SMT_P202C 0x202c
#define SMT_P202D 0x202d
#define SMT_P202E 0x202e
#define SMT_P202F 0x202f
#define SMT_P2030 0x2030
#define SMT_P2031 0x2031
#define SMT_P2032 0x2032
#define SMT_P2033 0x2033
#define SMT_P2034 0x2034
#define SMT_P2035 0x2035
#define SMT_P2036 0x2036
#define SMT_P2037 0x2037
#define SMT_P2038 0x2038
#define SMT_P2039 0x2039
#define SMT_P203A 0x203a
#define SMT_P203B 0x203b
#define SMT_P203C 0x203c
#define SMT_P203D 0x203d
#define SMT_P203E 0x203e
#define SMT_P203F 0x203f
#define SMT_P2040 0x2040
#define SMT_P2041 0x2041
#define SMT_P2042 0x2042
#define SMT_P2043 0x2043
#define SMT_P2044 0x2044
#define SMT_P2045 0x2045
#define SMT_P2046 0x2046
#define SMT_P2047 0x2047
#define SMT_P2048 0x2048
#define SMT_P2049 0x2049
#define SMT_P204A 0x204a
#define SMT_P204B 0x204b
#define SMT_P204C 0x204c
#define SMT_P204D 0x204d
#define SMT_P204E 0x204e
#define SMT_P204F 0x204f
#define SMT_P2050 0x2050
#define SMT_P2051 0x2051
#define SMT_P2052 0x2052
#define SMT_P2053 0x2053
#define SMT_P2054 0x2054
#define SMT_P2055 0x2055
#define SMT_P2056 0x2056
#define SMT_P2057 0x2057
#define SMT_P2058 0x2058
#define SMT_P2059 0x2059
#define SMT_P205A 0x205a
#define SMT_P205B 0x205b
#define SMT_P205C 0x205c
#define SMT_P205D 0x205d
#define SMT_P205E 0x205e
#define SMT_P205F 0x205f
#define SMT_P2060 0x2060
#define SMT_P2061 0x2061
#define SMT_P2062 0x2062
#define SMT_P2063 0x2063
#define SMT_P2064 0x2064
#define SMT_P2065 0x2065
#define SMT_P2066 0x2066
#define SMT_P2067 0x2067
#define SMT_P2068 0x2068
#define SMT_P2069 0x2069
#define SMT_P206A 0x206a
#define SMT_P206B 0x206b
#define SMT_P206C 0x206c
#define SMT_P206D 0x206d
#define SMT_P206E 0x206e
#define SMT_P206F 0x206f
#define SMT_P2070 0x2070
#define SMT_P2071 0x2071
#define SMT_P2072 0x2072
#define SMT_P2073 0x2073
#define SMT_P2074 0x2074
#define SMT_P2075 0x2075
#define SMT_P2076 0x2076
#define SMT_P208C 0x208c
#define SMT_P208D 0x208d
#define SMT_P208E 0x208e
#define SMT_P208F 0x208f
#define SMT_P2090 0x2090
#define SMT_P20F0 0x20F0
#define SMT_P20F1 0x20F1
#define SMT_P320A 0x320a
#define SMT_P320B 0x320b
#define SMT_P320C 0x320c
#define SMT_P320D 0x320d
#define SMT_P320E 0x320e
#define SMT_P320F 0x320f
#define SMT_P3210 0x3210
#define SMT_P3211 0x3211
#define SMT_P3212 0x3212
#define SMT_P3213 0x3213
#define SMT_P3214 0x3214
#define SMT_P3215 0x3215
#define SMT_P3216 0x3216
#define SMT_P3217 0x3217
#define SMT_P400A 0x400a
#define SMT_P400B 0x400b
#define SMT_P400C 0x400c
#define SMT_P400D 0x400d
#define SMT_P400E 0x400e
#define SMT_P400F 0x400f
#define SMT_P4010 0x4010
#define SMT_P4011 0x4011
#define SMT_P4012 0x4012
#define SMT_P4013 0x4013
#define SMT_P4014 0x4014
#define SMT_P4015 0x4015
#define SMT_P4016 0x4016
#define SMT_P4017 0x4017
#define SMT_P4018 0x4018
#define SMT_P4019 0x4019
#define SMT_P401A 0x401a
#define SMT_P401B 0x401b
#define SMT_P401C 0x401c
#define SMT_P401D 0x401d
#define SMT_P401E 0x401e
#define SMT_P401F 0x401f
#define SMT_P4020 0x4020
#define SMT_P4021 0x4021
#define SMT_P4022 0x4022
#define SMT_P4023 0x4023
#define SMT_P4024 0x4024
#define SMT_P4025 0x4025
#define SMT_P4026 0x4026
#define SMT_P4027 0x4027
#define SMT_P4028 0x4028
#define SMT_P4029 0x4029
#define SMT_P402A 0x402a
#define SMT_P402B 0x402b
#define SMT_P402C 0x402c
#define SMT_P402D 0x402d
#define SMT_P402E 0x402e
#define SMT_P402F 0x402f
#define SMT_P4030 0x4030
#define SMT_P4031 0x4031
#define SMT_P4032 0x4032
#define SMT_P4033 0x4033
#define SMT_P4034 0x4034
#define SMT_P4035 0x4035
#define SMT_P4036 0x4036
#define SMT_P4037 0x4037
#define SMT_P4038 0x4038
#define SMT_P4039 0x4039
#define SMT_P403A 0x403a
#define SMT_P403B 0x403b
#define SMT_P403C 0x403c
#define SMT_P403D 0x403d
#define SMT_P403E 0x403e
#define SMT_P403F 0x403f
#define SMT_P4040 0x4040
#define SMT_P4041 0x4041
#define SMT_P4042 0x4042
#define SMT_P4043 0x4043
#define SMT_P4044 0x4044
#define SMT_P4045 0x4045
#define SMT_P4046 0x4046
#define SMT_P4050 0x4050
#define SMT_P4051 0x4051
#define SMT_P4052 0x4052
#define SMT_P4053 0x4053

View file

@ -0,0 +1,106 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 _SKFP_H_SMTSTATE_H_
#define _SKFP_H_SMTSTATE_H_
/*
* SMT state definitions
*/
#ifndef KERNEL
/*
* PCM states
*/
#define PC0_OFF 0
#define PC1_BREAK 1
#define PC2_TRACE 2
#define PC3_CONNECT 3
#define PC4_NEXT 4
#define PC5_SIGNAL 5
#define PC6_JOIN 6
#define PC7_VERIFY 7
#define PC8_ACTIVE 8
#define PC9_MAINT 9
/*
* PCM modes
*/
#define PM_NONE 0
#define PM_PEER 1
#define PM_TREE 2
/*
* PCM type
*/
#define TA 0
#define TB 1
#define TS 2
#define TM 3
#define TNONE 4
/*
* CFM states
*/
#define SC0_ISOLATED 0 /* isolated */
#define SC1_WRAP_A 5 /* wrap A */
#define SC2_WRAP_B 6 /* wrap B */
#define SC4_THRU_A 12 /* through A */
#define SC5_THRU_B 7 /* through B (SMt 6.2) */
#define SC7_WRAP_S 8 /* SAS */
/*
* ECM states
*/
#define EC0_OUT 0
#define EC1_IN 1
#define EC2_TRACE 2
#define EC3_LEAVE 3
#define EC4_PATH_TEST 4
#define EC5_INSERT 5
#define EC6_CHECK 6
#define EC7_DEINSERT 7
/*
* RMT states
*/
#define RM0_ISOLATED 0
#define RM1_NON_OP 1 /* not operational */
#define RM2_RING_OP 2 /* ring operational */
#define RM3_DETECT 3 /* detect dupl addresses */
#define RM4_NON_OP_DUP 4 /* dupl. addr detected */
#define RM5_RING_OP_DUP 5 /* ring oper. with dupl. addr */
#define RM6_DIRECTED 6 /* sending directed beacons */
#define RM7_TRACE 7 /* trace initiated */
#endif
struct pcm_state {
unsigned char pcm_type ; /* TA TB TS TM */
unsigned char pcm_state ; /* state PC[0-9]_* */
unsigned char pcm_mode ; /* PM_{NONE,PEER,TREE} */
unsigned char pcm_neighbor ; /* TA TB TS TM */
unsigned char pcm_bsf ; /* flag bs : TRUE/FALSE */
unsigned char pcm_lsf ; /* flag ls : TRUE/FALSE */
unsigned char pcm_lct_fail ; /* counter lct_fail */
unsigned char pcm_ls_rx ; /* rx line state */
short pcm_r_val ; /* signaling bits */
short pcm_t_val ; /* signaling bits */
} ;
struct smt_state {
struct pcm_state pcm_state[NUMPHYS] ; /* port A & port B */
} ;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,138 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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 _TARGETHW_
#define _TARGETHW_
/*
* PCI Watermark definition
*/
#ifdef PCI
#define RX_WATERMARK 24
#define TX_WATERMARK 24
#define SK_ML_ID_1 0x20
#define SK_ML_ID_2 0x30
#endif
#include "skfbi.h"
#ifndef TAG_MODE
#include "fplus.h"
#else
#include "fplustm.h"
#endif
#ifndef HW_PTR
#define HW_PTR void __iomem *
#endif
#ifdef MULT_OEM
#define OI_STAT_LAST 0 /* end of OEM data base */
#define OI_STAT_PRESENT 1 /* entry present but not empty */
#define OI_STAT_VALID 2 /* holds valid ID, but is not active */
#define OI_STAT_ACTIVE 3 /* holds valid ID, entry is active */
/* active = adapter is supported */
/* Memory representation of IDs must match representation in adapter. */
struct s_oem_ids {
u_char oi_status ; /* Stat: last, present, valid, active */
u_char oi_mark[5] ; /* "PID00" .. "PID07" .. */
u_char oi_id[4] ; /* id bytes, representation as */
/* defined by hardware, */
#ifdef PCI
u_char oi_sub_id[4] ; /* sub id bytes, representation as */
/* defined by hardware, */
#endif
} ;
#endif /* MULT_OEM */
struct s_smt_hw {
/*
* global
*/
HW_PTR iop ; /* IO base address */
short dma ; /* DMA channel */
short irq ; /* IRQ level */
short eprom ; /* FLASH prom */
#ifndef SYNC
u_short n_a_send ; /* pending send requests */
#endif
#if defined(PCI)
short slot ; /* slot number */
short max_slots ; /* maximum number of slots */
short wdog_used ; /* TRUE if the watch dog is used */
#endif
#ifdef PCI
u_short pci_handle ; /* handle to access the BIOS func */
u_long is_imask ; /* int maske for the int source reg */
u_long phys_mem_addr ; /* physical memory address */
u_short mc_dummy ; /* work around for MC compiler bug */
/*
* state of the hardware
*/
u_short hw_state ; /* started or stopped */
#define STARTED 1
#define STOPPED 0
int hw_is_64bit ; /* does we have a 64 bit adapter */
#endif
#ifdef TAG_MODE
u_long pci_fix_value ; /* value parsed by PCIFIX */
#endif
/*
* hwt.c
*/
u_long t_start ; /* HWT start */
u_long t_stop ; /* HWT stop */
u_short timer_activ ; /* HWT timer active */
/*
* PIC
*/
u_char pic_a1 ;
u_char pic_21 ;
/*
* GENERIC ; do not modify beyond this line
*/
/*
* physical and canonical address
*/
struct fddi_addr fddi_home_addr ;
struct fddi_addr fddi_canon_addr ;
struct fddi_addr fddi_phys_addr ;
/*
* mac variables
*/
struct mac_parameter mac_pa ; /* tmin, tmax, tvx, treq .. */
struct mac_counter mac_ct ; /* recv., lost, error */
u_short mac_ring_is_up ; /* ring is up flag */
struct s_smt_fp fp ; /* formac+ */
#ifdef MULT_OEM
struct s_oem_ids *oem_id ; /* pointer to selected id */
int oem_min_status ; /* IDs to take care of */
#endif /* MULT_OEM */
} ;
#endif

View file

@ -0,0 +1,164 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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.
*
******************************************************************************/
/*
* Operating system specific definitions for driver and
* hardware module.
*/
#ifndef TARGETOS_H
#define TARGETOS_H
//-------- those should go into include/linux/pci.h
#define PCI_VENDOR_ID_SK 0x1148
#define PCI_DEVICE_ID_SK_FP 0x4000
//--------
//-------- those should go into include/linux/if_fddi.h
#define FDDI_MAC_HDR_LEN 13
#define FDDI_RII 0x01 /* routing information bit */
#define FDDI_RCF_DIR_BIT 0x80
#define FDDI_RCF_LEN_MASK 0x1f
#define FDDI_RCF_BROADCAST 0x8000
#define FDDI_RCF_LIMITED_BROADCAST 0xA000
#define FDDI_RCF_FRAME2K 0x20
#define FDDI_RCF_FRAME4K 0x30
//--------
#undef ADDR
#include <asm/io.h>
#include <linux/netdevice.h>
#include <linux/fddidevice.h>
#include <linux/skbuff.h>
#include <linux/pci.h>
// is redefined by linux, but we need our definition
#undef ADDR
#ifdef MEM_MAPPED_IO
#define ADDR(a) (smc->hw.iop+(a))
#else
#define ADDR(a) (((a)>>7) ? (outp(smc->hw.iop+B0_RAP,(a)>>7), (smc->hw.iop+( ((a)&0x7F) | ((a)>>7 ? 0x80:0)) )) : (smc->hw.iop+(((a)&0x7F)|((a)>>7 ? 0x80:0))))
#endif
#include "hwmtm.h"
#define TRUE 1
#define FALSE 0
// HWM Definitions
// -----------------------
#define FDDI_TRACE(string, arg1, arg2, arg3) // Performance analysis.
#ifdef PCI
#define NDD_TRACE(string, arg1, arg2, arg3) // Performance analysis.
#endif // PCI
#define SMT_PAGESIZE PAGE_SIZE // Size of a memory page (power of 2).
// -----------------------
// SMT Definitions
// -----------------------
#define TICKS_PER_SECOND HZ
#define SMC_VERSION 1
// -----------------------
// OS-Driver Definitions
// -----------------------
#define NO_ADDRESS 0xffe0 /* No Device (I/O) Address */
#define SKFP_MAX_NUM_BOARDS 8 /* maximum number of PCI boards */
#define SK_BUS_TYPE_PCI 0
#define SK_BUS_TYPE_EISA 1
#define FP_IO_LEN 256 /* length of IO area used */
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
#define MAX_TX_QUEUE_LEN 20 // number of packets queued by driver
#define MAX_FRAME_SIZE 4550
#define RX_LOW_WATERMARK NUM_RECEIVE_BUFFERS / 2
#define TX_LOW_WATERMARK NUM_TRANSMIT_BUFFERS - 2
/*
** Include the IOCTL stuff
*/
#include <linux/sockios.h>
#define SKFPIOCTL SIOCDEVPRIVATE
struct s_skfp_ioctl {
unsigned short cmd; /* Command to run */
unsigned short len; /* Length of the data buffer */
unsigned char __user *data; /* Pointer to the data buffer */
};
/*
** Recognised ioctl commands for the driver
*/
#define SKFP_GET_STATS 0x05 /* Get the driver statistics */
#define SKFP_CLR_STATS 0x06 /* Zero out the driver statistics */
// The per-adapter driver structure
struct s_smt_os {
struct net_device *dev;
struct net_device *next_module;
u32 bus_type; /* bus type (0 == PCI, 1 == EISA) */
struct pci_dev pdev; /* PCI device structure */
unsigned long base_addr;
unsigned char factory_mac_addr[8];
ulong SharedMemSize;
ulong SharedMemHeap;
void* SharedMemAddr;
dma_addr_t SharedMemDMA;
ulong QueueSkb;
struct sk_buff_head SendSkbQueue;
ulong MaxFrameSize;
u8 ResetRequested;
// MAC statistics structure
struct fddi_statistics MacStat;
// receive into this local buffer if no skb available
// data will be not valid, because multiple RxDs can
// point here at the same time, it must be at least
// MAX_FRAME_SIZE bytes in size
unsigned char *LocalRxBuffer;
dma_addr_t LocalRxBufferDMA;
// Version (required by SMT module).
u_long smc_version ;
// Required by Hardware Module (HWM).
struct hw_modul hwm ;
// For SMP-savety
spinlock_t DriverLock;
};
typedef struct s_smt_os skfddi_priv;
#endif // _TARGETOS_

View file

@ -0,0 +1,39 @@
/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* 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.
*
******************************************************************************/
#include <linux/types.h>
/*
----------------------
Basic SMT system types
----------------------
*/
#ifndef _TYPES_
#define _TYPES_
#define _packed
#ifndef far
#define far
#endif
#ifndef _far
#define _far
#endif
#define inp(p) ioread8(p)
#define inpw(p) ioread16(p)
#define inpd(p) ioread32(p)
#define outp(p,c) iowrite8(c,p)
#define outpw(p,s) iowrite16(s,p)
#define outpd(p,l) iowrite32(l,p)
#endif /* _TYPES_ */

File diff suppressed because it is too large Load diff

269
drivers/net/fddi/skfp/hwt.c Normal file
View file

@ -0,0 +1,269 @@
/******************************************************************************
*
* (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.
*
******************************************************************************/
/*
* Timer Driver for FBI board (timer chip 82C54)
*/
/*
* Modifications:
*
* 28-Jun-1994 sw Edit v1.6.
* MCA: Added support for the SK-NET FDDI-FM2 adapter. The
* following functions have been added(+) or modified(*):
* hwt_start(*), hwt_stop(*), hwt_restart(*), hwt_read(*)
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#ifndef lint
static const char ID_sccs[] = "@(#)hwt.c 1.13 97/04/23 (C) SK " ;
#endif
/*
* Prototypes of local functions.
*/
/* 28-Jun-1994 sw - Note: hwt_restart() is also used in module 'drvfbi.c'. */
/*static void hwt_restart() ; */
/************************
*
* hwt_start
*
* Start hardware timer (clock ticks are 16us).
*
* void hwt_start(
* struct s_smc *smc,
* u_long time) ;
* In
* smc - A pointer to the SMT Context structure.
*
* time - The time in units of 16us to load the timer with.
* Out
* Nothing.
*
************************/
#define HWT_MAX (65000)
void hwt_start(struct s_smc *smc, u_long time)
{
u_short cnt ;
if (time > HWT_MAX)
time = HWT_MAX ;
smc->hw.t_start = time ;
smc->hw.t_stop = 0L ;
cnt = (u_short)time ;
/*
* if time < 16 us
* time = 16 us
*/
if (!cnt)
cnt++ ;
outpd(ADDR(B2_TI_INI), (u_long) cnt * 200) ; /* Load timer value. */
outpw(ADDR(B2_TI_CRTL), TIM_START) ; /* Start timer. */
smc->hw.timer_activ = TRUE ;
}
/************************
*
* hwt_stop
*
* Stop hardware timer.
*
* void hwt_stop(
* struct s_smc *smc) ;
* In
* smc - A pointer to the SMT Context structure.
* Out
* Nothing.
*
************************/
void hwt_stop(struct s_smc *smc)
{
outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
outpw(ADDR(B2_TI_CRTL), TIM_CL_IRQ) ;
smc->hw.timer_activ = FALSE ;
}
/************************
*
* hwt_init
*
* Initialize hardware timer.
*
* void hwt_init(
* struct s_smc *smc) ;
* In
* smc - A pointer to the SMT Context structure.
* Out
* Nothing.
*
************************/
void hwt_init(struct s_smc *smc)
{
smc->hw.t_start = 0 ;
smc->hw.t_stop = 0 ;
smc->hw.timer_activ = FALSE ;
hwt_restart(smc) ;
}
/************************
*
* hwt_restart
*
* Clear timer interrupt.
*
* void hwt_restart(
* struct s_smc *smc) ;
* In
* smc - A pointer to the SMT Context structure.
* Out
* Nothing.
*
************************/
void hwt_restart(struct s_smc *smc)
{
hwt_stop(smc) ;
}
/************************
*
* hwt_read
*
* Stop hardware timer and read time elapsed since last start.
*
* u_long hwt_read(smc) ;
* In
* smc - A pointer to the SMT Context structure.
* Out
* The elapsed time since last start in units of 16us.
*
************************/
u_long hwt_read(struct s_smc *smc)
{
u_short tr ;
u_long is ;
if (smc->hw.timer_activ) {
hwt_stop(smc) ;
tr = (u_short)((inpd(ADDR(B2_TI_VAL))/200) & 0xffff) ;
is = GET_ISR() ;
/* Check if timer expired (or wraparound). */
if ((tr > smc->hw.t_start) || (is & IS_TIMINT)) {
hwt_restart(smc) ;
smc->hw.t_stop = smc->hw.t_start ;
}
else
smc->hw.t_stop = smc->hw.t_start - tr ;
}
return smc->hw.t_stop;
}
#ifdef PCI
/************************
*
* hwt_quick_read
*
* Stop hardware timer and read timer value and start the timer again.
*
* u_long hwt_read(smc) ;
* In
* smc - A pointer to the SMT Context structure.
* Out
* current timer value in units of 80ns.
*
************************/
u_long hwt_quick_read(struct s_smc *smc)
{
u_long interval ;
u_long time ;
interval = inpd(ADDR(B2_TI_INI)) ;
outpw(ADDR(B2_TI_CRTL), TIM_STOP) ;
time = inpd(ADDR(B2_TI_VAL)) ;
outpd(ADDR(B2_TI_INI),time) ;
outpw(ADDR(B2_TI_CRTL), TIM_START) ;
outpd(ADDR(B2_TI_INI),interval) ;
return time;
}
/************************
*
* hwt_wait_time(smc,start,duration)
*
* This function returnes after the amount of time is elapsed
* since the start time.
*
* para start start time
* duration time to wait
*
* NOTE: The function will return immediately, if the timer is not
* started
************************/
void hwt_wait_time(struct s_smc *smc, u_long start, long int duration)
{
long diff ;
long interval ;
int wrapped ;
/*
* check if timer is running
*/
if (smc->hw.timer_activ == FALSE ||
hwt_quick_read(smc) == hwt_quick_read(smc)) {
return ;
}
interval = inpd(ADDR(B2_TI_INI)) ;
if (interval > duration) {
do {
diff = (long)(start - hwt_quick_read(smc)) ;
if (diff < 0) {
diff += interval ;
}
} while (diff <= duration) ;
}
else {
diff = interval ;
wrapped = 0 ;
do {
if (!wrapped) {
if (hwt_quick_read(smc) >= start) {
diff += interval ;
wrapped = 1 ;
}
}
else {
if (hwt_quick_read(smc) < start) {
wrapped = 0 ;
}
}
} while (diff <= duration) ;
}
}
#endif

File diff suppressed because it is too large Load diff

1663
drivers/net/fddi/skfp/pmf.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,173 @@
/******************************************************************************
*
* (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 Event Queue Management
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#ifndef lint
static const char ID_sccs[] = "@(#)queue.c 2.9 97/08/04 (C) SK " ;
#endif
#define PRINTF(a,b,c)
/*
* init event queue management
*/
void ev_init(struct s_smc *smc)
{
smc->q.ev_put = smc->q.ev_get = smc->q.ev_queue ;
}
/*
* add event to queue
*/
void queue_event(struct s_smc *smc, int class, int event)
{
PRINTF("queue class %d event %d\n",class,event) ;
smc->q.ev_put->class = class ;
smc->q.ev_put->event = event ;
if (++smc->q.ev_put == &smc->q.ev_queue[MAX_EVENT])
smc->q.ev_put = smc->q.ev_queue ;
if (smc->q.ev_put == smc->q.ev_get) {
SMT_ERR_LOG(smc,SMT_E0137, SMT_E0137_MSG) ;
}
}
/*
* timer_event is called from HW timer package.
*/
void timer_event(struct s_smc *smc, u_long token)
{
PRINTF("timer event class %d token %d\n",
EV_T_CLASS(token),
EV_T_EVENT(token)) ;
queue_event(smc,EV_T_CLASS(token),EV_T_EVENT(token));
}
/*
* event dispatcher
* while event queue is not empty
* get event from queue
* send command to state machine
* end
*/
void ev_dispatcher(struct s_smc *smc)
{
struct event_queue *ev ; /* pointer into queue */
int class ;
ev = smc->q.ev_get ;
PRINTF("dispatch get %x put %x\n",ev,smc->q.ev_put) ;
while (ev != smc->q.ev_put) {
PRINTF("dispatch class %d event %d\n",ev->class,ev->event) ;
switch(class = ev->class) {
case EVENT_ECM : /* Entity Corordination Man. */
ecm(smc,(int)ev->event) ;
break ;
case EVENT_CFM : /* Configuration Man. */
cfm(smc,(int)ev->event) ;
break ;
case EVENT_RMT : /* Ring Man. */
rmt(smc,(int)ev->event) ;
break ;
case EVENT_SMT :
smt_event(smc,(int)ev->event) ;
break ;
#ifdef CONCENTRATOR
case 99 :
timer_test_event(smc,(int)ev->event) ;
break ;
#endif
case EVENT_PCMA : /* PHY A */
case EVENT_PCMB : /* PHY B */
default :
if (class >= EVENT_PCMA &&
class < EVENT_PCMA + NUMPHYS) {
pcm(smc,class - EVENT_PCMA,(int)ev->event) ;
break ;
}
SMT_PANIC(smc,SMT_E0121, SMT_E0121_MSG) ;
return ;
}
if (++ev == &smc->q.ev_queue[MAX_EVENT])
ev = smc->q.ev_queue ;
/* Renew get: it is used in queue_events to detect overruns */
smc->q.ev_get = ev;
}
}
/*
* smt_online connects to or disconnects from the ring
* MUST be called to initiate connection establishment
*
* on 0 disconnect
* on 1 connect
*/
u_short smt_online(struct s_smc *smc, int on)
{
queue_event(smc,EVENT_ECM,on ? EC_CONNECT : EC_DISCONNECT) ;
ev_dispatcher(smc) ;
return smc->mib.fddiSMTCF_State;
}
/*
* set SMT flag to value
* flag flag name
* value flag value
* dump current flag setting
*/
#ifdef CONCENTRATOR
void do_smt_flag(struct s_smc *smc, char *flag, int value)
{
#ifdef DEBUG
struct smt_debug *deb;
SK_UNUSED(smc) ;
#ifdef DEBUG_BRD
deb = &smc->debug;
#else
deb = &debug;
#endif
if (!strcmp(flag,"smt"))
deb->d_smt = value ;
else if (!strcmp(flag,"smtf"))
deb->d_smtf = value ;
else if (!strcmp(flag,"pcm"))
deb->d_pcm = value ;
else if (!strcmp(flag,"rmt"))
deb->d_rmt = value ;
else if (!strcmp(flag,"cfm"))
deb->d_cfm = value ;
else if (!strcmp(flag,"ecm"))
deb->d_ecm = value ;
printf("smt %d\n",deb->d_smt) ;
printf("smtf %d\n",deb->d_smtf) ;
printf("pcm %d\n",deb->d_pcm) ;
printf("rmt %d\n",deb->d_rmt) ;
printf("cfm %d\n",deb->d_cfm) ;
printf("ecm %d\n",deb->d_ecm) ;
#endif /* DEBUG */
}
#endif

654
drivers/net/fddi/skfp/rmt.c Normal file
View file

@ -0,0 +1,654 @@
/******************************************************************************
*
* (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 RMT
Ring Management
*/
/*
* Hardware independent state machine implemantation
* The following external SMT functions are referenced :
*
* queue_event()
* smt_timer_start()
* smt_timer_stop()
*
* The following external HW dependent functions are referenced :
* sm_ma_control()
* sm_mac_check_beacon_claim()
*
* The following HW dependent events are required :
* RM_RING_OP
* RM_RING_NON_OP
* RM_MY_BEACON
* RM_OTHER_BEACON
* RM_MY_CLAIM
* RM_TRT_EXP
* RM_VALID_CLAIM
*
*/
#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[] = "@(#)rmt.c 2.13 99/07/02 (C) SK " ;
#endif
/*
* FSM Macros
*/
#define AFLAG 0x10
#define GO_STATE(x) (smc->mib.m[MAC0].fddiMACRMTState = (x)|AFLAG)
#define ACTIONS_DONE() (smc->mib.m[MAC0].fddiMACRMTState &= ~AFLAG)
#define ACTIONS(x) (x|AFLAG)
#define RM0_ISOLATED 0
#define RM1_NON_OP 1 /* not operational */
#define RM2_RING_OP 2 /* ring operational */
#define RM3_DETECT 3 /* detect dupl addresses */
#define RM4_NON_OP_DUP 4 /* dupl. addr detected */
#define RM5_RING_OP_DUP 5 /* ring oper. with dupl. addr */
#define RM6_DIRECTED 6 /* sending directed beacons */
#define RM7_TRACE 7 /* trace initiated */
#ifdef DEBUG
/*
* symbolic state names
*/
static const char * const rmt_states[] = {
"RM0_ISOLATED","RM1_NON_OP","RM2_RING_OP","RM3_DETECT",
"RM4_NON_OP_DUP","RM5_RING_OP_DUP","RM6_DIRECTED",
"RM7_TRACE"
} ;
/*
* symbolic event names
*/
static const char * const rmt_events[] = {
"NONE","RM_RING_OP","RM_RING_NON_OP","RM_MY_BEACON",
"RM_OTHER_BEACON","RM_MY_CLAIM","RM_TRT_EXP","RM_VALID_CLAIM",
"RM_JOIN","RM_LOOP","RM_DUP_ADDR","RM_ENABLE_FLAG",
"RM_TIMEOUT_NON_OP","RM_TIMEOUT_T_STUCK",
"RM_TIMEOUT_ANNOUNCE","RM_TIMEOUT_T_DIRECT",
"RM_TIMEOUT_D_MAX","RM_TIMEOUT_POLL","RM_TX_STATE_CHANGE"
} ;
#endif
/*
* Globals
* in struct s_rmt
*/
/*
* function declarations
*/
static void rmt_fsm(struct s_smc *smc, int cmd);
static void start_rmt_timer0(struct s_smc *smc, u_long value, int event);
static void start_rmt_timer1(struct s_smc *smc, u_long value, int event);
static void start_rmt_timer2(struct s_smc *smc, u_long value, int event);
static void stop_rmt_timer0(struct s_smc *smc);
static void stop_rmt_timer1(struct s_smc *smc);
static void stop_rmt_timer2(struct s_smc *smc);
static void rmt_dup_actions(struct s_smc *smc);
static void rmt_reinsert_actions(struct s_smc *smc);
static void rmt_leave_actions(struct s_smc *smc);
static void rmt_new_dup_actions(struct s_smc *smc);
#ifndef SUPERNET_3
extern void restart_trt_for_dbcn() ;
#endif /*SUPERNET_3*/
/*
init RMT state machine
clear all RMT vars and flags
*/
void rmt_init(struct s_smc *smc)
{
smc->mib.m[MAC0].fddiMACRMTState = ACTIONS(RM0_ISOLATED) ;
smc->r.dup_addr_test = DA_NONE ;
smc->r.da_flag = 0 ;
smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
smc->r.sm_ma_avail = FALSE ;
smc->r.loop_avail = 0 ;
smc->r.bn_flag = 0 ;
smc->r.jm_flag = 0 ;
smc->r.no_flag = TRUE ;
}
/*
RMT state machine
called by dispatcher
do
display state change
process event
until SM is stable
*/
void rmt(struct s_smc *smc, int event)
{
int state ;
do {
DB_RMT("RMT : state %s%s",
(smc->mib.m[MAC0].fddiMACRMTState & AFLAG) ? "ACTIONS " : "",
rmt_states[smc->mib.m[MAC0].fddiMACRMTState & ~AFLAG]) ;
DB_RMT(" event %s\n",rmt_events[event],0) ;
state = smc->mib.m[MAC0].fddiMACRMTState ;
rmt_fsm(smc,event) ;
event = 0 ;
} while (state != smc->mib.m[MAC0].fddiMACRMTState) ;
rmt_state_change(smc,(int)smc->mib.m[MAC0].fddiMACRMTState) ;
}
/*
process RMT event
*/
static void rmt_fsm(struct s_smc *smc, int cmd)
{
/*
* RM00-RM70 : from all states
*/
if (!smc->r.rm_join && !smc->r.rm_loop &&
smc->mib.m[MAC0].fddiMACRMTState != ACTIONS(RM0_ISOLATED) &&
smc->mib.m[MAC0].fddiMACRMTState != RM0_ISOLATED) {
RS_SET(smc,RS_NORINGOP) ;
rmt_indication(smc,0) ;
GO_STATE(RM0_ISOLATED) ;
return ;
}
switch(smc->mib.m[MAC0].fddiMACRMTState) {
case ACTIONS(RM0_ISOLATED) :
stop_rmt_timer0(smc) ;
stop_rmt_timer1(smc) ;
stop_rmt_timer2(smc) ;
/*
* Disable MAC.
*/
sm_ma_control(smc,MA_OFFLINE) ;
smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
smc->r.loop_avail = FALSE ;
smc->r.sm_ma_avail = FALSE ;
smc->r.no_flag = TRUE ;
DB_RMTN(1,"RMT : ISOLATED\n",0,0) ;
ACTIONS_DONE() ;
break ;
case RM0_ISOLATED :
/*RM01*/
if (smc->r.rm_join || smc->r.rm_loop) {
/*
* According to the standard the MAC must be reset
* here. The FORMAC will be initialized and Claim
* and Beacon Frames will be uploaded to the MAC.
* So any change of Treq will take effect NOW.
*/
sm_ma_control(smc,MA_RESET) ;
GO_STATE(RM1_NON_OP) ;
break ;
}
break ;
case ACTIONS(RM1_NON_OP) :
start_rmt_timer0(smc,smc->s.rmt_t_non_op,RM_TIMEOUT_NON_OP) ;
stop_rmt_timer1(smc) ;
stop_rmt_timer2(smc) ;
sm_ma_control(smc,MA_BEACON) ;
DB_RMTN(1,"RMT : RING DOWN\n",0,0) ;
RS_SET(smc,RS_NORINGOP) ;
smc->r.sm_ma_avail = FALSE ;
rmt_indication(smc,0) ;
ACTIONS_DONE() ;
break ;
case RM1_NON_OP :
/*RM12*/
if (cmd == RM_RING_OP) {
RS_SET(smc,RS_RINGOPCHANGE) ;
GO_STATE(RM2_RING_OP) ;
break ;
}
/*RM13*/
else if (cmd == RM_TIMEOUT_NON_OP) {
smc->r.bn_flag = FALSE ;
smc->r.no_flag = TRUE ;
GO_STATE(RM3_DETECT) ;
break ;
}
break ;
case ACTIONS(RM2_RING_OP) :
stop_rmt_timer0(smc) ;
stop_rmt_timer1(smc) ;
stop_rmt_timer2(smc) ;
smc->r.no_flag = FALSE ;
if (smc->r.rm_loop)
smc->r.loop_avail = TRUE ;
if (smc->r.rm_join) {
smc->r.sm_ma_avail = TRUE ;
if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
else
smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
}
DB_RMTN(1,"RMT : RING UP\n",0,0) ;
RS_CLEAR(smc,RS_NORINGOP) ;
RS_SET(smc,RS_RINGOPCHANGE) ;
rmt_indication(smc,1) ;
smt_stat_counter(smc,0) ;
ACTIONS_DONE() ;
break ;
case RM2_RING_OP :
/*RM21*/
if (cmd == RM_RING_NON_OP) {
smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
smc->r.loop_avail = FALSE ;
RS_SET(smc,RS_RINGOPCHANGE) ;
GO_STATE(RM1_NON_OP) ;
break ;
}
/*RM22a*/
else if (cmd == RM_ENABLE_FLAG) {
if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
else
smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
}
/*RM25*/
else if (smc->r.dup_addr_test == DA_FAILED) {
smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
smc->r.loop_avail = FALSE ;
smc->r.da_flag = TRUE ;
GO_STATE(RM5_RING_OP_DUP) ;
break ;
}
break ;
case ACTIONS(RM3_DETECT) :
start_rmt_timer0(smc,smc->s.mac_d_max*2,RM_TIMEOUT_D_MAX) ;
start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
sm_mac_check_beacon_claim(smc) ;
DB_RMTN(1,"RMT : RM3_DETECT\n",0,0) ;
ACTIONS_DONE() ;
break ;
case RM3_DETECT :
if (cmd == RM_TIMEOUT_POLL) {
start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
sm_mac_check_beacon_claim(smc) ;
break ;
}
if (cmd == RM_TIMEOUT_D_MAX) {
smc->r.timer0_exp = TRUE ;
}
/*
*jd(22-Feb-1999)
* We need a time ">= 2*mac_d_max" since we had finished
* Claim or Beacon state. So we will restart timer0 at
* every state change.
*/
if (cmd == RM_TX_STATE_CHANGE) {
start_rmt_timer0(smc,
smc->s.mac_d_max*2,
RM_TIMEOUT_D_MAX) ;
}
/*RM32*/
if (cmd == RM_RING_OP) {
GO_STATE(RM2_RING_OP) ;
break ;
}
/*RM33a*/
else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON)
&& smc->r.bn_flag) {
smc->r.bn_flag = FALSE ;
}
/*RM33b*/
else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
int tx ;
/*
* set bn_flag only if in state T4 or T5:
* only if we're the beaconer should we start the
* trace !
*/
if ((tx = sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
DB_RMTN(2,"RMT : DETECT && TRT_EXPIRED && T4/T5\n",0,0);
smc->r.bn_flag = TRUE ;
/*
* If one of the upstream stations beaconed
* and the link to the upstream neighbor is
* lost we need to restart the stuck timer to
* check the "stuck beacon" condition.
*/
start_rmt_timer1(smc,smc->s.rmt_t_stuck,
RM_TIMEOUT_T_STUCK) ;
}
/*
* We do NOT need to clear smc->r.bn_flag in case of
* not being in state T4 or T5, because the flag
* must be cleared in order to get in this condition.
*/
DB_RMTN(2,
"RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)\n",
tx,smc->r.bn_flag) ;
}
/*RM34a*/
else if (cmd == RM_MY_CLAIM && smc->r.timer0_exp) {
rmt_new_dup_actions(smc) ;
GO_STATE(RM4_NON_OP_DUP) ;
break ;
}
/*RM34b*/
else if (cmd == RM_MY_BEACON && smc->r.timer0_exp) {
rmt_new_dup_actions(smc) ;
GO_STATE(RM4_NON_OP_DUP) ;
break ;
}
/*RM34c*/
else if (cmd == RM_VALID_CLAIM) {
rmt_new_dup_actions(smc) ;
GO_STATE(RM4_NON_OP_DUP) ;
break ;
}
/*RM36*/
else if (cmd == RM_TIMEOUT_T_STUCK &&
smc->r.rm_join && smc->r.bn_flag) {
GO_STATE(RM6_DIRECTED) ;
break ;
}
break ;
case ACTIONS(RM4_NON_OP_DUP) :
start_rmt_timer0(smc,smc->s.rmt_t_announce,RM_TIMEOUT_ANNOUNCE);
start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
sm_mac_check_beacon_claim(smc) ;
DB_RMTN(1,"RMT : RM4_NON_OP_DUP\n",0,0) ;
ACTIONS_DONE() ;
break ;
case RM4_NON_OP_DUP :
if (cmd == RM_TIMEOUT_POLL) {
start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
sm_mac_check_beacon_claim(smc) ;
break ;
}
/*RM41*/
if (!smc->r.da_flag) {
GO_STATE(RM1_NON_OP) ;
break ;
}
/*RM44a*/
else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
smc->r.bn_flag) {
smc->r.bn_flag = FALSE ;
}
/*RM44b*/
else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
int tx ;
/*
* set bn_flag only if in state T4 or T5:
* only if we're the beaconer should we start the
* trace !
*/
if ((tx = sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
DB_RMTN(2,"RMT : NOPDUP && TRT_EXPIRED && T4/T5\n",0,0);
smc->r.bn_flag = TRUE ;
/*
* If one of the upstream stations beaconed
* and the link to the upstream neighbor is
* lost we need to restart the stuck timer to
* check the "stuck beacon" condition.
*/
start_rmt_timer1(smc,smc->s.rmt_t_stuck,
RM_TIMEOUT_T_STUCK) ;
}
/*
* We do NOT need to clear smc->r.bn_flag in case of
* not being in state T4 or T5, because the flag
* must be cleared in order to get in this condition.
*/
DB_RMTN(2,
"RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)\n",
tx,smc->r.bn_flag) ;
}
/*RM44c*/
else if (cmd == RM_TIMEOUT_ANNOUNCE && !smc->r.bn_flag) {
rmt_dup_actions(smc) ;
}
/*RM45*/
else if (cmd == RM_RING_OP) {
smc->r.no_flag = FALSE ;
GO_STATE(RM5_RING_OP_DUP) ;
break ;
}
/*RM46*/
else if (cmd == RM_TIMEOUT_T_STUCK &&
smc->r.rm_join && smc->r.bn_flag) {
GO_STATE(RM6_DIRECTED) ;
break ;
}
break ;
case ACTIONS(RM5_RING_OP_DUP) :
stop_rmt_timer0(smc) ;
stop_rmt_timer1(smc) ;
stop_rmt_timer2(smc) ;
DB_RMTN(1,"RMT : RM5_RING_OP_DUP\n",0,0) ;
ACTIONS_DONE() ;
break;
case RM5_RING_OP_DUP :
/*RM52*/
if (smc->r.dup_addr_test == DA_PASSED) {
smc->r.da_flag = FALSE ;
GO_STATE(RM2_RING_OP) ;
break ;
}
/*RM54*/
else if (cmd == RM_RING_NON_OP) {
smc->r.jm_flag = FALSE ;
smc->r.bn_flag = FALSE ;
GO_STATE(RM4_NON_OP_DUP) ;
break ;
}
break ;
case ACTIONS(RM6_DIRECTED) :
start_rmt_timer0(smc,smc->s.rmt_t_direct,RM_TIMEOUT_T_DIRECT) ;
stop_rmt_timer1(smc) ;
start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
sm_ma_control(smc,MA_DIRECTED) ;
RS_SET(smc,RS_BEACON) ;
DB_RMTN(1,"RMT : RM6_DIRECTED\n",0,0) ;
ACTIONS_DONE() ;
break ;
case RM6_DIRECTED :
/*RM63*/
if (cmd == RM_TIMEOUT_POLL) {
start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
sm_mac_check_beacon_claim(smc) ;
#ifndef SUPERNET_3
/* Because of problems with the Supernet II chip set
* sending of Directed Beacon will stop after 165ms
* therefore restart_trt_for_dbcn(smc) will be called
* to prevent this.
*/
restart_trt_for_dbcn(smc) ;
#endif /*SUPERNET_3*/
break ;
}
if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
!smc->r.da_flag) {
smc->r.bn_flag = FALSE ;
GO_STATE(RM3_DETECT) ;
break ;
}
/*RM64*/
else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
smc->r.da_flag) {
smc->r.bn_flag = FALSE ;
GO_STATE(RM4_NON_OP_DUP) ;
break ;
}
/*RM67*/
else if (cmd == RM_TIMEOUT_T_DIRECT) {
GO_STATE(RM7_TRACE) ;
break ;
}
break ;
case ACTIONS(RM7_TRACE) :
stop_rmt_timer0(smc) ;
stop_rmt_timer1(smc) ;
stop_rmt_timer2(smc) ;
smc->e.trace_prop |= ENTITY_BIT(ENTITY_MAC) ;
queue_event(smc,EVENT_ECM,EC_TRACE_PROP) ;
DB_RMTN(1,"RMT : RM7_TRACE\n",0,0) ;
ACTIONS_DONE() ;
break ;
case RM7_TRACE :
break ;
default:
SMT_PANIC(smc,SMT_E0122, SMT_E0122_MSG) ;
break;
}
}
/*
* (jd) RMT duplicate address actions
* leave the ring or reinsert just as configured
*/
static void rmt_dup_actions(struct s_smc *smc)
{
if (smc->r.jm_flag) {
}
else {
if (smc->s.rmt_dup_mac_behavior) {
SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
rmt_reinsert_actions(smc) ;
}
else {
SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
rmt_leave_actions(smc) ;
}
}
}
/*
* Reconnect to the Ring
*/
static void rmt_reinsert_actions(struct s_smc *smc)
{
queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
queue_event(smc,EVENT_ECM,EC_CONNECT) ;
}
/*
* duplicate address detected
*/
static void rmt_new_dup_actions(struct s_smc *smc)
{
smc->r.da_flag = TRUE ;
smc->r.bn_flag = FALSE ;
smc->r.jm_flag = FALSE ;
/*
* we have three options : change address, jam or leave
* we leave the ring as default
* Optionally it's possible to reinsert after leaving the Ring
* but this will not conform with SMT Spec.
*/
if (smc->s.rmt_dup_mac_behavior) {
SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
rmt_reinsert_actions(smc) ;
}
else {
SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
rmt_leave_actions(smc) ;
}
}
/*
* leave the ring
*/
static void rmt_leave_actions(struct s_smc *smc)
{
queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
/*
* Note: Do NOT try again later. (with please reconnect)
* The station must be left from the ring!
*/
}
/*
* SMT timer interface
* start RMT timer 0
*/
static void start_rmt_timer0(struct s_smc *smc, u_long value, int event)
{
smc->r.timer0_exp = FALSE ; /* clear timer event flag */
smt_timer_start(smc,&smc->r.rmt_timer0,value,EV_TOKEN(EVENT_RMT,event));
}
/*
* SMT timer interface
* start RMT timer 1
*/
static void start_rmt_timer1(struct s_smc *smc, u_long value, int event)
{
smc->r.timer1_exp = FALSE ; /* clear timer event flag */
smt_timer_start(smc,&smc->r.rmt_timer1,value,EV_TOKEN(EVENT_RMT,event));
}
/*
* SMT timer interface
* start RMT timer 2
*/
static void start_rmt_timer2(struct s_smc *smc, u_long value, int event)
{
smc->r.timer2_exp = FALSE ; /* clear timer event flag */
smt_timer_start(smc,&smc->r.rmt_timer2,value,EV_TOKEN(EVENT_RMT,event));
}
/*
* SMT timer interface
* stop RMT timer 0
*/
static void stop_rmt_timer0(struct s_smc *smc)
{
if (smc->r.rmt_timer0.tm_active)
smt_timer_stop(smc,&smc->r.rmt_timer0) ;
}
/*
* SMT timer interface
* stop RMT timer 1
*/
static void stop_rmt_timer1(struct s_smc *smc)
{
if (smc->r.rmt_timer1.tm_active)
smt_timer_stop(smc,&smc->r.rmt_timer1) ;
}
/*
* SMT timer interface
* stop RMT timer 2
*/
static void stop_rmt_timer2(struct s_smc *smc)
{
if (smc->r.rmt_timer2.tm_active)
smt_timer_stop(smc,&smc->r.rmt_timer2) ;
}

File diff suppressed because it is too large Load diff

2046
drivers/net/fddi/skfp/smt.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,355 @@
/******************************************************************************
*
* (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/CMT defaults
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#ifndef OEM_USER_DATA
#define OEM_USER_DATA "SK-NET FDDI V2.0 Userdata"
#endif
#ifndef lint
static const char ID_sccs[] = "@(#)smtdef.c 2.53 99/08/11 (C) SK " ;
#endif
/*
* defaults
*/
#define TTMS(x) ((u_long)(x)*1000L)
#define TTS(x) ((u_long)(x)*1000000L)
#define TTUS(x) ((u_long)(x))
#define DEFAULT_TB_MIN TTMS(5)
#define DEFAULT_TB_MAX TTMS(50)
#define DEFAULT_C_MIN TTUS(1600)
#define DEFAULT_T_OUT TTMS(100+5)
#define DEFAULT_TL_MIN TTUS(30)
#define DEFAULT_LC_SHORT TTMS(50+5)
#define DEFAULT_LC_MEDIUM TTMS(500+20)
#define DEFAULT_LC_LONG TTS(5)+TTMS(50)
#define DEFAULT_LC_EXTENDED TTS(50)+TTMS(50)
#define DEFAULT_T_NEXT_9 TTMS(200+10)
#define DEFAULT_NS_MAX TTUS(1310)
#define DEFAULT_I_MAX TTMS(25)
#define DEFAULT_IN_MAX TTMS(40)
#define DEFAULT_TD_MIN TTMS(5)
#define DEFAULT_T_NON_OP TTS(1)
#define DEFAULT_T_STUCK TTS(8)
#define DEFAULT_T_DIRECT TTMS(370)
#define DEFAULT_T_JAM TTMS(370)
#define DEFAULT_T_ANNOUNCE TTMS(2500)
#define DEFAULT_D_MAX TTUS(1617)
#define DEFAULT_LEM_ALARM (8)
#define DEFAULT_LEM_CUTOFF (7)
#define DEFAULT_TEST_DONE TTS(1)
#define DEFAULT_CHECK_POLL TTS(1)
#define DEFAULT_POLL TTMS(50)
/*
* LCT errors threshold
*/
#define DEFAULT_LCT_SHORT 1
#define DEFAULT_LCT_MEDIUM 3
#define DEFAULT_LCT_LONG 5
#define DEFAULT_LCT_EXTEND 50
/* Forward declarations */
void smt_reset_defaults(struct s_smc *smc, int level);
static void smt_init_mib(struct s_smc *smc, int level);
static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper);
#define MS2BCLK(x) ((x)*12500L)
#define US2BCLK(x) ((x)*1250L)
void smt_reset_defaults(struct s_smc *smc, int level)
{
struct smt_config *smt ;
int i ;
u_long smt_boot_time;
smt_init_mib(smc,level) ;
smc->os.smc_version = SMC_VERSION ;
smt_boot_time = smt_get_time();
for( i = 0; i < NUMMACS; i++ )
smc->sm.last_tok_time[i] = smt_boot_time ;
smt = &smc->s ;
smt->attach_s = 0 ;
smt->build_ring_map = 1 ;
smt->sas = SMT_DAS ;
smt->numphys = NUMPHYS ;
smt->pcm_tb_min = DEFAULT_TB_MIN ;
smt->pcm_tb_max = DEFAULT_TB_MAX ;
smt->pcm_c_min = DEFAULT_C_MIN ;
smt->pcm_t_out = DEFAULT_T_OUT ;
smt->pcm_tl_min = DEFAULT_TL_MIN ;
smt->pcm_lc_short = DEFAULT_LC_SHORT ;
smt->pcm_lc_medium = DEFAULT_LC_MEDIUM ;
smt->pcm_lc_long = DEFAULT_LC_LONG ;
smt->pcm_lc_extended = DEFAULT_LC_EXTENDED ;
smt->pcm_t_next_9 = DEFAULT_T_NEXT_9 ;
smt->pcm_ns_max = DEFAULT_NS_MAX ;
smt->ecm_i_max = DEFAULT_I_MAX ;
smt->ecm_in_max = DEFAULT_IN_MAX ;
smt->ecm_td_min = DEFAULT_TD_MIN ;
smt->ecm_test_done = DEFAULT_TEST_DONE ;
smt->ecm_check_poll = DEFAULT_CHECK_POLL ;
smt->rmt_t_non_op = DEFAULT_T_NON_OP ;
smt->rmt_t_stuck = DEFAULT_T_STUCK ;
smt->rmt_t_direct = DEFAULT_T_DIRECT ;
smt->rmt_t_jam = DEFAULT_T_JAM ;
smt->rmt_t_announce = DEFAULT_T_ANNOUNCE ;
smt->rmt_t_poll = DEFAULT_POLL ;
smt->rmt_dup_mac_behavior = FALSE ; /* See Struct smt_config */
smt->mac_d_max = DEFAULT_D_MAX ;
smt->lct_short = DEFAULT_LCT_SHORT ;
smt->lct_medium = DEFAULT_LCT_MEDIUM ;
smt->lct_long = DEFAULT_LCT_LONG ;
smt->lct_extended = DEFAULT_LCT_EXTEND ;
#ifndef SLIM_SMT
#ifdef ESS
if (level == 0) {
smc->ess.sync_bw_available = FALSE ;
smc->mib.fddiESSPayload = 0 ;
smc->mib.fddiESSOverhead = 0 ;
smc->mib.fddiESSMaxTNeg = (u_long)(- MS2BCLK(25)) ;
smc->mib.fddiESSMinSegmentSize = 1 ;
smc->mib.fddiESSCategory = SB_STATIC ;
smc->mib.fddiESSSynchTxMode = FALSE ;
smc->ess.raf_act_timer_poll = FALSE ;
smc->ess.timer_count = 7 ; /* first RAF alc req after 3s */
}
smc->ess.local_sba_active = FALSE ;
smc->ess.sba_reply_pend = NULL ;
#endif
#ifdef SBA
smt_init_sba(smc,level) ;
#endif
#endif /* no SLIM_SMT */
#ifdef TAG_MODE
if (level == 0) {
smc->hw.pci_fix_value = 0 ;
}
#endif
}
/*
* manufacturer data
*/
static const char man_data[32] =
/* 01234567890123456789012345678901 */
"xxxSK-NET FDDI SMT 7.3 - V2.8.8" ;
static void smt_init_mib(struct s_smc *smc, int level)
{
struct fddi_mib *mib ;
struct fddi_mib_p *pm ;
int port ;
int path ;
mib = &smc->mib ;
if (level == 0) {
/*
* set EVERYTHING to ZERO
* EXCEPT hw and os
*/
memset(((char *)smc)+
sizeof(struct s_smt_os)+sizeof(struct s_smt_hw), 0,
sizeof(struct s_smc) -
sizeof(struct s_smt_os) - sizeof(struct s_smt_hw)) ;
}
else {
mib->fddiSMTRemoteDisconnectFlag = 0 ;
mib->fddiSMTPeerWrapFlag = 0 ;
}
mib->fddiSMTOpVersionId = 2 ;
mib->fddiSMTHiVersionId = 2 ;
mib->fddiSMTLoVersionId = 2 ;
memcpy((char *) mib->fddiSMTManufacturerData,man_data,32) ;
if (level == 0) {
strcpy(mib->fddiSMTUserData,OEM_USER_DATA) ;
}
mib->fddiSMTMIBVersionId = 1 ;
mib->fddiSMTMac_Ct = NUMMACS ;
mib->fddiSMTConnectionPolicy = POLICY_MM | POLICY_AA | POLICY_BB ;
/*
* fddiSMTNonMaster_Ct and fddiSMTMaster_Ct are set in smt_fixup_mib
* s.sas is not set yet (is set in init driver)
*/
mib->fddiSMTAvailablePaths = MIB_PATH_P | MIB_PATH_S ;
mib->fddiSMTConfigCapabilities = 0 ; /* no hold,no wrap_ab*/
mib->fddiSMTTT_Notify = 10 ;
mib->fddiSMTStatRptPolicy = TRUE ;
mib->fddiSMTTrace_MaxExpiration = SEC2MIB(7) ;
mib->fddiSMTMACIndexes = INDEX_MAC ;
mib->fddiSMTStationStatus = MIB_SMT_STASTA_SEPA ; /* separated */
mib->m[MAC0].fddiMACIndex = INDEX_MAC ;
mib->m[MAC0].fddiMACFrameStatusFunctions = FSC_TYPE0 ;
mib->m[MAC0].fddiMACRequestedPaths =
MIB_P_PATH_LOCAL |
MIB_P_PATH_SEC_ALTER |
MIB_P_PATH_PRIM_ALTER ;
mib->m[MAC0].fddiMACAvailablePaths = MIB_PATH_P ;
mib->m[MAC0].fddiMACCurrentPath = MIB_PATH_PRIMARY ;
mib->m[MAC0].fddiMACT_MaxCapabilitiy = (u_long)(- MS2BCLK(165)) ;
mib->m[MAC0].fddiMACTVXCapabilitiy = (u_long)(- US2BCLK(52)) ;
if (level == 0) {
mib->m[MAC0].fddiMACTvxValue = (u_long)(- US2BCLK(27)) ;
mib->m[MAC0].fddiMACTvxValueMIB = (u_long)(- US2BCLK(27)) ;
mib->m[MAC0].fddiMACT_Req = (u_long)(- MS2BCLK(165)) ;
mib->m[MAC0].fddiMACT_ReqMIB = (u_long)(- MS2BCLK(165)) ;
mib->m[MAC0].fddiMACT_Max = (u_long)(- MS2BCLK(165)) ;
mib->m[MAC0].fddiMACT_MaxMIB = (u_long)(- MS2BCLK(165)) ;
mib->m[MAC0].fddiMACT_Min = (u_long)(- MS2BCLK(4)) ;
}
mib->m[MAC0].fddiMACHardwarePresent = TRUE ;
mib->m[MAC0].fddiMACMA_UnitdataEnable = TRUE ;
mib->m[MAC0].fddiMACFrameErrorThreshold = 1 ;
mib->m[MAC0].fddiMACNotCopiedThreshold = 1 ;
/*
* Path attributes
*/
for (path = 0 ; path < NUMPATHS ; path++) {
mib->a[path].fddiPATHIndex = INDEX_PATH + path ;
if (level == 0) {
mib->a[path].fddiPATHTVXLowerBound =
(u_long)(- US2BCLK(27)) ;
mib->a[path].fddiPATHT_MaxLowerBound =
(u_long)(- MS2BCLK(165)) ;
mib->a[path].fddiPATHMaxT_Req =
(u_long)(- MS2BCLK(165)) ;
}
}
/*
* Port attributes
*/
pm = mib->p ;
for (port = 0 ; port < NUMPHYS ; port++) {
/*
* set MIB pointer in phy
*/
/* Attention: don't initialize mib pointer here! */
/* It must be initialized during phase 2 */
smc->y[port].mib = NULL;
mib->fddiSMTPORTIndexes[port] = port+INDEX_PORT ;
pm->fddiPORTIndex = port+INDEX_PORT ;
pm->fddiPORTHardwarePresent = TRUE ;
if (level == 0) {
pm->fddiPORTLer_Alarm = DEFAULT_LEM_ALARM ;
pm->fddiPORTLer_Cutoff = DEFAULT_LEM_CUTOFF ;
}
/*
* fddiPORTRequestedPaths are set in pcmplc.c
* we don't know the port type yet !
*/
pm->fddiPORTRequestedPaths[1] = 0 ;
pm->fddiPORTRequestedPaths[2] = 0 ;
pm->fddiPORTRequestedPaths[3] = 0 ;
pm->fddiPORTAvailablePaths = MIB_PATH_P ;
pm->fddiPORTPMDClass = MIB_PMDCLASS_MULTI ;
pm++ ;
}
(void) smt_set_mac_opvalues(smc) ;
}
int smt_set_mac_opvalues(struct s_smc *smc)
{
int st ;
int st2 ;
st = set_min_max(1,smc->mib.m[MAC0].fddiMACTvxValueMIB,
smc->mib.a[PATH0].fddiPATHTVXLowerBound,
&smc->mib.m[MAC0].fddiMACTvxValue) ;
st |= set_min_max(0,smc->mib.m[MAC0].fddiMACT_MaxMIB,
smc->mib.a[PATH0].fddiPATHT_MaxLowerBound,
&smc->mib.m[MAC0].fddiMACT_Max) ;
st |= (st2 = set_min_max(0,smc->mib.m[MAC0].fddiMACT_ReqMIB,
smc->mib.a[PATH0].fddiPATHMaxT_Req,
&smc->mib.m[MAC0].fddiMACT_Req)) ;
if (st2) {
/* Treq attribute changed remotely. So send an AIX_EVENT to the
* user
*/
AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_T_REQ,
smt_get_event_word(smc));
}
return st;
}
void smt_fixup_mib(struct s_smc *smc)
{
#ifdef CONCENTRATOR
switch (smc->s.sas) {
case SMT_SAS :
smc->mib.fddiSMTNonMaster_Ct = 1 ;
break ;
case SMT_DAS :
smc->mib.fddiSMTNonMaster_Ct = 2 ;
break ;
case SMT_NAC :
smc->mib.fddiSMTNonMaster_Ct = 0 ;
break ;
}
smc->mib.fddiSMTMaster_Ct = NUMPHYS - smc->mib.fddiSMTNonMaster_Ct ;
#else
switch (smc->s.sas) {
case SMT_SAS :
smc->mib.fddiSMTNonMaster_Ct = 1 ;
break ;
case SMT_DAS :
smc->mib.fddiSMTNonMaster_Ct = 2 ;
break ;
}
smc->mib.fddiSMTMaster_Ct = 0 ;
#endif
}
/*
* determine new setting for operational value
* if limit is lower than mib
* use limit
* else
* use mib
* NOTE : numbers are negative, negate comparison !
*/
static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper)
{
u_long old ;
old = *oper ;
if ((limit > mib) ^ maxflag)
*oper = limit ;
else
*oper = mib ;
return old != *oper;
}

View file

@ -0,0 +1,125 @@
/******************************************************************************
*
* (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.
*
******************************************************************************/
/*
Init SMT
call all module level initialization routines
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#ifndef lint
static const char ID_sccs[] = "@(#)smtinit.c 1.15 97/05/06 (C) SK " ;
#endif
void init_fddi_driver(struct s_smc *smc, u_char *mac_addr);
/* define global debug variable */
#if defined(DEBUG) && !defined(DEBUG_BRD)
struct smt_debug debug;
#endif
#ifndef MULT_OEM
#define OEMID(smc,i) oem_id[i]
extern u_char oem_id[] ;
#else /* MULT_OEM */
#define OEMID(smc,i) smc->hw.oem_id->oi_mark[i]
extern struct s_oem_ids oem_ids[] ;
#endif /* MULT_OEM */
/*
* Set OEM specific values
*
* Can not be called in smt_reset_defaults, because it is not sure that
* the OEM ID is already defined.
*/
static void set_oem_spec_val(struct s_smc *smc)
{
struct fddi_mib *mib ;
mib = &smc->mib ;
/*
* set IBM specific values
*/
if (OEMID(smc,0) == 'I') {
mib->fddiSMTConnectionPolicy = POLICY_MM ;
}
}
/*
* Init SMT
*/
int init_smt(struct s_smc *smc, u_char *mac_addr)
/* u_char *mac_addr; canonical address or NULL */
{
int p ;
#if defined(DEBUG) && !defined(DEBUG_BRD)
debug.d_smt = 0 ;
debug.d_smtf = 0 ;
debug.d_rmt = 0 ;
debug.d_ecm = 0 ;
debug.d_pcm = 0 ;
debug.d_cfm = 0 ;
debug.d_plc = 0 ;
#ifdef ESS
debug.d_ess = 0 ;
#endif
#ifdef SBA
debug.d_sba = 0 ;
#endif
#endif /* DEBUG && !DEBUG_BRD */
/* First initialize the ports mib->pointers */
for ( p = 0; p < NUMPHYS; p ++ ) {
smc->y[p].mib = & smc->mib.p[p] ;
}
set_oem_spec_val(smc) ;
(void) smt_set_mac_opvalues(smc) ;
init_fddi_driver(smc,mac_addr) ; /* HW driver */
smt_fixup_mib(smc) ; /* update values that depend on s.sas */
ev_init(smc) ; /* event queue */
#ifndef SLIM_SMT
smt_init_evc(smc) ; /* evcs in MIB */
#endif /* no SLIM_SMT */
smt_timer_init(smc) ; /* timer package */
smt_agent_init(smc) ; /* SMT frame manager */
pcm_init(smc) ; /* PCM state machine */
ecm_init(smc) ; /* ECM state machine */
cfm_init(smc) ; /* CFM state machine */
rmt_init(smc) ; /* RMT state machine */
for (p = 0 ; p < NUMPHYS ; p++) {
pcm(smc,p,0) ; /* PCM A state machine */
}
ecm(smc,0) ; /* ECM state machine */
cfm(smc,0) ; /* CFM state machine */
rmt(smc,0) ; /* RMT state machine */
smt_agent_task(smc) ; /* NIF FSM etc */
PNMI_INIT(smc) ; /* PNMI initialization */
return 0;
}

View file

@ -0,0 +1,156 @@
/******************************************************************************
*
* (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 timer
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#ifndef lint
static const char ID_sccs[] = "@(#)smttimer.c 2.4 97/08/04 (C) SK " ;
#endif
static void timer_done(struct s_smc *smc, int restart);
void smt_timer_init(struct s_smc *smc)
{
smc->t.st_queue = NULL;
smc->t.st_fast.tm_active = FALSE ;
smc->t.st_fast.tm_next = NULL;
hwt_init(smc) ;
}
void smt_timer_stop(struct s_smc *smc, struct smt_timer *timer)
{
struct smt_timer **prev ;
struct smt_timer *tm ;
/*
* remove timer from queue
*/
timer->tm_active = FALSE ;
if (smc->t.st_queue == timer && !timer->tm_next) {
hwt_stop(smc) ;
}
for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
if (tm == timer) {
*prev = tm->tm_next ;
if (tm->tm_next) {
tm->tm_next->tm_delta += tm->tm_delta ;
}
return ;
}
}
}
void smt_timer_start(struct s_smc *smc, struct smt_timer *timer, u_long time,
u_long token)
{
struct smt_timer **prev ;
struct smt_timer *tm ;
u_long delta = 0 ;
time /= 16 ; /* input is uS, clock ticks are 16uS */
if (!time)
time = 1 ;
smt_timer_stop(smc,timer) ;
timer->tm_smc = smc ;
timer->tm_token = token ;
timer->tm_active = TRUE ;
if (!smc->t.st_queue) {
smc->t.st_queue = timer ;
timer->tm_next = NULL;
timer->tm_delta = time ;
hwt_start(smc,time) ;
return ;
}
/*
* timer correction
*/
timer_done(smc,0) ;
/*
* find position in queue
*/
delta = 0 ;
for (prev = &smc->t.st_queue ; (tm = *prev) ; prev = &tm->tm_next ) {
if (delta + tm->tm_delta > time) {
break ;
}
delta += tm->tm_delta ;
}
/* insert in queue */
*prev = timer ;
timer->tm_next = tm ;
timer->tm_delta = time - delta ;
if (tm)
tm->tm_delta -= timer->tm_delta ;
/*
* start new with first
*/
hwt_start(smc,smc->t.st_queue->tm_delta) ;
}
void smt_force_irq(struct s_smc *smc)
{
smt_timer_start(smc,&smc->t.st_fast,32L, EV_TOKEN(EVENT_SMT,SM_FAST));
}
void smt_timer_done(struct s_smc *smc)
{
timer_done(smc,1) ;
}
static void timer_done(struct s_smc *smc, int restart)
{
u_long delta ;
struct smt_timer *tm ;
struct smt_timer *next ;
struct smt_timer **last ;
int done = 0 ;
delta = hwt_read(smc) ;
last = &smc->t.st_queue ;
tm = smc->t.st_queue ;
while (tm && !done) {
if (delta >= tm->tm_delta) {
tm->tm_active = FALSE ;
delta -= tm->tm_delta ;
last = &tm->tm_next ;
tm = tm->tm_next ;
}
else {
tm->tm_delta -= delta ;
delta = 0 ;
done = 1 ;
}
}
*last = NULL;
next = smc->t.st_queue ;
smc->t.st_queue = tm ;
for ( tm = next ; tm ; tm = next) {
next = tm->tm_next ;
timer_event(smc,tm->tm_token) ;
}
if (restart && smc->t.st_queue)
hwt_start(smc,smc->t.st_queue->tm_delta) ;
}

429
drivers/net/fddi/skfp/srf.c Normal file
View file

@ -0,0 +1,429 @@
/******************************************************************************
*
* (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 7.2 Status Response Frame Implementation
SRF state machine and frame generation
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#include "h/smt_p.h"
#define KERNEL
#include "h/smtstate.h"
#ifndef SLIM_SMT
#ifndef BOOT
#ifndef lint
static const char ID_sccs[] = "@(#)srf.c 1.18 97/08/04 (C) SK " ;
#endif
/*
* function declarations
*/
static void clear_all_rep(struct s_smc *smc);
static void clear_reported(struct s_smc *smc);
static void smt_send_srf(struct s_smc *smc);
static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index);
#define MAX_EVCS ARRAY_SIZE(smc->evcs)
struct evc_init {
u_char code ;
u_char index ;
u_char n ;
u_short para ;
} ;
static const struct evc_init evc_inits[] = {
{ SMT_COND_SMT_PEER_WRAP, 0,1,SMT_P1048 } ,
{ SMT_COND_MAC_DUP_ADDR, INDEX_MAC, NUMMACS,SMT_P208C } ,
{ SMT_COND_MAC_FRAME_ERROR, INDEX_MAC, NUMMACS,SMT_P208D } ,
{ SMT_COND_MAC_NOT_COPIED, INDEX_MAC, NUMMACS,SMT_P208E } ,
{ SMT_EVENT_MAC_NEIGHBOR_CHANGE, INDEX_MAC, NUMMACS,SMT_P208F } ,
{ SMT_EVENT_MAC_PATH_CHANGE, INDEX_MAC, NUMMACS,SMT_P2090 } ,
{ SMT_COND_PORT_LER, INDEX_PORT,NUMPHYS,SMT_P4050 } ,
{ SMT_COND_PORT_EB_ERROR, INDEX_PORT,NUMPHYS,SMT_P4052 } ,
{ SMT_EVENT_PORT_CONNECTION, INDEX_PORT,NUMPHYS,SMT_P4051 } ,
{ SMT_EVENT_PORT_PATH_CHANGE, INDEX_PORT,NUMPHYS,SMT_P4053 } ,
} ;
#define MAX_INIT_EVC ARRAY_SIZE(evc_inits)
void smt_init_evc(struct s_smc *smc)
{
struct s_srf_evc *evc ;
const struct evc_init *init ;
unsigned int i ;
int index ;
int offset ;
static u_char fail_safe = FALSE ;
memset((char *)smc->evcs,0,sizeof(smc->evcs)) ;
evc = smc->evcs ;
init = evc_inits ;
for (i = 0 ; i < MAX_INIT_EVC ; i++) {
for (index = 0 ; index < init->n ; index++) {
evc->evc_code = init->code ;
evc->evc_para = init->para ;
evc->evc_index = init->index + index ;
#ifndef DEBUG
evc->evc_multiple = &fail_safe ;
evc->evc_cond_state = &fail_safe ;
#endif
evc++ ;
}
init++ ;
}
if ((unsigned int) (evc - smc->evcs) > MAX_EVCS) {
SMT_PANIC(smc,SMT_E0127, SMT_E0127_MSG) ;
}
/*
* conditions
*/
smc->evcs[0].evc_cond_state = &smc->mib.fddiSMTPeerWrapFlag ;
smc->evcs[1].evc_cond_state =
&smc->mib.m[MAC0].fddiMACDuplicateAddressCond ;
smc->evcs[2].evc_cond_state =
&smc->mib.m[MAC0].fddiMACFrameErrorFlag ;
smc->evcs[3].evc_cond_state =
&smc->mib.m[MAC0].fddiMACNotCopiedFlag ;
/*
* events
*/
smc->evcs[4].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_N ;
smc->evcs[5].evc_multiple = &smc->mib.m[MAC0].fddiMACMultiple_P ;
offset = 6 ;
for (i = 0 ; i < NUMPHYS ; i++) {
/*
* conditions
*/
smc->evcs[offset + 0*NUMPHYS].evc_cond_state =
&smc->mib.p[i].fddiPORTLerFlag ;
smc->evcs[offset + 1*NUMPHYS].evc_cond_state =
&smc->mib.p[i].fddiPORTEB_Condition ;
/*
* events
*/
smc->evcs[offset + 2*NUMPHYS].evc_multiple =
&smc->mib.p[i].fddiPORTMultiple_U ;
smc->evcs[offset + 3*NUMPHYS].evc_multiple =
&smc->mib.p[i].fddiPORTMultiple_P ;
offset++ ;
}
#ifdef DEBUG
for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
if (SMT_IS_CONDITION(evc->evc_code)) {
if (!evc->evc_cond_state) {
SMT_PANIC(smc,SMT_E0128, SMT_E0128_MSG) ;
}
evc->evc_multiple = &fail_safe ;
}
else {
if (!evc->evc_multiple) {
SMT_PANIC(smc,SMT_E0129, SMT_E0129_MSG) ;
}
evc->evc_cond_state = &fail_safe ;
}
}
#endif
smc->srf.TSR = smt_get_time() ;
smc->srf.sr_state = SR0_WAIT ;
}
static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index)
{
unsigned int i ;
struct s_srf_evc *evc ;
for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
if (evc->evc_code == code && evc->evc_index == index)
return evc;
}
return NULL;
}
#define THRESHOLD_2 (2*TICKS_PER_SECOND)
#define THRESHOLD_32 (32*TICKS_PER_SECOND)
#ifdef DEBUG
static const char * const srf_names[] = {
"None","MACPathChangeEvent", "MACNeighborChangeEvent",
"PORTPathChangeEvent", "PORTUndesiredConnectionAttemptEvent",
"SMTPeerWrapCondition", "SMTHoldCondition",
"MACFrameErrorCondition", "MACDuplicateAddressCondition",
"MACNotCopiedCondition", "PORTEBErrorCondition",
"PORTLerCondition"
} ;
#endif
void smt_srf_event(struct s_smc *smc, int code, int index, int cond)
{
struct s_srf_evc *evc ;
int cond_asserted = 0 ;
int cond_deasserted = 0 ;
int event_occurred = 0 ;
int tsr ;
int T_Limit = 2*TICKS_PER_SECOND ;
if (code == SMT_COND_MAC_DUP_ADDR && cond) {
RS_SET(smc,RS_DUPADDR) ;
}
if (code) {
DB_SMT("SRF: %s index %d\n",srf_names[code],index) ;
if (!(evc = smt_get_evc(smc,code,index))) {
DB_SMT("SRF : smt_get_evc() failed\n",0,0) ;
return ;
}
/*
* ignore condition if no change
*/
if (SMT_IS_CONDITION(code)) {
if (*evc->evc_cond_state == cond)
return ;
}
/*
* set transition time stamp
*/
smt_set_timestamp(smc,smc->mib.fddiSMTTransitionTimeStamp) ;
if (SMT_IS_CONDITION(code)) {
DB_SMT("SRF: condition is %s\n",cond ? "ON":"OFF",0) ;
if (cond) {
*evc->evc_cond_state = TRUE ;
evc->evc_rep_required = TRUE ;
smc->srf.any_report = TRUE ;
cond_asserted = TRUE ;
}
else {
*evc->evc_cond_state = FALSE ;
cond_deasserted = TRUE ;
}
}
else {
if (evc->evc_rep_required) {
*evc->evc_multiple = TRUE ;
}
else {
evc->evc_rep_required = TRUE ;
*evc->evc_multiple = FALSE ;
}
smc->srf.any_report = TRUE ;
event_occurred = TRUE ;
}
#ifdef FDDI_MIB
snmp_srf_event(smc,evc) ;
#endif /* FDDI_MIB */
}
tsr = smt_get_time() - smc->srf.TSR ;
switch (smc->srf.sr_state) {
case SR0_WAIT :
/* SR01a */
if (cond_asserted && tsr < T_Limit) {
smc->srf.SRThreshold = THRESHOLD_2 ;
smc->srf.sr_state = SR1_HOLDOFF ;
break ;
}
/* SR01b */
if (cond_deasserted && tsr < T_Limit) {
smc->srf.sr_state = SR1_HOLDOFF ;
break ;
}
/* SR01c */
if (event_occurred && tsr < T_Limit) {
smc->srf.sr_state = SR1_HOLDOFF ;
break ;
}
/* SR00b */
if (cond_asserted && tsr >= T_Limit) {
smc->srf.SRThreshold = THRESHOLD_2 ;
smc->srf.TSR = smt_get_time() ;
smt_send_srf(smc) ;
break ;
}
/* SR00c */
if (cond_deasserted && tsr >= T_Limit) {
smc->srf.TSR = smt_get_time() ;
smt_send_srf(smc) ;
break ;
}
/* SR00d */
if (event_occurred && tsr >= T_Limit) {
smc->srf.TSR = smt_get_time() ;
smt_send_srf(smc) ;
break ;
}
/* SR00e */
if (smc->srf.any_report && (u_long) tsr >=
smc->srf.SRThreshold) {
smc->srf.SRThreshold *= 2 ;
if (smc->srf.SRThreshold > THRESHOLD_32)
smc->srf.SRThreshold = THRESHOLD_32 ;
smc->srf.TSR = smt_get_time() ;
smt_send_srf(smc) ;
break ;
}
/* SR02 */
if (!smc->mib.fddiSMTStatRptPolicy) {
smc->srf.sr_state = SR2_DISABLED ;
break ;
}
break ;
case SR1_HOLDOFF :
/* SR10b */
if (tsr >= T_Limit) {
smc->srf.sr_state = SR0_WAIT ;
smc->srf.TSR = smt_get_time() ;
smt_send_srf(smc) ;
break ;
}
/* SR11a */
if (cond_asserted) {
smc->srf.SRThreshold = THRESHOLD_2 ;
}
/* SR11b */
/* SR11c */
/* handled above */
/* SR12 */
if (!smc->mib.fddiSMTStatRptPolicy) {
smc->srf.sr_state = SR2_DISABLED ;
break ;
}
break ;
case SR2_DISABLED :
if (smc->mib.fddiSMTStatRptPolicy) {
smc->srf.sr_state = SR0_WAIT ;
smc->srf.TSR = smt_get_time() ;
smc->srf.SRThreshold = THRESHOLD_2 ;
clear_all_rep(smc) ;
break ;
}
break ;
}
}
static void clear_all_rep(struct s_smc *smc)
{
struct s_srf_evc *evc ;
unsigned int i ;
for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
evc->evc_rep_required = FALSE ;
if (SMT_IS_CONDITION(evc->evc_code))
*evc->evc_cond_state = FALSE ;
}
smc->srf.any_report = FALSE ;
}
static void clear_reported(struct s_smc *smc)
{
struct s_srf_evc *evc ;
unsigned int i ;
smc->srf.any_report = FALSE ;
for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
if (SMT_IS_CONDITION(evc->evc_code)) {
if (*evc->evc_cond_state == FALSE)
evc->evc_rep_required = FALSE ;
else
smc->srf.any_report = TRUE ;
}
else {
evc->evc_rep_required = FALSE ;
*evc->evc_multiple = FALSE ;
}
}
}
/*
* build and send SMT SRF frame
*/
static void smt_send_srf(struct s_smc *smc)
{
struct smt_header *smt ;
struct s_srf_evc *evc ;
SK_LOC_DECL(struct s_pcon,pcon) ;
SMbuf *mb ;
unsigned int i ;
static const struct fddi_addr SMT_SRF_DA = {
{ 0x80, 0x01, 0x43, 0x00, 0x80, 0x08 }
} ;
/*
* build SMT header
*/
if (!smc->r.sm_ma_avail)
return ;
if (!(mb = smt_build_frame(smc,SMT_SRF,SMT_ANNOUNCE,0)))
return ;
RS_SET(smc,RS_SOFTERROR) ;
smt = smtod(mb, struct smt_header *) ;
smt->smt_dest = SMT_SRF_DA ; /* DA == SRF multicast */
/*
* setup parameter status
*/
pcon.pc_len = SMT_MAX_INFO_LEN ; /* max para length */
pcon.pc_err = 0 ; /* no error */
pcon.pc_badset = 0 ; /* no bad set count */
pcon.pc_p = (void *) (smt + 1) ; /* paras start here */
smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ;
smt_add_para(smc,&pcon,(u_short) SMT_P1034,0,0) ;
for (i = 0, evc = smc->evcs ; i < MAX_EVCS ; i++, evc++) {
if (evc->evc_rep_required) {
smt_add_para(smc,&pcon,evc->evc_para,
(int)evc->evc_index,0) ;
}
}
smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ;
mb->sm_len = smt->smt_len + sizeof(struct smt_header) ;
DB_SMT("SRF: sending SRF at %x, len %d\n",smt,mb->sm_len) ;
DB_SMT("SRF: state SR%d Threshold %d\n",
smc->srf.sr_state,smc->srf.SRThreshold/TICKS_PER_SECOND) ;
#ifdef DEBUG
dump_smt(smc,smt,"SRF Send") ;
#endif
smt_send_frame(smc,mb,FC_SMT_INFO,0) ;
clear_reported(smc) ;
}
#endif /* no BOOT */
#endif /* no SLIM_SMT */