From: David Marchand <david.marchand@6wind.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 1/7] ethdev: retrieve flow control configuration
Date: Fri, 13 Jun 2014 15:37:37 +0200 [thread overview]
Message-ID: <1402666663-10260-2-git-send-email-david.marchand@6wind.com> (raw)
In-Reply-To: <1402666663-10260-1-git-send-email-david.marchand@6wind.com>
From: Zijie Pan <zijie.pan@6wind.com>
This patch adds a new function in ethdev api to retrieve current flow control
configuration.
This operation has been implemented for rte_em_pmd, rte_igb_pmd and
rte_ixgbe_pmd.
Signed-off-by: Zijie Pan <zijie.pan@6wind.com>
Signed-off-by: David Marchand <david.marchand@6wind.com>
---
lib/librte_ether/rte_ethdev.c | 16 ++++++++++
lib/librte_ether/rte_ethdev.h | 24 +++++++++++++--
lib/librte_pmd_e1000/em_ethdev.c | 44 ++++++++++++++++++++++++++++
lib/librte_pmd_e1000/igb_ethdev.c | 44 ++++++++++++++++++++++++++++
lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 55 +++++++++++++++++++++++++++++++++--
5 files changed, 179 insertions(+), 4 deletions(-)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 8011b8b..e881ebe 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1617,6 +1617,22 @@ rte_eth_dev_fdir_set_masks(uint8_t port_id, struct rte_fdir_masks *fdir_mask)
}
int
+rte_eth_dev_flow_ctrl_get(uint8_t port_id, struct rte_eth_fc_conf *fc_conf)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return (-ENODEV);
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->flow_ctrl_get, -ENOTSUP);
+ memset(fc_conf, 0, sizeof(*fc_conf));
+ return (*dev->dev_ops->flow_ctrl_get)(dev, fc_conf);
+}
+
+int
rte_eth_dev_flow_ctrl_set(uint8_t port_id, struct rte_eth_fc_conf *fc_conf)
{
struct rte_eth_dev *dev;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 67eda50..71e9ae0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -969,8 +969,12 @@ typedef int (*fdir_set_masks_t)(struct rte_eth_dev *dev,
struct rte_fdir_masks *fdir_masks);
/**< @internal Setup flow director masks on an Ethernet device */
+typedef int (*flow_ctrl_get_t)(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf);
+/**< @internal Get current flow control parameter on an Ethernet device */
+
typedef int (*flow_ctrl_set_t)(struct rte_eth_dev *dev,
- struct rte_eth_fc_conf *fc_conf);
+ struct rte_eth_fc_conf *fc_conf);
/**< @internal Setup flow control parameter on an Ethernet device */
typedef int (*priority_flow_ctrl_set_t)(struct rte_eth_dev *dev,
@@ -1151,6 +1155,7 @@ struct eth_dev_ops {
eth_queue_release_t tx_queue_release;/**< Release TX queue.*/
eth_dev_led_on_t dev_led_on; /**< Turn on LED. */
eth_dev_led_off_t dev_led_off; /**< Turn off LED. */
+ flow_ctrl_get_t flow_ctrl_get; /**< Get flow control. */
flow_ctrl_set_t flow_ctrl_set; /**< Setup flow control. */
priority_flow_ctrl_set_t priority_flow_ctrl_set; /**< Setup priority flow control.*/
eth_mac_addr_remove_t mac_addr_remove; /**< Remove MAC address */
@@ -2432,6 +2437,21 @@ int rte_eth_led_on(uint8_t port_id);
int rte_eth_led_off(uint8_t port_id);
/**
+ * Get current status of the Ethernet link flow control for Ethernet device
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param fc_conf
+ * The pointer to the structure where to store the flow control parameters.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support flow control.
+ * - (-ENODEV) if *port_id* invalid.
+ */
+int rte_eth_dev_flow_ctrl_get(uint8_t port_id,
+ struct rte_eth_fc_conf *fc_conf);
+
+/**
* Configure the Ethernet link flow control for Ethernet device
*
* @param port_id
@@ -2446,7 +2466,7 @@ int rte_eth_led_off(uint8_t port_id);
* - (-EIO) if flow control setup failure
*/
int rte_eth_dev_flow_ctrl_set(uint8_t port_id,
- struct rte_eth_fc_conf *fc_conf);
+ struct rte_eth_fc_conf *fc_conf);
/**
* Configure the Ethernet priority flow control under DCB environment
diff --git a/lib/librte_pmd_e1000/em_ethdev.c b/lib/librte_pmd_e1000/em_ethdev.c
index 398838f..cb5eb4a 100644
--- a/lib/librte_pmd_e1000/em_ethdev.c
+++ b/lib/librte_pmd_e1000/em_ethdev.c
@@ -77,6 +77,8 @@ static void eth_em_stats_get(struct rte_eth_dev *dev,
static void eth_em_stats_reset(struct rte_eth_dev *dev);
static void eth_em_infos_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
+static int eth_em_flow_ctrl_get(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf);
static int eth_em_flow_ctrl_set(struct rte_eth_dev *dev,
struct rte_eth_fc_conf *fc_conf);
static int eth_em_interrupt_setup(struct rte_eth_dev *dev);
@@ -153,6 +155,7 @@ static struct eth_dev_ops eth_em_ops = {
.tx_queue_release = eth_em_tx_queue_release,
.dev_led_on = eth_em_led_on,
.dev_led_off = eth_em_led_off,
+ .flow_ctrl_get = eth_em_flow_ctrl_get,
.flow_ctrl_set = eth_em_flow_ctrl_set,
.mac_addr_add = eth_em_rar_set,
.mac_addr_remove = eth_em_rar_clear,
@@ -1358,6 +1361,47 @@ eth_em_led_off(struct rte_eth_dev *dev)
}
static int
+eth_em_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct e1000_hw *hw;
+ uint32_t ctrl;
+ int tx_pause;
+ int rx_pause;
+
+ hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ fc_conf->pause_time = hw->fc.pause_time;
+ fc_conf->high_water = hw->fc.high_water;
+ fc_conf->low_water = hw->fc.low_water;
+ fc_conf->send_xon = hw->fc.send_xon;
+
+ /*
+ * Return rx_pause and tx_pause status according to actual setting of
+ * the TFCE and RFCE bits in the CTRL register.
+ */
+ ctrl = E1000_READ_REG(hw, E1000_CTRL);
+ if (ctrl & E1000_CTRL_TFCE)
+ tx_pause = 1;
+ else
+ tx_pause = 0;
+
+ if (ctrl & E1000_CTRL_RFCE)
+ rx_pause = 1;
+ else
+ rx_pause = 0;
+
+ if (rx_pause && tx_pause)
+ fc_conf->mode = RTE_FC_FULL;
+ else if (rx_pause)
+ fc_conf->mode = RTE_FC_RX_PAUSE;
+ else if (tx_pause)
+ fc_conf->mode = RTE_FC_TX_PAUSE;
+ else
+ fc_conf->mode = RTE_FC_NONE;
+
+ return 0;
+}
+
+static int
eth_em_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
{
struct e1000_hw *hw;
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 6e835c3..3fbbc1a 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -72,6 +72,8 @@ static void eth_igb_stats_get(struct rte_eth_dev *dev,
static void eth_igb_stats_reset(struct rte_eth_dev *dev);
static void eth_igb_infos_get(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info);
+static int eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf);
static int eth_igb_flow_ctrl_set(struct rte_eth_dev *dev,
struct rte_eth_fc_conf *fc_conf);
static int eth_igb_lsc_interrupt_setup(struct rte_eth_dev *dev);
@@ -189,6 +191,7 @@ static struct eth_dev_ops eth_igb_ops = {
.tx_queue_release = eth_igb_tx_queue_release,
.dev_led_on = eth_igb_led_on,
.dev_led_off = eth_igb_led_off,
+ .flow_ctrl_get = eth_igb_flow_ctrl_get,
.flow_ctrl_set = eth_igb_flow_ctrl_set,
.mac_addr_add = eth_igb_rar_set,
.mac_addr_remove = eth_igb_rar_clear,
@@ -1798,6 +1801,47 @@ eth_igb_led_off(struct rte_eth_dev *dev)
}
static int
+eth_igb_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct e1000_hw *hw;
+ uint32_t ctrl;
+ int tx_pause;
+ int rx_pause;
+
+ hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ fc_conf->pause_time = hw->fc.pause_time;
+ fc_conf->high_water = hw->fc.high_water;
+ fc_conf->low_water = hw->fc.low_water;
+ fc_conf->send_xon = hw->fc.send_xon;
+
+ /*
+ * Return rx_pause and tx_pause status according to actual setting of
+ * the TFCE and RFCE bits in the CTRL register.
+ */
+ ctrl = E1000_READ_REG(hw, E1000_CTRL);
+ if (ctrl & E1000_CTRL_TFCE)
+ tx_pause = 1;
+ else
+ tx_pause = 0;
+
+ if (ctrl & E1000_CTRL_RFCE)
+ rx_pause = 1;
+ else
+ rx_pause = 0;
+
+ if (rx_pause && tx_pause)
+ fc_conf->mode = RTE_FC_FULL;
+ else if (rx_pause)
+ fc_conf->mode = RTE_FC_RX_PAUSE;
+ else if (tx_pause)
+ fc_conf->mode = RTE_FC_TX_PAUSE;
+ else
+ fc_conf->mode = RTE_FC_NONE;
+
+ return 0;
+}
+
+static int
eth_igb_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
{
struct e1000_hw *hw;
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index 10e5633..34d6d8d 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -133,8 +133,10 @@ static void ixgbe_vlan_hw_extend_disable(struct rte_eth_dev *dev);
static int ixgbe_dev_led_on(struct rte_eth_dev *dev);
static int ixgbe_dev_led_off(struct rte_eth_dev *dev);
-static int ixgbe_flow_ctrl_set(struct rte_eth_dev *dev,
- struct rte_eth_fc_conf *fc_conf);
+static int ixgbe_flow_ctrl_get(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf);
+static int ixgbe_flow_ctrl_set(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf);
static int ixgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,
struct rte_eth_pfc_conf *pfc_conf);
static int ixgbe_dev_rss_reta_update(struct rte_eth_dev *dev,
@@ -289,6 +291,7 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
.tx_queue_release = ixgbe_dev_tx_queue_release,
.dev_led_on = ixgbe_dev_led_on,
.dev_led_off = ixgbe_dev_led_off,
+ .flow_ctrl_get = ixgbe_flow_ctrl_get,
.flow_ctrl_set = ixgbe_flow_ctrl_set,
.priority_flow_ctrl_set = ixgbe_priority_flow_ctrl_set,
.mac_addr_add = ixgbe_add_rar,
@@ -2259,6 +2262,54 @@ ixgbe_dev_led_off(struct rte_eth_dev *dev)
}
static int
+ixgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
+{
+ struct ixgbe_hw *hw;
+ uint32_t mflcn_reg;
+ uint32_t fccfg_reg;
+ int rx_pause;
+ int tx_pause;
+
+ hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ fc_conf->pause_time = hw->fc.pause_time;
+ fc_conf->high_water = hw->fc.high_water[0];
+ fc_conf->low_water = hw->fc.low_water[0];
+ fc_conf->send_xon = hw->fc.send_xon;
+
+ /*
+ * Return rx_pause status according to actual setting of
+ * MFLCN register.
+ */
+ mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+ if (mflcn_reg & (IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_RFCE))
+ rx_pause = 1;
+ else
+ rx_pause = 0;
+
+ /*
+ * Return tx_pause status according to actual setting of
+ * FCCFG register.
+ */
+ fccfg_reg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+ if (fccfg_reg & (IXGBE_FCCFG_TFCE_802_3X | IXGBE_FCCFG_TFCE_PRIORITY))
+ tx_pause = 1;
+ else
+ tx_pause = 0;
+
+ if (rx_pause && tx_pause)
+ fc_conf->mode = RTE_FC_FULL;
+ else if (rx_pause)
+ fc_conf->mode = RTE_FC_RX_PAUSE;
+ else if (tx_pause)
+ fc_conf->mode = RTE_FC_TX_PAUSE;
+ else
+ fc_conf->mode = RTE_FC_NONE;
+
+ return 0;
+}
+
+static int
ixgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
{
struct ixgbe_hw *hw;
--
1.7.10.4
next prev parent reply other threads:[~2014-06-13 13:37 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-13 13:37 [dpdk-dev] [PATCH v2 0/7] add mtu and flow control handlers David Marchand
2014-06-13 13:37 ` David Marchand [this message]
2014-06-13 13:37 ` [dpdk-dev] [PATCH v2 2/7] ethdev: add autoneg parameter in flow ctrl accessors David Marchand
2014-06-13 13:37 ` [dpdk-dev] [PATCH v2 3/7] ethdev: store min rx buffer size David Marchand
2014-06-13 13:37 ` [dpdk-dev] [PATCH v2 4/7] ethdev: introduce enable_scatter rx mode David Marchand
2014-06-13 13:37 ` [dpdk-dev] [PATCH v2 5/7] ethdev: add mtu accessors David Marchand
2014-06-13 13:37 ` [dpdk-dev] [PATCH v2 6/7] ixgbe: add set_mtu to ixgbevf David Marchand
2014-06-13 13:37 ` [dpdk-dev] [PATCH v2 7/7] app/testpmd: allow to configure mtu David Marchand
2014-06-16 17:07 ` [dpdk-dev] [PATCH v2 0/7] add mtu and flow control handlers Ananyev, Konstantin
2014-06-17 8:42 ` David Marchand
2014-06-17 8:57 ` Ananyev, Konstantin
2014-06-17 9:25 ` Thomas Monjalon
2014-06-17 11:42 ` Ananyev, Konstantin
2014-06-17 13:39 ` David Marchand
2014-06-17 15:26 ` Ananyev, Konstantin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1402666663-10260-2-git-send-email-david.marchand@6wind.com \
--to=david.marchand@6wind.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).