From 1ba959c6b342b314dfb01ca0a926ed6832c090b3 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 22 Apr 2008 17:40:50 +0100 Subject: [NETDEV] Add notion of link state Add ability for network devices to flag link up/down state to the networking core. Autobooting code will now wait for link-up before attempting DHCP. IPoIB reflects the Infiniband link state as the network device link state (which is not strictly correct; we also need a succesful IPoIB IPv4 broadcast group join), but is probably more informative. --- src/drivers/net/e1000/e1000.c | 3 +++ src/drivers/net/ipoib.c | 20 +++++++++++++++++++- src/drivers/net/legacy.c | 3 +++ src/drivers/net/mtnic.c | 3 +++ src/drivers/net/natsemi.c | 3 +++ src/drivers/net/pnic.c | 3 +++ src/drivers/net/rtl8139.c | 3 +++ 7 files changed, 37 insertions(+), 1 deletion(-) (limited to 'src/drivers/net') diff --git a/src/drivers/net/e1000/e1000.c b/src/drivers/net/e1000/e1000.c index 739217cf7..a9aa508ac 100644 --- a/src/drivers/net/e1000/e1000.c +++ b/src/drivers/net/e1000/e1000.c @@ -876,6 +876,9 @@ e1000_probe ( struct pci_device *pdev, e1000_get_hw_control ( adapter ); + /* Mark as link up; we don't yet handle link state */ + netdev_link_up ( netdev ); + if ( ( err = register_netdev ( netdev ) ) != 0) goto err_register; diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c index 3b915bf05..e3baa14f2 100644 --- a/src/drivers/net/ipoib.c +++ b/src/drivers/net/ipoib.c @@ -471,6 +471,12 @@ static int ipoib_transmit ( struct net_device *netdev, } iob_pull ( iobuf, ( sizeof ( *ipoib_pshdr ) ) ); + /* Attempting transmission while link is down will put the + * queue pair into an error state, so don't try it. + */ + if ( ! ibdev->link_up ) + return -ENETUNREACH; + /* Construct address vector */ memset ( &av, 0, sizeof ( av ) ); av.qkey = IB_GLOBAL_QKEY; @@ -790,6 +796,10 @@ static int ipoib_join_broadcast_group ( struct ipoib_device *ipoib ) { return rc; } + /* We will set link up on the network device when we receive + * the broadcast join response. + */ + return 0; } @@ -907,16 +917,24 @@ static struct net_device_operations ipoib_operations = { */ static void ipoib_set_ib_params ( struct ipoib_device *ipoib ) { struct ib_device *ibdev = ipoib->ibdev; + struct net_device *netdev = ipoib->netdev; struct ipoib_mac *mac; /* Calculate GID portion of MAC address based on port GID */ - mac = ( ( struct ipoib_mac * ) ipoib->netdev->ll_addr ); + mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); memcpy ( &mac->gid, &ibdev->port_gid, sizeof ( mac->gid ) ); /* Calculate broadcast GID based on partition key */ memcpy ( &ipoib->broadcast_gid, &ipv4_broadcast_gid, sizeof ( ipoib->broadcast_gid ) ); ipoib->broadcast_gid.u.words[2] = htons ( ibdev->pkey ); + + /* Set net device link state to reflect Infiniband link state */ + if ( ibdev->link_up ) { + netdev_link_up ( netdev ); + } else { + netdev_link_down ( netdev ); + } } /** diff --git a/src/drivers/net/legacy.c b/src/drivers/net/legacy.c index 32460adba..cbec3cf5c 100644 --- a/src/drivers/net/legacy.c +++ b/src/drivers/net/legacy.c @@ -112,6 +112,9 @@ int legacy_probe ( void *hwdev, */ dev->desc.irq = nic.irqno; + /* Mark as link up; legacy devices don't handle link state */ + netdev_link_up ( netdev ); + if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register; diff --git a/src/drivers/net/mtnic.c b/src/drivers/net/mtnic.c index 536fcb8d7..575070655 100755 --- a/src/drivers/net/mtnic.c +++ b/src/drivers/net/mtnic.c @@ -1731,6 +1731,9 @@ mtnic_probe(struct pci_device *pci, mac = mac >> 8; } + /* Mark as link up; we don't yet handle link state */ + netdev_link_up ( dev ); + if (register_netdev(dev)) { eprintf("Netdev registration failed\n"); return MTNIC_ERROR; diff --git a/src/drivers/net/natsemi.c b/src/drivers/net/natsemi.c index 98a5ff848..028b905ce 100644 --- a/src/drivers/net/natsemi.c +++ b/src/drivers/net/natsemi.c @@ -205,6 +205,9 @@ static int natsemi_probe (struct pci_device *pci, last = last1; } + /* Mark as link up; we don't yet handle link state */ + netdev_link_up ( netdev ); + if ((rc = register_netdev (netdev)) != 0) goto err_register_netdev; diff --git a/src/drivers/net/pnic.c b/src/drivers/net/pnic.c index b431ec52a..c7f08670d 100644 --- a/src/drivers/net/pnic.c +++ b/src/drivers/net/pnic.c @@ -250,6 +250,9 @@ static int pnic_probe ( struct pci_device *pci, status = pnic_command ( pnic, PNIC_CMD_READ_MAC, NULL, 0, netdev->ll_addr, ETH_ALEN, NULL ); + /* Mark as link up; PNIC has no concept of link state */ + netdev_link_up ( netdev ); + /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err; diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c index c432884cd..509047a93 100644 --- a/src/drivers/net/rtl8139.c +++ b/src/drivers/net/rtl8139.c @@ -518,6 +518,9 @@ static int rtl_probe ( struct pci_device *pci, rtl_reset ( netdev ); rtl_init_eeprom ( netdev ); nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN ); + + /* Mark as link up; we don't yet handle link state */ + netdev_link_up ( netdev ); /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) -- cgit v1.2.3-55-g7522