1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */
3
4#include <linux/module.h>
5#include <linux/netdevice.h>
6#include <linux/sfp.h>
7
8#include "ionic.h"
9#include "ionic_bus.h"
10#include "ionic_lif.h"
11#include "ionic_ethtool.h"
12#include "ionic_stats.h"
13
14static const char ionic_priv_flags_strings[][ETH_GSTRING_LEN] = {
15#define IONIC_PRIV_F_SW_DBG_STATS	BIT(0)
16	"sw-dbg-stats",
17};
18
19#define IONIC_PRIV_FLAGS_COUNT ARRAY_SIZE(ionic_priv_flags_strings)
20
21static void ionic_get_stats_strings(struct ionic_lif *lif, u8 *buf)
22{
23	u32 i;
24
25	for (i = 0; i < ionic_num_stats_grps; i++)
26		ionic_stats_groups[i].get_strings(lif, &buf);
27}
28
29static void ionic_get_stats(struct net_device *netdev,
30			    struct ethtool_stats *stats, u64 *buf)
31{
32	struct ionic_lif *lif;
33	u32 i;
34
35	lif = netdev_priv(netdev);
36
37	memset(buf, 0, stats->n_stats * sizeof(*buf));
38	for (i = 0; i < ionic_num_stats_grps; i++)
39		ionic_stats_groups[i].get_values(lif, &buf);
40}
41
42static int ionic_get_stats_count(struct ionic_lif *lif)
43{
44	int i, num_stats = 0;
45
46	for (i = 0; i < ionic_num_stats_grps; i++)
47		num_stats += ionic_stats_groups[i].get_count(lif);
48
49	return num_stats;
50}
51
52static int ionic_get_sset_count(struct net_device *netdev, int sset)
53{
54	struct ionic_lif *lif = netdev_priv(netdev);
55	int count = 0;
56
57	switch (sset) {
58	case ETH_SS_STATS:
59		count = ionic_get_stats_count(lif);
60		break;
61	case ETH_SS_PRIV_FLAGS:
62		count = IONIC_PRIV_FLAGS_COUNT;
63		break;
64	}
65	return count;
66}
67
68static void ionic_get_strings(struct net_device *netdev,
69			      u32 sset, u8 *buf)
70{
71	struct ionic_lif *lif = netdev_priv(netdev);
72
73	switch (sset) {
74	case ETH_SS_STATS:
75		ionic_get_stats_strings(lif, buf);
76		break;
77	case ETH_SS_PRIV_FLAGS:
78		memcpy(buf, ionic_priv_flags_strings,
79		       IONIC_PRIV_FLAGS_COUNT * ETH_GSTRING_LEN);
80		break;
81	}
82}
83
84static void ionic_get_drvinfo(struct net_device *netdev,
85			      struct ethtool_drvinfo *drvinfo)
86{
87	struct ionic_lif *lif = netdev_priv(netdev);
88	struct ionic *ionic = lif->ionic;
89
90	strlcpy(drvinfo->driver, IONIC_DRV_NAME, sizeof(drvinfo->driver));
91	strlcpy(drvinfo->fw_version, ionic->idev.dev_info.fw_version,
92		sizeof(drvinfo->fw_version));
93	strlcpy(drvinfo->bus_info, ionic_bus_info(ionic),
94		sizeof(drvinfo->bus_info));
95}
96
97static int ionic_get_regs_len(struct net_device *netdev)
98{
99	return (IONIC_DEV_INFO_REG_COUNT + IONIC_DEV_CMD_REG_COUNT) * sizeof(u32);
100}
101
102static void ionic_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
103			   void *p)
104{
105	struct ionic_lif *lif = netdev_priv(netdev);
106	unsigned int offset;
107	unsigned int size;
108
109	regs->version = IONIC_DEV_CMD_REG_VERSION;
110
111	offset = 0;
112	size = IONIC_DEV_INFO_REG_COUNT * sizeof(u32);
113	memcpy_fromio(p + offset, lif->ionic->idev.dev_info_regs->words, size);
114
115	offset += size;
116	size = IONIC_DEV_CMD_REG_COUNT * sizeof(u32);
117	memcpy_fromio(p + offset, lif->ionic->idev.dev_cmd_regs->words, size);
118}
119
120static int ionic_get_link_ksettings(struct net_device *netdev,
121				    struct ethtool_link_ksettings *ks)
122{
123	struct ionic_lif *lif = netdev_priv(netdev);
124	struct ionic_dev *idev = &lif->ionic->idev;
125	int copper_seen = 0;
126
127	ethtool_link_ksettings_zero_link_mode(ks, supported);
128
129	if (!idev->port_info) {
130		netdev_err(netdev, "port_info not initialized\n");
131		return -EOPNOTSUPP;
132	}
133
134	/* The port_info data is found in a DMA space that the NIC keeps
135	 * up-to-date, so there's no need to request the data from the
136	 * NIC, we already have it in our memory space.
137	 */
138
139	switch (le16_to_cpu(idev->port_info->status.xcvr.pid)) {
140		/* Copper */
141	case IONIC_XCVR_PID_QSFP_100G_CR4:
142		ethtool_link_ksettings_add_link_mode(ks, supported,
143						     100000baseCR4_Full);
144		copper_seen++;
145		break;
146	case IONIC_XCVR_PID_QSFP_40GBASE_CR4:
147		ethtool_link_ksettings_add_link_mode(ks, supported,
148						     40000baseCR4_Full);
149		copper_seen++;
150		break;
151	case IONIC_XCVR_PID_SFP_25GBASE_CR_S:
152	case IONIC_XCVR_PID_SFP_25GBASE_CR_L:
153	case IONIC_XCVR_PID_SFP_25GBASE_CR_N:
154		ethtool_link_ksettings_add_link_mode(ks, supported,
155						     25000baseCR_Full);
156		copper_seen++;
157		break;
158	case IONIC_XCVR_PID_SFP_10GBASE_AOC:
159	case IONIC_XCVR_PID_SFP_10GBASE_CU:
160		ethtool_link_ksettings_add_link_mode(ks, supported,
161						     10000baseCR_Full);
162		copper_seen++;
163		break;
164
165		/* Fibre */
166	case IONIC_XCVR_PID_QSFP_100G_SR4:
167	case IONIC_XCVR_PID_QSFP_100G_AOC:
168		ethtool_link_ksettings_add_link_mode(ks, supported,
169						     100000baseSR4_Full);
170		break;
171	case IONIC_XCVR_PID_QSFP_100G_CWDM4:
172	case IONIC_XCVR_PID_QSFP_100G_PSM4:
173	case IONIC_XCVR_PID_QSFP_100G_LR4:
174		ethtool_link_ksettings_add_link_mode(ks, supported,
175						     100000baseLR4_ER4_Full);
176		break;
177	case IONIC_XCVR_PID_QSFP_100G_ER4:
178		ethtool_link_ksettings_add_link_mode(ks, supported,
179						     100000baseLR4_ER4_Full);
180		break;
181	case IONIC_XCVR_PID_QSFP_40GBASE_SR4:
182	case IONIC_XCVR_PID_QSFP_40GBASE_AOC:
183		ethtool_link_ksettings_add_link_mode(ks, supported,
184						     40000baseSR4_Full);
185		break;
186	case IONIC_XCVR_PID_QSFP_40GBASE_LR4:
187		ethtool_link_ksettings_add_link_mode(ks, supported,
188						     40000baseLR4_Full);
189		break;
190	case IONIC_XCVR_PID_SFP_25GBASE_SR:
191	case IONIC_XCVR_PID_SFP_25GBASE_AOC:
192	case IONIC_XCVR_PID_SFP_25GBASE_ACC:
193		ethtool_link_ksettings_add_link_mode(ks, supported,
194						     25000baseSR_Full);
195		break;
196	case IONIC_XCVR_PID_SFP_10GBASE_SR:
197		ethtool_link_ksettings_add_link_mode(ks, supported,
198						     10000baseSR_Full);
199		break;
200	case IONIC_XCVR_PID_SFP_10GBASE_LR:
201		ethtool_link_ksettings_add_link_mode(ks, supported,
202						     10000baseLR_Full);
203		break;
204	case IONIC_XCVR_PID_SFP_10GBASE_LRM:
205		ethtool_link_ksettings_add_link_mode(ks, supported,
206						     10000baseLRM_Full);
207		break;
208	case IONIC_XCVR_PID_SFP_10GBASE_ER:
209		ethtool_link_ksettings_add_link_mode(ks, supported,
210						     10000baseER_Full);
211		break;
212	case IONIC_XCVR_PID_UNKNOWN:
213		/* This means there's no module plugged in */
214		break;
215	default:
216		dev_info(lif->ionic->dev, "unknown xcvr type pid=%d / 0x%x\n",
217			 idev->port_info->status.xcvr.pid,
218			 idev->port_info->status.xcvr.pid);
219		break;
220	}
221
222	bitmap_copy(ks->link_modes.advertising, ks->link_modes.supported,
223		    __ETHTOOL_LINK_MODE_MASK_NBITS);
224
225	ethtool_link_ksettings_add_link_mode(ks, supported, FEC_BASER);
226	ethtool_link_ksettings_add_link_mode(ks, supported, FEC_RS);
227	if (idev->port_info->config.fec_type == IONIC_PORT_FEC_TYPE_FC)
228		ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_BASER);
229	else if (idev->port_info->config.fec_type == IONIC_PORT_FEC_TYPE_RS)
230		ethtool_link_ksettings_add_link_mode(ks, advertising, FEC_RS);
231
232	ethtool_link_ksettings_add_link_mode(ks, supported, FIBRE);
233	ethtool_link_ksettings_add_link_mode(ks, supported, Pause);
234
235	if (idev->port_info->status.xcvr.phy == IONIC_PHY_TYPE_COPPER ||
236	    copper_seen)
237		ks->base.port = PORT_DA;
238	else if (idev->port_info->status.xcvr.phy == IONIC_PHY_TYPE_FIBER)
239		ks->base.port = PORT_FIBRE;
240	else
241		ks->base.port = PORT_NONE;
242
243	if (ks->base.port != PORT_NONE) {
244		ks->base.speed = le32_to_cpu(lif->info->status.link_speed);
245
246		if (le16_to_cpu(lif->info->status.link_status))
247			ks->base.duplex = DUPLEX_FULL;
248		else
249			ks->base.duplex = DUPLEX_UNKNOWN;
250
251		ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg);
252
253		if (idev->port_info->config.an_enable) {
254			ethtool_link_ksettings_add_link_mode(ks, advertising,
255							     Autoneg);
256			ks->base.autoneg = AUTONEG_ENABLE;
257		}
258	}
259
260	return 0;
261}
262
263static int ionic_set_link_ksettings(struct net_device *netdev,
264				    const struct ethtool_link_ksettings *ks)
265{
266	struct ionic_lif *lif = netdev_priv(netdev);
267	struct ionic *ionic = lif->ionic;
268	struct ionic_dev *idev;
269	int err = 0;
270
271	idev = &lif->ionic->idev;
272
273	/* set autoneg */
274	if (ks->base.autoneg != idev->port_info->config.an_enable) {
275		mutex_lock(&ionic->dev_cmd_lock);
276		ionic_dev_cmd_port_autoneg(idev, ks->base.autoneg);
277		err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
278		mutex_unlock(&ionic->dev_cmd_lock);
279		if (err)
280			return err;
281	}
282
283	/* set speed */
284	if (ks->base.speed != le32_to_cpu(idev->port_info->config.speed)) {
285		mutex_lock(&ionic->dev_cmd_lock);
286		ionic_dev_cmd_port_speed(idev, ks->base.speed);
287		err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
288		mutex_unlock(&ionic->dev_cmd_lock);
289		if (err)
290			return err;
291	}
292
293	return 0;
294}
295
296static void ionic_get_pauseparam(struct net_device *netdev,
297				 struct ethtool_pauseparam *pause)
298{
299	struct ionic_lif *lif = netdev_priv(netdev);
300	u8 pause_type;
301
302	pause->autoneg = 0;
303
304	pause_type = lif->ionic->idev.port_info->config.pause_type;
305	if (pause_type) {
306		pause->rx_pause = (pause_type & IONIC_PAUSE_F_RX) ? 1 : 0;
307		pause->tx_pause = (pause_type & IONIC_PAUSE_F_TX) ? 1 : 0;
308	}
309}
310
311static int ionic_set_pauseparam(struct net_device *netdev,
312				struct ethtool_pauseparam *pause)
313{
314	struct ionic_lif *lif = netdev_priv(netdev);
315	struct ionic *ionic = lif->ionic;
316	u32 requested_pause;
317	int err;
318
319	if (pause->autoneg)
320		return -EOPNOTSUPP;
321
322	/* change both at the same time */
323	requested_pause = IONIC_PORT_PAUSE_TYPE_LINK;
324	if (pause->rx_pause)
325		requested_pause |= IONIC_PAUSE_F_RX;
326	if (pause->tx_pause)
327		requested_pause |= IONIC_PAUSE_F_TX;
328
329	if (requested_pause == lif->ionic->idev.port_info->config.pause_type)
330		return 0;
331
332	mutex_lock(&ionic->dev_cmd_lock);
333	ionic_dev_cmd_port_pause(&lif->ionic->idev, requested_pause);
334	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
335	mutex_unlock(&ionic->dev_cmd_lock);
336	if (err)
337		return err;
338
339	return 0;
340}
341
342static int ionic_get_fecparam(struct net_device *netdev,
343			      struct ethtool_fecparam *fec)
344{
345	struct ionic_lif *lif = netdev_priv(netdev);
346
347	switch (lif->ionic->idev.port_info->config.fec_type) {
348	case IONIC_PORT_FEC_TYPE_NONE:
349		fec->active_fec = ETHTOOL_FEC_OFF;
350		break;
351	case IONIC_PORT_FEC_TYPE_RS:
352		fec->active_fec = ETHTOOL_FEC_RS;
353		break;
354	case IONIC_PORT_FEC_TYPE_FC:
355		fec->active_fec = ETHTOOL_FEC_BASER;
356		break;
357	}
358
359	fec->fec = ETHTOOL_FEC_OFF | ETHTOOL_FEC_RS | ETHTOOL_FEC_BASER;
360
361	return 0;
362}
363
364static int ionic_set_fecparam(struct net_device *netdev,
365			      struct ethtool_fecparam *fec)
366{
367	struct ionic_lif *lif = netdev_priv(netdev);
368	u8 fec_type;
369	int ret = 0;
370
371	if (lif->ionic->idev.port_info->config.an_enable) {
372		netdev_err(netdev, "FEC request not allowed while autoneg is enabled\n");
373		return -EINVAL;
374	}
375
376	switch (fec->fec) {
377	case ETHTOOL_FEC_NONE:
378		fec_type = IONIC_PORT_FEC_TYPE_NONE;
379		break;
380	case ETHTOOL_FEC_OFF:
381		fec_type = IONIC_PORT_FEC_TYPE_NONE;
382		break;
383	case ETHTOOL_FEC_RS:
384		fec_type = IONIC_PORT_FEC_TYPE_RS;
385		break;
386	case ETHTOOL_FEC_BASER:
387		fec_type = IONIC_PORT_FEC_TYPE_FC;
388		break;
389	case ETHTOOL_FEC_AUTO:
390	default:
391		netdev_err(netdev, "FEC request 0x%04x not supported\n",
392			   fec->fec);
393		return -EINVAL;
394	}
395
396	if (fec_type != lif->ionic->idev.port_info->config.fec_type) {
397		mutex_lock(&lif->ionic->dev_cmd_lock);
398		ionic_dev_cmd_port_fec(&lif->ionic->idev, fec_type);
399		ret = ionic_dev_cmd_wait(lif->ionic, DEVCMD_TIMEOUT);
400		mutex_unlock(&lif->ionic->dev_cmd_lock);
401	}
402
403	return ret;
404}
405
406static int ionic_get_coalesce(struct net_device *netdev,
407			      struct ethtool_coalesce *coalesce)
408{
409	struct ionic_lif *lif = netdev_priv(netdev);
410
411	coalesce->tx_coalesce_usecs = lif->tx_coalesce_usecs;
412	coalesce->rx_coalesce_usecs = lif->rx_coalesce_usecs;
413
414	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
415		coalesce->use_adaptive_tx_coalesce = test_bit(IONIC_LIF_F_TX_DIM_INTR, lif->state);
416	else
417		coalesce->use_adaptive_tx_coalesce = 0;
418
419	coalesce->use_adaptive_rx_coalesce = test_bit(IONIC_LIF_F_RX_DIM_INTR, lif->state);
420
421	return 0;
422}
423
424static int ionic_set_coalesce(struct net_device *netdev,
425			      struct ethtool_coalesce *coalesce)
426{
427	struct ionic_lif *lif = netdev_priv(netdev);
428	struct ionic_identity *ident;
429	u32 rx_coal, rx_dim;
430	u32 tx_coal, tx_dim;
431	unsigned int i;
432
433	ident = &lif->ionic->ident;
434	if (ident->dev.intr_coal_div == 0) {
435		netdev_warn(netdev, "bad HW value in dev.intr_coal_div = %d\n",
436			    ident->dev.intr_coal_div);
437		return -EIO;
438	}
439
440	/* Tx normally shares Rx interrupt, so only change Rx if not split */
441	if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state) &&
442	    (coalesce->tx_coalesce_usecs != lif->rx_coalesce_usecs ||
443	     coalesce->use_adaptive_tx_coalesce)) {
444		netdev_warn(netdev, "only rx parameters can be changed\n");
445		return -EINVAL;
446	}
447
448	/* Convert the usec request to a HW usable value.  If they asked
449	 * for non-zero and it resolved to zero, bump it up
450	 */
451	rx_coal = ionic_coal_usec_to_hw(lif->ionic, coalesce->rx_coalesce_usecs);
452	if (!rx_coal && coalesce->rx_coalesce_usecs)
453		rx_coal = 1;
454	tx_coal = ionic_coal_usec_to_hw(lif->ionic, coalesce->tx_coalesce_usecs);
455	if (!tx_coal && coalesce->tx_coalesce_usecs)
456		tx_coal = 1;
457
458	if (rx_coal > IONIC_INTR_CTRL_COAL_MAX ||
459	    tx_coal > IONIC_INTR_CTRL_COAL_MAX)
460		return -ERANGE;
461
462	/* Save the new values */
463	lif->rx_coalesce_usecs = coalesce->rx_coalesce_usecs;
464	lif->rx_coalesce_hw = rx_coal;
465
466	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
467		lif->tx_coalesce_usecs = coalesce->tx_coalesce_usecs;
468	else
469		lif->tx_coalesce_usecs = coalesce->rx_coalesce_usecs;
470	lif->tx_coalesce_hw = tx_coal;
471
472	if (coalesce->use_adaptive_rx_coalesce) {
473		set_bit(IONIC_LIF_F_RX_DIM_INTR, lif->state);
474		rx_dim = rx_coal;
475	} else {
476		clear_bit(IONIC_LIF_F_RX_DIM_INTR, lif->state);
477		rx_dim = 0;
478	}
479
480	if (coalesce->use_adaptive_tx_coalesce) {
481		set_bit(IONIC_LIF_F_TX_DIM_INTR, lif->state);
482		tx_dim = tx_coal;
483	} else {
484		clear_bit(IONIC_LIF_F_TX_DIM_INTR, lif->state);
485		tx_dim = 0;
486	}
487
488	if (test_bit(IONIC_LIF_F_UP, lif->state)) {
489		for (i = 0; i < lif->nxqs; i++) {
490			if (lif->rxqcqs[i]->flags & IONIC_QCQ_F_INTR) {
491				ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
492						     lif->rxqcqs[i]->intr.index,
493						     lif->rx_coalesce_hw);
494				lif->rxqcqs[i]->intr.dim_coal_hw = rx_dim;
495			}
496
497			if (lif->txqcqs[i]->flags & IONIC_QCQ_F_INTR) {
498				ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
499						     lif->txqcqs[i]->intr.index,
500						     lif->tx_coalesce_hw);
501				lif->txqcqs[i]->intr.dim_coal_hw = tx_dim;
502			}
503		}
504	}
505
506	return 0;
507}
508
509static void ionic_get_ringparam(struct net_device *netdev,
510				struct ethtool_ringparam *ring)
511{
512	struct ionic_lif *lif = netdev_priv(netdev);
513
514	ring->tx_max_pending = IONIC_MAX_TX_DESC;
515	ring->tx_pending = lif->ntxq_descs;
516	ring->rx_max_pending = IONIC_MAX_RX_DESC;
517	ring->rx_pending = lif->nrxq_descs;
518}
519
520static int ionic_set_ringparam(struct net_device *netdev,
521			       struct ethtool_ringparam *ring)
522{
523	struct ionic_lif *lif = netdev_priv(netdev);
524	struct ionic_queue_params qparam;
525	int err;
526
527	ionic_init_queue_params(lif, &qparam);
528
529	if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
530		netdev_info(netdev, "Changing jumbo or mini descriptors not supported\n");
531		return -EINVAL;
532	}
533
534	if (!is_power_of_2(ring->tx_pending) ||
535	    !is_power_of_2(ring->rx_pending)) {
536		netdev_info(netdev, "Descriptor count must be a power of 2\n");
537		return -EINVAL;
538	}
539
540	/* if nothing to do return success */
541	if (ring->tx_pending == lif->ntxq_descs &&
542	    ring->rx_pending == lif->nrxq_descs)
543		return 0;
544
545	if (ring->tx_pending != lif->ntxq_descs)
546		netdev_info(netdev, "Changing Tx ring size from %d to %d\n",
547			    lif->ntxq_descs, ring->tx_pending);
548
549	if (ring->rx_pending != lif->nrxq_descs)
550		netdev_info(netdev, "Changing Rx ring size from %d to %d\n",
551			    lif->nrxq_descs, ring->rx_pending);
552
553	/* if we're not running, just set the values and return */
554	if (!netif_running(lif->netdev)) {
555		lif->ntxq_descs = ring->tx_pending;
556		lif->nrxq_descs = ring->rx_pending;
557		return 0;
558	}
559
560	qparam.ntxq_descs = ring->tx_pending;
561	qparam.nrxq_descs = ring->rx_pending;
562	err = ionic_reconfigure_queues(lif, &qparam);
563	if (err)
564		netdev_info(netdev, "Ring reconfiguration failed, changes canceled: %d\n", err);
565
566	return err;
567}
568
569static void ionic_get_channels(struct net_device *netdev,
570			       struct ethtool_channels *ch)
571{
572	struct ionic_lif *lif = netdev_priv(netdev);
573
574	/* report maximum channels */
575	ch->max_combined = lif->ionic->ntxqs_per_lif;
576	ch->max_rx = lif->ionic->ntxqs_per_lif / 2;
577	ch->max_tx = lif->ionic->ntxqs_per_lif / 2;
578
579	/* report current channels */
580	if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
581		ch->rx_count = lif->nxqs;
582		ch->tx_count = lif->nxqs;
583	} else {
584		ch->combined_count = lif->nxqs;
585	}
586}
587
588static int ionic_set_channels(struct net_device *netdev,
589			      struct ethtool_channels *ch)
590{
591	struct ionic_lif *lif = netdev_priv(netdev);
592	struct ionic_queue_params qparam;
593	int max_cnt;
594	int err;
595
596	ionic_init_queue_params(lif, &qparam);
597
598	if (ch->rx_count != ch->tx_count) {
599		netdev_info(netdev, "The rx and tx count must be equal\n");
600		return -EINVAL;
601	}
602
603	if (ch->combined_count && ch->rx_count) {
604		netdev_info(netdev, "Use either combined or rx and tx, not both\n");
605		return -EINVAL;
606	}
607
608	max_cnt = lif->ionic->ntxqs_per_lif;
609	if (ch->combined_count) {
610		if (ch->combined_count > max_cnt)
611			return -EINVAL;
612
613		if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
614			netdev_info(lif->netdev, "Sharing queue interrupts\n");
615		else if (ch->combined_count == lif->nxqs)
616			return 0;
617
618		if (lif->nxqs != ch->combined_count)
619			netdev_info(netdev, "Changing queue count from %d to %d\n",
620				    lif->nxqs, ch->combined_count);
621
622		qparam.nxqs = ch->combined_count;
623		qparam.intr_split = 0;
624	} else {
625		max_cnt /= 2;
626		if (ch->rx_count > max_cnt)
627			return -EINVAL;
628
629		if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
630			netdev_info(lif->netdev, "Splitting queue interrupts\n");
631		else if (ch->rx_count == lif->nxqs)
632			return 0;
633
634		if (lif->nxqs != ch->rx_count)
635			netdev_info(netdev, "Changing queue count from %d to %d\n",
636				    lif->nxqs, ch->rx_count);
637
638		qparam.nxqs = ch->rx_count;
639		qparam.intr_split = 1;
640	}
641
642	/* if we're not running, just set the values and return */
643	if (!netif_running(lif->netdev)) {
644		lif->nxqs = qparam.nxqs;
645
646		if (qparam.intr_split) {
647			set_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
648		} else {
649			clear_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
650			lif->tx_coalesce_usecs = lif->rx_coalesce_usecs;
651			lif->tx_coalesce_hw = lif->rx_coalesce_hw;
652		}
653		return 0;
654	}
655
656	err = ionic_reconfigure_queues(lif, &qparam);
657	if (err)
658		netdev_info(netdev, "Queue reconfiguration failed, changes canceled: %d\n", err);
659
660	return err;
661}
662
663static u32 ionic_get_priv_flags(struct net_device *netdev)
664{
665	struct ionic_lif *lif = netdev_priv(netdev);
666	u32 priv_flags = 0;
667
668	if (test_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state))
669		priv_flags |= IONIC_PRIV_F_SW_DBG_STATS;
670
671	return priv_flags;
672}
673
674static int ionic_set_priv_flags(struct net_device *netdev, u32 priv_flags)
675{
676	struct ionic_lif *lif = netdev_priv(netdev);
677
678	clear_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state);
679	if (priv_flags & IONIC_PRIV_F_SW_DBG_STATS)
680		set_bit(IONIC_LIF_F_SW_DEBUG_STATS, lif->state);
681
682	return 0;
683}
684
685static int ionic_get_rxnfc(struct net_device *netdev,
686			   struct ethtool_rxnfc *info, u32 *rules)
687{
688	struct ionic_lif *lif = netdev_priv(netdev);
689	int err = 0;
690
691	switch (info->cmd) {
692	case ETHTOOL_GRXRINGS:
693		info->data = lif->nxqs;
694		break;
695	default:
696		netdev_dbg(netdev, "Command parameter %d is not supported\n",
697			   info->cmd);
698		err = -EOPNOTSUPP;
699	}
700
701	return err;
702}
703
704static u32 ionic_get_rxfh_indir_size(struct net_device *netdev)
705{
706	struct ionic_lif *lif = netdev_priv(netdev);
707
708	return le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz);
709}
710
711static u32 ionic_get_rxfh_key_size(struct net_device *netdev)
712{
713	return IONIC_RSS_HASH_KEY_SIZE;
714}
715
716static int ionic_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
717			  u8 *hfunc)
718{
719	struct ionic_lif *lif = netdev_priv(netdev);
720	unsigned int i, tbl_sz;
721
722	if (indir) {
723		tbl_sz = le16_to_cpu(lif->ionic->ident.lif.eth.rss_ind_tbl_sz);
724		for (i = 0; i < tbl_sz; i++)
725			indir[i] = lif->rss_ind_tbl[i];
726	}
727
728	if (key)
729		memcpy(key, lif->rss_hash_key, IONIC_RSS_HASH_KEY_SIZE);
730
731	if (hfunc)
732		*hfunc = ETH_RSS_HASH_TOP;
733
734	return 0;
735}
736
737static int ionic_set_rxfh(struct net_device *netdev, const u32 *indir,
738			  const u8 *key, const u8 hfunc)
739{
740	struct ionic_lif *lif = netdev_priv(netdev);
741	int err;
742
743	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
744		return -EOPNOTSUPP;
745
746	err = ionic_lif_rss_config(lif, lif->rss_types, key, indir);
747	if (err)
748		return err;
749
750	return 0;
751}
752
753static int ionic_set_tunable(struct net_device *dev,
754			     const struct ethtool_tunable *tuna,
755			     const void *data)
756{
757	struct ionic_lif *lif = netdev_priv(dev);
758
759	switch (tuna->id) {
760	case ETHTOOL_RX_COPYBREAK:
761		lif->rx_copybreak = *(u32 *)data;
762		break;
763	default:
764		return -EOPNOTSUPP;
765	}
766
767	return 0;
768}
769
770static int ionic_get_tunable(struct net_device *netdev,
771			     const struct ethtool_tunable *tuna, void *data)
772{
773	struct ionic_lif *lif = netdev_priv(netdev);
774
775	switch (tuna->id) {
776	case ETHTOOL_RX_COPYBREAK:
777		*(u32 *)data = lif->rx_copybreak;
778		break;
779	default:
780		return -EOPNOTSUPP;
781	}
782
783	return 0;
784}
785
786static int ionic_get_module_info(struct net_device *netdev,
787				 struct ethtool_modinfo *modinfo)
788
789{
790	struct ionic_lif *lif = netdev_priv(netdev);
791	struct ionic_dev *idev = &lif->ionic->idev;
792	struct ionic_xcvr_status *xcvr;
793	struct sfp_eeprom_base *sfp;
794
795	xcvr = &idev->port_info->status.xcvr;
796	sfp = (struct sfp_eeprom_base *) xcvr->sprom;
797
798	/* report the module data type and length */
799	switch (sfp->phys_id) {
800	case SFF8024_ID_SFP:
801		modinfo->type = ETH_MODULE_SFF_8079;
802		modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
803		break;
804	case SFF8024_ID_QSFP_8436_8636:
805	case SFF8024_ID_QSFP28_8636:
806		modinfo->type = ETH_MODULE_SFF_8436;
807		modinfo->eeprom_len = ETH_MODULE_SFF_8436_LEN;
808		break;
809	default:
810		netdev_info(netdev, "unknown xcvr type 0x%02x\n",
811			    xcvr->sprom[0]);
812		modinfo->type = 0;
813		modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN;
814		break;
815	}
816
817	return 0;
818}
819
820static int ionic_get_module_eeprom(struct net_device *netdev,
821				   struct ethtool_eeprom *ee,
822				   u8 *data)
823{
824	struct ionic_lif *lif = netdev_priv(netdev);
825	struct ionic_dev *idev = &lif->ionic->idev;
826	struct ionic_xcvr_status *xcvr;
827	char tbuf[sizeof(xcvr->sprom)];
828	int count = 10;
829	u32 len;
830
831	/* The NIC keeps the module prom up-to-date in the DMA space
832	 * so we can simply copy the module bytes into the data buffer.
833	 */
834	xcvr = &idev->port_info->status.xcvr;
835	len = min_t(u32, sizeof(xcvr->sprom), ee->len);
836
837	do {
838		memcpy(data, xcvr->sprom, len);
839		memcpy(tbuf, xcvr->sprom, len);
840
841		/* Let's make sure we got a consistent copy */
842		if (!memcmp(data, tbuf, len))
843			break;
844
845	} while (--count);
846
847	if (!count)
848		return -ETIMEDOUT;
849
850	return 0;
851}
852
853static int ionic_nway_reset(struct net_device *netdev)
854{
855	struct ionic_lif *lif = netdev_priv(netdev);
856	struct ionic *ionic = lif->ionic;
857	int err = 0;
858
859	/* flap the link to force auto-negotiation */
860
861	mutex_lock(&ionic->dev_cmd_lock);
862
863	ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_DOWN);
864	err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
865
866	if (!err) {
867		ionic_dev_cmd_port_state(&ionic->idev, IONIC_PORT_ADMIN_STATE_UP);
868		err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
869	}
870
871	mutex_unlock(&ionic->dev_cmd_lock);
872
873	return err;
874}
875
876static const struct ethtool_ops ionic_ethtool_ops = {
877	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
878				     ETHTOOL_COALESCE_USE_ADAPTIVE_RX |
879				     ETHTOOL_COALESCE_USE_ADAPTIVE_TX,
880	.get_drvinfo		= ionic_get_drvinfo,
881	.get_regs_len		= ionic_get_regs_len,
882	.get_regs		= ionic_get_regs,
883	.get_link		= ethtool_op_get_link,
884	.get_link_ksettings	= ionic_get_link_ksettings,
885	.set_link_ksettings	= ionic_set_link_ksettings,
886	.get_coalesce		= ionic_get_coalesce,
887	.set_coalesce		= ionic_set_coalesce,
888	.get_ringparam		= ionic_get_ringparam,
889	.set_ringparam		= ionic_set_ringparam,
890	.get_channels		= ionic_get_channels,
891	.set_channels		= ionic_set_channels,
892	.get_strings		= ionic_get_strings,
893	.get_ethtool_stats	= ionic_get_stats,
894	.get_sset_count		= ionic_get_sset_count,
895	.get_priv_flags		= ionic_get_priv_flags,
896	.set_priv_flags		= ionic_set_priv_flags,
897	.get_rxnfc		= ionic_get_rxnfc,
898	.get_rxfh_indir_size	= ionic_get_rxfh_indir_size,
899	.get_rxfh_key_size	= ionic_get_rxfh_key_size,
900	.get_rxfh		= ionic_get_rxfh,
901	.set_rxfh		= ionic_set_rxfh,
902	.get_tunable		= ionic_get_tunable,
903	.set_tunable		= ionic_set_tunable,
904	.get_module_info	= ionic_get_module_info,
905	.get_module_eeprom	= ionic_get_module_eeprom,
906	.get_pauseparam		= ionic_get_pauseparam,
907	.set_pauseparam		= ionic_set_pauseparam,
908	.get_fecparam		= ionic_get_fecparam,
909	.set_fecparam		= ionic_set_fecparam,
910	.nway_reset		= ionic_nway_reset,
911};
912
913void ionic_ethtool_set_ops(struct net_device *netdev)
914{
915	netdev->ethtool_ops = &ionic_ethtool_ops;
916}
917