struct mii_bus *mdio_base_tx;
        struct mii_bus *mdio_pcs;
        struct dw_xpcs *xpcs[SJA1105_MAX_NUM_PORTS];
-       struct sja1105_tagger_data tagger_data;
        struct sja1105_ptp_data ptp_data;
        struct sja1105_tas_data tas_data;
 };
 
        kfree(xmit_work);
 }
 
+static int sja1105_connect_tag_protocol(struct dsa_switch *ds,
+                                       enum dsa_tag_protocol proto)
+{
+       struct sja1105_tagger_data *tagger_data;
+
+       switch (proto) {
+       case DSA_TAG_PROTO_SJA1105:
+               tagger_data = sja1105_tagger_data(ds);
+               tagger_data->xmit_work_fn = sja1105_port_deferred_xmit;
+               return 0;
+       default:
+               return -EPROTONOSUPPORT;
+       }
+}
+
 /* The MAXAGE setting belongs to the L2 Forwarding Parameters table,
  * which cannot be reconfigured at runtime. So a switch reset is required.
  */
        return 0;
 }
 
-static void sja1105_teardown_ports(struct sja1105_private *priv)
-{
-       struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
-
-       kthread_destroy_worker(tagger_data->xmit_worker);
-}
-
-static int sja1105_setup_ports(struct sja1105_private *priv)
-{
-       struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
-       struct dsa_switch *ds = priv->ds;
-       struct kthread_worker *worker;
-       struct dsa_port *dp;
-
-       worker = kthread_create_worker(0, "dsa%d:%d_xmit", ds->dst->index,
-                                      ds->index);
-       if (IS_ERR(worker)) {
-               dev_err(ds->dev,
-                       "failed to create deferred xmit thread: %pe\n",
-                       worker);
-               return PTR_ERR(worker);
-       }
-
-       tagger_data->xmit_worker = worker;
-       tagger_data->xmit_work_fn = sja1105_port_deferred_xmit;
-
-       dsa_switch_for_each_user_port(dp, ds)
-               dp->priv = tagger_data;
-
-       return 0;
-}
-
 /* The programming model for the SJA1105 switch is "all-at-once" via static
  * configuration tables. Some of these can be dynamically modified at runtime,
  * but not the xMII mode parameters table.
                }
        }
 
-       rc = sja1105_setup_ports(priv);
-       if (rc)
-               goto out_static_config_free;
-
        sja1105_tas_setup(ds);
        sja1105_flower_setup(ds);
 
 out_flower_teardown:
        sja1105_flower_teardown(ds);
        sja1105_tas_teardown(ds);
-       sja1105_teardown_ports(priv);
 out_static_config_free:
        sja1105_static_config_free(&priv->static_config);
 
        sja1105_ptp_clock_unregister(ds);
        sja1105_flower_teardown(ds);
        sja1105_tas_teardown(ds);
-       sja1105_teardown_ports(priv);
        sja1105_static_config_free(&priv->static_config);
 }
 
 static const struct dsa_switch_ops sja1105_switch_ops = {
        .get_tag_protocol       = sja1105_get_tag_protocol,
+       .connect_tag_protocol   = sja1105_connect_tag_protocol,
        .setup                  = sja1105_setup,
        .teardown               = sja1105_teardown,
        .set_ageing_time        = sja1105_set_ageing_time,
 
 #define ptp_data_to_sja1105(d) \
                container_of((d), struct sja1105_private, ptp_data)
 
-/* Must be called only with priv->tagger_data.state bit
+/* Must be called only with the tagger_data->state bit
  * SJA1105_HWTS_RX_EN cleared
  */
 static int sja1105_change_rxtstamping(struct sja1105_private *priv,
+                                     struct sja1105_tagger_data *tagger_data,
                                      bool on)
 {
-       struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
        struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
        struct sja1105_general_params_entry *general_params;
        struct sja1105_table *table;
        general_params->send_meta0 = on;
 
        /* Initialize the meta state machine to a known state */
-       if (priv->tagger_data.stampable_skb) {
-               kfree_skb(priv->tagger_data.stampable_skb);
-               priv->tagger_data.stampable_skb = NULL;
+       if (tagger_data->stampable_skb) {
+               kfree_skb(tagger_data->stampable_skb);
+               tagger_data->stampable_skb = NULL;
        }
        ptp_cancel_worker_sync(ptp_data->clock);
        skb_queue_purge(&tagger_data->skb_txtstamp_queue);
 
 int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
 {
+       struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
        struct sja1105_private *priv = ds->priv;
        struct hwtstamp_config config;
        bool rx_on;
                break;
        }
 
-       if (rx_on != test_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state)) {
-               clear_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state);
+       if (rx_on != test_bit(SJA1105_HWTS_RX_EN, &tagger_data->state)) {
+               clear_bit(SJA1105_HWTS_RX_EN, &tagger_data->state);
 
-               rc = sja1105_change_rxtstamping(priv, rx_on);
+               rc = sja1105_change_rxtstamping(priv, tagger_data, rx_on);
                if (rc < 0) {
                        dev_err(ds->dev,
                                "Failed to change RX timestamping: %d\n", rc);
                        return rc;
                }
                if (rx_on)
-                       set_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state);
+                       set_bit(SJA1105_HWTS_RX_EN, &tagger_data->state);
        }
 
        if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
 
 int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr)
 {
+       struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
        struct sja1105_private *priv = ds->priv;
        struct hwtstamp_config config;
 
                config.tx_type = HWTSTAMP_TX_ON;
        else
                config.tx_type = HWTSTAMP_TX_OFF;
-       if (test_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state))
+       if (test_bit(SJA1105_HWTS_RX_EN, &tagger_data->state))
                config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
        else
                config.rx_filter = HWTSTAMP_FILTER_NONE;
 
 bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
 {
+       struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
        struct sja1105_private *priv = ds->priv;
        struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
 
-       if (!test_bit(SJA1105_HWTS_RX_EN, &priv->tagger_data.state))
+       if (!test_bit(SJA1105_HWTS_RX_EN, &tagger_data->state))
                return false;
 
        /* We need to read the full PTP clock to reconstruct the Rx
  */
 void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
 {
+       struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
        struct sk_buff *clone = SJA1105_SKB_CB(skb)->clone;
        struct sja1105_private *priv = ds->priv;
-       struct sja1105_tagger_data *tagger_data;
        u8 ts_id;
 
-       tagger_data = &priv->tagger_data;
-
        skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
 
        spin_lock(&priv->ts_id_lock);
 int sja1105_ptp_clock_register(struct dsa_switch *ds)
 {
        struct sja1105_private *priv = ds->priv;
-       struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
        struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
 
        ptp_data->caps = (struct ptp_clock_info) {
 
        /* Only used on SJA1105 */
        skb_queue_head_init(&ptp_data->skb_rxtstamp_queue);
-       /* Only used on SJA1110 */
-       skb_queue_head_init(&tagger_data->skb_txtstamp_queue);
-       spin_lock_init(&tagger_data->meta_lock);
 
        ptp_data->clock = ptp_clock_register(&ptp_data->caps, ds->dev);
        if (IS_ERR_OR_NULL(ptp_data->clock))
 
 void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
 {
+       struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
        struct sja1105_private *priv = ds->priv;
-       struct sja1105_tagger_data *tagger_data = &priv->tagger_data;
        struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
 
        if (IS_ERR_OR_NULL(ptp_data->clock))
 
        return ticks * SJA1105_TICK_NS;
 }
 
-static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
+static inline struct sja1105_tagger_data *
+sja1105_tagger_data(struct dsa_switch *ds)
 {
-       return true;
+       BUG_ON(ds->dst->tag_ops->proto != DSA_TAG_PROTO_SJA1105);
+
+       return ds->tagger_data;
 }
 
 #endif /* _NET_DSA_SJA1105_H */
 
 static struct sk_buff *sja1105_defer_xmit(struct dsa_port *dp,
                                          struct sk_buff *skb)
 {
-       struct sja1105_tagger_data *tagger_data = dp->priv;
+       struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(dp->ds);
        void (*xmit_work_fn)(struct kthread_work *work);
        struct sja1105_deferred_xmit_work *xmit_work;
        struct kthread_worker *xmit_worker;
         */
        if (is_link_local) {
                struct dsa_port *dp = dsa_slave_to_port(skb->dev);
-               struct sja1105_tagger_data *tagger_data = dp->priv;
+               struct sja1105_tagger_data *tagger_data;
+               struct dsa_switch *ds = dp->ds;
 
-               if (unlikely(!dsa_port_is_sja1105(dp)))
-                       return skb;
+               tagger_data = sja1105_tagger_data(ds);
 
                if (!test_bit(SJA1105_HWTS_RX_EN, &tagger_data->state))
                        /* Do normal processing. */
                 * that we were expecting?
                 */
                if (tagger_data->stampable_skb) {
-                       dev_err_ratelimited(dp->ds->dev,
+                       dev_err_ratelimited(ds->dev,
                                            "Expected meta frame, is %12llx "
                                            "in the DSA master multicast filter?\n",
                                            SJA1105_META_DMAC);
         */
        } else if (is_meta) {
                struct dsa_port *dp = dsa_slave_to_port(skb->dev);
-               struct sja1105_tagger_data *tagger_data = dp->priv;
+               struct sja1105_tagger_data *tagger_data;
+               struct dsa_switch *ds = dp->ds;
                struct sk_buff *stampable_skb;
 
-               if (unlikely(!dsa_port_is_sja1105(dp)))
-                       return skb;
+               tagger_data = sja1105_tagger_data(ds);
 
                /* Drop the meta frame if we're not in the right state
                 * to process it.
                 * that we were expecting?
                 */
                if (!stampable_skb) {
-                       dev_err_ratelimited(dp->ds->dev,
+                       dev_err_ratelimited(ds->dev,
                                            "Unexpected meta frame\n");
                        spin_unlock(&tagger_data->meta_lock);
                        return NULL;
                }
 
                if (stampable_skb->dev != skb->dev) {
-                       dev_err_ratelimited(dp->ds->dev,
+                       dev_err_ratelimited(ds->dev,
                                            "Meta frame on wrong port\n");
                        spin_unlock(&tagger_data->meta_lock);
                        return NULL;
                                        u8 ts_id, enum sja1110_meta_tstamp dir,
                                        u64 tstamp)
 {
+       struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
        struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
-       struct dsa_port *dp = dsa_to_port(ds, port);
-       struct sja1105_tagger_data *tagger_data;
        struct skb_shared_hwtstamps shwt = {0};
 
-       if (!dsa_port_is_sja1105(dp))
-               return;
-
        /* We don't care about RX timestamps on the CPU port */
        if (dir == SJA1110_META_TSTAMP_RX)
                return;
 
-       tagger_data = dp->priv;
-
        spin_lock(&tagger_data->skb_txtstamp_queue.lock);
 
        skb_queue_walk_safe(&tagger_data->skb_txtstamp_queue, skb, skb_tmp) {
        *proto = ((__be16 *)skb->data)[(VLAN_HLEN / 2) - 1];
 }
 
+static void sja1105_disconnect(struct dsa_switch_tree *dst)
+{
+       struct sja1105_tagger_data *tagger_data;
+       struct dsa_port *dp;
+
+       list_for_each_entry(dp, &dst->ports, list) {
+               tagger_data = dp->ds->tagger_data;
+
+               if (!tagger_data)
+                       continue;
+
+               if (tagger_data->xmit_worker)
+                       kthread_destroy_worker(tagger_data->xmit_worker);
+
+               kfree(tagger_data);
+               dp->ds->tagger_data = NULL;
+       }
+}
+
+static int sja1105_connect(struct dsa_switch_tree *dst)
+{
+       struct sja1105_tagger_data *tagger_data;
+       struct kthread_worker *xmit_worker;
+       struct dsa_port *dp;
+       int err;
+
+       list_for_each_entry(dp, &dst->ports, list) {
+               if (dp->ds->tagger_data)
+                       continue;
+
+               tagger_data = kzalloc(sizeof(*tagger_data), GFP_KERNEL);
+               if (!tagger_data) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+
+               /* Only used on SJA1110 */
+               skb_queue_head_init(&tagger_data->skb_txtstamp_queue);
+               spin_lock_init(&tagger_data->meta_lock);
+
+               xmit_worker = kthread_create_worker(0, "dsa%d:%d_xmit",
+                                                   dst->index, dp->ds->index);
+               if (IS_ERR(xmit_worker)) {
+                       err = PTR_ERR(xmit_worker);
+                       goto out;
+               }
+
+               tagger_data->xmit_worker = xmit_worker;
+               dp->ds->tagger_data = tagger_data;
+       }
+
+       return 0;
+
+out:
+       sja1105_disconnect(dst);
+       return err;
+}
+
 static const struct dsa_device_ops sja1105_netdev_ops = {
        .name = "sja1105",
        .proto = DSA_TAG_PROTO_SJA1105,
        .xmit = sja1105_xmit,
        .rcv = sja1105_rcv,
+       .connect = sja1105_connect,
+       .disconnect = sja1105_disconnect,
        .needed_headroom = VLAN_HLEN,
        .flow_dissect = sja1105_flow_dissect,
        .promisc_on_master = true,
        .proto = DSA_TAG_PROTO_SJA1110,
        .xmit = sja1110_xmit,
        .rcv = sja1110_rcv,
+       .connect = sja1105_connect,
+       .disconnect = sja1105_disconnect,
        .flow_dissect = sja1110_flow_dissect,
        .needed_headroom = SJA1110_HEADER_LEN + VLAN_HLEN,
        .needed_tailroom = SJA1110_RX_TRAILER_LEN + SJA1110_MAX_PADDING_LEN,