1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Handling of a master device, switching frames via its switch fabric CPU port
5 * Copyright (c) 2017 Savoir-faire Linux Inc.
6 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
11 static void dsa_master_get_ethtool_stats(struct net_device
*dev
,
12 struct ethtool_stats
*stats
,
15 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
16 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
17 struct dsa_switch
*ds
= cpu_dp
->ds
;
18 int port
= cpu_dp
->index
;
21 if (ops
->get_sset_count
&& ops
->get_ethtool_stats
) {
22 count
= ops
->get_sset_count(dev
, ETH_SS_STATS
);
23 ops
->get_ethtool_stats(dev
, stats
, data
);
26 if (ds
->ops
->get_ethtool_stats
)
27 ds
->ops
->get_ethtool_stats(ds
, port
, data
+ count
);
30 static void dsa_master_get_ethtool_phy_stats(struct net_device
*dev
,
31 struct ethtool_stats
*stats
,
34 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
35 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
36 struct dsa_switch
*ds
= cpu_dp
->ds
;
37 int port
= cpu_dp
->index
;
40 if (dev
->phydev
&& !ops
->get_ethtool_phy_stats
) {
41 count
= phy_ethtool_get_sset_count(dev
->phydev
);
43 phy_ethtool_get_stats(dev
->phydev
, stats
, data
);
44 } else if (ops
->get_sset_count
&& ops
->get_ethtool_phy_stats
) {
45 count
= ops
->get_sset_count(dev
, ETH_SS_PHY_STATS
);
46 ops
->get_ethtool_phy_stats(dev
, stats
, data
);
52 if (ds
->ops
->get_ethtool_phy_stats
)
53 ds
->ops
->get_ethtool_phy_stats(ds
, port
, data
+ count
);
56 static int dsa_master_get_sset_count(struct net_device
*dev
, int sset
)
58 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
59 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
60 struct dsa_switch
*ds
= cpu_dp
->ds
;
63 if (sset
== ETH_SS_PHY_STATS
&& dev
->phydev
&&
64 !ops
->get_ethtool_phy_stats
)
65 count
= phy_ethtool_get_sset_count(dev
->phydev
);
66 else if (ops
->get_sset_count
)
67 count
= ops
->get_sset_count(dev
, sset
);
72 if (ds
->ops
->get_sset_count
)
73 count
+= ds
->ops
->get_sset_count(ds
, cpu_dp
->index
, sset
);
78 static void dsa_master_get_strings(struct net_device
*dev
, uint32_t stringset
,
81 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
82 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
83 struct dsa_switch
*ds
= cpu_dp
->ds
;
84 int port
= cpu_dp
->index
;
85 int len
= ETH_GSTRING_LEN
;
86 int mcount
= 0, count
;
91 snprintf(pfx
, sizeof(pfx
), "p%.2d", port
);
92 /* We do not want to be NULL-terminated, since this is a prefix */
93 pfx
[sizeof(pfx
) - 1] = '_';
95 if (stringset
== ETH_SS_PHY_STATS
&& dev
->phydev
&&
96 !ops
->get_ethtool_phy_stats
) {
97 mcount
= phy_ethtool_get_sset_count(dev
->phydev
);
101 phy_ethtool_get_strings(dev
->phydev
, data
);
102 } else if (ops
->get_sset_count
&& ops
->get_strings
) {
103 mcount
= ops
->get_sset_count(dev
, stringset
);
106 ops
->get_strings(dev
, stringset
, data
);
109 if (ds
->ops
->get_strings
) {
110 ndata
= data
+ mcount
* len
;
111 /* This function copies ETH_GSTRINGS_LEN bytes, we will mangle
112 * the output after to prepend our CPU port prefix we
113 * constructed earlier
115 ds
->ops
->get_strings(ds
, port
, stringset
, ndata
);
116 count
= ds
->ops
->get_sset_count(ds
, port
, stringset
);
117 for (i
= 0; i
< count
; i
++) {
118 memmove(ndata
+ (i
* len
+ sizeof(pfx
)),
119 ndata
+ i
* len
, len
- sizeof(pfx
));
120 memcpy(ndata
+ i
* len
, pfx
, sizeof(pfx
));
125 static int dsa_master_get_phys_port_name(struct net_device
*dev
,
126 char *name
, size_t len
)
128 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
130 if (snprintf(name
, len
, "p%d", cpu_dp
->index
) >= len
)
136 static int dsa_master_ethtool_setup(struct net_device
*dev
)
138 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
139 struct dsa_switch
*ds
= cpu_dp
->ds
;
140 struct ethtool_ops
*ops
;
142 ops
= devm_kzalloc(ds
->dev
, sizeof(*ops
), GFP_KERNEL
);
146 cpu_dp
->orig_ethtool_ops
= dev
->ethtool_ops
;
147 if (cpu_dp
->orig_ethtool_ops
)
148 memcpy(ops
, cpu_dp
->orig_ethtool_ops
, sizeof(*ops
));
150 ops
->get_sset_count
= dsa_master_get_sset_count
;
151 ops
->get_ethtool_stats
= dsa_master_get_ethtool_stats
;
152 ops
->get_strings
= dsa_master_get_strings
;
153 ops
->get_ethtool_phy_stats
= dsa_master_get_ethtool_phy_stats
;
155 dev
->ethtool_ops
= ops
;
160 static void dsa_master_ethtool_teardown(struct net_device
*dev
)
162 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
164 dev
->ethtool_ops
= cpu_dp
->orig_ethtool_ops
;
165 cpu_dp
->orig_ethtool_ops
= NULL
;
168 static int dsa_master_ndo_setup(struct net_device
*dev
)
170 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
171 struct dsa_switch
*ds
= cpu_dp
->ds
;
172 struct net_device_ops
*ops
;
174 if (dev
->netdev_ops
->ndo_get_phys_port_name
)
177 ops
= devm_kzalloc(ds
->dev
, sizeof(*ops
), GFP_KERNEL
);
181 cpu_dp
->orig_ndo_ops
= dev
->netdev_ops
;
182 if (cpu_dp
->orig_ndo_ops
)
183 memcpy(ops
, cpu_dp
->orig_ndo_ops
, sizeof(*ops
));
185 ops
->ndo_get_phys_port_name
= dsa_master_get_phys_port_name
;
187 dev
->netdev_ops
= ops
;
192 static void dsa_master_ndo_teardown(struct net_device
*dev
)
194 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
196 dev
->netdev_ops
= cpu_dp
->orig_ndo_ops
;
197 cpu_dp
->orig_ndo_ops
= NULL
;
200 static ssize_t
tagging_show(struct device
*d
, struct device_attribute
*attr
,
203 struct net_device
*dev
= to_net_dev(d
);
204 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
206 return sprintf(buf
, "%s\n",
207 dsa_tag_protocol_to_str(cpu_dp
->tag_ops
));
209 static DEVICE_ATTR_RO(tagging
);
211 static struct attribute
*dsa_slave_attrs
[] = {
212 &dev_attr_tagging
.attr
,
216 static const struct attribute_group dsa_group
= {
218 .attrs
= dsa_slave_attrs
,
221 static void dsa_master_set_mtu(struct net_device
*dev
, struct dsa_port
*cpu_dp
)
223 unsigned int mtu
= ETH_DATA_LEN
+ cpu_dp
->tag_ops
->overhead
;
227 if (mtu
<= dev
->max_mtu
) {
228 err
= dev_set_mtu(dev
, mtu
);
230 netdev_dbg(dev
, "Unable to set MTU to include for DSA overheads\n");
235 static void dsa_master_reset_mtu(struct net_device
*dev
)
240 err
= dev_set_mtu(dev
, ETH_DATA_LEN
);
243 "Unable to reset MTU to exclude DSA overheads\n");
247 static struct lock_class_key dsa_master_addr_list_lock_key
;
249 int dsa_master_setup(struct net_device
*dev
, struct dsa_port
*cpu_dp
)
253 dsa_master_set_mtu(dev
, cpu_dp
);
255 /* If we use a tagging format that doesn't have an ethertype
256 * field, make sure that all packets from this point on get
257 * sent to the tag format's receive function.
261 dev
->dsa_ptr
= cpu_dp
;
262 lockdep_set_class(&dev
->addr_list_lock
,
263 &dsa_master_addr_list_lock_key
);
265 ret
= dsa_master_ethtool_setup(dev
);
269 ret
= dsa_master_ndo_setup(dev
);
271 goto out_err_ethtool_teardown
;
273 ret
= sysfs_create_group(&dev
->dev
.kobj
, &dsa_group
);
275 goto out_err_ndo_teardown
;
279 out_err_ndo_teardown
:
280 dsa_master_ndo_teardown(dev
);
281 out_err_ethtool_teardown
:
282 dsa_master_ethtool_teardown(dev
);
286 void dsa_master_teardown(struct net_device
*dev
)
288 sysfs_remove_group(&dev
->dev
.kobj
, &dsa_group
);
289 dsa_master_ndo_teardown(dev
);
290 dsa_master_ethtool_teardown(dev
);
291 dsa_master_reset_mtu(dev
);
295 /* If we used a tagging format that doesn't have an ethertype
296 * field, make sure that all packets from this point get sent
297 * without the tag and go through the regular receive path.