diff mbox

[7/9,ETH] : Start net device with carrier down

Message ID ebb4b9e34a594b9ca0fda9042bfa12bff9e9fac2.1221537369.git.tpiepho@freescale.com
State Rejected, archived
Delegated to: David Miller
Headers show

Commit Message

Trent Piepho Sept. 24, 2008, 9:20 p.m. UTC
Because it _is_ down when the device starts.

The device's carrier status is controlled via the functions
netif_carrier_on() and netif_carrier_off().  These set or clear a bit
indicating the lower level link aka carrier is down, and if the state
changed, they fire off a routing netlink event.

The problem is that when the device is first created and opened, the state
bit indicating the carrier is down isn't set, i.e. the state is wrong.
When the carrier comes up for the first time no netlink event is sent,
since the device state indicated the carrier was already up.

Signed-off-by: Trent Piepho <tpiepho@freescale.com>
CC: Andy Fleming <afleming@freescale.com>
---
 net/ethernet/eth.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

Comments

stephen hemminger Sept. 24, 2008, 9:32 p.m. UTC | #1
On Wed, 24 Sep 2008 14:20:55 -0700
Trent Piepho <tpiepho@freescale.com> wrote:

> Because it _is_ down when the device starts.
> 
> The device's carrier status is controlled via the functions
> netif_carrier_on() and netif_carrier_off().  These set or clear a bit
> indicating the lower level link aka carrier is down, and if the state
> changed, they fire off a routing netlink event.
> 
> The problem is that when the device is first created and opened, the state
> bit indicating the carrier is down isn't set, i.e. the state is wrong.
> When the carrier comes up for the first time no netlink event is sent,
> since the device state indicated the carrier was already up.
> 
> Signed-off-by: Trent Piepho <tpiepho@freescale.com>
> CC: Andy Fleming <afleming@freescale.com>
> ---
>  net/ethernet/eth.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index a80839b..cdba6d0 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -333,6 +333,7 @@ void ether_setup(struct net_device *dev)
>  	dev->addr_len		= ETH_ALEN;
>  	dev->tx_queue_len	= 1000;	/* Ethernet wants good queues */
>  	dev->flags		= IFF_BROADCAST|IFF_MULTICAST;
> +	dev->state		= 1 << __LINK_STATE_NOCARRIER;
>  
>  	memset(dev->broadcast, 0xFF, ETH_ALEN);
>  

This breaks devices that never call netif_carrier_on.

Standard practice is to call netif_carrier_off after allocation but before
register_netdev
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller Sept. 24, 2008, 10:24 p.m. UTC | #2
From: Trent Piepho <tpiepho@freescale.com>
Date: Wed, 24 Sep 2008 14:20:55 -0700

> The problem is that when the device is first created and opened, the state
> bit indicating the carrier is down isn't set, i.e. the state is wrong.
> When the carrier comes up for the first time no netlink event is sent,
> since the device state indicated the carrier was already up.

It works properly if the device driver does as it is supposed to,
which is invoke netif_carrier_off() in it's ->open() method in this
situation.

Please fix the drivers where this is not happening.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller Sept. 24, 2008, 10:25 p.m. UTC | #3
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Wed, 24 Sep 2008 14:32:03 -0700

> This breaks devices that never call netif_carrier_on.
> 
> Standard practice is to call netif_carrier_off after allocation but before
> register_netdev

Or in ->open()
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Trent Piepho Sept. 24, 2008, 10:43 p.m. UTC | #4
On Wed, 24 Sep 2008, David Miller wrote:
> From: Trent Piepho <tpiepho@freescale.com>
> Date: Wed, 24 Sep 2008 14:20:55 -0700
>
>> The problem is that when the device is first created and opened, the state
>> bit indicating the carrier is down isn't set, i.e. the state is wrong.
>> When the carrier comes up for the first time no netlink event is sent,
>> since the device state indicated the carrier was already up.
>
> It works properly if the device driver does as it is supposed to,
> which is invoke netif_carrier_off() in it's ->open() method in this
> situation.
>
> Please fix the drivers where this is not happening.

I tried that first, but if the carrier is already up, opening the interface
generated extra rt-netlink messages for carrier down then carrier up, even
though the carrier was up all along.

But maybe I didn't have it at the right place in the open() method.  I'll try
Stephen's suggestion to put it after allocation but before register_netdev()
and see if the problem is still there.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index a80839b..cdba6d0 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -333,6 +333,7 @@  void ether_setup(struct net_device *dev)
 	dev->addr_len		= ETH_ALEN;
 	dev->tx_queue_len	= 1000;	/* Ethernet wants good queues */
 	dev->flags		= IFF_BROADCAST|IFF_MULTICAST;
+	dev->state		= 1 << __LINK_STATE_NOCARRIER;
 
 	memset(dev->broadcast, 0xFF, ETH_ALEN);