0001
0002
0003 #include <linux/if_bridge.h>
0004 #include <net/switchdev.h>
0005
0006 #include "lan966x_main.h"
0007
0008 static struct notifier_block lan966x_netdevice_nb __read_mostly;
0009 static struct notifier_block lan966x_switchdev_nb __read_mostly;
0010 static struct notifier_block lan966x_switchdev_blocking_nb __read_mostly;
0011
0012 static void lan966x_port_set_mcast_ip_flood(struct lan966x_port *port,
0013 u32 pgid_ip)
0014 {
0015 struct lan966x *lan966x = port->lan966x;
0016 u32 flood_mask_ip;
0017
0018 flood_mask_ip = lan_rd(lan966x, ANA_PGID(pgid_ip));
0019 flood_mask_ip = ANA_PGID_PGID_GET(flood_mask_ip);
0020
0021
0022
0023
0024 if (!port->mcast_ena) {
0025 u32 flood_mask;
0026
0027 flood_mask = lan_rd(lan966x, ANA_PGID(PGID_MC));
0028 flood_mask = ANA_PGID_PGID_GET(flood_mask);
0029
0030 if (flood_mask & BIT(port->chip_port))
0031 flood_mask_ip |= BIT(port->chip_port);
0032 else
0033 flood_mask_ip &= ~BIT(port->chip_port);
0034 } else {
0035 flood_mask_ip &= ~BIT(port->chip_port);
0036 }
0037
0038 lan_rmw(ANA_PGID_PGID_SET(flood_mask_ip),
0039 ANA_PGID_PGID,
0040 lan966x, ANA_PGID(pgid_ip));
0041 }
0042
0043 static void lan966x_port_set_mcast_flood(struct lan966x_port *port,
0044 bool enabled)
0045 {
0046 u32 val = lan_rd(port->lan966x, ANA_PGID(PGID_MC));
0047
0048 val = ANA_PGID_PGID_GET(val);
0049 if (enabled)
0050 val |= BIT(port->chip_port);
0051 else
0052 val &= ~BIT(port->chip_port);
0053
0054 lan_rmw(ANA_PGID_PGID_SET(val),
0055 ANA_PGID_PGID,
0056 port->lan966x, ANA_PGID(PGID_MC));
0057
0058 if (!port->mcast_ena) {
0059 lan966x_port_set_mcast_ip_flood(port, PGID_MCIPV4);
0060 lan966x_port_set_mcast_ip_flood(port, PGID_MCIPV6);
0061 }
0062 }
0063
0064 static void lan966x_port_set_ucast_flood(struct lan966x_port *port,
0065 bool enabled)
0066 {
0067 u32 val = lan_rd(port->lan966x, ANA_PGID(PGID_UC));
0068
0069 val = ANA_PGID_PGID_GET(val);
0070 if (enabled)
0071 val |= BIT(port->chip_port);
0072 else
0073 val &= ~BIT(port->chip_port);
0074
0075 lan_rmw(ANA_PGID_PGID_SET(val),
0076 ANA_PGID_PGID,
0077 port->lan966x, ANA_PGID(PGID_UC));
0078 }
0079
0080 static void lan966x_port_set_bcast_flood(struct lan966x_port *port,
0081 bool enabled)
0082 {
0083 u32 val = lan_rd(port->lan966x, ANA_PGID(PGID_BC));
0084
0085 val = ANA_PGID_PGID_GET(val);
0086 if (enabled)
0087 val |= BIT(port->chip_port);
0088 else
0089 val &= ~BIT(port->chip_port);
0090
0091 lan_rmw(ANA_PGID_PGID_SET(val),
0092 ANA_PGID_PGID,
0093 port->lan966x, ANA_PGID(PGID_BC));
0094 }
0095
0096 static void lan966x_port_set_learning(struct lan966x_port *port, bool enabled)
0097 {
0098 lan_rmw(ANA_PORT_CFG_LEARN_ENA_SET(enabled),
0099 ANA_PORT_CFG_LEARN_ENA,
0100 port->lan966x, ANA_PORT_CFG(port->chip_port));
0101
0102 port->learn_ena = enabled;
0103 }
0104
0105 static void lan966x_port_bridge_flags(struct lan966x_port *port,
0106 struct switchdev_brport_flags flags)
0107 {
0108 if (flags.mask & BR_MCAST_FLOOD)
0109 lan966x_port_set_mcast_flood(port,
0110 !!(flags.val & BR_MCAST_FLOOD));
0111
0112 if (flags.mask & BR_FLOOD)
0113 lan966x_port_set_ucast_flood(port,
0114 !!(flags.val & BR_FLOOD));
0115
0116 if (flags.mask & BR_BCAST_FLOOD)
0117 lan966x_port_set_bcast_flood(port,
0118 !!(flags.val & BR_BCAST_FLOOD));
0119
0120 if (flags.mask & BR_LEARNING)
0121 lan966x_port_set_learning(port,
0122 !!(flags.val & BR_LEARNING));
0123 }
0124
0125 static int lan966x_port_pre_bridge_flags(struct lan966x_port *port,
0126 struct switchdev_brport_flags flags)
0127 {
0128 if (flags.mask & ~(BR_MCAST_FLOOD | BR_FLOOD | BR_BCAST_FLOOD |
0129 BR_LEARNING))
0130 return -EINVAL;
0131
0132 return 0;
0133 }
0134
0135 static void lan966x_update_fwd_mask(struct lan966x *lan966x)
0136 {
0137 int i;
0138
0139 for (i = 0; i < lan966x->num_phys_ports; i++) {
0140 struct lan966x_port *port = lan966x->ports[i];
0141 unsigned long mask = 0;
0142
0143 if (port && lan966x->bridge_fwd_mask & BIT(i))
0144 mask = lan966x->bridge_fwd_mask & ~BIT(i);
0145
0146 mask |= BIT(CPU_PORT);
0147
0148 lan_wr(ANA_PGID_PGID_SET(mask),
0149 lan966x, ANA_PGID(PGID_SRC + i));
0150 }
0151 }
0152
0153 static void lan966x_port_stp_state_set(struct lan966x_port *port, u8 state)
0154 {
0155 struct lan966x *lan966x = port->lan966x;
0156 bool learn_ena = false;
0157
0158 if ((state == BR_STATE_FORWARDING || state == BR_STATE_LEARNING) &&
0159 port->learn_ena)
0160 learn_ena = true;
0161
0162 if (state == BR_STATE_FORWARDING)
0163 lan966x->bridge_fwd_mask |= BIT(port->chip_port);
0164 else
0165 lan966x->bridge_fwd_mask &= ~BIT(port->chip_port);
0166
0167 lan_rmw(ANA_PORT_CFG_LEARN_ENA_SET(learn_ena),
0168 ANA_PORT_CFG_LEARN_ENA,
0169 lan966x, ANA_PORT_CFG(port->chip_port));
0170
0171 lan966x_update_fwd_mask(lan966x);
0172 }
0173
0174 static void lan966x_port_ageing_set(struct lan966x_port *port,
0175 unsigned long ageing_clock_t)
0176 {
0177 unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
0178 u32 ageing_time = jiffies_to_msecs(ageing_jiffies) / 1000;
0179
0180 lan966x_mac_set_ageing(port->lan966x, ageing_time);
0181 }
0182
0183 static void lan966x_port_mc_set(struct lan966x_port *port, bool mcast_ena)
0184 {
0185 struct lan966x *lan966x = port->lan966x;
0186
0187 port->mcast_ena = mcast_ena;
0188 if (mcast_ena)
0189 lan966x_mdb_restore_entries(lan966x);
0190 else
0191 lan966x_mdb_clear_entries(lan966x);
0192
0193 lan_rmw(ANA_CPU_FWD_CFG_IGMP_REDIR_ENA_SET(mcast_ena) |
0194 ANA_CPU_FWD_CFG_MLD_REDIR_ENA_SET(mcast_ena) |
0195 ANA_CPU_FWD_CFG_IPMC_CTRL_COPY_ENA_SET(mcast_ena),
0196 ANA_CPU_FWD_CFG_IGMP_REDIR_ENA |
0197 ANA_CPU_FWD_CFG_MLD_REDIR_ENA |
0198 ANA_CPU_FWD_CFG_IPMC_CTRL_COPY_ENA,
0199 lan966x, ANA_CPU_FWD_CFG(port->chip_port));
0200
0201 lan966x_port_set_mcast_ip_flood(port, PGID_MCIPV4);
0202 lan966x_port_set_mcast_ip_flood(port, PGID_MCIPV6);
0203 }
0204
0205 static int lan966x_port_attr_set(struct net_device *dev, const void *ctx,
0206 const struct switchdev_attr *attr,
0207 struct netlink_ext_ack *extack)
0208 {
0209 struct lan966x_port *port = netdev_priv(dev);
0210 int err = 0;
0211
0212 if (ctx && ctx != port)
0213 return 0;
0214
0215 switch (attr->id) {
0216 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
0217 lan966x_port_bridge_flags(port, attr->u.brport_flags);
0218 break;
0219 case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
0220 err = lan966x_port_pre_bridge_flags(port, attr->u.brport_flags);
0221 break;
0222 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
0223 lan966x_port_stp_state_set(port, attr->u.stp_state);
0224 break;
0225 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
0226 lan966x_port_ageing_set(port, attr->u.ageing_time);
0227 break;
0228 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
0229 lan966x_vlan_port_set_vlan_aware(port, attr->u.vlan_filtering);
0230 lan966x_vlan_port_apply(port);
0231 break;
0232 case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
0233 lan966x_port_mc_set(port, !attr->u.mc_disabled);
0234 break;
0235 default:
0236 err = -EOPNOTSUPP;
0237 break;
0238 }
0239
0240 return err;
0241 }
0242
0243 static int lan966x_port_bridge_join(struct lan966x_port *port,
0244 struct net_device *bridge,
0245 struct netlink_ext_ack *extack)
0246 {
0247 struct switchdev_brport_flags flags = {0};
0248 struct lan966x *lan966x = port->lan966x;
0249 struct net_device *dev = port->dev;
0250 int err;
0251
0252 if (!lan966x->bridge_mask) {
0253 lan966x->bridge = bridge;
0254 } else {
0255 if (lan966x->bridge != bridge) {
0256 NL_SET_ERR_MSG_MOD(extack, "Not allow to add port to different bridge");
0257 return -ENODEV;
0258 }
0259 }
0260
0261 err = switchdev_bridge_port_offload(dev, dev, port,
0262 &lan966x_switchdev_nb,
0263 &lan966x_switchdev_blocking_nb,
0264 false, extack);
0265 if (err)
0266 return err;
0267
0268 lan966x->bridge_mask |= BIT(port->chip_port);
0269
0270 flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
0271 flags.val = flags.mask;
0272 lan966x_port_bridge_flags(port, flags);
0273
0274 return 0;
0275 }
0276
0277 static void lan966x_port_bridge_leave(struct lan966x_port *port,
0278 struct net_device *bridge)
0279 {
0280 struct switchdev_brport_flags flags = {0};
0281 struct lan966x *lan966x = port->lan966x;
0282
0283 flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
0284 flags.val = flags.mask & ~BR_LEARNING;
0285 lan966x_port_bridge_flags(port, flags);
0286
0287 lan966x->bridge_mask &= ~BIT(port->chip_port);
0288
0289 if (!lan966x->bridge_mask)
0290 lan966x->bridge = NULL;
0291
0292
0293 lan966x_vlan_port_set_vlan_aware(port, false);
0294 lan966x_vlan_port_set_vid(port, HOST_PVID, false, false);
0295 lan966x_vlan_port_apply(port);
0296 }
0297
0298 static int lan966x_port_changeupper(struct net_device *dev,
0299 struct netdev_notifier_changeupper_info *info)
0300 {
0301 struct lan966x_port *port = netdev_priv(dev);
0302 struct netlink_ext_ack *extack;
0303 int err = 0;
0304
0305 extack = netdev_notifier_info_to_extack(&info->info);
0306
0307 if (netif_is_bridge_master(info->upper_dev)) {
0308 if (info->linking)
0309 err = lan966x_port_bridge_join(port, info->upper_dev,
0310 extack);
0311 else
0312 lan966x_port_bridge_leave(port, info->upper_dev);
0313 }
0314
0315 return err;
0316 }
0317
0318 static int lan966x_port_prechangeupper(struct net_device *dev,
0319 struct netdev_notifier_changeupper_info *info)
0320 {
0321 struct lan966x_port *port = netdev_priv(dev);
0322
0323 if (netif_is_bridge_master(info->upper_dev) && !info->linking)
0324 switchdev_bridge_port_unoffload(port->dev, port,
0325 NULL, NULL);
0326
0327 return NOTIFY_DONE;
0328 }
0329
0330 static int lan966x_foreign_bridging_check(struct net_device *bridge,
0331 struct netlink_ext_ack *extack)
0332 {
0333 struct lan966x *lan966x = NULL;
0334 bool has_foreign = false;
0335 struct net_device *dev;
0336 struct list_head *iter;
0337
0338 if (!netif_is_bridge_master(bridge))
0339 return 0;
0340
0341 netdev_for_each_lower_dev(bridge, dev, iter) {
0342 if (lan966x_netdevice_check(dev)) {
0343 struct lan966x_port *port = netdev_priv(dev);
0344
0345 if (lan966x) {
0346
0347
0348
0349
0350 if (port->lan966x != lan966x) {
0351 NL_SET_ERR_MSG_MOD(extack,
0352 "Bridging between multiple lan966x switches disallowed");
0353 return -EINVAL;
0354 }
0355 } else {
0356
0357
0358
0359 lan966x = port->lan966x;
0360 }
0361 } else {
0362 has_foreign = true;
0363 }
0364
0365 if (lan966x && has_foreign) {
0366 NL_SET_ERR_MSG_MOD(extack,
0367 "Bridging lan966x ports with foreign interfaces disallowed");
0368 return -EINVAL;
0369 }
0370 }
0371
0372 return 0;
0373 }
0374
0375 static int lan966x_bridge_check(struct net_device *dev,
0376 struct netdev_notifier_changeupper_info *info)
0377 {
0378 return lan966x_foreign_bridging_check(info->upper_dev,
0379 info->info.extack);
0380 }
0381
0382 static int lan966x_netdevice_port_event(struct net_device *dev,
0383 struct notifier_block *nb,
0384 unsigned long event, void *ptr)
0385 {
0386 int err = 0;
0387
0388 if (!lan966x_netdevice_check(dev)) {
0389 if (event == NETDEV_CHANGEUPPER)
0390 return lan966x_bridge_check(dev, ptr);
0391 return 0;
0392 }
0393
0394 switch (event) {
0395 case NETDEV_PRECHANGEUPPER:
0396 err = lan966x_port_prechangeupper(dev, ptr);
0397 break;
0398 case NETDEV_CHANGEUPPER:
0399 err = lan966x_bridge_check(dev, ptr);
0400 if (err)
0401 return err;
0402
0403 err = lan966x_port_changeupper(dev, ptr);
0404 break;
0405 }
0406
0407 return err;
0408 }
0409
0410 static int lan966x_netdevice_event(struct notifier_block *nb,
0411 unsigned long event, void *ptr)
0412 {
0413 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
0414 int ret;
0415
0416 ret = lan966x_netdevice_port_event(dev, nb, event, ptr);
0417
0418 return notifier_from_errno(ret);
0419 }
0420
0421
0422
0423
0424 static bool lan966x_foreign_dev_check(const struct net_device *dev,
0425 const struct net_device *foreign_dev)
0426 {
0427 struct lan966x_port *port = netdev_priv(dev);
0428 struct lan966x *lan966x = port->lan966x;
0429
0430 if (netif_is_bridge_master(foreign_dev))
0431 if (lan966x->bridge == foreign_dev)
0432 return false;
0433
0434 return true;
0435 }
0436
0437 static int lan966x_switchdev_event(struct notifier_block *nb,
0438 unsigned long event, void *ptr)
0439 {
0440 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
0441 int err;
0442
0443 switch (event) {
0444 case SWITCHDEV_PORT_ATTR_SET:
0445 err = switchdev_handle_port_attr_set(dev, ptr,
0446 lan966x_netdevice_check,
0447 lan966x_port_attr_set);
0448 return notifier_from_errno(err);
0449 case SWITCHDEV_FDB_ADD_TO_DEVICE:
0450 case SWITCHDEV_FDB_DEL_TO_DEVICE:
0451 err = switchdev_handle_fdb_event_to_device(dev, event, ptr,
0452 lan966x_netdevice_check,
0453 lan966x_foreign_dev_check,
0454 lan966x_handle_fdb);
0455 return notifier_from_errno(err);
0456 }
0457
0458 return NOTIFY_DONE;
0459 }
0460
0461 static int lan966x_handle_port_vlan_add(struct lan966x_port *port,
0462 const struct switchdev_obj *obj)
0463 {
0464 const struct switchdev_obj_port_vlan *v = SWITCHDEV_OBJ_PORT_VLAN(obj);
0465 struct lan966x *lan966x = port->lan966x;
0466
0467 if (!netif_is_bridge_master(obj->orig_dev))
0468 lan966x_vlan_port_add_vlan(port, v->vid,
0469 v->flags & BRIDGE_VLAN_INFO_PVID,
0470 v->flags & BRIDGE_VLAN_INFO_UNTAGGED);
0471 else
0472 lan966x_vlan_cpu_add_vlan(lan966x, v->vid);
0473
0474 return 0;
0475 }
0476
0477 static int lan966x_handle_port_obj_add(struct net_device *dev, const void *ctx,
0478 const struct switchdev_obj *obj,
0479 struct netlink_ext_ack *extack)
0480 {
0481 struct lan966x_port *port = netdev_priv(dev);
0482 int err;
0483
0484 if (ctx && ctx != port)
0485 return 0;
0486
0487 switch (obj->id) {
0488 case SWITCHDEV_OBJ_ID_PORT_VLAN:
0489 err = lan966x_handle_port_vlan_add(port, obj);
0490 break;
0491 case SWITCHDEV_OBJ_ID_PORT_MDB:
0492 case SWITCHDEV_OBJ_ID_HOST_MDB:
0493 err = lan966x_handle_port_mdb_add(port, obj);
0494 break;
0495 default:
0496 err = -EOPNOTSUPP;
0497 break;
0498 }
0499
0500 return err;
0501 }
0502
0503 static int lan966x_handle_port_vlan_del(struct lan966x_port *port,
0504 const struct switchdev_obj *obj)
0505 {
0506 const struct switchdev_obj_port_vlan *v = SWITCHDEV_OBJ_PORT_VLAN(obj);
0507 struct lan966x *lan966x = port->lan966x;
0508
0509 if (!netif_is_bridge_master(obj->orig_dev))
0510 lan966x_vlan_port_del_vlan(port, v->vid);
0511 else
0512 lan966x_vlan_cpu_del_vlan(lan966x, v->vid);
0513
0514 return 0;
0515 }
0516
0517 static int lan966x_handle_port_obj_del(struct net_device *dev, const void *ctx,
0518 const struct switchdev_obj *obj)
0519 {
0520 struct lan966x_port *port = netdev_priv(dev);
0521 int err;
0522
0523 if (ctx && ctx != port)
0524 return 0;
0525
0526 switch (obj->id) {
0527 case SWITCHDEV_OBJ_ID_PORT_VLAN:
0528 err = lan966x_handle_port_vlan_del(port, obj);
0529 break;
0530 case SWITCHDEV_OBJ_ID_PORT_MDB:
0531 case SWITCHDEV_OBJ_ID_HOST_MDB:
0532 err = lan966x_handle_port_mdb_del(port, obj);
0533 break;
0534 default:
0535 err = -EOPNOTSUPP;
0536 break;
0537 }
0538
0539 return err;
0540 }
0541
0542 static int lan966x_switchdev_blocking_event(struct notifier_block *nb,
0543 unsigned long event,
0544 void *ptr)
0545 {
0546 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
0547 int err;
0548
0549 switch (event) {
0550 case SWITCHDEV_PORT_OBJ_ADD:
0551 err = switchdev_handle_port_obj_add(dev, ptr,
0552 lan966x_netdevice_check,
0553 lan966x_handle_port_obj_add);
0554 return notifier_from_errno(err);
0555 case SWITCHDEV_PORT_OBJ_DEL:
0556 err = switchdev_handle_port_obj_del(dev, ptr,
0557 lan966x_netdevice_check,
0558 lan966x_handle_port_obj_del);
0559 return notifier_from_errno(err);
0560 case SWITCHDEV_PORT_ATTR_SET:
0561 err = switchdev_handle_port_attr_set(dev, ptr,
0562 lan966x_netdevice_check,
0563 lan966x_port_attr_set);
0564 return notifier_from_errno(err);
0565 }
0566
0567 return NOTIFY_DONE;
0568 }
0569
0570 static struct notifier_block lan966x_netdevice_nb __read_mostly = {
0571 .notifier_call = lan966x_netdevice_event,
0572 };
0573
0574 static struct notifier_block lan966x_switchdev_nb __read_mostly = {
0575 .notifier_call = lan966x_switchdev_event,
0576 };
0577
0578 static struct notifier_block lan966x_switchdev_blocking_nb __read_mostly = {
0579 .notifier_call = lan966x_switchdev_blocking_event,
0580 };
0581
0582 void lan966x_register_notifier_blocks(void)
0583 {
0584 register_netdevice_notifier(&lan966x_netdevice_nb);
0585 register_switchdev_notifier(&lan966x_switchdev_nb);
0586 register_switchdev_blocking_notifier(&lan966x_switchdev_blocking_nb);
0587 }
0588
0589 void lan966x_unregister_notifier_blocks(void)
0590 {
0591 unregister_switchdev_blocking_notifier(&lan966x_switchdev_blocking_nb);
0592 unregister_switchdev_notifier(&lan966x_switchdev_nb);
0593 unregister_netdevice_notifier(&lan966x_netdevice_nb);
0594 }