aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Iversen <ci@iversenit.dk>2021-01-26 23:48:44 +0100
committerMichael Brown <mcb30@ipxe.org>2021-01-29 00:46:53 +0000
commit43d72d0087c4d81354abfff26d6900047f56b0e4 (patch)
tree01b89aaecfd046d3ae11a9f8f0da4f1cecec2af7
parent699b9f1d1b0338272dc4871ec3348ff3281784a3 (diff)
downloadipxe-43d72d0087c4d81354abfff26d6900047f56b0e4.zip
ipxe-43d72d0087c4d81354abfff26d6900047f56b0e4.tar.gz
ipxe-43d72d0087c4d81354abfff26d6900047f56b0e4.tar.bz2
[hermon] Perform clean MPT unmap on device shutdown
This change is ported from Flexboot sources. When stopping a Hermon device, perform hermon_unmap_mpt() which runs HERMON_HCR_HW2SW_MPT to bring the Memory Protection Table (MPT) back to software control. Signed-off-by: Christian Iversen <ci@iversenit.dk> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/drivers/infiniband/hermon.c28
-rw-r--r--src/drivers/infiniband/hermon.h1
2 files changed, 29 insertions, 0 deletions
diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c
index d766ed5..2a9649d 100644
--- a/src/drivers/infiniband/hermon.c
+++ b/src/drivers/infiniband/hermon.c
@@ -332,6 +332,13 @@ hermon_cmd_sw2hw_mpt ( struct hermon *hermon, unsigned int index,
}
static inline int
+hermon_cmd_hw2sw_mpt ( struct hermon *hermon, unsigned int index ) {
+ return hermon_cmd ( hermon,
+ HERMON_HCR_VOID_CMD ( HERMON_HCR_HW2SW_MPT ),
+ 0, NULL, index, NULL );
+}
+
+static inline int
hermon_cmd_write_mtt ( struct hermon *hermon,
const struct hermonprm_write_mtt *write_mtt ) {
return hermon_cmd ( hermon,
@@ -2808,6 +2815,25 @@ static int hermon_setup_mpt ( struct hermon *hermon ) {
}
/**
+ * Unmap memory protection table
+ *
+ * @v hermon Hermon device
+ * @ret rc Return status code
+ */
+static int hermon_unmap_mpt ( struct hermon *hermon ) {
+ int rc;
+
+ if ( ( rc = hermon_cmd_hw2sw_mpt ( hermon,
+ hermon->cap.reserved_mrws ) ) != 0 ){
+ DBGC ( hermon, "Hermon %p could not unmap MPT: %s\n",
+ hermon, strerror ( rc ) );
+ return rc;
+ }
+
+ return 0;
+}
+
+/**
* Configure special queue pairs
*
* @v hermon Hermon device
@@ -2888,6 +2914,7 @@ static int hermon_start ( struct hermon *hermon, int running ) {
err_conf_special_qps:
hermon_destroy_eq ( hermon );
err_create_eq:
+ hermon_unmap_mpt ( hermon );
err_setup_mpt:
hermon_cmd_close_hca ( hermon );
err_init_hca:
@@ -2905,6 +2932,7 @@ static int hermon_start ( struct hermon *hermon, int running ) {
*/
static void hermon_stop ( struct hermon *hermon ) {
hermon_destroy_eq ( hermon );
+ hermon_unmap_mpt ( hermon );
hermon_cmd_close_hca ( hermon );
hermon_unmap_icm ( hermon );
hermon_stop_firmware ( hermon );
diff --git a/src/drivers/infiniband/hermon.h b/src/drivers/infiniband/hermon.h
index 381e2e4..61f3b04 100644
--- a/src/drivers/infiniband/hermon.h
+++ b/src/drivers/infiniband/hermon.h
@@ -52,6 +52,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define HERMON_HCR_CLOSE_PORT 0x000a
#define HERMON_HCR_SET_PORT 0x000c
#define HERMON_HCR_SW2HW_MPT 0x000d
+#define HERMON_HCR_HW2SW_MPT 0x000f
#define HERMON_HCR_WRITE_MTT 0x0011
#define HERMON_HCR_MAP_EQ 0x0012
#define HERMON_HCR_SW2HW_EQ 0x0013