1 // SPDX-License-Identifier: GPL-2.0-only
3 * aQuantia Corporation Network Driver
4 * Copyright (C) 2014-2019 aQuantia Corporation. All rights reserved
7 /* File aq_ethtool.c: Definition of ethertool related functions. */
9 #include "aq_ethtool.h"
13 #include "aq_filters.h"
15 #include <linux/ptp_clock_kernel.h>
17 static void aq_ethtool_get_regs(struct net_device *ndev,
18 struct ethtool_regs *regs, void *p)
20 struct aq_nic_s *aq_nic = netdev_priv(ndev);
21 u32 regs_count = aq_nic_get_regs_count(aq_nic);
23 memset(p, 0, regs_count * sizeof(u32));
24 aq_nic_get_regs(aq_nic, regs, p);
27 static int aq_ethtool_get_regs_len(struct net_device *ndev)
29 struct aq_nic_s *aq_nic = netdev_priv(ndev);
30 u32 regs_count = aq_nic_get_regs_count(aq_nic);
32 return regs_count * sizeof(u32);
35 static u32 aq_ethtool_get_link(struct net_device *ndev)
37 return ethtool_op_get_link(ndev);
40 static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
41 struct ethtool_link_ksettings *cmd)
43 struct aq_nic_s *aq_nic = netdev_priv(ndev);
45 aq_nic_get_link_ksettings(aq_nic, cmd);
46 cmd->base.speed = netif_carrier_ok(ndev) ?
47 aq_nic_get_link_speed(aq_nic) : 0U;
53 aq_ethtool_set_link_ksettings(struct net_device *ndev,
54 const struct ethtool_link_ksettings *cmd)
56 struct aq_nic_s *aq_nic = netdev_priv(ndev);
58 return aq_nic_set_link_ksettings(aq_nic, cmd);
61 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
86 static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
87 "Queue[%d] InPackets",
88 "Queue[%d] OutPackets",
90 "Queue[%d] InJumboPackets",
91 "Queue[%d] InLroPackets",
95 static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
99 "PHYInternalLoopback",
100 "PHYExternalLoopback",
103 static void aq_ethtool_stats(struct net_device *ndev,
104 struct ethtool_stats *stats, u64 *data)
106 struct aq_nic_s *aq_nic = netdev_priv(ndev);
107 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
109 memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
110 ARRAY_SIZE(aq_ethtool_queue_stat_names) *
111 cfg->vecs) * sizeof(u64));
112 aq_nic_get_stats(aq_nic, data);
115 static void aq_ethtool_get_drvinfo(struct net_device *ndev,
116 struct ethtool_drvinfo *drvinfo)
118 struct aq_nic_s *aq_nic = netdev_priv(ndev);
119 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
120 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
121 u32 firmware_version = aq_nic_get_fw_version(aq_nic);
122 u32 regs_count = aq_nic_get_regs_count(aq_nic);
124 strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
125 strlcat(drvinfo->version, AQ_CFG_DRV_VERSION, sizeof(drvinfo->version));
127 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
128 "%u.%u.%u", firmware_version >> 24,
129 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
131 strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
132 sizeof(drvinfo->bus_info));
133 drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
134 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
135 drvinfo->testinfo_len = 0;
136 drvinfo->regdump_len = regs_count;
137 drvinfo->eedump_len = 0;
140 static void aq_ethtool_get_strings(struct net_device *ndev,
141 u32 stringset, u8 *data)
144 struct aq_nic_s *aq_nic = netdev_priv(ndev);
145 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
150 memcpy(p, aq_ethtool_stat_names,
151 sizeof(aq_ethtool_stat_names));
152 p = p + sizeof(aq_ethtool_stat_names);
153 for (i = 0; i < cfg->vecs; i++) {
155 si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
157 snprintf(p, ETH_GSTRING_LEN,
158 aq_ethtool_queue_stat_names[si], i);
159 p += ETH_GSTRING_LEN;
163 case ETH_SS_PRIV_FLAGS:
164 memcpy(p, aq_ethtool_priv_flag_names,
165 sizeof(aq_ethtool_priv_flag_names));
170 static int aq_ethtool_set_phys_id(struct net_device *ndev,
171 enum ethtool_phys_id_state state)
173 struct aq_nic_s *aq_nic = netdev_priv(ndev);
174 struct aq_hw_s *hw = aq_nic->aq_hw;
177 if (!aq_nic->aq_fw_ops->led_control)
180 mutex_lock(&aq_nic->fwreq_mutex);
183 case ETHTOOL_ID_ACTIVE:
184 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
185 AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
187 case ETHTOOL_ID_INACTIVE:
188 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
194 mutex_unlock(&aq_nic->fwreq_mutex);
199 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
202 struct aq_nic_s *aq_nic = netdev_priv(ndev);
203 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
207 ret = ARRAY_SIZE(aq_ethtool_stat_names) +
208 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
210 case ETH_SS_PRIV_FLAGS:
211 ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
219 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
221 return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
224 static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
226 struct aq_nic_s *aq_nic = netdev_priv(ndev);
227 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
229 return sizeof(cfg->aq_rss.hash_secret_key);
232 static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
235 struct aq_nic_s *aq_nic = netdev_priv(ndev);
236 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
240 *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
242 for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
243 indir[i] = cfg->aq_rss.indirection_table[i];
246 memcpy(key, cfg->aq_rss.hash_secret_key,
247 sizeof(cfg->aq_rss.hash_secret_key));
251 static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
252 const u8 *key, const u8 hfunc)
254 struct aq_nic_s *aq_nic = netdev_priv(netdev);
255 struct aq_nic_cfg_s *cfg;
260 cfg = aq_nic_get_cfg(aq_nic);
261 rss_entries = cfg->aq_rss.indirection_table_size;
263 /* We do not allow change in unsupported parameters */
264 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
266 /* Fill out the redirection table */
268 for (i = 0; i < rss_entries; i++)
269 cfg->aq_rss.indirection_table[i] = indir[i];
271 /* Fill out the rss hash key */
273 memcpy(cfg->aq_rss.hash_secret_key, key,
274 sizeof(cfg->aq_rss.hash_secret_key));
275 err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
281 err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
286 static int aq_ethtool_get_rxnfc(struct net_device *ndev,
287 struct ethtool_rxnfc *cmd,
290 struct aq_nic_s *aq_nic = netdev_priv(ndev);
291 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
295 case ETHTOOL_GRXRINGS:
296 cmd->data = cfg->vecs;
298 case ETHTOOL_GRXCLSRLCNT:
299 cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
301 case ETHTOOL_GRXCLSRULE:
302 err = aq_get_rxnfc_rule(aq_nic, cmd);
304 case ETHTOOL_GRXCLSRLALL:
305 err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
315 static int aq_ethtool_set_rxnfc(struct net_device *ndev,
316 struct ethtool_rxnfc *cmd)
319 struct aq_nic_s *aq_nic = netdev_priv(ndev);
322 case ETHTOOL_SRXCLSRLINS:
323 err = aq_add_rxnfc_rule(aq_nic, cmd);
325 case ETHTOOL_SRXCLSRLDEL:
326 err = aq_del_rxnfc_rule(aq_nic, cmd);
336 static int aq_ethtool_get_coalesce(struct net_device *ndev,
337 struct ethtool_coalesce *coal)
339 struct aq_nic_s *aq_nic = netdev_priv(ndev);
340 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
342 if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
343 cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
344 coal->rx_coalesce_usecs = cfg->rx_itr;
345 coal->tx_coalesce_usecs = cfg->tx_itr;
346 coal->rx_max_coalesced_frames = 0;
347 coal->tx_max_coalesced_frames = 0;
349 coal->rx_coalesce_usecs = 0;
350 coal->tx_coalesce_usecs = 0;
351 coal->rx_max_coalesced_frames = 1;
352 coal->tx_max_coalesced_frames = 1;
357 static int aq_ethtool_set_coalesce(struct net_device *ndev,
358 struct ethtool_coalesce *coal)
360 struct aq_nic_s *aq_nic = netdev_priv(ndev);
361 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
363 /* This is not yet supported
365 if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce)
368 /* Atlantic only supports timing based coalescing
370 if (coal->rx_max_coalesced_frames > 1 ||
371 coal->rx_coalesce_usecs_irq ||
372 coal->rx_max_coalesced_frames_irq)
375 if (coal->tx_max_coalesced_frames > 1 ||
376 coal->tx_coalesce_usecs_irq ||
377 coal->tx_max_coalesced_frames_irq)
380 /* We do not support frame counting. Check this
382 if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
384 if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
387 if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
388 coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
391 cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
393 cfg->rx_itr = coal->rx_coalesce_usecs;
394 cfg->tx_itr = coal->tx_coalesce_usecs;
396 return aq_nic_update_interrupt_moderation_settings(aq_nic);
399 static void aq_ethtool_get_wol(struct net_device *ndev,
400 struct ethtool_wolinfo *wol)
402 struct aq_nic_s *aq_nic = netdev_priv(ndev);
403 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
405 wol->supported = AQ_NIC_WOL_MODES;
406 wol->wolopts = cfg->wol;
409 static int aq_ethtool_set_wol(struct net_device *ndev,
410 struct ethtool_wolinfo *wol)
412 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
413 struct aq_nic_s *aq_nic = netdev_priv(ndev);
414 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
417 if (wol->wolopts & ~AQ_NIC_WOL_MODES)
420 cfg->wol = wol->wolopts;
422 err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
427 static int aq_ethtool_get_ts_info(struct net_device *ndev,
428 struct ethtool_ts_info *info)
430 struct aq_nic_s *aq_nic = netdev_priv(ndev);
432 ethtool_op_get_ts_info(ndev, info);
437 info->so_timestamping |=
438 SOF_TIMESTAMPING_TX_HARDWARE |
439 SOF_TIMESTAMPING_RX_HARDWARE |
440 SOF_TIMESTAMPING_RAW_HARDWARE;
442 info->tx_types = BIT(HWTSTAMP_TX_OFF) |
445 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
447 info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
448 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
449 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
451 info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
456 static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
460 if (speed & AQ_NIC_RATE_EEE_10G)
461 rate |= SUPPORTED_10000baseT_Full;
463 if (speed & AQ_NIC_RATE_EEE_2GS)
464 rate |= SUPPORTED_2500baseX_Full;
466 if (speed & AQ_NIC_RATE_EEE_1G)
467 rate |= SUPPORTED_1000baseT_Full;
472 static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
474 struct aq_nic_s *aq_nic = netdev_priv(ndev);
475 u32 rate, supported_rates;
478 if (!aq_nic->aq_fw_ops->get_eee_rate)
481 mutex_lock(&aq_nic->fwreq_mutex);
482 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
484 mutex_unlock(&aq_nic->fwreq_mutex);
488 eee->supported = eee_mask_to_ethtool_mask(supported_rates);
490 if (aq_nic->aq_nic_cfg.eee_speeds)
491 eee->advertised = eee->supported;
493 eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
495 eee->eee_enabled = !!eee->advertised;
497 eee->tx_lpi_enabled = eee->eee_enabled;
498 if (eee->advertised & eee->lp_advertised)
499 eee->eee_active = true;
504 static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
506 struct aq_nic_s *aq_nic = netdev_priv(ndev);
507 u32 rate, supported_rates;
508 struct aq_nic_cfg_s *cfg;
511 cfg = aq_nic_get_cfg(aq_nic);
513 if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
514 !aq_nic->aq_fw_ops->set_eee_rate))
517 mutex_lock(&aq_nic->fwreq_mutex);
518 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
520 mutex_unlock(&aq_nic->fwreq_mutex);
524 if (eee->eee_enabled) {
525 rate = supported_rates;
526 cfg->eee_speeds = rate;
532 mutex_lock(&aq_nic->fwreq_mutex);
533 err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
534 mutex_unlock(&aq_nic->fwreq_mutex);
539 static int aq_ethtool_nway_reset(struct net_device *ndev)
541 struct aq_nic_s *aq_nic = netdev_priv(ndev);
544 if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
547 if (netif_running(ndev)) {
548 mutex_lock(&aq_nic->fwreq_mutex);
549 err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
550 mutex_unlock(&aq_nic->fwreq_mutex);
556 static void aq_ethtool_get_pauseparam(struct net_device *ndev,
557 struct ethtool_pauseparam *pause)
559 struct aq_nic_s *aq_nic = netdev_priv(ndev);
560 u32 fc = aq_nic->aq_nic_cfg.flow_control;
564 pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
565 pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
569 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
570 struct ethtool_pauseparam *pause)
572 struct aq_nic_s *aq_nic = netdev_priv(ndev);
575 if (!aq_nic->aq_fw_ops->set_flow_control)
578 if (pause->autoneg == AUTONEG_ENABLE)
582 aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_RX;
584 aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_RX;
587 aq_nic->aq_hw->aq_nic_cfg->flow_control |= AQ_NIC_FC_TX;
589 aq_nic->aq_hw->aq_nic_cfg->flow_control &= ~AQ_NIC_FC_TX;
591 mutex_lock(&aq_nic->fwreq_mutex);
592 err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
593 mutex_unlock(&aq_nic->fwreq_mutex);
598 static void aq_get_ringparam(struct net_device *ndev,
599 struct ethtool_ringparam *ring)
601 struct aq_nic_s *aq_nic = netdev_priv(ndev);
602 struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
604 ring->rx_pending = aq_nic_cfg->rxds;
605 ring->tx_pending = aq_nic_cfg->txds;
607 ring->rx_max_pending = aq_nic_cfg->aq_hw_caps->rxds_max;
608 ring->tx_max_pending = aq_nic_cfg->aq_hw_caps->txds_max;
611 static int aq_set_ringparam(struct net_device *ndev,
612 struct ethtool_ringparam *ring)
615 bool ndev_running = false;
616 struct aq_nic_s *aq_nic = netdev_priv(ndev);
617 struct aq_nic_cfg_s *aq_nic_cfg = aq_nic_get_cfg(aq_nic);
618 const struct aq_hw_caps_s *hw_caps = aq_nic_cfg->aq_hw_caps;
620 if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
625 if (netif_running(ndev)) {
630 aq_nic_free_vectors(aq_nic);
632 aq_nic_cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
633 aq_nic_cfg->rxds = min(aq_nic_cfg->rxds, hw_caps->rxds_max);
634 aq_nic_cfg->rxds = ALIGN(aq_nic_cfg->rxds, AQ_HW_RXD_MULTIPLE);
636 aq_nic_cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
637 aq_nic_cfg->txds = min(aq_nic_cfg->txds, hw_caps->txds_max);
638 aq_nic_cfg->txds = ALIGN(aq_nic_cfg->txds, AQ_HW_TXD_MULTIPLE);
640 for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < aq_nic_cfg->vecs;
642 aq_nic->aq_vec[aq_nic->aq_vecs] =
643 aq_vec_alloc(aq_nic, aq_nic->aq_vecs, aq_nic_cfg);
644 if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) {
650 err = dev_open(ndev, NULL);
656 static u32 aq_get_msg_level(struct net_device *ndev)
658 struct aq_nic_s *aq_nic = netdev_priv(ndev);
660 return aq_nic->msg_enable;
663 static void aq_set_msg_level(struct net_device *ndev, u32 data)
665 struct aq_nic_s *aq_nic = netdev_priv(ndev);
667 aq_nic->msg_enable = data;
670 u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
672 struct aq_nic_s *aq_nic = netdev_priv(ndev);
674 return aq_nic->aq_nic_cfg.priv_flags;
677 int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
679 struct aq_nic_s *aq_nic = netdev_priv(ndev);
680 struct aq_nic_cfg_s *cfg;
683 cfg = aq_nic_get_cfg(aq_nic);
684 priv_flags = cfg->priv_flags;
686 if (flags & ~AQ_PRIV_FLAGS_MASK)
689 cfg->priv_flags = flags;
691 if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
692 if (netif_running(ndev)) {
695 dev_open(ndev, NULL);
697 } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
698 aq_nic_set_loopback(aq_nic);
704 const struct ethtool_ops aq_ethtool_ops = {
705 .get_link = aq_ethtool_get_link,
706 .get_regs_len = aq_ethtool_get_regs_len,
707 .get_regs = aq_ethtool_get_regs,
708 .get_drvinfo = aq_ethtool_get_drvinfo,
709 .get_strings = aq_ethtool_get_strings,
710 .set_phys_id = aq_ethtool_set_phys_id,
711 .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
712 .get_wol = aq_ethtool_get_wol,
713 .set_wol = aq_ethtool_set_wol,
714 .nway_reset = aq_ethtool_nway_reset,
715 .get_ringparam = aq_get_ringparam,
716 .set_ringparam = aq_set_ringparam,
717 .get_eee = aq_ethtool_get_eee,
718 .set_eee = aq_ethtool_set_eee,
719 .get_pauseparam = aq_ethtool_get_pauseparam,
720 .set_pauseparam = aq_ethtool_set_pauseparam,
721 .get_rxfh_key_size = aq_ethtool_get_rss_key_size,
722 .get_rxfh = aq_ethtool_get_rss,
723 .set_rxfh = aq_ethtool_set_rss,
724 .get_rxnfc = aq_ethtool_get_rxnfc,
725 .set_rxnfc = aq_ethtool_set_rxnfc,
726 .get_msglevel = aq_get_msg_level,
727 .set_msglevel = aq_set_msg_level,
728 .get_sset_count = aq_ethtool_get_sset_count,
729 .get_ethtool_stats = aq_ethtool_stats,
730 .get_priv_flags = aq_ethtool_get_priv_flags,
731 .set_priv_flags = aq_ethtool_set_priv_flags,
732 .get_link_ksettings = aq_ethtool_get_link_ksettings,
733 .set_link_ksettings = aq_ethtool_set_link_ksettings,
734 .get_coalesce = aq_ethtool_get_coalesce,
735 .set_coalesce = aq_ethtool_set_coalesce,
736 .get_ts_info = aq_ethtool_get_ts_info,