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 int dsa_master_get_regs_len(struct net_device
*dev
)
13 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
14 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
15 struct dsa_switch
*ds
= cpu_dp
->ds
;
16 int port
= cpu_dp
->index
;
20 if (ops
->get_regs_len
) {
21 len
= ops
->get_regs_len(dev
);
27 ret
+= sizeof(struct ethtool_drvinfo
);
28 ret
+= sizeof(struct ethtool_regs
);
30 if (ds
->ops
->get_regs_len
) {
31 len
= ds
->ops
->get_regs_len(ds
, port
);
40 static void dsa_master_get_regs(struct net_device
*dev
,
41 struct ethtool_regs
*regs
, void *data
)
43 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
44 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
45 struct dsa_switch
*ds
= cpu_dp
->ds
;
46 struct ethtool_drvinfo
*cpu_info
;
47 struct ethtool_regs
*cpu_regs
;
48 int port
= cpu_dp
->index
;
51 if (ops
->get_regs_len
&& ops
->get_regs
) {
52 len
= ops
->get_regs_len(dev
);
56 ops
->get_regs(dev
, regs
, data
);
60 cpu_info
= (struct ethtool_drvinfo
*)data
;
61 strlcpy(cpu_info
->driver
, "dsa", sizeof(cpu_info
->driver
));
62 data
+= sizeof(*cpu_info
);
63 cpu_regs
= (struct ethtool_regs
*)data
;
64 data
+= sizeof(*cpu_regs
);
66 if (ds
->ops
->get_regs_len
&& ds
->ops
->get_regs
) {
67 len
= ds
->ops
->get_regs_len(ds
, port
);
71 ds
->ops
->get_regs(ds
, port
, cpu_regs
, data
);
75 static void dsa_master_get_ethtool_stats(struct net_device
*dev
,
76 struct ethtool_stats
*stats
,
79 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
80 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
81 struct dsa_switch
*ds
= cpu_dp
->ds
;
82 int port
= cpu_dp
->index
;
85 if (ops
->get_sset_count
&& ops
->get_ethtool_stats
) {
86 count
= ops
->get_sset_count(dev
, ETH_SS_STATS
);
87 ops
->get_ethtool_stats(dev
, stats
, data
);
90 if (ds
->ops
->get_ethtool_stats
)
91 ds
->ops
->get_ethtool_stats(ds
, port
, data
+ count
);
94 static void dsa_master_get_ethtool_phy_stats(struct net_device
*dev
,
95 struct ethtool_stats
*stats
,
98 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
99 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
100 struct dsa_switch
*ds
= cpu_dp
->ds
;
101 int port
= cpu_dp
->index
;
104 if (dev
->phydev
&& !ops
->get_ethtool_phy_stats
) {
105 count
= phy_ethtool_get_sset_count(dev
->phydev
);
107 phy_ethtool_get_stats(dev
->phydev
, stats
, data
);
108 } else if (ops
->get_sset_count
&& ops
->get_ethtool_phy_stats
) {
109 count
= ops
->get_sset_count(dev
, ETH_SS_PHY_STATS
);
110 ops
->get_ethtool_phy_stats(dev
, stats
, data
);
116 if (ds
->ops
->get_ethtool_phy_stats
)
117 ds
->ops
->get_ethtool_phy_stats(ds
, port
, data
+ count
);
120 static int dsa_master_get_sset_count(struct net_device
*dev
, int sset
)
122 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
123 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
124 struct dsa_switch
*ds
= cpu_dp
->ds
;
127 if (sset
== ETH_SS_PHY_STATS
&& dev
->phydev
&&
128 !ops
->get_ethtool_phy_stats
)
129 count
= phy_ethtool_get_sset_count(dev
->phydev
);
130 else if (ops
->get_sset_count
)
131 count
= ops
->get_sset_count(dev
, sset
);
136 if (ds
->ops
->get_sset_count
)
137 count
+= ds
->ops
->get_sset_count(ds
, cpu_dp
->index
, sset
);
142 static void dsa_master_get_strings(struct net_device
*dev
, uint32_t stringset
,
145 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
146 const struct ethtool_ops
*ops
= cpu_dp
->orig_ethtool_ops
;
147 struct dsa_switch
*ds
= cpu_dp
->ds
;
148 int port
= cpu_dp
->index
;
149 int len
= ETH_GSTRING_LEN
;
150 int mcount
= 0, count
;
155 snprintf(pfx
, sizeof(pfx
), "p%.2d", port
);
156 /* We do not want to be NULL-terminated, since this is a prefix */
157 pfx
[sizeof(pfx
) - 1] = '_';
159 if (stringset
== ETH_SS_PHY_STATS
&& dev
->phydev
&&
160 !ops
->get_ethtool_phy_stats
) {
161 mcount
= phy_ethtool_get_sset_count(dev
->phydev
);
165 phy_ethtool_get_strings(dev
->phydev
, data
);
166 } else if (ops
->get_sset_count
&& ops
->get_strings
) {
167 mcount
= ops
->get_sset_count(dev
, stringset
);
170 ops
->get_strings(dev
, stringset
, data
);
173 if (ds
->ops
->get_strings
) {
174 ndata
= data
+ mcount
* len
;
175 /* This function copies ETH_GSTRINGS_LEN bytes, we will mangle
176 * the output after to prepend our CPU port prefix we
177 * constructed earlier
179 ds
->ops
->get_strings(ds
, port
, stringset
, ndata
);
180 count
= ds
->ops
->get_sset_count(ds
, port
, stringset
);
181 for (i
= 0; i
< count
; i
++) {
182 memmove(ndata
+ (i
* len
+ sizeof(pfx
)),
183 ndata
+ i
* len
, len
- sizeof(pfx
));
184 memcpy(ndata
+ i
* len
, pfx
, sizeof(pfx
));
189 static int dsa_master_get_phys_port_name(struct net_device
*dev
,
190 char *name
, size_t len
)
192 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
194 if (snprintf(name
, len
, "p%d", cpu_dp
->index
) >= len
)
200 static int dsa_master_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
202 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
203 struct dsa_switch
*ds
= cpu_dp
->ds
;
204 struct dsa_switch_tree
*dst
;
205 int err
= -EOPNOTSUPP
;
213 /* Deny PTP operations on master if there is at least one
214 * switch in the tree that is PTP capable.
216 list_for_each_entry(dp
, &dst
->ports
, list
)
217 if (dp
->ds
->ops
->port_hwtstamp_get
||
218 dp
->ds
->ops
->port_hwtstamp_set
)
223 if (cpu_dp
->orig_ndo_ops
&& cpu_dp
->orig_ndo_ops
->ndo_do_ioctl
)
224 err
= cpu_dp
->orig_ndo_ops
->ndo_do_ioctl(dev
, ifr
, cmd
);
229 static int dsa_master_ethtool_setup(struct net_device
*dev
)
231 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
232 struct dsa_switch
*ds
= cpu_dp
->ds
;
233 struct ethtool_ops
*ops
;
235 ops
= devm_kzalloc(ds
->dev
, sizeof(*ops
), GFP_KERNEL
);
239 cpu_dp
->orig_ethtool_ops
= dev
->ethtool_ops
;
240 if (cpu_dp
->orig_ethtool_ops
)
241 memcpy(ops
, cpu_dp
->orig_ethtool_ops
, sizeof(*ops
));
243 ops
->get_regs_len
= dsa_master_get_regs_len
;
244 ops
->get_regs
= dsa_master_get_regs
;
245 ops
->get_sset_count
= dsa_master_get_sset_count
;
246 ops
->get_ethtool_stats
= dsa_master_get_ethtool_stats
;
247 ops
->get_strings
= dsa_master_get_strings
;
248 ops
->get_ethtool_phy_stats
= dsa_master_get_ethtool_phy_stats
;
250 dev
->ethtool_ops
= ops
;
255 static void dsa_master_ethtool_teardown(struct net_device
*dev
)
257 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
259 dev
->ethtool_ops
= cpu_dp
->orig_ethtool_ops
;
260 cpu_dp
->orig_ethtool_ops
= NULL
;
263 static int dsa_master_ndo_setup(struct net_device
*dev
)
265 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
266 struct dsa_switch
*ds
= cpu_dp
->ds
;
267 struct net_device_ops
*ops
;
269 if (dev
->netdev_ops
->ndo_get_phys_port_name
)
272 ops
= devm_kzalloc(ds
->dev
, sizeof(*ops
), GFP_KERNEL
);
276 cpu_dp
->orig_ndo_ops
= dev
->netdev_ops
;
277 if (cpu_dp
->orig_ndo_ops
)
278 memcpy(ops
, cpu_dp
->orig_ndo_ops
, sizeof(*ops
));
280 ops
->ndo_get_phys_port_name
= dsa_master_get_phys_port_name
;
281 ops
->ndo_do_ioctl
= dsa_master_ioctl
;
283 dev
->netdev_ops
= ops
;
288 static void dsa_master_ndo_teardown(struct net_device
*dev
)
290 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
292 if (cpu_dp
->orig_ndo_ops
)
293 dev
->netdev_ops
= cpu_dp
->orig_ndo_ops
;
294 cpu_dp
->orig_ndo_ops
= NULL
;
297 static ssize_t
tagging_show(struct device
*d
, struct device_attribute
*attr
,
300 struct net_device
*dev
= to_net_dev(d
);
301 struct dsa_port
*cpu_dp
= dev
->dsa_ptr
;
303 return sprintf(buf
, "%s\n",
304 dsa_tag_protocol_to_str(cpu_dp
->tag_ops
));
306 static DEVICE_ATTR_RO(tagging
);
308 static struct attribute
*dsa_slave_attrs
[] = {
309 &dev_attr_tagging
.attr
,
313 static const struct attribute_group dsa_group
= {
315 .attrs
= dsa_slave_attrs
,
318 static void dsa_master_reset_mtu(struct net_device
*dev
)
323 err
= dev_set_mtu(dev
, ETH_DATA_LEN
);
326 "Unable to reset MTU to exclude DSA overheads\n");
330 int dsa_master_setup(struct net_device
*dev
, struct dsa_port
*cpu_dp
)
335 ret
= dev_set_mtu(dev
, ETH_DATA_LEN
+ cpu_dp
->tag_ops
->overhead
);
338 netdev_warn(dev
, "error %d setting MTU to include DSA overhead\n",
341 /* If we use a tagging format that doesn't have an ethertype
342 * field, make sure that all packets from this point on get
343 * sent to the tag format's receive function.
347 dev
->dsa_ptr
= cpu_dp
;
348 ret
= dsa_master_ethtool_setup(dev
);
352 ret
= dsa_master_ndo_setup(dev
);
354 goto out_err_ethtool_teardown
;
356 ret
= sysfs_create_group(&dev
->dev
.kobj
, &dsa_group
);
358 goto out_err_ndo_teardown
;
362 out_err_ndo_teardown
:
363 dsa_master_ndo_teardown(dev
);
364 out_err_ethtool_teardown
:
365 dsa_master_ethtool_teardown(dev
);
369 void dsa_master_teardown(struct net_device
*dev
)
371 sysfs_remove_group(&dev
->dev
.kobj
, &dsa_group
);
372 dsa_master_ndo_teardown(dev
);
373 dsa_master_ethtool_teardown(dev
);
374 dsa_master_reset_mtu(dev
);
378 /* If we used a tagging format that doesn't have an ethertype
379 * field, make sure that all packets from this point get sent
380 * without the tag and go through the regular receive path.