From patchwork Tue Mar 28 03:48:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 22480 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 36580D23A; Tue, 28 Mar 2017 05:50:14 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (lpdvrndsmtp01.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id A65512C1A for ; Tue, 28 Mar 2017 05:49:20 +0200 (CEST) Received: from mail-irv-17.broadcom.com (mail-irv-17.lvn.broadcom.net [10.75.224.233]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id AE3A330D2BC; Mon, 27 Mar 2017 20:49:19 -0700 (PDT) Received: from C02PT1RBG8WP.vpn.broadcom.net (unknown [10.10.115.230]) by mail-irv-17.broadcom.com (Postfix) with ESMTP id 3641E81E9A; Mon, 27 Mar 2017 20:49:19 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: Stephen Hurd Date: Mon, 27 Mar 2017 22:48:56 -0500 Message-Id: <20170328034903.41482-22-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20170328034903.41482-1-ajit.khaparde@broadcom.com> References: <20170328034903.41482-1-ajit.khaparde@broadcom.com> Subject: [dpdk-dev] [PATCH 21/28] bnxt: Add VF stats get/reset functions 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" This patch adds functions to get/reset VF stats. It also adds the HWRM API needed to support this. Signed-off-by: Stephen Hurd Signed-off-by: Ajit Khaparde --- drivers/net/bnxt/bnxt_hwrm.c | 55 ++++++++ drivers/net/bnxt/bnxt_hwrm.h | 3 + drivers/net/bnxt/hsi_struct_def_dpdk.h | 219 ++++++++++++++++++++++++++++++ drivers/net/bnxt/rte_pmd_bnxt.c | 49 +++++++ drivers/net/bnxt/rte_pmd_bnxt.h | 33 +++++ drivers/net/bnxt/rte_pmd_bnxt_version.map | 2 + 6 files changed, 361 insertions(+) diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index 41e3e50..47f264b 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -1151,6 +1151,61 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id, return rc; } +int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid, + struct rte_eth_stats *stats) +{ + int rc = 0; + struct hwrm_func_qstats_input req = {.req_type = 0}; + struct hwrm_func_qstats_output *resp = bp->hwrm_cmd_resp_addr; + + HWRM_PREP(req, FUNC_QSTATS, -1, resp); + + req.fid = rte_cpu_to_le_16(fid); + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req)); + + HWRM_CHECK_RESULT; + + memset(stats, 0, sizeof(*stats)); + + stats->ipackets = rte_le_to_cpu_64(resp->rx_ucast_pkts); + stats->ipackets += rte_le_to_cpu_64(resp->rx_mcast_pkts); + stats->ipackets += rte_le_to_cpu_64(resp->rx_bcast_pkts); + stats->ibytes = rte_le_to_cpu_64(resp->rx_ucast_bytes); + stats->ibytes += rte_le_to_cpu_64(resp->rx_mcast_bytes); + stats->ibytes += rte_le_to_cpu_64(resp->rx_bcast_bytes); + + stats->opackets = rte_le_to_cpu_64(resp->tx_ucast_pkts); + stats->opackets += rte_le_to_cpu_64(resp->tx_mcast_pkts); + stats->opackets += rte_le_to_cpu_64(resp->tx_bcast_pkts); + stats->obytes = rte_le_to_cpu_64(resp->tx_ucast_bytes); + stats->obytes += rte_le_to_cpu_64(resp->tx_mcast_bytes); + stats->obytes += rte_le_to_cpu_64(resp->tx_bcast_bytes); + + stats->ierrors = rte_le_to_cpu_64(resp->rx_err_pkts); + stats->oerrors = rte_le_to_cpu_64(resp->tx_err_pkts); + stats->rx_nombuf = rte_le_to_cpu_64(resp->rx_drop_pkts); + + return rc; +} + +int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid) +{ + int rc = 0; + struct hwrm_func_clr_stats_input req = {.req_type = 0}; + struct hwrm_func_clr_stats_output *resp = bp->hwrm_cmd_resp_addr; + + HWRM_PREP(req, FUNC_CLR_STATS, -1, resp); + + req.fid = rte_cpu_to_le_16(fid); + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req)); + + HWRM_CHECK_RESULT; + + return rc; +} + /* * HWRM utility functions */ diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index 5e73136..33c246c 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -63,6 +63,9 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp); int bnxt_hwrm_func_qcaps(struct bnxt *bp); int bnxt_hwrm_func_reset(struct bnxt *bp); int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags); +int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid, + struct rte_eth_stats *stats); +int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid); int bnxt_hwrm_queue_qportcfg(struct bnxt *bp); diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h index c2ca6f5..31b8557 100644 --- a/drivers/net/bnxt/hsi_struct_def_dpdk.h +++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h @@ -90,6 +90,8 @@ struct ctx_hw_stats64 { #define HWRM_FUNC_QCAPS (UINT32_C(0x15)) #define HWRM_FUNC_QCFG (UINT32_C(0x16)) #define HWRM_FUNC_CFG (UINT32_C(0x17)) +#define HWRM_FUNC_QSTATS (UINT32_C(0x18)) +#define HWRM_FUNC_CLR_STATS (UINT32_C(0x19)) #define HWRM_FUNC_DRV_UNRGTR (UINT32_C(0x1a)) #define HWRM_FUNC_VF_VNIC_IDS_QUERY (UINT32_C(0x1c)) #define HWRM_FUNC_DRV_RGTR (UINT32_C(0x1d)) @@ -2809,6 +2811,223 @@ struct hwrm_func_cfg_output { */ } __attribute__((packed)); +/* hwrm_func_qstats */ +/* + * Description: This command returns statistics of a function. The input FID + * value is used to indicate what function is being queried. This allows a + * physical function driver to query virtual functions that are children of the + * physical function. The HWRM shall return any unsupported counter with a value + * of 0xFFFFFFFF for 32-bit counters and 0xFFFFFFFFFFFFFFFF for 64-bit counters. + */ +/* Input (24 bytes) */ +struct hwrm_func_qstats_input { + uint16_t req_type; + /* + * This value indicates what type of request this is. The format + * for the rest of the command is determined by this field. + */ + uint16_t cmpl_ring; + /* + * This value indicates the what completion ring the request + * will be optionally completed on. If the value is -1, then no + * CR completion will be generated. Any other value must be a + * valid CR ring_id value for this function. + */ + uint16_t seq_id; + /* This value indicates the command sequence number. */ + uint16_t target_id; + /* + * Target ID of this command. 0x0 - 0xFFF8 - Used for function + * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF + * - HWRM + */ + uint64_t resp_addr; + /* + * This is the host address where the response will be written + * when the request is complete. This area must be 16B aligned + * and must be cleared to zero before the request is made. + */ + uint16_t fid; + /* + * Function ID of the function that is being queried. 0xFF... + * (All Fs) if the query is for the requesting function. + */ + uint16_t unused_0[3]; +} __attribute__((packed)); + +/* Output (176 bytes) */ +struct hwrm_func_qstats_output { + uint16_t error_code; + /* + * Pass/Fail or error type Note: receiver to verify the in + * parameters, and fail the call with an error when appropriate + */ + uint16_t req_type; + /* This field returns the type of original request. */ + uint16_t seq_id; + /* This field provides original sequence number of the command. */ + uint16_t resp_len; + /* + * This field is the length of the response in bytes. The last + * byte of the response is a valid flag that will read as '1' + * when the command has been completely written to memory. + */ + uint64_t tx_ucast_pkts; + /* Number of transmitted unicast packets on the function. */ + uint64_t tx_mcast_pkts; + /* Number of transmitted multicast packets on the function. */ + uint64_t tx_bcast_pkts; + /* Number of transmitted broadcast packets on the function. */ + uint64_t tx_err_pkts; + /* + * Number of transmitted packets that were discarded due to + * internal NIC resource problems. For transmit, this can only + * happen if TMP is configured to allow dropping in HOL blocking + * conditions, which is not a normal configuration. + */ + uint64_t tx_drop_pkts; + /* + * Number of dropped packets on transmit path on the function. + * These are packets that have been marked for drop by the TE + * CFA block or are packets that exceeded the transmit MTU limit + * for the function. + */ + uint64_t tx_ucast_bytes; + /* Number of transmitted bytes for unicast traffic on the function. */ + uint64_t tx_mcast_bytes; + /* + * Number of transmitted bytes for multicast traffic on the + * function. + */ + uint64_t tx_bcast_bytes; + /* + * Number of transmitted bytes for broadcast traffic on the + * function. + */ + uint64_t rx_ucast_pkts; + /* Number of received unicast packets on the function. */ + uint64_t rx_mcast_pkts; + /* Number of received multicast packets on the function. */ + uint64_t rx_bcast_pkts; + /* Number of received broadcast packets on the function. */ + uint64_t rx_err_pkts; + /* + * Number of received packets that were discarded on the + * function due to resource limitations. This can happen for 3 + * reasons. # The BD used for the packet has a bad format. # + * There were no BDs available in the ring for the packet. # + * There were no BDs available on-chip for the packet. + */ + uint64_t rx_drop_pkts; + /* + * Number of dropped packets on received path on the function. + * These are packets that have been marked for drop by the RE + * CFA. + */ + uint64_t rx_ucast_bytes; + /* Number of received bytes for unicast traffic on the function. */ + uint64_t rx_mcast_bytes; + /* Number of received bytes for multicast traffic on the function. */ + uint64_t rx_bcast_bytes; + /* Number of received bytes for broadcast traffic on the function. */ + uint64_t rx_agg_pkts; + /* Number of aggregated unicast packets on the function. */ + uint64_t rx_agg_bytes; + /* Number of aggregated unicast bytes on the function. */ + uint64_t rx_agg_events; + /* Number of aggregation events on the function. */ + uint64_t rx_agg_aborts; + /* Number of aborted aggregations on the function. */ + uint32_t unused_0; + uint8_t unused_1; + uint8_t unused_2; + uint8_t unused_3; + uint8_t valid; + /* + * This field is used in Output records to indicate that the + * output is completely written to RAM. This field should be + * read as '1' to indicate that the output has been completely + * written. When writing a command completion or response to an + * internal processor, the order of writes has to be such that + * this field is written last. + */ +} __attribute__((packed)); + +/* hwrm_func_clr_stats */ +/* + * Description: This command clears statistics of a function. The input FID + * value is used to indicate what function's statistics is being cleared. This + * allows a physical function driver to clear statistics of virtual functions + * that are children of the physical function. + */ +/* Input (24 bytes) */ +struct hwrm_func_clr_stats_input { + uint16_t req_type; + /* + * This value indicates what type of request this is. The format + * for the rest of the command is determined by this field. + */ + uint16_t cmpl_ring; + /* + * This value indicates the what completion ring the request + * will be optionally completed on. If the value is -1, then no + * CR completion will be generated. Any other value must be a + * valid CR ring_id value for this function. + */ + uint16_t seq_id; + /* This value indicates the command sequence number. */ + uint16_t target_id; + /* + * Target ID of this command. 0x0 - 0xFFF8 - Used for function + * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF + * - HWRM + */ + uint64_t resp_addr; + /* + * This is the host address where the response will be written + * when the request is complete. This area must be 16B aligned + * and must be cleared to zero before the request is made. + */ + uint16_t fid; + /* + * Function ID of the function. 0xFF... (All Fs) if the query is + * for the requesting function. + */ + uint16_t unused_0[3]; +} __attribute__((packed)); + +/* Output (16 bytes) */ +struct hwrm_func_clr_stats_output { + uint16_t error_code; + /* + * Pass/Fail or error type Note: receiver to verify the in + * parameters, and fail the call with an error when appropriate + */ + uint16_t req_type; + /* This field returns the type of original request. */ + uint16_t seq_id; + /* This field provides original sequence number of the command. */ + uint16_t resp_len; + /* + * This field is the length of the response in bytes. The last + * byte of the response is a valid flag that will read as '1' + * when the command has been completely written to memory. + */ + uint32_t unused_0; + uint8_t unused_1; + uint8_t unused_2; + uint8_t unused_3; + uint8_t valid; + /* + * This field is used in Output records to indicate that the + * output is completely written to RAM. This field should be + * read as '1' to indicate that the output has been completely + * written. When writing a command completion or response to an + * internal processor, the order of writes has to be such that + * this field is written last. + */ +} __attribute__((packed)); + /* hwrm_func_drv_rgtr */ /* * Description: This command is used by the function driver to register its diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c index 370d865..d59c38b 100644 --- a/drivers/net/bnxt/rte_pmd_bnxt.c +++ b/drivers/net/bnxt/rte_pmd_bnxt.c @@ -429,3 +429,52 @@ int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf, return rc; } + +int rte_pmd_bnxt_get_vf_stats(uint8_t port, + uint16_t vf_id, + struct rte_eth_stats *stats) +{ + struct rte_eth_dev *dev; + struct rte_eth_dev_info dev_info; + struct bnxt *bp; + + dev = &rte_eth_devices[port]; + rte_eth_dev_info_get(port, &dev_info); + bp = (struct bnxt *)dev->data->dev_private; + + if (vf_id >= dev_info.max_vfs) + return -EINVAL; + + if (!BNXT_PF(bp)) { + RTE_LOG(ERR, PMD, + "Attempt to get VF %d stats on non-PF port %d!\n", + vf_id, port); + return -ENOTSUP; + } + + return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats); +} + +int rte_pmd_bnxt_reset_vf_stats(uint8_t port, + uint16_t vf_id) +{ + struct rte_eth_dev *dev; + struct rte_eth_dev_info dev_info; + struct bnxt *bp; + + dev = &rte_eth_devices[port]; + rte_eth_dev_info_get(port, &dev_info); + bp = (struct bnxt *)dev->data->dev_private; + + if (vf_id >= dev_info.max_vfs) + return -EINVAL; + + if (!BNXT_PF(bp)) { + RTE_LOG(ERR, PMD, + "Attempt to reset VF %d stats on non-PF port %d!\n", + vf_id, port); + return -ENOTSUP; + } + + return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id); +} diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h index e509c62..d78b575 100644 --- a/drivers/net/bnxt/rte_pmd_bnxt.h +++ b/drivers/net/bnxt/rte_pmd_bnxt.h @@ -229,4 +229,37 @@ int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on); */ int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf, uint16_t rx_mask, uint8_t on); + +/** + * Get VF's statistics + * + * @param port + * The port identifier of the Ethernet device. + * @param vf_id + * VF on which to get. + * @param stats + * A pointer to a structure of type *rte_eth_stats* to be filled with + * the values of device counters supported statistics: + * @return + * - (0) if successful. + * - (-ENODEV) if *port* invalid. + * - (-EINVAL) if bad parameter. + */ + +int rte_pmd_bnxt_get_vf_stats(uint8_t port, uint16_t vf_id, + struct rte_eth_stats *stats); + +/** + * Clear VF's statistics + * + * @param port + * The port identifier of the Ethernet device. + * @param vf_id + * VF on which to get. + * @return + * - (0) if successful. + * - (-ENODEV) if *port* invalid. + * - (-EINVAL) if bad parameter. + */ +int rte_pmd_bnxt_reset_vf_stats(uint8_t port, uint16_t vf_id); #endif /* _PMD_BNXT_H_ */ diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map index af6300a..1fd271b 100644 --- a/drivers/net/bnxt/rte_pmd_bnxt_version.map +++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map @@ -9,5 +9,7 @@ DPDK_17.05 { rte_pmd_bnxt_set_vf_vlan_stripq; rte_pmd_bnxt_set_vf_vlan_insert; rte_pmd_bnxt_set_vf_rxmode; + rte_pmd_bnxt_get_vf_stats; + rte_pmd_bnxt_reset_vf_stats; };