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 @@ ...@@ -5,6 +5,6 @@
obj-$(CONFIG_OCTEONTX2_PF) += octeontx2_nicpf.o 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 ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
...@@ -16,6 +16,72 @@ ...@@ -16,6 +16,72 @@
#include "otx2_common.h" #include "otx2_common.h"
#include "otx2_struct.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) void otx2_get_dev_stats(struct otx2_nic *pfvf)
{ {
struct otx2_dev_stats *dev_stats = &pfvf->hw.dev_stats; 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) ...@@ -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->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->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 */ /* Get memory to put this msg */
aq = otx2_mbox_alloc_msg_nix_aq_enq(&pfvf->mbox); aq = otx2_mbox_alloc_msg_nix_aq_enq(&pfvf->mbox);
if (!aq) if (!aq)
...@@ -1238,6 +1307,18 @@ void otx2_ctx_disable(struct mbox *mbox, int type, bool npa) ...@@ -1238,6 +1307,18 @@ void otx2_ctx_disable(struct mbox *mbox, int type, bool npa)
otx2_mbox_unlock(mbox); 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, void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
struct nix_txsch_alloc_rsp *rsp) struct nix_txsch_alloc_rsp *rsp)
{ {
...@@ -1250,7 +1331,6 @@ void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf, ...@@ -1250,7 +1331,6 @@ void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
rsp->schq_list[lvl][schq]; rsp->schq_list[lvl][schq];
} }
/* Mbox message handlers */
void mbox_handler_npa_lf_alloc(struct otx2_nic *pfvf, void mbox_handler_npa_lf_alloc(struct otx2_nic *pfvf,
struct npa_lf_alloc_rsp *rsp) struct npa_lf_alloc_rsp *rsp)
{ {
......
...@@ -187,6 +187,8 @@ struct otx2_hw { ...@@ -187,6 +187,8 @@ struct otx2_hw {
/* Stats */ /* Stats */
struct otx2_dev_stats dev_stats; struct otx2_dev_stats dev_stats;
struct otx2_drv_stats drv_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 { struct refill_work {
...@@ -588,12 +590,20 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf, ...@@ -588,12 +590,20 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf,
struct nix_lf_alloc_rsp *rsp); struct nix_lf_alloc_rsp *rsp);
void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf, void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
struct nix_txsch_alloc_rsp *rsp); struct nix_txsch_alloc_rsp *rsp);
void mbox_handler_cgx_stats(struct otx2_nic *pfvf,
struct cgx_stats_rsp *rsp);
/* Device stats APIs */ /* Device stats APIs */
void otx2_get_dev_stats(struct otx2_nic *pfvf); void otx2_get_dev_stats(struct otx2_nic *pfvf);
void otx2_get_stats64(struct net_device *netdev, void otx2_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats); 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_open(struct net_device *netdev);
int otx2_stop(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 */ #endif /* OTX2_COMMON_H */
This diff is collapsed.
...@@ -148,6 +148,9 @@ static void otx2_process_pfaf_mbox_msg(struct otx2_nic *pf, ...@@ -148,6 +148,9 @@ static void otx2_process_pfaf_mbox_msg(struct otx2_nic *pf,
mbox_handler_nix_txsch_alloc(pf, mbox_handler_nix_txsch_alloc(pf,
(struct nix_txsch_alloc_rsp *)msg); (struct nix_txsch_alloc_rsp *)msg);
break; break;
case MBOX_MSG_CGX_STATS:
mbox_handler_cgx_stats(pf, (struct cgx_stats_rsp *)msg);
break;
default: default:
if (msg->rc) if (msg->rc)
dev_err(pf->dev, dev_err(pf->dev,
...@@ -459,8 +462,8 @@ static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable) ...@@ -459,8 +462,8 @@ static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
return err; return err;
} }
static int otx2_set_real_num_queues(struct net_device *netdev, int otx2_set_real_num_queues(struct net_device *netdev,
int tx_queues, int rx_queues) int tx_queues, int rx_queues)
{ {
int err; int err;
...@@ -812,6 +815,11 @@ int otx2_open(struct net_device *netdev) ...@@ -812,6 +815,11 @@ int otx2_open(struct net_device *netdev)
if (!qset->sq) if (!qset->sq)
goto err_free_mem; 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); err = otx2_init_hw_resources(pf);
if (err) if (err)
goto err_free_mem; goto err_free_mem;
...@@ -917,6 +925,7 @@ int otx2_open(struct net_device *netdev) ...@@ -917,6 +925,7 @@ int otx2_open(struct net_device *netdev)
err_free_mem: err_free_mem:
kfree(qset->sq); kfree(qset->sq);
kfree(qset->cq); kfree(qset->cq);
kfree(qset->rq);
kfree(qset->napi); kfree(qset->napi);
return err; return err;
} }
...@@ -973,6 +982,7 @@ int otx2_stop(struct net_device *netdev) ...@@ -973,6 +982,7 @@ int otx2_stop(struct net_device *netdev)
kfree(qset->sq); kfree(qset->sq);
kfree(qset->cq); kfree(qset->cq);
kfree(qset->rq);
kfree(qset->napi); kfree(qset->napi);
/* Do not clear RQ/SQ ringsize settings */ /* Do not clear RQ/SQ ringsize settings */
memset((void *)qset + offsetof(struct otx2_qset, sqe_cnt), 0, 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) ...@@ -1268,6 +1278,8 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_detach_rsrc; goto err_detach_rsrc;
} }
otx2_set_ethtool_ops(netdev);
/* Enable link notifications */ /* Enable link notifications */
otx2_cgx_config_linkevents(pf, true); otx2_cgx_config_linkevents(pf, true);
......
...@@ -60,6 +60,15 @@ ...@@ -60,6 +60,15 @@
*/ */
#define CQ_QCOUNT_DEFAULT 1 #define CQ_QCOUNT_DEFAULT 1
struct queue_stats {
u64 bytes;
u64 pkts;
};
struct otx2_rcv_queue {
struct queue_stats stats;
};
struct sg_list { struct sg_list {
u16 num_segs; u16 num_segs;
u64 skb; u64 skb;
...@@ -82,6 +91,7 @@ struct otx2_snd_queue { ...@@ -82,6 +91,7 @@ struct otx2_snd_queue {
struct qmem *sqe; struct qmem *sqe;
struct qmem *tso_hdrs; struct qmem *tso_hdrs;
struct sg_list *sg; struct sg_list *sg;
struct queue_stats stats;
u16 sqb_count; u16 sqb_count;
u64 *sqb_ptrs; u64 *sqb_ptrs;
} ____cacheline_aligned_in_smp; } ____cacheline_aligned_in_smp;
...@@ -134,6 +144,7 @@ struct otx2_qset { ...@@ -134,6 +144,7 @@ struct otx2_qset {
struct otx2_cq_poll *napi; struct otx2_cq_poll *napi;
struct otx2_cq_queue *cq; struct otx2_cq_queue *cq;
struct otx2_snd_queue *sq; struct otx2_snd_queue *sq;
struct otx2_rcv_queue *rq;
}; };
/* Translate IOVA to physical address */ /* 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