blob: b5ffe6724eb7b9ca3337d5850d49f931e5f9c9b4 [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 Oltean4c08c582021-02-12 17:15:51 +02001008 const struct switchdev_attr *attr,
1009 struct netlink_ext_ack *extack)
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001010{
1011 struct ocelot_port_private *priv = netdev_priv(dev);
1012 struct ocelot *ocelot = priv->port.ocelot;
1013 int port = priv->chip_port;
1014 int err = 0;
1015
1016 switch (attr->id) {
1017 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
Vladimir Olteanbae33f22021-01-09 02:01:50 +02001018 ocelot_port_attr_stp_state_set(ocelot, port, attr->u.stp_state);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001019 break;
1020 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
1021 ocelot_port_attr_ageing_set(ocelot, port, attr->u.ageing_time);
1022 break;
1023 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
Vladimir Olteanbae33f22021-01-09 02:01:50 +02001024 ocelot_port_vlan_filtering(ocelot, port, attr->u.vlan_filtering);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001025 break;
1026 case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
1027 ocelot_port_attr_mc_set(ocelot, port, !attr->u.mc_disabled);
1028 break;
Vladimir Oltean421741e2021-02-12 17:15:59 +02001029 case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
1030 err = ocelot_port_pre_bridge_flags(ocelot, port,
1031 attr->u.brport_flags);
1032 break;
1033 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
1034 ocelot_port_bridge_flags(ocelot, port, attr->u.brport_flags);
1035 break;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001036 default:
1037 err = -EOPNOTSUPP;
1038 break;
1039 }
1040
1041 return err;
1042}
1043
1044static int ocelot_port_obj_add_vlan(struct net_device *dev,
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001045 const struct switchdev_obj_port_vlan *vlan)
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001046{
Vladimir Olteanb7a9e0d2021-01-09 02:01:46 +02001047 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1048 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001049 int ret;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001050
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001051 ret = ocelot_vlan_vid_prepare(dev, vlan->vid, pvid, untagged);
1052 if (ret)
1053 return ret;
Vladimir Oltean2f0402f2020-10-31 12:29:15 +02001054
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001055 return ocelot_vlan_vid_add(dev, vlan->vid, pvid, untagged);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001056}
1057
Vladimir Oltean209edf92020-06-21 14:46:01 +03001058static int ocelot_port_obj_add_mdb(struct net_device *dev,
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001059 const struct switchdev_obj_port_mdb *mdb)
Vladimir Oltean209edf92020-06-21 14:46:01 +03001060{
1061 struct ocelot_port_private *priv = netdev_priv(dev);
1062 struct ocelot_port *ocelot_port = &priv->port;
1063 struct ocelot *ocelot = ocelot_port->ocelot;
1064 int port = priv->chip_port;
1065
Vladimir Oltean209edf92020-06-21 14:46:01 +03001066 return ocelot_port_mdb_add(ocelot, port, mdb);
1067}
1068
1069static int ocelot_port_obj_del_mdb(struct net_device *dev,
1070 const struct switchdev_obj_port_mdb *mdb)
1071{
1072 struct ocelot_port_private *priv = netdev_priv(dev);
1073 struct ocelot_port *ocelot_port = &priv->port;
1074 struct ocelot *ocelot = ocelot_port->ocelot;
1075 int port = priv->chip_port;
1076
1077 return ocelot_port_mdb_del(ocelot, port, mdb);
1078}
1079
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001080static int ocelot_port_obj_add(struct net_device *dev,
1081 const struct switchdev_obj *obj,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001082 struct netlink_ext_ack *extack)
1083{
1084 int ret = 0;
1085
1086 switch (obj->id) {
1087 case SWITCHDEV_OBJ_ID_PORT_VLAN:
1088 ret = ocelot_port_obj_add_vlan(dev,
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001089 SWITCHDEV_OBJ_PORT_VLAN(obj));
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001090 break;
1091 case SWITCHDEV_OBJ_ID_PORT_MDB:
Vladimir Olteanffb68fc2021-01-09 02:01:48 +02001092 ret = ocelot_port_obj_add_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001093 break;
1094 default:
1095 return -EOPNOTSUPP;
1096 }
1097
1098 return ret;
1099}
1100
1101static int ocelot_port_obj_del(struct net_device *dev,
1102 const struct switchdev_obj *obj)
1103{
1104 int ret = 0;
1105
1106 switch (obj->id) {
1107 case SWITCHDEV_OBJ_ID_PORT_VLAN:
Vladimir Olteanb7a9e0d2021-01-09 02:01:46 +02001108 ret = ocelot_vlan_vid_del(dev,
1109 SWITCHDEV_OBJ_PORT_VLAN(obj)->vid);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001110 break;
1111 case SWITCHDEV_OBJ_ID_PORT_MDB:
1112 ret = ocelot_port_obj_del_mdb(dev, SWITCHDEV_OBJ_PORT_MDB(obj));
1113 break;
1114 default:
1115 return -EOPNOTSUPP;
1116 }
1117
1118 return ret;
1119}
1120
Vladimir Oltean421741e2021-02-12 17:15:59 +02001121static int ocelot_netdevice_bridge_join(struct ocelot *ocelot, int port,
1122 struct net_device *bridge)
1123{
1124 struct switchdev_brport_flags flags;
1125 int err;
1126
1127 flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
1128 flags.val = flags.mask;
1129
1130 err = ocelot_port_bridge_join(ocelot, port, bridge);
1131 if (err)
1132 return err;
1133
1134 ocelot_port_bridge_flags(ocelot, port, flags);
1135
1136 return 0;
1137}
1138
1139static int ocelot_netdevice_bridge_leave(struct ocelot *ocelot, int port,
1140 struct net_device *bridge)
1141{
1142 struct switchdev_brport_flags flags;
1143 int err;
1144
1145 flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
1146 flags.val = flags.mask & ~BR_LEARNING;
1147
1148 err = ocelot_port_bridge_leave(ocelot, port, bridge);
1149
1150 ocelot_port_bridge_flags(ocelot, port, flags);
1151
1152 return err;
1153}
1154
Vladimir Oltean662981b2021-02-06 00:02:10 +02001155static int ocelot_netdevice_changeupper(struct net_device *dev,
1156 struct netdev_notifier_changeupper_info *info)
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001157{
1158 struct ocelot_port_private *priv = netdev_priv(dev);
1159 struct ocelot_port *ocelot_port = &priv->port;
1160 struct ocelot *ocelot = ocelot_port->ocelot;
1161 int port = priv->chip_port;
1162 int err = 0;
1163
Vladimir Oltean662981b2021-02-06 00:02:10 +02001164 if (netif_is_bridge_master(info->upper_dev)) {
1165 if (info->linking) {
Vladimir Oltean421741e2021-02-12 17:15:59 +02001166 err = ocelot_netdevice_bridge_join(ocelot, port,
1167 info->upper_dev);
Vladimir Oltean662981b2021-02-06 00:02:10 +02001168 } else {
Vladimir Oltean421741e2021-02-12 17:15:59 +02001169 err = ocelot_netdevice_bridge_leave(ocelot, port,
1170 info->upper_dev);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001171 }
Vladimir Oltean662981b2021-02-06 00:02:10 +02001172 }
1173 if (netif_is_lag_master(info->upper_dev)) {
Vladimir Oltean583cbbe2021-02-06 00:02:12 +02001174 if (info->linking) {
Vladimir Oltean662981b2021-02-06 00:02:10 +02001175 err = ocelot_port_lag_join(ocelot, port,
Vladimir Oltean583cbbe2021-02-06 00:02:12 +02001176 info->upper_dev,
1177 info->upper_info);
1178 if (err == -EOPNOTSUPP) {
1179 NL_SET_ERR_MSG_MOD(info->info.extack,
1180 "Offloading not supported");
1181 err = 0;
1182 }
1183 } else {
Vladimir Oltean662981b2021-02-06 00:02:10 +02001184 ocelot_port_lag_leave(ocelot, port,
1185 info->upper_dev);
Vladimir Oltean583cbbe2021-02-06 00:02:12 +02001186 }
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001187 }
1188
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001189 return notifier_from_errno(err);
1190}
1191
1192static int
1193ocelot_netdevice_lag_changeupper(struct net_device *dev,
1194 struct netdev_notifier_changeupper_info *info)
1195{
1196 struct net_device *lower;
1197 struct list_head *iter;
1198 int err = NOTIFY_DONE;
1199
1200 netdev_for_each_lower_dev(dev, lower, iter) {
1201 err = ocelot_netdevice_changeupper(lower, info);
1202 if (err)
1203 return notifier_from_errno(err);
1204 }
1205
1206 return NOTIFY_DONE;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001207}
1208
Vladimir Oltean23ca3b72021-02-06 00:02:19 +02001209static int
1210ocelot_netdevice_changelowerstate(struct net_device *dev,
1211 struct netdev_lag_lower_state_info *info)
1212{
1213 struct ocelot_port_private *priv = netdev_priv(dev);
1214 bool is_active = info->link_up && info->tx_enabled;
1215 struct ocelot_port *ocelot_port = &priv->port;
1216 struct ocelot *ocelot = ocelot_port->ocelot;
1217 int port = priv->chip_port;
1218
1219 if (!ocelot_port->bond)
1220 return NOTIFY_DONE;
1221
1222 if (ocelot_port->lag_tx_active == is_active)
1223 return NOTIFY_DONE;
1224
1225 ocelot_port_lag_change(ocelot, port, is_active);
1226
1227 return NOTIFY_OK;
1228}
1229
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001230static int ocelot_netdevice_event(struct notifier_block *unused,
1231 unsigned long event, void *ptr)
1232{
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001233 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001234
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001235 switch (event) {
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001236 case NETDEV_CHANGEUPPER: {
1237 struct netdev_notifier_changeupper_info *info = ptr;
1238
1239 if (ocelot_netdevice_dev_check(dev))
1240 return ocelot_netdevice_changeupper(dev, info);
1241
1242 if (netif_is_lag_master(dev))
1243 return ocelot_netdevice_lag_changeupper(dev, info);
1244
1245 break;
1246 }
Vladimir Oltean23ca3b72021-02-06 00:02:19 +02001247 case NETDEV_CHANGELOWERSTATE: {
1248 struct netdev_notifier_changelowerstate_info *info = ptr;
1249
1250 if (!ocelot_netdevice_dev_check(dev))
1251 break;
1252
1253 return ocelot_netdevice_changelowerstate(dev,
1254 info->lower_state_info);
1255 }
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001256 default:
1257 break;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001258 }
1259
Vladimir Oltean41e66fa2021-02-06 00:02:11 +02001260 return NOTIFY_DONE;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001261}
1262
1263struct notifier_block ocelot_netdevice_nb __read_mostly = {
1264 .notifier_call = ocelot_netdevice_event,
1265};
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001266
1267static int ocelot_switchdev_event(struct notifier_block *unused,
1268 unsigned long event, void *ptr)
1269{
1270 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1271 int err;
1272
1273 switch (event) {
1274 case SWITCHDEV_PORT_ATTR_SET:
1275 err = switchdev_handle_port_attr_set(dev, ptr,
1276 ocelot_netdevice_dev_check,
1277 ocelot_port_attr_set);
1278 return notifier_from_errno(err);
1279 }
1280
1281 return NOTIFY_DONE;
1282}
1283
1284struct notifier_block ocelot_switchdev_nb __read_mostly = {
1285 .notifier_call = ocelot_switchdev_event,
1286};
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001287
1288static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
1289 unsigned long event, void *ptr)
1290{
1291 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1292 int err;
1293
1294 switch (event) {
1295 /* Blocking events. */
1296 case SWITCHDEV_PORT_OBJ_ADD:
1297 err = switchdev_handle_port_obj_add(dev, ptr,
1298 ocelot_netdevice_dev_check,
1299 ocelot_port_obj_add);
1300 return notifier_from_errno(err);
1301 case SWITCHDEV_PORT_OBJ_DEL:
1302 err = switchdev_handle_port_obj_del(dev, ptr,
1303 ocelot_netdevice_dev_check,
1304 ocelot_port_obj_del);
1305 return notifier_from_errno(err);
1306 case SWITCHDEV_PORT_ATTR_SET:
1307 err = switchdev_handle_port_attr_set(dev, ptr,
1308 ocelot_netdevice_dev_check,
1309 ocelot_port_attr_set);
1310 return notifier_from_errno(err);
1311 }
1312
1313 return NOTIFY_DONE;
1314}
1315
1316struct notifier_block ocelot_switchdev_blocking_nb __read_mostly = {
1317 .notifier_call = ocelot_switchdev_blocking_event,
1318};
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001319
Vladimir Oltean91c724c2020-07-13 19:57:01 +03001320int ocelot_probe_port(struct ocelot *ocelot, int port, struct regmap *target,
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001321 struct phy_device *phy)
1322{
1323 struct ocelot_port_private *priv;
1324 struct ocelot_port *ocelot_port;
1325 struct net_device *dev;
1326 int err;
1327
1328 dev = alloc_etherdev(sizeof(struct ocelot_port_private));
1329 if (!dev)
1330 return -ENOMEM;
1331 SET_NETDEV_DEV(dev, ocelot->dev);
1332 priv = netdev_priv(dev);
1333 priv->dev = dev;
1334 priv->phy = phy;
1335 priv->chip_port = port;
1336 ocelot_port = &priv->port;
1337 ocelot_port->ocelot = ocelot;
Vladimir Oltean91c724c2020-07-13 19:57:01 +03001338 ocelot_port->target = target;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001339 ocelot->ports[port] = ocelot_port;
1340
1341 dev->netdev_ops = &ocelot_port_netdev_ops;
1342 dev->ethtool_ops = &ocelot_ethtool_ops;
1343
1344 dev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_RXFCS |
1345 NETIF_F_HW_TC;
1346 dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_TC;
1347
1348 memcpy(dev->dev_addr, ocelot->base_mac, ETH_ALEN);
1349 dev->dev_addr[ETH_ALEN - 1] += port;
Vladimir Olteanc3e58a752020-10-31 12:29:12 +02001350 ocelot_mact_learn(ocelot, PGID_CPU, dev->dev_addr,
1351 ocelot_port->pvid_vlan.vid, ENTRYTYPE_LOCKED);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001352
1353 ocelot_init_port(ocelot, port);
1354
1355 err = register_netdev(dev);
1356 if (err) {
1357 dev_err(ocelot->dev, "register_netdev failed\n");
1358 free_netdev(dev);
Dan Carpentere0c16232021-02-02 12:12:38 +03001359 ocelot->ports[port] = NULL;
1360 return err;
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001361 }
1362
Dan Carpentere0c16232021-02-02 12:12:38 +03001363 return 0;
1364}
1365
1366void ocelot_release_port(struct ocelot_port *ocelot_port)
1367{
1368 struct ocelot_port_private *priv = container_of(ocelot_port,
1369 struct ocelot_port_private,
1370 port);
1371
1372 unregister_netdev(priv->dev);
1373 free_netdev(priv->dev);
Vladimir Oltean9c90eea2020-06-20 18:43:44 +03001374}