aboutsummaryrefslogtreecommitdiffstats
path: root/src/drivers/infiniband/arbel.h
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2010-07-16 13:48:20 +0100
committerMichael Brown <mcb30@ipxe.org>2010-09-17 05:41:57 +0100
commit40d7c70438aaa7ffd6b3dd0027230b9371683b9b (patch)
treebe3b900f7c9864efbc82f96045bc1052b0d50e1d /src/drivers/infiniband/arbel.h
parent46f2580049d85264dee3a1f36dd1eaa05d5d1973 (diff)
downloadipxe-40d7c70438aaa7ffd6b3dd0027230b9371683b9b.tar.gz
[arbel] Allow software GMA to receive packets destined for QP1
This is a backport of commit cd5a213 ("[hermon] Allow software GMA to receive packets destined for QP1") to the Arbel driver. This patch includes a correction to a bug in the autogenerated hardware description header file. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/infiniband/arbel.h')
-rw-r--r--src/drivers/infiniband/arbel.h64
1 files changed, 50 insertions, 14 deletions
diff --git a/src/drivers/infiniband/arbel.h b/src/drivers/infiniband/arbel.h
index b4ad3db6a..501b01355 100644
--- a/src/drivers/infiniband/arbel.h
+++ b/src/drivers/infiniband/arbel.h
@@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <stdint.h>
#include <ipxe/uaccess.h>
+#include <ipxe/ib_packet.h>
#include "mlx_bitops.h"
#include "MT25218_PRM.h"
@@ -61,6 +62,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ARBEL_HCR_RTR2RTS_QPEE 0x001b
#define ARBEL_HCR_RTS2RTS_QPEE 0x001c
#define ARBEL_HCR_2RST_QPEE 0x0021
+#define ARBEL_HCR_CONF_SPECIAL_QP 0x0023
#define ARBEL_HCR_MAD_IFC 0x0024
#define ARBEL_HCR_READ_MGM 0x0025
#define ARBEL_HCR_WRITE_MGM 0x0026
@@ -78,6 +80,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
/* Service types */
#define ARBEL_ST_UD 0x03
+#define ARBEL_ST_MLX 0x07
/* MTUs */
#define ARBEL_MTU_2048 0x04
@@ -183,6 +186,7 @@ struct MLX_DECLARE_STRUCT ( arbelprm_scalar_parameter );
struct MLX_DECLARE_STRUCT ( arbelprm_send_doorbell );
struct MLX_DECLARE_STRUCT ( arbelprm_ud_address_vector );
struct MLX_DECLARE_STRUCT ( arbelprm_virtual_physical_mapping );
+struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ctrl_mlx );
struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ctrl_send );
struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_data_ptr );
struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_next );
@@ -193,7 +197,7 @@ struct MLX_DECLARE_STRUCT ( arbelprm_wqe_segment_ud );
*
*/
-#define ARBEL_MAX_GATHER 1
+#define ARBEL_MAX_GATHER 2
struct arbelprm_ud_send_wqe {
struct arbelprm_wqe_segment_next next;
@@ -202,6 +206,13 @@ struct arbelprm_ud_send_wqe {
struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER];
} __attribute__ (( packed ));
+struct arbelprm_mlx_send_wqe {
+ struct arbelprm_wqe_segment_next next;
+ struct arbelprm_wqe_segment_ctrl_mlx ctrl;
+ struct arbelprm_wqe_segment_data_ptr data[ARBEL_MAX_GATHER];
+ uint8_t headers[IB_MAX_HEADER_SIZE];
+} __attribute__ (( packed ));
+
#define ARBEL_MAX_SCATTER 1
struct arbelprm_recv_wqe {
@@ -298,7 +309,9 @@ struct arbel_dev_limits {
/** An Arbel send work queue entry */
union arbel_send_wqe {
+ struct arbelprm_wqe_segment_next next;
struct arbelprm_ud_send_wqe ud;
+ struct arbelprm_mlx_send_wqe mlx;
uint8_t force_align[ARBEL_SEND_WQE_ALIGN];
} __attribute__ (( packed ));
@@ -331,6 +344,16 @@ struct arbel_recv_work_queue {
size_t wqe_size;
};
+/** Number of special queue pairs */
+#define ARBEL_NUM_SPECIAL_QPS 4
+
+/** Number of queue pairs reserved for the "special QP" block
+ *
+ * The special QPs must be in (2n,2n+1) pairs, hence we need to
+ * reserve one extra QP to allow for alignment.
+ */
+#define ARBEL_RSVD_SPECIAL_QPS ( ARBEL_NUM_SPECIAL_QPS + 1 )
+
/** Maximum number of allocatable queue pairs
*
* This is a policy decision, not a device limit.
@@ -441,6 +464,10 @@ struct arbel {
/** Device limits */
struct arbel_dev_limits limits;
+ /** Special QPN base */
+ unsigned long special_qpn_base;
+ /** QPN base */
+ unsigned long qpn_base;
/** Infiniband devices */
struct ib_device *ibdev[ARBEL_NUM_PORTS];
@@ -512,50 +539,59 @@ struct arbel {
*/
#define ARBEL_MAX_DOORBELL_RECORDS 512
-#define ARBEL_GROUP_SEPARATOR_DOORBELL ( ARBEL_MAX_CQS + ARBEL_MAX_QPS )
+#define ARBEL_GROUP_SEPARATOR_DOORBELL \
+ ( ARBEL_MAX_CQS + ARBEL_RSVD_SPECIAL_QPS + ARBEL_MAX_QPS )
/**
* Get arm completion queue doorbell index
*
- * @v cqn_offset Completion queue number offset
+ * @v arbel Arbel device
+ * @v cq Completion queue
* @ret doorbell_idx Doorbell index
*/
static inline unsigned int
-arbel_cq_arm_doorbell_idx ( unsigned int cqn_offset ) {
- return cqn_offset;
+arbel_cq_arm_doorbell_idx ( struct arbel *arbel,
+ struct ib_completion_queue *cq ) {
+ return ( cq->cqn - arbel->limits.reserved_cqs );
}
/**
* Get send work request doorbell index
*
- * @v qpn_offset Queue pair number offset
+ * @v arbel Arbel device
+ * @v qp Queue pair
* @ret doorbell_idx Doorbell index
*/
static inline unsigned int
-arbel_send_doorbell_idx ( unsigned int qpn_offset ) {
- return ( ARBEL_MAX_CQS + qpn_offset );
+arbel_send_doorbell_idx ( struct arbel *arbel, struct ib_queue_pair *qp ) {
+ return ( ARBEL_MAX_CQS + ( qp->qpn - arbel->special_qpn_base ) );
}
/**
* Get receive work request doorbell index
*
- * @v qpn_offset Queue pair number offset
+ * @v arbel Arbel device
+ * @v qp Queue pair
* @ret doorbell_idx Doorbell index
*/
static inline unsigned int
-arbel_recv_doorbell_idx ( unsigned int qpn_offset ) {
- return ( ARBEL_MAX_DOORBELL_RECORDS - ARBEL_MAX_CQS - qpn_offset - 1 );
+arbel_recv_doorbell_idx ( struct arbel *arbel, struct ib_queue_pair *qp ) {
+ return ( ARBEL_MAX_DOORBELL_RECORDS - ARBEL_MAX_CQS -
+ ( qp->qpn - arbel->special_qpn_base ) - 1 );
}
/**
* Get completion queue consumer counter doorbell index
*
- * @v cqn_offset Completion queue number offset
+ * @v arbel Arbel device
+ * @v cq Completion queue
* @ret doorbell_idx Doorbell index
*/
static inline unsigned int
-arbel_cq_ci_doorbell_idx ( unsigned int cqn_offset ) {
- return ( ARBEL_MAX_DOORBELL_RECORDS - cqn_offset - 1 );
+arbel_cq_ci_doorbell_idx ( struct arbel *arbel,
+ struct ib_completion_queue *cq ) {
+ return ( ARBEL_MAX_DOORBELL_RECORDS -
+ ( cq->cqn - arbel->limits.reserved_cqs ) - 1 );
}
#endif /* _ARBEL_H */