From patchwork Mon May 22 14:32:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Jastrzebski X-Patchwork-Id: 24453 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 8D6C6377A; Mon, 22 May 2017 16:33:51 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 795DA326C for ; Mon, 22 May 2017 16:33:49 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga104.jf.intel.com with ESMTP; 22 May 2017 07:33:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.38,377,1491289200"; d="scan'208"; a="1151274814" Received: from unknown ([10.103.103.41]) by fmsmga001.fm.intel.com with SMTP; 22 May 2017 07:33:45 -0700 Received: by (sSMTP sendmail emulation); Mon, 22 May 2017 16:33:24 +0200 From: Michal Jastrzebski To: dev@dpdk.org Cc: reshma.pattan@intel.com, deepak.k.jain@intel.com, harry.van.haaren@intel.com, Michal Jastrzebski , Piotr Azarewicz Date: Mon, 22 May 2017 16:32:01 +0200 Message-Id: <20170522143202.22424-3-michalx.k.jastrzebski@intel.com> X-Mailer: git-send-email 2.12.2 In-Reply-To: <20170522143202.22424-1-michalx.k.jastrzebski@intel.com> References: <20170522143202.22424-1-michalx.k.jastrzebski@intel.com> Subject: [dpdk-dev] [PATCH 2/3] drivers/net: add support for IF-MIB and EtherLike-MIB for i40e X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" If-MIB xstats: ifNumber ifIndex ifType ifMtu ifSpeed ifPhysAddress ifOperStatus ifLastChange ifHighSpeed ifConnectorPresent ifCounterDiscontinuityTime EtherLike-MIB xstats: dot3PauseOperMode dot3StatsDuplexStatus dot3StatsRateControlAbility dot3StatsRateControlStatus dot3ControlFunctionsSupported Signed-off-by: Piotr Azarewicz Signed-off-by: Michal Jastrzebski --- drivers/net/i40e/i40e_ethdev.c | 171 +++++++++++++++++++++++++++++++++++++++- drivers/net/i40e/i40e_ethdev.h | 60 ++++++++++++++ 2 files changed, 230 insertions(+), 1 deletion(-) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 4c49673..52bc566 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -630,6 +630,45 @@ struct rte_i40e_xstats_name_off { #define I40E_NB_TXQ_PRIO_XSTATS (sizeof(rte_i40e_txq_prio_strings) / \ sizeof(rte_i40e_txq_prio_strings[0])) +static const struct rte_i40e_xstats_name_off i40e_if_mib_strings[] = { + {"ifNumber", offsetof(struct i40e_if_mib_stats, if_number)}, + {"ifIndex", offsetof(struct i40e_if_mib_stats, if_index)}, + {"ifType", offsetof(struct i40e_if_mib_stats, if_type)}, + {"ifMtu", offsetof(struct i40e_if_mib_stats, if_mtu)}, + {"ifSpeed", offsetof(struct i40e_if_mib_stats, if_speed)}, + {"ifPhysAddress", offsetof(struct i40e_if_mib_stats, if_phys_address)}, + {"ifOperStatus", offsetof(struct i40e_if_mib_stats, if_oper_status)}, + {"ifLastChange", offsetof(struct i40e_if_mib_stats, if_last_change)}, + {"ifHighSpeed", offsetof(struct i40e_if_mib_stats, if_high_speed)}, + {"ifConnectorPresent", offsetof(struct i40e_if_mib_stats, + if_connector_present)}, + {"ifCounterDiscontinuityTime", offsetof(struct i40e_if_mib_stats, + if_counter_discontinuity_time)}, +}; + +#define I40E_NB_IF_MIB_XSTATS (sizeof(i40e_if_mib_strings) / \ + sizeof(i40e_if_mib_strings[0])) + +static const struct rte_i40e_xstats_name_off i40e_ether_like_mib_strings[] = { + {"dot3PauseOperMode", offsetof(struct i40e_ether_like_mib_stats, + dot3_pause_oper_mode)}, + {"dot3StatsDuplexStatus", offsetof(struct i40e_ether_like_mib_stats, + dot3_stats_duplex_status)}, + {"dot3StatsRateControlAbility", offsetof( + struct i40e_ether_like_mib_stats, + dot3_stats_rate_control_ability)}, + {"dot3StatsRateControlStatus", offsetof( + struct i40e_ether_like_mib_stats, + dot3_stats_rate_control_status)}, + {"dot3ControlFunctionsSupported", offsetof( + struct i40e_ether_like_mib_stats, + dot3_control_functions_supported)}, +}; + +#define I40E_NB_ETHER_LIKE_MIB_XSTATS \ + (sizeof(i40e_ether_like_mib_strings) / \ + sizeof(i40e_ether_like_mib_strings[0])) + static int eth_i40e_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, struct rte_pci_device *pci_dev) { @@ -1273,6 +1312,11 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw) /* initialize pf host driver to setup SRIOV resource if applicable */ i40e_pf_host_init(dev); + /* indicate sysUpTime start */ + pf->adapter->sys_up_time_start = rte_rdtsc(); + pf->adapter->if_last_change = 0; + pf->adapter->if_counter_discontinuity_time = 0; + /* register callback func to eal lib */ rte_intr_callback_register(intr_handle, i40e_dev_interrupt_handler, dev); @@ -2235,6 +2279,8 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw) #define CHECK_INTERVAL 100 /* 100ms */ #define MAX_REPEAT_TIME 10 /* 1s (10 * 100ms) in total */ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + struct i40e_adapter *adapter = + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); struct i40e_link_status link_status; struct rte_eth_link link, old; int status; @@ -2303,6 +2349,7 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw) if (link.link_status == old.link_status) return -1; + adapter->if_last_change = rte_rdtsc() - adapter->sys_up_time_start; i40e_notify_all_vfs_link_status(dev); return 0; @@ -2683,6 +2730,9 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw) /* read the stats, reading current register values into offset */ i40e_read_stats_registers(pf, hw); + + pf->adapter->if_counter_discontinuity_time = + rte_rdtsc() - pf->adapter->sys_up_time_start; } static uint32_t @@ -2690,7 +2740,8 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw) { return I40E_NB_ETH_XSTATS + I40E_NB_HW_PORT_XSTATS + (I40E_NB_RXQ_PRIO_XSTATS * 8) + - (I40E_NB_TXQ_PRIO_XSTATS * 8); + (I40E_NB_TXQ_PRIO_XSTATS * 8) + + I40E_NB_IF_MIB_XSTATS + I40E_NB_ETHER_LIKE_MIB_XSTATS; } static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, @@ -2740,9 +2791,105 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, count++; } } + + /* Get stats from IF-MIB objects */ + for (i = 0; i < I40E_NB_IF_MIB_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", i40e_if_mib_strings[i].name); + count++; + } + + /* Get stats from Ethernet-like-MIB objects */ + for (i = 0; i < I40E_NB_ETHER_LIKE_MIB_XSTATS; i++) { + snprintf(xstats_names[count].name, + sizeof(xstats_names[count].name), + "%s", i40e_ether_like_mib_strings[i].name); + count++; + } + return count; } +static void +i40e_read_if_mib(struct rte_eth_dev *dev, struct i40e_if_mib_stats *stats) +{ + struct rte_eth_dev_data *data = dev->data; + struct rte_device *device = dev->device; + struct i40e_adapter *adapter = + I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + + stats->if_number = rte_eth_dev_count(); + stats->if_index = data->port_id + 1; + stats->if_type = I40E_MIB_IF_TYPE_ETHERNETCSMACD; + stats->if_mtu = data->mtu; + stats->if_speed = (data->dev_link.link_speed < (UINT32_MAX / 1000000)) ? + (data->dev_link.link_speed * 1000000) : UINT32_MAX; + stats->if_phys_address = 0; + ether_addr_copy(data->mac_addrs, + (struct ether_addr *)&stats->if_phys_address); + stats->if_oper_status = data->dev_link.link_status ? + i40e_mib_truth_true : i40e_mib_truth_false; + stats->if_last_change = adapter->if_last_change / + (rte_get_tsc_hz() * 100); + stats->if_high_speed = data->dev_link.link_speed; + if (device->devargs) + stats->if_connector_present = + (device->devargs->type == RTE_DEVTYPE_VIRTUAL) ? + i40e_mib_truth_false : + i40e_mib_truth_true; + else + stats->if_connector_present = 0; + stats->if_counter_discontinuity_time = + adapter->if_counter_discontinuity_time / + (rte_get_tsc_hz() * 100); +} + +static void +i40e_read_ether_like_mib(struct rte_eth_dev *dev, + struct i40e_ether_like_mib_stats *stats) +{ + struct rte_eth_dev_data *data = dev->data; + struct i40e_hw *hw = + I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + + switch (hw->fc.current_mode) { + case I40E_FC_NONE: + stats->dot3_pause_oper_mode = i40e_dot3_pause_disabled; + break; + case I40E_FC_RX_PAUSE: + stats->dot3_pause_oper_mode = i40e_dot3_pause_enabledrcv; + break; + case I40E_FC_TX_PAUSE: + stats->dot3_pause_oper_mode = i40e_dot3_pause_enabledxmit; + break; + case I40E_FC_FULL: + stats->dot3_pause_oper_mode = + i40e_dot3_pause_enabledxmitandrcv; + break; + default: + stats->dot3_pause_oper_mode = 0; + break; + } + + switch (data->dev_link.link_duplex) { + case ETH_LINK_FULL_DUPLEX: + stats->dot3_stats_duplex_status = i40e_dot3_duplex_fullduplex; + break; + case ETH_LINK_HALF_DUPLEX: + stats->dot3_stats_duplex_status = i40e_dot3_duplex_halfduplex; + break; + default: + stats->dot3_stats_duplex_status = i40e_dot3_duplex_unknown; + break; + } + + stats->dot3_stats_rate_control_ability = i40e_mib_truth_false; + stats->dot3_stats_rate_control_status = i40e_dot3_rate_control_off; + stats->dot3_control_functions_supported = I40E_DOT3_CF_PAUSE | + I40E_DOT3_CF_PFC; +} + static int i40e_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats, unsigned n) @@ -2751,6 +2898,8 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); unsigned i, count, prio; struct i40e_hw_port_stats *hw_stats = &pf->stats; + struct i40e_if_mib_stats if_mib_stats; + struct i40e_ether_like_mib_stats ether_like_mib_stats; count = i40e_xstats_calc_num(); if (n < count) @@ -2758,6 +2907,9 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, i40e_read_stats_registers(pf, hw); + i40e_read_if_mib(dev, &if_mib_stats); + i40e_read_ether_like_mib(dev, ðer_like_mib_stats); + if (xstats == NULL) return 0; @@ -2801,6 +2953,23 @@ static int i40e_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, } } + /* Get stats from IF-MIB objects */ + for (i = 0; i < I40E_NB_IF_MIB_XSTATS; i++) { + xstats[count].value = *(uint64_t *)(((char *)&if_mib_stats) + + i40e_if_mib_strings[i].offset); + xstats[count].id = count; + count++; + } + + /* Get stats from Ethernet-like-MIB objects */ + for (i = 0; i < I40E_NB_ETHER_LIKE_MIB_XSTATS; i++) { + xstats[count].value = + *(uint64_t *)(((char *)ðer_like_mib_stats) + + i40e_ether_like_mib_strings[i].offset); + xstats[count].id = count; + count++; + } + return count; } diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 2ff8282..7a4d9ac 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -625,6 +625,62 @@ struct rte_flow { TAILQ_HEAD(i40e_flow_list, rte_flow); +#define I40E_MIB_IF_TYPE_ETHERNETCSMACD 6 + +enum i40e_mib_truth_value { + i40e_mib_truth_true = 1, + i40e_mib_truth_false +}; + +/* IF-MIB statistics */ +struct i40e_if_mib_stats { + uint64_t if_number; /* ifNumber */ + uint64_t if_index; /* ifIndex */ + uint64_t if_type; /* ifType */ + uint64_t if_mtu; /* ifMtu */ + uint64_t if_speed; /* ifSpeed */ + uint64_t if_phys_address; /* ifPhysAddress */ + uint64_t if_oper_status; /* ifOperStatus */ + uint64_t if_last_change; /* ifLastChange */ + uint64_t if_high_speed; /* ifHighSpeed */ + uint64_t if_connector_present; /* ifConnectorPresent */ + uint64_t if_counter_discontinuity_time; /* ifCounterDiscontinuityTime */ +}; + +enum i40e_dot3_pause_oper_mode { + i40e_dot3_pause_disabled = 1, + i40e_dot3_pause_enabledxmit, + i40e_dot3_pause_enabledrcv, + i40e_dot3_pause_enabledxmitandrcv +}; + +enum i40e_dot3_stats_duplex_status { + i40e_dot3_duplex_unknown = 1, + i40e_dot3_duplex_halfduplex, + i40e_dot3_duplex_fullduplex +}; + +enum i40e_dot3_stats_rate_control_status { + i40e_dot3_rate_control_off = 1, + i40e_dot3_rate_control_on, + i40e_dot3_rate_control_unknown +}; + +#define I40E_DOT3_CF_PAUSE (1 << 0) /* PAUSE command implemented */ +#define I40E_DOT3_CF_MPCP (1 << 1) /* MPCP implemented */ +#define I40E_DOT3_CF_PFC (1 << 2) /* PFC implemented */ + +/* Ethernet-like-MIB statistics */ +struct i40e_ether_like_mib_stats { + uint64_t dot3_pause_oper_mode; /* dot3PauseOperMode */ + uint64_t dot3_stats_duplex_status; /* dot3StatsDuplexStatus */ + uint64_t dot3_stats_rate_control_ability; + /* dot3StatsRateControlAbility */ + uint64_t dot3_stats_rate_control_status;/* dot3StatsRateControlStatus */ + uint64_t dot3_control_functions_supported; + /* dot3ControlFunctionsSupported */ +}; + /* * Structure to store private data specific for PF instance. */ @@ -778,6 +834,10 @@ struct i40e_adapter { struct rte_timecounter rx_tstamp_tc; struct rte_timecounter tx_tstamp_tc; + uint64_t sys_up_time_start; + uint64_t if_last_change; + uint64_t if_counter_discontinuity_time; + /* ptype mapping table */ uint32_t ptype_tbl[I40E_MAX_PKT_TYPE] __rte_cache_min_aligned; };