📄 skaddr.c
字号:
/****************************************************************************** * * Name: skaddr.c * Project: Gigabit Ethernet Adapters, ADDR-Module * Version: $Revision: 2.15 $ * Date: $Date: 2008/04/02 10:42:40 $ * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode. * ******************************************************************************//****************************************************************************** * * LICENSE: * (C)Copyright 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. * /LICENSE * ******************************************************************************//****************************************************************************** * * Description: * * This module is intended to manage multicast addresses, address override, * and promiscuous mode on Yukon adapters. * * Address Layout: * port address: physical MAC address * * Include File Hierarchy: * * "skdrv1st.h" * "skdrv2nd.h" * ******************************************************************************/#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))static const char SysKonnectFileId[] = "@(#) $Id: skaddr.c,v 2.15 2008/04/02 10:42:40 tschilli Exp $ (C) Marvell.";#endif /* DEBUG ||!LINT || !SK_SLIM */#define __SKADDR_C#ifdef __cplusplusextern "C" {#endif /* cplusplus */#include "h/skdrv1st.h"#include "h/skdrv2nd.h"/* defines ********************************************************************/#define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */#define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */#define HASH_BITS 6 /* #bits in hash */#define SK_MC_BIT 0x01/* Error numbers and messages. */#define SKERR_ADDR_E001 (SK_ERRBASE_ADDR + 0)#define SKERR_ADDR_E001MSG "Bad Flags."#define SKERR_ADDR_E002 (SKERR_ADDR_E001 + 1)#define SKERR_ADDR_E002MSG "New Error."/* typedefs *******************************************************************//* None. *//* global variables ***********************************************************//* 64-bit hash values with all bits set. */SK_U16 OnesHash[4] = {0xffff, 0xffff, 0xffff, 0xffff};/* local variables ************************************************************/#ifdef DEBUGstatic int Next0[SK_MAX_MACS] = {0};#endif /* DEBUG *//* functions ******************************************************************//****************************************************************************** * * SkAddrInit - initialize data, set state to init * * Description: * * SK_INIT_DATA * ============ * * This routine clears the multicast tables and resets promiscuous mode. * Some entries are reserved for the "logical MAC address", the * SK-RLMT multicast address, and the BPDU multicast address. * * * SK_INIT_IO * ========== * * All permanent MAC addresses are read from EPROM. * If the current MAC addresses are not already set in software, * they are set to the values of the permanent addresses. * The current addresses are written to the corresponding MAC. * * * SK_INIT_RUN * =========== * * Nothing. * * Context: * init, pageable * * Returns: * SK_ADDR_SUCCESS */int SkAddrInit(SK_AC *pAC, /* the adapter context */SK_IOC IoC, /* I/O context */int Level) /* initialization level */{ int j; SK_U32 i; SK_U8 *InAddr; SK_U16 *OutAddr; SK_ADDR_PORT *pAPort; switch (Level) { case SK_INIT_DATA: SK_MEMSET((char *)&pAC->Addr, (SK_U8)0, (SK_U16)sizeof(SK_ADDR)); for (i = 0; i < SK_MAX_MACS; i++) { pAPort = &pAC->Addr.Port[i]; pAPort->PromMode = SK_PROM_MODE_NONE; pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; }#ifdef xDEBUG for (i = 0; i < SK_MAX_MACS; i++) { if (pAC->Addr.Port[i].NextExactMatchRlmt < SK_ADDR_FIRST_MATCH_RLMT) { Next0[i] |= 4; } }#endif /* DEBUG */ /* pAC->Addr.InitDone = SK_INIT_DATA; */ break; case SK_INIT_IO:#ifndef SK_NO_RLMT for (i = 0; i < SK_MAX_NETS; i++) { pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort; }#endif /* !SK_NO_RLMT */#ifdef xDEBUG for (i = 0; i < SK_MAX_MACS; i++) { if (pAC->Addr.Port[i].NextExactMatchRlmt < SK_ADDR_FIRST_MATCH_RLMT) { Next0[i] |= 8; } }#endif /* DEBUG */ /* Read permanent logical MAC address from Control Register File. */ for (j = 0; j < SK_MAC_ADDR_LEN; j++) { InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j]; SK_IN8(IoC, B2_MAC_1 + j, InAddr); } if (!pAC->Addr.Net[0].CurrentMacAddressSet) { /* Set the current logical MAC address to the permanent one. */ pAC->Addr.Net[0].CurrentMacAddress = pAC->Addr.Net[0].PermanentMacAddress; pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE; } /* Set the current logical MAC address. */ pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] = pAC->Addr.Net[0].CurrentMacAddress;#if SK_MAX_NETS > 1 /* Set logical MAC address for net 2 to. */ if (!pAC->Addr.Net[1].CurrentMacAddressSet) { pAC->Addr.Net[1].PermanentMacAddress = pAC->Addr.Net[0].PermanentMacAddress; pAC->Addr.Net[1].PermanentMacAddress.a[5] += 1; /* Set the current logical MAC address to the permanent one. */ pAC->Addr.Net[1].CurrentMacAddress = pAC->Addr.Net[1].PermanentMacAddress; pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE; }#endif /* SK_MAX_NETS > 1 */#ifdef DEBUG for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", i, pAC->Addr.Net[i].PermanentMacAddress.a[0], pAC->Addr.Net[i].PermanentMacAddress.a[1], pAC->Addr.Net[i].PermanentMacAddress.a[2], pAC->Addr.Net[i].PermanentMacAddress.a[3], pAC->Addr.Net[i].PermanentMacAddress.a[4], pAC->Addr.Net[i].PermanentMacAddress.a[5])); SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", i, pAC->Addr.Net[i].CurrentMacAddress.a[0], pAC->Addr.Net[i].CurrentMacAddress.a[1], pAC->Addr.Net[i].CurrentMacAddress.a[2], pAC->Addr.Net[i].CurrentMacAddress.a[3], pAC->Addr.Net[i].CurrentMacAddress.a[4], pAC->Addr.Net[i].CurrentMacAddress.a[5])); }#endif /* DEBUG */ for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { pAPort = &pAC->Addr.Port[i]; /* Read permanent port addresses from Control Register File. */ for (j = 0; j < SK_MAC_ADDR_LEN; j++) { InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j]; SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr); } if (!pAPort->CurrentMacAddressSet) { /* * Set the current and previous physical MAC address * of this port to its permanent MAC address. */ pAPort->CurrentMacAddress = pAPort->PermanentMacAddress; pAPort->PreviousMacAddress = pAPort->PermanentMacAddress; pAPort->CurrentMacAddressSet = SK_TRUE; } /* Set port's current physical MAC address. */ OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr);#ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", pAPort->PermanentMacAddress.a[0], pAPort->PermanentMacAddress.a[1], pAPort->PermanentMacAddress.a[2], pAPort->PermanentMacAddress.a[3], pAPort->PermanentMacAddress.a[4], pAPort->PermanentMacAddress.a[5])); SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", pAPort->CurrentMacAddress.a[0], pAPort->CurrentMacAddress.a[1], pAPort->CurrentMacAddress.a[2], pAPort->CurrentMacAddress.a[3], pAPort->CurrentMacAddress.a[4], pAPort->CurrentMacAddress.a[5]));#endif /* DEBUG */ } /* pAC->Addr.InitDone = SK_INIT_IO; */ break; case SK_INIT_RUN:#ifdef xDEBUG for (i = 0; i < SK_MAX_MACS; i++) { if (pAC->Addr.Port[i].NextExactMatchRlmt < SK_ADDR_FIRST_MATCH_RLMT) { Next0[i] |= 16; } }#endif /* DEBUG */ /* pAC->Addr.InitDone = SK_INIT_RUN; */ break; default: /* error */ break; } return (SK_ADDR_SUCCESS);} /* SkAddrInit */#ifndef SK_SLIM/****************************************************************************** * * SkAddrMcClear - clear the multicast table * * Description: * This routine clears the multicast table. * * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated * immediately. * * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according * to the adapter in use. The real work is done there. * * Context: * runtime, pageable * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY * may be called after SK_INIT_IO without limitation * * Returns: * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */int SkAddrMcClear(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* I/O context */SK_U32 PortNumber, /* Index of affected port */int Flags) /* permanent/non-perm, sw-only */{ int ReturnCode; if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags); return (ReturnCode);} /* SkAddrMcClear *//****************************************************************************** * * SkAddrGmacMcClear - clear the multicast table * * Description: * This routine clears the multicast hashing table (InexactFilter) * (either the RLMT or the driver bits) of the given port. * * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated * immediately. * * Context: * runtime, pageable * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY * may be called after SK_INIT_IO without limitation * * Returns: * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */int SkAddrGmacMcClear(SK_AC *pAC, /* adapter context */SK_IOC IoC, /* I/O context */SK_U32 PortNumber, /* Index of affected port */int Flags) /* permanent/non-perm, sw-only */{ int i;#ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]));#endif /* DEBUG */ /* Clear InexactFilter */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; } if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ /* Copy DRV bits to InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; /* Clear InexactRlmtFilter. */ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0; } } else { /* not permanent => DRV */ /* Copy RLMT bits to InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; /* Clear InexactDrvFilter. */ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0; } }#ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7]));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -