Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Handling of a single switch chip, part of a switch fabric
0004  *
0005  * Copyright (c) 2017 Savoir-faire Linux Inc.
0006  *  Vivien Didelot <vivien.didelot@savoirfairelinux.com>
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     /* Program the fastest ageing time in case of multiple bridges */
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 /* Matches for all upstream-facing ports (the CPU port and all upstream-facing
0123  * DSA links) that sit between the targeted port on which the notifier was
0124  * emitted and its dedicated CPU port.
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     /* No need to bother with refcounting for user ports */
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     /* No need to bother with refcounting for user ports */
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     /* No need to bother with refcounting for user ports */
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     /* No need to bother with refcounting for user ports */
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     /* Notify switch only if it has a port in this LAG */
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     /* Notify switch only if it has a port in this LAG */
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 /* Port VLANs match on the targeted port and on all DSA ports */
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 /* Host VLANs match on the targeted port's CPU port, and on all DSA ports
0605  * (upstream and downstream) of that switch and its upstream switches.
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     /* No need to bother with refcounting for user ports. */
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     /* No need to propagate on shared ports the existing VLANs that were
0644      * re-notified after just the flags have changed. This would cause a
0645      * refcount bump which we need to avoid, since it unbalances the
0646      * additions with the deletions.
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     /* No need to bother with refcounting for user ports */
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     /* Now that changing the tag protocol can no longer fail, let's update
0821      * the remaining bits which are "duplicated for faster access", and the
0822      * bits that depend on the tagger, such as the MTU.
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         /* rtnl_mutex is held in dsa_tree_change_tag_proto */
0830         dsa_slave_change_mtu(slave, slave->mtu);
0831     }
0832 
0833     return 0;
0834 }
0835 
0836 /* We use the same cross-chip notifiers to inform both the tagger side, as well
0837  * as the switch side, of connection and disconnection events.
0838  * Since ds->tagger_data is owned by the tagger, it isn't a hard error if the
0839  * switch side doesn't support connecting to this tagger, and therefore, the
0840  * fact that we don't disconnect the tagger side doesn't constitute a memory
0841  * leak: the tagger will still operate with persistent per-switch memory, just
0842  * with the switch side unconnected to it. What does constitute a hard error is
0843  * when the switch side supports connecting but fails.
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     /* Notify the new tagger about the connection to this switch */
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     /* Notify the switch about the connection to the new tagger */
0863     err = ds->ops->connect_tag_protocol(ds, tag_ops->proto);
0864     if (err) {
0865         /* Revert the new tagger's connection to this tree */
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     /* Notify the tagger about the disconnection from this switch */
0881     if (tag_ops->disconnect && ds->tagger_data)
0882         tag_ops->disconnect(ds);
0883 
0884     /* No need to notify the switch, since it shouldn't have any
0885      * resources to tear down
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 }