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.
This commit is contained in:
Michael Brown
2007-07-07 16:43:39 +01:00
parent 2823688a92
commit 4c418d2100
8 changed files with 291 additions and 145 deletions

View File

@@ -68,7 +68,7 @@ int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
goto err;
}
if ( ( rc = netdev->transmit ( netdev, iobuf ) ) != 0 )
if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 )
goto err;
return 0;
@@ -187,22 +187,18 @@ void netdev_rx_err ( struct net_device *netdev,
}
/**
* Poll for packet on network device
* Poll for completed and received packets on network device
*
* @v netdev Network device
* @v rx_quota Maximum number of packets to receive
* @ret True There are packets present in the receive queue
* @ret False There are no packets present in the receive queue
*
* Polls the network device for received packets. Any received
* packets will be added to the RX packet queue via netdev_rx().
* Polls the network device for completed transmissions and received
* packets. Any received packets will be added to the RX packet queue
* via netdev_rx().
*/
int netdev_poll ( struct net_device *netdev, unsigned int rx_quota ) {
void netdev_poll ( struct net_device *netdev ) {
if ( netdev->state & NETDEV_OPEN )
netdev->poll ( netdev, rx_quota );
return ( ! list_empty ( &netdev->rx_queue ) );
netdev->op->poll ( netdev );
}
/**
@@ -317,7 +313,7 @@ int netdev_open ( struct net_device *netdev ) {
DBGC ( netdev, "NETDEV %p opening\n", netdev );
/* Open the device */
if ( ( rc = netdev->open ( netdev ) ) != 0 )
if ( ( rc = netdev->op->open ( netdev ) ) != 0 )
return rc;
/* Mark as opened */
@@ -339,7 +335,7 @@ void netdev_close ( struct net_device *netdev ) {
DBGC ( netdev, "NETDEV %p closing\n", netdev );
/* Close the device */
netdev->close ( netdev );
netdev->op->close ( netdev );
/* Flush TX and RX queues */
netdev_tx_flush ( netdev );
@@ -367,6 +363,15 @@ void unregister_netdev ( struct net_device *netdev ) {
DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
}
/** Enable or disable interrupts
*
* @v netdev Network device
* @v enable Interrupts should be enabled
*/
void netdev_irq ( struct net_device *netdev, int enable ) {
netdev->op->irq ( netdev, enable );
}
/**
* Get network device by name
*
@@ -462,7 +467,7 @@ static void net_step ( struct process *process __unused ) {
list_for_each_entry ( netdev, &net_devices, list ) {
/* Poll for new packets */
netdev_poll ( netdev, -1U );
netdev_poll ( netdev );
/* Process at most one received packet. Give priority
* to getting packets out of the NIC over processing

57
src/net/nullnet.c Normal file
View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdint.h>
#include <gpxe/iobuf.h>
#include <gpxe/netdevice.h>
/** @file
*
* Null network device
*
*/
static int null_open ( struct net_device *netdev __unused ) {
return -ENODEV;
};
static void null_close ( struct net_device *netdev __unused ) {
/* Do nothing */
};
static int null_transmit ( struct net_device *netdev __unused,
struct io_buffer *iobuf __unused ) {
return -ENODEV;
};
static void null_poll ( struct net_device *netdev __unused ) {
/* Do nothing */
}
static void null_irq ( struct net_device *netdev __unused,
int enable __unused ) {
/* Do nothing */
}
struct net_device_operations null_netdev_operations = {
.open = null_open,
.close = null_close,
.transmit = null_transmit,
.poll = null_poll,
.irq = null_irq,
};