net: systemport: use standard netdevice notifier to detect DSA presence

The SYSTEMPORT driver maps each port of the embedded Broadcom DSA switch
port to a certain queue of the master Ethernet controller. For that it
currently uses a dedicated notifier infrastructure which was added in
commit 60724d4bae ("net: dsa: Add support for DSA specific notifiers").

However, since commit 2f1e8ea726 ("net: dsa: link interfaces with the
DSA master to get rid of lockdep warnings"), DSA is actually an upper of
the Broadcom SYSTEMPORT as far as the netdevice adjacency lists are
concerned. So naturally, the plain NETDEV_CHANGEUPPER net device notifiers
are emitted. It looks like there is enough API exposed by DSA to the
outside world already to make the call_dsa_notifiers API redundant. So
let's convert its only user to plain netdev notifiers.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Vladimir Oltean 2021-01-07 03:24:02 +02:00 committed by Jakub Kicinski
parent a5e3c9ba92
commit 1593cd40d7
2 changed files with 37 additions and 46 deletions

View File

@ -2311,33 +2311,22 @@ static const struct net_device_ops bcm_sysport_netdev_ops = {
.ndo_select_queue = bcm_sysport_select_queue,
};
static int bcm_sysport_map_queues(struct notifier_block *nb,
struct dsa_notifier_register_info *info)
static int bcm_sysport_map_queues(struct net_device *dev,
struct net_device *slave_dev)
{
struct dsa_port *dp = dsa_port_from_netdev(slave_dev);
struct bcm_sysport_priv *priv = netdev_priv(dev);
struct bcm_sysport_tx_ring *ring;
struct bcm_sysport_priv *priv;
struct net_device *slave_dev;
unsigned int num_tx_queues;
unsigned int q, qp, port;
struct net_device *dev;
priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier);
if (priv->netdev != info->master)
return 0;
dev = info->master;
/* We can't be setting up queue inspection for non directly attached
* switches
*/
if (info->switch_number)
if (dp->ds->index)
return 0;
if (dev->netdev_ops != &bcm_sysport_netdev_ops)
return 0;
port = info->port_number;
slave_dev = info->info.dev;
port = dp->index;
/* On SYSTEMPORT Lite we have twice as less queues, so we cannot do a
* 1:1 mapping, we can only do a 2:1 mapping. By reducing the number of
@ -2377,27 +2366,16 @@ static int bcm_sysport_map_queues(struct notifier_block *nb,
return 0;
}
static int bcm_sysport_unmap_queues(struct notifier_block *nb,
struct dsa_notifier_register_info *info)
static int bcm_sysport_unmap_queues(struct net_device *dev,
struct net_device *slave_dev)
{
struct dsa_port *dp = dsa_port_from_netdev(slave_dev);
struct bcm_sysport_priv *priv = netdev_priv(dev);
struct bcm_sysport_tx_ring *ring;
struct bcm_sysport_priv *priv;
struct net_device *slave_dev;
unsigned int num_tx_queues;
struct net_device *dev;
unsigned int q, qp, port;
priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier);
if (priv->netdev != info->master)
return 0;
dev = info->master;
if (dev->netdev_ops != &bcm_sysport_netdev_ops)
return 0;
port = info->port_number;
slave_dev = info->info.dev;
port = dp->index;
num_tx_queues = slave_dev->real_num_tx_queues;
@ -2418,17 +2396,30 @@ static int bcm_sysport_unmap_queues(struct notifier_block *nb,
return 0;
}
static int bcm_sysport_dsa_notifier(struct notifier_block *nb,
unsigned long event, void *ptr)
static int bcm_sysport_netdevice_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{
int ret = NOTIFY_DONE;
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct netdev_notifier_changeupper_info *info = ptr;
struct bcm_sysport_priv *priv;
int ret = 0;
priv = container_of(nb, struct bcm_sysport_priv, netdev_notifier);
if (priv->netdev != dev)
return NOTIFY_DONE;
switch (event) {
case DSA_PORT_REGISTER:
ret = bcm_sysport_map_queues(nb, ptr);
break;
case DSA_PORT_UNREGISTER:
ret = bcm_sysport_unmap_queues(nb, ptr);
case NETDEV_CHANGEUPPER:
if (dev->netdev_ops != &bcm_sysport_netdev_ops)
return NOTIFY_DONE;
if (!dsa_slave_dev_check(info->upper_dev))
return NOTIFY_DONE;
if (info->linking)
ret = bcm_sysport_map_queues(dev, info->upper_dev);
else
ret = bcm_sysport_unmap_queues(dev, info->upper_dev);
break;
}
@ -2601,9 +2592,9 @@ static int bcm_sysport_probe(struct platform_device *pdev)
priv->rx_max_coalesced_frames = 1;
u64_stats_init(&priv->syncp);
priv->dsa_notifier.notifier_call = bcm_sysport_dsa_notifier;
priv->netdev_notifier.notifier_call = bcm_sysport_netdevice_event;
ret = register_dsa_notifier(&priv->dsa_notifier);
ret = register_netdevice_notifier(&priv->netdev_notifier);
if (ret) {
dev_err(&pdev->dev, "failed to register DSA notifier\n");
goto err_deregister_fixed_link;
@ -2630,7 +2621,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
return 0;
err_deregister_notifier:
unregister_dsa_notifier(&priv->dsa_notifier);
unregister_netdevice_notifier(&priv->netdev_notifier);
err_deregister_fixed_link:
if (of_phy_is_fixed_link(dn))
of_phy_deregister_fixed_link(dn);
@ -2648,7 +2639,7 @@ static int bcm_sysport_remove(struct platform_device *pdev)
/* Not much to do, ndo_close has been called
* and we use managed allocations
*/
unregister_dsa_notifier(&priv->dsa_notifier);
unregister_netdevice_notifier(&priv->netdev_notifier);
unregister_netdev(dev);
if (of_phy_is_fixed_link(dn))
of_phy_deregister_fixed_link(dn);

View File

@ -787,7 +787,7 @@ struct bcm_sysport_priv {
struct u64_stats_sync syncp;
/* map information between switch port queues and local queues */
struct notifier_block dsa_notifier;
struct notifier_block netdev_notifier;
unsigned int per_port_num_tx_queues;
struct bcm_sysport_tx_ring *ring_map[DSA_MAX_PORTS * 8];