[PATCH net-next 3/6] net: bcmasp: Add support for ASP2.0 Ethernet controller

Andrew Lunn andrew at lunn.ch
Wed Apr 19 01:05:22 UTC 2023


On Tue, Apr 18, 2023 at 05:10:15PM -0700, Justin Chen wrote:
> Add support for the Broadcom ASP 2.0 Ethernet controller which is first
> introduced with 72165. This controller features two distinct Ethernet
> ports that can be independently operated.
> 
> This patch supports:
> 
> - Wake-on-LAN using magic packets
> - basic ethtool operations (link, counters, message level)
> - MAC destination address filtering (promiscuous, ALL_MULTI, etc.)
> 
> Signed-off-by: Justin Chen <justinpopo6 at gmail.com>
> Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>

Hi Justin

Since you are submitting this, your Signed-off-by: needs to be last
here.


> ---
>  drivers/net/ethernet/broadcom/Kconfig              |   11 +
>  drivers/net/ethernet/broadcom/Makefile             |    1 +
>  drivers/net/ethernet/broadcom/asp2/Makefile        |    2 +
>  drivers/net/ethernet/broadcom/asp2/bcmasp.c        | 1527 ++++++++++++++++++++
>  drivers/net/ethernet/broadcom/asp2/bcmasp.h        |  636 ++++++++
>  .../net/ethernet/broadcom/asp2/bcmasp_ethtool.c    |  620 ++++++++
>  drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c   | 1425 ++++++++++++++++++
>  .../net/ethernet/broadcom/asp2/bcmasp_intf_defs.h  |  238 +++
>  8 files changed, 4460 insertions(+)
>  create mode 100644 drivers/net/ethernet/broadcom/asp2/Makefile
>  create mode 100644 drivers/net/ethernet/broadcom/asp2/bcmasp.c
>  create mode 100644 drivers/net/ethernet/broadcom/asp2/bcmasp.h
>  create mode 100644 drivers/net/ethernet/broadcom/asp2/bcmasp_ethtool.c
>  create mode 100644 drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
>  create mode 100644 drivers/net/ethernet/broadcom/asp2/bcmasp_intf_defs.h
> 
> diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
> index 948586bf1b5b..d4166141145d 100644
> --- a/drivers/net/ethernet/broadcom/Kconfig
> +++ b/drivers/net/ethernet/broadcom/Kconfig
> @@ -255,4 +255,15 @@ config BNXT_HWMON
>  	  Say Y if you want to expose the thermal sensor data on NetXtreme-C/E
>  	  devices, via the hwmon sysfs interface.
>  
> +config BCMASP
> +	tristate "Broadcom ASP 2.0 Ethernet support"
> +	default ARCH_BRCMSTB
> +	depends on OF
> +	select MII
> +	select PHYLIB
> +	select MDIO_BCM_UNIMAC
> +	help
> +	  This configuration enables the Broadcom ASP 2.0 Ethernet controller
> +	  driver which is present in Broadcom STB SoCs such as 72165.
> +
>  endif # NET_VENDOR_BROADCOM
> diff --git a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile
> index 0ddfb5b5d53c..bac5cb6ad0cd 100644
> --- a/drivers/net/ethernet/broadcom/Makefile
> +++ b/drivers/net/ethernet/broadcom/Makefile
> @@ -17,3 +17,4 @@ obj-$(CONFIG_BGMAC_BCMA) += bgmac-bcma.o bgmac-bcma-mdio.o
>  obj-$(CONFIG_BGMAC_PLATFORM) += bgmac-platform.o
>  obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o
>  obj-$(CONFIG_BNXT) += bnxt/
> +obj-$(CONFIG_BCMASP) += asp2/
> diff --git a/drivers/net/ethernet/broadcom/asp2/Makefile b/drivers/net/ethernet/broadcom/asp2/Makefile
> new file mode 100644
> index 000000000000..e07550315f83
> --- /dev/null
> +++ b/drivers/net/ethernet/broadcom/asp2/Makefile
> @@ -0,0 +1,2 @@
> +obj-$(CONFIG_BCMASP) += bcm-asp.o
> +bcm-asp-objs := bcmasp.o bcmasp_intf.o bcmasp_ethtool.o
> diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp.c b/drivers/net/ethernet/broadcom/asp2/bcmasp.c
> new file mode 100644
> index 000000000000..9cf5f4d6dd0d
> --- /dev/null
> +++ b/drivers/net/ethernet/broadcom/asp2/bcmasp.c
> @@ -0,0 +1,1527 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Broadcom STB ASP 2.0 Driver
> + *
> + * Copyright (c) 2020 Broadcom
> + */
> +#include <linux/etherdevice.h>
> +#include <linux/if_vlan.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/clk.h>
> +
> +#include "bcmasp.h"
> +#include "bcmasp_intf_defs.h"
> +
> +static inline void _intr2_mask_clear(struct bcmasp_priv *priv, u32 mask)
> +{
> +	intr2_core_wl(priv, mask, ASP_INTR2_MASK_CLEAR);
> +	priv->irq_mask &= ~mask;
> +}

