summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEyal Harari <Eyal.Harari@freescale.com>2013-10-23 14:48:43 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-03-07 17:33:51 (GMT)
commit8b32a91deffcc4cded99b366449c8139eea39690 (patch)
tree660bee4a95b400ad50956cf591106d6be51f589e
parentf2569c4d162f1a10c5cdb68b5d29f2e0b8325afb (diff)
downloadlinux-fsl-qoriq-8b32a91deffcc4cded99b366449c8139eea39690.tar.xz
FMD: DSAR: Establish the auto-response driver
- New code for auto-response - Changed parser init - Added DsarCheckParams and fm_port_dsar_dump_regs - Added snmp support - Added statistics features - Fixed SNMP oid table - Removed usage of create_proc_entry - for merging to master Change-Id: Icd6292c8d68ddb4ee60ecfed87419c1f4cbf5e74 Signed-off-by: Eyal Harari <Eyal.Harari@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/8711 Reviewed-by: Madalin-Cristian Bucur <madalin.bucur@freescale.com> Reviewed-by: Mandy Lavi <Mandy.Lavi@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com> Tested-by: Jose Rivera <German.Rivera@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/9445
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_prs.c8
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fman_prs.c5
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c664
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.h16
-rwxr-xr-xdrivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port_dsar.h494
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c5
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h2
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h289
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/flib/fsl_fman_prs.h1
-rw-r--r--drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_fsl_fman.h198
-rwxr-xr-x[-rw-r--r--]drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c85
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h3
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm_port.c61
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_sysfs_fm_port.c404
14 files changed, 2228 insertions, 7 deletions
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_prs.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_prs.c
index e198afd..1666865 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_prs.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fm_prs.c
@@ -191,6 +191,14 @@ void PrsDisable(t_FmPcd *p_FmPcd)
fman_prs_disable(PrsRegs);
}
+int PrsIsEnabled(t_FmPcd *p_FmPcd)
+{
+ struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
+
+ ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
+ return fman_prs_is_enabled(PrsRegs);
+}
+
t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
{
struct fman_prs_regs *PrsRegs;
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fman_prs.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fman_prs.c
index caa1d28..108779d 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fman_prs.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Pcd/fman_prs.c
@@ -110,6 +110,11 @@ void fman_prs_disable(struct fman_prs_regs *regs)
iowrite32be(tmp, &regs->fmpr_rpimac);
}
+int fman_prs_is_enabled(struct fman_prs_regs *regs)
+{
+ return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
+}
+
void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
{
iowrite32be(pid_msk, &regs->fmpr_ppsc);
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c
index bfa05c5..4949b79 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c
@@ -45,12 +45,13 @@
#include "fman_common.h"
#include "fm_port.h"
-
+#include "fm_port_dsar.h"
#include "common/general.h"
/****************************************/
/* static functions */
/****************************************/
+static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
static t_Error CheckInitParameters(t_FmPort *p_FmPort)
{
@@ -2252,6 +2253,9 @@ t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
return p_FmPort;
}
+t_FmPort *rx_port = 0;
+t_FmPort *tx_port = 0;
+
/**************************************************************************//**
@Function FM_PORT_Init
@@ -2443,7 +2447,10 @@ t_Error FM_PORT_Init(t_Handle h_FmPort)
#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
}
#endif /* (DPAA_VERSION >= 11) */
-
+
+ if (p_FmPort->deepSleepVars.autoResMaxSizes)
+ FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
+
return E_OK;
}
@@ -5183,3 +5190,656 @@ t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCo
}
#endif /* (DPAA_VERSION >= 11) */
+t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params)
+{
+ t_FmPort *p_FmPort= (t_FmPort *)h_FmPortRx;
+ p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(sizeof(struct t_FmPortDsarTablesSizes));
+ memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params, sizeof(struct t_FmPortDsarTablesSizes));
+ return E_OK;
+}
+
+static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
+{
+ uint32_t *param_page;
+ t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
+ t_ArCommonDesc *ArCommonDescPtr;
+ uint32_t size = sizeof(t_ArCommonDesc);
+ // ARP
+ // should put here if (params->max_num_of_arp_entries)?
+ size = ROUND_UP(size,4);
+ size += sizeof(t_DsarArpDescriptor);
+ size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
+ size += sizeof(t_DsarArpStatistics);
+ //ICMPV4
+ size = ROUND_UP(size,4);
+ size += sizeof(t_DsarIcmpV4Descriptor);
+ size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
+ size += sizeof(t_DsarIcmpV4Statistics);
+ //ICMPV6
+ size = ROUND_UP(size,4);
+ size += sizeof(t_DsarIcmpV6Descriptor);
+ size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
+ size += sizeof(t_DsarIcmpV6Statistics);
+ //ND
+ size = ROUND_UP(size,4);
+ size += sizeof(t_DsarNdDescriptor);
+ size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
+ size += sizeof(t_DsarIcmpV6Statistics);
+ //SNMP
+ size = ROUND_UP(size,4);
+ size += sizeof(t_DsarSnmpDescriptor);
+ size += sizeof(t_DsarSnmpIpv4AddrTblEntry) * params->maxNumOfSnmpIPV4Entries;
+ size += sizeof(t_DsarSnmpIpv6AddrTblEntry) * params->maxNumOfSnmpIPV6Entries;
+ size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
+ size += params->maxNumOfSnmpOidChar;
+ size += sizeof(t_DsarIcmpV6Statistics);
+ //filters
+ size = ROUND_UP(size,4);
+ size += params->maxNumOfIpProtFiltering;
+ size = ROUND_UP(size,4);
+ size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
+ size = ROUND_UP(size,4);
+ size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
+
+ // add here for more protocols
+
+ // statistics
+ size = ROUND_UP(size,4);
+ size += sizeof(t_ArStatistics);
+
+ ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
+
+ param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
+ WRITE_UINT32(*param_page,
+ (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
+ return E_OK;
+}
+
+t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
+{
+ t_FmPort *p_FmPort= (t_FmPort *)h_FmPortRx;
+ return p_FmPort->deepSleepVars.autoResMaxSizes;
+}
+
+struct arOffsets
+{
+ uint32_t arp;
+ uint32_t nd;
+ uint32_t icmpv4;
+ uint32_t icmpv6;
+ uint32_t snmp;
+ uint32_t stats;
+ uint32_t filtIp;
+ uint32_t filtUdp;
+ uint32_t filtTcp;
+};
+
+static uint32_t AR_ComputeOffsets(struct arOffsets* of, struct t_FmPortDsarParams *params, t_FmPort *p_FmPort)
+{
+ uint32_t size = sizeof(t_ArCommonDesc);
+ // ARP
+ if (params->p_AutoResArpInfo)
+ {
+ size = ROUND_UP(size,4);
+ of->arp = size;
+ size += sizeof(t_DsarArpDescriptor);
+ size += sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize;
+ size += sizeof(t_DsarArpStatistics);
+ }
+ // ICMPV4
+ if (params->p_AutoResEchoIpv4Info)
+ {
+ size = ROUND_UP(size,4);
+ of->icmpv4 = size;
+ size += sizeof(t_DsarIcmpV4Descriptor);
+ size += sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize;
+ size += sizeof(t_DsarIcmpV4Statistics);
+ }
+ // ICMPV6
+ if (params->p_AutoResEchoIpv6Info)
+ {
+ size = ROUND_UP(size,4);
+ of->icmpv6 = size;
+ size += sizeof(t_DsarIcmpV6Descriptor);
+ size += sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize;
+ size += sizeof(t_DsarIcmpV6Statistics);
+ }
+ // ND
+ if (params->p_AutoResNdpInfo)
+ {
+ size = ROUND_UP(size,4);
+ of->nd = size;
+ size += sizeof(t_DsarNdDescriptor);
+ size += sizeof(t_DsarIcmpV6BindingEntry) *
+ (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp);
+ size += sizeof(t_DsarIcmpV6Statistics);
+ }
+ // SNMP
+ if (params->p_AutoResSnmpInfo)
+ {
+ size = ROUND_UP(size,4);
+ of->snmp = size;
+ size += sizeof(t_DsarSnmpDescriptor);
+ size += sizeof(t_DsarSnmpIpv4AddrTblEntry) * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
+ size += sizeof(t_DsarSnmpIpv6AddrTblEntry) * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
+ size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
+ size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
+ size += sizeof(t_DsarIcmpV6Statistics);
+ }
+ //filters
+ size = ROUND_UP(size,4);
+ if (params->p_AutoResFilteringInfo)
+ {
+ of->filtIp = size;
+ size += params->p_AutoResFilteringInfo->ipProtTableSize;
+ size = ROUND_UP(size,4);
+ of->filtUdp = size;
+ size += params->p_AutoResFilteringInfo->udpPortsTableSize * sizeof(t_PortTblEntry);
+ size = ROUND_UP(size,4);
+ of->filtTcp = size;
+ size += params->p_AutoResFilteringInfo->tcpPortsTableSize * sizeof(t_PortTblEntry);
+ }
+ // add here for more protocols
+ // statistics
+ size = ROUND_UP(size,4);
+ of->stats = size;
+ size += sizeof(t_ArStatistics);
+ return size;
+}
+
+uint32_t* ARDesc;
+void PrsEnable(t_Handle p_FmPcd);
+void PrsDisable(t_Handle p_FmPcd);
+int PrsIsEnabled(t_Handle p_FmPcd);
+
+static t_Error DsarCheckParams(t_FmPortDsarParams *params, t_FmPortDsarTablesSizes *sizes)
+{
+ bool macInit = FALSE;
+ uint8_t mac[6];
+ int i;
+
+ // check table sizes
+ if (params->p_AutoResArpInfo && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Arp table size exceeds the configured maximum size."));
+ if (params->p_AutoResEchoIpv4Info && sizes->maxNumOfEchoIpv4Entries < params->p_AutoResEchoIpv4Info->tableSize)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
+ if (params->p_AutoResNdpInfo && sizes->maxNumOfNdpEntries < params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: NDP table size exceeds the configured maximum size."));
+ if (params->p_AutoResEchoIpv6Info && sizes->maxNumOfEchoIpv6Entries < params->p_AutoResEchoIpv6Info->tableSize)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
+ if (params->p_AutoResSnmpInfo && sizes->maxNumOfSnmpOidEntries < params->p_AutoResSnmpInfo->oidsTblSize)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
+ if (params->p_AutoResSnmpInfo && sizes->maxNumOfSnmpIPV4Entries < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
+ if (params->p_AutoResSnmpInfo && sizes->maxNumOfSnmpIPV6Entries < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
+ if (params->p_AutoResFilteringInfo)
+ {
+ if (sizes->maxNumOfIpProtFiltering < params->p_AutoResFilteringInfo->ipProtTableSize)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: ip filter table size exceeds the configured maximum size."));
+ if (sizes->maxNumOfTcpPortFiltering < params->p_AutoResFilteringInfo->udpPortsTableSize)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: udp filter table size exceeds the configured maximum size."));
+ if (sizes->maxNumOfUdpPortFiltering < params->p_AutoResFilteringInfo->tcpPortsTableSize)
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: tcp filter table size exceeds the configured maximum size."));
+ }
+ // check only 1 MAC address is configured (this is what ucode currently supports)
+ if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
+ {
+ i = 0;
+ if (!macInit)
+ {
+ memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
+ i = 1;
+ macInit = TRUE;
+ }
+ for (; i < params->p_AutoResArpInfo->tableSize; i++)
+ if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Only 1 mac address is currently supported."));
+ }
+ if (params->p_AutoResEchoIpv4Info && params->p_AutoResEchoIpv4Info->tableSize)
+ {
+ i = 0;
+ if (!macInit)
+ {
+ memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac, 6);
+ i = 1;
+ macInit = TRUE;
+ }
+ for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
+ if (memcmp(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Only 1 mac address is currently supported."));
+ }
+ if (params->p_AutoResEchoIpv6Info && params->p_AutoResEchoIpv6Info->tableSize)
+ {
+ i = 0;
+ if (!macInit)
+ {
+ memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac, 6);
+ i = 1;
+ macInit = TRUE;
+ }
+ for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
+ if (memcmp(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Only 1 mac address is currently supported."));
+ }
+ if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
+ {
+ i = 0;
+ if (!macInit)
+ {
+ memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac, 6);
+ i = 1;
+ macInit = TRUE;
+ }
+ for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
+ if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac, 6))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Only 1 mac address is currently supported."));
+ }
+ if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
+ {
+ i = 0;
+ if (!macInit)
+ {
+ memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
+ i = 1;
+ macInit = TRUE;
+ }
+ for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
+ if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac, 6))
+ RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("DSAR: Only 1 mac address is currently supported."));
+ }
+ return E_OK;
+}
+
+static int GetBERLen(uint8_t* buf)
+{
+ if (*buf & 0x80)
+ {
+ if ((*buf & 0x7F) == 1)
+ return buf[1];
+ else
+ return *(uint16_t*)&buf[1]; // assuming max len is 2
+ }
+ else
+ return buf[0];
+}
+#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
+
+t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
+{
+ int i,j;
+ t_Error err;
+ uint32_t nia;
+ t_FmPort *p_FmPort= (t_FmPort *)h_FmPortRx;
+ t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
+ t_DsarArpDescriptor *ArpDescriptor;
+ t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
+ t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
+ t_DsarNdDescriptor* NDDescriptor;
+ uint64_t fmMuramVirtBaseAddr = (uint64_t)XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
+ uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
+ t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
+ struct arOffsets* of;
+ uint8_t tmp = 0;
+ t_Handle *h_FmPcd;
+
+ err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
+ if (err != E_OK)
+ return err;
+
+ p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
+ of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
+ IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
+
+ // common
+ WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
+ nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
+ if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
+ WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
+ else
+ WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
+ WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
+
+ // ARP
+ if (params->p_AutoResArpInfo)
+ {
+ t_DsarArpBindingEntry* arp_bindings;
+ ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
+ WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
+ arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
+ WRITE_UINT16(ArpDescriptor->control, 0);
+ if (params->p_AutoResArpInfo->tableSize)
+ {
+ t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
+ WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
+ WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
+ WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
+
+ for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
+ {
+ WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
+ if (arp_entry[i].isVlan)
+ WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
+ }
+ WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
+ }
+ WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
+ sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
+ }
+
+ // ICMPV4
+ if (params->p_AutoResEchoIpv4Info)
+ {
+ t_DsarIcmpV4BindingEntry* icmpv4_bindings;
+ ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
+ WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
+ icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
+ WRITE_UINT16(ICMPV4Descriptor->control, 0);
+ if (params->p_AutoResEchoIpv4Info->tableSize)
+ {
+ t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
+ WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
+ WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
+ WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
+
+ for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
+ {
+ WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
+ if (arp_entry[i].isVlan)
+ WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
+ }
+ WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
+ }
+ WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
+ sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
+ }
+
+ // ICMPV6
+ if (params->p_AutoResEchoIpv6Info)
+ {
+ t_DsarIcmpV6BindingEntry* icmpv6_bindings;
+ ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
+ WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
+ icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
+ WRITE_UINT16(ICMPV6Descriptor->control, 0);
+ if (params->p_AutoResEchoIpv6Info->tableSize)
+ {
+ t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
+ WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
+ WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
+ WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
+
+ for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
+ {
+ for (j = 0; j < 4; j++)
+ WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
+ if (ndp_entry[i].isVlan)
+ WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
+ }
+ WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
+ }
+ WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
+ sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
+ }
+
+ // ND
+ if (params->p_AutoResNdpInfo)
+ {
+ t_DsarIcmpV6BindingEntry* icmpv6_bindings;
+ NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
+ WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
+ icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
+ WRITE_UINT16(NDDescriptor->control, 0);
+ if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
+ {
+ t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
+ WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
+ WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
+ WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
+ + params->p_AutoResNdpInfo->tableSizeTmp);
+
+ for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
+ {
+ for (j = 0; j < 4; j++)
+ WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
+ if (ndp_entry[i].isVlan)
+ WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
+ }
+ ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
+ for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
+ {
+ for (j = 0; j < 4; j++)
+ WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
+ if (ndp_entry[i].isVlan)
+ WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
+ }
+ WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
+ }
+ WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
+ * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
+ - fmMuramVirtBaseAddr);
+ WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
+ }
+
+ // SNMP
+ if (params->p_AutoResSnmpInfo)
+ {
+ t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
+ t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
+ t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
+ t_OidsTblEntry* snmpOid;
+ uint8_t *charPointer;
+ int len;
+ t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
+ WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
+ WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
+ WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
+ snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
+ if (snmpSrc->numOfIpv4Addresses)
+ {
+ t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
+ WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
+ for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
+ {
+ WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
+ if (snmpIpv4AddrSrc[i].isVlan)
+ WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
+ }
+ WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
+ }
+ snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
+ + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
+ if (snmpSrc->numOfIpv6Addresses)
+ {
+ t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
+ WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
+ for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
+ {
+ for (j = 0; j < 4; j++)
+ WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
+ if (snmpIpv6AddrSrc[i].isVlan)
+ WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
+ }
+ WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
+ }
+ snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
+ + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
+ charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
+ + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
+ len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
+ Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
+ WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
+ charPointer += len;
+ len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
+ Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
+ WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
+ charPointer += len;
+ WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
+ WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
+ for (i = 0; i < snmpSrc->oidsTblSize; i++)
+ {
+ WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
+ WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
+ Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].p_Oid, snmpSrc->p_OidsTbl[i].oidSize);
+ WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
+ charPointer += snmpSrc->p_OidsTbl[i].oidSize;
+ if (snmpSrc->p_OidsTbl[i].resSize <= 4)
+ WRITE_UINT32(snmpOid->resValOrPtr, snmpSrc->p_OidsTbl[i].resValOrPtr);
+ else
+ {
+ Mem2IOCpy32(charPointer, UINT_TO_PTR(snmpSrc->p_OidsTbl[i].resValOrPtr), snmpSrc->p_OidsTbl[i].resSize);
+ WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
+ charPointer += snmpSrc->p_OidsTbl[i].resSize;
+ }
+ snmpOid++;
+ }
+ charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
+ WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
+ }
+
+ // filtering
+ if (params->p_AutoResFilteringInfo)
+ {
+ if (params->p_AutoResFilteringInfo->ipProtDropOnHit)
+ tmp |= IP_PROT_TBL_PASS_MASK;
+ if (params->p_AutoResFilteringInfo->udpPortDropOnHit)
+ tmp |= UDP_PORT_TBL_PASS_MASK;
+ if (params->p_AutoResFilteringInfo->tcpPortDropOnHit)
+ tmp |= TCP_PORT_TBL_PASS_MASK;
+ WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
+
+ // ip filtering
+ if (params->p_AutoResFilteringInfo->ipProtTableSize)
+ {
+ uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
+ WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
+ for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
+ WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
+ WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
+ }
+
+ // udp filtering
+ if (params->p_AutoResFilteringInfo->udpPortsTableSize)
+ {
+ t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
+ WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
+ for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
+ {
+ WRITE_UINT32(udp_tbl[i].Ports,
+ (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
+ params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
+ WRITE_UINT32(udp_tbl[i].PortsMask,
+ (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
+ params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
+ }
+ WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
+ }
+
+ // tcp filtering
+ if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
+ {
+ t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
+ WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
+ for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
+ {
+ WRITE_UINT32(tcp_tbl[i].Ports,
+ (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
+ params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
+ WRITE_UINT32(tcp_tbl[i].PortsMask,
+ (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
+ params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
+ }
+ WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
+ }
+ }
+ // common stats
+ WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
+
+ // get into Deep Sleep sequence:
+ // Stage 6: configure tx port to im
+ p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
+ WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg) | BMI_PORT_CFG_IM);
+ // ????
+ p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
+ WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
+ // Stage 7:echo
+ p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
+ p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
+ h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
+ if (!PrsIsEnabled(h_FmPcd))
+ {
+ p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
+ PrsEnable(h_FmPcd);
+ }
+ else
+ p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
+
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
+ // Stage 8: We don't support magic packet for now.
+ // Stage 9: Accumulate mode
+// WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg) | BMI_PORT_CFG_AM);
+ ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
+ return E_OK;
+}
+
+void FM_PORT_Dsar_DumpRegs()
+{
+ uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
+ DUMP_MEMORY(hh, 0x180);
+}
+
+void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
+{
+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
+ t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
+ if (p_FmPort->deepSleepVars.autoResOffsets)
+ {
+ XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
+ p_FmPort->deepSleepVars.autoResOffsets = 0;
+ }
+ if (p_FmPort->deepSleepVars.autoResMaxSizes)
+ {
+ XX_Free(p_FmPort->deepSleepVars.autoResMaxSizes);
+ p_FmPort->deepSleepVars.autoResMaxSizes = 0;
+ }
+
+ if (p_FmPort->deepSleepVars.dsarEnabledParser)
+ PrsDisable(FmGetPcd(p_FmPort->h_Fm));
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
+ WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
+ WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
+ WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
+}
+
+bool FM_PORT_IsInDsar(t_Handle h_FmPort)
+{
+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
+ return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
+}
+
+t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
+{
+ t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
+ struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
+ uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
+ uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
+ t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
+ t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
+ t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
+ t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
+ t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
+ t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
+ t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
+ t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
+ t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
+ t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
+ t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
+ stats->arpArCnt = arp_stats->arCnt;
+ stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
+ stats->ndpArCnt = nd_stats->arCnt;
+ stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
+ stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
+ stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
+ return E_OK;
+}
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.h
index d4cc285..7568258 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.h
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.h
@@ -46,7 +46,7 @@
#include "fm_common.h"
#include "fm_sp_common.h"
#include "fsl_fman_sp.h"
-
+#include "fm_port_ext.h"
#include "fsl_fman_port.h"
#define __ERR_MODULE__ MODULE_FM_PORT
@@ -854,6 +854,16 @@ typedef struct t_FmPortRxPoolsParams
uint16_t largestBufSize;
} t_FmPortRxPoolsParams;
+typedef struct t_FmPortDsarVars {
+ t_Handle *autoResOffsets;
+ t_FmPortDsarTablesSizes *autoResMaxSizes;
+ uint32_t fmbm_tcfg;
+ uint32_t fmbm_tcmne;
+ uint32_t fmbm_rfne;
+ uint32_t fmbm_rfpne;
+ bool dsarEnabledParser;
+} t_FmPortDsarVars;
+
typedef struct {
struct fman_port port;
t_Handle h_Fm;
@@ -919,7 +929,7 @@ typedef struct {
e_FmPortGprFuncType gprFunc;
t_FmPcdCtrlParamsPage *p_ParamsPage;
#endif /* (DPAA_VERSION >= 11) */
-
+ t_FmPortDsarVars deepSleepVars;
t_FmPortDriverParam *p_FmPortDriverParam;
} t_FmPort;
@@ -970,5 +980,7 @@ static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
return 0;
}
+void FM_PORT_Dsar_DumpRegs(void);
+
#endif /* __FM_PORT_H */
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port_dsar.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port_dsar.h
new file mode 100755
index 0000000..95619ef
--- /dev/null
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port_dsar.h
@@ -0,0 +1,494 @@
+/*
+ * Copyright 2008-2012 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************//**
+ @File fm_port_dsar.h
+
+ @Description Deep Sleep Auto Response project - common module header file.
+
+ Author - Eyal Harari
+
+ @Cautions See the FMan Controller spec and design document for more information.
+*//***************************************************************************/
+
+#ifndef __FM_PORT_DSAR_H_
+#define __FM_PORT_DSAR_H_
+
+#define DSAR_GETSER_MASK 0xFF0000FF
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(push,1)
+#endif /* defined(__MWERKS__) && ... */
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
+ uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
+ uint16_t reserved;
+} _PackedType t_DsarArpBindingEntry;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
+ Refer to the FMan Controller spec for more details.
+ 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
+ 0x04 ECHO_CNT Echo counter
+ 0x08 CD_CNT Conflict Detection counter
+ 0x0C AR_CNT Auto-Response counter
+ 0x10 RATM_CNT Replies Addressed To Me counter
+ 0x14 UKOP_CNT Unknown Operation counter
+ 0x18 NMTP_CNT Not my TPA counter
+ 0x1C NMVLAN_CNT Not My VLAN counter
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
+ uint32_t echoCnt; /**< Echo counter. */
+ uint32_t cdCnt; /**< Conflict Detection counter. */
+ uint32_t arCnt; /**< Auto-Response counter. */
+ uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
+ uint32_t ukopCnt; /**< Unknown Operation counter. */
+ uint32_t nmtpCnt; /**< Not my TPA counter. */
+ uint32_t nmVlanCnt; /**< Not My VLAN counter */
+} _PackedType t_DsarArpStatistics;
+
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
+ 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
+ 0x2 0-15 NumOfBindings Number of entries in the binding list.
+ 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
+ 0x6 0-15
+ 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
+ 0xA 0-15
+ 0xC 0-15 Reserved Reserved. Must be cleared.
+ 0xE 015
+
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
+ uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
+ uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
+ uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
+ uint32_t reserved1; /**< Reserved. */
+} _PackedType t_DsarArpDescriptor;
+
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
+ uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
+ uint16_t reserved;
+} _PackedType t_DsarIcmpV4BindingEntry;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
+ Refer to the FMan Controller spec for more details.
+ 0x00 INVAL_CNT Invalid ICMPv4 header counter
+ 0x04 NMVLAN_CNT Not My VLAN counter
+ 0x08 NMIP_CNT Not My IP counter
+ 0x0C AR_CNT Auto-Response counter
+ 0x10 CSERR_CNT Checksum Error counter
+ 0x14 Reserved Reserved
+ 0x18 Reserved Reserved
+ 0x1C Reserved Reserved
+
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
+ uint32_t nmVlanCnt; /**< Not My VLAN counter */
+ uint32_t nmIpCnt; /**< Not My IP counter */
+ uint32_t arCnt; /**< Auto-Response counter */
+ uint32_t cserrCnt; /**< Checksum Error counter */
+ uint32_t reserved0; /**< Reserved */
+ uint32_t reserved1; /**< Reserved */
+ uint32_t reserved2; /**< Reserved */
+} _PackedType t_DsarIcmpV4Statistics;
+
+
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response ICMPv4 Descriptor
+ 0x0 0-15 Control bits [0-15]
+ 0x2 0-15 NumOfBindings Number of entries in the binding list.
+ 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
+ 0x6 0-15
+ 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
+ 0xA 0-15
+ 0xC 0-15 Reserved Reserved. Must be cleared.
+ 0xE 015
+
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint16_t control; /** Control bits [0-15]. */
+ uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
+ uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
+ uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
+ uint32_t reserved1; /**< Reserved. */
+} _PackedType t_DsarIcmpV4Descriptor;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
+ The 4 left-most bits (15:12) of the VlanId parameter are control flags.
+ Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
+ Flags[0] (VlanId[12]): Temporary address.
+ • 0 - Assigned IP address.
+ • 1- Temporary (tentative) IP address.
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
+ uint16_t resFlags:4; /*!< reserved flags. should be cleared */
+ uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
+ /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
+ uint16_t reserved;
+} _PackedType t_DsarIcmpV6BindingEntry;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
+ Refer to the FMan Controller spec for more details.
+ 0x00 INVAL_CNT Invalid ICMPv4 header counter
+ 0x04 NMVLAN_CNT Not My VLAN counter
+ 0x08 NMIP_CNT Not My IP counter
+ 0x0C AR_CNT Auto-Response counter
+ 0x10 CSERR_CNT Checksum Error counter
+ 0x14 MCAST_CNT Multicast counter
+ 0x18 Reserved Reserved
+ 0x1C Reserved Reserved
+
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
+ uint32_t nmVlanCnt; /**< Not My VLAN counter */
+ uint32_t nmIpCnt; /**< Not My IP counter */
+ uint32_t arCnt; /**< Auto-Response counter */
+ uint32_t reserved1; /**< Reserved */
+ uint32_t reserved2; /**< Reserved */
+ uint32_t reserved3; /**< Reserved */
+ uint32_t reserved4; /**< Reserved */
+} _PackedType t_DsarIcmpV6Statistics;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
+ 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
+ 0x04 NMVLAN_CNT Not My VLAN counter
+ 0x08 NMIP_CNT Not My IP counter
+ 0x0C AR_CNT Auto-Response counter
+ 0x10 CSERR_CNT Checksum Error counter
+ 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
+ 0x18 NMMCAST_CNT Not My Multicast group counter
+ 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
+ Address of a packet that its source IP address is a unicast address, but the ICMPv6
+ Source Link-layer Address option is omitted
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
+ uint32_t nmVlanCnt; /**< Not My VLAN counter */
+ uint32_t nmIpCnt; /**< Not My IP counter */
+ uint32_t arCnt; /**< Auto-Response counter */
+ uint32_t reserved1; /**< Reserved */
+ uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
+ uint32_t nmmcastCnt; /**< Not My Multicast group counter */
+ uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
+} _PackedType t_NdStatistics;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response ICMPv6 Descriptor
+ 0x0 0-15 Control bits [0-15]
+ 0x2 0-15 NumOfBindings Number of entries in the binding list.
+ 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
+ 0x6 0-15
+ 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
+ 0xA 0-15
+ 0xC 0-15 Reserved Reserved. Must be cleared.
+ 0xE 015
+
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint16_t control; /** Control bits [0-15]. */
+ uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
+ uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
+ uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
+ uint32_t reserved1; /**< Reserved. */
+} _PackedType t_DsarIcmpV6Descriptor;
+
+
+/**************************************************************************//**
+ @Description Internet Control Message Protocol (ICMPv6) Echo message header
+ The fields names are taken from RFC 4443.
+*//***************************************************************************/
+/* 0 1 2 3 */
+/* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 */
+/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
+/* | Type | Code | Checksum | */
+/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
+/* | Identifier | Sequence Number | */
+/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
+/* | Data ... */
+/* +-+-+-+-+- */
+typedef _Packed struct
+{
+ uint8_t type;
+ uint8_t code;
+ uint16_t checksum;
+ uint16_t identifier;
+ uint16_t sequenceNumber;
+} _PackedType t_IcmpV6EchoHdr;
+
+/**************************************************************************//**
+ @Description Internet Control Message Protocol (ICMPv6)
+ Neighbor Solicitation/Advertisement header
+ The fields names are taken from RFC 4861.
+ The R/S/O fields are valid for Neighbor Advertisement only
+*//***************************************************************************/
+/* 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type | Code | Checksum |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |R|S|O| Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * + +
+ * | |
+ * + Target Address +
+ * | |
+ * + +
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Options ...
+ * +-+-+-+-+-+-+-+-+-+-+-+-
+ *
+ * Options Format:
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type | Length | Link-Layer Address ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Link-Layer Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+typedef _Packed struct
+{
+ uint8_t type;
+ uint8_t code;
+ uint16_t checksum;
+ uint32_t router:1;
+ uint32_t solicited:1;
+ uint32_t override:1;
+ uint32_t reserved:29;
+ uint32_t targetAddr[4];
+ uint8_t optionType;
+ uint8_t optionLength;
+ uint8_t linkLayerAddr[6];
+} _PackedType t_IcmpV6NdHdr;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response ICMPv6 Descriptor
+ 0x0 0-15 Control bits [0-15]
+ 0x2 0-15 NumOfBindings Number of entries in the binding list.
+ 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
+ 0x6 0-15
+ 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
+ 0xA 0-15
+ 0xC 0-15 Reserved Reserved. Must be cleared.
+ 0xE 015
+
+*//***************************************************************************/
+typedef _Packed struct
+{
+ uint16_t control; /** Control bits [0-15]. */
+ uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
+ uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
+ uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
+ uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
+} _PackedType t_DsarNdDescriptor;
+
+/**************************************************************************//**
+@Description Deep Sleep Auto Response SNMP OIDs table entry
+
+*//***************************************************************************/
+typedef struct {
+ uint16_t oidSize; /**< Size in octets of the OID. */
+ uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
+ uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
+ uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
+ uint32_t reserved;
+} t_OidsTblEntry;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+typedef struct
+{
+ uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
+ uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
+ uint16_t reserved;
+} t_DsarSnmpIpv4AddrTblEntry;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+#pragma pack(push,1)
+typedef struct
+{
+ uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
+ uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
+ uint16_t reserved;
+} t_DsarSnmpIpv6AddrTblEntry;
+#pragma pack(pop)
+
+/**************************************************************************//**
+@Description Deep Sleep Auto Response SNMP statistics table
+
+*//***************************************************************************/
+typedef struct {
+ uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
+ uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
+ uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
+ uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
+ uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
+} t_DsarSnmpStatistics;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response SNMP Descriptor
+
+*//***************************************************************************/
+typedef struct
+{
+ uint16_t control; /**< Control bits [0-15]. */
+ uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
+ uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
+ uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
+ uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
+ uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
+ uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
+ uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
+ uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
+ uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
+ uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
+} t_DsarSnmpDescriptor;
+
+/**************************************************************************//**
+@Description Deep Sleep Auto Response (Common) Statistics
+
+*//***************************************************************************/
+typedef _Packed struct {
+ uint32_t dsarDiscarded;
+ uint32_t dsarErrDiscarded;
+ uint32_t dsarFragDiscarded;
+ uint32_t dsarTunnelDiscarded;
+ uint32_t dsarArpDiscarded;
+ uint32_t dsarIpDiscarded;
+ uint32_t dsarTcpDiscarded;
+ uint32_t dsarUdpDiscarded;
+ uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
+ uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
+ uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
+} _PackedType t_ArStatistics;
+
+
+/**************************************************************************//**
+@Description Deep Sleep Auto Response TCP/UDP port filter table entry
+
+*//***************************************************************************/
+typedef _Packed struct {
+ uint32_t Ports;
+ uint32_t PortsMask;
+} _PackedType t_PortTblEntry;
+
+
+
+/**************************************************************************//**
+@Description Deep Sleep Auto Response Common Parameters Descriptor
+
+*//***************************************************************************/
+typedef _Packed struct {
+ uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
+ uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
+ uint16_t res1; /* 0x00 16-31 Reserved */
+ uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
+ uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
+ uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
+ uint8_t res2; /* 0x10 0-7 Reserved */
+ uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
+ uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
+ uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
+ uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
+ uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
+ uint8_t res3; /* 0x14 24-31 Reserved */
+ uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
+ uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
+ uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
+ uint32_t res4; /* 0x24 Reserved */
+ uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
+ uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
+ uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
+ uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
+ uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
+ uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
+} _PackedType t_ArCommonDesc;
+
+#if defined(__MWERKS__) && !defined(__GNUC__)
+#pragma pack(pop)
+#endif /* defined(__MWERKS__) && ... */
+
+/* t_ArCommonDesc.filterControl bits */
+#define IP_PROT_TBL_PASS_MASK 0x08
+#define UDP_PORT_TBL_PASS_MASK 0x04
+#define TCP_PORT_TBL_PASS_MASK 0x02
+
+/* Offset of TCF flags within TCP packet */
+#define TCP_FLAGS_OFFSET 12
+
+
+#endif /* __FM_PORT_DSAR_H_ */
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c
index 5bb8282..17ac17e 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c
@@ -5201,3 +5201,8 @@ t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
return E_OK;
}
+
+t_Handle FmGetPcd(t_Handle h_Fm)
+{
+ return ((t_Fm*)h_Fm)->h_Pcd;
+}
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h
index 0d7bf55..a015900 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h
@@ -658,6 +658,8 @@ bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
void FmPcdLockUnlockAll(t_Handle h_FmPcd);
t_Error FmPcdHcSync(t_Handle h_FmPcd);
+t_Handle FmGetPcd(t_Handle h_Fm);
+
/***********************************************************************/
/* Common API for FM-PCD KG module */
diff --git a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h
index 4d05857..3a62b8d 100644
--- a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h
+++ b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_port_ext.h
@@ -45,7 +45,6 @@
#include "fm_ext.h"
#include "net_ext.h"
-
/**************************************************************************//**
@Group FM_grp Frame Manager API
@@ -435,9 +434,47 @@ typedef struct t_FmPortPerformanceCnt {
uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
} t_FmPortPerformanceCnt;
+/**************************************************************************//**
+ @Description A structure for defining the sizes of the Deep Sleep
+ the Auto Response tables
+*//***************************************************************************/
+typedef struct t_FmPortDsarTablesSizes
+{
+ uint16_t maxNumOfArpEntries;
+ uint16_t maxNumOfEchoIpv4Entries;
+ uint16_t maxNumOfNdpEntries;
+ uint16_t maxNumOfEchoIpv6Entries;
+ uint16_t maxNumOfSnmpIPV4Entries;
+ uint16_t maxNumOfSnmpIPV6Entries;
+ uint16_t maxNumOfSnmpOidEntries;
+ uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
+
+ uint16_t maxNumOfIpProtFiltering;
+ uint16_t maxNumOfTcpPortFiltering;
+ uint16_t maxNumOfUdpPortFiltering;
+} t_FmPortDsarTablesSizes;
/**************************************************************************//**
+ @Function FM_PORT_ConfigDsarSupport
+
+ @Description This function will allocate the amount of MURAM needed for
+ this max number of entries for Deep Sleep Auto Response.
+ it will calculate all needed MURAM for autoresponse including
+ necesary common stuff.
+
+
+ @Param[in] h_FmPort A handle to a FM Port module.
+ @Param[in] params A pointer to a structure containing the maximum
+ sizes of the auto response tables
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
+
+/**************************************************************************//**
@Function FM_PORT_ConfigNumOfOpenDmas
@Description Calling this routine changes the max number of open DMA's
@@ -1277,6 +1314,256 @@ typedef struct t_FmPortCongestionGrps {
#endif /* (DPAA_VERSION >= 11) */
} t_FmPortCongestionGrps;
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response ARP Entry
+*//***************************************************************************/
+typedef struct t_FmPortDsarArpEntry
+{
+ uint32_t ipAddress;
+ uint8_t mac[6];
+ bool isVlan;
+ uint16_t vid;
+} t_FmPortDsarArpEntry;
+
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response ARP info
+*//***************************************************************************/
+typedef struct t_FmPortDsarArpInfo
+{
+ uint8_t tableSize;
+ t_FmPortDsarArpEntry *p_AutoResTable;
+ bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
+} t_FmPortDsarArpInfo;
+
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response NDP Entry
+*//***************************************************************************/
+typedef struct t_FmPortDsarNdpEntry
+{
+ uint32_t ipAddress[4];
+ uint8_t mac[6];
+ bool isVlan;
+ uint16_t vid;
+} t_FmPortDsarNdpEntry;
+
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response NDP info
+*//***************************************************************************/
+typedef struct t_FmPortDsarNdpInfo
+{
+ uint32_t multicastGroup;
+
+ uint8_t tableSizeAssigned;
+ t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
+ Note that all IP adresses must be from the same multicast group.
+ This will be checked and if not operation will fail. */
+ uint8_t tableSizeTmp;
+ t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
+ Note that all temp IP adresses must be from the same multicast group.
+ This will be checked and if not operation will fail. */
+
+ bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
+
+} t_FmPortDsarNdpInfo;
+
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response ICMPV4 info
+*//***************************************************************************/
+typedef struct t_FmPortDsarEchoIpv4Info
+{
+ uint8_t tableSize;
+ t_FmPortDsarArpEntry *p_AutoResTable;
+} t_FmPortDsarEchoIpv4Info;
+
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response ICMPV6 info
+*//***************************************************************************/
+typedef struct t_FmPortDsarEchoIpv6Info
+{
+ uint8_t tableSize;
+ t_FmPortDsarNdpEntry *p_AutoResTable;
+} t_FmPortDsarEchoIpv6Info;
+
+/**************************************************************************//**
+@Description Deep Sleep Auto Response SNMP OIDs table entry
+
+*//***************************************************************************/
+typedef struct {
+ uint16_t oidSize; /**< Size in octets of the OID. */
+ uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
+ uint8_t *p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
+ uint64_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
+} t_FmPortDsarOidsEntry;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+typedef struct
+{
+ uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
+ bool isVlan;
+ uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
+} t_FmPortDsarSnmpIpv4AddrTblEntry;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+typedef struct
+{
+ uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
+ bool isVlan;
+ uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
+} t_FmPortDsarSnmpIpv6AddrTblEntry;
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response SNMP Descriptor
+
+*//***************************************************************************/
+typedef struct
+{
+ uint16_t control; /**< Control bits [0-15]. */
+ uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
+ uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
+ uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
+ t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
+ t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
+ uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
+ uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
+ t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
+ uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
+} t_FmPortDsarSnmpInfo;
+
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response filtering Entry
+*//***************************************************************************/
+typedef struct t_FmPortDsarFilteringEntry
+{
+ uint16_t srcPort;
+ uint16_t dstPort;
+ uint16_t srcPortMask;
+ uint16_t dstPortMask;
+} t_FmPortDsarFilteringEntry;
+
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response filtering info
+*//***************************************************************************/
+typedef struct t_FmPortDsarFilteringInfo
+{
+ /* IP protocol filtering parameters */
+ uint8_t ipProtTableSize;
+ uint8_t *p_IpProtTablePtr;
+ bool ipProtDropOnHit; /* when TRUE, hit in the table will cause the packet to be droped,
+ miss will pass the packet to UDP/TCP filters if needed and if not
+ to the classification tree. If the classification tree will pass
+ the packet to a queue it will cause a wake interupt.
+ When FALSE it the other way around. */
+ /* UDP port filtering parameters */
+ uint8_t udpPortsTableSize;
+ t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
+ bool udpPortDropOnHit; /* when TRUE, hit in the table will cause the packet to be droped,
+ miss will pass the packet to classification tree.
+ If the classification tree will pass the packet to a queue it
+ will cause a wake interupt.
+ When FALSE it the other way around. */
+ /* TCP port filtering parameters */
+ uint16_t tcpFlagsMask;
+ uint8_t tcpPortsTableSize;
+ t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
+ bool tcpPortDropOnHit; /* when TRUE, hit in the table will cause the packet to be droped,
+ miss will pass the packet to classification tree.
+ If the classification tree will pass the packet to a queue it
+ will cause a wake interupt.
+ When FALSE it the other way around. */
+} t_FmPortDsarFilteringInfo;
+
+/**************************************************************************//**
+ @Description Structure for Deep Sleep Auto Response parameters
+*//***************************************************************************/
+typedef struct t_FmPortDsarParams
+{
+ t_Handle h_FmPortTx;
+ t_FmPortDsarArpInfo *p_AutoResArpInfo;
+ t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
+ t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
+ t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
+ t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
+ t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
+} t_FmPortDsarParams;
+
+/**************************************************************************//**
+ @Function FM_PORT_EnterDsar
+
+ @Description Enter Deep Sleep Auto Response mode.
+ This function write the apropriate values to in the relevant
+ tables in the MURAM. It then set the Tx port in independent
+ mode as needed and redirect the receive flow to go through the
+ Dsar Fman-ctrl code
+
+ Calling this routine invalidates the descriptor.
+
+ @Param[in] h_FmPortRx - FM PORT module descriptor
+ @Param[in] params - Auto Response parameters
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_Init().
+*//***************************************************************************/
+t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
+
+/**************************************************************************//**
+ @Function FM_PORT_ExitDsar
+
+ @Description Exit Deep Sleep Auto Response mode.
+ This function reverse the AR mode and put the ports back into
+ their original wake mode
+
+ @Param[in] h_FmPortRx - FM PORT Rx module descriptor
+ @Param[in] h_FmPortTx - FM PORT Tx module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+
+ @Cautions Allowed only following FM_PORT_EnterDsar().
+*//***************************************************************************/
+void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
+
+/**************************************************************************//**
+ @Function FM_PORT_IsInDsar
+
+ @Description This function returns TRUE if the port was set as Auto Response
+ and FALSE if not. Once Exit AR mode it will return FALSE as well
+ until re-enabled once more.
+
+ @Param[in] h_FmPort - FM PORT module descriptor
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+bool FM_PORT_IsInDsar(t_Handle h_FmPort);
+
+typedef struct t_FmPortDsarStats
+{
+ uint32_t arpArCnt;
+ uint32_t echoIcmpv4ArCnt;
+ uint32_t ndpArCnt;
+ uint32_t echoIcmpv6ArCnt;
+ uint32_t snmpGetCnt;
+ uint32_t snmpGetNextCnt;
+} t_FmPortDsarStats;
+
+/**************************************************************************//**
+ @Function FM_PORT_GetDsarStats
+
+ @Description Return statistics for Deep Sleep Auto Response
+
+ @Param[in] h_FmPortRx - FM PORT module descriptor
+ @Param[out] stats - structure containing the statistics counters
+
+ @Return E_OK on success; Error code otherwise.
+*//***************************************************************************/
+t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
/**************************************************************************//**
diff --git a/drivers/net/ethernet/freescale/fman/inc/flib/fsl_fman_prs.h b/drivers/net/ethernet/freescale/fman/inc/flib/fsl_fman_prs.h
index 30d2ecf..b18997d 100644
--- a/drivers/net/ethernet/freescale/fman/inc/flib/fsl_fman_prs.h
+++ b/drivers/net/ethernet/freescale/fman/inc/flib/fsl_fman_prs.h
@@ -96,6 +96,7 @@ void fman_prs_defconfig(struct fman_prs_cfg *cfg);
int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
void fman_prs_enable(struct fman_prs_regs *regs);
void fman_prs_disable(struct fman_prs_regs *regs);
+int fman_prs_is_enabled(struct fman_prs_regs *regs);
void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
#endif /* __FSL_FMAN_PRS_H */
diff --git a/drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_fsl_fman.h b/drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_fsl_fman.h
index f4fabbe..3a66493 100644
--- a/drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_fsl_fman.h
+++ b/drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_fsl_fman.h
@@ -350,6 +350,204 @@ int fm_port_set_rate_limit(struct fm_port *port,
*//***************************************************************************/
int fm_port_del_rate_limit(struct fm_port *port);
+struct auto_res_tables_sizes
+{
+ uint16_t max_num_of_arp_entries;
+ uint16_t max_num_of_echo_ipv4_entries;
+ uint16_t max_num_of_ndp_entries;
+ uint16_t max_num_of_echo_ipv6_entries;
+ uint16_t max_num_of_snmp_ipv4_entries;
+ uint16_t max_num_of_snmp_ipv6_entries;
+ uint16_t max_num_of_snmp_oid_entries;
+ uint16_t max_num_of_snmp_char; /* total amount of character needed
+ for the snmp table */
+ uint16_t max_num_of_ip_prot_filtering;
+ uint16_t max_num_of_tcp_port_filtering;
+ uint16_t max_num_of_udp_port_filtering;
+};
+/* ARP */
+struct auto_res_arp_entry
+{
+ uint32_t ip_address;
+ uint8_t mac[6];
+ bool is_vlan;
+ uint16_t vid;
+};
+struct auto_res_arp_info
+{
+ uint8_t table_size;
+ struct auto_res_arp_entry *auto_res_table;
+ bool enable_conflict_detection; /* when TRUE
+ Conflict Detection will be checked and wake the host if
+ needed */
+};
+
+/* NDP */
+struct auto_res_ndp_entry
+{
+ uint32_t ip_address[4];
+ uint8_t mac[6];
+ bool is_vlan;
+ uint16_t vid;
+};
+struct auto_res_ndp_info
+{
+ uint32_t multicast_group;
+ uint8_t table_size_assigned;
+ struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
+ refer to solicitation IP addresses. Note that all IP adresses
+ must be from the same multicast group. This will be checked and
+ if not operation will fail. */
+ uint8_t table_size_tmp;
+ struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
+ refer to temp IP addresses. Note that all temp IP adresses must
+ be from the same multicast group. This will be checked and if
+ not operation will fail. */
+
+ bool enable_conflict_detection; /* when TRUE
+ Conflict Detection will be checked and wake the host if
+ needed */
+};
+
+/* ICMP ECHO */
+struct auto_res_echo_ipv4_info
+{
+ uint8_t table_size;
+ struct auto_res_arp_entry *auto_res_table;
+};
+
+struct auto_res_echo_ipv6_info
+{
+ uint8_t table_size;
+ struct auto_res_ndp_entry *auto_res_table;
+};
+
+/* SNMP */
+struct auto_res_snmp_entry
+{
+ uint16_t oidSize;
+ uint8_t *oidVal; /* only the oid string */
+ uint16_t resSize;
+ uint8_t *resVal; /* resVal will be the entire reply,
+ i.e. "Type|Length|Value" */
+};
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+struct auto_res_snmp_ipv4addr_tbl_entry
+{
+ uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
+ bool is_vlan;
+ uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
+};
+
+/**************************************************************************//**
+ @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
+ Refer to the FMan Controller spec for more details.
+*//***************************************************************************/
+struct auto_res_snmp_ipv6addr_tbl_entry
+{
+ uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
+ bool isVlan;
+ uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
+ /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
+};
+
+struct auto_res_snmp_info
+{
+ uint16_t control; /**< Control bits [0-15]. */
+ uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
+ uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
+ uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
+ struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
+ struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
+ char *community_read_write_string;
+ char *community_read_only_string;
+ struct auto_res_snmp_entry *oid_table;
+ uint32_t oid_table_size;
+};
+
+/* Filtering */
+struct auto_res_port_filtering_entry
+{
+ uint16_t src_port;
+ uint16_t dst_port;
+ uint16_t src_port_mask;
+ uint16_t dst_port_mask;
+};
+struct auto_res_filtering_info
+{
+ /* IP protocol filtering parameters */
+ uint8_t ip_prot_table_size;
+ uint8_t *ip_prot_table_ptr;
+ bool ip_prot_drop_on_hit; /* when TRUE, hit in the table will
+ cause the packet to be droped, miss will pass the packet to
+ UDP/TCP filters if needed and if not to the classification
+ tree. If the classification tree will pass the packet to a
+ queue it will cause a wake interupt. When FALSE it the other
+ way around. */
+ /* UDP port filtering parameters */
+ uint8_t udp_ports_table_size;
+ struct auto_res_port_filtering_entry *udp_ports_table_ptr;
+ bool udp_port_drop_on_hit; /* when TRUE, hit in the table will
+ cause the packet to be droped, miss will pass the packet to
+ classification tree. If the classification tree will pass the
+ packet to a queue it will cause a wake interupt. When FALSE it
+ the other way around. */
+ /* TCP port filtering parameters */
+ uint16_t tcp_flags_mask;
+ uint8_t tcp_ports_table_size;
+ struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
+ bool tcp_port_drop_on_hit; /* when TRUE, hit in the table will
+ cause the packet to be droped, miss will pass the packet to
+ classification tree. If the classification tree will pass the
+ packet to a queue it will cause a wake interupt. When FALSE it
+ the other way around. */
+};
+
+struct auto_res_port_params
+{
+ t_Handle h_FmPortTx;
+ struct auto_res_arp_info *p_auto_res_arp_info;
+ struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
+ struct auto_res_ndp_info *p_auto_res_ndp_info;
+ struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
+ struct auto_res_snmp_info *p_auto_res_snmp_info;
+ struct auto_res_filtering_info *p_auto_res_filtering_info;
+};
+
+struct auto_res_port_stats
+{
+ uint32_t arp_ar_cnt;
+ uint32_t echo_icmpv4_ar_cnt;
+ uint32_t ndp_ar_cnt;
+ uint32_t echo_icmpv6_ar_cnt;
+};
+
+int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
+ struct auto_res_tables_sizes *params);
+
+int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
+ struct auto_res_port_params *params);
+
+void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
+ struct fm_port *port_tx);
+
+bool fm_port_is_in_auto_res_mode(struct fm_port *port);
+
+struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
+ struct fm_port *port);
+
+int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
+ *stats);
+
+int fm_port_resume(struct fm_port *port);
+
+int fm_port_suspend(struct fm_port *port);
+
/**************************************************************************//**
@Function fm_mac_set_exception
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
index d161209..4cd0142 100644..100755
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
@@ -62,6 +62,7 @@
#include <sysdev/fsl_soc.h>
#include <linux/stat.h> /* For file access mask */
#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
/* NetCommSw Headers --------------- */
#include "std_ext.h"
@@ -707,7 +708,7 @@ static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
{
struct device_node *dev_node;
t_Error err = E_INVALID_VALUE;
- /*const uint32_t *uint32_prop;*/
+ const uint32_t *uint32_prop;
const char *str_prop;
int lenp;
@@ -723,6 +724,16 @@ static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
}
+ uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
+ &lenp);
+ if (uint32_prop) {
+ if (WARN_ON(lenp != sizeof(uint32_t)))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
+ (uint16_t)uint32_prop[0]/*tnumAgingPeriod*/);
+ }
+
if (err != E_OK)
RETURN_ERROR(MINOR, err, NO_MSG);
@@ -1327,6 +1338,78 @@ int fm_port_del_rate_limit(struct fm_port *port)
}
EXPORT_SYMBOL(fm_port_del_rate_limit);
+void FM_PORT_Dsar_DumpRegs(void);
+int ar_showmem(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ FM_PORT_Dsar_DumpRegs();
+ return 2;
+}
+
+struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
+ struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ return &p_LnxWrpFmPortDev->dsar_table_sizes;
+}
+EXPORT_SYMBOL(fm_port_get_autores_maxsize);
+
+int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
+ struct auto_res_port_params *params)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ /*Register other under /proc/autoresponse */
+ if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
+ return -EFAULT;
+
+ FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
+ return 0;
+}
+EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
+
+void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
+ struct fm_port *port_tx)
+{
+ FM_PORT_ExitDsar(port_rx, port_tx);
+}
+EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
+
+int fm_port_get_autores_stats(struct fm_port *port,
+ struct auto_res_port_stats *stats)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
+ return -EFAULT;
+ return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
+}
+EXPORT_SYMBOL(fm_port_get_autores_stats);
+
+int fm_port_suspend(struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
+ return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
+ else
+ return 0;
+}
+EXPORT_SYMBOL(fm_port_suspend);
+
+int fm_port_resume(struct fm_port *port)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
+ return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
+ else
+ return 0;
+}
+EXPORT_SYMBOL(fm_port_resume);
+
+bool fm_port_is_in_auto_res_mode(struct fm_port *port)
+{
+ return FM_PORT_IsInDsar(port);
+}
+EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
+
int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
e_FmMacExceptions exception, bool enable)
{
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h
index 30b6bf2..9c657ac 100644
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.h
@@ -118,6 +118,9 @@ typedef struct {
#if (DPAA_VERSION >= 11)
struct device_attribute *dev_attr_ipv4_opt;
#endif
+ struct device_attribute *dev_attr_dsar_regs;
+ struct device_attribute *dev_attr_dsar_mem;
+ struct auto_res_tables_sizes dsar_table_sizes;
} t_LnxWrpFmPortDev;
typedef struct {
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm_port.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm_port.c
index a8cd7bf..6e135a2 100644
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm_port.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm_port.c
@@ -54,6 +54,7 @@
#include "sprint_ext.h"
#include "fm_common.h"
+#include "lnxwrp_fsl_fman.h"
#include "fm_port_ext.h"
#if (DPAA_VERSION >= 11)
#include "fm_vsp_ext.h"
@@ -501,6 +502,7 @@ static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
/*const char *str_prop;*/
int lenp;
+
fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
if (!fm_node) /* no advance parameters for FMan */
return E_OK;
@@ -554,12 +556,61 @@ static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
if (uint32_prop) {
if (WARN_ON(lenp != sizeof(uint32_t)))
RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
-
if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
uint32_prop[0])) != E_OK)
RETURN_ERROR(MINOR, err, NO_MSG);
}
+ uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
+ &lenp);
+ if (uint32_prop) {
+
+ if (WARN_ON(lenp != sizeof(uint32_t)*8))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+ if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
+ e_FM_PORT_TYPE_RX) &&
+ (p_LnxWrpFmPortDev->settings.param.portType !=
+ e_FM_PORT_TYPE_RX_10G))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE,
+ ("Auto Response is an Rx port atribute."));
+
+ memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
+
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
+ (uint16_t)uint32_prop[0];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
+ (uint16_t)uint32_prop[1];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
+ (uint16_t)uint32_prop[2];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
+ (uint16_t)uint32_prop[3];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
+ (uint16_t)uint32_prop[4];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
+ (uint16_t)uint32_prop[5];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
+ (uint16_t)uint32_prop[6];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
+ (uint16_t)uint32_prop[7];
+ uint32_prop = (uint32_t *)of_get_property(port_node,
+ "ar-filters-sizes", &lenp);
+ if (uint32_prop) {
+ if (WARN_ON(lenp != sizeof(uint32_t)*3))
+ RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
+
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
+ (uint16_t)uint32_prop[0];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
+ (uint16_t)uint32_prop[1];
+ p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
+ (uint16_t)uint32_prop[2];
+ }
+
+ if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
+ (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
+ RETURN_ERROR(MINOR, err, NO_MSG);
+ }
+
of_node_put(port_node);
of_node_put(fm_node);
@@ -800,6 +851,14 @@ static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
#endif
#endif
+ if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
+ (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
+ if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
+ FM_PORT_FRM_ERR_IPR_NCSP |
+ FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
+ RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
+ }
+
if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
diff --git a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_sysfs_fm_port.c b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_sysfs_fm_port.c
index 73db24b..ead8c7a 100644
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_sysfs_fm_port.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_sysfs_fm_port.c
@@ -37,6 +37,7 @@
#include "lnxwrp_sysfs_fm.h"
#include "../../fman/Peripherals/FM/Port/fm_port.h"
+#include "../../fman/Peripherals/FM/Port/fm_port_dsar.h"
#if defined(__ERR_MODULE__)
#undef __ERR_MODULE__
@@ -276,7 +277,400 @@ static ssize_t show_fm_port_regs(struct device *dev,
return n;
#endif
}
+static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
+{
+ t_FmPort *p_FmPort;
+ t_Fm *p_Fm;
+ uint8_t hardwarePortId;
+ uint32_t *param_page;
+ t_ArCommonDesc *ArCommonDescPtr;
+ uint32_t *mem;
+ int i, n = nn;
+
+ p_FmPort = (t_FmPort *)h_dev;
+ hardwarePortId = p_FmPort->hardwarePortId;
+ p_Fm = (t_Fm *)p_FmPort->h_Fm;
+
+ if (!FM_PORT_IsInDsar(p_FmPort))
+ {
+ FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
+ hardwarePortId);
+ return n;
+ }
+ FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
+ FM_DMP_LN(buf, n, "========================\n");
+
+ /* do I need request_mem_region here? */
+ param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
+ ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
+ mem = (uint32_t*)ArCommonDescPtr;
+ for (i = 0; i < 100; i+=4)
+ FM_DMP_LN(buf, n, "%08x %08x %08x %08x\n", mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
+ iounmap(ArCommonDescPtr);
+ iounmap(param_page);
+ return n;
+}
+
+static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
+{
+ t_FmPort *p_FmPort;
+ t_Fm *p_Fm;
+ uint8_t hardwarePortId;
+ uint32_t *param_page;
+ t_ArCommonDesc *ArCommonDescPtr;
+ int i, n = nn;
+ p_FmPort = (t_FmPort *)h_dev;
+ hardwarePortId = p_FmPort->hardwarePortId;
+ p_Fm = (t_Fm *)p_FmPort->h_Fm;
+
+ if (!FM_PORT_IsInDsar(p_FmPort))
+ {
+ FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
+ hardwarePortId);
+ return n;
+ }
+ FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
+ FM_DMP_LN(buf, n, "========================\n");
+
+ /* do I need request_mem_region here? */
+ param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
+ ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
+ FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
+ FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
+ FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
+ FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
+ ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
+ ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
+ ArCommonDescPtr->macStationAddr[5]);
+ FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
+ FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
+ FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
+ FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
+ FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
+ if (ArCommonDescPtr->p_ArStats)
+ {
+ t_ArStatistics *arStatistics = (t_ArStatistics*)
+ ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof (t_ArStatistics));
+ FM_DMP_LN(buf, n, "\nDSAR statistics\n");
+ FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
+ FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
+ FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
+ FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
+
+ iounmap(arStatistics);
+ }
+ if (ArCommonDescPtr->p_ArpDescriptor)
+ {
+ t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
+ ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof (t_DsarArpDescriptor));
+ FM_DMP_LN(buf, n, "\nARP\n");
+ FM_DMP_LN(buf, n, "===\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
+ if (ArpDescriptor->numOfBindings)
+ {
+ char ip_str[20];
+ t_DsarArpBindingEntry* bindings = ioremap(
+ ioread32be(&ArpDescriptor->p_Bindings) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ ArpDescriptor->numOfBindings *
+ sizeof(t_DsarArpBindingEntry));
+ uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < ArpDescriptor->numOfBindings; i++)
+ {
+ n += sprintf(ip_str, "%d:%d:%d:%d", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
+ FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, bindings->vlanId);
+ }
+ iounmap(bindings);
+ }
+ if (ArpDescriptor->p_Statistics)
+ {
+ t_DsarArpStatistics* arpStats = ioremap(
+ ioread32be(&ArpDescriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_DsarArpStatistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
+ FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
+ FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
+ FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
+ FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
+ FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
+ iounmap(arpStats);
+ }
+
+ iounmap(ArpDescriptor);
+ }
+ if (ArCommonDescPtr->p_IcmpV4Descriptor)
+ {
+ t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
+ (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
+ &ArCommonDescPtr->p_IcmpV4Descriptor) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof (t_DsarIcmpV4Descriptor));
+ FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
+ FM_DMP_LN(buf, n, "===========\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
+ if (ICMPV4Descriptor->numOfBindings)
+ {
+ char ip_str[20];
+ t_DsarArpBindingEntry* bindings = ioremap(
+ ioread32be(&ICMPV4Descriptor->p_Bindings) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ ICMPV4Descriptor->numOfBindings *
+ sizeof(t_DsarArpBindingEntry));
+ uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
+ {
+ n += sprintf(ip_str, "%d:%d:%d:%d", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
+ FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, bindings->vlanId);
+ }
+ iounmap(bindings);
+ }
+ if (ICMPV4Descriptor->p_Statistics)
+ {
+ t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
+ ioread32be(&ICMPV4Descriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_DsarIcmpV4Statistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
+ FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
+ iounmap(icmpv4Stats);
+ }
+ iounmap(ICMPV4Descriptor);
+ }
+ if (ArCommonDescPtr->p_NdDescriptor)
+ {
+ t_DsarNdDescriptor *NDDescriptor =
+ (t_DsarNdDescriptor*)ioremap(ioread32be(
+ &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
+ fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
+ FM_DMP_LN(buf, n, "\nNDP\n");
+ FM_DMP_LN(buf, n, "===\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
+ FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
+ if (NDDescriptor->numOfBindings)
+ {
+ char ip_str[20];
+ t_DsarIcmpV6BindingEntry* bindings = ioremap(
+ ioread32be(&NDDescriptor->p_Bindings) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ NDDescriptor->numOfBindings *
+ sizeof(t_DsarIcmpV6BindingEntry));
+ uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < NDDescriptor->numOfBindings; i++)
+ {
+ n += sprintf(ip_str, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
+ ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
+ FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
+ }
+ iounmap(bindings);
+ }
+ if (NDDescriptor->p_Statistics)
+ {
+ t_NdStatistics* ndStats = ioremap(
+ ioread32be(&NDDescriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_NdStatistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
+ FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
+ FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
+ FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
+ iounmap(ndStats);
+ }
+ iounmap(NDDescriptor);
+ }
+ if (ArCommonDescPtr->p_IcmpV6Descriptor)
+ {
+ t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
+ (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
+ &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
+ fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
+ FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
+ FM_DMP_LN(buf, n, "===========\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
+ if (ICMPV6Descriptor->numOfBindings)
+ {
+ char ip_str[20];
+ t_DsarIcmpV6BindingEntry* bindings = ioremap(
+ ioread32be(&ICMPV6Descriptor->p_Bindings) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ ICMPV6Descriptor->numOfBindings *
+ sizeof(t_DsarIcmpV6BindingEntry));
+ uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
+ {
+ n += sprintf(ip_str, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
+ ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
+ ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
+ FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
+ }
+ iounmap(bindings);
+ }
+ if (ICMPV6Descriptor->p_Statistics)
+ {
+ t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
+ ioread32be(&ICMPV6Descriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_DsarIcmpV6Statistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
+ FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
+ FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
+ FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
+ iounmap(icmpv6Stats);
+ }
+ iounmap(ICMPV6Descriptor);
+ }
+ if (ArCommonDescPtr->p_SnmpDescriptor)
+ {
+ t_DsarSnmpDescriptor *SnmpDescriptor =
+ (t_DsarSnmpDescriptor*)ioremap(ioread32be(
+ &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
+ fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
+ FM_DMP_LN(buf, n, "\nSNMP\n");
+ FM_DMP_LN(buf, n, "===========\n");
+ FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
+ FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
+ if (SnmpDescriptor->numOfIpv4Addresses)
+ {
+ char ip_str[20];
+ t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
+ ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ SnmpDescriptor->numOfIpv4Addresses *
+ sizeof(t_DsarSnmpIpv4AddrTblEntry));
+ uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
+ FM_DMP_LN(buf, n, " ip vlan id\n");
+ for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
+ {
+ n += sprintf(ip_str, "%d:%d:%d:%d", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]);
+ FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
+ }
+ iounmap(addrs);
+ }
+ if (SnmpDescriptor->p_Statistics)
+ {
+ t_DsarSnmpStatistics* snmpStats = ioremap(
+ ioread32be(&SnmpDescriptor->p_Statistics) +
+ p_FmPort->fmMuramPhysBaseAddr,
+ sizeof(t_DsarSnmpStatistics));
+ FM_DMP_LN(buf, n, "statistics\n");
+ FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
+ FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
+ FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
+ FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
+ FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
+ iounmap(snmpStats);
+ }
+ iounmap(SnmpDescriptor);
+ }
+ iounmap(ArCommonDescPtr);
+ iounmap(param_page);
+ return n;
+}
+
+static ssize_t show_fm_port_dsar_mem(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev =
+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+#endif
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ local_irq_save(flags);
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ } else {
+ n = snprintf(buf, PAGE_SIZE,
+ "FM port driver registers dump.\n");
+ n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+ return n;
+#endif
+}
+
+static ssize_t show_fm_port_dsar_regs(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned long flags;
+ unsigned n = 0;
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev =
+ (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
+#endif
+ if (attr == NULL || buf == NULL || dev == NULL)
+ return -EINVAL;
+
+#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
+ local_irq_save(flags);
+
+ if (!p_LnxWrpFmPortDev->h_Dev) {
+ n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
+ return n;
+ } else {
+ n = snprintf(buf, PAGE_SIZE,
+ "FM port driver registers dump.\n");
+ n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
+ }
+
+ local_irq_restore(flags);
+
+ return n;
+#else
+
+ local_irq_save(flags);
+ n = snprintf(buf, PAGE_SIZE,
+ "Debug level is too low to dump registers!!!\n");
+ local_irq_restore(flags);
+
+ return n;
+#endif
+}
#if (DPAA_VERSION >= 11)
static ssize_t show_fm_port_ipv4_options(struct device *dev,
@@ -404,6 +798,8 @@ static DEVICE_ATTR(fm_port_bmi_regs, 0x644, show_fm_port_bmi_regs, NULL);
#if (DPAA_VERSION >= 11)
static DEVICE_ATTR(fm_port_ipv4_opt, 0x644, show_fm_port_ipv4_options, NULL);
#endif
+static DEVICE_ATTR(fm_port_dsar_regs, 0x644, show_fm_port_dsar_regs, NULL);
+static DEVICE_ATTR(fm_port_dsar_mem, 0x644, show_fm_port_dsar_mem, NULL);
int fm_port_sysfs_create(struct device *dev)
{
@@ -423,6 +819,8 @@ int fm_port_sysfs_create(struct device *dev)
#if (DPAA_VERSION >= 11)
p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
#endif
+ p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
+ p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
/* Registers dump entry - in future will be moved to debugfs */
if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
return -EIO;
@@ -434,6 +832,10 @@ int fm_port_sysfs_create(struct device *dev)
if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
return -EIO;
#endif
+ if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
+ return -EIO;
+ if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
+ return -EIO;
/* FM Ports statistics */
switch (p_LnxWrpFmPortDev->settings.param.portType) {
@@ -504,6 +906,8 @@ void fm_port_sysfs_destroy(struct device *dev)
#if (DPAA_VERSION >= 11)
device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
#endif
+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
+ device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
}