From 43d72d0087c4d81354abfff26d6900047f56b0e4 Mon Sep 17 00:00:00 2001 From: Christian Iversen Date: Tue, 26 Jan 2021 23:48:44 +0100 Subject: [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 Modified-by: Michael Brown Signed-off-by: Michael Brown --- src/drivers/infiniband/hermon.c | 28 ++++++++++++++++++++++++++++ src/drivers/infiniband/hermon.h | 1 + 2 files changed, 29 insertions(+) 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 -- cgit v1.1