brintos

brintos / linux-shallow public Read only

0
0
Text · 38.2 KiB · 32468c6 Raw
1468 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Marvell RVU Ethernet driver3 *4 * Copyright (C) 2020 Marvell.5 *6 */7 8#include <linux/pci.h>9#include <linux/ethtool.h>10#include <linux/stddef.h>11#include <linux/etherdevice.h>12#include <linux/log2.h>13#include <linux/net_tstamp.h>14#include <linux/linkmode.h>15 16#include "otx2_common.h"17#include "otx2_ptp.h"18 19#define DRV_NAME	"rvu-nicpf"20#define DRV_VF_NAME	"rvu-nicvf"21 22struct otx2_stat {23	char name[ETH_GSTRING_LEN];24	unsigned int index;25};26 27/* HW device stats */28#define OTX2_DEV_STAT(stat) { \29	.name = #stat, \30	.index = offsetof(struct otx2_dev_stats, stat) / sizeof(u64), \31}32 33enum link_mode {34	OTX2_MODE_SUPPORTED,35	OTX2_MODE_ADVERTISED36};37 38static const struct otx2_stat otx2_dev_stats[] = {39	OTX2_DEV_STAT(rx_ucast_frames),40	OTX2_DEV_STAT(rx_bcast_frames),41	OTX2_DEV_STAT(rx_mcast_frames),42 43	OTX2_DEV_STAT(tx_ucast_frames),44	OTX2_DEV_STAT(tx_bcast_frames),45	OTX2_DEV_STAT(tx_mcast_frames),46};47 48/* Driver level stats */49#define OTX2_DRV_STAT(stat) { \50	.name = #stat, \51	.index = offsetof(struct otx2_drv_stats, stat) / sizeof(atomic_t), \52}53 54static const struct otx2_stat otx2_drv_stats[] = {55	OTX2_DRV_STAT(rx_fcs_errs),56	OTX2_DRV_STAT(rx_oversize_errs),57	OTX2_DRV_STAT(rx_undersize_errs),58	OTX2_DRV_STAT(rx_csum_errs),59	OTX2_DRV_STAT(rx_len_errs),60	OTX2_DRV_STAT(rx_other_errs),61};62 63static const struct otx2_stat otx2_queue_stats[] = {64	{ "bytes", 0 },65	{ "frames", 1 },66};67 68static const unsigned int otx2_n_dev_stats = ARRAY_SIZE(otx2_dev_stats);69static const unsigned int otx2_n_drv_stats = ARRAY_SIZE(otx2_drv_stats);70static const unsigned int otx2_n_queue_stats = ARRAY_SIZE(otx2_queue_stats);71 72static struct cgx_fw_data *otx2_get_fwdata(struct otx2_nic *pfvf);73 74static void otx2_get_drvinfo(struct net_device *netdev,75			     struct ethtool_drvinfo *info)76{77	struct otx2_nic *pfvf = netdev_priv(netdev);78 79	strscpy(info->driver, DRV_NAME, sizeof(info->driver));80	strscpy(info->bus_info, pci_name(pfvf->pdev), sizeof(info->bus_info));81}82 83static void otx2_get_qset_strings(struct otx2_nic *pfvf, u8 **data, int qset)84{85	int start_qidx = qset * pfvf->hw.rx_queues;86	int qidx, stats;87 88	for (qidx = 0; qidx < pfvf->hw.rx_queues; qidx++) {89		for (stats = 0; stats < otx2_n_queue_stats; stats++) {90			sprintf(*data, "rxq%d: %s", qidx + start_qidx,91				otx2_queue_stats[stats].name);92			*data += ETH_GSTRING_LEN;93		}94	}95 96	for (qidx = 0; qidx < otx2_get_total_tx_queues(pfvf); qidx++) {97		for (stats = 0; stats < otx2_n_queue_stats; stats++) {98			if (qidx >= pfvf->hw.non_qos_queues)99				sprintf(*data, "txq_qos%d: %s",100					qidx + start_qidx - pfvf->hw.non_qos_queues,101					otx2_queue_stats[stats].name);102			else103				sprintf(*data, "txq%d: %s", qidx + start_qidx,104					otx2_queue_stats[stats].name);105			*data += ETH_GSTRING_LEN;106		}107	}108}109 110static void otx2_get_strings(struct net_device *netdev, u32 sset, u8 *data)111{112	struct otx2_nic *pfvf = netdev_priv(netdev);113	int stats;114 115	if (sset != ETH_SS_STATS)116		return;117 118	for (stats = 0; stats < otx2_n_dev_stats; stats++) {119		memcpy(data, otx2_dev_stats[stats].name, ETH_GSTRING_LEN);120		data += ETH_GSTRING_LEN;121	}122 123	for (stats = 0; stats < otx2_n_drv_stats; stats++) {124		memcpy(data, otx2_drv_stats[stats].name, ETH_GSTRING_LEN);125		data += ETH_GSTRING_LEN;126	}127 128	otx2_get_qset_strings(pfvf, &data, 0);129 130	if (!test_bit(CN10K_RPM, &pfvf->hw.cap_flag)) {131		for (stats = 0; stats < CGX_RX_STATS_COUNT; stats++) {132			sprintf(data, "cgx_rxstat%d: ", stats);133			data += ETH_GSTRING_LEN;134		}135 136		for (stats = 0; stats < CGX_TX_STATS_COUNT; stats++) {137			sprintf(data, "cgx_txstat%d: ", stats);138			data += ETH_GSTRING_LEN;139		}140	}141 142	strcpy(data, "reset_count");143	data += ETH_GSTRING_LEN;144	sprintf(data, "Fec Corrected Errors: ");145	data += ETH_GSTRING_LEN;146	sprintf(data, "Fec Uncorrected Errors: ");147	data += ETH_GSTRING_LEN;148}149 150static void otx2_get_qset_stats(struct otx2_nic *pfvf,151				struct ethtool_stats *stats, u64 **data)152{153	int stat, qidx;154 155	if (!pfvf)156		return;157	for (qidx = 0; qidx < pfvf->hw.rx_queues; qidx++) {158		if (!otx2_update_rq_stats(pfvf, qidx)) {159			for (stat = 0; stat < otx2_n_queue_stats; stat++)160				*((*data)++) = 0;161			continue;162		}163		for (stat = 0; stat < otx2_n_queue_stats; stat++)164			*((*data)++) = ((u64 *)&pfvf->qset.rq[qidx].stats)165				[otx2_queue_stats[stat].index];166	}167 168	for (qidx = 0; qidx < otx2_get_total_tx_queues(pfvf); qidx++) {169		if (!otx2_update_sq_stats(pfvf, qidx)) {170			for (stat = 0; stat < otx2_n_queue_stats; stat++)171				*((*data)++) = 0;172			continue;173		}174		for (stat = 0; stat < otx2_n_queue_stats; stat++)175			*((*data)++) = ((u64 *)&pfvf->qset.sq[qidx].stats)176				[otx2_queue_stats[stat].index];177	}178}179 180static int otx2_get_phy_fec_stats(struct otx2_nic *pfvf)181{182	struct msg_req *req;183	int rc = -ENOMEM;184 185	mutex_lock(&pfvf->mbox.lock);186	req = otx2_mbox_alloc_msg_cgx_get_phy_fec_stats(&pfvf->mbox);187	if (!req)188		goto end;189 190	if (!otx2_sync_mbox_msg(&pfvf->mbox))191		rc = 0;192end:193	mutex_unlock(&pfvf->mbox.lock);194	return rc;195}196 197/* Get device and per queue statistics */198static void otx2_get_ethtool_stats(struct net_device *netdev,199				   struct ethtool_stats *stats, u64 *data)200{201	struct otx2_nic *pfvf = netdev_priv(netdev);202	u64 fec_corr_blks, fec_uncorr_blks;203	struct cgx_fw_data *rsp;204	int stat;205 206	otx2_get_dev_stats(pfvf);207	for (stat = 0; stat < otx2_n_dev_stats; stat++)208		*(data++) = ((u64 *)&pfvf->hw.dev_stats)209				[otx2_dev_stats[stat].index];210 211	for (stat = 0; stat < otx2_n_drv_stats; stat++)212		*(data++) = atomic_read(&((atomic_t *)&pfvf->hw.drv_stats)213						[otx2_drv_stats[stat].index]);214 215	otx2_get_qset_stats(pfvf, stats, &data);216 217	if (!test_bit(CN10K_RPM, &pfvf->hw.cap_flag)) {218		otx2_update_lmac_stats(pfvf);219		for (stat = 0; stat < CGX_RX_STATS_COUNT; stat++)220			*(data++) = pfvf->hw.cgx_rx_stats[stat];221		for (stat = 0; stat < CGX_TX_STATS_COUNT; stat++)222			*(data++) = pfvf->hw.cgx_tx_stats[stat];223	}224 225	*(data++) = pfvf->reset_count;226 227	fec_corr_blks = pfvf->hw.cgx_fec_corr_blks;228	fec_uncorr_blks = pfvf->hw.cgx_fec_uncorr_blks;229 230	rsp = otx2_get_fwdata(pfvf);231	if (!IS_ERR(rsp) && rsp->fwdata.phy.misc.has_fec_stats &&232	    !otx2_get_phy_fec_stats(pfvf)) {233		/* Fetch fwdata again because it's been recently populated with234		 * latest PHY FEC stats.235		 */236		rsp = otx2_get_fwdata(pfvf);237		if (!IS_ERR(rsp)) {238			struct fec_stats_s *p = &rsp->fwdata.phy.fec_stats;239 240			if (pfvf->linfo.fec == OTX2_FEC_BASER) {241				fec_corr_blks   = p->brfec_corr_blks;242				fec_uncorr_blks = p->brfec_uncorr_blks;243			} else {244				fec_corr_blks   = p->rsfec_corr_cws;245				fec_uncorr_blks = p->rsfec_uncorr_cws;246			}247		}248	}249 250	*(data++) = fec_corr_blks;251	*(data++) = fec_uncorr_blks;252}253 254static int otx2_get_sset_count(struct net_device *netdev, int sset)255{256	struct otx2_nic *pfvf = netdev_priv(netdev);257	int qstats_count, mac_stats = 0;258 259	if (sset != ETH_SS_STATS)260		return -EINVAL;261 262	qstats_count = otx2_n_queue_stats *263		       (pfvf->hw.rx_queues + otx2_get_total_tx_queues(pfvf));264	if (!test_bit(CN10K_RPM, &pfvf->hw.cap_flag))265		mac_stats = CGX_RX_STATS_COUNT + CGX_TX_STATS_COUNT;266	otx2_update_lmac_fec_stats(pfvf);267 268	return otx2_n_dev_stats + otx2_n_drv_stats + qstats_count +269	       mac_stats + OTX2_FEC_STATS_CNT + 1;270}271 272/* Get no of queues device supports and current queue count */273static void otx2_get_channels(struct net_device *dev,274			      struct ethtool_channels *channel)275{276	struct otx2_nic *pfvf = netdev_priv(dev);277 278	channel->max_rx = pfvf->hw.max_queues;279	channel->max_tx = pfvf->hw.max_queues;280 281	channel->rx_count = pfvf->hw.rx_queues;282	channel->tx_count = pfvf->hw.tx_queues;283}284 285/* Set no of Tx, Rx queues to be used */286static int otx2_set_channels(struct net_device *dev,287			     struct ethtool_channels *channel)288{289	struct otx2_nic *pfvf = netdev_priv(dev);290	bool if_up = netif_running(dev);291	int err, qos_txqs;292 293	if (!channel->rx_count || !channel->tx_count)294		return -EINVAL;295 296	if (bitmap_weight(&pfvf->rq_bmap, pfvf->hw.rx_queues) > 1) {297		netdev_err(dev,298			   "Receive queues are in use by TC police action\n");299		return -EINVAL;300	}301 302	if (if_up)303		dev->netdev_ops->ndo_stop(dev);304 305	qos_txqs = bitmap_weight(pfvf->qos.qos_sq_bmap,306				 OTX2_QOS_MAX_LEAF_NODES);307 308	err = otx2_set_real_num_queues(dev, channel->tx_count + qos_txqs,309				       channel->rx_count);310	if (err)311		return err;312 313	pfvf->hw.rx_queues = channel->rx_count;314	pfvf->hw.tx_queues = channel->tx_count;315	if (pfvf->xdp_prog)316		pfvf->hw.xdp_queues = channel->rx_count;317 318	if (if_up)319		err = dev->netdev_ops->ndo_open(dev);320 321	netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n",322		    pfvf->hw.tx_queues, pfvf->hw.rx_queues);323 324	return err;325}326 327static void otx2_get_pauseparam(struct net_device *netdev,328				struct ethtool_pauseparam *pause)329{330	struct otx2_nic *pfvf = netdev_priv(netdev);331	struct cgx_pause_frm_cfg *req, *rsp;332 333	if (is_otx2_lbkvf(pfvf->pdev))334		return;335 336	mutex_lock(&pfvf->mbox.lock);337	req = otx2_mbox_alloc_msg_cgx_cfg_pause_frm(&pfvf->mbox);338	if (!req) {339		mutex_unlock(&pfvf->mbox.lock);340		return;341	}342 343	if (!otx2_sync_mbox_msg(&pfvf->mbox)) {344		rsp = (struct cgx_pause_frm_cfg *)345		       otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);346		pause->rx_pause = rsp->rx_pause;347		pause->tx_pause = rsp->tx_pause;348	}349	mutex_unlock(&pfvf->mbox.lock);350}351 352static int otx2_set_pauseparam(struct net_device *netdev,353			       struct ethtool_pauseparam *pause)354{355	struct otx2_nic *pfvf = netdev_priv(netdev);356 357	if (pause->autoneg)358		return -EOPNOTSUPP;359 360	if (is_otx2_lbkvf(pfvf->pdev))361		return -EOPNOTSUPP;362 363	if (pause->rx_pause)364		pfvf->flags |= OTX2_FLAG_RX_PAUSE_ENABLED;365	else366		pfvf->flags &= ~OTX2_FLAG_RX_PAUSE_ENABLED;367 368	if (pause->tx_pause)369		pfvf->flags |= OTX2_FLAG_TX_PAUSE_ENABLED;370	else371		pfvf->flags &= ~OTX2_FLAG_TX_PAUSE_ENABLED;372 373	return otx2_config_pause_frm(pfvf);374}375 376static void otx2_get_ringparam(struct net_device *netdev,377			       struct ethtool_ringparam *ring,378			       struct kernel_ethtool_ringparam *kernel_ring,379			       struct netlink_ext_ack *extack)380{381	struct otx2_nic *pfvf = netdev_priv(netdev);382	struct otx2_qset *qs = &pfvf->qset;383 384	ring->rx_max_pending = Q_COUNT(Q_SIZE_MAX);385	ring->rx_pending = qs->rqe_cnt ? qs->rqe_cnt : Q_COUNT(Q_SIZE_256);386	ring->tx_max_pending = Q_COUNT(Q_SIZE_MAX);387	ring->tx_pending = qs->sqe_cnt ? qs->sqe_cnt : Q_COUNT(Q_SIZE_4K);388	kernel_ring->rx_buf_len = pfvf->hw.rbuf_len;389	kernel_ring->cqe_size = pfvf->hw.xqe_size;390}391 392static int otx2_set_ringparam(struct net_device *netdev,393			      struct ethtool_ringparam *ring,394			      struct kernel_ethtool_ringparam *kernel_ring,395			      struct netlink_ext_ack *extack)396{397	struct otx2_nic *pfvf = netdev_priv(netdev);398	u32 rx_buf_len = kernel_ring->rx_buf_len;399	u32 old_rx_buf_len = pfvf->hw.rbuf_len;400	u32 xqe_size = kernel_ring->cqe_size;401	bool if_up = netif_running(netdev);402	struct otx2_qset *qs = &pfvf->qset;403	u32 rx_count, tx_count;404 405	if (ring->rx_mini_pending || ring->rx_jumbo_pending)406		return -EINVAL;407 408	/* Hardware supports max size of 32k for a receive buffer409	 * and 1536 is typical ethernet frame size.410	 */411	if (rx_buf_len && (rx_buf_len < 1536 || rx_buf_len > 32768)) {412		netdev_err(netdev,413			   "Receive buffer range is 1536 - 32768");414		return -EINVAL;415	}416 417	if (xqe_size != 128 && xqe_size != 512) {418		netdev_err(netdev,419			   "Completion event size must be 128 or 512");420		return -EINVAL;421	}422 423	/* Permitted lengths are 16 64 256 1K 4K 16K 64K 256K 1M  */424	rx_count = ring->rx_pending;425	/* On some silicon variants a skid or reserved CQEs are426	 * needed to avoid CQ overflow.427	 */428	if (rx_count < pfvf->hw.rq_skid)429		rx_count =  pfvf->hw.rq_skid;430	rx_count = Q_COUNT(Q_SIZE(rx_count, 3));431 432	/* Due pipelining impact minimum 2000 unused SQ CQE's433	 * need to be maintained to avoid CQ overflow, hence the434	 * minimum 4K size.435	 */436	tx_count = clamp_t(u32, ring->tx_pending,437			   Q_COUNT(Q_SIZE_4K), Q_COUNT(Q_SIZE_MAX));438	tx_count = Q_COUNT(Q_SIZE(tx_count, 3));439 440	if (tx_count == qs->sqe_cnt && rx_count == qs->rqe_cnt &&441	    rx_buf_len == old_rx_buf_len && xqe_size == pfvf->hw.xqe_size)442		return 0;443 444	if (if_up)445		netdev->netdev_ops->ndo_stop(netdev);446 447	/* Assigned to the nearest possible exponent. */448	qs->sqe_cnt = tx_count;449	qs->rqe_cnt = rx_count;450 451	pfvf->hw.rbuf_len = rx_buf_len;452	pfvf->hw.xqe_size = xqe_size;453 454	if (if_up)455		return netdev->netdev_ops->ndo_open(netdev);456 457	return 0;458}459 460static int otx2_get_coalesce(struct net_device *netdev,461			     struct ethtool_coalesce *cmd,462			     struct kernel_ethtool_coalesce *kernel_coal,463			     struct netlink_ext_ack *extack)464{465	struct otx2_nic *pfvf = netdev_priv(netdev);466	struct otx2_hw *hw = &pfvf->hw;467 468	cmd->rx_coalesce_usecs = hw->cq_time_wait;469	cmd->rx_max_coalesced_frames = hw->cq_ecount_wait;470	cmd->tx_coalesce_usecs = hw->cq_time_wait;471	cmd->tx_max_coalesced_frames = hw->cq_ecount_wait;472	if ((pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) ==473			OTX2_FLAG_ADPTV_INT_COAL_ENABLED) {474		cmd->use_adaptive_rx_coalesce = 1;475		cmd->use_adaptive_tx_coalesce = 1;476	} else {477		cmd->use_adaptive_rx_coalesce = 0;478		cmd->use_adaptive_tx_coalesce = 0;479	}480 481	return 0;482}483 484static int otx2_set_coalesce(struct net_device *netdev,485			     struct ethtool_coalesce *ec,486			     struct kernel_ethtool_coalesce *kernel_coal,487			     struct netlink_ext_ack *extack)488{489	struct otx2_nic *pfvf = netdev_priv(netdev);490	struct otx2_hw *hw = &pfvf->hw;491	u8 priv_coalesce_status;492	int qidx;493 494	if (!ec->rx_max_coalesced_frames || !ec->tx_max_coalesced_frames)495		return 0;496 497	if (ec->use_adaptive_rx_coalesce != ec->use_adaptive_tx_coalesce) {498		netdev_err(netdev,499			   "adaptive-rx should be same as adaptive-tx");500		return -EINVAL;501	}502 503	/* Check and update coalesce status */504	if ((pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) ==505			OTX2_FLAG_ADPTV_INT_COAL_ENABLED) {506		priv_coalesce_status = 1;507		if (!ec->use_adaptive_rx_coalesce)508			pfvf->flags &= ~OTX2_FLAG_ADPTV_INT_COAL_ENABLED;509	} else {510		priv_coalesce_status = 0;511		if (ec->use_adaptive_rx_coalesce)512			pfvf->flags |= OTX2_FLAG_ADPTV_INT_COAL_ENABLED;513	}514 515	/* 'cq_time_wait' is 8bit and is in multiple of 100ns,516	 * so clamp the user given value to the range of 1 to 25usec.517	 */518	ec->rx_coalesce_usecs = clamp_t(u32, ec->rx_coalesce_usecs,519					1, CQ_TIMER_THRESH_MAX);520	ec->tx_coalesce_usecs = clamp_t(u32, ec->tx_coalesce_usecs,521					1, CQ_TIMER_THRESH_MAX);522 523	/* Rx and Tx are mapped to same CQ, check which one524	 * is changed, if both then choose the min.525	 */526	if (hw->cq_time_wait == ec->rx_coalesce_usecs)527		hw->cq_time_wait = ec->tx_coalesce_usecs;528	else if (hw->cq_time_wait == ec->tx_coalesce_usecs)529		hw->cq_time_wait = ec->rx_coalesce_usecs;530	else531		hw->cq_time_wait = min_t(u8, ec->rx_coalesce_usecs,532					 ec->tx_coalesce_usecs);533 534	/* Max ecount_wait supported is 16bit,535	 * so clamp the user given value to the range of 1 to 64k.536	 */537	ec->rx_max_coalesced_frames = clamp_t(u32, ec->rx_max_coalesced_frames,538					      1, NAPI_POLL_WEIGHT);539	ec->tx_max_coalesced_frames = clamp_t(u32, ec->tx_max_coalesced_frames,540					      1, NAPI_POLL_WEIGHT);541 542	/* Rx and Tx are mapped to same CQ, check which one543	 * is changed, if both then choose the min.544	 */545	if (hw->cq_ecount_wait == ec->rx_max_coalesced_frames)546		hw->cq_ecount_wait = ec->tx_max_coalesced_frames;547	else if (hw->cq_ecount_wait == ec->tx_max_coalesced_frames)548		hw->cq_ecount_wait = ec->rx_max_coalesced_frames;549	else550		hw->cq_ecount_wait = min_t(u16, ec->rx_max_coalesced_frames,551					   ec->tx_max_coalesced_frames);552 553	/* Reset 'cq_time_wait' and 'cq_ecount_wait' to554	 * default values if coalesce status changed from555	 * 'on' to 'off'.556	 */557	if (priv_coalesce_status &&558	    ((pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) !=559	     OTX2_FLAG_ADPTV_INT_COAL_ENABLED)) {560		hw->cq_time_wait = CQ_TIMER_THRESH_DEFAULT;561		hw->cq_ecount_wait = CQ_CQE_THRESH_DEFAULT;562	}563 564	if (netif_running(netdev)) {565		for (qidx = 0; qidx < pfvf->hw.cint_cnt; qidx++)566			otx2_config_irq_coalescing(pfvf, qidx);567	}568 569	return 0;570}571 572static int otx2_get_rss_hash_opts(struct otx2_nic *pfvf,573				  struct ethtool_rxnfc *nfc)574{575	struct otx2_rss_info *rss = &pfvf->hw.rss_info;576 577	if (!(rss->flowkey_cfg &578	    (NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6)))579		return 0;580 581	/* Mimimum is IPv4 and IPv6, SIP/DIP */582	nfc->data = RXH_IP_SRC | RXH_IP_DST;583	if (rss->flowkey_cfg & NIX_FLOW_KEY_TYPE_VLAN)584		nfc->data |= RXH_VLAN;585 586	switch (nfc->flow_type) {587	case TCP_V4_FLOW:588	case TCP_V6_FLOW:589		if (rss->flowkey_cfg & NIX_FLOW_KEY_TYPE_TCP)590			nfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;591		break;592	case UDP_V4_FLOW:593	case UDP_V6_FLOW:594		if (rss->flowkey_cfg & NIX_FLOW_KEY_TYPE_UDP)595			nfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;596		break;597	case SCTP_V4_FLOW:598	case SCTP_V6_FLOW:599		if (rss->flowkey_cfg & NIX_FLOW_KEY_TYPE_SCTP)600			nfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;601		break;602	case AH_ESP_V4_FLOW:603	case AH_ESP_V6_FLOW:604		if (rss->flowkey_cfg & NIX_FLOW_KEY_TYPE_ESP)605			nfc->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;606		break;607	case AH_V4_FLOW:608	case ESP_V4_FLOW:609	case IPV4_FLOW:610		break;611	case AH_V6_FLOW:612	case ESP_V6_FLOW:613	case IPV6_FLOW:614		break;615	default:616		return -EINVAL;617	}618 619	return 0;620}621 622static int otx2_set_rss_hash_opts(struct otx2_nic *pfvf,623				  struct ethtool_rxnfc *nfc)624{625	struct otx2_rss_info *rss = &pfvf->hw.rss_info;626	u32 rxh_l4 = RXH_L4_B_0_1 | RXH_L4_B_2_3;627	u32 rss_cfg = rss->flowkey_cfg;628 629	if (!rss->enable) {630		netdev_err(pfvf->netdev,631			   "RSS is disabled, cannot change settings\n");632		return -EIO;633	}634 635	/* Mimimum is IPv4 and IPv6, SIP/DIP */636	if (!(nfc->data & RXH_IP_SRC) || !(nfc->data & RXH_IP_DST))637		return -EINVAL;638 639	if (nfc->data & RXH_VLAN)640		rss_cfg |=  NIX_FLOW_KEY_TYPE_VLAN;641	else642		rss_cfg &= ~NIX_FLOW_KEY_TYPE_VLAN;643 644	switch (nfc->flow_type) {645	case TCP_V4_FLOW:646	case TCP_V6_FLOW:647		/* Different config for v4 and v6 is not supported.648		 * Both of them have to be either 4-tuple or 2-tuple.649		 */650		switch (nfc->data & rxh_l4) {651		case 0:652			rss_cfg &= ~NIX_FLOW_KEY_TYPE_TCP;653			break;654		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):655			rss_cfg |= NIX_FLOW_KEY_TYPE_TCP;656			break;657		default:658			return -EINVAL;659		}660		break;661	case UDP_V4_FLOW:662	case UDP_V6_FLOW:663		switch (nfc->data & rxh_l4) {664		case 0:665			rss_cfg &= ~NIX_FLOW_KEY_TYPE_UDP;666			break;667		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):668			rss_cfg |= NIX_FLOW_KEY_TYPE_UDP;669			break;670		default:671			return -EINVAL;672		}673		break;674	case SCTP_V4_FLOW:675	case SCTP_V6_FLOW:676		switch (nfc->data & rxh_l4) {677		case 0:678			rss_cfg &= ~NIX_FLOW_KEY_TYPE_SCTP;679			break;680		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):681			rss_cfg |= NIX_FLOW_KEY_TYPE_SCTP;682			break;683		default:684			return -EINVAL;685		}686		break;687	case AH_ESP_V4_FLOW:688	case AH_ESP_V6_FLOW:689		switch (nfc->data & rxh_l4) {690		case 0:691			rss_cfg &= ~(NIX_FLOW_KEY_TYPE_ESP |692				     NIX_FLOW_KEY_TYPE_AH);693			rss_cfg |= NIX_FLOW_KEY_TYPE_VLAN |694				   NIX_FLOW_KEY_TYPE_IPV4_PROTO;695			break;696		case (RXH_L4_B_0_1 | RXH_L4_B_2_3):697			/* If VLAN hashing is also requested for ESP then do not698			 * allow because of hardware 40 bytes flow key limit.699			 */700			if (rss_cfg & NIX_FLOW_KEY_TYPE_VLAN) {701				netdev_err(pfvf->netdev,702					   "RSS hash of ESP or AH with VLAN is not supported\n");703				return -EOPNOTSUPP;704			}705 706			rss_cfg |= NIX_FLOW_KEY_TYPE_ESP | NIX_FLOW_KEY_TYPE_AH;707			/* Disable IPv4 proto hashing since IPv6 SA+DA(32 bytes)708			 * and ESP SPI+sequence(8 bytes) uses hardware maximum709			 * limit of 40 byte flow key.710			 */711			rss_cfg &= ~NIX_FLOW_KEY_TYPE_IPV4_PROTO;712			break;713		default:714			return -EINVAL;715		}716		break;717	case IPV4_FLOW:718	case IPV6_FLOW:719		rss_cfg = NIX_FLOW_KEY_TYPE_IPV4 | NIX_FLOW_KEY_TYPE_IPV6;720		break;721	default:722		return -EINVAL;723	}724 725	rss->flowkey_cfg = rss_cfg;726	otx2_set_flowkey_cfg(pfvf);727	return 0;728}729 730static int otx2_get_rxnfc(struct net_device *dev,731			  struct ethtool_rxnfc *nfc, u32 *rules)732{733	bool ntuple = !!(dev->features & NETIF_F_NTUPLE);734	struct otx2_nic *pfvf = netdev_priv(dev);735	int ret = -EOPNOTSUPP;736 737	switch (nfc->cmd) {738	case ETHTOOL_GRXRINGS:739		nfc->data = pfvf->hw.rx_queues;740		ret = 0;741		break;742	case ETHTOOL_GRXCLSRLCNT:743		if (netif_running(dev) && ntuple) {744			nfc->rule_cnt = pfvf->flow_cfg->nr_flows;745			ret = 0;746		}747		break;748	case ETHTOOL_GRXCLSRULE:749		if (netif_running(dev) && ntuple)750			ret = otx2_get_flow(pfvf, nfc,  nfc->fs.location);751		break;752	case ETHTOOL_GRXCLSRLALL:753		if (netif_running(dev) && ntuple)754			ret = otx2_get_all_flows(pfvf, nfc, rules);755		break;756	case ETHTOOL_GRXFH:757		return otx2_get_rss_hash_opts(pfvf, nfc);758	default:759		break;760	}761	return ret;762}763 764static int otx2_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *nfc)765{766	bool ntuple = !!(dev->features & NETIF_F_NTUPLE);767	struct otx2_nic *pfvf = netdev_priv(dev);768	int ret = -EOPNOTSUPP;769 770	pfvf->flow_cfg->ntuple = ntuple;771	switch (nfc->cmd) {772	case ETHTOOL_SRXFH:773		ret = otx2_set_rss_hash_opts(pfvf, nfc);774		break;775	case ETHTOOL_SRXCLSRLINS:776		if (netif_running(dev) && ntuple)777			ret = otx2_add_flow(pfvf, nfc);778		break;779	case ETHTOOL_SRXCLSRLDEL:780		if (netif_running(dev) && ntuple)781			ret = otx2_remove_flow(pfvf, nfc->fs.location);782		break;783	default:784		break;785	}786 787	return ret;788}789 790static u32 otx2_get_rxfh_key_size(struct net_device *netdev)791{792	struct otx2_nic *pfvf = netdev_priv(netdev);793	struct otx2_rss_info *rss;794 795	rss = &pfvf->hw.rss_info;796 797	return sizeof(rss->key);798}799 800static u32 otx2_get_rxfh_indir_size(struct net_device *dev)801{802	return  MAX_RSS_INDIR_TBL_SIZE;803}804 805static int otx2_rss_ctx_delete(struct otx2_nic *pfvf, int ctx_id)806{807	struct otx2_rss_info *rss = &pfvf->hw.rss_info;808 809	otx2_rss_ctx_flow_del(pfvf, ctx_id);810	kfree(rss->rss_ctx[ctx_id]);811	rss->rss_ctx[ctx_id] = NULL;812 813	return 0;814}815 816static int otx2_rss_ctx_create(struct otx2_nic *pfvf,817			       u32 *rss_context)818{819	struct otx2_rss_info *rss = &pfvf->hw.rss_info;820	u8 ctx;821 822	for (ctx = 0; ctx < MAX_RSS_GROUPS; ctx++) {823		if (!rss->rss_ctx[ctx])824			break;825	}826	if (ctx == MAX_RSS_GROUPS)827		return -EINVAL;828 829	rss->rss_ctx[ctx] = kzalloc(sizeof(*rss->rss_ctx[ctx]), GFP_KERNEL);830	if (!rss->rss_ctx[ctx])831		return -ENOMEM;832	*rss_context = ctx;833 834	return 0;835}836 837/* Configure RSS table and hash key */838static int otx2_set_rxfh(struct net_device *dev,839			 struct ethtool_rxfh_param *rxfh,840			 struct netlink_ext_ack *extack)841{842	u32 rss_context = DEFAULT_RSS_CONTEXT_GROUP;843	struct otx2_nic *pfvf = netdev_priv(dev);844	struct otx2_rss_ctx *rss_ctx;845	struct otx2_rss_info *rss;846	int ret, idx;847 848	if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&849	    rxfh->hfunc != ETH_RSS_HASH_TOP)850		return -EOPNOTSUPP;851 852	if (rxfh->rss_context)853		rss_context = rxfh->rss_context;854 855	if (rss_context != ETH_RXFH_CONTEXT_ALLOC &&856	    rss_context >= MAX_RSS_GROUPS)857		return -EINVAL;858 859	rss = &pfvf->hw.rss_info;860 861	if (!rss->enable) {862		netdev_err(dev, "RSS is disabled, cannot change settings\n");863		return -EIO;864	}865 866	if (rxfh->key) {867		memcpy(rss->key, rxfh->key, sizeof(rss->key));868		otx2_set_rss_key(pfvf);869	}870	if (rxfh->rss_delete)871		return otx2_rss_ctx_delete(pfvf, rss_context);872 873	if (rss_context == ETH_RXFH_CONTEXT_ALLOC) {874		ret = otx2_rss_ctx_create(pfvf, &rss_context);875		rxfh->rss_context = rss_context;876		if (ret)877			return ret;878	}879	if (rxfh->indir) {880		rss_ctx = rss->rss_ctx[rss_context];881		for (idx = 0; idx < rss->rss_size; idx++)882			rss_ctx->ind_tbl[idx] = rxfh->indir[idx];883	}884	otx2_set_rss_table(pfvf, rss_context);885 886	return 0;887}888 889/* Get RSS configuration */890static int otx2_get_rxfh(struct net_device *dev,891			 struct ethtool_rxfh_param *rxfh)892{893	u32 rss_context = DEFAULT_RSS_CONTEXT_GROUP;894	struct otx2_nic *pfvf = netdev_priv(dev);895	struct otx2_rss_ctx *rss_ctx;896	struct otx2_rss_info *rss;897	u32 *indir = rxfh->indir;898	int idx, rx_queues;899 900	rss = &pfvf->hw.rss_info;901 902	rxfh->hfunc = ETH_RSS_HASH_TOP;903	if (rxfh->rss_context)904		rss_context = rxfh->rss_context;905 906	if (!indir)907		return 0;908 909	if (!rss->enable && rss_context == DEFAULT_RSS_CONTEXT_GROUP) {910		rx_queues = pfvf->hw.rx_queues;911		for (idx = 0; idx < MAX_RSS_INDIR_TBL_SIZE; idx++)912			indir[idx] = ethtool_rxfh_indir_default(idx, rx_queues);913		return 0;914	}915	if (rss_context >= MAX_RSS_GROUPS)916		return -ENOENT;917 918	rss_ctx = rss->rss_ctx[rss_context];919	if (!rss_ctx)920		return -ENOENT;921 922	if (indir) {923		for (idx = 0; idx < rss->rss_size; idx++)924			indir[idx] = rss_ctx->ind_tbl[idx];925	}926	if (rxfh->key)927		memcpy(rxfh->key, rss->key, sizeof(rss->key));928 929	return 0;930}931 932static u32 otx2_get_msglevel(struct net_device *netdev)933{934	struct otx2_nic *pfvf = netdev_priv(netdev);935 936	return pfvf->msg_enable;937}938 939static void otx2_set_msglevel(struct net_device *netdev, u32 val)940{941	struct otx2_nic *pfvf = netdev_priv(netdev);942 943	pfvf->msg_enable = val;944}945 946static u32 otx2_get_link(struct net_device *netdev)947{948	struct otx2_nic *pfvf = netdev_priv(netdev);949 950	/* LBK link is internal and always UP */951	if (is_otx2_lbkvf(pfvf->pdev))952		return 1;953	return pfvf->linfo.link_up;954}955 956static int otx2_get_ts_info(struct net_device *netdev,957			    struct kernel_ethtool_ts_info *info)958{959	struct otx2_nic *pfvf = netdev_priv(netdev);960 961	if (!pfvf->ptp)962		return ethtool_op_get_ts_info(netdev, info);963 964	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |965				SOF_TIMESTAMPING_TX_HARDWARE |966				SOF_TIMESTAMPING_RX_HARDWARE |967				SOF_TIMESTAMPING_RAW_HARDWARE;968 969	info->phc_index = otx2_ptp_clock_index(pfvf);970 971	info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);972	if (test_bit(CN10K_PTP_ONESTEP, &pfvf->hw.cap_flag))973		info->tx_types |= BIT(HWTSTAMP_TX_ONESTEP_SYNC);974 975	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |976			   BIT(HWTSTAMP_FILTER_ALL);977 978	return 0;979}980 981static struct cgx_fw_data *otx2_get_fwdata(struct otx2_nic *pfvf)982{983	struct cgx_fw_data *rsp = NULL;984	struct msg_req *req;985	int err = 0;986 987	mutex_lock(&pfvf->mbox.lock);988	req = otx2_mbox_alloc_msg_cgx_get_aux_link_info(&pfvf->mbox);989	if (!req) {990		mutex_unlock(&pfvf->mbox.lock);991		return ERR_PTR(-ENOMEM);992	}993 994	err = otx2_sync_mbox_msg(&pfvf->mbox);995	if (!err) {996		rsp = (struct cgx_fw_data *)997			otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);998	} else {999		rsp = ERR_PTR(err);1000	}1001 1002	mutex_unlock(&pfvf->mbox.lock);1003	return rsp;1004}1005 1006static int otx2_get_fecparam(struct net_device *netdev,1007			     struct ethtool_fecparam *fecparam)1008{1009	struct otx2_nic *pfvf = netdev_priv(netdev);1010	struct cgx_fw_data *rsp;1011	const int fec[] = {1012		ETHTOOL_FEC_OFF,1013		ETHTOOL_FEC_BASER,1014		ETHTOOL_FEC_RS,1015		ETHTOOL_FEC_BASER | ETHTOOL_FEC_RS};1016#define FEC_MAX_INDEX 41017	if (pfvf->linfo.fec < FEC_MAX_INDEX)1018		fecparam->active_fec = fec[pfvf->linfo.fec];1019 1020	rsp = otx2_get_fwdata(pfvf);1021	if (IS_ERR(rsp))1022		return PTR_ERR(rsp);1023 1024	if (rsp->fwdata.supported_fec < FEC_MAX_INDEX) {1025		if (!rsp->fwdata.supported_fec)1026			fecparam->fec = ETHTOOL_FEC_NONE;1027		else1028			fecparam->fec = fec[rsp->fwdata.supported_fec];1029	}1030	return 0;1031}1032 1033static int otx2_set_fecparam(struct net_device *netdev,1034			     struct ethtool_fecparam *fecparam)1035{1036	struct otx2_nic *pfvf = netdev_priv(netdev);1037	struct mbox *mbox = &pfvf->mbox;1038	struct fec_mode *req, *rsp;1039	int err = 0, fec = 0;1040 1041	switch (fecparam->fec) {1042	/* Firmware does not support AUTO mode consider it as FEC_OFF */1043	case ETHTOOL_FEC_OFF:1044	case ETHTOOL_FEC_AUTO:1045		fec = OTX2_FEC_OFF;1046		break;1047	case ETHTOOL_FEC_RS:1048		fec = OTX2_FEC_RS;1049		break;1050	case ETHTOOL_FEC_BASER:1051		fec = OTX2_FEC_BASER;1052		break;1053	default:1054		netdev_warn(pfvf->netdev, "Unsupported FEC mode: %d",1055			    fecparam->fec);1056		return -EINVAL;1057	}1058 1059	if (fec == pfvf->linfo.fec)1060		return 0;1061 1062	mutex_lock(&mbox->lock);1063	req = otx2_mbox_alloc_msg_cgx_set_fec_param(&pfvf->mbox);1064	if (!req) {1065		err = -ENOMEM;1066		goto end;1067	}1068	req->fec = fec;1069	err = otx2_sync_mbox_msg(&pfvf->mbox);1070	if (err)1071		goto end;1072 1073	rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,1074						   0, &req->hdr);1075	if (rsp->fec >= 0)1076		pfvf->linfo.fec = rsp->fec;1077	else1078		err = rsp->fec;1079end:1080	mutex_unlock(&mbox->lock);1081	return err;1082}1083 1084static void otx2_get_fec_info(u64 index, int req_mode,1085			      struct ethtool_link_ksettings *link_ksettings)1086{1087	__ETHTOOL_DECLARE_LINK_MODE_MASK(otx2_fec_modes) = { 0, };1088 1089	switch (index) {1090	case OTX2_FEC_NONE:1091		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT,1092				 otx2_fec_modes);1093		break;1094	case OTX2_FEC_BASER:1095		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT,1096				 otx2_fec_modes);1097		break;1098	case OTX2_FEC_RS:1099		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT,1100				 otx2_fec_modes);1101		break;1102	case OTX2_FEC_BASER | OTX2_FEC_RS:1103		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT,1104				 otx2_fec_modes);1105		linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT,1106				 otx2_fec_modes);1107		break;1108	}1109 1110	/* Add fec modes to existing modes */1111	if (req_mode == OTX2_MODE_ADVERTISED)1112		linkmode_or(link_ksettings->link_modes.advertising,1113			    link_ksettings->link_modes.advertising,1114			    otx2_fec_modes);1115	else1116		linkmode_or(link_ksettings->link_modes.supported,1117			    link_ksettings->link_modes.supported,1118			    otx2_fec_modes);1119}1120 1121static void otx2_get_link_mode_info(u64 link_mode_bmap,1122				    bool req_mode,1123				    struct ethtool_link_ksettings1124				    *link_ksettings)1125{1126	__ETHTOOL_DECLARE_LINK_MODE_MASK(otx2_link_modes) = { 0, };1127	const int otx2_sgmii_features[6] = {1128		ETHTOOL_LINK_MODE_10baseT_Half_BIT,1129		ETHTOOL_LINK_MODE_10baseT_Full_BIT,1130		ETHTOOL_LINK_MODE_100baseT_Half_BIT,1131		ETHTOOL_LINK_MODE_100baseT_Full_BIT,1132		ETHTOOL_LINK_MODE_1000baseT_Half_BIT,1133		ETHTOOL_LINK_MODE_1000baseT_Full_BIT,1134	};1135	/* CGX link modes to Ethtool link mode mapping */1136	const int cgx_link_mode[27] = {1137		0, /* SGMII  Mode */1138		ETHTOOL_LINK_MODE_1000baseX_Full_BIT,1139		ETHTOOL_LINK_MODE_10000baseT_Full_BIT,1140		ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,1141		ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,1142		ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,1143		0,1144		ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,1145		0,1146		0,1147		ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,1148		ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,1149		ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,1150		ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,1151		ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,1152		ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,1153		0,1154		ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,1155		0,1156		ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,1157		ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,1158		ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,1159		0,1160		ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,1161		ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,1162		ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,1163		ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT1164	};1165	u8 bit;1166 1167	for_each_set_bit(bit, (unsigned long *)&link_mode_bmap, 27) {1168		/* SGMII mode is set */1169		if (bit == 0)1170			linkmode_set_bit_array(otx2_sgmii_features,1171					       ARRAY_SIZE(otx2_sgmii_features),1172					       otx2_link_modes);1173		else1174			linkmode_set_bit(cgx_link_mode[bit], otx2_link_modes);1175	}1176 1177	if (req_mode == OTX2_MODE_ADVERTISED)1178		linkmode_copy(link_ksettings->link_modes.advertising,1179			      otx2_link_modes);1180	else1181		linkmode_copy(link_ksettings->link_modes.supported,1182			      otx2_link_modes);1183}1184 1185static int otx2_get_link_ksettings(struct net_device *netdev,1186				   struct ethtool_link_ksettings *cmd)1187{1188	struct otx2_nic *pfvf = netdev_priv(netdev);1189	struct cgx_fw_data *rsp = NULL;1190 1191	cmd->base.duplex  = pfvf->linfo.full_duplex;1192	cmd->base.speed   = pfvf->linfo.speed;1193	cmd->base.autoneg = pfvf->linfo.an;1194 1195	rsp = otx2_get_fwdata(pfvf);1196	if (IS_ERR(rsp))1197		return PTR_ERR(rsp);1198 1199	if (rsp->fwdata.supported_an)1200		ethtool_link_ksettings_add_link_mode(cmd,1201						     supported,1202						     Autoneg);1203 1204	otx2_get_link_mode_info(rsp->fwdata.advertised_link_modes,1205				OTX2_MODE_ADVERTISED, cmd);1206	otx2_get_fec_info(rsp->fwdata.advertised_fec,1207			  OTX2_MODE_ADVERTISED, cmd);1208	otx2_get_link_mode_info(rsp->fwdata.supported_link_modes,1209				OTX2_MODE_SUPPORTED, cmd);1210	otx2_get_fec_info(rsp->fwdata.supported_fec,1211			  OTX2_MODE_SUPPORTED, cmd);1212	return 0;1213}1214 1215static void otx2_get_advertised_mode(const struct ethtool_link_ksettings *cmd,1216				     u64 *mode)1217{1218	u32 bit_pos;1219 1220	/* Firmware does not support requesting multiple advertised modes1221	 * return first set bit1222	 */1223	bit_pos = find_first_bit(cmd->link_modes.advertising,1224				 __ETHTOOL_LINK_MODE_MASK_NBITS);1225	if (bit_pos != __ETHTOOL_LINK_MODE_MASK_NBITS)1226		*mode = bit_pos;1227}1228 1229static int otx2_set_link_ksettings(struct net_device *netdev,1230				   const struct ethtool_link_ksettings *cmd)1231{1232	struct otx2_nic *pf = netdev_priv(netdev);1233	struct ethtool_link_ksettings cur_ks;1234	struct cgx_set_link_mode_req *req;1235	struct mbox *mbox = &pf->mbox;1236	int err = 0;1237 1238	memset(&cur_ks, 0, sizeof(struct ethtool_link_ksettings));1239 1240	if (!ethtool_validate_speed(cmd->base.speed) ||1241	    !ethtool_validate_duplex(cmd->base.duplex))1242		return -EINVAL;1243 1244	if (cmd->base.autoneg != AUTONEG_ENABLE &&1245	    cmd->base.autoneg != AUTONEG_DISABLE)1246		return -EINVAL;1247 1248	otx2_get_link_ksettings(netdev, &cur_ks);1249 1250	/* Check requested modes against supported modes by hardware */1251	if (!linkmode_subset(cmd->link_modes.advertising,1252			     cur_ks.link_modes.supported))1253		return -EINVAL;1254 1255	mutex_lock(&mbox->lock);1256	req = otx2_mbox_alloc_msg_cgx_set_link_mode(&pf->mbox);1257	if (!req) {1258		err = -ENOMEM;1259		goto end;1260	}1261 1262	req->args.speed = cmd->base.speed;1263	/* firmware expects 1 for half duplex and 0 for full duplex1264	 * hence inverting1265	 */1266	req->args.duplex = cmd->base.duplex ^ 0x1;1267	req->args.an = cmd->base.autoneg;1268	otx2_get_advertised_mode(cmd, &req->args.mode);1269 1270	err = otx2_sync_mbox_msg(&pf->mbox);1271end:1272	mutex_unlock(&mbox->lock);1273	return err;1274}1275 1276static void otx2_get_fec_stats(struct net_device *netdev,1277			       struct ethtool_fec_stats *fec_stats)1278{1279	struct otx2_nic *pfvf = netdev_priv(netdev);1280	struct cgx_fw_data *rsp;1281 1282	otx2_update_lmac_fec_stats(pfvf);1283 1284	/* Report MAC FEC stats */1285	fec_stats->corrected_blocks.total     = pfvf->hw.cgx_fec_corr_blks;1286	fec_stats->uncorrectable_blocks.total = pfvf->hw.cgx_fec_uncorr_blks;1287 1288	rsp = otx2_get_fwdata(pfvf);1289	if (!IS_ERR(rsp) && rsp->fwdata.phy.misc.has_fec_stats &&1290	    !otx2_get_phy_fec_stats(pfvf)) {1291		/* Fetch fwdata again because it's been recently populated with1292		 * latest PHY FEC stats.1293		 */1294		rsp = otx2_get_fwdata(pfvf);1295		if (!IS_ERR(rsp)) {1296			struct fec_stats_s *p = &rsp->fwdata.phy.fec_stats;1297 1298			if (pfvf->linfo.fec == OTX2_FEC_BASER) {1299				fec_stats->corrected_blocks.total = p->brfec_corr_blks;1300				fec_stats->uncorrectable_blocks.total = p->brfec_uncorr_blks;1301			} else {1302				fec_stats->corrected_blocks.total = p->rsfec_corr_cws;1303				fec_stats->uncorrectable_blocks.total = p->rsfec_uncorr_cws;1304			}1305		}1306	}1307}1308 1309static const struct ethtool_ops otx2_ethtool_ops = {1310	.cap_rss_ctx_supported	= true,1311	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |1312				     ETHTOOL_COALESCE_MAX_FRAMES |1313				     ETHTOOL_COALESCE_USE_ADAPTIVE,1314	.supported_ring_params  = ETHTOOL_RING_USE_RX_BUF_LEN |1315				  ETHTOOL_RING_USE_CQE_SIZE,1316	.get_link		= otx2_get_link,1317	.get_drvinfo		= otx2_get_drvinfo,1318	.get_strings		= otx2_get_strings,1319	.get_ethtool_stats	= otx2_get_ethtool_stats,1320	.get_sset_count		= otx2_get_sset_count,1321	.set_channels		= otx2_set_channels,1322	.get_channels		= otx2_get_channels,1323	.get_ringparam		= otx2_get_ringparam,1324	.set_ringparam		= otx2_set_ringparam,1325	.get_coalesce		= otx2_get_coalesce,1326	.set_coalesce		= otx2_set_coalesce,1327	.get_rxnfc		= otx2_get_rxnfc,1328	.set_rxnfc              = otx2_set_rxnfc,1329	.get_rxfh_key_size	= otx2_get_rxfh_key_size,1330	.get_rxfh_indir_size	= otx2_get_rxfh_indir_size,1331	.get_rxfh		= otx2_get_rxfh,1332	.set_rxfh		= otx2_set_rxfh,1333	.get_msglevel		= otx2_get_msglevel,1334	.set_msglevel		= otx2_set_msglevel,1335	.get_pauseparam		= otx2_get_pauseparam,1336	.set_pauseparam		= otx2_set_pauseparam,1337	.get_ts_info		= otx2_get_ts_info,1338	.get_fec_stats		= otx2_get_fec_stats,1339	.get_fecparam		= otx2_get_fecparam,1340	.set_fecparam		= otx2_set_fecparam,1341	.get_link_ksettings     = otx2_get_link_ksettings,1342	.set_link_ksettings     = otx2_set_link_ksettings,1343};1344 1345void otx2_set_ethtool_ops(struct net_device *netdev)1346{1347	netdev->ethtool_ops = &otx2_ethtool_ops;1348}1349 1350/* VF's ethtool APIs */1351static void otx2vf_get_drvinfo(struct net_device *netdev,1352			       struct ethtool_drvinfo *info)1353{1354	struct otx2_nic *vf = netdev_priv(netdev);1355 1356	strscpy(info->driver, DRV_VF_NAME, sizeof(info->driver));1357	strscpy(info->bus_info, pci_name(vf->pdev), sizeof(info->bus_info));1358}1359 1360static void otx2vf_get_strings(struct net_device *netdev, u32 sset, u8 *data)1361{1362	struct otx2_nic *vf = netdev_priv(netdev);1363	int stats;1364 1365	if (sset != ETH_SS_STATS)1366		return;1367 1368	for (stats = 0; stats < otx2_n_dev_stats; stats++) {1369		memcpy(data, otx2_dev_stats[stats].name, ETH_GSTRING_LEN);1370		data += ETH_GSTRING_LEN;1371	}1372 1373	for (stats = 0; stats < otx2_n_drv_stats; stats++) {1374		memcpy(data, otx2_drv_stats[stats].name, ETH_GSTRING_LEN);1375		data += ETH_GSTRING_LEN;1376	}1377 1378	otx2_get_qset_strings(vf, &data, 0);1379 1380	strcpy(data, "reset_count");1381	data += ETH_GSTRING_LEN;1382}1383 1384static void otx2vf_get_ethtool_stats(struct net_device *netdev,1385				     struct ethtool_stats *stats, u64 *data)1386{1387	struct otx2_nic *vf = netdev_priv(netdev);1388	int stat;1389 1390	otx2_get_dev_stats(vf);1391	for (stat = 0; stat < otx2_n_dev_stats; stat++)1392		*(data++) = ((u64 *)&vf->hw.dev_stats)1393				[otx2_dev_stats[stat].index];1394 1395	for (stat = 0; stat < otx2_n_drv_stats; stat++)1396		*(data++) = atomic_read(&((atomic_t *)&vf->hw.drv_stats)1397						[otx2_drv_stats[stat].index]);1398 1399	otx2_get_qset_stats(vf, stats, &data);1400	*(data++) = vf->reset_count;1401}1402 1403static int otx2vf_get_sset_count(struct net_device *netdev, int sset)1404{1405	struct otx2_nic *vf = netdev_priv(netdev);1406	int qstats_count;1407 1408	if (sset != ETH_SS_STATS)1409		return -EINVAL;1410 1411	qstats_count = otx2_n_queue_stats *1412		       (vf->hw.rx_queues + otx2_get_total_tx_queues(vf));1413 1414	return otx2_n_dev_stats + otx2_n_drv_stats + qstats_count + 1;1415}1416 1417static int otx2vf_get_link_ksettings(struct net_device *netdev,1418				     struct ethtool_link_ksettings *cmd)1419{1420	struct otx2_nic *pfvf = netdev_priv(netdev);1421 1422	if (is_otx2_lbkvf(pfvf->pdev)) {1423		cmd->base.duplex = DUPLEX_FULL;1424		cmd->base.speed = SPEED_100000;1425	} else {1426		return otx2_get_link_ksettings(netdev, cmd);1427	}1428	return 0;1429}1430 1431static const struct ethtool_ops otx2vf_ethtool_ops = {1432	.cap_rss_ctx_supported	= true,1433	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |1434				     ETHTOOL_COALESCE_MAX_FRAMES |1435				     ETHTOOL_COALESCE_USE_ADAPTIVE,1436	.supported_ring_params  = ETHTOOL_RING_USE_RX_BUF_LEN |1437				  ETHTOOL_RING_USE_CQE_SIZE,1438	.get_link		= otx2_get_link,1439	.get_drvinfo		= otx2vf_get_drvinfo,1440	.get_strings		= otx2vf_get_strings,1441	.get_ethtool_stats	= otx2vf_get_ethtool_stats,1442	.get_sset_count		= otx2vf_get_sset_count,1443	.set_channels		= otx2_set_channels,1444	.get_channels		= otx2_get_channels,1445	.get_rxnfc		= otx2_get_rxnfc,1446	.set_rxnfc              = otx2_set_rxnfc,1447	.get_rxfh_key_size	= otx2_get_rxfh_key_size,1448	.get_rxfh_indir_size	= otx2_get_rxfh_indir_size,1449	.get_rxfh		= otx2_get_rxfh,1450	.set_rxfh		= otx2_set_rxfh,1451	.get_ringparam		= otx2_get_ringparam,1452	.set_ringparam		= otx2_set_ringparam,1453	.get_coalesce		= otx2_get_coalesce,1454	.set_coalesce		= otx2_set_coalesce,1455	.get_msglevel		= otx2_get_msglevel,1456	.set_msglevel		= otx2_set_msglevel,1457	.get_pauseparam		= otx2_get_pauseparam,1458	.set_pauseparam		= otx2_set_pauseparam,1459	.get_link_ksettings     = otx2vf_get_link_ksettings,1460	.get_ts_info		= otx2_get_ts_info,1461};1462 1463void otx2vf_set_ethtool_ops(struct net_device *netdev)1464{1465	netdev->ethtool_ops = &otx2vf_ethtool_ops;1466}1467EXPORT_SYMBOL(otx2vf_set_ethtool_ops);1468