summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/pnic.c
diff options
context:
space:
mode:
authorMichael Brown2007-07-07 17:43:39 +0200
committerMichael Brown2007-07-07 17:43:39 +0200
commit4c418d2100228b1c478908c08f51811a474e0e1e (patch)
treee55c3fc14b82a642f1a3cf08c2356b0aad907536 /src/drivers/net/pnic.c
parentRevert "Replace natsemi driver with Indolent's updated one that uses the gPXE... (diff)
downloadipxe-4c418d2100228b1c478908c08f51811a474e0e1e.tar.gz
ipxe-4c418d2100228b1c478908c08f51811a474e0e1e.tar.xz
ipxe-4c418d2100228b1c478908c08f51811a474e0e1e.zip
Use net_device_operations structure and netdev_nullify() to allow for
safe dropping of the netdev ref by the driver while other refs still exist. Add netdev_irq() method. Net device open()/close() methods should no longer enable or disable IRQs. Remove rx_quota; it wasn't used anywhere and added too much complexity to implementing correct interrupt-masking behaviour in pxe_undi.c.
Diffstat (limited to 'src/drivers/net/pnic.c')
-rw-r--r--src/drivers/net/pnic.c61
1 files changed, 34 insertions, 27 deletions
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;
}