mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-14 23:31:39 +00:00
Make open() and close() an official part of the netdevice API.
Call netdevice's poll() and transmit() methods only when device is open.
This commit is contained in:
parent
d4894f0127
commit
0c03bb5a9a
@ -56,6 +56,14 @@ static void legacy_poll ( struct net_device *netdev ) {
|
||||
}
|
||||
}
|
||||
|
||||
static int legacy_open ( struct net_device *netdev __unused ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void legacy_close ( struct net_device *netdev __unused ) {
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
int legacy_probe ( struct pci_device *pci,
|
||||
const struct pci_device_id *id __unused,
|
||||
int ( * probe ) ( struct nic *nic,
|
||||
@ -74,6 +82,8 @@ int legacy_probe ( struct pci_device *pci,
|
||||
memset ( &nic, 0, sizeof ( nic ) );
|
||||
pci_set_drvdata ( pci, netdev );
|
||||
|
||||
netdev->open = legacy_open;
|
||||
netdev->close = legacy_close;
|
||||
netdev->transmit = legacy_transmit;
|
||||
netdev->poll = legacy_poll;
|
||||
nic.node_addr = netdev->ll_addr;
|
||||
|
@ -185,6 +185,20 @@ static void pnic_irq ( struct net_device *netdev, irq_action_t action ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
OPEN - Open network device
|
||||
***************************************************************************/
|
||||
static int pnic_open ( struct net_device *netdev __unused ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
CLOSE - Close network device
|
||||
***************************************************************************/
|
||||
static void pnic_close ( struct net_device *netdev __unused ) {
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
DISABLE - Turn off ethernet interface
|
||||
***************************************************************************/
|
||||
@ -238,6 +252,8 @@ static int pnic_probe ( struct pci_device *pci,
|
||||
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;
|
||||
|
||||
|
@ -542,8 +542,8 @@ static int rtl_probe ( struct pci_device *pci,
|
||||
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->open = rtl_open;
|
||||
netdev->close = rtl_close;
|
||||
netdev->transmit = rtl_transmit;
|
||||
netdev->poll = rtl_poll;
|
||||
|
||||
@ -558,10 +558,6 @@ static int rtl_probe ( struct pci_device *pci,
|
||||
goto err;
|
||||
}
|
||||
|
||||
#warning "Hack alert"
|
||||
rtl_open ( netdev );
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
@ -584,10 +580,6 @@ static void rtl_remove ( struct pci_device *pci ) {
|
||||
struct net_device *netdev = pci_get_drvdata ( pci );
|
||||
struct rtl8139_nic *rtl = netdev->priv;
|
||||
|
||||
|
||||
#warning "Hack alert"
|
||||
rtl_close ( netdev );
|
||||
|
||||
if ( rtl->nvo.nvs )
|
||||
nvo_unregister ( &rtl->nvo );
|
||||
unregister_netdev ( netdev );
|
||||
|
@ -142,6 +142,23 @@ struct net_device {
|
||||
/** List of persistent reference holders */
|
||||
struct list_head references;
|
||||
|
||||
/** Open network device
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This method should allocate RX packet buffers and enable
|
||||
* the hardware to start transmitting and receiving packets.
|
||||
*/
|
||||
int ( * open ) ( struct net_device *netdev );
|
||||
/** Close network device
|
||||
*
|
||||
* @v netdev Network device
|
||||
*
|
||||
* This method should stop the flow of packets, and free up
|
||||
* any packets that are currently in the device's TX queue.
|
||||
*/
|
||||
void ( * close ) ( struct net_device *netdev );
|
||||
/** Transmit packet
|
||||
*
|
||||
* @v netdev Network device
|
||||
@ -154,6 +171,9 @@ struct net_device {
|
||||
* Ownership of the packet buffer is transferred to the @c
|
||||
* net_device, which must eventually call free_pkb() to
|
||||
* release the buffer.
|
||||
*
|
||||
* This method is guaranteed to be called only when the device
|
||||
* is open.
|
||||
*/
|
||||
int ( * transmit ) ( struct net_device *netdev, struct pk_buff *pkb );
|
||||
/** Poll for received packet
|
||||
@ -163,6 +183,9 @@ struct net_device {
|
||||
* This method should cause the hardware to check for received
|
||||
* packets. Any received packets should be delivered via
|
||||
* netdev_rx().
|
||||
*
|
||||
* This method is guaranteed to be called only when the device
|
||||
* is open.
|
||||
*/
|
||||
void ( * poll ) ( struct net_device *netdev );
|
||||
|
||||
@ -174,6 +197,11 @@ struct net_device {
|
||||
*/
|
||||
uint8_t ll_addr[MAX_LL_ADDR_LEN];
|
||||
|
||||
/** Current device state
|
||||
*
|
||||
* This is the bitwise-OR of zero or more NETDEV_XXX constants.
|
||||
*/
|
||||
unsigned int state;
|
||||
/** Received packet queue */
|
||||
struct list_head rx_queue;
|
||||
|
||||
@ -181,6 +209,9 @@ struct net_device {
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/** Network device is open */
|
||||
#define NETDEV_OPEN 0x0001
|
||||
|
||||
/** Declare a link-layer protocol */
|
||||
#define __ll_protocol __table ( ll_protocols, 01 )
|
||||
|
||||
@ -209,6 +240,8 @@ extern int netdev_poll ( struct net_device *netdev );
|
||||
extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
|
||||
extern struct net_device * alloc_netdev ( size_t priv_size );
|
||||
extern int register_netdev ( struct net_device *netdev );
|
||||
extern int netdev_open ( struct net_device *netdev );
|
||||
extern void netdev_close ( struct net_device *netdev );
|
||||
extern void unregister_netdev ( struct net_device *netdev );
|
||||
extern void free_netdev ( struct net_device *netdev );
|
||||
extern struct net_device * next_netdev ( void );
|
||||
|
@ -54,6 +54,12 @@ static LIST_HEAD ( net_devices );
|
||||
int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
DBG ( "%s transmitting %p+%zx\n", netdev_name ( netdev ),
|
||||
pkb->data, pkb_len ( pkb ) );
|
||||
|
||||
if ( ! ( netdev->state & NETDEV_OPEN ) ) {
|
||||
free_pkb ( pkb );
|
||||
return -ENETUNREACH;
|
||||
}
|
||||
|
||||
return netdev->transmit ( netdev, pkb );
|
||||
}
|
||||
|
||||
@ -100,7 +106,7 @@ int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
uint16_t net_proto, const void *ll_source ) {
|
||||
uint16_t net_proto, const void *ll_source ) {
|
||||
struct net_protocol *net_protocol;
|
||||
|
||||
/* Hand off to network-layer protocol, if any */
|
||||
@ -125,7 +131,10 @@ int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
* packets will be added to the RX packet queue via netdev_rx().
|
||||
*/
|
||||
int netdev_poll ( struct net_device *netdev ) {
|
||||
netdev->poll ( netdev );
|
||||
|
||||
if ( netdev->state & NETDEV_OPEN )
|
||||
netdev->poll ( netdev );
|
||||
|
||||
return ( ! list_empty ( &netdev->rx_queue ) );
|
||||
}
|
||||
|
||||
@ -186,15 +195,46 @@ int register_netdev ( struct net_device *netdev ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister network device
|
||||
* Open network device
|
||||
*
|
||||
* @v netdev Network device
|
||||
*
|
||||
* Removes the network device from the list of network devices.
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
void unregister_netdev ( struct net_device *netdev ) {
|
||||
int netdev_open ( struct net_device *netdev ) {
|
||||
int rc;
|
||||
|
||||
/* Do nothing if device is already open */
|
||||
if ( netdev->state & NETDEV_OPEN )
|
||||
return 0;
|
||||
|
||||
DBG ( "%s opening\n", netdev_name ( netdev ) );
|
||||
|
||||
/* Open the device */
|
||||
if ( ( rc = netdev->open ( netdev ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Mark as opened */
|
||||
netdev->state |= NETDEV_OPEN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close network device
|
||||
*
|
||||
* @v netdev Network device
|
||||
*/
|
||||
void netdev_close ( struct net_device *netdev ) {
|
||||
struct pk_buff *pkb;
|
||||
|
||||
/* Do nothing if device is already closed */
|
||||
if ( ! ( netdev->state & NETDEV_OPEN ) )
|
||||
return;
|
||||
|
||||
DBG ( "%s closing\n", netdev_name ( netdev ) );
|
||||
|
||||
/* Close the device */
|
||||
netdev->close ( netdev );
|
||||
|
||||
/* Discard any packets in the RX queue */
|
||||
while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
|
||||
DBG ( "%s discarding %p+%zx\n", netdev_name ( netdev ),
|
||||
@ -202,6 +242,22 @@ void unregister_netdev ( struct net_device *netdev ) {
|
||||
free_pkb ( pkb );
|
||||
}
|
||||
|
||||
/* Mark as closed */
|
||||
netdev->state &= ~NETDEV_OPEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister network device
|
||||
*
|
||||
* @v netdev Network device
|
||||
*
|
||||
* Removes the network device from the list of network devices.
|
||||
*/
|
||||
void unregister_netdev ( struct net_device *netdev ) {
|
||||
|
||||
/* Ensure device is closed */
|
||||
netdev_close ( netdev );
|
||||
|
||||
/* Kill off any persistent references to this device */
|
||||
forget_references ( &netdev->references );
|
||||
|
||||
|
@ -16,7 +16,9 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <vsprintf.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/autoboot.h>
|
||||
|
||||
/** @file
|
||||
@ -30,11 +32,21 @@ void test_dhcp ( struct net_device *netdev );
|
||||
|
||||
void autoboot ( void ) {
|
||||
struct net_device *netdev;
|
||||
int rc;
|
||||
|
||||
netdev = next_netdev ();
|
||||
if ( netdev ) {
|
||||
test_dhcp ( netdev );
|
||||
} else {
|
||||
if ( ! netdev ) {
|
||||
printf ( "No network device found\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( rc = netdev_open ( netdev ) ) != 0 ) {
|
||||
printf ( "Could not open %s: %s\n", netdev_name ( netdev ),
|
||||
strerror ( rc ) );
|
||||
return;
|
||||
}
|
||||
|
||||
test_dhcp ( netdev );
|
||||
|
||||
netdev_close ( netdev );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user