fddi: Move the FDDI drivers

Move the FDDI drivers into drivers/net/fddi/ and make the
necessary Kconfig and Makefile changes.

CC: "Maciej W. Rozycki" <macro@linux-mips.org>
CC: Christoph Goos <cgoos@syskonnect.de>
CC: <linux@syskonnect.de>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Jeff Kirsher
2011-07-31 00:06:29 -07:00
父節點 3cd0999d13
當前提交 33f810b203
共有 44 個文件被更改,包括 87 次插入73 次删除

查看文件

@@ -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
查看文件

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

查看文件

@@ -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
查看文件

@@ -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
查看文件

@@ -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 */

文件差異過大導致無法顯示 Load Diff

查看文件

@@ -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 "h/mbuf.h" /* Type definitions for MBUFs */
#include "h/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_ */

查看文件

@@ -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_ */

查看文件

@@ -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 */

查看文件

@@ -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

查看文件

@@ -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 "h/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

查看文件

@@ -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_ */

查看文件

@@ -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)))

查看文件

@@ -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 "h/mbuf.h"
#include "h/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

查看文件

@@ -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

文件差異過大導致無法顯示 Load Diff

查看文件

@@ -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 "h/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_ */

查看文件

@@ -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 "h/osdef1st.h"
#endif /* OSDEF */
#ifdef OEM_CONCEPT
#include "oemdef.h"
#endif /* OEM_CONCEPT */
#include "h/smt.h"
#include "h/cmtdef.h"
#include "h/fddimib.h"
#include "h/targethw.h" /* all target hw dependencies */
#include "h/targetos.h" /* all target os dependencies */
#ifdef ESS
#include "h/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;
extern void all_selection_criteria(struct s_smc *smc);
extern void card_stop(struct s_smc *smc);
extern void init_board(struct s_smc *smc, u_char *mac_addr);
extern int init_fplus(struct s_smc *smc);
extern void init_plc(struct s_smc *smc);
extern int init_smt(struct s_smc *smc, u_char * mac_addr);
extern void mac1_irq(struct s_smc *smc, u_short stu, u_short stl);
extern void mac2_irq(struct s_smc *smc, u_short code_s2u, u_short code_s2l);
extern void mac3_irq(struct s_smc *smc, u_short code_s3u, u_short code_s3l);
extern int pcm_status_twisted(struct s_smc *smc);
extern void plc1_irq(struct s_smc *smc);
extern void plc2_irq(struct s_smc *smc);
extern void read_address(struct s_smc *smc, u_char * mac_addr);
extern void timer_irq(struct s_smc *smc);
#endif /* _SCMECM_ */

查看文件

@@ -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_ */

查看文件

@@ -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

查看文件

@@ -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

文件差異過大導致無法顯示 Load Diff

查看文件

@@ -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 "h/skfbi.h"
#ifndef TAG_MODE
#include "h/fplus.h"
#else
#include "h/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

查看文件

@@ -0,0 +1,165 @@
/******************************************************************************
*
* (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>
#include <linux/init.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 "h/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_

查看文件

@@ -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_ */

文件差異過大導致無法顯示 Load Diff

269
drivers/net/fddi/skfp/hwt.c Normal 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

文件差異過大導致無法顯示 Load Diff

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

文件差異過大導致無法顯示 Load Diff

查看文件

@@ -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
查看文件

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

文件差異過大導致無法顯示 Load Diff

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

文件差異過大導致無法顯示 Load Diff

查看文件

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

查看文件

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

查看文件

@@ -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
查看文件

@@ -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 ;
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 ; (unsigned) 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) (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 ; (unsigned) 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)
{
int i ;
struct s_srf_evc *evc ;
for (i = 0, evc = smc->evcs ; (unsigned) 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 ;
int i ;
for (i = 0, evc = smc->evcs ; (unsigned) 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 ;
int i ;
smc->srf.any_report = FALSE ;
for (i = 0, evc = smc->evcs ; (unsigned) 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 ;
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 ; (unsigned) 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 */