diff options
author | Michael Brown <mcb30@ipxe.org> | 2010-09-04 23:35:09 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2010-09-05 03:06:16 +0100 |
commit | 35b19d8848c5141aff8ef858f908e9f7a7cf0b1d (patch) | |
tree | d877ea90a56a0bb5c61a0e0c34c2d6cbe7ef6b7d /src/drivers/net/ipoib.c | |
parent | ca4df90a6383d47617038328fb506bf273f1e80e (diff) | |
download | ipxe-35b19d8848c5141aff8ef858f908e9f7a7cf0b1d.tar.gz |
[infiniband] Add the concept of an Infiniband upper-layer driver
Replace the explicit calls from the Infiniband core to the IPoIB layer
with the general concept of an Infiniband upper-layer driver
(analogous to a PCI driver) which can create arbitrary devices on top
of Infiniband devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/ipoib.c')
-rw-r--r-- | src/drivers/net/ipoib.c | 84 |
1 files changed, 46 insertions, 38 deletions
diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c index baa1c644..82d7ca99 100644 --- a/src/drivers/net/ipoib.c +++ b/src/drivers/net/ipoib.c @@ -598,6 +598,42 @@ static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) { } /** + * Handle link status change + * + * @v ibdev Infiniband device + */ +static void ipoib_link_state_changed ( struct ib_device *ibdev ) { + struct net_device *netdev = ib_get_ownerdata ( ibdev ); + struct ipoib_device *ipoib = netdev->priv; + struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); + int rc; + + /* Leave existing broadcast group */ + ipoib_leave_broadcast_group ( ipoib ); + + /* Update MAC address based on potentially-new GID prefix */ + memcpy ( &mac->gid.u.half[0], &ibdev->gid.u.half[0], + sizeof ( mac->gid.u.half[0] ) ); + + /* Update broadcast GID based on potentially-new partition key */ + ipoib->broadcast.gid.u.words[2] = + htons ( ibdev->pkey | IB_PKEY_FULL ); + + /* Set net device link state to reflect Infiniband link state */ + rc = ib_link_rc ( ibdev ); + netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) ); + + /* Join new broadcast group */ + if ( ib_is_open ( ibdev ) && ib_link_ok ( ibdev ) && + ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) { + DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: " + "%s\n", ipoib, strerror ( rc ) ); + netdev_link_err ( netdev, rc ); + return; + } +} + +/** * Open IPoIB network device * * @v netdev Network device @@ -691,48 +727,12 @@ static struct net_device_operations ipoib_operations = { }; /** - * Handle link status change - * - * @v ibdev Infiniband device - */ -void ipoib_link_state_changed ( struct ib_device *ibdev ) { - struct net_device *netdev = ib_get_ownerdata ( ibdev ); - struct ipoib_device *ipoib = netdev->priv; - struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr ); - int rc; - - /* Leave existing broadcast group */ - ipoib_leave_broadcast_group ( ipoib ); - - /* Update MAC address based on potentially-new GID prefix */ - memcpy ( &mac->gid.u.half[0], &ibdev->gid.u.half[0], - sizeof ( mac->gid.u.half[0] ) ); - - /* Update broadcast GID based on potentially-new partition key */ - ipoib->broadcast.gid.u.words[2] = - htons ( ibdev->pkey | IB_PKEY_FULL ); - - /* Set net device link state to reflect Infiniband link state */ - rc = ib_link_rc ( ibdev ); - netdev_link_err ( netdev, ( rc ? rc : -EINPROGRESS_JOINING ) ); - - /* Join new broadcast group */ - if ( ib_link_ok ( ibdev ) && - ( ( rc = ipoib_join_broadcast_group ( ipoib ) ) != 0 ) ) { - DBGC ( ipoib, "IPoIB %p could not rejoin broadcast group: " - "%s\n", ipoib, strerror ( rc ) ); - netdev_link_err ( netdev, rc ); - return; - } -} - -/** * Probe IPoIB device * * @v ibdev Infiniband device * @ret rc Return status code */ -int ipoib_probe ( struct ib_device *ibdev ) { +static int ipoib_probe ( struct ib_device *ibdev ) { struct net_device *netdev; struct ipoib_device *ipoib; int rc; @@ -775,10 +775,18 @@ int ipoib_probe ( struct ib_device *ibdev ) { * * @v ibdev Infiniband device */ -void ipoib_remove ( struct ib_device *ibdev ) { +static void ipoib_remove ( struct ib_device *ibdev ) { struct net_device *netdev = ib_get_ownerdata ( ibdev ); unregister_netdev ( netdev ); netdev_nullify ( netdev ); netdev_put ( netdev ); } + +/** IPoIB driver */ +struct ib_driver ipoib_driver __ib_driver = { + .name = "IPoIB", + .probe = ipoib_probe, + .notify = ipoib_link_state_changed, + .remove = ipoib_remove, +}; |