Example #1
0
/** ReadMacTableEntries
 * \ingroup intDiagMATable
 *
 * \desc            Output an MA Table entry as it appears in hardware and
 *                  in the memory-based cache.
 * 
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[in]       index is the index into the MA Table.
 *
 * \param[out]      dmacEntry points to a structure to receive the decoded
 *                  destination MAC table entry.
 *
 * \param[out]      smacEntry points to a structure to receive the decoded
 *                  source MAC table entry.
 *
 * \return          None.
 *
 *****************************************************************************/
static fm_status ReadMacTableEntries(fm_int                 sw,
                                     fm_uint32              index,
                                     fm10000_maTableEntry * dmacEntry,
                                     fm10000_maTableEntry * smacEntry)
{
    fm_switch * switchPtr;
    fm_uint32   words[FM10000_MA_TABLE_WIDTH];
    fm_status   status;

    switchPtr = GET_SWITCH_PTR(sw);

    /* Retrieve DMAC table entry. */
    status = switchPtr->ReadUINT32Mult(sw,
                                       FM10000_MA_TABLE(0, index, 0),
                                       FM10000_MA_TABLE_WIDTH,
                                       words);
    if (status != FM_OK)
    {
        FM_LOG_PRINT("Error reading DMAC entry %u: %s\n",
                     index,
                     fmErrorMsg(status));
        return status;
    }

    status = DecodeMacTableEntry(sw, dmacEntry, words);
    if (status != FM_OK)
    {
        FM_LOG_PRINT("Error decoding DMAC entry %u: %s\n",
                     index,
                     fmErrorMsg(status));
        return status;
    }

    /* Retrieve SMAC table entry. */
    status = switchPtr->ReadUINT32Mult(sw,
                                       FM10000_MA_TABLE(1, index, 0),
                                       FM10000_MA_TABLE_WIDTH,
                                       words);
    if (status != FM_OK)
    {
        FM_LOG_PRINT("Error reading SMAC entry %u: %s\n",
                     index,
                     fmErrorMsg(status));
        return status;
    }

    status = DecodeMacTableEntry(sw, smacEntry, words);
    if (status != FM_OK)
    {
        FM_LOG_PRINT("Error decoding SMAC entry %u: %s\n",
                     index,
                     fmErrorMsg(status));
    }

    return status;

}   /* end ReadMacTableEntries */
Example #2
0
/** fmDbgPrintChipSnapshot
 * \ingroup diagReg 
 *
 * \chips           FM2000, FM3000, FM4000, FM6000, FM10000
 *
 * \desc            Display a snapshot of the switch's configuration (the
 *                  register file) taken with a prior call to
 *                  fmDbgTakeChipSnapshot.
 *
 * \param[in]       snapshot is the snapshot number specified in a prior call
 *                  to fmDbgTakeChipSnapshot.
 *
 * \param[in]       showZeroValues should be TRUE to print registers with a
 *                  zero value or FALSE to only print registers with non-zero
 *                  values (this is useful to avoid printing thousands of
 *                  unused VID and FID table entries).
 *
 * \return          None.
 *
 *****************************************************************************/
void fmDbgPrintChipSnapshot(fm_int snapshot, fm_bool showZeroValues)
{
    fmDbgFulcrumSnapshot *        pSnapshot;
    fm_int                        index;
    fmDbgFulcrumRegisterSnapshot *pRegister;

    if (snapshot < 0 || snapshot >= FM_DBG_MAX_SNAPSHOTS)
    {
        FM_LOG_PRINT("snapshot number must be between 0 and %d inclusive\n",
                     FM_DBG_MAX_SNAPSHOTS - 1);
        return;
    }

    pSnapshot = fmRootDebug->fmDbgSnapshots[snapshot];

    if (pSnapshot == NULL)
    {
        FM_LOG_PRINT("snapshot %d is unused\n", snapshot);
        return;
    }

    if (pSnapshot->regCount == 0)
    {
        FM_LOG_PRINT("snapshot %d is empty\n", snapshot);
        return;
    }

    pRegister = pSnapshot->registers;

    FM_LOG_PRINT("Snapshot %d was taken from switch %d at timestamp "
                 "%" FM_FORMAT_64 "u.%06" FM_FORMAT_64 "u with %d registers\n",
                 snapshot,
                 pSnapshot->sw,
                 pSnapshot->timestamp.sec,
                 pSnapshot->timestamp.usec,
                 pSnapshot->regCount);

    for (index = 0 ; index < pSnapshot->regCount ; index++, pRegister++)
    {
        if ( (pRegister->regValue1 != 0) || (pRegister->regValue2 != 0)
            || (showZeroValues == TRUE) )
        {
            fmDbgPrintRegValue(pSnapshot->sw,
                               pRegister->regId,
                               pRegister->regAddress,
                               pRegister->regSize,
                               pRegister->isStatReg,
                               pRegister->regValue1,
                               pRegister->regValue2, 0);
        }
    }

}   /* end fmDbgPrintChipSnapshot */
Example #3
0
/** fmDbgTakeChipSnapshot
 * \ingroup diagReg 
 *
 * \chips           FM2000, FM3000, FM4000, FM6000, FM10000
 *
 * \desc            Record a snapshot of the switch's configuration (the
 *                  register file).
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[in]       snapshot is an arbitrary snapshot number (0 - 31) by
 *                  which to recall the snapshot later.  The snapshot number
 *                  is global across all switches in the system.
 *
 * \return          None.
 *
 *****************************************************************************/
void fmDbgTakeChipSnapshot(fm_int sw, fm_int snapshot)
{
    fmDbgFulcrumSnapshot *pSnapshot;
    fm_switch *           switchPtr;

    if (snapshot < 0 || snapshot >= FM_DBG_MAX_SNAPSHOTS)
    {
        FM_LOG_PRINT("snapshot number must be between 0 and %d inclusive\n",
                     FM_DBG_MAX_SNAPSHOTS - 1);
        return;
    }

    PROTECT_SWITCH(sw);

    switchPtr = fmRootApi->fmSwitchStateTable[sw];

    if (switchPtr == NULL)
    {
        UNPROTECT_SWITCH(sw);
        FM_LOG_PRINT("Invalid switch number %d, snapshot %d\n", sw, snapshot);
        return;
    }

    if (fmRootDebug->fmDbgSnapshots[snapshot] != NULL)
    {
        FREE(fmRootDebug->fmDbgSnapshots[snapshot]);
    }

    pSnapshot = (fmDbgFulcrumSnapshot *) ALLOC( sizeof(fmDbgFulcrumSnapshot) );
    fmRootDebug->fmDbgSnapshots[snapshot] = pSnapshot;

    if (pSnapshot == NULL)
    {
        UNPROTECT_SWITCH(sw);
        FM_LOG_PRINT("can't allocate memory for snapshot %d\n", snapshot);
        return;
    }

    memset( pSnapshot, 0, sizeof(fmDbgFulcrumSnapshot) );

    pSnapshot->sw = sw;
    fmGetTime(&pSnapshot->timestamp);

    FM_API_CALL_FAMILY_VOID(switchPtr->DbgTakeChipSnapshot,
                            sw,
                            pSnapshot,
                            fmDbgSaveRegValueInSnapshot);

    UNPROTECT_SWITCH(sw);

}   /* end fmDbgTakeChipSnapshot */
Example #4
0
/** fmDbgDeleteChipSnapshot
 * \ingroup diagReg 
 *
 * \chips           FM2000, FM3000, FM4000, FM6000, FM10000
 *
 * \desc            Discard a snapshot of the switch's configuration (the
 *                  register file) taken with a prior call to
 *                  fmDbgTakeChipSnapshot.
 *
 * \param[in]       snapshot is the snapshot number specified in a prior call
 *                  to fmDbgTakeChipSnapshot.
 *
 * \return          None.
 *
 *****************************************************************************/
void fmDbgDeleteChipSnapshot(fm_int snapshot)
{
    if (snapshot < 0 || snapshot >= FM_DBG_MAX_SNAPSHOTS)
    {
        FM_LOG_PRINT("snapshot number must be between 0 and %d inclusive\n",
                     FM_DBG_MAX_SNAPSHOTS - 1);
        return;
    }

    if (fmRootDebug->fmDbgSnapshots[snapshot] != NULL)
    {
        FREE(fmRootDebug->fmDbgSnapshots[snapshot]);
        fmRootDebug->fmDbgSnapshots[snapshot] = NULL;
        FM_LOG_PRINT("Snapshot %d deleted\n", snapshot);
    }
    else
    {
        FM_LOG_PRINT("Snapshot %d was unused: no action taken\n", snapshot);
    }

}   /* end fmDbgDeleteChipSnapshot */
Example #5
0
/** fm10000DbgDumpPortMap
 * \ingroup intDiagPorts
 *
 * \desc            Display detailed port mapping if there exists an API
 *                  call to specific hardware. Otherwise default to
 *                  simple fmDbgDumpPortMap function.
 *
 * \param[in]       sw is the switch whose port map is to be displayed.
 *
 * \param[in]       port is the port number to be displayed. If the port
 *                  value is out of its range, then the entire range will
 *                  be displayed.
 *
 * \param[in]       portType indicates which type port parameter refers to:
 *                  0 - logical port.
 *                  1 - physical port.
 *                  2 - epl port.
 *
 * \return          FM_OK if successful
 * \return          FM_ERR_INVALID_PORT if port is invalid
 *
 *****************************************************************************/
