return 0;
}
-static int rtl83xx_handle_changeupper(struct rtl838x_switch_priv *priv,
- struct net_device *ndev,
- 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))
- return 0;
-
- mutex_lock(&priv->reg_mutex);
-
- for (i = 0; i < priv->ds->num_lag_ids; i++) {
- if ((!priv->lag_devs[i]) || (priv->lag_devs[i] == upper))
- break;
- }
- for (j = 0; j < priv->cpu_port; j++) {
- if (priv->ports[j].dp->user == ndev)
- break;
- }
- if (j >= priv->cpu_port) {
- err = -EINVAL;
- goto out;
- }
-
- 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, lag_upper_info);
- if (err) {
- err = -EINVAL;
- goto out;
- }
- } else {
- if (!priv->lag_devs[i])
- err = -EINVAL;
- err = rtl83xx_lag_del(priv->ds, i, priv->ports[j].dp->index);
- if (err) {
- err = -EINVAL;
- goto out;
- }
- if (!priv->lags_port_members[i])
- priv->lag_devs[i] = NULL;
- }
-
-out:
- mutex_unlock(&priv->reg_mutex);
-
- return 0;
-}
-
int rtl83xx_port_is_under(const struct net_device * dev, struct rtl838x_switch_priv *priv)
{
/* Is the lower network device a DSA user network device of our RTL930X-switch?
return -EINVAL;
}
-static int rtl83xx_netdevice_event(struct notifier_block *this,
- unsigned long event, void *ptr)
-{
- struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
- struct rtl838x_switch_priv *priv;
- int err;
-
- pr_debug("In: %s, event: %lu\n", __func__, event);
-
- if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE))
- return NOTIFY_DONE;
-
- priv = container_of(this, struct rtl838x_switch_priv, nb);
- switch (event) {
- case NETDEV_CHANGEUPPER:
- err = rtl83xx_handle_changeupper(priv, ndev, ptr);
- break;
- }
-
- if (err)
- return err;
-
- return NOTIFY_DONE;
-}
-
static const struct rhashtable_params route_ht_params = {
.key_len = sizeof(u32),
.key_offset = offsetof(struct rtl83xx_route, gw_ip),
for (int i = 0; i < 4; i++)
priv->mirror_group_ports[i] = -1;
- /* Register netdevice event callback to catch changes in link aggregation groups */
- priv->nb.notifier_call = rtl83xx_netdevice_event;
- if (register_netdevice_notifier(&priv->nb)) {
- priv->nb.notifier_call = NULL;
- dev_err(dev, "Failed to register LAG netdev notifier\n");
- goto err_register_nb;
- }
-
/* Initialize hash table for L3 routing */
rhltable_init(&priv->routes, &route_ht_params);
err_register_fib_nb:
unregister_netevent_notifier(&priv->ne_nb);
err_register_ne_nb:
- unregister_netdevice_notifier(&priv->nb);
-err_register_nb:
dsa_switch_shutdown(priv->ds);
err_register_switch:
destroy_workqueue(priv->wq);