* FORWARD frames, which use the LAG ID as the
                         * source port, we must translate dev/port to
                         * the special "LAG device" in the PVT, using
-                        * the LAG ID as the port number.
+                        * the LAG ID (one-based) as the port number
+                        * (zero-based).
                         */
                        dev = MV88E6XXX_G2_PVT_ADDR_DEV_TRUNK;
-                       port = dsa_lag_id(dst, dp->lag_dev);
+                       port = dsa_lag_id(dst, dp->lag_dev) - 1;
                }
        }
 
                return false;
 
        id = dsa_lag_id(ds->dst, lag_dev);
-       if (id < 0 || id >= ds->num_lag_ids)
+       if (id <= 0 || id > ds->num_lag_ids)
                return false;
 
        dsa_lag_foreach_port(dp, ds->dst, lag_dev)
        u16 map = 0;
        int id;
 
-       id = dsa_lag_id(ds->dst, lag_dev);
+       /* DSA LAG IDs are one-based, hardware is zero-based */
+       id = dsa_lag_id(ds->dst, lag_dev) - 1;
 
        /* Build the map of all ports to distribute flows destined for
         * this LAG. This can be either a local user port, or a DSA
        if (!mv88e6xxx_lag_can_offload(ds, lag_dev, info))
                return -EOPNOTSUPP;
 
-       id = dsa_lag_id(ds->dst, lag_dev);
+       /* DSA LAG IDs are one-based */
+       id = dsa_lag_id(ds->dst, lag_dev) - 1;
 
        mv88e6xxx_reg_lock(chip);
 
 
        int id, members = 0;
 
        id = dsa_lag_id(ds->dst, lag_dev);
-       if (id < 0 || id >= ds->num_lag_ids)
+       if (id <= 0 || id > ds->num_lag_ids)
                return false;
 
        dsa_lag_foreach_port(dp, ds->dst, lag_dev)
        int ret, id, i;
        u32 val;
 
-       id = dsa_lag_id(ds->dst, lag_dev);
+       /* DSA LAG IDs are one-based, hardware is zero-based */
+       id = dsa_lag_id(ds->dst, lag_dev) - 1;
 
        /* Read current port member */
        ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
 
        unsigned int last_switch;
 };
 
+/* LAG IDs are one-based, the dst->lags array is zero-based */
 #define dsa_lags_foreach_id(_id, _dst)                         \
-       for ((_id) = 0; (_id) < (_dst)->lags_len; (_id)++)      \
-               if ((_dst)->lags[(_id)])
+       for ((_id) = 1; (_id) <= (_dst)->lags_len; (_id)++)     \
+               if ((_dst)->lags[(_id) - 1])
 
 #define dsa_lag_foreach_port(_dp, _dst, _lag)                  \
        list_for_each_entry((_dp), &(_dst)->ports, list)        \
 static inline struct net_device *dsa_lag_dev(struct dsa_switch_tree *dst,
                                             unsigned int id)
 {
-       return dst->lags[id];
+       /* DSA LAG IDs are one-based, dst->lags is zero-based */
+       return dst->lags[id - 1];
 }
 
 static inline int dsa_lag_id(struct dsa_switch_tree *dst,
 
 {
        unsigned int id;
 
-       if (dsa_lag_id(dst, lag_dev) >= 0)
+       if (dsa_lag_id(dst, lag_dev) > 0)
                /* Already mapped */
                return;
 
-       for (id = 0; id < dst->lags_len; id++) {
+       for (id = 1; id <= dst->lags_len; id++) {
                if (!dsa_lag_dev(dst, id)) {
-                       dst->lags[id] = lag_dev;
+                       dst->lags[id - 1] = lag_dev;
                        return;
                }
        }
 
        dsa_lags_foreach_id(id, dst) {
                if (dsa_lag_dev(dst, id) == lag_dev) {
-                       dst->lags[id] = NULL;
+                       dst->lags[id - 1] = NULL;
                        break;
                }
        }
 
                 * so we inject the frame directly on the upper
                 * team/bond.
                 */
-               skb->dev = dsa_lag_dev(cpu_dp->dst, source_port);
+               skb->dev = dsa_lag_dev(cpu_dp->dst, source_port + 1);
        } else {
                skb->dev = dsa_master_find_slave(dev, source_device,
                                                 source_port);