Skip to content

Commit

Permalink
Merge branch 'reduce-coupling-between-dsa-and-broadcom-systemport-dri…
Browse files Browse the repository at this point in the history
…ver'

Vladimir Oltean says:

====================
Reduce coupling between DSA and Broadcom SYSTEMPORT driver

Upon a quick inspection, it seems that there is some code in the generic
DSA layer that is somehow specific to the Broadcom SYSTEMPORT driver.
The challenge there is that the hardware integration is very tight between
the switch and the DSA master interface. However this does not mean that
the drivers must also be as integrated as the hardware is. We can avoid
creating a DSA notifier just for the Broadcom SYSTEMPORT, and we can
move some Broadcom-specific queue mapping helpers outside of the common
include/net/dsa.h.
====================

Link: https://lore.kernel.org/r/20210107012403.1521114-1-olteanv@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Jan 7, 2021
2 parents c214cc3 + 1dbb130 commit 85b277d
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 131 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -3400,6 +3400,7 @@ L: openwrt-devel@lists.openwrt.org (subscribers-only)
S: Supported
F: Documentation/devicetree/bindings/net/dsa/brcm,b53.yaml
F: drivers/net/dsa/b53/*
F: include/linux/dsa/brcm.h
F: include/linux/platform_data/b53.h

BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE
Expand Down
82 changes: 37 additions & 45 deletions drivers/net/ethernet/broadcom/bcmsysport.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/dsa/brcm.h>
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/of.h>
Expand Down Expand Up @@ -2310,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
Expand Down Expand Up @@ -2376,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;

Expand All @@ -2417,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;
}

Expand Down Expand Up @@ -2600,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;
Expand All @@ -2629,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);
Expand All @@ -2647,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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/broadcom/bcmsysport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down
16 changes: 16 additions & 0 deletions include/linux/dsa/brcm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only
* Copyright (C) 2014 Broadcom Corporation
*/

/* Included by drivers/net/ethernet/broadcom/bcmsysport.c and
* net/dsa/tag_brcm.c
*/
#ifndef _NET_DSA_BRCM_H
#define _NET_DSA_BRCM_H

/* Broadcom tag specific helpers to insert and extract queue/port number */
#define BRCM_TAG_SET_PORT_QUEUE(p, q) ((p) << 8 | q)
#define BRCM_TAG_GET_PORT(v) ((v) >> 8)
#define BRCM_TAG_GET_QUEUE(v) ((v) & 0xff)

#endif
48 changes: 3 additions & 45 deletions include/net/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -833,57 +833,15 @@ static inline int dsa_switch_resume(struct dsa_switch *ds)
}
#endif /* CONFIG_PM_SLEEP */

enum dsa_notifier_type {
DSA_PORT_REGISTER,
DSA_PORT_UNREGISTER,
};

struct dsa_notifier_info {
struct net_device *dev;
};

struct dsa_notifier_register_info {
struct dsa_notifier_info info; /* must be first */
struct net_device *master;
unsigned int port_number;
unsigned int switch_number;
};

static inline struct net_device *
dsa_notifier_info_to_dev(const struct dsa_notifier_info *info)
{
return info->dev;
}

#if IS_ENABLED(CONFIG_NET_DSA)
int register_dsa_notifier(struct notifier_block *nb);
int unregister_dsa_notifier(struct notifier_block *nb);
int call_dsa_notifiers(unsigned long val, struct net_device *dev,
struct dsa_notifier_info *info);
bool dsa_slave_dev_check(const struct net_device *dev);
#else
static inline int register_dsa_notifier(struct notifier_block *nb)
{
return 0;
}

static inline int unregister_dsa_notifier(struct notifier_block *nb)
{
return 0;
}

static inline int call_dsa_notifiers(unsigned long val, struct net_device *dev,
struct dsa_notifier_info *info)
static inline bool dsa_slave_dev_check(const struct net_device *dev)
{
return NOTIFY_DONE;
return false;
}
#endif

