int dsa_master_ethtool_setup(struct net_device *dev);
 void dsa_master_ethtool_restore(struct net_device *dev);
 
+static inline struct net_device *dsa_master_get_slave(struct net_device *dev,
+                                                     int device, int port)
+{
+       struct dsa_switch_tree *dst = dev->dsa_ptr;
+       struct dsa_switch *ds;
+
+       if (device < 0 || device >= DSA_MAX_SWITCHES)
+               return NULL;
+
+       ds = dst->ds[device];
+       if (!ds)
+               return NULL;
+
+       if (port < 0 || port >= ds->num_ports)
+               return NULL;
+
+       return ds->ports[port].netdev;
+}
+
 /* port.c */
 int dsa_port_set_state(struct dsa_port *dp, u8 state,
                       struct switchdev_trans *trans);
        return p->dp->cpu_dp->netdev;
 }
 
-static inline struct dsa_port *dsa_get_cpu_port(struct dsa_switch_tree *dst)
-{
-       return dst->cpu_dp;
-}
-
 #endif
 
 static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
                                    struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
-       struct dsa_switch *ds = cpu_dp->ds;
        int source_port;
        u8 *brcm_tag;
 
        /* Locate which port this is coming from */
        source_port = brcm_tag[3] & BRCM_EG_PID_MASK;
 
-       /* Validate port against switch setup, either the port is totally */
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+       skb->dev = dsa_master_get_slave(dev, 0, source_port);
+       if (!skb->dev)
                return NULL;
 
        /* Remove Broadcom tag and update checksum */
                skb->data - ETH_HLEN - BRCM_TAG_LEN,
                2 * ETH_ALEN);
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
 
 static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
                               struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_switch *ds;
        u8 *dsa_header;
        int source_device;
        int source_port;
        source_device = dsa_header[0] & 0x1f;
        source_port = (dsa_header[1] >> 3) & 0x1f;
 
-       /*
-        * Check that the source device exists and that the source
-        * port is a registered DSA port.
-        */
-       if (source_device >= DSA_MAX_SWITCHES)
-               return NULL;
-
-       ds = dst->ds[source_device];
-       if (!ds)
-               return NULL;
-
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+       skb->dev = dsa_master_get_slave(dev, source_device, source_port);
+       if (!skb->dev)
                return NULL;
 
        /*
                        2 * ETH_ALEN);
        }
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
 
 static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
                                struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_switch *ds;
        u8 *edsa_header;
        int source_device;
        int source_port;
        source_device = edsa_header[0] & 0x1f;
        source_port = (edsa_header[1] >> 3) & 0x1f;
 
-       /*
-        * Check that the source device exists and that the source
-        * port is a registered DSA port.
-        */
-       if (source_device >= DSA_MAX_SWITCHES)
-               return NULL;
-
-       ds = dst->ds[source_device];
-       if (!ds)
-               return NULL;
-
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+       skb->dev = dsa_master_get_slave(dev, source_device, source_port);
+       if (!skb->dev)
                return NULL;
 
        /*
                        2 * ETH_ALEN);
        }
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
 
 static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct net_device *dev,
                               struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
-       struct dsa_switch *ds = cpu_dp->ds;
        u8 *tag;
        int source_port;
 
        tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN;
 
        source_port = tag[0] & 7;
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+
+       skb->dev = dsa_master_get_slave(dev, 0, source_port);
+       if (!skb->dev)
                return NULL;
 
        pskb_trim_rcsum(skb, skb->len - KSZ_EGRESS_TAG_LEN);
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
 
                        struct packet_type *pt)
 {
        u16 *lan9303_tag;
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_switch *ds;
        unsigned int source_port;
 
-       ds = dst->ds[0];
-
-       if (unlikely(!ds)) {
-               dev_warn_ratelimited(&dev->dev, "Dropping packet, due to missing DSA switch device\n");
-               return NULL;
-       }
-
        if (unlikely(!pskb_may_pull(skb, LAN9303_TAG_LEN))) {
                dev_warn_ratelimited(&dev->dev,
                                     "Dropping packet, cannot pull\n");
 
        source_port = ntohs(lan9303_tag[1]) & 0x3;
 
-       if (source_port >= ds->num_ports) {
+       skb->dev = dsa_master_get_slave(dev, 0, source_port);
+       if (!skb->dev) {
                dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid source port\n");
                return NULL;
        }
 
-       if (!ds->ports[source_port].netdev) {
-               dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid netdev or device\n");
-               return NULL;
-       }
-
        /* remove the special VLAN tag between the MAC addresses
         * and the current ethertype field.
         */
        memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
                2 * ETH_ALEN);
 
-       /* forward the packet to the dedicated interface */
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
 
 static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
                                   struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_switch *ds;
        int port;
        __be16 *phdr, hdr;
 
                skb->data - ETH_HLEN - MTK_HDR_LEN,
                2 * ETH_ALEN);
 
-       /* This protocol doesn't support cascading multiple
-        * switches so it's safe to assume the switch is first
-        * in the tree.
-        */
-       ds = dst->ds[0];
-       if (!ds)
-               return NULL;
-
        /* Get source port information */
        port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK);
-       if (!ds->ports[port].netdev)
-               return NULL;
 
-       skb->dev = ds->ports[port].netdev;
+       skb->dev = dsa_master_get_slave(dev, 0, port);
+       if (!skb->dev)
+               return NULL;
 
        return skb;
 }
 
 static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
                                   struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
-       struct dsa_switch *ds;
        u8 ver;
        int port;
        __be16 *phdr, hdr;
        memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - QCA_HDR_LEN,
                ETH_HLEN - QCA_HDR_LEN);
 
-       /* This protocol doesn't support cascading multiple switches so it's
-        * safe to assume the switch is first in the tree
-        */
-       ds = cpu_dp->ds;
-       if (!ds)
-               return NULL;
-
        /* Get source port information */
        port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK);
-       if (!ds->ports[port].netdev)
-               return NULL;
 
-       /* Update skb & forward the frame accordingly */
-       skb->dev = ds->ports[port].netdev;
+       skb->dev = dsa_master_get_slave(dev, 0, port);
+       if (!skb->dev)
+               return NULL;
 
        return skb;
 }
 
 static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev,
                                   struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
-       struct dsa_switch *ds = cpu_dp->ds;
        u8 *trailer;
        int source_port;
 
                return NULL;
 
        source_port = trailer[1] & 7;
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+
+       skb->dev = dsa_master_get_slave(dev, 0, source_port);
+       if (!skb->dev)
                return NULL;
 
        pskb_trim_rcsum(skb, skb->len - 4);
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }