summaryrefslogtreecommitdiffstats
path: root/src/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/net')
-rw-r--r--src/drivers/net/legacy.c51
-rw-r--r--src/drivers/net/pnic.c61
-rw-r--r--src/drivers/net/rtl8139.c48
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 );
}