* Re: bug fix patch lost: git problem or just incorrect merge?
From: David Miller @ 2010-05-21 22:07 UTC (permalink / raw)
To: torvalds; +Cc: James.Bottomley, linux-kernel, netdev, linux-scsi
In-Reply-To: <alpine.LFD.2.00.1005210931010.4243@i5.linux-foundation.org>
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Fri, 21 May 2010 09:45:49 -0700 (PDT)
> One of the reasons I ask people to let me merge is that it results in
> cleaner history to not have criss-cross merges. And another is that I'm
> pretty good at it, and letting me make merges also means that I am more
> aware of problem spots.
That wasn't possible in this case.
This happened more than a week ago, as I needed to merge your tree into
net-2.6 to resolve a conflict there. That's what took in the iscsi
bug fix, and this is way before the merge window.
Then I needed to pull net-2.6 into net-next-2.6 to resolve conflicts
existing between those two trees.
And this is why I ended up having to do the merge :-)
>> Either way, of course, we need the patch back ...
>
> I'll fix it up.
Thanks Linus.
^ permalink raw reply
* Re: bug fix patch lost: git problem or just incorrect merge?
From: David Miller @ 2010-05-21 22:02 UTC (permalink / raw)
To: James.Bottomley; +Cc: torvalds, linux-kernel, netdev, linux-scsi
In-Reply-To: <1274456515.9022.14.camel@mulgrave.site>
From: James Bottomley <James.Bottomley@suse.de>
Date: Fri, 21 May 2010 10:41:55 -0500
> Is this a git problem ... or is it just a mismerge in the net tree?
Mismerge, because sk->sk_sleep() doesn't exist any more I mistakenly
updated the original line to do the sk_sleep() stuff.
Sorry about that.
^ permalink raw reply
* [PATCH] net-caif: drop redundant Kconfig entries
From: Mike Frysinger @ 2010-05-21 20:45 UTC (permalink / raw)
To: netdev, David S. Miller, Sjur Braendeland
There is already a submenu entry that is always displayed, so there is
no need to also show a dedicated CAIF comment.
Drop dead commented code while we're here, and change the submenu text
to better match the style everyone else is using.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
net/caif/Kconfig | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/net/caif/Kconfig b/net/caif/Kconfig
index cd1daf6..ed65178 100644
--- a/net/caif/Kconfig
+++ b/net/caif/Kconfig
@@ -2,10 +2,8 @@
# CAIF net configurations
#
-#menu "CAIF Support"
-comment "CAIF Support"
menuconfig CAIF
- tristate "Enable CAIF support"
+ tristate "CAIF support"
select CRC_CCITT
default n
---help---
@@ -45,4 +43,3 @@ config CAIF_NETDEV
If unsure say Y.
endif
-#endmenu
--
1.7.1
^ permalink raw reply related
* ixgbe: macvlan on PF/VF when SRIOV is enabled
From: Shirley Ma @ 2010-05-21 20:30 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: davem, kvm, netdev, e1000-devel
Hello Jeff,
macvlan doesn't work on PF when SRIOV is enabled. Creating macvlan has
been successful, but ping (icmp request) goes to VF interface not
PF/macvlan even arp entry is correct. I patched ixgbe driver, and
macvlan/PF has worked with the patch. But I am not sure whether it is
right since I don't have the HW spec. What I did for ixgbe driver was:
1. PF's rar index is 0, VMDQ index is adatper->num_vfs;
2. VF's rar is based on rar_used_count and mc_addr_in_rar_count, VMDQ
index is ;
3. PF's secondary addresses is PF's rar index + i, VMDQ index is
adapter->num_vfs.
Before I submit the patch, I want to understand the right index
assignment for both rar index and VMDQ index, when SRIOV enabled:
1. VMDQ index for PF is adapter->num_vfs, or 0? rar index is 0?
2. PF's secondary address rar index is based on
rar_used_count/mc_addr_in_rar_count?
2. VF's VPDQ index is based on vf number?
3. VF's rar index is vf + 1, or should be based on rar_used_count?
I am also working on macvlan on VF. The question here is whether macvlan
on VF should work or not? Looks like ixgbevf secondary addresses are not
in receiver address filter, so macvlan on VF doesn't work.
Thanks
Shirley
^ permalink raw reply
* [RFC PATCH] packet_mmap: expose hw packet timestamps to network packet capture utilities
From: Mcmillan, Scott A @ 2010-05-21 20:24 UTC (permalink / raw)
To: netdev@vger.kernel.org, davem@davemloft.net
Cc: tcpdump-workers@lists.tcpdump.org
This patch adds a setting, PACKET_TIMESTAMP, to specify the packet timestamp source that is exported to capture utilities like tcpdump by packet_mmap.
PACKET_TIMESTAMP accepts the same integer bit field as SO_TIMESTAMPING. However, only the SOF_TIMESTAMPING_SYS_HARDWARE
and SOF_TIMESTAMPING_RAW_HARDWARE values are currently recognized by PACKET_TIMESTAMP. SOF_TIMESTAMPING_SYS_HARDWARE takes precedence over SOF_TIMESTAMPING_RAW_HARDWARE if both bits are set.
If PACKET_TIMESTAMP is not set, a software timestamp generated inside the networking stack is used (the behavior before this setting was added).
I am concurrently submitting a patch to the tcpdump / libpcap maintainers adding support for this capability.
Thanks,
Scott
Signed-off-by: Scott McMillan <scott.a.mcmillan@intel.com>
--- a/include/linux/if_packet.h 2010-05-18 17:22:59.000000000 -0500
+++ b/include/linux/if_packet.h 2010-05-21 14:37:30.000000000 -0500
@@ -48,6 +48,7 @@
#define PACKET_LOSS 14
#define PACKET_VNET_HDR 15
#define PACKET_TX_TIMESTAMP 16
+#define PACKET_TIMESTAMP 17
struct tpacket_stats {
unsigned int tp_packets;
--- a/net/packet/af_packet.c 2010-05-18 17:21:48.000000000 -0500
+++ b/net/packet/af_packet.c 2010-05-21 14:48:41.000000000 -0500
@@ -83,6 +83,7 @@
#include <linux/if_vlan.h>
#include <linux/virtio_net.h>
#include <linux/errqueue.h>
+#include <linux/net_tstamp.h>
#ifdef CONFIG_INET
#include <net/inet_common.h>
@@ -202,6 +203,7 @@
unsigned int tp_hdrlen;
unsigned int tp_reserve;
unsigned int tp_loss:1;
+ unsigned int tp_tstamp;
struct packet_type prot_hook ____cacheline_aligned_in_smp;
};
@@ -656,6 +658,7 @@
struct sk_buff *copy_skb = NULL;
struct timeval tv;
struct timespec ts;
+ struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
if (skb->pkt_type == PACKET_LOOPBACK)
goto drop;
@@ -737,7 +740,13 @@
h.h1->tp_snaplen = snaplen;
h.h1->tp_mac = macoff;
h.h1->tp_net = netoff;
- if (skb->tstamp.tv64)
+ if ((po->tp_tstamp & SOF_TIMESTAMPING_SYS_HARDWARE)
+ && shhwtstamps->syststamp.tv64)
+ tv = ktime_to_timeval(shhwtstamps->syststamp);
+ else if ((po->tp_tstamp & SOF_TIMESTAMPING_RAW_HARDWARE)
+ && shhwtstamps->hwtstamp.tv64)
+ tv = ktime_to_timeval(shhwtstamps->hwtstamp);
+ else if (skb->tstamp.tv64)
tv = ktime_to_timeval(skb->tstamp);
else
do_gettimeofday(&tv);
@@ -750,7 +759,13 @@
h.h2->tp_snaplen = snaplen;
h.h2->tp_mac = macoff;
h.h2->tp_net = netoff;
- if (skb->tstamp.tv64)
+ if ((po->tp_tstamp & SOF_TIMESTAMPING_SYS_HARDWARE)
+ && shhwtstamps->syststamp.tv64)
+ ts = ktime_to_timespec(shhwtstamps->syststamp);
+ else if ((po->tp_tstamp & SOF_TIMESTAMPING_RAW_HARDWARE)
+ && shhwtstamps->hwtstamp.tv64)
+ ts = ktime_to_timespec(shhwtstamps->hwtstamp);
+ else if (skb->tstamp.tv64)
ts = ktime_to_timespec(skb->tstamp);
else
getnstimeofday(&ts);
@@ -2027,6 +2042,18 @@
po->has_vnet_hdr = !!val;
return 0;
}
+ case PACKET_TIMESTAMP:
+ {
+ int val;
+
+ if (optlen != sizeof(val))
+ return -EINVAL;
+ if (copy_from_user(&val, optval, sizeof(val)))
+ return -EFAULT;
+
+ po->tp_tstamp = val;
+ return 0;
+ }
default:
return -ENOPROTOOPT;
}
@@ -2119,6 +2146,12 @@
val = po->tp_loss;
data = &val;
break;
+ case PACKET_TIMESTAMP:
+ if (len > sizeof(int))
+ len = sizeof(int);
+ val = po->tp_tstamp;
+ data = &val;
+ break;
default:
return -ENOPROTOOPT;
}
--- a/Documentation/networking/packet_mmap.txt 2010-05-18 17:24:18.000000000 -0500
+++ b/Documentation/networking/packet_mmap.txt 2010-05-21 14:39:48.000000000 -0500
@@ -493,6 +493,32 @@
pfd.events = POLLOUT;
retval = poll(&pfd, 1, timeout);
+-------------------------------------------------------------------------------
++ PACKET_TIMESTAMP
+-------------------------------------------------------------------------------
+
+The PACKET_TIMESTAMP setting determines the source of the timestamp in
+the packet meta information. If your NIC is capable of timestamping
+packets in hardware, you can request those hardware timestamps to used.
+Note: you may need to enable the generation of hardware timestamps with
+SIOCSHWTSTAMP.
+
+PACKET_TIMESTAMP accepts the same integer bit field as
+SO_TIMESTAMPING. However, only the SOF_TIMESTAMPING_SYS_HARDWARE
+and SOF_TIMESTAMPING_RAW_HARDWARE values are recognized by
+PACKET_TIMESTAMP. SOF_TIMESTAMPING_SYS_HARDWARE takes precedence over
+SOF_TIMESTAMPING_RAW_HARDWARE if both bits are set.
+
+ int req = 0;
+ req |= SOF_TIMESTAMPING_SYS_HARDWARE;
+ setsockopt(fd, SOL_PACKET, PACKET_TIMESTAMP, (void *) &req, sizeof(req))
+
+If PACKET_TIMESTAMP is not set, a software timestamp generated inside
+the networking stack is used (the behavior before this setting was added).
+
+See include/linux/net_tstamp.h and Documentation/networking/timestamping
+for more information on hardware timestamps.
+
--------------------------------------------------------------------------------
+ THANKS
--------------------------------------------------------------------------------
^ permalink raw reply
* RE: [PATCH] net: add additional lock to qdisc to increase throughput
From: Duyck, Alexander H @ 2010-05-21 20:04 UTC (permalink / raw)
To: Eric Dumazet, David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <1274454480.2439.418.camel@edumazet-laptop>
Eric Dumazet wrote:
> Tests with following script gave a boost from ~50.000 pps to ~600.000
> pps on a dual quad core machine (E5450 @3.00GHz), tg3 driver.
> (A single netperf flow can reach ~800.000 pps on this platform)
>
> for j in `seq 0 3`; do
> for i in `seq 0 7`; do
> netperf -H 192.168.0.1 -t UDP_STREAM -l 60 -N -T $i -- -m 6 &
> done
> done
Running the same script with your patch my results went from 200Kpps to 1.2Mpps on a dual Xeon 5570.
Acked-by: Alexander Duyck <alexander.h.duyck@intel.com>
^ permalink raw reply
* RE: ixgbe and SRIOV failure in driver?
From: Rose, Gregory V @ 2010-05-21 19:18 UTC (permalink / raw)
To: Fischer, Anna, e1000-devel@lists.sourceforge.net,
netdev@vger.kernel.org
In-Reply-To: <0199E0D51A61344794750DC57738F58E70B08A2A20@GVW1118EXC.americas.hpqcorp.net>
>-----Original Message-----
>From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
>On Behalf Of Fischer, Anna
>Sent: Friday, May 21, 2010 9:33 AM
>To: e1000-devel@lists.sourceforge.net; netdev@vger.kernel.org
>Subject: ixgbe and SRIOV failure in driver?
>
>I am running a system with 3 Intel NICs. Two of them are 82598 devices,
>and one is a SRIOV capable 82599.
>
>All devices use the ixgbe driver. What happens (I believe) now is that
>when the driver loads at first, it sees the 82598 first (because of its
>position in the PCI tree) and then it says "Device not IOV capable -
>switching off IOV."
>
>So then it switches into non-IOV mode, and I can never enable SRIOV on
>my 82599, because the driver does not enable it any more for further
>devices.
>
>So to get around this issue, I tried to use pciback.hide to hide the
>82598 devices from the OS. That way I was hoping that the driver would
>switch on SRIOV on my 82599. However, then I got a kernel panic on boot
>(see below).
>
>I am running Xen 4 and the Dom0 kernel is a 2.6.31 kernel.
The ixgbe driver included with the 2.6.31 kernel does not support SR-IOV.
Where did you get the driver that does? Please run ethtool -i <ethx> and
post the results.
- Greg Rose
Intel Corp.
Lan Access Division
^ permalink raw reply
* Re: [PATCH v2 2/2] phylib: Convert MDIO bitbang to new MDIO 45 format
From: Ben Hutchings @ 2010-05-21 18:55 UTC (permalink / raw)
To: Andy Fleming; +Cc: davem, netdev
In-Reply-To: <1274466711-24962-3-git-send-email-afleming@freescale.com>
On Fri, 2010-05-21 at 13:31 -0500, Andy Fleming wrote:
> Now that we've added somewhat more complete MDIO 45 support to the PHY
> Lib, convert the MDIO bitbang driver to use this new infrastructure.
>
> Signed-off-by: Andy Fleming <afleming@freescale.com>
> ---
> drivers/net/phy/mdio-bitbang.c | 29 +++++++++++++++--------------
> 1 files changed, 15 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
> index 2f6f02e..be7ae74 100644
> --- a/drivers/net/phy/mdio-bitbang.c
> +++ b/drivers/net/phy/mdio-bitbang.c
[...]
> @@ -157,11 +154,13 @@ static int mdiobb_read(struct mii_bus *bus, int phy, int devad, int reg)
> struct mdiobb_ctrl *ctrl = bus->priv;
> int ret, i;
>
> - if (reg & MII_ADDR_C45) {
> - reg = mdiobb_cmd_addr(ctrl, phy, reg);
> - mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
> - } else
> + /* Clause 22 PHYs only use devad = 0, and Clause 45 only use nonzero */
> + if (devad == MDIO_DEVAD_NONE)
> mdiobb_cmd(ctrl, MDIO_READ, phy, reg);
> + else {
> + mdiobb_cmd_addr(ctrl, phy, devad, reg);
> + mdiobb_cmd(ctrl, MDIO_C45_READ, phy, devad);
> + }
[...]
This comment is now wrong.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH v2 1/2] phylib: Convert MDIO and PHY Lib drivers to support 10G
From: Ben Hutchings @ 2010-05-21 18:55 UTC (permalink / raw)
To: Andy Fleming; +Cc: davem, netdev
In-Reply-To: <1274466711-24962-2-git-send-email-afleming@freescale.com>
On Fri, 2010-05-21 at 13:31 -0500, Andy Fleming wrote:
[...]
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 1a99bb2..c72ba85 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
[...]
> @@ -873,6 +941,36 @@ static int genphy_config_init(struct phy_device *phydev)
>
> return 0;
> }
> +
> +/* Replicate mdio45_probe */
> +int gen10g_config_init(struct phy_device *phydev)
> +{
> + int mmd, stat2, devs1, devs2;
> +
> + phydev->supported = phydev->advertising = SUPPORTED_10000baseT_Full;
[...]
Whyever are you assuming that?
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index 987e111..8fb1b52 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
[...]
> @@ -62,7 +63,8 @@ typedef enum {
> PHY_INTERFACE_MODE_RGMII_ID,
> PHY_INTERFACE_MODE_RGMII_RXID,
> PHY_INTERFACE_MODE_RGMII_TXID,
> - PHY_INTERFACE_MODE_RTBI
> + PHY_INTERFACE_MODE_RTBI,
> + PHY_INTERFACE_MODE_XGMII
> } phy_interface_t;
[...]
What about XAUI and XFI? I don't think anyone uses XGMII other than as
an on-chip interface.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH v2 2/2] phylib: Convert MDIO bitbang to new MDIO 45 format
From: Andy Fleming @ 2010-05-21 18:31 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1274466711-24962-2-git-send-email-afleming@freescale.com>
Now that we've added somewhat more complete MDIO 45 support to the PHY
Lib, convert the MDIO bitbang driver to use this new infrastructure.
Signed-off-by: Andy Fleming <afleming@freescale.com>
---
drivers/net/phy/mdio-bitbang.c | 29 +++++++++++++++--------------
1 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 2f6f02e..be7ae74 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -134,11 +134,10 @@ static void mdiobb_cmd(struct mdiobb_ctrl *ctrl, int op, u8 phy, u8 reg)
MII_ADDR_C45 into the address. Theoretically clause 45 and normal devices
can exist on the same bus. Normal devices should ignore the MDIO_ADDR
phase. */
-static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr)
+static void mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, int devad,
+ int reg)
{
- unsigned int dev_addr = (addr >> 16) & 0x1F;
- unsigned int reg = addr & 0xFFFF;
- mdiobb_cmd(ctrl, MDIO_C45_ADDR, phy, dev_addr);
+ mdiobb_cmd(ctrl, MDIO_C45_ADDR, phy, devad);
/* send the turnaround (10) */
mdiobb_send_bit(ctrl, 1);
@@ -148,8 +147,6 @@ static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr)
ctrl->ops->set_mdio_dir(ctrl, 0);
mdiobb_get_bit(ctrl);
-
- return dev_addr;
}
static int mdiobb_read(struct mii_bus *bus, int phy, int devad, int reg)
@@ -157,11 +154,13 @@ static int mdiobb_read(struct mii_bus *bus, int phy, int devad, int reg)
struct mdiobb_ctrl *ctrl = bus->priv;
int ret, i;
- if (reg & MII_ADDR_C45) {
- reg = mdiobb_cmd_addr(ctrl, phy, reg);
- mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
- } else
+ /* Clause 22 PHYs only use devad = 0, and Clause 45 only use nonzero */
+ if (devad == MDIO_DEVAD_NONE)
mdiobb_cmd(ctrl, MDIO_READ, phy, reg);
+ else {
+ mdiobb_cmd_addr(ctrl, phy, devad, reg);
+ mdiobb_cmd(ctrl, MDIO_C45_READ, phy, devad);
+ }
ctrl->ops->set_mdio_dir(ctrl, 0);
@@ -186,11 +185,13 @@ static int mdiobb_write(struct mii_bus *bus, int phy, int devad, int reg,
{
struct mdiobb_ctrl *ctrl = bus->priv;
- if (reg & MII_ADDR_C45) {
- reg = mdiobb_cmd_addr(ctrl, phy, reg);
- mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
- } else
+ /* Clause 22 PHYs only use devad = 0, and Clause 45 only use nonzero */
+ if (devad == MDIO_DEVAD_NONE)
mdiobb_cmd(ctrl, MDIO_WRITE, phy, reg);
+ else {
+ mdiobb_cmd_addr(ctrl, phy, devad, reg);
+ mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, devad);
+ }
/* send the turnaround (10) */
mdiobb_send_bit(ctrl, 1);
--
1.6.5.2.g6ff9a
^ permalink raw reply related
* [PATCH v2 1/2] phylib: Convert MDIO and PHY Lib drivers to support 10G
From: Andy Fleming @ 2010-05-21 18:31 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <1274466711-24962-1-git-send-email-afleming@freescale.com>
10G MDIO is a totally different protocol (clause 45 of 802.3).
Supporting this new protocol requires a couple of changes:
* Add a new parameter to the mdiobus_read functions to specify the
"device address" inside the PHY.
* Add a phy45_read command which takes advantage of that new parameter
* Add a generic PHY driver for 10G PHYs
* Convert all of the existing drivers to use the new format
Signed-off-by: Andy Fleming <afleming@freescale.com>
---
Documentation/networking/phy.txt | 13 +-
arch/powerpc/platforms/pasemi/gpio_mdio.c | 6 +-
drivers/net/arm/ixp4xx_eth.c | 7 +-
drivers/net/au1000_eth.c | 7 +-
drivers/net/bcm63xx_enet.c | 4 +-
drivers/net/bfin_mac.c | 7 +-
drivers/net/cpmac.c | 4 +-
drivers/net/davinci_emac.c | 5 +-
drivers/net/dnet.c | 7 +-
drivers/net/ethoc.c | 5 +-
drivers/net/fec.c | 7 +-
drivers/net/fec_mpc52xx_phy.c | 7 +-
drivers/net/fs_enet/mii-fec.c | 6 +-
drivers/net/fsl_pq_mdio.c | 13 +-
drivers/net/fsl_pq_mdio.h | 11 +-
drivers/net/greth.c | 5 +-
drivers/net/ll_temac_mdio.c | 5 +-
drivers/net/macb.c | 7 +-
drivers/net/mv643xx_eth.c | 5 +-
drivers/net/phy/fixed.c | 5 +-
drivers/net/phy/icplus.c | 15 ++-
drivers/net/phy/mdio-bitbang.c | 5 +-
drivers/net/phy/mdio-octeon.c | 5 +-
drivers/net/phy/mdio_bus.c | 8 +-
drivers/net/phy/phy_device.c | 170 ++++++++++++++++++++++++++---
drivers/net/s6gmac.c | 5 +-
drivers/net/sb1250-mac.c | 14 ++-
drivers/net/smsc911x.c | 19 ++--
drivers/net/smsc9420.c | 9 +-
drivers/net/stmmac/stmmac_mdio.c | 9 +-
drivers/net/tc35815.c | 5 +-
drivers/net/tg3.c | 5 +-
drivers/net/xilinx_emaclite.c | 9 +-
include/linux/phy.h | 57 ++++++++--
34 files changed, 343 insertions(+), 128 deletions(-)
diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt
index 88bb71b..8729cac 100644
--- a/Documentation/networking/phy.txt
+++ b/Documentation/networking/phy.txt
@@ -40,13 +40,14 @@ The MDIO bus
1) read and write functions must be implemented. Their prototypes are:
- int write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
- int read(struct mii_bus *bus, int mii_id, int regnum);
-
- mii_id is the address on the bus for the PHY, and regnum is the register
- number. These functions are guaranteed not to be called from interrupt
- time, so it is safe for them to block, waiting for an interrupt to signal
- the operation is complete
+ int write(struct mii_bus *bus, int addr, int devad, u16 regnum,
+ u16 value);
+ int read(struct mii_bus *bus, int addr, int devad, u16 regnum);
+
+ addr is the address on the bus for the PHY, devad is the address of the
+ internal device, and regnum is the register number. These functions are
+ guaranteed not to be called from interrupt time, so it is safe for them
+ to block, waiting for an interrupt to signal the operation is complete
2) A reset function is necessary. This is used to return the bus to an
initialized state.
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index 0f881f6..ce9764c 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -124,7 +124,8 @@ static void bitbang_pre(struct mii_bus *bus, int read, u8 addr, u8 reg)
}
}
-static int gpio_mdio_read(struct mii_bus *bus, int phy_id, int location)
+static int gpio_mdio_read(struct mii_bus *bus, int phy_id, int devad,
+ int location)
{
u16 rdreg;
int ret, i;
@@ -163,7 +164,8 @@ static int gpio_mdio_read(struct mii_bus *bus, int phy_id, int location)
return ret;
}
-static int gpio_mdio_write(struct mii_bus *bus, int phy_id, int location, u16 val)
+static int gpio_mdio_write(struct mii_bus *bus, int phy_id, int devad,
+ int location, u16 val)
{
int i;
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index 24df032..51f1a72 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -298,7 +298,8 @@ static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location,
((__raw_readl(&mdio_regs->mdio_status[1]) & 0xFF) << 8);
}
-static int ixp4xx_mdio_read(struct mii_bus *bus, int phy_id, int location)
+static int ixp4xx_mdio_read(struct mii_bus *bus, int phy_id, int devad,
+ int location)
{
unsigned long flags;
int ret;
@@ -313,8 +314,8 @@ static int ixp4xx_mdio_read(struct mii_bus *bus, int phy_id, int location)
return ret;
}
-static int ixp4xx_mdio_write(struct mii_bus *bus, int phy_id, int location,
- u16 val)
+static int ixp4xx_mdio_write(struct mii_bus *bus, int phy_id, int devad,
+ int location, u16 val)
{
unsigned long flags;
int ret;
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index ece6128..d3cddb1 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -232,7 +232,8 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr,
*mii_control_reg = mii_control;
}
-static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
+static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int devad,
+ int regnum)
{
/* WARNING: bus->phy_map[phy_addr].attached_dev == dev does
* _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */
@@ -243,8 +244,8 @@ static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
return au1000_mdio_read(dev, phy_addr, regnum);
}
-static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
- u16 value)
+static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int devad,
+ int regnum, u16 value)
{
struct net_device *const dev = bus->priv;
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index faf5add..152afa3 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -139,7 +139,7 @@ static int bcm_enet_mdio_write(struct bcm_enet_priv *priv, int mii_id,
* MII read callback from phylib
*/
static int bcm_enet_mdio_read_phylib(struct mii_bus *bus, int mii_id,
- int regnum)
+ int devad, int regnum)
{
return bcm_enet_mdio_read(bus->priv, mii_id, regnum);
}
@@ -148,7 +148,7 @@ static int bcm_enet_mdio_read_phylib(struct mii_bus *bus, int mii_id,
* MII write callback from phylib
*/
static int bcm_enet_mdio_write_phylib(struct mii_bus *bus, int mii_id,
- int regnum, u16 value)
+ int devad, int regnum, u16 value)
{
return bcm_enet_mdio_write(bus->priv, mii_id, regnum, value);
}
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 39a54ba..15ff21e 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -275,7 +275,8 @@ static int bfin_mdio_poll(void)
}
/* Read an off-chip register in a PHY through the MDC/MDIO port */
-static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
+static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr,
+ int devad, int regnum)
{
int ret;
@@ -296,8 +297,8 @@ static int bfin_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum)
}
/* Write an off-chip register in a PHY through the MDC/MDIO port */
-static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum,
- u16 value)
+static int bfin_mdiobus_write(struct mii_bus *bus, int phy_addr, int devad,
+ int regnum, u16 value)
{
int ret;
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 3c58db5..eec4007 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -271,7 +271,7 @@ static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb)
printk("\n");
}
-static int cpmac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+static int cpmac_mdio_read(struct mii_bus *bus, int phy_id, int devad, int reg)
{
u32 val;
@@ -285,7 +285,7 @@ static int cpmac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
}
static int cpmac_mdio_write(struct mii_bus *bus, int phy_id,
- int reg, u16 val)
+ int devad, int reg, u16 val)
{
while (cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0)) & MDIO_BUSY)
cpu_relax();
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 08e82b1..43c1023 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -2240,7 +2240,8 @@ void emac_poll_controller(struct net_device *ndev)
while ((emac_mdio_read((MDIO_USERACCESS(0))) &\
MDIO_USERACCESS_GO) != 0)
-static int emac_mii_read(struct mii_bus *bus, int phy_id, int phy_reg)
+static int emac_mii_read(struct mii_bus *bus, int phy_id, int devad,
+ int phy_reg)
{
unsigned int phy_data = 0;
unsigned int phy_control;
@@ -2263,7 +2264,7 @@ static int emac_mii_read(struct mii_bus *bus, int phy_id, int phy_reg)
}
static int emac_mii_write(struct mii_bus *bus, int phy_id,
- int phy_reg, u16 phy_data)
+ int devad, int phy_reg, u16 phy_data)
{
unsigned int control;
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index 8b0f50b..b1d26fd 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -99,7 +99,8 @@ static void __devinit dnet_get_hwaddr(struct dnet *bp)
memcpy(bp->dev->dev_addr, addr, sizeof(addr));
}
-static int dnet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+static int dnet_mdio_read(struct mii_bus *bus, int mii_id, int devad,
+ int regnum)
{
struct dnet *bp = bus->priv;
u16 value;
@@ -131,8 +132,8 @@ static int dnet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
return value;
}
-static int dnet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
- u16 value)
+static int dnet_mdio_write(struct mii_bus *bus, int mii_id, int devad,
+ int regnum, u16 value)
{
struct dnet *bp = bus->priv;
u16 tmp;
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 14cbde5..a2c6647 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -564,7 +564,7 @@ static int ethoc_poll(struct napi_struct *napi, int budget)
return work_done;
}
-static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg)
+static int ethoc_mdio_read(struct mii_bus *bus, int phy, int devad, int reg)
{
unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT;
struct ethoc *priv = bus->priv;
@@ -587,7 +587,8 @@ static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg)
return -EBUSY;
}
-static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
+static int ethoc_mdio_write(struct mii_bus *bus, int phy, int devad,
+ int reg, u16 val)
{
unsigned long timeout = jiffies + ETHOC_MII_TIMEOUT;
struct ethoc *priv = bus->priv;
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 42d9ac9..5286e88 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -609,7 +609,8 @@ spin_unlock:
/*
* NOTE: a MII transaction is during around 25 us, so polling it...
*/
-static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int devad,
+ int regnum)
{
struct fec_enet_private *fep = bus->priv;
int timeout = FEC_MII_TIMEOUT;
@@ -638,8 +639,8 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
return FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
}
-static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
- u16 value)
+static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int devad,
+ int regnum, u16 value)
{
struct fec_enet_private *fep = bus->priv;
int timeout = FEC_MII_TIMEOUT;
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index 7658a08..af52b5a 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -50,13 +50,14 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK : 0;
}
-static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int devad,
+ int reg)
{
return mpc52xx_fec_mdio_transfer(bus, phy_id, reg, FEC_MII_READ_FRAME);
}
-static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg,
- u16 data)
+static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int devad,
+ int reg, u16 data)
{
return mpc52xx_fec_mdio_transfer(bus, phy_id, reg,
data | FEC_MII_WRITE_FRAME);
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 5944b65..2d02356 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -49,7 +49,8 @@
#define FEC_MII_LOOPS 10000
-static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
+static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int devad,
+ int location)
{
struct fec_info* fec = bus->priv;
struct fec __iomem *fecp = fec->fecp;
@@ -72,7 +73,8 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
return ret;
}
-static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
+static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int devad,
+ int location, u16 val)
{
struct fec_info* fec = bus->priv;
struct fec __iomem *fecp = fec->fecp;
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index ff028f5..1b66b23 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -61,7 +61,7 @@ struct fsl_pq_mdio_priv {
* controlling the external PHYs, for example.
*/
int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
- int regnum, u16 value)
+ int regnum, u16 value)
{
/* Set the PHY address and the register address we want to write */
out_be32(®s->miimadd, (mii_id << 8) | regnum);
@@ -86,8 +86,8 @@ int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
* and are always tied to the local mdio pins, which may not be the
* same as system mdio bus, used for controlling the external PHYs, for eg.
*/
-int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs,
- int mii_id, int regnum)
+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id,
+ int regnum)
{
u16 value;
@@ -119,7 +119,8 @@ static struct fsl_pq_mdio __iomem *fsl_pq_mdio_get_regs(struct mii_bus *bus)
* Write value to the PHY at mii_id at register regnum,
* on the bus, waiting until the write is done before returning.
*/
-int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
+int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int devad, int regnum,
+ u16 value)
{
struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus);
@@ -131,7 +132,7 @@ int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
* Read the bus for PHY at addr mii_id, register regnum, and
* return the value. Clears miimcom first.
*/
-int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int devad, int regnum)
{
struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus);
@@ -190,7 +191,7 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus)
for (i = PHY_MAX_ADDR; i > 0; i--) {
u32 phy_id;
- if (get_phy_id(new_bus, i, &phy_id))
+ if (get_phy_id(new_bus, i, MDIO_DEVAD_NONE, &phy_id))
return -1;
if (phy_id == 0xffffffff)
diff --git a/drivers/net/fsl_pq_mdio.h b/drivers/net/fsl_pq_mdio.h
index 1f7d865..48328eb 100644
--- a/drivers/net/fsl_pq_mdio.h
+++ b/drivers/net/fsl_pq_mdio.h
@@ -41,11 +41,14 @@ struct fsl_pq_mdio {
u8 res4[2728];
} __attribute__ ((packed));
-int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
-int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
+
+int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int devad, int regnum);
+int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int devad, int regnum,
+ u16 value);
int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
- int regnum, u16 value);
-int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum);
+ int regnum, u16 value);
+int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id,
+ int regnum);
int __init fsl_pq_mdio_init(void);
void fsl_pq_mdio_exit(void);
void fsl_pq_mdio_bus_name(char *name, struct device_node *np);
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index fd491e4..230ad75 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -1169,7 +1169,7 @@ static inline int wait_for_mdio(struct greth_private *greth)
return 1;
}
-static int greth_mdio_read(struct mii_bus *bus, int phy, int reg)
+static int greth_mdio_read(struct mii_bus *bus, int phy, int devad, int reg)
{
struct greth_private *greth = bus->priv;
int data;
@@ -1191,7 +1191,8 @@ static int greth_mdio_read(struct mii_bus *bus, int phy, int reg)
}
}
-static int greth_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
+static int greth_mdio_write(struct mii_bus *bus, int phy, int devad, int reg,
+ u16 val)
{
struct greth_private *greth = bus->priv;
diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c
index 5ae28c9..c02d5a5 100644
--- a/drivers/net/ll_temac_mdio.c
+++ b/drivers/net/ll_temac_mdio.c
@@ -18,7 +18,7 @@
/* ---------------------------------------------------------------------
* MDIO Bus functions
*/
-static int temac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+static int temac_mdio_read(struct mii_bus *bus, int phy_id, int devad, int reg)
{
struct temac_local *lp = bus->priv;
u32 rc;
@@ -37,7 +37,8 @@ static int temac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
return rc;
}
-static int temac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
+static int temac_mdio_write(struct mii_bus *bus, int phy_id, int devad, int reg,
+ u16 val)
{
struct temac_local *lp = bus->priv;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 40797fb..15c1b14 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -88,7 +88,8 @@ static void __init macb_get_hwaddr(struct macb *bp)
}
}
-static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+static int macb_mdio_read(struct mii_bus *bus, int mii_id, int devad,
+ int regnum)
{
struct macb *bp = bus->priv;
int value;
@@ -108,8 +109,8 @@ static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
return value;
}
-static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
- u16 value)
+static int macb_mdio_write(struct mii_bus *bus, int mii_id, int devad,
+ int regnum, u16 value)
{
struct macb *bp = bus->priv;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index e345ec8..93f4bf1 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1111,7 +1111,7 @@ static int smi_wait_ready(struct mv643xx_eth_shared_private *msp)
return 0;
}
-static int smi_bus_read(struct mii_bus *bus, int addr, int reg)
+static int smi_bus_read(struct mii_bus *bus, int addr, int devad, int reg)
{
struct mv643xx_eth_shared_private *msp = bus->priv;
void __iomem *smi_reg = msp->base + SMI_REG;
@@ -1138,7 +1138,8 @@ static int smi_bus_read(struct mii_bus *bus, int addr, int reg)
return ret & 0xffff;
}
-static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)
+static int smi_bus_write(struct mii_bus *bus, int addr, int devad, int reg,
+ u16 val)
{
struct mv643xx_eth_shared_private *msp = bus->priv;
void __iomem *smi_reg = msp->base + SMI_REG;
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 1fa4d73..31f621e 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -115,7 +115,8 @@ static int fixed_phy_update_regs(struct fixed_phy *fp)
return 0;
}
-static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num)
+static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int devad,
+ int reg_num)
{
struct fixed_mdio_bus *fmb = bus->priv;
struct fixed_phy *fp;
@@ -139,7 +140,7 @@ static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num)
}
static int fixed_mdio_write(struct mii_bus *bus, int phy_id, int reg_num,
- u16 val)
+ int devad, u16 val)
{
return 0;
}
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 439adaf..4b5b059 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -42,36 +42,41 @@ static int ip175c_config_init(struct phy_device *phydev)
if (full_reset_performed == 0) {
/* master reset */
- err = phydev->bus->write(phydev->bus, 30, 0, 0x175c);
+ err = phydev->bus->write(phydev->bus, 30, MDIO_DEVAD_NONE, 0,
+ 0x175c);
if (err < 0)
return err;
/* ensure no bus delays overlap reset period */
- err = phydev->bus->read(phydev->bus, 30, 0);
+ err = phydev->bus->read(phydev->bus, 30, MDIO_DEVAD_NONE, 0);
/* data sheet specifies reset period is 2 msec */
mdelay(2);
/* enable IP175C mode */
- err = phydev->bus->write(phydev->bus, 29, 31, 0x175c);
+ err = phydev->bus->write(phydev->bus, 29, MDIO_DEVAD_NONE, 31,
+ 0x175c);
if (err < 0)
return err;
/* Set MII0 speed and duplex (in PHY mode) */
- err = phydev->bus->write(phydev->bus, 29, 22, 0x420);
+ err = phydev->bus->write(phydev->bus, 29, MDIO_DEVAD_NONE, 22,
+ 0x420);
if (err < 0)
return err;
/* reset switch ports */
for (i = 0; i < 5; i++) {
err = phydev->bus->write(phydev->bus, i,
+ MDIO_DEVAD_NONE,
MII_BMCR, BMCR_RESET);
if (err < 0)
return err;
}
for (i = 0; i < 5; i++)
- err = phydev->bus->read(phydev->bus, i, MII_BMCR);
+ err = phydev->bus->read(phydev->bus, i, MDIO_DEVAD_NONE,
+ MII_BMCR);
mdelay(2);
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 6539189..2f6f02e 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -152,7 +152,7 @@ static int mdiobb_cmd_addr(struct mdiobb_ctrl *ctrl, int phy, u32 addr)
return dev_addr;
}
-static int mdiobb_read(struct mii_bus *bus, int phy, int reg)
+static int mdiobb_read(struct mii_bus *bus, int phy, int devad, int reg)
{
struct mdiobb_ctrl *ctrl = bus->priv;
int ret, i;
@@ -181,7 +181,8 @@ static int mdiobb_read(struct mii_bus *bus, int phy, int reg)
return ret;
}
-static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
+static int mdiobb_write(struct mii_bus *bus, int phy, int devad, int reg,
+ u16 val)
{
struct mdiobb_ctrl *ctrl = bus->priv;
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index f443d43..021af21 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -24,7 +24,8 @@ struct octeon_mdiobus {
int phy_irq[PHY_MAX_ADDR];
};
-static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
+static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int devad,
+ int regnum)
{
struct octeon_mdiobus *p = bus->priv;
union cvmx_smix_cmd smi_cmd;
@@ -52,7 +53,7 @@ static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
return -EIO;
}
-static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
+static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id, int devad
int regnum, u16 val)
{
struct octeon_mdiobus *p = bus->priv;
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 6a6b819..5c7df03 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -208,14 +208,14 @@ EXPORT_SYMBOL(mdiobus_scan);
* because the bus read/write functions may wait for an interrupt
* to conclude the operation.
*/
-int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum)
+int mdiobus_read(struct mii_bus *bus, int addr, int devad, u16 regnum)
{
int retval;
BUG_ON(in_interrupt());
mutex_lock(&bus->mdio_lock);
- retval = bus->read(bus, addr, regnum);
+ retval = bus->read(bus, addr, devad, regnum);
mutex_unlock(&bus->mdio_lock);
return retval;
@@ -233,14 +233,14 @@ EXPORT_SYMBOL(mdiobus_read);
* because the bus read/write functions may wait for an interrupt
* to conclude the operation.
*/
-int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val)
+int mdiobus_write(struct mii_bus *bus, int addr, int devad, u16 regnum, u16 val)
{
int err;
BUG_ON(in_interrupt());
mutex_lock(&bus->mdio_lock);
- err = bus->write(bus, addr, regnum, val);
+ err = bus->write(bus, addr, devad, regnum, val);
mutex_unlock(&bus->mdio_lock);
return err;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 1a99bb2..c72ba85 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -4,9 +4,11 @@
* Framework for finding and configuring PHYs.
* Also contains generic PHY driver
*
+ * 10G PHY Driver support mostly appropriated from drivers/net/mdio.c
+ *
* Author: Andy Fleming
*
- * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ * Copyright (c) 2004-2006, 2008-2009 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -29,6 +31,7 @@
#include <linux/module.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
+#include <linux/mdio.h>
#include <linux/phy.h>
#include <asm/io.h>
@@ -51,6 +54,7 @@ static void phy_device_release(struct device *dev)
}
static struct phy_driver genphy_driver;
+static struct phy_driver gen10g_driver;
extern int mdio_bus_init(void);
extern void mdio_bus_exit(void);
@@ -204,13 +208,13 @@ EXPORT_SYMBOL(phy_device_create);
* Description: Reads the ID registers of the PHY at @addr on the
* @bus, stores it in @phy_id and returns zero on success.
*/
-int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
+int get_phy_id(struct mii_bus *bus, int addr, int devad, u32 *phy_id)
{
int phy_reg;
/* Grab the bits from PHYIR1, and put them
* in the upper half */
- phy_reg = bus->read(bus, addr, MII_PHYSID1);
+ phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
if (phy_reg < 0)
return -EIO;
@@ -218,7 +222,7 @@ int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id)
*phy_id = (phy_reg & 0xffff) << 16;
/* Grab the bits from PHYIR2, and put them in the lower half */
- phy_reg = bus->read(bus, addr, MII_PHYSID2);
+ phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
if (phy_reg < 0)
return -EIO;
@@ -239,21 +243,31 @@ EXPORT_SYMBOL(get_phy_id);
*/
struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
{
- struct phy_device *dev = NULL;
- u32 phy_id;
+ u32 phy_id = 0x1fffffff;
+ int i;
int r;
- r = get_phy_id(bus, addr, &phy_id);
+ /* Try Standard (ie Clause 22) access */
+ r = get_phy_id(bus, addr, MDIO_DEVAD_NONE, &phy_id);
if (r)
return ERR_PTR(r);
- /* If the phy_id is mostly Fs, there is no device there */
- if ((phy_id & 0x1fffffff) == 0x1fffffff)
- return NULL;
+ /* If the PHY ID is mostly f's, we didn't find anything */
+ if ((phy_id & 0x1fffffff) != 0x1fffffff)
+ return phy_device_create(bus, addr, phy_id);
- dev = phy_device_create(bus, addr, phy_id);
+ /* Otherwise we have to try Clause 45 */
+ for (i = 1; i < 5; i++) {
+ r = get_phy_id(bus, addr, i, &phy_id);
+ if (r)
+ return ERR_PTR(r);
- return dev;
+ /* If the phy_id is mostly Fs, there is no device there */
+ if ((phy_id & 0x1fffffff) != 0x1fffffff)
+ break;
+ }
+
+ return phy_device_create(bus, addr, phy_id);
}
EXPORT_SYMBOL(get_phy_device);
@@ -430,8 +444,8 @@ int phy_init_hw(struct phy_device *phydev)
*
* Description: Called by drivers to attach to a particular PHY
* device. The phy_device is found, and properly hooked up
- * to the phy_driver. If no driver is attached, then the
- * genphy_driver is used. The phy_device is given a ptr to
+ * to the phy_driver. If no driver is attached, then a
+ * generic driver is used. The phy_device is given a ptr to
* the attaching device, and given a callback for link status
* change. The phy_device is returned to the attaching driver.
*/
@@ -444,7 +458,10 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
* exist, and we should use the genphy driver. */
if (NULL == d->driver) {
int err;
- d->driver = &genphy_driver.driver;
+ if (interface == PHY_INTERFACE_MODE_XGMII)
+ d->driver = &gen10g_driver.driver;
+ else
+ d->driver = &genphy_driver.driver;
err = d->driver->probe(d);
if (err >= 0)
@@ -521,6 +538,8 @@ void phy_detach(struct phy_device *phydev)
* real driver could be loaded */
if (phydev->dev.driver == &genphy_driver.driver)
device_release_driver(&phydev->dev);
+ else if (phydev->dev.driver == &gen10g_driver.driver)
+ device_release_driver(&phydev->dev);
}
EXPORT_SYMBOL(phy_detach);
@@ -603,6 +622,12 @@ int genphy_config_advert(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_config_advert);
+int gen10g_config_advert(struct phy_device *dev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(gen10g_config_advert);
+
/**
* genphy_setup_forced - configures/forces speed/duplex from @phydev
* @phydev: target phy_device struct
@@ -631,6 +656,10 @@ int genphy_setup_forced(struct phy_device *phydev)
return err;
}
+int gen10g_setup_forced(struct phy_device *phydev)
+{
+ return 0;
+}
/**
* genphy_restart_aneg - Enable and Restart Autonegotiation
@@ -656,6 +685,12 @@ int genphy_restart_aneg(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_restart_aneg);
+int gen10g_restart_aneg(struct phy_device *phydev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(gen10g_restart_aneg);
+
/**
* genphy_config_aneg - restart auto-negotiation or write BMCR
@@ -698,6 +733,12 @@ int genphy_config_aneg(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_config_aneg);
+int gen10g_config_aneg(struct phy_device *phydev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(gen10g_config_aneg);
+
/**
* genphy_update_link - update link status in @phydev
* @phydev: target phy_device struct
@@ -827,6 +868,33 @@ int genphy_read_status(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_read_status);
+int gen10g_read_status(struct phy_device *phydev)
+{
+ int devad, reg;
+ u32 mmd_mask = phydev->mmds;
+
+ phydev->link = 1;
+
+ /* For now just lie and say it's 10G all the time */
+ phydev->speed = 10000;
+ phydev->duplex = DUPLEX_FULL;
+
+ for (devad = 0; mmd_mask; devad++, mmd_mask = mmd_mask >> 1) {
+ if (!mmd_mask & 1)
+ continue;
+
+ /* Read twice because link state is latched and a
+ * read moves the current state into the register */
+ phy45_read(phydev, devad, MDIO_STAT1);
+ reg = phy45_read(phydev, devad, MDIO_STAT1);
+ if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
+ phydev->link = 0;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(gen10g_read_status);
+
static int genphy_config_init(struct phy_device *phydev)
{
int val;
@@ -873,6 +941,36 @@ static int genphy_config_init(struct phy_device *phydev)
return 0;
}
+
+/* Replicate mdio45_probe */
+int gen10g_config_init(struct phy_device *phydev)
+{
+ int mmd, stat2, devs1, devs2;
+
+ phydev->supported = phydev->advertising = SUPPORTED_10000baseT_Full;
+
+ /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY
+ * XS or DTE XS; give up if none is present. */
+ for (mmd = 1; mmd <= 5; mmd++) {
+ /* Is this MMD present? */
+ stat2 = phy45_read(phydev, mmd, MDIO_STAT2);
+ if (stat2 < 0 ||
+ (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL)
+ continue;
+
+ /* It should tell us about all the other MMDs */
+ devs1 = phy45_read(phydev, mmd, MDIO_DEVS1);
+ devs2 = phy45_read(phydev, mmd, MDIO_DEVS2);
+ if (devs1 < 0 || devs2 < 0)
+ continue;
+
+ phydev->mmds = devs1 | (devs2 << 16);
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
int genphy_suspend(struct phy_device *phydev)
{
int value;
@@ -888,6 +986,12 @@ int genphy_suspend(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_suspend);
+int gen10g_suspend(struct phy_device *phydev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(gen10g_suspend);
+
int genphy_resume(struct phy_device *phydev)
{
int value;
@@ -903,6 +1007,13 @@ int genphy_resume(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_resume);
+int gen10g_resume(struct phy_device *phydev)
+{
+ return 0;
+}
+EXPORT_SYMBOL(gen10g_resume);
+
+
/**
* phy_probe - probe and init a PHY device
* @dev: device to probe and init
@@ -1013,7 +1124,20 @@ static struct phy_driver genphy_driver = {
.read_status = genphy_read_status,
.suspend = genphy_suspend,
.resume = genphy_resume,
- .driver = {.owner= THIS_MODULE, },
+ .driver = {.owner = THIS_MODULE, },
+};
+
+static struct phy_driver gen10g_driver = {
+ .phy_id = 0xffffffff,
+ .phy_id_mask = 0xffffffff,
+ .name = "Generic 10G PHY",
+ .config_init = gen10g_config_init,
+ .features = 0,
+ .config_aneg = gen10g_config_aneg,
+ .read_status = gen10g_read_status,
+ .suspend = gen10g_suspend,
+ .resume = gen10g_resume,
+ .driver = {.owner = THIS_MODULE, },
};
static int __init phy_init(void)
@@ -1026,13 +1150,25 @@ static int __init phy_init(void)
rc = phy_driver_register(&genphy_driver);
if (rc)
- mdio_bus_exit();
+ goto genphy_register_failed;
+
+ rc = phy_driver_register(&gen10g_driver);
+ if (rc)
+ goto gen10g_register_failed;
+
+ return rc;
+
+gen10g_register_failed:
+ phy_driver_unregister(&genphy_driver);
+genphy_register_failed:
+ mdio_bus_exit();
return rc;
}
static void __exit phy_exit(void)
{
+ phy_driver_unregister(&gen10g_driver);
phy_driver_unregister(&genphy_driver);
mdio_bus_exit();
}
diff --git a/drivers/net/s6gmac.c b/drivers/net/s6gmac.c
index a7ff8ea..7430211 100644
--- a/drivers/net/s6gmac.c
+++ b/drivers/net/s6gmac.c
@@ -661,7 +661,7 @@ static int s6mii_busy(struct s6gmac *pd, int tmo)
return 0;
}
-static int s6mii_read(struct mii_bus *bus, int phy_addr, int regnum)
+static int s6mii_read(struct mii_bus *bus, int phy_addr, int devad, int regnum)
{
struct s6gmac *pd = bus->priv;
s6mii_enable(pd);
@@ -677,7 +677,8 @@ static int s6mii_read(struct mii_bus *bus, int phy_addr, int regnum)
return (u16)readl(pd->reg + S6_GMAC_MACMIISTAT);
}
-static int s6mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
+static int s6mii_write(struct mii_bus *bus, int phy_addr, int devad,
+ int regnum, u16 value)
{
struct s6gmac *pd = bus->priv;
s6mii_enable(pd);
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 1f3acc3..5168400 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -322,9 +322,10 @@ static int sbmac_mii_probe(struct net_device *dev);
static void sbmac_mii_sync(void __iomem *sbm_mdio);
static void sbmac_mii_senddata(void __iomem *sbm_mdio, unsigned int data,
int bitcnt);
-static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx);
-static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
- u16 val);
+static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int devad,
+ int regidx);
+static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int devad,
+ int regidx, u16 val);
/**********************************************************************
@@ -434,7 +435,8 @@ static void sbmac_mii_senddata(void __iomem *sbm_mdio, unsigned int data,
* value read, or 0xffff if an error occurred.
********************************************************************* */
-static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
+static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int devad,
+ int regidx)
{
struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv;
void __iomem *sbm_mdio = sc->sbm_mdio;
@@ -527,8 +529,8 @@ static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
* 0 for success
********************************************************************* */
-static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
- u16 regval)
+static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int devad,
+ int regidx, u16 regval)
{
struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv;
void __iomem *sbm_mdio = sc->sbm_mdio;
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 89f35f9..4424da5 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -302,7 +302,8 @@ static void smsc911x_mac_write(struct smsc911x_data *pdata,
}
/* Get a phy register */
-static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
+static int smsc911x_mii_read(struct mii_bus *bus, int phyaddr, int devad,
+ int regidx)
{
struct smsc911x_data *pdata = (struct smsc911x_data *)bus->priv;
unsigned long flags;
@@ -339,8 +340,8 @@ out:
}
/* Set a phy register */
-static int smsc911x_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
- u16 val)
+static int smsc911x_mii_write(struct mii_bus *bus, int phyaddr, int devad,
+ int regidx, u16 val)
{
struct smsc911x_data *pdata = (struct smsc911x_data *)bus->priv;
unsigned long flags;
@@ -570,11 +571,10 @@ static int smsc911x_phy_reset(struct smsc911x_data *pdata)
BUG_ON(!phy_dev->bus);
SMSC_TRACE(HW, "Performing PHY BCR Reset");
- smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, BMCR_RESET);
+ phy_write(phy_dev, MII_BMCR, BMCR_RESET);
do {
msleep(1);
- temp = smsc911x_mii_read(phy_dev->bus, phy_dev->addr,
- MII_BMCR);
+ temp = phy_read(phy_dev, MII_BMCR);
} while ((i--) && (temp & BMCR_RESET));
if (temp & BMCR_RESET) {
@@ -622,8 +622,7 @@ static int smsc911x_phy_loopbacktest(struct net_device *dev)
for (i = 0; i < 10; i++) {
/* Set PHY to 10/FD, no ANEG, and loopback mode */
- smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR,
- BMCR_LOOPBACK | BMCR_FULLDPLX);
+ phy_write(phy_dev, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX);
/* Enable MAC tx/rx, FD */
spin_lock_irqsave(&pdata->mac_lock, flags);
@@ -651,7 +650,7 @@ static int smsc911x_phy_loopbacktest(struct net_device *dev)
spin_unlock_irqrestore(&pdata->mac_lock, flags);
/* Cancel PHY loopback mode */
- smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, 0);
+ phy_write(phy_dev, MII_BMCR, 0);
smsc911x_reg_write(pdata, TX_CFG, 0);
smsc911x_reg_write(pdata, RX_CFG, 0);
@@ -1615,7 +1614,7 @@ smsc911x_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
}
for (i = 0; i <= 31; i++)
- data[j++] = smsc911x_mii_read(phy_dev->bus, phy_dev->addr, i);
+ data[j++] = phy_read(phy_dev, i);
}
static void smsc911x_eeprom_enable_access(struct smsc911x_data *pdata)
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 6cdee6a..871a71e 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -127,7 +127,8 @@ static inline void smsc9420_pci_flush_write(struct smsc9420_pdata *pd)
smsc9420_reg_read(pd, ID_REV);
}
-static int smsc9420_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
+static int smsc9420_mii_read(struct mii_bus *bus, int phyaddr, int devad,
+ int regidx)
{
struct smsc9420_pdata *pd = (struct smsc9420_pdata *)bus->priv;
unsigned long flags;
@@ -164,8 +165,8 @@ out:
return reg;
}
-static int smsc9420_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
- u16 val)
+static int smsc9420_mii_write(struct mii_bus *bus, int phyaddr, int devad,
+ int regidx, u16 val)
{
struct smsc9420_pdata *pd = (struct smsc9420_pdata *)bus->priv;
unsigned long flags;
@@ -328,7 +329,7 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
return;
for (i = 0; i <= 31; i++)
- data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i);
+ data[j++] = phy_read(phy_dev, i);
}
static void smsc9420_eeprom_enable_access(struct smsc9420_pdata *pd)
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
index 40b2c79..dd0a89a 100644
--- a/drivers/net/stmmac/stmmac_mdio.c
+++ b/drivers/net/stmmac/stmmac_mdio.c
@@ -37,13 +37,15 @@
* stmmac_mdio_read
* @bus: points to the mii_bus structure
* @phyaddr: MII addr reg bits 15-11
+ * @devad: unused
* @phyreg: MII addr reg bits 10-6
* Description: it reads data from the MII register from within the phy device.
* For the 7111 GMAC, we must set the bit 0 in the MII address register while
* accessing the PHY registers.
* Fortunately, it seems this has no drawback for the 7109 MAC.
*/
-static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
+static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int devad,
+ int phyreg)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
@@ -70,12 +72,13 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
* stmmac_mdio_write
* @bus: points to the mii_bus structure
* @phyaddr: MII addr reg bits 15-11
+ * @devad: unused
* @phyreg: MII addr reg bits 10-6
* @phydata: phy data
* Description: it writes the data into the MII register from within the device.
*/
-static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
- u16 phydata)
+static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int devad,
+ int phyreg, u16 phydata)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index be08b75..b2a5e8c 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -500,7 +500,7 @@ static void panic_queues(struct net_device *dev);
static void tc35815_restart_work(struct work_struct *work);
-static int tc_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+static int tc_mdio_read(struct mii_bus *bus, int mii_id, int devad, int regnum)
{
struct net_device *dev = bus->priv;
struct tc35815_regs __iomem *tr =
@@ -517,7 +517,8 @@ static int tc_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
return tc_readl(&tr->MD_Data) & 0xffff;
}
-static int tc_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 val)
+static int tc_mdio_write(struct mii_bus *bus, int mii_id, int devad,
+ int regnum, u16 val)
{
struct net_device *dev = bus->priv;
struct tc35815_regs __iomem *tr =
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 573054a..5c8a864 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -936,7 +936,7 @@ static int tg3_bmcr_reset(struct tg3 *tp)
return 0;
}
-static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
+static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int devad, int reg)
{
struct tg3 *tp = bp->priv;
u32 val;
@@ -951,7 +951,8 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
return val;
}
-static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
+static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int devad,
+ int reg, u16 val)
{
struct tg3 *tp = bp->priv;
u32 ret = 0;
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index a7db68d..653e493 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -738,6 +738,7 @@ static int xemaclite_mdio_wait(struct net_local *lp)
* xemaclite_mdio_read - Read from a given MII management register
* @bus: the mii_bus struct
* @phy_id: the phy address
+ * @devad: unused
* @reg: register number to read from
*
* This function waits till the device is ready to accept a new MDIO
@@ -746,7 +747,8 @@ static int xemaclite_mdio_wait(struct net_local *lp)
*
* Return: Value read from the MII management register
*/
-static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int devad,
+ int reg)
{
struct net_local *lp = bus->priv;
u32 ctrl_reg;
@@ -782,14 +784,15 @@ static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg)
* xemaclite_mdio_write - Write to a given MII management register
* @bus: the mii_bus struct
* @phy_id: the phy address
+ * @devad: unused
* @reg: register number to write to
* @val: value to write to the register number specified by reg
*
* This fucntion waits till the device is ready to accept a new MDIO
* request and then writes the val to the MDIO Write Data register.
*/
-static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg,
- u16 val)
+static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int devad,
+ int reg, u16 val)
{
struct net_local *lp = bus->priv;
u32 ctrl_reg;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 987e111..8fb1b52 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -6,7 +6,7 @@
*
* Author: Andy Fleming
*
- * Copyright (c) 2004 Freescale Semiconductor, Inc.
+ * Copyright (c) 2004-2009 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -22,6 +22,7 @@
#include <linux/device.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
+#include <linux/mdio.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/mod_devicetable.h>
@@ -62,7 +63,8 @@ typedef enum {
PHY_INTERFACE_MODE_RGMII_ID,
PHY_INTERFACE_MODE_RGMII_RXID,
PHY_INTERFACE_MODE_RGMII_TXID,
- PHY_INTERFACE_MODE_RTBI
+ PHY_INTERFACE_MODE_RTBI,
+ PHY_INTERFACE_MODE_XGMII
} phy_interface_t;
@@ -94,8 +96,10 @@ struct mii_bus {
const char *name;
char id[MII_BUS_ID_SIZE];
void *priv;
- int (*read)(struct mii_bus *bus, int phy_id, int regnum);
- int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);
+ int (*read)(struct mii_bus *bus, int port_addr, int dev_addr,
+ int regnum);
+ int (*write)(struct mii_bus *bus, int port_addr, int dev_addr,
+ int regnum, u16 val);
int (*reset)(struct mii_bus *bus);
/*
@@ -132,8 +136,9 @@ int mdiobus_register(struct mii_bus *bus);
void mdiobus_unregister(struct mii_bus *bus);
void mdiobus_free(struct mii_bus *bus);
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
-int mdiobus_read(struct mii_bus *bus, int addr, u32 regnum);
-int mdiobus_write(struct mii_bus *bus, int addr, u32 regnum, u16 val);
+int mdiobus_read(struct mii_bus *bus, int addr, int devad, u16 regnum);
+int mdiobus_write(struct mii_bus *bus, int addr, int devad,
+ u16 regnum, u16 val);
#define PHY_INTERRUPT_DISABLED 0x0
@@ -303,6 +308,7 @@ struct phy_device {
/* See mii.h for more info */
u32 supported;
u32 advertising;
+ u32 mmds;
int autoneg;
@@ -429,7 +435,22 @@ struct phy_fixup {
*/
static inline int phy_read(struct phy_device *phydev, u32 regnum)
{
- return mdiobus_read(phydev->bus, phydev->addr, regnum);
+ return mdiobus_read(phydev->bus, phydev->addr, MDIO_DEVAD_NONE, regnum);
+}
+
+/**
+ * phy45_read - Convenience function for reading a given port/dev/reg address
+ * @phydev: The phy_device struct
+ * @devad: The device address to read
+ * @regnum: The register number to read
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ */
+static inline int phy45_read(struct phy_device *phydev, int devad, u16 regnum)
+{
+ return mdiobus_read(phydev->bus, phydev->addr, devad, regnum);
}
/**
@@ -444,10 +465,28 @@ static inline int phy_read(struct phy_device *phydev, u32 regnum)
*/
static inline int phy_write(struct phy_device *phydev, u32 regnum, u16 val)
{
- return mdiobus_write(phydev->bus, phydev->addr, regnum, val);
+ return mdiobus_write(phydev->bus, phydev->addr, MDIO_DEVAD_NONE, regnum,
+ val);
+}
+
+/**
+ * phy45_write - Convenience function for writing a given port/dev/reg
+ * @phydev: the phy_device struct
+ * @devad: the device addr
+ * @regnum: register number to write
+ * @val: value to write to @regnum
+ *
+ * NOTE: MUST NOT be called from interrupt context,
+ * because the bus read/write functions may wait for an interrupt
+ * to conclude the operation.
+ */
+static inline int phy45_write(struct phy_device *phydev, u16 regnum,
+ int devad, u16 val)
+{
+ return mdiobus_write(phydev->bus, phydev->addr, devad, regnum, val);
}
-int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
+int get_phy_id(struct mii_bus *bus, int addr, int devad, u32 *phy_id);
struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
int phy_device_register(struct phy_device *phy);
int phy_clear_interrupt(struct phy_device *phydev);
--
1.6.5.2.g6ff9a
^ permalink raw reply related
* [PATCH v2 0/2] phylib: Add support for MDIO clause 45
From: Andy Fleming @ 2010-05-21 18:31 UTC (permalink / raw)
To: davem; +Cc: netdev
MDIO Clause 45 adds a new argument for accessing PHY registers, so
that you need the PHY address, the "device" address, and the register
address (which can now be up to 65,535). It's best if, moving forward
we add this new device address argument to the MDIO read/write functions,
which means all of the current bus drivers need to be modified.
I opted not to modify the phy read/write functions mostly because all of the
existing code which calls those functions is correct as-is, and any code which
accesses the new 10G PHYs must do so in a fashion quite distinct from that
of accessing older PHYs (the registers are layed out differently, and the
initialization sequences are also quite different).
However, the MDIO buses are technically allowed to use both access mechanisms
on the same bus, so there's an advantage to adding support to all of the
current implementations.
Changes in v2:
Instead of using device address "0" to indicate a Clause 22 transaction, we
use Ben's suggestion of using MDIO_DEVAD_NONE. Also, modify the PHY
identification code to allow Clauses 22 and 45 to coexist on the same bus.
Andy Fleming (2):
phylib: Convert MDIO and PHY Lib drivers to support 10G
phylib: Convert MDIO bitbang to new MDIO 45 format
Documentation/networking/phy.txt | 13 +-
arch/powerpc/platforms/pasemi/gpio_mdio.c | 6 +-
drivers/net/arm/ixp4xx_eth.c | 7 +-
drivers/net/au1000_eth.c | 7 +-
drivers/net/bcm63xx_enet.c | 4 +-
drivers/net/bfin_mac.c | 7 +-
drivers/net/cpmac.c | 4 +-
drivers/net/davinci_emac.c | 5 +-
drivers/net/dnet.c | 7 +-
drivers/net/ethoc.c | 5 +-
drivers/net/fec.c | 7 +-
drivers/net/fec_mpc52xx_phy.c | 7 +-
drivers/net/fs_enet/mii-fec.c | 6 +-
drivers/net/fsl_pq_mdio.c | 13 +-
drivers/net/fsl_pq_mdio.h | 11 +-
drivers/net/greth.c | 5 +-
drivers/net/ll_temac_mdio.c | 5 +-
drivers/net/macb.c | 7 +-
drivers/net/mv643xx_eth.c | 5 +-
drivers/net/phy/fixed.c | 5 +-
drivers/net/phy/icplus.c | 15 ++-
drivers/net/phy/mdio-bitbang.c | 34 +++---
drivers/net/phy/mdio-octeon.c | 5 +-
drivers/net/phy/mdio_bus.c | 8 +-
drivers/net/phy/phy_device.c | 170 ++++++++++++++++++++++++++---
drivers/net/s6gmac.c | 5 +-
drivers/net/sb1250-mac.c | 14 ++-
drivers/net/smsc911x.c | 19 ++--
drivers/net/smsc9420.c | 9 +-
drivers/net/stmmac/stmmac_mdio.c | 9 +-
drivers/net/tc35815.c | 5 +-
drivers/net/tg3.c | 5 +-
drivers/net/xilinx_emaclite.c | 9 +-
include/linux/phy.h | 57 ++++++++--
34 files changed, 358 insertions(+), 142 deletions(-)
^ permalink raw reply
* Re: [RFC PATCH] net: add additional lock to qdisc to increase enqueue/dequeue fairness
From: Eric Dumazet @ 2010-05-21 17:40 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, alexander.h.duyck, netdev
In-Reply-To: <1274460275.2439.469.camel@edumazet-laptop>
Le vendredi 21 mai 2010 à 18:44 +0200, Eric Dumazet a écrit :
> We could use cmpxchg() and manipulate several bits at once in fast path.
> ( __QDISC_STATE_RUNNING, __QDISC_STATE_LOCKED ... ) but making the crowd
> of cpus spin on the same bits/cacheline than dequeue worker would
> definitely slowdown the worker.
>
>
Maybe I am missing something, but __QDISC_STATE_RUNNING is always
manipulated with the lock held...
We might avoid two atomic ops when changing this state (if moved to a
separate container) in fast path (when a cpu sends only one packet and
returns)
^ permalink raw reply
* Re: [RFC PATCH] net: add additional lock to qdisc to increase enqueue/dequeue fairness
From: Stephen Hemminger @ 2010-05-21 17:38 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, alexander.h.duyck, netdev
In-Reply-To: <1274460275.2439.469.camel@edumazet-laptop>
On Fri, 21 May 2010 18:44:35 +0200
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le vendredi 21 mai 2010 à 08:43 -0700, Stephen Hemminger a écrit :
>
> > What about having a special function (spin_lock_greedy?) that just ignores
> > the ticket mechanism and always assumes it has right to next ticket.
> >
>
> I am not sure we want to do this, for a single use case...
> Adding a new lock primitive to linux should be really really motivated.
>
> x86 ticket spinlocks are nice because we are sure no cpu is going to
> stay forever in this code. For other arches, I dont know how this is
> coped.
>
> I thought about this before re-working on this patch, but found it was
> easier to slightly change Alexander code, ie adding a regular spinlock
> for the slowpath.
>
> We could use cmpxchg() and manipulate several bits at once in fast path.
> ( __QDISC_STATE_RUNNING, __QDISC_STATE_LOCKED ... ) but making the crowd
> of cpus spin on the same bits/cacheline than dequeue worker would
> definitely slowdown the worker.
Your solution is okay, but it is a special case performance hack
and we seem to be getting more and more of these lately.
This is a general problem of any producer/consumer case;
other code will have same problem (like disk requests)
and can't use the same solution.
Maybe the RT and scheduler folks have some input because it does
seem like the same problem has occurred in other contexts before.
--
^ permalink raw reply
* Re: bug fix patch lost: git problem or just incorrect merge?
From: James Bottomley @ 2010-05-21 17:23 UTC (permalink / raw)
To: Linus Torvalds; +Cc: David Miller, linux-kernel, netdev, linux-scsi
In-Reply-To: <alpine.LFD.2.00.1005210947440.4243@i5.linux-foundation.org>
On Fri, 2010-05-21 at 10:04 -0700, Linus Torvalds wrote:
>
> On Fri, 21 May 2010, Linus Torvalds wrote:
> >
> > > Either way, of course, we need the patch back ...
> >
> > I'll fix it up.
>
> Hmm. Pushed that out as appended, since that is the correct resolve.
Thanks!
> HOWEVER - the code still doesn't actually make any sense. It does
>
> if (sk_sleep(sock->sk)) {
>
> and that sk_sleep() today is an inline function that just does
>
> return &sk->sk_wq->wait;
>
> and testing the result of an address-of operation for NULL is almost
> certainly totally non-sensical. Sure, it _might_ work (maybe 'wait' is the
> first element in the 'sk_wq' data structure, and sk_wq is NULL), but that
> kind of code is always total and utterl crap regardless.
>
> So I pushed it out because I had done the resolve already, and it's no
> worse than it was before, but it's still a steaming buggy pile of shit.
Yes, the problem was caused by this patch
commit 43815482370c510c569fd18edb57afcb0fa8cab6
Author: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu Apr 29 11:01:49 2010 +0000
net: sock_def_readable() and friends RCU conversion
Which moved sk_sleep() from returning the pointer to the waitqueue,
which may or may not be assigned to returning a pointer to an internal
waitqueue in the socket, which, obviously, can never be null.
I suspect what iscsi should be doing is always sending the wakeup ... in
which case with your resolution, the code is operating correctly even if
the form is suboptimal.
> It being iscsi, I can't bring myself to care. But somebody who does,
> should really look at it. The most likely resolution is to remove the test
> entirely, since I don't think it's ever valid to have a socket that
> doesn't have a sk_wq (there's a _lot_ of unconditional use of sk_sleep()).
I'll have Mike look at it, but I think just removing the if() will be
the correct resolution.
James
^ permalink raw reply
* Re: bug fix patch lost: git problem or just incorrect merge?
From: Linus Torvalds @ 2010-05-21 17:04 UTC (permalink / raw)
To: James Bottomley; +Cc: David Miller, linux-kernel, netdev, linux-scsi
In-Reply-To: <alpine.LFD.2.00.1005210931010.4243@i5.linux-foundation.org>
On Fri, 21 May 2010, Linus Torvalds wrote:
>
> > Either way, of course, we need the patch back ...
>
> I'll fix it up.
Hmm. Pushed that out as appended, since that is the correct resolve.
HOWEVER - the code still doesn't actually make any sense. It does
if (sk_sleep(sock->sk)) {
and that sk_sleep() today is an inline function that just does
return &sk->sk_wq->wait;
and testing the result of an address-of operation for NULL is almost
certainly totally non-sensical. Sure, it _might_ work (maybe 'wait' is the
first element in the 'sk_wq' data structure, and sk_wq is NULL), but that
kind of code is always total and utterl crap regardless.
So I pushed it out because I had done the resolve already, and it's no
worse than it was before, but it's still a steaming buggy pile of shit.
It being iscsi, I can't bring myself to care. But somebody who does,
should really look at it. The most likely resolution is to remove the test
entirely, since I don't think it's ever valid to have a socket that
doesn't have a sk_wq (there's a _lot_ of unconditional use of sk_sleep()).
Linus
^ permalink raw reply
* Re: bug fix patch lost: git problem or just incorrect merge?
From: Linus Torvalds @ 2010-05-21 16:45 UTC (permalink / raw)
To: James Bottomley; +Cc: David Miller, linux-kernel, netdev, linux-scsi
In-Reply-To: <1274456515.9022.14.camel@mulgrave.site>
On Fri, 21 May 2010, James Bottomley wrote:
>
> The patch in question is this one (upstream for a while):
>
> commit d7d05548a62c87ee55b0c81933669177f885aa8d
> Author: Mike Christie <michaelc@cs.wisc.edu>
> Date: Wed Mar 31 14:41:35 2010 -0500
>
> [SCSI] iscsi_tcp: fix relogin/shutdown hang
>
> It's a simple one line change in iscsi_tcp.c (diff clipped):
>
> --- a/drivers/scsi/iscsi_tcp.c
> +++ b/drivers/scsi/iscsi_tcp.c
> @@ -599,7 +599,7 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
> - if (sock->sk->sk_sleep && waitqueue_active(sock->sk->sk_sleep)) {
> + if (sock->sk->sk_sleep) {
>
> It was killed by this merge commit in the net-next tree:
>
> commit 278554bd6579206921f5d8a523649a7a57f8850d
> Merge: 5a147e8 cea0d76
> Author: David S. Miller <davem@davemloft.net>
> Date: Wed May 12 00:05:35 2010 -0700
>
> However, the curious thing is that git seems to have lost trace of the
> missing patch entirely
No, it's there, and the bug is that David doesn't do merges well.
One of the reasons I ask people to let me merge is that it results in
cleaner history to not have criss-cross merges. And another is that I'm
pretty good at it, and letting me make merges also means that I am more
aware of problem spots.
> if I try to find it in linus' tree with a git log --
> drivers/scsi/iscsi_tcp.c, it doesn't show up.
That is because "git log" will see the merge, see that _all_ history came
from the other side, and ignore the side that was ignored. Because
clearly, that other side didn't actually contribute anything.
Now, the _reason_ that other side didn't contribute anything is that David
messed up the merge, and took just his own sides changes.
> The merge commit which killed it does list iscsi_tcp.c as a file
> conflict
Yes. I re-did the merge, and the result looks like this (cut-and-paste
whitespace damage, I'm just illustrating he point):
diff --cc drivers/scsi/iscsi_tcp.c
index 9eae04a,02143af..0000000
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@@ -599,9 -599,9 +599,13 @@@ static void iscsi_sw_tcp_conn_stop(stru
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock);
++<<<<<<< HEAD
+ if (sk_sleep(sock->sk) && waitqueue_active(sk_sleep(sock->sk))) {
++=======
+ if (sock->sk->sk_sleep) {
++>>>>>>> cea0d76
sock->sk->sk_err = EIO;
- wake_up_interruptible(sock->sk->sk_sleep);
+ wake_up_interruptible(sk_sleep(sock->sk));
}
iscsi_conn_stop(cls_conn, flag);
and David picked his side of things, not your side.
The _correct_ merge would have been to take both changes, as is quite
obvious if you do
gitk 5a147e8...cea0d76 drivers/scsi/iscsi_tcp.c
and see that the conflict comes because:
- one side (David's) changed
sock->sk->sk_sleep
into
sk_sleep(sock->sk)
in commit aa395145165cb06a0d0885221bbe0ce4a564391d
- the other side (your) removed the 'waitqueue_active()' part in commit
d7d05548a62c87ee55b0c81933669177f885aa8d.
So the end result _should_ have been this merge resolution:
diff --cc drivers/scsi/iscsi_tcp.c
index 9eae04a,02143af..0000000
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@@ -599,9 -599,9 +599,9 @@@ static void iscsi_sw_tcp_conn_stop(stru
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
write_unlock_bh(&tcp_sw_conn->sock->sk->sk_callback_lock);
- if (sk_sleep(sock->sk) && waitqueue_active(sk_sleep(sock->sk))) {
- if (sock->sk->sk_sleep) {
++ if (sk_sleep(sock->sk)) {
sock->sk->sk_err = EIO;
- wake_up_interruptible(sock->sk->sk_sleep);
+ wake_up_interruptible(sk_sleep(sock->sk));
}
iscsi_conn_stop(cls_conn, flag);
but David just picked his side entirely. And that is also the reason for:
> but git show on that commit doesn't list that file in the resolution
> diff ... even though this is where it actually got killed.
A merge diff ("combined diff") only shows conflicts as defined by "you
resolved it to something that didn't match either side". That's a _real_
conflict. If you just end up picking one side, there is no diff.
> Is this a git problem ... or is it just a mismerge in the net tree?
So it's a mis-merge. You can see the commit with
gitk v2.6.34.. --full-history drivers/scsi/iscsi_tcp.c
which doesn't do the "ignore the side of a merge that didn't bring any new
data in". Or, with any recent git, you can use "--simplify-merges" instead
of full-history, which only simplifies trivial merges where neither side
really touched things at all.
If you do that, you'll also see why git doesn't show the uninteresting
side of a merge by default. Just for fun, compare the graphs of
gitk v2.6.34.. drivers/scsi/iscsi_tcp.c
gitk v2.6.34.. --simplify-merges drivers/scsi/iscsi_tcp.c
gitk v2.6.34.. --full-history drivers/scsi/iscsi_tcp.c
and ask yourself: do you normally want to see _all_ the history, even
stuff that didn't end up affecting the end result?
> Either way, of course, we need the patch back ...
I'll fix it up.
Linus
^ permalink raw reply
* [PATCH] Add ip route {save,restore}
From: Dan Smith @ 2010-05-21 16:45 UTC (permalink / raw)
To: shemminger; +Cc: netdev
This patch adds save and restore commands to "ip route". Save dumps
the RTNL stream to stdout which can then be passed to restore later.
This may be helpful in some normal situations, and will allow C/R to
migrate the routing information in userspace. Tweaking of the stream
can be done by userspace helpers to convert between versions and adjust
things like device indexes when restoring routes in a different
environment.
By factoring out some of the common bits of print_route() into
filter_nlmsg(), the "save" command can use the same selection logic
as "list," allowing the caller to save only specific routes as
necessary.
The only change since the RFC is the addition of manpage and doc
material.
Signed-off-by: Dan Smith <danms@us.ibm.com>
---
doc/ip-cref.tex | 35 +++++++++++
ip/iproute.c | 169 +++++++++++++++++++++++++++++++++++++++++--------------
man/man8/ip.8 | 22 +++++++
3 files changed, 184 insertions(+), 42 deletions(-)
diff --git a/doc/ip-cref.tex b/doc/ip-cref.tex
index 056e3bf..d8fed66 100644
--- a/doc/ip-cref.tex
+++ b/doc/ip-cref.tex
@@ -1675,6 +1675,41 @@ information about this route is shown:
\item \verb|used| --- the number of lookups of this route since its creation.
\end{itemize}
+\subsection{{\tt ip route save} -- save routing tables}
+\label{IP-ROUTE-SAVE}
+
+\paragraph{Description:} this command saves the contents of the routing
+tables or the route(s) selected by some criteria to standard output.
+
+\paragraph{Arguments:} \verb|ip route save| has the same arguments as
+\verb|ip route show|.
+
+\paragraph{Example:} This saves all the routes to the {\tt saved\_routes}
+file:
+\begin{verbatim}
+dan@caffeine:~ # ip route save > saved_routes
+\end{verbatim}
+
+\paragraph{Output format:} The format of the data stream provided by
+\verb|ip route save| is that of \verb|rtnetlink|. See
+\verb|rtnetlink(7)| for more information.
+
+\subsection{{\tt ip route restore} -- restore routing tables}
+\label{IP-ROUTE-RESTORE}
+
+\paragraph{Description:} this command restores the contents of the routing
+tables according to a data stream as provided by \verb|ip route save| via
+standard input. Note that any routes already in the table are left unchanged.
+Any routes in the input stream that already exist in the tables are ignored.
+
+\paragraph{Arguments:} This command takes no arguments.
+
+\paragraph{Example:} This restores all routes that were saved to the
+{\tt saved\_routes} file:
+
+\begin{verbatim}
+dan@caffeine:~ # ip route restore < saved_routes
+\end{verbatim}
\subsection{{\tt ip route flush} --- flush routing tables}
\label{IP-ROUTE-FLUSH}
diff --git a/ip/iproute.c b/ip/iproute.c
index 8252e18..3049975 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -23,6 +23,7 @@
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <linux/in_route.h>
+#include <errno.h>
#include "rt_names.h"
#include "utils.h"
@@ -32,7 +33,11 @@
#define RTAX_RTTVAR RTAX_HOPS
#endif
-
+enum list_action {
+ IPROUTE_LIST,
+ IPROUTE_FLUSH,
+ IPROUTE_SAVE,
+};
static const char *mx_names[RTAX_MAX+1] = {
[RTAX_MTU] = "mtu",
[RTAX_WINDOW] = "window",
@@ -53,6 +58,8 @@ static void usage(void) __attribute__((noreturn));
static void usage(void)
{
fprintf(stderr, "Usage: ip route { list | flush } SELECTOR\n");
+ fprintf(stderr, " ip route save SELECTOR\n");
+ fprintf(stderr, " ip route restore\n");
fprintf(stderr, " ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
fprintf(stderr, " [ oif STRING ] [ tos TOS ]\n");
fprintf(stderr, " ip route { add | del | change | append | replace | monitor } ROUTE\n");
@@ -115,46 +122,16 @@ static int flush_update(void)
return 0;
}
-int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
{
- FILE *fp = (FILE*)arg;
struct rtmsg *r = NLMSG_DATA(n);
- int len = n->nlmsg_len;
- struct rtattr * tb[RTA_MAX+1];
- char abuf[256];
inet_prefix dst;
inet_prefix src;
- inet_prefix prefsrc;
inet_prefix via;
- int host_len = -1;
- static int ip6_multiple_tables;
+ inet_prefix prefsrc;
__u32 table;
- SPRINT_BUF(b1);
- static int hz;
-
- if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
- fprintf(stderr, "Not a route: %08x %08x %08x\n",
- n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
- return 0;
- }
- if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
- return 0;
- len -= NLMSG_LENGTH(sizeof(*r));
- if (len < 0) {
- fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
- return -1;
- }
-
- if (r->rtm_family == AF_INET6)
- host_len = 128;
- else if (r->rtm_family == AF_INET)
- host_len = 32;
- else if (r->rtm_family == AF_DECnet)
- host_len = 16;
- else if (r->rtm_family == AF_IPX)
- host_len = 80;
+ static int ip6_multiple_tables;
- parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
table = rtm_get_table(r, tb);
if (r->rtm_family == AF_INET6 && table != RT_TABLE_MAIN)
@@ -281,6 +258,56 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
*(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1)
return 0;
+ return 1;
+}
+
+int calc_host_len(struct rtmsg *r)
+{
+ if (r->rtm_family == AF_INET6)
+ return 128;
+ else if (r->rtm_family == AF_INET)
+ return 32;
+ else if (r->rtm_family == AF_DECnet)
+ return 16;
+ else if (r->rtm_family == AF_IPX)
+ return 80;
+ else
+ return -1;
+}
+
+int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+{
+ FILE *fp = (FILE*)arg;
+ struct rtmsg *r = NLMSG_DATA(n);
+ int len = n->nlmsg_len;
+ struct rtattr * tb[RTA_MAX+1];
+ char abuf[256];
+ int host_len = -1;
+ __u32 table;
+ SPRINT_BUF(b1);
+ static int hz;
+
+ if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
+ fprintf(stderr, "Not a route: %08x %08x %08x\n",
+ n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
+ return 0;
+ }
+ if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
+ return 0;
+ len -= NLMSG_LENGTH(sizeof(*r));
+ if (len < 0) {
+ fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
+ return -1;
+ }
+
+ host_len = calc_host_len(r);
+
+ parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
+ table = rtm_get_table(r, tb);
+
+ if (!filter_nlmsg(n, tb, host_len))
+ return 0;
+
if (filter.flushb) {
struct nlmsghdr *fn;
if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
@@ -1041,17 +1068,51 @@ static int iproute_flush_cache(void)
return 0;
}
+int save_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+{
+ int ret;
+ int len = n->nlmsg_len;
+ struct rtmsg *r = NLMSG_DATA(n);
+ struct rtattr *tb[RTA_MAX+1];
+ int host_len = -1;
+
+ if (isatty(STDOUT_FILENO)) {
+ fprintf(stderr, "Not sending binary stream to stdout\n");
+ return -1;
+ }
+
+ host_len = calc_host_len(r);
+ len -= NLMSG_LENGTH(sizeof(*r));
+ parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
+
+ if (!filter_nlmsg(n, tb, host_len))
+ return 0;
+
+ ret = write(STDOUT_FILENO, n, n->nlmsg_len);
+ if ((ret > 0) && (ret != n->nlmsg_len)) {
+ fprintf(stderr, "Short write while saving nlmsg\n");
+ ret = -EIO;
+ }
+
+ return ret == n->nlmsg_len ? 0 : ret;
+}
-static int iproute_list_or_flush(int argc, char **argv, int flush)
+static int iproute_list_flush_or_save(int argc, char **argv, int action)
{
int do_ipv6 = preferred_family;
char *id = NULL;
char *od = NULL;
+ rtnl_filter_t filter_fn;
+
+ if (action == IPROUTE_SAVE)
+ filter_fn = save_route;
+ else
+ filter_fn = print_route;
iproute_reset_filter();
filter.tb = RT_TABLE_MAIN;
- if (flush && argc <= 0) {
+ if ((action == IPROUTE_FLUSH) && argc <= 0) {
fprintf(stderr, "\"ip route flush\" requires arguments.\n");
return -1;
}
@@ -1201,7 +1262,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
}
}
- if (flush) {
+ if (action == IPROUTE_FLUSH) {
int round = 0;
char flushb[4096-512];
time_t start = time(0);
@@ -1226,7 +1287,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
exit(1);
}
filter.flushed = 0;
- if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
+ if (rtnl_dump_filter(&rth, filter_fn, stdout, NULL, NULL) < 0) {
fprintf(stderr, "Flush terminated\n");
exit(1);
}
@@ -1269,7 +1330,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
}
}
- if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
+ if (rtnl_dump_filter(&rth, filter_fn, stdout, NULL, NULL) < 0) {
fprintf(stderr, "Dump terminated\n");
exit(1);
}
@@ -1436,6 +1497,26 @@ int iproute_get(int argc, char **argv)
exit(0);
}
+int restore_handler(struct sockaddr_nl *nl, struct nlmsghdr *n, void *arg)
+{
+ int ret;
+
+ n->nlmsg_flags |= NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
+
+ ll_init_map(&rth);
+
+ ret = rtnl_talk(&rth, n, 0, 0, n, NULL, NULL);
+ if ((ret < 0) && (errno == EEXIST))
+ ret = 0;
+
+ return ret;
+}
+
+int iproute_restore(void)
+{
+ exit(rtnl_from_file(stdin, &restore_handler, NULL));
+}
+
void iproute_reset_filter()
{
memset(&filter, 0, sizeof(filter));
@@ -1446,7 +1527,7 @@ void iproute_reset_filter()
int do_iproute(int argc, char **argv)
{
if (argc < 1)
- return iproute_list_or_flush(0, NULL, 0);
+ return iproute_list_flush_or_save(0, NULL, IPROUTE_LIST);
if (matches(*argv, "add") == 0)
return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_EXCL,
@@ -1471,11 +1552,15 @@ int do_iproute(int argc, char **argv)
argc-1, argv+1);
if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
|| matches(*argv, "lst") == 0)
- return iproute_list_or_flush(argc-1, argv+1, 0);
+ return iproute_list_flush_or_save(argc-1, argv+1, IPROUTE_LIST);
if (matches(*argv, "get") == 0)
return iproute_get(argc-1, argv+1);
if (matches(*argv, "flush") == 0)
- return iproute_list_or_flush(argc-1, argv+1, 1);
+ return iproute_list_flush_or_save(argc-1, argv+1, IPROUTE_FLUSH);
+ if (matches(*argv, "save") == 0)
+ return iproute_list_flush_or_save(argc-1, argv+1, IPROUTE_SAVE);
+ if (matches(*argv, "restore") == 0)
+ return iproute_restore();
if (matches(*argv, "help") == 0)
usage();
fprintf(stderr, "Command \"%s\" is unknown, try \"ip route help\".\n", *argv);
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index a5d2915..8158f5e 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -132,6 +132,13 @@ tentative " | " deprecated " | " dadfailed " | " temporary " ]"
.I SELECTOR
.ti -8
+.BR "ip route save"
+.I SELECTOR
+
+.ti -8
+.BR "ip route restore"
+
+.ti -8
.B ip route get
.IR ADDRESS " [ "
.BI from " ADDRESS " iif " STRING"
@@ -1867,6 +1874,21 @@ however, no packets are actually sent. With the
argument, the kernel pretends that a packet arrived from this interface
and searches for a path to forward the packet.
+.SS ip route save - save routing table information to stdout
+this command behaves like
+.BR "ip route show"
+except that the output is raw data suitable for passing to
+.BR "ip route restore" .
+
+.SS ip route restore - restore routing table information from stdin
+this command expects to read a data stream as returned from
+.BR "ip route save" .
+It will attempt to restore the routing table information exactly as
+it was at the time of the save, so any translation of information
+in the stream (such as device indexes) must be done first. Any existing
+routes are left unchanged. Any routes specified in the data stream that
+already exist in the table will be ignored.
+
.SH ip rule - routing policy database management
.BR "Rule" s
--
1.7.0.4
^ permalink raw reply related
* Re: [RFC PATCH] net: add additional lock to qdisc to increase enqueue/dequeue fairness
From: Eric Dumazet @ 2010-05-21 16:44 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, alexander.h.duyck, netdev
In-Reply-To: <20100521084349.0d6f8f9a@nehalam>
Le vendredi 21 mai 2010 à 08:43 -0700, Stephen Hemminger a écrit :
> What about having a special function (spin_lock_greedy?) that just ignores
> the ticket mechanism and always assumes it has right to next ticket.
>
I am not sure we want to do this, for a single use case...
Adding a new lock primitive to linux should be really really motivated.
x86 ticket spinlocks are nice because we are sure no cpu is going to
stay forever in this code. For other arches, I dont know how this is
coped.
I thought about this before re-working on this patch, but found it was
easier to slightly change Alexander code, ie adding a regular spinlock
for the slowpath.
We could use cmpxchg() and manipulate several bits at once in fast path.
( __QDISC_STATE_RUNNING, __QDISC_STATE_LOCKED ... ) but making the crowd
of cpus spin on the same bits/cacheline than dequeue worker would
definitely slowdown the worker.
^ permalink raw reply
* Re: bnx2x + SFP+ DA/2.6.33.3: Got bad status 0x0 when reading from SFP+ EEPROM -> SFP+ module is not initialized
From: Krzysztof Olędzki @ 2010-05-21 16:43 UTC (permalink / raw)
To: eilong; +Cc: Rick Jones, Michael Chan, netdev@vger.kernel.org
In-Reply-To: <4BF68854.5060409@ans.pl>
On 2010-05-21 15:19, Krzysztof Olędzki wrote:
> On 2010-05-21 14:58, Eilon Greenstein wrote:
>> On Thu, 2010-05-20 at 13:54 -0700, Krzysztof Olędzki wrote:
>>> On 2010-05-20 22:25, Rick Jones wrote:
>>>> Some simple/simplistic thoughts/questions...
>>>>
>>>> Has the DAC been used successfully prior to this?
>>>
>>> Yes. It was successfully used to connect two HP switches, before I
>>> received SFP+ SR modules, that allowed me to put the switches into
>>> distanced rooms.
>>
>> Krzysztof,
>>
>> I would like to check in what speed the I2C is running at, and while we
>> are there, to make sure it is at low speed (100KHz and not 400KHz). Can
>> you please add this patch and let me know what you see:
>
> Sure.
>
>>
>> diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
>
> <CUT>
>
> [bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
> [bnx2x_8727_read_sfp_module_eeprom:2774(eth5)]I2C 2W speed 0x0, bit 8 0
>
>> Since we are already off for the weekend, I couldn't find a machine with
>> this kind of board to test it for myself. On top of that, I don't have
>> this type of DAC cable, so I need your help in this debug process.
>
> No problem. There is no need to ask for a help a person who depends on
> your support. ;) I would like to solve it as soon as possible so I'm
> willing to test everything you send me. ;)
Hello again,
To make sure the NICs are OK I made a test and plugged a SFP+ SR module (HP J9150A):
[bnx2x_8727_handle_mod_abs:4639(eth4)]MOD_ABS indication show module is present
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_8727_read_sfp_module_eeprom:2835(eth4)]Got bad status 0x0 when reading from SFP+ EEPROM
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_8727_read_sfp_module_eeprom:2835(eth4)]Got bad status 0x0 when reading from SFP+ EEPROM
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_8727_read_sfp_module_eeprom:2835(eth4)]Got bad status 0x0 when reading from SFP+ EEPROM
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_8727_read_sfp_module_eeprom:2835(eth4)]Got bad status 0x0 when reading from SFP+ EEPROM
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_8727_read_sfp_module_eeprom:2835(eth4)]Got bad status 0x0 when reading from SFP+ EEPROM
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_wait_for_sfp_module_initialized:3138(eth4)]SFP+ module initialization took 25 ms
[bnx2x_sfp_module_detection:3197(eth4)]SFP+ module plugged in/out detected on port 0
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_get_edc_mode:2930(eth4)]Optic module detected
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_get_edc_mode:2954(eth4)]EDC mode is set to 0x44
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
[bnx2x_8727_read_sfp_module_eeprom:2774(eth4)]I2C 2W speed 0x0, bit 8 0
bnx2x: Warning: Unqualified SFP+ module detected on eth4, Port 0 from MergeOptics GmbH part number TRX10GVP2010CA01
[bnx2x_sfp_module_detection:3205(eth4)]Module verification failed!!
So, both NICs and SFP+ DA cables are OK. The only problem we have is to make them talk together. :|
Best regards,
Krzysztof Olędzki
^ permalink raw reply
* Re: tun: Use netif_receive_skb instead of netif_rx
From: Neil Horman @ 2010-05-21 16:40 UTC (permalink / raw)
To: Herbert Xu; +Cc: David Miller, eric.dumazet, bmb, tgraf, nhorman, netdev
In-Reply-To: <20100521110847.GA29878@gondor.apana.org.au>
On Fri, May 21, 2010 at 09:08:47PM +1000, Herbert Xu wrote:
> On Fri, May 21, 2010 at 06:51:28AM -0400, Neil Horman wrote:
> >
> > I read it, we just described the issue in diferent terms.
>
> Yeah I wasn't clear enough with my email without an actual patch :)
>
> Thanks for testing Neil!
So a bit of bad news. I think you're patch is correct herbert but its still not
working. When I initially started messing with this it was on 2.6.32. But
since you're patches I (naturally) started testing them on 2.6.34. Whereas in
2.6.32 the tasks classid value for the net_cls cgroup subsys was set properly,
in 2.6.34 its not. It appears since we started using the cgroup subsys
registration calls, we never registered an attach method, so we never set the
tasks classid, so the comparison always fails.
There may also be an issue with the setting of the classid (possible use of the
wrong subsys id value when grabbing our cgroup_subsys_state), but I'm checking
on that now.
Best
Neil
> --
> Visit Openswan at http://www.openswan.org/
> Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
>
^ permalink raw reply
* ixgbe and SRIOV failure in driver?
From: Fischer, Anna @ 2010-05-21 16:32 UTC (permalink / raw)
To: e1000-devel@lists.sourceforge.net, netdev@vger.kernel.org
I am running a system with 3 Intel NICs. Two of them are 82598 devices, and one is a SRIOV capable 82599.
All devices use the ixgbe driver. What happens (I believe) now is that when the driver loads at first, it sees the 82598 first (because of its position in the PCI tree) and then it says "Device not IOV capable - switching off IOV."
So then it switches into non-IOV mode, and I can never enable SRIOV on my 82599, because the driver does not enable it any more for further devices.
So to get around this issue, I tried to use pciback.hide to hide the 82598 devices from the OS. That way I was hoping that the driver would switch on SRIOV on my 82599. However, then I got a kernel panic on boot (see below).
I am running Xen 4 and the Dom0 kernel is a 2.6.31 kernel.
Any help would be greatly appreciated.
Thanks,
Anna
Starting udev: (XEN) ioapic_guest_write: apic=0, pin=16, irq=16
(XEN) ioapic_guest_write: new_entry=0001a9a8
(XEN) ioapic_guest_write: old_entry=0000a9a8 pirq=16
(XEN) ioapic_guest_write: Attempt to modify IO-APIC pin for in-use IRQ!
(XEN) printk: 11 messages suppressed.
(XEN) mm.c:859:d0 Error getting mfn 40000 (pfn 5555555555555555) from L1 entry 3
(XEN) mm.c:859:d0 Error getting mfn 40001 (pfn 5555555555555555) from L1 entry 3
(XEN) mm.c:859:d0 Error getting mfn 40002 (pfn 5555555555555555) from L1 entry 3
(XEN) mm.c:859:d0 Error getting mfn 40003 (pfn 5555555555555555) from L1 entry 3
[ 23.067972] BUG: unable to handle kernel paging request at ffffc90020e10010
[ 23.067985] IP: [<ffffffffa00c6652>] ixgbe_init_ops_generic+0x12/0x1c0 [ixgb]
[ 23.068004] PGD 220a067 PUD 220b067 PMD 3e841067 PTE 0
[ 23.068004] Oops: 0000 [#1] SMP
[ 23.068004] last sysfs file: /sys/devices/pci0000:00/0000:00:1d.1/usb6/dev
[ 23.068004] CPU 0
[ 23.068004] Modules linked in: ixgbe(+) e1000e usb_storage ahci libata sd_mod
[ 23.068004] Pid: 1172, comm: modprobe Not tainted 2.6.31.13 #2 Montevina Plam
[ 23.068004] RIP: e030:[<ffffffffa00c6652>] [<ffffffffa00c6652>] ixgbe_init_]
[ 23.068004] RSP: e02b:ffff88003d981c78 EFLAGS: 00010246
[ 23.068004] RAX: ffff88003c1ed550 RBX: ffff88003c1ed550 RCX: 0000000080050008
[ 23.068004] RDX: ffffc90020e00000 RSI: ffff88003c1ed7f0 RDI: ffff88003c1ed540
[ 23.068004] RBP: ffff88003d981c78 R08: 0000000000000030 R09: 00000000fffffffb
[ 23.068004] R10: 0000000000000000 R11: 800000000000056b R12: ffff88003c1ed540
[ 23.068004] R13: ffff88003c1ed740 R14: 00000000fffffffb R15: ffff88003c1ec000
[ 23.068004] FS: 00007f24a1a736e0(0000) GS:ffffc90000000000(0000) knlGS:00000
[ 23.068004] CS: e033 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 23.068004] CR2: ffffc90020e10010 CR3: 000000003c183000 CR4: 0000000000002660
[ 23.068004] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 23.068004] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 23.068004] Process modprobe (pid: 1172, threadinfo ffff88003d980000, task f)
[ 23.068004] Stack:
[ 23.068004] ffff88003d981ca8 ffffffffa00cf7f6 ffff88003c1ed540 ffff88003c1e0
[ 23.068004] <0> ffff88003c1ed540 00000000fffffffb ffff88003d981cc8 ffffffffa8
[ 23.068004] <0> 00000000fffffffb ffff88003fab5000 ffff88003d981d48 ffffffffa7
[ 23.068004] Call Trace:
[ 23.068004] [<ffffffffa00cf7f6>] ixgbe_init_ops_82599+0x36/0x1a0 [ixgbe]
[ 23.068004] [<ffffffffa00c8818>] ixgbe_init_shared_code+0x48/0x50 [ixgbe]
[ 23.068004] [<ffffffffa00d6b37>] ixgbe_probe+0x317/0x1380 [ixgbe]
[ 23.068004] [<ffffffff812147b0>] ? pci_match_id+0x1f/0x43
[ 23.068004] [<ffffffff812147e6>] local_pci_probe+0x12/0x16
[ 23.068004] [<ffffffff812152fc>] pci_device_probe+0x5c/0x88
[ 23.068004] [<ffffffff812e23e4>] ? driver_sysfs_add+0x4d/0x73
[ 23.068004] [<ffffffff812e2535>] driver_probe_device+0xb2/0x136
[ 23.068004] [<ffffffff812e260d>] __driver_attach+0x54/0x77
[ 23.068004] [<ffffffff812e25b9>] ? __driver_attach+0x0/0x77
[ 23.068004] [<ffffffff812e25b9>] ? __driver_attach+0x0/0x77
[ 23.068004] [<ffffffff812e1bb3>] bus_for_each_dev+0x49/0x78
[ 23.068004] [<ffffffff812e2395>] driver_attach+0x1c/0x1e
[ 23.068004] [<ffffffff812e16c2>] bus_add_driver+0xba/0x220
[ 23.068004] [<ffffffff812e299a>] driver_register+0x9e/0x115
[ 23.068004] [<ffffffff81215574>] __pci_register_driver+0x50/0xad
[ 23.068004] [<ffffffffa00eb000>] ? ixgbe_init_module+0x0/0x56 [ixgbe]
[ 23.068004] [<ffffffffa00eb054>] ixgbe_init_module+0x54/0x56 [ixgbe]
[ 23.068004] [<ffffffff8100a0e7>] do_one_initcall+0x59/0x159
[ 23.068004] [<ffffffff81095311>] sys_init_module+0xcb/0x1fe
[ 23.068004] [<ffffffff81033cc2>] system_call_fastpath+0x16/0x1b
[ 23.068004] Code: 5d c9 c3 48 83 c4 08 b8 ff ff ff ff 5b 41 5c 41 5d c9 c3 6
[ 23.068004] RIP [<ffffffffa00c6652>] ixgbe_init_ops_generic+0x12/0x1c0 [ixg]
[ 23.068004] RSP <ffff88003d981c78>
[ 23.068004] CR2: ffffc90020e10010
[ 23.068004] ---[ end trace a981c9cfc87a2d66 ]---
------------------------------------------------------------------------------
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Namespaces and devices
From: Martín Ferrari @ 2010-05-21 16:27 UTC (permalink / raw)
To: netdev; +Cc: Mathieu Lacage
Hi,
Sorry if this is a dumb question, but I couldn't find any
documentation that matches the current behaviour... So I don't know if
what I see is what is intended, or if it's a bug.
I would like to know what is the exact behaviour re. devices when a
netns is destroyed, and which kind of devices can be moved.
According to http://lxc.sourceforge.net/network/configuration.php,
devices assigned to a netns should move to the main netns when the
former is destroyed. What I see is that the devices are deleted, at
least for veth and dummy devices. I also see a bug I previously
reported that caused an oops in some cases.
Also, I have read somewhere (now I cannot find it) that supposedly, I
should be able to move real devices to a netns, but I always get
Invalid argument errors.
Thanks.
--
Martín Ferrari
^ permalink raw reply
* Re: [RFC PATCH] net: add additional lock to qdisc to increase enqueue/dequeue fairness
From: Stephen Hemminger @ 2010-05-21 15:43 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, alexander.h.duyck, netdev
In-Reply-To: <1269382380.2915.40.camel@edumazet-laptop>
On Tue, 23 Mar 2010 23:13:00 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Le mardi 23 mars 2010 à 14:45 -0700, David Miller a écrit :
> > From: Eric Dumazet <eric.dumazet@gmail.com>
> > Date: Tue, 23 Mar 2010 21:54:27 +0100
> >
> > > Quite frankly, the real problem in this case is not the reduced
> > > throughput, but fact that one cpu can stay a long time doing the xmits
> > > to device, of skb queued by other cpus. This can hurt latencies a lot,
> > > for real time threads for example...
> > >
> > > I wonder if ticket spinlocks are not the problem. Maybe we want a
> > > variant of spinlocks, so that cpu doing transmits can get the lock
> > > before other cpus...
> >
> > I want to note that things operate the way they do now
> > intentionally.
> >
> > Herbert Xu and Jamal Hadi Salim were active in this area
> > about 4 years ago.
>
> Yes, but ticket spinlocks were added after their work (in 2008 - 2.6.25
> if I remember well) and change things.
>
> We want cpu owning __QDISC_STATE_RUNNING being able to re-get the lock
> as fast as possible. Alexander results can show the possible speedup.
What about having a special function (spin_lock_greedy?) that just ignores
the ticket mechanism and always assumes it has right to next ticket.
--
^ permalink raw reply
* bug fix patch lost: git problem or just incorrect merge?
From: James Bottomley @ 2010-05-21 15:41 UTC (permalink / raw)
To: Linus Torvalds, David Miller; +Cc: linux-kernel, netdev, linux-scsi
The patch in question is this one (upstream for a while):
commit d7d05548a62c87ee55b0c81933669177f885aa8d
Author: Mike Christie <michaelc@cs.wisc.edu>
Date: Wed Mar 31 14:41:35 2010 -0500
[SCSI] iscsi_tcp: fix relogin/shutdown hang
It's a simple one line change in iscsi_tcp.c (diff clipped):
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -599,7 +599,7 @@ static void iscsi_sw_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
- if (sock->sk->sk_sleep && waitqueue_active(sock->sk->sk_sleep)) {
+ if (sock->sk->sk_sleep) {
It was killed by this merge commit in the net-next tree:
commit 278554bd6579206921f5d8a523649a7a57f8850d
Merge: 5a147e8 cea0d76
Author: David S. Miller <davem@davemloft.net>
Date: Wed May 12 00:05:35 2010 -0700
However, the curious thing is that git seems to have lost trace of the
missing patch entirely: if I try to find it in linus' tree with a git
log -- drivers/scsi/iscsi_tcp.c, it doesn't show up. The merge commit
which killed it does list iscsi_tcp.c as a file conflict, but git show
on that commit doesn't list that file in the resolution diff ... even
though this is where it actually got killed.
Is this a git problem ... or is it just a mismerge in the net tree?
Either way, of course, we need the patch back ...
James
^ permalink raw reply
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