fm_status fm10000DbgDumpPortMap(fm_int sw, fm_int port, fm_int portType)
{
    fm_int     logPort;
    fm_int     physPort;
    fm_int     cpi;
    fm_int     filterPhysPort = -1;
    fm_int     filterEpl      = -1;
    fm_status  err            = FM_OK;
    fm_switch *switchPtr      = GET_SWITCH_PTR(sw);

    FM_LOG_PRINT("LogPort PhysPort FabricPort EPL/PEP Lane SERDES SBUS        Type      polarity\n");

    switch (portType)
    {
        case FM_PORT_DUMP_TYPE_PHYSICAL:
            filterPhysPort = port;
            break;

        case FM_PORT_DUMP_TYPE_EPL:
            filterEpl = port;
            break;

        default:
            break;
    }   /* end switch (portType) */


    for (cpi = 0 ; cpi < switchPtr->numCardinalPorts ; cpi++)
    {
        fmMapCardinalPort(sw, cpi, &logPort, &physPort);
        if ((port != -1) && (logPort != port) &&
            (filterPhysPort == -1) && (filterEpl == -1))
        {
            continue;
        }

        err = fm10000DbgDumpLogicalPortMapping(sw,
                                               logPort,
                                               filterPhysPort,
                                               filterEpl);
    }

    return err;

}   /* end fm10000DbgDumpPortMap */
Example #6
0
/** fm10000DbgDumpSerDes
 * \ingroup intSerdes
 *
 * \desc            Dump debug info for a given SERDES.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[in]       serDes is the SERDES number.
 *
 * \param[in]       cmd is the command to execude..
 *
 * \return          FM_OK if successful.
 * \return          Other ''Status Codes'' as appropriate in case of failure.
 *
 *****************************************************************************/
fm_status fm10000DbgDumpSerDes(fm_int  sw,
                               fm_int  serDes,
                               fm_text cmd)
{
    fm_status        err;
    fm10000_serdes  *serdesPtr;
    fm10000_switch  *switchExt;


    switchExt = GET_SWITCH_EXT(sw);
    serdesPtr = &switchExt->serdesXServices;

    err = FM_ERR_UNSUPPORTED;

    if (cmd == NULL)
    {
        err =  FM_ERR_INVALID_ARGUMENT;
    }
    else if (serdesPtr->magicNumber != FM10000_SERDES_STRUCT_MAGIG_NUMBER)
    {

        err = FM_ERR_UNINITIALIZED;
    }
    else if (STR_EQ(cmd, "status"))
    {
        if (serdesPtr->dbgDumpStatus == NULL)
        {
            return FM_ERR_UNSUPPORTED;
        }
        err = serdesPtr->dbgDumpStatus(sw,serDes);
    }
    else if (STR_EQ(cmd, "imageVersion"))
    {
        if (serdesPtr->dbgDumpSpicoSbmVersions == NULL)
        {
            return FM_ERR_UNSUPPORTED;
        }
        err = serdesPtr->dbgDumpSpicoSbmVersions(sw,serDes);
    }
    else if (STR_EQ(cmd, "serdesRegs"))
    {
        if (serdesPtr->dbgDumpRegisters == NULL)
        {
            return FM_ERR_UNSUPPORTED;
        }
        err = serdesPtr->dbgDumpRegisters(sw,serDes);
    }
    else if (STR_EQ(cmd, "krStatus"))
    {
        if (serdesPtr->dbgDumpKrStatus == NULL)
        {
            return FM_ERR_UNSUPPORTED;
        }
        err = serdesPtr->dbgDumpKrStatus(sw,serDes);
    }
    else if (STR_EQ(cmd, "dfeStatus"))
    {
        if (serdesPtr->dbgDumpDfeStatus == NULL)
        {
            return FM_ERR_UNSUPPORTED;
        }
        err = serdesPtr->dbgDumpDfeStatus(sw,serDes, FALSE);
    }
    else if (STR_EQ(cmd, "dfeStatusDetailed"))
    {
        if (serdesPtr->dbgDumpDfeStatus == NULL)
        {
            return FM_ERR_UNSUPPORTED;
        }
        err = serdesPtr->dbgDumpDfeStatus(sw,serDes, TRUE);
    }
    else if (STR_EQ(cmd, "resetStats"))
    {
        if (serdesPtr->dbgResetStats == NULL)
        {
            return FM_ERR_UNSUPPORTED;
        }
        err = serdesPtr->dbgResetStats(sw,serDes);
    }
    else
    {
        err = FM_ERR_INVALID_ARGUMENT;
        FM_LOG_PRINT("Valid serdes dump commands:\n"
                    "    status, imageVersion, serdesRegs, krStatus, and dfeStatus\n");
    }

    return err;

}
Example #7
0
/* fmPlatformCfgDump
 * \ingroup intPlatform
 *
 * \desc            Dump platform configuration.
 *
 * \return          NONE.
 *
 *****************************************************************************/
