forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
....@@ -1,19 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*******************************************************************************
23 STMMAC Ethtool support
34
45 Copyright (C) 2007-2009 STMicroelectronics Ltd
56
6
- This program is free software; you can redistribute it and/or modify it
7
- under the terms and conditions of the GNU General Public License,
8
- version 2, as published by the Free Software Foundation.
9
-
10
- This program is distributed in the hope it will be useful, but WITHOUT
11
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
- more details.
14
-
15
- The full GNU General Public License is included in this distribution in
16
- the file called "COPYING".
177
188 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
199 *******************************************************************************/
....@@ -22,16 +12,26 @@
2212 #include <linux/ethtool.h>
2313 #include <linux/interrupt.h>
2414 #include <linux/mii.h>
25
-#include <linux/phy.h>
15
+#include <linux/phylink.h>
2616 #include <linux/net_tstamp.h>
2717 #include <asm/io.h>
2818
2919 #include "stmmac.h"
3020 #include "dwmac_dma.h"
21
+#include "dwxgmac2.h"
3122
3223 #define REG_SPACE_SIZE 0x1060
24
+#define GMAC4_REG_SPACE_SIZE 0x116C
3325 #define MAC100_ETHTOOL_NAME "st_mac100"
3426 #define GMAC_ETHTOOL_NAME "st_gmac"
27
+#define XGMAC_ETHTOOL_NAME "st_xgmac"
28
+
29
+/* Same as DMA_CHAN_BASE_ADDR defined in dwmac4_dma.h
30
+ *
31
+ * It is here because dwmac_dma.h and dwmac4_dam.h can not be included at the
32
+ * same time due to the conflicting macro names.
33
+ */
34
+#define GMAC4_DMA_CHAN_BASE_ADDR 0x00001100
3535
3636 #define ETHTOOL_DMA_OFFSET 55
3737
....@@ -42,7 +42,7 @@
4242 };
4343
4444 #define STMMAC_STAT(m) \
45
- { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m), \
45
+ { #m, sizeof_field(struct stmmac_extra_stats, m), \
4646 offsetof(struct stmmac_priv, xstats.m)}
4747
4848 static const struct stmmac_stats stmmac_gstrings_stats[] = {
....@@ -75,6 +75,7 @@
7575 STMMAC_STAT(rx_missed_cntr),
7676 STMMAC_STAT(rx_overflow_cntr),
7777 STMMAC_STAT(rx_vlan),
78
+ STMMAC_STAT(rx_split_hdr_pkt_n),
7879 /* Tx/Rx IRQ error info */
7980 STMMAC_STAT(tx_undeflow_irq),
8081 STMMAC_STAT(tx_process_stopped_irq),
....@@ -170,7 +171,7 @@
170171
171172 /* HW MAC Management counters (if supported) */
172173 #define STMMAC_MMC_STAT(m) \
173
- { #m, FIELD_SIZEOF(struct stmmac_counters, m), \
174
+ { #m, sizeof_field(struct stmmac_counters, m), \
174175 offsetof(struct stmmac_priv, mmc.m)}
175176
176177 static const struct stmmac_stats stmmac_mmc[] = {
....@@ -253,6 +254,12 @@
253254 STMMAC_MMC_STAT(mmc_rx_tcp_err_octets),
254255 STMMAC_MMC_STAT(mmc_rx_icmp_gd_octets),
255256 STMMAC_MMC_STAT(mmc_rx_icmp_err_octets),
257
+ STMMAC_MMC_STAT(mmc_tx_fpe_fragment_cntr),
258
+ STMMAC_MMC_STAT(mmc_tx_hold_req_cntr),
259
+ STMMAC_MMC_STAT(mmc_rx_packet_assembly_err_cntr),
260
+ STMMAC_MMC_STAT(mmc_rx_packet_smd_err_cntr),
261
+ STMMAC_MMC_STAT(mmc_rx_packet_assembly_ok_cntr),
262
+ STMMAC_MMC_STAT(mmc_rx_fpe_fragment_cntr),
256263 };
257264 #define STMMAC_MMC_STATS_LEN ARRAY_SIZE(stmmac_mmc)
258265
....@@ -263,6 +270,8 @@
263270
264271 if (priv->plat->has_gmac || priv->plat->has_gmac4)
265272 strlcpy(info->driver, GMAC_ETHTOOL_NAME, sizeof(info->driver));
273
+ else if (priv->plat->has_xgmac)
274
+ strlcpy(info->driver, XGMAC_ETHTOOL_NAME, sizeof(info->driver));
266275 else
267276 strlcpy(info->driver, MAC100_ETHTOOL_NAME,
268277 sizeof(info->driver));
....@@ -274,7 +283,6 @@
274283 struct ethtool_link_ksettings *cmd)
275284 {
276285 struct stmmac_priv *priv = netdev_priv(dev);
277
- struct phy_device *phy = dev->phydev;
278286
279287 if (priv->hw->pcs & STMMAC_PCS_RGMII ||
280288 priv->hw->pcs & STMMAC_PCS_SGMII) {
....@@ -353,18 +361,7 @@
353361 return 0;
354362 }
355363
356
- if (phy == NULL) {
357
- pr_err("%s: %s: PHY is not registered\n",
358
- __func__, dev->name);
359
- return -ENODEV;
360
- }
361
- if (!netif_running(dev)) {
362
- pr_err("%s: interface is disabled: we cannot track "
363
- "link speed / duplex setting\n", dev->name);
364
- return -EBUSY;
365
- }
366
- phy_ethtool_ksettings_get(phy, cmd);
367
- return 0;
364
+ return phylink_ethtool_ksettings_get(priv->phylink, cmd);
368365 }
369366
370367 static int
....@@ -372,8 +369,6 @@
372369 const struct ethtool_link_ksettings *cmd)
373370 {
374371 struct stmmac_priv *priv = netdev_priv(dev);
375
- struct phy_device *phy = dev->phydev;
376
- int rc;
377372
378373 if (priv->hw->pcs & STMMAC_PCS_RGMII ||
379374 priv->hw->pcs & STMMAC_PCS_SGMII) {
....@@ -397,9 +392,12 @@
397392 return 0;
398393 }
399394
400
- rc = phy_ethtool_ksettings_set(phy, cmd);
395
+ if (priv->plat->tx_queues_to_use > 1 && cmd->base.duplex == DUPLEX_HALF) {
396
+ netdev_warn(priv->dev, "Half-Duplex can only work with single queue\n");
397
+ return -EINVAL;
398
+ }
401399
402
- return rc;
400
+ return phylink_ethtool_ksettings_set(priv->phylink, cmd);
403401 }
404402
405403 static u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
....@@ -424,23 +422,69 @@
424422
425423 static int stmmac_ethtool_get_regs_len(struct net_device *dev)
426424 {
425
+ struct stmmac_priv *priv = netdev_priv(dev);
426
+
427
+ if (priv->plat->has_xgmac)
428
+ return XGMAC_REGSIZE * 4;
429
+ else if (priv->plat->has_gmac4)
430
+ return GMAC4_REG_SPACE_SIZE;
427431 return REG_SPACE_SIZE;
428432 }
429433
430434 static void stmmac_ethtool_gregs(struct net_device *dev,
431435 struct ethtool_regs *regs, void *space)
432436 {
433
- u32 *reg_space = (u32 *) space;
434
-
435437 struct stmmac_priv *priv = netdev_priv(dev);
436
-
437
- memset(reg_space, 0x0, REG_SPACE_SIZE);
438
+ u32 *reg_space = (u32 *) space;
438439
439440 stmmac_dump_mac_regs(priv, priv->hw, reg_space);
440441 stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
442
+
441443 /* Copy DMA registers to where ethtool expects them */
442
- memcpy(&reg_space[ETHTOOL_DMA_OFFSET], &reg_space[DMA_BUS_MODE / 4],
443
- NUM_DWMAC1000_DMA_REGS * 4);
444
+ if (priv->plat->has_gmac4) {
445
+ /* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */
446
+ memcpy(&reg_space[ETHTOOL_DMA_OFFSET],
447
+ &reg_space[GMAC4_DMA_CHAN_BASE_ADDR / 4],
448
+ NUM_DWMAC4_DMA_REGS * 4);
449
+ } else if (!priv->plat->has_xgmac) {
450
+ memcpy(&reg_space[ETHTOOL_DMA_OFFSET],
451
+ &reg_space[DMA_BUS_MODE / 4],
452
+ NUM_DWMAC1000_DMA_REGS * 4);
453
+ }
454
+}
455
+
456
+static int stmmac_nway_reset(struct net_device *dev)
457
+{
458
+ struct stmmac_priv *priv = netdev_priv(dev);
459
+
460
+ return phylink_ethtool_nway_reset(priv->phylink);
461
+}
462
+
463
+static void stmmac_get_ringparam(struct net_device *netdev,
464
+ struct ethtool_ringparam *ring)
465
+{
466
+ struct stmmac_priv *priv = netdev_priv(netdev);
467
+
468
+ ring->rx_max_pending = DMA_MAX_RX_SIZE;
469
+ ring->tx_max_pending = DMA_MAX_TX_SIZE;
470
+ ring->rx_pending = priv->dma_rx_size;
471
+ ring->tx_pending = priv->dma_tx_size;
472
+}
473
+
474
+static int stmmac_set_ringparam(struct net_device *netdev,
475
+ struct ethtool_ringparam *ring)
476
+{
477
+ if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
478
+ ring->rx_pending < DMA_MIN_RX_SIZE ||
479
+ ring->rx_pending > DMA_MAX_RX_SIZE ||
480
+ !is_power_of_2(ring->rx_pending) ||
481
+ ring->tx_pending < DMA_MIN_TX_SIZE ||
482
+ ring->tx_pending > DMA_MAX_TX_SIZE ||
483
+ !is_power_of_2(ring->tx_pending))
484
+ return -EINVAL;
485
+
486
+ return stmmac_reinit_ringparam(netdev, ring->rx_pending,
487
+ ring->tx_pending);
444488 }
445489
446490 static void
....@@ -450,26 +494,13 @@
450494 struct stmmac_priv *priv = netdev_priv(netdev);
451495 struct rgmii_adv adv_lp;
452496
453
- pause->rx_pause = 0;
454
- pause->tx_pause = 0;
455
-
456497 if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) {
457498 pause->autoneg = 1;
458499 if (!adv_lp.pause)
459500 return;
460501 } else {
461
- if (!(netdev->phydev->supported & SUPPORTED_Pause) ||
462
- !(netdev->phydev->supported & SUPPORTED_Asym_Pause))
463
- return;
502
+ phylink_ethtool_get_pauseparam(priv->phylink, pause);
464503 }
465
-
466
- pause->autoneg = netdev->phydev->autoneg;
467
-
468
- if (priv->flow_ctrl & FLOW_RX)
469
- pause->rx_pause = 1;
470
- if (priv->flow_ctrl & FLOW_TX)
471
- pause->tx_pause = 1;
472
-
473504 }
474505
475506 static int
....@@ -477,37 +508,16 @@
477508 struct ethtool_pauseparam *pause)
478509 {
479510 struct stmmac_priv *priv = netdev_priv(netdev);
480
- u32 tx_cnt = priv->plat->tx_queues_to_use;
481
- struct phy_device *phy = netdev->phydev;
482
- int new_pause = FLOW_OFF;
483511 struct rgmii_adv adv_lp;
484512
485513 if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) {
486514 pause->autoneg = 1;
487515 if (!adv_lp.pause)
488516 return -EOPNOTSUPP;
517
+ return 0;
489518 } else {
490
- if (!(phy->supported & SUPPORTED_Pause) ||
491
- !(phy->supported & SUPPORTED_Asym_Pause))
492
- return -EOPNOTSUPP;
519
+ return phylink_ethtool_set_pauseparam(priv->phylink, pause);
493520 }
494
-
495
- if (pause->rx_pause)
496
- new_pause |= FLOW_RX;
497
- if (pause->tx_pause)
498
- new_pause |= FLOW_TX;
499
-
500
- priv->flow_ctrl = new_pause;
501
- phy->autoneg = pause->autoneg;
502
-
503
- if (phy->autoneg) {
504
- if (netif_running(netdev))
505
- return phy_start_aneg(phy);
506
- }
507
-
508
- stmmac_flow_ctrl(priv, priv->hw, phy->duplex, priv->flow_ctrl,
509
- priv->pause, tx_cnt);
510
- return 0;
511521 }
512522
513523 static void stmmac_get_ethtool_stats(struct net_device *dev,
....@@ -533,7 +543,7 @@
533543 if (ret) {
534544 /* If supported, for new GMAC chips expose the MMC counters */
535545 if (priv->dma_cap.rmon) {
536
- dwmac_mmc_read(priv->mmcaddr, &priv->mmc);
546
+ stmmac_mmc_read(priv, priv->mmcaddr, &priv->mmc);
537547
538548 for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
539549 char *p;
....@@ -545,7 +555,7 @@
545555 }
546556 }
547557 if (priv->eee_enabled) {
548
- int val = phy_get_eee_err(dev->phydev);
558
+ int val = phylink_get_eee_err(priv->phylink);
549559 if (val)
550560 priv->xstats.phy_eee_wakeup_error_n = val;
551561 }
....@@ -585,6 +595,8 @@
585595 }
586596
587597 return len;
598
+ case ETH_SS_TEST:
599
+ return stmmac_selftest_get_count(priv);
588600 default:
589601 return -EOPNOTSUPP;
590602 }
....@@ -621,6 +633,9 @@
621633 p += ETH_GSTRING_LEN;
622634 }
623635 break;
636
+ case ETH_SS_TEST:
637
+ stmmac_selftest_get_strings(priv, p);
638
+ break;
624639 default:
625640 WARN_ON(1);
626641 break;
....@@ -632,9 +647,14 @@
632647 {
633648 struct stmmac_priv *priv = netdev_priv(dev);
634649
650
+ if (!priv->plat->pmt)
651
+ return phylink_ethtool_get_wol(priv->phylink, wol);
652
+
635653 mutex_lock(&priv->lock);
636654 if (device_can_wakeup(priv->device)) {
637655 wol->supported = WAKE_MAGIC | WAKE_UCAST;
656
+ if (priv->hw_cap_support && !priv->dma_cap.pmt_magic_frame)
657
+ wol->supported &= ~WAKE_MAGIC;
638658 wol->wolopts = priv->wolopts;
639659 }
640660 mutex_unlock(&priv->lock);
....@@ -645,14 +665,22 @@
645665 struct stmmac_priv *priv = netdev_priv(dev);
646666 u32 support = WAKE_MAGIC | WAKE_UCAST;
647667
668
+ if (!device_can_wakeup(priv->device))
669
+ return -EOPNOTSUPP;
670
+
671
+ if (!priv->plat->pmt) {
672
+ int ret = phylink_ethtool_set_wol(priv->phylink, wol);
673
+
674
+ if (!ret)
675
+ device_set_wakeup_enable(priv->device, !!wol->wolopts);
676
+ return ret;
677
+ }
678
+
648679 /* By default almost all GMAC devices support the WoL via
649680 * magic frame but we can disable it if the HW capability
650681 * register shows no support for pmt_magic_frame. */
651682 if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))
652683 wol->wolopts &= ~WAKE_MAGIC;
653
-
654
- if (!device_can_wakeup(priv->device))
655
- return -EINVAL;
656684
657685 if (wol->wolopts & ~support)
658686 return -EINVAL;
....@@ -684,8 +712,9 @@
684712 edata->eee_enabled = priv->eee_enabled;
685713 edata->eee_active = priv->eee_active;
686714 edata->tx_lpi_timer = priv->tx_lpi_timer;
715
+ edata->tx_lpi_enabled = priv->tx_lpi_enabled;
687716
688
- return phy_ethtool_get_eee(dev->phydev, edata);
717
+ return phylink_ethtool_get_eee(priv->phylink, edata);
689718 }
690719
691720 static int stmmac_ethtool_op_set_eee(struct net_device *dev,
....@@ -697,14 +726,23 @@
697726 if (!priv->dma_cap.eee)
698727 return -EOPNOTSUPP;
699728
729
+ if (priv->tx_lpi_enabled != edata->tx_lpi_enabled)
730
+ netdev_warn(priv->dev,
731
+ "Setting EEE tx-lpi is not supported\n");
732
+
700733 if (!edata->eee_enabled)
701734 stmmac_disable_eee_mode(priv);
702735
703
- ret = phy_ethtool_set_eee(dev->phydev, edata);
736
+ ret = phylink_ethtool_set_eee(priv->phylink, edata);
704737 if (ret)
705738 return ret;
706739
707
- priv->tx_lpi_timer = edata->tx_lpi_timer;
740
+ if (edata->eee_enabled &&
741
+ priv->tx_lpi_timer != edata->tx_lpi_timer) {
742
+ priv->tx_lpi_timer = edata->tx_lpi_timer;
743
+ stmmac_eee_init(priv);
744
+ }
745
+
708746 return 0;
709747 }
710748
....@@ -742,8 +780,10 @@
742780 ec->tx_coalesce_usecs = priv->tx_coal_timer;
743781 ec->tx_max_coalesced_frames = priv->tx_coal_frames;
744782
745
- if (priv->use_riwt)
783
+ if (priv->use_riwt) {
784
+ ec->rx_max_coalesced_frames = priv->rx_coal_frames;
746785 ec->rx_coalesce_usecs = stmmac_riwt2usec(priv->rx_riwt, priv);
786
+ }
747787
748788 return 0;
749789 }
....@@ -755,22 +795,15 @@
755795 u32 rx_cnt = priv->plat->rx_queues_to_use;
756796 unsigned int rx_riwt;
757797
758
- /* Check not supported parameters */
759
- if ((ec->rx_max_coalesced_frames) || (ec->rx_coalesce_usecs_irq) ||
760
- (ec->rx_max_coalesced_frames_irq) || (ec->tx_coalesce_usecs_irq) ||
761
- (ec->use_adaptive_rx_coalesce) || (ec->use_adaptive_tx_coalesce) ||
762
- (ec->pkt_rate_low) || (ec->rx_coalesce_usecs_low) ||
763
- (ec->rx_max_coalesced_frames_low) || (ec->tx_coalesce_usecs_high) ||
764
- (ec->tx_max_coalesced_frames_low) || (ec->pkt_rate_high) ||
765
- (ec->tx_coalesce_usecs_low) || (ec->rx_coalesce_usecs_high) ||
766
- (ec->rx_max_coalesced_frames_high) ||
767
- (ec->tx_max_coalesced_frames_irq) ||
768
- (ec->stats_block_coalesce_usecs) ||
769
- (ec->tx_max_coalesced_frames_high) || (ec->rate_sample_interval))
770
- return -EOPNOTSUPP;
798
+ if (priv->use_riwt && (ec->rx_coalesce_usecs > 0)) {
799
+ rx_riwt = stmmac_usec2riwt(ec->rx_coalesce_usecs, priv);
771800
772
- if (ec->rx_coalesce_usecs == 0)
773
- return -EINVAL;
801
+ if ((rx_riwt > MAX_DMA_RIWT) || (rx_riwt < MIN_DMA_RIWT))
802
+ return -EINVAL;
803
+
804
+ priv->rx_riwt = rx_riwt;
805
+ stmmac_rx_watchdog(priv, priv->ioaddr, priv->rx_riwt, rx_cnt);
806
+ }
774807
775808 if ((ec->tx_coalesce_usecs == 0) &&
776809 (ec->tx_max_coalesced_frames == 0))
....@@ -780,20 +813,105 @@
780813 (ec->tx_max_coalesced_frames > STMMAC_TX_MAX_FRAMES))
781814 return -EINVAL;
782815
783
- rx_riwt = stmmac_usec2riwt(ec->rx_coalesce_usecs, priv);
784
-
785
- if ((rx_riwt > MAX_DMA_RIWT) || (rx_riwt < MIN_DMA_RIWT))
786
- return -EINVAL;
787
- else if (!priv->use_riwt)
788
- return -EOPNOTSUPP;
789
-
790816 /* Only copy relevant parameters, ignore all others. */
791817 priv->tx_coal_frames = ec->tx_max_coalesced_frames;
792818 priv->tx_coal_timer = ec->tx_coalesce_usecs;
793
- priv->rx_riwt = rx_riwt;
794
- stmmac_rx_watchdog(priv, priv->ioaddr, priv->rx_riwt, rx_cnt);
819
+ priv->rx_coal_frames = ec->rx_max_coalesced_frames;
820
+ return 0;
821
+}
822
+
823
+static int stmmac_get_rxnfc(struct net_device *dev,
824
+ struct ethtool_rxnfc *rxnfc, u32 *rule_locs)
825
+{
826
+ struct stmmac_priv *priv = netdev_priv(dev);
827
+
828
+ switch (rxnfc->cmd) {
829
+ case ETHTOOL_GRXRINGS:
830
+ rxnfc->data = priv->plat->rx_queues_to_use;
831
+ break;
832
+ default:
833
+ return -EOPNOTSUPP;
834
+ }
795835
796836 return 0;
837
+}
838
+
839
+static u32 stmmac_get_rxfh_key_size(struct net_device *dev)
840
+{
841
+ struct stmmac_priv *priv = netdev_priv(dev);
842
+
843
+ return sizeof(priv->rss.key);
844
+}
845
+
846
+static u32 stmmac_get_rxfh_indir_size(struct net_device *dev)
847
+{
848
+ struct stmmac_priv *priv = netdev_priv(dev);
849
+
850
+ return ARRAY_SIZE(priv->rss.table);
851
+}
852
+
853
+static int stmmac_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
854
+ u8 *hfunc)
855
+{
856
+ struct stmmac_priv *priv = netdev_priv(dev);
857
+ int i;
858
+
859
+ if (indir) {
860
+ for (i = 0; i < ARRAY_SIZE(priv->rss.table); i++)
861
+ indir[i] = priv->rss.table[i];
862
+ }
863
+
864
+ if (key)
865
+ memcpy(key, priv->rss.key, sizeof(priv->rss.key));
866
+ if (hfunc)
867
+ *hfunc = ETH_RSS_HASH_TOP;
868
+
869
+ return 0;
870
+}
871
+
872
+static int stmmac_set_rxfh(struct net_device *dev, const u32 *indir,
873
+ const u8 *key, const u8 hfunc)
874
+{
875
+ struct stmmac_priv *priv = netdev_priv(dev);
876
+ int i;
877
+
878
+ if ((hfunc != ETH_RSS_HASH_NO_CHANGE) && (hfunc != ETH_RSS_HASH_TOP))
879
+ return -EOPNOTSUPP;
880
+
881
+ if (indir) {
882
+ for (i = 0; i < ARRAY_SIZE(priv->rss.table); i++)
883
+ priv->rss.table[i] = indir[i];
884
+ }
885
+
886
+ if (key)
887
+ memcpy(priv->rss.key, key, sizeof(priv->rss.key));
888
+
889
+ return stmmac_rss_configure(priv, priv->hw, &priv->rss,
890
+ priv->plat->rx_queues_to_use);
891
+}
892
+
893
+static void stmmac_get_channels(struct net_device *dev,
894
+ struct ethtool_channels *chan)
895
+{
896
+ struct stmmac_priv *priv = netdev_priv(dev);
897
+
898
+ chan->rx_count = priv->plat->rx_queues_to_use;
899
+ chan->tx_count = priv->plat->tx_queues_to_use;
900
+ chan->max_rx = priv->dma_cap.number_rx_queues;
901
+ chan->max_tx = priv->dma_cap.number_tx_queues;
902
+}
903
+
904
+static int stmmac_set_channels(struct net_device *dev,
905
+ struct ethtool_channels *chan)
906
+{
907
+ struct stmmac_priv *priv = netdev_priv(dev);
908
+
909
+ if (chan->rx_count > priv->dma_cap.number_rx_queues ||
910
+ chan->tx_count > priv->dma_cap.number_tx_queues ||
911
+ !chan->rx_count || !chan->tx_count)
912
+ return -EINVAL;
913
+
914
+ return stmmac_reinit_queues(dev, chan->rx_count, chan->tx_count);
797915 }
798916
799917 static int stmmac_get_ts_info(struct net_device *dev,
....@@ -869,6 +987,8 @@
869987 }
870988
871989 static const struct ethtool_ops stmmac_ethtool_ops = {
990
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
991
+ ETHTOOL_COALESCE_MAX_FRAMES,
872992 .begin = stmmac_check_if_running,
873993 .get_drvinfo = stmmac_ethtool_getdrvinfo,
874994 .get_msglevel = stmmac_ethtool_getmsglevel,
....@@ -876,9 +996,12 @@
876996 .get_regs = stmmac_ethtool_gregs,
877997 .get_regs_len = stmmac_ethtool_get_regs_len,
878998 .get_link = ethtool_op_get_link,
879
- .nway_reset = phy_ethtool_nway_reset,
999
+ .nway_reset = stmmac_nway_reset,
1000
+ .get_ringparam = stmmac_get_ringparam,
1001
+ .set_ringparam = stmmac_set_ringparam,
8801002 .get_pauseparam = stmmac_get_pauseparam,
8811003 .set_pauseparam = stmmac_set_pauseparam,
1004
+ .self_test = stmmac_selftest_run,
8821005 .get_ethtool_stats = stmmac_get_ethtool_stats,
8831006 .get_strings = stmmac_get_strings,
8841007 .get_wol = stmmac_get_wol,
....@@ -886,9 +1009,16 @@
8861009 .get_eee = stmmac_ethtool_op_get_eee,
8871010 .set_eee = stmmac_ethtool_op_set_eee,
8881011 .get_sset_count = stmmac_get_sset_count,
1012
+ .get_rxnfc = stmmac_get_rxnfc,
1013
+ .get_rxfh_key_size = stmmac_get_rxfh_key_size,
1014
+ .get_rxfh_indir_size = stmmac_get_rxfh_indir_size,
1015
+ .get_rxfh = stmmac_get_rxfh,
1016
+ .set_rxfh = stmmac_set_rxfh,
8891017 .get_ts_info = stmmac_get_ts_info,
8901018 .get_coalesce = stmmac_get_coalesce,
8911019 .set_coalesce = stmmac_set_coalesce,
1020
+ .get_channels = stmmac_get_channels,
1021
+ .set_channels = stmmac_set_channels,
8921022 .get_tunable = stmmac_get_tunable,
8931023 .set_tunable = stmmac_set_tunable,
8941024 .get_link_ksettings = stmmac_ethtool_get_link_ksettings,