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);
23 regs_count = aq_nic_get_regs_count(aq_nic);
25 memset(p, 0, regs_count * sizeof(u32));
26 aq_nic_get_regs(aq_nic, regs, p);
29 static int aq_ethtool_get_regs_len(struct net_device *ndev)
31 struct aq_nic_s *aq_nic = netdev_priv(ndev);
34 regs_count = aq_nic_get_regs_count(aq_nic);
36 return regs_count * sizeof(u32);
39 static u32 aq_ethtool_get_link(struct net_device *ndev)
41 return ethtool_op_get_link(ndev);
44 static int aq_ethtool_get_link_ksettings(struct net_device *ndev,
45 struct ethtool_link_ksettings *cmd)
47 struct aq_nic_s *aq_nic = netdev_priv(ndev);
49 aq_nic_get_link_ksettings(aq_nic, cmd);
50 cmd->base.speed = netif_carrier_ok(ndev) ?
51 aq_nic_get_link_speed(aq_nic) : 0U;
57 aq_ethtool_set_link_ksettings(struct net_device *ndev,
58 const struct ethtool_link_ksettings *cmd)
60 struct aq_nic_s *aq_nic = netdev_priv(ndev);
62 return aq_nic_set_link_ksettings(aq_nic, cmd);
65 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = {
90 static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = {
91 "Queue[%d] InPackets",
92 "Queue[%d] OutPackets",
94 "Queue[%d] InJumboPackets",
95 "Queue[%d] InLroPackets",
99 static const char aq_ethtool_priv_flag_names[][ETH_GSTRING_LEN] = {
102 "DMANetworkLoopback",
103 "PHYInternalLoopback",
104 "PHYExternalLoopback",
107 static void aq_ethtool_stats(struct net_device *ndev,
108 struct ethtool_stats *stats, u64 *data)
110 struct aq_nic_s *aq_nic = netdev_priv(ndev);
111 struct aq_nic_cfg_s *cfg;
113 cfg = aq_nic_get_cfg(aq_nic);
115 memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) +
116 ARRAY_SIZE(aq_ethtool_queue_stat_names) *
117 cfg->vecs) * sizeof(u64));
118 aq_nic_get_stats(aq_nic, data);
121 static void aq_ethtool_get_drvinfo(struct net_device *ndev,
122 struct ethtool_drvinfo *drvinfo)
124 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
125 struct aq_nic_s *aq_nic = netdev_priv(ndev);
126 struct aq_nic_cfg_s *cfg;
127 u32 firmware_version;
130 cfg = aq_nic_get_cfg(aq_nic);
131 firmware_version = aq_nic_get_fw_version(aq_nic);
132 regs_count = aq_nic_get_regs_count(aq_nic);
134 strlcat(drvinfo->driver, AQ_CFG_DRV_NAME, sizeof(drvinfo->driver));
136 snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
137 "%u.%u.%u", firmware_version >> 24,
138 (firmware_version >> 16) & 0xFFU, firmware_version & 0xFFFFU);
140 strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "",
141 sizeof(drvinfo->bus_info));
142 drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
143 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
144 drvinfo->testinfo_len = 0;
145 drvinfo->regdump_len = regs_count;
146 drvinfo->eedump_len = 0;
149 static void aq_ethtool_get_strings(struct net_device *ndev,
150 u32 stringset, u8 *data)
152 struct aq_nic_s *aq_nic = netdev_priv(ndev);
153 struct aq_nic_cfg_s *cfg;
157 cfg = aq_nic_get_cfg(aq_nic);
161 memcpy(p, aq_ethtool_stat_names,
162 sizeof(aq_ethtool_stat_names));
163 p = p + sizeof(aq_ethtool_stat_names);
164 for (i = 0; i < cfg->vecs; i++) {
166 si < ARRAY_SIZE(aq_ethtool_queue_stat_names);
168 snprintf(p, ETH_GSTRING_LEN,
169 aq_ethtool_queue_stat_names[si], i);
170 p += ETH_GSTRING_LEN;
174 case ETH_SS_PRIV_FLAGS:
175 memcpy(p, aq_ethtool_priv_flag_names,
176 sizeof(aq_ethtool_priv_flag_names));
181 static int aq_ethtool_set_phys_id(struct net_device *ndev,
182 enum ethtool_phys_id_state state)
184 struct aq_nic_s *aq_nic = netdev_priv(ndev);
185 struct aq_hw_s *hw = aq_nic->aq_hw;
188 if (!aq_nic->aq_fw_ops->led_control)
191 mutex_lock(&aq_nic->fwreq_mutex);
194 case ETHTOOL_ID_ACTIVE:
195 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_BLINK |
196 AQ_HW_LED_BLINK << 2 | AQ_HW_LED_BLINK << 4);
198 case ETHTOOL_ID_INACTIVE:
199 ret = aq_nic->aq_fw_ops->led_control(hw, AQ_HW_LED_DEFAULT);
205 mutex_unlock(&aq_nic->fwreq_mutex);
210 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset)
212 struct aq_nic_s *aq_nic = netdev_priv(ndev);
213 struct aq_nic_cfg_s *cfg;
216 cfg = aq_nic_get_cfg(aq_nic);
220 ret = ARRAY_SIZE(aq_ethtool_stat_names) +
221 cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names);
223 case ETH_SS_PRIV_FLAGS:
224 ret = ARRAY_SIZE(aq_ethtool_priv_flag_names);
233 static u32 aq_ethtool_get_rss_indir_size(struct net_device *ndev)
235 return AQ_CFG_RSS_INDIRECTION_TABLE_MAX;
238 static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
240 struct aq_nic_s *aq_nic = netdev_priv(ndev);
241 struct aq_nic_cfg_s *cfg;
243 cfg = aq_nic_get_cfg(aq_nic);
245 return sizeof(cfg->aq_rss.hash_secret_key);
248 static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
251 struct aq_nic_s *aq_nic = netdev_priv(ndev);
252 struct aq_nic_cfg_s *cfg;
255 cfg = aq_nic_get_cfg(aq_nic);
258 *hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
260 for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
261 indir[i] = cfg->aq_rss.indirection_table[i];
264 memcpy(key, cfg->aq_rss.hash_secret_key,
265 sizeof(cfg->aq_rss.hash_secret_key));
270 static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
271 const u8 *key, const u8 hfunc)
273 struct aq_nic_s *aq_nic = netdev_priv(netdev);
274 struct aq_nic_cfg_s *cfg;
279 cfg = aq_nic_get_cfg(aq_nic);
280 rss_entries = cfg->aq_rss.indirection_table_size;
282 /* We do not allow change in unsupported parameters */
283 if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
285 /* Fill out the redirection table */
287 for (i = 0; i < rss_entries; i++)
288 cfg->aq_rss.indirection_table[i] = indir[i];
290 /* Fill out the rss hash key */
292 memcpy(cfg->aq_rss.hash_secret_key, key,
293 sizeof(cfg->aq_rss.hash_secret_key));
294 err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
300 err = aq_nic->aq_hw_ops->hw_rss_set(aq_nic->aq_hw, &cfg->aq_rss);
305 static int aq_ethtool_get_rxnfc(struct net_device *ndev,
306 struct ethtool_rxnfc *cmd,
309 struct aq_nic_s *aq_nic = netdev_priv(ndev);
310 struct aq_nic_cfg_s *cfg;
313 cfg = aq_nic_get_cfg(aq_nic);
316 case ETHTOOL_GRXRINGS:
317 cmd->data = cfg->vecs;
319 case ETHTOOL_GRXCLSRLCNT:
320 cmd->rule_cnt = aq_get_rxnfc_count_all_rules(aq_nic);
322 case ETHTOOL_GRXCLSRULE:
323 err = aq_get_rxnfc_rule(aq_nic, cmd);
325 case ETHTOOL_GRXCLSRLALL:
326 err = aq_get_rxnfc_all_rules(aq_nic, cmd, rule_locs);
336 static int aq_ethtool_set_rxnfc(struct net_device *ndev,
337 struct ethtool_rxnfc *cmd)
339 struct aq_nic_s *aq_nic = netdev_priv(ndev);
343 case ETHTOOL_SRXCLSRLINS:
344 err = aq_add_rxnfc_rule(aq_nic, cmd);
346 case ETHTOOL_SRXCLSRLDEL:
347 err = aq_del_rxnfc_rule(aq_nic, cmd);
357 static int aq_ethtool_get_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;
363 cfg = aq_nic_get_cfg(aq_nic);
365 if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON ||
366 cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) {
367 coal->rx_coalesce_usecs = cfg->rx_itr;
368 coal->tx_coalesce_usecs = cfg->tx_itr;
369 coal->rx_max_coalesced_frames = 0;
370 coal->tx_max_coalesced_frames = 0;
372 coal->rx_coalesce_usecs = 0;
373 coal->tx_coalesce_usecs = 0;
374 coal->rx_max_coalesced_frames = 1;
375 coal->tx_max_coalesced_frames = 1;
381 static int aq_ethtool_set_coalesce(struct net_device *ndev,
382 struct ethtool_coalesce *coal)
384 struct aq_nic_s *aq_nic = netdev_priv(ndev);
385 struct aq_nic_cfg_s *cfg;
387 cfg = aq_nic_get_cfg(aq_nic);
389 /* Atlantic only supports timing based coalescing
391 if (coal->rx_max_coalesced_frames > 1 ||
392 coal->tx_max_coalesced_frames > 1)
395 /* We do not support frame counting. Check this
397 if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs))
399 if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs))
402 if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX ||
403 coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX)
406 cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON;
408 cfg->rx_itr = coal->rx_coalesce_usecs;
409 cfg->tx_itr = coal->tx_coalesce_usecs;
411 return aq_nic_update_interrupt_moderation_settings(aq_nic);
414 static void aq_ethtool_get_wol(struct net_device *ndev,
415 struct ethtool_wolinfo *wol)
417 struct aq_nic_s *aq_nic = netdev_priv(ndev);
418 struct aq_nic_cfg_s *cfg;
420 cfg = aq_nic_get_cfg(aq_nic);
422 wol->supported = AQ_NIC_WOL_MODES;
423 wol->wolopts = cfg->wol;
426 static int aq_ethtool_set_wol(struct net_device *ndev,
427 struct ethtool_wolinfo *wol)
429 struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
430 struct aq_nic_s *aq_nic = netdev_priv(ndev);
431 struct aq_nic_cfg_s *cfg;
434 cfg = aq_nic_get_cfg(aq_nic);
436 if (wol->wolopts & ~AQ_NIC_WOL_MODES)
439 cfg->wol = wol->wolopts;
441 err = device_set_wakeup_enable(&pdev->dev, !!cfg->wol);
446 static int aq_ethtool_get_ts_info(struct net_device *ndev,
447 struct ethtool_ts_info *info)
449 struct aq_nic_s *aq_nic = netdev_priv(ndev);
451 ethtool_op_get_ts_info(ndev, info);
456 info->so_timestamping |=
457 SOF_TIMESTAMPING_TX_HARDWARE |
458 SOF_TIMESTAMPING_RX_HARDWARE |
459 SOF_TIMESTAMPING_RAW_HARDWARE;
461 info->tx_types = BIT(HWTSTAMP_TX_OFF) |
464 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
466 info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
467 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
468 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
470 info->phc_index = ptp_clock_index(aq_ptp_get_ptp_clock(aq_nic->aq_ptp));
475 static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
479 if (speed & AQ_NIC_RATE_EEE_10G)
480 rate |= SUPPORTED_10000baseT_Full;
482 if (speed & AQ_NIC_RATE_EEE_2GS)
483 rate |= SUPPORTED_2500baseX_Full;
485 if (speed & AQ_NIC_RATE_EEE_1G)
486 rate |= SUPPORTED_1000baseT_Full;
491 static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
493 struct aq_nic_s *aq_nic = netdev_priv(ndev);
494 u32 rate, supported_rates;
497 if (!aq_nic->aq_fw_ops->get_eee_rate)
500 mutex_lock(&aq_nic->fwreq_mutex);
501 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
503 mutex_unlock(&aq_nic->fwreq_mutex);
507 eee->supported = eee_mask_to_ethtool_mask(supported_rates);
509 if (aq_nic->aq_nic_cfg.eee_speeds)
510 eee->advertised = eee->supported;
512 eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
514 eee->eee_enabled = !!eee->advertised;
516 eee->tx_lpi_enabled = eee->eee_enabled;
517 if (eee->advertised & eee->lp_advertised)
518 eee->eee_active = true;
523 static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
525 struct aq_nic_s *aq_nic = netdev_priv(ndev);
526 u32 rate, supported_rates;
527 struct aq_nic_cfg_s *cfg;
530 cfg = aq_nic_get_cfg(aq_nic);
532 if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
533 !aq_nic->aq_fw_ops->set_eee_rate))
536 mutex_lock(&aq_nic->fwreq_mutex);
537 err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
539 mutex_unlock(&aq_nic->fwreq_mutex);
543 if (eee->eee_enabled) {
544 rate = supported_rates;
545 cfg->eee_speeds = rate;
551 mutex_lock(&aq_nic->fwreq_mutex);
552 err = aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
553 mutex_unlock(&aq_nic->fwreq_mutex);
558 static int aq_ethtool_nway_reset(struct net_device *ndev)
560 struct aq_nic_s *aq_nic = netdev_priv(ndev);
563 if (unlikely(!aq_nic->aq_fw_ops->renegotiate))
566 if (netif_running(ndev)) {
567 mutex_lock(&aq_nic->fwreq_mutex);
568 err = aq_nic->aq_fw_ops->renegotiate(aq_nic->aq_hw);
569 mutex_unlock(&aq_nic->fwreq_mutex);
575 static void aq_ethtool_get_pauseparam(struct net_device *ndev,
576 struct ethtool_pauseparam *pause)
578 struct aq_nic_s *aq_nic = netdev_priv(ndev);
579 u32 fc = aq_nic->aq_nic_cfg.fc.req;
583 pause->rx_pause = !!(fc & AQ_NIC_FC_RX);
584 pause->tx_pause = !!(fc & AQ_NIC_FC_TX);
588 static int aq_ethtool_set_pauseparam(struct net_device *ndev,
589 struct ethtool_pauseparam *pause)
591 struct aq_nic_s *aq_nic = netdev_priv(ndev);
594 if (!aq_nic->aq_fw_ops->set_flow_control)
597 if (pause->autoneg == AUTONEG_ENABLE)
601 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_RX;
603 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_RX;
606 aq_nic->aq_hw->aq_nic_cfg->fc.req |= AQ_NIC_FC_TX;
608 aq_nic->aq_hw->aq_nic_cfg->fc.req &= ~AQ_NIC_FC_TX;
610 mutex_lock(&aq_nic->fwreq_mutex);
611 err = aq_nic->aq_fw_ops->set_flow_control(aq_nic->aq_hw);
612 mutex_unlock(&aq_nic->fwreq_mutex);
617 static void aq_get_ringparam(struct net_device *ndev,
618 struct ethtool_ringparam *ring)
620 struct aq_nic_s *aq_nic = netdev_priv(ndev);
621 struct aq_nic_cfg_s *cfg;
623 cfg = aq_nic_get_cfg(aq_nic);
625 ring->rx_pending = cfg->rxds;
626 ring->tx_pending = cfg->txds;
628 ring->rx_max_pending = cfg->aq_hw_caps->rxds_max;
629 ring->tx_max_pending = cfg->aq_hw_caps->txds_max;
632 static int aq_set_ringparam(struct net_device *ndev,
633 struct ethtool_ringparam *ring)
635 struct aq_nic_s *aq_nic = netdev_priv(ndev);
636 const struct aq_hw_caps_s *hw_caps;
637 bool ndev_running = false;
638 struct aq_nic_cfg_s *cfg;
641 cfg = aq_nic_get_cfg(aq_nic);
642 hw_caps = cfg->aq_hw_caps;
644 if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
649 if (netif_running(ndev)) {
654 aq_nic_free_vectors(aq_nic);
656 cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min);
657 cfg->rxds = min(cfg->rxds, hw_caps->rxds_max);
658 cfg->rxds = ALIGN(cfg->rxds, AQ_HW_RXD_MULTIPLE);
660 cfg->txds = max(ring->tx_pending, hw_caps->txds_min);
661 cfg->txds = min(cfg->txds, hw_caps->txds_max);
662 cfg->txds = ALIGN(cfg->txds, AQ_HW_TXD_MULTIPLE);
664 for (aq_nic->aq_vecs = 0; aq_nic->aq_vecs < cfg->vecs;
666 aq_nic->aq_vec[aq_nic->aq_vecs] =
667 aq_vec_alloc(aq_nic, aq_nic->aq_vecs, cfg);
668 if (unlikely(!aq_nic->aq_vec[aq_nic->aq_vecs])) {
674 err = dev_open(ndev, NULL);
680 static u32 aq_get_msg_level(struct net_device *ndev)
682 struct aq_nic_s *aq_nic = netdev_priv(ndev);
684 return aq_nic->msg_enable;
687 static void aq_set_msg_level(struct net_device *ndev, u32 data)
689 struct aq_nic_s *aq_nic = netdev_priv(ndev);
691 aq_nic->msg_enable = data;
694 static u32 aq_ethtool_get_priv_flags(struct net_device *ndev)
696 struct aq_nic_s *aq_nic = netdev_priv(ndev);
698 return aq_nic->aq_nic_cfg.priv_flags;
701 static int aq_ethtool_set_priv_flags(struct net_device *ndev, u32 flags)
703 struct aq_nic_s *aq_nic = netdev_priv(ndev);
704 struct aq_nic_cfg_s *cfg;
707 cfg = aq_nic_get_cfg(aq_nic);
708 priv_flags = cfg->priv_flags;
710 if (flags & ~AQ_PRIV_FLAGS_MASK)
713 if (hweight32((flags | priv_flags) & AQ_HW_LOOPBACK_MASK) > 1) {
714 netdev_info(ndev, "Can't enable more than one loopback simultaneously\n");
718 cfg->priv_flags = flags;
720 if ((priv_flags ^ flags) & BIT(AQ_HW_LOOPBACK_DMA_NET)) {
721 if (netif_running(ndev)) {
724 dev_open(ndev, NULL);
726 } else if ((priv_flags ^ flags) & AQ_HW_LOOPBACK_MASK) {
727 aq_nic_set_loopback(aq_nic);
733 const struct ethtool_ops aq_ethtool_ops = {
734 .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
735 ETHTOOL_COALESCE_MAX_FRAMES,
736 .get_link = aq_ethtool_get_link,
737 .get_regs_len = aq_ethtool_get_regs_len,
738 .get_regs = aq_ethtool_get_regs,
739 .get_drvinfo = aq_ethtool_get_drvinfo,
740 .get_strings = aq_ethtool_get_strings,
741 .set_phys_id = aq_ethtool_set_phys_id,
742 .get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
743 .get_wol = aq_ethtool_get_wol,
744 .set_wol = aq_ethtool_set_wol,
745 .nway_reset = aq_ethtool_nway_reset,
746 .get_ringparam = aq_get_ringparam,
747 .set_ringparam = aq_set_ringparam,
748 .get_eee = aq_ethtool_get_eee,
749 .set_eee = aq_ethtool_set_eee,
750 .get_pauseparam = aq_ethtool_get_pauseparam,
751 .set_pauseparam = aq_ethtool_set_pauseparam,
752 .get_rxfh_key_size = aq_ethtool_get_rss_key_size,
753 .get_rxfh = aq_ethtool_get_rss,
754 .set_rxfh = aq_ethtool_set_rss,
755 .get_rxnfc = aq_ethtool_get_rxnfc,
756 .set_rxnfc = aq_ethtool_set_rxnfc,
757 .get_msglevel = aq_get_msg_level,
758 .set_msglevel = aq_set_msg_level,
759 .get_sset_count = aq_ethtool_get_sset_count,
760 .get_ethtool_stats = aq_ethtool_stats,
761 .get_priv_flags = aq_ethtool_get_priv_flags,
762 .set_priv_flags = aq_ethtool_set_priv_flags,
763 .get_link_ksettings = aq_ethtool_get_link_ksettings,
764 .set_link_ksettings = aq_ethtool_set_link_ksettings,
765 .get_coalesce = aq_ethtool_get_coalesce,
766 .set_coalesce = aq_ethtool_set_coalesce,
767 .get_ts_info = aq_ethtool_get_ts_info,