void fmPlatformCfgDump(void)
{
    fm_platformCfg *      platCfg;
    fm_platformCfgLib *   libCfg;
    fm_platformCfgPort *  portCfg;
    fm_platformCfgLane *  laneCfg;
    fm_platformCfgSwitch *swCfg;
    fm_platformCfgPhy *   phyCfg;
    fm_gn2412LaneCfg *    phyLaneCfg;
    fm_int                swIdx;
    fm_int                portIdx;
    fm_int                epl;
    fm_int                lane;
    fm_int                phyIdx;
    fm_char               tmpStr[MAX_BUF_SIZE+1];

    platCfg = FM_PLAT_GET_CFG;
    PRINT_VALUE("debug", platCfg->debug);
    PRINT_VALUE("numSwitches", FM_PLAT_NUM_SW);
    PRINT_STRING("platformName", platCfg->name);
    PRINT_STRING("fileLockName", platCfg->fileLockName);

#ifdef FM_SUPPORT_SWAG
    PRINT_STRING("topology",
                 GetStrMap( platCfg->topology,
                            swagTopology,
                            FM_NENTRIES(swagTopology),
                            FALSE,
                            tmpStr,
                            sizeof(tmpStr) ) );
#endif

    for (swIdx = 0 ; swIdx < FM_PLAT_NUM_SW ; swIdx++)
    {
        /* Logical switch is the same as swIdx */
        FM_LOG_PRINT("################################ SW#%d ################################\n", swIdx);
        swCfg = FM_PLAT_GET_SWITCH_CFG(swIdx);
        PRINT_VALUE(" swIdx", swCfg->swIdx);
        PRINT_VALUE(" switchNumber", swCfg->swNum);
        PRINT_VALUE(" numPorts", swCfg->numPorts);
        PRINT_VALUE(" maxLogicalPortValue", swCfg->maxLogicalPortValue);
        PRINT_VALUE(" ledPollPeriodMsec", swCfg->ledPollPeriodMsec);
        PRINT_STRING("  ledBlinkMode",
                     GetStrMap( swCfg->ledBlinkMode,
                                ledBlinkModeMap,
                                FM_NENTRIES(ledBlinkModeMap),
                                FALSE,
                                tmpStr,
                                sizeof(tmpStr) ) );
        PRINT_VALUE(" xcvrPollPeriodMsec", swCfg->xcvrPollPeriodMsec);
        PRINT_VALUE(" intrPollPeriodMsec", swCfg->intrPollPeriodMsec);
        PRINT_STRING(" uioDevName", swCfg->uioDevName);
        PRINT_STRING(" netDevName", swCfg->netDevName);
        PRINT_STRING(" devMemOffset", swCfg->devMemOffset);
        PRINT_VALUE(" gpioPortIntr", swCfg->gpioPortIntr);
        PRINT_VALUE(" gpioI2cReset", swCfg->gpioI2cReset);
        PRINT_VALUE(" gpioFlashWP", swCfg->gpioFlashWP);
        PRINT_VALUE(" enablePhyDeEmphasis", swCfg->enablePhyDeEmphasis);
        PRINT_VALUE(" vrm.useDefVoltages", swCfg->vrm.useDefVoltages);
        PRINT_VALUE(" VDDS.hwResourceId",
                swCfg->vrm.hwResourceId[FM_PLAT_VRM_VDDS]);
        PRINT_VALUE(" VDDF.hwResourceId",
                swCfg->vrm.hwResourceId[FM_PLAT_VRM_VDDF]);
        PRINT_VALUE(" AVDD.hwResourceId",
                swCfg->vrm.hwResourceId[FM_PLAT_VRM_AVDD]);
        PRINT_VALUE(" fhClock", swCfg->fhClock);
#ifdef FM_SUPPORT_SWAG
        PRINT_STRING("  switchRole",
                     GetStrMap( swCfg->switchRole,
                                swagRole,
                                FM_NENTRIES(swagRole),
                                FALSE,
                                tmpStr,
                                sizeof(tmpStr) ) );
#endif

        for (portIdx = 0 ; portIdx < FM_PLAT_NUM_PORT(swIdx) ; portIdx++)
        {
            portCfg = FM_PLAT_GET_PORT_CFG(swIdx, portIdx);
            FM_LOG_PRINT("==============Port Index %d============\n", portIdx);
            PRINT_VALUE("  logicalPort", portCfg->port);
            PRINT_VALUE("  hwResourceId", portCfg->hwResourceId);
            PRINT_VALUE("  physPort", portCfg->physPort);
            PRINT_VALUE("  epl", portCfg->epl);
            PRINT_VALUE("  lane[0]", portCfg->lane[0]);
            PRINT_VALUE("  lane[1]", portCfg->lane[1]);
            PRINT_VALUE("  lane[2]", portCfg->lane[2]);
            PRINT_VALUE("  lane[3]", portCfg->lane[3]);
            PRINT_VALUE("  pep", portCfg->pep);
            PRINT_VALUE("  tunnel", portCfg->tunnel);
            PRINT_VALUE("  loopback", portCfg->loopback);
            PRINT_VALUE("  speed", portCfg->speed);
            PRINT_VALUE("  autodetect", portCfg->autodetect);
            PRINT_STRING( "  ethMode",
                         GetStrMap( portCfg->ethMode,
                                    ethModeMap,
                                    FM_NENTRIES(ethModeMap),
                                    TRUE,
                                    tmpStr,
                                    sizeof(tmpStr) ) );
            PRINT_STRING( "  portType",
                         GetStrMap( portCfg->portType,
                                    portTypeMap,
                                    FM_NENTRIES(portTypeMap),
                                    FALSE,
                                    tmpStr,
                                    sizeof(tmpStr) ) );
            PRINT_STRING( "  intfType",
                         GetStrMap( portCfg->intfType,
                                    intfTypeMap,
                                    FM_NENTRIES(intfTypeMap),
                                    FALSE,
                                    tmpStr,
                                    sizeof(tmpStr)  ) );
            PRINT_STRING( "  capability",
                         GetStrBitMap( portCfg->cap,
                                       portCapMap,
                                       FM_NENTRIES(portCapMap),
                                       tmpStr,
                                       sizeof(tmpStr) ) );
            PRINT_STRING("  dfeMode",
                         GetStrMap(portCfg->dfeMode, 
                                   dfeModeMap, 
                                   FM_NENTRIES(dfeModeMap), 
                                   FALSE,
                                   tmpStr,
                                   sizeof(tmpStr) ) );
            PRINT_STRING( "  an73Ability",
                         GetStrBitMap( portCfg->an73Ability,
                                       an73AbilityMap,
                                       FM_NENTRIES(an73AbilityMap),
                                       tmpStr,
                                       sizeof(tmpStr) ) );
            PRINT_VALUE("  phyNum", portCfg->phyNum);
            PRINT_VALUE("  phyPort", portCfg->phyPort);

#ifdef FM_SUPPORT_SWAG
            PRINT_STRING("   swagLinkType",
                         GetStrMap( portCfg->swagLink.type,
                                    swagLinkType,
                                    FM_NENTRIES(swagLinkType),
                                    FALSE,
                                    tmpStr,
                                    sizeof(tmpStr) ) );
            if (portCfg->swagLink.type == FM_SWAG_LINK_INTERNAL)
            {
                FM_LOG_PRINT("   SWAG port %d <--> SWAG port %d\n",
                             portCfg->swagLink.logicalPort, portCfg->swagLink.partnerLogicalPort);
                FM_LOG_PRINT("   SW %d, port %d <--> SW %d, port %d\n",
                             portCfg->swagLink.swId, portCfg->swagLink.swPort,
                             portCfg->swagLink.partnerSwitch, portCfg->swagLink.partnerPort);
            }
            else if (portCfg->swagLink.type == FM_SWAG_LINK_EXTERNAL)
            {
                FM_LOG_PRINT("   SWAG port %d, SW %d, port %d\n",
                             portCfg->swagLink.logicalPort,
                             portCfg->swagLink.swId, portCfg->swagLink.swPort);
            }
#endif
            FM_LOG_PRINT("\n");
        }

        for (epl = 0 ; epl < FM_PLAT_NUM_EPL ; epl++)
        {
            FM_LOG_PRINT("#######################################\n");
            FM_LOG_PRINT("#                EPL %d                #\n", epl);
            FM_LOG_PRINT("#######################################\n");
            PRINT_VALUE("  laneToPortIdx[0]", swCfg->epls[epl].laneToPortIdx[0]);
            PRINT_VALUE("  laneToPortIdx[1]", swCfg->epls[epl].laneToPortIdx[1]);
            PRINT_VALUE("  laneToPortIdx[2]", swCfg->epls[epl].laneToPortIdx[2]);
            PRINT_VALUE("  laneToPortIdx[3]", swCfg->epls[epl].laneToPortIdx[3]);


            for (lane = 0 ; lane < FM_PLAT_LANES_PER_EPL ; lane++)
            {
                FM_LOG_PRINT("============ EPL %d, lane %d ============\n", epl, lane);
                laneCfg = &swCfg->epls[epl].lane[lane];
                PRINT_STRING("  lanePolarity",
                             GetStrMap(laneCfg->lanePolarity, 
                                       lanePolarityMap, 
                                       FM_NENTRIES(lanePolarityMap), 
                                       FALSE,
                                    tmpStr,
                                    sizeof(tmpStr)));
                PRINT_STRING("  rxTermination",
                             GetStrMap(laneCfg->rxTermination, 
                                       rxTerminationMap, 
                                       FM_NENTRIES(rxTerminationMap), 
                                       FALSE,
                                    tmpStr,
                                    sizeof(tmpStr)));
                PRINT_VALUE("  preCursor1GCopper", 
                            laneCfg->copper[BPS_1G].preCursor);
                PRINT_VALUE("  preCursor10GCopper", 
                            laneCfg->copper[BPS_10G].preCursor);
                PRINT_VALUE("  preCursor25GCopper", 
                            laneCfg->copper[BPS_25G].preCursor);
                PRINT_VALUE("  preCursor1GOptical",
                            laneCfg->optical[BPS_1G].preCursor);
                PRINT_VALUE("  preCursor10GOptical",
                            laneCfg->optical[BPS_10G].preCursor);
                PRINT_VALUE("  preCursor25GOptical",
                            laneCfg->optical[BPS_25G].preCursor);

                PRINT_VALUE("  cursor1GCopper",
                            laneCfg->copper[BPS_1G].cursor);
                PRINT_VALUE("  cursor10GCopper",
                            laneCfg->copper[BPS_10G].cursor);
                PRINT_VALUE("  cursor25GCopper",
                            laneCfg->copper[BPS_25G].cursor);
                PRINT_VALUE("  cursor1GOptical",
                            laneCfg->optical[BPS_1G].cursor);
                PRINT_VALUE("  cursor10GOptical",
                            laneCfg->optical[BPS_10G].cursor);
                PRINT_VALUE("  cursor25GOptical",
                            laneCfg->optical[BPS_25G].cursor);

                PRINT_VALUE("  postCursor1GCopper",
                            laneCfg->copper[BPS_1G].postCursor);
                PRINT_VALUE("  postCursor10GCopper",
                            laneCfg->copper[BPS_10G].postCursor);
                PRINT_VALUE("  postCursor25GCopper",
                            laneCfg->copper[BPS_25G].postCursor);
                PRINT_VALUE("  postCursor1GOptical",
                            laneCfg->optical[BPS_1G].postCursor);
                PRINT_VALUE("  postCursor10GOptical",
                            laneCfg->optical[BPS_10G].postCursor);
                PRINT_VALUE("  postCursor25GOptical",
                            laneCfg->optical[BPS_25G].postCursor);

                FM_LOG_PRINT("\n");
            }
            FM_LOG_PRINT("\n");
        }

        for ( phyIdx = 0 ; phyIdx < FM_PLAT_NUM_PHY(swIdx) ; phyIdx++ )
        {
            phyCfg = FM_PLAT_GET_PHY_CFG(swIdx, phyIdx);
            FM_LOG_PRINT("==============PHY Index %d============\n", phyIdx);

            PRINT_STRING("  model",
                         GetStrMap( phyCfg->model,
                                    phyModelMap,
                                    FM_NENTRIES(phyModelMap),
                                    FALSE,
                                    tmpStr,
                                    sizeof(tmpStr) ) );
            PRINT_VALUE("  addr", phyCfg->addr);
            PRINT_VALUE("  hwResourceId", phyCfg->hwResourceId);

            if ( phyCfg->model == FM_PLAT_PHY_GN2412 )
            {
                for ( lane = 0 ; lane < FM_GN2412_NUM_LANES ; lane++ )
                {
                    phyLaneCfg = &phyCfg->gn2412Lane[lane];
                    FM_LOG_PRINT("    ======== GN2412 %d, lane %d ========\n", 
                                 phyIdx, 
                                 lane);

                    PRINT_VALUE("  appMode", phyLaneCfg->appMode);
                    PRINT_VALUE("  polarity", phyLaneCfg->polarity);
                    PRINT_VALUE("  preTap", phyLaneCfg->preTap);
                    PRINT_VALUE("  attenuation", phyLaneCfg->attenuation);
                    PRINT_VALUE("  postTap", phyLaneCfg->postTap);
                }
            }

            FM_LOG_PRINT("\n");
        }

        FM_LOG_PRINT(" Shared Library Config:\n");
        libCfg = FM_PLAT_GET_LIBS_CFG(swIdx);
        PRINT_STRING("  sharedLibraryName", libCfg->libName);
        PRINT_STRING("  disableFuncIntf",
                     GetStrBitMap( libCfg->disableFuncIntf,
                                   disableFuncIntfMap,
                                   FM_NENTRIES(disableFuncIntfMap),
                                   tmpStr,
                                   sizeof(tmpStr) )  );
        PRINT_VALUE("  tlvCfgBufSize", libCfg->tlvCfgBufSize);
        PRINT_VALUE("  tlvCfgLen", libCfg->tlvCfgLen);

        FM_LOG_PRINT("#######################################################################\n\n");
    }

    return;

}   /* end fmPlatformCfgDump */
Example #8
0
/** fmDbgDumpParityErrorEvent
 * \ingroup intParity
 *
 * \desc            Dumps a parity error event structure.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[in]       parityEvent points to the parity event object.
 *
 * \return          None
 *
 *****************************************************************************/
void fmDbgDumpParityErrorEvent(fm_int                sw,
                               fm_eventParityError * parityEvent)
{
    fm_int  i;

    FM_LOG_PRINT("\nParity event on switch %d:\n", sw);

    FM_LOG_PRINT("  Error Type  : %s\n",
                 fmParityErrTypeToText(parityEvent->errType));

    FM_LOG_PRINT("  Severity    : %s\n",
                 fmParitySeverityToText(parityEvent->paritySeverity));

    FM_LOG_PRINT("  Status      : %s\n",
                 fmParityStatusToText(parityEvent->parityStatus));

    FM_LOG_PRINT("  Memory Area : %s\n",
                 fmParityMemAreaToText(parityEvent->memoryArea));

    switch ( parityEvent->errType )
    {
        case FM_PARITY_ERRTYPE_CACHE_MISMATCH:
            FM_LOG_PRINT("  Base Addr   : %08x\n", parityEvent->baseAddr);
            break;

        case FM_PARITY_ERRTYPE_SRAM_CORRECTED:
        case FM_PARITY_ERRTYPE_SRAM_UNCORRECTABLE:
            FM_LOG_PRINT("  SRAM Number : %d\n", parityEvent->sramNo);
            break;

        default:
            break;
    }

    if ( parityEvent->numIndices != 0 )
    {
        FM_LOG_PRINT("  Indices     :");
        for ( i = 0 ; i < (fm_int)parityEvent->numIndices ; i++ )
        {
            FM_LOG_PRINT(" %d", parityEvent->tableIndices[i]);
        }
        FM_LOG_PRINT("\n");
    }

    if ( parityEvent->numValidData != 0 )
    {
        FM_LOG_PRINT("  Bad Data    :");
        for ( i = (fm_int)parityEvent->numValidData - 1 ; i >= 0 ; i-- )
        {
            FM_LOG_PRINT(" %08x", parityEvent->badData[i]);
        }
        FM_LOG_PRINT("\n");

        FM_LOG_PRINT("  Good Data   :");
        for ( i = (fm_int)parityEvent->numValidData - 1 ; i >= 0 ; i-- )
        {
            FM_LOG_PRINT(" %08x", parityEvent->cachedData[i]);
        }
        FM_LOG_PRINT("\n");
    }

    if ( parityEvent->numErrors != 0 )
    {
        FM_LOG_PRINT("  Error Count : %d\n", parityEvent->numErrors);
    }

}   /* end fmDbgDumpParityErrorEvent */
Example #9
0
/** fm10000DbgDumpSFlows
 * \ingroup intSflow
 *
 * \desc            Dumps information about the SFLOW subsystem.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \return          FM_OK if successful.
 *
 *****************************************************************************/
