summaryrefslogtreecommitdiffstats
path: root/src/drivers/infiniband
diff options
context:
space:
mode:
authorMichael Brown2010-09-19 19:20:20 +0200
committerMichael Brown2010-09-21 03:15:24 +0200
commitf62c433d66ba9064fc6797e6d9b03ec20f4dadef (patch)
tree46d0bd376afb7eff2d1b7c29bdf28787c365b9f9 /src/drivers/infiniband
parent[infiniband] Add the notion of an Ethernet queue pair type (diff)
downloadipxe-f62c433d66ba9064fc6797e6d9b03ec20f4dadef.tar.gz
ipxe-f62c433d66ba9064fc6797e6d9b03ec20f4dadef.tar.xz
ipxe-f62c433d66ba9064fc6797e6d9b03ec20f4dadef.zip
[hermon] Use SET_PORT to set port parameters
Unlike Arbel, port parameters must be applied via a separate call to SET_PORT, rather than as parameters to INIT_PORT. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/infiniband')
-rw-r--r--src/drivers/infiniband/hermon.c58
-rw-r--r--src/drivers/infiniband/hermon.h54
2 files changed, 89 insertions, 23 deletions
diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c
index 85cafb05..73411aab 100644
--- a/src/drivers/infiniband/hermon.c
+++ b/src/drivers/infiniband/hermon.c
@@ -186,6 +186,7 @@ static int hermon_cmd ( struct hermon *hermon, unsigned long command,
memset ( &hcr, 0, sizeof ( hcr ) );
in_buffer = &hcr.u.dwords[0];
if ( in_len && ( command & HERMON_HCR_IN_MBOX ) ) {
+ memset ( hermon->mailbox_in, 0, HERMON_MBOX_SIZE );
in_buffer = hermon->mailbox_in;
MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) );
}
@@ -289,12 +290,10 @@ hermon_cmd_close_hca ( struct hermon *hermon ) {
}
static inline int
-hermon_cmd_init_port ( struct hermon *hermon, unsigned int port,
- const struct hermonprm_init_port *init_port ) {
+hermon_cmd_init_port ( struct hermon *hermon, unsigned int port ) {
return hermon_cmd ( hermon,
- HERMON_HCR_IN_CMD ( HERMON_HCR_INIT_PORT,
- 1, sizeof ( *init_port ) ),
- 0, init_port, port, NULL );
+ HERMON_HCR_VOID_CMD ( HERMON_HCR_INIT_PORT ),
+ 0, NULL, port, NULL );
}
static inline int
@@ -305,6 +304,15 @@ hermon_cmd_close_port ( struct hermon *hermon, unsigned int port ) {
}
static inline int
+hermon_cmd_set_port ( struct hermon *hermon, unsigned int port,
+ struct hermonprm_set_port *set_port ) {
+ return hermon_cmd ( hermon,
+ HERMON_HCR_IN_CMD ( HERMON_HCR_SET_PORT,
+ 1, sizeof ( *set_port ) ),
+ 0, set_port, port, NULL );
+}
+
+static inline int
hermon_cmd_sw2hw_mpt ( struct hermon *hermon, unsigned int index,
const struct hermonprm_mpt *mpt ) {
return hermon_cmd ( hermon,
@@ -1903,8 +1911,11 @@ static int hermon_sense_port_type ( struct ib_device *ibdev ) {
int rc;
/* If DPDP is not supported, always assume Infiniband */
- if ( ! hermon->cap.dpdp )
+ if ( ! hermon->cap.dpdp ) {
+ DBGC ( hermon, "Hermon %p does not support DPDP; assuming "
+ "Infiniband\n", hermon );
return HERMON_PORT_TYPE_IB;
+ }
/* Sense the port type */
if ( ( rc = hermon_cmd_sense_port ( hermon, ibdev->port,
@@ -1928,7 +1939,7 @@ static int hermon_sense_port_type ( struct ib_device *ibdev ) {
*/
static int hermon_open ( struct ib_device *ibdev ) {
struct hermon *hermon = ib_get_drvdata ( ibdev );
- struct hermonprm_init_port init_port;
+ struct hermonprm_set_port set_port;
int port_type;
int rc;
@@ -1941,18 +1952,29 @@ static int hermon_open ( struct ib_device *ibdev ) {
return -ENOTCONN;
}
- /* Init Port */
- memset ( &init_port, 0, sizeof ( init_port ) );
- MLX_FILL_2 ( &init_port, 0,
- port_width_cap, 3,
- vl_cap, 1 );
- MLX_FILL_2 ( &init_port, 1,
- mtu, HERMON_MTU_2048,
+ /* Set port parameters */
+ memset ( &set_port, 0, sizeof ( set_port ) );
+ MLX_FILL_7 ( &set_port, 0,
+ mmc, 1,
+ mvc, 1,
+ mp, 1,
+ mg, 1,
+ mtu_cap, IB_MTU_2048,
+ vl_cap, IB_VL_0,
+ rcm, 1 );
+ MLX_FILL_2 ( &set_port, 10,
+ max_pkey, 1,
max_gid, 1 );
- MLX_FILL_1 ( &init_port, 2, max_pkey, 64 );
- if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port,
- &init_port ) ) != 0 ) {
- DBGC ( hermon, "Hermon %p port %d could not intialise port: "
+ if ( ( rc = hermon_cmd_set_port ( hermon, ibdev->port,
+ &set_port ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p port %d could not set port: %s\n",
+ hermon, ibdev->port, strerror ( rc ) );
+ return rc;
+ }
+
+ /* Initialise port */
+ if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port ) ) != 0 ) {
+ DBGC ( hermon, "Hermon %p port %d could not initialise port: "
"%s\n", hermon, ibdev->port, strerror ( rc ) );
return rc;
}
diff --git a/src/drivers/infiniband/hermon.h b/src/drivers/infiniband/hermon.h
index f9edd6fa..f936c97e 100644
--- a/src/drivers/infiniband/hermon.h
+++ b/src/drivers/infiniband/hermon.h
@@ -47,6 +47,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define HERMON_HCR_CLOSE_HCA 0x0008
#define HERMON_HCR_INIT_PORT 0x0009
#define HERMON_HCR_CLOSE_PORT 0x000a
+#define HERMON_HCR_SET_PORT 0x000c
#define HERMON_HCR_SW2HW_MPT 0x000d
#define HERMON_HCR_WRITE_MTT 0x0011
#define HERMON_HCR_MAP_EQ 0x0012
@@ -84,6 +85,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define HERMON_ST_UD 0x03
#define HERMON_ST_MLX 0x07
+/* Port types */
+#define HERMON_PORT_TYPE_IB 1
+
/* MTUs */
#define HERMON_MTU_2048 0x04
@@ -190,13 +194,53 @@ struct hermonprm_port_state_change_event_st {
struct hermonprm_port_state_change_st data;
} __attribute__ (( packed ));
-/** Hermon sense port */
struct hermonprm_sense_port_st {
pseudo_bit_t port_type[0x00020];
/* -------------- */
pseudo_bit_t reserved[0x00020];
-};
-#define HERMON_PORT_TYPE_IB 1
+} __attribute__ (( packed ));
+
+struct hermonprm_set_port_st {
+ pseudo_bit_t rqk[0x00001];
+ pseudo_bit_t rcm[0x00001];
+ pseudo_bit_t reserved0[0x00002];
+ pseudo_bit_t vl_cap[0x00004];
+ pseudo_bit_t reserved1[0x00004];
+ pseudo_bit_t mtu_cap[0x00004];
+ pseudo_bit_t g0[0x00001];
+ pseudo_bit_t ng[0x00001];
+ pseudo_bit_t sig[0x00001];
+ pseudo_bit_t mg[0x00001];
+ pseudo_bit_t mp[0x00001];
+ pseudo_bit_t mvc[0x00001];
+ pseudo_bit_t mmc[0x00001];
+ pseudo_bit_t reserved2[0x00009];
+/* -------------- */
+ pseudo_bit_t capability_mask[0x00020];
+/* -------------- */
+ pseudo_bit_t system_image_guid_h[0x00020];
+/* -------------- */
+ pseudo_bit_t system_image_guid_l[0x00020];
+/* -------------- */
+ pseudo_bit_t guid0_h[0x00020];
+/* -------------- */
+ pseudo_bit_t guid0_l[0x00020];
+/* -------------- */
+ pseudo_bit_t node_guid_h[0x00020];
+/* -------------- */
+ pseudo_bit_t node_guid_l[0x00020];
+/* -------------- */
+ pseudo_bit_t egress_sniff_qpn[0x00018];
+ pseudo_bit_t egress_sniff_mode[0x00002];
+ pseudo_bit_t reserved3[0x00006];
+/* -------------- */
+ pseudo_bit_t ingress_sniff_qpn[0x00018];
+ pseudo_bit_t ingress_sniff_mode[0x00002];
+ pseudo_bit_t reserved4[0x00006];
+/* -------------- */
+ pseudo_bit_t max_gid[0x00010];
+ pseudo_bit_t max_pkey[0x00010];
+} __attribute__ (( packed ));
/*
* Wrapper structures for hardware datatypes
@@ -213,7 +257,6 @@ struct MLX_DECLARE_STRUCT ( hermonprm_event_mask );
struct MLX_DECLARE_STRUCT ( hermonprm_event_queue_entry );
struct MLX_DECLARE_STRUCT ( hermonprm_hca_command_register );
struct MLX_DECLARE_STRUCT ( hermonprm_init_hca );
-struct MLX_DECLARE_STRUCT ( hermonprm_init_port );
struct MLX_DECLARE_STRUCT ( hermonprm_mad_ifc );
struct MLX_DECLARE_STRUCT ( hermonprm_mcg_entry );
struct MLX_DECLARE_STRUCT ( hermonprm_mgm_hash );
@@ -228,6 +271,7 @@ struct MLX_DECLARE_STRUCT ( hermonprm_queue_pair_ee_context_entry );
struct MLX_DECLARE_STRUCT ( hermonprm_scalar_parameter );
struct MLX_DECLARE_STRUCT ( hermonprm_sense_port );
struct MLX_DECLARE_STRUCT ( hermonprm_send_db_register );
+struct MLX_DECLARE_STRUCT ( hermonprm_set_port );
struct MLX_DECLARE_STRUCT ( hermonprm_ud_address_vector );
struct MLX_DECLARE_STRUCT ( hermonprm_virtual_physical_mapping );
struct MLX_DECLARE_STRUCT ( hermonprm_wqe_segment_ctrl_mlx );
@@ -590,7 +634,7 @@ struct hermon {
#define HERMON_HCR_REG(x) ( HERMON_HCR_BASE + 4 * (x) )
#define HERMON_HCR_MAX_WAIT_MS 2000
#define HERMON_MBOX_ALIGN 4096
-#define HERMON_MBOX_SIZE 512
+#define HERMON_MBOX_SIZE 1024
/* HCA command is split into
*