blob: 0a4de949f4d99867de9f82988ebc42c70a35dc62 [file] [log] [blame]
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/* Microsemi Ocelot Switch driver
3 *
Vladimir Olteanf59fd9c2021-01-15 04:11:20 +02004 * This contains glue logic between the switchdev driver operations and the
5 * mscc_ocelot_switch_lib.
6 *
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03007 * Copyright (c) 2017, 2019 Microsemi Corporation
Vladimir Olteanf59fd9c2021-01-15 04:11:20 +02008 * Copyright 2020-2021 NXP Semiconductors
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03009 */
10
11#include <linux/if_bridge.h>
Vladimir Oltean0e9bb4e2021-01-29 03:00:00 +020012#include <net/pkt_cls.h>
Vladimir Oltean9c90eea2020-06-20 18:43:44 +030013#include "ocelot.h"
Vladimir Oltean3c836542020-06-20 18:43:45 +030014#include "ocelot_vcap.h"
Vladimir Oltean9c90eea2020-06-20 18:43:44 +030015
Vladimir Olteanf59fd9c2021-01-15 04:11:20 +020016static struct ocelot *devlink_port_to_ocelot(struct devlink_port *dlp)
17{
18 return devlink_priv(dlp->devlink);
19}
20
21static int devlink_port_to_port(struct devlink_port *dlp)
22{
23 struct ocelot *ocelot = devlink_port_to_ocelot(dlp);
24
25 return dlp - ocelot->devlink_ports;
26}
27
28static int ocelot_devlink_sb_pool_get(struct devlink *dl,
29 unsigned int sb_index, u16 pool_index,
30 struct devlink_sb_pool_info *pool_info)
31{
32 struct ocelot *ocelot = devlink_priv(dl);
33
34 return ocelot_sb_pool_get(ocelot, sb_index, pool_index, pool_info);
35}
36
37static int ocelot_devlink_sb_pool_set(struct devlink *dl, unsigned int sb_index,
38 u16 pool_index, u32 size,
39 enum devlink_sb_threshold_type threshold_type,
40 struct netlink_ext_ack *extack)
41{
42 struct ocelot *ocelot = devlink_priv(dl);
43
44 return ocelot_sb_pool_set(ocelot, sb_index, pool_index, size,
45 threshold_type, extack);
46}
47
48static int ocelot_devlink_sb_port_pool_get(struct devlink_port *dlp,
49 unsigned int sb_index, u16 pool_index,
50 u32 *p_threshold)
51{
52 struct ocelot *ocelot = devlink_port_to_ocelot(dlp);
53 int port = devlink_port_to_port(dlp);
54
55 return ocelot_sb_port_pool_get(ocelot, port, sb_index, pool_index,
56 p_threshold);
57}
58
59static int ocelot_devlink_sb_port_pool_set(struct devlink_port *dlp,
60 unsigned int sb_index, u16 pool_index,
61 u32 threshold,
62 struct netlink_ext_ack *extack)
63{
64 struct ocelot *ocelot = devlink_port_to_ocelot(dlp);
65 int port = devlink_port_to_port(dlp);
66
67 return ocelot_sb_port_pool_set(ocelot, port, sb_index, pool_index,
68 threshold, extack);
69}
70
71static int
72ocelot_devlink_sb_tc_pool_bind_get(struct devlink_port *dlp,
73 unsigned int sb_index, u16 tc_index,
74 enum devlink_sb_pool_type pool_type,
75 u16 *p_pool_index, u32 *p_threshold)
76{
77 struct ocelot *ocelot = devlink_port_to_ocelot(dlp);
78 int port = devlink_port_to_port(dlp);
79
80 return ocelot_sb_tc_pool_bind_get(ocelot, port, sb_index, tc_index,
81 pool_type, p_pool_index,
82 p_threshold);
83}
84
85static int
86ocelot_devlink_sb_tc_pool_bind_set(struct devlink_port *dlp,
87 unsigned int sb_index, u16 tc_index,
88 enum devlink_sb_pool_type pool_type,
89 u16 pool_index, u32 threshold,
90 struct netlink_ext_ack *extack)
91{
92 struct ocelot *ocelot = devlink_port_to_ocelot(dlp);
93 int port = devlink_port_to_port(dlp);
94
95 return ocelot_sb_tc_pool_bind_set(ocelot, port, sb_index, tc_index,
96 pool_type, pool_index, threshold,
97 extack);
98}
99
100static int ocelot_devlink_sb_occ_snapshot(struct devlink *dl,
101 unsigned int sb_index)
102{
103 struct ocelot *ocelot = devlink_priv(dl);
104
105 return ocelot_sb_occ_snapshot(ocelot, sb_index);
106}
107
108static int ocelot_devlink_sb_occ_max_clear(struct devlink *dl,
109 unsigned int sb_index)
110{
111 struct ocelot *ocelot = devlink_priv(dl);
112
113 return ocelot_sb_occ_max_clear(ocelot, sb_index);
114}
115
116static int ocelot_devlink_sb_occ_port_pool_get(struct devlink_port *dlp,
117 unsigned int sb_index,
118 u16 pool_index, u32 *p_cur,
119 u32 *p_max)
120{
121 struct ocelot *ocelot = devlink_port_to_ocelot(dlp);
122 int port = devlink_port_to_port(dlp);
123
124 return ocelot_sb_occ_port_pool_get(ocelot, port, sb_index, pool_index,
125 p_cur, p_max);
126}
127
128static int
129ocelot_devlink_sb_occ_tc_port_bind_get(struct devlink_port *dlp,
130 unsigned int sb_index, u16 tc_index,
131 enum devlink_sb_pool_type pool_type,
132 u32 *p_cur, u32 *p_max)
133{
134 struct ocelot *ocelot = devlink_port_to_ocelot(dlp);
135 int port = devlink_port_to_port(dlp);
136
137 return ocelot_sb_occ_tc_port_bind_get(ocelot, port, sb_index,
138 tc_index, pool_type,
139 p_cur, p_max);
140}
141
Vladimir Oltean6c30384e2021-01-15 04:11:18 +0200142const struct devlink_ops ocelot_devlink_ops = {
Vladimir Olteanf59fd9c2021-01-15 04:11:20 +0200143 .sb_pool_get = ocelot_devlink_sb_pool_get,
144 .sb_pool_set = ocelot_devlink_sb_pool_set,
145 .sb_port_pool_get = ocelot_devlink_sb_port_pool_get,
146 .sb_port_pool_set = ocelot_devlink_sb_port_pool_set,
147 .sb_tc_pool_bind_get = ocelot_devlink_sb_tc_pool_bind_get,
148 .sb_tc_pool_bind_set = ocelot_devlink_sb_tc_pool_bind_set,
149 .sb_occ_snapshot = ocelot_devlink_sb_occ_snapshot,
150 .sb_occ_max_clear = ocelot_devlink_sb_occ_max_clear,
151 .sb_occ_port_pool_get = ocelot_devlink_sb_occ_port_pool_get,
152 .sb_occ_tc_port_bind_get = ocelot_devlink_sb_occ_tc_port_bind_get,
Vladimir Oltean6c30384e2021-01-15 04:11:18 +0200153};
154
155int ocelot_port_devlink_init(struct ocelot *ocelot, int port,
156 enum devlink_port_flavour flavour)
157{
158 struct devlink_port *dlp = &ocelot->devlink_ports[port];
159 int id_len = sizeof(ocelot->base_mac);
160 struct devlink *dl = ocelot->devlink;
161 struct devlink_port_attrs attrs = {};
162
163 memcpy(attrs.switch_id.id, &ocelot->base_mac, id_len);
164 attrs.switch_id.id_len = id_len;
165 attrs.phys.port_number = port;
166 attrs.flavour = flavour;
167
168 devlink_port_attrs_set(dlp, &attrs);
169
170 return devlink_port_register(dl, dlp, port);
171}
172
173void ocelot_port_devlink_teardown(struct ocelot *ocelot, int port)
174{
175 struct devlink_port *dlp = &ocelot->devlink_ports[port];
176
177 devlink_port_unregister(dlp);
178}
179
180static struct devlink_port *ocelot_get_devlink_port(struct net_device *dev)
181{
182 struct ocelot_port_private *priv = netdev_priv(dev);
183 struct ocelot *ocelot = priv->port.ocelot;
184 int port = priv->chip_port;
185
186 return &ocelot->devlink_ports[port];
187}
188
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300189int ocelot_setup_tc_cls_flower(struct ocelot_port_private *priv,
190 struct flow_cls_offload *f,
191 bool ingress)
192{
193 struct ocelot *ocelot = priv->port.ocelot;
194 int port = priv->chip_port;
195
196 if (!ingress)
197 return -EOPNOTSUPP;
198
199 switch (f->command) {
200 case FLOW_CLS_REPLACE:
201 return ocelot_cls_flower_replace(ocelot, port, f, ingress);
202 case FLOW_CLS_DESTROY:
203 return ocelot_cls_flower_destroy(ocelot, port, f, ingress);
204 case FLOW_CLS_STATS:
205 return ocelot_cls_flower_stats(ocelot, port, f, ingress);
206 default:
207 return -EOPNOTSUPP;
208 }
209}
210
211static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv,
212 struct tc_cls_matchall_offload *f,
213 bool ingress)
214{
215 struct netlink_ext_ack *extack = f->common.extack;
216 struct ocelot *ocelot = priv->port.ocelot;
217 struct ocelot_policer pol = { 0 };
218 struct flow_action_entry *action;
219 int port = priv->chip_port;
220 int err;
221
222 if (!ingress) {
223 NL_SET_ERR_MSG_MOD(extack, "Only ingress is supported");
224 return -EOPNOTSUPP;
225 }
226
227 switch (f->command) {
228 case TC_CLSMATCHALL_REPLACE:
229 if (!flow_offload_has_one_action(&f->rule->action)) {
230 NL_SET_ERR_MSG_MOD(extack,
231 "Only one action is supported");
232 return -EOPNOTSUPP;
233 }
234
235 if (priv->tc.block_shared) {
236 NL_SET_ERR_MSG_MOD(extack,
237 "Rate limit is not supported on shared blocks");
238 return -EOPNOTSUPP;
239 }
240
241 action = &f->rule->action.entries[0];
242
243 if (action->id != FLOW_ACTION_POLICE) {
244 NL_SET_ERR_MSG_MOD(extack, "Unsupported action");
245 return -EOPNOTSUPP;
246 }
247
248 if (priv->tc.police_id && priv->tc.police_id != f->cookie) {
249 NL_SET_ERR_MSG_MOD(extack,
250 "Only one policer per port is supported");
251 return -EEXIST;
252 }
253
254 pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
Po Liu5f035af2020-06-29 14:54:16 +0800255 pol.burst = action->police.burst;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300256
257 err = ocelot_port_policer_add(ocelot, port, &pol);
258 if (err) {
259 NL_SET_ERR_MSG_MOD(extack, "Could not add policer");
260 return err;
261 }
262
263 priv->tc.police_id = f->cookie;
264 priv->tc.offload_cnt++;
265 return 0;
266 case TC_CLSMATCHALL_DESTROY:
267 if (priv->tc.police_id != f->cookie)
268 return -ENOENT;
269
270 err = ocelot_port_policer_del(ocelot, port);
271 if (err) {
272 NL_SET_ERR_MSG_MOD(extack,
273 "Could not delete policer");
274 return err;
275 }
276 priv->tc.police_id = 0;
277 priv->tc.offload_cnt--;
278 return 0;
279 case TC_CLSMATCHALL_STATS:
280 default:
281 return -EOPNOTSUPP;
282 }
283}
284
285static int ocelot_setup_tc_block_cb(enum tc_setup_type type,
286 void *type_data,
287 void *cb_priv, bool ingress)
288{
289 struct ocelot_port_private *priv = cb_priv;
290
291 if (!tc_cls_can_offload_and_chain0(priv->dev, type_data))
292 return -EOPNOTSUPP;
293
294 switch (type) {
295 case TC_SETUP_CLSMATCHALL:
296 return ocelot_setup_tc_cls_matchall(priv, type_data, ingress);
297 case TC_SETUP_CLSFLOWER:
298 return ocelot_setup_tc_cls_flower(priv, type_data, ingress);
299 default:
300 return -EOPNOTSUPP;
301 }
302}
303
304static int ocelot_setup_tc_block_cb_ig(enum tc_setup_type type,
305 void *type_data,
306 void *cb_priv)
307{
308 return ocelot_setup_tc_block_cb(type, type_data,
309 cb_priv, true);
310}
311
312static int ocelot_setup_tc_block_cb_eg(enum tc_setup_type type,
313 void *type_data,
314 void *cb_priv)
315{
316 return ocelot_setup_tc_block_cb(type, type_data,
317 cb_priv, false);
318}
319
320static LIST_HEAD(ocelot_block_cb_list);
321
322static int ocelot_setup_tc_block(struct ocelot_port_private *priv,
323 struct flow_block_offload *f)
324{
325 struct flow_block_cb *block_cb;
326 flow_setup_cb_t *cb;
327
328 if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) {
329 cb = ocelot_setup_tc_block_cb_ig;
330 priv->tc.block_shared = f->block_shared;
331 } else if (f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS) {
332 cb = ocelot_setup_tc_block_cb_eg;
333 } else {
334 return -EOPNOTSUPP;
335 }
336
337 f->driver_block_list = &ocelot_block_cb_list;
338
339 switch (f->command) {
340 case FLOW_BLOCK_BIND:
341 if (flow_block_cb_is_busy(cb, priv, &ocelot_block_cb_list))
342 return -EBUSY;
343
344 block_cb = flow_block_cb_alloc(cb, priv, priv, NULL);
345 if (IS_ERR(block_cb))
346 return PTR_ERR(block_cb);
347
348 flow_block_cb_add(block_cb, f);
349 list_add_tail(&block_cb->driver_list, f->driver_block_list);
350 return 0;
351 case FLOW_BLOCK_UNBIND:
352 block_cb = flow_block_cb_lookup(f->block, cb, priv);
353 if (!block_cb)
354 return -ENOENT;
355
356 flow_block_cb_remove(block_cb, f);
357 list_del(&block_cb->driver_list);
358 return 0;
359 default:
360 return -EOPNOTSUPP;
361 }
362}
363
364static int ocelot_setup_tc(struct net_device *dev, enum tc_setup_type type,
365 void *type_data)
366{
367 struct ocelot_port_private *priv = netdev_priv(dev);
368
369 switch (type) {
370 case TC_SETUP_BLOCK:
371 return ocelot_setup_tc_block(priv, type_data);
372 default:
373 return -EOPNOTSUPP;
374 }
375 return 0;
376}
377
378static void ocelot_port_adjust_link(struct net_device *dev)
379{
380 struct ocelot_port_private *priv = netdev_priv(dev);
381 struct ocelot *ocelot = priv->port.ocelot;
382 int port = priv->chip_port;
383
384 ocelot_adjust_link(ocelot, port, dev->phydev);
385}
386
Vladimir Oltean2f0402f2020-10-31 12:29:15 +0200387static int ocelot_vlan_vid_prepare(struct net_device *dev, u16 vid, bool pvid,
388 bool untagged)
389{
390 struct ocelot_port_private *priv = netdev_priv(dev);
391 struct ocelot_port *ocelot_port = &priv->port;
392 struct ocelot *ocelot = ocelot_port->ocelot;
393 int port = priv->chip_port;
394
395 return ocelot_vlan_prepare(ocelot, port, vid, pvid, untagged);
396}
397
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300398static int ocelot_vlan_vid_add(struct net_device *dev, u16 vid, bool pvid,
399 bool untagged)
400{
401 struct ocelot_port_private *priv = netdev_priv(dev);
402 struct ocelot_port *ocelot_port = &priv->port;
403 struct ocelot *ocelot = ocelot_port->ocelot;
404 int port = priv->chip_port;
405 int ret;
406
407 ret = ocelot_vlan_add(ocelot, port, vid, pvid, untagged);
408 if (ret)
409 return ret;
410
411 /* Add the port MAC address to with the right VLAN information */
412 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr, vid,
413 ENTRYTYPE_LOCKED);
414
415 return 0;
416}
417
418static int ocelot_vlan_vid_del(struct net_device *dev, u16 vid)
419{
420 struct ocelot_port_private *priv = netdev_priv(dev);
421 struct ocelot *ocelot = priv->port.ocelot;
422 int port = priv->chip_port;
423 int ret;
424
425 /* 8021q removes VID 0 on module unload for all interfaces
426 * with VLAN filtering feature. We need to keep it to receive
427 * untagged traffic.
428 */
429 if (vid == 0)
430 return 0;
431
432 ret = ocelot_vlan_del(ocelot, port, vid);
433 if (ret)
434 return ret;
435
436 /* Del the port MAC address to with the right VLAN information */
437 ocelot_mact_forget(ocelot, dev->dev_addr, vid);
438
439 return 0;
440}
441
442static int ocelot_port_open(struct net_device *dev)
443{
444 struct ocelot_port_private *priv = netdev_priv(dev);
445 struct ocelot_port *ocelot_port = &priv->port;
446 struct ocelot *ocelot = ocelot_port->ocelot;
447 int port = priv->chip_port;
448 int err;
449
450 if (priv->serdes) {
451 err = phy_set_mode_ext(priv->serdes, PHY_MODE_ETHERNET,
452 ocelot_port->phy_mode);
453 if (err) {
454 netdev_err(dev, "Could not set mode of SerDes\n");
455 return err;
456 }
457 }
458
459 err = phy_connect_direct(dev, priv->phy, &ocelot_port_adjust_link,
460 ocelot_port->phy_mode);
461 if (err) {
462 netdev_err(dev, "Could not attach to PHY\n");
463 return err;
464 }
465
466 dev->phydev = priv->phy;
467
468 phy_attached_info(priv->phy);
469 phy_start(priv->phy);
470
471 ocelot_port_enable(ocelot, port, priv->phy);
472
473 return 0;
474}
475
476static int ocelot_port_stop(struct net_device *dev)
477{
478 struct ocelot_port_private *priv = netdev_priv(dev);
479 struct ocelot *ocelot = priv->port.ocelot;
480 int port = priv->chip_port;
481
482 phy_disconnect(priv->phy);
483
484 dev->phydev = NULL;
485
486 ocelot_port_disable(ocelot, port);
487
488 return 0;
489}
490
491/* Generate the IFH for frame injection
492 *
493 * The IFH is a 128bit-value
494 * bit 127: bypass the analyzer processing
495 * bit 56-67: destination mask
496 * bit 28-29: pop_cnt: 3 disables all rewriting of the frame
497 * bit 20-27: cpu extraction queue mask
498 * bit 16: tag type 0: C-tag, 1: S-tag
499 * bit 0-11: VID
500 */
501static int ocelot_gen_ifh(u32 *ifh, struct frame_info *info)
502{
503 ifh[0] = IFH_INJ_BYPASS | ((0x1ff & info->rew_op) << 21);
504 ifh[1] = (0xf00 & info->port) >> 8;
505 ifh[2] = (0xff & info->port) << 24;
506 ifh[3] = (info->tag_type << 16) | info->vid;
507
508 return 0;
509}
510
511static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev)
512{
513 struct ocelot_port_private *priv = netdev_priv(dev);
514 struct skb_shared_info *shinfo = skb_shinfo(skb);
515 struct ocelot_port *ocelot_port = &priv->port;
516 struct ocelot *ocelot = ocelot_port->ocelot;
517 u32 val, ifh[OCELOT_TAG_LEN / 4];
518 struct frame_info info = {};
519 u8 grp = 0; /* Send everything on CPU group 0 */
520 unsigned int i, count, last;
521 int port = priv->chip_port;
522
523 val = ocelot_read(ocelot, QS_INJ_STATUS);
524 if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))) ||
525 (val & QS_INJ_STATUS_WMARK_REACHED(BIT(grp))))
526 return NETDEV_TX_BUSY;
527
528 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
529 QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp);
530
531 info.port = BIT(port);
532 info.tag_type = IFH_TAG_TYPE_C;
533 info.vid = skb_vlan_tag_get(skb);
534
535 /* Check if timestamping is needed */
Vladimir Olteane2f9a8f2020-09-23 14:24:20 +0300536 if (ocelot->ptp && (shinfo->tx_flags & SKBTX_HW_TSTAMP)) {
537 info.rew_op = ocelot_port->ptp_cmd;
538
539 if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP) {
540 struct sk_buff *clone;
541
542 clone = skb_clone_sk(skb);
543 if (!clone) {
544 kfree_skb(skb);
545 return NETDEV_TX_OK;
546 }
547
548 ocelot_port_add_txtstamp_skb(ocelot, port, clone);
549
550 info.rew_op |= clone->cb[0] << 3;
551 }
552 }
Vladimir Oltean9dda66a2020-09-18 04:07:23 +0300553
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300554 if (ocelot->ptp && shinfo->tx_flags & SKBTX_HW_TSTAMP) {
555 info.rew_op = ocelot_port->ptp_cmd;
Vladimir Oltean65652432020-09-18 04:07:24 +0300556 if (ocelot_port->ptp_cmd == IFH_REW_OP_TWO_STEP_PTP)
557 info.rew_op |= skb->cb[0] << 3;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300558 }
559
560 ocelot_gen_ifh(ifh, &info);
561
562 for (i = 0; i < OCELOT_TAG_LEN / 4; i++)
563 ocelot_write_rix(ocelot, (__force u32)cpu_to_be32(ifh[i]),
564 QS_INJ_WR, grp);
565
566 count = (skb->len + 3) / 4;
567 last = skb->len % 4;
568 for (i = 0; i < count; i++)
569 ocelot_write_rix(ocelot, ((u32 *)skb->data)[i], QS_INJ_WR, grp);
570
571 /* Add padding */
572 while (i < (OCELOT_BUFFER_CELL_SZ / 4)) {
573 ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp);
574 i++;
575 }
576
577 /* Indicate EOF and valid bytes in last word */
578 ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
579 QS_INJ_CTRL_VLD_BYTES(skb->len < OCELOT_BUFFER_CELL_SZ ? 0 : last) |
580 QS_INJ_CTRL_EOF,
581 QS_INJ_CTRL, grp);
582
583 /* Add dummy CRC */
584 ocelot_write_rix(ocelot, 0, QS_INJ_WR, grp);
585 skb_tx_timestamp(skb);
586
587 dev->stats.tx_packets++;
588 dev->stats.tx_bytes += skb->len;
589
Vladimir Olteane2f9a8f2020-09-23 14:24:20 +0300590 kfree_skb(skb);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300591
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300592 return NETDEV_TX_OK;
593}
594
Vladimir Olteanca0b2722020-12-12 21:16:12 +0200595enum ocelot_action_type {
596 OCELOT_MACT_LEARN,
597 OCELOT_MACT_FORGET,
598};
599
600struct ocelot_mact_work_ctx {
601 struct work_struct work;
602 struct ocelot *ocelot;
603 enum ocelot_action_type type;
604 union {
605 /* OCELOT_MACT_LEARN */
606 struct {
607 unsigned char addr[ETH_ALEN];
608 u16 vid;
609 enum macaccess_entry_type entry_type;
610 int pgid;
611 } learn;
612 /* OCELOT_MACT_FORGET */
613 struct {
614 unsigned char addr[ETH_ALEN];
615 u16 vid;
616 } forget;
617 };
618};
619
620#define ocelot_work_to_ctx(x) \
621 container_of((x), struct ocelot_mact_work_ctx, work)
622
623static void ocelot_mact_work(struct work_struct *work)
624{
625 struct ocelot_mact_work_ctx *w = ocelot_work_to_ctx(work);
626 struct ocelot *ocelot = w->ocelot;
627
628 switch (w->type) {
629 case OCELOT_MACT_LEARN:
630 ocelot_mact_learn(ocelot, w->learn.pgid, w->learn.addr,
631 w->learn.vid, w->learn.entry_type);
632 break;
633 case OCELOT_MACT_FORGET:
634 ocelot_mact_forget(ocelot, w->forget.addr, w->forget.vid);
635 break;
636 default:
637 break;
Xu Wang20efd2c2021-01-15 09:55:44 +0000638 }
Vladimir Olteanca0b2722020-12-12 21:16:12 +0200639
640 kfree(w);
641}
642
643static int ocelot_enqueue_mact_action(struct ocelot *ocelot,
644 const struct ocelot_mact_work_ctx *ctx)
645{
646 struct ocelot_mact_work_ctx *w = kmemdup(ctx, sizeof(*w), GFP_ATOMIC);
647
648 if (!w)
649 return -ENOMEM;
650
651 w->ocelot = ocelot;
652 INIT_WORK(&w->work, ocelot_mact_work);
653 queue_work(ocelot->owq, &w->work);
654
655 return 0;
656}
657
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300658static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr)
659{
660 struct ocelot_port_private *priv = netdev_priv(dev);
661 struct ocelot_port *ocelot_port = &priv->port;
662 struct ocelot *ocelot = ocelot_port->ocelot;
Vladimir Olteanca0b2722020-12-12 21:16:12 +0200663 struct ocelot_mact_work_ctx w;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300664
Vladimir Olteanca0b2722020-12-12 21:16:12 +0200665 ether_addr_copy(w.forget.addr, addr);
666 w.forget.vid = ocelot_port->pvid_vlan.vid;
667 w.type = OCELOT_MACT_FORGET;
668
669 return ocelot_enqueue_mact_action(ocelot, &w);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300670}
671
672static int ocelot_mc_sync(struct net_device *dev, const unsigned char *addr)
673{
674 struct ocelot_port_private *priv = netdev_priv(dev);
675 struct ocelot_port *ocelot_port = &priv->port;
676 struct ocelot *ocelot = ocelot_port->ocelot;
Vladimir Olteanca0b2722020-12-12 21:16:12 +0200677 struct ocelot_mact_work_ctx w;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300678
Vladimir Olteanca0b2722020-12-12 21:16:12 +0200679 ether_addr_copy(w.learn.addr, addr);
680 w.learn.vid = ocelot_port->pvid_vlan.vid;
681 w.learn.pgid = PGID_CPU;
682 w.learn.entry_type = ENTRYTYPE_LOCKED;
683 w.type = OCELOT_MACT_LEARN;
684
685 return ocelot_enqueue_mact_action(ocelot, &w);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300686}
687
688static void ocelot_set_rx_mode(struct net_device *dev)
689{
690 struct ocelot_port_private *priv = netdev_priv(dev);
691 struct ocelot *ocelot = priv->port.ocelot;
692 u32 val;
693 int i;
694
695 /* This doesn't handle promiscuous mode because the bridge core is
696 * setting IFF_PROMISC on all slave interfaces and all frames would be
697 * forwarded to the CPU port.
698 */
699 val = GENMASK(ocelot->num_phys_ports - 1, 0);
Vladimir Oltean96b029b2020-06-21 14:46:02 +0300700 for_each_nonreserved_multicast_dest_pgid(ocelot, i)
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300701 ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i);
702
703 __dev_mc_sync(dev, ocelot_mc_sync, ocelot_mc_unsync);
704}
705
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300706static int ocelot_port_set_mac_address(struct net_device *dev, void *p)
707{
708 struct ocelot_port_private *priv = netdev_priv(dev);
709 struct ocelot_port *ocelot_port = &priv->port;
710 struct ocelot *ocelot = ocelot_port->ocelot;
711 const struct sockaddr *addr = p;
712
713 /* Learn the new net device MAC address in the mac table. */
Vladimir Olteanc3e58a752020-10-31 12:29:12 +0200714 ocelot_mact_learn(ocelot, PGID_CPU, addr->sa_data,
715 ocelot_port->pvid_vlan.vid, ENTRYTYPE_LOCKED);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300716 /* Then forget the previous one. */
Vladimir Olteanc3e58a752020-10-31 12:29:12 +0200717 ocelot_mact_forget(ocelot, dev->dev_addr, ocelot_port->pvid_vlan.vid);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300718
719 ether_addr_copy(dev->dev_addr, addr->sa_data);
720 return 0;
721}
722
723static void ocelot_get_stats64(struct net_device *dev,
724 struct rtnl_link_stats64 *stats)
725{
726 struct ocelot_port_private *priv = netdev_priv(dev);
727 struct ocelot *ocelot = priv->port.ocelot;
728 int port = priv->chip_port;
729
730 /* Configure the port to read the stats from */
731 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port),
732 SYS_STAT_CFG);
733
734 /* Get Rx stats */
735 stats->rx_bytes = ocelot_read(ocelot, SYS_COUNT_RX_OCTETS);
736 stats->rx_packets = ocelot_read(ocelot, SYS_COUNT_RX_SHORTS) +
737 ocelot_read(ocelot, SYS_COUNT_RX_FRAGMENTS) +
738 ocelot_read(ocelot, SYS_COUNT_RX_JABBERS) +
739 ocelot_read(ocelot, SYS_COUNT_RX_LONGS) +
740 ocelot_read(ocelot, SYS_COUNT_RX_64) +
741 ocelot_read(ocelot, SYS_COUNT_RX_65_127) +
742 ocelot_read(ocelot, SYS_COUNT_RX_128_255) +
743 ocelot_read(ocelot, SYS_COUNT_RX_256_1023) +
744 ocelot_read(ocelot, SYS_COUNT_RX_1024_1526) +
745 ocelot_read(ocelot, SYS_COUNT_RX_1527_MAX);
746 stats->multicast = ocelot_read(ocelot, SYS_COUNT_RX_MULTICAST);
747 stats->rx_dropped = dev->stats.rx_dropped;
748
749 /* Get Tx stats */
750 stats->tx_bytes = ocelot_read(ocelot, SYS_COUNT_TX_OCTETS);
751 stats->tx_packets = ocelot_read(ocelot, SYS_COUNT_TX_64) +
752 ocelot_read(ocelot, SYS_COUNT_TX_65_127) +
753 ocelot_read(ocelot, SYS_COUNT_TX_128_511) +
754 ocelot_read(ocelot, SYS_COUNT_TX_512_1023) +
755 ocelot_read(ocelot, SYS_COUNT_TX_1024_1526) +
756 ocelot_read(ocelot, SYS_COUNT_TX_1527_MAX);
757 stats->tx_dropped = ocelot_read(ocelot, SYS_COUNT_TX_DROPS) +
758 ocelot_read(ocelot, SYS_COUNT_TX_AGING);
759 stats->collisions = ocelot_read(ocelot, SYS_COUNT_TX_COLLISION);
760}
761
762static int ocelot_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
763 struct net_device *dev,
764 const unsigned char *addr,
765 u16 vid, u16 flags,
766 struct netlink_ext_ack *extack)
767{
768 struct ocelot_port_private *priv = netdev_priv(dev);
769 struct ocelot *ocelot = priv->port.ocelot;
770 int port = priv->chip_port;
771
772 return ocelot_fdb_add(ocelot, port, addr, vid);
773}
774
775static int ocelot_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
776 struct net_device *dev,
777 const unsigned char *addr, u16 vid)
778{
779 struct ocelot_port_private *priv = netdev_priv(dev);
780 struct ocelot *ocelot = priv->port.ocelot;
781 int port = priv->chip_port;
782
783 return ocelot_fdb_del(ocelot, port, addr, vid);
784}
785
786static int ocelot_port_fdb_dump(struct sk_buff *skb,
787 struct netlink_callback *cb,
788 struct net_device *dev,
789 struct net_device *filter_dev, int *idx)
790{
791 struct ocelot_port_private *priv = netdev_priv(dev);
792 struct ocelot *ocelot = priv->port.ocelot;
793 struct ocelot_dump_ctx dump = {
794 .dev = dev,
795 .skb = skb,
796 .cb = cb,
797 .idx = *idx,
798 };
799 int port = priv->chip_port;
800 int ret;
801
802 ret = ocelot_fdb_dump(ocelot, port, ocelot_port_fdb_do_dump, &dump);
803
804 *idx = dump.idx;
805
806 return ret;
807}
808
809static int ocelot_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
810 u16 vid)
811{
812 return ocelot_vlan_vid_add(dev, vid, false, false);
813}
814
815static int ocelot_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
816 u16 vid)
817{
818 return ocelot_vlan_vid_del(dev, vid);
819}
820
821static void ocelot_vlan_mode(struct ocelot *ocelot, int port,
822 netdev_features_t features)
823{
824 u32 val;
825
826 /* Filtering */
827 val = ocelot_read(ocelot, ANA_VLANMASK);
828 if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
829 val |= BIT(port);
830 else
831 val &= ~BIT(port);
832 ocelot_write(ocelot, val, ANA_VLANMASK);
833}
834
835static int ocelot_set_features(struct net_device *dev,
836 netdev_features_t features)
837{
838 netdev_features_t changed = dev->features ^ features;
839 struct ocelot_port_private *priv = netdev_priv(dev);
840 struct ocelot *ocelot = priv->port.ocelot;
841 int port = priv->chip_port;
842
843 if ((dev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
844 priv->tc.offload_cnt) {
845 netdev_err(dev,
846 "Cannot disable HW TC offload while offloads active\n");
847 return -EBUSY;
848 }
849
850 if (changed & NETIF_F_HW_VLAN_CTAG_FILTER)
851 ocelot_vlan_mode(ocelot, port, features);
852
853 return 0;
854}
855
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300856static int ocelot_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
857{
858 struct ocelot_port_private *priv = netdev_priv(dev);
859 struct ocelot *ocelot = priv->port.ocelot;
860 int port = priv->chip_port;
861
862 /* If the attached PHY device isn't capable of timestamping operations,
863 * use our own (when possible).
864 */
865 if (!phy_has_hwtstamp(dev->phydev) && ocelot->ptp) {
866 switch (cmd) {
867 case SIOCSHWTSTAMP:
868 return ocelot_hwstamp_set(ocelot, port, ifr);
869 case SIOCGHWTSTAMP:
870 return ocelot_hwstamp_get(ocelot, port, ifr);
871 }
872 }
873
874 return phy_mii_ioctl(dev->phydev, ifr, cmd);
875}
876
877static const struct net_device_ops ocelot_port_netdev_ops = {
878 .ndo_open = ocelot_port_open,
879 .ndo_stop = ocelot_port_stop,
880 .ndo_start_xmit = ocelot_port_xmit,
881 .ndo_set_rx_mode = ocelot_set_rx_mode,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300882 .ndo_set_mac_address = ocelot_port_set_mac_address,
883 .ndo_get_stats64 = ocelot_get_stats64,
884 .ndo_fdb_add = ocelot_port_fdb_add,
885 .ndo_fdb_del = ocelot_port_fdb_del,
886 .ndo_fdb_dump = ocelot_port_fdb_dump,
887 .ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid,
888 .ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid,
889 .ndo_set_features = ocelot_set_features,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300890 .ndo_setup_tc = ocelot_setup_tc,
891 .ndo_do_ioctl = ocelot_ioctl,
Vladimir Oltean6c30384e2021-01-15 04:11:18 +0200892 .ndo_get_devlink_port = ocelot_get_devlink_port,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300893};
894
Vladimir Oltean319e4dd2020-10-02 15:02:21 +0300895struct net_device *ocelot_port_to_netdev(struct ocelot *ocelot, int port)
896{
897 struct ocelot_port *ocelot_port = ocelot->ports[port];
898 struct ocelot_port_private *priv;
899
900 if (!ocelot_port)
901 return NULL;
902
903 priv = container_of(ocelot_port, struct ocelot_port_private, port);
904
905 return priv->dev;
906}
907
Vladimir Oltean7e38b032020-10-11 12:20:41 +0300908/* Checks if the net_device instance given to us originates from our driver */
909static bool ocelot_netdevice_dev_check(const struct net_device *dev)
Vladimir Oltean319e4dd2020-10-02 15:02:21 +0300910{
911 return dev->netdev_ops == &ocelot_port_netdev_ops;
912}
913
914int ocelot_netdev_to_port(struct net_device *dev)
915{
916 struct ocelot_port_private *priv;
917
Vladimir Oltean7e38b032020-10-11 12:20:41 +0300918 if (!dev || !ocelot_netdevice_dev_check(dev))
Vladimir Oltean319e4dd2020-10-02 15:02:21 +0300919 return -EINVAL;
920
921 priv = netdev_priv(dev);
922
923 return priv->chip_port;
924}
925
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300926static void ocelot_port_get_strings(struct net_device *netdev, u32 sset,
927 u8 *data)
928{
929 struct ocelot_port_private *priv = netdev_priv(netdev);
930 struct ocelot *ocelot = priv->port.ocelot;
931 int port = priv->chip_port;
932
933 ocelot_get_strings(ocelot, port, sset, data);
934}
935
936static void ocelot_port_get_ethtool_stats(struct net_device *dev,
937 struct ethtool_stats *stats,
938 u64 *data)
939{
940 struct ocelot_port_private *priv = netdev_priv(dev);
941 struct ocelot *ocelot = priv->port.ocelot;
942 int port = priv->chip_port;
943
944 ocelot_get_ethtool_stats(ocelot, port, data);
945}
946
947static int ocelot_port_get_sset_count(struct net_device *dev, int sset)
948{
949 struct ocelot_port_private *priv = netdev_priv(dev);
950 struct ocelot *ocelot = priv->port.ocelot;
951 int port = priv->chip_port;
952
953 return ocelot_get_sset_count(ocelot, port, sset);
954}
955
956static int ocelot_port_get_ts_info(struct net_device *dev,
957 struct ethtool_ts_info *info)
958{
959 struct ocelot_port_private *priv = netdev_priv(dev);
960 struct ocelot *ocelot = priv->port.ocelot;
961 int port = priv->chip_port;
962
963 if (!ocelot->ptp)
964 return ethtool_op_get_ts_info(dev, info);
965
966 return ocelot_get_ts_info(ocelot, port, info);
967}
968
969static const struct ethtool_ops ocelot_ethtool_ops = {
970 .get_strings = ocelot_port_get_strings,
971 .get_ethtool_stats = ocelot_port_get_ethtool_stats,
972 .get_sset_count = ocelot_port_get_sset_count,
973 .get_link_ksettings = phy_ethtool_get_link_ksettings,
974 .set_link_ksettings = phy_ethtool_set_link_ksettings,
975 .get_ts_info = ocelot_port_get_ts_info,
976};
977
978static void ocelot_port_attr_stp_state_set(struct ocelot *ocelot, int port,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300979 u8 state)
980{
Vladimir Oltean9c90eea2020-06-20 18:43:44 +0300981 ocelot_bridge_stp_state_set(ocelot, port, state);
982}
983
984static void ocelot_port_attr_ageing_set(struct ocelot *ocelot, int port,
985 unsigned long ageing_clock_t)
986{
987 unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
988 u32 ageing_time = jiffies_to_msecs(ageing_jiffies);
989
990 ocelot_set_ageing_time(ocelot, ageing_time);
991}
992
993static void ocelot_port_attr_mc_set(struct ocelot *ocelot, int port, bool mc)
994{
995 u32 cpu_fwd_mcast = ANA_PORT_CPU_FWD_CFG_CPU_IGMP_REDIR_ENA |
996 ANA_PORT_CPU_FWD_CFG_CPU_MLD_REDIR_ENA |
997 ANA_PORT_CPU_FWD_CFG_CPU_IPMC_CTRL_COPY_ENA;
998 u32 val = 0;
999
1000 if (mc)
1001 val = cpu_fwd_mcast;
1002
1003 ocelot_rmw_gix(ocelot, val, cpu_fwd_mcast,
1004 ANA_PORT_CPU_FWD_CFG, port);
1005}
1006
1007static int ocelot_port_attr_set(struct net_device *dev,
Vladimir Olteanbae33f22021-01-09 02:01:50 +02001008 const struct switchdev_attr *attr)
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001009{
1010 struct ocelot_port_private *priv = netdev_priv(dev);
1011 struct ocelot *ocelot = priv->port.ocelot;
1012 int port = priv->chip_port;
1013 int err = 0;
1014
1015 switch (attr->id) {
1016 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
Vladimir Olteanbae33f22021-01-09 02:01:50 +02001017 ocelot_port_attr_stp_state_set(ocelot, port, attr->u.stp_state);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001018 break;
1019 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
1020 ocelot_port_attr_ageing_set(ocelot, port, attr->u.ageing_time);
1021 break;
1022 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
Vladimir Olteanbae33f22021-01-09 02:01:50 +02001023 ocelot_port_vlan_filtering(ocelot, port, attr->u.vlan_filtering);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001024 break;
1025 case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
1026 ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled);
1027 break;
1028 default:
1029 err = -EOPNOTSUPP;
1030 break;
1031 }
1032
1033 return err;
1034}
1035
1036static int ocelot_port_obj_add_vlan(struct net_device *dev,
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001037 const struct switchdev_obj_port_vlan *vlan)
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001038{
Vladimir Olteanb7a9e0d2021-01-09 02:01:46 +02001039 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1040 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001041 int ret;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001042
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001043 ret = ocelot_vlan_vid_prepare(dev, vlan->vid, pvid, untagged);
1044 if (ret)
1045 return ret;
Vladimir Oltean2f0402f2020-10-31 12:29:15 +02001046
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001047 return ocelot_vlan_vid_add(dev, vlan->vid, pvid, untagged);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001048}
1049
Vladimir Oltean209edf92020-06-21 14:46:01 +03001050static int ocelot_port_obj_add_mdb(struct net_device *dev,
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001051 const struct switchdev_obj_port_mdb *mdb)
Vladimir Oltean209edf92020-06-21 14:46:01 +03001052{
1053 struct ocelot_port_private *priv = netdev_priv(dev);
1054 struct ocelot_port *ocelot_port = &priv->port;
1055 struct ocelot *ocelot = ocelot_port->ocelot;
1056 int port = priv->chip_port;
1057
Vladimir Oltean209edf92020-06-21 14:46:01 +03001058 return ocelot_port_mdb_add(ocelot, port, mdb);
1059}
1060
1061static int ocelot_port_obj_del_mdb(struct net_device *dev,
1062 const struct switchdev_obj_port_mdb *mdb)
1063{
1064 struct ocelot_port_private *priv = netdev_priv(dev);
1065 struct ocelot_port *ocelot_port = &priv->port;
1066 struct ocelot *ocelot = ocelot_port->ocelot;
1067 int port = priv->chip_port;
1068
1069 return ocelot_port_mdb_del(ocelot, port, mdb);
1070}
1071
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001072static int ocelot_port_obj_add(struct net_device *dev,
1073 const struct switchdev_obj *obj,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001074 struct netlink_ext_ack *extack)
1075{
1076 int ret = 0;
1077
1078 switch (obj->id) {
1079 case SWITCHDEV_OBJ_ID_PORT_VLAN:
1080 ret = ocelot_port_obj_add_vlan(dev,
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001081 SWITCHDEV_OBJ_PORT_VLAN(obj));
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001082 break;
1083 case SWITCHDEV_OBJ_ID_PORT_MDB:
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001084 ret = ocelot_port_obj_add_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001085 break;
1086 default:
1087 return -EOPNOTSUPP;
1088 }
1089
1090 return ret;
1091}
1092
1093static int ocelot_port_obj_del(struct net_device *dev,
1094 const struct switchdev_obj *obj)
1095{
1096 int ret = 0;
1097
1098 switch (obj->id) {
1099 case SWITCHDEV_OBJ_ID_PORT_VLAN:
Vladimir Olteanb7a9e0d2021-01-09 02:01:46 +02001100 ret = ocelot_vlan_vid_del(dev,
1101 SWITCHDEV_OBJ_PORT_VLAN(obj)->vid);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001102 break;
1103 case SWITCHDEV_OBJ_ID_PORT_MDB:
1104 ret = ocelot_port_obj_del_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
1105 break;
1106 default:
1107 return -EOPNOTSUPP;
1108 }
1109
1110 return ret;
1111}
1112
Vladimir Oltean662981b2021-02-06 00:02:10 +02001113static int ocelot_netdevice_changeupper(struct net_device *dev,
1114 struct netdev_notifier_changeupper_info *info)
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001115{
1116 struct ocelot_port_private *priv = netdev_priv(dev);
1117 struct ocelot_port *ocelot_port = &priv->port;
1118 struct ocelot *ocelot = ocelot_port->ocelot;
1119 int port = priv->chip_port;
1120 int err = 0;
1121
Vladimir Oltean662981b2021-02-06 00:02:10 +02001122 if (netif_is_bridge_master(info->upper_dev)) {
1123 if (info->linking) {
1124 err = ocelot_port_bridge_join(ocelot, port,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001125 info->upper_dev);
Vladimir Oltean662981b2021-02-06 00:02:10 +02001126 } else {
1127 err = ocelot_port_bridge_leave(ocelot, port,
1128 info->upper_dev);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001129 }
Vladimir Oltean662981b2021-02-06 00:02:10 +02001130 }
1131 if (netif_is_lag_master(info->upper_dev)) {
Vladimir Oltean583cbbe2021-02-06 00:02:12 +02001132 if (info->linking) {
Vladimir Oltean662981b2021-02-06 00:02:10 +02001133 err = ocelot_port_lag_join(ocelot, port,
Vladimir Oltean583cbbe2021-02-06 00:02:12 +02001134 info->upper_dev,
1135 info->upper_info);
1136 if (err == -EOPNOTSUPP) {
1137 NL_SET_ERR_MSG_MOD(info->info.extack,
1138 "Offloading not supported");
1139 err = 0;
1140 }
1141 } else {
Vladimir Oltean662981b2021-02-06 00:02:10 +02001142 ocelot_port_lag_leave(ocelot, port,
1143 info->upper_dev);
Vladimir Oltean583cbbe2021-02-06 00:02:12 +02001144 }
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001145 }
1146
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001147 return notifier_from_errno(err);
1148}
1149
1150static int
1151ocelot_netdevice_lag_changeupper(struct net_device *dev,
1152 struct netdev_notifier_changeupper_info *info)
1153{
1154 struct net_device *lower;
1155 struct list_head *iter;
1156 int err = NOTIFY_DONE;
1157
1158 netdev_for_each_lower_dev(dev, lower, iter) {
1159 err = ocelot_netdevice_changeupper(lower, info);
1160 if (err)
1161 return notifier_from_errno(err);
1162 }
1163
1164 return NOTIFY_DONE;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001165}
1166
1167static int ocelot_netdevice_event(struct notifier_block *unused,
1168 unsigned long event, void *ptr)
1169{
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001170 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001171
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001172 switch (event) {
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001173 case NETDEV_CHANGEUPPER: {
1174 struct netdev_notifier_changeupper_info *info = ptr;
1175
1176 if (ocelot_netdevice_dev_check(dev))
1177 return ocelot_netdevice_changeupper(dev, info);
1178
1179 if (netif_is_lag_master(dev))
1180 return ocelot_netdevice_lag_changeupper(dev, info);
1181
1182 break;
1183 }
1184 default:
1185 break;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001186 }
1187
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001188 return NOTIFY_DONE;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001189}
1190
1191struct notifier_block ocelot_netdevice_nb __read_mostly = {
1192 .notifier_call = ocelot_netdevice_event,
1193};
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001194
1195static int ocelot_switchdev_event(struct notifier_block *unused,
1196 unsigned long event, void *ptr)
1197{
1198 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1199 int err;
1200
1201 switch (event) {
1202 case SWITCHDEV_PORT_ATTR_SET:
1203 err = switchdev_handle_port_attr_set(dev, ptr,
1204 ocelot_netdevice_dev_check,
1205 ocelot_port_attr_set);
1206 return notifier_from_errno(err);
1207 }
1208
1209 return NOTIFY_DONE;
1210}
1211
1212struct notifier_block ocelot_switchdev_nb __read_mostly = {
1213 .notifier_call = ocelot_switchdev_event,
1214};
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001215
1216static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
1217 unsigned long event, void *ptr)
1218{
1219 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1220 int err;
1221
1222 switch (event) {
1223 /* Blocking events. */
1224 case SWITCHDEV_PORT_OBJ_ADD:
1225 err = switchdev_handle_port_obj_add(dev, ptr,
1226 ocelot_netdevice_dev_check,
1227 ocelot_port_obj_add);
1228 return notifier_from_errno(err);
1229 case SWITCHDEV_PORT_OBJ_DEL:
1230 err = switchdev_handle_port_obj_del(dev, ptr,
1231 ocelot_netdevice_dev_check,
1232 ocelot_port_obj_del);
1233 return notifier_from_errno(err);
1234 case SWITCHDEV_PORT_ATTR_SET:
1235 err = switchdev_handle_port_attr_set(dev, ptr,
1236 ocelot_netdevice_dev_check,
1237 ocelot_port_attr_set);
1238 return notifier_from_errno(err);
1239 }
1240
1241 return NOTIFY_DONE;
1242}
1243
1244struct notifier_block ocelot_switchdev_blocking_nb __read_mostly = {
1245 .notifier_call = ocelot_switchdev_blocking_event,
1246};
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001247
Vladimir Oltean91c724c2020-07-13 19:57:01 +03001248int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001249 struct phy_device *phy)
1250{
1251 struct ocelot_port_private *priv;
1252 struct ocelot_port *ocelot_port;
1253 struct net_device *dev;
1254 int err;
1255
1256 dev = alloc_etherdev(sizeof(struct ocelot_port_private));
1257 if (!dev)
1258 return -ENOMEM;
1259 SET_NETDEV_DEV(dev, ocelot->dev);
1260 priv = netdev_priv(dev);
1261 priv->dev = dev;
1262 priv->phy = phy;
1263 priv->chip_port = port;
1264 ocelot_port = &priv->port;
1265 ocelot_port->ocelot = ocelot;
Vladimir Oltean91c724c2020-07-13 19:57:01 +03001266 ocelot_port->target = target;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001267 ocelot->ports[port] = ocelot_port;
1268
1269 dev->netdev_ops = &ocelot_port_netdev_ops;
1270 dev->ethtool_ops = &ocelot_ethtool_ops;
1271
1272 dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS |
1273 NETIF_F_HW_TC;
1274 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
1275
1276 memcpy(dev->dev_addr, ocelot->base_mac, ETH_ALEN);
1277 dev->dev_addr[ETH_ALEN - 1] += port;
Vladimir Olteanc3e58a752020-10-31 12:29:12 +02001278 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr,
1279 ocelot_port->pvid_vlan.vid, ENTRYTYPE_LOCKED);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001280
1281 ocelot_init_port(ocelot, port);
1282
1283 err = register_netdev(dev);
1284 if (err) {
1285 dev_err(ocelot->dev, "register_netdev failed\n");
1286 free_netdev(dev);
Dan Carpentere0c16232021-02-02 12:12:38 +03001287 ocelot->ports[port] = NULL;
1288 return err;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001289 }
1290
Dan Carpentere0c16232021-02-02 12:12:38 +03001291 return 0;
1292}
1293
1294void ocelot_release_port(struct ocelot_port *ocelot_port)
1295{
1296 struct ocelot_port_private *priv = container_of(ocelot_port,
1297 struct ocelot_port_private,
1298 port);
1299
1300 unregister_netdev(priv->dev);
1301 free_netdev(priv->dev);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001302}