Commit 7c03ed85 authored by Easwar Hariharan's avatar Easwar Hariharan Committed by Greg Kroah-Hartman

staging/rdma/hfi1: Fix code to reset ASIC CSRs on FLR

The ASIC registers were not reset on FLR, and the code to
protect the ASIC block against multiple initializations by
peer HFIs did not extend to multiple ASICs in a system. This
patch addresses this gap.
Reviewed-by: default avatarDean Luick <dean.luick@intel.com>
Signed-off-by: default avatarEaswar Hariharan <easwar.hariharan@intel.com>
Signed-off-by: default avatarIra Weiny <ira.weiny@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 13a69f52
...@@ -9324,8 +9324,6 @@ static void reset_cce_csrs(struct hfi1_devdata *dd) ...@@ -9324,8 +9324,6 @@ static void reset_cce_csrs(struct hfi1_devdata *dd)
/* set ASIC CSRs to chip reset defaults */ /* set ASIC CSRs to chip reset defaults */
static void reset_asic_csrs(struct hfi1_devdata *dd) static void reset_asic_csrs(struct hfi1_devdata *dd)
{ {
static DEFINE_MUTEX(asic_mutex);
static int called;
int i; int i;
/* /*
...@@ -9335,15 +9333,8 @@ static void reset_asic_csrs(struct hfi1_devdata *dd) ...@@ -9335,15 +9333,8 @@ static void reset_asic_csrs(struct hfi1_devdata *dd)
* a known first load do the reset and blocking all others. * a known first load do the reset and blocking all others.
*/ */
/* if (!(dd->flags & HFI1_DO_INIT_ASIC))
* These CSRs should only be reset once - the first one here will return;
* do the work. Use a mutex so that a non-first caller waits until
* the first is finished before it can proceed.
*/
mutex_lock(&asic_mutex);
if (called)
goto done;
called = 1;
if (dd->icode != ICODE_FPGA_EMULATION) { if (dd->icode != ICODE_FPGA_EMULATION) {
/* emulation does not have an SBus - leave these alone */ /* emulation does not have an SBus - leave these alone */
...@@ -9363,7 +9354,10 @@ static void reset_asic_csrs(struct hfi1_devdata *dd) ...@@ -9363,7 +9354,10 @@ static void reset_asic_csrs(struct hfi1_devdata *dd)
for (i = 0; i < ASIC_NUM_SCRATCH; i++) for (i = 0; i < ASIC_NUM_SCRATCH; i++)
write_csr(dd, ASIC_CFG_SCRATCH + (8 * i), 0); write_csr(dd, ASIC_CFG_SCRATCH + (8 * i), 0);
write_csr(dd, ASIC_CFG_MUTEX, 0); /* this will clear it */ write_csr(dd, ASIC_CFG_MUTEX, 0); /* this will clear it */
/* We might want to retain this state across FLR if we ever use it */
write_csr(dd, ASIC_CFG_DRV_STR, 0); write_csr(dd, ASIC_CFG_DRV_STR, 0);
write_csr(dd, ASIC_CFG_THERM_POLL_EN, 0); write_csr(dd, ASIC_CFG_THERM_POLL_EN, 0);
/* ASIC_STS_THERM read-only */ /* ASIC_STS_THERM read-only */
/* ASIC_CFG_RESET leave alone */ /* ASIC_CFG_RESET leave alone */
...@@ -9410,9 +9404,6 @@ static void reset_asic_csrs(struct hfi1_devdata *dd) ...@@ -9410,9 +9404,6 @@ static void reset_asic_csrs(struct hfi1_devdata *dd)
/* this also writes a NOP command, clearing paging mode */ /* this also writes a NOP command, clearing paging mode */
write_csr(dd, ASIC_EEP_ADDR_CMD, 0); write_csr(dd, ASIC_EEP_ADDR_CMD, 0);
write_csr(dd, ASIC_EEP_DATA, 0); write_csr(dd, ASIC_EEP_DATA, 0);
done:
mutex_unlock(&asic_mutex);
} }
/* set MISC CSRs to chip reset defaults */ /* set MISC CSRs to chip reset defaults */
...@@ -9824,6 +9815,7 @@ static void init_chip(struct hfi1_devdata *dd) ...@@ -9824,6 +9815,7 @@ static void init_chip(struct hfi1_devdata *dd)
restore_pci_variables(dd); restore_pci_variables(dd);
} }
reset_asic_csrs(dd);
} else { } else {
dd_dev_info(dd, "Resetting CSRs with writes\n"); dd_dev_info(dd, "Resetting CSRs with writes\n");
reset_cce_csrs(dd); reset_cce_csrs(dd);
...@@ -9834,6 +9826,7 @@ static void init_chip(struct hfi1_devdata *dd) ...@@ -9834,6 +9826,7 @@ static void init_chip(struct hfi1_devdata *dd)
} }
/* clear the DC reset */ /* clear the DC reset */
write_csr(dd, CCE_DC_CTRL, 0); write_csr(dd, CCE_DC_CTRL, 0);
/* Set the LED off */ /* Set the LED off */
if (is_a0(dd)) if (is_a0(dd))
setextled(dd, 0); setextled(dd, 0);
...@@ -10329,7 +10322,7 @@ static void asic_should_init(struct hfi1_devdata *dd) ...@@ -10329,7 +10322,7 @@ static void asic_should_init(struct hfi1_devdata *dd)
} }
/** /**
* Allocate an initialize the device structure for the hfi. * Allocate and initialize the device structure for the hfi.
* @dev: the pci_dev for hfi1_ib device * @dev: the pci_dev for hfi1_ib device
* @ent: pci_device_id struct for this dev * @ent: pci_device_id struct for this dev
* *
...@@ -10485,6 +10478,12 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev, ...@@ -10485,6 +10478,12 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
else if (dd->rcv_intr_timeout_csr == 0 && rcv_intr_timeout) else if (dd->rcv_intr_timeout_csr == 0 && rcv_intr_timeout)
dd->rcv_intr_timeout_csr = 1; dd->rcv_intr_timeout_csr = 1;
/* needs to be done before we look for the peer device */
read_guid(dd);
/* should this device init the ASIC block? */
asic_should_init(dd);
/* obtain chip sizes, reset chip CSRs */ /* obtain chip sizes, reset chip CSRs */
init_chip(dd); init_chip(dd);
...@@ -10493,11 +10492,6 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev, ...@@ -10493,11 +10492,6 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
if (ret) if (ret)
goto bail_cleanup; goto bail_cleanup;
/* needs to be done before we look for the peer device */
read_guid(dd);
asic_should_init(dd);
/* read in firmware */ /* read in firmware */
ret = hfi1_firmware_init(dd); ret = hfi1_firmware_init(dd);
if (ret) if (ret)
...@@ -10712,6 +10706,7 @@ static int thermal_init(struct hfi1_devdata *dd) ...@@ -10712,6 +10706,7 @@ static int thermal_init(struct hfi1_devdata *dd)
acquire_hw_mutex(dd); acquire_hw_mutex(dd);
dd_dev_info(dd, "Initializing thermal sensor\n"); dd_dev_info(dd, "Initializing thermal sensor\n");
/* Thermal Sensor Initialization */ /* Thermal Sensor Initialization */
/* Step 1: Reset the Thermal SBus Receiver */ /* Step 1: Reset the Thermal SBus Receiver */
ret = sbus_request_slow(dd, SBUS_THERMAL, 0x0, ret = sbus_request_slow(dd, SBUS_THERMAL, 0x0,
......
...@@ -1614,6 +1614,10 @@ int load_pcie_firmware(struct hfi1_devdata *dd) ...@@ -1614,6 +1614,10 @@ int load_pcie_firmware(struct hfi1_devdata *dd)
*/ */
void read_guid(struct hfi1_devdata *dd) void read_guid(struct hfi1_devdata *dd)
{ {
/* Take the DC out of reset to get a valid GUID value */
write_csr(dd, CCE_DC_CTRL, 0);
(void) read_csr(dd, CCE_DC_CTRL);
dd->base_guid = read_csr(dd, DC_DC8051_CFG_LOCAL_GUID); dd->base_guid = read_csr(dd, DC_DC8051_CFG_LOCAL_GUID);
dd_dev_info(dd, "GUID %llx", dd_dev_info(dd, "GUID %llx",
(unsigned long long)dd->base_guid); (unsigned long long)dd->base_guid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment