diff options
author | Michael Brown <mcb30@ipxe.org> | 2020-08-17 13:08:05 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2020-08-17 14:28:21 +0100 |
commit | ef2c844d01e78723af54b6ca67019fd9fe7f08e4 (patch) | |
tree | a7f6e0179487c0b35ac5cd7972b396b499d82778 | |
parent | c63e61df75c815da1dc93196bbb6a931743b736f (diff) | |
download | ipxe-ef2c844d01e78723af54b6ca67019fd9fe7f08e4.tar.gz |
[efi] Attempt NII initialisation both with and without cable detection
We currently use a heuristic to determine whether or not to request
cable detection in PXE_OPCODE_INITIALIZE, based on the need to work
around a known Emulex driver bug (see commit c0b61ba "[efi] Work
around bugs in Emulex NII driver") and the need to accommodate links
that are legitimately slow to come up (see commit 6324227 "[efi] Skip
cable detection at initialisation where possible").
This heuristic appears to fail with newer Emulex drivers. Attempt to
support all known drivers (past and present) by first attempting
initialisation with cable detection, then falling back to attempting
initialisation without cable detection.
Reported-by: Kwang Woo Lee <kwleeyh@gmail.com>
Tested-by: Kwang Woo Lee <kwleeyh@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/drivers/net/efi/nii.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/src/drivers/net/efi/nii.c b/src/drivers/net/efi/nii.c index 2d87e0c63..e76e211c1 100644 --- a/src/drivers/net/efi/nii.c +++ b/src/drivers/net/efi/nii.c @@ -789,6 +789,20 @@ static int nii_initialise_flags ( struct nii_nic *nii, unsigned int flags ) { } /** + * Initialise UNDI with cable detection + * + * @v nii NII NIC + * @ret rc Return status code + */ +static int nii_initialise_cable ( struct nii_nic *nii ) { + unsigned int flags; + + /* Initialise UNDI */ + flags = PXE_OPFLAGS_INITIALIZE_DETECT_CABLE; + return nii_initialise_flags ( nii, flags ); +} + +/** * Initialise UNDI * * @v nii NII NIC @@ -1122,7 +1136,6 @@ static void nii_poll ( struct net_device *netdev ) { */ static int nii_open ( struct net_device *netdev ) { struct nii_nic *nii = netdev->priv; - unsigned int flags; int rc; /* Initialise NIC @@ -1140,15 +1153,21 @@ static int nii_open ( struct net_device *netdev ) { * presence during initialisation on links that are physically * slow to reach link-up. * - * Attempt to work around both of these problems by requesting - * cable detection at this point if any only if the driver is - * not capable of reporting link status changes at runtime via - * PXE_OPCODE_GET_STATUS. + * Attempt to work around both of these problems by first + * attempting to initialise with cable presence detection, + * then falling back to initialising without cable presence + * detection. */ - flags = ( nii->media ? PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE - : PXE_OPFLAGS_INITIALIZE_DETECT_CABLE ); - if ( ( rc = nii_initialise_flags ( nii, flags ) ) != 0 ) - goto err_initialise; + if ( ( rc = nii_initialise_cable ( nii ) ) != 0 ) { + DBGC ( nii, "NII %s could not initialise with cable " + "detection: %s\n", nii->dev.name, strerror ( rc ) ); + if ( ( rc = nii_initialise ( nii ) ) != 0 ) { + DBGC ( nii, "NII %s could not initialise without " + "cable detection: %s\n", + nii->dev.name, strerror ( rc ) ); + goto err_initialise; + } + } /* Attempt to set station address */ if ( ( rc = nii_set_station_address ( nii, netdev ) ) != 0 ) { |