summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/legacy.c
diff options
context:
space:
mode:
authorSimon Rettberg2026-01-28 12:53:53 +0100
committerSimon Rettberg2026-01-28 12:53:53 +0100
commit8e82785c584dc13e20f9229decb95bd17bbe9cd1 (patch)
treea8b359e59196be5b2e3862bed189107f4bc9975f /src/drivers/net/legacy.c
parentMerge branch 'master' into openslx (diff)
parent[prefix] Make unlzma.S compatible with 386 class CPUs (diff)
downloadipxe-openslx.tar.gz
ipxe-openslx.tar.xz
ipxe-openslx.zip
Merge branch 'master' into openslxopenslx
Diffstat (limited to 'src/drivers/net/legacy.c')
-rw-r--r--src/drivers/net/legacy.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/src/drivers/net/legacy.c b/src/drivers/net/legacy.c
index 73a80194f..b86f77fc8 100644
--- a/src/drivers/net/legacy.c
+++ b/src/drivers/net/legacy.c
@@ -19,7 +19,7 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-struct nic nic;
+struct nic legacy_nic;
static int legacy_registered = 0;
@@ -42,7 +42,8 @@ static void legacy_poll ( struct net_device *netdev ) {
struct nic *nic = netdev->priv;
struct io_buffer *iobuf;
- iobuf = alloc_iob ( ETH_FRAME_LEN );
+ iobuf = alloc_iob ( ETH_FRAME_LEN + 4 /* possible VLAN */
+ + 4 /* possible CRC */ );
if ( ! iobuf )
return;
@@ -83,26 +84,42 @@ int legacy_probe ( void *hwdev,
void ( * set_drvdata ) ( void *hwdev, void *priv ),
struct device *dev,
int ( * probe ) ( struct nic *nic, void *hwdev ),
- void ( * disable ) ( struct nic *nic, void *hwdev ) ) {
+ void ( * disable ) ( struct nic *nic, void *hwdev ),
+ size_t fake_bss_len ) {
struct net_device *netdev;
+ struct nic *nic;
int rc;
- if ( legacy_registered )
- return -EBUSY;
-
+ if ( legacy_registered ) {
+ rc = -EBUSY;
+ goto err_registered;
+ }
+
netdev = alloc_etherdev ( 0 );
- if ( ! netdev )
- return -ENOMEM;
+ if ( ! netdev ) {
+ rc = -ENOMEM;
+ goto err_alloc;
+ }
netdev_init ( netdev, &legacy_operations );
- netdev->priv = &nic;
- memset ( &nic, 0, sizeof ( nic ) );
+ nic = &legacy_nic;
+ netdev->priv = nic;
+ memset ( nic, 0, sizeof ( *nic ) );
set_drvdata ( hwdev, netdev );
netdev->dev = dev;
- nic.node_addr = netdev->hw_addr;
- nic.irqno = dev->desc.irq;
+ nic->node_addr = netdev->hw_addr;
+ nic->irqno = dev->desc.irq;
- if ( ! probe ( &nic, hwdev ) ) {
+ if ( fake_bss_len ) {
+ nic->fake_bss = malloc_phys ( fake_bss_len, PAGE_SIZE );
+ if ( ! nic->fake_bss ) {
+ rc = -ENOMEM;
+ goto err_fake_bss;
+ }
+ }
+ nic->fake_bss_len = fake_bss_len;
+
+ if ( ! probe ( nic, hwdev ) ) {
rc = -ENODEV;
goto err_probe;
}
@@ -112,7 +129,7 @@ int legacy_probe ( void *hwdev,
* don't support interrupts; doing this allows the timer
* interrupt to be used instead.
*/
- dev->desc.irq = nic.irqno;
+ dev->desc.irq = nic->irqno;
if ( ( rc = register_netdev ( netdev ) ) != 0 )
goto err_register;
@@ -122,16 +139,21 @@ int legacy_probe ( void *hwdev,
/* Do not remove this message */
printf ( "WARNING: Using legacy NIC wrapper on %s\n",
- netdev->ll_protocol->ntoa ( nic.node_addr ) );
+ netdev->ll_protocol->ntoa ( nic->node_addr ) );
legacy_registered = 1;
return 0;
err_register:
- disable ( &nic, hwdev );
+ disable ( nic, hwdev );
err_probe:
+ if ( fake_bss_len )
+ free_phys ( nic->fake_bss, fake_bss_len );
+ err_fake_bss:
netdev_nullify ( netdev );
netdev_put ( netdev );
+ err_alloc:
+ err_registered:
return rc;
}
@@ -143,6 +165,8 @@ void legacy_remove ( void *hwdev,
unregister_netdev ( netdev );
disable ( nic, hwdev );
+ if ( nic->fake_bss_len )
+ free_phys ( nic->fake_bss, nic->fake_bss_len );
netdev_nullify ( netdev );
netdev_put ( netdev );
legacy_registered = 0;