[Infiniband] Add preliminary support for multi-port devices.
authorMichael Brown <mcb30@etherboot.org>
Wed, 27 Feb 2008 13:59:56 +0000 (13:59 +0000)
committerMichael Brown <mcb30@etherboot.org>
Wed, 27 Feb 2008 13:59:56 +0000 (13:59 +0000)
Arbel and Hermon cards both have multiple ports.  Add the
infrastructure required to register each port as a separate IB
device.  Don't yet register more than one port, since registration
will currently fail unless a valid link is detected.

Use ib_*_{set,get}_{drv,owner}data wrappers to access driver- and
owner-private data on Infiniband structures.

src/drivers/infiniband/arbel.c
src/drivers/infiniband/arbel.h
src/drivers/infiniband/hermon.c
src/drivers/infiniband/hermon.h
src/drivers/net/ipoib.c
src/include/gpxe/infiniband.h
src/net/infiniband.c

index 8e2187f..147cf8b 100644 (file)
@@ -43,9 +43,6 @@
  *
  */
 
-/* Port to use */
-#define PXE_IB_PORT 1
-
 /***************************************************************************
  *
  * Queue number allocation
@@ -482,7 +479,7 @@ arbel_cmd_map_fa ( struct arbel *arbel,
  */
 static int arbel_create_cq ( struct ib_device *ibdev,
                             struct ib_completion_queue *cq ) {
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
        struct arbel_completion_queue *arbel_cq;
        struct arbelprm_completion_queue_context cqctx;
        struct arbelprm_cq_ci_db_record *ci_db_rec;
@@ -560,7 +557,7 @@ static int arbel_create_cq ( struct ib_device *ibdev,
        DBGC ( arbel, "Arbel %p CQN %#lx ring at [%p,%p)\n",
               arbel, cq->cqn, arbel_cq->cqe,
               ( ( ( void * ) arbel_cq->cqe ) + arbel_cq->cqe_size ) );
-       cq->dev_priv = arbel_cq;
+       ib_cq_set_drvdata ( cq, arbel_cq );
        return 0;
 
  err_sw2hw_cq:
@@ -583,8 +580,8 @@ static int arbel_create_cq ( struct ib_device *ibdev,
  */
 static void arbel_destroy_cq ( struct ib_device *ibdev,
                               struct ib_completion_queue *cq ) {
-       struct arbel *arbel = ibdev->dev_priv;
-       struct arbel_completion_queue *arbel_cq = cq->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
+       struct arbel_completion_queue *arbel_cq = ib_cq_get_drvdata ( cq );
        struct arbelprm_completion_queue_context cqctx;
        struct arbelprm_cq_ci_db_record *ci_db_rec;
        struct arbelprm_cq_arm_db_record *arm_db_rec;
@@ -613,7 +610,7 @@ static void arbel_destroy_cq ( struct ib_device *ibdev,
        cqn_offset = ( cq->cqn - arbel->limits.reserved_cqs );
        arbel_free_qn_offset ( arbel->cq_inuse, cqn_offset );
 
-       cq->dev_priv = NULL;
+       ib_cq_set_drvdata ( cq, NULL );
 }
 
 /***************************************************************************
@@ -712,7 +709,7 @@ static int arbel_create_recv_wq ( struct arbel_recv_work_queue *arbel_recv_wq,
  */
 static int arbel_create_qp ( struct ib_device *ibdev,
                             struct ib_queue_pair *qp ) {
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
        struct arbel_queue_pair *arbel_qp;
        struct arbelprm_qp_ee_state_transitions qpctx;
        struct arbelprm_qp_db_record *send_db_rec;
@@ -819,7 +816,7 @@ static int arbel_create_qp ( struct ib_device *ibdev,
        DBGC ( arbel, "Arbel %p QPN %#lx receive ring at [%p,%p)\n",
               arbel, qp->qpn, arbel_qp->recv.wqe,
               ( ( (void *) arbel_qp->recv.wqe ) + arbel_qp->recv.wqe_size ) );
-       qp->dev_priv = arbel_qp;
+       ib_qp_set_drvdata ( qp, arbel_qp );
        return 0;
 
  err_rtr2rts_qpee:
@@ -847,8 +844,8 @@ static int arbel_create_qp ( struct ib_device *ibdev,
  */
 static void arbel_destroy_qp ( struct ib_device *ibdev,
                               struct ib_queue_pair *qp ) {
-       struct arbel *arbel = ibdev->dev_priv;
-       struct arbel_queue_pair *arbel_qp = qp->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
+       struct arbel_queue_pair *arbel_qp = ib_qp_get_drvdata ( qp );
        struct arbelprm_qp_db_record *send_db_rec;
        struct arbelprm_qp_db_record *recv_db_rec;
        int qpn_offset;
@@ -877,7 +874,7 @@ static void arbel_destroy_qp ( struct ib_device *ibdev,
        qpn_offset = ( qp->qpn - ARBEL_QPN_BASE - arbel->limits.reserved_qps );
        arbel_free_qn_offset ( arbel->qp_inuse, qpn_offset );
 
-       qp->dev_priv = NULL;
+       ib_qp_set_drvdata ( qp, NULL );
 }
 
 /***************************************************************************
@@ -926,8 +923,8 @@ static int arbel_post_send ( struct ib_device *ibdev,
                             struct ib_queue_pair *qp,
                             struct ib_address_vector *av,
                             struct io_buffer *iobuf ) {
-       struct arbel *arbel = ibdev->dev_priv;
-       struct arbel_queue_pair *arbel_qp = qp->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
+       struct arbel_queue_pair *arbel_qp = ib_qp_get_drvdata ( qp );
        struct ib_work_queue *wq = &qp->send;
        struct arbel_send_work_queue *arbel_send_wq = &arbel_qp->send;
        struct arbelprm_ud_send_wqe *prev_wqe;
@@ -1016,8 +1013,8 @@ static int arbel_post_send ( struct ib_device *ibdev,
 static int arbel_post_recv ( struct ib_device *ibdev,
                             struct ib_queue_pair *qp,
                             struct io_buffer *iobuf ) {
-       struct arbel *arbel = ibdev->dev_priv;
-       struct arbel_queue_pair *arbel_qp = qp->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
+       struct arbel_queue_pair *arbel_qp = ib_qp_get_drvdata ( qp );
        struct ib_work_queue *wq = &qp->recv;
        struct arbel_recv_work_queue *arbel_recv_wq = &arbel_qp->recv;
        struct arbelprm_recv_wqe *wqe;
@@ -1066,7 +1063,7 @@ static int arbel_complete ( struct ib_device *ibdev,
                            union arbelprm_completion_entry *cqe,
                            ib_completer_t complete_send,
                            ib_completer_t complete_recv ) {
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
        struct ib_completion completion;
        struct ib_work_queue *wq;
        struct ib_queue_pair *qp;
@@ -1108,7 +1105,7 @@ static int arbel_complete ( struct ib_device *ibdev,
                return -EIO;
        }
        qp = wq->qp;
-       arbel_qp = qp->dev_priv;
+       arbel_qp = ib_qp_get_drvdata ( qp );
        arbel_send_wq = &arbel_qp->send;
        arbel_recv_wq = &arbel_qp->recv;
 
@@ -1170,8 +1167,8 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
                            struct ib_completion_queue *cq,
                            ib_completer_t complete_send,
                            ib_completer_t complete_recv ) {
-       struct arbel *arbel = ibdev->dev_priv;
-       struct arbel_completion_queue *arbel_cq = cq->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
+       struct arbel_completion_queue *arbel_cq = ib_cq_get_drvdata ( cq );
        struct arbelprm_cq_ci_db_record *ci_db_rec;
        union arbelprm_completion_entry *cqe;
        unsigned int cqe_idx_mask;
@@ -1220,7 +1217,7 @@ static void arbel_poll_cq ( struct ib_device *ibdev,
  * @ret rc             Return status code
  */
 static int arbel_open ( struct ib_device *ibdev ) {
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
        struct arbelprm_init_ib init_ib;
        int rc;
 
@@ -1247,7 +1244,7 @@ static int arbel_open ( struct ib_device *ibdev ) {
  * @v ibdev            Infiniband device
  */
 static void arbel_close ( struct ib_device *ibdev ) {
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
        int rc;
 
        if ( ( rc = arbel_cmd_close_ib ( arbel, ibdev->port ) ) != 0 ) {
@@ -1275,7 +1272,7 @@ static void arbel_close ( struct ib_device *ibdev ) {
 static int arbel_mcast_attach ( struct ib_device *ibdev,
                                struct ib_queue_pair *qp,
                                struct ib_gid *gid ) {
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
        struct arbelprm_mgm_hash hash;
        struct arbelprm_mgm_entry mgm;
        unsigned int index;
@@ -1330,7 +1327,7 @@ static int arbel_mcast_attach ( struct ib_device *ibdev,
 static void arbel_mcast_detach ( struct ib_device *ibdev,
                                 struct ib_queue_pair *qp __unused,
                                 struct ib_gid *gid ) {
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
        struct arbelprm_mgm_hash hash;
        struct arbelprm_mgm_entry mgm;
        unsigned int index;
@@ -1370,7 +1367,7 @@ static void arbel_mcast_detach ( struct ib_device *ibdev,
  */
 static int arbel_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
                       size_t len ) {
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = ib_get_drvdata ( ibdev );
        union arbelprm_mad mad_ifc;
        int rc;
 
@@ -1837,23 +1834,33 @@ static int arbel_setup_mpt ( struct arbel *arbel ) {
  */
 static int arbel_probe ( struct pci_device *pci,
                         const struct pci_device_id *id __unused ) {
-       struct ib_device *ibdev;
        struct arbel *arbel;
+       struct ib_device *ibdev;
        struct arbelprm_init_hca init_hca;
+       int i;
        int rc;
 
-       /* Allocate Infiniband device */
-       ibdev = alloc_ibdev ( sizeof ( *arbel ) );
-       if ( ! ibdev ) {
+       /* Allocate Arbel device */
+       arbel = zalloc ( sizeof ( *arbel ) );
+       if ( ! arbel ) {
                rc = -ENOMEM;
-               goto err_ibdev;
+               goto err_alloc_arbel;
+       }
+       pci_set_drvdata ( pci, arbel );
+
+       /* Allocate Infiniband devices */
+       for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) {
+               ibdev = alloc_ibdev ( 0 );
+               if ( ! ibdev ) {
+                       rc = -ENOMEM;
+                       goto err_alloc_ibdev;
+               }
+               arbel->ibdev[i] = ibdev;
+               ibdev->op = &arbel_ib_operations;
+               ibdev->dev = &pci->dev;
+               ibdev->port = ( ARBEL_PORT_BASE + i );
+               ib_set_drvdata ( ibdev, arbel );
        }
-       ibdev->op = &arbel_ib_operations;
-       pci_set_drvdata ( pci, ibdev );
-       ibdev->dev = &pci->dev;
-       ibdev->port = PXE_IB_PORT;
-       arbel = ibdev->dev_priv;
-       memset ( arbel, 0, sizeof ( *arbel ) );
 
        /* Fix up PCI device */
        adjust_pci_device ( pci );
@@ -1902,16 +1909,21 @@ static int arbel_probe ( struct pci_device *pci,
        if ( ( rc = arbel_setup_mpt ( arbel ) ) != 0 )
                goto err_setup_mpt;
 
-       /* Register Infiniband device */
-       if ( ( rc = register_ibdev ( ibdev ) ) != 0 ) {
-               DBGC ( arbel, "Arbel %p could not register IB device: %s\n",
-                      arbel, strerror ( rc ) );
-               goto err_register_ibdev;
+       /* Register Infiniband devices */
+       for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) {
+               if ( ( rc = register_ibdev ( arbel->ibdev[i] ) ) != 0 ) {
+                       DBGC ( arbel, "Arbel %p could not register IB "
+                              "device: %s\n", arbel, strerror ( rc ) );
+                       goto err_register_ibdev;
+               }
        }
 
        return 0;
 
+       i = ( ARBEL_NUM_PORTS - 1 );
  err_register_ibdev:
+       for ( ; i >= 0 ; i-- )
+               unregister_ibdev ( arbel->ibdev[i] );
  err_setup_mpt:
        arbel_cmd_close_hca ( arbel );
  err_init_hca:
@@ -1924,8 +1936,12 @@ static int arbel_probe ( struct pci_device *pci,
  err_mailbox_out:
        free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
  err_mailbox_in:
-       free_ibdev ( ibdev );
- err_ibdev:
+       i = ( ARBEL_NUM_PORTS - 1 );
+ err_alloc_ibdev:
+       for ( ; i >= 0 ; i-- )
+               free_ibdev ( arbel->ibdev[i] );
+       free ( arbel );
+ err_alloc_arbel:
        return rc;
 }
 
@@ -1935,17 +1951,20 @@ static int arbel_probe ( struct pci_device *pci,
  * @v pci              PCI device
  */
 static void arbel_remove ( struct pci_device *pci ) {
-       struct ib_device *ibdev = pci_get_drvdata ( pci );
-       struct arbel *arbel = ibdev->dev_priv;
+       struct arbel *arbel = pci_get_drvdata ( pci );
+       int i;
 
-       unregister_ibdev ( ibdev );
+       for ( i = ( ARBEL_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
+               unregister_ibdev ( arbel->ibdev[i] );
        arbel_cmd_close_hca ( arbel );
        arbel_free_icm ( arbel );
        arbel_stop_firmware ( arbel );
        arbel_stop_firmware ( arbel );
        free_dma ( arbel->mailbox_out, ARBEL_MBOX_SIZE );
        free_dma ( arbel->mailbox_in, ARBEL_MBOX_SIZE );
-       free_ibdev ( ibdev );
+       for ( i = ( ARBEL_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
+               free_ibdev ( arbel->ibdev[i] );
+       free ( arbel );
 }
 
 static struct pci_device_id arbel_nics[] = {
index 4d7e4fc..94fa67c 100644 (file)
  *
  */
 
+/* Ports in existence */
+#define ARBEL_NUM_PORTS                        1
+#define ARBEL_PORT_BASE                        1
+
 /* PCI BARs */
 #define ARBEL_PCI_CONFIG_BAR           PCI_BASE_ADDRESS_0
 #define ARBEL_PCI_CONFIG_BAR_SIZE      0x100000
@@ -344,6 +348,9 @@ struct arbel {
        
        /** Device limits */
        struct arbel_dev_limits limits;
+
+       /** Infiniband devices */
+       struct ib_device *ibdev[ARBEL_NUM_PORTS];
 };
 
 /** Global protection domain */
index ce1d0cf..fecf398 100644 (file)
@@ -41,9 +41,6 @@
  *
  */
 
-/* Port to use */
-#define PXE_IB_PORT 1
-
 /***************************************************************************
  *
  * Queue number allocation
@@ -599,7 +596,7 @@ static void hermon_free_mtt ( struct hermon *hermon,
  */
 static int hermon_create_cq ( struct ib_device *ibdev,
                              struct ib_completion_queue *cq ) {
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
        struct hermon_completion_queue *hermon_cq;
        struct hermonprm_completion_queue_context cqctx;
        int cqn_offset;
@@ -665,7 +662,7 @@ static int hermon_create_cq ( struct ib_device *ibdev,
        DBGC ( hermon, "Hermon %p CQN %#lx ring at [%p,%p)\n",
               hermon, cq->cqn, hermon_cq->cqe,
               ( ( ( void * ) hermon_cq->cqe ) + hermon_cq->cqe_size ) );
-       cq->dev_priv = hermon_cq;
+       ib_cq_set_drvdata ( cq, hermon_cq );
        return 0;
 
  err_sw2hw_cq:
@@ -688,8 +685,8 @@ static int hermon_create_cq ( struct ib_device *ibdev,
  */
 static void hermon_destroy_cq ( struct ib_device *ibdev,
                                struct ib_completion_queue *cq ) {
-       struct hermon *hermon = ibdev->dev_priv;
-       struct hermon_completion_queue *hermon_cq = cq->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
+       struct hermon_completion_queue *hermon_cq = ib_cq_get_drvdata ( cq );
        struct hermonprm_completion_queue_context cqctx;
        int cqn_offset;
        int rc;
@@ -713,7 +710,7 @@ static void hermon_destroy_cq ( struct ib_device *ibdev,
        cqn_offset = ( cq->cqn - hermon->cap.reserved_cqs );
        hermon_bitmask_free ( hermon->cq_inuse, cqn_offset, 1 );
 
-       cq->dev_priv = NULL;
+       ib_cq_set_drvdata ( cq, NULL );
 }
 
 /***************************************************************************
@@ -732,7 +729,7 @@ static void hermon_destroy_cq ( struct ib_device *ibdev,
  */
 static int hermon_create_qp ( struct ib_device *ibdev,
                              struct ib_queue_pair *qp ) {
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
        struct hermon_queue_pair *hermon_qp;
        struct hermonprm_qp_ee_state_transitions qpctx;
        int qpn_offset;
@@ -845,7 +842,7 @@ static int hermon_create_qp ( struct ib_device *ibdev,
        DBGC ( hermon, "Hermon %p QPN %#lx receive ring at [%p,%p)\n",
               hermon, qp->qpn, hermon_qp->recv.wqe,
               ( ((void *)hermon_qp->recv.wqe ) + hermon_qp->recv.wqe_size ) );
-       qp->dev_priv = hermon_qp;
+       ib_qp_set_drvdata ( qp, hermon_qp );
        return 0;
 
  err_rtr2rts_qp:
@@ -871,8 +868,8 @@ static int hermon_create_qp ( struct ib_device *ibdev,
  */
 static void hermon_destroy_qp ( struct ib_device *ibdev,
                                struct ib_queue_pair *qp ) {
-       struct hermon *hermon = ibdev->dev_priv;
-       struct hermon_queue_pair *hermon_qp = qp->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
+       struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
        int qpn_offset;
        int rc;
 
@@ -896,7 +893,7 @@ static void hermon_destroy_qp ( struct ib_device *ibdev,
                       hermon->cap.reserved_qps );
        hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 );
 
-       qp->dev_priv = NULL;
+       ib_qp_set_drvdata ( qp, NULL );
 }
 
 /***************************************************************************
@@ -924,8 +921,8 @@ static int hermon_post_send ( struct ib_device *ibdev,
                              struct ib_queue_pair *qp,
                              struct ib_address_vector *av,
                              struct io_buffer *iobuf ) {
-       struct hermon *hermon = ibdev->dev_priv;
-       struct hermon_queue_pair *hermon_qp = qp->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
+       struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
        struct ib_work_queue *wq = &qp->send;
        struct hermon_send_work_queue *hermon_send_wq = &hermon_qp->send;
        struct hermonprm_ud_send_wqe *wqe;
@@ -1000,8 +997,8 @@ static int hermon_post_send ( struct ib_device *ibdev,
 static int hermon_post_recv ( struct ib_device *ibdev,
                              struct ib_queue_pair *qp,
                              struct io_buffer *iobuf ) {
-       struct hermon *hermon = ibdev->dev_priv;
-       struct hermon_queue_pair *hermon_qp = qp->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
+       struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp );
        struct ib_work_queue *wq = &qp->recv;
        struct hermon_recv_work_queue *hermon_recv_wq = &hermon_qp->recv;
        struct hermonprm_recv_wqe *wqe;
@@ -1048,7 +1045,7 @@ static int hermon_complete ( struct ib_device *ibdev,
                             union hermonprm_completion_entry *cqe,
                             ib_completer_t complete_send,
                             ib_completer_t complete_recv ) {
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
        struct ib_completion completion;
        struct ib_work_queue *wq;
        struct ib_queue_pair *qp;
@@ -1085,7 +1082,7 @@ static int hermon_complete ( struct ib_device *ibdev,
                return -EIO;
        }
        qp = wq->qp;
-       hermon_qp = qp->dev_priv;
+       hermon_qp = ib_qp_get_drvdata ( qp );
 
        /* Identify I/O buffer */
        wqe_idx = ( MLX_GET ( &cqe->normal, wqe_counter ) &
@@ -1128,8 +1125,8 @@ static void hermon_poll_cq ( struct ib_device *ibdev,
                             struct ib_completion_queue *cq,
                             ib_completer_t complete_send,
                             ib_completer_t complete_recv ) {
-       struct hermon *hermon = ibdev->dev_priv;
-       struct hermon_completion_queue *hermon_cq = cq->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
+       struct hermon_completion_queue *hermon_cq = ib_cq_get_drvdata ( cq );
        union hermonprm_completion_entry *cqe;
        unsigned int cqe_idx_mask;
        int rc;
@@ -1177,7 +1174,7 @@ static void hermon_poll_cq ( struct ib_device *ibdev,
  * @ret rc             Return status code
  */
 static int hermon_open ( struct ib_device *ibdev ) {
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
        struct hermonprm_init_port init_port;
        int rc;
 
@@ -1205,7 +1202,7 @@ static int hermon_open ( struct ib_device *ibdev ) {
  * @v ibdev            Infiniband device
  */
 static void hermon_close ( struct ib_device *ibdev ) {
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
        int rc;
 
        if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) {
@@ -1233,7 +1230,7 @@ static void hermon_close ( struct ib_device *ibdev ) {
 static int hermon_mcast_attach ( struct ib_device *ibdev,
                                 struct ib_queue_pair *qp,
                                 struct ib_gid *gid ) {
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
        struct hermonprm_mgm_hash hash;
        struct hermonprm_mcg_entry mcg;
        unsigned int index;
@@ -1287,7 +1284,7 @@ static int hermon_mcast_attach ( struct ib_device *ibdev,
 static void hermon_mcast_detach ( struct ib_device *ibdev,
                                  struct ib_queue_pair *qp __unused,
                                  struct ib_gid *gid ) {
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
        struct hermonprm_mgm_hash hash;
        struct hermonprm_mcg_entry mcg;
        unsigned int index;
@@ -1327,7 +1324,7 @@ static void hermon_mcast_detach ( struct ib_device *ibdev,
  */
 static int hermon_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad,
                        size_t len ) {
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = ib_get_drvdata ( ibdev );
        union hermonprm_mad mad_ifc;
        int rc;
 
@@ -1870,23 +1867,33 @@ static int hermon_setup_mpt ( struct hermon *hermon ) {
  */
 static int hermon_probe ( struct pci_device *pci,
                          const struct pci_device_id *id __unused ) {
-       struct ib_device *ibdev;
        struct hermon *hermon;
+       struct ib_device *ibdev;
        struct hermonprm_init_hca init_hca;
+       int i;
        int rc;
 
-       /* Allocate Infiniband device */
-       ibdev = alloc_ibdev ( sizeof ( *hermon ) );
-       if ( ! ibdev ) {
+       /* Allocate Hermon device */
+       hermon = zalloc ( sizeof ( *hermon ) );
+       if ( ! hermon ) {
                rc = -ENOMEM;
-               goto err_ibdev;
+               goto err_alloc_hermon;
+       }
+       pci_set_drvdata ( pci, hermon );
+
+       /* Allocate Infiniband devices */
+       for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ ) {
+               ibdev = alloc_ibdev ( 0 );
+               if ( ! ibdev ) {
+                       rc = -ENOMEM;
+                       goto err_alloc_ibdev;
+               }
+               hermon->ibdev[i] = ibdev;
+               ibdev->op = &hermon_ib_operations;
+               ibdev->dev = &pci->dev;
+               ibdev->port = ( HERMON_PORT_BASE + i );
+               ib_set_drvdata ( ibdev, hermon );
        }
-       ibdev->op = &hermon_ib_operations;
-       pci_set_drvdata ( pci, ibdev );
-       ibdev->dev = &pci->dev;
-       ibdev->port = PXE_IB_PORT;
-       hermon = ibdev->dev_priv;
-       memset ( hermon, 0, sizeof ( *hermon ) );
 
        /* Fix up PCI device */
        adjust_pci_device ( pci );
@@ -1939,16 +1946,21 @@ static int hermon_probe ( struct pci_device *pci,
        if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 )
                goto err_setup_mpt;
 
-       /* Register Infiniband device */
-       if ( ( rc = register_ibdev ( ibdev ) ) != 0 ) {
-               DBGC ( hermon, "Hermon %p could not register IB device: %s\n",
-                      hermon, strerror ( rc ) );
-               goto err_register_ibdev;
+       /* Register Infiniband devices */
+       for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ ) {
+               if ( ( rc = register_ibdev ( hermon->ibdev[i] ) ) != 0 ) {
+                       DBGC ( hermon, "Hermon %p could not register IB "
+                              "device: %s\n", hermon, strerror ( rc ) );
+                       goto err_register_ibdev;
+               }
        }
 
        return 0;
 
+       i = ( HERMON_NUM_PORTS - 1 );
  err_register_ibdev:
+       for ( ; i >= 0 ; i-- )
+               unregister_ibdev ( hermon->ibdev[i] );
  err_setup_mpt:
        hermon_cmd_close_hca ( hermon );
  err_init_hca:
@@ -1961,8 +1973,12 @@ static int hermon_probe ( struct pci_device *pci,
  err_mailbox_out:
        free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
  err_mailbox_in:
-       free_ibdev ( ibdev );
- err_ibdev:
+       i = ( HERMON_NUM_PORTS - 1 );
+ err_alloc_ibdev:
+       for ( ; i >= 0 ; i-- )
+               free_ibdev ( hermon->ibdev[i] );
+       free ( hermon );
+ err_alloc_hermon:
        return rc;
 }
 
@@ -1972,17 +1988,20 @@ static int hermon_probe ( struct pci_device *pci,
  * @v pci              PCI device
  */
 static void hermon_remove ( struct pci_device *pci ) {
-       struct ib_device *ibdev = pci_get_drvdata ( pci );
-       struct hermon *hermon = ibdev->dev_priv;
+       struct hermon *hermon = pci_get_drvdata ( pci );
+       int i;
 
-       unregister_ibdev ( ibdev );
+       for ( i = ( HERMON_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
+               unregister_ibdev ( hermon->ibdev[i] );
        hermon_cmd_close_hca ( hermon );
        hermon_free_icm ( hermon );
        hermon_stop_firmware ( hermon );
        hermon_stop_firmware ( hermon );
        free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
        free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
-       free_ibdev ( ibdev );
+       for ( i = ( HERMON_NUM_PORTS - 1 ) ; i >= 0 ; i-- )
+               free_ibdev ( hermon->ibdev[i] );
+       free ( hermon );
 }
 
 static struct pci_device_id hermon_nics[] = {
index 1aee443..959e6a9 100644 (file)
  *
  */
 
+/* Ports in existence */
+#define HERMON_NUM_PORTS               1
+#define HERMON_PORT_BASE               1
+
 /* PCI BARs */
 #define HERMON_PCI_CONFIG_BAR          PCI_BASE_ADDRESS_0
 #define HERMON_PCI_CONFIG_BAR_SIZE     0x100000
@@ -402,6 +406,9 @@ struct hermon {
 
        /** Device capabilities */
        struct hermon_dev_cap cap;
+
+       /** Infiniband devices */
+       struct ib_device *ibdev[HERMON_NUM_PORTS];
 };
 
 /** Global protection domain */
index 784c072..905051b 100644 (file)
@@ -294,7 +294,7 @@ static int ipoib_create_qset ( struct ipoib_device *ipoib,
                rc = -ENOMEM;
                goto err;
        }
-       qset->qp->owner_priv = ipoib->netdev;
+       ib_qp_set_ownerdata ( qset->qp, ipoib->netdev );
 
        return 0;
 
@@ -506,7 +506,7 @@ static void ipoib_data_complete_send ( struct ib_device *ibdev __unused,
                                       struct ib_queue_pair *qp,
                                       struct ib_completion *completion,
                                       struct io_buffer *iobuf ) {
-       struct net_device *netdev = qp->owner_priv;
+       struct net_device *netdev = ib_qp_get_ownerdata ( qp );
 
        netdev_tx_complete_err ( netdev, iobuf,
                                 ( completion->syndrome ? -EIO : 0 ) );
@@ -524,7 +524,7 @@ static void ipoib_data_complete_recv ( struct ib_device *ibdev __unused,
                                       struct ib_queue_pair *qp,
                                       struct ib_completion *completion,
                                       struct io_buffer *iobuf ) {
-       struct net_device *netdev = qp->owner_priv;
+       struct net_device *netdev = ib_qp_get_ownerdata ( qp );
        struct ipoib_device *ipoib = netdev->priv;
        struct ipoib_pseudo_hdr *ipoib_pshdr;
 
@@ -572,7 +572,7 @@ static void ipoib_meta_complete_send ( struct ib_device *ibdev __unused,
                                       struct ib_queue_pair *qp,
                                       struct ib_completion *completion,
                                       struct io_buffer *iobuf ) {
-       struct net_device *netdev = qp->owner_priv;
+       struct net_device *netdev = ib_qp_get_ownerdata ( qp );
        struct ipoib_device *ipoib = netdev->priv;
 
        if ( completion->syndrome ) {
@@ -640,7 +640,7 @@ static void ipoib_meta_complete_recv ( struct ib_device *ibdev __unused,
                                       struct ib_queue_pair *qp,
                                       struct ib_completion *completion,
                                       struct io_buffer *iobuf ) {
-       struct net_device *netdev = qp->owner_priv;
+       struct net_device *netdev = ib_qp_get_ownerdata ( qp );
        struct ipoib_device *ipoib = netdev->priv;
        union ib_mad *mad;
 
index ad64b2a..354dc57 100644 (file)
@@ -75,8 +75,8 @@ struct ib_work_queue {
        unsigned long next_idx;
        /** I/O buffers assigned to work queue */
        struct io_buffer **iobufs;
-       /** Device private data */
-       void *dev_priv;
+       /** Driver private data */
+       void *drv_priv;
 };
 
 /** An Infiniband Queue Pair */
@@ -89,8 +89,8 @@ struct ib_queue_pair {
        struct ib_work_queue send;
        /** Receive queue */
        struct ib_work_queue recv;
-       /** Device private data */
-       void *dev_priv;
+       /** Driver private data */
+       void *drv_priv;
        /** Queue owner private data */
        void *owner_priv;
 };
@@ -111,8 +111,8 @@ struct ib_completion_queue {
        unsigned long next_idx;
        /** List of work queues completing to this queue */
        struct list_head work_queues;
-       /** Device private data */
-       void *dev_priv;
+       /** Driver private data */
+       void *drv_priv;
 };
 
 /** An Infiniband completion */
@@ -297,8 +297,8 @@ struct ib_device {
        unsigned long sm_lid;
        /** Partition key */
        unsigned int pkey;
-       /** Device private data */
-       void *dev_priv;
+       /** Driver private data */
+       void *drv_priv;
        /** Owner private data */
        void *owner_priv;
 };
@@ -425,20 +425,130 @@ ib_mad ( struct ib_device *ibdev, struct ib_mad_hdr *mad, size_t len ) {
 }
 
 /**
- * Set Infiniband owner-private data
+ * Set Infiniband work queue driver-private data
  *
- * @v pci              Infiniband device
+ * @v wq               Work queue
  * @v priv             Private data
  */
 static inline __attribute__ (( always_inline )) void
-ib_set_ownerdata ( struct ib_device *ibdev, void *owner_priv ) {
-       ibdev->owner_priv = owner_priv;
+ib_wq_set_drvdata ( struct ib_work_queue *wq, void *priv ) {
+       wq->drv_priv = priv;
 }
 
 /**
- * Get Infiniband owner-private data
+ * Get Infiniband work queue driver-private data
  *
- * @v pci              Infiniband device
+ * @v wq               Work queue
+ * @ret priv           Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_wq_get_drvdata ( struct ib_work_queue *wq ) {
+       return wq->drv_priv;
+}
+
+/**
+ * Set Infiniband queue pair driver-private data
+ *
+ * @v qp               Queue pair
+ * @v priv             Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_qp_set_drvdata ( struct ib_queue_pair *qp, void *priv ) {
+       qp->drv_priv = priv;
+}
+
+/**
+ * Get Infiniband queue pair driver-private data
+ *
+ * @v qp               Queue pair
+ * @ret priv           Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_qp_get_drvdata ( struct ib_queue_pair *qp ) {
+       return qp->drv_priv;
+}
+
+/**
+ * Set Infiniband queue pair owner-private data
+ *
+ * @v qp               Queue pair
+ * @v priv             Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_qp_set_ownerdata ( struct ib_queue_pair *qp, void *priv ) {
+       qp->owner_priv = priv;
+}
+
+/**
+ * Get Infiniband queue pair owner-private data
+ *
+ * @v qp               Queue pair
+ * @ret priv           Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_qp_get_ownerdata ( struct ib_queue_pair *qp ) {
+       return qp->owner_priv;
+}
+
+/**
+ * Set Infiniband completion queue driver-private data
+ *
+ * @v cq               Completion queue
+ * @v priv             Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_cq_set_drvdata ( struct ib_completion_queue *cq, void *priv ) {
+       cq->drv_priv = priv;
+}
+
+/**
+ * Get Infiniband completion queue driver-private data
+ *
+ * @v cq               Completion queue
+ * @ret priv           Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_cq_get_drvdata ( struct ib_completion_queue *cq ) {
+       return cq->drv_priv;
+}
+
+/**
+ * Set Infiniband device driver-private data
+ *
+ * @v ibdev            Infiniband device
+ * @v priv             Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_set_drvdata ( struct ib_device *ibdev, void *priv ) {
+       ibdev->drv_priv = priv;
+}
+
+/**
+ * Get Infiniband device driver-private data
+ *
+ * @v ibdev            Infiniband device
+ * @ret priv           Private data
+ */
+static inline __attribute__ (( always_inline )) void *
+ib_get_drvdata ( struct ib_device *ibdev ) {
+       return ibdev->drv_priv;
+}
+
+/**
+ * Set Infiniband device owner-private data
+ *
+ * @v ibdev            Infiniband device
+ * @v priv             Private data
+ */
+static inline __attribute__ (( always_inline )) void
+ib_set_ownerdata ( struct ib_device *ibdev, void *priv ) {
+       ibdev->owner_priv = priv;
+}
+
+/**
+ * Get Infiniband device owner-private data
+ *
+ * @v ibdev            Infiniband device
  * @ret priv           Private data
  */
 static inline __attribute__ (( always_inline )) void *
index 2edadc9..39d1128 100644 (file)
@@ -67,7 +67,8 @@ struct ib_completion_queue * ib_create_cq ( struct ib_device *ibdev,
        }
 
        DBGC ( ibdev, "IBDEV %p created %d-entry completion queue %p (%p) "
-              "with CQN %#lx\n", ibdev, num_cqes, cq, cq->dev_priv, cq->cqn );
+              "with CQN %#lx\n", ibdev, num_cqes, cq,
+              ib_cq_get_drvdata ( cq ), cq->cqn );
        return cq;
 }
 
@@ -141,7 +142,7 @@ struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
        }
 
        DBGC ( ibdev, "IBDEV %p created queue pair %p (%p) with QPN %#lx\n",
-              ibdev, qp, qp->dev_priv, qp->qpn );
+              ibdev, qp, ib_qp_get_drvdata ( qp ), qp->qpn );
        DBGC ( ibdev, "IBDEV %p QPN %#lx has %d send entries at [%p,%p)\n",
               ibdev, qp->qpn, num_send_wqes, qp->send.iobufs,
               qp->recv.iobufs );
@@ -360,17 +361,19 @@ static int ib_get_mad_params ( struct ib_device *ibdev ) {
 /**
  * Allocate Infiniband device
  *
- * @v priv_size                Size of private data area
+ * @v priv_size                Size of driver private data area
  * @ret ibdev          Infiniband device, or NULL
  */
 struct ib_device * alloc_ibdev ( size_t priv_size ) {
        struct ib_device *ibdev;
+       void *drv_priv;
        size_t total_len;
 
        total_len = ( sizeof ( *ibdev ) + priv_size );
        ibdev = zalloc ( total_len );
        if ( ibdev ) {
-               ibdev->dev_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) );
+               drv_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) );
+               ib_set_drvdata ( ibdev, drv_priv );
        }
        return ibdev;
 }