.sb_occ_tc_port_bind_get        = dsa_devlink_sb_occ_tc_port_bind_get,
 };
 
+static int dsa_switch_setup_tag_protocol(struct dsa_switch *ds)
+{
+       const struct dsa_device_ops *tag_ops = ds->dst->tag_ops;
+       struct dsa_switch_tree *dst = ds->dst;
+       int port, err;
+
+       if (tag_ops->proto == dst->default_proto)
+               return 0;
+
+       for (port = 0; port < ds->num_ports; port++) {
+               if (!dsa_is_cpu_port(ds, port))
+                       continue;
+
+               err = ds->ops->change_tag_protocol(ds, port, tag_ops->proto);
+               if (err) {
+                       dev_err(ds->dev, "Unable to use tag protocol \"%s\": %pe\n",
+                               tag_ops->name, ERR_PTR(err));
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
 static int dsa_switch_setup(struct dsa_switch *ds)
 {
        struct dsa_devlink_priv *dl_priv;
        if (err < 0)
                goto unregister_notifier;
 
+       err = dsa_switch_setup_tag_protocol(ds);
+       if (err)
+               goto teardown;
+
        devlink_params_publish(ds->devlink);
 
        if (!ds->slave_mii_bus && ds->ops->phy_read) {
        return ds->ops->get_tag_protocol(ds, dp->index, tag_protocol);
 }
 
-static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master)
+static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master,
+                             const char *user_protocol)
 {
        struct dsa_switch *ds = dp->ds;
        struct dsa_switch_tree *dst = ds->dst;
        const struct dsa_device_ops *tag_ops;
-       enum dsa_tag_protocol tag_protocol;
+       enum dsa_tag_protocol default_proto;
+
+       /* Find out which protocol the switch would prefer. */
+       default_proto = dsa_get_tag_protocol(dp, master);
+       if (dst->default_proto) {
+               if (dst->default_proto != default_proto) {
+                       dev_err(ds->dev,
+                               "A DSA switch tree can have only one tagging protocol\n");
+                       return -EINVAL;
+               }
+       } else {
+               dst->default_proto = default_proto;
+       }
+
+       /* See if the user wants to override that preference. */
+       if (user_protocol) {
+               if (!ds->ops->change_tag_protocol) {
+                       dev_err(ds->dev, "Tag protocol cannot be modified\n");
+                       return -EINVAL;
+               }
+
+               tag_ops = dsa_find_tagger_by_name(user_protocol);
+       } else {
+               tag_ops = dsa_tag_driver_get(default_proto);
+       }
+
+       if (IS_ERR(tag_ops)) {
+               if (PTR_ERR(tag_ops) == -ENOPROTOOPT)
+                       return -EPROBE_DEFER;
+
+               dev_warn(ds->dev, "No tagger for this switch\n");
+               return PTR_ERR(tag_ops);
+       }
 
-       tag_protocol = dsa_get_tag_protocol(dp, master);
        if (dst->tag_ops) {
-               if (dst->tag_ops->proto != tag_protocol) {
+               if (dst->tag_ops != tag_ops) {
                        dev_err(ds->dev,
                                "A DSA switch tree can have only one tagging protocol\n");
+
+                       dsa_tag_driver_put(tag_ops);
                        return -EINVAL;
                }
+
                /* In the case of multiple CPU ports per switch, the tagging
-                * protocol is still reference-counted only per switch tree, so
-                * nothing to do here.
+                * protocol is still reference-counted only per switch tree.
                 */
+               dsa_tag_driver_put(tag_ops);
        } else {
-               tag_ops = dsa_tag_driver_get(tag_protocol);
-               if (IS_ERR(tag_ops)) {
-                       if (PTR_ERR(tag_ops) == -ENOPROTOOPT)
-                               return -EPROBE_DEFER;
-                       dev_warn(ds->dev, "No tagger for this switch\n");
-                       dp->master = NULL;
-                       return PTR_ERR(tag_ops);
-               }
-
                dst->tag_ops = tag_ops;
        }
 
        dsa_port_set_tag_protocol(dp, dst->tag_ops);
        dp->dst = dst;
 
+       /* At this point, the tree may be configured to use a different
+        * tagger than the one chosen by the switch driver during
+        * .setup, in the case when a user selects a custom protocol
+        * through the DT.
+        *
+        * This is resolved by syncing the driver with the tree in
+        * dsa_switch_setup_tag_protocol once .setup has run and the
+        * driver is ready to accept calls to .change_tag_protocol. If
+        * the driver does not support the custom protocol at that
+        * point, the tree is wholly rejected, thereby ensuring that the
+        * tree and driver are always in agreement on the protocol to
+        * use.
+        */
        return 0;
 }
 
 
        if (ethernet) {
                struct net_device *master;
+               const char *user_protocol;
 
                master = of_find_net_device_by_node(ethernet);
                if (!master)
                        return -EPROBE_DEFER;
 
-               return dsa_port_parse_cpu(dp, master);
+               user_protocol = of_get_property(dn, "dsa-tag-protocol", NULL);
+               return dsa_port_parse_cpu(dp, master, user_protocol);
        }
 
        if (link)
 
                dev_put(master);
 
-               return dsa_port_parse_cpu(dp, master);
+               return dsa_port_parse_cpu(dp, master, NULL);
        }
 
        if (!strcmp(name, "dsa"))