[linux-yocto] [PATCH 10/94] drivers/net/ethernet: add ACP wrappers back into kernel

Bruce Ashfield bruce.ashfield at windriver.com
Sat Nov 9 06:17:46 PST 2013


On 11/7/2013, 8:12 PM, Paul Butler wrote:
> From: David Mercado <david.mercado at windriver.com>
>
> This patch adds the LSI ACP wrapper routines back into the kernel. These
> were previously removed as part of the acp34xx Ethernet driver updates,

Can you put a shortlog of the commit that removes the driver here ?

i.e. removed via [<short log>], which was part of the ...

That way we can actually locate the commit and see for ourselves.

Bruce

> but are needed for the LSI RTE application.
>
> The wrappers are restored at arch/powerpc/sysdev/lsi_acp_wrappers.c
>
> Signed-off-by: David Mercado <david.mercado at windriver.com>
> ---
>   arch/powerpc/include/asm/lsi/acp_ncr.h |   3 +
>   arch/powerpc/sysdev/Makefile           |   2 +-
>   arch/powerpc/sysdev/lsi_acp_wrappers.c | 325 +++++++++++++++++++++++++++++++++
>   drivers/net/ethernet/lsi/lsi_acp_net.c | 117 +-----------
>   drivers/net/ethernet/lsi/lsi_acp_net.h |   2 -
>   5 files changed, 333 insertions(+), 116 deletions(-)
>   create mode 100644 arch/powerpc/sysdev/lsi_acp_wrappers.c
>
> diff --git a/arch/powerpc/include/asm/lsi/acp_ncr.h b/arch/powerpc/include/asm/lsi/acp_ncr.h
> index a7399e7..1a08f07 100644
> --- a/arch/powerpc/include/asm/lsi/acp_ncr.h
> +++ b/arch/powerpc/include/asm/lsi/acp_ncr.h
> @@ -39,4 +39,7 @@ int ncr_write(unsigned long, unsigned long, int, void *);
>
>   int is_asic(void);
>
> +extern int acp_mdio_read(unsigned long, unsigned long, unsigned short *);
> +extern int acp_mdio_write(unsigned long, unsigned long, unsigned short);
> +
>   #endif /*  __DRIVERS_LSI_ACP_NCR_H */
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
> index 6354d1c..a95b59f 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -73,4 +73,4 @@ obj-$(CONFIG_PPC_XICS)		+= xics/
>
>   obj-$(CONFIG_GE_FPGA)		+= ge/
>
> -obj-$(CONFIG_ACP)		+= lsi_acp_ncr.o
> +obj-$(CONFIG_ACP)		+= lsi_acp_ncr.o lsi_acp_wrappers.o
> diff --git a/arch/powerpc/sysdev/lsi_acp_wrappers.c b/arch/powerpc/sysdev/lsi_acp_wrappers.c
> new file mode 100644
> index 0000000..910ed25
> --- /dev/null
> +++ b/arch/powerpc/sysdev/lsi_acp_wrappers.c
> @@ -0,0 +1,325 @@
> +/*
> + * arch/powerpc/sysdev/lsi_acp_wrappers.c
> + *
> + * Copyright (C) 2013 LSI
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
> + */
> +
> +#include <linux/module.h>
> +#include <linux/spinlock.h>
> +#include <linux/sched.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +#include <asm/irq.h>
> +#include <asm/lsi/acp_ncr.h>
> +
> +MODULE_AUTHOR("LSI Corporation");
> +MODULE_DESCRIPTION("ACP Wrappers");
> +MODULE_LICENSE("GPL");
> +
> +/*
> +  ============================================================================
> +  ============================================================================
> +  MDIO Access
> +  ============================================================================
> +  ============================================================================
> +*/
> +
> +
> +static unsigned long mdio_base;
> +DEFINE_SPINLOCK(mdio_lock);
> +
> +#define MDIO_CONTROL_RD_DATA ((void *)(mdio_base + 0x0))
> +#define MDIO_STATUS_RD_DATA  ((void *)(mdio_base + 0x4))
> +#define MDIO_CLK_OFFSET      ((void *)(mdio_base + 0x8))
> +#define MDIO_CLK_PERIOD      ((void *)(mdio_base + 0xc))
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_mdio_read
> + */
> +
> +int acp_mdio_read(unsigned long address, unsigned long offset,
> +		  unsigned short *value)
> +{
> +	unsigned long command = 0;
> +	unsigned long status;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&mdio_lock, flags);
> +
> +	/* Set the mdio_busy (status) bit. */
> +	status = in_le32(MDIO_STATUS_RD_DATA);
> +	status |= 0x40000000;
> +	out_le32(MDIO_STATUS_RD_DATA, status);
> +
> +	/* Write the command.*/
> +	command |= 0x10000000;	/* op_code: read */
> +	command |= (address & 0x1f) << 16; /* port_addr (target device) */
> +	command |= (offset & 0x1f) << 21; /* device_addr (target register) */
> +	out_le32(MDIO_CONTROL_RD_DATA, command);
> +
> +	/* Wait for the mdio_busy (status) bit to clear. */
> +	do {
> +		status = in_le32(MDIO_STATUS_RD_DATA);
> +	} while (0 != (status & 0x40000000));
> +
> +	/* Wait for the mdio_busy (control) bit to clear. */
> +	do {
> +		command = in_le32(MDIO_CONTROL_RD_DATA);
> +	} while (0 != (command & 0x80000000));
> +
> +	*value = (unsigned short)(command & 0xffff);
> +
> +	spin_unlock_irqrestore(&mdio_lock, flags);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(acp_mdio_read);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_mdio_write
> + */
> +
> +int acp_mdio_write(unsigned long address, unsigned long offset,
> +		   unsigned short value)
> +{
> +	unsigned long command = 0;
> +	unsigned long status;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&mdio_lock, flags);
> +
> +	/* Wait for mdio_busy (control) to be clear. */
> +	do {
> +		command = in_le32(MDIO_CONTROL_RD_DATA);
> +	} while (0 != (command & 0x80000000));
> +
> +	/* Set the mdio_busy (status) bit. */
> +	status = in_le32(MDIO_STATUS_RD_DATA);
> +	status |= 0x40000000;
> +	out_le32(MDIO_STATUS_RD_DATA, status);
> +
> +	/* Write the command. */
> +	command = 0x08000000;	/* op_code: write */
> +	command |= (address & 0x1f) << 16; /* port_addr (target device) */
> +	command |= (offset & 0x1f) << 21; /* device_addr (target register) */
> +	command |= (value & 0xffff); /* value */
> +	out_le32(MDIO_CONTROL_RD_DATA, command);
> +
> +	/* Wait for the mdio_busy (status) bit to clear. */
> +	do {
> +		status = in_le32(MDIO_STATUS_RD_DATA);
> +	} while (0 != (status & 0x40000000));
> +
> +	/* Wait for the mdio_busy (control) bit to clear. */
> +	do {
> +		command = in_le32(MDIO_CONTROL_RD_DATA);
> +	} while (0 != (command & 0x80000000));
> +
> +	spin_unlock_irqrestore(&mdio_lock, flags);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(acp_mdio_write);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_mdio_initialize
> + */
> +
> +static int acp_mdio_initialize(void)
> +{
> +	if (is_asic()) {
> +		out_le32(MDIO_CLK_OFFSET, 0x10);
> +		out_le32(MDIO_CLK_PERIOD, 0x2c);
> +	} else {
> +		out_le32(MDIO_CLK_OFFSET, 0x05);
> +		out_le32(MDIO_CLK_PERIOD, 0x0c);
> +	}
> +
> +	return 0;
> +}
> +
> +
> +/*
> +  ============================================================================
> +  ============================================================================
> +  Interrupts
> +  ============================================================================
> +  ============================================================================
> +*/
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_irq_create_mapping
> + */
> +unsigned int acp_irq_create_mapping(struct irq_domain *host,
> +				    irq_hw_number_t hwirq)
> +{
> +	unsigned int mapped_irq;
> +
> +	preempt_disable();
> +	mapped_irq = irq_create_mapping(host, hwirq);
> +	preempt_enable();
> +
> +	return mapped_irq;
> +}
> +EXPORT_SYMBOL(acp_irq_create_mapping);
> +
> +/*
> +  ============================================================================
> +  ============================================================================
> +  Spin Locks
> +  ============================================================================
> +  ============================================================================
> +*/
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_spin_lock_init
> + */
> +
> +void acp_spin_lock_init(spinlock_t *lock)
> +{
> +	spin_lock_init(lock);
> +}
> +EXPORT_SYMBOL(acp_spin_lock_init);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_spin_lock
> + */
> +
> +void acp_spin_lock(spinlock_t *lock)
> +{
> +	spin_lock(lock);
> +}
> +EXPORT_SYMBOL(acp_spin_lock);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_spin_unlock
> + */
> +
> +void acp_spin_unlock(spinlock_t *lock)
> +{
> +	spin_unlock(lock);
> +}
> +EXPORT_SYMBOL(acp_spin_unlock);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_spin_lock_bh
> + */
> +
> +void acp_spin_lock_bh(spinlock_t *lock)
> +{
> +	spin_lock_bh(lock);
> +}
> +EXPORT_SYMBOL(acp_spin_lock_bh);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_spin_unlock_bh
> + */
> +
> +void acp_spin_unlock_bh(spinlock_t *lock)
> +{
> +	spin_unlock_bh(lock);
> +}
> +EXPORT_SYMBOL(acp_spin_unlock_bh);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_spin_lock_irqsave
> + */
> +
> +void acp_spin_lock_irqsave(spinlock_t *lock, unsigned long flags)
> +{
> +	spin_lock_irqsave(lock, flags);
> +}
> +EXPORT_SYMBOL(acp_spin_lock_irqsave);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_spin_unlock_irqrestore
> + */
> +
> +void acp_spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
> +{
> +	spin_unlock_irqrestore(lock, flags);
> +}
> +EXPORT_SYMBOL(acp_spin_unlock_irqrestore);
> +
> +/*
> + * -------------------------------------------------------------------------
> + * acp_wrappers_init
> + */
> +
> +int __init acp_wrappers_init(void)
> +{
> +	int rc = -1;
> +	struct device_node *np = NULL;
> +	const u32 *field;
> +	u64 mdio_phys_address;
> +	u32 mdio_size;
> +
> +	pr_info("Initializing ACP Wrappers.\n");
> +
> +	np = of_find_node_by_type(np, "network");
> +
> +	while (np && !of_device_is_compatible(np, "acp-femac"))
> +		np = of_find_node_by_type(np, "network");
> +
> +	if (np) {
> +		field = of_get_property(np, "enabled", NULL);
> +
> +		if (!field || (field && (0 == *field))) {
> +			pr_warn("Networking is Not Enabled.\n");
> +			goto acp_wrappers_init_done;
> +		}
> +
> +		field = of_get_property(np, "mdio-reg", NULL);
> +
> +		if (!field) {
> +			pr_err("Couldn't get \"mdio-reg\" property.\n");
> +		} else {
> +			mdio_phys_address = of_translate_address(np, field);
> +			mdio_size = field[1];
> +			rc = 0;
> +		}
> +	}
> +
> +	if (0 != rc) {
> +		mdio_phys_address = 0x002000409000ULL;
> +		mdio_size = 0x1000;
> +		pr_warn("** MDIO Address Not Specified in Device Tree.\n");
> +	}
> +
> +	mdio_base = (unsigned long)ioremap(mdio_phys_address, mdio_size);
> +	rc = acp_mdio_initialize();
> +
> +	if (0 != rc)
> +		pr_err("MDIO Initiailzation Failed!\n");
> +
> +acp_wrappers_init_done:
> +
> +	return 0;
> +}
> +
> +module_init(acp_wrappers_init);
> diff --git a/drivers/net/ethernet/lsi/lsi_acp_net.c b/drivers/net/ethernet/lsi/lsi_acp_net.c
> index 21153bf..605a431 100644
> --- a/drivers/net/ethernet/lsi/lsi_acp_net.c
> +++ b/drivers/net/ethernet/lsi/lsi_acp_net.c
> @@ -72,7 +72,6 @@
>   #define LSI_MDIO_NAME          "acp-femac-mdio"
>   #define LSI_DRV_VERSION        "2013-04-30"
>
> -
>   MODULE_AUTHOR("John Jacques");
>   MODULE_DESCRIPTION("LSI ACP-FEMAC Ethernet driver");
>   MODULE_LICENSE("GPL");
> @@ -83,37 +82,6 @@ static void *tx_base;
>   static void *dma_base;
>
>   /*
> -  =============================================================================
> -  MDIO / PHY
> -  =============================================================================
> -*/
> -
> -#define MDIO_CONTROL_RD_DATA ((void *)(pdata->mdio_base + 0x0))
> -#define MDIO_STATUS_RD_DATA  ((void *)(pdata->mdio_base + 0x4))
> -#define MDIO_CLK_OFFSET      ((void *)(pdata->mdio_base + 0x8))
> -#define MDIO_CLK_PERIOD      ((void *)(pdata->mdio_base + 0xc))
> -
> -/*
> - * ----------------------------------------------------------------------
> - * appnic_mdio_initialize
> - */
> -
> -static void appnic_mdio_initialize(struct net_device *dev)
> -{
> -	struct appnic_device *pdata = netdev_priv(dev);
> -
> -	if (is_asic()) {
> -		out_le32(MDIO_CLK_OFFSET, 0x10);
> -		out_le32(MDIO_CLK_PERIOD, 0x2c);
> -	} else {
> -		out_le32(MDIO_CLK_OFFSET, 0x05);
> -		out_le32(MDIO_CLK_PERIOD, 0x0c);
> -	}
> -
> -	return;
> -}
> -
> -/*
>    * ----------------------------------------------------------------------
>    * appnic_mii_read
>    *
> @@ -122,42 +90,14 @@ static void appnic_mdio_initialize(struct net_device *dev)
>
>   static int appnic_mii_read(struct mii_bus *bus, int phy, int reg)
>   {
> -	struct appnic_device *pdata = (struct appnic_device *)bus->priv;
> -	unsigned long flags;
>   	unsigned short value;
> -	unsigned long command = 0;
> -	unsigned long status;
> -
> -	spin_lock_irqsave(&pdata->mdio_lock, flags);
>
> -	/* Set the mdio_busy (status) bit. */
> -	status = in_le32(MDIO_STATUS_RD_DATA);
> -	status |= 0x40000000;
> -	out_le32(MDIO_STATUS_RD_DATA, status);
> +	/* Always returns success, so no need to check return status. */
> +	acp_mdio_read(phy, reg, &value);
>
> -	/* Write the command. */
> -	command |= 0x10000000;          /* op_code: read */
> -	command |= (phy & 0x1f) << 16;  /* port_addr (target device) */
> -	command |= (reg & 0x1f) << 21;  /* device_addr (target register) */
> -	out_le32(MDIO_CONTROL_RD_DATA, command);
> -
> -	/* Wait for the mdio_busy (status) bit to clear. */
> -	do {
> -		status = in_le32(MDIO_STATUS_RD_DATA);
> -	} while (0 != (status & 0x40000000));
> -
> -	/* Wait for the mdio_busy (control) bit to clear. */
> -	do {
> -		command = in_le32(MDIO_CONTROL_RD_DATA);
> -	} while (0 != (command & 0x80000000));
> -
> -	value = (unsigned short)(command & 0xffff);
> -	spin_unlock_irqrestore(&pdata->mdio_lock, flags);
> -
> -	return value;
> +	return (int)value;
>   }
>
> -
>   /*
>    * ----------------------------------------------------------------------
>    * appnic_mii_write
> @@ -165,43 +105,7 @@ static int appnic_mii_read(struct mii_bus *bus, int phy, int reg)
>
>   static int appnic_mii_write(struct mii_bus *bus, int phy, int reg, u16 val)
>   {
> -	struct appnic_device *pdata = (struct appnic_device *)bus->priv;
> -	unsigned long flags;
> -	unsigned long command = 0;
> -	unsigned long status;
> -
> -	spin_lock_irqsave(&pdata->mdio_lock, flags);
> -
> -	/* Wait for mdio_busy (control) to be clear. */
> -	do {
> -		command = in_le32(MDIO_CONTROL_RD_DATA);
> -	} while (0 != (command & 0x80000000));
> -
> -	/* Set the mdio_busy (status) bit. */
> -	status = in_le32(MDIO_STATUS_RD_DATA);
> -	status |= 0x40000000;
> -	out_le32(MDIO_STATUS_RD_DATA, status);
> -
> -	/* Write the command. */
> -	command = 0x08000000;           /* op_code: write */
> -	command |= (phy & 0x1f) << 16;  /* port_addr (target device) */
> -	command |= (reg & 0x1f) << 21;  /* device_addr (target register) */
> -	command |= (val & 0xffff);      /* value */
> -	out_le32(MDIO_CONTROL_RD_DATA, command);
> -
> -	/* Wait for the mdio_busy (status) bit to clear. */
> -	do {
> -		status = in_le32(MDIO_STATUS_RD_DATA);
> -	} while (0 != (status & 0x40000000));
> -
> -	/* Wait for the mdio_busy (control) bit to clear. */
> -	do {
> -		command = in_le32(MDIO_CONTROL_RD_DATA);
> -	} while (0 != (command & 0x80000000));
> -
> -	spin_unlock_irqrestore(&pdata->mdio_lock, flags);
> -
> -	return 0;
> +	return acp_mdio_write(phy, reg, val);
>   }
>
>   /*
> @@ -1596,7 +1500,6 @@ int appnic_init(struct net_device *dev)
>   	 * Initialize the spinlocks.
>   	 */
>
> -	spin_lock_init(&pdata->mdio_lock);
>   	spin_lock_init(&pdata->dev_lock);
>   	spin_lock_init(&pdata->extra_lock);
>
> @@ -1807,15 +1710,6 @@ static int __devinit appnic_probe_config_dt(struct net_device *dev,
>   	else
>   		pdata->mdio_clock = field[0];
>
> -	field = of_get_property(np, "mdio-reg", NULL);
> -	if (!field) {
> -		goto device_tree_failed;
> -	} else {
> -		value64 = of_translate_address(np, field);
> -		value32 = field[1];
> -		pdata->mdio_base = (unsigned long)ioremap(value64, value32);
> -	}
> -
>   	field = of_get_property(np, "phy-address", NULL);
>   	if (!field)
>   		goto device_tree_failed;
> @@ -1998,9 +1892,6 @@ static int __devinit appnic_drv_probe(struct platform_device *pdev)
>   		goto out;
>   	}
>
> -	/* Initialize the MDIO interface. */
> -	appnic_mdio_initialize(dev);
> -
>   	/* Initialize the PHY. */
>   	rc = appnic_mii_init(pdev, dev);
>   	if (rc) {
> diff --git a/drivers/net/ethernet/lsi/lsi_acp_net.h b/drivers/net/ethernet/lsi/lsi_acp_net.h
> index db4bfcf..f7de38d 100644
> --- a/drivers/net/ethernet/lsi/lsi_acp_net.h
> +++ b/drivers/net/ethernet/lsi/lsi_acp_net.h
> @@ -93,7 +93,6 @@ struct appnic_device {
>   	unsigned long dma_base;
>   	unsigned long interrupt;
>   	unsigned long mdio_clock;
> -	unsigned long mdio_base;
>   	unsigned long phy_address;
>   	unsigned long ad_value;
>   	unsigned char mac_addr[6];
> @@ -149,7 +148,6 @@ struct appnic_device {
>   	union appnic_queue_pointer tx_head;
>
>   	/* Spin Lock */
> -	spinlock_t mdio_lock;
>   	spinlock_t dev_lock;
>   	spinlock_t extra_lock;
>
>




More information about the linux-yocto mailing list