forked from openwrt/openwrt
-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
701-net-0216-dpaa2-eth-Add-autoneg-support.patch
129 lines (118 loc) · 4.55 KB
/
701-net-0216-dpaa2-eth-Add-autoneg-support.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From c6365855a6d9aef3b75e301d26872bc51398c2f3 Mon Sep 17 00:00:00 2001
From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Date: Thu, 18 Oct 2018 18:59:41 +0300
Subject: [PATCH] dpaa2-eth: Add autoneg support
For MC versions that support it, use the new DPNI link APIs, which
allow setting/getting of advertised and supported link modes.
A mapping between DPNI link modes and ethtool ones is created to
help converting from one to the other.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Valentin Catalin Neacsu <valentin-catalin.neacsu@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 8 ++-
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 3 ++
.../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 57 ++++++++++++++++++++--
3 files changed, 62 insertions(+), 6 deletions(-)
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -1357,7 +1357,13 @@ static int link_state_update(struct dpaa
bool tx_pause;
int err;
- err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, &state);
+ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_LINK_AUTONEG_VER_MAJOR,
+ DPNI_LINK_AUTONEG_VER_MINOR) < 0)
+ err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token,
+ &state);
+ else
+ err = dpni_get_link_state_v2(priv->mc_io, 0, priv->mc_token,
+ &state);
if (unlikely(err)) {
netdev_err(priv->net_dev,
"dpni_get_link_state() failed\n");
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -542,6 +542,9 @@ static inline bool dpaa2_eth_rx_pause_en
return !!(link_options & DPNI_LINK_OPT_PAUSE);
}
+#define DPNI_LINK_AUTONEG_VER_MAJOR 7
+#define DPNI_LINK_AUTONEG_VER_MINOR 8
+
static inline
unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv,
struct sk_buff *skb)
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -79,6 +79,41 @@ static void dpaa2_eth_get_drvinfo(struct
sizeof(drvinfo->bus_info));
}
+struct dpaa2_eth_link_mode_map {
+ u64 dpni_lm;
+ u64 ethtool_lm;
+};
+
+static const struct dpaa2_eth_link_mode_map dpaa2_eth_lm_map[] = {
+ {DPNI_ADVERTISED_10BASET_FULL, ETHTOOL_LINK_MODE_10baseT_Full_BIT},
+ {DPNI_ADVERTISED_100BASET_FULL, ETHTOOL_LINK_MODE_100baseT_Full_BIT},
+ {DPNI_ADVERTISED_1000BASET_FULL, ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
+ {DPNI_ADVERTISED_10000BASET_FULL, ETHTOOL_LINK_MODE_10000baseT_Full_BIT},
+ {DPNI_ADVERTISED_2500BASEX_FULL, ETHTOOL_LINK_MODE_2500baseT_Full_BIT},
+ {DPNI_ADVERTISED_AUTONEG, ETHTOOL_LINK_MODE_Autoneg_BIT},
+};
+
+static void link_mode_dpni2ethtool(u64 dpni_lm, unsigned long *ethtool_lm)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_lm_map); i++) {
+ if (dpni_lm & dpaa2_eth_lm_map[i].dpni_lm)
+ __set_bit(dpaa2_eth_lm_map[i].ethtool_lm, ethtool_lm);
+ }
+}
+
+static void link_mode_ethtool2dpni(const unsigned long *ethtool_lm,
+ u64 *dpni_lm)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dpaa2_eth_lm_map); i++) {
+ if (test_bit(dpaa2_eth_lm_map[i].ethtool_lm, ethtool_lm))
+ *dpni_lm |= dpaa2_eth_lm_map[i].dpni_lm;
+ }
+}
+
static int
dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
struct ethtool_link_ksettings *link_settings)
@@ -91,6 +126,14 @@ dpaa2_eth_get_link_ksettings(struct net_
link_settings->base.duplex = DUPLEX_FULL;
link_settings->base.speed = priv->link_state.rate;
+ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_LINK_AUTONEG_VER_MAJOR,
+ DPNI_LINK_AUTONEG_VER_MINOR) >= 0) {
+ link_mode_dpni2ethtool(priv->link_state.supported,
+ link_settings->link_modes.supported);
+ link_mode_dpni2ethtool(priv->link_state.advertising,
+ link_settings->link_modes.advertising);
+ }
+
return 0;
}
@@ -127,12 +170,16 @@ dpaa2_eth_set_link_ksettings(struct net_
else
cfg.options &= ~DPNI_LINK_OPT_HALF_DUPLEX;
- err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
+ if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_LINK_AUTONEG_VER_MAJOR,
+ DPNI_LINK_AUTONEG_VER_MINOR) < 0) {
+ err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
+ } else {
+ link_mode_ethtool2dpni(link_settings->link_modes.advertising,
+ &cfg.advertising);
+ dpni_set_link_cfg_v2(priv->mc_io, 0, priv->mc_token, &cfg);
+ }
if (err)
- /* ethtool will be loud enough if we return an error; no point
- * in putting our own error message on the console by default
- */
- netdev_dbg(net_dev, "ERROR %d setting link cfg\n", err);
+ netdev_err(net_dev, "dpni_set_link_cfg failed");
return err;
}