[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