net/mlx4_core: Add helper to query counters
authorEran Ben Elisha <eranbe@mellanox.com>
Mon, 15 Jun 2015 14:59:05 +0000 (17:59 +0300)
committerDavid S. Miller <davem@davemloft.net>
Tue, 16 Jun 2015 00:23:02 +0000 (17:23 -0700)
This is an infrastructure step for querying VF and PF counters.

This code was in the IB driver, move it to the mlx4 core driver
so it will be accessible for more use cases.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/infiniband/hw/mlx4/mad.c
drivers/net/ethernet/mellanox/mlx4/cmd.c
include/linux/mlx4/cmd.h
include/linux/mlx4/device.h

index bc698b14683fa1d79a845dcaf053cdb9863cc1d7..bc09b4e1f57c5d0ba3c73407a824c3cbabcd9296 100644 (file)
@@ -64,14 +64,6 @@ enum {
 #define GUID_TBL_BLK_NUM_ENTRIES 8
 #define GUID_TBL_BLK_SIZE (GUID_TBL_ENTRY_SIZE * GUID_TBL_BLK_NUM_ENTRIES)
 
-/* Counters should be saturate once they reach their maximum value */
-#define ASSIGN_32BIT_COUNTER(counter, value) do {\
-       if ((value) > U32_MAX)                   \
-               counter = cpu_to_be32(U32_MAX); \
-       else                                     \
-               counter = cpu_to_be32(value);    \
-} while (0)
-
 struct mlx4_mad_rcv_buf {
        struct ib_grh grh;
        u8 payload[256];
@@ -828,31 +820,25 @@ static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                        struct ib_wc *in_wc, struct ib_grh *in_grh,
                        struct ib_mad *in_mad, struct ib_mad *out_mad)
 {
-       struct mlx4_cmd_mailbox *mailbox;
+       struct mlx4_counter counter_stats;
        struct mlx4_ib_dev *dev = to_mdev(ibdev);
        int err;
-       u32 inmod = dev->counters[port_num - 1].index & 0xffff;
-       u8 mode;
 
        if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT)
                return -EINVAL;
 
-       mailbox = mlx4_alloc_cmd_mailbox(dev->dev);
-       if (IS_ERR(mailbox))
-               return IB_MAD_RESULT_FAILURE;
-
-       err = mlx4_cmd_box(dev->dev, 0, mailbox->dma, inmod, 0,
-                          MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C,
-                          MLX4_CMD_WRAPPED);
+       memset(&counter_stats, 0, sizeof(counter_stats));
+       err = mlx4_get_counter_stats(dev->dev,
+                                    dev->counters[port_num - 1].index,
+                                    &counter_stats, 0);
        if (err)
                err = IB_MAD_RESULT_FAILURE;
        else {
                memset(out_mad->data, 0, sizeof out_mad->data);
-               mode = ((struct mlx4_counter *)mailbox->buf)->counter_mode;
-               switch (mode & 0xf) {
+               switch (counter_stats.counter_mode & 0xf) {
                case 0:
-                       edit_counter(mailbox->buf,
-                                               (void *)(out_mad->data + 40));
+                       edit_counter(&counter_stats,
+                                    (void *)(out_mad->data + 40));
                        err = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
                        break;
                default:
@@ -860,8 +846,6 @@ static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
                }
        }
 
-       mlx4_free_cmd_mailbox(dev->dev, mailbox);
-
        return err;
 }
 
index 68ae765873a9617becd0804749718a5ae3529b11..44b8f7715ade5952ac26bebd0df72cbfdad6392e 100644 (file)
@@ -49,6 +49,7 @@
 #include "mlx4.h"
 #include "fw.h"
 #include "fw_qos.h"
+#include "mlx4_stats.h"
 
 #define CMD_POLL_TOKEN 0xffff
 #define INBOX_MASK     0xffffffffffffff00ULL
