Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next] myri10ge: fix truesize underestimation
From: Andrew Gallatin @ 2011-10-20 21:04 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Jon Mason, David Miller, netdev
In-Reply-To: <1319144356.2854.36.camel@edumazet-laptop>

On 10/20/11 16:59, Eric Dumazet wrote:
> Le jeudi 20 octobre 2011 à 16:45 -0400, Andrew Gallatin a écrit :
>> On 10/20/11 16:44, Eric Dumazet wrote:
>>> Le jeudi 20 octobre 2011 à 15:33 -0500, Jon Mason a écrit :
>>>> On Thu, Oct 20, 2011 at 3:10 PM, Eric Dumazet<eric.dumazet@gmail.com>   wrote:
>>>>> skb->truesize must account for allocated memory, not the used part of
>>>>> it. Doing this work is important to avoid unexpected OOM situations.
>>>>>
>>>>> Signed-off-by: Eric Dumazet<eric.dumazet@gmail.com>
>>>>
>>>> Acked-by: Jon Mason<mason@myri.com>
>>>
>>> Thanks for reviewing Jon !
>>>
>>>
>>
>> Please wait a second..  I think the patch is incorrect.
>>
>> There is already code in myri10ge_rx_skb_build() which
>> attempts to set the truesize.  However, it sets it to
>> the used, rather than the allocated size so it is apparently
>> incorrect.
>>
>> I'd prefer we fix that code.
>
> Well, I believe I did exactly that :)
>
> truesize of initial skb is fine.
>
> Then for everay frag added, you must add to skb-truesize the allocated
> memory for this frag.
>
> You add frags of a given size (small or big)
>
> In the end, its truesize += bytes * number_of_frags
>
> (bytes being small_size or big_size)
>
>

OK, I'm feeling foolish.  I somehow missed the first hunk
of your patch (some local change made it not apply cleanly, and
I did not notice that).

Yes, your patch is correct.  Sorry for the hassle!


Acked-by: Andrew Gallatin <gallatin@myri.com>

^ permalink raw reply

* Re: [patch] pktgen: bug when calling ndelay in x86 architectures
From: David Miller @ 2011-10-20 21:02 UTC (permalink / raw)
  To: eric.dumazet
  Cc: bhutchings, daniel.turull, netdev, robert, voravit, jens.laas
In-Reply-To: <1319144138.2854.33.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 22:55:38 +0200

> Well, I am not sure a patch is needed for net, since there is no bug,
> but maybe small inaccuracies ? Correct me if I misunderstood Daniel !

Ok that appears to be the case, so this is not something we should
deal with in the 'net' tree.

The constant ndelay() case would purposely cause a build failure for
values larger than 40000, but the specific call site we are discussing
in pktgen is never constant and therefore should would never trigger
that bug check.

>> Eric, could you please formally submit this patch with proper
>> changelog etc.?
> 
> Sure !
> 
> [PATCH net-next] pktgen: remove ndelay() call

Applied, thanks!

^ permalink raw reply

* Re: [PATCH net-next] myri10ge: fix truesize underestimation
From: Eric Dumazet @ 2011-10-20 21:06 UTC (permalink / raw)
  To: Andrew Gallatin; +Cc: Jon Mason, David Miller, netdev
In-Reply-To: <4EA08CCB.8030207@myri.com>

Le jeudi 20 octobre 2011 à 17:04 -0400, Andrew Gallatin a écrit :

> OK, I'm feeling foolish.  I somehow missed the first hunk
> of your patch (some local change made it not apply cleanly, and
> I did not notice that).
> 
> Yes, your patch is correct.  Sorry for the hassle!
> 

No worry, thanks a lot for reviewing !

> 
> Acked-by: Andrew Gallatin <gallatin@myri.com>

^ permalink raw reply

* Re: [net-next-2.6 PATCH 0/8 RFC v2] macvlan: MAC Address filtering support for passthru mode
From: Roopa Prabhu @ 2011-10-20 21:06 UTC (permalink / raw)
  To: Rose, Gregory V, netdev@vger.kernel.org
  Cc: sri@us.ibm.com, dragos.tatulea@gmail.com, arnd@arndb.de,
	kvm@vger.kernel.org, mst@redhat.com, davem@davemloft.net,
	mchan@broadcom.com, dwang2@cisco.com, shemminger@vyatta.com,
	eric.dumazet@gmail.com, kaber@trash.net, benve@cisco.com
In-Reply-To: <43F901BD926A4E43B106BF17856F075501A19FF1D8@orsmsx508.amr.corp.intel.com>




On 10/20/11 1:43 PM, "Rose, Gregory V" <gregory.v.rose@intel.com> wrote:

>> -----Original Message-----
>> From: Roopa Prabhu [mailto:roprabhu@cisco.com]
>> Sent: Wednesday, October 19, 2011 3:30 PM
>> To: Rose, Gregory V; netdev@vger.kernel.org
>> Cc: sri@us.ibm.com; dragos.tatulea@gmail.com; arnd@arndb.de;
>> kvm@vger.kernel.org; mst@redhat.com; davem@davemloft.net;
>> mchan@broadcom.com; dwang2@cisco.com; shemminger@vyatta.com;
>> eric.dumazet@gmail.com; kaber@trash.net; benve@cisco.com
>> Subject: Re: [net-next-2.6 PATCH 0/8 RFC v2] macvlan: MAC Address
>> filtering support for passthru mode
>> 
>> 
>> 
>> 
>> On 10/19/11 2:06 PM, "Rose, Gregory V" <gregory.v.rose@intel.com> wrote:
>> 
>>>> -----Original Message-----
>>>> From: netdev-owner@vger.kernel.org [mailto:netdev-
>> owner@vger.kernel.org]
>>>> On Behalf Of Roopa Prabhu
>>>> Sent: Tuesday, October 18, 2011 11:26 PM
>>>> To: netdev@vger.kernel.org
>>>> Cc: sri@us.ibm.com; dragos.tatulea@gmail.com; arnd@arndb.de;
>>>> kvm@vger.kernel.org; mst@redhat.com; davem@davemloft.net;
>>>> mchan@broadcom.com; dwang2@cisco.com; shemminger@vyatta.com;
>>>> eric.dumazet@gmail.com; kaber@trash.net; benve@cisco.com
>>>> Subject: [net-next-2.6 PATCH 0/8 RFC v2] macvlan: MAC Address filtering
>>>> support for passthru mode
>>>> 
>>> 
>>> [snip...]
>>> 
>>>> 
>>>> 
>>>> Note: The choice of rtnl_link_ops was because I saw the use case for
>>>> this in virtual devices that need  to do filtering in sw like macvlan
>>>> and tun. Hw devices usually have filtering in hw with netdev->uc and
>>>> mc lists to indicate active filters. But I can move from rtnl_link_ops
>>>> to netdev_ops if that is the preferred way to go and if there is a
>>>> need to support this interface on all kinds of interfaces.
>>>> Please suggest.
>>> 
>>> I'm still digesting the rest of the RFC patches but I did want to
>> quickly jump
>>> in and push for adding this support in netdev_ops.  I would like to see
>> these
>>> features available in more devices than just macvtap and macvlan.  I can
>>> conceive
>>> of use cases for multiple HW MAC and VLAN filters for a VF device that
>> isn't
>>> owned by a macvlan/macvtap interface and only has netdev_ops support.
>> In this
>>> case it would be necessary to program the filters directly to the VF
>> device
>>> interface or PF interface (or lowerdev as you refer to it) instead of
>> going
>>> through macvlan/macvtap.
>>> 
>>> This work dovetails nicely with some work I've been doing and I'd be
>> very
>>> interested
>>> in helping move this forward if we could work out the details that would
>> allow
>>> support
>>> of the features we (and the community) require.
>> 
>> Great. Thanks. I will definitely be interested to get this patch working
>> for
>> any other use case you have.
>> 
>> Moving the ops to netdev should be trivial. You probably want the ops to
>> work on the VF via the PF, like the existing ndo_set_vf_mac etc.
> 
> That is correct, so we would need to add some way to pass the VF number to the
> op.
> In addition, there are use cases for multiple MAC address filters for the
> Physical
> Function (PF) so we would like to be able to identify to the netdev op that it
> is
> supposed to perform the action on the PF filters instead of a VF.
> 
> An example of this would be when an administrator has created some number of
> VFs
> for a given PF but is also running the PF in bridged (i.e. promiscuous) mode
> so that it
> can support purely SW emulated network connections in some VMs that have low
> network
> latency and bandwidth requirements while reserving the VFs for VMs that
> require the low latency, high throughput that directly assigned VFs can
> provide.  In this case an
> emulated SW interface in a VM is unable to properly communicate with VFs on
> the same
> PF because the emulated SW interface's MAC address isn't programmed into the
> HW filters
> on the PF.  If we could use this op to program the MAC address and VLAN
> filters of
> the emulated SW interfaces into the PF HW a VF could then properly communicate
> across
> the NIC's internal VEB to the emulated SW interfaces.
> 
>> Yes, lets work out the details and I can move this to netdev->ops. Let me
>> know.
> 
> I think essentially if you could add some parameter to the ops to specify
> whether it
> is addressing a VF or the PF and then if it is a VF further specify the VF
> number we
> would be very close to addressing the requirements of many valuable use cases
> in
> addition to the ones you have identified in your RFC.
> 
> Does that sound reasonable?
> 

Thanks for the details Greg. Sounds good. I will change it to provide netdev
ops with a vf argument and respin.

Thanks,
Roopa

^ permalink raw reply

* [RFC PATCH 0/17] Miscellaneous generic PHY layer improvements
From: Kyle Moffett @ 2011-10-20 21:00 UTC (permalink / raw)
  To: linux-kernel, netdev; +Cc: Kyle Moffett

Hello all,

I have had the following series of phylib improvements and bugfixes
kicking around in a GIT repository for over a year and I finally
decided to get around to submitting them.

They are some preparatory work for later patches that I am still
working on to support unidirectional ethernet links in phylib.

These patches are currently based on v3.1-rc9; I apologize if these
conflict with any existing ongoing work.  Please let me know and I am
happy to respin against the appropriate tree.

Cheers,
Kyle Moffett

--
Curious about my work on the Debian powerpcspe port?
I'm keeping a blog here: http://pureperl.blogspot.com/

^ permalink raw reply

* Re: [PATCH net-next] igb: fix a compile warning
From: David Miller @ 2011-10-20 21:09 UTC (permalink / raw)
  To: gregory.v.rose; +Cc: roy.qing.li, netdev
In-Reply-To: <43F901BD926A4E43B106BF17856F075501A1776E6B@orsmsx508.amr.corp.intel.com>

From: "Rose, Gregory V" <gregory.v.rose@intel.com>
Date: Wed, 19 Oct 2011 09:28:54 -0700

>> -----Original Message-----
>> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
>> On Behalf Of roy.qing.li@gmail.com
>> Sent: Wednesday, October 19, 2011 1:53 AM
>> To: netdev@vger.kernel.org
>> Subject: [PATCH net-next] igb: fix a compile warning
>> 
>> From: RongQing Li <roy.qing.li@gmail.com>
>> 
>> control these three function declarations and
>> definitions with same macro CONFIG_PCI_IOV
>> 
>> drivers/net/ethernet/intel/igb/igb_main.c:165:
>> warning: ‘igb_vf_configure’ declared ‘static’ but never defined
>> drivers/net/ethernet/intel/igb/igb_main.c:166:
>> warning: ‘igb_find_enabled_vfs’ declared ‘static’ but never defined
>> drivers/net/ethernet/intel/igb/igb_main.c:167:
>> warning: ‘igb_check_vf_assignment’ declared ‘static’ but never defined
>> 
>> Signed-off-by: RongQing Li <roy.qing.li@gmail.com>
> 
> Acked-by: Greg Rose <gregory.v.rose@intel.com>

Applied, thanks.

^ permalink raw reply

* Re: [RFC PATCH 05/17] phy_driver: Make .read_status()/.config_aneg() optional
From: Mike Frysinger @ 2011-10-20 21:10 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: linux-kernel, netdev, Randy Dunlap, Stephen Hemminger,
	David S. Miller, Greg Dietsche, Giuseppe Cavallaro, David Daney,
	Arnaud Patard, Grant Likely, Baruch Siach, Thorsten Schubert,
	David Decotigny, Andrew Morton, Lucas De Marchi,
	Marc Kleine-Budde, linux-doc
In-Reply-To: <1319144425-15547-6-git-send-email-Kyle.D.Moffett@boeing.com>

[-- Attachment #1: Type: Text/Plain, Size: 1165 bytes --]

On Thursday 20 October 2011 17:00:12 Kyle Moffett wrote:
> Approximately 90% of the PHY drivers follow the PHY layer docs and
> simply use &genphy_read_status and &genphy_config_aneg.  There would
> seem to be little point in requiring them all to manually specify those
> functions.

well, it does make sense if you think about the compile vs build time 
overhead.  yes, your patch does make things much nicer to read, and a little 
easier to maintain the source.  however, it adds runtime overhead (checking 
the func pointers) while the func pointer storage is unchanged (it's now a 
NULL pointer instead of pointing to the genphy funcs).  personally, i think 
the savings in runtime and smaller compiled code is more important.  so i'm 
going to NAK this.  sorry.

> This patch makes it much easier for subsequent patches to split and
> refactor the functionality of the .config_aneg() method.
> 
> Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
> ---
>  Documentation/networking/phy.txt |   13 +++++--------
>  drivers/net/phy/bcm63xx.c        |    4 ----

hrm, what tree are you using ?  this driver is not in mainline.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH net-next] tcp: remove unused tcp_fin() parameters
From: Eric Dumazet @ 2011-10-20 21:11 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

tcp_fin() only needs socket pointer, we can remove skb and th params.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 net/ipv4/tcp_input.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 1e848b2..6f7fef9 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4127,7 +4127,7 @@ static void tcp_reset(struct sock *sk)
  *
  *	If we are in FINWAIT-2, a received FIN moves us to TIME-WAIT.
  */
-static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
+static void tcp_fin(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
@@ -4398,7 +4398,7 @@ static void tcp_ofo_queue(struct sock *sk)
 		__skb_queue_tail(&sk->sk_receive_queue, skb);
 		tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;
 		if (tcp_hdr(skb)->fin)
-			tcp_fin(skb, sk, tcp_hdr(skb));
+			tcp_fin(sk);
 	}
 }
 
@@ -4480,7 +4480,7 @@ queue_and_out:
 		if (skb->len)
 			tcp_event_data_recv(sk, skb);
 		if (th->fin)
-			tcp_fin(skb, sk, th);
+			tcp_fin(sk);
 
 		if (!skb_queue_empty(&tp->out_of_order_queue)) {
 			tcp_ofo_queue(sk);

^ permalink raw reply related

* Re: [PATCHv2] ll_temac: Add support for ethtool
From: David Miller @ 2011-10-20 21:12 UTC (permalink / raw)
  To: ricardo.ribalda
  Cc: ian.campbell, jeffrey.t.kirsher, grant.likely, jpirko, netdev,
	linux-kernel
In-Reply-To: <1319009725-7869-1-git-send-email-ricardo.ribalda@gmail.com>

From: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Date: Wed, 19 Oct 2011 09:35:25 +0200

> This patch enables the ethtool interface. The implementation is done
> using the libphy helper functions.

Applied, thanks.

In the future, please put the reviewed-by and signoffs before the "---"
otherwise automated tools will omit it from the final commit message.

^ permalink raw reply

* [RFC PATCH 06/17] phy_driver: Add and use phy_driver_[un]register_multiple()
From: Kyle Moffett @ 2011-10-20 21:00 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: Kyle Moffett, David S. Miller, Greg Dietsche, Giuseppe Cavallaro,
	David Daney, Arnaud Patard, Grant Likely, Baruch Siach,
	Stephen Hemminger, Lucas De Marchi, Marc Kleine-Budde,
	Andrew Morton, Mike Frysinger
In-Reply-To: <1319144425-15547-1-git-send-email-Kyle.D.Moffett@boeing.com>

Several of the PHY drivers are registering dozens of "phy_driver"
structures at load-time, with different IDs and variations on methods.
As a result, the error handling is exceptionally ugly.

The "marvell" driver already uses an array of "struct phy_driver" and
iterates over that to add the drivers, but even then its error handling
contains a bug (it will not unregister array item 0 on failure).

To resolve these problems, new functions phy_driver_register_multiple()
and phy_driver_unregister_multiple() are added which take an array and a
number of drivers and iterate over them internally.

All of the PHY driver files which register more than one "phy_driver"
are modified to use the new helpers.  This is a sizable net removal of
about 260 lines of code.

Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
---
 drivers/net/phy/bcm63xx.c    |   30 +++--------
 drivers/net/phy/broadcom.c   |  118 ++++++------------------------------------
 drivers/net/phy/cicada.c     |   32 +++---------
 drivers/net/phy/davicom.c    |   40 +++-----------
 drivers/net/phy/icplus.c     |   21 +++-----
 drivers/net/phy/lxt.c        |   40 +++-----------
 drivers/net/phy/marvell.c    |   22 ++------
 drivers/net/phy/micrel.c     |   61 ++++------------------
 drivers/net/phy/phy_device.c |   32 +++++++++++
 drivers/net/phy/realtek.c    |    6 +--
 drivers/net/phy/smsc.c       |   63 ++++-------------------
 drivers/net/phy/ste10Xp.c    |   20 +++-----
 drivers/net/phy/vitesse.c    |   45 ++++++----------
 include/linux/phy.h          |    2 +
 14 files changed, 138 insertions(+), 394 deletions(-)

diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c
index c455f02..3b4258d 100644
--- a/drivers/net/phy/bcm63xx.c
+++ b/drivers/net/phy/bcm63xx.c
@@ -74,7 +74,7 @@ static int bcm63xx_config_intr(struct phy_device *phydev)
 	return err;
 }
 
-static struct phy_driver bcm63xx_1_driver = {
+static struct phy_driver bcm63xx_drivers[] = { {
 	.phy_id		= 0x00406000,
 	.phy_id_mask	= 0xfffffc00,
 	.name		= "Broadcom BCM63XX (1)",
@@ -85,10 +85,8 @@ static struct phy_driver bcm63xx_1_driver = {
 	.ack_interrupt	= bcm63xx_ack_interrupt,
 	.config_intr	= bcm63xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-/* same phy as above, with just a different OUI */
-static struct phy_driver bcm63xx_2_driver = {
+}, {
+	/* same phy as above, with just a different OUI */
 	.phy_id		= 0x002bdc00,
 	.phy_id_mask	= 0xfffffc00,
 	.name		= "Broadcom BCM63XX (2)",
@@ -98,30 +96,18 @@ static struct phy_driver bcm63xx_2_driver = {
 	.ack_interrupt	= bcm63xx_ack_interrupt,
 	.config_intr	= bcm63xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
+} };
 
 static int __init bcm63xx_phy_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register(&bcm63xx_1_driver);
-	if (ret)
-		goto out_63xx_1;
-	ret = phy_driver_register(&bcm63xx_2_driver);
-	if (ret)
-		goto out_63xx_2;
-	return ret;
-
-out_63xx_2:
-	phy_driver_unregister(&bcm63xx_1_driver);
-out_63xx_1:
-	return ret;
+	return phy_driver_register_multiple(bcm63xx_drivers,
+			ARRAY_SIZE(bcm63xx_drivers));
 }
 
 static void __exit bcm63xx_phy_exit(void)
 {
-	phy_driver_unregister(&bcm63xx_1_driver);
-	phy_driver_unregister(&bcm63xx_2_driver);
+	phy_driver_unregister_multiple(bcm63xx_drivers,
+			ARRAY_SIZE(bcm63xx_drivers));
 }
 
 module_init(bcm63xx_phy_init);
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index f220264..1b83f75 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -684,7 +684,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
 	return err;
 }
 
-static struct phy_driver bcm5411_driver = {
+static struct phy_driver broadcom_drivers[] = { {
 	.phy_id		= PHY_ID_BCM5411,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5411",
@@ -695,9 +695,7 @@ static struct phy_driver bcm5411_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5421_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM5421,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5421",
@@ -708,9 +706,7 @@ static struct phy_driver bcm5421_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5461_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM5461,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5461",
@@ -721,9 +717,7 @@ static struct phy_driver bcm5461_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5464_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM5464,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5464",
@@ -734,9 +728,7 @@ static struct phy_driver bcm5464_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5481_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM5481,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5481",
@@ -748,9 +740,7 @@ static struct phy_driver bcm5481_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5482_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM5482,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5482",
@@ -762,9 +752,7 @@ static struct phy_driver bcm5482_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm50610_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM50610,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM50610",
@@ -775,9 +763,7 @@ static struct phy_driver bcm50610_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm50610m_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM50610M,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM50610M",
@@ -788,9 +774,7 @@ static struct phy_driver bcm50610m_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm57780_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM57780,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM57780",
@@ -801,9 +785,7 @@ static struct phy_driver bcm57780_driver = {
 	.ack_interrupt	= bcm54xx_ack_interrupt,
 	.config_intr	= bcm54xx_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcmac131_driver = {
+}, {
 	.phy_id		= PHY_ID_BCMAC131,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCMAC131",
@@ -814,9 +796,7 @@ static struct phy_driver bcmac131_driver = {
 	.ack_interrupt	= brcm_fet_ack_interrupt,
 	.config_intr	= brcm_fet_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
-
-static struct phy_driver bcm5241_driver = {
+}, {
 	.phy_id		= PHY_ID_BCM5241,
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "Broadcom BCM5241",
@@ -827,84 +807,18 @@ static struct phy_driver bcm5241_driver = {
 	.ack_interrupt	= brcm_fet_ack_interrupt,
 	.config_intr	= brcm_fet_config_intr,
 	.driver		= { .owner = THIS_MODULE },
-};
+} };
 
 static int __init broadcom_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register(&bcm5411_driver);
-	if (ret)
-		goto out_5411;
-	ret = phy_driver_register(&bcm5421_driver);
-	if (ret)
-		goto out_5421;
-	ret = phy_driver_register(&bcm5461_driver);
-	if (ret)
-		goto out_5461;
-	ret = phy_driver_register(&bcm5464_driver);
-	if (ret)
-		goto out_5464;
-	ret = phy_driver_register(&bcm5481_driver);
-	if (ret)
-		goto out_5481;
-	ret = phy_driver_register(&bcm5482_driver);
-	if (ret)
-		goto out_5482;
-	ret = phy_driver_register(&bcm50610_driver);
-	if (ret)
-		goto out_50610;
-	ret = phy_driver_register(&bcm50610m_driver);
-	if (ret)
-		goto out_50610m;
-	ret = phy_driver_register(&bcm57780_driver);
-	if (ret)
-		goto out_57780;
-	ret = phy_driver_register(&bcmac131_driver);
-	if (ret)
-		goto out_ac131;
-	ret = phy_driver_register(&bcm5241_driver);
-	if (ret)
-		goto out_5241;
-	return ret;
-
-out_5241:
-	phy_driver_unregister(&bcmac131_driver);
-out_ac131:
-	phy_driver_unregister(&bcm57780_driver);
-out_57780:
-	phy_driver_unregister(&bcm50610m_driver);
-out_50610m:
-	phy_driver_unregister(&bcm50610_driver);
-out_50610:
-	phy_driver_unregister(&bcm5482_driver);
-out_5482:
-	phy_driver_unregister(&bcm5481_driver);
-out_5481:
-	phy_driver_unregister(&bcm5464_driver);
-out_5464:
-	phy_driver_unregister(&bcm5461_driver);
-out_5461:
-	phy_driver_unregister(&bcm5421_driver);
-out_5421:
-	phy_driver_unregister(&bcm5411_driver);
-out_5411:
-	return ret;
+	return phy_driver_register_multiple(broadcom_drivers,
+			ARRAY_SIZE(broadcom_drivers));
 }
 
 static void __exit broadcom_exit(void)
 {
-	phy_driver_unregister(&bcm5241_driver);
-	phy_driver_unregister(&bcmac131_driver);
-	phy_driver_unregister(&bcm57780_driver);
-	phy_driver_unregister(&bcm50610m_driver);
-	phy_driver_unregister(&bcm50610_driver);
-	phy_driver_unregister(&bcm5482_driver);
-	phy_driver_unregister(&bcm5481_driver);
-	phy_driver_unregister(&bcm5464_driver);
-	phy_driver_unregister(&bcm5461_driver);
-	phy_driver_unregister(&bcm5421_driver);
-	phy_driver_unregister(&bcm5411_driver);
+	phy_driver_unregister_multiple(broadcom_drivers,
+			ARRAY_SIZE(broadcom_drivers));
 }
 
 module_init(broadcom_init);
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c
index c409ca2..9c805cd 100644
--- a/drivers/net/phy/cicada.c
+++ b/drivers/net/phy/cicada.c
@@ -101,8 +101,8 @@ static int cis820x_config_intr(struct phy_device *phydev)
 	return err;
 }
 
-/* Cicada 8201, a.k.a Vitesse VSC8201 */
-static struct phy_driver cis8201_driver = {
+static struct phy_driver cicada_drivers[] = { {
+	/* Cicada 8201, a.k.a Vitesse VSC8201 */
 	.phy_id		= 0x000fc410,
 	.name		= "Cicada Cis8201",
 	.phy_id_mask	= 0x000ffff0,
@@ -112,10 +112,7 @@ static struct phy_driver cis8201_driver = {
 	.ack_interrupt	= &cis820x_ack_interrupt,
 	.config_intr	= &cis820x_config_intr,
 	.driver 	= { .owner = THIS_MODULE,},
-};
-
-/* Cicada 8204 */
-static struct phy_driver cis8204_driver = {
+}, {
 	.phy_id		= 0x000fc440,
 	.name		= "Cicada Cis8204",
 	.phy_id_mask	= 0x000fffc0,
@@ -125,31 +122,18 @@ static struct phy_driver cis8204_driver = {
 	.ack_interrupt	= &cis820x_ack_interrupt,
 	.config_intr	= &cis820x_config_intr,
 	.driver 	= { .owner = THIS_MODULE,},
-};
+} };
 
 static int __init cicada_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register(&cis8204_driver);
-	if (ret)
-		goto err1;
-
-	ret = phy_driver_register(&cis8201_driver);
-	if (ret)
-		goto err2;
-	return 0;
-
-err2:
-	phy_driver_unregister(&cis8204_driver);
-err1:
-	return ret;
+	return phy_driver_register_multiple(cicada_drivers,
+			ARRAY_SIZE(cicada_drivers));
 }
 
 static void __exit cicada_exit(void)
 {
-	phy_driver_unregister(&cis8204_driver);
-	phy_driver_unregister(&cis8201_driver);
+	phy_driver_unregister_multiple(cicada_drivers,
+			ARRAY_SIZE(cicada_drivers));
 }
 
 module_init(cicada_init);
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 5249e1e..435be46 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -149,7 +149,7 @@ static int dm9161_ack_interrupt(struct phy_device *phydev)
 	return (err < 0) ? err : 0;
 }
 
-static struct phy_driver dm9161e_driver = {
+static struct phy_driver davicom_drivers[] = { {
 	.phy_id		= 0x0181b880,
 	.name		= "Davicom DM9161E",
 	.phy_id_mask	= 0x0ffffff0,
@@ -157,9 +157,7 @@ static struct phy_driver dm9161e_driver = {
 	.config_init	= dm9161_config_init,
 	.config_aneg	= dm9161_config_aneg,
 	.driver		= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver dm9161a_driver = {
+}, {
 	.phy_id		= 0x0181b8a0,
 	.name		= "Davicom DM9161A",
 	.phy_id_mask	= 0x0ffffff0,
@@ -167,9 +165,7 @@ static struct phy_driver dm9161a_driver = {
 	.config_init	= dm9161_config_init,
 	.config_aneg	= dm9161_config_aneg,
 	.driver		= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver dm9131_driver = {
+}, {
 	.phy_id		= 0x00181b80,
 	.name		= "Davicom DM9131",
 	.phy_id_mask	= 0x0ffffff0,
@@ -178,38 +174,18 @@ static struct phy_driver dm9131_driver = {
 	.ack_interrupt	= dm9161_ack_interrupt,
 	.config_intr	= dm9161_config_intr,
 	.driver		= { .owner = THIS_MODULE,},
-};
+} };
 
 static int __init davicom_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register(&dm9161e_driver);
-	if (ret)
-		goto err1;
-
-	ret = phy_driver_register(&dm9161a_driver);
-	if (ret)
-		goto err2;
-
-	ret = phy_driver_register(&dm9131_driver);
-	if (ret)
-		goto err3;
-	return 0;
-
- err3:
-	phy_driver_unregister(&dm9161a_driver);
- err2:
-	phy_driver_unregister(&dm9161e_driver);
- err1:
-	return ret;
+	return phy_driver_register_multiple(davicom_drivers,
+			ARRAY_SIZE(davicom_drivers));
 }
 
 static void __exit davicom_exit(void)
 {
-	phy_driver_unregister(&dm9161e_driver);
-	phy_driver_unregister(&dm9161a_driver);
-	phy_driver_unregister(&dm9131_driver);
+	phy_driver_unregister_multiple(davicom_drivers,
+			ARRAY_SIZE(davicom_drivers));
 }
 
 module_init(davicom_init);
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 28a190e..b23c78f 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -131,7 +131,7 @@ static int ip175c_config_aneg(struct phy_device *phydev)
 	return 0;
 }
 
-static struct phy_driver ip175c_driver = {
+static struct phy_driver icplus_drivers[] = { {
 	.phy_id		= 0x02430d80,
 	.name		= "ICPlus IP175C",
 	.phy_id_mask	= 0x0ffffff0,
@@ -142,9 +142,7 @@ static struct phy_driver ip175c_driver = {
 	.suspend	= genphy_suspend,
 	.resume		= genphy_resume,
 	.driver		= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ip1001_driver = {
+}, {
 	.phy_id		= 0x02430d90,
 	.name		= "ICPlus IP1001",
 	.phy_id_mask	= 0x0ffffff0,
@@ -154,23 +152,18 @@ static struct phy_driver ip1001_driver = {
 	.suspend	= genphy_suspend,
 	.resume		= genphy_resume,
 	.driver		= { .owner = THIS_MODULE,},
-};
+} };
 
 static int __init icplus_init(void)
 {
-	int ret = 0;
-
-	ret = phy_driver_register(&ip1001_driver);
-	if (ret < 0)
-		return -ENODEV;
-
-	return phy_driver_register(&ip175c_driver);
+	return phy_driver_register_multiple(icplus_drivers,
+			ARRAY_SIZE(icplus_drivers));
 }
 
 static void __exit icplus_exit(void)
 {
-	phy_driver_unregister(&ip1001_driver);
-	phy_driver_unregister(&ip175c_driver);
+	phy_driver_unregister_multiple(icplus_drivers,
+			ARRAY_SIZE(icplus_drivers));
 }
 
 module_init(icplus_init);
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index 0ed7e51..902d2d1 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -149,7 +149,7 @@ static int lxt973_config_aneg(struct phy_device *phydev)
 	return phydev->priv ? 0 : genphy_config_aneg(phydev);
 }
 
-static struct phy_driver lxt970_driver = {
+static struct phy_driver lxt_drivers[] = { {
 	.phy_id		= 0x78100000,
 	.name		= "LXT970",
 	.phy_id_mask	= 0xfffffff0,
@@ -159,9 +159,7 @@ static struct phy_driver lxt970_driver = {
 	.ack_interrupt	= lxt970_ack_interrupt,
 	.config_intr	= lxt970_config_intr,
 	.driver 	= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver lxt971_driver = {
+}, {
 	.phy_id		= 0x001378e0,
 	.name		= "LXT971",
 	.phy_id_mask	= 0xfffffff0,
@@ -170,9 +168,7 @@ static struct phy_driver lxt971_driver = {
 	.ack_interrupt	= lxt971_ack_interrupt,
 	.config_intr	= lxt971_config_intr,
 	.driver 	= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver lxt973_driver = {
+}, {
 	.phy_id		= 0x00137a10,
 	.name		= "LXT973",
 	.phy_id_mask	= 0xfffffff0,
@@ -181,38 +177,18 @@ static struct phy_driver lxt973_driver = {
 	.probe		= lxt973_probe,
 	.config_aneg	= lxt973_config_aneg,
 	.driver 	= { .owner = THIS_MODULE,},
-};
+} };
 
 static int __init lxt_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register(&lxt970_driver);
-	if (ret)
-		goto err1;
-
-	ret = phy_driver_register(&lxt971_driver);
-	if (ret)
-		goto err2;
-
-	ret = phy_driver_register(&lxt973_driver);
-	if (ret)
-		goto err3;
-	return 0;
-
- err3:
-	phy_driver_unregister(&lxt971_driver);
- err2:
-	phy_driver_unregister(&lxt970_driver);
- err1:
-	return ret;
+	return phy_driver_register_multiple(lxt_drivers,
+			ARRAY_SIZE(lxt_drivers));
 }
 
 static void __exit lxt_exit(void)
 {
-	phy_driver_unregister(&lxt970_driver);
-	phy_driver_unregister(&lxt971_driver);
-	phy_driver_unregister(&lxt973_driver);
+	phy_driver_unregister_multiple(lxt_drivers,
+			ARRAY_SIZE(lxt_drivers));
 }
 
 module_init(lxt_init);
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index e4beb96..9aaae96 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -832,28 +832,14 @@ static struct phy_driver marvell_drivers[] = {
 
 static int __init marvell_init(void)
 {
-	int ret;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) {
-		ret = phy_driver_register(&marvell_drivers[i]);
-
-		if (ret) {
-			while (i-- > 0)
-				phy_driver_unregister(&marvell_drivers[i]);
-			return ret;
-		}
-	}
-
-	return 0;
+	return phy_driver_register_multiple(marvell_drivers,
+			ARRAY_SIZE(marvell_drivers));
 }
 
 static void __exit marvell_exit(void)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++)
-		phy_driver_unregister(&marvell_drivers[i]);
+	phy_driver_unregister_multiple(marvell_drivers,
+			ARRAY_SIZE(marvell_drivers));
 }
 
 module_init(marvell_init);
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 1404b3c..1359a2e 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -114,7 +114,7 @@ static int ks8051_config_init(struct phy_device *phydev)
 	return 0;
 }
 
-static struct phy_driver ks8737_driver = {
+static struct phy_driver ksphy_drivers[] = { {
 	.phy_id		= PHY_ID_KS8737,
 	.phy_id_mask	= 0x00fffff0,
 	.name		= "Micrel KS8737",
@@ -124,9 +124,7 @@ static struct phy_driver ks8737_driver = {
 	.ack_interrupt	= kszphy_ack_interrupt,
 	.config_intr	= ks8737_config_intr,
 	.driver		= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ks8041_driver = {
+}, {
 	.phy_id		= PHY_ID_KS8041,
 	.phy_id_mask	= 0x00fffff0,
 	.name		= "Micrel KS8041",
@@ -137,9 +135,7 @@ static struct phy_driver ks8041_driver = {
 	.ack_interrupt	= kszphy_ack_interrupt,
 	.config_intr	= kszphy_config_intr,
 	.driver		= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ks8051_driver = {
+}, {
 	.phy_id		= PHY_ID_KS8051,
 	.phy_id_mask	= 0x00fffff0,
 	.name		= "Micrel KS8051",
@@ -150,9 +146,7 @@ static struct phy_driver ks8051_driver = {
 	.ack_interrupt	= kszphy_ack_interrupt,
 	.config_intr	= kszphy_config_intr,
 	.driver		= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ks8001_driver = {
+}, {
 	.phy_id		= PHY_ID_KS8001,
 	.name		= "Micrel KS8001 or KS8721",
 	.phy_id_mask	= 0x00fffff0,
@@ -162,9 +156,7 @@ static struct phy_driver ks8001_driver = {
 	.ack_interrupt	= kszphy_ack_interrupt,
 	.config_intr	= kszphy_config_intr,
 	.driver		= { .owner = THIS_MODULE,},
-};
-
-static struct phy_driver ksz9021_driver = {
+}, {
 	.phy_id		= PHY_ID_KSZ9021,
 	.phy_id_mask	= 0x000fff10,
 	.name		= "Micrel KSZ9021 Gigabit PHY",
@@ -175,51 +167,18 @@ static struct phy_driver ksz9021_driver = {
 	.ack_interrupt	= kszphy_ack_interrupt,
 	.config_intr	= ksz9021_config_intr,
 	.driver		= { .owner = THIS_MODULE, },
-};
+} };
 
 static int __init ksphy_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register(&ks8001_driver);
-	if (ret)
-		goto err1;
-
-	ret = phy_driver_register(&ksz9021_driver);
-	if (ret)
-		goto err2;
-
-	ret = phy_driver_register(&ks8737_driver);
-	if (ret)
-		goto err3;
-	ret = phy_driver_register(&ks8041_driver);
-	if (ret)
-		goto err4;
-	ret = phy_driver_register(&ks8051_driver);
-	if (ret)
-		goto err5;
-
-	return 0;
-
-err5:
-	phy_driver_unregister(&ks8041_driver);
-err4:
-	phy_driver_unregister(&ks8737_driver);
-err3:
-	phy_driver_unregister(&ksz9021_driver);
-err2:
-	phy_driver_unregister(&ks8001_driver);
-err1:
-	return ret;
+	return phy_driver_register_multiple(ksphy_drivers,
+			ARRAY_SIZE(ksphy_drivers));
 }
 
 static void __exit ksphy_exit(void)
 {
-	phy_driver_unregister(&ks8001_driver);
-	phy_driver_unregister(&ks8737_driver);
-	phy_driver_unregister(&ksz9021_driver);
-	phy_driver_unregister(&ks8041_driver);
-	phy_driver_unregister(&ks8051_driver);
+	phy_driver_unregister_multiple(ksphy_drivers,
+			ARRAY_SIZE(ksphy_drivers));
 }
 
 module_init(ksphy_init);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f1d8352..8990e87 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1012,6 +1012,38 @@ void phy_driver_unregister(struct phy_driver *drv)
 }
 EXPORT_SYMBOL(phy_driver_unregister);
 
+/**
+ * phy_driver_register_multiple - register an array of phy_drivers
+ * @drivers: array of phy_drivers to register
+ */
+int phy_driver_register_multiple(struct phy_driver *drivers,
+		unsigned long nr_drivers)
+{
+	unsigned long i;
+	for (i = 0; i < nr_drivers; i++) {
+		int retval = phy_driver_register(&drivers[i]);
+		if (retval) {
+			/*
+			 * A failure occurred, so unregister everything that
+			 * was already successfully registered.
+			 */
+			phy_driver_unregister_multiple__(drivers, i);
+			return retval;
+		}
+	}
+	return 0;
+}
+EXPORT_SYMBOL(phy_driver_register_multiple);
+
+void phy_driver_unregister_multiple(struct phy_driver *drivers,
+		unsigned long nr_drivers)
+{
+	unsigned long i;
+	for (i = nr_drivers; i > 0; i++)
+		phy_driver_unregister(drvs[i-1]);
+}
+EXPORT_SYMBOL(phy_driver_unregister_multiple);
+
 static struct phy_driver genphy_driver = {
 	.phy_id		= 0xffffffff,
 	.phy_id_mask	= 0xffffffff,
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 1a00deb..0172248 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -62,11 +62,7 @@ static struct phy_driver rtl821x_driver = {
 
 static int __init realtek_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register(&rtl821x_driver);
-
-	return ret;
+	return phy_driver_register(&rtl821x_driver);
 }
 
 static void __exit realtek_exit(void)
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index a8aa088..eb05b0f 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -80,7 +80,7 @@ static int lan911x_config_init(struct phy_device *phydev)
 	return smsc_phy_ack_interrupt(phydev);
 }
 
-static struct phy_driver lan83c185_driver = {
+static struct phy_driver smsc_drivers[] = { {
 	.phy_id		= 0x0007c0a0, /* OUI=0x00800f, Model#=0x0a */
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN83C185",
@@ -100,9 +100,7 @@ static struct phy_driver lan83c185_driver = {
 	.resume		= genphy_resume,
 
 	.driver		= { .owner = THIS_MODULE, }
-};
-
-static struct phy_driver lan8187_driver = {
+}, {
 	.phy_id		= 0x0007c0b0, /* OUI=0x00800f, Model#=0x0b */
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN8187",
@@ -122,9 +120,7 @@ static struct phy_driver lan8187_driver = {
 	.resume		= genphy_resume,
 
 	.driver		= { .owner = THIS_MODULE, }
-};
-
-static struct phy_driver lan8700_driver = {
+}, {
 	.phy_id		= 0x0007c0c0, /* OUI=0x00800f, Model#=0x0c */
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN8700",
@@ -144,9 +140,7 @@ static struct phy_driver lan8700_driver = {
 	.resume		= genphy_resume,
 
 	.driver		= { .owner = THIS_MODULE, }
-};
-
-static struct phy_driver lan911x_int_driver = {
+}, {
 	.phy_id		= 0x0007c0d0, /* OUI=0x00800f, Model#=0x0d */
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN911x Internal PHY",
@@ -166,9 +160,7 @@ static struct phy_driver lan911x_int_driver = {
 	.resume		= genphy_resume,
 
 	.driver		= { .owner = THIS_MODULE, }
-};
-
-static struct phy_driver lan8710_driver = {
+}, {
 	.phy_id		= 0x0007c0f0, /* OUI=0x00800f, Model#=0x0f */
 	.phy_id_mask	= 0xfffffff0,
 	.name		= "SMSC LAN8710/LAN8720",
@@ -188,53 +180,18 @@ static struct phy_driver lan8710_driver = {
 	.resume		= genphy_resume,
 
 	.driver		= { .owner = THIS_MODULE, }
-};
+} };
 
 static int __init smsc_init(void)
 {
-	int ret;
-
-	ret = phy_driver_register (&lan83c185_driver);
-	if (ret)
-		goto err1;
-
-	ret = phy_driver_register (&lan8187_driver);
-	if (ret)
-		goto err2;
-
-	ret = phy_driver_register (&lan8700_driver);
-	if (ret)
-		goto err3;
-
-	ret = phy_driver_register (&lan911x_int_driver);
-	if (ret)
-		goto err4;
-
-	ret = phy_driver_register (&lan8710_driver);
-	if (ret)
-		goto err5;
-
-	return 0;
-
-err5:
-	phy_driver_unregister (&lan911x_int_driver);
-err4:
-	phy_driver_unregister (&lan8700_driver);
-err3:
-	phy_driver_unregister (&lan8187_driver);
-err2:
-	phy_driver_unregister (&lan83c185_driver);
-err1:
-	return ret;
+	return phy_driver_register_multiple(smsc_drivers,
+			ARRAY_SIZE(smsc_drivers));
 }
 
 static void __exit smsc_exit(void)
 {
-	phy_driver_unregister (&lan8710_driver);
-	phy_driver_unregister (&lan911x_int_driver);
-	phy_driver_unregister (&lan8700_driver);
-	phy_driver_unregister (&lan8187_driver);
-	phy_driver_unregister (&lan83c185_driver);
+	phy_driver_unregister_multiple(smsc_drivers,
+			ARRAY_SIZE(smsc_drivers));
 }
 
 MODULE_DESCRIPTION("SMSC PHY driver");
diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c
index 45cde8f..855589c 100644
--- a/drivers/net/phy/ste10Xp.c
+++ b/drivers/net/phy/ste10Xp.c
@@ -81,7 +81,7 @@ static int ste10Xp_ack_interrupt(struct phy_device *phydev)
 	return 0;
 }
 
-static struct phy_driver ste101p_pdriver = {
+static struct phy_driver ste10Xp_drivers[] = { {
 	.phy_id = STE101P_PHY_ID,
 	.phy_id_mask = 0xfffffff0,
 	.name = "STe101p",
@@ -93,9 +93,7 @@ static struct phy_driver ste101p_pdriver = {
 	.suspend = genphy_suspend,
 	.resume = genphy_resume,
 	.driver = {.owner = THIS_MODULE,}
-};
-
-static struct phy_driver ste100p_pdriver = {
+}, {
 	.phy_id = STE100P_PHY_ID,
 	.phy_id_mask = 0xffffffff,
 	.name = "STe100p",
@@ -107,22 +105,18 @@ static struct phy_driver ste100p_pdriver = {
 	.suspend = genphy_suspend,
 	.resume = genphy_resume,
 	.driver = {.owner = THIS_MODULE,}
-};
+} };
 
 static int __init ste10Xp_init(void)
 {
-	int retval;
-
-	retval = phy_driver_register(&ste100p_pdriver);
-	if (retval < 0)
-		return retval;
-	return phy_driver_register(&ste101p_pdriver);
+	return phy_driver_register_multiple(ste10Xp_drivers,
+			ARRAY_SIZE(ste10Xp_drivers));
 }
 
 static void __exit ste10Xp_exit(void)
 {
-	phy_driver_unregister(&ste100p_pdriver);
-	phy_driver_unregister(&ste101p_pdriver);
+	phy_driver_unregister_multiple(ste10Xp_drivers,
+			ARRAY_SIZE(ste10Xp_drivers));
 }
 
 module_init(ste10Xp_init);
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 20ea438..82f808e 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -128,19 +128,6 @@ static int vsc82xx_config_intr(struct phy_device *phydev)
 	return err;
 }
 
-/* Vitesse 824x */
-static struct phy_driver vsc8244_driver = {
-	.phy_id		= PHY_ID_VSC8244,
-	.name		= "Vitesse VSC8244",
-	.phy_id_mask	= 0x000fffc0,
-	.features	= PHY_GBIT_FEATURES,
-	.flags		= PHY_HAS_INTERRUPT,
-	.config_init	= &vsc824x_config_init,
-	.ack_interrupt	= &vsc824x_ack_interrupt,
-	.config_intr	= &vsc82xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE,},
-};
-
 static int vsc8221_config_init(struct phy_device *phydev)
 {
 	int err;
@@ -153,8 +140,17 @@ static int vsc8221_config_init(struct phy_device *phydev)
 	   Options are 802.3Z SerDes or SGMII */
 }
 
-/* Vitesse 8221 */
-static struct phy_driver vsc8221_driver = {
+static struct phy_driver vitesse_drivers[] = { {
+	.phy_id		= PHY_ID_VSC8244,
+	.name		= "Vitesse VSC8244",
+	.phy_id_mask	= 0x000fffc0,
+	.features	= PHY_GBIT_FEATURES,
+	.flags		= PHY_HAS_INTERRUPT,
+	.config_init	= &vsc824x_config_init,
+	.ack_interrupt	= &vsc824x_ack_interrupt,
+	.config_intr	= &vsc82xx_config_intr,
+	.driver		= { .owner = THIS_MODULE, },
+}, {
 	.phy_id		= PHY_ID_VSC8221,
 	.phy_id_mask	= 0x000ffff0,
 	.name		= "Vitesse VSC8221",
@@ -163,26 +159,19 @@ static struct phy_driver vsc8221_driver = {
 	.config_init	= &vsc8221_config_init,
 	.ack_interrupt	= &vsc824x_ack_interrupt,
 	.config_intr	= &vsc82xx_config_intr,
-	.driver 	= { .owner = THIS_MODULE,},
-};
+	.driver		= { .owner = THIS_MODULE, },
+} };
 
 static int __init vsc82xx_init(void)
 {
-	int err;
-
-	err = phy_driver_register(&vsc8244_driver);
-	if (err < 0)
-		return err;
-	err = phy_driver_register(&vsc8221_driver);
-	if (err < 0)
-		phy_driver_unregister(&vsc8244_driver);
-	return err;
+	return phy_driver_register_multiple(vitesse_drivers,
+			ARRAY_SIZE(vitesse_drivers));
 }
 
 static void __exit vsc82xx_exit(void)
 {
-	phy_driver_unregister(&vsc8244_driver);
-	phy_driver_unregister(&vsc8221_driver);
+	phy_driver_unregister_multiple(vitesse_drivers,
+			ARRAY_SIZE(vitesse_drivers));
 }
 
 module_init(vsc82xx_init);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index a55a6c4..c6bbb38 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -505,7 +505,9 @@ int genphy_read_status(struct phy_device *phydev);
 int genphy_suspend(struct phy_device *phydev);
 int genphy_resume(struct phy_device *phydev);
 void phy_driver_unregister(struct phy_driver *drv);
+void phy_driver_unregister_multiple(struct phy_driver *drvs, unsigned long nr);
 int phy_driver_register(struct phy_driver *new_driver);
+int phy_driver_register_multiple(struct phy_driver *drvs, unsigned long nr);
 void phy_state_machine(struct work_struct *work);
 void phy_start_machine(struct phy_device *phydev,
 		void (*handler)(struct net_device *));
-- 
1.7.2.5

^ permalink raw reply related

* Re: [RFC PATCH 05/17] phy_driver: Make .read_status()/.config_aneg() optional
From: Mike Frysinger @ 2011-10-20 21:14 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: linux-kernel, netdev, Randy Dunlap, Stephen Hemminger,
	David S. Miller, Greg Dietsche, Giuseppe Cavallaro, David Daney,
	Arnaud Patard, Grant Likely, Baruch Siach, Thorsten Schubert,
	David Decotigny, Andrew Morton, Lucas De Marchi,
	Marc Kleine-Budde, linux-doc
In-Reply-To: <201110201710.17519.vapier@gentoo.org>

[-- Attachment #1: Type: Text/Plain, Size: 1601 bytes --]

On Thursday 20 October 2011 17:10:12 Mike Frysinger wrote:
> On Thursday 20 October 2011 17:00:12 Kyle Moffett wrote:
> > Approximately 90% of the PHY drivers follow the PHY layer docs and
> > simply use &genphy_read_status and &genphy_config_aneg.  There would
> > seem to be little point in requiring them all to manually specify those
> > functions.
> 
> well, it does make sense if you think about the compile vs build time
> overhead.  yes, your patch does make things much nicer to read, and a
> little easier to maintain the source.  however, it adds runtime overhead
> (checking the func pointers) while the func pointer storage is unchanged
> (it's now a NULL pointer instead of pointing to the genphy funcs). 
> personally, i think the savings in runtime and smaller compiled code is
> more important.  so i'm going to NAK this.  sorry.
> 
> > This patch makes it much easier for subsequent patches to split and
> > refactor the functionality of the .config_aneg() method.
> > 
> > Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
> > ---
> > 
> >  Documentation/networking/phy.txt |   13 +++++--------
> >  drivers/net/phy/bcm63xx.c        |    4 ----
> 
> hrm, what tree are you using ?  this driver is not in mainline.

ah, sorry, i was thinking this was u-boot since we were just having 
conversations there.

since this is Linux, and i don't have real standing in the general netdev 
community, i can't really NAK here.  but i think my comment still stands in 
that this patch makes things much worse than the minor code style improvement.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [RFC PATCH 06/17] phy_driver: Add and use phy_driver_[un]register_multiple()
From: Mike Frysinger @ 2011-10-20 21:15 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: linux-kernel, netdev, David S. Miller, Greg Dietsche,
	Giuseppe Cavallaro, David Daney, Arnaud Patard, Grant Likely,
	Baruch Siach, Stephen Hemminger, Lucas De Marchi,
	Marc Kleine-Budde, Andrew Morton
In-Reply-To: <1319144425-15547-7-git-send-email-Kyle.D.Moffett@boeing.com>

[-- Attachment #1: Type: Text/Plain, Size: 390 bytes --]

On Thursday 20 October 2011 17:00:13 Kyle Moffett wrote:
> +	return phy_driver_register_multiple(bcm63xx_drivers,
> +			ARRAY_SIZE(bcm63xx_drivers));

if only the arm ARRAY_AND_SIZE() macro could gain traction in the wider tree:
	return phy_driver_register_multiple(ARRAY_AND_SIZE(bcm63xx_drivers));

ignoring that, this patch looks cool

Acked-by: Mike Frysinger <vapier@gentoo.org>
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH net-next] net: constify skbuff and Qdisc elements
From: Eric Dumazet @ 2011-10-20 21:41 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Preliminary patch before tcp constification

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 include/linux/skbuff.h    |   17 +++++++++--------
 include/net/sch_generic.h |   24 ++++++++++++------------
 2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1ebf1ea..3411f22 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -853,9 +853,9 @@ static inline struct sk_buff *skb_unshare(struct sk_buff *skb,
  *	The reference count is not incremented and the reference is therefore
  *	volatile. Use with caution.
  */
-static inline struct sk_buff *skb_peek(struct sk_buff_head *list_)
+static inline struct sk_buff *skb_peek(const struct sk_buff_head *list_)
 {
-	struct sk_buff *list = ((struct sk_buff *)list_)->next;
+	struct sk_buff *list = ((const struct sk_buff *)list_)->next;
 	if (list == (struct sk_buff *)list_)
 		list = NULL;
 	return list;
@@ -874,9 +874,9 @@ static inline struct sk_buff *skb_peek(struct sk_buff_head *list_)
  *	The reference count is not incremented and the reference is therefore
  *	volatile. Use with caution.
  */
-static inline struct sk_buff *skb_peek_tail(struct sk_buff_head *list_)
+static inline struct sk_buff *skb_peek_tail(const struct sk_buff_head *list_)
 {
-	struct sk_buff *list = ((struct sk_buff *)list_)->prev;
+	struct sk_buff *list = ((const struct sk_buff *)list_)->prev;
 	if (list == (struct sk_buff *)list_)
 		list = NULL;
 	return list;
@@ -1830,7 +1830,7 @@ static inline dma_addr_t skb_frag_dma_map(struct device *dev,
  *	Returns true if modifying the header part of the cloned buffer
  *	does not requires the data to be copied.
  */
-static inline int skb_clone_writable(struct sk_buff *skb, unsigned int len)
+static inline int skb_clone_writable(const struct sk_buff *skb, unsigned int len)
 {
 	return !skb_header_cloned(skb) &&
 	       skb_headroom(skb) + len <= skb->hdr_len;
@@ -2451,7 +2451,8 @@ static inline bool skb_warn_if_lro(const struct sk_buff *skb)
 {
 	/* LRO sets gso_size but not gso_type, whereas if GSO is really
 	 * wanted then gso_type will be set. */
-	struct skb_shared_info *shinfo = skb_shinfo(skb);
+	const struct skb_shared_info *shinfo = skb_shinfo(skb);
+
 	if (skb_is_nonlinear(skb) && shinfo->gso_size != 0 &&
 	    unlikely(shinfo->gso_type == 0)) {
 		__skb_warn_lro_forwarding(skb);
@@ -2475,7 +2476,7 @@ static inline void skb_forward_csum(struct sk_buff *skb)
  * Instead of forcing ip_summed to CHECKSUM_NONE, we can
  * use this helper, to document places where we make this assertion.
  */
-static inline void skb_checksum_none_assert(struct sk_buff *skb)
+static inline void skb_checksum_none_assert(const struct sk_buff *skb)
 {
 #ifdef DEBUG
 	BUG_ON(skb->ip_summed != CHECKSUM_NONE);
@@ -2484,7 +2485,7 @@ static inline void skb_checksum_none_assert(struct sk_buff *skb)
 
 bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off);
 
-static inline bool skb_is_recycleable(struct sk_buff *skb, int skb_size)
+static inline bool skb_is_recycleable(const struct sk_buff *skb, int skb_size)
 {
 	if (irqs_disabled())
 		return false;
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 4fc88f3..2eb207e 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -46,14 +46,14 @@ struct qdisc_size_table {
 struct Qdisc {
 	int 			(*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
 	struct sk_buff *	(*dequeue)(struct Qdisc *dev);
-	unsigned		flags;
+	unsigned int		flags;
 #define TCQ_F_BUILTIN		1
 #define TCQ_F_INGRESS		2
 #define TCQ_F_CAN_BYPASS	4
 #define TCQ_F_MQROOT		8
 #define TCQ_F_WARN_NONWC	(1 << 16)
 	int			padded;
-	struct Qdisc_ops	*ops;
+	const struct Qdisc_ops	*ops;
 	struct qdisc_size_table	__rcu *stab;
 	struct list_head	list;
 	u32			handle;
@@ -224,7 +224,7 @@ struct qdisc_skb_cb {
 	long			data[];
 };
 
-static inline int qdisc_qlen(struct Qdisc *q)
+static inline int qdisc_qlen(const struct Qdisc *q)
 {
 	return q->q.qlen;
 }
@@ -239,12 +239,12 @@ static inline spinlock_t *qdisc_lock(struct Qdisc *qdisc)
 	return &qdisc->q.lock;
 }
 
-static inline struct Qdisc *qdisc_root(struct Qdisc *qdisc)
+static inline struct Qdisc *qdisc_root(const struct Qdisc *qdisc)
 {
 	return qdisc->dev_queue->qdisc;
 }
 
-static inline struct Qdisc *qdisc_root_sleeping(struct Qdisc *qdisc)
+static inline struct Qdisc *qdisc_root_sleeping(const struct Qdisc *qdisc)
 {
 	return qdisc->dev_queue->qdisc_sleeping;
 }
@@ -260,7 +260,7 @@ static inline struct Qdisc *qdisc_root_sleeping(struct Qdisc *qdisc)
  * root.  This is enforced by holding the RTNL semaphore, which
  * all users of this lock accessor must do.
  */
-static inline spinlock_t *qdisc_root_lock(struct Qdisc *qdisc)
+static inline spinlock_t *qdisc_root_lock(const struct Qdisc *qdisc)
 {
 	struct Qdisc *root = qdisc_root(qdisc);
 
@@ -268,7 +268,7 @@ static inline spinlock_t *qdisc_root_lock(struct Qdisc *qdisc)
 	return qdisc_lock(root);
 }
 
-static inline spinlock_t *qdisc_root_sleeping_lock(struct Qdisc *qdisc)
+static inline spinlock_t *qdisc_root_sleeping_lock(const struct Qdisc *qdisc)
 {
 	struct Qdisc *root = qdisc_root_sleeping(qdisc);
 
@@ -276,17 +276,17 @@ static inline spinlock_t *qdisc_root_sleeping_lock(struct Qdisc *qdisc)
 	return qdisc_lock(root);
 }
 
-static inline struct net_device *qdisc_dev(struct Qdisc *qdisc)
+static inline struct net_device *qdisc_dev(const struct Qdisc *qdisc)
 {
 	return qdisc->dev_queue->dev;
 }
 
-static inline void sch_tree_lock(struct Qdisc *q)
+static inline void sch_tree_lock(const struct Qdisc *q)
 {
 	spin_lock_bh(qdisc_root_sleeping_lock(q));
 }
 
-static inline void sch_tree_unlock(struct Qdisc *q)
+static inline void sch_tree_unlock(const struct Qdisc *q)
 {
 	spin_unlock_bh(qdisc_root_sleeping_lock(q));
 }
@@ -319,7 +319,7 @@ static inline unsigned int qdisc_class_hash(u32 id, u32 mask)
 }
 
 static inline struct Qdisc_class_common *
-qdisc_class_find(struct Qdisc_class_hash *hash, u32 id)
+qdisc_class_find(const struct Qdisc_class_hash *hash, u32 id)
 {
 	struct Qdisc_class_common *cl;
 	struct hlist_node *n;
@@ -393,7 +393,7 @@ static inline bool qdisc_all_tx_empty(const struct net_device *dev)
 }
 
 /* Are any of the TX qdiscs changing?  */
-static inline bool qdisc_tx_changing(struct net_device *dev)
+static inline bool qdisc_tx_changing(const struct net_device *dev)
 {
 	unsigned int i;
 	for (i = 0; i < dev->num_tx_queues; i++) {

^ permalink raw reply related

* Re: pull request: batman-adv 2011-10-18 (more regression fixes)
From: David Miller @ 2011-10-20 21:42 UTC (permalink / raw)
  To: lindner_marek-LWAfsSFWpa4
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
In-Reply-To: <1318971669-941-1-git-send-email-lindner_marek-LWAfsSFWpa4@public.gmane.org>

From: Marek Lindner <lindner_marek-LWAfsSFWpa4@public.gmane.org>
Date: Tue, 18 Oct 2011 23:01:07 +0200

> we have identified and fixed 2 more critical bugs in the linux-3.1
> code base. We are somewhat late in the 3.1 release cycle but hoped
> to take advantage of the delayed release to get these patches 
> included before the final version is out.

Pulled, thanks Marek.

^ permalink raw reply

* Re: [PATCH net-next] igbvf: fix truesize underestimation
From: David Miller @ 2011-10-20 21:42 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, jeffrey.t.kirsher
In-Reply-To: <1319138538.2854.9.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 21:22:18 +0200

> igbvf allocates half a page per skb fragment. We must account
> PAGE_SIZE/2 increments on skb->truesize, not the actual frag length.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next] myri10ge: fix truesize underestimation
From: David Miller @ 2011-10-20 21:42 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, mason
In-Reply-To: <1319141403.2854.17.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 22:10:03 +0200

> skb->truesize must account for allocated memory, not the used part of
> it. Doing this work is important to avoid unexpected OOM situations.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next] tcp: remove unused tcp_fin() parameters
From: David Miller @ 2011-10-20 21:44 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1319145084.2854.42.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 23:11:24 +0200

> tcp_fin() only needs socket pointer, we can remove skb and th params.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied, thanks Eric.

^ permalink raw reply

* Re: [PATCH net-next] net: constify skbuff and Qdisc elements
From: David Miller @ 2011-10-20 21:46 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1319146917.2854.46.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 20 Oct 2011 23:41:57 +0200

> Preliminary patch before tcp constification
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied, thanks Eric.

^ permalink raw reply

* Re: [PATCH] net: Fix driver name for mdio-gpio.c
From: David Miller @ 2011-10-20 21:48 UTC (permalink / raw)
  To: eibach; +Cc: linux-kernel, netdev, grant.likely
In-Reply-To: <1318943051-22432-1-git-send-email-eibach@gdsys.de>

From: Dirk Eibach <eibach@gdsys.de>
Date: Tue, 18 Oct 2011 15:04:11 +0200

> Since commit
> "7488876... dt/net: Eliminate users of of_platform_{,un}register_driver"
> there are two platform drivers named "mdio-gpio" registered.
> I renamed the of variant to "mdio-ofgpio".
> 
> Signed-off-by: Dirk Eibach <eibach@gdsys.de>

Applied, thanks.

^ permalink raw reply

* [PATCH] net: allow CAP_NET_RAW to set socket options IP{,V6}_TRANSPARENT
From: Maciej Żenczykowski @ 2011-10-20 22:10 UTC (permalink / raw)
  To: Maciej Żenczykowski; +Cc: David Miller, netdev, Maciej Żenczykowski
In-Reply-To: <20111020.003458.1034042223691970343.davem@davemloft.net>

From: Maciej Żenczykowski <maze@google.com>

Up till now the IP{,V6}_TRANSPARENT socket options (which actually set
the same bit in the socket struct) have required CAP_NET_ADMIN
privileges to set or clear the option.

- we make clearing the bit not require any privileges.
- we allow CAP_NET_ADMIN to set the bit (as before this change)
- we allow CAP_NET_RAW to set this bit, because raw
  sockets already pretty much effectively allow you
  to emulate socket transparency.

Signed-off-by: Maciej Żenczykowski <maze@google.com>
---
 include/linux/capability.h |    3 ++-
 net/ipv4/ip_sockglue.c     |    2 +-
 net/ipv6/ipv6_sockglue.c   |    2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/capability.h b/include/linux/capability.h
index c421123..a63d13d 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -198,7 +198,7 @@ struct cpu_vfs_cap_data {
 /* Allow modification of routing tables */
 /* Allow setting arbitrary process / process group ownership on
    sockets */
-/* Allow binding to any address for transparent proxying */
+/* Allow binding to any address for transparent proxying (also via NET_RAW) */
 /* Allow setting TOS (type of service) */
 /* Allow setting promiscuous mode */
 /* Allow clearing driver statistics */
@@ -210,6 +210,7 @@ struct cpu_vfs_cap_data {
 
 /* Allow use of RAW sockets */
 /* Allow use of PACKET sockets */
+/* Allow binding to any address for transparent proxying (also via NET_ADMIN) */
 
 #define CAP_NET_RAW          13
 
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 8905e92..f0dc3ad 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -961,7 +961,7 @@ mc_msf_out:
 		break;
 
 	case IP_TRANSPARENT:
-		if (!capable(CAP_NET_ADMIN)) {
+		if (!!val && !capable(CAP_NET_RAW) && !capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
 			break;
 		}
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 2fbda5f..c99e3ee 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -343,7 +343,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
 		break;
 
 	case IPV6_TRANSPARENT:
-		if (!capable(CAP_NET_ADMIN)) {
+		if (valbool && !capable(CAP_NET_ADMIN) && !capable(CAP_NET_RAW)) {
 			retv = -EPERM;
 			break;
 		}
-- 
1.7.3.1

^ permalink raw reply related

* Re: [PATCH] net: allow CAP_NET_RAW to set socket options IP{,V6}_TRANSPARENT
From: David Miller @ 2011-10-20 22:22 UTC (permalink / raw)
  To: zenczykowski; +Cc: maze, netdev
In-Reply-To: <1319148614-6739-1-git-send-email-zenczykowski@gmail.com>

From: Maciej Żenczykowski <zenczykowski@gmail.com>
Date: Thu, 20 Oct 2011 15:10:14 -0700

> From: Maciej Żenczykowski <maze@google.com>
> 
> Up till now the IP{,V6}_TRANSPARENT socket options (which actually set
> the same bit in the socket struct) have required CAP_NET_ADMIN
> privileges to set or clear the option.
> 
> - we make clearing the bit not require any privileges.
> - we allow CAP_NET_ADMIN to set the bit (as before this change)
> - we allow CAP_NET_RAW to set this bit, because raw
>   sockets already pretty much effectively allow you
>   to emulate socket transparency.
> 
> Signed-off-by: Maciej Żenczykowski <maze@google.com>

Applied, thanks.

^ permalink raw reply

* Re: [RFC PATCH 15/17] phy_device: Add "port" and "transciever" fields
From: Ben Hutchings @ 2011-10-20 23:27 UTC (permalink / raw)
  To: Kyle Moffett
  Cc: linux-kernel, netdev, David S. Miller, David Decotigny,
	Stephen Hemminger, Andrew Morton, Lucas De Marchi,
	Marc Kleine-Budde, Mike Frysinger
In-Reply-To: <1319144425-15547-16-git-send-email-Kyle.D.Moffett@boeing.com>

On Thu, 2011-10-20 at 17:00 -0400, Kyle Moffett wrote:
> Some PHYs have multiple software-selectable inputs and outputs,
> including RGMII, SGMII, SerDes, etc.  New fields are added to the
> "struct phy_device" for "port" and "transciever" to allow "ethtool" to
> switch outputs at runtime.  The defaults for the new fields are
> identical to the hardcoded values used previously.
> 
> This should make no functional changes to the PHY layer behavior, but
> it will allow later PHY/ethernet drivers to override those fields.
> 
> Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com>
> ---
>  drivers/net/phy/phy.c        |    4 ++--
>  drivers/net/phy/phy_device.c |    2 ++
>  include/linux/phy.h          |    4 ++++
>  3 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index c378f91..5f72055 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -290,9 +290,9 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
>  
>  	ethtool_cmd_speed_set(cmd, phydev->speed);
>  	cmd->duplex = phydev->duplex;
> -	cmd->port = PORT_MII;
> +	cmd->port = phydev->port;
>  	cmd->phy_address = phydev->addr;
> -	cmd->transceiver = XCVR_EXTERNAL;
> +	cmd->transceiver = phydev->transciever;

'transceiver' is spelt thus.

[...]
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -308,6 +308,10 @@ struct phy_device {
>  	u32 supported;
>  	u32 advertising;
>  
> +	/* The current port/xcvr info (Copper, Fibre, MII, Direct-Attach) */
> +	u8 port;
> +	u8 transceiver;
> +

And yet you got it right here.

Ben.

>  	int autoneg;
>  
>  	int link_timeout;

-- 
Ben Hutchings, Staff Engineer, Solarflare
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] ipvs: Fix compilation error in ip_vs.h for ip_vs_confirm_conntrack function.
From: Simon Horman @ 2011-10-21  1:25 UTC (permalink / raw)
  To: Krzysztof Wilczynski; +Cc: Patrick McHardy, netdev
In-Reply-To: <1319113084-7498-1-git-send-email-krzysztof.wilczynski@linux.com>

On Thu, Oct 20, 2011 at 01:18:04PM +0100, Krzysztof Wilczynski wrote:
> This is to address the following error during the compilation:
> 
>   In file included from kernel/sysctl_binary.c:6:
>   include/net/ip_vs.h:1406: error: expected identifier or ‘(’ before ‘{’ token
>   make[1]: *** [kernel/sysctl_binary.o] Error 1
>   make[1]: *** Waiting for unfinished jobs....
> 
> That manifests itself when CONFIG_IP_VS_NFCT is undefined in .config file.
> 
> Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
> ---
>  include/net/ip_vs.h |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index 139784e..de527d1 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -1395,7 +1395,7 @@ static inline void ip_vs_update_conntrack(struct sk_buff *skb,
>  {
>  }
>  
> -static inline int ip_vs_confirm_conntrack(struct sk_buff *skb);
> +static inline int ip_vs_confirm_conntrack(struct sk_buff *skb)
>  {
>  	return NF_ACCEPT;
>  }

Thanks Krzysztof,

that fixes a brown paper bag effort from me.

^ permalink raw reply

* [GIT PULL nf-next] IPVS
From: Simon Horman @ 2011-10-21  1:33 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
	Julian Anastasov, Krzysztof Wilczynski

Hi Pablo,

please consider pulling the following to get compile fix
and cleanup patches from Krzysztof Wilczynski.

The following changes since commit 2ca5b853f1dd81c605ddc8a55e06bdad85636597:

  netfilter: export NAT definitions through linux/netfilter_ipv4/nf_nat.h (2011-10-11 03:32:34 +0200)

are available in the git repository at:
  git://github.com/horms/ipvs-next.git master

Krzysztof Wilczynski (2):
      ipvs: Remove unused variable "cs" from ip_vs_leave function.
      ipvs: Fix compilation error in ip_vs.h for ip_vs_confirm_conntrack function.

 include/net/ip_vs.h             |    2 +-
 net/netfilter/ipvs/ip_vs_core.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

^ permalink raw reply

* [PATCH 1/2] ipvs: Remove unused variable "cs" from ip_vs_leave function.
From: Simon Horman @ 2011-10-21  1:33 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: lvs-devel, netdev, netfilter-devel, Wensong Zhang,
	Julian Anastasov, Krzysztof Wilczynski, Simon Horman
In-Reply-To: <1319160783-28422-1-git-send-email-horms@verge.net.au>

From: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>

This is to address the following warning during compilation time:

  net/netfilter/ipvs/ip_vs_core.c: In function ‘ip_vs_leave’:
  net/netfilter/ipvs/ip_vs_core.c:532: warning: unused variable ‘cs’

This variable is indeed no longer in use.

Signed-off-by: Krzysztof Wilczynski <krzysztof.wilczynski@linux.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
 net/netfilter/ipvs/ip_vs_core.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 46a8130..093cc32 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -529,7 +529,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
 	   a cache_bypass connection entry */
 	ipvs = net_ipvs(net);
 	if (ipvs->sysctl_cache_bypass && svc->fwmark && unicast) {
-		int ret, cs;
+		int ret;
 		struct ip_vs_conn *cp;
 		unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET &&
 				      iph.protocol == IPPROTO_UDP)?
-- 
1.7.6.3

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox