📄 skrlmt.c
字号:
/****************************************************************************** * * Name: skrlmt.c * Project: GEnesis, PCI Gigabit Ethernet Adapter * Version: $Revision: 1.69 $ * Date: $Date: 2003/04/15 09:39:22 $ * Purpose: Manage links on SK-NET Adapters, esp. redundant ones. * ******************************************************************************//****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. * (C)Copyright 2002-2003 Marvell. * * 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. * ******************************************************************************//****************************************************************************** * * Description: * * This module contains code for Link ManagemenT (LMT) of SK-NET Adapters. * It is mainly intended for adapters with more than one link. * For such adapters, this module realizes Redundant Link ManagemenT (RLMT). * * Include File Hierarchy: * * "skdrv1st.h" * "skdrv2nd.h" * ******************************************************************************/#ifndef lintstatic const char SysKonnectFileId[] = "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell.";#endif /* !defined(lint) */#define __SKRLMT_C#ifdef __cplusplusextern "C" {#endif /* cplusplus */#include "h/skdrv1st.h"#include "h/skdrv2nd.h"/* defines ********************************************************************/#ifndef SK_HWAC_LINK_LED#define SK_HWAC_LINK_LED(a,b,c,d)#endif /* !defined(SK_HWAC_LINK_LED) */#ifndef DEBUG#define RLMT_STATIC static#else /* DEBUG */#define RLMT_STATIC#ifndef SK_LITTLE_ENDIAN/* First 32 bits */#define OFFS_LO32 1/* Second 32 bits */#define OFFS_HI32 0#else /* SK_LITTLE_ENDIAN *//* First 32 bits */#define OFFS_LO32 0/* Second 32 bits */#define OFFS_HI32 1#endif /* SK_LITTLE_ENDIAN */#endif /* DEBUG *//* ----- Private timeout values ----- */#define SK_RLMT_MIN_TO_VAL 125000 /* 1/8 sec. */#define SK_RLMT_DEF_TO_VAL 1000000 /* 1 sec. */#define SK_RLMT_PORTDOWN_TIM_VAL 900000 /* another 0.9 sec. */#define SK_RLMT_PORTSTART_TIM_VAL 100000 /* 0.1 sec. */#define SK_RLMT_PORTUP_TIM_VAL 2500000 /* 2.5 sec. */#define SK_RLMT_SEG_TO_VAL 900000000 /* 15 min. *//* Assume tick counter increment is 1 - may be set OS-dependent. */#ifndef SK_TICK_INCR#define SK_TICK_INCR SK_CONSTU64(1)#endif /* !defined(SK_TICK_INCR) *//* * Amount that a time stamp must be later to be recognized as "substantially * later". This is about 1/128 sec, but above 1 tick counter increment. */#define SK_RLMT_BC_DELTA (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \ (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))/* ----- Private RLMT defaults ----- */#define SK_RLMT_DEF_PREF_PORT 0 /* "Lower" port. */#define SK_RLMT_DEF_MODE SK_RLMT_CHECK_LINK /* Default RLMT Mode. *//* ----- Private RLMT checking states ----- */#define SK_RLMT_RCS_SEG 1 /* RLMT Check State: check seg. */#define SK_RLMT_RCS_START_SEG 2 /* RLMT Check State: start check seg. */#define SK_RLMT_RCS_SEND_SEG 4 /* RLMT Check State: send BPDU packet */#define SK_RLMT_RCS_REPORT_SEG 8 /* RLMT Check State: report seg. *//* ----- Private PORT checking states ----- */#define SK_RLMT_PCS_TX 1 /* Port Check State: check tx. */#define SK_RLMT_PCS_RX 2 /* Port Check State: check rx. *//* ----- Private PORT events ----- *//* Note: Update simulation when changing these. */#define SK_RLMT_PORTSTART_TIM 1100 /* Port start timeout. */#define SK_RLMT_PORTUP_TIM 1101 /* Port can now go up. */#define SK_RLMT_PORTDOWN_RX_TIM 1102 /* Port did not receive once ... */#define SK_RLMT_PORTDOWN 1103 /* Port went down. */#define SK_RLMT_PORTDOWN_TX_TIM 1104 /* Partner did not receive ... *//* ----- Private RLMT events ----- *//* Note: Update simulation when changing these. */#define SK_RLMT_TIM 2100 /* RLMT timeout. */#define SK_RLMT_SEG_TIM 2101 /* RLMT segmentation check timeout. */#define TO_SHORTEN(tim) ((tim) / 2)/* Error numbers and messages. */#define SKERR_RLMT_E001 (SK_ERRBASE_RLMT + 0)#define SKERR_RLMT_E001_MSG "No Packet."#define SKERR_RLMT_E002 (SKERR_RLMT_E001 + 1)#define SKERR_RLMT_E002_MSG "Short Packet."#define SKERR_RLMT_E003 (SKERR_RLMT_E002 + 1)#define SKERR_RLMT_E003_MSG "Unknown RLMT event."#define SKERR_RLMT_E004 (SKERR_RLMT_E003 + 1)#define SKERR_RLMT_E004_MSG "PortsUp incorrect."#define SKERR_RLMT_E005 (SKERR_RLMT_E004 + 1)#define SKERR_RLMT_E005_MSG \ "Net seems to be segmented (different root bridges are reported on the ports)."#define SKERR_RLMT_E006 (SKERR_RLMT_E005 + 1)#define SKERR_RLMT_E006_MSG "Duplicate MAC Address detected."#define SKERR_RLMT_E007 (SKERR_RLMT_E006 + 1)#define SKERR_RLMT_E007_MSG "LinksUp incorrect."#define SKERR_RLMT_E008 (SKERR_RLMT_E007 + 1)#define SKERR_RLMT_E008_MSG "Port not started but link came up."#define SKERR_RLMT_E009 (SKERR_RLMT_E008 + 1)#define SKERR_RLMT_E009_MSG "Corrected illegal setting of Preferred Port."#define SKERR_RLMT_E010 (SKERR_RLMT_E009 + 1)#define SKERR_RLMT_E010_MSG "Ignored illegal Preferred Port."/* LLC field values. */#define LLC_COMMAND_RESPONSE_BIT 1#define LLC_TEST_COMMAND 0xE3#define LLC_UI 0x03/* RLMT Packet fields. */#define SK_RLMT_DSAP 0#define SK_RLMT_SSAP 0#define SK_RLMT_CTRL (LLC_TEST_COMMAND)#define SK_RLMT_INDICATOR0 0x53 /* S */#define SK_RLMT_INDICATOR1 0x4B /* K */#define SK_RLMT_INDICATOR2 0x2D /* - */#define SK_RLMT_INDICATOR3 0x52 /* R */#define SK_RLMT_INDICATOR4 0x4C /* L */#define SK_RLMT_INDICATOR5 0x4D /* M */#define SK_RLMT_INDICATOR6 0x54 /* T */#define SK_RLMT_PACKET_VERSION 0/* RLMT SPT Flag values. */#define SK_RLMT_SPT_FLAG_CHANGE 0x01#define SK_RLMT_SPT_FLAG_CHANGE_ACK 0x80/* RLMT SPT Packet fields. */#define SK_RLMT_SPT_DSAP 0x42#define SK_RLMT_SPT_SSAP 0x42#define SK_RLMT_SPT_CTRL (LLC_UI)#define SK_RLMT_SPT_PROTOCOL_ID0 0x00#define SK_RLMT_SPT_PROTOCOL_ID1 0x00#define SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00#define SK_RLMT_SPT_BPDU_TYPE 0x00#define SK_RLMT_SPT_FLAGS 0x00 /* ?? */#define SK_RLMT_SPT_ROOT_ID0 0xFF /* Lowest possible priority. */#define SK_RLMT_SPT_ROOT_ID1 0xFF /* Lowest possible priority. *//* Remaining 6 bytes will be the current port address. */#define SK_RLMT_SPT_ROOT_PATH_COST0 0x00#define SK_RLMT_SPT_ROOT_PATH_COST1 0x00#define SK_RLMT_SPT_ROOT_PATH_COST2 0x00#define SK_RLMT_SPT_ROOT_PATH_COST3 0x00#define SK_RLMT_SPT_BRIDGE_ID0 0xFF /* Lowest possible priority. */#define SK_RLMT_SPT_BRIDGE_ID1 0xFF /* Lowest possible priority. *//* Remaining 6 bytes will be the current port address. */#define SK_RLMT_SPT_PORT_ID0 0xFF /* Lowest possible priority. */#define SK_RLMT_SPT_PORT_ID1 0xFF /* Lowest possible priority. */#define SK_RLMT_SPT_MSG_AGE0 0x00#define SK_RLMT_SPT_MSG_AGE1 0x00#define SK_RLMT_SPT_MAX_AGE0 0x00#define SK_RLMT_SPT_MAX_AGE1 0xFF#define SK_RLMT_SPT_HELLO_TIME0 0x00#define SK_RLMT_SPT_HELLO_TIME1 0xFF#define SK_RLMT_SPT_FWD_DELAY0 0x00#define SK_RLMT_SPT_FWD_DELAY1 0x40/* Size defines. */#define SK_RLMT_MIN_PACKET_SIZE 34#define SK_RLMT_MAX_PACKET_SIZE (SK_RLMT_MAX_TX_BUF_SIZE)#define SK_PACKET_DATA_LEN (SK_RLMT_MAX_PACKET_SIZE - \ SK_RLMT_MIN_PACKET_SIZE)/* ----- RLMT packet types ----- */#define SK_PACKET_ANNOUNCE 1 /* Port announcement. */#define SK_PACKET_ALIVE 2 /* Alive packet to port. */#define SK_PACKET_ADDR_CHANGED 3 /* Port address changed. */#define SK_PACKET_CHECK_TX 4 /* Check your tx line. */#ifdef SK_LITTLE_ENDIAN#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \ SK_U8 *_Addr = (SK_U8*)(Addr); \ SK_U16 _Val = (SK_U16)(Val); \ *_Addr++ = (SK_U8)(_Val >> 8); \ *_Addr = (SK_U8)(_Val & 0xFF); \}#endif /* SK_LITTLE_ENDIAN */#ifdef SK_BIG_ENDIAN#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))#endif /* SK_BIG_ENDIAN */#define AUTONEG_FAILED SK_FALSE#define AUTONEG_SUCCESS SK_TRUE/* typedefs *******************************************************************//* RLMT packet. Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */typedef struct s_RlmtPacket { SK_U8 DstAddr[SK_MAC_ADDR_LEN]; SK_U8 SrcAddr[SK_MAC_ADDR_LEN]; SK_U8 TypeLen[2]; SK_U8 DSap; SK_U8 SSap; SK_U8 Ctrl; SK_U8 Indicator[7]; SK_U8 RlmtPacketType[2]; SK_U8 Align1[2]; SK_U8 Random[4]; /* Random value of requesting(!) station. */ SK_U8 RlmtPacketVersion[2]; /* RLMT Packet version. */ SK_U8 Data[SK_PACKET_DATA_LEN];} SK_RLMT_PACKET;typedef struct s_SpTreeRlmtPacket { SK_U8 DstAddr[SK_MAC_ADDR_LEN]; SK_U8 SrcAddr[SK_MAC_ADDR_LEN]; SK_U8 TypeLen[2]; SK_U8 DSap; SK_U8 SSap; SK_U8 Ctrl; SK_U8 ProtocolId[2]; SK_U8 ProtocolVersionId; SK_U8 BpduType; SK_U8 Flags; SK_U8 RootId[8]; SK_U8 RootPathCost[4]; SK_U8 BridgeId[8]; SK_U8 PortId[2]; SK_U8 MessageAge[2]; SK_U8 MaxAge[2]; SK_U8 HelloTime[2]; SK_U8 ForwardDelay[2];} SK_SPTREE_PACKET;/* global variables ***********************************************************/SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}};SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}};SK_MAC_ADDR BcAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};/* local variables ************************************************************//* None. *//* functions ******************************************************************/RLMT_STATIC void SkRlmtCheckSwitch( SK_AC *pAC, SK_IOC IoC, SK_U32 NetIdx);RLMT_STATIC void SkRlmtCheckSeg( SK_AC *pAC, SK_IOC IoC, SK_U32 NetIdx);RLMT_STATIC void SkRlmtEvtSetNets( SK_AC *pAC, SK_IOC IoC, SK_EVPARA Para);/****************************************************************************** * * SkRlmtInit - initialize data, set state to init * * Description: * * SK_INIT_DATA * ============ * * This routine initializes all RLMT-related variables to a known state. * The initial state is SK_RLMT_RS_INIT. * All ports are initialized to SK_RLMT_PS_INIT. * * * SK_INIT_IO * ========== * * Nothing. * * * SK_INIT_RUN * =========== * * Determine the adapter's random value. * Set the hw registers, the "logical MAC address", the * RLMT multicast address, and eventually the BPDU multicast address. * * Context: * init, pageable * * Returns: * Nothing. */void SkRlmtInit(SK_AC *pAC, /* Adapter Context */SK_IOC IoC, /* I/O Context */int Level) /* Initialization Level */{ SK_U32 i, j; SK_U64 Random; SK_EVPARA Para; SK_MAC_ADDR VirtualMacAddress; SK_MAC_ADDR PhysicalAMacAddress; SK_BOOL VirtualMacAddressSet; SK_BOOL PhysicalAMacAddressSet; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, ("RLMT Init level %d.\n", Level)) switch (Level) { case SK_INIT_DATA: /* Initialize data structures. */ SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT)); for (i = 0; i < SK_MAX_MACS; i++) { pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT; pAC->Rlmt.Port[i].LinkDown = SK_TRUE; pAC->Rlmt.Port[i].PortDown = SK_TRUE; pAC->Rlmt.Port[i].PortStarted = SK_FALSE; pAC->Rlmt.Port[i].PortNoRx = SK_FALSE; pAC->Rlmt.Port[i].RootIdSet = SK_FALSE; pAC->Rlmt.Port[i].PortNumber = i; pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0]; pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i]; } pAC->Rlmt.NumNets = 1; for (i = 0; i < SK_MAX_NETS; i++) { pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */ /* Just assuming. */ pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL; pAC->Rlmt.Net[i].NetNumber = i; } pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0]; pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];#if SK_MAX_NETS > 1 pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];#endif /* SK_MAX_NETS > 1 */ break; case SK_INIT_IO: /* GIMacsFound first available here. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound)) pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; /* Initialize HW registers? */ if (pAC->GIni.GIMacsFound == 1) { Para.Para32[0] = SK_RLMT_MODE_CLS; Para.Para32[1] = 0; (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para); } break; case SK_INIT_RUN: /* Ensure RLMT is set to one net. */ if (pAC->Rlmt.NumNets > 1) { Para.Para32[0] = 1; Para.Para32[1] = -1; SkRlmtEvtSetNets(pAC, IoC, Para); } for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { Random = SkOsGetTime(pAC); *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random; for (j = 0; j < 4; j++) { pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort-> CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j]; } (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY); /* Add RLMT MC address. */ (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT); if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) { /* Add BPDU MC address. */ (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT); } (void)SkAddrMcUpdate(pAC, IoC, i); } VirtualMacAddressSet = SK_FALSE; /* Read virtual MAC address from Control Register File. */ for (j = 0; j < SK_MAC_ADDR_LEN; j++) { SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]); VirtualMacAddressSet |= VirtualMacAddress.a[j]; } PhysicalAMacAddressSet = SK_FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -