* [PATCH net-next v2 07/10] forcedeth: account for dropped RX frames
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
In-Reply-To: <cover.1320974990.git.david.decotigny@google.com>
This adds the stats counter for dropped RX frames.
Signed-off-by: David Decotigny <david.decotigny@google.com>
---
drivers/net/ethernet/nvidia/forcedeth.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
index cabc121..0a979b8 100644
--- a/drivers/net/ethernet/nvidia/forcedeth.c
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
@@ -824,6 +824,7 @@ struct fe_priv {
/* RX software stats */
struct nv_driver_stat stat_rx_bytes; /* not always available in HW */
struct nv_driver_stat stat_rx_missed_errors;
+ struct nv_driver_stat stat_rx_dropped;
/* media detection workaround.
* Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
@@ -1738,6 +1739,7 @@ static void nv_update_stats(struct net_device *dev)
/* update software stats */
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_rx_bytes);
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_rx_missed_errors);
+ NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_rx_dropped);
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_tx_packets);
NV_DRIVER_STAT_UPDATE_TOTAL(&np->stat_tx_dropped);
@@ -1780,6 +1782,8 @@ nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
storage->tx_bytes = np->estats.tx_bytes;
storage->rx_errors = np->estats.rx_errors_total;
storage->tx_errors = np->estats.tx_errors_total;
+ storage->rx_dropped = NV_DRIVER_STAT_GET_TOTAL(
+ &np->stat_rx_dropped);
storage->tx_dropped = NV_DRIVER_STAT_GET_TOTAL(
&np->stat_tx_dropped);
@@ -1835,8 +1839,10 @@ static int nv_alloc_rx(struct net_device *dev)
np->put_rx.orig = np->first_rx.orig;
if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
- } else
+ } else {
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_rx_dropped);
return 1;
+ }
}
return 0;
}
@@ -1867,8 +1873,10 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
np->put_rx.ex = np->first_rx.ex;
if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
- } else
+ } else {
+ NV_DRIVER_STAT_ATOMIC_INC(&np->stat_rx_dropped);
return 1;
+ }
}
return 0;
}
--
1.7.3.1
^ permalink raw reply related
* [PATCH net-next v2 00/10] forcedeth: stats & debug enhancements
From: David Decotigny @ 2011-11-11 1:31 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: David S. Miller, Ian Campbell, Eric Dumazet, Jeff Kirsher,
Ben Hutchings, Jiri Pirko, Joe Perches, Szymon Janc,
David Decotigny
These changes implement the ndo_get_stats64 API and add a few more
stats and debugging features for forcedeth. They also ensure that
stats updates are correct in SMP systems, 32 or 64-bits.
Changes since v1:
- patch 1/10 is the same as
http://patchwork.ozlabs.org/patch/125017/ (targetting net)
- other patches updated to take patch 1/10 into account
- various commit message updates
Tested:
~150Mbps incoming TCP, ethtool -S in a loop, x86_64 16-way:
tx_bytes: 1413863329
rx_packets: 38918872
tx_packets: 19828148
rx_bytes: 57818685991
############################################
# Patch Set Summary:
David Decotigny (8):
forcedeth: fix ifconfig stats on hardware without extended stats
support
forcedeth: expose module parameters in /sys/module
forcedeth: stats for rx_packets based on hardware registers
forcedeth: implement ndo_get_stats64() API
forcedeth: account for dropped RX frames
forcedeth: new ethtool stat counter for TX timeouts
forcedeth: stats updated with a deferrable timer
forcedeth: whitespace/indentation fixes
Mike Ditto (1):
forcedeth: Add messages to indicate using MSI or MSI-X
Sameer Nanda (1):
forcedeth: allow to silence "TX timeout" debug messages
drivers/net/ethernet/nvidia/forcedeth.c | 314 ++++++++++++++++++++++---------
1 files changed, 225 insertions(+), 89 deletions(-)
--
1.7.3.1
^ permalink raw reply
* [PATCH 0/8] of/MIPS/i2c/net: Convert OCTEON to use device-tree
From: ddaney.cavm @ 2011-11-11 2:21 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: devel, David Daney, netdev, Greg Kroah-Hartman, linux-i2c,
Ben Dooks (embedded platforms), Jean Delvare (PC drivers, core),
David S. Miller
From: David Daney <david.daney@cavium.com>
This series touches several different drivers, but since OCTEON is a
MIPS based SOC, we may want to merge the whole series via Ralf's
linux-mips.org tree.
Summary of the patches:
1) Template device trees to be patched in early boot for legacy boards
that do not supply a device tree.
2) Get rid of some garbage.
3) Interrupt mapping support.
4) Patch/fix-up device tree for lagacy boards.
5) I2C bus driver.
6) MDIO bus driver.
7,8) Ethernet drivers.
Cc: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org>
Cc: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
Cc: linux-i2c@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: devel@driverdev.osuosl.org
David Daney (8):
MIPS: Octeon: Add device tree source files.
MIPS: Prune some target specific code out of prom.c
MIPS: Octeon: Add irq_create_of_mapping() and GPIO interrupts.
MIPS: Octeon: Initialize and fixup device tree.
i2c: Convert i2c-octeon.c to use device tree.
netdev: mdio-octeon.c: Convert to use device tree.
netdev: octeon_mgmt: Convert to use device tree.
staging: octeon_ethernet: Convert to use device tree.
.../bindings/ata/cavium-compact-flash.txt | 30 +
.../bindings/gpio/cavium-octeon-gpio.txt | 48 ++
.../devicetree/bindings/i2c/cavium-i2c.txt | 34 +
.../devicetree/bindings/mips/cavium/bootbus.txt | 126 ++++
.../devicetree/bindings/mips/cavium/ciu.txt | 26 +
.../devicetree/bindings/mips/cavium/ciu2.txt | 27 +
.../devicetree/bindings/mips/cavium/dma-engine.txt | 21 +
.../devicetree/bindings/mips/cavium/uctl.txt | 47 ++
.../devicetree/bindings/net/cavium-mdio.txt | 27 +
.../devicetree/bindings/net/cavium-mix.txt | 40 ++
.../devicetree/bindings/net/cavium-pip.txt | 98 +++
.../devicetree/bindings/serial/cavium-uart.txt | 19 +
arch/mips/Kconfig | 1 +
arch/mips/cavium-octeon/.gitignore | 2 +
arch/mips/cavium-octeon/Makefile | 16 +
arch/mips/cavium-octeon/octeon-irq.c | 188 ++++++-
arch/mips/cavium-octeon/octeon-platform.c | 699 +++++++++++++++-----
arch/mips/cavium-octeon/octeon_3xxx.dts | 571 ++++++++++++++++
arch/mips/cavium-octeon/octeon_68xx.dts | 625 +++++++++++++++++
arch/mips/cavium-octeon/setup.c | 45 ++
arch/mips/include/asm/octeon/octeon.h | 5 -
arch/mips/kernel/prom.c | 50 --
drivers/i2c/busses/i2c-octeon.c | 94 ++--
drivers/net/ethernet/octeon/octeon_mgmt.c | 312 ++++++---
drivers/net/phy/mdio-octeon.c | 89 ++-
drivers/staging/octeon/ethernet-mdio.c | 28 +-
drivers/staging/octeon/ethernet.c | 91 ++-
drivers/staging/octeon/octeon-ethernet.h | 3 +
28 files changed, 2901 insertions(+), 461 deletions(-)
create mode 100644 Documentation/devicetree/bindings/ata/cavium-compact-flash.txt
create mode 100644 Documentation/devicetree/bindings/gpio/cavium-octeon-gpio.txt
create mode 100644 Documentation/devicetree/bindings/i2c/cavium-i2c.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/bootbus.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/ciu2.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/dma-engine.txt
create mode 100644 Documentation/devicetree/bindings/mips/cavium/uctl.txt
create mode 100644 Documentation/devicetree/bindings/net/cavium-mdio.txt
create mode 100644 Documentation/devicetree/bindings/net/cavium-mix.txt
create mode 100644 Documentation/devicetree/bindings/net/cavium-pip.txt
create mode 100644 Documentation/devicetree/bindings/serial/cavium-uart.txt
create mode 100644 arch/mips/cavium-octeon/.gitignore
create mode 100644 arch/mips/cavium-octeon/octeon_3xxx.dts
create mode 100644 arch/mips/cavium-octeon/octeon_68xx.dts
--
1.7.2.3
^ permalink raw reply
* [PATCH 6/8] netdev: mdio-octeon.c: Convert to use device tree.
From: ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w @ 2011-11-11 2:22 UTC (permalink / raw)
To: linux-mips-6z/3iImG2C8G8FEW9MqTrA, ralf-6z/3iImG2C8G8FEW9MqTrA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
grant.likely-s3s/WqlpOiPyB63q8FvJNQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, David S. Miller, David Daney
In-Reply-To: <1320978124-13042-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
Get the MDIO bus controller addresses from the device tree.
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Acked-by: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Signed-off-by: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
---
arch/mips/cavium-octeon/octeon-platform.c | 30 ----------
drivers/net/phy/mdio-octeon.c | 89 +++++++++++++++++++----------
2 files changed, 58 insertions(+), 61 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index f62a40f..66cabc2 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -168,36 +168,6 @@ out:
}
device_initcall(octeon_rng_device_init);
-/* Octeon SMI/MDIO interface. */
-static int __init octeon_mdiobus_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
-
- if (octeon_is_simulation())
- return 0; /* No mdio in the simulator. */
-
- /* The bus number is the platform_device id. */
- pd = platform_device_alloc("mdio-octeon", 0);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = platform_device_add(pd);
- if (ret)
- goto fail;
-
- return ret;
-fail:
- platform_device_put(pd);
-
-out:
- return ret;
-
-}
-device_initcall(octeon_mdiobus_device_init);
-
/* Octeon mgmt port Ethernet interface. */
static int __init octeon_mgmt_device_init(void)
{
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index bd12ba9..b18b8c5 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -3,14 +3,17 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2009 Cavium Networks
+ * Copyright (C) 2009, 2010, 2011 Cavium Networks
*/
-#include <linux/gfp.h>
-#include <linux/init.h>
-#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/of_mdio.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
#include <linux/phy.h>
+#include <linux/io.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-smix-defs.h>
@@ -18,9 +21,17 @@
#define DRV_VERSION "1.0"
#define DRV_DESCRIPTION "Cavium Networks Octeon SMI/MDIO driver"
+#define SMI_CMD 0x0
+#define SMI_WR_DAT 0x8
+#define SMI_RD_DAT 0x10
+#define SMI_CLK 0x18
+#define SMI_EN 0x20
+
struct octeon_mdiobus {
struct mii_bus *mii_bus;
- int unit;
+ u64 register_base;
+ resource_size_t mdio_phys;
+ resource_size_t regsize;
int phy_irq[PHY_MAX_ADDR];
};
@@ -35,15 +46,15 @@ static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */
smi_cmd.s.phy_adr = phy_id;
smi_cmd.s.reg_adr = regnum;
- cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64);
+ cvmx_write_csr(p->register_base + SMI_CMD, smi_cmd.u64);
do {
/*
* Wait 1000 clocks so we don't saturate the RSL bus
* doing reads.
*/
- cvmx_wait(1000);
- smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(p->unit));
+ __delay(1000);
+ smi_rd.u64 = cvmx_read_csr(p->register_base + SMI_RD_DAT);
} while (smi_rd.s.pending && --timeout);
if (smi_rd.s.val)
@@ -62,21 +73,21 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
smi_wr.u64 = 0;
smi_wr.s.dat = val;
- cvmx_write_csr(CVMX_SMIX_WR_DAT(p->unit), smi_wr.u64);
+ cvmx_write_csr(p->register_base + SMI_WR_DAT, smi_wr.u64);
smi_cmd.u64 = 0;
smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */
smi_cmd.s.phy_adr = phy_id;
smi_cmd.s.reg_adr = regnum;
- cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64);
+ cvmx_write_csr(p->register_base + SMI_CMD, smi_cmd.u64);
do {
/*
* Wait 1000 clocks so we don't saturate the RSL bus
* doing reads.
*/
- cvmx_wait(1000);
- smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(p->unit));
+ __delay(1000);
+ smi_wr.u64 = cvmx_read_csr(p->register_base + SMI_WR_DAT);
} while (smi_wr.s.pending && --timeout);
if (timeout <= 0)
@@ -88,8 +99,8 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
{
struct octeon_mdiobus *bus;
+ struct resource *res_mem;
union cvmx_smix_en smi_en;
- int i;
int err = -ENOENT;
bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
@@ -97,28 +108,37 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
return -ENOMEM;
/* The platform_device id is our unit number. */
- bus->unit = pdev->id;
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (res_mem == NULL) {
+ dev_err(&pdev->dev, "found no memory resource\n");
+ err = -ENXIO;
+ goto fail;
+ }
+ bus->mdio_phys = res_mem->start;
+ bus->regsize = resource_size(res_mem);
+ if (!devm_request_mem_region(&pdev->dev, bus->mdio_phys, bus->regsize,
+ res_mem->name)) {
+ dev_err(&pdev->dev, "request_mem_region failed\n");
+ goto fail;
+ }
+ bus->register_base =
+ (u64)devm_ioremap(&pdev->dev, bus->mdio_phys, bus->regsize);
bus->mii_bus = mdiobus_alloc();
if (!bus->mii_bus)
- goto err;
+ goto fail;
smi_en.u64 = 0;
smi_en.s.en = 1;
- cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+ cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64);
- /*
- * Standard Octeon evaluation boards don't support phy
- * interrupts, we need to poll.
- */
- for (i = 0; i < PHY_MAX_ADDR; i++)
- bus->phy_irq[i] = PHY_POLL;
bus->mii_bus->priv = bus;
bus->mii_bus->irq = bus->phy_irq;
bus->mii_bus->name = "mdio-octeon";
- snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%x", bus->unit);
+ snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", bus->register_base);
bus->mii_bus->parent = &pdev->dev;
bus->mii_bus->read = octeon_mdiobus_read;
@@ -126,20 +146,18 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, bus);
- err = mdiobus_register(bus->mii_bus);
+ err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node);
if (err)
- goto err_register;
+ goto fail_register;
dev_info(&pdev->dev, "Version " DRV_VERSION "\n");
return 0;
-err_register:
+fail_register:
mdiobus_free(bus->mii_bus);
-
-err:
- devm_kfree(&pdev->dev, bus);
+fail:
smi_en.u64 = 0;
- cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+ cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64);
return err;
}
@@ -153,14 +171,23 @@ static int __devexit octeon_mdiobus_remove(struct platform_device *pdev)
mdiobus_unregister(bus->mii_bus);
mdiobus_free(bus->mii_bus);
smi_en.u64 = 0;
- cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64);
+ cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64);
return 0;
}
+static struct of_device_id octeon_mdiobus_match[] = {
+ {
+ .compatible = "cavium,octeon-3860-mdio",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, octeon_mdiobus_match);
+
static struct platform_driver octeon_mdiobus_driver = {
.driver = {
.name = "mdio-octeon",
.owner = THIS_MODULE,
+ .of_match_table = octeon_mdiobus_match,
},
.probe = octeon_mdiobus_probe,
.remove = __devexit_p(octeon_mdiobus_remove),
--
1.7.2.3
^ permalink raw reply related
* [PATCH 7/8] netdev: octeon_mgmt: Convert to use device tree.
From: ddaney.cavm @ 2011-11-11 2:22 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: David Daney, David S. Miller, netdev
In-Reply-To: <1320978124-13042-1-git-send-email-ddaney.cavm@gmail.com>
From: David Daney <david.daney@cavium.com>
The device tree will supply the register bank base addresses, make
register addressing relative to those. PHY connection is now
described by the device tree.
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: David Daney <david.daney@cavium.com>
---
arch/mips/cavium-octeon/octeon-platform.c | 62 ------
drivers/net/ethernet/octeon/octeon_mgmt.c | 312 +++++++++++++++++++----------
2 files changed, 207 insertions(+), 167 deletions(-)
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 66cabc2..0938df1 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -168,68 +168,6 @@ out:
}
device_initcall(octeon_rng_device_init);
-/* Octeon mgmt port Ethernet interface. */
-static int __init octeon_mgmt_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
- int port, num_ports;
-
- struct resource mgmt_port_resource = {
- .flags = IORESOURCE_IRQ,
- .start = -1,
- .end = -1
- };
-
- if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX))
- return 0;
-
- if (OCTEON_IS_MODEL(OCTEON_CN56XX))
- num_ports = 1;
- else
- num_ports = 2;
-
- for (port = 0; port < num_ports; port++) {
- pd = platform_device_alloc("octeon_mgmt", port);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
- /* No DMA restrictions */
- pd->dev.coherent_dma_mask = DMA_BIT_MASK(64);
- pd->dev.dma_mask = &pd->dev.coherent_dma_mask;
-
- switch (port) {
- case 0:
- mgmt_port_resource.start = OCTEON_IRQ_MII0;
- break;
- case 1:
- mgmt_port_resource.start = OCTEON_IRQ_MII1;
- break;
- default:
- BUG();
- }
- mgmt_port_resource.end = mgmt_port_resource.start;
-
- ret = platform_device_add_resources(pd, &mgmt_port_resource, 1);
-
- if (ret)
- goto fail;
-
- ret = platform_device_add(pd);
- if (ret)
- goto fail;
- }
- return ret;
-fail:
- platform_device_put(pd);
-
-out:
- return ret;
-
-}
-device_initcall(octeon_mgmt_device_init);
-
#ifdef CONFIG_USB
static int __init octeon_ehci_device_init(void)
diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c
index 212f43b..c42bbb1 100644
--- a/drivers/net/ethernet/octeon/octeon_mgmt.c
+++ b/drivers/net/ethernet/octeon/octeon_mgmt.c
@@ -6,19 +6,21 @@
* Copyright (C) 2009 Cavium Networks
*/
-#include <linux/capability.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/capability.h>
#include <linux/interrupt.h>
-#include <linux/platform_device.h>
#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if.h>
+#include <linux/spinlock.h>
#include <linux/if_vlan.h>
+#include <linux/of_mdio.h>
+#include <linux/module.h>
+#include <linux/of_net.h>
+#include <linux/init.h>
#include <linux/slab.h>
#include <linux/phy.h>
-#include <linux/spinlock.h>
+#include <linux/io.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-mixx-defs.h>
@@ -58,8 +60,56 @@ union mgmt_port_ring_entry {
} s;
};
+#define MIX_ORING1 0x0
+#define MIX_ORING2 0x8
+#define MIX_IRING1 0x10
+#define MIX_IRING2 0x18
+#define MIX_CTL 0x20
+#define MIX_IRHWM 0x28
+#define MIX_IRCNT 0x30
+#define MIX_ORHWM 0x38
+#define MIX_ORCNT 0x40
+#define MIX_ISR 0x48
+#define MIX_INTENA 0x50
+#define MIX_REMCNT 0x58
+#define MIX_BIST 0x78
+
+#define AGL_GMX_PRT_CFG 0x10
+#define AGL_GMX_RX_FRM_CTL 0x18
+#define AGL_GMX_RX_FRM_MAX 0x30
+#define AGL_GMX_RX_JABBER 0x38
+#define AGL_GMX_RX_STATS_CTL 0x50
+
+#define AGL_GMX_RX_STATS_PKTS_DRP 0xb0
+#define AGL_GMX_RX_STATS_OCTS_DRP 0xb8
+#define AGL_GMX_RX_STATS_PKTS_BAD 0xc0
+
+#define AGL_GMX_RX_ADR_CTL 0x100
+#define AGL_GMX_RX_ADR_CAM_EN 0x108
+#define AGL_GMX_RX_ADR_CAM0 0x180
+#define AGL_GMX_RX_ADR_CAM1 0x188
+#define AGL_GMX_RX_ADR_CAM2 0x190
+#define AGL_GMX_RX_ADR_CAM3 0x198
+#define AGL_GMX_RX_ADR_CAM4 0x1a0
+#define AGL_GMX_RX_ADR_CAM5 0x1a8
+
+#define AGL_GMX_TX_STATS_CTL 0x268
+#define AGL_GMX_TX_CTL 0x270
+#define AGL_GMX_TX_STAT0 0x280
+#define AGL_GMX_TX_STAT1 0x288
+#define AGL_GMX_TX_STAT2 0x290
+#define AGL_GMX_TX_STAT3 0x298
+#define AGL_GMX_TX_STAT4 0x2a0
+#define AGL_GMX_TX_STAT5 0x2a8
+#define AGL_GMX_TX_STAT6 0x2b0
+#define AGL_GMX_TX_STAT7 0x2b8
+#define AGL_GMX_TX_STAT8 0x2c0
+#define AGL_GMX_TX_STAT9 0x2c8
+
struct octeon_mgmt {
struct net_device *netdev;
+ u64 mix;
+ u64 agl;
int port;
int irq;
u64 *tx_ring;
@@ -85,31 +135,34 @@ struct octeon_mgmt {
struct napi_struct napi;
struct tasklet_struct tx_clean_tasklet;
struct phy_device *phydev;
+ struct device_node *phy_np;
+ resource_size_t mix_phys;
+ resource_size_t mix_size;
+ resource_size_t agl_phys;
+ resource_size_t agl_size;
};
static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable)
{
- int port = p->port;
union cvmx_mixx_intena mix_intena;
unsigned long flags;
spin_lock_irqsave(&p->lock, flags);
- mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port));
+ mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA);
mix_intena.s.ithena = enable ? 1 : 0;
- cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+ cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
spin_unlock_irqrestore(&p->lock, flags);
}
static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable)
{
- int port = p->port;
union cvmx_mixx_intena mix_intena;
unsigned long flags;
spin_lock_irqsave(&p->lock, flags);
- mix_intena.u64 = cvmx_read_csr(CVMX_MIXX_INTENA(port));
+ mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA);
mix_intena.s.othena = enable ? 1 : 0;
- cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+ cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
spin_unlock_irqrestore(&p->lock, flags);
}
@@ -146,7 +199,6 @@ static unsigned int ring_size_to_bytes(unsigned int ring_size)
static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
while (p->rx_current_fill < ring_max_fill(OCTEON_MGMT_RX_RING_SIZE)) {
unsigned int size;
@@ -177,24 +229,23 @@ static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
(p->rx_next_fill + 1) % OCTEON_MGMT_RX_RING_SIZE;
p->rx_current_fill++;
/* Ring the bell. */
- cvmx_write_csr(CVMX_MIXX_IRING2(port), 1);
+ cvmx_write_csr(p->mix + MIX_IRING2, 1);
}
}
static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
{
- int port = p->port;
union cvmx_mixx_orcnt mix_orcnt;
union mgmt_port_ring_entry re;
struct sk_buff *skb;
int cleaned = 0;
unsigned long flags;
- mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
+ mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT);
while (mix_orcnt.s.orcnt) {
spin_lock_irqsave(&p->tx_list.lock, flags);
- mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
+ mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT);
if (mix_orcnt.s.orcnt == 0) {
spin_unlock_irqrestore(&p->tx_list.lock, flags);
@@ -214,7 +265,7 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
mix_orcnt.s.orcnt = 1;
/* Acknowledge to hardware that we have the buffer. */
- cvmx_write_csr(CVMX_MIXX_ORCNT(port), mix_orcnt.u64);
+ cvmx_write_csr(p->mix + MIX_ORCNT, mix_orcnt.u64);
p->tx_current_fill--;
spin_unlock_irqrestore(&p->tx_list.lock, flags);
@@ -224,7 +275,7 @@ static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
dev_kfree_skb_any(skb);
cleaned++;
- mix_orcnt.u64 = cvmx_read_csr(CVMX_MIXX_ORCNT(port));
+ mix_orcnt.u64 = cvmx_read_csr(p->mix + MIX_ORCNT);
}
if (cleaned && netif_queue_stopped(p->netdev))
@@ -241,13 +292,12 @@ static void octeon_mgmt_clean_tx_tasklet(unsigned long arg)
static void octeon_mgmt_update_rx_stats(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
unsigned long flags;
u64 drop, bad;
/* These reads also clear the count registers. */
- drop = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port));
- bad = cvmx_read_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port));
+ drop = cvmx_read_csr(p->agl + AGL_GMX_RX_STATS_PKTS_DRP);
+ bad = cvmx_read_csr(p->agl + AGL_GMX_RX_STATS_PKTS_BAD);
if (drop || bad) {
/* Do an atomic update. */
@@ -261,15 +311,14 @@ static void octeon_mgmt_update_rx_stats(struct net_device *netdev)
static void octeon_mgmt_update_tx_stats(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
unsigned long flags;
union cvmx_agl_gmx_txx_stat0 s0;
union cvmx_agl_gmx_txx_stat1 s1;
/* These reads also clear the count registers. */
- s0.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT0(port));
- s1.u64 = cvmx_read_csr(CVMX_AGL_GMX_TXX_STAT1(port));
+ s0.u64 = cvmx_read_csr(p->agl + AGL_GMX_TX_STAT0);
+ s1.u64 = cvmx_read_csr(p->agl + AGL_GMX_TX_STAT1);
if (s0.s.xsdef || s0.s.xscol || s1.s.scol || s1.s.mcol) {
/* Do an atomic update. */
@@ -308,7 +357,6 @@ static u64 octeon_mgmt_dequeue_rx_buffer(struct octeon_mgmt *p,
static int octeon_mgmt_receive_one(struct octeon_mgmt *p)
{
- int port = p->port;
struct net_device *netdev = p->netdev;
union cvmx_mixx_ircnt mix_ircnt;
union mgmt_port_ring_entry re;
@@ -381,18 +429,17 @@ done:
/* Tell the hardware we processed a packet. */
mix_ircnt.u64 = 0;
mix_ircnt.s.ircnt = 1;
- cvmx_write_csr(CVMX_MIXX_IRCNT(port), mix_ircnt.u64);
+ cvmx_write_csr(p->mix + MIX_IRCNT, mix_ircnt.u64);
return rc;
}
static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget)
{
- int port = p->port;
unsigned int work_done = 0;
union cvmx_mixx_ircnt mix_ircnt;
int rc;
- mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port));
+ mix_ircnt.u64 = cvmx_read_csr(p->mix + MIX_IRCNT);
while (work_done < budget && mix_ircnt.s.ircnt) {
rc = octeon_mgmt_receive_one(p);
@@ -400,7 +447,7 @@ static int octeon_mgmt_receive_packets(struct octeon_mgmt *p, int budget)
work_done++;
/* Check for more packets. */
- mix_ircnt.u64 = cvmx_read_csr(CVMX_MIXX_IRCNT(port));
+ mix_ircnt.u64 = cvmx_read_csr(p->mix + MIX_IRCNT);
}
octeon_mgmt_rx_fill_ring(p->netdev);
@@ -434,16 +481,16 @@ static void octeon_mgmt_reset_hw(struct octeon_mgmt *p)
union cvmx_agl_gmx_bist agl_gmx_bist;
mix_ctl.u64 = 0;
- cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64);
+ cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
do {
- mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(p->port));
+ mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL);
} while (mix_ctl.s.busy);
mix_ctl.s.reset = 1;
- cvmx_write_csr(CVMX_MIXX_CTL(p->port), mix_ctl.u64);
- cvmx_read_csr(CVMX_MIXX_CTL(p->port));
+ cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
+ cvmx_read_csr(p->mix + MIX_CTL);
cvmx_wait(64);
- mix_bist.u64 = cvmx_read_csr(CVMX_MIXX_BIST(p->port));
+ mix_bist.u64 = cvmx_read_csr(p->mix + MIX_BIST);
if (mix_bist.u64)
dev_warn(p->dev, "MIX failed BIST (0x%016llx)\n",
(unsigned long long)mix_bist.u64);
@@ -474,7 +521,6 @@ static void octeon_mgmt_cam_state_add(struct octeon_mgmt_cam_state *cs,
static void octeon_mgmt_set_rx_filtering(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
union cvmx_agl_gmx_rxx_adr_ctl adr_ctl;
union cvmx_agl_gmx_prtx_cfg agl_gmx_prtx;
unsigned long flags;
@@ -520,29 +566,29 @@ static void octeon_mgmt_set_rx_filtering(struct net_device *netdev)
spin_lock_irqsave(&p->lock, flags);
/* Disable packet I/O. */
- agl_gmx_prtx.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+ agl_gmx_prtx.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
prev_packet_enable = agl_gmx_prtx.s.en;
agl_gmx_prtx.s.en = 0;
- cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64);
+ cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, agl_gmx_prtx.u64);
adr_ctl.u64 = 0;
adr_ctl.s.cam_mode = cam_mode;
adr_ctl.s.mcst = multicast_mode;
adr_ctl.s.bcst = 1; /* Allow broadcast */
- cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CTL(port), adr_ctl.u64);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CTL, adr_ctl.u64);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM0(port), cam_state.cam[0]);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM1(port), cam_state.cam[1]);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM2(port), cam_state.cam[2]);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM3(port), cam_state.cam[3]);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM4(port), cam_state.cam[4]);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM5(port), cam_state.cam[5]);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_ADR_CAM_EN(port), cam_state.cam_mask);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM0, cam_state.cam[0]);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM1, cam_state.cam[1]);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM2, cam_state.cam[2]);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM3, cam_state.cam[3]);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM4, cam_state.cam[4]);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM5, cam_state.cam[5]);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_ADR_CAM_EN, cam_state.cam_mask);
/* Restore packet I/O. */
agl_gmx_prtx.s.en = prev_packet_enable;
- cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), agl_gmx_prtx.u64);
+ cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, agl_gmx_prtx.u64);
spin_unlock_irqrestore(&p->lock, flags);
}
@@ -564,7 +610,6 @@ static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr)
static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM;
/*
@@ -580,8 +625,8 @@ static int octeon_mgmt_change_mtu(struct net_device *netdev, int new_mtu)
netdev->mtu = new_mtu;
- cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_MAX(port), size_without_fcs);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_JABBER(port),
+ cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_MAX, size_without_fcs);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_JABBER,
(size_without_fcs + 7) & 0xfff8);
return 0;
@@ -591,14 +636,13 @@ static irqreturn_t octeon_mgmt_interrupt(int cpl, void *dev_id)
{
struct net_device *netdev = dev_id;
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
union cvmx_mixx_isr mixx_isr;
- mixx_isr.u64 = cvmx_read_csr(CVMX_MIXX_ISR(port));
+ mixx_isr.u64 = cvmx_read_csr(p->mix + MIX_ISR);
/* Clear any pending interrupts */
- cvmx_write_csr(CVMX_MIXX_ISR(port), mixx_isr.u64);
- cvmx_read_csr(CVMX_MIXX_ISR(port));
+ cvmx_write_csr(p->mix + MIX_ISR, mixx_isr.u64);
+ cvmx_read_csr(p->mix + MIX_ISR);
if (mixx_isr.s.irthresh) {
octeon_mgmt_disable_rx_irq(p);
@@ -629,7 +673,6 @@ static int octeon_mgmt_ioctl(struct net_device *netdev,
static void octeon_mgmt_adjust_link(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
union cvmx_agl_gmx_prtx_cfg prtx_cfg;
unsigned long flags;
int link_changed = 0;
@@ -640,11 +683,9 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev)
link_changed = 1;
if (p->last_duplex != p->phydev->duplex) {
p->last_duplex = p->phydev->duplex;
- prtx_cfg.u64 =
- cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+ prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
prtx_cfg.s.duplex = p->phydev->duplex;
- cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port),
- prtx_cfg.u64);
+ cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
}
} else {
if (p->last_link)
@@ -670,18 +711,16 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev)
static int octeon_mgmt_init_phy(struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- char phy_id[20];
- if (octeon_is_simulation()) {
+ if (octeon_is_simulation() || p->phy_np == NULL) {
/* No PHYs in the simulator. */
netif_carrier_on(netdev);
return 0;
}
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", p->port);
-
- p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0,
- PHY_INTERFACE_MODE_MII);
+ p->phydev = of_phy_connect(netdev, p->phy_np,
+ octeon_mgmt_adjust_link, 0,
+ PHY_INTERFACE_MODE_MII);
if (IS_ERR(p->phydev)) {
p->phydev = NULL;
@@ -737,14 +776,14 @@ static int octeon_mgmt_open(struct net_device *netdev)
octeon_mgmt_reset_hw(p);
- mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port));
+ mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL);
/* Bring it out of reset if needed. */
if (mix_ctl.s.reset) {
mix_ctl.s.reset = 0;
- cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64);
+ cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
do {
- mix_ctl.u64 = cvmx_read_csr(CVMX_MIXX_CTL(port));
+ mix_ctl.u64 = cvmx_read_csr(p->mix + MIX_CTL);
} while (mix_ctl.s.reset);
}
@@ -755,17 +794,17 @@ static int octeon_mgmt_open(struct net_device *netdev)
oring1.u64 = 0;
oring1.s.obase = p->tx_ring_handle >> 3;
oring1.s.osize = OCTEON_MGMT_TX_RING_SIZE;
- cvmx_write_csr(CVMX_MIXX_ORING1(port), oring1.u64);
+ cvmx_write_csr(p->mix + MIX_ORING1, oring1.u64);
iring1.u64 = 0;
iring1.s.ibase = p->rx_ring_handle >> 3;
iring1.s.isize = OCTEON_MGMT_RX_RING_SIZE;
- cvmx_write_csr(CVMX_MIXX_IRING1(port), iring1.u64);
+ cvmx_write_csr(p->mix + MIX_IRING1, iring1.u64);
/* Disable packet I/O. */
- prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+ prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
prtx_cfg.s.en = 0;
- cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64);
+ cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
memcpy(sa.sa_data, netdev->dev_addr, ETH_ALEN);
octeon_mgmt_set_mac_address(netdev, &sa);
@@ -782,7 +821,7 @@ static int octeon_mgmt_open(struct net_device *netdev)
mix_ctl.s.nbtarb = 0; /* Arbitration mode */
/* MII CB-request FIFO programmable high watermark */
mix_ctl.s.mrq_hwm = 1;
- cvmx_write_csr(CVMX_MIXX_CTL(port), mix_ctl.u64);
+ cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
|| OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
@@ -809,16 +848,16 @@ static int octeon_mgmt_open(struct net_device *netdev)
/* Clear statistics. */
/* Clear on read. */
- cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_CTL(port), 1);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_DRP(port), 0);
- cvmx_write_csr(CVMX_AGL_GMX_RXX_STATS_PKTS_BAD(port), 0);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_CTL, 1);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_PKTS_DRP, 0);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_STATS_PKTS_BAD, 0);
- cvmx_write_csr(CVMX_AGL_GMX_TXX_STATS_CTL(port), 1);
- cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT0(port), 0);
- cvmx_write_csr(CVMX_AGL_GMX_TXX_STAT1(port), 0);
+ cvmx_write_csr(p->agl + AGL_GMX_TX_STATS_CTL, 1);
+ cvmx_write_csr(p->agl + AGL_GMX_TX_STAT0, 0);
+ cvmx_write_csr(p->agl + AGL_GMX_TX_STAT1, 0);
/* Clear any pending interrupts */
- cvmx_write_csr(CVMX_MIXX_ISR(port), cvmx_read_csr(CVMX_MIXX_ISR(port)));
+ cvmx_write_csr(p->mix + MIX_ISR, cvmx_read_csr(p->mix + MIX_ISR));
if (request_irq(p->irq, octeon_mgmt_interrupt, 0, netdev->name,
netdev)) {
@@ -829,18 +868,18 @@ static int octeon_mgmt_open(struct net_device *netdev)
/* Interrupt every single RX packet */
mix_irhwm.u64 = 0;
mix_irhwm.s.irhwm = 0;
- cvmx_write_csr(CVMX_MIXX_IRHWM(port), mix_irhwm.u64);
+ cvmx_write_csr(p->mix + MIX_IRHWM, mix_irhwm.u64);
/* Interrupt when we have 1 or more packets to clean. */
mix_orhwm.u64 = 0;
mix_orhwm.s.orhwm = 1;
- cvmx_write_csr(CVMX_MIXX_ORHWM(port), mix_orhwm.u64);
+ cvmx_write_csr(p->mix + MIX_ORHWM, mix_orhwm.u64);
/* Enable receive and transmit interrupts */
mix_intena.u64 = 0;
mix_intena.s.ithena = 1;
mix_intena.s.othena = 1;
- cvmx_write_csr(CVMX_MIXX_INTENA(port), mix_intena.u64);
+ cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
/* Enable packet I/O. */
@@ -871,7 +910,7 @@ static int octeon_mgmt_open(struct net_device *netdev)
* frame. GMX checks that the PREAMBLE is sent correctly.
*/
rxx_frm_ctl.s.pre_chk = 1;
- cvmx_write_csr(CVMX_AGL_GMX_RXX_FRM_CTL(port), rxx_frm_ctl.u64);
+ cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
/* Enable the AGL block */
agl_gmx_inf_mode.u64 = 0;
@@ -879,13 +918,13 @@ static int octeon_mgmt_open(struct net_device *netdev)
cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
/* Configure the port duplex and enables */
- prtx_cfg.u64 = cvmx_read_csr(CVMX_AGL_GMX_PRTX_CFG(port));
+ prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
prtx_cfg.s.tx_en = 1;
prtx_cfg.s.rx_en = 1;
prtx_cfg.s.en = 1;
p->last_duplex = 1;
prtx_cfg.s.duplex = p->last_duplex;
- cvmx_write_csr(CVMX_AGL_GMX_PRTX_CFG(port), prtx_cfg.u64);
+ cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
p->last_link = 0;
netif_carrier_off(netdev);
@@ -949,7 +988,6 @@ static int octeon_mgmt_stop(struct net_device *netdev)
static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct octeon_mgmt *p = netdev_priv(netdev);
- int port = p->port;
union mgmt_port_ring_entry re;
unsigned long flags;
int rv = NETDEV_TX_BUSY;
@@ -993,7 +1031,7 @@ static int octeon_mgmt_xmit(struct sk_buff *skb, struct net_device *netdev)
netdev->stats.tx_bytes += skb->len;
/* Ring the bell. */
- cvmx_write_csr(CVMX_MIXX_ORING2(port), 1);
+ cvmx_write_csr(p->mix + MIX_ORING2, 1);
rv = NETDEV_TX_OK;
out:
@@ -1071,10 +1109,14 @@ static const struct net_device_ops octeon_mgmt_ops = {
static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
{
- struct resource *res_irq;
struct net_device *netdev;
struct octeon_mgmt *p;
- int i;
+ const __be32 *data;
+ const u8 *mac;
+ struct resource *res_mix;
+ struct resource *res_agl;
+ int len;
+ int result;
netdev = alloc_etherdev(sizeof(struct octeon_mgmt));
if (netdev == NULL)
@@ -1088,14 +1130,63 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
p->netdev = netdev;
p->dev = &pdev->dev;
- p->port = pdev->id;
+ data = of_get_property(pdev->dev.of_node, "cell-index", &len);
+ if (data && len == sizeof(*data)) {
+ p->port = be32_to_cpup(data);
+ } else {
+ dev_err(&pdev->dev, "no 'cell-index' property\n");
+ result = -ENXIO;
+ goto err;
+ }
+
snprintf(netdev->name, IFNAMSIZ, "mgmt%d", p->port);
- res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!res_irq)
+ result = platform_get_irq(pdev, 0);
+ if (result < 0)
+ goto err;
+
+ p->irq = result;
+
+ res_mix = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res_mix == NULL) {
+ dev_err(&pdev->dev, "no 'reg' resource\n");
+ result = -ENXIO;
+ goto err;
+ }
+
+ res_agl = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res_agl == NULL) {
+ dev_err(&pdev->dev, "no 'reg' resource\n");
+ result = -ENXIO;
+ goto err;
+ }
+
+ p->mix_phys = res_mix->start;
+ p->mix_size = resource_size(res_mix);
+ p->agl_phys = res_agl->start;
+ p->agl_size = resource_size(res_agl);
+
+
+ if (!devm_request_mem_region(&pdev->dev, p->mix_phys, p->mix_size,
+ res_mix->name)) {
+ dev_err(&pdev->dev, "request_mem_region (%s) failed\n",
+ res_mix->name);
+ result = -ENXIO;
+ goto err;
+ }
+
+ if (!devm_request_mem_region(&pdev->dev, p->agl_phys, p->agl_size,
+ res_agl->name)) {
+ result = -ENXIO;
+ dev_err(&pdev->dev, "request_mem_region (%s) failed\n",
+ res_agl->name);
goto err;
+ }
+
+
+ p->mix = (u64)devm_ioremap(&pdev->dev, p->mix_phys, p->mix_size);
+ p->agl = (u64)devm_ioremap(&pdev->dev, p->agl_phys, p->agl_size);
- p->irq = res_irq->start;
spin_lock_init(&p->lock);
skb_queue_head_init(&p->tx_list);
@@ -1108,24 +1199,26 @@ static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
netdev->netdev_ops = &octeon_mgmt_ops;
netdev->ethtool_ops = &octeon_mgmt_ethtool_ops;
- /* The mgmt ports get the first N MACs. */
- for (i = 0; i < 6; i++)
- netdev->dev_addr[i] = octeon_bootinfo->mac_addr_base[i];
- netdev->dev_addr[5] += p->port;
+ mac = of_get_mac_address(pdev->dev.of_node);
+
+ if (mac)
+ memcpy(netdev->dev_addr, mac, 6);
- if (p->port >= octeon_bootinfo->mac_addr_count)
- dev_err(&pdev->dev,
- "Error %s: Using MAC outside of the assigned range: %pM\n",
- netdev->name, netdev->dev_addr);
+ p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
- if (register_netdev(netdev))
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+
+ result = register_netdev(netdev);
+ if (result)
goto err;
dev_info(&pdev->dev, "Version " DRV_VERSION "\n");
return 0;
+
err:
free_netdev(netdev);
- return -ENOENT;
+ return result;
}
static int __devexit octeon_mgmt_remove(struct platform_device *pdev)
@@ -1137,10 +1230,19 @@ static int __devexit octeon_mgmt_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id octeon_mgmt_match[] = {
+ {
+ .compatible = "cavium,octeon-5750-mix",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, octeon_mgmt_match);
+
static struct platform_driver octeon_mgmt_driver = {
.driver = {
.name = "octeon_mgmt",
.owner = THIS_MODULE,
+ .of_match_table = octeon_mgmt_match,
},
.probe = octeon_mgmt_probe,
.remove = __devexit_p(octeon_mgmt_remove),
--
1.7.2.3
^ permalink raw reply related
* [PATCH 8/8] staging: octeon_ethernet: Convert to use device tree.
From: ddaney.cavm @ 2011-11-11 2:22 UTC (permalink / raw)
To: linux-mips, ralf, devicetree-discuss, grant.likely, linux-kernel
Cc: David Daney, David S. Miller, netdev, Greg Kroah-Hartman, devel
In-Reply-To: <1320978124-13042-1-git-send-email-ddaney.cavm@gmail.com>
From: David Daney <david.daney@cavium.com>
Get MAC address and PHY connection from the device tree.
Cc: "David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: devel@driverdev.osuosl.org
Signed-off-by: David Daney <david.daney@cavium.com>
---
drivers/staging/octeon/ethernet-mdio.c | 28 +++++----
drivers/staging/octeon/ethernet.c | 91 ++++++++++++++++++------------
drivers/staging/octeon/octeon-ethernet.h | 3 +
3 files changed, 72 insertions(+), 50 deletions(-)
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index 63800ba..f15b31b 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -28,6 +28,7 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/ratelimit.h>
+#include <linux/of_mdio.h>
#include <net/dst.h>
@@ -161,22 +162,23 @@ static void cvm_oct_adjust_link(struct net_device *dev)
int cvm_oct_phy_setup_device(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
+ struct device_node *phy_node;
- int phy_addr = cvmx_helper_board_get_mii_address(priv->port);
- if (phy_addr != -1) {
- char phy_id[20];
+ if (!priv->of_node)
+ return 0;
- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", phy_addr);
+ phy_node = of_parse_phandle(priv->of_node, "phy-handle", 0);
+ if (!phy_node)
+ return 0;
- priv->phydev = phy_connect(dev, phy_id, cvm_oct_adjust_link, 0,
- PHY_INTERFACE_MODE_GMII);
+ priv->phydev = of_phy_connect(dev, phy_node, cvm_oct_adjust_link, 0,
+ PHY_INTERFACE_MODE_GMII);
+
+ if (priv->phydev == NULL)
+ return -ENODEV;
+
+ priv->last_link = 0;
+ phy_start_aneg(priv->phydev);
- if (IS_ERR(priv->phydev)) {
- priv->phydev = NULL;
- return -1;
- }
- priv->last_link = 0;
- phy_start_aneg(priv->phydev);
- }
return 0;
}
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 9112cd8..5e96da6 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -31,6 +31,7 @@
#include <linux/etherdevice.h>
#include <linux/phy.h>
#include <linux/slab.h>
+#include <linux/of_net.h>
#include <net/dst.h>
@@ -112,15 +113,6 @@ int rx_napi_weight = 32;
module_param(rx_napi_weight, int, 0444);
MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter.");
-/*
- * The offset from mac_addr_base that should be used for the next port
- * that is configured. By convention, if any mgmt ports exist on the
- * chip, they get the first mac addresses, The ports controlled by
- * this driver are numbered sequencially following any mgmt addresses
- * that may exist.
- */
-static unsigned int cvm_oct_mac_addr_offset;
-
/**
* cvm_oct_poll_queue - Workqueue for polling operations.
*/
@@ -447,26 +439,16 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
int cvm_oct_common_init(struct net_device *dev)
{
struct octeon_ethernet *priv = netdev_priv(dev);
- struct sockaddr sa;
- u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) |
- ((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) |
- ((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) |
- ((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) |
- ((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) |
- (u64)(octeon_bootinfo->mac_addr_base[5] & 0xff);
-
- mac += cvm_oct_mac_addr_offset;
- sa.sa_data[0] = (mac >> 40) & 0xff;
- sa.sa_data[1] = (mac >> 32) & 0xff;
- sa.sa_data[2] = (mac >> 24) & 0xff;
- sa.sa_data[3] = (mac >> 16) & 0xff;
- sa.sa_data[4] = (mac >> 8) & 0xff;
- sa.sa_data[5] = mac & 0xff;
-
- if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count)
- printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:"
- " %pM\n", dev->name, sa.sa_data);
- cvm_oct_mac_addr_offset++;
+ struct sockaddr sa = {0};
+ const u8 *mac = NULL;
+
+ if (priv->of_node)
+ mac = of_get_mac_address(priv->of_node);
+
+ if (mac)
+ memcpy(sa.sa_data, mac, ETH_ALEN);
+ else
+ dev_hw_addr_random(dev, sa.sa_data);
/*
* Force the interface to use the POW send if always_use_pow
@@ -594,22 +576,55 @@ static const struct net_device_ops cvm_oct_pow_netdev_ops = {
extern void octeon_mdiobus_force_mod_depencency(void);
+static struct device_node * __init cvm_oct_of_get_child(const struct device_node *parent,
+ int reg_val)
+{
+ struct device_node *node = NULL;
+ int size;
+ const __be32 *addr;
+
+ for (;;) {
+ node = of_get_next_child(parent, node);
+ if (!node)
+ break;
+ addr = of_get_property(node, "reg", &size);
+ if (addr && (be32_to_cpu(*addr) == reg_val))
+ break;
+ }
+ return node;
+}
+
+static struct device_node * __init cvm_oct_node_for_port(struct device_node *pip,
+ int interface, int port)
+{
+ struct device_node *ni, *np;
+
+ ni = cvm_oct_of_get_child(pip, interface);
+ if (!ni)
+ return NULL;
+
+ np = cvm_oct_of_get_child(ni, port);
+ of_node_put(ni);
+
+ return np;
+}
+
static int __init cvm_oct_init_module(void)
{
int num_interfaces;
int interface;
int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
int qos;
+ struct device_node *pip;
octeon_mdiobus_force_mod_depencency();
pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
- if (OCTEON_IS_MODEL(OCTEON_CN52XX))
- cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */
- else if (OCTEON_IS_MODEL(OCTEON_CN56XX))
- cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */
- else
- cvm_oct_mac_addr_offset = 0;
+ pip = of_find_node_by_path("pip");
+ if (!pip) {
+ pr_err("Error: No 'pip' in /aliases\n");
+ return -EINVAL;
+ }
cvm_oct_poll_queue = create_singlethread_workqueue("octeon-ethernet");
if (cvm_oct_poll_queue == NULL) {
@@ -688,10 +703,11 @@ static int __init cvm_oct_init_module(void)
cvmx_helper_interface_get_mode(interface);
int num_ports = cvmx_helper_ports_on_interface(interface);
int port;
+ int port_index;
- for (port = cvmx_helper_get_ipd_port(interface, 0);
+ for (port_index = 0, port = cvmx_helper_get_ipd_port(interface, 0);
port < cvmx_helper_get_ipd_port(interface, num_ports);
- port++) {
+ port_index++, port++) {
struct octeon_ethernet *priv;
struct net_device *dev =
alloc_etherdev(sizeof(struct octeon_ethernet));
@@ -702,6 +718,7 @@ static int __init cvm_oct_init_module(void)
/* Initialize the device private structure. */
priv = netdev_priv(dev);
+ priv->of_node = cvm_oct_node_for_port(pip, interface, port_index);
INIT_DELAYED_WORK(&priv->port_periodic_work,
cvm_oct_periodic_worker);
diff --git a/drivers/staging/octeon/octeon-ethernet.h b/drivers/staging/octeon/octeon-ethernet.h
index d581925..9360e22 100644
--- a/drivers/staging/octeon/octeon-ethernet.h
+++ b/drivers/staging/octeon/octeon-ethernet.h
@@ -31,6 +31,8 @@
#ifndef OCTEON_ETHERNET_H
#define OCTEON_ETHERNET_H
+#include <linux/of.h>
+
/**
* This is the definition of the Ethernet driver's private
* driver state stored in netdev_priv(dev).
@@ -59,6 +61,7 @@ struct octeon_ethernet {
void (*poll) (struct net_device *dev);
struct delayed_work port_periodic_work;
struct work_struct port_work; /* may be unused. */
+ struct device_node *of_node;
};
int cvm_oct_free_work(void *work_queue_entry);
--
1.7.2.3
^ permalink raw reply related
* Re: tg3: BMC stops responding in 3.0
From: Arkadiusz Miśkiewicz @ 2011-11-11 4:30 UTC (permalink / raw)
To: Matt Carlson; +Cc: Michael Chan, netdev@vger.kernel.org
In-Reply-To: <201110261749.28799.a.miskiewicz@gmail.com>
On Wednesday 26 of October 2011, Arkadiusz Miśkiewicz wrote:
> On Saturday 01 of October 2011, Arkadiusz Miśkiewicz wrote:
> > On Saturday 01 of October 2011, Matt Carlson wrote:
> > > On Fri, Sep 30, 2011 at 01:06:25AM -0700, Arkadiusz Mi??kiewicz wrote:
> > > > On Friday 30 of September 2011, Matt Carlson wrote:
> > > > > On Mon, Sep 26, 2011 at 11:31:33AM -0700, Arkadiusz Mi??kiewicz wrote:
> > > > > > On Monday 26 of September 2011, Matt Carlson wrote:
> > > > > > > On Fri, Sep 23, 2011 at 12:45:50PM -0700, Arkadiusz Mi??kiewicz
> >
> > wrote:
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > I was using 2.6.38.8 and recently tried to switch to 3.0.4 on
> > > > > > > > Tyan S2891 platform.
> > > > > > > >
> > > > > > > > This platform uses tg3:
> > > > > > > > tg3 0000:0a:09.1: eth1: Tigon3 [partno(BCM95704) rev 2003]
> > > > > > > > (PCIX:133MHz:64- bit) MAC address 00:e0:81:33:5e:af
> > > > > > > > tg3 0000:0a:09.1: eth1: attached PHY is 5704
> > > > > > > > (10/100/1000Base-T Ethernet) (WireSpeed[1], EEE[0])
> > > > > > > > tg3 0000:0a:09.1: eth1: RXcsums[1] LinkChgREG[0] MIirq[0]
> > > > > > > > ASF[0] TSOcap[1] tg3 0000:0a:09.1: eth1: dma_rwctrl[769f4000]
> > > > > > > > dma_mask[64-bit]
> > > > > > > >
> > > > > > > > With 2.6.38.8 everything was working fine. With 3.0.4 there
> > > > > > > > is a problem. As soon as tg3 module is loaded or eth0
> > > > > > > > configured (can't tell which one since the machine is 400km
> > > > > > > > away from me and I have no way to play with it other than
> > > > > > > > ipmi or ssh) BMC stops responding (so all ipmitool commands
> > > > > > > > over LAN stop working). Normal tg3 activity is not affected
> > > > > > > > - I can ssh-in without a problem etc but ipmi over lan
> > > > > > > > doesn't work.
> > > > > > > >
> > > > > > > > From ssh console "ipmitool lan print" works, shows data but
> > > > > > > > for example after "ipmitool mc reset cold" it doesn't
> > > > > > > > recover - ipmitool returns "Invalid channel: 255". I have to
> > > > > > > > reboot to 2.6.38.8 and then issue "ipmitool mc reset cold"
> > > > > > > > to recover.
> > > > > > > >
> > > > > > > > Any idea which tg3 change could break this? Can't bisect this
> > > > > > > > due remote access only.
> > > > > > > >
> > > > > > > > I was hoping that maybe
> > > > > > > > 9e975cc291d80d5e4562d6bed15ec171e896d69b "tg3: Fix io
> > > > > > > > failures after chip reset" will fix things for me but no -
> > > > > > > > this doesn't help.
> > > > > > >
> > > > > > > What version of the tg3 driver are you working with?
> > > > > >
> > > > > > The one in 3.0.4 kernel. I think it's 3.119 (at least modinfo
> > > > > > says so).
> > > > >
> > > > > Unfortunately there were a lot of changes between 3.117 and
> > > > > 3.119(+). Is there any way you can narrow down the gap?
> > > >
> > > > The machines are 400km away from me and it's hard to debug that way
> > > > then ipmi/network conectivity is in stake :-/ I could try some form
> > > > of bisecting but need to know if all git versions between 3.117 and
> > > > 3.119 were known to be safe and working? I don't want to loose any
> > > > conectivity to this machine.
> > > >
> > > > I was going to try 2.6.39 but it looks like it also uses 3.117
> > > > driver.
> > >
> > > O.K. Can you give me the details of your machine? Maybe we have the
> > > exact machine or a machine similar enough to reproduce the problem
> > > with.
>
> Did you have any chance to find and test on a similar system?
I was finally able to bisect the thing. Reverting commit below from 3.0 kernel
makes my IPMI working even after tg3 is loaded.
commit 0da0606f493c5cdab74bdcc96b12f4305ad94085
Author: Matt Carlson <mcarlson@broadcom.com>
Date: Thu May 19 12:12:53 2011 +0000
tg3: Consolidate all netdev feature assignments
This patch consolidates all the netdev feature bit assignments to one
location.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
git bisect start 'drivers/net/tg3.c'
# good: [61c4f2c81c61f73549928dfd9f3e8f26aa36a8cf] Linux 2.6.39
git bisect good 61c4f2c81c61f73549928dfd9f3e8f26aa36a8cf
# bad: [02f8c6aee8df3cdc935e9bdd4f2d020306035dbe] Linux 3.0
git bisect bad 02f8c6aee8df3cdc935e9bdd4f2d020306035dbe
# good: [470078312515f12e7cd916f1bd002acad313b9c8] tg3: Add additional EEE messaging
git bisect good 470078312515f12e7cd916f1bd002acad313b9c8
# good: [1ff30a59f6d0c754e99442501a5145bdbbcfa6ea] tg3: Fix 57765 B0 data corruption
git bisect good 1ff30a59f6d0c754e99442501a5145bdbbcfa6ea
# bad: [0da0606f493c5cdab74bdcc96b12f4305ad94085] tg3: Consolidate all netdev feature assignments
git bisect bad 0da0606f493c5cdab74bdcc96b12f4305ad94085
# good: [42b64a450b81ec9e8cdd5b3fb13613ab9bb25048] tg3: Consolidate autoneg advertisement setup code
git bisect good 42b64a450b81ec9e8cdd5b3fb13613ab9bb25048
# good: [4452d0999906e3e26b718566362e943fcaa3d694] tg3: Fix stats for 5704 and later devices
git bisect good 4452d0999906e3e26b718566362e943fcaa3d694
# good: [dabc5c670d3f86d15ee4f42ab38ec5bd2682487d] tg3: Move TSO_CAPABLE assignment
git bisect good dabc5c670d3f86d15ee4f42ab38ec5bd2682487d
>
> > It's 1U server, with Tyan S2891 mainboard and some chenbro chassis. ipmi
> > and eth0 share physical rj45 port in the server.
> >
> > lspci & dmidecode below:
> >
> > 00:00.0 Memory controller: nVidia Corporation CK804 Memory Controller
> > (rev a3) Subsystem: Tyan Computer Thunder K8SRE Mainboard
> >
> > Flags: bus master, 66MHz, fast devsel, latency 0
> > Capabilities: [44] HyperTransport: Slave or Primary Interface
> > Capabilities: [e0] HyperTransport: MSI Mapping Enable+ Fixed-
> >
> > 00:01.0 ISA bridge: nVidia Corporation CK804 ISA Bridge (rev a3)
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: bus master, 66MHz, fast devsel, latency 0
> > I/O ports at 8c00 [size=1K]
> >
> > 00:01.1 SMBus: nVidia Corporation CK804 SMBus (rev a2)
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: 66MHz, fast devsel
> > I/O ports at 1000 [size=32]
> > I/O ports at 5000 [size=64]
> > I/O ports at 5040 [size=64]
> > Capabilities: [44] Power Management version 2
> >
> > 00:02.0 USB Controller: nVidia Corporation CK804 USB Controller (rev a2)
> > (prog-if 10 [OHCI])
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: bus master, 66MHz, fast devsel, latency 0, IRQ 10
> > Memory at dd000000 (32-bit, non-prefetchable) [size=4K]
> > Capabilities: [44] Power Management version 2
> >
> > 00:02.1 USB Controller: nVidia Corporation CK804 USB Controller (rev a3)
> > (prog-if 20 [EHCI])
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: bus master, 66MHz, fast devsel, latency 0, IRQ 7
> > Memory at dd001000 (32-bit, non-prefetchable) [size=256]
> > Capabilities: [44] Debug port: BAR=1 offset=0098
> > Capabilities: [80] Power Management version 2
> >
> > 00:06.0 IDE interface: nVidia Corporation CK804 IDE (rev f2) (prog-if 8a
> > [Master SecP PriP])
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: bus master, 66MHz, fast devsel, latency 0
> > [virtual] Memory at 000001f0 (32-bit, non-prefetchable) [size=8]
> > [virtual] Memory at 000003f0 (type 3, non-prefetchable) [size=1]
> > [virtual] Memory at 00000170 (32-bit, non-prefetchable) [size=8]
> > [virtual] Memory at 00000370 (type 3, non-prefetchable) [size=1]
> > I/O ports at 1400 [size=16]
> > Capabilities: [44] Power Management version 2
> >
> > 00:07.0 IDE interface: nVidia Corporation CK804 Serial ATA Controller
> > (rev f3) (prog-if 85 [Master SecO PriO])
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: bus master, 66MHz, fast devsel, latency 0, IRQ 11
> > I/O ports at 1440 [size=8]
> > I/O ports at 1434 [size=4]
> > I/O ports at 1438 [size=8]
> > I/O ports at 1430 [size=4]
> > I/O ports at 1410 [size=16]
> > Memory at dd002000 (32-bit, non-prefetchable) [size=4K]
> > Capabilities: [44] Power Management version 2
> >
> > 00:08.0 IDE interface: nVidia Corporation CK804 Serial ATA Controller
> > (rev f3) (prog-if 85 [Master SecO PriO])
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: bus master, 66MHz, fast devsel, latency 0, IRQ 10
> > I/O ports at 1458 [size=8]
> > I/O ports at 144c [size=4]
> > I/O ports at 1450 [size=8]
> > I/O ports at 1448 [size=4]
> > I/O ports at 1420 [size=16]
> > Memory at dd003000 (32-bit, non-prefetchable) [size=4K]
> > Capabilities: [44] Power Management version 2
> >
> > 00:09.0 PCI bridge: nVidia Corporation CK804 PCI Bridge (rev a2) (prog-if
> > 00 [Normal decode])
> >
> > Flags: bus master, 66MHz, fast devsel, latency 0
> > Bus: primary=00, secondary=01, subordinate=01, sec-latency=64
> > I/O behind bridge: 00002000-00002fff
> > Memory behind bridge: dd100000-deffffff
> > Prefetchable memory behind bridge: d0000000-d00fffff
> >
> > 00:0e.0 PCI bridge: nVidia Corporation CK804 PCIE Bridge (rev a3)
> > (prog-if 00 [Normal decode])
> >
> > Flags: bus master, fast devsel, latency 0
> > Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
> > Capabilities: [40] Power Management version 2
> > Capabilities: [48] MSI: Enable- Count=1/2 Maskable- 64bit+
> > Capabilities: [58] HyperTransport: MSI Mapping Enable- Fixed-
> > Capabilities: [80] Express Root Port (Slot+), MSI 00
> > Kernel driver in use: pcieport
> >
> > 00:18.0 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron]
> > HyperTransport Technology Configuration
> >
> > Flags: fast devsel
> > Capabilities: [80] HyperTransport: Host or Secondary Interface
> > Capabilities: [a0] HyperTransport: Host or Secondary Interface
> > Capabilities: [c0] HyperTransport: Host or Secondary Interface
> >
> > 00:18.1 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron]
> > Address Map
> >
> > Flags: fast devsel
> >
> > 00:18.2 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron]
> > DRAM Controller
> >
> > Flags: fast devsel
> >
> > 00:18.3 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron]
> > Miscellaneous Control
> >
> > Flags: fast devsel
> >
> > 00:19.0 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron]
> > HyperTransport Technology Configuration
> >
> > Flags: fast devsel
> > Capabilities: [80] HyperTransport: Host or Secondary Interface
> > Capabilities: [a0] HyperTransport: Host or Secondary Interface
> > Capabilities: [c0] HyperTransport: Host or Secondary Interface
> >
> > 00:19.1 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron]
> > Address Map
> >
> > Flags: fast devsel
> >
> > 00:19.2 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron]
> > DRAM Controller
> >
> > Flags: fast devsel
> >
> > 00:19.3 Host bridge: Advanced Micro Devices [AMD] K8 [Athlon64/Opteron]
> > Miscellaneous Control
> >
> > Flags: fast devsel
> >
> > 01:07.0 VGA compatible controller: ATI Technologies Inc Rage XL (rev 27)
> > (prog-if 00 [VGA controller])
> >
> > Subsystem: ATI Technologies Inc Rage XL
> > Flags: bus master, stepping, medium devsel, latency 66, IRQ 11
> > Memory at de000000 (32-bit, non-prefetchable) [size=16M]
> > I/O ports at 2000 [size=256]
> > Memory at dd100000 (32-bit, non-prefetchable) [size=4K]
> > [virtual] Expansion ROM at d0000000 [disabled] [size=128K]
> > Capabilities: [5c] Power Management version 2
> >
> > 08:0a.0 PCI bridge: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge
> > (rev 12) (prog-if 00 [Normal decode])
> >
> > Flags: bus master, 66MHz, medium devsel, latency 64
> > Bus: primary=08, secondary=09, subordinate=09, sec-latency=64
> > I/O behind bridge: 00003000-00003fff
> > Memory behind bridge: df300000-df3fffff
> > Prefetchable memory behind bridge: 00000000df500000-00000000df5fffff
> > Capabilities: [a0] PCI-X bridge device
> > Capabilities: [b8] HyperTransport: Interrupt Discovery and Configuration
> > Capabilities: [c0] HyperTransport: Slave or Primary Interface
> >
> > 08:0a.1 PIC: Advanced Micro Devices [AMD] AMD-8131 PCI-X IOAPIC (rev 01)
> > (prog-if 10 [IO-APIC])
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: bus master, medium devsel, latency 0
> > Memory at df200000 (64-bit, non-prefetchable) [size=4K]
> >
> > 08:0b.0 PCI bridge: Advanced Micro Devices [AMD] AMD-8131 PCI-X Bridge
> > (rev 12) (prog-if 00 [Normal decode])
> >
> > Flags: bus master, 66MHz, medium devsel, latency 64
> > Bus: primary=08, secondary=0a, subordinate=0a, sec-latency=64
> > Memory behind bridge: df400000-df4fffff
> > Capabilities: [a0] PCI-X bridge device
> > Capabilities: [b8] HyperTransport: Interrupt Discovery and Configuration
> >
> > 08:0b.1 PIC: Advanced Micro Devices [AMD] AMD-8131 PCI-X IOAPIC (rev 01)
> > (prog-if 10 [IO-APIC])
> >
> > Subsystem: Tyan Computer Device 2891
> > Flags: bus master, medium devsel, latency 0
> > Memory at df201000 (64-bit, non-prefetchable) [size=4K]
> >
> > 09:08.0 Fibre Channel: QLogic Corp. ISP2312-based 2Gb Fibre Channel to
> > PCI-X HBA (rev 02)
> >
> > Subsystem: Compaq Computer Corporation Device 0100
> > Flags: bus master, 66MHz, medium devsel, latency 128, IRQ 24
> > I/O ports at 3000 [size=256]
> > Memory at df300000 (64-bit, non-prefetchable) [size=4K]
> > [virtual] Expansion ROM at df500000 [disabled] [size=128K]
> > Capabilities: [44] Power Management version 2
> > Capabilities: [4c] PCI-X non-bridge device
> > Capabilities: [54] MSI: Enable- Count=1/8 Maskable- 64bit+
> > Capabilities: [64] CompactPCI hot-swap <?>
> > Kernel driver in use: qla2xxx
> >
> > 0a:09.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5704
> > Gigabit Ethernet (rev 03)
> >
> > Subsystem: Broadcom Corporation NetXtreme BCM5704 Gigabit Ethernet
> > Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 28
> > Memory at df410000 (64-bit, non-prefetchable) [size=64K]
> > Memory at df400000 (64-bit, non-prefetchable) [size=64K]
> > Capabilities: [40] PCI-X non-bridge device
> > Capabilities: [48] Power Management version 2
> > Capabilities: [50] Vital Product Data
> > Capabilities: [58] MSI: Enable- Count=1/8 Maskable- 64bit+
> > Kernel driver in use: tg3
> >
> > 0a:09.1 Ethernet controller: Broadcom Corporation NetXtreme BCM5704
> > Gigabit Ethernet (rev 03)
> >
> > Subsystem: Broadcom Corporation NetXtreme BCM5704 Gigabit Ethernet
> > Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 29
> > Memory at df430000 (64-bit, non-prefetchable) [size=64K]
> > Memory at df420000 (64-bit, non-prefetchable) [size=64K]
> > Capabilities: [40] PCI-X non-bridge device
> > Capabilities: [48] Power Management version 2
> > Capabilities: [50] Vital Product Data
> > Capabilities: [58] MSI: Enable- Count=1/8 Maskable- 64bit+
> > Kernel driver in use: tg3
> >
> > # dmidecode 2.11
> > SMBIOS version fixup (2.33 -> 2.3).
> > SMBIOS 2.3 present.
> > 34 structures occupying 1202 bytes.
> > Table at 0x7FFEF000.
> >
> > Handle 0x0000, DMI type 0, 20 bytes
> > BIOS Information
> >
> > Vendor: Phoenix Technologies Ltd.
> > Version: 2003Q2
> > Release Date: 03/27/2006
> > Address: 0xE65B0
> > Runtime Size: 105040 bytes
> > ROM Size: 1024 kB
> >
> > Characteristics:
> > PCI is supported
> > PNP is supported
> > BIOS is upgradeable
> > BIOS shadowing is allowed
> > ESCD support is available
> > Boot from CD is supported
> > Selectable boot is supported
> > EDD is supported
> > 5.25"/360 kB floppy services are supported (int 13h)
> > 5.25"/1.2 MB floppy services are supported (int 13h)
> > 3.5"/720 kB floppy services are supported (int 13h)
> > 3.5"/2.88 MB floppy services are supported (int 13h)
> > Print screen service is supported (int 5h)
> > 8042 keyboard services are supported (int 9h)
> > Serial services are supported (int 14h)
> > Printer services are supported (int 17h)
> > CGA/mono video services are supported (int 10h)
> > ACPI is supported
> > USB legacy is supported
> >
> > Handle 0x0001, DMI type 1, 25 bytes
> > System Information
> >
> > Manufacturer: TYAN Computer Corp
> > Product Name: S2891
> > Version: REFERENCE
> > Serial Number: 0123456789
> > UUID: Not Settable
> > Wake-up Type: Power Switch
> >
> > Handle 0x0002, DMI type 2, 8 bytes
> > Base Board Information
> >
> > Manufacturer: TYAN Computer Corp
> > Product Name: GT24-B2891
> > Version: REFERENCE
> > Serial Number: 0123456789
> >
> > Handle 0x0003, DMI type 3, 17 bytes
> > Chassis Information
> >
> > Manufacturer: TYAN Computer Corp
> > Type: Main Server Chassis
> > Lock: Not Present
> > Version: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Boot-up State: Unknown
> > Power Supply State: Unknown
> > Thermal State: Unknown
> > Security Status: Unknown
> > OEM Information: 0x00000000
> >
> > Handle 0x0004, DMI type 4, 35 bytes
> > Processor Information
> >
> > Socket Designation: CPU0-Socket 940
> > Type: Central Processor
> > Family: Opteron
> > Manufacturer: AMD
> > ID: 12 0F 02 00 FF FB 8B 17
> > Signature: Family 15, Model 33, Stepping 2
> >
> > Flags:
> > FPU (Floating-point unit on-chip)
> > VME (Virtual mode extension)
> > DE (Debugging extension)
> > PSE (Page size extension)
> > TSC (Time stamp counter)
> > MSR (Model specific registers)
> > PAE (Physical address extension)
> > MCE (Machine check exception)
> > CX8 (CMPXCHG8 instruction supported)
> > APIC (On-chip APIC hardware supported)
> > SEP (Fast system call)
> > MTRR (Memory type range registers)
> > PGE (Page global enable)
> > MCA (Machine check architecture)
> > CMOV (Conditional move instruction supported)
> > PAT (Page attribute table)
> > PSE-36 (36-bit page size extension)
> > CLFSH (CLFLUSH instruction supported)
> > MMX (MMX technology supported)
> > FXSR (FXSAVE and FXSTOR instructions supported)
> > SSE (Streaming SIMD extensions)
> > SSE2 (Streaming SIMD extensions 2)
> > HTT (Multi-threading)
> >
> > Version: AMD
> > Voltage: 1.2 V
> > External Clock: 200 MHz
> > Max Speed: 3000 MHz
> > Current Speed: 2000 MHz
> > Status: Populated, Enabled
> > Upgrade: None
> > L1 Cache Handle: 0x0006
> > L2 Cache Handle: 0x0007
> > L3 Cache Handle: Not Provided
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0005, DMI type 4, 35 bytes
> > Processor Information
> >
> > Socket Designation: CPU1-Socket 940
> > Type: Central Processor
> > Family: Opteron
> > Manufacturer: AMD
> > ID: 12 0F 02 00 FF FB 8B 17
> > Signature: Family 15, Model 33, Stepping 2
> >
> > Flags:
> > FPU (Floating-point unit on-chip)
> > VME (Virtual mode extension)
> > DE (Debugging extension)
> > PSE (Page size extension)
> > TSC (Time stamp counter)
> > MSR (Model specific registers)
> > PAE (Physical address extension)
> > MCE (Machine check exception)
> > CX8 (CMPXCHG8 instruction supported)
> > APIC (On-chip APIC hardware supported)
> > SEP (Fast system call)
> > MTRR (Memory type range registers)
> > PGE (Page global enable)
> > MCA (Machine check architecture)
> > CMOV (Conditional move instruction supported)
> > PAT (Page attribute table)
> > PSE-36 (36-bit page size extension)
> > CLFSH (CLFLUSH instruction supported)
> > MMX (MMX technology supported)
> > FXSR (FXSAVE and FXSTOR instructions supported)
> > SSE (Streaming SIMD extensions)
> > SSE2 (Streaming SIMD extensions 2)
> > HTT (Multi-threading)
> >
> > Version: AMD
> > Voltage: 1.2 V
> > External Clock: 200 MHz
> > Max Speed: 3000 MHz
> > Current Speed: 2000 MHz
> > Status: Populated, Enabled
> > Upgrade: None
> > L1 Cache Handle: 0x0008
> > L2 Cache Handle: 0x0009
> > L3 Cache Handle: Not Provided
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0006, DMI type 7, 19 bytes
> > Cache Information
> >
> > Socket Designation: H0 L1 Cache
> > Configuration: Enabled, Not Socketed, Level 1
> > Operational Mode: Write Back
> > Location: Internal
> > Installed Size: 64 kB
> > Maximum Size: 64 kB
> >
> > Supported SRAM Types:
> > Burst
> > Pipeline Burst
> > Asynchronous
> >
> > Installed SRAM Type: Asynchronous
> > Speed: Unknown
> > Error Correction Type: Unknown
> > System Type: Unknown
> > Associativity: Unknown
> >
> > Handle 0x0007, DMI type 7, 19 bytes
> > Cache Information
> >
> > Socket Designation: H0 L2 Cache
> > Configuration: Enabled, Not Socketed, Level 2
> > Operational Mode: Write Through
> > Location: Internal
> > Installed Size: 2048 kB
> > Maximum Size: 1024 kB
> >
> > Supported SRAM Types:
> > Burst
> > Pipeline Burst
> > Synchronous
> >
> > Installed SRAM Type: Synchronous
> > Speed: Unknown
> > Error Correction Type: Unknown
> > System Type: Unified
> > Associativity: Unknown
> >
> > Handle 0x0008, DMI type 7, 19 bytes
> > Cache Information
> >
> > Socket Designation: H1 L1 Cache
> > Configuration: Enabled, Not Socketed, Level 1
> > Operational Mode: Write Back
> > Location: Internal
> > Installed Size: 64 kB
> > Maximum Size: 64 kB
> >
> > Supported SRAM Types:
> > Burst
> > Pipeline Burst
> > Asynchronous
> >
> > Installed SRAM Type: Asynchronous
> > Speed: Unknown
> > Error Correction Type: Unknown
> > System Type: Unknown
> > Associativity: Unknown
> >
> > Handle 0x0009, DMI type 7, 19 bytes
> > Cache Information
> >
> > Socket Designation: H1 L2 Cache
> > Configuration: Enabled, Not Socketed, Level 2
> > Operational Mode: Write Through
> > Location: Internal
> > Installed Size: 2048 kB
> > Maximum Size: 1024 kB
> >
> > Supported SRAM Types:
> > Burst
> > Pipeline Burst
> > Synchronous
> >
> > Installed SRAM Type: Synchronous
> > Speed: Unknown
> > Error Correction Type: Unknown
> > System Type: Unified
> > Associativity: Unknown
> >
> > Handle 0x000A, DMI type 8, 9 bytes
> > Port Connector Information
> >
> > Internal Reference Designator: J2
> > Internal Connector Type: PS/2
> > External Reference Designator: PS/2 Mouse
> > External Connector Type: PS/2
> > Port Type: Mouse Port
> >
> > Handle 0x000B, DMI type 9, 13 bytes
> > System Slot Information
> >
> > Designation: PCI Slot 1
> > Type: 32-bit PCI
> > Current Usage: Unknown
> > Length: Long
> > ID: 0
> >
> > Characteristics:
> > 3.3 V is provided
> > PME signal is supported
> >
> > Handle 0x000C, DMI type 11, 5 bytes
> > OEM Strings
> >
> > String 1: 0
> > String 2: 0
> > String 3: .........................
> >
> > Handle 0x000D, DMI type 16, 15 bytes
> > Physical Memory Array
> >
> > Location: System Board Or Motherboard
> > Use: System Memory
> > Error Correction Type: Single-bit ECC
> > Maximum Capacity: 32 GB
> > Error Information Handle: Not Provided
> > Number Of Devices: 8
> >
> > Handle 0x000E, DMI type 17, 27 bytes
> > Memory Device
> >
> > Array Handle: 0x000D
> > Error Information Handle: No Error
> > Total Width: 128 bits
> > Data Width: 64 bits
> > Size: 8192 MB
> > Form Factor: DIMM
> > Set: 1
> > Locator: C0_DIMM0
> > Bank Locator: Bank 0
> > Type: DRAM
> > Type Detail: Synchronous
> > Speed: Unknown
> > Manufacturer: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x000F, DMI type 17, 27 bytes
> > Memory Device
> >
> > Array Handle: 0x000D
> > Error Information Handle: No Error
> > Total Width: 128 bits
> > Data Width: 64 bits
> > Size: 8192 MB
> > Form Factor: DIMM
> > Set: 2
> > Locator: C0_DIMM1
> > Bank Locator: Bank 1
> > Type: DRAM
> > Type Detail: Synchronous
> > Speed: Unknown
> > Manufacturer: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0010, DMI type 17, 27 bytes
> > Memory Device
> >
> > Array Handle: 0x000D
> > Error Information Handle: No Error
> > Total Width: 128 bits
> > Data Width: 64 bits
> > Size: 8192 MB
> > Form Factor: DIMM
> > Set: 3
> > Locator: C0_DIMM2
> > Bank Locator: Bank 2
> > Type: DRAM
> > Type Detail: Synchronous
> > Speed: Unknown
> > Manufacturer: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0011, DMI type 17, 27 bytes
> > Memory Device
> >
> > Array Handle: 0x000D
> > Error Information Handle: No Error
> > Total Width: 128 bits
> > Data Width: 64 bits
> > Size: 8192 MB
> > Form Factor: DIMM
> > Set: 3
> > Locator: C0_DIMM3
> > Bank Locator: Bank 3
> > Type: DRAM
> > Type Detail: Synchronous
> > Speed: Unknown
> > Manufacturer: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0012, DMI type 17, 27 bytes
> > Memory Device
> >
> > Array Handle: 0x000D
> > Error Information Handle: No Error
> > Total Width: 128 bits
> > Data Width: 64 bits
> > Size: 8192 MB
> > Form Factor: DIMM
> > Set: 3
> > Locator: C0_DIMM0
> > Bank Locator: Bank 0
> > Type: DRAM
> > Type Detail: Synchronous
> > Speed: Unknown
> > Manufacturer: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0013, DMI type 17, 27 bytes
> > Memory Device
> >
> > Array Handle: 0x000D
> > Error Information Handle: No Error
> > Total Width: 128 bits
> > Data Width: 64 bits
> > Size: 8192 MB
> > Form Factor: DIMM
> > Set: 3
> > Locator: C1_DIMM1
> > Bank Locator: Bank 1
> > Type: DRAM
> > Type Detail: Synchronous
> > Speed: Unknown
> > Manufacturer: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0014, DMI type 17, 27 bytes
> > Memory Device
> >
> > Array Handle: 0x000D
> > Error Information Handle: No Error
> > Total Width: Unknown
> > Data Width: Unknown
> > Size: No Module Installed
> > Form Factor: DIMM
> > Set: 3
> > Locator: C1_DIMM2
> > Bank Locator: Bank 2
> > Type: DRAM
> > Type Detail: Synchronous
> > Speed: Unknown
> > Manufacturer: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0015, DMI type 17, 27 bytes
> > Memory Device
> >
> > Array Handle: 0x000D
> > Error Information Handle: No Error
> > Total Width: Unknown
> > Data Width: Unknown
> > Size: No Module Installed
> > Form Factor: DIMM
> > Set: 3
> > Locator: C1_DIMM3
> > Bank Locator: Bank 3
> > Type: DRAM
> > Type Detail: Synchronous
> > Speed: Unknown
> > Manufacturer: Not Specified
> > Serial Number: Not Specified
> > Asset Tag: Not Specified
> > Part Number: Not Specified
> >
> > Handle 0x0016, DMI type 19, 15 bytes
> > Memory Array Mapped Address
> >
> > Starting Address: 0x00000000000
> > Ending Address: 0x00BFFFFFFFF
> > Range Size: 48 GB
> > Physical Array Handle: 0x000D
> > Partition Width: 2
> >
> > Handle 0x0017, DMI type 20, 19 bytes
> > Memory Device Mapped Address
> >
> > Starting Address: 0x00000000000
> > Ending Address: 0x001FFFFFFFF
> > Range Size: 8 GB
> > Physical Device Handle: 0x000E
> > Memory Array Mapped Address Handle: 0x0016
> > Partition Row Position: 1
> > Interleaved Data Depth: 1
> >
> > Handle 0x0018, DMI type 20, 19 bytes
> > Memory Device Mapped Address
> >
> > Starting Address: 0x00200000000
> > Ending Address: 0x003FFFFFFFF
> > Range Size: 8 GB
> > Physical Device Handle: 0x000F
> > Memory Array Mapped Address Handle: 0x0016
> > Partition Row Position: 1
> > Interleaved Data Depth: 1
> >
> > Handle 0x0019, DMI type 20, 19 bytes
> > Memory Device Mapped Address
> >
> > Starting Address: 0x00400000000
> > Ending Address: 0x005FFFFFFFF
> > Range Size: 8 GB
> > Physical Device Handle: 0x0010
> > Memory Array Mapped Address Handle: 0x0016
> > Partition Row Position: 1
> > Interleaved Data Depth: 1
> >
> > Handle 0x001A, DMI type 20, 19 bytes
> > Memory Device Mapped Address
> >
> > Starting Address: 0x00600000000
> > Ending Address: 0x007FFFFFFFF
> > Range Size: 8 GB
> > Physical Device Handle: 0x0011
> > Memory Array Mapped Address Handle: 0x0016
> > Partition Row Position: 1
> > Interleaved Data Depth: 1
> >
> > Handle 0x001B, DMI type 20, 19 bytes
> > Memory Device Mapped Address
> >
> > Starting Address: 0x00800000000
> > Ending Address: 0x009FFFFFFFF
> > Range Size: 8 GB
> > Physical Device Handle: 0x0012
> > Memory Array Mapped Address Handle: 0x0016
> > Partition Row Position: 1
> > Interleaved Data Depth: 1
> >
> > Handle 0x001C, DMI type 20, 19 bytes
> > Memory Device Mapped Address
> >
> > Starting Address: 0x00A00000000
> > Ending Address: 0x00BFFFFFFFF
> > Range Size: 8 GB
> > Physical Device Handle: 0x0013
> > Memory Array Mapped Address Handle: 0x0016
> > Partition Row Position: 1
> > Interleaved Data Depth: 1
> >
> > Handle 0x001D, DMI type 20, 19 bytes
> > Memory Device Mapped Address
> >
> > Starting Address: 0x00BFFFFFC00
> > Ending Address: 0x00BFFFFFFFF
> > Range Size: 1 kB
> > Physical Device Handle: 0x0014
> > Memory Array Mapped Address Handle: 0x0016
> > Partition Row Position: 1
> > Interleaved Data Depth: 1
> >
> > Handle 0x001E, DMI type 20, 19 bytes
> > Memory Device Mapped Address
> >
> > Starting Address: 0x00BFFFFFC00
> > Ending Address: 0x00BFFFFFFFF
> > Range Size: 1 kB
> > Physical Device Handle: 0x0015
> > Memory Array Mapped Address Handle: 0x0016
> > Partition Row Position: 1
> > Interleaved Data Depth: 1
> >
> > Handle 0x001F, DMI type 32, 20 bytes
> > System Boot Information
> >
> > Status: <OUT OF SPEC>
> >
> > Handle 0x0020, DMI type 38, 18 bytes
> > IPMI Device Information
> >
> > Interface Type: KCS (Keyboard Control Style)
> > Specification Version: 2.0
> > I2C Slave Address: 0x10
> > NV Storage Device: Not Present
> > Base Address: 0x0000000000000CA8 (I/O)
> > Register Spacing: 32-bit Boundaries
> > Interrupt Polarity: Active Low
> > Interrupt Trigger Mode: Edge
> >
> > Handle 0x0021, DMI type 127, 4 bytes
> > End Of Table
--
Arkadiusz Miśkiewicz PLD/Linux Team
arekm / maven.pl http://ftp.pld-linux.org/
^ permalink raw reply
* [PATCH net-next 0/4] be2net fixes
From: Sathya Perla @ 2011-11-11 5:17 UTC (permalink / raw)
To: netdev
Pls apply. Thanks.
Sathya Perla (4):
be2net: init (vf)_if_handle/vf_pmac_id to handle failure scenarios
be2net: stop checking the UE registers after an EEH error
be2net: don't log more than one error on detecting EEH/UE errors
be2net: stop issuing FW cmds if any cmd times out
drivers/net/ethernet/emulex/benet/be.h | 16 ++++---
drivers/net/ethernet/emulex/benet/be_cmds.c | 49 +++++++-------------
drivers/net/ethernet/emulex/benet/be_cmds.h | 4 +-
drivers/net/ethernet/emulex/benet/be_main.c | 66 ++++++++++++++++-----------
4 files changed, 69 insertions(+), 66 deletions(-)
--
1.7.4
^ permalink raw reply
* [PATCH net-next 1/4] be2net: init (vf)_if_handle/vf_pmac_id to handle failure scenarios
From: Sathya Perla @ 2011-11-11 5:17 UTC (permalink / raw)
To: netdev
In-Reply-To: <1320988680-7842-1-git-send-email-sathya.perla@emulex.com>
Initialize if_handle, vf_if_handle and vf_pmac_id with "-1" so that in
failure cases when be_clear() is called, we can skip over
if_destroy/pmac_del cmds if they have not been created.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 8 +--
drivers/net/ethernet/emulex/benet/be_cmds.c | 9 +++-
drivers/net/ethernet/emulex/benet/be_cmds.h | 4 +-
drivers/net/ethernet/emulex/benet/be_main.c | 55 +++++++++++++++------------
4 files changed, 42 insertions(+), 34 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 644e8fe..4163980 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -289,14 +289,12 @@ struct be_drv_stats {
struct be_vf_cfg {
unsigned char vf_mac_addr[ETH_ALEN];
- u32 vf_if_handle;
- u32 vf_pmac_id;
+ int vf_if_handle;
+ int vf_pmac_id;
u16 vf_vlan_tag;
u32 vf_tx_rate;
};
-#define BE_INVALID_PMAC_ID 0xffffffff
-
struct be_adapter {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -347,7 +345,7 @@ struct be_adapter {
/* Ethtool knobs and info */
char fw_ver[FW_VER_LEN];
- u32 if_handle; /* Used to configure filtering */
+ int if_handle; /* Used to configure filtering */
u32 pmac_id; /* MAC addr handle used by BE card */
u32 beacon_state; /* for set_phys_id */
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 2c7b366..c5912c4 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -695,12 +695,15 @@ err:
}
/* Uses synchronous MCCQ */
-int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id, u32 dom)
+int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_pmac_del *req;
int status;
+ if (pmac_id == -1)
+ return 0;
+
spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter);
@@ -1136,7 +1139,7 @@ err:
}
/* Uses MCCQ */
-int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain)
+int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_if_destroy *req;
@@ -1145,7 +1148,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id, u32 domain)
if (adapter->eeh_err)
return -EIO;
- if (!interface_id)
+ if (interface_id == -1)
return 0;
spin_lock_bh(&adapter->mcc_lock);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index a35cd03..0818039 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1417,11 +1417,11 @@ extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
u32 if_id, u32 *pmac_id, u32 domain);
extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id,
- u32 pmac_id, u32 domain);
+ int pmac_id, u32 domain);
extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
u32 en_flags, u8 *mac, u32 *if_handle, u32 *pmac_id,
u32 domain);
-extern int be_cmd_if_destroy(struct be_adapter *adapter, u32 if_handle,
+extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle,
u32 domain);
extern int be_cmd_eq_create(struct be_adapter *adapter,
struct be_queue_info *eq, int eq_delay);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index bf266a0..83d971d 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -848,15 +848,11 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
if (!is_valid_ether_addr(mac) || (vf >= num_vfs))
return -EINVAL;
- if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
- status = be_cmd_pmac_del(adapter,
- adapter->vf_cfg[vf].vf_if_handle,
- adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
+ status = be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle,
+ adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
- status = be_cmd_pmac_add(adapter, mac,
- adapter->vf_cfg[vf].vf_if_handle,
+ status = be_cmd_pmac_add(adapter, mac, adapter->vf_cfg[vf].vf_if_handle,
&adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
-
if (status)
dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
mac, vf);
@@ -2488,17 +2484,13 @@ static void be_vf_clear(struct be_adapter *adapter)
{
u32 vf;
- for (vf = 0; vf < num_vfs; vf++) {
- if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
- be_cmd_pmac_del(adapter,
- adapter->vf_cfg[vf].vf_if_handle,
- adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
- }
+ for (vf = 0; vf < num_vfs; vf++)
+ be_cmd_pmac_del(adapter, adapter->vf_cfg[vf].vf_if_handle,
+ adapter->vf_cfg[vf].vf_pmac_id, vf + 1);
for (vf = 0; vf < num_vfs; vf++)
- if (adapter->vf_cfg[vf].vf_if_handle)
- be_cmd_if_destroy(adapter,
- adapter->vf_cfg[vf].vf_if_handle, vf + 1);
+ be_cmd_if_destroy(adapter, adapter->vf_cfg[vf].vf_if_handle,
+ vf + 1);
}
static int be_clear(struct be_adapter *adapter)
@@ -2511,22 +2503,30 @@ static int be_clear(struct be_adapter *adapter)
be_mcc_queues_destroy(adapter);
be_rx_queues_destroy(adapter);
be_tx_queues_destroy(adapter);
- adapter->eq_next_idx = 0;
-
- adapter->be3_native = false;
- adapter->promiscuous = false;
/* tell fw we're done with firing cmds */
be_cmd_fw_clean(adapter);
return 0;
}
+static void be_vf_setup_init(struct be_adapter *adapter)
+{
+ int vf;
+
+ for (vf = 0; vf < num_vfs; vf++) {
+ adapter->vf_cfg[vf].vf_if_handle = -1;
+ adapter->vf_cfg[vf].vf_pmac_id = -1;
+ }
+}
+
static int be_vf_setup(struct be_adapter *adapter)
{
u32 cap_flags, en_flags, vf;
u16 lnk_speed;
int status;
+ be_vf_setup_init(adapter);
+
cap_flags = en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST;
for (vf = 0; vf < num_vfs; vf++) {
status = be_cmd_if_create(adapter, cap_flags, en_flags, NULL,
@@ -2534,7 +2534,6 @@ static int be_vf_setup(struct be_adapter *adapter)
NULL, vf+1);
if (status)
goto err;
- adapter->vf_cfg[vf].vf_pmac_id = BE_INVALID_PMAC_ID;
}
if (!lancer_chip(adapter)) {
@@ -2555,6 +2554,16 @@ err:
return status;
}
+static void be_setup_init(struct be_adapter *adapter)
+{
+ adapter->vlan_prio_bmap = 0xff;
+ adapter->link_speed = -1;
+ adapter->if_handle = -1;
+ adapter->be3_native = false;
+ adapter->promiscuous = false;
+ adapter->eq_next_idx = 0;
+}
+
static int be_setup(struct be_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
@@ -2563,9 +2572,7 @@ static int be_setup(struct be_adapter *adapter)
int status;
u8 mac[ETH_ALEN];
- /* Allow all priorities by default. A GRP5 evt may modify this */
- adapter->vlan_prio_bmap = 0xff;
- adapter->link_speed = -1;
+ be_setup_init(adapter);
be_cmd_req_native_mode(adapter);
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 2/4] be2net: stop checking the UE registers after an EEH error
From: Sathya Perla @ 2011-11-11 5:17 UTC (permalink / raw)
To: netdev
In-Reply-To: <1320988680-7842-1-git-send-email-sathya.perla@emulex.com>
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 83d971d..99da07f 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1978,6 +1978,9 @@ void be_detect_dump_ue(struct be_adapter *adapter)
u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
u32 i;
+ if (adapter->eeh_err || adapter->ue_detected)
+ return;
+
if (lancer_chip(adapter)) {
sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
@@ -2039,8 +2042,7 @@ static void be_worker(struct work_struct *work)
struct be_rx_obj *rxo;
int i;
- if (!adapter->ue_detected)
- be_detect_dump_ue(adapter);
+ be_detect_dump_ue(adapter);
/* when interrupts are not yet enabled, just reap any pending
* mcc completions */
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 3/4] be2net: don't log more than one error on detecting EEH/UE errors
From: Sathya Perla @ 2011-11-11 5:17 UTC (permalink / raw)
To: netdev
In-Reply-To: <1320988680-7842-1-git-send-email-sathya.perla@emulex.com>
Currently we're spamming error messages each time a FW cmd call is made
while in EEH/UE error state. One log msg on error detection is enough.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_cmds.c | 15 +++------------
drivers/net/ethernet/emulex/benet/be_main.c | 3 ++-
2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index c5912c4..94cd77c 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -31,11 +31,8 @@ static void be_mcc_notify(struct be_adapter *adapter)
struct be_queue_info *mccq = &adapter->mcc_obj.q;
u32 val = 0;
- if (adapter->eeh_err) {
- dev_info(&adapter->pdev->dev,
- "Error in Card Detected! Cannot issue commands\n");
+ if (adapter->eeh_err)
return;
- }
val |= mccq->id & DB_MCCQ_RING_ID_MASK;
val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
@@ -298,19 +295,13 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
int msecs = 0;
u32 ready;
- if (adapter->eeh_err) {
- dev_err(&adapter->pdev->dev,
- "Error detected in card.Cannot issue commands\n");
+ if (adapter->eeh_err)
return -EIO;
- }
do {
ready = ioread32(db);
- if (ready == 0xffffffff) {
- dev_err(&adapter->pdev->dev,
- "pci slot disconnected\n");
+ if (ready == 0xffffffff)
return -1;
- }
ready &= MPU_MAILBOX_DB_RDY_MASK;
if (ready)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 99da07f..0e97b6d 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2007,7 +2007,8 @@ void be_detect_dump_ue(struct be_adapter *adapter)
sliport_status & SLIPORT_STATUS_ERR_MASK) {
adapter->ue_detected = true;
adapter->eeh_err = true;
- dev_err(&adapter->pdev->dev, "UE Detected!!\n");
+ dev_err(&adapter->pdev->dev,
+ "Unrecoverable error in the card\n");
}
if (ue_lo) {
--
1.7.4
^ permalink raw reply related
* [PATCH net-next 4/4] be2net: stop issuing FW cmds if any cmd times out
From: Sathya Perla @ 2011-11-11 5:18 UTC (permalink / raw)
To: netdev
In-Reply-To: <1320988680-7842-1-git-send-email-sathya.perla@emulex.com>
A FW cmd timeout (with a sufficiently large timeout value in the
order of tens of seconds) indicates an unresponsive FW. In this state
issuing further cmds and waiting for a completion will only stall the process.
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
---
drivers/net/ethernet/emulex/benet/be.h | 8 ++++++-
drivers/net/ethernet/emulex/benet/be_cmds.c | 29 ++++++++++----------------
drivers/net/ethernet/emulex/benet/be_main.c | 2 +
3 files changed, 20 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 4163980..34f162d 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -350,6 +350,8 @@ struct be_adapter {
u32 beacon_state; /* for set_phys_id */
bool eeh_err;
+ bool ue_detected;
+ bool fw_timeout;
u32 port_num;
bool promiscuous;
bool wol;
@@ -357,7 +359,6 @@ struct be_adapter {
u32 function_caps;
u32 rx_fc; /* Rx flow control */
u32 tx_fc; /* Tx flow control */
- bool ue_detected;
bool stats_cmd_sent;
int link_speed;
u8 port_type;
@@ -522,6 +523,11 @@ static inline bool be_multi_rxq(const struct be_adapter *adapter)
return adapter->num_rx_qs > 1;
}
+static inline bool be_error(struct be_adapter *adapter)
+{
+ return adapter->eeh_err || adapter->ue_detected || adapter->fw_timeout;
+}
+
extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
extern void be_link_status_update(struct be_adapter *adapter, u32 link_status);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 94cd77c..ad3eef0 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -31,7 +31,7 @@ static void be_mcc_notify(struct be_adapter *adapter)
struct be_queue_info *mccq = &adapter->mcc_obj.q;
u32 val = 0;
- if (adapter->eeh_err)
+ if (be_error(adapter))
return;
val |= mccq->id & DB_MCCQ_RING_ID_MASK;
@@ -263,10 +263,10 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
int i, num, status = 0;
struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
- if (adapter->eeh_err)
- return -EIO;
-
for (i = 0; i < mcc_timeout; i++) {
+ if (be_error(adapter))
+ return -EIO;
+
num = be_process_mcc(adapter, &status);
if (num)
be_cq_notify(adapter, mcc_obj->cq.id,
@@ -277,7 +277,8 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
udelay(100);
}
if (i == mcc_timeout) {
- dev_err(&adapter->pdev->dev, "mccq poll timed out\n");
+ dev_err(&adapter->pdev->dev, "FW not responding\n");
+ adapter->fw_timeout = true;
return -1;
}
return status;
@@ -295,10 +296,10 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
int msecs = 0;
u32 ready;
- if (adapter->eeh_err)
- return -EIO;
-
do {
+ if (be_error(adapter))
+ return -EIO;
+
ready = ioread32(db);
if (ready == 0xffffffff)
return -1;
@@ -308,7 +309,8 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
break;
if (msecs > 4000) {
- dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
+ dev_err(&adapter->pdev->dev, "FW not responding\n");
+ adapter->fw_timeout = true;
be_detect_dump_ue(adapter);
return -1;
}
@@ -546,9 +548,6 @@ int be_cmd_fw_clean(struct be_adapter *adapter)
u8 *wrb;
int status;
- if (adapter->eeh_err)
- return -EIO;
-
if (mutex_lock_interruptible(&adapter->mbox_lock))
return -1;
@@ -1012,9 +1011,6 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
u8 subsys = 0, opcode = 0;
int status;
- if (adapter->eeh_err)
- return -EIO;
-
if (mutex_lock_interruptible(&adapter->mbox_lock))
return -1;
@@ -1136,9 +1132,6 @@ int be_cmd_if_destroy(struct be_adapter *adapter, int interface_id, u32 domain)
struct be_cmd_req_if_destroy *req;
int status;
- if (adapter->eeh_err)
- return -EIO;
-
if (interface_id == -1)
return 0;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 0e97b6d..ce20d64 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3569,6 +3569,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
dev_info(&adapter->pdev->dev, "EEH reset\n");
adapter->eeh_err = false;
+ adapter->ue_detected = false;
+ adapter->fw_timeout = false;
status = pci_enable_device(pdev);
if (status)
--
1.7.4
^ permalink raw reply related
* Re: [PATCH V2 01/14] clk: add helper functions clk_prepare_enable and clk_disable_unprepare
From: Baruch Siach @ 2011-11-11 7:28 UTC (permalink / raw)
To: Richard Zhao
Cc: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial,
amit.kucheria, linux, kernel, eric.miao, ben-linux, cjb, alan
In-Reply-To: <1320973829-4388-2-git-send-email-richard.zhao@linaro.org>
Hi Richard,
On Fri, Nov 11, 2011 at 09:10:16AM +0800, Richard Zhao wrote:
> Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
> ---
> include/linux/clk.h | 19 +++++++++++++++++++
> 1 files changed, 19 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 7213b52..63985f7 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -107,6 +107,25 @@ static inline void clk_unprepare(struct clk *clk)
> }
> #endif
>
> +static inline int clk_prepare_enable(struct clk *clk)
> +{
> + int ret;
> +
> + ret = clk_prepare(clk);
> + if (!ret)
> + ret = clk_enable(clk);
> + if (ret)
Using 'else' here makes the code more readable IMO.
baruch
> + clk_unprepare(clk);
> +
> + return ret;
> +}
> +
> +static inline void clk_disable_unprepare(struct clk *clk)
> +{
> + clk_disable(clk);
> + clk_unprepare(clk);
> +}
> +
> /**
> * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
> * This is only valid once the clock source has been enabled.
> --
> 1.7.5.4
--
~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch@tkos.co.il - tel: +972.2.679.5364, http://www.tkos.co.il -
^ permalink raw reply
* RE: [PATCH] r8169: more driver shutdown WoL regression.
From: hayeswang @ 2011-11-11 8:37 UTC (permalink / raw)
To: 'Francois Romieu'
Cc: netdev, 'Stefan Becker', 'David Miller',
'Ben Hutchings'
In-Reply-To: <20111110104117.GA23906@electric-eye.fr.zoreil.com>
Francois Romieu [mailto:romieu@fr.zoreil.com]
[...]
>
> Hayes, should I consider similar cross-behaviors between
> RxConfig and WoL
> ConfigX bits with different configurations ?
>
> I.e., assuming Config5.UWF is active and Config3.MagicPacket
> is not, can
> RxConfig.AcceptMyPhys make a difference to the WoL function ?
>
Yes. The RxConfig influences if you could receive unicast, multicast, or
broadcast packets. If you don't enable the relative bits of RxConfig, the WOL
feature won't work no matter which WOL mode you set.
> > Further, it may be dangerous to enable both rx_enable
> (ChipCmd bit 3) and
> > RxConfig for 8168b for WOL, because the hw would try to
> write the rx buffer.
>
> Ok.
>
Best Regards,
Hayes
^ permalink raw reply
* Re: [PATCH V2 01/14] clk: add helper functions clk_prepare_enable and clk_disable_unprepare
From: Sascha Hauer @ 2011-11-11 8:49 UTC (permalink / raw)
To: Richard Zhao
Cc: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial,
linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao
In-Reply-To: <1320973829-4388-2-git-send-email-richard.zhao@linaro.org>
On Fri, Nov 11, 2011 at 09:10:16AM +0800, Richard Zhao wrote:
> Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
> ---
> include/linux/clk.h | 19 +++++++++++++++++++
> 1 files changed, 19 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 7213b52..63985f7 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> @@ -107,6 +107,25 @@ static inline void clk_unprepare(struct clk *clk)
> }
> #endif
>
> +static inline int clk_prepare_enable(struct clk *clk)
> +{
> + int ret;
> +
> + ret = clk_prepare(clk);
> + if (!ret)
> + ret = clk_enable(clk);
> + if (ret)
> + clk_unprepare(clk);
As Baruch already pointed out this is hard to read. Also it contains a
bug. When clk_prepare fails clk_unprepare is called afterwards.
Hint: Kernel guys are not afraid of having multiple return statements
in a function, instead they like it when something is handled early
without having to read the rest of the function.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH V2 01/14] clk: add helper functions clk_prepare_enable and clk_disable_unprepare
From: Richard Zhao @ 2011-11-11 9:05 UTC (permalink / raw)
To: Sascha Hauer
Cc: amit.kucheria, linux, kernel, netdev, linux-mmc, ben-linux,
eric.miao, linux-i2c, linux-serial, cjb, linux-arm-kernel, alan
In-Reply-To: <20111111084950.GH16886@pengutronix.de>
On Fri, Nov 11, 2011 at 09:49:50AM +0100, Sascha Hauer wrote:
> On Fri, Nov 11, 2011 at 09:10:16AM +0800, Richard Zhao wrote:
> > Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
> > ---
> > include/linux/clk.h | 19 +++++++++++++++++++
> > 1 files changed, 19 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/clk.h b/include/linux/clk.h
> > index 7213b52..63985f7 100644
> > --- a/include/linux/clk.h
> > +++ b/include/linux/clk.h
> > @@ -107,6 +107,25 @@ static inline void clk_unprepare(struct clk *clk)
> > }
> > #endif
> >
> > +static inline int clk_prepare_enable(struct clk *clk)
> > +{
> > + int ret;
> > +
> > + ret = clk_prepare(clk);
> > + if (!ret)
> > + ret = clk_enable(clk);
> > + if (ret)
> > + clk_unprepare(clk);
>
> As Baruch already pointed out this is hard to read. Also it contains a
> bug. When clk_prepare fails clk_unprepare is called afterwards.
>
> Hint: Kernel guys are not afraid of having multiple return statements
> in a function, instead they like it when something is handled early
> without having to read the rest of the function.
{
int ret;
ret = clk_prepare(clk);
if (ret)
return ret;
ret = clk_enable(clk);
if (ret)
clk_unprepare(clk);
return ret;
Like above code? Thanks for review.
Richard
>
> Sascha
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply
* Re: [PATCH V2 01/14] clk: add helper functions clk_prepare_enable and clk_disable_unprepare
From: Sascha Hauer @ 2011-11-11 9:15 UTC (permalink / raw)
To: Richard Zhao
Cc: amit.kucheria, linux, kernel, netdev, linux-mmc, ben-linux,
eric.miao, linux-i2c, linux-serial, cjb, linux-arm-kernel, alan
In-Reply-To: <20111111090546.GC14617@b20223-02.ap.freescale.net>
On Fri, Nov 11, 2011 at 05:05:47PM +0800, Richard Zhao wrote:
> On Fri, Nov 11, 2011 at 09:49:50AM +0100, Sascha Hauer wrote:
> > On Fri, Nov 11, 2011 at 09:10:16AM +0800, Richard Zhao wrote:
> > > Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
> > > ---
> > > include/linux/clk.h | 19 +++++++++++++++++++
> > > 1 files changed, 19 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/include/linux/clk.h b/include/linux/clk.h
> > > index 7213b52..63985f7 100644
> > > --- a/include/linux/clk.h
> > > +++ b/include/linux/clk.h
> > > @@ -107,6 +107,25 @@ static inline void clk_unprepare(struct clk *clk)
> > > }
> > > #endif
> > >
> > > +static inline int clk_prepare_enable(struct clk *clk)
> > > +{
> > > + int ret;
> > > +
> > > + ret = clk_prepare(clk);
> > > + if (!ret)
> > > + ret = clk_enable(clk);
> > > + if (ret)
> > > + clk_unprepare(clk);
> >
> > As Baruch already pointed out this is hard to read. Also it contains a
> > bug. When clk_prepare fails clk_unprepare is called afterwards.
> >
> > Hint: Kernel guys are not afraid of having multiple return statements
> > in a function, instead they like it when something is handled early
> > without having to read the rest of the function.
> {
> int ret;
>
> ret = clk_prepare(clk);
> if (ret)
> return ret;
> ret = clk_enable(clk);
> if (ret)
> clk_unprepare(clk);
> return ret;
Yes, looks good.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH V2 01/14] clk: add helper functions clk_prepare_enable and clk_disable_unprepare
From: Russell King - ARM Linux @ 2011-11-11 10:27 UTC (permalink / raw)
To: Sascha Hauer
Cc: Richard Zhao, amit.kucheria, kernel, netdev, linux-mmc, ben-linux,
eric.miao, linux-i2c, linux-serial, cjb, linux-arm-kernel, alan
In-Reply-To: <20111111091556.GI16886@pengutronix.de>
On Fri, Nov 11, 2011 at 10:15:56AM +0100, Sascha Hauer wrote:
> On Fri, Nov 11, 2011 at 05:05:47PM +0800, Richard Zhao wrote:
> > {
> > int ret;
> >
> > ret = clk_prepare(clk);
> > if (ret)
> > return ret;
> > ret = clk_enable(clk);
> > if (ret)
> > clk_unprepare(clk);
> > return ret;
>
> Yes, looks good.
While this looks like a nice easy solution for converting existing
drivers, I'd suggest thinking about this a little more...
I would suggest some thought is given to the placement of clk_enable()
and clk_disable() when adding clk_prepare(), especially if your existing
clk_enable() function can only be called from non-atomic contexts.
Obviously, the transition path needs to be along these lines:
1. add clk_prepare() to drivers
2. implement clk_prepare() and make clk_enable() callable from non-atomic
contexts
3. move clk_enable() in drivers to places it can be called from non-atomic
contexts to achieve greater power savings (maybe via the runtime pm)
and where a driver is shared between different sub-architectures which
have non-atomic clk_enable()s, (3) can only happen when all those sub-
architectures have been updated to step (2).
^ permalink raw reply
* [PATCH v3] Phonet: set the pipe handle using setsockopt
From: Hemant Vilas RAMDASI @ 2011-11-11 10:28 UTC (permalink / raw)
To: remi.denis-courmont; +Cc: netdev, Dinesh Kumar Sharma, Hemant Ramdasi
From: Dinesh Kumar Sharma <dinesh.sharma@stericsson.com>
This provides flexibility to set the pipe handle
using setsockopt and enable the same.
Signed-off-by: Hemant Ramdasi <hemant.ramdasi@stericsson.com>
Signed-off-by: Dinesh Kumar Sharma <dinesh.sharma@stericsson.com>
---
include/linux/phonet.h | 2 +
net/phonet/pep.c | 111 +++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 103 insertions(+), 10 deletions(-)
diff --git a/include/linux/phonet.h b/include/linux/phonet.h
index 6fb1384..491caec 100644
--- a/include/linux/phonet.h
+++ b/include/linux/phonet.h
@@ -37,6 +37,8 @@
#define PNPIPE_ENCAP 1
#define PNPIPE_IFINDEX 2
#define PNPIPE_HANDLE 3
+#define PNPIPE_ENABLE 4
+#define PNPIPE_INITSTATE 5
#define PNADDR_ANY 0
#define PNADDR_BROADCAST 0xFC
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index f17fd84..33230c5 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -167,6 +167,12 @@ static int pipe_handler_send_created_ind(struct sock *sk)
data, 4, GFP_ATOMIC);
}
+static int pipe_handler_send_enabled_ind(struct sock *sk)
+{
+ return pep_indicate(sk, PNS_PIPE_ENABLED_IND, 0 /* sub-blocks */,
+ NULL, 0, GFP_ATOMIC);
+}
+
static int pep_accept_conn(struct sock *sk, struct sk_buff *skb)
{
static const u8 data[20] = {
@@ -533,6 +539,27 @@ static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb)
return pipe_handler_send_created_ind(sk);
}
+static int pep_enableresp_rcv(struct sock *sk, struct sk_buff *skb)
+{
+ struct pnpipehdr *hdr = pnp_hdr(skb);
+
+ if (hdr->error_code != PN_PIPE_NO_ERROR)
+ return -ECONNREFUSED;
+
+ return pipe_handler_send_enabled_ind(sk);
+}
+
+static void pipe_start_flow_control(struct sock *sk)
+{
+ struct pep_sock *pn = pep_sk(sk);
+
+ if (!pn_flow_safe(pn->tx_fc)) {
+ atomic_set(&pn->tx_credits, 1);
+ sk->sk_write_space(sk);
+ }
+ pipe_grant_credits(sk, GFP_ATOMIC);
+}
+
/* Queue an skb to an actively connected sock.
* Socket lock must be held. */
static int pipe_handler_do_rcv(struct sock *sk, struct sk_buff *skb)
@@ -578,13 +605,25 @@ static int pipe_handler_do_rcv(struct sock *sk, struct sk_buff *skb)
sk->sk_state = TCP_CLOSE_WAIT;
break;
}
+ if (pn->init_enable == PN_PIPE_DISABLE)
+ sk->sk_state = TCP_SYN_RECV;
+ else {
+ sk->sk_state = TCP_ESTABLISHED;
+ pipe_start_flow_control(sk);
+ }
+ break;
- sk->sk_state = TCP_ESTABLISHED;
- if (!pn_flow_safe(pn->tx_fc)) {
- atomic_set(&pn->tx_credits, 1);
- sk->sk_write_space(sk);
+ case PNS_PEP_ENABLE_RESP:
+ if (sk->sk_state != TCP_SYN_SENT)
+ break;
+
+ if (pep_enableresp_rcv(sk, skb)) {
+ sk->sk_state = TCP_CLOSE_WAIT;
+ break;
}
- pipe_grant_credits(sk, GFP_ATOMIC);
+
+ sk->sk_state = TCP_ESTABLISHED;
+ pipe_start_flow_control(sk);
break;
case PNS_PEP_DISCONNECT_RESP:
@@ -863,14 +902,31 @@ static int pep_sock_connect(struct sock *sk, struct sockaddr *addr, int len)
int err;
u8 data[4] = { 0 /* sub-blocks */, PAD, PAD, PAD };
- pn->pipe_handle = 1; /* anything but INVALID_HANDLE */
+ if (pn->pipe_handle == PN_PIPE_INVALID_HANDLE)
+ pn->pipe_handle = 1; /* anything but INVALID_HANDLE */
+
err = pipe_handler_request(sk, PNS_PEP_CONNECT_REQ,
- PN_PIPE_ENABLE, data, 4);
- if (err) {
- pn->pipe_handle = PN_PIPE_INVALID_HANDLE;
+ pn->init_enable, data, 4);
+ if (err)
return err;
- }
+
sk->sk_state = TCP_SYN_SENT;
+
+ return 0;
+}
+
+static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len)
+{
+ int err;
+
+ err = pipe_handler_request(sk, PNS_PEP_ENABLE_REQ, PAD,
+ NULL, 0);
+
+ if (err)
+ return err;
+
+ sk->sk_state = TCP_SYN_SENT;
+
return 0;
}
@@ -959,6 +1015,30 @@ static int pep_setsockopt(struct sock *sk, int level, int optname,
}
goto out_norel;
+ case PNPIPE_HANDLE:
+ if ((sk->sk_state == TCP_CLOSE) &&
+ (val >= 0) && (val < PN_PIPE_INVALID_HANDLE))
+ pn->pipe_handle = val;
+ else
+ err = -EINVAL;
+ break;
+
+ case PNPIPE_ENABLE:
+ if (sk->sk_state == TCP_SYN_SENT)
+ err = -EBUSY;
+ else if (sk->sk_state == TCP_ESTABLISHED)
+ err = -EISCONN;
+ else
+ err = pep_sock_enable(sk, NULL, 0);
+ break;
+
+ case PNPIPE_INITSTATE:
+ if ((val == 0) || (val == 1))
+ pn->init_enable = val;
+ else
+ err = -EINVAL;
+ break;
+
default:
err = -ENOPROTOOPT;
}
@@ -994,6 +1074,17 @@ static int pep_getsockopt(struct sock *sk, int level, int optname,
return -EINVAL;
break;
+ case PNPIPE_ENABLE:
+ if (sk->sk_state == TCP_ESTABLISHED)
+ val = 1;
+ else
+ val = 0;
+ break;
+
+ case PNPIPE_INITSTATE:
+ val = pn->init_enable;
+ break;
+
default:
return -ENOPROTOOPT;
}
--
1.7.4.3
^ permalink raw reply related
* RE: [PATCH v2] Phonet: set the pipe handle using setsockopt
From: Hemant-vilas RAMDASI @ 2011-11-11 10:31 UTC (permalink / raw)
To: Rémi Denis-Courmont
Cc: remi.denis-courmont@nokia.com, netdev@vger.kernel.org,
Dinesh Kumar SHARMA (STE)
In-Reply-To: <97b602ea42b0467fa4e9f63a909f9080@chewa.net>
Remi,
We corrected errors in v3.
> -----Original Message-----
> From: Rémi Denis-Courmont [mailto:remi@remlab.net]
> Sent: Thursday, November 10, 2011 4:07 PM
> To: Hemant-vilas RAMDASI
> Cc: remi.denis-courmont@nokia.com; netdev@vger.kernel.org; Dinesh Kumar
> SHARMA (STE)
> Subject: Re: [PATCH v2] Phonet: set the pipe handle using setsockopt
>
> This still does not follow the setter/getter level-trigger semantics of
> (s|g)etsockopt().
We are still not sure about your concern. Can you suggest another way to do this?
Regards,
Hemant
^ permalink raw reply
* Re: [PATCH v3] Phonet: set the pipe handle using setsockopt
From: Rémi Denis-Courmont @ 2011-11-11 10:47 UTC (permalink / raw)
To: netdev
In-Reply-To: <1321007302-7269-1-git-send-email-hemant.ramdasi@stericsson.com>
Le Vendredi 11 Novembre 2011 15:58:22 ext Hemant Vilas RAMDASI a écrit :
> From: Dinesh Kumar Sharma <dinesh.sharma@stericsson.com>
>
> This provides flexibility to set the pipe handle
> using setsockopt and enable the same.
>
> Signed-off-by: Hemant Ramdasi <hemant.ramdasi@stericsson.com>
> Signed-off-by: Dinesh Kumar Sharma <dinesh.sharma@stericsson.com>
> ---
> include/linux/phonet.h | 2 +
> net/phonet/pep.c | 111
> +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 103
> insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/phonet.h b/include/linux/phonet.h
> index 6fb1384..491caec 100644
> --- a/include/linux/phonet.h
> +++ b/include/linux/phonet.h
> @@ -37,6 +37,8 @@
> #define PNPIPE_ENCAP 1
> #define PNPIPE_IFINDEX 2
> #define PNPIPE_HANDLE 3
> +#define PNPIPE_ENABLE 4
> +#define PNPIPE_INITSTATE 5
>
> #define PNADDR_ANY 0
> #define PNADDR_BROADCAST 0xFC
> diff --git a/net/phonet/pep.c b/net/phonet/pep.c
> index f17fd84..33230c5 100644
> --- a/net/phonet/pep.c
> +++ b/net/phonet/pep.c
> @@ -167,6 +167,12 @@ static int pipe_handler_send_created_ind(struct sock
> *sk) data, 4, GFP_ATOMIC);
> }
>
> +static int pipe_handler_send_enabled_ind(struct sock *sk)
> +{
> + return pep_indicate(sk, PNS_PIPE_ENABLED_IND, 0 /* sub-blocks */,
> + NULL, 0, GFP_ATOMIC);
> +}
This really could be inlined.
> +
> static int pep_accept_conn(struct sock *sk, struct sk_buff *skb)
> {
> static const u8 data[20] = {
> @@ -533,6 +539,27 @@ static int pep_connresp_rcv(struct sock *sk, struct
> sk_buff *skb) return pipe_handler_send_created_ind(sk);
> }
>
> +static int pep_enableresp_rcv(struct sock *sk, struct sk_buff *skb)
> +{
> + struct pnpipehdr *hdr = pnp_hdr(skb);
> +
> + if (hdr->error_code != PN_PIPE_NO_ERROR)
> + return -ECONNREFUSED;
> +
> + return pipe_handler_send_enabled_ind(sk);
> +}
> +
> +static void pipe_start_flow_control(struct sock *sk)
> +{
> + struct pep_sock *pn = pep_sk(sk);
> +
> + if (!pn_flow_safe(pn->tx_fc)) {
> + atomic_set(&pn->tx_credits, 1);
> + sk->sk_write_space(sk);
> + }
> + pipe_grant_credits(sk, GFP_ATOMIC);
> +}
> +
> /* Queue an skb to an actively connected sock.
> * Socket lock must be held. */
> static int pipe_handler_do_rcv(struct sock *sk, struct sk_buff *skb)
> @@ -578,13 +605,25 @@ static int pipe_handler_do_rcv(struct sock *sk, struct
> sk_buff *skb) sk->sk_state = TCP_CLOSE_WAIT;
> break;
> }
> + if (pn->init_enable == PN_PIPE_DISABLE)
> + sk->sk_state = TCP_SYN_RECV;
> + else {
> + sk->sk_state = TCP_ESTABLISHED;
> + pipe_start_flow_control(sk);
> + }
> + break;
>
> - sk->sk_state = TCP_ESTABLISHED;
> - if (!pn_flow_safe(pn->tx_fc)) {
> - atomic_set(&pn->tx_credits, 1);
> - sk->sk_write_space(sk);
> + case PNS_PEP_ENABLE_RESP:
> + if (sk->sk_state != TCP_SYN_SENT)
> + break;
> +
> + if (pep_enableresp_rcv(sk, skb)) {
> + sk->sk_state = TCP_CLOSE_WAIT;
> + break;
> }
> - pipe_grant_credits(sk, GFP_ATOMIC);
> +
> + sk->sk_state = TCP_ESTABLISHED;
> + pipe_start_flow_control(sk);
> break;
>
> case PNS_PEP_DISCONNECT_RESP:
> @@ -863,14 +902,31 @@ static int pep_sock_connect(struct sock *sk, struct
> sockaddr *addr, int len) int err;
> u8 data[4] = { 0 /* sub-blocks */, PAD, PAD, PAD };
>
> - pn->pipe_handle = 1; /* anything but INVALID_HANDLE */
> + if (pn->pipe_handle == PN_PIPE_INVALID_HANDLE)
> + pn->pipe_handle = 1; /* anything but INVALID_HANDLE */
> +
> err = pipe_handler_request(sk, PNS_PEP_CONNECT_REQ,
> - PN_PIPE_ENABLE, data, 4);
> - if (err) {
> - pn->pipe_handle = PN_PIPE_INVALID_HANDLE;
> + pn->init_enable, data, 4);
> + if (err)
> return err;
> - }
> +
> sk->sk_state = TCP_SYN_SENT;
> +
> + return 0;
> +}
> +
> +static int pep_sock_enable(struct sock *sk, struct sockaddr *addr, int len)
> +{
> + int err;
> +
> + err = pipe_handler_request(sk, PNS_PEP_ENABLE_REQ, PAD,
> + NULL, 0);
> +
> + if (err)
> + return err;
> +
> + sk->sk_state = TCP_SYN_SENT;
> +
> return 0;
> }
>
> @@ -959,6 +1015,30 @@ static int pep_setsockopt(struct sock *sk, int level,
> int optname, }
> goto out_norel;
>
> + case PNPIPE_HANDLE:
> + if ((sk->sk_state == TCP_CLOSE) &&
> + (val >= 0) && (val < PN_PIPE_INVALID_HANDLE))
> + pn->pipe_handle = val;
> + else
> + err = -EINVAL;
> + break;
> +
> + case PNPIPE_ENABLE:
> + if (sk->sk_state == TCP_SYN_SENT)
> + err = -EBUSY;
> + else if (sk->sk_state == TCP_ESTABLISHED)
> + err = -EISCONN;
> + else
> + err = pep_sock_enable(sk, NULL, 0);
> + break;
For the umpteenth time, this does not obey set/get conventions.
> +
> + case PNPIPE_INITSTATE:
> + if ((val == 0) || (val == 1))
> + pn->init_enable = val;
> + else
> + err = -EINVAL;
I think kernel style is more akin to:
pn->init_enable = !!val;
^ permalink raw reply
* Re: [PATCH v2] Phonet: set the pipe handle using setsockopt
From: Rémi Denis-Courmont @ 2011-11-11 10:48 UTC (permalink / raw)
To: netdev@vger.kernel.org
In-Reply-To: <81C3A93C17462B4BBD7E272753C105791FB090A941@EXDCVYMBSTM005.EQ1STM.local>
Le Vendredi 11 Novembre 2011 11:31:51 ext Hemant-vilas RAMDASI a écrit :
> > -----Original Message-----
> > From: Rémi Denis-Courmont [mailto:remi@remlab.net]
> > Sent: Thursday, November 10, 2011 4:07 PM
> > To: Hemant-vilas RAMDASI
> > Cc: remi.denis-courmont@nokia.com; netdev@vger.kernel.org; Dinesh Kumar
> > SHARMA (STE)
> > Subject: Re: [PATCH v2] Phonet: set the pipe handle using setsockopt
> >
> > This still does not follow the setter/getter level-trigger semantics of
> > (s|g)etsockopt().
>
>
> We are still not sure about your concern. Can you suggest another way to do'
> this?
Like every body else, I have my own work and life to attend to.
I cannot fix other people's problems.
--
Rémi Denis-Courmont
http://www.remlab.net/
^ permalink raw reply
* [PATCH V3 01/14] clk: add helper functions clk_prepare_enable and clk_disable_unprepare
From: Richard Zhao @ 2011-11-11 10:50 UTC (permalink / raw)
To: linux-arm-kernel, linux-i2c, linux-mmc, netdev, linux-serial
Cc: linux, amit.kucheria, kernel, ben-linux, cjb, alan, eric.miao,
Richard Zhao
In-Reply-To: <1321008637-19999-1-git-send-email-richard.zhao@linaro.org>
Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
---
include/linux/clk.h | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7213b52..a7dc00d 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -107,6 +107,26 @@ static inline void clk_unprepare(struct clk *clk)
}
#endif
+static inline int clk_prepare_enable(struct clk *clk)
+{
+ int ret;
+
+ ret = clk_prepare(clk);
+ if (ret)
+ return ret;
+ ret = clk_enable(clk);
+ if (ret)
+ clk_unprepare(clk);
+
+ return ret;
+}
+
+static inline void clk_disable_unprepare(struct clk *clk)
+{
+ clk_disable(clk);
+ clk_unprepare(clk);
+}
+
/**
* clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
* This is only valid once the clock source has been enabled.
--
1.7.5.4
^ permalink raw reply related
* [PATCH V3 02/14] ARM: mxc: time: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 10:50 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
amit.kucheria-Z7WLFzj8eWMS+FvcfC7Uqw,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
cjb-2X9k7bc8m7Mdnm+yROfE0A, alan-VuQAYsv1563Yd54FQh9/CA,
eric.miao-QSEj5FYQhm4dnm+yROfE0A, Richard Zhao
In-Reply-To: <1321008637-19999-1-git-send-email-richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Richard Zhao <richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/plat-mxc/time.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 4b0fe28..b4e8b18 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -292,7 +292,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
{
uint32_t tctl_val;
- clk_enable(timer_clk);
+ clk_prepare_enable(timer_clk);
timer_base = base;
--
1.7.5.4
^ permalink raw reply related
* [PATCH V3 03/14] ARM: mxc: ahci: add clk_prepare/clk_unprepare
From: Richard Zhao @ 2011-11-11 10:50 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-i2c-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
Cc: linux-lFZ/pmaqli7XmaaqVzeoHQ,
amit.kucheria-Z7WLFzj8eWMS+FvcfC7Uqw,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, ben-linux-elnMNo+KYs3YtjvyW6yDsg,
cjb-2X9k7bc8m7Mdnm+yROfE0A, alan-VuQAYsv1563Yd54FQh9/CA,
eric.miao-QSEj5FYQhm4dnm+yROfE0A, Richard Zhao
In-Reply-To: <1321008637-19999-1-git-send-email-richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Richard Zhao <richard.zhao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
arch/arm/plat-mxc/devices/platform-ahci-imx.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
index d8a56ae..ade4a1c 100644
--- a/arch/arm/plat-mxc/devices/platform-ahci-imx.c
+++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
@@ -60,9 +60,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
dev_err(dev, "no sata clock.\n");
return PTR_ERR(sata_clk);
}
- ret = clk_enable(sata_clk);
+ ret = clk_prepare_enable(sata_clk);
if (ret) {
- dev_err(dev, "can't enable sata clock.\n");
+ dev_err(dev, "can't prepare/enable sata clock.\n");
goto put_sata_clk;
}
@@ -73,9 +73,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
ret = PTR_ERR(sata_ref_clk);
goto release_sata_clk;
}
- ret = clk_enable(sata_ref_clk);
+ ret = clk_prepare_enable(sata_ref_clk);
if (ret) {
- dev_err(dev, "can't enable sata ref clock.\n");
+ dev_err(dev, "can't prepare/enable sata ref clock.\n");
goto put_sata_ref_clk;
}
@@ -104,11 +104,11 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
return 0;
release_sata_ref_clk:
- clk_disable(sata_ref_clk);
+ clk_disable_unprepare(sata_ref_clk);
put_sata_ref_clk:
clk_put(sata_ref_clk);
release_sata_clk:
- clk_disable(sata_clk);
+ clk_disable_unprepare(sata_clk);
put_sata_clk:
clk_put(sata_clk);
@@ -117,10 +117,10 @@ put_sata_clk:
static void imx_sata_exit(struct device *dev)
{
- clk_disable(sata_ref_clk);
+ clk_disable_unprepare(sata_ref_clk);
clk_put(sata_ref_clk);
- clk_disable(sata_clk);
+ clk_disable_unprepare(sata_clk);
clk_put(sata_clk);
}
--
1.7.5.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox