diff options
Diffstat (limited to 'target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c')
-rw-r--r-- | target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c index 5a90e53da2..ea08ca12fc 100644 --- a/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c +++ b/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c @@ -402,11 +402,15 @@ static int __init rtl83xx_get_l2aging(struct rtl838x_switch_priv *priv) } /* Caller must hold priv->reg_mutex */ -int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port) +int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port, struct netdev_lag_upper_info *info) { struct rtl838x_switch_priv *priv = ds->priv; int i; - + u32 algomsk = 0; + u32 algoidx = 0; + if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH) { + return -EINVAL; + } pr_info("%s: Adding port %d to LA-group %d\n", __func__, port, group); if (group >= priv->n_lags) { pr_err("Link Agrregation group too large.\n"); @@ -419,18 +423,40 @@ int rtl83xx_lag_add(struct dsa_switch *ds, int group, int port) } for (i = 0; i < priv->n_lags; i++) { - if (priv->lags_port_members[i] & BIT_ULL(i)) + if (priv->lags_port_members[i] & BIT_ULL(port)) break; } if (i != priv->n_lags) { pr_err("%s: Port already member of LAG: %d\n", __func__, i); return -ENOSPC; } - + switch(info->hash_type) { + case NETDEV_LAG_HASH_L2: + algomsk |= TRUNK_DISTRIBUTION_ALGO_DMAC_BIT; + algomsk |= TRUNK_DISTRIBUTION_ALGO_SMAC_BIT; + break; + case NETDEV_LAG_HASH_L23: + algomsk |= TRUNK_DISTRIBUTION_ALGO_DMAC_BIT; + algomsk |= TRUNK_DISTRIBUTION_ALGO_SMAC_BIT; + algomsk |= TRUNK_DISTRIBUTION_ALGO_SIP_BIT; //source ip + algomsk |= TRUNK_DISTRIBUTION_ALGO_DIP_BIT; //dest ip + algoidx = 1; + break; + case NETDEV_LAG_HASH_L34: + algomsk |= TRUNK_DISTRIBUTION_ALGO_SRC_L4PORT_BIT; //sport + algomsk |= TRUNK_DISTRIBUTION_ALGO_DST_L4PORT_BIT; //dport + algomsk |= TRUNK_DISTRIBUTION_ALGO_SIP_BIT; //source ip + algomsk |= TRUNK_DISTRIBUTION_ALGO_DIP_BIT; //dest ip + algoidx = 2; + break; + default: + algomsk |= 0x7f; + } + priv->r->set_distribution_algorithm(group, algoidx, algomsk); priv->r->mask_port_reg_be(0, BIT_ULL(port), priv->r->trk_mbr_ctr(group)); priv->lags_port_members[group] |= BIT_ULL(port); - pr_info("lags_port_members %d now %016llx\n", group, priv->lags_port_members[group]); + pr_debug("lags_port_members %d now %016llx\n", group, priv->lags_port_members[group]); return 0; } @@ -453,11 +479,10 @@ int rtl83xx_lag_del(struct dsa_switch *ds, int group, int port) if (!(priv->lags_port_members[group] & BIT_ULL(port))) { - pr_err("%s: Port not member of LAG: %d\n", __func__, group - ); + pr_err("%s: Port not member of LAG: %d\n", __func__, group); return -ENOSPC; } - + // 0x7f algo mask all priv->r->mask_port_reg_be(BIT_ULL(port), 0, priv->r->trk_mbr_ctr(group)); priv->lags_port_members[group] &= ~BIT_ULL(port); @@ -625,6 +650,7 @@ static int rtl83xx_handle_changeupper(struct rtl838x_switch_priv *priv, struct netdev_notifier_changeupper_info *info) { struct net_device *upper = info->upper_dev; + struct netdev_lag_upper_info *lag_upper_info = NULL; int i, j, err; if (!netif_is_lag_master(upper)) @@ -646,9 +672,10 @@ static int rtl83xx_handle_changeupper(struct rtl838x_switch_priv *priv, } if (info->linking) { + lag_upper_info = info->upper_info; if (!priv->lag_devs[i]) priv->lag_devs[i] = upper; - err = rtl83xx_lag_add(priv->ds, i, priv->ports[j].dp->index); + err = rtl83xx_lag_add(priv->ds, i, priv->ports[j].dp->index, lag_upper_info); if (err) { err = -EINVAL; goto out; |