fm_status fm10000DbgDumpSFlows(fm_int sw)
{
    fm10000_sflowEntry *sflowEntry;
    fm_int              sflowId;
    fm_text             typeText;
    fm_int              portList[48];
    fm_int              numPorts;

    VALIDATE_AND_PROTECT_SWITCH(sw);

    FM_LOG_PRINT("\n");
    FM_LOG_PRINT("Id  MirId sflowType  vlanID  ports\n");
    FM_LOG_PRINT("--  ----  ---------  ------  --------------------\n");

    for (sflowId = 0 ; sflowId < FM10000_MAX_SFLOWS ; ++sflowId)
    {
        sflowEntry = GetSflowEntry(sw, sflowId);
        if (!sflowEntry || !sflowEntry->isValid)
        {
            continue;
        }

        switch (sflowEntry->sflowType)
        {
            case FM_SFLOW_TYPE_INGRESS:
                typeText = "ingress";
                break;

            case FM_SFLOW_TYPE_EGRESS:
                typeText = "egress";
                break;

            default:
                typeText = "unknown";
                break;
        }

        FM_LOG_PRINT("%2d  %4d  %-9s  ",
                     sflowId,
                     sflowEntry->mirrorId,
                     typeText);

        if (sflowEntry->vlanID == FM_SFLOW_VLAN_ANY)
        {
            FM_LOG_PRINT("%5s   ", "ANY");
        }
        else
        {
            FM_LOG_PRINT("%5u   ",
                         sflowEntry->vlanID);
        }

        fm10000GetSFlowPortList(sw, sflowId, &numPorts, portList, 48);
        fmDbgPrintPortList(sw, numPorts, portList);
        FM_LOG_PRINT("\n");

    }   /* end for (sflowId = 0 ; sflowId < FM10000_MAX_SFLOWS ; ++sflowId) */

    UNPROTECT_SWITCH(sw);

    return FM_OK;

}   /* end fm10000DbgDumpSFlows */
Example #10
0
/** fm10000DbgDumpLogicalPortMapping
 * \ingroup intDiagPorts
 *
 * \desc            Display detailed port mapping information.
 *
 * \param[in]       sw is the switch whose port map is to be displayed.
 *
 * \param[in]       logPort is the port number to be displayed.
 *
 * \param[in]       filterPhysPort specifies only ports matching to
 *                  physical port to be displayed.
 *
 * \param[in]       filterEpl specifies only ports matching to
 *                  EPL port to be displayed.
 *
 * \return          FM_OK if successful
 *
 *****************************************************************************/
fm_status fm10000DbgDumpLogicalPortMapping(fm_int sw, fm_int logPort,
                                           fm_int filterPhysPort, fm_int filterEpl)
{
    fm10000_port   *portExt;
    fm_int         physPort;
    fm_int         fabricPort;
    fm_int         tmp;
    fm_int         eplPep;  /* EPL or PEP */
    fm_int         channel;
    fm_int         laneNum; /* As argument to port attribute function */
    fm_int         laneCount; /* Number of lanes for the port */
    fm_int         serdes;
    fm_int         ethMode;
    fm_uint32      rxPolarity;
    fm_uint32      txPolarity;
    fm_uint        sbusAddr;
    fm_serdesRing  ring;
    fm_status      status = FM_OK;
    fm_char        logPortStr[MAX_STR_LEN];
    fm_char        eplPepStr[MAX_STR_LEN];
    fm_char        serdesStr[MAX_STR_LEN];
    fm_char        fabPortStr[MAX_STR_LEN];
    fm_char        physPortStr[MAX_STR_LEN];
    fm_char        channelStr[MAX_STR_LEN];
    fm_char        sbusStr[MAX_STR_LEN];
    fm_char        modeStr[MAX_STR_LEN];
    fm_char        polarityStr[MAX_STR_LEN];


    if (!fmIsCardinalPort(sw, logPort))
    {
        /* Ignore it */
        return FM_OK;
    }

    FM_SNPRINTF_S(logPortStr, MAX_STR_LEN, "%s", "--");
    FM_SNPRINTF_S(eplPepStr, MAX_STR_LEN, "%s", "--");
    FM_SNPRINTF_S(serdesStr, MAX_STR_LEN, "%s", "--");
    FM_SNPRINTF_S(fabPortStr, MAX_STR_LEN, "%s", "--"); 
    FM_SNPRINTF_S(physPortStr, MAX_STR_LEN, "%s", "--");
    FM_SNPRINTF_S(channelStr, MAX_STR_LEN, "%s", "--");
    FM_SNPRINTF_S(sbusStr, MAX_STR_LEN, "%s", "--");
    FM_SNPRINTF_S(modeStr, MAX_STR_LEN, "%s", "----------");
    FM_SNPRINTF_S(polarityStr, MAX_STR_LEN, "%s", "----");

    status = fmPlatformMapLogicalPortToPhysical(sw, logPort, &sw, &physPort);
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_DEBUG, status);

    if (filterPhysPort > 0 && filterPhysPort != physPort)
    {
        return FM_OK;
    }
    if (status == FM_OK)
    {
        FM_SNPRINTF_S(physPortStr, MAX_STR_LEN, "%d", physPort);
    }
    FM_SNPRINTF_S(logPortStr, MAX_STR_LEN, "%d", logPort);

    status = fm10000MapPhysicalPortToEplChannel(sw, physPort, &eplPep, &channel);
    /* Could fail here */

    if (filterEpl > 0 && status && filterEpl != eplPep)
    {
        return FM_OK;
    }

    if (status)
    {
        status = fm10000MapLogicalPortToPep(sw, logPort, &eplPep);
    }
    if (status == FM_OK)
    {
        FM_SNPRINTF_S(eplPepStr, MAX_STR_LEN, "%d", eplPep);
    }
    else
    {
        eplPep = -1;
    }

    status = fm10000MapPhysicalPortToFabricPort(sw, physPort, &fabricPort);
    if (status == FM_OK)
    {
        FM_SNPRINTF_S(fabPortStr, MAX_STR_LEN, "%d", fabricPort);
    }

    status = fm10000GetNumLanes(sw, logPort, &laneCount);
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_DEBUG, status);

    status = fm10000GetPortAttribute(sw,
                                    logPort,
                                    FM_PORT_ACTIVE_MAC,
                                    FM_PORT_LANE_NA,
                                    FM_PORT_ETHERNET_INTERFACE_MODE,
                                    &ethMode);
    if (status != FM_OK)
    {
        ethMode = FM_ETH_MODE_DISABLED;
    }
    status = fm10000GetPortModeName(sw, logPort, modeStr, MAX_STR_LEN);
    FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_DEBUG, status);

    for (laneNum = 0; laneNum < laneCount; laneNum++)
    {
        if (eplPep >= 0)
        {
            status = fm10000MapPortLaneToSerdes(sw, logPort, laneNum, &serdes);
            if (status == FM_OK)
            {
                FM_SNPRINTF_S(serdesStr, MAX_STR_LEN, "%d", serdes);
                status = fm10000MapSerdesToSbus(sw, serdes, &sbusAddr, &ring);
                if (status == FM_OK)
                {
                    FM_SNPRINTF_S(sbusStr, MAX_STR_LEN, "%02x", sbusAddr);
                }
                status = fm10000MapSerdesToEplLane(sw, serdes, &tmp, &channel);
                if (status == FM_OK)
                {
                    FM_SNPRINTF_S(channelStr, MAX_STR_LEN, "%d", channel);
                }
            }

            status = fm10000GetPortAttribute(sw,
                                            logPort,
                                            FM_PORT_ACTIVE_MAC,
                                            laneNum,
                                            FM_PORT_RX_LANE_POLARITY,
                                            &rxPolarity);

            status = fm10000GetPortAttribute(sw,
                                            logPort,
                                            FM_PORT_ACTIVE_MAC,
                                            laneNum,
                                            FM_PORT_TX_LANE_POLARITY,
                                            &txPolarity);

            if (rxPolarity && txPolarity)
            {
                FM_SNPRINTF_S(polarityStr, MAX_STR_LEN, "%s", "RXTX");
            }
            else if (rxPolarity)
            {
                FM_SNPRINTF_S(polarityStr, MAX_STR_LEN, "%s", "RX");
            }
            else if (txPolarity)
            {
                FM_SNPRINTF_S(polarityStr, MAX_STR_LEN, "%s", "TX");
            }
            else
            {
                FM_SNPRINTF_S(polarityStr, MAX_STR_LEN, "%s", "NONE");;
            }
        }

        portExt = GET_PORT_EXT(sw, logPort);

        if (laneCount > 1)
        {
            FM_SNPRINTF_S(logPortStr, MAX_STR_LEN, "%d.%d", logPort, laneNum);
            if (laneNum > 0)
            {
                /* Not applicable for lane > 0 */
                FM_SNPRINTF_S(eplPepStr, MAX_STR_LEN, "%s", "--");
                FM_SNPRINTF_S(fabPortStr, MAX_STR_LEN, "%s", "--"); 
                FM_SNPRINTF_S(physPortStr, MAX_STR_LEN, "%s", "--");
                FM_SNPRINTF_S(modeStr, MAX_STR_LEN, "%s", "----------");
            }
        }

        FM_LOG_PRINT("%-4s %8s %8s %8s %7s %5s %5s %15s %8s\n",
                     logPortStr,
                     physPortStr,
                     fabPortStr,
                     eplPepStr,
                     channelStr,
                     serdesStr,
                     sbusStr,
                     modeStr,
                     polarityStr);
    }

    return FM_OK;

ABORT:
    return status;

}   /* end fm10000DbgDumpLogicalPortMapping */
Example #11
0
/** fm10000DbgDumpMACTableEntry
 * \ingroup intDiagMATable
 *
 * \desc            Display a specific entry in the switch's MAC Address Table
 *                  and the memory-based copy of the table entry.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[in]       address is the MAC address of the entry to display.
 *
 * \param[in]       vlan is the VLAN ID of the entry to display.
 *
 * \return          None.
 *
 *****************************************************************************/
void fm10000DbgDumpMACTableEntry(fm_int sw, fm_macaddr address, fm_uint16 vlan)
{
    fm_internalMacAddrEntry cacheEntry;
    fm10000_maTableEntry    dmacEntry;
    fm10000_maTableEntry    smacEntry;
    fm_switch *             switchPtr;
    fm_uint16               indexes[FM10000_MAC_ADDR_BANK_COUNT];
    fm_uint32               hashIndex;
    fm_status               status;
    fm_int                  bankId;
    fm_uint16               learningFID;
    fm_bool                 found;

    switchPtr = GET_SWITCH_PTR(sw);

    FM_LOG_PRINT("\n");

    status = fm10000GetLearningFID(sw, vlan, &learningFID);
    if (status != FM_OK)
    {
        return;
    }

    status = fm10000ComputeAddressIndex(sw,
                                        address,
                                        learningFID,
                                        0,
                                        indexes);
    if (status != FM_OK)
    {
        return;
    }

    found = FALSE;

    for (bankId = switchPtr->macTableBankCount - 1 ; bankId >= 0 ; bankId--)
    {
        hashIndex = indexes[bankId];
        FM_TAKE_L2_LOCK(sw);
        cacheEntry = switchPtr->maTable[hashIndex];
        FM_DROP_L2_LOCK(sw);

        if ( (cacheEntry.state != FM_MAC_ENTRY_STATE_INVALID) &&
             (cacheEntry.macAddress == address) &&
             (cacheEntry.vlanID == learningFID) )
        {
            /* Found the requested entry. */
            found = TRUE;
            break;
        }
    }

    if (found)
    {
        status = ReadMacTableEntries(sw, hashIndex, &dmacEntry, &smacEntry);
        if (status == FM_OK)
        {
            DumpMacTableEntry(hashIndex, &cacheEntry, &dmacEntry, &smacEntry);
        }
    }
    else
    {
        FM_LOG_PRINT("Entry not found for macAddress %012llx vlan %u (fid %u).\n",
                     address,
                     vlan,
                     learningFID);
    }
    

}   /* end fm10000DbgDumpMACTableEntry */
Example #12
0
/** fm10000DbgDumpMACTable
 * \ingroup intDiagMATable
 *
 * \desc            Display a given number of entries or count the number of
 *                  entries in the switch's MAC Address Table and the
 *                  memory-based copy of the table.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \param[in]       numEntries is the number of entries to display.  Specify
 *                  0 for the first 10 entries only.  Specify -1 to just count
 *                  the number of entries in the table without displaying them.
 *
 * \return          None.
 *
 *****************************************************************************/
void fm10000DbgDumpMACTable(fm_int sw, fm_int numEntries)
{
    fm_switch *             switchPtr;
    fm_internalMacAddrEntry cacheEntry;
    fm10000_maTableEntry    dmacEntry;
    fm10000_maTableEntry    smacEntry;
    fm_status               status;
    fm_int                  index;
    fm_int                  entriesReported;
    fm_bool                 countOnly;

    switchPtr = GET_SWITCH_PTR(sw);

    entriesReported = 0;
    countOnly = FALSE;

    if (numEntries < 0)
    {
        countOnly  = TRUE;
        numEntries = switchPtr->macTableSize;
    }
    else if (numEntries == 0)
    {
        numEntries = 10;
    }

    for (index = 0 ; index < switchPtr->macTableSize ; ++index)
    {
        /* Get cache entry. */
        FM_TAKE_L2_LOCK(sw);
        cacheEntry = switchPtr->maTable[index];
        FM_DROP_L2_LOCK(sw);

        /* Retrieve MAC table entries. */
        status = ReadMacTableEntries(sw, index, &dmacEntry, &smacEntry);
        if (status != FM_OK)
        {
            return;
        }

        if (dmacEntry.valid ||
            smacEntry.valid ||
            cacheEntry.state != FM_MAC_ENTRY_STATE_INVALID)
        {
            if (!countOnly)
            {
                DumpMacTableEntry(index, &cacheEntry, &dmacEntry, &smacEntry);
            }

            if (++entriesReported >= numEntries)
            {
                break;
            }

        }   /* end if (dmacEntry.valid) */

    }   /* end for (index = 0 ; index < switchPtr->macTableSize ; ++index) */

    FM_LOG_PRINT("%d %s %s\n",
                 entriesReported,
                 (entriesReported == 1) ? "entry" : "entries",
                 (countOnly) ? "in table" : "listed");

}   /* end fm10000DbgDumpMACTable */
Example #13
0
/** DumpMacTableEntry
 * \ingroup intDiagMATable
 *
 * \desc            Output an MA Table entry as it appears in hardware and
 *                  in the memory-based cache.
 *
 * \param[in]       index is the index into the MA Table.
 *
 * \param[in]       cacheEntry points to a copy of the memory-based cache
 *                  entry.
 *
 * \param[in]       dmacEntry points to a structure containing the decoded
 *                  destination MAC table entry.
 *
 * \param[in]       smacEntry points to a structure containing the decoded
 *                  source MAC table entry.
 *
 * \return          None.
 *
 *****************************************************************************/
static void DumpMacTableEntry(fm_int                    index,
                              fm_internalMacAddrEntry * cacheEntry,
                              fm10000_maTableEntry *    dmacEntry,
                              fm10000_maTableEntry *    smacEntry)
{
    char dmacVal[32];
    char smacVal[32];
    char cacheVal[32];
    
    FM_LOG_PRINT("MA_TABLE[%d]:\n\n", index);

#define HDR_FMT  "%-14s   %-18s %-18s %s\n"
#define STR_FMT  "%-14s : %-18s %-18s %s\n"
#define DEC_FMT  "%-14s : %-18d %-18d %d\n"
#define FILL_VAL "--"

    FM_LOG_PRINT(HDR_FMT,
                 "",
                 "CACHE ENTRY",
                 "DMAC ENTRY",
                 "SMAC ENTRY");

    FM_LOG_PRINT(STR_FMT,
                 "State",
                 fmEntryStateToText(cacheEntry->state),
                 (dmacEntry->valid) ? "Valid" : "Invalid",
                 (smacEntry->valid) ? "Valid" : "Invalid");

    FM_SNPRINTF_S(cacheVal, sizeof(cacheVal), "%012llx", cacheEntry->macAddress);
    FM_SNPRINTF_S(dmacVal,  sizeof(dmacVal),  "%012llx", dmacEntry->macAddress);
    FM_SNPRINTF_S(smacVal,  sizeof(smacVal),  "%012llx", smacEntry->macAddress);

    FM_LOG_PRINT(STR_FMT,
                 "MAC Address",
                 cacheVal,
                 dmacVal,
                 smacVal);

    FM_LOG_PRINT(DEC_FMT,
                 "FID",
                 cacheEntry->vlanID,
                 dmacEntry->fid,
                 smacEntry->fid);

    FM_LOG_PRINT(STR_FMT,
                 "Address Type",
                 fmAddressTypeToText(cacheEntry->addrType),
                 FILL_VAL,
                 FILL_VAL);

    FM_SNPRINTF_S(cacheVal, sizeof(cacheVal), "%s", FILL_VAL);
    FM_SNPRINTF_S(dmacVal,  sizeof(dmacVal),  "0x%04x", dmacEntry->glort);
    FM_SNPRINTF_S(smacVal,  sizeof(smacVal),  "0x%04x", smacEntry->glort);

    FM_LOG_PRINT(STR_FMT,
                 "Glort",
                 cacheVal,
                 dmacVal,
                 smacVal);

    FM_LOG_PRINT(DEC_FMT,
                 "Port",
                 cacheEntry->port,
                 dmacEntry->port,
                 smacEntry->port);

    FM_LOG_PRINT(DEC_FMT,
                 "Trigger",
                 cacheEntry->trigger,
                 dmacEntry->trigger,
                 smacEntry->trigger);

    FM_LOG_PRINT(STR_FMT,
                 "Secure",
                 FM_BOOLSTRING(FM_IS_ADDR_TYPE_SECURE(cacheEntry->addrType)),
                 FM_BOOLSTRING(dmacEntry->secure),
                 FM_BOOLSTRING(smacEntry->secure));

    FM_LOG_PRINT("\n");

}   /* end DumpMacTableEntry */
Example #14
0
/* _fmPlatformFm10000I2cWriteRead
 * \ingroup intPlatformfm10000I2c
 *
 * \desc            Write to then immediately read from an I2C device with
 *                  handling max response bytes using switch as I2C master.
 *
 * \param[in]       handle is the memory pointer to the switch.
 *
 * \param[in]       device is the I2C device address (0x00 - 0x7F).
 *
 * \param[in,out]   data points to an array from which data is written and
 *                  into which data is read.
 *
 * \param[in]       wl is the number of bytes to write.
 *
 * \param[in]       rl is the number of bytes to read.
 *
 * \return          FM_OK if successful.
 * \return          Other ''Status Codes'' as appropriate in case of
 *                  failure.
 *
 *****************************************************************************/