/* Broadcom tag specific helpers to insert and extract queue/port number */
#define BRCM_TAG_SET_PORT_QUEUE(p, q) ((p) << 8 | q)
#define BRCM_TAG_GET_PORT(v) ((v) >> 8)
#define BRCM_TAG_GET_QUEUE(v) ((v) & 0xff)


netdev_tx_t dsa_enqueue_skb(struct sk_buff *skb, struct net_device *dev);
int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data);
int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data);
Expand Down
22 changes: 0 additions & 22 deletions net/dsa/dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,28 +309,6 @@ bool dsa_schedule_work(struct work_struct *work)
return queue_work(dsa_owq, work);
}

static ATOMIC_NOTIFIER_HEAD(dsa_notif_chain);

int register_dsa_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_register(&dsa_notif_chain, nb);
}
EXPORT_SYMBOL_GPL(register_dsa_notifier);

int unregister_dsa_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(&dsa_notif_chain, nb);
}
EXPORT_SYMBOL_GPL(unregister_dsa_notifier);

int call_dsa_notifiers(unsigned long val, struct net_device *dev,
struct dsa_notifier_info *info)
{
info->dev = dev;
return atomic_notifier_call_chain(&dsa_notif_chain, val, info);
}
EXPORT_SYMBOL_GPL(call_dsa_notifiers);

int dsa_devlink_param_get(struct devlink *dl, u32 id,
struct devlink_param_gset_ctx *ctx)
{
Expand Down
1 change: 0 additions & 1 deletion net/dsa/dsa_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ extern const struct dsa_device_ops notag_netdev_ops;
void dsa_slave_mii_bus_init(struct dsa_switch *ds);
int dsa_slave_create(struct dsa_port *dp);
void dsa_slave_destroy(struct net_device *slave_dev);
bool dsa_slave_dev_check(const struct net_device *dev);
int dsa_slave_suspend(struct net_device *slave_dev);
int dsa_slave_resume(struct net_device *slave_dev);
int dsa_slave_register_notifier(void);
Expand Down
18 changes: 1 addition & 17 deletions net/dsa/slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -1764,20 +1764,6 @@ int dsa_slave_resume(struct net_device *slave_dev)
return 0;
}

static void dsa_slave_notify(struct net_device *dev, unsigned long val)
{
struct net_device *master = dsa_slave_to_master(dev);
struct dsa_port *dp = dsa_slave_to_port(dev);
struct dsa_notifier_register_info rinfo = {
.switch_number = dp->ds->index,
.port_number = dp->index,
.master = master,
.info.dev = dev,
};

call_dsa_notifiers(val, dev, &rinfo.info);
}

int dsa_slave_create(struct dsa_port *port)
{
const struct dsa_port *cpu_dp = port->cpu_dp;
Expand Down Expand Up @@ -1863,8 +1849,6 @@ int dsa_slave_create(struct dsa_port *port)
goto out_gcells;
}

dsa_slave_notify(slave_dev, DSA_PORT_REGISTER);

rtnl_lock();

ret = register_netdevice(slave_dev);
Expand Down Expand Up @@ -1913,7 +1897,6 @@ void dsa_slave_destroy(struct net_device *slave_dev)
phylink_disconnect_phy(dp->pl);
rtnl_unlock();

dsa_slave_notify(slave_dev, DSA_PORT_UNREGISTER);
phylink_destroy(dp->pl);
gro_cells_destroy(&p->gcells);
free_percpu(slave_dev->tstats);
Expand All @@ -1924,6 +1907,7 @@ bool dsa_slave_dev_check(const struct net_device *dev)
{
return dev->netdev_ops == &dsa_slave_netdev_ops;
}
EXPORT_SYMBOL_GPL(dsa_slave_dev_check);

static int dsa_slave_changeupper(struct net_device *dev,
struct netdev_notifier_changeupper_info *info)
Expand Down
1 change: 1 addition & 0 deletions net/dsa/tag_brcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Copyright (C) 2014 Broadcom Corporation
*/

#include <linux/dsa/brcm.h>
#include <linux/etherdevice.h>
#include <linux/list.h>
#include <linux/slab.h>
Expand Down

0 comments on commit 85b277d

Please sign in to comment.