Skip to content

Commit d0cf950

Browse files
Christina Jacobdavem330
authored andcommitted
octeontx2-pf: ethtool fec mode support
Add ethtool support to configure fec modes baser/rs and support to fecth FEC stats from CGX as well PHY. Configure fec mode - ethtool --set-fec eth0 encoding rs/baser/off/auto Query fec mode - ethtool --show-fec eth0 Signed-off-by: Christina Jacob <[email protected]> Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: Hariprasad Kelam <[email protected]> Reviewed-by: Jesse Brandeburg <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent bd74d4e commit d0cf950

File tree

4 files changed

+188
-1
lines changed

4 files changed

+188
-1
lines changed

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ void otx2_update_lmac_stats(struct otx2_nic *pfvf)
6060
mutex_unlock(&pfvf->mbox.lock);
6161
}
6262

63+
void otx2_update_lmac_fec_stats(struct otx2_nic *pfvf)
64+
{
65+
struct msg_req *req;
66+
67+
if (!netif_running(pfvf->netdev))
68+
return;
69+
mutex_lock(&pfvf->mbox.lock);
70+
req = otx2_mbox_alloc_msg_cgx_fec_stats(&pfvf->mbox);
71+
if (req)
72+
otx2_sync_mbox_msg(&pfvf->mbox);
73+
mutex_unlock(&pfvf->mbox.lock);
74+
}
75+
6376
int otx2_update_rq_stats(struct otx2_nic *pfvf, int qidx)
6477
{
6578
struct otx2_rcv_queue *rq = &pfvf->qset.rq[qidx];
@@ -1489,6 +1502,13 @@ void mbox_handler_cgx_stats(struct otx2_nic *pfvf,
14891502
pfvf->hw.cgx_tx_stats[id] = rsp->tx_stats[id];
14901503
}
14911504

1505+
void mbox_handler_cgx_fec_stats(struct otx2_nic *pfvf,
1506+
struct cgx_fec_stats_rsp *rsp)
1507+
{
1508+
pfvf->hw.cgx_fec_corr_blks += rsp->fec_corr_blks;
1509+
pfvf->hw.cgx_fec_uncorr_blks += rsp->fec_uncorr_blks;
1510+
}
1511+
14921512
void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
14931513
struct nix_txsch_alloc_rsp *rsp)
14941514
{

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ struct otx2_hw {
204204
struct otx2_drv_stats drv_stats;
205205
u64 cgx_rx_stats[CGX_RX_STATS_COUNT];
206206
u64 cgx_tx_stats[CGX_TX_STATS_COUNT];
207+
u64 cgx_fec_corr_blks;
208+
u64 cgx_fec_uncorr_blks;
207209
u8 cgx_links; /* No. of CGX links present in HW */
208210
u8 lbk_links; /* No. of LBK links present in HW */
209211
};
@@ -661,6 +663,9 @@ void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
661663
struct nix_txsch_alloc_rsp *rsp);
662664
void mbox_handler_cgx_stats(struct otx2_nic *pfvf,
663665
struct cgx_stats_rsp *rsp);
666+
void mbox_handler_cgx_fec_stats(struct otx2_nic *pfvf,
667+
struct cgx_fec_stats_rsp *rsp);
668+
void otx2_set_fec_stats_count(struct otx2_nic *pfvf);
664669
void mbox_handler_nix_bp_enable(struct otx2_nic *pfvf,
665670
struct nix_bp_cfg_rsp *rsp);
666671

@@ -669,6 +674,7 @@ void otx2_get_dev_stats(struct otx2_nic *pfvf);
669674
void otx2_get_stats64(struct net_device *netdev,
670675
struct rtnl_link_stats64 *stats);
671676
void otx2_update_lmac_stats(struct otx2_nic *pfvf);
677+
void otx2_update_lmac_fec_stats(struct otx2_nic *pfvf);
672678
int otx2_update_rq_stats(struct otx2_nic *pfvf, int qidx);
673679
int otx2_update_sq_stats(struct otx2_nic *pfvf, int qidx);
674680
void otx2_set_ethtool_ops(struct net_device *netdev);

drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ static const unsigned int otx2_n_dev_stats = ARRAY_SIZE(otx2_dev_stats);
6666
static const unsigned int otx2_n_drv_stats = ARRAY_SIZE(otx2_drv_stats);
6767
static const unsigned int otx2_n_queue_stats = ARRAY_SIZE(otx2_queue_stats);
6868