@@ -3166,6 +3167,62 @@ int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_stat
 }
 EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state);
 
+int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
+                          struct mlx4_counter *counter_stats, int reset)
+{
+       struct mlx4_cmd_mailbox *mailbox = NULL;
+       struct mlx4_counter *tmp_counter;
+       int err;
+       u32 if_stat_in_mod;
+
+       if (!counter_stats)
+               return -EINVAL;
+
+       if (counter_index == MLX4_SINK_COUNTER_INDEX(dev))
+               return 0;
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+
+       memset(mailbox->buf, 0, sizeof(struct mlx4_counter));
+       if_stat_in_mod = counter_index;
+       if (reset)
+               if_stat_in_mod |= MLX4_QUERY_IF_STAT_RESET;
+       err = mlx4_cmd_box(dev, 0, mailbox->dma,
+                          if_stat_in_mod, 0,
+                          MLX4_CMD_QUERY_IF_STAT,
+                          MLX4_CMD_TIME_CLASS_C,
+                          MLX4_CMD_NATIVE);
+       if (err) {
+               mlx4_dbg(dev, "%s: failed to read statistics for counter index %d\n",
+                        __func__, counter_index);
+               goto if_stat_out;
+       }
+       tmp_counter = (struct mlx4_counter *)mailbox->buf;
+       counter_stats->counter_mode = tmp_counter->counter_mode;
+       if (counter_stats->counter_mode == 0) {
+               counter_stats->rx_frames =
+                       cpu_to_be64(be64_to_cpu(counter_stats->rx_frames) +
+                                   be64_to_cpu(tmp_counter->rx_frames));
+               counter_stats->tx_frames =
+                       cpu_to_be64(be64_to_cpu(counter_stats->tx_frames) +
+                                   be64_to_cpu(tmp_counter->tx_frames));
+               counter_stats->rx_bytes =
+                       cpu_to_be64(be64_to_cpu(counter_stats->rx_bytes) +
+                                   be64_to_cpu(tmp_counter->rx_bytes));
+               counter_stats->tx_bytes =
+                       cpu_to_be64(be64_to_cpu(counter_stats->tx_bytes) +
+                                   be64_to_cpu(tmp_counter->tx_bytes));
+       }
+
+if_stat_out:
+       mlx4_free_cmd_mailbox(dev, mailbox);
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(mlx4_get_counter_stats);
+
 int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
index f62e7cf227c61c9510e96afda8482e8f5b7b606b..5dffc869988ba65b1a837f758496322877c0dd0a 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/if_link.h>
+#include <linux/mlx4/device.h>
 
 enum {
        /* initialization and general commands */
@@ -300,6 +301,8 @@ static inline int mlx4_cmd_imm(struct mlx4_dev *dev, u64 in_param, u64 *out_para
 struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev);
 void mlx4_free_cmd_mailbox(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox);
 
+int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
+                          struct mlx4_counter *counter_stats, int reset);
 u32 mlx4_comm_get_version(void);
 int mlx4_set_vf_mac(struct mlx4_dev *dev, int port, int vf, u64 mac);
 int mlx4_set_vf_vlan(struct mlx4_dev *dev, int port, int vf, u16 vlan, u8 qos);
index 4820080ac394b1a08d372549392d95ca6a2b9767..efe80c754b2f40612f1276b3801e2622ccf2d3a0 100644 (file)
@@ -771,6 +771,14 @@ union mlx4_ext_av {
        struct mlx4_eth_av      eth;
 };
 
+/* Counters should be saturate once they reach their maximum value */
+#define ASSIGN_32BIT_COUNTER(counter, value) do {      \
+       if ((value) > U32_MAX)                          \
+               counter = cpu_to_be32(U32_MAX);         \
+       else                                            \
+               counter = cpu_to_be32(value);           \
+} while (0)
+
 struct mlx4_counter {
        u8      reserved1[3];
        u8      counter_mode;