summaryrefslogtreecommitdiffstats
path: root/src/drivers/net
diff options
context:
space:
mode:
authorSimon Rettberg2022-05-11 10:41:01 +0200
committerSimon Rettberg2022-05-11 10:41:01 +0200
commita12e3c379cf2e5946c7316259ef46736cdd5f222 (patch)
tree49638dad528a4490e293ea4a0f87e39ce862a75b /src/drivers/net
parentLocal UEFI disk boot support (diff)
parent[cloud] Allow aws-import script to run on Python 3.6 (diff)
downloadipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.tar.gz
ipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.tar.xz
ipxe-a12e3c379cf2e5946c7316259ef46736cdd5f222.zip
Merge branch 'master' into openslx
Diffstat (limited to 'src/drivers/net')
-rw-r--r--src/drivers/net/efi/nii.c2
-rw-r--r--src/drivers/net/efi/snpnet.c18
-rw-r--r--src/drivers/net/intelx.c1
-rw-r--r--src/drivers/net/virtio-net.c36
4 files changed, 41 insertions, 16 deletions
diff --git a/src/drivers/net/efi/nii.c b/src/drivers/net/efi/nii.c
index b9f34650e..833462e77 100644
--- a/src/drivers/net/efi/nii.c
+++ b/src/drivers/net/efi/nii.c
@@ -576,7 +576,7 @@ static int nii_issue_cpb_db ( struct nii_nic *nii, unsigned int op, void *cpb,
cdb.IFnum = nii->nii->IfNum;
/* Raise task priority level */
- tpl = bs->RaiseTPL ( TPL_CALLBACK );
+ tpl = bs->RaiseTPL ( efi_internal_tpl );
/* Issue command */
DBGC2 ( nii, "NII %s issuing %02x:%04x ifnum %d%s%s\n",
diff --git a/src/drivers/net/efi/snpnet.c b/src/drivers/net/efi/snpnet.c
index fb5240277..69ec6f5e5 100644
--- a/src/drivers/net/efi/snpnet.c
+++ b/src/drivers/net/efi/snpnet.c
@@ -164,6 +164,10 @@ static int snpnet_transmit ( struct net_device *netdev,
EFI_STATUS efirc;
int rc;
+ /* Do nothing if shutdown is in progress */
+ if ( efi_shutdown_in_progress )
+ return -ECANCELED;
+
/* Defer the packet if there is already a transmission in progress */
if ( snp->txbuf ) {
netdev_tx_defer ( netdev, iobuf );
@@ -283,6 +287,10 @@ static void snpnet_poll_rx ( struct net_device *netdev ) {
*/
static void snpnet_poll ( struct net_device *netdev ) {
+ /* Do nothing if shutdown is in progress */
+ if ( efi_shutdown_in_progress )
+ return;
+
/* Process any TX completions */
snpnet_poll_tx ( netdev );
@@ -426,8 +434,9 @@ static void snpnet_close ( struct net_device *netdev ) {
EFI_STATUS efirc;
int rc;
- /* Shut down NIC */
- if ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) {
+ /* Shut down NIC (unless whole system shutdown is in progress) */
+ if ( ( ! efi_shutdown_in_progress ) &&
+ ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
rc = -EEFI ( efirc );
DBGC ( snp, "SNP %s could not shut down: %s\n",
netdev->name, strerror ( rc ) );
@@ -589,8 +598,9 @@ void snpnet_stop ( struct efi_device *efidev ) {
/* Unregister network device */
unregister_netdev ( netdev );
- /* Stop SNP protocol */
- if ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) {
+ /* Stop SNP protocol (unless whole system shutdown is in progress) */
+ if ( ( ! efi_shutdown_in_progress ) &&
+ ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) ) {
rc = -EEFI ( efirc );
DBGC ( device, "SNP %s could not stop: %s\n",
efi_handle_name ( device ), strerror ( rc ) );
diff --git a/src/drivers/net/intelx.c b/src/drivers/net/intelx.c
index ccf6b0648..f4dad8859 100644
--- a/src/drivers/net/intelx.c
+++ b/src/drivers/net/intelx.c
@@ -481,6 +481,7 @@ static struct pci_device_id intelx_nics[] = {
PCI_ROM ( 0x8086, 0x15ab, "x552", "X552", 0 ),
PCI_ROM ( 0x8086, 0x15c8, "x553t", "X553/X557-AT", 0 ),
PCI_ROM ( 0x8086, 0x15ce, "x553-sfp", "X553 (SFP+)", 0 ),
+ PCI_ROM ( 0x8086, 0x15e4, "x553a", "X553", 0 ),
PCI_ROM ( 0x8086, 0x15e5, "x553", "X553", 0 ),
};
diff --git a/src/drivers/net/virtio-net.c b/src/drivers/net/virtio-net.c
index 78ec9ac4e..0c4541924 100644
--- a/src/drivers/net/virtio-net.c
+++ b/src/drivers/net/virtio-net.c
@@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
#include <ipxe/pci.h>
+#include <ipxe/dma.h>
#include <ipxe/if_ether.h>
#include <ipxe/ethernet.h>
#include <ipxe/virtio-pci.h>
@@ -99,8 +100,9 @@ struct virtnet_nic {
/** Pending rx packet count */
unsigned int rx_num_iobufs;
- /** Virtio net dummy packet headers */
- struct virtio_net_hdr_modern empty_header[QUEUE_NB];
+ /** DMA device */
+ struct dma_device *dma;
+
};
/** Add an iobuf to a virtqueue
@@ -115,7 +117,7 @@ static void virtnet_enqueue_iob ( struct net_device *netdev,
int vq_idx, struct io_buffer *iobuf ) {
struct virtnet_nic *virtnet = netdev->priv;
struct vring_virtqueue *vq = &virtnet->virtqueue[vq_idx];
- struct virtio_net_hdr_modern *header = &virtnet->empty_header[vq_idx];
+ struct virtio_net_hdr_modern *header = vq->empty_header;
unsigned int out = ( vq_idx == TX_INDEX ) ? 2 : 0;
unsigned int in = ( vq_idx == TX_INDEX ) ? 0 : 2;
size_t header_len = ( virtnet->virtio_version ?
@@ -132,11 +134,11 @@ static void virtnet_enqueue_iob ( struct net_device *netdev,
* to header->flags for received packets. Work around
* this by using separate RX and TX headers.
*/
- .addr = ( char* ) header,
+ .addr = dma ( &vq->map, header ),
.length = header_len,
},
{
- .addr = ( char* ) iobuf->data,
+ .addr = iob_dma ( iobuf ),
.length = iob_len ( iobuf ),
},
};
@@ -161,7 +163,7 @@ static void virtnet_refill_rx_virtqueue ( struct net_device *netdev ) {
struct io_buffer *iobuf;
/* Try to allocate a buffer, stop for now if out of memory */
- iobuf = alloc_iob ( len );
+ iobuf = alloc_rx_iob ( len, virtnet->dma );
if ( ! iobuf )
break;
@@ -215,7 +217,8 @@ static int virtnet_open_legacy ( struct net_device *netdev ) {
/* Initialize rx/tx virtqueues */
for ( i = 0; i < QUEUE_NB; i++ ) {
- if ( vp_find_vq ( ioaddr, i, &virtnet->virtqueue[i] ) == -1 ) {
+ if ( vp_find_vq ( ioaddr, i, &virtnet->virtqueue[i], virtnet->dma,
+ sizeof ( struct virtio_net_hdr_modern ) ) == -1 ) {
DBGC ( virtnet, "VIRTIO-NET %p cannot register queue %d\n",
virtnet, i );
virtnet_free_virtqueues ( netdev );
@@ -280,7 +283,8 @@ static int virtnet_open_modern ( struct net_device *netdev ) {
}
/* Initialize rx/tx virtqueues */
- if ( vpm_find_vqs ( &virtnet->vdev, QUEUE_NB, virtnet->virtqueue ) ) {
+ if ( vpm_find_vqs ( &virtnet->vdev, QUEUE_NB, virtnet->virtqueue,
+ virtnet->dma, sizeof ( struct virtio_net_hdr_modern ) ) ) {
DBGC ( virtnet, "VIRTIO-NET %p cannot register queues\n",
virtnet );
virtnet_free_virtqueues ( netdev );
@@ -335,7 +339,7 @@ static void virtnet_close ( struct net_device *netdev ) {
/* Free rx iobufs */
list_for_each_entry_safe ( iobuf, next_iobuf, &virtnet->rx_iobufs, list ) {
- free_iob ( iobuf );
+ free_rx_iob ( iobuf );
}
INIT_LIST_HEAD ( &virtnet->rx_iobufs );
virtnet->rx_num_iobufs = 0;
@@ -478,6 +482,12 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
/* Enable PCI bus master and reset NIC */
adjust_pci_device ( pci );
+
+ /* Configure DMA */
+ virtnet->dma = &pci->dma;
+ dma_set_mask_64bit ( virtnet->dma );
+ netdev->dma = virtnet->dma;
+
vp_reset ( ioaddr );
/* Load MAC address and MTU */
@@ -506,7 +516,7 @@ static int virtnet_probe_legacy ( struct pci_device *pci ) {
return 0;
unregister_netdev ( netdev );
- err_register_netdev:
+err_register_netdev:
vp_reset ( ioaddr );
netdev_nullify ( netdev );
netdev_put ( netdev );
@@ -586,6 +596,11 @@ static int virtnet_probe_modern ( struct pci_device *pci, int *found_dev ) {
/* Enable the PCI device */
adjust_pci_device ( pci );
+ /* Configure DMA */
+ virtnet->dma = &pci->dma;
+ dma_set_mask_64bit ( virtnet->dma );
+ netdev->dma = virtnet->dma;
+
/* Reset the device and set initial status bits */
vpm_reset ( &virtnet->vdev );
vpm_add_status ( &virtnet->vdev, VIRTIO_CONFIG_S_ACKNOWLEDGE );
@@ -633,7 +648,6 @@ err_mac_address:
vpm_reset ( &virtnet->vdev );
netdev_nullify ( netdev );
netdev_put ( netdev );
-
virtio_pci_unmap_capability ( &virtnet->vdev.device );
err_map_device:
virtio_pci_unmap_capability ( &virtnet->vdev.isr );