[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1299100213-8770-7-git-send-email-dykmanj@linux.vnet.ibm.com>
Date: Wed, 2 Mar 2011 16:09:53 -0500
From: dykmanj@...ux.vnet.ibm.com
To: netdev@...r.kernel.org
Cc: Jim Dykman <dykmanj@...ux.vnet.ibm.com>,
Piyush Chaudhary <piyushc@...ux.vnet.ibm.com>,
Fu-Chung Chang <fcchang@...ux.vnet.ibm.com>,
" William S. Cadden" <wscadden@...ux.vnet.ibm.com>,
" Wen C. Chen" <winstonc@...ux.vnet.ibm.com>,
Scot Sakolish <sakolish@...ux.vnet.ibm.com>,
Jian Xiao <jian@...ux.vnet.ibm.com>,
" Carol L. Soto" <clsoto@...ux.vnet.ibm.com>,
" Sarah J. Sheppard" <sjsheppa@...ux.vnet.ibm.com>
Subject: [PATCH 07/27] HFI: Add nMMU start/stop hypervisor calls
From: Jim Dykman <dykmanj@...ux.vnet.ibm.com>
H_NMMU_START resets/inits state for the nMMU in the hypervisor.
H_NMMU_STOP cleans up hypervisor nMMU state, called on DD unload after HFIs are
stopped.
Signed-off-by: Piyush Chaudhary <piyushc@...ux.vnet.ibm.com>
Signed-off-by: Jim Dykman <dykmanj@...ux.vnet.ibm.com>
Signed-off-by: Fu-Chung Chang <fcchang@...ux.vnet.ibm.com>
Signed-off-by: William S. Cadden <wscadden@...ux.vnet.ibm.com>
Signed-off-by: Wen C. Chen <winstonc@...ux.vnet.ibm.com>
Signed-off-by: Scot Sakolish <sakolish@...ux.vnet.ibm.com>
Signed-off-by: Jian Xiao <jian@...ux.vnet.ibm.com>
Signed-off-by: Carol L. Soto <clsoto@...ux.vnet.ibm.com>
Signed-off-by: Sarah J. Sheppard <sjsheppa@...ux.vnet.ibm.com>
---
drivers/net/hfi/core/hfidd_adpt.c | 36 +++++++++++++++++++++++++++++++++++
drivers/net/hfi/core/hfidd_hcalls.c | 33 ++++++++++++++++++++++++++++++++
drivers/net/hfi/core/hfidd_init.c | 29 +++++++++++++++++++++++++--
drivers/net/hfi/core/hfidd_proto.h | 3 ++
include/linux/hfi/hfidd_hcalls.h | 2 +
5 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/drivers/net/hfi/core/hfidd_adpt.c b/drivers/net/hfi/core/hfidd_adpt.c
index bec838a..feb1b59 100644
--- a/drivers/net/hfi/core/hfidd_adpt.c
+++ b/drivers/net/hfi/core/hfidd_adpt.c
@@ -164,6 +164,42 @@ query1:
return rc;
}
+int hfidd_start_nmmu(struct hfidd_acs *p_acs)
+{
+ long long hvrc;
+ int rc = 0;
+ struct nmmu_info *nmmu_info;
+ caddr_t laddr = NULL;
+ u64 start_time = get_jiffies_64();
+
+ rc = hfidd_get_phyp_page(p_acs, (caddr_t *)&nmmu_info, &laddr,
+ PAGE_SIZE_4K);
+ if (rc) {
+ dev_printk(KERN_ERR, p_acs->hfidd_dev,
+ "hfidd_start_nmmu: hfidd_get_phyp_page failed\n");
+ return -ENOMEM;
+ }
+
+ while (1) {
+ hvrc = hfi_start_nmmu(p_acs->dds.torr_id,
+ (struct nmmu_info *) laddr);
+ if (hvrc != H_BUSY)
+ break;
+ if (hfidd_age_hcall(start_time))
+ break;
+ }
+
+ if (hvrc != H_SUCCESS) {
+ dev_printk(KERN_ERR, p_acs->hfidd_dev,
+ "hfidd_start_nmmu: HFI_START_NMMU failed "
+ "hvrc 0x%llx\n", hvrc);
+ rc = -EPERM;
+ }
+
+ hfidd_release_phyp_page((caddr_t)nmmu_info, PAGE_SIZE_4K);
+ return rc;
+}
+
int hfidd_start_interface(struct hfidd_acs *p_acs)
{
long long hvrc = 0;
diff --git a/drivers/net/hfi/core/hfidd_hcalls.c b/drivers/net/hfi/core/hfidd_hcalls.c
index 84467b3..2ca1c8a 100644
--- a/drivers/net/hfi/core/hfidd_hcalls.c
+++ b/drivers/net/hfi/core/hfidd_hcalls.c
@@ -33,6 +33,18 @@
#include <linux/hfi/hfidd_internal.h>
#include "hfidd_proto.h"
+static inline long long h_nmmu_start(int token,
+ u64 torrent_chip_ID,
+ void *output_page_ptr)
+{
+ return plpar_hcall_norets(token, torrent_chip_ID, output_page_ptr);
+}
+
+static inline long long h_nmmu_stop(int token, u64 torrent_chip_ID)
+{
+ return plpar_hcall_norets(token, torrent_chip_ID);
+}
+
static inline long long h_hfi_start_interface(int token,
u64 HFI_chip_ID)
{
@@ -61,6 +73,27 @@ static inline long long h_hfi_query_interface(int token,
return rc;
}
+long long hfi_start_nmmu(u64 chip_id, void *nmmu_info)
+{
+ return h_nmmu_start(H_NMMU_START, chip_id, nmmu_info);
+}
+
+long long hfi_stop_nmmu(u64 chip_id)
+{
+ long long hvrc;
+ u64 start_time = get_jiffies_64();
+
+ while (1) {
+ hvrc = h_nmmu_stop(H_NMMU_STOP,
+ chip_id);
+ if (hvrc != H_BUSY)
+ break;
+ if (hfidd_age_hcall(start_time))
+ break;
+ }
+ return hvrc;
+}
+
long long hfi_hquery_interface(u64 unit_id, u64 subtype,
u64 query_p, u64 *state)
{
diff --git a/drivers/net/hfi/core/hfidd_init.c b/drivers/net/hfi/core/hfidd_init.c
index 9dfd2b4..448349d 100644
--- a/drivers/net/hfi/core/hfidd_init.c
+++ b/drivers/net/hfi/core/hfidd_init.c
@@ -321,31 +321,44 @@ hfidd_create_devices_error0:
/*
* Disable message passing to each adapter by calling the
- * Stop Interface hcall.
+ * Stop Interface hcall and free phyp NMMU tables for this
+ * lpar by calling STOP NMMU
*/
static void hfidd_stop_adapter(void)
{
int i;
+ long long hvrc;
for (i = 0; i < MAX_HFIS; i++) {
hfidd_stop_interface(hfidd_global.p_acs[i],
hfidd_global.p_acs[i]->dds.hfi_id);
}
+ hvrc = hfi_stop_nmmu(hfidd_global.p_acs[0]->dds.torr_id);
+ if (hvrc != H_SUCCESS)
+ dev_printk(KERN_ERR, hfidd_global.p_acs[0]->hfidd_dev,
+ "%s: hfidd_stop_adapter: HFI_STOP_NMMU failed"
+ " hvrc = 0x%llx\n", HFIDD_DEV_NAME, hvrc);
return;
}
/*
* Query the interface to check the logical state of HFI.
- * Enable message passing to each adapter by calling Start
- * Interface hcall.
+ * Initialize the phyp NMMU tables for this lpar by calling
+ * the START NMMU hcall and enable message passing to each
+ * adapter by calling Start Interface hcall.
*/
static int hfidd_start_adapter(void)
{
+ long long hvrc;
unsigned long long hfi_state;
int i, j;
int rc = 0;
for (i = 0; i < MAX_HFIS; i++) {
+ /* query interface before doing START_NMMU.
+ * If we crashed the LPAR a few minutes ago, we never did the
+ * stop interface and the stop nmmu. Do it now.
+ */
rc = hfidd_query_interface(hfidd_global.p_acs[i], COMP_QUERY,
hfidd_global.p_acs[i]->dds.hfi_id, &hfi_state);
if (hfi_state != NOT_STARTED) {
@@ -376,6 +389,15 @@ static int hfidd_start_adapter(void)
}
+ hfi_stop_nmmu(hfidd_global.p_acs[0]->dds.torr_id);
+ hvrc = hfidd_start_nmmu(hfidd_global.p_acs[0]);
+ if (hvrc != H_SUCCESS) {
+ dev_printk(KERN_ERR, hfidd_global.p_acs[0]->hfidd_dev,
+ "%s: hfidd_start_adapter: HFI_START_NMMU failed"
+ " hvrc = 0x%llx\n", HFIDD_DEV_NAME, hvrc);
+ return -EIO;
+ }
+
for (i = 0; i < MAX_HFIS; i++) {
rc = hfidd_start_interface(hfidd_global.p_acs[i]);
if (rc) {
@@ -404,6 +426,7 @@ hfidd_start_adapter_err:
hfidd_stop_interface(hfidd_global.p_acs[j],
hfidd_global.p_acs[j]->dds.hfi_id);
}
+ hfi_stop_nmmu(hfidd_global.p_acs[0]->dds.torr_id);
return rc;
}
diff --git a/drivers/net/hfi/core/hfidd_proto.h b/drivers/net/hfi/core/hfidd_proto.h
index 6ec9245..320f41f 100644
--- a/drivers/net/hfi/core/hfidd_proto.h
+++ b/drivers/net/hfi/core/hfidd_proto.h
@@ -42,8 +42,11 @@ int hfidd_get_phyp_page(struct hfidd_acs *p_acs, caddr_t *page,
void hfidd_release_phyp_page(caddr_t page, int size);
int hfidd_query_interface(struct hfidd_acs *p_acs, unsigned int subtype,
unsigned int hfi_id, unsigned long long *state);
+int hfidd_start_nmmu(struct hfidd_acs *p_acs);
int hfidd_start_interface(struct hfidd_acs *p_acs);
int hfidd_stop_interface(struct hfidd_acs *p_acs, unsigned int hfi_id);
+long long hfi_start_nmmu(u64 chip_id, void *nmmu_info);
+long long hfi_stop_nmmu(u64 chip_id);
long long hfi_hquery_interface(u64 unit_id, u64 subtype, u64 query_p,
u64 *state);
long long hfi_start_interface(u64 unit_id);
diff --git a/include/linux/hfi/hfidd_hcalls.h b/include/linux/hfi/hfidd_hcalls.h
index 5349e9e..2a374e6 100644
--- a/include/linux/hfi/hfidd_hcalls.h
+++ b/include/linux/hfi/hfidd_hcalls.h
@@ -39,6 +39,8 @@
#define H_HFI_START_INTERFACE 0xF000
#define H_HFI_QUERY_INTERFACE 0xF004
#define H_HFI_STOP_INTERFACE 0xF008
+#define H_NMMU_START 0xF028
+#define H_NMMU_STOP 0xF02C
#define EEH_QUERY 1
#define COMP_QUERY 2
--
1.7.3.1
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists