Kill off hotplug.h and just make net devices normal reference-counted
structures. DHCP still broken and #if 0'd out.
This commit is contained in:
parent
e381714c07
commit
f77815f2b1
@ -675,7 +675,7 @@ int undinet_probe ( struct undi_device *undi ) {
|
|||||||
undinet_call ( undinic, PXENV_STOP_UNDI, &stop_undi,
|
undinet_call ( undinic, PXENV_STOP_UNDI, &stop_undi,
|
||||||
sizeof ( stop_undi ) );
|
sizeof ( stop_undi ) );
|
||||||
err_start_undi:
|
err_start_undi:
|
||||||
free_netdev ( netdev );
|
netdev_put ( netdev );
|
||||||
undi_set_drvdata ( undi, NULL );
|
undi_set_drvdata ( undi, NULL );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -710,7 +710,7 @@ void undinet_remove ( struct undi_device *undi ) {
|
|||||||
undi->flags &= ~UNDI_FL_STARTED;
|
undi->flags &= ~UNDI_FL_STARTED;
|
||||||
|
|
||||||
/* Free network device */
|
/* Free network device */
|
||||||
free_netdev ( netdev );
|
netdev_put ( netdev );
|
||||||
|
|
||||||
DBGC ( undinic, "UNDINIC %p removed\n", undinic );
|
DBGC ( undinic, "UNDINIC %p removed\n", undinic );
|
||||||
}
|
}
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 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 <assert.h>
|
|
||||||
#include <gpxe/hotplug.h>
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* Hotplug support
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forget all persistent references to an object
|
|
||||||
*
|
|
||||||
* @v list List of persistent references
|
|
||||||
*/
|
|
||||||
void forget_references ( struct list_head *list ) {
|
|
||||||
struct reference *ref;
|
|
||||||
struct reference *ref_tmp;
|
|
||||||
|
|
||||||
list_for_each_entry_safe ( ref, ref_tmp, list, list ) {
|
|
||||||
ref->forget ( ref );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The list had really better be empty by now, otherwise we're
|
|
||||||
* screwed.
|
|
||||||
*/
|
|
||||||
assert ( list_empty ( list ) );
|
|
||||||
}
|
|
@ -90,13 +90,13 @@ int legacy_probe ( void *hwdev,
|
|||||||
nic.node_addr = netdev->ll_addr;
|
nic.node_addr = netdev->ll_addr;
|
||||||
|
|
||||||
if ( ! probe ( &nic, hwdev ) ) {
|
if ( ! probe ( &nic, hwdev ) ) {
|
||||||
free_netdev ( netdev );
|
netdev_put ( netdev );
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
|
if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
|
||||||
disable ( &nic, hwdev );
|
disable ( &nic, hwdev );
|
||||||
free_netdev ( netdev );
|
netdev_put ( netdev );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ void legacy_remove ( void *hwdev,
|
|||||||
|
|
||||||
unregister_netdev ( netdev );
|
unregister_netdev ( netdev );
|
||||||
disable ( nic, hwdev );
|
disable ( nic, hwdev );
|
||||||
free_netdev ( netdev );
|
netdev_put ( netdev );
|
||||||
legacy_registered = 0;
|
legacy_registered = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ static void pnic_remove ( struct pci_device *pci ) {
|
|||||||
|
|
||||||
unregister_netdev ( netdev );
|
unregister_netdev ( netdev );
|
||||||
pnic_command ( pnic, PNIC_CMD_RESET, NULL, 0, NULL, 0, NULL );
|
pnic_command ( pnic, PNIC_CMD_RESET, NULL, 0, NULL, 0, NULL );
|
||||||
free_netdev ( netdev );
|
netdev_put ( netdev );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
@ -220,20 +220,18 @@ static int pnic_probe ( struct pci_device *pci,
|
|||||||
uint16_t status;
|
uint16_t status;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Fix up PCI device */
|
|
||||||
adjust_pci_device ( pci );
|
|
||||||
|
|
||||||
/* Allocate net device */
|
/* Allocate net device */
|
||||||
netdev = alloc_etherdev ( sizeof ( *pnic ) );
|
netdev = alloc_etherdev ( sizeof ( *pnic ) );
|
||||||
if ( ! netdev ) {
|
if ( ! netdev )
|
||||||
rc = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
pnic = netdev->priv;
|
pnic = netdev->priv;
|
||||||
pci_set_drvdata ( pci, netdev );
|
pci_set_drvdata ( pci, netdev );
|
||||||
netdev->dev = &pci->dev;
|
netdev->dev = &pci->dev;
|
||||||
pnic->ioaddr = pci->ioaddr;
|
pnic->ioaddr = pci->ioaddr;
|
||||||
|
|
||||||
|
/* Fix up PCI device */
|
||||||
|
adjust_pci_device ( pci );
|
||||||
|
|
||||||
/* API version check */
|
/* API version check */
|
||||||
status = pnic_command_quiet ( pnic, PNIC_CMD_API_VER, NULL, 0,
|
status = pnic_command_quiet ( pnic, PNIC_CMD_API_VER, NULL, 0,
|
||||||
&api_version,
|
&api_version,
|
||||||
@ -264,7 +262,7 @@ static int pnic_probe ( struct pci_device *pci,
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
/* Free net device */
|
/* Free net device */
|
||||||
free_netdev ( netdev );
|
netdev_put ( netdev );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,25 +501,22 @@ static void rtl_irq(struct nic *nic, irq_action_t action)
|
|||||||
static int rtl_probe ( struct pci_device *pci,
|
static int rtl_probe ( struct pci_device *pci,
|
||||||
const struct pci_device_id *id __unused ) {
|
const struct pci_device_id *id __unused ) {
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct rtl8139_nic *rtl = NULL;
|
struct rtl8139_nic *rtl;
|
||||||
int registered_netdev = 0;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Fix up PCI device */
|
|
||||||
adjust_pci_device ( pci );
|
|
||||||
|
|
||||||
/* Allocate net device */
|
/* Allocate net device */
|
||||||
netdev = alloc_etherdev ( sizeof ( *rtl ) );
|
netdev = alloc_etherdev ( sizeof ( *rtl ) );
|
||||||
if ( ! netdev ) {
|
if ( ! netdev )
|
||||||
rc = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
rtl = netdev->priv;
|
rtl = netdev->priv;
|
||||||
pci_set_drvdata ( pci, netdev );
|
pci_set_drvdata ( pci, netdev );
|
||||||
netdev->dev = &pci->dev;
|
netdev->dev = &pci->dev;
|
||||||
memset ( rtl, 0, sizeof ( *rtl ) );
|
memset ( rtl, 0, sizeof ( *rtl ) );
|
||||||
rtl->ioaddr = pci->ioaddr;
|
rtl->ioaddr = pci->ioaddr;
|
||||||
|
|
||||||
|
/* Fix up PCI device */
|
||||||
|
adjust_pci_device ( pci );
|
||||||
|
|
||||||
/* Reset the NIC, set up EEPROM access and read MAC address */
|
/* Reset the NIC, set up EEPROM access and read MAC address */
|
||||||
rtl_reset ( rtl );
|
rtl_reset ( rtl );
|
||||||
rtl_init_eeprom ( rtl );
|
rtl_init_eeprom ( rtl );
|
||||||
@ -533,25 +530,21 @@ static int rtl_probe ( struct pci_device *pci,
|
|||||||
|
|
||||||
/* Register network device */
|
/* Register network device */
|
||||||
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|
||||||
goto err;
|
goto err_register_netdev;
|
||||||
registered_netdev = 1;
|
|
||||||
|
|
||||||
/* Register non-volatile storage */
|
/* Register non-volatile storage */
|
||||||
if ( rtl->nvo.nvs ) {
|
if ( rtl->nvo.nvs ) {
|
||||||
if ( ( rc = nvo_register ( &rtl->nvo ) ) != 0 )
|
if ( ( rc = nvo_register ( &rtl->nvo ) ) != 0 )
|
||||||
goto err;
|
goto err_register_nvo;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err_register_nvo:
|
||||||
/* Disable NIC */
|
unregister_netdev ( netdev );
|
||||||
if ( rtl )
|
err_register_netdev:
|
||||||
rtl_reset ( rtl );
|
rtl_reset ( rtl );
|
||||||
if ( registered_netdev )
|
netdev_put ( netdev );
|
||||||
unregister_netdev ( netdev );
|
|
||||||
/* Free net device */
|
|
||||||
free_netdev ( netdev );
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,7 +561,7 @@ static void rtl_remove ( struct pci_device *pci ) {
|
|||||||
nvo_unregister ( &rtl->nvo );
|
nvo_unregister ( &rtl->nvo );
|
||||||
unregister_netdev ( netdev );
|
unregister_netdev ( netdev );
|
||||||
rtl_reset ( rtl );
|
rtl_reset ( rtl );
|
||||||
free_netdev ( netdev );
|
netdev_put ( netdev );
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_device_id rtl8139_nics[] = {
|
static struct pci_device_id rtl8139_nics[] = {
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include <gpxe/retry.h>
|
#include <gpxe/retry.h>
|
||||||
#include <gpxe/async.h>
|
#include <gpxe/async.h>
|
||||||
#include <gpxe/ata.h>
|
#include <gpxe/ata.h>
|
||||||
#include <gpxe/hotplug.h>
|
|
||||||
|
|
||||||
/** An AoE ATA command */
|
/** An AoE ATA command */
|
||||||
struct aoecmd {
|
struct aoecmd {
|
||||||
@ -87,8 +86,6 @@ struct aoe_session {
|
|||||||
|
|
||||||
/** Network device */
|
/** Network device */
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
/** Reference to network device */
|
|
||||||
struct reference netdev_ref;
|
|
||||||
|
|
||||||
/** Major number */
|
/** Major number */
|
||||||
uint16_t major;
|
uint16_t major;
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
#include <gpxe/udp.h>
|
#include <gpxe/udp.h>
|
||||||
#include <gpxe/async.h>
|
#include <gpxe/async.h>
|
||||||
#include <gpxe/retry.h>
|
#include <gpxe/retry.h>
|
||||||
#include <gpxe/hotplug.h>
|
|
||||||
|
|
||||||
/** BOOTP/DHCP server port */
|
/** BOOTP/DHCP server port */
|
||||||
#define BOOTPS_PORT 67
|
#define BOOTPS_PORT 67
|
||||||
@ -449,6 +448,8 @@ struct dhcp_packet {
|
|||||||
struct dhcp_option_block options[NUM_OPT_BLOCKS];
|
struct dhcp_option_block options[NUM_OPT_BLOCKS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct udp_connection {};
|
||||||
|
|
||||||
/** A DHCP session */
|
/** A DHCP session */
|
||||||
struct dhcp_session {
|
struct dhcp_session {
|
||||||
/** UDP connection for this session */
|
/** UDP connection for this session */
|
||||||
@ -456,8 +457,6 @@ struct dhcp_session {
|
|||||||
|
|
||||||
/** Network device being configured */
|
/** Network device being configured */
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
/** Persistent reference to network device */
|
|
||||||
struct reference netdev_ref;
|
|
||||||
|
|
||||||
/** Options obtained from server */
|
/** Options obtained from server */
|
||||||
struct dhcp_option_block *options;
|
struct dhcp_option_block *options;
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
#ifndef _GPXE_HOTPLUG_H
|
|
||||||
#define _GPXE_HOTPLUG_H
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* Hotplug support
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gpxe/list.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A persistent reference to another data structure
|
|
||||||
*
|
|
||||||
* This data structure should be embedded within any data structure
|
|
||||||
* (the referrer) which holds a persistent reference to a separate,
|
|
||||||
* volatile data structure (the referee).
|
|
||||||
*/
|
|
||||||
struct reference {
|
|
||||||
/** List of persistent references */
|
|
||||||
struct list_head list;
|
|
||||||
/** Forget persistent reference
|
|
||||||
*
|
|
||||||
* @v ref Persistent reference
|
|
||||||
*
|
|
||||||
* This method is called immediately before the referred-to
|
|
||||||
* data structure is destroyed. The reference holder must
|
|
||||||
* forget all references to the referee before returning from
|
|
||||||
* this method.
|
|
||||||
*
|
|
||||||
* This method must also call ref_del() to remove the
|
|
||||||
* reference.
|
|
||||||
*/
|
|
||||||
void ( * forget ) ( struct reference *ref );
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add persistent reference
|
|
||||||
*
|
|
||||||
* @v ref Persistent reference
|
|
||||||
* @v list List of persistent references
|
|
||||||
*/
|
|
||||||
static inline void ref_add ( struct reference *ref, struct list_head *list ) {
|
|
||||||
list_add ( &ref->list, list );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove persistent reference
|
|
||||||
*
|
|
||||||
* @v ref Persistent reference
|
|
||||||
*/
|
|
||||||
static inline void ref_del ( struct reference *ref ) {
|
|
||||||
list_del ( &ref->list );
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void forget_references ( struct list_head *list );
|
|
||||||
|
|
||||||
#endif /* _GPXE_HOTPLUG_H */
|
|
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <ip.h>
|
#include <ip.h>
|
||||||
#include <gpxe/retry.h>
|
#include <gpxe/retry.h>
|
||||||
#include <gpxe/hotplug.h>
|
|
||||||
|
|
||||||
/* IP constants */
|
/* IP constants */
|
||||||
|
|
||||||
@ -44,8 +43,6 @@ struct ipv4_miniroute {
|
|||||||
|
|
||||||
/** Network device */
|
/** Network device */
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
/** Reference to network device */
|
|
||||||
struct reference netdev_ref;
|
|
||||||
|
|
||||||
/** IPv4 address */
|
/** IPv4 address */
|
||||||
struct in_addr address;
|
struct in_addr address;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <gpxe/list.h>
|
#include <gpxe/list.h>
|
||||||
#include <gpxe/tables.h>
|
#include <gpxe/tables.h>
|
||||||
#include <gpxe/hotplug.h>
|
#include <gpxe/refcnt.h>
|
||||||
|
|
||||||
struct io_buffer;
|
struct io_buffer;
|
||||||
struct net_device;
|
struct net_device;
|
||||||
@ -137,14 +137,14 @@ struct ll_protocol {
|
|||||||
* not just an Ethernet device.
|
* not just an Ethernet device.
|
||||||
*/
|
*/
|
||||||
struct net_device {
|
struct net_device {
|
||||||
|
/** Reference counter */
|
||||||
|
struct refcnt refcnt;
|
||||||
/** List of network devices */
|
/** List of network devices */
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
/** Name of this network device */
|
/** Name of this network device */
|
||||||
char name[8];
|
char name[8];
|
||||||
/** Underlying hardware device */
|
/** Underlying hardware device */
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
/** List of persistent reference holders */
|
|
||||||
struct list_head references;
|
|
||||||
|
|
||||||
/** Open network device
|
/** Open network device
|
||||||
*
|
*
|
||||||
@ -251,6 +251,28 @@ static inline int have_netdevs ( void ) {
|
|||||||
return ( ! list_empty ( &net_devices ) );
|
return ( ! list_empty ( &net_devices ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get reference to network device
|
||||||
|
*
|
||||||
|
* @v netdev Network device
|
||||||
|
* @ret netdev Network device
|
||||||
|
*/
|
||||||
|
static inline __attribute__ (( always_inline )) struct net_device *
|
||||||
|
netdev_get ( struct net_device *netdev ) {
|
||||||
|
ref_get ( &netdev->refcnt );
|
||||||
|
return netdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop reference to network device
|
||||||
|
*
|
||||||
|
* @v netdev Network device
|
||||||
|
*/
|
||||||
|
static inline __attribute__ (( always_inline )) void
|
||||||
|
netdev_put ( struct net_device *netdev ) {
|
||||||
|
ref_put ( &netdev->refcnt );
|
||||||
|
}
|
||||||
|
|
||||||
extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
|
extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
|
||||||
void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf );
|
void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf );
|
||||||
void netdev_tx_complete_next ( struct net_device *netdev );
|
void netdev_tx_complete_next ( struct net_device *netdev );
|
||||||
@ -262,7 +284,6 @@ extern int register_netdev ( struct net_device *netdev );
|
|||||||
extern int netdev_open ( struct net_device *netdev );
|
extern int netdev_open ( struct net_device *netdev );
|
||||||
extern void netdev_close ( struct net_device *netdev );
|
extern void netdev_close ( struct net_device *netdev );
|
||||||
extern void unregister_netdev ( struct net_device *netdev );
|
extern void unregister_netdev ( struct net_device *netdev );
|
||||||
extern void free_netdev ( struct net_device *netdev );
|
|
||||||
struct net_device * find_netdev ( const char *name );
|
struct net_device * find_netdev ( const char *name );
|
||||||
struct net_device * find_pci_netdev ( unsigned int busdevfn );
|
struct net_device * find_pci_netdev ( unsigned int busdevfn );
|
||||||
|
|
||||||
|
@ -265,19 +265,6 @@ struct net_protocol aoe_protocol __net_protocol = {
|
|||||||
.rx = aoe_rx,
|
.rx = aoe_rx,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Forget reference to net_device
|
|
||||||
*
|
|
||||||
* @v ref Persistent reference
|
|
||||||
*/
|
|
||||||
static void aoe_forget_netdev ( struct reference *ref ) {
|
|
||||||
struct aoe_session *aoe
|
|
||||||
= container_of ( ref, struct aoe_session, netdev_ref );
|
|
||||||
|
|
||||||
aoe->netdev = NULL;
|
|
||||||
ref_del ( &aoe->netdev_ref );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open AoE session
|
* Open AoE session
|
||||||
*
|
*
|
||||||
@ -288,8 +275,6 @@ void aoe_open ( struct aoe_session *aoe ) {
|
|||||||
sizeof ( aoe->target ) );
|
sizeof ( aoe->target ) );
|
||||||
aoe->tag = AOE_TAG_MAGIC;
|
aoe->tag = AOE_TAG_MAGIC;
|
||||||
aoe->timer.expired = aoe_timer_expired;
|
aoe->timer.expired = aoe_timer_expired;
|
||||||
aoe->netdev_ref.forget = aoe_forget_netdev;
|
|
||||||
ref_add ( &aoe->netdev_ref, &aoe->netdev->references );
|
|
||||||
list_add ( &aoe->list, &aoe_sessions );
|
list_add ( &aoe->list, &aoe_sessions );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,8 +284,6 @@ void aoe_open ( struct aoe_session *aoe ) {
|
|||||||
* @v aoe AoE session
|
* @v aoe AoE session
|
||||||
*/
|
*/
|
||||||
void aoe_close ( struct aoe_session *aoe ) {
|
void aoe_close ( struct aoe_session *aoe ) {
|
||||||
if ( aoe->netdev )
|
|
||||||
ref_del ( &aoe->netdev_ref );
|
|
||||||
list_del ( &aoe->list );
|
list_del ( &aoe->list );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,6 @@ struct list_head ipv4_miniroutes = LIST_HEAD_INIT ( ipv4_miniroutes );
|
|||||||
/** List of fragment reassembly buffers */
|
/** List of fragment reassembly buffers */
|
||||||
static LIST_HEAD ( frag_buffers );
|
static LIST_HEAD ( frag_buffers );
|
||||||
|
|
||||||
static void ipv4_forget_netdev ( struct reference *ref );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add IPv4 minirouting table entry
|
* Add IPv4 minirouting table entry
|
||||||
*
|
*
|
||||||
@ -61,7 +59,7 @@ static struct ipv4_miniroute * add_ipv4_miniroute ( struct net_device *netdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Record routing information */
|
/* Record routing information */
|
||||||
miniroute->netdev = netdev;
|
miniroute->netdev = netdev_get ( netdev );
|
||||||
miniroute->address = address;
|
miniroute->address = address;
|
||||||
miniroute->netmask = netmask;
|
miniroute->netmask = netmask;
|
||||||
miniroute->gateway = gateway;
|
miniroute->gateway = gateway;
|
||||||
@ -75,10 +73,6 @@ static struct ipv4_miniroute * add_ipv4_miniroute ( struct net_device *netdev,
|
|||||||
list_add ( &miniroute->list, &ipv4_miniroutes );
|
list_add ( &miniroute->list, &ipv4_miniroutes );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record reference to net_device */
|
|
||||||
miniroute->netdev_ref.forget = ipv4_forget_netdev;
|
|
||||||
ref_add ( &miniroute->netdev_ref, &netdev->references );
|
|
||||||
|
|
||||||
return miniroute;
|
return miniroute;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,23 +89,11 @@ static void del_ipv4_miniroute ( struct ipv4_miniroute *miniroute ) {
|
|||||||
DBG ( "gw %s ", inet_ntoa ( miniroute->gateway ) );
|
DBG ( "gw %s ", inet_ntoa ( miniroute->gateway ) );
|
||||||
DBG ( "via %s\n", miniroute->netdev->name );
|
DBG ( "via %s\n", miniroute->netdev->name );
|
||||||
|
|
||||||
ref_del ( &miniroute->netdev_ref );
|
netdev_put ( miniroute->netdev );
|
||||||
list_del ( &miniroute->list );
|
list_del ( &miniroute->list );
|
||||||
free ( miniroute );
|
free ( miniroute );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Forget reference to net_device
|
|
||||||
*
|
|
||||||
* @v ref Persistent reference
|
|
||||||
*/
|
|
||||||
static void ipv4_forget_netdev ( struct reference *ref ) {
|
|
||||||
struct ipv4_miniroute *miniroute
|
|
||||||
= container_of ( ref, struct ipv4_miniroute, netdev_ref );
|
|
||||||
|
|
||||||
del_ipv4_miniroute ( miniroute );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add IPv4 interface
|
* Add IPv4 interface
|
||||||
*
|
*
|
||||||
|
@ -32,8 +32,6 @@ struct ipv6_miniroute {
|
|||||||
|
|
||||||
/* Network device */
|
/* Network device */
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
/** Reference to network device */
|
|
||||||
struct reference netdev_ref;
|
|
||||||
|
|
||||||
/* Destination prefix */
|
/* Destination prefix */
|
||||||
struct in6_addr prefix;
|
struct in6_addr prefix;
|
||||||
@ -48,8 +46,6 @@ struct ipv6_miniroute {
|
|||||||
/** List of IPv6 miniroutes */
|
/** List of IPv6 miniroutes */
|
||||||
static LIST_HEAD ( miniroutes );
|
static LIST_HEAD ( miniroutes );
|
||||||
|
|
||||||
static void ipv6_forget_netdev ( struct reference *ref );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add IPv6 minirouting table entry
|
* Add IPv6 minirouting table entry
|
||||||
*
|
*
|
||||||
@ -69,7 +65,7 @@ static struct ipv6_miniroute * add_ipv6_miniroute ( struct net_device *netdev,
|
|||||||
miniroute = malloc ( sizeof ( *miniroute ) );
|
miniroute = malloc ( sizeof ( *miniroute ) );
|
||||||
if ( miniroute ) {
|
if ( miniroute ) {
|
||||||
/* Record routing information */
|
/* Record routing information */
|
||||||
miniroute->netdev = netdev;
|
miniroute->netdev = netdev_get ( netdev );
|
||||||
miniroute->prefix = prefix;
|
miniroute->prefix = prefix;
|
||||||
miniroute->prefix_len = prefix_len;
|
miniroute->prefix_len = prefix_len;
|
||||||
miniroute->address = address;
|
miniroute->address = address;
|
||||||
@ -81,10 +77,6 @@ static struct ipv6_miniroute * add_ipv6_miniroute ( struct net_device *netdev,
|
|||||||
} else {
|
} else {
|
||||||
list_add ( &miniroute->list, &miniroutes );
|
list_add ( &miniroute->list, &miniroutes );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record reference to net_device */
|
|
||||||
miniroute->netdev_ref.forget = ipv6_forget_netdev;
|
|
||||||
ref_add ( &miniroute->netdev_ref, &netdev->references );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return miniroute;
|
return miniroute;
|
||||||
@ -96,23 +88,11 @@ static struct ipv6_miniroute * add_ipv6_miniroute ( struct net_device *netdev,
|
|||||||
* @v miniroute Routing table entry
|
* @v miniroute Routing table entry
|
||||||
*/
|
*/
|
||||||
static void del_ipv6_miniroute ( struct ipv6_miniroute *miniroute ) {
|
static void del_ipv6_miniroute ( struct ipv6_miniroute *miniroute ) {
|
||||||
ref_del ( &miniroute->netdev_ref );
|
netdev_put ( miniroute->netdev );
|
||||||
list_del ( &miniroute->list );
|
list_del ( &miniroute->list );
|
||||||
free ( miniroute );
|
free ( miniroute );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Forget reference to net_device
|
|
||||||
*
|
|
||||||
* @v ref Persistent reference
|
|
||||||
*/
|
|
||||||
static void ipv6_forget_netdev ( struct reference *ref ) {
|
|
||||||
struct ipv6_miniroute *miniroute
|
|
||||||
= container_of ( ref, struct ipv6_miniroute, netdev_ref );
|
|
||||||
|
|
||||||
del_ipv6_miniroute ( miniroute );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add IPv6 interface
|
* Add IPv6 interface
|
||||||
*
|
*
|
||||||
|
@ -115,6 +115,19 @@ void netdev_tx_complete_next ( struct net_device *netdev ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush device's transmit queue
|
||||||
|
*
|
||||||
|
* @v netdev Network device
|
||||||
|
*/
|
||||||
|
static void netdev_tx_flush ( struct net_device *netdev ) {
|
||||||
|
|
||||||
|
/* Discard any packets in the TX queue */
|
||||||
|
while ( ! list_empty ( &netdev->tx_queue ) ) {
|
||||||
|
netdev_tx_complete_next ( netdev );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add packet to receive queue
|
* Add packet to receive queue
|
||||||
*
|
*
|
||||||
@ -168,6 +181,36 @@ struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush device's receive queue
|
||||||
|
*
|
||||||
|
* @v netdev Network device
|
||||||
|
*/
|
||||||
|
static void netdev_rx_flush ( struct net_device *netdev ) {
|
||||||
|
struct io_buffer *iobuf;
|
||||||
|
|
||||||
|
/* Discard any packets in the RX queue */
|
||||||
|
while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
|
||||||
|
DBGC ( netdev, "NETDEV %p discarding received %p\n",
|
||||||
|
netdev, iobuf );
|
||||||
|
free_iob ( iobuf );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free network device
|
||||||
|
*
|
||||||
|
* @v refcnt Network device reference counter
|
||||||
|
*/
|
||||||
|
static void free_netdev ( struct refcnt *refcnt ) {
|
||||||
|
struct net_device *netdev =
|
||||||
|
container_of ( refcnt, struct net_device, refcnt );
|
||||||
|
|
||||||
|
netdev_tx_flush ( netdev );
|
||||||
|
netdev_rx_flush ( netdev );
|
||||||
|
free ( netdev );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate network device
|
* Allocate network device
|
||||||
*
|
*
|
||||||
@ -184,7 +227,7 @@ struct net_device * alloc_netdev ( size_t priv_size ) {
|
|||||||
netdev = malloc ( total_len );
|
netdev = malloc ( total_len );
|
||||||
if ( netdev ) {
|
if ( netdev ) {
|
||||||
memset ( netdev, 0, total_len );
|
memset ( netdev, 0, total_len );
|
||||||
INIT_LIST_HEAD ( &netdev->references );
|
netdev->refcnt.free = free_netdev;
|
||||||
INIT_LIST_HEAD ( &netdev->tx_queue );
|
INIT_LIST_HEAD ( &netdev->tx_queue );
|
||||||
INIT_LIST_HEAD ( &netdev->rx_queue );
|
INIT_LIST_HEAD ( &netdev->rx_queue );
|
||||||
netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
|
netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
|
||||||
@ -209,6 +252,7 @@ int register_netdev ( struct net_device *netdev ) {
|
|||||||
ifindex++ );
|
ifindex++ );
|
||||||
|
|
||||||
/* Add to device list */
|
/* Add to device list */
|
||||||
|
netdev_get ( netdev );
|
||||||
list_add_tail ( &netdev->list, &net_devices );
|
list_add_tail ( &netdev->list, &net_devices );
|
||||||
DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
|
DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n",
|
||||||
netdev, netdev->name, netdev->dev->name,
|
netdev, netdev->name, netdev->dev->name,
|
||||||
@ -247,7 +291,6 @@ int netdev_open ( struct net_device *netdev ) {
|
|||||||
* @v netdev Network device
|
* @v netdev Network device
|
||||||
*/
|
*/
|
||||||
void netdev_close ( struct net_device *netdev ) {
|
void netdev_close ( struct net_device *netdev ) {
|
||||||
struct io_buffer *iobuf;
|
|
||||||
|
|
||||||
/* Do nothing if device is already closed */
|
/* Do nothing if device is already closed */
|
||||||
if ( ! ( netdev->state & NETDEV_OPEN ) )
|
if ( ! ( netdev->state & NETDEV_OPEN ) )
|
||||||
@ -258,17 +301,9 @@ void netdev_close ( struct net_device *netdev ) {
|
|||||||
/* Close the device */
|
/* Close the device */
|
||||||
netdev->close ( netdev );
|
netdev->close ( netdev );
|
||||||
|
|
||||||
/* Discard any packets in the TX queue */
|
/* Flush TX and RX queues */
|
||||||
while ( ! list_empty ( &netdev->tx_queue ) ) {
|
netdev_tx_flush ( netdev );
|
||||||
netdev_tx_complete_next ( netdev );
|
netdev_rx_flush ( netdev );
|
||||||
}
|
|
||||||
|
|
||||||
/* Discard any packets in the RX queue */
|
|
||||||
while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
|
|
||||||
DBGC ( netdev, "NETDEV %p discarding received %p\n",
|
|
||||||
netdev, iobuf );
|
|
||||||
free_iob ( iobuf );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark as closed */
|
/* Mark as closed */
|
||||||
netdev->state &= ~NETDEV_OPEN;
|
netdev->state &= ~NETDEV_OPEN;
|
||||||
@ -286,23 +321,12 @@ void unregister_netdev ( struct net_device *netdev ) {
|
|||||||
/* Ensure device is closed */
|
/* Ensure device is closed */
|
||||||
netdev_close ( netdev );
|
netdev_close ( netdev );
|
||||||
|
|
||||||
/* Kill off any persistent references to this device */
|
|
||||||
forget_references ( &netdev->references );
|
|
||||||
|
|
||||||
/* Remove from device list */
|
/* Remove from device list */
|
||||||
list_del ( &netdev->list );
|
list_del ( &netdev->list );
|
||||||
|
netdev_put ( netdev );
|
||||||
DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
|
DBGC ( netdev, "NETDEV %p unregistered\n", netdev );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Free network device
|
|
||||||
*
|
|
||||||
* @v netdev Network device
|
|
||||||
*/
|
|
||||||
void free_netdev ( struct net_device *netdev ) {
|
|
||||||
free ( netdev );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get network device by name
|
* Get network device by name
|
||||||
*
|
*
|
||||||
|
@ -140,7 +140,7 @@ static int udp_open_common ( struct xfer_interface *xfer,
|
|||||||
* @ret rc Return status code
|
* @ret rc Return status code
|
||||||
*/
|
*/
|
||||||
int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer,
|
int udp_open ( struct xfer_interface *xfer, struct sockaddr *peer,
|
||||||
struct sockaddr *local ) {
|
struct sockaddr *local ) {
|
||||||
return udp_open_common ( xfer, peer, local, 0 );
|
return udp_open_common ( xfer, peer, local, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,6 +493,8 @@ udp_to_dhcp ( struct udp_connection *conn ) {
|
|||||||
return container_of ( conn, struct dhcp_session, udp );
|
return container_of ( conn, struct dhcp_session, udp );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark DHCP session as complete
|
* Mark DHCP session as complete
|
||||||
*
|
*
|
||||||
@ -515,9 +517,6 @@ static void dhcp_done ( struct dhcp_session *dhcp, int rc ) {
|
|||||||
/* Close UDP connection */
|
/* Close UDP connection */
|
||||||
udp_close ( &dhcp->udp );
|
udp_close ( &dhcp->udp );
|
||||||
|
|
||||||
/* Release reference on net device */
|
|
||||||
ref_del ( &dhcp->netdev_ref );
|
|
||||||
|
|
||||||
/* Mark async operation as complete */
|
/* Mark async operation as complete */
|
||||||
async_done ( &dhcp->async, rc );
|
async_done ( &dhcp->async, rc );
|
||||||
}
|
}
|
||||||
@ -705,19 +704,6 @@ static struct udp_operations dhcp_udp_operations = {
|
|||||||
.newdata = dhcp_newdata,
|
.newdata = dhcp_newdata,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Forget reference to net_device
|
|
||||||
*
|
|
||||||
* @v ref Persistent reference
|
|
||||||
*/
|
|
||||||
static void dhcp_forget_netdev ( struct reference *ref ) {
|
|
||||||
struct dhcp_session *dhcp
|
|
||||||
= container_of ( ref, struct dhcp_session, netdev_ref );
|
|
||||||
|
|
||||||
/* Kill DHCP session immediately */
|
|
||||||
dhcp_done ( dhcp, -ENETUNREACH );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate DHCP on a network interface
|
* Initiate DHCP on a network interface
|
||||||
*
|
*
|
||||||
@ -742,13 +728,12 @@ int start_dhcp ( struct dhcp_session *dhcp, struct async *parent ) {
|
|||||||
if ( ( rc = udp_open ( &dhcp->udp, htons ( BOOTPC_PORT ) ) ) != 0 )
|
if ( ( rc = udp_open ( &dhcp->udp, htons ( BOOTPC_PORT ) ) ) != 0 )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Add persistent reference to net device */
|
|
||||||
dhcp->netdev_ref.forget = dhcp_forget_netdev;
|
|
||||||
ref_add ( &dhcp->netdev_ref, &dhcp->netdev->references );
|
|
||||||
|
|
||||||
/* Proof of concept: just send a single DHCPDISCOVER */
|
/* Proof of concept: just send a single DHCPDISCOVER */
|
||||||
dhcp_send_request ( dhcp );
|
dhcp_send_request ( dhcp );
|
||||||
|
|
||||||
async_init ( &dhcp->async, &default_async_operations, parent );
|
async_init ( &dhcp->async, &default_async_operations, parent );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Reference in New Issue
Block a user