Skip to content

Commit

Permalink
liquidio: Added ndo_get_vf_stats support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Intiyaz Basha authored and David S. Miller committed Apr 20, 2018
1 parent eaa008d commit cea395a
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 0 deletions.
54 changes: 54 additions & 0 deletions drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
12 changes: 12 additions & 0 deletions drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
26 changes: 26 additions & 0 deletions drivers/net/ethernet/cavium/liquidio/lio_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
52 changes: 52 additions & 0 deletions drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "octeon_device.h"
#include "octeon_main.h"
#include "octeon_mailbox.h"
#include "cn23xx_pf_device.h"

/**
* octeon_mbox_read:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
7 changes: 7 additions & 0 deletions drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

0 comments on commit cea395a

Please sign in to comment.