Commit d45d8979 authored by Christina Jacob's avatar Christina Jacob Committed by David S. Miller

octeontx2-pf: Add basic ethtool support

This patch adds ethtool support for
 - Driver stats, Tx/Rx perqueue and CGX LMAC stats
 - Set/show Rx/Tx queue count
 - Set/show Rx/Tx ring sizes
 - Set/show IRQ coalescing parameters
Signed-off-by: default avatarChristina Jacob <cjacob@marvell.com>
Signed-off-by: default avatarSunil Goutham <sgoutham@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e239d0c7
......@@ -5,6 +5,6 @@
obj-$(CONFIG_OCTEONTX2_PF) += octeontx2_nicpf.o
octeontx2_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o
octeontx2_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o
ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
......@@ -16,6 +16,72 @@
#include "otx2_common.h"
#include "otx2_struct.h"
static void otx2_nix_rq_op_stats(struct queue_stats *stats,
struct otx2_nic *pfvf, int qidx)
{
u64 incr = (u64)qidx << 32;
u64 *ptr;
ptr = (u64 *)otx2_get_regaddr(pfvf, NIX_LF_RQ_OP_OCTS);
stats->bytes = otx2_atomic64_add(incr, ptr);
ptr = (u64 *)otx2_get_regaddr(pfvf, NIX_LF_RQ_OP_PKTS);
stats->pkts = otx2_atomic64_add(incr, ptr);
}
static void otx2_nix_sq_op_stats(struct queue_stats *stats,
struct otx2_nic *pfvf, int qidx)
{
u64 incr = (u64)qidx << 32;
u64 *ptr;
ptr = (u64 *)otx2_get_regaddr(pfvf, NIX_LF_SQ_OP_OCTS);
stats->bytes = otx2_atomic64_add(incr, ptr);
ptr = (u64 *)otx2_get_regaddr(pfvf, NIX_LF_SQ_OP_PKTS);
stats->pkts = otx2_atomic64_add(incr, ptr);
}
void otx2_update_lmac_stats(struct otx2_nic *pfvf)
{
struct msg_req *req;
if (!netif_running(pfvf->netdev))
return;
otx2_mbox_lock(&pfvf->mbox);
req = otx2_mbox_alloc_msg_cgx_stats(&pfvf->mbox);
if (!req) {
otx2_mbox_unlock(&pfvf->mbox);
return;
}
otx2_sync_mbox_msg(&pfvf->mbox);
otx2_mbox_unlock(&pfvf->mbox);
}
int otx2_update_rq_stats(struct otx2_nic *pfvf, int qidx)
{
struct otx2_rcv_queue *rq = &pfvf->qset.rq[qidx];
if (!pfvf->qset.rq)
return 0;
otx2_nix_rq_op_stats(&rq->stats, pfvf, qidx);
return 1;
}
int otx2_update_sq_stats(struct otx2_nic *pfvf, int qidx)
{
struct otx2_snd_queue *sq = &pfvf->qset.sq[qidx];
if (!pfvf->qset.sq)
return 0;
otx2_nix_sq_op_stats(&sq->stats, pfvf, qidx);
return 1;
}
void otx2_get_dev_stats(struct otx2_nic *pfvf)
{
struct otx2_dev_stats *dev_stats = &pfvf->hw.dev_stats;
......@@ -590,6 +656,9 @@ static int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura)
sq->lmt_addr = (__force u64 *)(pfvf->reg_base + LMT_LF_LMTLINEX(qidx));
sq->io_addr = (__force u64)otx2_get_regaddr(pfvf, NIX_LF_OP_SENDX(0));
sq->stats.bytes = 0;
sq->stats.pkts = 0;
/* Get memory to put this msg */
aq = otx2_mbox_alloc_msg_nix_aq_enq(&pfvf->mbox);
if (!aq)
......@@ -1238,6 +1307,18 @@ void otx2_ctx_disable(struct mbox *mbox, int type, bool npa)
otx2_mbox_unlock(mbox);
}
/* Mbox message handlers */
void mbox_handler_cgx_stats(struct otx2_nic *pfvf,
struct cgx_stats_rsp *rsp)
{
int id;
for (id = 0; id < CGX_RX_STATS_COUNT; id++)
pfvf->hw.cgx_rx_stats[id] = rsp->rx_stats[id];
for (id = 0; id < CGX_TX_STATS_COUNT; id++)
pfvf->hw.cgx_tx_stats[id] = rsp->tx_stats[id];
}
void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
struct nix_txsch_alloc_rsp *rsp)
{
......@@ -1250,7 +1331,6 @@ void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
rsp->schq_list[lvl][schq];
}
/* Mbox message handlers */
void mbox_handler_npa_lf_alloc(struct otx2_nic *pfvf,
struct npa_lf_alloc_rsp *rsp)
{
......
......@@ -187,6 +187,8 @@ struct otx2_hw {
/* Stats */
struct otx2_dev_stats dev_stats;
struct otx2_drv_stats drv_stats;
u64 cgx_rx_stats[CGX_RX_STATS_COUNT];
u64 cgx_tx_stats[CGX_TX_STATS_COUNT];
};
struct refill_work {
......@@ -588,12 +590,20 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf,
struct nix_lf_alloc_rsp *rsp);
void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
struct nix_txsch_alloc_rsp *rsp);
void mbox_handler_cgx_stats(struct otx2_nic *pfvf,
struct cgx_stats_rsp *rsp);
/* Device stats APIs */
void otx2_get_dev_stats(struct otx2_nic *pfvf);
void otx2_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats);
void otx2_update_lmac_stats(struct otx2_nic *pfvf);
int otx2_update_rq_stats(struct otx2_nic *pfvf, int qidx);
int otx2_update_sq_stats(struct otx2_nic *pfvf, int qidx);
void otx2_set_ethtool_ops(struct net_device *netdev);
int otx2_open(struct net_device *netdev);
int otx2_stop(struct net_device *netdev);
int otx2_set_real_num_queues(struct net_device *netdev,
int tx_queues, int rx_queues);
#endif /* OTX2_COMMON_H */
This diff is collapsed.
......@@ -148,6 +148,9 @@ static void otx2_process_pfaf_mbox_msg(struct otx2_nic *pf,
mbox_handler_nix_txsch_alloc(pf,
(struct nix_txsch_alloc_rsp *)msg);
break;
case MBOX_MSG_CGX_STATS:
mbox_handler_cgx_stats(pf, (struct cgx_stats_rsp *)msg);
break;
default:
if (msg->rc)
dev_err(pf->dev,
......@@ -459,8 +462,8 @@ static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
return err;
}
static int otx2_set_real_num_queues(struct net_device *netdev,
int tx_queues, int rx_queues)
int otx2_set_real_num_queues(struct net_device *netdev,
int tx_queues, int rx_queues)
{
int err;
......@@ -812,6 +815,11 @@ int otx2_open(struct net_device *netdev)
if (!qset->sq)
goto err_free_mem;
qset->rq = kcalloc(pf->hw.rx_queues,
sizeof(struct otx2_rcv_queue), GFP_KERNEL);
if (!qset->rq)
goto err_free_mem;
err = otx2_init_hw_resources(pf);
if (err)
goto err_free_mem;
......@@ -917,6 +925,7 @@ int otx2_open(struct net_device *netdev)
err_free_mem:
kfree(qset->sq);
kfree(qset->cq);
kfree(qset->rq);
kfree(qset->napi);
return err;
}
......@@ -973,6 +982,7 @@ int otx2_stop(struct net_device *netdev)
kfree(qset->sq);
kfree(qset->cq);
kfree(qset->rq);
kfree(qset->napi);
/* Do not clear RQ/SQ ringsize settings */
memset((void *)qset + offsetof(struct otx2_qset, sqe_cnt), 0,
......@@ -1268,6 +1278,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_detach_rsrc;
}
otx2_set_ethtool_ops(netdev);
/* Enable link notifications */
otx2_cgx_config_linkevents(pf, true);
......
......@@ -60,6 +60,15 @@
*/
#define CQ_QCOUNT_DEFAULT 1
struct queue_stats {
u64 bytes;
u64 pkts;
};
struct otx2_rcv_queue {
struct queue_stats stats;
};
struct sg_list {
u16 num_segs;
u64 skb;
......@@ -82,6 +91,7 @@ struct otx2_snd_queue {
struct qmem *sqe;
struct qmem *tso_hdrs;
struct sg_list *sg;
struct queue_stats stats;
u16 sqb_count;
u64 *sqb_ptrs;
} ____cacheline_aligned_in_smp;
......@@ -134,6 +144,7 @@ struct otx2_qset {
struct otx2_cq_poll *napi;
struct otx2_cq_queue *cq;
struct otx2_snd_queue *sq;
struct otx2_rcv_queue *rq;
};
/* Translate IOVA to physical address */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment