0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/if_bridge.h>
0010 #include <linux/netdevice.h>
0011 #include <linux/notifier.h>
0012 #include <linux/if_vlan.h>
0013 #include <net/switchdev.h>
0014
0015 #include "dsa_priv.h"
0016
0017 static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds,
0018 unsigned int ageing_time)
0019 {
0020 struct dsa_port *dp;
0021
0022 dsa_switch_for_each_port(dp, ds)
0023 if (dp->ageing_time && dp->ageing_time < ageing_time)
0024 ageing_time = dp->ageing_time;
0025
0026 return ageing_time;
0027 }
0028
0029 static int dsa_switch_ageing_time(struct dsa_switch *ds,
0030 struct dsa_notifier_ageing_time_info *info)
0031 {
0032 unsigned int ageing_time = info->ageing_time;
0033
0034 if (ds->ageing_time_min && ageing_time < ds->ageing_time_min)
0035 return -ERANGE;
0036
0037 if (ds->ageing_time_max && ageing_time > ds->ageing_time_max)
0038 return -ERANGE;
0039
0040
0041 ageing_time = dsa_switch_fastest_ageing_time(ds, ageing_time);
0042
0043 if (ds->ops->set_ageing_time)
0044 return ds->ops->set_ageing_time(ds, ageing_time);
0045
0046 return 0;
0047 }
0048
0049 static bool dsa_port_mtu_match(struct dsa_port *dp,
0050 struct dsa_notifier_mtu_info *info)
0051 {
0052 return dp == info->dp || dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp);
0053 }
0054
0055 static int dsa_switch_mtu(struct dsa_switch *ds,
0056 struct dsa_notifier_mtu_info *info)
0057 {
0058 struct dsa_port *dp;
0059 int ret;
0060
0061 if (!ds->ops->port_change_mtu)
0062 return -EOPNOTSUPP;
0063
0064 dsa_switch_for_each_port(dp, ds) {
0065 if (dsa_port_mtu_match(dp, info)) {
0066 ret = ds->ops->port_change_mtu(ds, dp->index,
0067 info->mtu);
0068 if (ret)
0069 return ret;
0070 }
0071 }
0072
0073 return 0;
0074 }
0075
0076 static int dsa_switch_bridge_join(struct dsa_switch *ds,
0077 struct dsa_notifier_bridge_info *info)
0078 {
0079 int err;
0080
0081 if (info->dp->ds == ds) {
0082 if (!ds->ops->port_bridge_join)
0083 return -EOPNOTSUPP;
0084
0085 err = ds->ops->port_bridge_join(ds, info->dp->index,
0086 info->bridge,
0087 &info->tx_fwd_offload,
0088 info->extack);
0089 if (err)
0090 return err;
0091 }
0092
0093 if (info->dp->ds != ds && ds->ops->crosschip_bridge_join) {
0094 err = ds->ops->crosschip_bridge_join(ds,
0095 info->dp->ds->dst->index,
0096 info->dp->ds->index,
0097 info->dp->index,
0098 info->bridge,
0099 info->extack);
0100 if (err)
0101 return err;
0102 }
0103
0104 return 0;
0105 }
0106
0107 static int dsa_switch_bridge_leave(struct dsa_switch *ds,
0108 struct dsa_notifier_bridge_info *info)
0109 {
0110 if (info->dp->ds == ds && ds->ops->port_bridge_leave)
0111 ds->ops->port_bridge_leave(ds, info->dp->index, info->bridge);
0112
0113 if (info->dp->ds != ds && ds->ops->crosschip_bridge_leave)
0114 ds->ops->crosschip_bridge_leave(ds, info->dp->ds->dst->index,
0115 info->dp->ds->index,
0116 info->dp->index,
0117 info->bridge);
0118
0119 return 0;
0120 }
0121
0122
0123
0124
0125
0126 static bool dsa_port_host_address_match(struct dsa_port *dp,
0127 const struct dsa_port *targeted_dp)
0128 {
0129 struct dsa_port *cpu_dp = targeted_dp->cpu_dp;
0130
0131 if (dsa_switch_is_upstream_of(dp->ds, targeted_dp->ds))
0132 return dp->index == dsa_towards_port(dp->ds, cpu_dp->ds->index,
0133 cpu_dp->index);
0134
0135 return false;
0136 }
0137
0138 static struct dsa_mac_addr *dsa_mac_addr_find(struct list_head *addr_list,
0139 const unsigned char *addr, u16 vid,
0140 struct dsa_db db)
0141 {
0142 struct dsa_mac_addr *a;
0143
0144 list_for_each_entry(a, addr_list, list)
0145 if (ether_addr_equal(a->addr, addr) && a->vid == vid &&
0146 dsa_db_equal(&a->db, &db))
0147 return a;
0148
0149 return NULL;
0150 }
0151
0152 static int dsa_port_do_mdb_add(struct dsa_port *dp,
0153 const struct switchdev_obj_port_mdb *mdb,
0154 struct dsa_db db)
0155 {
0156 struct dsa_switch *ds = dp->ds;
0157 struct dsa_mac_addr *a;
0158 int port = dp->index;
0159 int err = 0;
0160
0161
0162 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
0163 return ds->ops->port_mdb_add(ds, port, mdb, db);
0164
0165 mutex_lock(&dp->addr_lists_lock);
0166
0167 a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid, db);
0168 if (a) {
0169 refcount_inc(&a->refcount);
0170 goto out;
0171 }
0172
0173 a = kzalloc(sizeof(*a), GFP_KERNEL);
0174 if (!a) {
0175 err = -ENOMEM;
0176 goto out;
0177 }
0178
0179 err = ds->ops->port_mdb_add(ds, port, mdb, db);
0180 if (err) {
0181 kfree(a);
0182 goto out;
0183 }
0184
0185 ether_addr_copy(a->addr, mdb->addr);
0186 a->vid = mdb->vid;
0187 a->db = db;
0188 refcount_set(&a->refcount, 1);
0189 list_add_tail(&a->list, &dp->mdbs);
0190
0191 out:
0192 mutex_unlock(&dp->addr_lists_lock);
0193
0194 return err;
0195 }
0196
0197 static int dsa_port_do_mdb_del(struct dsa_port *dp,
0198 const struct switchdev_obj_port_mdb *mdb,
0199 struct dsa_db db)
0200 {
0201 struct dsa_switch *ds = dp->ds;
0202 struct dsa_mac_addr *a;
0203 int port = dp->index;
0204 int err = 0;
0205
0206
0207 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
0208 return ds->ops->port_mdb_del(ds, port, mdb, db);
0209
0210 mutex_lock(&dp->addr_lists_lock);
0211
0212 a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid, db);
0213 if (!a) {
0214 err = -ENOENT;
0215 goto out;
0216 }
0217
0218 if (!refcount_dec_and_test(&a->refcount))
0219 goto out;
0220
0221 err = ds->ops->port_mdb_del(ds, port, mdb, db);
0222 if (err) {
0223 refcount_set(&a->refcount, 1);
0224 goto out;
0225 }
0226
0227 list_del(&a->list);
0228 kfree(a);
0229
0230 out:
0231 mutex_unlock(&dp->addr_lists_lock);
0232
0233 return err;
0234 }
0235
0236 static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
0237 u16 vid, struct dsa_db db)
0238 {
0239 struct dsa_switch *ds = dp->ds;
0240 struct dsa_mac_addr *a;
0241 int port = dp->index;
0242 int err = 0;
0243
0244
0245 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
0246 return ds->ops->port_fdb_add(ds, port, addr, vid, db);
0247
0248 mutex_lock(&dp->addr_lists_lock);
0249
0250 a = dsa_mac_addr_find(&dp->fdbs, addr, vid, db);
0251 if (a) {
0252 refcount_inc(&a->refcount);
0253 goto out;
0254 }
0255
0256 a = kzalloc(sizeof(*a), GFP_KERNEL);
0257 if (!a) {
0258 err = -ENOMEM;
0259 goto out;
0260 }
0261
0262 err = ds->ops->port_fdb_add(ds, port, addr, vid, db);
0263 if (err) {
0264 kfree(a);
0265 goto out;
0266 }
0267
0268 ether_addr_copy(a->addr, addr);
0269 a->vid = vid;
0270 a->db = db;
0271 refcount_set(&a->refcount, 1);
0272 list_add_tail(&a->list, &dp->fdbs);
0273
0274 out:
0275 mutex_unlock(&dp->addr_lists_lock);
0276
0277 return err;
0278 }
0279
0280 static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
0281 u16 vid, struct dsa_db db)
0282 {
0283 struct dsa_switch *ds = dp->ds;
0284 struct dsa_mac_addr *a;
0285 int port = dp->index;
0286 int err = 0;
0287
0288
0289 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
0290 return ds->ops->port_fdb_del(ds, port, addr, vid, db);
0291
0292 mutex_lock(&dp->addr_lists_lock);
0293
0294 a = dsa_mac_addr_find(&dp->fdbs, addr, vid, db);
0295 if (!a) {
0296 err = -ENOENT;
0297 goto out;
0298 }
0299
0300 if (!refcount_dec_and_test(&a->refcount))
0301 goto out;
0302
0303 err = ds->ops->port_fdb_del(ds, port, addr, vid, db);
0304 if (err) {
0305 refcount_set(&a->refcount, 1);
0306 goto out;
0307 }
0308
0309 list_del(&a->list);
0310 kfree(a);
0311
0312 out:
0313 mutex_unlock(&dp->addr_lists_lock);
0314
0315 return err;
0316 }
0317
0318 static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
0319 const unsigned char *addr, u16 vid,
0320 struct dsa_db db)
0321 {
0322 struct dsa_mac_addr *a;
0323 int err = 0;
0324
0325 mutex_lock(&lag->fdb_lock);
0326
0327 a = dsa_mac_addr_find(&lag->fdbs, addr, vid, db);
0328 if (a) {
0329 refcount_inc(&a->refcount);
0330 goto out;
0331 }
0332
0333 a = kzalloc(sizeof(*a), GFP_KERNEL);
0334 if (!a) {
0335 err = -ENOMEM;
0336 goto out;
0337 }
0338
0339 err = ds->ops->lag_fdb_add(ds, *lag, addr, vid, db);
0340 if (err) {
0341 kfree(a);
0342 goto out;
0343 }
0344
0345 ether_addr_copy(a->addr, addr);
0346 a->vid = vid;
0347 a->db = db;
0348 refcount_set(&a->refcount, 1);
0349 list_add_tail(&a->list, &lag->fdbs);
0350
0351 out:
0352 mutex_unlock(&lag->fdb_lock);
0353
0354 return err;
0355 }
0356
0357 static int dsa_switch_do_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag *lag,
0358 const unsigned char *addr, u16 vid,
0359 struct dsa_db db)
0360 {
0361 struct dsa_mac_addr *a;
0362 int err = 0;
0363
0364 mutex_lock(&lag->fdb_lock);
0365
0366 a = dsa_mac_addr_find(&lag->fdbs, addr, vid, db);
0367 if (!a) {
0368 err = -ENOENT;
0369 goto out;
0370 }
0371
0372 if (!refcount_dec_and_test(&a->refcount))
0373 goto out;
0374
0375 err = ds->ops->lag_fdb_del(ds, *lag, addr, vid, db);
0376 if (err) {
0377 refcount_set(&a->refcount, 1);
0378 goto out;
0379 }
0380
0381 list_del(&a->list);
0382 kfree(a);
0383
0384 out:
0385 mutex_unlock(&lag->fdb_lock);
0386
0387 return err;
0388 }
0389
0390 static int dsa_switch_host_fdb_add(struct dsa_switch *ds,
0391 struct dsa_notifier_fdb_info *info)
0392 {
0393 struct dsa_port *dp;
0394 int err = 0;
0395
0396 if (!ds->ops->port_fdb_add)
0397 return -EOPNOTSUPP;
0398
0399 dsa_switch_for_each_port(dp, ds) {
0400 if (dsa_port_host_address_match(dp, info->dp)) {
0401 err = dsa_port_do_fdb_add(dp, info->addr, info->vid,
0402 info->db);
0403 if (err)
0404 break;
0405 }
0406 }
0407
0408 return err;
0409 }
0410
0411 static int dsa_switch_host_fdb_del(struct dsa_switch *ds,
0412 struct dsa_notifier_fdb_info *info)
0413 {
0414 struct dsa_port *dp;
0415 int err = 0;
0416
0417 if (!ds->ops->port_fdb_del)
0418 return -EOPNOTSUPP;
0419
0420 dsa_switch_for_each_port(dp, ds) {
0421 if (dsa_port_host_address_match(dp, info->dp)) {
0422 err = dsa_port_do_fdb_del(dp, info->addr, info->vid,
0423 info->db);
0424 if (err)
0425 break;
0426 }
0427 }
0428
0429 return err;
0430 }
0431
0432 static int dsa_switch_fdb_add(struct dsa_switch *ds,
0433 struct dsa_notifier_fdb_info *info)
0434 {
0435 int port = dsa_towards_port(ds, info->dp->ds->index, info->dp->index);
0436 struct dsa_port *dp = dsa_to_port(ds, port);
0437
0438 if (!ds->ops->port_fdb_add)
0439 return -EOPNOTSUPP;
0440
0441 return dsa_port_do_fdb_add(dp, info->addr, info->vid, info->db);
0442 }
0443
0444 static int dsa_switch_fdb_del(struct dsa_switch *ds,
0445 struct dsa_notifier_fdb_info *info)
0446 {
0447 int port = dsa_towards_port(ds, info->dp->ds->index, info->dp->index);
0448 struct dsa_port *dp = dsa_to_port(ds, port);
0449
0450 if (!ds->ops->port_fdb_del)
0451 return -EOPNOTSUPP;
0452
0453 return dsa_port_do_fdb_del(dp, info->addr, info->vid, info->db);
0454 }
0455
0456 static int dsa_switch_lag_fdb_add(struct dsa_switch *ds,
0457 struct dsa_notifier_lag_fdb_info *info)
0458 {
0459 struct dsa_port *dp;
0460
0461 if (!ds->ops->lag_fdb_add)
0462 return -EOPNOTSUPP;
0463
0464
0465 dsa_switch_for_each_port(dp, ds)
0466 if (dsa_port_offloads_lag(dp, info->lag))
0467 return dsa_switch_do_lag_fdb_add(ds, info->lag,
0468 info->addr, info->vid,
0469 info->db);
0470
0471 return 0;
0472 }
0473
0474 static int dsa_switch_lag_fdb_del(struct dsa_switch *ds,
0475 struct dsa_notifier_lag_fdb_info *info)
0476 {
0477 struct dsa_port *dp;
0478
0479 if (!ds->ops->lag_fdb_del)
0480 return -EOPNOTSUPP;
0481
0482
0483 dsa_switch_for_each_port(dp, ds)
0484 if (dsa_port_offloads_lag(dp, info->lag))
0485 return dsa_switch_do_lag_fdb_del(ds, info->lag,
0486 info->addr, info->vid,
0487 info->db);
0488
0489 return 0;
0490 }
0491
0492 static int dsa_switch_lag_change(struct dsa_switch *ds,
0493 struct dsa_notifier_lag_info *info)
0494 {
0495 if (info->dp->ds == ds && ds->ops->port_lag_change)
0496 return ds->ops->port_lag_change(ds, info->dp->index);
0497
0498 if (info->dp->ds != ds && ds->ops->crosschip_lag_change)
0499 return ds->ops->crosschip_lag_change(ds, info->dp->ds->index,
0500 info->dp->index);
0501
0502 return 0;
0503 }
0504
0505 static int dsa_switch_lag_join(struct dsa_switch *ds,
0506 struct dsa_notifier_lag_info *info)
0507 {
0508 if (info->dp->ds == ds && ds->ops->port_lag_join)
0509 return ds->ops->port_lag_join(ds, info->dp->index, info->lag,
0510 info->info);
0511
0512 if (info->dp->ds != ds && ds->ops->crosschip_lag_join)
0513 return ds->ops->crosschip_lag_join(ds, info->dp->ds->index,
0514 info->dp->index, info->lag,
0515 info->info);
0516
0517 return -EOPNOTSUPP;
0518 }
0519
0520 static int dsa_switch_lag_leave(struct dsa_switch *ds,
0521 struct dsa_notifier_lag_info *info)
0522 {
0523 if (info->dp->ds == ds && ds->ops->port_lag_leave)
0524 return ds->ops->port_lag_leave(ds, info->dp->index, info->lag);
0525
0526 if (info->dp->ds != ds && ds->ops->crosschip_lag_leave)
0527 return ds->ops->crosschip_lag_leave(ds, info->dp->ds->index,
0528 info->dp->index, info->lag);
0529
0530 return -EOPNOTSUPP;
0531 }
0532
0533 static int dsa_switch_mdb_add(struct dsa_switch *ds,
0534 struct dsa_notifier_mdb_info *info)
0535 {
0536 int port = dsa_towards_port(ds, info->dp->ds->index, info->dp->index);
0537 struct dsa_port *dp = dsa_to_port(ds, port);
0538
0539 if (!ds->ops->port_mdb_add)
0540 return -EOPNOTSUPP;
0541
0542 return dsa_port_do_mdb_add(dp, info->mdb, info->db);
0543 }
0544
0545 static int dsa_switch_mdb_del(struct dsa_switch *ds,
0546 struct dsa_notifier_mdb_info *info)
0547 {
0548 int port = dsa_towards_port(ds, info->dp->ds->index, info->dp->index);
0549 struct dsa_port *dp = dsa_to_port(ds, port);
0550
0551 if (!ds->ops->port_mdb_del)
0552 return -EOPNOTSUPP;
0553
0554 return dsa_port_do_mdb_del(dp, info->mdb, info->db);
0555 }
0556
0557 static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
0558 struct dsa_notifier_mdb_info *info)
0559 {
0560 struct dsa_port *dp;
0561 int err = 0;
0562
0563 if (!ds->ops->port_mdb_add)
0564 return -EOPNOTSUPP;
0565
0566 dsa_switch_for_each_port(dp, ds) {
0567 if (dsa_port_host_address_match(dp, info->dp)) {
0568 err = dsa_port_do_mdb_add(dp, info->mdb, info->db);
0569 if (err)
0570 break;
0571 }
0572 }
0573
0574 return err;
0575 }
0576
0577 static int dsa_switch_host_mdb_del(struct dsa_switch *ds,
0578 struct dsa_notifier_mdb_info *info)
0579 {
0580 struct dsa_port *dp;
0581 int err = 0;
0582
0583 if (!ds->ops->port_mdb_del)
0584 return -EOPNOTSUPP;
0585
0586 dsa_switch_for_each_port(dp, ds) {
0587 if (dsa_port_host_address_match(dp, info->dp)) {
0588 err = dsa_port_do_mdb_del(dp, info->mdb, info->db);
0589 if (err)
0590 break;
0591 }
0592 }
0593
0594 return err;
0595 }
0596
0597
0598 static bool dsa_port_vlan_match(struct dsa_port *dp,
0599 struct dsa_notifier_vlan_info *info)
0600 {
0601 return dsa_port_is_dsa(dp) || dp == info->dp;
0602 }
0603
0604
0605
0606
0607 static bool dsa_port_host_vlan_match(struct dsa_port *dp,
0608 const struct dsa_port *targeted_dp)
0609 {
0610 struct dsa_port *cpu_dp = targeted_dp->cpu_dp;
0611
0612 if (dsa_switch_is_upstream_of(dp->ds, targeted_dp->ds))
0613 return dsa_port_is_dsa(dp) || dp == cpu_dp;
0614
0615 return false;
0616 }
0617
0618 static struct dsa_vlan *dsa_vlan_find(struct list_head *vlan_list,
0619 const struct switchdev_obj_port_vlan *vlan)
0620 {
0621 struct dsa_vlan *v;
0622
0623 list_for_each_entry(v, vlan_list, list)
0624 if (v->vid == vlan->vid)
0625 return v;
0626
0627 return NULL;
0628 }
0629
0630 static int dsa_port_do_vlan_add(struct dsa_port *dp,
0631 const struct switchdev_obj_port_vlan *vlan,
0632 struct netlink_ext_ack *extack)
0633 {
0634 struct dsa_switch *ds = dp->ds;
0635 int port = dp->index;
0636 struct dsa_vlan *v;
0637 int err = 0;
0638
0639
0640 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
0641 return ds->ops->port_vlan_add(ds, port, vlan, extack);
0642
0643
0644
0645
0646
0647
0648 if (vlan->changed)
0649 return 0;
0650
0651 mutex_lock(&dp->vlans_lock);
0652
0653 v = dsa_vlan_find(&dp->vlans, vlan);
0654 if (v) {
0655 refcount_inc(&v->refcount);
0656 goto out;
0657 }
0658
0659 v = kzalloc(sizeof(*v), GFP_KERNEL);
0660 if (!v) {
0661 err = -ENOMEM;
0662 goto out;
0663 }
0664
0665 err = ds->ops->port_vlan_add(ds, port, vlan, extack);
0666 if (err) {
0667 kfree(v);
0668 goto out;
0669 }
0670
0671 v->vid = vlan->vid;
0672 refcount_set(&v->refcount, 1);
0673 list_add_tail(&v->list, &dp->vlans);
0674
0675 out:
0676 mutex_unlock(&dp->vlans_lock);
0677
0678 return err;
0679 }
0680
0681 static int dsa_port_do_vlan_del(struct dsa_port *dp,
0682 const struct switchdev_obj_port_vlan *vlan)
0683 {
0684 struct dsa_switch *ds = dp->ds;
0685 int port = dp->index;
0686 struct dsa_vlan *v;
0687 int err = 0;
0688
0689
0690 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
0691 return ds->ops->port_vlan_del(ds, port, vlan);
0692
0693 mutex_lock(&dp->vlans_lock);
0694
0695 v = dsa_vlan_find(&dp->vlans, vlan);
0696 if (!v) {
0697 err = -ENOENT;
0698 goto out;
0699 }
0700
0701 if (!refcount_dec_and_test(&v->refcount))
0702 goto out;
0703
0704 err = ds->ops->port_vlan_del(ds, port, vlan);
0705 if (err) {
0706 refcount_set(&v->refcount, 1);
0707 goto out;
0708 }
0709
0710 list_del(&v->list);
0711 kfree(v);
0712
0713 out:
0714 mutex_unlock(&dp->vlans_lock);
0715
0716 return err;
0717 }
0718
0719 static int dsa_switch_vlan_add(struct dsa_switch *ds,
0720 struct dsa_notifier_vlan_info *info)
0721 {
0722 struct dsa_port *dp;
0723 int err;
0724
0725 if (!ds->ops->port_vlan_add)
0726 return -EOPNOTSUPP;
0727
0728 dsa_switch_for_each_port(dp, ds) {
0729 if (dsa_port_vlan_match(dp, info)) {
0730 err = dsa_port_do_vlan_add(dp, info->vlan,
0731 info->extack);
0732 if (err)
0733 return err;
0734 }
0735 }
0736
0737 return 0;
0738 }
0739
0740 static int dsa_switch_vlan_del(struct dsa_switch *ds,
0741 struct dsa_notifier_vlan_info *info)
0742 {
0743 struct dsa_port *dp;
0744 int err;
0745
0746 if (!ds->ops->port_vlan_del)
0747 return -EOPNOTSUPP;
0748
0749 dsa_switch_for_each_port(dp, ds) {
0750 if (dsa_port_vlan_match(dp, info)) {
0751 err = dsa_port_do_vlan_del(dp, info->vlan);
0752 if (err)
0753 return err;
0754 }
0755 }
0756
0757 return 0;
0758 }
0759
0760 static int dsa_switch_host_vlan_add(struct dsa_switch *ds,
0761 struct dsa_notifier_vlan_info *info)
0762 {
0763 struct dsa_port *dp;
0764 int err;
0765
0766 if (!ds->ops->port_vlan_add)
0767 return -EOPNOTSUPP;
0768
0769 dsa_switch_for_each_port(dp, ds) {
0770 if (dsa_port_host_vlan_match(dp, info->dp)) {
0771 err = dsa_port_do_vlan_add(dp, info->vlan,
0772 info->extack);
0773 if (err)
0774 return err;
0775 }
0776 }
0777
0778 return 0;
0779 }
0780
0781 static int dsa_switch_host_vlan_del(struct dsa_switch *ds,
0782 struct dsa_notifier_vlan_info *info)
0783 {
0784 struct dsa_port *dp;
0785 int err;
0786
0787 if (!ds->ops->port_vlan_del)
0788 return -EOPNOTSUPP;
0789
0790 dsa_switch_for_each_port(dp, ds) {
0791 if (dsa_port_host_vlan_match(dp, info->dp)) {
0792 err = dsa_port_do_vlan_del(dp, info->vlan);
0793 if (err)
0794 return err;
0795 }
0796 }
0797
0798 return 0;
0799 }
0800
0801 static int dsa_switch_change_tag_proto(struct dsa_switch *ds,
0802 struct dsa_notifier_tag_proto_info *info)
0803 {
0804 const struct dsa_device_ops *tag_ops = info->tag_ops;
0805 struct dsa_port *dp, *cpu_dp;
0806 int err;
0807
0808 if (!ds->ops->change_tag_protocol)
0809 return -EOPNOTSUPP;
0810
0811 ASSERT_RTNL();
0812
0813 err = ds->ops->change_tag_protocol(ds, tag_ops->proto);
0814 if (err)
0815 return err;
0816
0817 dsa_switch_for_each_cpu_port(cpu_dp, ds)
0818 dsa_port_set_tag_protocol(cpu_dp, tag_ops);
0819
0820
0821
0822
0823
0824 dsa_switch_for_each_user_port(dp, ds) {
0825 struct net_device *slave = dp->slave;
0826
0827 dsa_slave_setup_tagger(slave);
0828
0829
0830 dsa_slave_change_mtu(slave, slave->mtu);
0831 }
0832
0833 return 0;
0834 }
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845 static int
0846 dsa_switch_connect_tag_proto(struct dsa_switch *ds,
0847 struct dsa_notifier_tag_proto_info *info)
0848 {
0849 const struct dsa_device_ops *tag_ops = info->tag_ops;
0850 int err;
0851
0852
0853 if (tag_ops->connect) {
0854 err = tag_ops->connect(ds);
0855 if (err)
0856 return err;
0857 }
0858
0859 if (!ds->ops->connect_tag_protocol)
0860 return -EOPNOTSUPP;
0861
0862
0863 err = ds->ops->connect_tag_protocol(ds, tag_ops->proto);
0864 if (err) {
0865
0866 if (tag_ops->disconnect)
0867 tag_ops->disconnect(ds);
0868 return err;
0869 }
0870
0871 return 0;
0872 }
0873
0874 static int
0875 dsa_switch_disconnect_tag_proto(struct dsa_switch *ds,
0876 struct dsa_notifier_tag_proto_info *info)
0877 {
0878 const struct dsa_device_ops *tag_ops = info->tag_ops;
0879
0880
0881 if (tag_ops->disconnect && ds->tagger_data)
0882 tag_ops->disconnect(ds);
0883
0884
0885
0886
0887 return 0;
0888 }
0889
0890 static int
0891 dsa_switch_master_state_change(struct dsa_switch *ds,
0892 struct dsa_notifier_master_state_info *info)
0893 {
0894 if (!ds->ops->master_state_change)
0895 return 0;
0896
0897 ds->ops->master_state_change(ds, info->master, info->operational);
0898
0899 return 0;
0900 }
0901
0902 static int dsa_switch_event(struct notifier_block *nb,
0903 unsigned long event, void *info)
0904 {
0905 struct dsa_switch *ds = container_of(nb, struct dsa_switch, nb);
0906 int err;
0907
0908 switch (event) {
0909 case DSA_NOTIFIER_AGEING_TIME:
0910 err = dsa_switch_ageing_time(ds, info);
0911 break;
0912 case DSA_NOTIFIER_BRIDGE_JOIN:
0913 err = dsa_switch_bridge_join(ds, info);
0914 break;
0915 case DSA_NOTIFIER_BRIDGE_LEAVE:
0916 err = dsa_switch_bridge_leave(ds, info);
0917 break;
0918 case DSA_NOTIFIER_FDB_ADD:
0919 err = dsa_switch_fdb_add(ds, info);
0920 break;
0921 case DSA_NOTIFIER_FDB_DEL:
0922 err = dsa_switch_fdb_del(ds, info);
0923 break;
0924 case DSA_NOTIFIER_HOST_FDB_ADD:
0925 err = dsa_switch_host_fdb_add(ds, info);
0926 break;
0927 case DSA_NOTIFIER_HOST_FDB_DEL:
0928 err = dsa_switch_host_fdb_del(ds, info);
0929 break;
0930 case DSA_NOTIFIER_LAG_FDB_ADD:
0931 err = dsa_switch_lag_fdb_add(ds, info);
0932 break;
0933 case DSA_NOTIFIER_LAG_FDB_DEL:
0934 err = dsa_switch_lag_fdb_del(ds, info);
0935 break;
0936 case DSA_NOTIFIER_LAG_CHANGE:
0937 err = dsa_switch_lag_change(ds, info);
0938 break;
0939 case DSA_NOTIFIER_LAG_JOIN:
0940 err = dsa_switch_lag_join(ds, info);
0941 break;
0942 case DSA_NOTIFIER_LAG_LEAVE:
0943 err = dsa_switch_lag_leave(ds, info);
0944 break;
0945 case DSA_NOTIFIER_MDB_ADD:
0946 err = dsa_switch_mdb_add(ds, info);
0947 break;
0948 case DSA_NOTIFIER_MDB_DEL:
0949 err = dsa_switch_mdb_del(ds, info);
0950 break;
0951 case DSA_NOTIFIER_HOST_MDB_ADD:
0952 err = dsa_switch_host_mdb_add(ds, info);
0953 break;
0954 case DSA_NOTIFIER_HOST_MDB_DEL:
0955 err = dsa_switch_host_mdb_del(ds, info);
0956 break;
0957 case DSA_NOTIFIER_VLAN_ADD:
0958 err = dsa_switch_vlan_add(ds, info);
0959 break;
0960 case DSA_NOTIFIER_VLAN_DEL:
0961 err = dsa_switch_vlan_del(ds, info);
0962 break;
0963 case DSA_NOTIFIER_HOST_VLAN_ADD:
0964 err = dsa_switch_host_vlan_add(ds, info);
0965 break;
0966 case DSA_NOTIFIER_HOST_VLAN_DEL:
0967 err = dsa_switch_host_vlan_del(ds, info);
0968 break;
0969 case DSA_NOTIFIER_MTU:
0970 err = dsa_switch_mtu(ds, info);
0971 break;
0972 case DSA_NOTIFIER_TAG_PROTO:
0973 err = dsa_switch_change_tag_proto(ds, info);
0974 break;
0975 case DSA_NOTIFIER_TAG_PROTO_CONNECT:
0976 err = dsa_switch_connect_tag_proto(ds, info);
0977 break;
0978 case DSA_NOTIFIER_TAG_PROTO_DISCONNECT:
0979 err = dsa_switch_disconnect_tag_proto(ds, info);
0980 break;
0981 case DSA_NOTIFIER_TAG_8021Q_VLAN_ADD:
0982 err = dsa_switch_tag_8021q_vlan_add(ds, info);
0983 break;
0984 case DSA_NOTIFIER_TAG_8021Q_VLAN_DEL:
0985 err = dsa_switch_tag_8021q_vlan_del(ds, info);
0986 break;
0987 case DSA_NOTIFIER_MASTER_STATE_CHANGE:
0988 err = dsa_switch_master_state_change(ds, info);
0989 break;
0990 default:
0991 err = -EOPNOTSUPP;
0992 break;
0993 }
0994
0995 if (err)
0996 dev_dbg(ds->dev, "breaking chain for DSA event %lu (%d)\n",
0997 event, err);
0998
0999 return notifier_from_errno(err);
1000 }
1001
1002 int dsa_switch_register_notifier(struct dsa_switch *ds)
1003 {
1004 ds->nb.notifier_call = dsa_switch_event;
1005
1006 return raw_notifier_chain_register(&ds->dst->nh, &ds->nb);
1007 }
1008
1009 void dsa_switch_unregister_notifier(struct dsa_switch *ds)
1010 {
1011 int err;
1012
1013 err = raw_notifier_chain_unregister(&ds->dst->nh, &ds->nb);
1014 if (err)
1015 dev_err(ds->dev, "failed to unregister notifier (%d)\n", err);
1016 }