[dpdk-dev,33/38] net/dpaa: add support for flow control

Message ID 1497591668-3320-34-git-send-email-shreyansh.jain@nxp.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Shreyansh Jain June 16, 2017, 5:41 a.m. UTC
  Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
 doc/guides/nics/features/dpaa.ini |   1 +
 drivers/net/dpaa/dpaa_ethdev.c    | 112 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+)
  

Comments

Ferruh Yigit June 28, 2017, 3:47 p.m. UTC | #1
On 6/16/2017 6:41 AM, Shreyansh Jain wrote:
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>

<...>

>  static int
> +dpaa_flow_ctrl_set(struct rte_eth_dev *dev,
> +		   struct rte_eth_fc_conf *fc_conf)
> +{
> +	struct dpaa_if *dpaa_intf = dev->data->dev_private;
> +	struct rte_eth_fc_conf *net_fc;
> +
> +	PMD_INIT_FUNC_TRACE();
> +
> +	if (!(dpaa_intf->fc_conf)) {
> +		dpaa_intf->fc_conf = rte_zmalloc(NULL,
> +			sizeof(struct rte_eth_fc_conf), MAX_CACHELINE);

Should this be freed in rte_dpaa_remove()

> +		if (!dpaa_intf->fc_conf) {
> +			PMD_DRV_LOG(ERR, "unable to save flow control info");
> +			return -ENOMEM;
> +		}
> +	}
> +	net_fc = dpaa_intf->fc_conf;
> +
<...>
  
Shreyansh Jain June 30, 2017, 9:37 a.m. UTC | #2
On Wednesday 28 June 2017 09:17 PM, Ferruh Yigit wrote:
> On 6/16/2017 6:41 AM, Shreyansh Jain wrote:
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
> 
> <...>
> 
>>  static int
>> +dpaa_flow_ctrl_set(struct rte_eth_dev *dev,
>> +		   struct rte_eth_fc_conf *fc_conf)
>> +{
>> +	struct dpaa_if *dpaa_intf = dev->data->dev_private;
>> +	struct rte_eth_fc_conf *net_fc;
>> +
>> +	PMD_INIT_FUNC_TRACE();
>> +
>> +	if (!(dpaa_intf->fc_conf)) {
>> +		dpaa_intf->fc_conf = rte_zmalloc(NULL,
>> +			sizeof(struct rte_eth_fc_conf), MAX_CACHELINE);
> 
> Should this be freed in rte_dpaa_remove()

Will fix this in v2.

> 
>> +		if (!dpaa_intf->fc_conf) {
>> +			PMD_DRV_LOG(ERR, "unable to save flow control info");
>> +			return -ENOMEM;
>> +		}
>> +	}
>> +	net_fc = dpaa_intf->fc_conf;
>> +
> <...>
> 
>
  

Patch

diff --git a/doc/guides/nics/features/dpaa.ini b/doc/guides/nics/features/dpaa.ini
index 54eb85c..ea4c2fe 100644
--- a/doc/guides/nics/features/dpaa.ini
+++ b/doc/guides/nics/features/dpaa.ini
@@ -12,6 +12,7 @@  MTU update           = Y
 Promiscuous mode     = Y
 Allmulticast mode    = Y
 Unicast MAC filter   = Y
+Flow control         = Y
 Basic stats          = Y
 ARMv8                = Y
 Usage doc            = Y
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 0eb5b71..3cfbae0 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -329,6 +329,85 @@  static int dpaa_link_up(struct rte_eth_dev *dev)
 }
 
 static int
+dpaa_flow_ctrl_set(struct rte_eth_dev *dev,
+		   struct rte_eth_fc_conf *fc_conf)
+{
+	struct dpaa_if *dpaa_intf = dev->data->dev_private;
+	struct rte_eth_fc_conf *net_fc;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (!(dpaa_intf->fc_conf)) {
+		dpaa_intf->fc_conf = rte_zmalloc(NULL,
+			sizeof(struct rte_eth_fc_conf), MAX_CACHELINE);
+		if (!dpaa_intf->fc_conf) {
+			PMD_DRV_LOG(ERR, "unable to save flow control info");
+			return -ENOMEM;
+		}
+	}
+	net_fc = dpaa_intf->fc_conf;
+
+	if (fc_conf->high_water < fc_conf->low_water) {
+		PMD_DRV_LOG(ERR, "Incorrect Flow Control Configuration");
+		return -EINVAL;
+	}
+
+	if (fc_conf->mode == RTE_FC_NONE) {
+		return 0;
+	} else if (fc_conf->mode == RTE_FC_TX_PAUSE ||
+		 fc_conf->mode == RTE_FC_FULL) {
+		fman_if_set_fc_threshold(dpaa_intf->fif, fc_conf->high_water,
+					 fc_conf->low_water,
+				dpaa_intf->bp_info->bpid);
+		if (fc_conf->pause_time)
+			fman_if_set_fc_quanta(dpaa_intf->fif,
+					      fc_conf->pause_time);
+	}
+
+	/* Save the information in dpaa device */
+	net_fc->pause_time = fc_conf->pause_time;
+	net_fc->high_water = fc_conf->high_water;
+	net_fc->low_water = fc_conf->low_water;
+	net_fc->send_xon = fc_conf->send_xon;
+	net_fc->mac_ctrl_frame_fwd = fc_conf->mac_ctrl_frame_fwd;
+	net_fc->mode = fc_conf->mode;
+	net_fc->autoneg = fc_conf->autoneg;
+
+	return 0;
+}
+
+static int
+dpaa_flow_ctrl_get(struct rte_eth_dev *dev,
+		   struct rte_eth_fc_conf *fc_conf)
+{
+	struct dpaa_if *dpaa_intf = dev->data->dev_private;
+	struct rte_eth_fc_conf *net_fc = dpaa_intf->fc_conf;
+	int ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (net_fc) {
+		fc_conf->pause_time = net_fc->pause_time;
+		fc_conf->high_water = net_fc->high_water;
+		fc_conf->low_water = net_fc->low_water;
+		fc_conf->send_xon = net_fc->send_xon;
+		fc_conf->mac_ctrl_frame_fwd = net_fc->mac_ctrl_frame_fwd;
+		fc_conf->mode = net_fc->mode;
+		fc_conf->autoneg = net_fc->autoneg;
+		return 0;
+	}
+	ret = fman_if_get_fc_threshold(dpaa_intf->fif);
+	if (ret) {
+		fc_conf->mode = RTE_FC_TX_PAUSE;
+		fc_conf->pause_time = fman_if_get_fc_quanta(dpaa_intf->fif);
+	} else {
+		fc_conf->mode = RTE_FC_NONE;
+	}
+
+	return 0;
+}
+
+static int
 dpaa_dev_add_mac_addr(struct rte_eth_dev *dev,
 			     struct ether_addr *addr,
 			     uint32_t index,
@@ -391,6 +470,9 @@  static struct eth_dev_ops dpaa_devops = {
 	.rx_queue_release	  = dpaa_eth_rx_queue_release,
 	.tx_queue_release	  = dpaa_eth_tx_queue_release,
 
+	.flow_ctrl_get		  = dpaa_flow_ctrl_get,
+	.flow_ctrl_set		  = dpaa_flow_ctrl_set,
+
 	.link_update		  = dpaa_eth_link_update,
 	.stats_get		  = dpaa_eth_stats_get,
 	.stats_reset		  = dpaa_eth_stats_reset,
@@ -407,6 +489,33 @@  static struct eth_dev_ops dpaa_devops = {
 
 };
 
+static int dpaa_fc_set_default(struct dpaa_if *dpaa_intf)
+{
+	struct rte_eth_fc_conf *fc_conf;
+	int ret;
+
+	PMD_INIT_FUNC_TRACE();
+
+	if (!(dpaa_intf->fc_conf)) {
+		dpaa_intf->fc_conf = rte_zmalloc(NULL,
+			sizeof(struct rte_eth_fc_conf), MAX_CACHELINE);
+		if (!dpaa_intf->fc_conf) {
+			PMD_DRV_LOG(ERR, "unable to save flow control info");
+			return -ENOMEM;
+		}
+	}
+	fc_conf = dpaa_intf->fc_conf;
+	ret = fman_if_get_fc_threshold(dpaa_intf->fif);
+	if (ret) {
+		fc_conf->mode = RTE_FC_TX_PAUSE;
+		fc_conf->pause_time = fman_if_get_fc_quanta(dpaa_intf->fif);
+	} else {
+		fc_conf->mode = RTE_FC_NONE;
+	}
+
+	return 0;
+}
+
 /* Initialise an Rx FQ */
 static int dpaa_rx_queue_init(struct qman_fq *fq,
 			      uint32_t fqid)
@@ -553,6 +662,9 @@  static int dpaa_eth_dev_init(struct rte_eth_dev *eth_dev)
 
 	PMD_DRV_LOG(DEBUG, "all fqs created");
 
+	/* Get the initial configuration for flow control */
+	dpaa_fc_set_default(dpaa_intf);
+
 	/* reset bpool list, initialize bpool dynamically */
 	list_for_each_entry_safe(bp, tmp_bp, &cfg->fman_if->bpool_list, node) {
 		list_del(&bp->node);