static fm_status _fmPlatformFm10000I2cWriteRead(fm_uintptr handle,
                                                fm_uint    device,
                                                fm_byte   *data,
                                                fm_uint    wl,
                                                fm_uint    rl)
{
    fm_status      status;
    fm_uint32      regValue;
    fm_uint        i;
    fm_uint        j;
    fm_bool        isTimeout;
    struct timeval startTime;
    fm_uint32     *memPtr;
    fm_uint32      tmp;

    if (i2cDebug & 0x4) 
    {
        FM_LOG_PRINT("fmPlatformfm10000I2cWriteRead "
                     "handle=%p device=0x%x wl=%d rl=%d\n",
                      (void*)handle, device, wl, rl);
    }

    memPtr = (fm_uint32*)handle;

    if (rl > I2C_MAX_LEN)
    {
        FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_INVALID_ARGUMENT);
    }

    if (wl > I2C_MAX_LEN)
    {
        FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_INVALID_ARGUMENT);
    }

    if (data == NULL)
    {
        FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_INVALID_ARGUMENT);
    }

    for (i = 0 ; i < (wl+3)/4 ; i++)
    {
        regValue = 0;
        for (j = 0 ; j < 4 ; j++)
        {
            if ((i*4 + j) < wl)
            {
                regValue |= (data[i*4 + j] << ((3 - j)*8));
            }
        }
        status = WriteSwitchMemMap(memPtr, FM10000_I2C_DATA(i), regValue);
        FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_PLATFORM, status);
        if (i2cDebug & 0x4)
        {
            FM_LOG_PRINT("WRITEDATA#%d : 0x%08x\n",i, regValue); 
        }
    }

    regValue = 0;
    FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Addr, (device  << 1));
    FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 0);
    FM_SET_FIELD(regValue, FM10000_I2C_CTRL, LengthW, wl);
    FM_SET_FIELD(regValue, FM10000_I2C_CTRL, LengthR, rl);

    if (i2cDebug & 0x4)
    {
         FM_LOG_PRINT("WRITE: eg 0x%08x Cmd %d wl %d rl %d "
                      "Comp %x LenSent %d intr %d\n",
                      regValue,
                      FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command),
                      FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW),
                      FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR),
                      FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
                      FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent),
                      FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));
    }

    status = WriteSwitchMemMap(memPtr, FM10000_I2C_CTRL, regValue);
    FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_PLATFORM, status);

    status = ReadSwitchMemMap(memPtr, FM10000_I2C_CTRL, &tmp);
    FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_PLATFORM, status);
    if (i2cDebug & 0x4)
    {
        FM_LOG_PRINT("READ: %d reg 0x%08x Cmd %d wl %d rl %d "
                     "Comp %x LenSent %d intr %d\n", status, tmp,
                     FM_GET_FIELD(tmp, FM10000_I2C_CTRL, Command),
                     FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthW),
                     FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthR),
                     FM_GET_FIELD(tmp, FM10000_I2C_CTRL, CommandCompleted),
                     FM_GET_FIELD(tmp, FM10000_I2C_CTRL, LengthSent),
                     FM_GET_BIT(tmp, FM10000_I2C_CTRL, InterruptPending));
    }

    /* Now change command to start the transaction */
    if (rl == 0) 
    {
        /* Write only allow write of 0 length */
        FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 1);
    }
    else if ((wl > 0) && (rl > 0))
    {
        /* Write Read */
        FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 2);
    }
    else
    {
        /* Read */
        FM_SET_FIELD(regValue, FM10000_I2C_CTRL, Command, 3);
    }

    if (i2cDebug & 0x4) 
    {
        FM_LOG_PRINT("WRITE2: reg 0x%08x Cmd %d wl %d rl %d "
                     "Comp %x LenSent %d intr %d\n", regValue,
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command),
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW),
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR),
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent),
                     FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));
    }

    status = WriteSwitchMemMap(memPtr, FM10000_I2C_CTRL, regValue);
    FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_PLATFORM, status);

    status = ReadSwitchMemMap(memPtr, FM10000_I2C_CTRL, &regValue);
    FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_PLATFORM, status);
    if (i2cDebug & 0x4) 
    {
        FM_LOG_PRINT("READ2: %d reg 0x%08x Cmd %d wl %d rl %d "
                     "Comp %x LenSent %d intr %d\n", status, regValue,
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command),
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW),
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR),
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
                     FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent),
                     FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));
    }

    /* Poll to check for command done */
    gettimeofday(&startTime, NULL);
    isTimeout = FALSE;
    do
    {
        usleep(10000);
        if (isTimeout)
        {
            FM_LOG_ERROR(
                   FM_LOG_CAT_PLATFORM, 
                   "Dev=0x%02x: Timeout (%d msec) waiting "
                   "for I2C_CTRL(0x%x).CommandCompleted!=0. 0x%02x\n",
                   device,
                   I2C_TIMEOUT,
                   FM10000_I2C_CTRL, 
                   FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted));

            FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_I2C_NO_RESPONSE);
        }

        /* Variable isTimeout is used to improve the timeout detecting */
        if (GetTimeIntervalMsec(&startTime, NULL) > I2C_TIMEOUT)
        {
            isTimeout = TRUE;
        }

        status = ReadSwitchMemMap(memPtr, FM10000_I2C_CTRL, &regValue);
        if (i2cDebug & 0x4)
        {
            FM_LOG_PRINT(
                   "STATUS: %d reg 0x%08x cmd %d wl %d rl %d "
                   "Comp %x LenSent %d intr %d\n", status, regValue,
                   FM_GET_FIELD(regValue, FM10000_I2C_CTRL, Command),
                   FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthW),
                   FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthR),
                   FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
                   FM_GET_FIELD(regValue, FM10000_I2C_CTRL, LengthSent),
                   FM_GET_BIT(regValue, FM10000_I2C_CTRL, InterruptPending));
        }

        if (status) break;

    } while (FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted) == 0);

    if (FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted) != 1)
    {
        if (FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted) == 3)
        {
            if (i2cDebug & 0x4)
            {
                FM_LOG_PRINT("No ACK received for address 0x%02x\n", device);
            }
        }
        else
        {
            FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
                         "Dev=0x%02x: I2C Command completed with error 0x%x. "
                         "I2C_CTRL(0x%x)=0x%x\n",
                         device,
                         FM_GET_FIELD(regValue, FM10000_I2C_CTRL, CommandCompleted),
                         FM10000_I2C_CTRL,
                         regValue);
        }

        FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_I2C_NO_RESPONSE);
    }

    for (i = 0 ; i < (rl+3)/4 ; i++)
    {
        status = ReadSwitchMemMap(memPtr, FM10000_I2C_DATA(i), &regValue);
        FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_PLATFORM, status);

        if (i2cDebug & 0x4)
        {
            FM_LOG_PRINT("READDATA#%d : 0x%08x\n",i, regValue);
        }

        for (j = 0 ; j < 4 ; j++)
        {
            if ((i*4 + j) < rl)
            {
                data[i*4 + j] = (regValue >> ((3 - j)*8)) & 0xFF;
            }
        }
    }
Example #15
0
/** fm6000DbgDumpVid
 * \ingroup intDiagMisc
 *
 * \desc            Dumps VID table for a switch.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \return          FM_OK on success.
 *
 *****************************************************************************/
fm_status fm10000DbgDumpVid(int sw)
{
    int        vid;
    fm_uint64  vidEntryLow;
    fm_uint32  vidEntryHigh;
    fm_status  status;
    fm_uint    vcnt;
    fm_bool    reflect;
    fm_int     fid1, fid2;
    fm_bool    fid2_ivl;
    char       members[600];
    int        memberCount;
    int        physPort;
    int        logPort;
    fm_int     cpi;
    int        portMembership;
    fm_uint32  portTag;
    char       tempBuf[10];
    fm_bool    trapIGMP;
    fm_bool    trapARP;
    fm_switch *switchPtr;
    fm_vlanEntry     *vtentry;
    fm10000_vlanEntry vtentryExt;

    FM_LOG_ENTRY(FM_LOG_CAT_VLAN, "sw=%d\n", sw);

    switchPtr = GET_SWITCH_PTR(sw);

    FM_LOG_PRINT("%4s %19s %7s %6s %6s %8s %6s %6s %6s %s\n",
                 "Vid#", "Entry", "Reflect", "Vcnt", "FID1", "FID2_IVL",
                 "FID2", "IGMP", "ARP", "Membership/Tagging");

    for (vid = 0 ; vid < 4096 ; vid++)
    {
        vtentry    = GET_VLAN_PTR(sw, vid);

        if (!vtentry->valid)
            continue;

        FM_TAKE_L2_LOCK(sw);
        FM_MEMCPY_S(&vtentryExt,
                    sizeof(vtentryExt),
                    (fm10000_vlanEntry *) GET_VLAN_EXT(sw, vid),
                    sizeof(fm10000_vlanEntry));
        FM_DROP_L2_LOCK(sw);

        vidEntryLow = (((fm_uint64) vtentryExt.member.maskWord[1]) << 32)
                    | vtentryExt.member.maskWord[0];
        vidEntryHigh = vtentryExt.member.maskWord[2];
        vcnt = vtentryExt.statIndex;
        status = fmGetVlanAttribute(sw,
                                    vid,
                                    FM_VLAN_REFLECT,
                                    &reflect);
        /* Successful? */
        FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_VLAN, status);

        status = fmGetVlanAttribute(sw,
                                    vid,
                                    FM_VLAN_IGMP_TRAPPING,
                                    &trapIGMP);
        /* Successful? */
        FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_VLAN, status);

#if 0
        status = fmGetVlanAttribute(sw,
                                    vid,
                                    FM_VLAN_ARP_TRAPPING,
                                    &trapARP);
        /* Successful? */
        FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_VLAN, status);
#else
        trapARP = FALSE;
#endif

        switch (switchPtr->stpMode)
        {
            case FM_SPANNING_TREE_SHARED:
                fid1 = 0;
                break;

            case FM_SPANNING_TREE_MULTIPLE:
                status = fmFindInstanceForVlan(sw, vid, &fid1);
                FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_VLAN, status);
                break;

            default:
                fid1 =-1;
                break;
        }

#if 0
        status = fmGetVlanAttribute(sw,
                                    vid,
                                    FM_VLAN_FID2_IVL,
                                    &fid2_ivl);
        /* Successful? */
        if ( status != FM_OK )
        {
            /* no, return the error code*/
            return status;
        }
#else
        fid2_ivl = -1;
#endif