69+
static struct cgx_fw_data *otx2_get_fwdata(struct otx2_nic *pfvf);
70+
6971
static void otx2_get_drvinfo(struct net_device *netdev,
7072
struct ethtool_drvinfo *info)
7173
{
@@ -128,6 +130,10 @@ static void otx2_get_strings(struct net_device *netdev, u32 sset, u8 *data)
128130

129131
strcpy(data, "reset_count");
130132
data += ETH_GSTRING_LEN;
133+
sprintf(data, "Fec Corrected Errors: ");
134+
data += ETH_GSTRING_LEN;
135+
sprintf(data, "Fec Uncorrected Errors: ");
136+
data += ETH_GSTRING_LEN;
131137
}
132138

133139
static void otx2_get_qset_stats(struct otx2_nic *pfvf,
@@ -160,11 +166,30 @@ static void otx2_get_qset_stats(struct otx2_nic *pfvf,
160166
}
161167
}
162168

169+
static int otx2_get_phy_fec_stats(struct otx2_nic *pfvf)
170+
{
171+
struct msg_req *req;
172+
int rc = -ENOMEM;
173+
174+
mutex_lock(&pfvf->mbox.lock);
175+
req = otx2_mbox_alloc_msg_cgx_get_phy_fec_stats(&pfvf->mbox);
176+
if (!req)
177+
goto end;
178+
179+
if (!otx2_sync_mbox_msg(&pfvf->mbox))
180+
rc = 0;
181+
end:
182+
mutex_unlock(&pfvf->mbox.lock);
183+
return rc;
184+
}
185+
163186
/* Get device and per queue statistics */
164187
static void otx2_get_ethtool_stats(struct net_device *netdev,
165188
struct ethtool_stats *stats, u64 *data)
166189
{
167190
struct otx2_nic *pfvf = netdev_priv(netdev);
191+
u64 fec_corr_blks, fec_uncorr_blks;
192+
struct cgx_fw_data *rsp;
168193
int stat;
169194

170195
otx2_get_dev_stats(pfvf);
@@ -183,6 +208,32 @@ static void otx2_get_ethtool_stats(struct net_device *netdev,
183208
for (stat = 0; stat < CGX_TX_STATS_COUNT; stat++)
184209
*(data++) = pfvf->hw.cgx_tx_stats[stat];
185210
*(data++) = pfvf->reset_count;
211+
212+
fec_corr_blks = pfvf->hw.cgx_fec_corr_blks;
213+
fec_uncorr_blks = pfvf->hw.cgx_fec_uncorr_blks;
214+
215+
rsp = otx2_get_fwdata(pfvf);
216+
if (!IS_ERR(rsp) && rsp->fwdata.phy.misc.has_fec_stats &&
217+
!otx2_get_phy_fec_stats(pfvf)) {
218+
/* Fetch fwdata again because it's been recently populated with
219+
* latest PHY FEC stats.
220+
*/
221+
rsp = otx2_get_fwdata(pfvf);
222+
if (!IS_ERR(rsp)) {
223+
struct fec_stats_s *p = &rsp->fwdata.phy.fec_stats;
224+
225+
if (pfvf->linfo.fec == OTX2_FEC_BASER) {
226+
fec_corr_blks = p->brfec_corr_blks;
227+
fec_uncorr_blks = p->brfec_uncorr_blks;
228+
} else {
229+
fec_corr_blks = p->rsfec_corr_cws;
230+
fec_uncorr_blks = p->rsfec_uncorr_cws;
231+
}
232+
}
233+
}
234+
235+
*(data++) = fec_corr_blks;
236+
*(data++) = fec_uncorr_blks;
186237
}
187238

188239
static int otx2_get_sset_count(struct net_device *netdev, int sset)
@@ -195,9 +246,11 @@ static int otx2_get_sset_count(struct net_device *netdev, int sset)
195246

196247
qstats_count = otx2_n_queue_stats *
197248
(pfvf->hw.rx_queues + pfvf->hw.tx_queues);
249+
otx2_update_lmac_fec_stats(pfvf);
198250

199251
return otx2_n_dev_stats + otx2_n_drv_stats + qstats_count +
200-
CGX_RX_STATS_COUNT + CGX_TX_STATS_COUNT + 1;
252+
CGX_RX_STATS_COUNT + CGX_TX_STATS_COUNT + OTX2_FEC_STATS_CNT
253+
+ 1;
201254
}
202255

203256
/* Get no of queues device supports and current queue count */
@@ -859,6 +912,109 @@ static int otx2_get_ts_info(struct net_device *netdev,
859912
return 0;
860913
}
861914

915+
static struct cgx_fw_data *otx2_get_fwdata(struct otx2_nic *pfvf)
916+
{
917+
struct cgx_fw_data *rsp = NULL;
918+
struct msg_req *req;
919+
int err = 0;
920+
921+
mutex_lock(&pfvf->mbox.lock);
922+
req = otx2_mbox_alloc_msg_cgx_get_aux_link_info(&pfvf->mbox);
923+
if (!req) {
924+
mutex_unlock(&pfvf->mbox.lock);
925+
return ERR_PTR(-ENOMEM);
926+
}
927+
928+
err = otx2_sync_mbox_msg(&pfvf->mbox);
929+
if (!err) {
930+
rsp = (struct cgx_fw_data *)
931+
otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
932+
} else {
933+
rsp = ERR_PTR(err);
934+
}
935+
936+
mutex_unlock(&pfvf->mbox.lock);
937+
return rsp;
938+
}
939+
940+
static int otx2_get_fecparam(struct net_device *netdev,
941+
struct ethtool_fecparam *fecparam)
942+
{
943+
struct otx2_nic *pfvf = netdev_priv(netdev);
944+
struct cgx_fw_data *rsp;
945+
const int fec[] = {
946+
ETHTOOL_FEC_OFF,
947+
ETHTOOL_FEC_BASER,
948+
ETHTOOL_FEC_RS,
949+
ETHTOOL_FEC_BASER | ETHTOOL_FEC_RS};
950+
#define FEC_MAX_INDEX 4
951+
if (pfvf->linfo.fec < FEC_MAX_INDEX)
952+
fecparam->active_fec = fec[pfvf->linfo.fec];
953+
954+
rsp = otx2_get_fwdata(pfvf);
955+
if (IS_ERR(rsp))
956+
return PTR_ERR(rsp);
957+
958+
if (rsp->fwdata.supported_fec <= FEC_MAX_INDEX) {
959+
if (!rsp->fwdata.supported_fec)
960+
fecparam->fec = ETHTOOL_FEC_NONE;
961+
else
962+
fecparam->fec = fec[rsp->fwdata.supported_fec];
963+
}
964+
return 0;
965+
}
966+
967+
static int otx2_set_fecparam(struct net_device *netdev,
968+
struct ethtool_fecparam *fecparam)
969+
{
970+
struct otx2_nic *pfvf = netdev_priv(netdev);
971+
struct mbox *mbox = &pfvf->mbox;
972+
struct fec_mode *req, *rsp;
973+
int err = 0, fec = 0;
974+
975+
switch (fecparam->fec) {
976+
/* Firmware does not support AUTO mode consider it as FEC_OFF */
977+
case ETHTOOL_FEC_OFF:
978+
case ETHTOOL_FEC_AUTO:
979+
fec = OTX2_FEC_OFF;
980+
break;
981+
case ETHTOOL_FEC_RS:
982+
fec = OTX2_FEC_RS;
983+
break;
984+
case ETHTOOL_FEC_BASER:
985+
fec = OTX2_FEC_BASER;
986+
break;
987+
default:
988+
netdev_warn(pfvf->netdev, "Unsupported FEC mode: %d",
989+
fecparam->fec);
990+
return -EINVAL;
991+
}
992+
993+
if (fec == pfvf->linfo.fec)
994+
return 0;
995+
996+
mutex_lock(&mbox->lock);
997+
req = otx2_mbox_alloc_msg_cgx_set_fec_param(&pfvf->mbox);
998+
if (!req) {
999+
err = -ENOMEM;
1000+
goto end;
1001+
}
1002+
req->fec = fec;
1003+
err = otx2_sync_mbox_msg(&pfvf->mbox);
1004+
if (err)
1005+
goto end;
1006+
1007+
rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
1008+
0, &req->hdr);
1009+
if (rsp->fec >= 0)
1010+
pfvf->linfo.fec = rsp->fec;
1011+
else
1012+
err = rsp->fec;
1013+
end:
1014+
mutex_unlock(&mbox->lock);
1015+
return err;
1016+
}
1017+
8621018
static const struct ethtool_ops otx2_ethtool_ops = {
8631019
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
8641020
ETHTOOL_COALESCE_MAX_FRAMES,
@@ -886,6 +1042,8 @@ static const struct ethtool_ops otx2_ethtool_ops = {
8861042
.get_pauseparam = otx2_get_pauseparam,
8871043
.set_pauseparam = otx2_set_pauseparam,
8881044
.get_ts_info = otx2_get_ts_info,
1045+
.get_fecparam = otx2_get_fecparam,
1046+
.set_fecparam = otx2_set_fecparam,
8891047
};
8901048

8911049
void otx2_set_ethtool_ops(struct net_device *netdev)

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,9 @@ static void otx2_process_pfaf_mbox_msg(struct otx2_nic *pf,
779779
case MBOX_MSG_CGX_STATS:
780780
mbox_handler_cgx_stats(pf, (struct cgx_stats_rsp *)msg);
781781
break;
782+
case MBOX_MSG_CGX_FEC_STATS:
783+
mbox_handler_cgx_fec_stats(pf, (struct cgx_fec_stats_rsp *)msg);
784+
break;
782785
default:
783786
if (msg->rc)
784787
dev_err(pf->dev,

0 commit comments

Comments
 (0)