aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c54
-rw-r--r--drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h12
-rw-r--r--drivers/net/ethernet/cavium/liquidio/lio_main.c26
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c52
-rw-r--r--drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h7
5 files changed, 151 insertions, 0 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
index e8b290473ee2..bc9861c90ea3 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c
@@ -1497,3 +1497,57 @@ void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx,
1497 octeon_mbox_write(oct, &mbox_cmd); 1497 octeon_mbox_write(oct, &mbox_cmd);
1498 } 1498 }
1499} 1499}
1500
1501static void
1502cn23xx_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
1511int 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}
diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h
index 2aba5247b6d8..63b3de4f2bfe 100644
--- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.h
@@ -43,6 +43,15 @@ struct octeon_cn23xx_pf {
43 43
44#define CN23XX_SLI_DEF_BP 0x40 44#define CN23XX_SLI_DEF_BP 0x40
45 45
46struct 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
46int setup_cn23xx_octeon_pf_device(struct octeon_device *oct); 55int setup_cn23xx_octeon_pf_device(struct octeon_device *oct);
47 56
48int validate_cn23xx_pf_config_info(struct octeon_device *oct, 57int validate_cn23xx_pf_config_info(struct octeon_device *oct,
@@ -56,4 +65,7 @@ int cn23xx_fw_loaded(struct octeon_device *oct);
56 65
57void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx, 66void cn23xx_tell_vf_its_macaddr_changed(struct octeon_device *oct, int vfidx,
58 u8 *mac); 67 u8 *mac);
68
69int cn23xx_get_vf_stats(struct octeon_device *oct, int ifidx,
70 struct oct_vf_stats *stats);
59#endif 71#endif
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 44c2a0c1bbdd..f3891ae11b02 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -3326,6 +3326,31 @@ static const struct switchdev_ops lio_pf_switchdev_ops = {
3326 .switchdev_port_attr_get = lio_pf_switchdev_attr_get, 3326 .switchdev_port_attr_get = lio_pf_switchdev_attr_get,
3327}; 3327};
3328 3328
3329static 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
3329static const struct net_device_ops lionetdevops = { 3354static const struct net_device_ops lionetdevops = {
3330 .ndo_open = liquidio_open, 3355 .ndo_open = liquidio_open,
3331 .ndo_stop = liquidio_stop, 3356 .ndo_stop = liquidio_stop,
@@ -3348,6 +3373,7 @@ static const struct net_device_ops lionetdevops = {
3348 .ndo_get_vf_config = liquidio_get_vf_config, 3373 .ndo_get_vf_config = liquidio_get_vf_config,
3349 .ndo_set_vf_trust = liquidio_set_vf_trust, 3374 .ndo_set_vf_trust = liquidio_set_vf_trust,
3350 .ndo_set_vf_link_state = liquidio_set_vf_link_state, 3375 .ndo_set_vf_link_state = liquidio_set_vf_link_state,
3376 .ndo_get_vf_stats = liquidio_get_vf_stats,
3351}; 3377};
3352 3378
3353/** \brief Entry point for the liquidio module 3379/** \brief Entry point for the liquidio module
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
index 28e74ee23ff8..021d99cd1665 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
@@ -24,6 +24,7 @@
24#include "octeon_device.h" 24#include "octeon_device.h"
25#include "octeon_main.h" 25#include "octeon_main.h"
26#include "octeon_mailbox.h" 26#include "octeon_mailbox.h"
27#include "cn23xx_pf_device.h"
27 28
28/** 29/**
29 * octeon_mbox_read: 30 * octeon_mbox_read:
@@ -205,6 +206,26 @@ int octeon_mbox_write(struct octeon_device *oct,
205 return ret; 206 return ret;
206} 207}
207 208
209static 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
208/** 229/**
209 * octeon_mbox_process_cmd: 230 * octeon_mbox_process_cmd:
210 * @mbox: Pointer mailbox 231 * @mbox: Pointer mailbox
@@ -250,6 +271,15 @@ static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
250 mbox_cmd->msg.s.params); 271 mbox_cmd->msg.s.params);
251 break; 272 break;
252 273
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;
253 default: 283 default:
254 break; 284 break;
255 } 285 }
@@ -322,3 +352,25 @@ int octeon_mbox_process_message(struct octeon_mbox *mbox)
322 352
323 return 0; 353 return 0;
324} 354}
355
356int 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}
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h
index 1def22afeff1..d92bd7e16477 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.h
@@ -25,6 +25,7 @@
25#define OCTEON_VF_ACTIVE 0x1 25#define OCTEON_VF_ACTIVE 0x1
26#define OCTEON_VF_FLR_REQUEST 0x2 26#define OCTEON_VF_FLR_REQUEST 0x2
27#define OCTEON_PF_CHANGED_VF_MACADDR 0x4 27#define OCTEON_PF_CHANGED_VF_MACADDR 0x4
28#define OCTEON_GET_VF_STATS 0x8
28 29
29/*Macro for Read acknowldgement*/ 30/*Macro for Read acknowldgement*/
30#define OCTEON_PFVFACK 0xffffffffffffffffULL 31#define OCTEON_PFVFACK 0xffffffffffffffffULL
@@ -107,9 +108,15 @@ struct octeon_mbox {
107 108
108}; 109};
109 110
111struct oct_vf_stats_ctx {
112 atomic_t status;
113 struct oct_vf_stats *stats;
114};
115
110int octeon_mbox_read(struct octeon_mbox *mbox); 116int octeon_mbox_read(struct octeon_mbox *mbox);
111int octeon_mbox_write(struct octeon_device *oct, 117int octeon_mbox_write(struct octeon_device *oct,
112 struct octeon_mbox_cmd *mbox_cmd); 118 struct octeon_mbox_cmd *mbox_cmd);
113int octeon_mbox_process_message(struct octeon_mbox *mbox); 119int octeon_mbox_process_message(struct octeon_mbox *mbox);
120int octeon_mbox_cancel(struct octeon_device *oct, int q_no);
114 121
115#endif 122#endif