#if 0
        status = fmGetVlanAttribute(sw,
                                    vid,
                                    FM6000_INGRESS_VID2_FID,
                                    &fid2);
        /* Successful? */
        if ( status != FM_OK )
        {
            /* no, return the error code*/
            return status;
        }
#else
        fid2 = -1;
#endif

        members[0]  = 0;
        memberCount = 0;

        /* Enumerate cardinal ports. */
        for (cpi = 0 ; cpi < switchPtr->numCardinalPorts ; cpi++)
        {
            /* Get logical and physical port numbers. */
            fmMapCardinalPortInternal(switchPtr, cpi, &logPort, &physPort);

            portMembership = FM_PORTMASK_GET_BIT(&vtentryExt.member, physPort);
            portTag = FM_PORTMASK_GET_BIT(&vtentryExt.tag, physPort);

            if (portMembership)
            {
                if ((memberCount > 0) && ((memberCount % 13) == 0))
                {
                    fmStringAppend(members,
                                 "\n                                      "
                                 "                                       ",
                                 sizeof(members));
                }

                FM_SNPRINTF_S(tempBuf, sizeof(tempBuf),
                              " %2d%c", logPort, (portTag) ? 'T' : ' ');
                fmStringAppend(members, tempBuf, sizeof(members));
                memberCount++;
            }
        }

        FM_LOG_PRINT("%4d %03x%016llx %7d %6d %6d %8d %6d %6s %6s %s\n",
                     vid,
                     vidEntryHigh,
                     vidEntryLow,
                     reflect,
                     vcnt,
                     fid1,
                     fid2_ivl,
                     fid2,
                     trapIGMP ? "trap" : "notrap",
                     trapARP ? "trap" : "notrap",
                     members);
    }

    return FM_OK;

}   /* end fm10000DbgDumpVid */
Example #16
0
/** fmDbgCompareChipSnapshots
 * \ingroup diagReg 
 *
 * \chips           FM2000, FM3000, FM4000, FM6000, FM10000
 *
 * \desc            Display a comparison between two or more snapshots of the
 *                  switch's configuration (the register file) taken with prior
 *                  calls to fmDbgTakeChipSnapshot.
 *
 * \param[in]       snapshotMask contains the bit mask of snapshots to compare,
 *                  where snapshot 0 is the least-significant bit, snapshot 1
 *                  is the next bit, etc.  A -1 will cause all snapshots to be
 *                  compared, ignoring unused snapshot numbers.
 *
 * \return          None.
 *
 *****************************************************************************/
void fmDbgCompareChipSnapshots(fm_uint snapshotMask)
{
    fmDbgFulcrumSnapshot *        pSnaps[FM_DBG_MAX_SNAPSHOTS];
    fm_int                        snapshotNumbers[FM_DBG_MAX_SNAPSHOTS];
    fmDbgFulcrumRegisterSnapshot *pReg0 = NULL;
    fmDbgFulcrumRegisterSnapshot *pRegX;
    fm_int                        snap;
    fm_int                        index;
    fm_bool                       different;
    fm_int                        activeCount;
    fm_bool                       abort = FALSE;
    fm_char                       regName[MAX_REG_NAME_LENGTH];
    fm_char                       curReg1[20];
    fm_char                       curReg2[20];
    fm_char                       tempBuf[40];
    fm_char                       outputBuffer1[1000];
    fm_char                       outputBuffer2[1000];
    fm_bool                       isPort;
    fm_int                        index0Ptr;
    fm_int                        index1Ptr;
    fm_int                        index2Ptr;

    memset( pSnaps, 0, sizeof(pSnaps) );

    /* count the active snapshots */
    index = 0;

    for (snap = 0 ; snap < FM_DBG_MAX_SNAPSHOTS ; snap++)
    {
        if ( (fmRootDebug->fmDbgSnapshots[snap] != NULL)
            && (fmRootDebug->fmDbgSnapshots[snap]->regCount > 0)
            && ( snapshotMask & (1 << snap) ) )
        {
            pSnaps[index]          = fmRootDebug->fmDbgSnapshots[snap];
            snapshotNumbers[index] = snap;
            index++;
        }
    }

    activeCount = index;

    if (activeCount == 0)
    {
        FM_LOG_PRINT("No active snapshots were found using mask %08X\n",
                     snapshotMask);
        return;
    }

    if (activeCount == 1)
    {
        FM_LOG_PRINT("Only one active snapshot was found using mask %08X\n",
                     snapshotMask);
        return;
    }

    /* compare snapshot information and registers */
    for (index = -4 ; index < pSnaps[0]->regCount ; index++)
    {
        if (abort)
        {
            break;
        }

        different = FALSE;

        /* compare snapshot 0 against all other snapshots */
        for (snap = 1 ; snap < activeCount ; snap++)
        {
            if (index < 0)
            {
                switch (index)
                {
                    case - 4:            /* snapshot numbers */
                        different = TRUE;
                        break;

                    case - 3:

                        /* switch number */
                        if (pSnaps[0]->sw != pSnaps[snap]->sw)
                        {
                            different = TRUE;
                            break;
                        }

                        break;

                    case - 2:

                        /* timestamp */
                        if ( (pSnaps[0]->timestamp.sec != pSnaps[snap]->
                                  timestamp.sec)
                            || (pSnaps[0]->timestamp.usec != pSnaps[snap]->
                                    timestamp.usec) )
                        {
                            different = TRUE;
                            break;
                        }

                        break;

                    case - 1:

                        /* register count */
                        if (pSnaps[0]->regCount != pSnaps[snap]->regCount)
                        {
                            different = TRUE;
                            break;
                        }

                        break;

                }   /* end switch (index) */

            }
            else
            {
                pReg0 = &pSnaps[0]->registers[index];
                pRegX = &pSnaps[snap]->registers[index];

                if (pReg0->regAddress != pRegX->regAddress)
                {
                    FM_LOG_PRINT("ERROR!  Snapshot register tables do not match!\n"
                                 "  index = %d, address 0 = %08X, "
                                 "address %d = %08X\n",
                                 index,
                                 pReg0->regAddress,
                                 snap,
                                 pRegX->regAddress);
                    abort = TRUE;
                    break;
                }

                if (pReg0->regSize != pRegX->regSize)
                {
                    FM_LOG_PRINT("ERROR!  Snapshot register sizes do not match!\n"
                                 " index = %d, address = %08X, size 0 = %d, "
                                 "size %d = %d\n",
                                 index,
                                 pReg0->regAddress,
                                 pReg0->regSize,
                                 snap,
                                 pRegX->regSize);
                    abort = TRUE;
                    break;
                }

                if ( (pReg0->regValue1 != pRegX->regValue1)
                    || (pReg0->regValue2 != pRegX->regValue2) )
                {
                    different = TRUE;
                    break;
                }
            }
        }

        if (abort)
        {
            break;
        }

        if (different)
        {
            if (index < 0)
            {
                switch (index)
                {
                    case - 4:            /* snapshot numbers */
                        fmStringCopy(regName, "Snapshot Number",
                                     sizeof(regName));
                        break;

                    case - 3:            /* switch number */
                        fmStringCopy(regName, "Switch Number",
                                     sizeof(regName));
                        break;

                    case - 2:            /* timestamp */
                        fmStringCopy(regName, "Timestamp", sizeof(regName));
                        break;

                    case - 1:            /* register count */
                        fmStringCopy(regName, "Register Count",
                                     sizeof(regName));
                        break;

                }   /* end switch (index) */

            }
            else
            {
                fmDbgGetRegisterName(pSnaps[0]->sw,
                                     pReg0->regId,
                                     pReg0->regAddress,
                                     regName,
                                     MAX_REG_NAME_LENGTH,
                                     &isPort,
                                     &index0Ptr,
                                     &index1Ptr,
                                     &index2Ptr,
                                     TRUE,
                                     FALSE);
            }

            outputBuffer1[0] = 0;
            outputBuffer2[0] = 0;

            for (snap = 0 ; snap < activeCount ; snap++)
            {
                curReg1[0] = 0;
                curReg2[0] = 0;

                if (index < 0)
                {
                    switch (index)
                    {
                        case -4:             /* Snapshot # */
                            FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                          "%d", snapshotNumbers[snap]);
                            break;

                        case -3:            /* switch number */
                            FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                          "%d", pSnaps[snap]->sw);
                            break;

                        case -2:             /* timestamp */
                            FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                          "%" FM_FORMAT_64 "u.%06" FM_FORMAT_64 "u",
                                          pSnaps[snap]->timestamp.sec,
                                          pSnaps[snap]->timestamp.usec);
                            break;

                        case -1:             /* register count */
                            FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                          "%d", pSnaps[snap]->regCount);
                            break;

                    }   /* end switch (index) */

                }
                else
                {
                    pRegX = &pSnaps[snap]->registers[index];

                    switch (pRegX->regSize)
                    {
                        case 1:
                            FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                          "%08X",
                                          (fm_uint32) pRegX->regValue1);
                            break;

                        case 2:

                            if (pRegX->isStatReg)
                            {
                                FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                              "%" FM_FORMAT_64 "u",
                                              pRegX->regValue1);
                            }
                            else
                            {
                                FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                              "%016" FM_FORMAT_64 "X",
                                              pRegX->regValue1);
                            }

                            break;

                        case 3:
                            FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                          "%016" FM_FORMAT_64 "X",
                                          pRegX->regValue1);
                            FM_SNPRINTF_S(curReg2, sizeof(curReg2),
                                          "%08X",
                                          (fm_uint32) pRegX->regValue2);
                            break;

                        case 4:
                            FM_SNPRINTF_S(curReg1, sizeof(curReg1),
                                          "%016" FM_FORMAT_64 "X",
                                          pRegX->regValue1);
                            FM_SNPRINTF_S(curReg2, sizeof(curReg2),
                                          "%016" FM_FORMAT_64 "X",
                                          pRegX->regValue2);
                            break;

                    }    /* end switch (pRegX->regSize) */

                }

                FM_SNPRINTF_S(tempBuf, sizeof(tempBuf), "%20s", curReg1);
                fmStringAppend(outputBuffer1, tempBuf, sizeof(outputBuffer1));

                if (curReg2[0] != 0)
                {
                    FM_SNPRINTF_S(tempBuf, sizeof(tempBuf), "%20s", curReg2);
                    fmStringAppend(outputBuffer2, tempBuf,
                                   sizeof(outputBuffer2));
                }
            }

            FM_LOG_PRINT("%-40s  %s\n", regName, outputBuffer1);

            if (outputBuffer2[0] != 0)
            {
                FM_LOG_PRINT("%40s  %s\n", " ", outputBuffer2);
            }
        }
    }

}   /* end fmDbgCompareChipSnapshots */
Example #17
0
/** fmLoadPortRemapTable
 * \ingroup intSwitch
 *
 * \desc            Load a new port mapping table from a given file.
 *
 * \param[in]       filename is the file name.
 *
 * \param[in]       portTable is ptr to table where to store port read from file
 *
 * \param[in]       origTable is ptr to the original port mapping table
 *
 * \param[in]       maxport is number of entries in portTable
 *
 * \return          FM_OK or FM_FAIL if unable to read table from file
 *
 *****************************************************************************/
