summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/freescale/fman/Kconfig43
-rw-r--r--drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_ext.h26
-rw-r--r--drivers/net/ethernet/freescale/fman/src/inc/wrapper/lnxwrp_fsl_fman.h25
-rwxr-xr-xdrivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c83
-rw-r--r--drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm_port.c38
5 files changed, 190 insertions, 25 deletions
diff --git a/drivers/net/ethernet/freescale/fman/Kconfig b/drivers/net/ethernet/freescale/fman/Kconfig
index 0b9b813..9bc40f8 100644
--- a/drivers/net/ethernet/freescale/fman/Kconfig
+++ b/drivers/net/ethernet/freescale/fman/Kconfig
@@ -108,6 +108,49 @@ config FSL_FM_RX_EXTRA_HEADROOM
* in non-Hypervisor-based scenarios, via u-boot's env, by
modifying the "bootargs" env variable.
+config FMAN_PFC
+ bool "FMan PFC support"
+ depends on FMAN_T4240 && FSL_FMAN
+ default n
+ ---help---
+ This option enables PFC support on FMan v3 ports.
+ Data Center Bridging defines Classes of Service that are
+ flow-controlled using PFC pause frames.
+
+if FMAN_PFC
+config FMAN_PFC_COS_COUNT
+ int "Number of PFC Classes of Service"
+ depends on FMAN_PFC && FSL_FMAN
+ range 1 4
+ default "1"
+ ---help ---
+ The number of Classes of Service controlled by PFC.
+
+config FMAN_PFC_QUANTA_0
+ int "The pause quanta for PFC CoS 0"
+ depends on FMAN_PFC && FSL_FMAN
+ range 0 65535
+ default "65535"
+
+config FMAN_PFC_QUANTA_1
+ int "The pause quanta for PFC CoS 1"
+ depends on FMAN_PFC && FSL_FMAN
+ range 0 65535
+ default "65535"
+
+config FMAN_PFC_QUANTA_2
+ int "The pause quanta for PFC CoS 2"
+ depends on FMAN_PFC && FSL_FMAN
+ range 0 65535
+ default "65535"
+
+config FMAN_PFC_QUANTA_3
+ int "The pause quanta for PFC CoS 3"
+ depends on FMAN_PFC && FSL_FMAN
+ range 0 65535
+ default "65535"
+endif
+
endif # FSL_FMAN
endmenu
diff --git a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_ext.h b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_ext.h
index a45682f..5bba643 100644
--- a/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_ext.h
+++ b/drivers/net/ethernet/freescale/fman/inc/Peripherals/fm_ext.h
@@ -411,17 +411,6 @@ typedef struct t_FmExtPoolParams {
} t_FmExtPoolParams;
/**************************************************************************//**
- @Description A structure for informing the driver about the external
- buffer pools allocated in the BM and used by a port or a
- storage-profile.
-*//***************************************************************************/
-typedef struct t_FmExtPools {
- uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
- t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
- /**< Parameters for each port */
-} t_FmExtPools;
-
-/**************************************************************************//**
@Description A structure for defining backup BM Pools.
*//***************************************************************************/
typedef struct t_FmBackupBmPools {
@@ -458,6 +447,21 @@ typedef struct t_FmBufPoolDepletion {
} t_FmBufPoolDepletion;
/**************************************************************************//**
+ @Description A structure for informing the driver about the external
+ buffer pools allocated in the BM and used by a port or a
+ storage-profile.
+*//***************************************************************************/
+typedef struct t_FmExtPools {
+ uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
+ t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
+ /**< Parameters for each port */
+ /**< External buffer pool depletion parameters */
+#ifdef CONFIG_FMAN_PFC
+ t_FmBufPoolDepletion poolDepletion;
+#endif
+} t_FmExtPools;
+
+/**************************************************************************//**
@Description A Structure for defining Ucode patch for loading.
*//***************************************************************************/
typedef struct t_FmFirmwareParams {
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 4c551ff..b30ec50 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
@@ -101,6 +101,12 @@ struct fm_port_pcd_param {
struct fm_port_pool_param {
uint8_t id; /**< External buffer pool id */
uint16_t size; /**< External buffer pool buffer size */
+#ifdef CONFIG_FMAN_PFC
+ /**<The Priority Enable Vector in the PFC frame which is transmitted
+ * when the buffer pool depletes;
+ */
+ uint8_t pfcv;
+#endif
};
/**************************************************************************//**
@@ -548,6 +554,25 @@ int fm_port_resume(struct fm_port *port);
int fm_port_suspend(struct fm_port *port);
+#ifdef CONFIG_FMAN_PFC
+/**************************************************************************//**
+@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
+
+@Description Associate a QMan Work Queue with a PFC priority on this
+ FM-port device (Tx port).
+
+@Param[in] port - A handle of the FM port device.
+
+@Param[in] prio - The PFC priority.
+
+@Param[in] wq - The Work Queue associated with the PFC priority.
+
+@Cautions Allowed only after the port is initialized.
+*//***************************************************************************/
+int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
+ uint8_t prio, uint8_t wq);
+#endif
+
/**************************************************************************//**
@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 d30f2ed..4ea2885 100755
--- a/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
+++ b/drivers/net/ethernet/freescale/fman/src/wrapper/lnxwrp_fm.c
@@ -110,10 +110,9 @@ extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_n
#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
-#define TX_PAUSE_PRIO_DEFAULT 0xff
-#define TX_PAUSE_TIME_ENABLE 0xf000
-#define TX_PAUSE_TIME_DISABLE 0
-#define TX_PAUSE_THRESH_DEFAULT 0
+#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
+#define FSL_FM_PAUSE_TIME_DISABLE 0
+#define FSL_FM_PAUSE_THRESH_DEFAULT 0
/*
* Max frame size, across all interfaces.
@@ -140,6 +139,15 @@ int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
*/
int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
+#ifdef CONFIG_FMAN_PFC
+static int fsl_fm_pfc_quanta[] = {
+ CONFIG_FMAN_PFC_QUANTA_0,
+ CONFIG_FMAN_PFC_QUANTA_1,
+ CONFIG_FMAN_PFC_QUANTA_2,
+ CONFIG_FMAN_PFC_QUANTA_3
+};
+#endif
+
static t_LnxWrpFm lnxWrpFm;
int fm_get_max_frm()
@@ -1410,6 +1418,25 @@ bool fm_port_is_in_auto_res_mode(struct fm_port *port)
}
EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
+#ifdef CONFIG_FMAN_PFC
+int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
+ uint8_t prio, uint8_t wq)
+{
+ t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
+ int err;
+ int _errno;
+
+ err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
+ prio, wq);
+ _errno = -GET_ERROR_TYPE(err);
+ if (unlikely(_errno < 0))
+ pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
+
+ return _errno;
+}
+EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
+#endif
+
int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
e_FmMacExceptions exception, bool enable)
{
@@ -1695,6 +1722,39 @@ int fm_mac_set_rx_pause_frames(
}
EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
+#ifdef CONFIG_FMAN_PFC
+int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
+ bool en)
+{
+ int _errno, i;
+ t_Error err;
+
+ if (en)
+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
+ err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
+ i, fsl_fm_pfc_quanta[i],
+ FSL_FM_PAUSE_THRESH_DEFAULT);
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0) {
+ pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
+ return _errno;
+ }
+ }
+ else
+ for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
+ err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
+ i, FSL_FM_PAUSE_TIME_DISABLE,
+ FSL_FM_PAUSE_THRESH_DEFAULT);
+ _errno = -GET_ERROR_TYPE(err);
+ if (_errno < 0) {
+ pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
+ return _errno;
+ }
+ }
+
+ return _errno;
+}
+#else
int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
bool en)
{
@@ -1702,22 +1762,19 @@ int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
t_Error err;
if (en)
- err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
- TX_PAUSE_PRIO_DEFAULT,
- TX_PAUSE_TIME_ENABLE,
- TX_PAUSE_THRESH_DEFAULT);
+ err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
+ FSL_FM_PAUSE_TIME_ENABLE);
else
- err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
- TX_PAUSE_PRIO_DEFAULT,
- TX_PAUSE_TIME_DISABLE,
- TX_PAUSE_THRESH_DEFAULT);
+ err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
+ FSL_FM_PAUSE_TIME_DISABLE);
_errno = -GET_ERROR_TYPE(err);
if (_errno < 0)
- pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
+ pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
return _errno;
}
+#endif
EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
int fm_rtc_enable(struct fm *fm_dev)
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 6e135a2..198691c 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
@@ -502,7 +502,17 @@ static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
/*const char *str_prop;*/
int lenp;
-
+#ifdef CONFIG_FMAN_PFC
+ if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
+ p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
+ t_Error errCode = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
+ &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
+ extBufPools.poolDepletion);
+ if (errCode != E_OK)
+ RETURN_ERROR(MAJOR, errCode, ("FM_PORT_ConfigPoolDepletion() failed"));
+ }
+#endif
+
fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
if (!fm_node) /* no advance parameters for FMan */
return E_OK;
@@ -925,6 +935,10 @@ void fm_set_rx_port_params(struct fm_port *port,
{
t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
int i;
+#ifdef CONFIG_FMAN_PFC
+ uint8_t pfcv = 0;
+ uint8_t id;
+#endif
p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
params->errq;
@@ -932,6 +946,14 @@ void fm_set_rx_port_params(struct fm_port *port,
params->defq;
p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
numOfPoolsUsed = params->num_pools;
+
+#ifdef CONFIG_FMAN_PFC
+ memset(&(p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
+ extBufPools.poolDepletion), 0, sizeof(t_FmBufPoolDepletion));
+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
+ poolDepletion.singlePoolModeEnable = true;
+#endif
+
for (i = 0; i < params->num_pools; i++) {
p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
extBufPools.extBufPool[i].id =
@@ -939,8 +961,22 @@ void fm_set_rx_port_params(struct fm_port *port,
p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
extBufPools.extBufPool[i].size =
params->pool_param[i].size;
+
+#ifdef CONFIG_FMAN_PFC
+ id = params->pool_param[i].id;
+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
+ extBufPools.poolDepletion.poolsToConsiderForSingleMode[id] = true;
+ pfcv |= params->pool_param[i].pfcv;
+#endif
}
+#ifdef CONFIG_FMAN_PFC
+ for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
+ if (pfcv & (1 << i))
+ p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
+ extBufPools.poolDepletion.pfcPrioritiesEn[i] = true;
+#endif
+
p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
params->priv_data_size;
p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =