?? spantask.c
字號(hào):
/* spanTask.c - Spanning Tree task code */
/* Copyright 2001 Wind River Systems, Inc. */
/* Copyright 1998-2000 Wind River Systems, Inc. */
/* Copyright 1999 Wind River Systems, Inc. */
/* Copyright 1998-1999 XACT, Inc. */
#include "copyright_wrs.h"
/*
Modification history
--------------------
01v,07feb02,kw Added support for muxError() return calls.
01u,18apr01,kc Replaced "extern" with "IMPORT".
01t,16apr01,kc Fixed PR #2175, changed spanInit() to return OK/ERROR (was TRUE/FALSE).
01s,12feb01,rkw PR #2045
01r,22feb01,kw Must validate the values to the STP formalus and accept what
the root bridge is telling us for timer values.
01q,22feb01,kw Do not check the STP version on recevied packets.
01p,10dec00,ajw Changes to comments for refgen web pages
01o,07Dec00,ba protocol_enable is set by calling oemArchIfaceSTPEnable.
01n,16nov00,kw Ran thru lint.
01m,06nov00,kw Removed a unused value 'state' in Recv Task.
01l,09oct00,kw netTupleGet called with invalid argument.
01k,25sep00,kw Make sure the port_info[x].designated_root is inited to
a large value so that any other stp will win. This appeared
in the bcm5600 switch because memory was zeroed.
01j,25sep00,kw Changed Identifer from long long to a structure for
Little Endian issues.
01j,24sep00,kw Make sure the Bridge Priority value is in correct byte order.
01i,24sep00,kw Fixed up the comments for the muxTkSend calls.
01h,07sep00,kw Remove the Swapi headers for rfc1493 header file.
01g,30jul00,kw Minor code clean up, have the stpTimerTask exit after 25 errors.
01f,26jul00,kw Convert from zero index base scalars to 1 based index.
01e,26Mar00,kw Now uses the agEnd device.
01d,09Mas99,kp Fixed a PR#1154 Throw away config BPDU also when its ID is not 0
01c,21Sep99,kw Fixed a PR#854 Not able to send packets.
01b,17Sep99,kw Added the support for BL2 PR#713
01a,09Sep99,kw Changed TX/RX processing for port number PR#793
*/
/*
DESCRIPTION
The routines in this midule are used to port Spanning Tree Algorithm and
Protocol.
Edit this file when porting Spanning Tree to another platform.
*/
/*lint -save -e773 */
/* includes */
#include <stp/types.h>
#include <msgQLib.h>
#include <end.h>
#include <muxLib.h>
#include <muxTkLib.h>
#include <netBufLib.h>
#include <errnoLib.h>
#include <drv/timer/timerDev.h>
#include <stp/llcLib.h>
#include <ioctl.h>
#include <stp/spantree.h>
#include <stp/spanglob.h>
#include <apcfg.h>
#include <wlanproto.h>
#include <vxdrv.h>
/*lint -restore */
/* defines */
#define FORCE_PRIORITY_ZERO 0
#define SPAN_BUFSIZ 128
#define glong(l) ( (((uchar_t *)(l))[0] << 24) | \
(((uchar_t *)(l))[1] << 16) | \
(((uchar_t *)(l))[2] << 8 ) | \
((uchar_t *)(l))[3] )
#define slong(l,v) { ((uchar_t *)(l))[0] = (uchar_t)((ulong_t)(v)>>24); \
((uchar_t *)(l))[1] = (uchar_t)((ulong_t)(v)>>16); \
((uchar_t *)(l))[2] = (uchar_t)((ulong_t)(v)>>8); \
((uchar_t *)(l))[3] = (uchar_t)((ulong_t)(v)); }
#define gshort(s) (ushort_t)( (((uchar_t *)(s))[0] << 8) | \
((uchar_t *)(s))[1])
#define sshort(s,v) { ((uchar_t *)(s))[0] = (uchar_t)((v)>>8); \
((uchar_t *)(s))[1] = (uchar_t)(v); }
#define SPAN_MSG_COUNT 128
#define SPAN_ON 0xfefefefe
#define SPAN_OFF 0xfdfdfdfd
#define SPAN_TIMER_TICK 0xfcfcfcfc
#define SPAN_RX_BPDU 0xfbfbfbfb
#define SPAN_PORT_ENABLE 0xfafafafa
#define SPAN_PORT_DISABLE 0xf9f9f9f9
#define SPAN_PROTO_ENABLE 0xf8f8f8f8
#define SPAN_PROTO_DISABLE 0xf7f7f7f7
#define SPAN_PRIO_CHANGE 0xf6f6f6f6
#define SPAN_PORT_PRIO_CHANGE 0xf5f5f5f5
#define SPAN_UPDATE_BRIDGE 0xf4f4f4f4
#define SPAN_PORT_PATH_COST_CHANGE 0xf3f3f3f3
#define AE_DEVICE_NAME "ae"
#define AE_DEVICE_UNIT 1
/* typedefs */
typedef struct {
void * pCookie; /* The MUX Bind ID. */
ulong_t qtag;
uchar_t mac[6]; /* MAC address */
ushort_t filler;
} muxInfo_t;
typedef struct
{
Boolean spanInitialized;
Boolean spanState;
ulong_t numPorts;
NET_POOL_ID pNetPool; /* Pool structure pointer. */
CL_POOL_ID pClPoolId; /* Pool structure pointer. */
Identifier bridge_id;
muxInfo_t * muxInfo;
char * portBitList;
} SPAN_DRV_CTRL;
typedef struct
{
ulong_t code;
void* data;
ulong_t extra;
} span_msg_t;
/********* DEBUG MACROS *********/
#define dbgEnable
#ifdef dbgEnable
#define STP_DEBUG_OFF 0x0000
#define STP_DEBUG_LINK 0x0001
#define STP_RXPDU 0x0002
#define STP_TXPDU 0x0004
#define STP_PORT_STATE 0x0008
#define STP_RX_SIGNAL 0x0010
#define STP_AG_WARNING 0x0020
int stpDebug = STP_DEBUG_OFF;
#define dbgPrintf(lvl, _x) if (lvl & stpDebug) {printf _x;}
#else /* dbgEnable */
#define dbgPrintf(lvl, _x)
#endif /* dbgEnable */
/* forward declarations */
LOCAL BOOL spanRecv(void *pCookie, long type, M_BLK_ID pMblk, LL_HDR_INFO * pLinkHdrInfo, void *pSpare);
LOCAL void spanErrorRtn(END_OBJ* pEnd, END_ERR* pError, void * pSpare);
LOCAL BOOL spanTxShutdownRtn(void * pCookie, void * pSpare);
LOCAL BOOL spanTxRestartRtn(void * pCookie, void * pSpare);
LOCAL STATUS stpTimerTask(char * appName, void * arg1, void * arg2);
LOCAL STATUS stpRecvTask(char * appName, void * arg1, void * arg2);
LOCAL void span_process(Bpdu_header_t * bpdu, ulong_t port);
STATUS No_of_ports;
/* globals */
#undef DEBUGGER_SYNC
#ifdef DEBUGGER_SYNC
SEM_ID span_debug_sync_sem;
#endif
LOCAL SEM_ID span_task_sem;
LOCAL Config_bpdu span_Config_bpdu;
LOCAL Tcn_bpdu span_Tcn_bpdu;
LOCAL void * Span_Queue;
LOCAL SPAN_DRV_CTRL * SpanDrvCtrl;
/* network buffers configuration */
LOCAL M_CL_CONFIG spanMclConfig =
{ /* mBlk configuration table */
0, 0, NULL, 0
};
LOCAL CL_DESC spanClDescTbl[] =
{ /* network cluster pool configuration table */
/*
* clusterSize num memArea memSize
* ----------- ---- ------- -------
*/
{SPAN_BUFSIZ, 0, NULL, 0}
};
LOCAL int spanClDescTblNumEnt = (NELEMENTS(spanClDescTbl));
/* locals */
LOCAL char* span_errmsg = "%s:%d Allocation Error\n";
char deviceName[22][4]; /*aaaa*/
int portNum[22];
int totalPort;
int bStpInit;
/*******************************************************************************
*
* stpQSend -
*
* DESCRIPTION
*
* RETURNS
*
* NOMANUAL
*/
LOCAL STATUS stpQSend
(
ulong_t code,
void * data,
ulong_t extra
)
{
span_msg_t Message;
if ( Span_Queue ) {
Message.code = code;
Message.data = data;
Message.extra = extra;
return msgQSend(Span_Queue,
(void *) &Message, sizeof(span_msg_t),
NO_WAIT, MSG_PRI_NORMAL);
}
return ERROR;
}
/*******************************************************************************
* stpInit - Spanning Tree: Startup, Initialization, etc.
*
* This routine initializes and starts SPAN
*
* INPUTS:
*
* RETURNS:
*
* ERRORS:
*
* ERRNO:
*
* NOMANUAL <this will be removed later>
*/
STATUS stpInit
(
char * appName,
void * arg1,
void * arg2
)
{
END_OBJ * pEndObj;
void * pCookie;
char tName[16];
ulong_t port;
int i;
for(i = 0; i < MAX_REMOTE_WBR; i++) {
WLAN_MACADDR rAp;
WLAN_MACADDR defaultRemoteWbrMacAddr = DEFAULT_REMOTE_AP_MACADDR;
apCfgRemoteWbrMacAddrGet(1, i, &rAp);
if (!A_MACADDR_COMP(&defaultRemoteWbrMacAddr, &rAp))
break;
totalPort++;
portNum[totalPort]=0x10000+totalPort;
memcpy(&deviceName[totalPort][0],"vp\0",3);
}
memcpy(&deviceName[0][0],"ae\0",3);
portNum[0]=1;
totalPort++;
bStpInit=1;
SpanDrvCtrl = (SPAN_DRV_CTRL *) calloc(1, sizeof(SPAN_DRV_CTRL));
if (!SpanDrvCtrl)
{
logMsg("SPAN could not allocate control structure.\n", 1, 2, 3, 4, 5, 6);
return ERROR;
}
SpanDrvCtrl->numPorts = totalPort;
No_of_ports = totalPort;
/* PortFast/UplinkFast init */
stPortFastInit();
stUplinkFastInit();
SpanDrvCtrl->muxInfo =
(muxInfo_t *)calloc( SpanDrvCtrl->numPorts+1, sizeof(muxInfo_t) );
if ( SpanDrvCtrl->muxInfo == NULL )
{
logMsg("calloc failed for muxInfo.\n",
1, 2, 3, 4, 5, 6);
cfree( (char *)SpanDrvCtrl );
SpanDrvCtrl = NULL;
return ERROR;
}
SpanDrvCtrl->muxInfo->filler = 0;
if ( muxTkDrvCheck(AE_DEVICE_NAME) != 0 )
{
logMsg("Not an END Driver %s%d.\n",
(int)AE_DEVICE_NAME, AE_DEVICE_UNIT, 3, 4, 5, 6);
return ERROR;
}
pEndObj = endFindByName(AE_DEVICE_NAME, AE_DEVICE_UNIT);
if (!pEndObj)
{
perror("spanTask: endFindByname Failed");
cfree( (char *)SpanDrvCtrl->muxInfo );
cfree( (char *)SpanDrvCtrl );
SpanDrvCtrl = NULL;
return ERROR;
}
/* Bind to sw0 driver, to get the base Bridge MAC address. */
pCookie = (void *) muxBind( AE_DEVICE_NAME, AE_DEVICE_UNIT,
NULL, NULL, NULL, NULL,
STP_ETHER_TYPE, "STP802.1D", (void *) 0);
if (!pCookie)
{
perror("spanTask: muxTkBind Failed");
cfree( (char *)SpanDrvCtrl->muxInfo );
cfree( (char *)SpanDrvCtrl );
return ERROR;
}
/*
* Retrive the MAC address for this device from swEnd device.
* The Bridge priority value will be retrived later.
*/
memset( (char *)&SpanDrvCtrl->bridge_id, 0, sizeof(Identifier) );
muxIoctl( pCookie, EIOCGADDR, (caddr_t)SpanDrvCtrl->bridge_id.mac );
/* Close binding to swEnd device. */
muxUnbind( pCookie, STP_ETHER_TYPE, NULL );
if (muxTkDrvCheck(AE_DEVICE_NAME) != 0)
{
perror("spanTask: Device is not an END driver");
cfree( (char *)SpanDrvCtrl->muxInfo );
cfree( (char *)SpanDrvCtrl );
return ERROR;
}
if (muxTkDrvCheck("vp") != 0)
{
perror("spanTask: Device is not an END driver");
cfree( (char *)SpanDrvCtrl->muxInfo );
cfree( (char *)SpanDrvCtrl );
return ERROR;
}
/* Allocate the SPAN data space. */
if (!port_info)
{
int port_cnt;
port_cnt = (int)(SpanDrvCtrl->numPorts + 1);
port_info = (Port_data *) calloc((unsigned int)port_cnt, sizeof(Port_data));
if (!port_info)
printf(span_errmsg, __FILE__, __LINE__);
config_bpdu = (Config_bpdu *) calloc((unsigned int)port_cnt, sizeof(Config_bpdu));
if (!config_bpdu)
printf(span_errmsg, __FILE__, __LINE__);
tcn_bpdu = (Tcn_bpdu *) calloc((unsigned int)port_cnt, sizeof(Tcn_bpdu));
if (!tcn_bpdu)
printf(span_errmsg, __FILE__, __LINE__);
message_age_timer = (Timer *) calloc((unsigned int)port_cnt, sizeof(Timer));
if (!message_age_timer)
printf(span_errmsg, __FILE__, __LINE__);
forward_delay_timer = (Timer *) calloc((unsigned int)port_cnt, sizeof(Timer));
if (!forward_delay_timer)
printf(span_errmsg, __FILE__, __LINE__);
hold_timer = (Timer *) calloc((unsigned int)port_cnt, sizeof(Timer));
if (!hold_timer)
printf(span_errmsg, __FILE__, __LINE__);
}
for(port = One; port <= SpanDrvCtrl->numPorts; port++)
{
pEndObj = endFindByName(&(deviceName[port-1][0]), portNum[port-1]);
if (!pEndObj)
{
perror("spanTask: endFindByName failed for 'ae' drivers");
cfree( (char *)SpanDrvCtrl->muxInfo );
cfree( (char *)SpanDrvCtrl );
return ERROR;
}
/* Bind to the END driver. */
SpanDrvCtrl->muxInfo[port].pCookie =
(void *) muxBind( &(deviceName[port-1][0]), portNum[port-1],
spanRecv, spanTxShutdownRtn, spanTxRestartRtn, spanErrorRtn,
STP_ETHER_TYPE, "STP802.1D/D17", (void *)&port_info[port]);
if (!SpanDrvCtrl->muxInfo[port].pCookie)
{
perror("spanTask: muxTkBind failed for 'ae' drivers");
cfree( (char *)SpanDrvCtrl->muxInfo );
cfree( (char *)SpanDrvCtrl );
return ERROR;
}
/* Retrieve the MAC address from agN device. */
muxIoctl( SpanDrvCtrl->muxInfo[port].pCookie, EIOCGADDR,
(caddr_t)SpanDrvCtrl->muxInfo[port].mac );
/* Get QTag Size.
muxIoctl( SpanDrvCtrl->muxInfo[port].pCookie, EIOCGQTAG,
(char *)&SpanDrvCtrl->muxInfo[port].qtag );*/
/* Leave the agN binding open, do not close */
}
if ((SpanDrvCtrl->pNetPool = calloc(1, sizeof(NET_POOL))) == NULL)
{
perror("spanTask: Could not allocate NetPool structure");
cfree( (char *)SpanDrvCtrl->muxInfo );
cfree( (char *)SpanDrvCtrl );
return ERROR;
}
SpanDrvCtrl->spanInitialized = False;
SpanDrvCtrl->spanState = False;
spanClDescTbl[0].clNum = (int)(SpanDrvCtrl->numPorts + 4);
spanMclConfig.mBlkNum = spanClDescTbl[0].clNum;
spanMclConfig.clBlkNum = spanClDescTbl[0].clNum;
spanMclConfig.memSize = (int)(
((unsigned int)spanMclConfig.mBlkNum * (MSIZE + sizeof(long))) +
((unsigned int)spanMclConfig.clBlkNum * (CL_BLK_SZ + sizeof(long))));
spanMclConfig.memArea = (char *) memalign(sizeof(long),
(unsigned int)spanMclConfig.memSize);
if (spanMclConfig.memArea == NULL)
{
cfree( (char *)SpanDrvCtrl->pNetPool );
cfree( (char *)SpanDrvCtrl->muxInfo );
cfree( (char *)SpanDrvCtrl );
return ERROR;
}
/*lint -save -e737 -e713 */
spanClDescTbl[0].memSize =
(spanClDescTbl[0].clNum * (SPAN_BUFSIZ + 8)) + sizeof(int);
/*lint -restore */
spanClDescTbl[0].memArea =
(char *) cacheDmaMalloc((unsigned int)spanClDescTbl[0].memSize);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -