summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorEyal Harari <Eyal.Harari@freesacle.com>2014-05-23 07:57:56 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-05-27 14:05:57 (GMT)
commit49a1bd52cb9a328460ee793967249223e379b809 (patch)
tree76da20971b5022834d33a007ad2d4f72955cdc0c /drivers/net/ethernet
parent8596def61c88a5dad865f82e0067b0a2dbe003f2 (diff)
downloadlinux-fsl-qoriq-49a1bd52cb9a328460ee793967249223e379b809.tar.xz
FMD: DSAR: workaround patch which enables AR in DS
Signed-off-by: Eyal Harari <Eyal.Harari@freesacle.com> Change-Id: I90e7e97c9ff8a149893c8244cb0e8376c66eb2ad Reviewed-on: http://git.am.freescale.net:8181/12925 Reviewed-by: Cristian-Constantin Sovaiala <Cristian.Sovaiala@freescale.com> Tested-by: Richard Schmitt <richard.schmitt@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com> Tested-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/Port/fm_port.c91
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c50
-rw-r--r--drivers/net/ethernet/freescale/fman/Peripherals/FM/inc/fm_common.h13
-rw-r--r--drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_fsl_fman.h1
-rwxr-xr-xdrivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c30
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_sysfs_fm_port.c6
6 files changed, 157 insertions, 34 deletions
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 00a3489..df05848 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
@@ -3166,10 +3166,13 @@ t_Error FM_PORT_Disable(t_Handle h_FmPort)
return E_OK;
}
+t_FmPort* opXX;
t_Error FM_PORT_Enable(t_Handle h_FmPort)
{
t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
int err;
+ if (p_FmPort->portId == 0) // save HC port for DSAR disable
+ opXX = p_FmPort;
SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
@@ -5465,6 +5468,20 @@ static int GetBERLen(uint8_t* buf)
}
#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
+#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
+#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
+#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
+static int fm_soc_suspend(void)
+{
+ uint32_t *fmclk, tmp32;
+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
+ tmp32 = GET_UINT32(*fmclk);
+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
+ tmp32 = GET_UINT32(*fmclk);
+ return 0;
+}
+
+t_FmPort *g_DsarFmPortRx, *g_DsarFmPortTx;
t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
{
int i,j;
@@ -5481,12 +5498,14 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
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;
t_FmGetSetParams fmGetSetParams;
memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
fmGetSetParams.setParams.sleep = 1;
+ g_DsarFmPortRx = p_FmPort;
+ g_DsarFmPortTx = p_FmPortTx;
+
err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
if (err != E_OK)
return err;
@@ -5760,7 +5779,27 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
// get into Deep Sleep sequence:
- // Stage 6: configure tx port to im
+
+ // Ensures that FMan do not enter the idle state. This is done by programing
+ // FMDPSLPCR[FM_STOP] to one.
+ fm_soc_suspend();
+
+ ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
+ return E_OK;
+
+}
+
+void FM_PORT_Dsar_enter_final(void)
+{
+ t_Handle *h_FmPcd;
+ t_FmGetSetParams fmGetSetParams;
+
+ t_FmPort *p_FmPort = g_DsarFmPortRx;
+ t_FmPort *p_FmPortTx = g_DsarFmPortTx;
+ // Issue graceful stop to HC port
+ FM_PORT_Disable(opXX);
+
+ // config auto response
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);
// ????
@@ -5780,20 +5819,55 @@ t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
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
+
+ // save rcfg for restoring: accumulate mode is changed by ucode
p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
- FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+// ***** issue external request sync command
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+ // get
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.getParams.type = GET_FMFP_EXTC;
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+ if (fmGetSetParams.getParams.fmfp_extc != 0)
+ {
+ // clear
+ XX_Print("FM: Sync did not finish 0\n");
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+ }
- ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
- return E_OK;
+ // get
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.getParams.type = GET_FMFP_EXTC;
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+ while (fmGetSetParams.getParams.fmfp_extc != 0)
+ {
+ // get
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.getParams.type = GET_FMFP_EXTC;
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+ }
+
+ // check that all stoped
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+ while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
+ FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
+ if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
+ XX_Print("FM: Sleeping\n");
}
+EXPORT_SYMBOL(FM_PORT_Dsar_enter_final);
+
void FM_PORT_Dsar_DumpRegs()
{
uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
- DUMP_MEMORY(hh, 0x180);
+ DUMP_MEMORY(hh, 0x220);
}
void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
@@ -5823,6 +5897,7 @@ void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
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);
+ FM_PORT_Enable(opXX);
}
bool FM_PORT_IsInDsar(t_Handle h_FmPort)
diff --git a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c
index 811c4f2..3f569b8 100644
--- a/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c
+++ b/drivers/net/ethernet/freescale/fman/Peripherals/FM/fm.c
@@ -4182,6 +4182,33 @@ UNUSED(p_Fm);
return E_OK;
}
+t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
+{
+ t_Fm* p_Fm = (t_Fm*)h_Fm;
+
+ if (p_Params->setParams.type & UPDATE_FPM_EXTC)
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
+ if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x08000000);
+ if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
+ {
+ if (p_Params->setParams.sleep)
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
+ p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
+ else
+ WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
+ p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
+ }
+ if (p_Params->getParams.type & GET_FMQM_GS)
+ p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
+ if (p_Params->getParams.type & GET_FM_NPI)
+ p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
+ if (p_Params->getParams.type & GET_FMFP_EXTC)
+ p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
+ return E_OK;
+}
+
+
/****************************************************/
/* API Run-time Control uint functions */
/****************************************************/
@@ -4215,7 +4242,14 @@ void FM_EventIsr(t_Handle h_Fm)
pending = fman_get_normal_pending(fpm_rg);
if (!pending)
return;
-
+ if (pending & 0x10000000) // this is a wake up from sleep interrupt
+ {
+ t_FmGetSetParams fmGetSetParams;
+ memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
+ fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
+ fmGetSetParams.setParams.sleep = 0;
+ FmGetSetParams(h_Fm, &fmGetSetParams);
+ }
if (pending & INTR_EN_QMI)
QmiEvent(p_Fm);
if (pending & INTR_EN_PRS)
@@ -5212,17 +5246,3 @@ t_Handle FmGetPcd(t_Handle h_Fm)
return ((t_Fm*)h_Fm)->h_Pcd;
}
-t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
-{
- t_Fm* p_Fm = (t_Fm*)h_Fm;
- if (p_Params->setParams.type == UPDATE_FPM_BRKC_SLP)
- {
- if (p_Params->setParams.sleep)
- WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
- p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
- else
- WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
- p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
- }
- return E_OK;
-}
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 c9c963a..f5f5428 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
@@ -264,7 +264,15 @@ typedef struct {
} t_FmSetParams;
typedef struct {
+ uint32_t type;
+ uint32_t fmqm_gs;
+ uint32_t fm_npi;
+ uint32_t fmfp_extc;
+} t_FmGetParams;
+
+typedef struct {
t_FmSetParams setParams;
+ t_FmGetParams getParams;
} t_FmGetSetParams;
t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
@@ -335,6 +343,11 @@ static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
/* @} */
#define UPDATE_FPM_BRKC_SLP 0x80000000
+#define UPDATE_FPM_EXTC 0x40000000
+#define UPDATE_FPM_EXTC_CLEAR 0x20000000
+#define GET_FMQM_GS 0x10000000
+#define GET_FM_NPI 0x08000000
+#define GET_FMFP_EXTC 0x04000000
#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
FM_MAX_NUM_OF_1G_RX_PORTS + \
FM_MAX_NUM_OF_10G_RX_PORTS + \
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 97a7c0c..4e66564 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
@@ -468,6 +468,7 @@ struct auto_res_snmp_info
char *community_read_only_string;
struct auto_res_snmp_entry *oid_table;
uint32_t oid_table_size;
+ uint32_t *statistics;
};
/* Filtering */
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 cdffe7a..646a90c 100755
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
@@ -60,6 +60,7 @@
#include <asm/errno.h>
#include <asm/qe.h> /* For struct qe_firmware */
#include <sysdev/fsl_soc.h>
+#include <asm/fsl_pm.h>
#include <linux/stat.h> /* For file access mask */
#include <linux/skbuff.h>
#include <linux/proc_fs.h>
@@ -1102,20 +1103,30 @@ MODULE_DEVICE_TABLE(of, fm_match);
#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
-
+void FM_PORT_Dsar_enter_final(void);
+static bool started_ar_enter = false;
static int fm_soc_suspend(struct device *dev)
{
- uint32_t *fmclk;
- fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
- WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
+ if (started_ar_enter)
+ {
+ uint32_t *fmclk;
+ fsl_set_power_except(dev,1);
+ FM_PORT_Dsar_enter_final();
+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
+ }
return 0;
}
static int fm_soc_resume(struct device *dev)
{
- uint32_t *fmclk;
- fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
- WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
+ if (started_ar_enter)
+ {
+ uint32_t *fmclk;
+ fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
+ WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
+ started_ar_enter = false;
+ }
return 0;
}
@@ -1360,6 +1371,7 @@ int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
return -EFAULT;
FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
+ started_ar_enter = true;
return 0;
}
EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
@@ -1367,7 +1379,9 @@ 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);
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDevRx = (t_LnxWrpFmPortDev *)port_rx;
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDevTx = (t_LnxWrpFmPortDev *)port_tx;
+ FM_PORT_ExitDsar(p_LnxWrpFmPortDevRx->h_Dev, p_LnxWrpFmPortDevTx->h_Dev);
}
EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
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 ead8c7a..ebed557 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
@@ -302,10 +302,10 @@ static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
/* 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*/
+ ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* 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]);
+ for (i = 0; i < 300; i+=4)
+ FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
iounmap(ArCommonDescPtr);
iounmap(param_page);
return n;