]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[fcoe] Use driver-private data to hold FCoE port structure
authorMichael Brown <mcb30@ipxe.org>
Wed, 13 Sep 2023 22:00:57 +0000 (23:00 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 14 Sep 2023 12:25:19 +0000 (13:25 +0100)
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>
src/net/fcoe.c

index 70804dd0347113d64d4e782f4332d77fd9ac45e1..9f3ddf88bd7ccdc2695db08bf94354258ab69f4a 100644 (file)
@@ -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
@@ -162,22 +156,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
  *
@@ -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,