diff options
Diffstat (limited to 'src/drivers/net/legacy.c')
| -rw-r--r-- | src/drivers/net/legacy.c | 56 |
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; |
