9
9
10
10
#include <linux/etherdevice.h>
11
11
#include <linux/string.h>
12
+ #include <linux/phy.h>
12
13
13
14
#include "hns3_enet.h"
14
15
@@ -358,17 +359,12 @@ static void hns3_driv_to_eth_caps(u32 caps, struct ethtool_link_ksettings *cmd,
358
359
if (!(caps & hns3_lm_map [i ].hns3_link_mode ))
359
360
continue ;
360
361
361
- if (is_advertised ) {
362
- ethtool_link_ksettings_zero_link_mode (cmd ,
363
- advertising );
362
+ if (is_advertised )
364
363
__set_bit (hns3_lm_map [i ].ethtool_link_mode ,
365
364
cmd -> link_modes .advertising );
366
- } else {
367
- ethtool_link_ksettings_zero_link_mode (cmd ,
368
- supported );
365
+ else
369
366
__set_bit (hns3_lm_map [i ].ethtool_link_mode ,
370
367
cmd -> link_modes .supported );
371
- }
372
368
}
373
369
}
374
370
@@ -571,26 +567,25 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
571
567
u32 advertised_caps ;
572
568
u8 media_type = HNAE3_MEDIA_TYPE_UNKNOWN ;
573
569
u8 link_stat ;
574
- u8 auto_neg ;
575
- u8 duplex ;
576
- u32 speed ;
577
570
578
571
if (!h -> ae_algo || !h -> ae_algo -> ops )
579
572
return - EOPNOTSUPP ;
580
573
581
574
/* 1.auto_neg & speed & duplex from cmd */
582
- if (h -> ae_algo -> ops -> get_ksettings_an_result ) {
583
- h -> ae_algo -> ops -> get_ksettings_an_result (h , & auto_neg ,
584
- & speed , & duplex );
585
- cmd -> base .autoneg = auto_neg ;
586
- cmd -> base .speed = speed ;
587
- cmd -> base .duplex = duplex ;
588
-
589
- link_stat = hns3_get_link (netdev );
590
- if (!link_stat ) {
591
- cmd -> base .speed = (u32 )SPEED_UNKNOWN ;
592
- cmd -> base .duplex = DUPLEX_UNKNOWN ;
593
- }
575
+ if (netdev -> phydev )
576
+ phy_ethtool_ksettings_get (netdev -> phydev , cmd );
577
+ else if (h -> ae_algo -> ops -> get_ksettings_an_result )
578
+ h -> ae_algo -> ops -> get_ksettings_an_result (h ,
579
+ & cmd -> base .autoneg ,
580
+ & cmd -> base .speed ,
581
+ & cmd -> base .duplex );
582
+ else
583
+ return - EOPNOTSUPP ;
584
+
585
+ link_stat = hns3_get_link (netdev );
586
+ if (!link_stat ) {
587
+ cmd -> base .speed = SPEED_UNKNOWN ;
588
+ cmd -> base .duplex = DUPLEX_UNKNOWN ;
594
589
}
595
590
596
591
/* 2.media_type get from bios parameter block */
@@ -640,6 +635,9 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
640
635
break ;
641
636
}
642
637
638
+ if (!cmd -> base .autoneg )
639
+ advertised_caps &= ~HNS3_LM_AUTONEG_BIT ;
640
+
643
641
/* now, map driver link modes to ethtool link modes */
644
642
hns3_driv_to_eth_caps (supported_caps , cmd , false);
645
643
hns3_driv_to_eth_caps (advertised_caps , cmd , true);
@@ -655,6 +653,16 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
655
653
return 0 ;
656
654
}
657
655
656
+ static int hns3_set_link_ksettings (struct net_device * netdev ,
657
+ const struct ethtool_link_ksettings * cmd )
658
+ {
659
+ /* Only support ksettings_set for netdev with phy attached for now */
660
+ if (netdev -> phydev )
661
+ return phy_ethtool_ksettings_set (netdev -> phydev , cmd );
662
+
663
+ return - EOPNOTSUPP ;
664
+ }
665
+
658
666
static u32 hns3_get_rss_key_size (struct net_device * netdev )
659
667
{
660
668
struct hnae3_handle * h = hns3_get_handle (netdev );
@@ -824,6 +832,23 @@ static int hns3_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
824
832
}
825
833
}
826
834
835
+ static int hns3_nway_reset (struct net_device * netdev )
836
+ {
837
+ struct phy_device * phy = netdev -> phydev ;
838
+
839
+ if (!netif_running (netdev ))
840
+ return 0 ;
841
+
842
+ /* Only support nway_reset for netdev with phy attached for now */
843
+ if (!phy )
844
+ return - EOPNOTSUPP ;
845
+
846
+ if (phy -> autoneg != AUTONEG_ENABLE )
847
+ return - EINVAL ;
848
+
849
+ return genphy_restart_aneg (phy );
850
+ }
851
+
827
852
static const struct ethtool_ops hns3_ethtool_ops = {
828
853
.self_test = hns3_self_test ,
829
854
.get_drvinfo = hns3_get_drvinfo ,
@@ -841,6 +866,8 @@ static const struct ethtool_ops hns3_ethtool_ops = {
841
866
.get_rxfh = hns3_get_rss ,
842
867
.set_rxfh = hns3_set_rss ,
843
868
.get_link_ksettings = hns3_get_link_ksettings ,
869
+ .set_link_ksettings = hns3_set_link_ksettings ,
870
+ .nway_reset = hns3_nway_reset ,
844
871
};
845
872
846
873
void hns3_ethtool_set_ops (struct net_device * netdev )
0 commit comments