Skip to content

Commit cea395a

Browse files
Intiyaz Bashadavem330
authored andcommitted
liquidio: Added ndo_get_vf_stats support
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>
1 parent eaa008d commit cea395a

File tree

5 files changed

+151
-0
lines changed

5 files changed

+151
-0
lines changed

drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,3 +1497,57 @@ void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx,
14971497
octeon_mbox_write(oct, &mbox_cmd);
14981498
}
14991499
}
1500+
1501+
static void
1502+
cn23xx_get_vf_stats_callback(struct octeon_device *oct,
1503+
struct octeon_mbox_cmd *cmd, void *arg)
1504+
{
1505+
struct oct_vf_stats_ctx *ctx = arg;
1506+
1507+
memcpy(ctx->stats, cmd->data, sizeof(struct oct_vf_stats));
1508+
atomic_set(&ctx->status, 1);
1509+
}
1510+
1511+
int cn23xx_get_vf_stats(struct octeon_device *oct, int vfidx,
1512+
struct oct_vf_stats *stats)
1513+
{
1514+
u32 timeout = HZ; // 1sec
1515+
struct octeon_mbox_cmd mbox_cmd;
1516+
struct oct_vf_stats_ctx ctx;
1517+
u32 count = 0, ret;
1518+
1519+
if (!(oct->sriov_info.vf_drv_loaded_mask & (1ULL << vfidx)))
1520+
return -1;
1521+
1522+
if (sizeof(struct oct_vf_stats) > sizeof(mbox_cmd.data))
1523+
return -1;
1524+
1525+
mbox_cmd.msg.u64 = 0;
1526+
mbox_cmd.msg.s.type = OCTEON_MBOX_REQUEST;
1527+
mbox_cmd.msg.s.resp_needed = 1;
1528+
mbox_cmd.msg.s.cmd = OCTEON_GET_VF_STATS;
1529+
mbox_cmd.msg.s.len = 1;
1530+
mbox_cmd.q_no = vfidx * oct->sriov_info.rings_per_vf;
1531+
mbox_cmd.recv_len = 0;
1532+
mbox_cmd.recv_status = 0;
1533+
mbox_cmd.fn = (octeon_mbox_callback_t)cn23xx_get_vf_stats_callback;
1534+
ctx.stats = stats;
1535+
atomic_set(&ctx.status, 0);
1536+
mbox_cmd.fn_arg = (void *)&ctx;
1537+
memset(mbox_cmd.data, 0, sizeof(mbox_cmd.data));
1538+
octeon_mbox_write(oct, &mbox_cmd);
1539+
1540+
do {
1541+
schedule_timeout_uninterruptible(1);
1542+
} while ((atomic_read(&ctx.status) == 0) && (count++ < timeout));
1543+
1544+
ret = atomic_read(&ctx.status);
1545+
if (ret == 0) {
1546+
octeon_mbox_cancel(oct, 0);
1547+
dev_err(&oct->pci_dev->dev, "Unable to get stats from VF-%d, timedout\n",
1548+
vfidx);
1549+
return -1;
1550+
}
1551+
1552+
return 0;
1553+
}

drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ struct octeon_cn23xx_pf {
4343

4444
#define CN23XX_SLI_DEF_BP 0x40
4545

46+
struct oct_vf_stats {
47+
u64 rx_packets;
48+
u64 tx_packets;
49+
u64 rx_bytes;
50+
u64 tx_bytes;
51+
u64 broadcast;
52+
u64 multicast;
53+
};
54+
4655
int setup_cn23xx_octeon_pf_device(struct octeon_device *oct);
4756

4857
int validate_cn23xx_pf_config_info(struct octeon_device *oct,
@@ -56,4 +65,7 @@ int cn23xx_fw_loaded(struct octeon_device *oct);
5665

5766
void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx,
5867
u8 *mac);
68+
69+
int cn23xx_get_vf_stats(struct octeon_device *oct, int ifidx,
70+
struct oct_vf_stats *stats);
5971
#endif

drivers/net/ethernet/cavium/liquidio/lio_main.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3326,6 +3326,31 @@ static const struct switchdev_ops lio_pf_switchdev_ops = {
33263326
.switchdev_port_attr_get = lio_pf_switchdev_attr_get,
33273327
};
33283328

3329+
static int liquidio_get_vf_stats(struct net_device *netdev, int vfidx,
3330+
struct ifla_vf_stats *vf_stats)
3331+
{
3332+
struct lio *lio = GET_LIO(netdev);
3333+
struct octeon_device *oct = lio->oct_dev;
3334+
struct oct_vf_stats stats;
3335+
int ret;
3336+
3337+
if (vfidx < 0 || vfidx >= oct->sriov_info.num_vfs_alloced)
3338+
return -EINVAL;
3339+
3340+
memset(&stats, 0, sizeof(struct oct_vf_stats));
3341+
ret = cn23xx_get_vf_stats(oct, vfidx, &stats);
3342+
if (!ret) {
3343+
vf_stats->rx_packets = stats.rx_packets;
3344+
vf_stats->tx_packets = stats.tx_packets;
3345+
vf_stats->rx_bytes = stats.rx_bytes;
3346+
vf_stats->tx_bytes = stats.tx_bytes;
3347+
vf_stats->broadcast = stats.broadcast;
3348+
vf_stats->multicast = stats.multicast;
3349+
}
3350+
3351+
return ret;
3352+
}
3353+
33293354
static const struct net_device_ops lionetdevops = {
33303355
.ndo_open = liquidio_open,
33313356
.ndo_stop = liquidio_stop,
@@ -3348,6 +3373,7 @@ static const struct net_device_ops lionetdevops = {
33483373
.ndo_get_vf_config = liquidio_get_vf_config,
33493374
.ndo_set_vf_trust = liquidio_set_vf_trust,
33503375
.ndo_set_vf_link_state = liquidio_set_vf_link_state,
3376+
.ndo_get_vf_stats = liquidio_get_vf_stats,
33513377
};
33523378

33533379
/** \brief Entry point for the liquidio module

drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "octeon_device.h"
2525
#include "octeon_main.h"
2626
#include "octeon_mailbox.h"
27+
#include "cn23xx_pf_device.h"
2728

2829
/**
2930
* octeon_mbox_read:
@@ -205,6 +206,26 @@ int octeon_mbox_write(struct octeon_device *oct,
205206
return ret;
206207
}
207208

209+
static void get_vf_stats(struct octeon_device *oct,
210+
struct oct_vf_stats *stats)
211+
{
212+
int i;
213+
214+
for (i = 0; i < oct->num_iqs; i++) {
215+
if (!oct->instr_queue[i])
216+
continue;
217+
stats->tx_packets += oct->instr_queue[i]->stats.tx_done;
218+
stats->tx_bytes += oct->instr_queue[i]->stats.tx_tot_bytes;
219+
}
220+
221+
for (i = 0; i < oct->num_oqs; i++) {
222+
if (!oct->droq[i])
223+
continue;
224+
stats->rx_packets += oct->droq[i]->stats.rx_pkts_received;
225+
stats->rx_bytes += oct->droq[i]->stats.rx_bytes_received;
226+
}
227+
}
228+
208229
/**
209230
* octeon_mbox_process_cmd:
210231
* @mbox: Pointer mailbox
@@ -250,6 +271,15 @@ static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
250271
mbox_cmd->msg.s.params);
251272
break;
252273

274+
case OCTEON_GET_VF_STATS:
275+
dev_dbg(&oct->pci_dev->dev, "Got VF stats request. Sending data back\n");
276+
mbox_cmd->msg.s.type = OCTEON_MBOX_RESPONSE;
277+
mbox_cmd->msg.s.resp_needed = 1;
278+
mbox_cmd->msg.s.len = 1 +
279+
sizeof(struct oct_vf_stats) / sizeof(u64);
280+
get_vf_stats(oct, (struct oct_vf_stats *)mbox_cmd->data);
281+
octeon_mbox_write(oct, mbox_cmd);
282+
break;
253283
default:
254284
break;
255285
}
@@ -322,3 +352,25 @@ int octeon_mbox_process_message(struct octeon_mbox *mbox)
322352

323353
return 0;
324354
}
355+
356+
int octeon_mbox_cancel(struct octeon_device *oct, int q_no)
357+
{
358+
struct octeon_mbox *mbox = oct->mbox[q_no];
359+
struct octeon_mbox_cmd *mbox_cmd;
360+
unsigned long flags = 0;
361+
362+
spin_lock_irqsave(&mbox->lock, flags);
363+
mbox_cmd = &mbox->mbox_resp;
364+
365+
if (!(mbox->state & OCTEON_MBOX_STATE_RESPONSE_PENDING)) {
366+
spin_unlock_irqrestore(&mbox->lock, flags);
367+
return 1;
368+
}
369+
370+
mbox->state = OCTEON_MBOX_STATE_IDLE;
371+
memset(mbox_cmd, 0, sizeof(*mbox_cmd));
372+
writeq(OCTEON_PFVFSIG, mbox->mbox_read_reg);
373+
spin_unlock_irqrestore(&mbox->lock, flags);
374+
375+
return 0;
376+
}

drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#define OCTEON_VF_ACTIVE 0x1
2626
#define OCTEON_VF_FLR_REQUEST 0x2
2727
#define OCTEON_PF_CHANGED_VF_MACADDR 0x4
28+
#define OCTEON_GET_VF_STATS 0x8
2829

2930
/*Macro for Read acknowldgement*/
3031
#define OCTEON_PFVFACK 0xffffffffffffffffULL
@@ -107,9 +108,15 @@ struct octeon_mbox {
107108

108109
};
109110

111+
struct oct_vf_stats_ctx {
112+
atomic_t status;
113+
struct oct_vf_stats *stats;
114+
};
115+
110116
int octeon_mbox_read(struct octeon_mbox *mbox);
111117
int octeon_mbox_write(struct octeon_device *oct,
112118
struct octeon_mbox_cmd *mbox_cmd);
113119
int octeon_mbox_process_message(struct octeon_mbox *mbox);
120+
int octeon_mbox_cancel(struct octeon_device *oct, int q_no);
114121

115122
#endif

0 commit comments

Comments
 (0)