summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/efi/nii.c
diff options
context:
space:
mode:
authorMichael Brown2015-04-14 17:44:37 +0200
committerMichael Brown2015-04-14 17:44:37 +0200
commit729c16ad5b5502913d15a1fb17747bc8b586bed2 (patch)
treeb8f152a53e806e3ea3103030cb69ab46f6efe02e /src/drivers/net/efi/nii.c
parent[efi] Provide a dummy data block in nii_initialise() (diff)
downloadipxe-729c16ad5b5502913d15a1fb17747bc8b586bed2.tar.gz
ipxe-729c16ad5b5502913d15a1fb17747bc8b586bed2.tar.xz
ipxe-729c16ad5b5502913d15a1fb17747bc8b586bed2.zip
[efi] Poll media status only if advertised as supported
Some NII implementations will fail the GET_STATUS operation if we request the media status. Fix by doing so only if GET_INIT_INFO reported that media status is supported. 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.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/drivers/net/efi/nii.c b/src/drivers/net/efi/nii.c
index 935ff099..3910dc9f 100644
--- a/src/drivers/net/efi/nii.c
+++ b/src/drivers/net/efi/nii.c
@@ -172,6 +172,9 @@ struct nii_nic {
/** Saved task priority level */
EFI_TPL saved_tpl;
+ /** Media status is supported */
+ int media;
+
/** Current transmit buffer */
struct io_buffer *txbuf;
/** Current receive buffer */
@@ -556,6 +559,7 @@ static int nii_get_init_info ( struct nii_nic *nii,
nii->buffer_len = db.MemoryRequired;
nii->mtu = ( db.FrameDataLen + db.MediaHeaderLen );
netdev->max_pkt_len = nii->mtu;
+ nii->media = ( stat & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
return 0;
}
@@ -878,11 +882,14 @@ static void nii_poll ( struct net_device *netdev ) {
int stat;
int rc;
+ /* Construct data block */
+ memset ( &db, 0, sizeof ( db ) );
+
/* Get status */
op = NII_OP ( PXE_OPCODE_GET_STATUS,
( PXE_OPFLAGS_GET_INTERRUPT_STATUS |
PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS |
- PXE_OPFLAGS_GET_MEDIA_STATUS ) );
+ ( nii->media ? PXE_OPFLAGS_GET_MEDIA_STATUS : 0 ) ) );
if ( ( stat = nii_issue_db ( nii, op, &db, sizeof ( db ) ) ) < 0 ) {
rc = -EIO_STAT ( stat );
DBGC ( nii, "NII %s could not get status: %s\n",
@@ -897,7 +904,8 @@ static void nii_poll ( struct net_device *netdev ) {
nii_poll_rx ( netdev );
/* Check for link state changes */
- nii_poll_link ( netdev, stat );
+ if ( nii->media )
+ nii_poll_link ( netdev, stat );
}
/**
@@ -1057,6 +1065,10 @@ int nii_start ( struct efi_device *efidev ) {
DBGC ( nii, "NII %s registered as %s for %p %s\n", nii->dev.name,
netdev->name, device, efi_handle_name ( device ) );
+ /* Set initial link state (if media detection is not supported) */
+ if ( ! nii->media )
+ netdev_link_up ( netdev );
+
return 0;
unregister_netdev ( netdev );