diff options
Diffstat (limited to 'src/drivers/net')
-rw-r--r-- | src/drivers/net/legacy.c | 51 | ||||
-rw-r--r-- | src/drivers/net/pnic.c | 61 | ||||
-rw-r--r-- | src/drivers/net/rtl8139.c | 48 |
3 files changed, 92 insertions, 68 deletions
diff --git a/src/drivers/net/legacy.c b/src/drivers/net/legacy.c index 2d4633d4..6ae2fbec 100644 --- a/src/drivers/net/legacy.c +++ b/src/drivers/net/legacy.c @@ -36,13 +36,10 @@ static int legacy_transmit ( struct net_device *netdev, struct io_buffer *iobuf return 0; } -static void legacy_poll ( struct net_device *netdev, unsigned int rx_quota ) { +static void legacy_poll ( struct net_device *netdev ) { struct nic *nic = netdev->priv; struct io_buffer *iobuf; - if ( ! rx_quota ) - return; - iobuf = alloc_iob ( ETH_FRAME_LEN ); if ( ! iobuf ) return; @@ -57,19 +54,29 @@ static void legacy_poll ( struct net_device *netdev, unsigned int rx_quota ) { } } -static int legacy_open ( struct net_device *netdev ) { - struct nic *nic = netdev->priv; - - nic->nic_op->irq ( nic, ENABLE ); +static int legacy_open ( struct net_device *netdev __unused ) { + /* Nothing to do */ return 0; } -static void legacy_close ( struct net_device *netdev ) { +static void legacy_close ( struct net_device *netdev __unused ) { + /* Nothing to do */ +} + +static void legacy_irq ( struct net_device *netdev __unused, int enable ) { struct nic *nic = netdev->priv; - nic->nic_op->irq ( nic, DISABLE ); + nic->nic_op->irq ( nic, ( enable ? ENABLE : DISABLE ) ); } +static struct net_device_operations legacy_operations = { + .open = legacy_open, + .close = legacy_close, + .transmit = legacy_transmit, + .poll = legacy_poll, + .irq = legacy_irq, +}; + int legacy_probe ( void *hwdev, void ( * set_drvdata ) ( void *hwdev, void *priv ), struct device *dev, @@ -84,27 +91,21 @@ int legacy_probe ( void *hwdev, netdev = alloc_etherdev ( 0 ); if ( ! netdev ) return -ENOMEM; + netdev_init ( netdev, &legacy_operations ); netdev->priv = &nic; memset ( &nic, 0, sizeof ( nic ) ); set_drvdata ( hwdev, netdev ); netdev->dev = dev; - netdev->open = legacy_open; - netdev->close = legacy_close; - netdev->transmit = legacy_transmit; - netdev->poll = legacy_poll; nic.node_addr = netdev->ll_addr; if ( ! probe ( &nic, hwdev ) ) { - netdev_put ( netdev ); - return -ENODEV; + rc = -ENODEV; + goto err_probe; } - if ( ( rc = register_netdev ( netdev ) ) != 0 ) { - disable ( &nic, hwdev ); - netdev_put ( netdev ); - return rc; - } + if ( ( rc = register_netdev ( netdev ) ) != 0 ) + goto err_register; /* Do not remove this message */ printf ( "WARNING: Using legacy NIC wrapper on %s\n", @@ -112,6 +113,13 @@ int legacy_probe ( void *hwdev, legacy_registered = 1; return 0; + + err_register: + disable ( &nic, hwdev ); + err_probe: + netdev_nullify ( netdev ); + netdev_put ( netdev ); + return rc; } void legacy_remove ( void *hwdev, @@ -122,6 +130,7 @@ void legacy_remove ( void *hwdev, unregister_netdev ( netdev ); disable ( nic, hwdev ); + netdev_nullify ( netdev ); netdev_put ( netdev ); legacy_registered = 0; } diff --git a/src/drivers/net/pnic.c b/src/drivers/net/pnic.c index 38b4af6d..b431ec52 100644 --- a/src/drivers/net/pnic.c +++ b/src/drivers/net/pnic.c @@ -112,35 +112,34 @@ static int pnic_api_check ( uint16_t api_version ) { /************************************************************************** POLL - Wait for a frame ***************************************************************************/ -static void pnic_poll ( struct net_device *netdev, unsigned int rx_quota ) { +static void pnic_poll ( struct net_device *netdev ) { struct pnic *pnic = netdev->priv; struct io_buffer *iobuf; uint16_t length; uint16_t qlen; /* Fetch all available packets */ - while ( rx_quota ) { + while ( 1 ) { if ( pnic_command ( pnic, PNIC_CMD_RECV_QLEN, NULL, 0, &qlen, sizeof ( qlen ), NULL ) != PNIC_STATUS_OK ) - break; + return; if ( qlen == 0 ) - break; + return; iobuf = alloc_iob ( ETH_FRAME_LEN ); if ( ! iobuf ) { DBG ( "could not allocate buffer\n" ); netdev_rx_err ( netdev, NULL, -ENOMEM ); - break; + return; } if ( pnic_command ( pnic, PNIC_CMD_RECV, NULL, 0, iobuf->data, ETH_FRAME_LEN, &length ) != PNIC_STATUS_OK ) { netdev_rx_err ( netdev, iobuf, -EIO ); - break; + return; } iob_put ( iobuf, length ); netdev_rx ( netdev, iobuf ); - --rx_quota; } } @@ -164,30 +163,41 @@ static int pnic_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) /************************************************************************** OPEN - Open network device ***************************************************************************/ -static int pnic_open ( struct net_device *netdev ) { - struct pnic *pnic = netdev->priv; - static const uint8_t enable = 1; - - /* Enable interrupts */ - pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &enable, - sizeof ( enable ), NULL, 0, NULL ); - +static int pnic_open ( struct net_device *netdev __unused ) { + /* Nothing to do */ return 0; } /************************************************************************** CLOSE - Close network device ***************************************************************************/ -static void pnic_close ( struct net_device *netdev ) { - struct pnic *pnic = netdev->priv; - static const uint8_t disable = 0; +static void pnic_close ( struct net_device *netdev __unused ) { + /* Nothing to do */ +} - /* Disable interrupts */ - pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &disable, - sizeof ( disable ), NULL, 0, NULL ); +/************************************************************************** +IRQ - Enable/disable interrupts +***************************************************************************/ +static void pnic_irq ( struct net_device *netdev, int enable ) { + struct pnic *pnic = netdev->priv; + uint8_t mask = ( enable ? 1 : 0 ); + + pnic_command ( pnic, PNIC_CMD_MASK_IRQ, &mask, sizeof ( mask ), + NULL, 0, NULL ); } /************************************************************************** +OPERATIONS TABLE +***************************************************************************/ +static struct net_device_operations pnic_operations = { + .open = pnic_open, + .close = pnic_close, + .transmit = pnic_transmit, + .poll = pnic_poll, + .irq = pnic_irq, +}; + +/************************************************************************** DISABLE - Turn off ethernet interface ***************************************************************************/ static void pnic_remove ( struct pci_device *pci ) { @@ -196,6 +206,7 @@ static void pnic_remove ( struct pci_device *pci ) { unregister_netdev ( netdev ); pnic_command ( pnic, PNIC_CMD_RESET, NULL, 0, NULL, 0, NULL ); + netdev_nullify ( netdev ); netdev_put ( netdev ); } @@ -214,6 +225,7 @@ static int pnic_probe ( struct pci_device *pci, netdev = alloc_etherdev ( sizeof ( *pnic ) ); if ( ! netdev ) return -ENOMEM; + netdev_init ( netdev, &pnic_operations ); pnic = netdev->priv; pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; @@ -238,12 +250,6 @@ static int pnic_probe ( struct pci_device *pci, status = pnic_command ( pnic, PNIC_CMD_READ_MAC, NULL, 0, netdev->ll_addr, ETH_ALEN, NULL ); - /* Point to NIC specific routines */ - netdev->open = pnic_open; - netdev->close = pnic_close; - netdev->poll = pnic_poll; - netdev->transmit = pnic_transmit; - /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err; @@ -252,6 +258,7 @@ static int pnic_probe ( struct pci_device *pci, err: /* Free net device */ + netdev_nullify ( netdev ); netdev_put ( netdev ); return rc; } diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c index 54bda07f..8b40918f 100644 --- a/src/drivers/net/rtl8139.c +++ b/src/drivers/net/rtl8139.c @@ -302,12 +302,6 @@ static struct nvo_fragment rtl_nvo_fragments[] = { */ static void rtl_reset ( struct rtl8139_nic *rtl ) { - /* Disable interrupts. May not be necessary, but datasheet - * doesn't say that the reset command also resets the - * interrupt mask. - */ - outw ( 0, rtl->ioaddr + IntrMask ); - /* Reset chip */ outb ( CmdReset, rtl->ioaddr + ChipCmd ); mdelay ( 10 ); @@ -346,9 +340,6 @@ static int rtl_open ( struct net_device *netdev ) { outl ( ( ( TX_DMA_BURST << 8 ) | ( TX_IPG << 24 ) ), rtl->ioaddr + TxConfig ); - /* Enable interrupts */ - outw ( ( ROK | RER | TOK | TER ), rtl->ioaddr + IntrMask ); - return 0; } @@ -400,13 +391,12 @@ static int rtl_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { return 0; } -/** +/** * Poll for received packets * * @v netdev Network device - * @v rx_quota Maximum number of packets to receive */ -static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) { +static void rtl_poll ( struct net_device *netdev ) { struct rtl8139_nic *rtl = netdev->priv; unsigned int status; unsigned int tsad; @@ -433,7 +423,7 @@ static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) { } /* Handle received packets */ - while ( rx_quota && ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ){ + while ( ! ( inw ( rtl->ioaddr + ChipCmd ) & RxBufEmpty ) ) { rx_status = * ( ( uint16_t * ) ( rtl->rx.ring + rtl->rx.offset ) ); rx_len = * ( ( uint16_t * ) @@ -461,7 +451,6 @@ static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) { rtl->rx.ring, wrapped_len ); netdev_rx ( netdev, rx_iob ); - rx_quota--; } else { DBG ( "RX bad packet (status %#04x len %d)\n", rx_status, rx_len ); @@ -474,6 +463,28 @@ static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) { } /** + * Enable/disable interrupts + * + * @v netdev Network device + * @v enable Interrupts should be enabled + */ +static void rtl_irq ( struct net_device *netdev, int enable ) { + struct rtl8139_nic *rtl = netdev->priv; + + outw ( ( enable ? ( ROK | RER | TOK | TER ) : 0 ), + rtl->ioaddr + IntrMask ); +} + +/** RTL8139 net device operations */ +static struct net_device_operations rtl_operations = { + .open = rtl_open, + .close = rtl_close, + .transmit = rtl_transmit, + .poll = rtl_poll, + .irq = rtl_irq, +}; + +/** * Probe PCI device * * @v pci PCI device @@ -490,6 +501,7 @@ static int rtl_probe ( struct pci_device *pci, netdev = alloc_etherdev ( sizeof ( *rtl ) ); if ( ! netdev ) return -ENOMEM; + netdev_init ( netdev, &rtl_operations ); rtl = netdev->priv; pci_set_drvdata ( pci, netdev ); netdev->dev = &pci->dev; @@ -504,12 +516,6 @@ static int rtl_probe ( struct pci_device *pci, rtl_init_eeprom ( rtl ); nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN ); - /* Point to NIC specific routines */ - netdev->open = rtl_open; - netdev->close = rtl_close; - netdev->transmit = rtl_transmit; - netdev->poll = rtl_poll; - /* Register network device */ if ( ( rc = register_netdev ( netdev ) ) != 0 ) goto err_register_netdev; @@ -526,6 +532,7 @@ static int rtl_probe ( struct pci_device *pci, unregister_netdev ( netdev ); err_register_netdev: rtl_reset ( rtl ); + netdev_nullify ( netdev ); netdev_put ( netdev ); return rc; } @@ -543,6 +550,7 @@ static void rtl_remove ( struct pci_device *pci ) { nvo_unregister ( &rtl->nvo ); unregister_netdev ( netdev ); rtl_reset ( rtl ); + netdev_nullify ( netdev ); netdev_put ( netdev ); } |