summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/efi/nii.c
diff options
context:
space:
mode:
authorMichael Brown2020-08-17 14:08:05 +0200
committerMichael Brown2020-08-17 15:28:21 +0200
commitef2c844d01e78723af54b6ca67019fd9fe7f08e4 (patch)
treea7f6e0179487c0b35ac5cd7972b396b499d82778 /src/drivers/net/efi/nii.c
parent[efi] Use device path to locate filesystem from which we were loaded (diff)
downloadipxe-ef2c844d01e78723af54b6ca67019fd9fe7f08e4.tar.gz
ipxe-ef2c844d01e78723af54b6ca67019fd9fe7f08e4.tar.xz
ipxe-ef2c844d01e78723af54b6ca67019fd9fe7f08e4.zip
[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>
Diffstat (limited to 'src/drivers/net/efi/nii.c')
-rw-r--r--src/drivers/net/efi/nii.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/src/drivers/net/efi/nii.c b/src/drivers/net/efi/nii.c
index 2d87e0c6..e76e211c 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 ) {