]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
liquidio: Added ndo_get_vf_stats support
authorIntiyaz Basha <intiyaz.basha@cavium.com>
Thu, 19 Apr 2018 06:18:28 +0000 (23:18 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Apr 2018 14:53:46 +0000 (10:53 -0400)
Added the ndo to gather VF statistics through the PF.

Collect VF statistics via mailbox from VF.

Signed-off-by: Intiyaz Basha <intiyaz.basha@cavium.com>
Signed-off-by: Felix Manlunas <felix.manlunas@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h
drivers/net/ethernet/cavium/liquidio/lio_main.c
drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h

index e8b290473ee25fe3c6f5b9683c86b87254d3767b..bc9861c90ea3472060e15ded6a1032fffc0a6cd1 100644 (file)
@@ -1497,3 +1497,57 @@ void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx,
                octeon_mbox_write(oct, &mbox_cmd);
        }
 }
+
+static void
+cn23xx_get_vf_stats_callback(struct octeon_device *oct,
+                            struct octeon_mbox_cmd *cmd, void *arg)
+{
+       struct oct_vf_stats_ctx *ctx = arg;
+
+       memcpy(ctx->stats, cmd->data, sizeof(struct oct_vf_stats));
+       atomic_set(&ctx->status, 1);
+}
+
+int cn23xx_get_vf_stats(struct octeon_device *oct, int vfidx,
+                       struct oct_vf_stats *stats)
+{
+       u32 timeout = HZ; // 1sec
+       struct octeon_mbox_cmd mbox_cmd;
+       struct oct_vf_stats_ctx ctx;
+       u32 count = 0, ret;
+
+       if (!(oct->sriov_info.vf_drv_loaded_mask & (1ULL << vfidx)))
+               return -1;
+
+       if (sizeof(struct oct_vf_stats) > sizeof(mbox_cmd.data))
+               return -1;
+
+       mbox_cmd.msg.u64 = 0;
+       mbox_cmd.msg.s.type = OCTEON_MBOX_REQUEST;
+       mbox_cmd.msg.s.resp_needed = 1;
+       mbox_cmd.msg.s.cmd = OCTEON_GET_VF_STATS;
+       mbox_cmd.msg.s.len = 1;
+       mbox_cmd.q_no = vfidx * oct->sriov_info.rings_per_vf;
+       mbox_cmd.recv_len = 0;
+       mbox_cmd.recv_status = 0;
+       mbox_cmd.fn = (octeon_mbox_callback_t)cn23xx_get_vf_stats_callback;
+       ctx.stats = stats;
+       atomic_set(&ctx.status, 0);
+       mbox_cmd.fn_arg = (void *)&ctx;
+       memset(mbox_cmd.data, 0, sizeof(mbox_cmd.data));
+       octeon_mbox_write(oct, &mbox_cmd);
+
+       do {
+               schedule_timeout_uninterruptible(1);
+       } while ((atomic_read(&ctx.status) == 0) && (count++ < timeout));
+
+       ret = atomic_read(&ctx.status);
+       if (ret == 0) {
+               octeon_mbox_cancel(oct, 0);
+               dev_err(&oct->pci_dev->dev, "Unable to get stats from VF-%d, timedout\n",
+                       vfidx);
+               return -1;
+       }
+
+       return 0;
+}
index 2aba5247b6d8d7b917aa11327b499643ceb106c3..63b3de4f2bfedd4e91f97ddda41a0a217631391a 100644 (file)
@@ -43,6 +43,15 @@ struct octeon_cn23xx_pf {
 
 #define CN23XX_SLI_DEF_BP                      0x40
 
+struct oct_vf_stats {
+       u64 rx_packets;
+       u64 tx_packets;
+       u64 rx_bytes;
+       u64 tx_bytes;
+       u64 broadcast;
+       u64 multicast;
+};
+
 int setup_cn23xx_octeon_pf_device(struct octeon_device *oct);
 
 int validate_cn23xx_pf_config_info(struct octeon_device *oct,
@@ -56,4 +65,7 @@ int cn23xx_fw_loaded(struct octeon_device *oct);
 
 void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx,
                                        u8 *mac);
+
+int cn23xx_get_vf_stats(struct octeon_device *oct, int ifidx,
+                       struct oct_vf_stats *stats);
 #endif
index 44c2a0c1bbdd1be48f4680a498031bc52d0b9ff8..f3891ae11b02cfd9b37844f64bf2e98504007d82 100644 (file)
@@ -3326,6 +3326,31 @@ static const struct switchdev_ops lio_pf_switchdev_ops = {
        .switchdev_port_attr_get = lio_pf_switchdev_attr_get,
 };
 
+static int liquidio_get_vf_stats(struct net_device *netdev, int vfidx,
+                                struct ifla_vf_stats *vf_stats)
+{
+       struct lio *lio = GET_LIO(netdev);
+       struct octeon_device *oct = lio->oct_dev;
+       struct oct_vf_stats stats;
+       int ret;
+
+       if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced)
+               return -EINVAL;
+
+       memset(&stats, 0, sizeof(struct oct_vf_stats));
+       ret = cn23xx_get_vf_stats(oct, vfidx, &stats);
+       if (!ret) {
+               vf_stats->rx_packets = stats.rx_packets;
+               vf_stats->tx_packets = stats.tx_packets;
+               vf_stats->rx_bytes = stats.rx_bytes;
+               vf_stats->tx_bytes = stats.tx_bytes;
+               vf_stats->broadcast = stats.broadcast;
+               vf_stats->multicast = stats.multicast;
+       }
+
+       return ret;
+}
+
 static const struct net_device_ops lionetdevops = {
        .ndo_open               = liquidio_open,
        .ndo_stop               = liquidio_stop,
@@ -3348,6 +3373,7 @@ static const struct net_device_ops lionetdevops = {
        .ndo_get_vf_config      = liquidio_get_vf_config,
        .ndo_set_vf_trust       = liquidio_set_vf_trust,
        .ndo_set_vf_link_state  = liquidio_set_vf_link_state,
+       .ndo_get_vf_stats       = liquidio_get_vf_stats,
 };
 
 /** \brief Entry point for the liquidio module
index 28e74ee23ff85a6056c09328fb91549c094cc93d..021d99cd166550f2a8a81d3dbe4d60799e7c1bd9 100644 (file)
@@ -24,6 +24,7 @@
 #include "octeon_device.h"
 #include "octeon_main.h"
 #include "octeon_mailbox.h"
+#include "cn23xx_pf_device.h"
 
 /**
  * octeon_mbox_read:
@@ -205,6 +206,26 @@ int octeon_mbox_write(struct octeon_device *oct,
        return ret;
 }
 
+static void get_vf_stats(struct octeon_device *oct,
+                        struct oct_vf_stats *stats)
+{
+       int i;
+
+       for (i = 0; i < oct->num_iqs; i++) {
+               if (!oct->instr_queue[i])
+                       continue;
+               stats->tx_packets += oct->instr_queue[i]->stats.tx_done;
+               stats->tx_bytes += oct->instr_queue[i]->stats.tx_tot_bytes;
+       }
+
+       for (i = 0; i < oct->num_oqs; i++) {
+               if (!oct->droq[i])
+                       continue;
+               stats->rx_packets += oct->droq[i]->stats.rx_pkts_received;
+               stats->rx_bytes += oct->droq[i]->stats.rx_bytes_received;
+       }
+}
+
 /**
  * octeon_mbox_process_cmd:
  * @mbox: Pointer mailbox
@@ -250,6 +271,15 @@ static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
                                                     mbox_cmd->msg.s.params);
                break;
 
+       case OCTEON_GET_VF_STATS:
+               dev_dbg(&oct->pci_dev->dev, "Got VF stats request. Sending data back\n");
+               mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE;
+               mbox_cmd->msg.s.resp_needed = 1;
+               mbox_cmd->msg.s.len = 1 +
+                       sizeof(struct oct_vf_stats) / sizeof(u64);
+               get_vf_stats(oct, (struct oct_vf_stats *)mbox_cmd->data);
+               octeon_mbox_write(oct, mbox_cmd);
+               break;
        default:
                break;
        }
@@ -322,3 +352,25 @@ int octeon_mbox_process_message(struct octeon_mbox *mbox)
 
        return 0;
 }
+
+int octeon_mbox_cancel(struct octeon_device *oct, int q_no)
+{
+       struct octeon_mbox *mbox = oct->mbox[q_no];
+       struct octeon_mbox_cmd *mbox_cmd;
+       unsigned long flags = 0;
+
+       spin_lock_irqsave(&mbox->lock, flags);
+       mbox_cmd = &mbox->mbox_resp;
+
+       if (!(mbox->state & OCTEON_MBOX_STATE_RESPONSE_PENDING)) {
+               spin_unlock_irqrestore(&mbox->lock, flags);
+               return 1;
+       }
+
+       mbox->state = OCTEON_MBOX_STATE_IDLE;
+       memset(mbox_cmd, 0, sizeof(*mbox_cmd));
+       writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
+       spin_unlock_irqrestore(&mbox->lock, flags);
+
+       return 0;
+}
index 1def22afeff1049edc8e5eb0923ad904cc57fcbd..d92bd7e164775b9523430a04fa5dddfa5bbbc929 100644 (file)
@@ -25,6 +25,7 @@
 #define OCTEON_VF_ACTIVE               0x1
 #define OCTEON_VF_FLR_REQUEST          0x2
 #define OCTEON_PF_CHANGED_VF_MACADDR   0x4
+#define OCTEON_GET_VF_STATS            0x8
 
 /*Macro for Read acknowldgement*/
 #define OCTEON_PFVFACK                 0xffffffffffffffffULL
@@ -107,9 +108,15 @@ struct octeon_mbox {
 
 };
 
+struct oct_vf_stats_ctx {
+       atomic_t status;
+       struct oct_vf_stats *stats;
+};
+
 int octeon_mbox_read(struct octeon_mbox *mbox);
 int octeon_mbox_write(struct octeon_device *oct,
                      struct octeon_mbox_cmd *mbox_cmd);
 int octeon_mbox_process_message(struct octeon_mbox *mbox);
+int octeon_mbox_cancel(struct octeon_device *oct, int q_no);
 
 #endif