No inline functions in .c files. Let the compiler decide.

> +static inline void bcmasp_intr2_handling(struct bcmasp_intf *intf, u32 status)
> +{
> +	if (unlikely(!intf))
> +		return;

Can it even happen? An interrupt from an interface which does not
exist?

> +static void bcmasp_set_mda_filter(struct bcmasp_intf *intf,
> +				  const unsigned char *addr,
> +				  unsigned char *mask,
> +				  unsigned int i)
> +{
> +	struct bcmasp_priv *priv = intf->parent;
> +	u32 addr_h, addr_l, mask_h, mask_l;
> +
> +	/* Set local copy */
> +	memcpy(priv->mda_filters[i].mask, mask, ETH_ALEN);
> +	memcpy(priv->mda_filters[i].addr, addr, ETH_ALEN);

eth_addr_copy() ?

> +static inline void u64_to_mac(unsigned char *addr, u64 val)
> +{
> +	addr[0] = (u8)(val >> 40);
> +	addr[1] = (u8)(val >> 32);
> +	addr[2] = (u8)(val >> 24);
> +	addr[3] = (u8)(val >> 16);
> +	addr[4] = (u8)(val >> 8);
> +	addr[5] = (u8)val;
> +}

u64_to_ether_addr() ?

> +
> +#define mac_to_u64(a)		((((u64)a[0]) << 40) | \
> +				(((u64)a[1]) << 32) | \
> +				(((u64)a[2]) << 24) | \
> +				(((u64)a[3]) << 16) | \
> +				(((u64)a[4]) << 8) | \
> +				((u64)a[5]))
> +

ether_addr_to_u64()

You might want to read that include file and see if there is anything
else you can replace.

> +static int bcmasp_probe(struct platform_device *pdev)
> +{
> +	struct bcmasp_priv *priv;
> +	struct device_node *ports_node, *intf_node;
> +	struct device *dev = &pdev->dev;
> +	const struct bcmasp_plat_data *pdata;
> +	int ret, i, count = 0, port;
> +	struct bcmasp_intf *intf;

Reverse christmass tree.

> +	priv->clk = devm_clk_get(dev, "sw_asp");
> +	if (IS_ERR(priv->clk)) {
> +		if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
> +			return -EPROBE_DEFER;
> +		dev_warn(dev, "failed to request clock\n");
> +		priv->clk = NULL;
> +	}

Maybe devm_clk_get_optional() ??

> +
> +	/* Base from parent node */
> +	priv->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(priv->base)) {
> +		dev_err(dev, "failed to iomap\n");
> +		return PTR_ERR(priv->base);
> +	}
> +
> +	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40));
> +	if (ret)
> +		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> +	if (ret) {
> +		dev_err(&pdev->dev, "unable to set DMA mask: %d\n", ret);
> +		return ret;
> +	}
> +
> +	dev_set_drvdata(&pdev->dev, priv);
> +	priv->pdev = pdev;
> +	spin_lock_init(&priv->mda_lock);
> +	spin_lock_init(&priv->clk_lock);
> +	mutex_init(&priv->net_lock);
> +	mutex_init(&priv->wol_lock);
> +
> +	pdata = device_get_match_data(&pdev->dev);
> +	if (pdata) {
> +		priv->init_wol = pdata->init_wol;
> +		priv->enable_wol = pdata->enable_wol;
> +		priv->destroy_wol = pdata->destroy_wol;
> +		priv->hw_info = pdata->hw_info;
> +	} else {
> +		dev_err(&pdev->dev, "unable to find platform data\n");
> +		return ret;
> +	}
> +
> +	ret = clk_prepare_enable(priv->clk);
> +	if (ret)
> +		return ret;

I think there is also a devm_clk_get_enable_optional().

> +static void bcmasp_get_drvinfo(struct net_device *dev,
> +			       struct ethtool_drvinfo *info)
> +{
> +	strscpy(info->driver, "bcmasp", sizeof(info->driver));
> +	strscpy(info->version, "v2.0", sizeof(info->version));

Don't fill in the version, it is useless. The core will insert the git
hash which has more value.

> +	strscpy(info->bus_info, dev_name(dev->dev.parent),
> +		sizeof(info->bus_info));
> +}
> +
> +static int bcmasp_get_link_ksettings(struct net_device *dev,
> +				     struct ethtool_link_ksettings *cmd)
> +{
> +	if (!netif_running(dev))
> +		return -EINVAL;
> +
> +	if (!dev->phydev)
> +		return -ENODEV;

I skipped the PHY handling section. Is it possible to not have a PHY?
Normally you have a fixed-link if their is not a real PHY.

There is also phy_ethtool_set_link_ksettings()

> +static int bcmasp_nway_reset(struct net_device *dev)
> +{
> +	if (!dev->phydev)
> +		return -ENODEV;
> +
> +	return genphy_restart_aneg(dev->phydev);

phy_ethtool_nway_reset().

I get the feeling this code was written against an old kernel version,
and has not been updated to use all the new helpers.

	Andrew


More information about the dri-devel mailing list