aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files-5.10/drivers/net/dsa/rtl83xx/common.c
diff options
context:
space:
mode:
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.c45
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;