Skip to content

Commit

Permalink
[efi] Skip cable detection at initialisation where possible
Browse files Browse the repository at this point in the history
We currently request cable detection in PXE_OPCODE_INITIALIZE to work
around buggy Emulex drivers (see commit c0b61ba ("[efi] Work around
bugs in Emulex NII driver")).

This causes problems with some other NII drivers (e.g. Mellanox),
which may time out if the underlying link is intrinsically slow to
come up.

Attempt to work around both problems simultaneously by requesting
cable detection only if the underlying NII driver does not support
link status reporting via PXE_OPCODE_GET_STATUS.  (This is based on a
potentially incorrect assumption that the buggy Emulex drivers do not
claim to report link status via PXE_OPCODE_GET_STATUS.)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Mar 19, 2017
1 parent fdcdc52 commit 6324227
Showing 1 changed file with 19 additions and 23 deletions.
42 changes: 19 additions & 23 deletions src/drivers/net/efi/nii.c
Expand Up @@ -632,22 +632,6 @@ static int nii_initialise ( struct nii_nic *nii ) {
return nii_initialise_flags ( nii, flags );
}

/**
* Initialise UNDI and detect cable
*
* @v nii NII NIC
* @ret rc Return status code
*/
static int nii_initialise_and_detect ( struct nii_nic *nii ) {
unsigned int flags;

/* Initialise UNDI and detect cable. This is required to work
* around bugs in some Emulex NII drivers.
*/
flags = PXE_OPFLAGS_INITIALIZE_DETECT_CABLE;
return nii_initialise_flags ( nii, flags );
}

/**
* Shut down UNDI
*
Expand Down Expand Up @@ -968,20 +952,32 @@ 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
*
* We don't care about link state here, and would prefer to
* have the NIC initialise even if no cable is present, to
* match the behaviour of all other iPXE drivers.
*
* Some Emulex NII drivers have a bug which prevents packets
* from being sent or received unless we specifically ask it
* to detect cable presence during initialisation. Work
* around these buggy drivers by requesting cable detection at
* this point, even though we don't care about link state here
* (and would prefer to have the NIC initialise even if no
* cable is present, to match the behaviour of all other iPXE
* drivers).
* to detect cable presence during initialisation.
*
* Unfortunately, some other NII drivers (e.g. Mellanox) may
* time out and report failure if asked to detect cable
* 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.
*/
if ( ( rc = nii_initialise_and_detect ( nii ) ) != 0 )
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;

/* Attempt to set station address */
Expand Down

0 comments on commit 6324227

Please sign in to comment.