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
14 static 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
ionic_get_stats_strings(struct ionic_lif * lif,u8 * buf)21 static 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
ionic_get_stats(struct net_device * netdev,struct ethtool_stats * stats,u64 * buf)29 static 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
ionic_get_stats_count(struct ionic_lif * lif)42 static 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
ionic_get_sset_count(struct net_device * netdev,int sset)52 static 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
ionic_get_strings(struct net_device * netdev,u32 sset,u8 * buf)68 static 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
ionic_get_drvinfo(struct net_device * netdev,struct ethtool_drvinfo * drvinfo)84 static 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
ionic_get_regs_len(struct net_device * netdev)97 static 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
ionic_get_regs(struct net_device * netdev,struct ethtool_regs * regs,void * p)102 static 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
ionic_get_link_ksettings(struct net_device * netdev,struct ethtool_link_ksettings * ks)120 static 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
ionic_set_link_ksettings(struct net_device * netdev,const struct ethtool_link_ksettings * ks)263 static 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
ionic_get_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)296 static 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
ionic_set_pauseparam(struct net_device * netdev,struct ethtool_pauseparam * pause)311 static 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
ionic_get_fecparam(struct net_device * netdev,struct ethtool_fecparam * fec)342 static 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
ionic_set_fecparam(struct net_device * netdev,struct ethtool_fecparam * fec)364 static 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
ionic_get_coalesce(struct net_device * netdev,struct ethtool_coalesce * coalesce)406 static 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
ionic_set_coalesce(struct net_device * netdev,struct ethtool_coalesce * coalesce)424 static 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
ionic_get_ringparam(struct net_device * netdev,struct ethtool_ringparam * ring)509 static 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
ionic_set_ringparam(struct net_device * netdev,struct ethtool_ringparam * ring)520 static 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
ionic_get_channels(struct net_device * netdev,struct ethtool_channels * ch)569 static 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
ionic_set_channels(struct net_device * netdev,struct ethtool_channels * ch)588 static 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
ionic_get_priv_flags(struct net_device * netdev)663 static 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
ionic_set_priv_flags(struct net_device * netdev,u32 priv_flags)674 static 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
ionic_get_rxnfc(struct net_device * netdev,struct ethtool_rxnfc * info,u32 * rules)685 static 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_err(netdev, "Command parameter %d is not supported\n",
697 info->cmd);
698 err = -EOPNOTSUPP;
699 }
700
701 return err;
702 }
703
ionic_get_rxfh_indir_size(struct net_device * netdev)704 static 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
ionic_get_rxfh_key_size(struct net_device * netdev)711 static u32 ionic_get_rxfh_key_size(struct net_device *netdev)
712 {
713 return IONIC_RSS_HASH_KEY_SIZE;
714 }
715
ionic_get_rxfh(struct net_device * netdev,u32 * indir,u8 * key,u8 * hfunc)716 static 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
ionic_set_rxfh(struct net_device * netdev,const u32 * indir,const u8 * key,const u8 hfunc)737 static 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
ionic_set_tunable(struct net_device * dev,const struct ethtool_tunable * tuna,const void * data)753 static 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
ionic_get_tunable(struct net_device * netdev,const struct ethtool_tunable * tuna,void * data)770 static 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
ionic_get_module_info(struct net_device * netdev,struct ethtool_modinfo * modinfo)786 static 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
ionic_get_module_eeprom(struct net_device * netdev,struct ethtool_eeprom * ee,u8 * data)820 static 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
ionic_nway_reset(struct net_device * netdev)853 static 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
876 static 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
ionic_ethtool_set_ops(struct net_device * netdev)913 void ionic_ethtool_set_ops(struct net_device *netdev)
914 {
915 netdev->ethtool_ops = &ionic_ethtool_ops;
916 }
917