Implement Silicom card features #1

Merged
DataHoarder merged 12 commits from implement-silicom-card into master 2021-10-28 05:16:53 +00:00
14 changed files with 259 additions and 98 deletions

View file

@ -13,10 +13,8 @@ AM_CFLAGS = -std=c99
-Wno-override-init \ -Wno-override-init \
-DFM_SUPPORT_FM10000 \ -DFM_SUPPORT_FM10000 \
-DINSTRUMENT_LOG_LEVEL=0 \ -DINSTRUMENT_LOG_LEVEL=0 \
-DPLATFORM_FIRST_FOCALPOINT=0 \
-DPLATFORM_NUM_FOCALPOINTS=1 \
-D_GNU_SOURCE \ -D_GNU_SOURCE \
-Lsrc/.libs/ -lFocalpointSDK -lm -lpthread -ldl -lrt \ -Lsrc/.libs/ -lFocalpointSDK -lm -lpthread -lrt \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/include/alos/linux \ -I$(top_srcdir)/include/alos/linux \
-I$(top_srcdir)/include/std/intel \ -I$(top_srcdir)/include/std/intel \

View file

@ -161,7 +161,7 @@ typedef enum
#define FM10000_ETHERNET_MODE_CONFIG_PAUSE 100000000 #define FM10000_ETHERNET_MODE_CONFIG_PAUSE 100000000
/* From EAS MAC_CFG.TxFcsMode */ /* From EAS MAC_CFG.TxFcsMode */
enum typedef enum
{ {
FM10000_FCS_PASSTHRU = 0, FM10000_FCS_PASSTHRU = 0,
FM10000_FCS_PASSTHRU_CHECK, FM10000_FCS_PASSTHRU_CHECK,

View file

@ -50,6 +50,12 @@ typedef enum
/** Bus to transceiver state */ /** Bus to transceiver state */
FM_PLAT_BUS_XCVR_STATE, FM_PLAT_BUS_XCVR_STATE,
FM_PLAT_BUS_UNKNOWN_4,
FM_PLAT_BUS_UNKNOWN_5,
FM_PLAT_BUS_UNKNOWN_6,
FM_PLAT_BUS_UNKNOWN_7,
FM_PLAT_BUS_UNKNOWN_8,
/** Bus to transceiver eeprom */ /** Bus to transceiver eeprom */
FM_PLAT_BUS_PHY, FM_PLAT_BUS_PHY,

View file

@ -13,8 +13,6 @@ AM_CFLAGS = -std=c99
-Wno-override-init \ -Wno-override-init \
-DFM_SUPPORT_FM10000 \ -DFM_SUPPORT_FM10000 \
-DINSTRUMENT_LOG_LEVEL=0 \ -DINSTRUMENT_LOG_LEVEL=0 \
-DPLATFORM_FIRST_FOCALPOINT=0 \
-DPLATFORM_NUM_FOCALPOINTS=1 \
-D_GNU_SOURCE \ -D_GNU_SOURCE \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-I$(top_srcdir)/include/alos \ -I$(top_srcdir)/include/alos \
@ -26,8 +24,8 @@ AM_CFLAGS = -std=c99
lib_LTLIBRARIES = libFocalpointSDK.la lib_LTLIBRARIES = libFocalpointSDK.la
libFocalpointSDK_la_LDFLAGS = -release `cd $(top_srcdir) ; ./version.sh` libFocalpointSDK_la_LDFLAGS = -avoid-version
libFocalpointSDK_la_LIBADD = -ldl libFocalpointSDK_la_LIBADD = -lrt
libFocalpointSDK_la_LDFLAGS += -Wl,-Ttext-segment=0x08000000 -shared -fPIC libFocalpointSDK_la_LDFLAGS += -Wl,-Ttext-segment=0x08000000 -shared -fPIC
libFocalpointSDK_la_SOURCES = \ libFocalpointSDK_la_SOURCES = \
@ -233,7 +231,7 @@ platforms/util/retimer/fm_util_gn2412.c
lib_LTLIBRARIES += libLTStdPlatform.la lib_LTLIBRARIES += libLTStdPlatform.la
libLTStdPlatform_la_LDFLAGS = -release `cd $(top_srcdir) ; ./version.sh` libLTStdPlatform_la_LDFLAGS = -avoid-version
libLTStdPlatform_la_LDFLAGS += -Wl,-Ttext-segment=0x09600000 -shared -fPIC libLTStdPlatform_la_LDFLAGS += -Wl,-Ttext-segment=0x09600000 -shared -fPIC
libLTStdPlatform_la_LIBADD = libFocalpointSDK.la libLTStdPlatform_la_LIBADD = libFocalpointSDK.la

View file

@ -2324,7 +2324,9 @@ fm_status fmPlatformSwitchInserted(fm_int sw)
libFunc = FM_PLAT_GET_LIB_FUNCS_PTR(sw); libFunc = FM_PLAT_GET_LIB_FUNCS_PTR(sw);
if ( libFunc->InitSwitch ) if ( libFunc->InitSwitch )
{ {
TAKE_PLAT_I2C_BUS_LOCK(sw);
status = libFunc->InitSwitch(swCfg->swNum); status = libFunc->InitSwitch(swCfg->swNum);
DROP_PLAT_I2C_BUS_LOCK(sw);
FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_PLATFORM, status); FM_LOG_EXIT_ON_ERR(FM_LOG_CAT_PLATFORM, status);
} }

View file

@ -1320,7 +1320,7 @@ static fm_status SwitchI2cWriteRead(fm_uintptr handle,
i2c = &hwCfg.i2c[sw]; i2c = &hwCfg.i2c[sw];
/* Read chip version: FM10000_CHIP_VERSION => register: 0x452 */ /* Read chip version: FM10000_CHIP_VERSION => register: 0x452 */
status = fmReadUINT32(sw, 0x452, &rv); status = fmReadUINT32(sw, FM10000_CHIP_VERSION(), &rv);
if (status == FM_OK) if (status == FM_OK)
{ {
i2c->chipVersion = rv & 0x7F; i2c->chipVersion = rv & 0x7F;
@ -1361,7 +1361,7 @@ static fm_status SwitchI2cWriteRead(fm_uintptr handle,
} }
} }
else else if (device != 0x8) // specifically VRM_IR device from Silicom patch
{ {
FM_LOG_ERROR(FM_LOG_CAT_PLATFORM, FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
"I2C error accessing device 0x%x via switch %d: %s\n", "I2C error accessing device 0x%x via switch %d: %s\n",
@ -2145,7 +2145,7 @@ static fm_status LoadTlv(fm_byte *tlv)
if (!(hwCfg.pcaIo[idx].loadFlags & LF_IO_MODEL)) if (!(hwCfg.pcaIo[idx].loadFlags & LF_IO_MODEL))
{ {
CfgOrderErrorMsg(tlv, idx, CfgOrderErrorMsg(tlv, idx,
"must be before PCA IO %d model config"); "must be after PCA IO %d model config");
return FM_ERR_INVALID_ARGUMENT; return FM_ERR_INVALID_ARGUMENT;
} }
@ -2163,7 +2163,7 @@ static fm_status LoadTlv(fm_byte *tlv)
if (!(hwCfg.pcaIo[idx].loadFlags & LF_IO_MODEL)) if (!(hwCfg.pcaIo[idx].loadFlags & LF_IO_MODEL))
{ {
CfgOrderErrorMsg(tlv, idx, CfgOrderErrorMsg(tlv, idx,
"must be before PCA IO %d model config"); "must be after PCA IO %d model config");
return FM_ERR_INVALID_ARGUMENT; return FM_ERR_INVALID_ARGUMENT;
} }
@ -2221,8 +2221,10 @@ static fm_status LoadTlv(fm_byte *tlv)
FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_NO_MEM); FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, FM_ERR_NO_MEM);
} }
for (idx = 0; idx < hwCfg.numResId; idx++) { for (idx = 0; idx < hwCfg.numResId; idx++) {
hwCfg.hwResId[idx].xcvrI2cBusSel.ioIdx = UINT_NOT_USED;
hwCfg.hwResId[idx].xcvrI2cBusSel.parentMuxIdx = hwCfg.hwResId[idx].xcvrI2cBusSel.parentMuxIdx =
UINT_NOT_USED; UINT_NOT_USED;
hwCfg.hwResId[idx].xcvrStateIo.ioIdx = UINT_NOT_USED;
hwCfg.hwResId[idx].xcvrStateIo.basePin = UINT_NOT_USED; hwCfg.hwResId[idx].xcvrStateIo.basePin = UINT_NOT_USED;
hwCfg.hwResId[idx].phy.parentMuxIdx = UINT_NOT_USED; hwCfg.hwResId[idx].phy.parentMuxIdx = UINT_NOT_USED;
hwCfg.hwResId[idx].vrm.parentMuxIdx = UINT_NOT_USED; hwCfg.hwResId[idx].vrm.parentMuxIdx = UINT_NOT_USED;
@ -2304,21 +2306,37 @@ static fm_status LoadTlv(fm_byte *tlv)
xcvrIo->u.qsfpPin.modPresN = xcvrIo->basePin + xcvrIo->u.qsfpPin.modPresN = xcvrIo->basePin +
hwCfg.defQsfpPat.modPresN; hwCfg.defQsfpPat.modPresN;
} }
else
{
xcvrIo->u.qsfpPin.modPresN = UINT_NOT_USED;
}
if (hwCfg.defQsfpPat.intrN != UINT_NOT_USED) if (hwCfg.defQsfpPat.intrN != UINT_NOT_USED)
{ {
xcvrIo->u.qsfpPin.intrN = xcvrIo->basePin + xcvrIo->u.qsfpPin.intrN = xcvrIo->basePin +
hwCfg.defQsfpPat.intrN; hwCfg.defQsfpPat.intrN;
} }
else
{
xcvrIo->u.qsfpPin.intrN = UINT_NOT_USED;
}
if (hwCfg.defQsfpPat.lpMode != UINT_NOT_USED) if (hwCfg.defQsfpPat.lpMode != UINT_NOT_USED)
{ {
xcvrIo->u.qsfpPin.lpMode = xcvrIo->basePin + xcvrIo->u.qsfpPin.lpMode = xcvrIo->basePin +
hwCfg.defQsfpPat.lpMode; hwCfg.defQsfpPat.lpMode;
} }
else
{
xcvrIo->u.qsfpPin.lpMode = UINT_NOT_USED;
}
if (hwCfg.defQsfpPat.resetN != UINT_NOT_USED) if (hwCfg.defQsfpPat.resetN != UINT_NOT_USED)
{ {
xcvrIo->u.qsfpPin.resetN = xcvrIo->basePin + xcvrIo->u.qsfpPin.resetN = xcvrIo->basePin +
hwCfg.defQsfpPat.resetN; hwCfg.defQsfpPat.resetN;
} }
else
{
xcvrIo->u.qsfpPin.resetN = UINT_NOT_USED;
}
} }
break; break;
case FM_TLV_PLAT_LIB_XCVR_MODABS_PIN: case FM_TLV_PLAT_LIB_XCVR_MODABS_PIN:
@ -2453,7 +2471,7 @@ static fm_status LoadTlv(fm_byte *tlv)
if (hwCfg.numResId != 0) if (hwCfg.numResId != 0)
{ {
CfgOrderErrorMsg(tlv, 0, CfgOrderErrorMsg(tlv, 0,
"must must be before hwResourceId.count config"); "must be before hwResourceId.count config");
return FM_ERR_INVALID_ARGUMENT; return FM_ERR_INVALID_ARGUMENT;
} }
hwCfg.defBusSelType = GetTlvInt(tlv + 3, 1); hwCfg.defBusSelType = GetTlvInt(tlv + 3, 1);
@ -2823,8 +2841,7 @@ static fm_status LoadConfig(void)
} }
/* Release lib config to free memory */ fflush(stdout);
fmPlatformReleaseLibTlvCfg(swIdx);
return FM_OK; return FM_OK;
@ -3066,6 +3083,60 @@ static void DumpConfig(void)
static fm_status VerifyConfig(void)
{
fm_uint32 idx;
fm_uint32 subLed;
fm_status status;
status = FM_OK;
if (hwCfg.numResId > 0)
{
for(idx = 0; idx < hwCfg.numResId; ++idx)
{
if (
hwCfg.hwResId[idx].xcvrI2cBusSel.busSelType == BUS_SEL_TYPE_PCA_IO &&
hwCfg.hwResId[idx].xcvrStateIo.ioIdx >= hwCfg.numPcaIo
)
{
FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
"hwResourceId %d xcvrI2C.pcaIo.index is out of range.\n",
idx);
status = FM_ERR_INVALID_ARGUMENT;
}
if (
(hwCfg.hwResId[idx].xcvrStateIo.intfType == INTF_TYPE_SFPP || hwCfg.hwResId[idx].xcvrStateIo.intfType == INTF_TYPE_QSFP) &&
hwCfg.hwResId[idx].xcvrStateIo.ioIdx >= hwCfg.numPcaIo
)
{
FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
"hwResourceId %d xcvrState.pcaIo.index is out of range.\n",
idx);
status = FM_ERR_INVALID_ARGUMENT;
}
{
for(subLed = 0; subLed < NUM_SUB_LED; ++subLed){
if (
hwCfg.hwResId[idx].portLed[0].subLed[subLed].usage == LED_USAGE_LINK &&
hwCfg.hwResId[idx].portLed[0].subLed[subLed].pin >= hwCfg.numPcaIo
)
{
FM_LOG_ERROR(FM_LOG_CAT_PLATFORM,
"hwResourceId %d LED pcaIo.index is out of range.\n",
idx);
status = FM_ERR_INVALID_ARGUMENT;
}
}
}
}
}
FM_LOG_EXIT(FM_LOG_CAT_PLATFORM, status);
}
/*****************************************************************************/ /*****************************************************************************/
/* SetupMuxPathRcrsv /* SetupMuxPathRcrsv
@ -3802,10 +3873,11 @@ fm_status GetVrmVoltageInt(fm_int sw,
{ {
/* Select Page */ /* Select Page */
data[0] = 0x18; data[0] = 0x18;
data[1] = 0x00;
status = i2c->writeReadFunc(i2c->handle, vrmI2c->addr, data, 1, 1); status = i2c->writeReadFunc(i2c->handle, vrmI2c->addr, data, 1, 1);
FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_PLATFORM, status); if (status != FM_OK){
return status;
}
*mVolt = (data[0] * 5000 + 245000) / 1000; *mVolt = (data[0] * 5000 + 245000) / 1000;
@ -3827,7 +3899,6 @@ ABORT:
* Public Functions * Public Functions
*****************************************************************************/ *****************************************************************************/
/*****************************************************************************/ /*****************************************************************************/
/* fmPlatformLibInit /* fmPlatformLibInit
* \ingroup platformLib * \ingroup platformLib
@ -3906,6 +3977,12 @@ fm_status fmPlatformLibInit(void)
DumpConfig(); DumpConfig();
} }
status = VerifyConfig();
if(status != FM_OK)
{
goto ABORT;
}
if (strlen(hwCfg.fileLockName) > 0) if (strlen(hwCfg.fileLockName) > 0)
{ {
hwCfg.fileLock = hwCfg.fileLock =
@ -4219,6 +4296,7 @@ fm_status fmPlatformLibSelectBus(fm_int sw,
fm_uint bitIdx; fm_uint bitIdx;
fm_uint cnt; fm_uint cnt;
fm_busSel *xcvrI2cBus; fm_busSel *xcvrI2cBus;
fm_pcaMux *pcaMuxPtr;
fm_uint lastId; fm_uint lastId;
fm_uint id; fm_uint id;
@ -4277,7 +4355,78 @@ fm_status fmPlatformLibSelectBus(fm_int sw,
muxIdx = UINT_NOT_USED; muxIdx = UINT_NOT_USED;
if (busType == FM_PLAT_BUS_XCVR_STATE) if (busType == FM_PLAT_BUS_UNKNOWN_4)
{
if (hwCfg.numPcaMux > 0)
{
for (muxValue = 0; muxValue < hwCfg.numPcaMux; ++muxValue)
{
if (hwCfg.pcaMux[muxValue].bus == sw)
{
status = SetupMuxPath(muxValue, 2);
break;
}
}
}
}
else if (busType == FM_PLAT_BUS_UNKNOWN_5)
{
if (hwCfg.numPcaMux > 0)
{
for (muxValue = 0; muxValue < hwCfg.numPcaMux; ++muxValue)
{
if (hwCfg.pcaMux[muxValue].bus == sw)
{
status = SetupMuxPath(muxValue, 4);
break;
}
}
}
}
else if (busType == FM_PLAT_BUS_UNKNOWN_6)
{
if (hwCfg.numPcaMux > 0)
{
for (muxValue = 0; muxValue < hwCfg.numPcaMux; ++muxValue)
{
if (hwCfg.pcaMux[muxValue].bus == sw)
{
status = SetupMuxPath(muxValue + 1, 1);
break;
}
}
}
}
else if (busType == FM_PLAT_BUS_UNKNOWN_7)
{
if (hwCfg.numPcaMux > 0)
{
for (muxValue = 0; muxValue < hwCfg.numPcaMux; ++muxValue)
{
if (hwCfg.pcaMux[muxValue].bus == sw)
{
status = SetupMuxPath(muxValue, 4);
break;
}
}
}
}
else if (busType == FM_PLAT_BUS_UNKNOWN_8)
{
if (hwCfg.numPcaMux > 0)
{
for (muxValue = 0; muxValue < hwCfg.numPcaMux; ++muxValue)
{
if (hwCfg.pcaMux[muxValue].bus == sw)
{
status = SetupMuxPath(muxValue, 8);
break;
}
}
}
}
else if (busType == FM_PLAT_BUS_XCVR_STATE)
{ {
idx = hwResId->xcvrStateIo.ioIdx; idx = hwResId->xcvrStateIo.ioIdx;
muxIdx = hwCfg.pcaIo[idx].parentMuxIdx; muxIdx = hwCfg.pcaIo[idx].parentMuxIdx;
@ -4683,6 +4832,11 @@ fm_status fmPlatformLibGetPortXcvrState(fm_int sw,
else if (xcvrIo->intfType == INTF_TYPE_QSFP) else if (xcvrIo->intfType == INTF_TYPE_QSFP)
{ {
offset = xcvrIo->u.qsfpPin.modPresN; offset = xcvrIo->u.qsfpPin.modPresN;
if (offset == UINT_NOT_USED)
{
xcvrState[cnt] |= FM_PLAT_XCVR_PRESENT;
}
if ((offset != UINT_NOT_USED) && (offset < NUM_PCA_PINS)) if ((offset != UINT_NOT_USED) && (offset < NUM_PCA_PINS))
{ {
byteIdx = offset / 8; byteIdx = offset / 8;
@ -4710,6 +4864,11 @@ fm_status fmPlatformLibGetPortXcvrState(fm_int sw,
input/output mismatch seen with specific cables input/output mismatch seen with specific cables
(Vendor : TE Connectivity : PN 2231368-1).*/ (Vendor : TE Connectivity : PN 2231368-1).*/
offset = xcvrIo->u.qsfpPin.lpMode; offset = xcvrIo->u.qsfpPin.lpMode;
if (offset == UINT_NOT_USED)
{
xcvrState[cnt] |= FM_PLAT_XCVR_LPMODE;
}
if ((offset != UINT_NOT_USED) && (offset < NUM_PCA_PINS)) if ((offset != UINT_NOT_USED) && (offset < NUM_PCA_PINS))
{ {
byteIdx = offset / 8; byteIdx = offset / 8;
@ -5282,6 +5441,7 @@ fm_status fmPlatformLibSetVrmVoltage(fm_int sw,
fm_i2cCfg * i2c; fm_i2cCfg * i2c;
fm_hwResId * hwResId; fm_hwResId * hwResId;
fm_vrmI2C * vrmI2c; fm_vrmI2C * vrmI2c;
uint voltageCalc;
fm_byte data[4]; fm_byte data[4];
fm_uint channel; fm_uint channel;
fm_uint regVidSet; fm_uint regVidSet;
@ -5531,31 +5691,27 @@ fm_status fmPlatformLibSetVrmVoltage(fm_int sw,
else if (hwResId->vrm.model && (hwResId->vrm.model == VRM_IR)) else if (hwResId->vrm.model && (hwResId->vrm.model == VRM_IR))
{ {
printf("vrm mVolt %d delta %d\n", mVolt, hwResId->vrm.delta); printf("vrm mVolt %d delta %d\n", mVolt, hwResId->vrm.delta);
uint voltageCalc = (mVolt + hwResId->vrm.delta) / 5 - 49; voltageCalc = (mVolt + hwResId->vrm.delta) / 5 - 49;
data[1] = (char) voltageCalc; data[1] = voltageCalc;
printf("vrm channel %d data 0x%x\n", channel, voltageCalc & 0xff); printf("vrm channel %d data 0x%x\n", channel, voltageCalc);
fflush(stdout); fflush(stdout);
if(channel == 0){ if(status == 0){
data[0] = 0x26; data[0] = 0x26;
} else if (channel == 1){ } else if (channel == 1){
data[0] = 0x27; data[0] = 0x27;
} }
for(uint i; i < 0x32; ++i){ for(uint i = 0; i < 50; ++i){
status = i2c->writeReadFunc(i2c->handle, vrmI2c->addr, data, 2, 0); status = i2c->writeReadFunc(i2c->handle, vrmI2c->addr, data, 2, 0);
if(status == FM_OK){ if(status == FM_OK){
status = i2c->writeReadFunc(i2c->handle, vrmI2c->addr, data, 0, 1);
break; break;
} }
fmDelayBy(1, 0);
fmDelay(0, 1);
} }
if(status != FM_OK){
i2c->writeReadFunc(i2c->handle, vrmI2c->addr, data, 0, 1); i2c->writeReadFunc(i2c->handle, vrmI2c->addr, data, 0, 1);
FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_PLATFORM, status); FM_LOG_ABORT_ON_ERR(FM_LOG_CAT_PLATFORM, status);
} }
}
else else
{ {
status = FM_ERR_INVALID_ARGUMENT; status = FM_ERR_INVALID_ARGUMENT;

View file

@ -1677,7 +1677,7 @@ fm_status fmUtilPcaIoUpdateInputRegs(fm_pcaIoDevice *dev)
PCA_IO_REG_TYPE_INPUT, PCA_IO_REG_TYPE_INPUT,
0, 0,
dev->devCap.numBytes); dev->devCap.numBytes);
break;
default: default:
status = FM_ERR_INVALID_ARGUMENT; status = FM_ERR_INVALID_ARGUMENT;
break; break;
@ -1717,6 +1717,7 @@ fm_status fmUtilPcaIoWriteRegs(fm_pcaIoDevice *dev,
{ {
fm_status status; fm_status status;
fflush(stdout);
switch (dev->model) switch (dev->model)
{ {
case PCA_IO_9505: case PCA_IO_9505: