summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/ipoib.c
diff options
context:
space:
mode:
authorMichael Brown2016-03-01 16:26:32 +0100
committerMichael Brown2016-03-07 22:04:40 +0100
commit60e205a551f07882ed18a33fa192ad7cefe548a0 (patch)
tree89dce4b91d85dc435aca2047262e10c18a3e3ef2 /src/drivers/net/ipoib.c
parent[netdevice] Refuse to create duplicate network device names (diff)
downloadipxe-60e205a551f07882ed18a33fa192ad7cefe548a0.tar.gz
ipxe-60e205a551f07882ed18a33fa192ad7cefe548a0.tar.xz
ipxe-60e205a551f07882ed18a33fa192ad7cefe548a0.zip
[infiniband] Remove concept of whole-device owner data
Remove the implicit assumption that the IPoIB protocol owns the whole Infiniband device. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/ipoib.c')
-rw-r--r--src/drivers/net/ipoib.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/src/drivers/net/ipoib.c b/src/drivers/net/ipoib.c
index 6552d764..e54f8df4 100644
--- a/src/drivers/net/ipoib.c
+++ b/src/drivers/net/ipoib.c
@@ -79,6 +79,8 @@ struct ipoib_device {
struct net_device *netdev;
/** Underlying Infiniband device */
struct ib_device *ibdev;
+ /** List of IPoIB devices */
+ struct list_head list;
/** Completion queue */
struct ib_completion_queue *cq;
/** Queue pair */
@@ -116,6 +118,9 @@ struct errortab ipoib_errors[] __errortab = {
__einfo_errortab ( EINFO_EINPROGRESS_JOINING ),
};
+/** List of all IPoIB devices */
+static LIST_HEAD ( ipoib_devices );
+
static struct net_device_operations ipoib_operations;
/****************************************************************************
@@ -783,11 +788,11 @@ static void ipoib_leave_broadcast_group ( struct ipoib_device *ipoib ) {
/**
* Handle link status change
*
- * @v ibdev Infiniband device
+ * @v ipoib IPoIB 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;
+static void ipoib_link_state_changed ( struct ipoib_device *ipoib ) {
+ struct ib_device *ibdev = ipoib->ibdev;
+ struct net_device *netdev = ipoib->netdev;
int rc;
/* Leave existing broadcast group */
@@ -862,7 +867,7 @@ static int ipoib_open ( struct net_device *netdev ) {
ib_refill_recv ( ibdev, ipoib->qp );
/* Fake a link status change to join the broadcast group */
- ipoib_link_state_changed ( ibdev );
+ ipoib_link_state_changed ( ipoib );
return 0;
@@ -928,7 +933,6 @@ static int ipoib_probe ( struct ib_device *ibdev ) {
return -ENOMEM;
netdev_init ( netdev, &ipoib_operations );
ipoib = netdev->priv;
- ib_set_ownerdata ( ibdev, netdev );
netdev->dev = ibdev->dev;
memset ( ipoib, 0, sizeof ( *ipoib ) );
ipoib->netdev = netdev;
@@ -947,35 +951,65 @@ static int ipoib_probe ( struct ib_device *ibdev ) {
memcpy ( &ipoib->broadcast, &ipoib_broadcast,
sizeof ( ipoib->broadcast ) );
+ /* Add to list of IPoIB devices */
+ list_add_tail ( &ipoib->list, &ipoib_devices );
+
/* Register network device */
if ( ( rc = register_netdev ( netdev ) ) != 0 )
goto err_register_netdev;
return 0;
+ unregister_netdev ( netdev );
err_register_netdev:
+ list_del ( &ipoib->list );
netdev_nullify ( netdev );
netdev_put ( netdev );
return rc;
}
/**
+ * Handle device or link status change
+ *
+ * @v ibdev Infiniband device
+ */
+static void ipoib_notify ( struct ib_device *ibdev ) {
+ struct ipoib_device *ipoib;
+
+ /* Handle link status change for any attached IPoIB devices */
+ list_for_each_entry ( ipoib, &ipoib_devices, list ) {
+ if ( ipoib->ibdev != ibdev )
+ continue;
+ ipoib_link_state_changed ( ipoib );
+ }
+}
+
+/**
* Remove IPoIB device
*
* @v ibdev Infiniband device
*/
static void ipoib_remove ( struct ib_device *ibdev ) {
- struct net_device *netdev = ib_get_ownerdata ( ibdev );
+ struct ipoib_device *ipoib;
+ struct ipoib_device *tmp;
+ struct net_device *netdev;
- unregister_netdev ( netdev );
- netdev_nullify ( netdev );
- netdev_put ( netdev );
+ /* Remove any attached IPoIB devices */
+ list_for_each_entry_safe ( ipoib, tmp, &ipoib_devices, list ) {
+ if ( ipoib->ibdev != ibdev )
+ continue;
+ netdev = ipoib->netdev;
+ unregister_netdev ( netdev );
+ list_del ( &ipoib->list );
+ 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,
+ .notify = ipoib_notify,
.remove = ipoib_remove,
};