aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-09-13 23:00:57 +0100
committerMichael Brown <mcb30@ipxe.org>2023-09-14 13:25:19 +0100
commitcac3a584dc8acea1522669f1ed16e0979fb92252 (patch)
tree3334e8632bea212f4fa3e4065898c2acdc113c1d
parent8cbf248198f3bc66c52b2340b4decf293af8af47 (diff)
downloadipxe-cac3a584dc8acea1522669f1ed16e0979fb92252.zip
ipxe-cac3a584dc8acea1522669f1ed16e0979fb92252.tar.gz
ipxe-cac3a584dc8acea1522669f1ed16e0979fb92252.tar.bz2
[fcoe] Use driver-private data to hold FCoE port structure
Simplify the FCoE code by using driver-private data to hold the FCoE port for each network device, instead of using a separate allocation. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/net/fcoe.c85
1 files changed, 21 insertions, 64 deletions
diff --git a/src/net/fcoe.c b/src/net/fcoe.c
index 70804dd..9f3ddf8 100644
--- a/src/net/fcoe.c
+++ b/src/net/fcoe.c
@@ -69,10 +69,6 @@ FEATURE ( FEATURE_PROTOCOL, "FCoE", DHCP_EB_FEATURE_FCOE, 1 );
/** An FCoE port */
struct fcoe_port {
- /** Reference count */
- struct refcnt refcnt;
- /** List of FCoE ports */
- struct list_head list;
/** Transport interface */
struct interface transport;
/** Network device */
@@ -115,6 +111,7 @@ enum fcoe_flags {
FCOE_VLAN_TIMED_OUT = 0x0020,
};
+struct net_driver fcoe_driver __net_driver;
struct net_protocol fcoe_protocol __net_protocol;
struct net_protocol fip_protocol __net_protocol;
@@ -152,9 +149,6 @@ static uint8_t default_fcf_mac[ETH_ALEN] =
/** Maximum number of missing discovery advertisements */
#define FCOE_MAX_FIP_MISSING_KEEPALIVES 4
-/** List of FCoE ports */
-static LIST_HEAD ( fcoe_ports );
-
/******************************************************************************
*
* FCoE protocol
@@ -163,22 +157,6 @@ static LIST_HEAD ( fcoe_ports );
*/
/**
- * Identify FCoE port by network device
- *
- * @v netdev Network device
- * @ret fcoe FCoE port, or NULL
- */
-static struct fcoe_port * fcoe_demux ( struct net_device *netdev ) {
- struct fcoe_port *fcoe;
-
- list_for_each_entry ( fcoe, &fcoe_ports, list ) {
- if ( fcoe->netdev == netdev )
- return fcoe;
- }
- return NULL;
-}
-
-/**
* Reset FCoE port
*
* @v fcoe FCoE port
@@ -348,7 +326,8 @@ static int fcoe_rx ( struct io_buffer *iobuf, struct net_device *netdev,
int rc;
/* Identify FCoE port */
- if ( ( fcoe = fcoe_demux ( netdev ) ) == NULL ) {
+ fcoe = netdev_priv ( netdev, &fcoe_driver );
+ if ( ! fcoe->netdev ) {
DBG ( "FCoE received frame for net device %s missing FCoE "
"port\n", netdev->name );
rc = -ENOTCONN;
@@ -448,9 +427,6 @@ static void fcoe_close ( struct fcoe_port *fcoe, int rc ) {
stop_timer ( &fcoe->timer );
intf_shutdown ( &fcoe->transport, rc );
- netdev_put ( fcoe->netdev );
- list_del ( &fcoe->list );
- ref_put ( &fcoe->refcnt );
}
/**
@@ -947,7 +923,8 @@ static int fcoe_fip_rx ( struct io_buffer *iobuf,
int rc;
/* Identify FCoE port */
- if ( ( fcoe = fcoe_demux ( netdev ) ) == NULL ) {
+ fcoe = netdev_priv ( netdev, &fcoe_driver );
+ if ( ! fcoe->netdev ) {
DBG ( "FCoE received FIP frame for net device %s missing FCoE "
"port\n", netdev->name );
rc = -ENOTCONN;
@@ -1113,29 +1090,21 @@ static void fcoe_expired ( struct retry_timer *timer, int over __unused ) {
* @v priv Private data
* @ret rc Return status code
*/
-static int fcoe_probe ( struct net_device *netdev, void *priv __unused ) {
+static int fcoe_probe ( struct net_device *netdev, void *priv ) {
struct ll_protocol *ll_protocol = netdev->ll_protocol;
- struct fcoe_port *fcoe;
- int rc;
+ struct fcoe_port *fcoe = priv;
/* Sanity check */
if ( ll_protocol->ll_proto != htons ( ARPHRD_ETHER ) ) {
/* Not an error; simply skip this net device */
DBG ( "FCoE skipping non-Ethernet device %s\n", netdev->name );
- rc = 0;
- goto err_non_ethernet;
+ return 0;
}
- /* Allocate and initialise structure */
- fcoe = zalloc ( sizeof ( *fcoe ) );
- if ( ! fcoe ) {
- rc = -ENOMEM;
- goto err_zalloc;
- }
- ref_init ( &fcoe->refcnt, NULL );
- intf_init ( &fcoe->transport, &fcoe_transport_desc, &fcoe->refcnt );
- timer_init ( &fcoe->timer, fcoe_expired, &fcoe->refcnt );
- fcoe->netdev = netdev_get ( netdev );
+ /* Initialise structure */
+ intf_init ( &fcoe->transport, &fcoe_transport_desc, &netdev->refcnt );
+ timer_init ( &fcoe->timer, fcoe_expired, &netdev->refcnt );
+ fcoe->netdev = netdev;
/* Construct node and port names */
fcoe->node_wwn.fcoe.authority = htons ( FCOE_AUTHORITY_IEEE );
@@ -1149,14 +1118,7 @@ static int fcoe_probe ( struct net_device *netdev, void *priv __unused ) {
fc_ntoa ( &fcoe->node_wwn.fc ) );
DBGC ( fcoe, " port %s\n", fc_ntoa ( &fcoe->port_wwn.fc ) );
- /* Transfer reference to port list */
- list_add ( &fcoe->list, &fcoe_ports );
return 0;
-
- netdev_put ( fcoe->netdev );
- err_zalloc:
- err_non_ethernet:
- return rc;
}
/**
@@ -1165,15 +1127,12 @@ static int fcoe_probe ( struct net_device *netdev, void *priv __unused ) {
* @v netdev Network device
* @v priv Private data
*/
-static void fcoe_notify ( struct net_device *netdev, void *priv __unused ) {
- struct fcoe_port *fcoe;
+static void fcoe_notify ( struct net_device *netdev, void *priv ) {
+ struct fcoe_port *fcoe = priv;
- /* Sanity check */
- if ( ( fcoe = fcoe_demux ( netdev ) ) == NULL ) {
- DBG ( "FCoE notification for net device %s missing FCoE "
- "port\n", netdev->name );
+ /* Skip non-FCoE net devices */
+ if ( ! fcoe->netdev )
return;
- }
/* Reset the FCoE link if necessary */
if ( ! ( netdev_is_open ( netdev ) &&
@@ -1189,15 +1148,12 @@ static void fcoe_notify ( struct net_device *netdev, void *priv __unused ) {
* @v netdev Network device
* @v priv Private data
*/
-static void fcoe_remove ( struct net_device *netdev, void *priv __unused ) {
- struct fcoe_port *fcoe;
+static void fcoe_remove ( struct net_device *netdev __unused, void *priv ) {
+ struct fcoe_port *fcoe = priv;
- /* Sanity check */
- if ( ( fcoe = fcoe_demux ( netdev ) ) == NULL ) {
- DBG ( "FCoE removal of net device %s missing FCoE port\n",
- netdev->name );
+ /* Skip non-FCoE net devices */
+ if ( ! fcoe->netdev )
return;
- }
/* Close FCoE device */
fcoe_close ( fcoe, 0 );
@@ -1206,6 +1162,7 @@ static void fcoe_remove ( struct net_device *netdev, void *priv __unused ) {
/** FCoE driver */
struct net_driver fcoe_driver __net_driver = {
.name = "FCoE",
+ .priv_len = sizeof ( struct fcoe_port ),
.probe = fcoe_probe,
.notify = fcoe_notify,
.remove = fcoe_remove,