fm_status fmLoadPortRemapTable(fm_char *filename,
                               fm_int *portTable,
                               fm_int *origTable,
                               fm_int maxport)
{
    FILE       *fp;
    fm_char    *pch;
    fm_char     line[200];
    fm_int      i;
    fm_int      j;
    fm_int      portNum;
    fm_char *   context;
    fm_uint     s1max;
    fm_uint     lineLeft;

    if ((fp = fopen(filename,"r")) == NULL)
    {
        FM_LOG_PRINT("cannot open file %s \n", filename);
        return(FM_FAIL);
    }

    /* Display the original port mapping table. */
    FM_CLEAR(line);
    lineLeft = sizeof(line);
    FM_SPRINTF_S(line, lineLeft, "\noriginalTable[%d,", origTable[0]);
    i = strlen(line);
    lineLeft -= i;
    pch = &line[i];

    for (i = 1 ; i < maxport ; i++)
    {
        FM_SPRINTF_S(pch, lineLeft, "%d,",origTable[i]);
        j = strlen(pch);
        lineLeft -= j;
        pch += j;
    }

    /* Reposition back to the trailing comma, then overwrite it */
    --pch;
    *pch = ']';
    FM_LOG_PRINT("%s\n", line);

    while ( fgets(line,200,fp) != NULL )
    {
        if (strstr(line,"mappingTable") != NULL)
        {
            FM_LOG_PRINT("%s\n", line);
            if ((pch = strchr(line,'[')) != NULL)
            {
                i       = 0;
                context = NULL;
                s1max   = RSIZE_MAX - 1;
                pch     = FM_STRTOK_S(++pch, &s1max, " ,", &context);

                while (pch != NULL && i < maxport)
                {
                    portNum = atoi(pch);
                    if (portNum >= 0 && portNum < maxport)
                    {
                        portTable[i++] = portNum;
                        pch = FM_STRTOK_S(NULL, &s1max, " ,]", &context);
                    }
                    else
                    {
                        FM_LOG_PRINT("*** Invalid port number %d ***\n",portNum);
                        fclose(fp);
                        return(FM_FAIL);
                    }
                }
            }
        }
    }

    fclose(fp);

    return FM_OK;

}   /* end fmLoadPortRemapTable */
/** PerformPurge
 * \ingroup intMacMaint
 *
 * \desc            Initiates an MA table purge operation.
 *
 * \param[in]       sw is the switch on which to operate.
 *
 * \return          FM_OK if successful.
 *
 *****************************************************************************/
static fm_status PerformPurge(fm_int sw)
{
    fm_switch *     switchPtr;
    fm_bool         l2Locked;
    fm_int          numSkipped;
    fm_event *      eventPtr;
    fm_uint32       numUpdates;
    fm_int          entryIndex;
    fm_status       err;

    fm_internalMacAddrEntry *   cachePtr;
    fm_internalMacAddrEntry     oldEntry;

    FM_LOG_ENTRY(FM_LOG_CAT_EVENT_MAC_MAINT, "sw=%d\n", sw);

    switchPtr = GET_SWITCH_PTR(sw);

    l2Locked    = FALSE;
    numSkipped  = 0;
    eventPtr    = NULL;
    numUpdates  = 0;

    /***************************************************
     * Preallocate an event buffer.
     **************************************************/

    /* NOTE: This call will block if the number of free event
     * buffers drops below the acceptable threshold. */
    eventPtr = fmAllocateEvent(sw,
                               FM_EVID_HIGH_TABLE_UPDATE,
                               FM_EVENT_TABLE_UPDATE,
                               FM_EVENT_PRIORITY_LOW);

    if (eventPtr == NULL)
    {
        fmDbgDiagCountIncr(sw, FM_CTR_MAC_EVENT_ALLOC_ERR, 1);

        FM_LOG_ERROR(FM_LOG_CAT_EVENT_MAC_MAINT,
                     "out of event buffers\n");
    }

    /***************************************************
     * Iterate over MAC table cache.
     **************************************************/

    for ( entryIndex = 0 ;
            entryIndex < switchPtr->macTableSize ;
            ++entryIndex )
    {
        if (!l2Locked)
        {
            FM_TAKE_L2_LOCK(sw);
            l2Locked   = TRUE;
            numSkipped = 0;
        }

        cachePtr = &switchPtr->maTable[entryIndex];

        /***************************************************
         * Determine whether to purge this entry.
         **************************************************/

        if (!MeetsPurgeCriteria(sw, cachePtr))
        {
            ++numSkipped;
            if (numSkipped >= SKIP_THRESHOLD)
            {
                FM_DROP_L2_LOCK(sw);
                l2Locked = FALSE;
            }
            continue;
        }

        if (FM_IS_TEST_TRACE_ADDRESS(cachePtr->macAddress))
        {
            FM_LOG_PRINT("fm10000HandlePurgeRequest(%d): "
                         "purging mac address " FM_FORMAT_ADDR "/%u\n",
                         sw,
                         cachePtr->macAddress,
                         cachePtr->vlanID);
        }

        /***************************************************
         * Remove entry from MAC table.
         **************************************************/

        /* Make a copy of the cache entry before we invalidate it.
         * We'll need it to generate the AGED event. */
        oldEntry = *cachePtr;

        /* Invalidate cache and hardware entry. */
        err = fm10000InvalidateEntryAtIndex(sw, entryIndex);
        if (err != FM_OK)
        {
            FM_LOG_ERROR(FM_LOG_CAT_EVENT_MAC_MAINT,
                         "Error purging MA table entry: sw=%d index=%d\n",
                         sw,
                         entryIndex);
        }

        /***************************************************
         * Generate an AGED event.
         **************************************************/

        /* Relinquish lock before generating event. */
        FM_DROP_L2_LOCK(sw);
        l2Locked = FALSE;

        fmGenerateUpdateForEvent(sw,
                                 &fmRootApi->eventThread,
                                 FM_EVENT_ENTRY_AGED,
                                 FM_MAC_REASON_PURGE_AGED,
                                 entryIndex,
                                 &oldEntry,
                                 &numUpdates,
                                 &eventPtr);

        fmDbgDiagCountIncr(sw, FM_CTR_MAC_PURGE_AGED, 1);

    }   /* end for ( entryIndex = 0 ; ... ) */

    if (l2Locked)
    {
        FM_DROP_L2_LOCK(sw);
    }

    if (numUpdates != 0)
    {
        fmSendMacUpdateEvent(sw,
                             &fmRootApi->eventThread,
                             &numUpdates,
                             &eventPtr,
                             FALSE);
    }

    if (eventPtr != NULL)
    {
        fmReleaseEvent(eventPtr);
    }

    err = FinishPurge(sw);

    FM_LOG_EXIT(FM_LOG_CAT_EVENT_MAC_MAINT, err);

}   /* end PerformPurge */
Example #19
0
/** fmDbgPrintPortList
 * \ingroup intSflow
 *
 * \desc            Prints a port set as a list of comma-separated ranges.
 *
 * \param[in]       sw is the switch on which to operate.
 * 
 * \param[in]       numPorts is the number of ports in the array.
 *
 * \param[in]       portList is the array which contains the list of ports.
 *
 * \return          FM_OK if successful.
 * \return          FM_OK if successful.
 *
 *****************************************************************************/
static fm_status fmDbgPrintPortList(fm_int sw, fm_int numPorts, fm_int *portList)
{
    fm_switch * switchPtr;
    fm_int      cpi;
    fm_int      port;
    fm_int      lastPort;
    fm_bool     inSet;
    fm_int      i;

    enum { EMPTY, FIRST, RANGE, GAP } state;

    switchPtr = GET_SWITCH_PTR(sw);
    lastPort  = -1;
    state     = EMPTY;

    for (cpi = 0 ; cpi < switchPtr->numCardinalPorts ; ++cpi)
    {
        port  = GET_LOGICAL_PORT(sw, cpi);
        inSet = FALSE;
        for (i = 0; i < numPorts; i++)
        {
            if (portList[i] == port)
            {
                inSet = TRUE;
            }
        }

        switch (state)
        {
            case EMPTY:
                /* The output set is empty. */
                if (inSet)
                {
                    FM_LOG_PRINT("%d", port);
                    state = FIRST;
                }
                break;

            case FIRST:
                /* We've processed the first port in a sequence. */
                if (inSet)
                {
                    lastPort = port;
                    state = RANGE;
                }
                else
                {
                    state = GAP;
                }
                break;

            case RANGE:
                /* We're processing a range in the port list. */
                if (inSet)
                {
                    lastPort = port;
                }
                else
                {
                    FM_LOG_PRINT("..%d", lastPort);
                    state = GAP;
                }
                break;

            case GAP:
                /* We're processing a gap in the port list. */
                if (inSet)
                {
                    FM_LOG_PRINT(",%d", port);
                    state = FIRST;
                }
                break;

        }   /* end switch (state) */

    }   /* end for (cpi = 0 ; cpi < switchPtr->numCardinalPorts ; ++cpi) */

    if (state == RANGE)
    {
        FM_LOG_PRINT("..%d", lastPort);
    }

    return FM_OK;

}   /* end fmDbgPrintPortList */