1145eba1aSCai Huoqing // SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause
2f48ad614SDennis Dalessandro /*
35e6e9424SMichael J. Ruhl  * Copyright(c) 2015 - 2017 Intel Corporation.
4f48ad614SDennis Dalessandro  */
5f48ad614SDennis Dalessandro 
6f48ad614SDennis Dalessandro #include <linux/firmware.h>
7f48ad614SDennis Dalessandro #include <linux/mutex.h>
8f48ad614SDennis Dalessandro #include <linux/delay.h>
9f48ad614SDennis Dalessandro #include <linux/crc32.h>
10f48ad614SDennis Dalessandro 
11f48ad614SDennis Dalessandro #include "hfi.h"
12f48ad614SDennis Dalessandro #include "trace.h"
13f48ad614SDennis Dalessandro 
14f48ad614SDennis Dalessandro /*
15f48ad614SDennis Dalessandro  * Make it easy to toggle firmware file name and if it gets loaded by
16f48ad614SDennis Dalessandro  * editing the following. This may be something we do while in development
17f48ad614SDennis Dalessandro  * but not necessarily something a user would ever need to use.
18f48ad614SDennis Dalessandro  */
19f48ad614SDennis Dalessandro #define DEFAULT_FW_8051_NAME_FPGA "hfi_dc8051.bin"
20f48ad614SDennis Dalessandro #define DEFAULT_FW_8051_NAME_ASIC "hfi1_dc8051.fw"
21f48ad614SDennis Dalessandro #define DEFAULT_FW_FABRIC_NAME "hfi1_fabric.fw"
22f48ad614SDennis Dalessandro #define DEFAULT_FW_SBUS_NAME "hfi1_sbus.fw"
23f48ad614SDennis Dalessandro #define DEFAULT_FW_PCIE_NAME "hfi1_pcie.fw"
24f48ad614SDennis Dalessandro #define ALT_FW_8051_NAME_ASIC "hfi1_dc8051_d.fw"
25f48ad614SDennis Dalessandro #define ALT_FW_FABRIC_NAME "hfi1_fabric_d.fw"
26f48ad614SDennis Dalessandro #define ALT_FW_SBUS_NAME "hfi1_sbus_d.fw"
27f48ad614SDennis Dalessandro #define ALT_FW_PCIE_NAME "hfi1_pcie_d.fw"
28f48ad614SDennis Dalessandro 
296a28d5a9SThomas Bogendoerfer MODULE_FIRMWARE(DEFAULT_FW_8051_NAME_ASIC);
306a28d5a9SThomas Bogendoerfer MODULE_FIRMWARE(DEFAULT_FW_FABRIC_NAME);
316a28d5a9SThomas Bogendoerfer MODULE_FIRMWARE(DEFAULT_FW_SBUS_NAME);
326a28d5a9SThomas Bogendoerfer MODULE_FIRMWARE(DEFAULT_FW_PCIE_NAME);
336a28d5a9SThomas Bogendoerfer 
34f48ad614SDennis Dalessandro static uint fw_8051_load = 1;
35f48ad614SDennis Dalessandro static uint fw_fabric_serdes_load = 1;
36f48ad614SDennis Dalessandro static uint fw_pcie_serdes_load = 1;
37f48ad614SDennis Dalessandro static uint fw_sbus_load = 1;
38f48ad614SDennis Dalessandro 
39f48ad614SDennis Dalessandro /* Firmware file names get set in hfi1_firmware_init() based on the above */
40f48ad614SDennis Dalessandro static char *fw_8051_name;
41f48ad614SDennis Dalessandro static char *fw_fabric_serdes_name;
42f48ad614SDennis Dalessandro static char *fw_sbus_name;
43f48ad614SDennis Dalessandro static char *fw_pcie_serdes_name;
44f48ad614SDennis Dalessandro 
45f48ad614SDennis Dalessandro #define SBUS_MAX_POLL_COUNT 100
46f48ad614SDennis Dalessandro #define SBUS_COUNTER(reg, name) \
47f48ad614SDennis Dalessandro 	(((reg) >> ASIC_STS_SBUS_COUNTERS_##name##_CNT_SHIFT) & \
48f48ad614SDennis Dalessandro 	 ASIC_STS_SBUS_COUNTERS_##name##_CNT_MASK)
49f48ad614SDennis Dalessandro 
50f48ad614SDennis Dalessandro /*
51f48ad614SDennis Dalessandro  * Firmware security header.
52f48ad614SDennis Dalessandro  */
53f48ad614SDennis Dalessandro struct css_header {
54f48ad614SDennis Dalessandro 	u32 module_type;
55f48ad614SDennis Dalessandro 	u32 header_len;
56f48ad614SDennis Dalessandro 	u32 header_version;
57f48ad614SDennis Dalessandro 	u32 module_id;
58f48ad614SDennis Dalessandro 	u32 module_vendor;
59f48ad614SDennis Dalessandro 	u32 date;		/* BCD yyyymmdd */
60f48ad614SDennis Dalessandro 	u32 size;		/* in DWORDs */
61f48ad614SDennis Dalessandro 	u32 key_size;		/* in DWORDs */
62f48ad614SDennis Dalessandro 	u32 modulus_size;	/* in DWORDs */
63f48ad614SDennis Dalessandro 	u32 exponent_size;	/* in DWORDs */
64f48ad614SDennis Dalessandro 	u32 reserved[22];
65f48ad614SDennis Dalessandro };
66f48ad614SDennis Dalessandro 
67f48ad614SDennis Dalessandro /* expected field values */
68f48ad614SDennis Dalessandro #define CSS_MODULE_TYPE	   0x00000006
69f48ad614SDennis Dalessandro #define CSS_HEADER_LEN	   0x000000a1
70f48ad614SDennis Dalessandro #define CSS_HEADER_VERSION 0x00010000
71f48ad614SDennis Dalessandro #define CSS_MODULE_VENDOR  0x00008086
72f48ad614SDennis Dalessandro 
73f48ad614SDennis Dalessandro #define KEY_SIZE      256
74f48ad614SDennis Dalessandro #define MU_SIZE		8
75f48ad614SDennis Dalessandro #define EXPONENT_SIZE	4
76f48ad614SDennis Dalessandro 
779773afb9SJakub Byczkowski /* size of platform configuration partition */
789773afb9SJakub Byczkowski #define MAX_PLATFORM_CONFIG_FILE_SIZE 4096
799773afb9SJakub Byczkowski 
809773afb9SJakub Byczkowski /* size of file of plaform configuration encoded in format version 4 */
819773afb9SJakub Byczkowski #define PLATFORM_CONFIG_FORMAT_4_FILE_SIZE 528
829773afb9SJakub Byczkowski 
83f48ad614SDennis Dalessandro /* the file itself */
84f48ad614SDennis Dalessandro struct firmware_file {
85f48ad614SDennis Dalessandro 	struct css_header css_header;
86f48ad614SDennis Dalessandro 	u8 modulus[KEY_SIZE];
87f48ad614SDennis Dalessandro 	u8 exponent[EXPONENT_SIZE];
88f48ad614SDennis Dalessandro 	u8 signature[KEY_SIZE];
89f48ad614SDennis Dalessandro 	u8 firmware[];
90f48ad614SDennis Dalessandro };
91f48ad614SDennis Dalessandro 
92f48ad614SDennis Dalessandro struct augmented_firmware_file {
93f48ad614SDennis Dalessandro 	struct css_header css_header;
94f48ad614SDennis Dalessandro 	u8 modulus[KEY_SIZE];
95f48ad614SDennis Dalessandro 	u8 exponent[EXPONENT_SIZE];
96f48ad614SDennis Dalessandro 	u8 signature[KEY_SIZE];
97f48ad614SDennis Dalessandro 	u8 r2[KEY_SIZE];
98f48ad614SDennis Dalessandro 	u8 mu[MU_SIZE];
99f48ad614SDennis Dalessandro 	u8 firmware[];
100f48ad614SDennis Dalessandro };
101f48ad614SDennis Dalessandro 
102f48ad614SDennis Dalessandro /* augmented file size difference */
103f48ad614SDennis Dalessandro #define AUGMENT_SIZE (sizeof(struct augmented_firmware_file) - \
104f48ad614SDennis Dalessandro 						sizeof(struct firmware_file))
105f48ad614SDennis Dalessandro 
106f48ad614SDennis Dalessandro struct firmware_details {
107f48ad614SDennis Dalessandro 	/* Linux core piece */
108f48ad614SDennis Dalessandro 	const struct firmware *fw;
109f48ad614SDennis Dalessandro 
110f48ad614SDennis Dalessandro 	struct css_header *css_header;
111f48ad614SDennis Dalessandro 	u8 *firmware_ptr;		/* pointer to binary data */
112f48ad614SDennis Dalessandro 	u32 firmware_len;		/* length in bytes */
113f48ad614SDennis Dalessandro 	u8 *modulus;			/* pointer to the modulus */
114f48ad614SDennis Dalessandro 	u8 *exponent;			/* pointer to the exponent */
115f48ad614SDennis Dalessandro 	u8 *signature;			/* pointer to the signature */
116f48ad614SDennis Dalessandro 	u8 *r2;				/* pointer to r2 */
117f48ad614SDennis Dalessandro 	u8 *mu;				/* pointer to mu */
118f48ad614SDennis Dalessandro 	struct augmented_firmware_file dummy_header;
119f48ad614SDennis Dalessandro };
120f48ad614SDennis Dalessandro 
121f48ad614SDennis Dalessandro /*
122f48ad614SDennis Dalessandro  * The mutex protects fw_state, fw_err, and all of the firmware_details
123f48ad614SDennis Dalessandro  * variables.
124f48ad614SDennis Dalessandro  */
125f48ad614SDennis Dalessandro static DEFINE_MUTEX(fw_mutex);
126f48ad614SDennis Dalessandro enum fw_state {
127f48ad614SDennis Dalessandro 	FW_EMPTY,
128f48ad614SDennis Dalessandro 	FW_TRY,
129f48ad614SDennis Dalessandro 	FW_FINAL,
130f48ad614SDennis Dalessandro 	FW_ERR
131f48ad614SDennis Dalessandro };
132f48ad614SDennis Dalessandro 
133f48ad614SDennis Dalessandro static enum fw_state fw_state = FW_EMPTY;
134f48ad614SDennis Dalessandro static int fw_err;
135f48ad614SDennis Dalessandro static struct firmware_details fw_8051;
136f48ad614SDennis Dalessandro static struct firmware_details fw_fabric;
137f48ad614SDennis Dalessandro static struct firmware_details fw_pcie;
138f48ad614SDennis Dalessandro static struct firmware_details fw_sbus;
139f48ad614SDennis Dalessandro 
140f48ad614SDennis Dalessandro /* flags for turn_off_spicos() */
141f48ad614SDennis Dalessandro #define SPICO_SBUS   0x1
142f48ad614SDennis Dalessandro #define SPICO_FABRIC 0x2
143f48ad614SDennis Dalessandro #define ENABLE_SPICO_SMASK 0x1
144f48ad614SDennis Dalessandro 
145f48ad614SDennis Dalessandro /* security block commands */
146f48ad614SDennis Dalessandro #define RSA_CMD_INIT  0x1
147f48ad614SDennis Dalessandro #define RSA_CMD_START 0x2
148f48ad614SDennis Dalessandro 
149f48ad614SDennis Dalessandro /* security block status */
150f48ad614SDennis Dalessandro #define RSA_STATUS_IDLE   0x0
151f48ad614SDennis Dalessandro #define RSA_STATUS_ACTIVE 0x1
152f48ad614SDennis Dalessandro #define RSA_STATUS_DONE   0x2
153f48ad614SDennis Dalessandro #define RSA_STATUS_FAILED 0x3
154f48ad614SDennis Dalessandro 
155f48ad614SDennis Dalessandro /* RSA engine timeout, in ms */
156f48ad614SDennis Dalessandro #define RSA_ENGINE_TIMEOUT 100 /* ms */
157f48ad614SDennis Dalessandro 
158f48ad614SDennis Dalessandro /* hardware mutex timeout, in ms */
159f48ad614SDennis Dalessandro #define HM_TIMEOUT 10 /* ms */
160f48ad614SDennis Dalessandro 
161f48ad614SDennis Dalessandro /* 8051 memory access timeout, in us */
162f48ad614SDennis Dalessandro #define DC8051_ACCESS_TIMEOUT 100 /* us */
163f48ad614SDennis Dalessandro 
164f48ad614SDennis Dalessandro /* the number of fabric SerDes on the SBus */
165f48ad614SDennis Dalessandro #define NUM_FABRIC_SERDES 4
166f48ad614SDennis Dalessandro 
167b3bf270bSDean Luick /* ASIC_STS_SBUS_RESULT.RESULT_CODE value */
168b3bf270bSDean Luick #define SBUS_READ_COMPLETE 0x4
169b3bf270bSDean Luick 
170f48ad614SDennis Dalessandro /* SBus fabric SerDes addresses, one set per HFI */
171f48ad614SDennis Dalessandro static const u8 fabric_serdes_addrs[2][NUM_FABRIC_SERDES] = {
172f48ad614SDennis Dalessandro 	{ 0x01, 0x02, 0x03, 0x04 },
173f48ad614SDennis Dalessandro 	{ 0x28, 0x29, 0x2a, 0x2b }
174f48ad614SDennis Dalessandro };
175f48ad614SDennis Dalessandro 
176f48ad614SDennis Dalessandro /* SBus PCIe SerDes addresses, one set per HFI */
177f48ad614SDennis Dalessandro static const u8 pcie_serdes_addrs[2][NUM_PCIE_SERDES] = {
178f48ad614SDennis Dalessandro 	{ 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,
179f48ad614SDennis Dalessandro 	  0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26 },
180f48ad614SDennis Dalessandro 	{ 0x2f, 0x31, 0x33, 0x35, 0x37, 0x39, 0x3b, 0x3d,
181f48ad614SDennis Dalessandro 	  0x3f, 0x41, 0x43, 0x45, 0x47, 0x49, 0x4b, 0x4d }
182f48ad614SDennis Dalessandro };
183f48ad614SDennis Dalessandro 
184f48ad614SDennis Dalessandro /* SBus PCIe PCS addresses, one set per HFI */
185f48ad614SDennis Dalessandro const u8 pcie_pcs_addrs[2][NUM_PCIE_SERDES] = {
186f48ad614SDennis Dalessandro 	{ 0x09, 0x0b, 0x0d, 0x0f, 0x11, 0x13, 0x15, 0x17,
187f48ad614SDennis Dalessandro 	  0x19, 0x1b, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27 },
188f48ad614SDennis Dalessandro 	{ 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
189f48ad614SDennis Dalessandro 	  0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e }
190f48ad614SDennis Dalessandro };
191f48ad614SDennis Dalessandro 
192f48ad614SDennis Dalessandro /* SBus fabric SerDes broadcast addresses, one per HFI */
193f48ad614SDennis Dalessandro static const u8 fabric_serdes_broadcast[2] = { 0xe4, 0xe5 };
194f48ad614SDennis Dalessandro static const u8 all_fabric_serdes_broadcast = 0xe1;
195f48ad614SDennis Dalessandro 
196f48ad614SDennis Dalessandro /* SBus PCIe SerDes broadcast addresses, one per HFI */
197f48ad614SDennis Dalessandro const u8 pcie_serdes_broadcast[2] = { 0xe2, 0xe3 };
198f48ad614SDennis Dalessandro static const u8 all_pcie_serdes_broadcast = 0xe0;
199f48ad614SDennis Dalessandro 
20066431b0eSBart Van Assche static const u32 platform_config_table_limits[PLATFORM_CONFIG_TABLE_MAX] = {
20166431b0eSBart Van Assche 	0,
20266431b0eSBart Van Assche 	SYSTEM_TABLE_MAX,
20366431b0eSBart Van Assche 	PORT_TABLE_MAX,
20466431b0eSBart Van Assche 	RX_PRESET_TABLE_MAX,
20566431b0eSBart Van Assche 	TX_PRESET_TABLE_MAX,
20666431b0eSBart Van Assche 	QSFP_ATTEN_TABLE_MAX,
20766431b0eSBart Van Assche 	VARIABLE_SETTINGS_TABLE_MAX
20866431b0eSBart Van Assche };
20966431b0eSBart Van Assche 
210f48ad614SDennis Dalessandro /* forwards */
211f48ad614SDennis Dalessandro static void dispose_one_firmware(struct firmware_details *fdet);
212f48ad614SDennis Dalessandro static int load_fabric_serdes_firmware(struct hfi1_devdata *dd,
213f48ad614SDennis Dalessandro 				       struct firmware_details *fdet);
214b3bf270bSDean Luick static void dump_fw_version(struct hfi1_devdata *dd);
215f48ad614SDennis Dalessandro 
216f48ad614SDennis Dalessandro /*
217f48ad614SDennis Dalessandro  * Read a single 64-bit value from 8051 data memory.
218f48ad614SDennis Dalessandro  *
219f48ad614SDennis Dalessandro  * Expects:
220f48ad614SDennis Dalessandro  * o caller to have already set up data read, no auto increment
221f48ad614SDennis Dalessandro  * o caller to turn off read enable when finished
222f48ad614SDennis Dalessandro  *
223f48ad614SDennis Dalessandro  * The address argument is a byte offset.  Bits 0:2 in the address are
224f48ad614SDennis Dalessandro  * ignored - i.e. the hardware will always do aligned 8-byte reads as if
225f48ad614SDennis Dalessandro  * the lower bits are zero.
226f48ad614SDennis Dalessandro  *
227f48ad614SDennis Dalessandro  * Return 0 on success, -ENXIO on a read error (timeout).
228f48ad614SDennis Dalessandro  */
__read_8051_data(struct hfi1_devdata * dd,u32 addr,u64 * result)229f48ad614SDennis Dalessandro static int __read_8051_data(struct hfi1_devdata *dd, u32 addr, u64 *result)
230f48ad614SDennis Dalessandro {
231f48ad614SDennis Dalessandro 	u64 reg;
232f48ad614SDennis Dalessandro 	int count;
233f48ad614SDennis Dalessandro 
234d7cf4ccfSDean Luick 	/* step 1: set the address, clear enable */
235d7cf4ccfSDean Luick 	reg = (addr & DC_DC8051_CFG_RAM_ACCESS_CTRL_ADDRESS_MASK)
236d7cf4ccfSDean Luick 			<< DC_DC8051_CFG_RAM_ACCESS_CTRL_ADDRESS_SHIFT;
237f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_CTRL, reg);
238d7cf4ccfSDean Luick 	/* step 2: enable */
239d7cf4ccfSDean Luick 	write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_CTRL,
240d7cf4ccfSDean Luick 		  reg | DC_DC8051_CFG_RAM_ACCESS_CTRL_READ_ENA_SMASK);
241f48ad614SDennis Dalessandro 
242f48ad614SDennis Dalessandro 	/* wait until ACCESS_COMPLETED is set */
243f48ad614SDennis Dalessandro 	count = 0;
244f48ad614SDennis Dalessandro 	while ((read_csr(dd, DC_DC8051_CFG_RAM_ACCESS_STATUS)
245f48ad614SDennis Dalessandro 		    & DC_DC8051_CFG_RAM_ACCESS_STATUS_ACCESS_COMPLETED_SMASK)
246f48ad614SDennis Dalessandro 		    == 0) {
247f48ad614SDennis Dalessandro 		count++;
248f48ad614SDennis Dalessandro 		if (count > DC8051_ACCESS_TIMEOUT) {
249f48ad614SDennis Dalessandro 			dd_dev_err(dd, "timeout reading 8051 data\n");
250f48ad614SDennis Dalessandro 			return -ENXIO;
251f48ad614SDennis Dalessandro 		}
252f48ad614SDennis Dalessandro 		ndelay(10);
253f48ad614SDennis Dalessandro 	}
254f48ad614SDennis Dalessandro 
255f48ad614SDennis Dalessandro 	/* gather the data */
256f48ad614SDennis Dalessandro 	*result = read_csr(dd, DC_DC8051_CFG_RAM_ACCESS_RD_DATA);
257f48ad614SDennis Dalessandro 
258f48ad614SDennis Dalessandro 	return 0;
259f48ad614SDennis Dalessandro }
260f48ad614SDennis Dalessandro 
261f48ad614SDennis Dalessandro /*
262f48ad614SDennis Dalessandro  * Read 8051 data starting at addr, for len bytes.  Will read in 8-byte chunks.
263f48ad614SDennis Dalessandro  * Return 0 on success, -errno on error.
264f48ad614SDennis Dalessandro  */
read_8051_data(struct hfi1_devdata * dd,u32 addr,u32 len,u64 * result)265f48ad614SDennis Dalessandro int read_8051_data(struct hfi1_devdata *dd, u32 addr, u32 len, u64 *result)
266f48ad614SDennis Dalessandro {
267f48ad614SDennis Dalessandro 	unsigned long flags;
268f48ad614SDennis Dalessandro 	u32 done;
269f48ad614SDennis Dalessandro 	int ret = 0;
270f48ad614SDennis Dalessandro 
271f48ad614SDennis Dalessandro 	spin_lock_irqsave(&dd->dc8051_memlock, flags);
272f48ad614SDennis Dalessandro 
273f48ad614SDennis Dalessandro 	/* data read set-up, no auto-increment */
274f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_SETUP, 0);
275f48ad614SDennis Dalessandro 
276f48ad614SDennis Dalessandro 	for (done = 0; done < len; addr += 8, done += 8, result++) {
277f48ad614SDennis Dalessandro 		ret = __read_8051_data(dd, addr, result);
278f48ad614SDennis Dalessandro 		if (ret)
279f48ad614SDennis Dalessandro 			break;
280f48ad614SDennis Dalessandro 	}
281f48ad614SDennis Dalessandro 
282f48ad614SDennis Dalessandro 	/* turn off read enable */
283f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_CTRL, 0);
284f48ad614SDennis Dalessandro 
285f48ad614SDennis Dalessandro 	spin_unlock_irqrestore(&dd->dc8051_memlock, flags);
286f48ad614SDennis Dalessandro 
287f48ad614SDennis Dalessandro 	return ret;
288f48ad614SDennis Dalessandro }
289f48ad614SDennis Dalessandro 
290f48ad614SDennis Dalessandro /*
291f48ad614SDennis Dalessandro  * Write data or code to the 8051 code or data RAM.
292f48ad614SDennis Dalessandro  */
write_8051(struct hfi1_devdata * dd,int code,u32 start,const u8 * data,u32 len)293f48ad614SDennis Dalessandro static int write_8051(struct hfi1_devdata *dd, int code, u32 start,
294f48ad614SDennis Dalessandro 		      const u8 *data, u32 len)
295f48ad614SDennis Dalessandro {
296f48ad614SDennis Dalessandro 	u64 reg;
297f48ad614SDennis Dalessandro 	u32 offset;
298f48ad614SDennis Dalessandro 	int aligned, count;
299f48ad614SDennis Dalessandro 
300f48ad614SDennis Dalessandro 	/* check alignment */
301f48ad614SDennis Dalessandro 	aligned = ((unsigned long)data & 0x7) == 0;
302f48ad614SDennis Dalessandro 
303f48ad614SDennis Dalessandro 	/* write set-up */
304f48ad614SDennis Dalessandro 	reg = (code ? DC_DC8051_CFG_RAM_ACCESS_SETUP_RAM_SEL_SMASK : 0ull)
305f48ad614SDennis Dalessandro 		| DC_DC8051_CFG_RAM_ACCESS_SETUP_AUTO_INCR_ADDR_SMASK;
306f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_SETUP, reg);
307f48ad614SDennis Dalessandro 
308f48ad614SDennis Dalessandro 	reg = ((start & DC_DC8051_CFG_RAM_ACCESS_CTRL_ADDRESS_MASK)
309f48ad614SDennis Dalessandro 			<< DC_DC8051_CFG_RAM_ACCESS_CTRL_ADDRESS_SHIFT)
310f48ad614SDennis Dalessandro 		| DC_DC8051_CFG_RAM_ACCESS_CTRL_WRITE_ENA_SMASK;
311f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_CTRL, reg);
312f48ad614SDennis Dalessandro 
313f48ad614SDennis Dalessandro 	/* write */
314f48ad614SDennis Dalessandro 	for (offset = 0; offset < len; offset += 8) {
315f48ad614SDennis Dalessandro 		int bytes = len - offset;
316f48ad614SDennis Dalessandro 
317f48ad614SDennis Dalessandro 		if (bytes < 8) {
318f48ad614SDennis Dalessandro 			reg = 0;
319f48ad614SDennis Dalessandro 			memcpy(&reg, &data[offset], bytes);
320f48ad614SDennis Dalessandro 		} else if (aligned) {
321f48ad614SDennis Dalessandro 			reg = *(u64 *)&data[offset];
322f48ad614SDennis Dalessandro 		} else {
323f48ad614SDennis Dalessandro 			memcpy(&reg, &data[offset], 8);
324f48ad614SDennis Dalessandro 		}
325f48ad614SDennis Dalessandro 		write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_WR_DATA, reg);
326f48ad614SDennis Dalessandro 
327f48ad614SDennis Dalessandro 		/* wait until ACCESS_COMPLETED is set */
328f48ad614SDennis Dalessandro 		count = 0;
329f48ad614SDennis Dalessandro 		while ((read_csr(dd, DC_DC8051_CFG_RAM_ACCESS_STATUS)
330f48ad614SDennis Dalessandro 		    & DC_DC8051_CFG_RAM_ACCESS_STATUS_ACCESS_COMPLETED_SMASK)
331f48ad614SDennis Dalessandro 		    == 0) {
332f48ad614SDennis Dalessandro 			count++;
333f48ad614SDennis Dalessandro 			if (count > DC8051_ACCESS_TIMEOUT) {
334f48ad614SDennis Dalessandro 				dd_dev_err(dd, "timeout writing 8051 data\n");
335f48ad614SDennis Dalessandro 				return -ENXIO;
336f48ad614SDennis Dalessandro 			}
337f48ad614SDennis Dalessandro 			udelay(1);
338f48ad614SDennis Dalessandro 		}
339f48ad614SDennis Dalessandro 	}
340f48ad614SDennis Dalessandro 
341f48ad614SDennis Dalessandro 	/* turn off write access, auto increment (also sets to data access) */
342f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_CTRL, 0);
343f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RAM_ACCESS_SETUP, 0);
344f48ad614SDennis Dalessandro 
345f48ad614SDennis Dalessandro 	return 0;
346f48ad614SDennis Dalessandro }
347f48ad614SDennis Dalessandro 
348f48ad614SDennis Dalessandro /* return 0 if values match, non-zero and complain otherwise */
invalid_header(struct hfi1_devdata * dd,const char * what,u32 actual,u32 expected)349f48ad614SDennis Dalessandro static int invalid_header(struct hfi1_devdata *dd, const char *what,
350f48ad614SDennis Dalessandro 			  u32 actual, u32 expected)
351f48ad614SDennis Dalessandro {
352f48ad614SDennis Dalessandro 	if (actual == expected)
353f48ad614SDennis Dalessandro 		return 0;
354f48ad614SDennis Dalessandro 
355f48ad614SDennis Dalessandro 	dd_dev_err(dd,
356f48ad614SDennis Dalessandro 		   "invalid firmware header field %s: expected 0x%x, actual 0x%x\n",
357f48ad614SDennis Dalessandro 		   what, expected, actual);
358f48ad614SDennis Dalessandro 	return 1;
359f48ad614SDennis Dalessandro }
360f48ad614SDennis Dalessandro 
361f48ad614SDennis Dalessandro /*
362f48ad614SDennis Dalessandro  * Verify that the static fields in the CSS header match.
363f48ad614SDennis Dalessandro  */
verify_css_header(struct hfi1_devdata * dd,struct css_header * css)364f48ad614SDennis Dalessandro static int verify_css_header(struct hfi1_devdata *dd, struct css_header *css)
365f48ad614SDennis Dalessandro {
366f48ad614SDennis Dalessandro 	/* verify CSS header fields (most sizes are in DW, so add /4) */
367f48ad614SDennis Dalessandro 	if (invalid_header(dd, "module_type", css->module_type,
368f48ad614SDennis Dalessandro 			   CSS_MODULE_TYPE) ||
369f48ad614SDennis Dalessandro 	    invalid_header(dd, "header_len", css->header_len,
370f48ad614SDennis Dalessandro 			   (sizeof(struct firmware_file) / 4)) ||
371f48ad614SDennis Dalessandro 	    invalid_header(dd, "header_version", css->header_version,
372f48ad614SDennis Dalessandro 			   CSS_HEADER_VERSION) ||
373f48ad614SDennis Dalessandro 	    invalid_header(dd, "module_vendor", css->module_vendor,
374f48ad614SDennis Dalessandro 			   CSS_MODULE_VENDOR) ||
375f48ad614SDennis Dalessandro 	    invalid_header(dd, "key_size", css->key_size, KEY_SIZE / 4) ||
376f48ad614SDennis Dalessandro 	    invalid_header(dd, "modulus_size", css->modulus_size,
377f48ad614SDennis Dalessandro 			   KEY_SIZE / 4) ||
378f48ad614SDennis Dalessandro 	    invalid_header(dd, "exponent_size", css->exponent_size,
379f48ad614SDennis Dalessandro 			   EXPONENT_SIZE / 4)) {
380f48ad614SDennis Dalessandro 		return -EINVAL;
381f48ad614SDennis Dalessandro 	}
382f48ad614SDennis Dalessandro 	return 0;
383f48ad614SDennis Dalessandro }
384f48ad614SDennis Dalessandro 
385f48ad614SDennis Dalessandro /*
386f48ad614SDennis Dalessandro  * Make sure there are at least some bytes after the prefix.
387f48ad614SDennis Dalessandro  */
payload_check(struct hfi1_devdata * dd,const char * name,long file_size,long prefix_size)388f48ad614SDennis Dalessandro static int payload_check(struct hfi1_devdata *dd, const char *name,
389f48ad614SDennis Dalessandro 			 long file_size, long prefix_size)
390f48ad614SDennis Dalessandro {
391f48ad614SDennis Dalessandro 	/* make sure we have some payload */
392f48ad614SDennis Dalessandro 	if (prefix_size >= file_size) {
393f48ad614SDennis Dalessandro 		dd_dev_err(dd,
394f48ad614SDennis Dalessandro 			   "firmware \"%s\", size %ld, must be larger than %ld bytes\n",
395f48ad614SDennis Dalessandro 			   name, file_size, prefix_size);
396f48ad614SDennis Dalessandro 		return -EINVAL;
397f48ad614SDennis Dalessandro 	}
398f48ad614SDennis Dalessandro 
399f48ad614SDennis Dalessandro 	return 0;
400f48ad614SDennis Dalessandro }
401f48ad614SDennis Dalessandro 
402f48ad614SDennis Dalessandro /*
403f48ad614SDennis Dalessandro  * Request the firmware from the system.  Extract the pieces and fill in
404f48ad614SDennis Dalessandro  * fdet.  If successful, the caller will need to call dispose_one_firmware().
405f48ad614SDennis Dalessandro  * Returns 0 on success, -ERRNO on error.
406f48ad614SDennis Dalessandro  */
obtain_one_firmware(struct hfi1_devdata * dd,const char * name,struct firmware_details * fdet)407f48ad614SDennis Dalessandro static int obtain_one_firmware(struct hfi1_devdata *dd, const char *name,
408f48ad614SDennis Dalessandro 			       struct firmware_details *fdet)
409f48ad614SDennis Dalessandro {
410f48ad614SDennis Dalessandro 	struct css_header *css;
411f48ad614SDennis Dalessandro 	int ret;
412f48ad614SDennis Dalessandro 
413f48ad614SDennis Dalessandro 	memset(fdet, 0, sizeof(*fdet));
414f48ad614SDennis Dalessandro 
415f48ad614SDennis Dalessandro 	ret = request_firmware(&fdet->fw, name, &dd->pcidev->dev);
416f48ad614SDennis Dalessandro 	if (ret) {
417f48ad614SDennis Dalessandro 		dd_dev_warn(dd, "cannot find firmware \"%s\", err %d\n",
418f48ad614SDennis Dalessandro 			    name, ret);
419f48ad614SDennis Dalessandro 		return ret;
420f48ad614SDennis Dalessandro 	}
421f48ad614SDennis Dalessandro 
422f48ad614SDennis Dalessandro 	/* verify the firmware */
423f48ad614SDennis Dalessandro 	if (fdet->fw->size < sizeof(struct css_header)) {
424f48ad614SDennis Dalessandro 		dd_dev_err(dd, "firmware \"%s\" is too small\n", name);
425f48ad614SDennis Dalessandro 		ret = -EINVAL;
426f48ad614SDennis Dalessandro 		goto done;
427f48ad614SDennis Dalessandro 	}
428f48ad614SDennis Dalessandro 	css = (struct css_header *)fdet->fw->data;
429f48ad614SDennis Dalessandro 
430f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "Firmware %s details:", name);
431f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "file size: 0x%lx bytes", fdet->fw->size);
432f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "CSS structure:");
433f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  module_type    0x%x", css->module_type);
434f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  header_len     0x%03x (0x%03x bytes)",
435f48ad614SDennis Dalessandro 		  css->header_len, 4 * css->header_len);
436f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  header_version 0x%x", css->header_version);
437f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  module_id      0x%x", css->module_id);
438f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  module_vendor  0x%x", css->module_vendor);
439f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  date           0x%x", css->date);
440f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  size           0x%03x (0x%03x bytes)",
441f48ad614SDennis Dalessandro 		  css->size, 4 * css->size);
442f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  key_size       0x%03x (0x%03x bytes)",
443f48ad614SDennis Dalessandro 		  css->key_size, 4 * css->key_size);
444f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  modulus_size   0x%03x (0x%03x bytes)",
445f48ad614SDennis Dalessandro 		  css->modulus_size, 4 * css->modulus_size);
446f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "  exponent_size  0x%03x (0x%03x bytes)",
447f48ad614SDennis Dalessandro 		  css->exponent_size, 4 * css->exponent_size);
448f48ad614SDennis Dalessandro 	hfi1_cdbg(FIRMWARE, "firmware size: 0x%lx bytes",
449f48ad614SDennis Dalessandro 		  fdet->fw->size - sizeof(struct firmware_file));
450f48ad614SDennis Dalessandro 
451f48ad614SDennis Dalessandro 	/*
452f48ad614SDennis Dalessandro 	 * If the file does not have a valid CSS header, fail.
453f48ad614SDennis Dalessandro 	 * Otherwise, check the CSS size field for an expected size.
454f48ad614SDennis Dalessandro 	 * The augmented file has r2 and mu inserted after the header
455f48ad614SDennis Dalessandro 	 * was generated, so there will be a known difference between
456f48ad614SDennis Dalessandro 	 * the CSS header size and the actual file size.  Use this
457f48ad614SDennis Dalessandro 	 * difference to identify an augmented file.
458f48ad614SDennis Dalessandro 	 *
459f48ad614SDennis Dalessandro 	 * Note: css->size is in DWORDs, multiply by 4 to get bytes.
460f48ad614SDennis Dalessandro 	 */
461f48ad614SDennis Dalessandro 	ret = verify_css_header(dd, css);
462f48ad614SDennis Dalessandro 	if (ret) {
463f48ad614SDennis Dalessandro 		dd_dev_info(dd, "Invalid CSS header for \"%s\"\n", name);
464f48ad614SDennis Dalessandro 	} else if ((css->size * 4) == fdet->fw->size) {
465f48ad614SDennis Dalessandro 		/* non-augmented firmware file */
466f48ad614SDennis Dalessandro 		struct firmware_file *ff = (struct firmware_file *)
467f48ad614SDennis Dalessandro 							fdet->fw->data;
468f48ad614SDennis Dalessandro 
469f48ad614SDennis Dalessandro 		/* make sure there are bytes in the payload */
470f48ad614SDennis Dalessandro 		ret = payload_check(dd, name, fdet->fw->size,
471f48ad614SDennis Dalessandro 				    sizeof(struct firmware_file));
472f48ad614SDennis Dalessandro 		if (ret == 0) {
473f48ad614SDennis Dalessandro 			fdet->css_header = css;
474f48ad614SDennis Dalessandro 			fdet->modulus = ff->modulus;
475f48ad614SDennis Dalessandro 			fdet->exponent = ff->exponent;
476f48ad614SDennis Dalessandro 			fdet->signature = ff->signature;
477f48ad614SDennis Dalessandro 			fdet->r2 = fdet->dummy_header.r2; /* use dummy space */
478f48ad614SDennis Dalessandro 			fdet->mu = fdet->dummy_header.mu; /* use dummy space */
479f48ad614SDennis Dalessandro 			fdet->firmware_ptr = ff->firmware;
480f48ad614SDennis Dalessandro 			fdet->firmware_len = fdet->fw->size -
481f48ad614SDennis Dalessandro 						sizeof(struct firmware_file);
482f48ad614SDennis Dalessandro 			/*
483f48ad614SDennis Dalessandro 			 * Header does not include r2 and mu - generate here.
484f48ad614SDennis Dalessandro 			 * For now, fail.
485f48ad614SDennis Dalessandro 			 */
486f48ad614SDennis Dalessandro 			dd_dev_err(dd, "driver is unable to validate firmware without r2 and mu (not in firmware file)\n");
487f48ad614SDennis Dalessandro 			ret = -EINVAL;
488f48ad614SDennis Dalessandro 		}
489f48ad614SDennis Dalessandro 	} else if ((css->size * 4) + AUGMENT_SIZE == fdet->fw->size) {
490f48ad614SDennis Dalessandro 		/* augmented firmware file */
491f48ad614SDennis Dalessandro 		struct augmented_firmware_file *aff =
492f48ad614SDennis Dalessandro 			(struct augmented_firmware_file *)fdet->fw->data;
493f48ad614SDennis Dalessandro 
494f48ad614SDennis Dalessandro 		/* make sure there are bytes in the payload */
495f48ad614SDennis Dalessandro 		ret = payload_check(dd, name, fdet->fw->size,
496f48ad614SDennis Dalessandro 				    sizeof(struct augmented_firmware_file));
497f48ad614SDennis Dalessandro 		if (ret == 0) {
498f48ad614SDennis Dalessandro 			fdet->css_header = css;
499f48ad614SDennis Dalessandro 			fdet->modulus = aff->modulus;
500f48ad614SDennis Dalessandro 			fdet->exponent = aff->exponent;
501f48ad614SDennis Dalessandro 			fdet->signature = aff->signature;
502f48ad614SDennis Dalessandro 			fdet->r2 = aff->r2;
503f48ad614SDennis Dalessandro 			fdet->mu = aff->mu;
504f48ad614SDennis Dalessandro 			fdet->firmware_ptr = aff->firmware;
505f48ad614SDennis Dalessandro 			fdet->firmware_len = fdet->fw->size -
506f48ad614SDennis Dalessandro 					sizeof(struct augmented_firmware_file);
507f48ad614SDennis Dalessandro 		}
508f48ad614SDennis Dalessandro 	} else {
509f48ad614SDennis Dalessandro 		/* css->size check failed */
510f48ad614SDennis Dalessandro 		dd_dev_err(dd,
511f48ad614SDennis Dalessandro 			   "invalid firmware header field size: expected 0x%lx or 0x%lx, actual 0x%x\n",
512f48ad614SDennis Dalessandro 			   fdet->fw->size / 4,
513f48ad614SDennis Dalessandro 			   (fdet->fw->size - AUGMENT_SIZE) / 4,
514f48ad614SDennis Dalessandro 			   css->size);
515f48ad614SDennis Dalessandro 
516f48ad614SDennis Dalessandro 		ret = -EINVAL;
517f48ad614SDennis Dalessandro 	}
518f48ad614SDennis Dalessandro 
519f48ad614SDennis Dalessandro done:
520f48ad614SDennis Dalessandro 	/* if returning an error, clean up after ourselves */
521f48ad614SDennis Dalessandro 	if (ret)
522f48ad614SDennis Dalessandro 		dispose_one_firmware(fdet);
523f48ad614SDennis Dalessandro 	return ret;
524f48ad614SDennis Dalessandro }
525f48ad614SDennis Dalessandro 
dispose_one_firmware(struct firmware_details * fdet)526f48ad614SDennis Dalessandro static void dispose_one_firmware(struct firmware_details *fdet)
527f48ad614SDennis Dalessandro {
528f48ad614SDennis Dalessandro 	release_firmware(fdet->fw);
529f48ad614SDennis Dalessandro 	/* erase all previous information */
530f48ad614SDennis Dalessandro 	memset(fdet, 0, sizeof(*fdet));
531f48ad614SDennis Dalessandro }
532f48ad614SDennis Dalessandro 
533f48ad614SDennis Dalessandro /*
534f48ad614SDennis Dalessandro  * Obtain the 4 firmwares from the OS.  All must be obtained at once or not
535f48ad614SDennis Dalessandro  * at all.  If called with the firmware state in FW_TRY, use alternate names.
536f48ad614SDennis Dalessandro  * On exit, this routine will have set the firmware state to one of FW_TRY,
537f48ad614SDennis Dalessandro  * FW_FINAL, or FW_ERR.
538f48ad614SDennis Dalessandro  *
539f48ad614SDennis Dalessandro  * Must be holding fw_mutex.
540f48ad614SDennis Dalessandro  */
__obtain_firmware(struct hfi1_devdata * dd)541f48ad614SDennis Dalessandro static void __obtain_firmware(struct hfi1_devdata *dd)
542f48ad614SDennis Dalessandro {
543f48ad614SDennis Dalessandro 	int err = 0;
544f48ad614SDennis Dalessandro 
545f48ad614SDennis Dalessandro 	if (fw_state == FW_FINAL)	/* nothing more to obtain */
546f48ad614SDennis Dalessandro 		return;
547f48ad614SDennis Dalessandro 	if (fw_state == FW_ERR)		/* already in error */
548f48ad614SDennis Dalessandro 		return;
549f48ad614SDennis Dalessandro 
550f48ad614SDennis Dalessandro 	/* fw_state is FW_EMPTY or FW_TRY */
551f48ad614SDennis Dalessandro retry:
552f48ad614SDennis Dalessandro 	if (fw_state == FW_TRY) {
553f48ad614SDennis Dalessandro 		/*
554f48ad614SDennis Dalessandro 		 * We tried the original and it failed.  Move to the
555f48ad614SDennis Dalessandro 		 * alternate.
556f48ad614SDennis Dalessandro 		 */
557f48ad614SDennis Dalessandro 		dd_dev_warn(dd, "using alternate firmware names\n");
558f48ad614SDennis Dalessandro 		/*
559f48ad614SDennis Dalessandro 		 * Let others run.  Some systems, when missing firmware, does
560f48ad614SDennis Dalessandro 		 * something that holds for 30 seconds.  If we do that twice
561f48ad614SDennis Dalessandro 		 * in a row it triggers task blocked warning.
562f48ad614SDennis Dalessandro 		 */
563f48ad614SDennis Dalessandro 		cond_resched();
564f48ad614SDennis Dalessandro 		if (fw_8051_load)
565f48ad614SDennis Dalessandro 			dispose_one_firmware(&fw_8051);
566f48ad614SDennis Dalessandro 		if (fw_fabric_serdes_load)
567f48ad614SDennis Dalessandro 			dispose_one_firmware(&fw_fabric);
568f48ad614SDennis Dalessandro 		if (fw_sbus_load)
569f48ad614SDennis Dalessandro 			dispose_one_firmware(&fw_sbus);
570f48ad614SDennis Dalessandro 		if (fw_pcie_serdes_load)
571f48ad614SDennis Dalessandro 			dispose_one_firmware(&fw_pcie);
572f48ad614SDennis Dalessandro 		fw_8051_name = ALT_FW_8051_NAME_ASIC;
573f48ad614SDennis Dalessandro 		fw_fabric_serdes_name = ALT_FW_FABRIC_NAME;
574f48ad614SDennis Dalessandro 		fw_sbus_name = ALT_FW_SBUS_NAME;
575f48ad614SDennis Dalessandro 		fw_pcie_serdes_name = ALT_FW_PCIE_NAME;
576a156abb3SByczkowski, Jakub 
577a156abb3SByczkowski, Jakub 		/*
578a156abb3SByczkowski, Jakub 		 * Add a delay before obtaining and loading debug firmware.
579a156abb3SByczkowski, Jakub 		 * Authorization will fail if the delay between firmware
580a156abb3SByczkowski, Jakub 		 * authorization events is shorter than 50us. Add 100us to
581a156abb3SByczkowski, Jakub 		 * make a delay time safe.
582a156abb3SByczkowski, Jakub 		 */
583a156abb3SByczkowski, Jakub 		usleep_range(100, 120);
584f48ad614SDennis Dalessandro 	}
585f48ad614SDennis Dalessandro 
586f48ad614SDennis Dalessandro 	if (fw_sbus_load) {
587f48ad614SDennis Dalessandro 		err = obtain_one_firmware(dd, fw_sbus_name, &fw_sbus);
588f48ad614SDennis Dalessandro 		if (err)
589f48ad614SDennis Dalessandro 			goto done;
590f48ad614SDennis Dalessandro 	}
591f48ad614SDennis Dalessandro 
592f48ad614SDennis Dalessandro 	if (fw_pcie_serdes_load) {
593f48ad614SDennis Dalessandro 		err = obtain_one_firmware(dd, fw_pcie_serdes_name, &fw_pcie);
594f48ad614SDennis Dalessandro 		if (err)
595f48ad614SDennis Dalessandro 			goto done;
596f48ad614SDennis Dalessandro 	}
597f48ad614SDennis Dalessandro 
598f48ad614SDennis Dalessandro 	if (fw_fabric_serdes_load) {
599f48ad614SDennis Dalessandro 		err = obtain_one_firmware(dd, fw_fabric_serdes_name,
600f48ad614SDennis Dalessandro 					  &fw_fabric);
601f48ad614SDennis Dalessandro 		if (err)
602f48ad614SDennis Dalessandro 			goto done;
603f48ad614SDennis Dalessandro 	}
604f48ad614SDennis Dalessandro 
605f48ad614SDennis Dalessandro 	if (fw_8051_load) {
606f48ad614SDennis Dalessandro 		err = obtain_one_firmware(dd, fw_8051_name, &fw_8051);
607f48ad614SDennis Dalessandro 		if (err)
608f48ad614SDennis Dalessandro 			goto done;
609f48ad614SDennis Dalessandro 	}
610f48ad614SDennis Dalessandro 
611f48ad614SDennis Dalessandro done:
612f48ad614SDennis Dalessandro 	if (err) {
613f48ad614SDennis Dalessandro 		/* oops, had problems obtaining a firmware */
614f48ad614SDennis Dalessandro 		if (fw_state == FW_EMPTY && dd->icode == ICODE_RTL_SILICON) {
615f48ad614SDennis Dalessandro 			/* retry with alternate (RTL only) */
616f48ad614SDennis Dalessandro 			fw_state = FW_TRY;
617f48ad614SDennis Dalessandro 			goto retry;
618f48ad614SDennis Dalessandro 		}
619f48ad614SDennis Dalessandro 		dd_dev_err(dd, "unable to obtain working firmware\n");
620f48ad614SDennis Dalessandro 		fw_state = FW_ERR;
621f48ad614SDennis Dalessandro 		fw_err = -ENOENT;
622f48ad614SDennis Dalessandro 	} else {
623f48ad614SDennis Dalessandro 		/* success */
624f48ad614SDennis Dalessandro 		if (fw_state == FW_EMPTY &&
625f48ad614SDennis Dalessandro 		    dd->icode != ICODE_FUNCTIONAL_SIMULATOR)
626f48ad614SDennis Dalessandro 			fw_state = FW_TRY;	/* may retry later */
627f48ad614SDennis Dalessandro 		else
628f48ad614SDennis Dalessandro 			fw_state = FW_FINAL;	/* cannot try again */
629f48ad614SDennis Dalessandro 	}
630f48ad614SDennis Dalessandro }
631f48ad614SDennis Dalessandro 
632f48ad614SDennis Dalessandro /*
633f48ad614SDennis Dalessandro  * Called by all HFIs when loading their firmware - i.e. device probe time.
634f48ad614SDennis Dalessandro  * The first one will do the actual firmware load.  Use a mutex to resolve
635f48ad614SDennis Dalessandro  * any possible race condition.
636f48ad614SDennis Dalessandro  *
637f48ad614SDennis Dalessandro  * The call to this routine cannot be moved to driver load because the kernel
638f48ad614SDennis Dalessandro  * call request_firmware() requires a device which is only available after
639f48ad614SDennis Dalessandro  * the first device probe.
640f48ad614SDennis Dalessandro  */
obtain_firmware(struct hfi1_devdata * dd)641f48ad614SDennis Dalessandro static int obtain_firmware(struct hfi1_devdata *dd)
642f48ad614SDennis Dalessandro {
643f48ad614SDennis Dalessandro 	unsigned long timeout;
644f48ad614SDennis Dalessandro 
645f48ad614SDennis Dalessandro 	mutex_lock(&fw_mutex);
646f48ad614SDennis Dalessandro 
647f48ad614SDennis Dalessandro 	/* 40s delay due to long delay on missing firmware on some systems */
648f48ad614SDennis Dalessandro 	timeout = jiffies + msecs_to_jiffies(40000);
649f48ad614SDennis Dalessandro 	while (fw_state == FW_TRY) {
650f48ad614SDennis Dalessandro 		/*
651f48ad614SDennis Dalessandro 		 * Another device is trying the firmware.  Wait until it
652f48ad614SDennis Dalessandro 		 * decides what works (or not).
653f48ad614SDennis Dalessandro 		 */
654f48ad614SDennis Dalessandro 		if (time_after(jiffies, timeout)) {
655f48ad614SDennis Dalessandro 			/* waited too long */
656f48ad614SDennis Dalessandro 			dd_dev_err(dd, "Timeout waiting for firmware try");
657f48ad614SDennis Dalessandro 			fw_state = FW_ERR;
658f48ad614SDennis Dalessandro 			fw_err = -ETIMEDOUT;
659f48ad614SDennis Dalessandro 			break;
660f48ad614SDennis Dalessandro 		}
661f48ad614SDennis Dalessandro 		mutex_unlock(&fw_mutex);
662f48ad614SDennis Dalessandro 		msleep(20);	/* arbitrary delay */
663f48ad614SDennis Dalessandro 		mutex_lock(&fw_mutex);
664f48ad614SDennis Dalessandro 	}
665f48ad614SDennis Dalessandro 	/* not in FW_TRY state */
666f48ad614SDennis Dalessandro 
667f48ad614SDennis Dalessandro 	/* set fw_state to FW_TRY, FW_FINAL, or FW_ERR, and fw_err */
66876ae6222SJakub Byczkowski 	if (fw_state == FW_EMPTY)
669f48ad614SDennis Dalessandro 		__obtain_firmware(dd);
670f48ad614SDennis Dalessandro 
671f48ad614SDennis Dalessandro 	mutex_unlock(&fw_mutex);
672f48ad614SDennis Dalessandro 	return fw_err;
673f48ad614SDennis Dalessandro }
674f48ad614SDennis Dalessandro 
675f48ad614SDennis Dalessandro /*
676f48ad614SDennis Dalessandro  * Called when the driver unloads.  The timing is asymmetric with its
677f48ad614SDennis Dalessandro  * counterpart, obtain_firmware().  If called at device remove time,
678f48ad614SDennis Dalessandro  * then it is conceivable that another device could probe while the
679f48ad614SDennis Dalessandro  * firmware is being disposed.  The mutexes can be moved to do that
680f48ad614SDennis Dalessandro  * safely, but then the firmware would be requested from the OS multiple
681f48ad614SDennis Dalessandro  * times.
682f48ad614SDennis Dalessandro  *
683f48ad614SDennis Dalessandro  * No mutex is needed as the driver is unloading and there cannot be any
684f48ad614SDennis Dalessandro  * other callers.
685f48ad614SDennis Dalessandro  */
dispose_firmware(void)686f48ad614SDennis Dalessandro void dispose_firmware(void)
687f48ad614SDennis Dalessandro {
688f48ad614SDennis Dalessandro 	dispose_one_firmware(&fw_8051);
689f48ad614SDennis Dalessandro 	dispose_one_firmware(&fw_fabric);
690f48ad614SDennis Dalessandro 	dispose_one_firmware(&fw_pcie);
691f48ad614SDennis Dalessandro 	dispose_one_firmware(&fw_sbus);
692f48ad614SDennis Dalessandro 
693f48ad614SDennis Dalessandro 	/* retain the error state, otherwise revert to empty */
694f48ad614SDennis Dalessandro 	if (fw_state != FW_ERR)
695f48ad614SDennis Dalessandro 		fw_state = FW_EMPTY;
696f48ad614SDennis Dalessandro }
697f48ad614SDennis Dalessandro 
698f48ad614SDennis Dalessandro /*
699f48ad614SDennis Dalessandro  * Called with the result of a firmware download.
700f48ad614SDennis Dalessandro  *
701f48ad614SDennis Dalessandro  * Return 1 to retry loading the firmware, 0 to stop.
702f48ad614SDennis Dalessandro  */
retry_firmware(struct hfi1_devdata * dd,int load_result)703f48ad614SDennis Dalessandro static int retry_firmware(struct hfi1_devdata *dd, int load_result)
704f48ad614SDennis Dalessandro {
705f48ad614SDennis Dalessandro 	int retry;
706f48ad614SDennis Dalessandro 
707f48ad614SDennis Dalessandro 	mutex_lock(&fw_mutex);
708f48ad614SDennis Dalessandro 
709f48ad614SDennis Dalessandro 	if (load_result == 0) {
710f48ad614SDennis Dalessandro 		/*
711f48ad614SDennis Dalessandro 		 * The load succeeded, so expect all others to do the same.
712f48ad614SDennis Dalessandro 		 * Do not retry again.
713f48ad614SDennis Dalessandro 		 */
714f48ad614SDennis Dalessandro 		if (fw_state == FW_TRY)
715f48ad614SDennis Dalessandro 			fw_state = FW_FINAL;
716f48ad614SDennis Dalessandro 		retry = 0;	/* do NOT retry */
717f48ad614SDennis Dalessandro 	} else if (fw_state == FW_TRY) {
718f48ad614SDennis Dalessandro 		/* load failed, obtain alternate firmware */
719f48ad614SDennis Dalessandro 		__obtain_firmware(dd);
720f48ad614SDennis Dalessandro 		retry = (fw_state == FW_FINAL);
721f48ad614SDennis Dalessandro 	} else {
722f48ad614SDennis Dalessandro 		/* else in FW_FINAL or FW_ERR, no retry in either case */
723f48ad614SDennis Dalessandro 		retry = 0;
724f48ad614SDennis Dalessandro 	}
725f48ad614SDennis Dalessandro 
726f48ad614SDennis Dalessandro 	mutex_unlock(&fw_mutex);
727f48ad614SDennis Dalessandro 	return retry;
728f48ad614SDennis Dalessandro }
729f48ad614SDennis Dalessandro 
730f48ad614SDennis Dalessandro /*
731f48ad614SDennis Dalessandro  * Write a block of data to a given array CSR.  All calls will be in
732f48ad614SDennis Dalessandro  * multiples of 8 bytes.
733f48ad614SDennis Dalessandro  */
write_rsa_data(struct hfi1_devdata * dd,int what,const u8 * data,int nbytes)734f48ad614SDennis Dalessandro static void write_rsa_data(struct hfi1_devdata *dd, int what,
735f48ad614SDennis Dalessandro 			   const u8 *data, int nbytes)
736f48ad614SDennis Dalessandro {
737f48ad614SDennis Dalessandro 	int qw_size = nbytes / 8;
738f48ad614SDennis Dalessandro 	int i;
739f48ad614SDennis Dalessandro 
740f48ad614SDennis Dalessandro 	if (((unsigned long)data & 0x7) == 0) {
741f48ad614SDennis Dalessandro 		/* aligned */
742f48ad614SDennis Dalessandro 		u64 *ptr = (u64 *)data;
743f48ad614SDennis Dalessandro 
744f48ad614SDennis Dalessandro 		for (i = 0; i < qw_size; i++, ptr++)
745f48ad614SDennis Dalessandro 			write_csr(dd, what + (8 * i), *ptr);
746f48ad614SDennis Dalessandro 	} else {
747f48ad614SDennis Dalessandro 		/* not aligned */
748f48ad614SDennis Dalessandro 		for (i = 0; i < qw_size; i++, data += 8) {
749f48ad614SDennis Dalessandro 			u64 value;
750f48ad614SDennis Dalessandro 
751f48ad614SDennis Dalessandro 			memcpy(&value, data, 8);
752f48ad614SDennis Dalessandro 			write_csr(dd, what + (8 * i), value);
753f48ad614SDennis Dalessandro 		}
754f48ad614SDennis Dalessandro 	}
755f48ad614SDennis Dalessandro }
756f48ad614SDennis Dalessandro 
757f48ad614SDennis Dalessandro /*
758f48ad614SDennis Dalessandro  * Write a block of data to a given CSR as a stream of writes.  All calls will
759f48ad614SDennis Dalessandro  * be in multiples of 8 bytes.
760f48ad614SDennis Dalessandro  */
write_streamed_rsa_data(struct hfi1_devdata * dd,int what,const u8 * data,int nbytes)761f48ad614SDennis Dalessandro static void write_streamed_rsa_data(struct hfi1_devdata *dd, int what,
762f48ad614SDennis Dalessandro 				    const u8 *data, int nbytes)
763f48ad614SDennis Dalessandro {
764f48ad614SDennis Dalessandro 	u64 *ptr = (u64 *)data;
765f48ad614SDennis Dalessandro 	int qw_size = nbytes / 8;
766f48ad614SDennis Dalessandro 
767f48ad614SDennis Dalessandro 	for (; qw_size > 0; qw_size--, ptr++)
768f48ad614SDennis Dalessandro 		write_csr(dd, what, *ptr);
769f48ad614SDennis Dalessandro }
770f48ad614SDennis Dalessandro 
771f48ad614SDennis Dalessandro /*
772f48ad614SDennis Dalessandro  * Download the signature and start the RSA mechanism.  Wait for
773f48ad614SDennis Dalessandro  * RSA_ENGINE_TIMEOUT before giving up.
774f48ad614SDennis Dalessandro  */
run_rsa(struct hfi1_devdata * dd,const char * who,const u8 * signature)775f48ad614SDennis Dalessandro static int run_rsa(struct hfi1_devdata *dd, const char *who,
776f48ad614SDennis Dalessandro 		   const u8 *signature)
777f48ad614SDennis Dalessandro {
778f48ad614SDennis Dalessandro 	unsigned long timeout;
779f48ad614SDennis Dalessandro 	u64 reg;
780f48ad614SDennis Dalessandro 	u32 status;
781f48ad614SDennis Dalessandro 	int ret = 0;
782f48ad614SDennis Dalessandro 
783f48ad614SDennis Dalessandro 	/* write the signature */
784f48ad614SDennis Dalessandro 	write_rsa_data(dd, MISC_CFG_RSA_SIGNATURE, signature, KEY_SIZE);
785f48ad614SDennis Dalessandro 
786f48ad614SDennis Dalessandro 	/* initialize RSA */
787f48ad614SDennis Dalessandro 	write_csr(dd, MISC_CFG_RSA_CMD, RSA_CMD_INIT);
788f48ad614SDennis Dalessandro 
789f48ad614SDennis Dalessandro 	/*
790f48ad614SDennis Dalessandro 	 * Make sure the engine is idle and insert a delay between the two
791f48ad614SDennis Dalessandro 	 * writes to MISC_CFG_RSA_CMD.
792f48ad614SDennis Dalessandro 	 */
793f48ad614SDennis Dalessandro 	status = (read_csr(dd, MISC_CFG_FW_CTRL)
794f48ad614SDennis Dalessandro 			   & MISC_CFG_FW_CTRL_RSA_STATUS_SMASK)
795f48ad614SDennis Dalessandro 			     >> MISC_CFG_FW_CTRL_RSA_STATUS_SHIFT;
796f48ad614SDennis Dalessandro 	if (status != RSA_STATUS_IDLE) {
797f48ad614SDennis Dalessandro 		dd_dev_err(dd, "%s security engine not idle - giving up\n",
798f48ad614SDennis Dalessandro 			   who);
799f48ad614SDennis Dalessandro 		return -EBUSY;
800f48ad614SDennis Dalessandro 	}
801f48ad614SDennis Dalessandro 
802f48ad614SDennis Dalessandro 	/* start RSA */
803f48ad614SDennis Dalessandro 	write_csr(dd, MISC_CFG_RSA_CMD, RSA_CMD_START);
804f48ad614SDennis Dalessandro 
805f48ad614SDennis Dalessandro 	/*
806f48ad614SDennis Dalessandro 	 * Look for the result.
807f48ad614SDennis Dalessandro 	 *
808f48ad614SDennis Dalessandro 	 * The RSA engine is hooked up to two MISC errors.  The driver
809f48ad614SDennis Dalessandro 	 * masks these errors as they do not respond to the standard
810f48ad614SDennis Dalessandro 	 * error "clear down" mechanism.  Look for these errors here and
811f48ad614SDennis Dalessandro 	 * clear them when possible.  This routine will exit with the
812f48ad614SDennis Dalessandro 	 * errors of the current run still set.
813f48ad614SDennis Dalessandro 	 *
814f48ad614SDennis Dalessandro 	 * MISC_FW_AUTH_FAILED_ERR
815f48ad614SDennis Dalessandro 	 *	Firmware authorization failed.  This can be cleared by
816f48ad614SDennis Dalessandro 	 *	re-initializing the RSA engine, then clearing the status bit.
817f48ad614SDennis Dalessandro 	 *	Do not re-init the RSA angine immediately after a successful
818f48ad614SDennis Dalessandro 	 *	run - this will reset the current authorization.
819f48ad614SDennis Dalessandro 	 *
820f48ad614SDennis Dalessandro 	 * MISC_KEY_MISMATCH_ERR
821f48ad614SDennis Dalessandro 	 *	Key does not match.  The only way to clear this is to load
822f48ad614SDennis Dalessandro 	 *	a matching key then clear the status bit.  If this error
823f48ad614SDennis Dalessandro 	 *	is raised, it will persist outside of this routine until a
824f48ad614SDennis Dalessandro 	 *	matching key is loaded.
825f48ad614SDennis Dalessandro 	 */
826f48ad614SDennis Dalessandro 	timeout = msecs_to_jiffies(RSA_ENGINE_TIMEOUT) + jiffies;
827f48ad614SDennis Dalessandro 	while (1) {
828f48ad614SDennis Dalessandro 		status = (read_csr(dd, MISC_CFG_FW_CTRL)
829f48ad614SDennis Dalessandro 			   & MISC_CFG_FW_CTRL_RSA_STATUS_SMASK)
830f48ad614SDennis Dalessandro 			     >> MISC_CFG_FW_CTRL_RSA_STATUS_SHIFT;
831f48ad614SDennis Dalessandro 
832f48ad614SDennis Dalessandro 		if (status == RSA_STATUS_IDLE) {
833f48ad614SDennis Dalessandro 			/* should not happen */
834f48ad614SDennis Dalessandro 			dd_dev_err(dd, "%s firmware security bad idle state\n",
835f48ad614SDennis Dalessandro 				   who);
836f48ad614SDennis Dalessandro 			ret = -EINVAL;
837f48ad614SDennis Dalessandro 			break;
838f48ad614SDennis Dalessandro 		} else if (status == RSA_STATUS_DONE) {
839f48ad614SDennis Dalessandro 			/* finished successfully */
840f48ad614SDennis Dalessandro 			break;
841f48ad614SDennis Dalessandro 		} else if (status == RSA_STATUS_FAILED) {
842f48ad614SDennis Dalessandro 			/* finished unsuccessfully */
843f48ad614SDennis Dalessandro 			ret = -EINVAL;
844f48ad614SDennis Dalessandro 			break;
845f48ad614SDennis Dalessandro 		}
846f48ad614SDennis Dalessandro 		/* else still active */
847f48ad614SDennis Dalessandro 
848f48ad614SDennis Dalessandro 		if (time_after(jiffies, timeout)) {
849f48ad614SDennis Dalessandro 			/*
850f48ad614SDennis Dalessandro 			 * Timed out while active.  We can't reset the engine
851f48ad614SDennis Dalessandro 			 * if it is stuck active, but run through the
852f48ad614SDennis Dalessandro 			 * error code to see what error bits are set.
853f48ad614SDennis Dalessandro 			 */
854f48ad614SDennis Dalessandro 			dd_dev_err(dd, "%s firmware security time out\n", who);
855f48ad614SDennis Dalessandro 			ret = -ETIMEDOUT;
856f48ad614SDennis Dalessandro 			break;
857f48ad614SDennis Dalessandro 		}
858f48ad614SDennis Dalessandro 
859f48ad614SDennis Dalessandro 		msleep(20);
860f48ad614SDennis Dalessandro 	}
861f48ad614SDennis Dalessandro 
862f48ad614SDennis Dalessandro 	/*
863f48ad614SDennis Dalessandro 	 * Arrive here on success or failure.  Clear all RSA engine
864f48ad614SDennis Dalessandro 	 * errors.  All current errors will stick - the RSA logic is keeping
865f48ad614SDennis Dalessandro 	 * error high.  All previous errors will clear - the RSA logic
866f48ad614SDennis Dalessandro 	 * is not keeping the error high.
867f48ad614SDennis Dalessandro 	 */
868f48ad614SDennis Dalessandro 	write_csr(dd, MISC_ERR_CLEAR,
869f48ad614SDennis Dalessandro 		  MISC_ERR_STATUS_MISC_FW_AUTH_FAILED_ERR_SMASK |
870f48ad614SDennis Dalessandro 		  MISC_ERR_STATUS_MISC_KEY_MISMATCH_ERR_SMASK);
871f48ad614SDennis Dalessandro 	/*
872f48ad614SDennis Dalessandro 	 * All that is left are the current errors.  Print warnings on
873f48ad614SDennis Dalessandro 	 * authorization failure details, if any.  Firmware authorization
874f48ad614SDennis Dalessandro 	 * can be retried, so these are only warnings.
875f48ad614SDennis Dalessandro 	 */
876f48ad614SDennis Dalessandro 	reg = read_csr(dd, MISC_ERR_STATUS);
877f48ad614SDennis Dalessandro 	if (ret) {
878f48ad614SDennis Dalessandro 		if (reg & MISC_ERR_STATUS_MISC_FW_AUTH_FAILED_ERR_SMASK)
879f48ad614SDennis Dalessandro 			dd_dev_warn(dd, "%s firmware authorization failed\n",
880f48ad614SDennis Dalessandro 				    who);
881f48ad614SDennis Dalessandro 		if (reg & MISC_ERR_STATUS_MISC_KEY_MISMATCH_ERR_SMASK)
882f48ad614SDennis Dalessandro 			dd_dev_warn(dd, "%s firmware key mismatch\n", who);
883f48ad614SDennis Dalessandro 	}
884f48ad614SDennis Dalessandro 
885f48ad614SDennis Dalessandro 	return ret;
886f48ad614SDennis Dalessandro }
887f48ad614SDennis Dalessandro 
load_security_variables(struct hfi1_devdata * dd,struct firmware_details * fdet)888f48ad614SDennis Dalessandro static void load_security_variables(struct hfi1_devdata *dd,
889f48ad614SDennis Dalessandro 				    struct firmware_details *fdet)
890f48ad614SDennis Dalessandro {
891f48ad614SDennis Dalessandro 	/* Security variables a.  Write the modulus */
892f48ad614SDennis Dalessandro 	write_rsa_data(dd, MISC_CFG_RSA_MODULUS, fdet->modulus, KEY_SIZE);
893f48ad614SDennis Dalessandro 	/* Security variables b.  Write the r2 */
894f48ad614SDennis Dalessandro 	write_rsa_data(dd, MISC_CFG_RSA_R2, fdet->r2, KEY_SIZE);
895f48ad614SDennis Dalessandro 	/* Security variables c.  Write the mu */
896f48ad614SDennis Dalessandro 	write_rsa_data(dd, MISC_CFG_RSA_MU, fdet->mu, MU_SIZE);
897f48ad614SDennis Dalessandro 	/* Security variables d.  Write the header */
898f48ad614SDennis Dalessandro 	write_streamed_rsa_data(dd, MISC_CFG_SHA_PRELOAD,
899f48ad614SDennis Dalessandro 				(u8 *)fdet->css_header,
900f48ad614SDennis Dalessandro 				sizeof(struct css_header));
901f48ad614SDennis Dalessandro }
902f48ad614SDennis Dalessandro 
903f48ad614SDennis Dalessandro /* return the 8051 firmware state */
get_firmware_state(struct hfi1_devdata * dd)904f48ad614SDennis Dalessandro static inline u32 get_firmware_state(struct hfi1_devdata *dd)
905f48ad614SDennis Dalessandro {
906f48ad614SDennis Dalessandro 	u64 reg = read_csr(dd, DC_DC8051_STS_CUR_STATE);
907f48ad614SDennis Dalessandro 
908f48ad614SDennis Dalessandro 	return (reg >> DC_DC8051_STS_CUR_STATE_FIRMWARE_SHIFT)
909f48ad614SDennis Dalessandro 				& DC_DC8051_STS_CUR_STATE_FIRMWARE_MASK;
910f48ad614SDennis Dalessandro }
911f48ad614SDennis Dalessandro 
912f48ad614SDennis Dalessandro /*
913f48ad614SDennis Dalessandro  * Wait until the firmware is up and ready to take host requests.
914f48ad614SDennis Dalessandro  * Return 0 on success, -ETIMEDOUT on timeout.
915f48ad614SDennis Dalessandro  */
wait_fm_ready(struct hfi1_devdata * dd,u32 mstimeout)916f48ad614SDennis Dalessandro int wait_fm_ready(struct hfi1_devdata *dd, u32 mstimeout)
917f48ad614SDennis Dalessandro {
918f48ad614SDennis Dalessandro 	unsigned long timeout;
919f48ad614SDennis Dalessandro 
920f48ad614SDennis Dalessandro 	/* in the simulator, the fake 8051 is always ready */
921f48ad614SDennis Dalessandro 	if (dd->icode == ICODE_FUNCTIONAL_SIMULATOR)
922f48ad614SDennis Dalessandro 		return 0;
923f48ad614SDennis Dalessandro 
924f48ad614SDennis Dalessandro 	timeout = msecs_to_jiffies(mstimeout) + jiffies;
925f48ad614SDennis Dalessandro 	while (1) {
926f48ad614SDennis Dalessandro 		if (get_firmware_state(dd) == 0xa0)	/* ready */
927f48ad614SDennis Dalessandro 			return 0;
928f48ad614SDennis Dalessandro 		if (time_after(jiffies, timeout))	/* timed out */
929f48ad614SDennis Dalessandro 			return -ETIMEDOUT;
930f48ad614SDennis Dalessandro 		usleep_range(1950, 2050); /* sleep 2ms-ish */
931f48ad614SDennis Dalessandro 	}
932f48ad614SDennis Dalessandro }
933f48ad614SDennis Dalessandro 
934f48ad614SDennis Dalessandro /*
935f48ad614SDennis Dalessandro  * Load the 8051 firmware.
936f48ad614SDennis Dalessandro  */
load_8051_firmware(struct hfi1_devdata * dd,struct firmware_details * fdet)937f48ad614SDennis Dalessandro static int load_8051_firmware(struct hfi1_devdata *dd,
938f48ad614SDennis Dalessandro 			      struct firmware_details *fdet)
939f48ad614SDennis Dalessandro {
940f48ad614SDennis Dalessandro 	u64 reg;
941f48ad614SDennis Dalessandro 	int ret;
9425e6e9424SMichael J. Ruhl 	u8 ver_major;
9435e6e9424SMichael J. Ruhl 	u8 ver_minor;
9445e6e9424SMichael J. Ruhl 	u8 ver_patch;
945f48ad614SDennis Dalessandro 
946f48ad614SDennis Dalessandro 	/*
947f48ad614SDennis Dalessandro 	 * DC Reset sequence
948f48ad614SDennis Dalessandro 	 * Load DC 8051 firmware
949f48ad614SDennis Dalessandro 	 */
950f48ad614SDennis Dalessandro 	/*
951f48ad614SDennis Dalessandro 	 * DC reset step 1: Reset DC8051
952f48ad614SDennis Dalessandro 	 */
953f48ad614SDennis Dalessandro 	reg = DC_DC8051_CFG_RST_M8051W_SMASK
954f48ad614SDennis Dalessandro 		| DC_DC8051_CFG_RST_CRAM_SMASK
955f48ad614SDennis Dalessandro 		| DC_DC8051_CFG_RST_DRAM_SMASK
956f48ad614SDennis Dalessandro 		| DC_DC8051_CFG_RST_IRAM_SMASK
957f48ad614SDennis Dalessandro 		| DC_DC8051_CFG_RST_SFR_SMASK;
958f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RST, reg);
959f48ad614SDennis Dalessandro 
960f48ad614SDennis Dalessandro 	/*
961f48ad614SDennis Dalessandro 	 * DC reset step 2 (optional): Load 8051 data memory with link
962f48ad614SDennis Dalessandro 	 * configuration
963f48ad614SDennis Dalessandro 	 */
964f48ad614SDennis Dalessandro 
965f48ad614SDennis Dalessandro 	/*
966f48ad614SDennis Dalessandro 	 * DC reset step 3: Load DC8051 firmware
967f48ad614SDennis Dalessandro 	 */
968f48ad614SDennis Dalessandro 	/* release all but the core reset */
969f48ad614SDennis Dalessandro 	reg = DC_DC8051_CFG_RST_M8051W_SMASK;
970f48ad614SDennis Dalessandro 	write_csr(dd, DC_DC8051_CFG_RST, reg);
971f48ad614SDennis Dalessandro 
972f48ad614SDennis Dalessandro 	/* Firmware load step 1 */
973f48ad614SDennis Dalessandro 	load_security_variables(dd, fdet);
974f48ad614SDennis Dalessandro 
975f48ad614SDennis Dalessandro 	/*
976f48ad614SDennis Dalessandro 	 * Firmware load step 2.  Clear MISC_CFG_FW_CTRL.FW_8051_LOADED
977f48ad614SDennis Dalessandro 	 */
978f48ad614SDennis Dalessandro 	write_csr(dd, MISC_CFG_FW_CTRL, 0);
979f48ad614SDennis Dalessandro 
980f48ad614SDennis Dalessandro 	/* Firmware load steps 3-5 */
981f48ad614SDennis Dalessandro 	ret = write_8051(dd, 1/*code*/, 0, fdet->firmware_ptr,
982f48ad614SDennis Dalessandro 			 fdet->firmware_len);
983f48ad614SDennis Dalessandro 	if (ret)
984f48ad614SDennis Dalessandro 		return ret;
985f48ad614SDennis Dalessandro 
986f48ad614SDennis Dalessandro 	/*
987f48ad614SDennis Dalessandro 	 * DC reset step 4. Host starts the DC8051 firmware
988f48ad614SDennis Dalessandro 	 */
989f48ad614SDennis Dalessandro 	/*
990f48ad614SDennis Dalessandro 	 * Firmware load step 6.  Set MISC_CFG_FW_CTRL.FW_8051_LOADED
991f48ad614SDennis Dalessandro 	 */
992f48ad614SDennis Dalessandro 	write_csr(dd, MISC_CFG_FW_CTRL, MISC_CFG_FW_CTRL_FW_8051_LOADED_SMASK);
993f48ad614SDennis Dalessandro 
994f48ad614SDennis Dalessandro 	/* Firmware load steps 7-10 */
995f48ad614SDennis Dalessandro 	ret = run_rsa(dd, "8051", fdet->signature);
996f48ad614SDennis Dalessandro 	if (ret)
997f48ad614SDennis Dalessandro 		return ret;
998f48ad614SDennis Dalessandro 
9999996b049SSebastian Sanchez 	/* clear all reset bits, releasing the 8051 */
10009996b049SSebastian Sanchez 	write_csr(dd, DC_DC8051_CFG_RST, 0ull);
10019996b049SSebastian Sanchez 
1002f48ad614SDennis Dalessandro 	/*
1003f48ad614SDennis Dalessandro 	 * DC reset step 5. Wait for firmware to be ready to accept host
1004f48ad614SDennis Dalessandro 	 * requests.
1005f48ad614SDennis Dalessandro 	 */
10069996b049SSebastian Sanchez 	ret = wait_fm_ready(dd, TIMEOUT_8051_START);
10079996b049SSebastian Sanchez 	if (ret) { /* timed out */
10089996b049SSebastian Sanchez 		dd_dev_err(dd, "8051 start timeout, current state 0x%x\n",
10099996b049SSebastian Sanchez 			   get_firmware_state(dd));
10109996b049SSebastian Sanchez 		return -ETIMEDOUT;
10119996b049SSebastian Sanchez 	}
1012f48ad614SDennis Dalessandro 
10135e6e9424SMichael J. Ruhl 	read_misc_status(dd, &ver_major, &ver_minor, &ver_patch);
10145e6e9424SMichael J. Ruhl 	dd_dev_info(dd, "8051 firmware version %d.%d.%d\n",
10155e6e9424SMichael J. Ruhl 		    (int)ver_major, (int)ver_minor, (int)ver_patch);
10165e6e9424SMichael J. Ruhl 	dd->dc8051_ver = dc8051_ver(ver_major, ver_minor, ver_patch);
10179996b049SSebastian Sanchez 	ret = write_host_interface_version(dd, HOST_INTERFACE_VERSION);
10189996b049SSebastian Sanchez 	if (ret != HCMD_SUCCESS) {
10199996b049SSebastian Sanchez 		dd_dev_err(dd,
10209996b049SSebastian Sanchez 			   "Failed to set host interface version, return 0x%x\n",
10219996b049SSebastian Sanchez 			   ret);
10229996b049SSebastian Sanchez 		return -EIO;
10239996b049SSebastian Sanchez 	}
1024f48ad614SDennis Dalessandro 
1025f48ad614SDennis Dalessandro 	return 0;
1026f48ad614SDennis Dalessandro }
1027f48ad614SDennis Dalessandro 
1028f48ad614SDennis Dalessandro /*
1029f48ad614SDennis Dalessandro  * Write the SBus request register
1030f48ad614SDennis Dalessandro  *
1031f48ad614SDennis Dalessandro  * No need for masking - the arguments are sized exactly.
1032f48ad614SDennis Dalessandro  */
sbus_request(struct hfi1_devdata * dd,u8 receiver_addr,u8 data_addr,u8 command,u32 data_in)1033f48ad614SDennis Dalessandro void sbus_request(struct hfi1_devdata *dd,
1034f48ad614SDennis Dalessandro 		  u8 receiver_addr, u8 data_addr, u8 command, u32 data_in)
1035f48ad614SDennis Dalessandro {
1036f48ad614SDennis Dalessandro 	write_csr(dd, ASIC_CFG_SBUS_REQUEST,
1037f48ad614SDennis Dalessandro 		  ((u64)data_in << ASIC_CFG_SBUS_REQUEST_DATA_IN_SHIFT) |
1038f48ad614SDennis Dalessandro 		  ((u64)command << ASIC_CFG_SBUS_REQUEST_COMMAND_SHIFT) |
1039f48ad614SDennis Dalessandro 		  ((u64)data_addr << ASIC_CFG_SBUS_REQUEST_DATA_ADDR_SHIFT) |
1040f48ad614SDennis Dalessandro 		  ((u64)receiver_addr <<
1041f48ad614SDennis Dalessandro 		   ASIC_CFG_SBUS_REQUEST_RECEIVER_ADDR_SHIFT));
1042f48ad614SDennis Dalessandro }
1043f48ad614SDennis Dalessandro 
1044f48ad614SDennis Dalessandro /*
1045b3bf270bSDean Luick  * Read a value from the SBus.
1046b3bf270bSDean Luick  *
1047b3bf270bSDean Luick  * Requires the caller to be in fast mode
1048b3bf270bSDean Luick  */
sbus_read(struct hfi1_devdata * dd,u8 receiver_addr,u8 data_addr,u32 data_in)1049b3bf270bSDean Luick static u32 sbus_read(struct hfi1_devdata *dd, u8 receiver_addr, u8 data_addr,
1050b3bf270bSDean Luick 		     u32 data_in)
1051b3bf270bSDean Luick {
1052b3bf270bSDean Luick 	u64 reg;
1053b3bf270bSDean Luick 	int retries;
1054b3bf270bSDean Luick 	int success = 0;
1055b3bf270bSDean Luick 	u32 result = 0;
1056b3bf270bSDean Luick 	u32 result_code = 0;
1057b3bf270bSDean Luick 
1058b3bf270bSDean Luick 	sbus_request(dd, receiver_addr, data_addr, READ_SBUS_RECEIVER, data_in);
1059b3bf270bSDean Luick 
1060b3bf270bSDean Luick 	for (retries = 0; retries < 100; retries++) {
1061b3bf270bSDean Luick 		usleep_range(1000, 1200); /* arbitrary */
1062b3bf270bSDean Luick 		reg = read_csr(dd, ASIC_STS_SBUS_RESULT);
1063b3bf270bSDean Luick 		result_code = (reg >> ASIC_STS_SBUS_RESULT_RESULT_CODE_SHIFT)
1064b3bf270bSDean Luick 				& ASIC_STS_SBUS_RESULT_RESULT_CODE_MASK;
1065b3bf270bSDean Luick 		if (result_code != SBUS_READ_COMPLETE)
1066b3bf270bSDean Luick 			continue;
1067b3bf270bSDean Luick 
1068b3bf270bSDean Luick 		success = 1;
1069b3bf270bSDean Luick 		result = (reg >> ASIC_STS_SBUS_RESULT_DATA_OUT_SHIFT)
1070b3bf270bSDean Luick 			   & ASIC_STS_SBUS_RESULT_DATA_OUT_MASK;
1071b3bf270bSDean Luick 		break;
1072b3bf270bSDean Luick 	}
1073b3bf270bSDean Luick 
1074b3bf270bSDean Luick 	if (!success) {
1075b3bf270bSDean Luick 		dd_dev_err(dd, "%s: read failed, result code 0x%x\n", __func__,
1076b3bf270bSDean Luick 			   result_code);
1077b3bf270bSDean Luick 	}
1078b3bf270bSDean Luick 
1079b3bf270bSDean Luick 	return result;
1080b3bf270bSDean Luick }
1081b3bf270bSDean Luick 
1082b3bf270bSDean Luick /*
1083f48ad614SDennis Dalessandro  * Turn off the SBus and fabric serdes spicos.
1084f48ad614SDennis Dalessandro  *
1085f48ad614SDennis Dalessandro  * + Must be called with Sbus fast mode turned on.
1086f48ad614SDennis Dalessandro  * + Must be called after fabric serdes broadcast is set up.
1087f48ad614SDennis Dalessandro  * + Must be called before the 8051 is loaded - assumes 8051 is not loaded
1088f48ad614SDennis Dalessandro  *   when using MISC_CFG_FW_CTRL.
1089f48ad614SDennis Dalessandro  */
turn_off_spicos(struct hfi1_devdata * dd,int flags)1090f48ad614SDennis Dalessandro static void turn_off_spicos(struct hfi1_devdata *dd, int flags)
1091f48ad614SDennis Dalessandro {
1092f48ad614SDennis Dalessandro 	/* only needed on A0 */
1093f48ad614SDennis Dalessandro 	if (!is_ax(dd))
1094f48ad614SDennis Dalessandro 		return;
1095f48ad614SDennis Dalessandro 
1096f48ad614SDennis Dalessandro 	dd_dev_info(dd, "Turning off spicos:%s%s\n",
1097f48ad614SDennis Dalessandro 		    flags & SPICO_SBUS ? " SBus" : "",
1098f48ad614SDennis Dalessandro 		    flags & SPICO_FABRIC ? " fabric" : "");
1099f48ad614SDennis Dalessandro 
1100f48ad614SDennis Dalessandro 	write_csr(dd, MISC_CFG_FW_CTRL, ENABLE_SPICO_SMASK);
1101f48ad614SDennis Dalessandro 	/* disable SBus spico */
1102f48ad614SDennis Dalessandro 	if (flags & SPICO_SBUS)
1103f48ad614SDennis Dalessandro 		sbus_request(dd, SBUS_MASTER_BROADCAST, 0x01,
1104f48ad614SDennis Dalessandro 			     WRITE_SBUS_RECEIVER, 0x00000040);
1105f48ad614SDennis Dalessandro 
1106f48ad614SDennis Dalessandro 	/* disable the fabric serdes spicos */
1107f48ad614SDennis Dalessandro 	if (flags & SPICO_FABRIC)
1108f48ad614SDennis Dalessandro 		sbus_request(dd, fabric_serdes_broadcast[dd->hfi1_id],
1109f48ad614SDennis Dalessandro 			     0x07, WRITE_SBUS_RECEIVER, 0x00000000);
1110f48ad614SDennis Dalessandro 	write_csr(dd, MISC_CFG_FW_CTRL, 0);
1111f48ad614SDennis Dalessandro }
1112f48ad614SDennis Dalessandro 
1113f48ad614SDennis Dalessandro /*
1114f48ad614SDennis Dalessandro  * Reset all of the fabric serdes for this HFI in preparation to take the
1115f48ad614SDennis Dalessandro  * link to Polling.
1116f48ad614SDennis Dalessandro  *
111767d8f59bSwangjianli  * To do a reset, we need to write to the serdes registers.  Unfortunately,
1118f48ad614SDennis Dalessandro  * the fabric serdes download to the other HFI on the ASIC will have turned
1119f48ad614SDennis Dalessandro  * off the firmware validation on this HFI.  This means we can't write to the
1120f48ad614SDennis Dalessandro  * registers to reset the serdes.  Work around this by performing a complete
1121f48ad614SDennis Dalessandro  * re-download and validation of the fabric serdes firmware.  This, as a
1122f48ad614SDennis Dalessandro  * by-product, will reset the serdes.  NOTE: the re-download requires that
1123f48ad614SDennis Dalessandro  * the 8051 be in the Offline state.  I.e. not actively trying to use the
1124f48ad614SDennis Dalessandro  * serdes.  This routine is called at the point where the link is Offline and
1125f48ad614SDennis Dalessandro  * is getting ready to go to Polling.
1126f48ad614SDennis Dalessandro  */
fabric_serdes_reset(struct hfi1_devdata * dd)1127f48ad614SDennis Dalessandro void fabric_serdes_reset(struct hfi1_devdata *dd)
1128f48ad614SDennis Dalessandro {
1129f48ad614SDennis Dalessandro 	int ret;
1130f48ad614SDennis Dalessandro 
1131f48ad614SDennis Dalessandro 	if (!fw_fabric_serdes_load)
1132f48ad614SDennis Dalessandro 		return;
1133f48ad614SDennis Dalessandro 
1134f48ad614SDennis Dalessandro 	ret = acquire_chip_resource(dd, CR_SBUS, SBUS_TIMEOUT);
1135f48ad614SDennis Dalessandro 	if (ret) {
1136f48ad614SDennis Dalessandro 		dd_dev_err(dd,
1137f48ad614SDennis Dalessandro 			   "Cannot acquire SBus resource to reset fabric SerDes - perhaps you should reboot\n");
1138f48ad614SDennis Dalessandro 		return;
1139f48ad614SDennis Dalessandro 	}
1140f48ad614SDennis Dalessandro 	set_sbus_fast_mode(dd);
1141f48ad614SDennis Dalessandro 
1142f48ad614SDennis Dalessandro 	if (is_ax(dd)) {
1143f48ad614SDennis Dalessandro 		/* A0 serdes do not work with a re-download */
1144f48ad614SDennis Dalessandro 		u8 ra = fabric_serdes_broadcast[dd->hfi1_id];
1145f48ad614SDennis Dalessandro 
1146f48ad614SDennis Dalessandro 		/* place SerDes in reset and disable SPICO */
1147f48ad614SDennis Dalessandro 		sbus_request(dd, ra, 0x07, WRITE_SBUS_RECEIVER, 0x00000011);
1148f48ad614SDennis Dalessandro 		/* wait 100 refclk cycles @ 156.25MHz => 640ns */
1149f48ad614SDennis Dalessandro 		udelay(1);
1150f48ad614SDennis Dalessandro 		/* remove SerDes reset */
1151f48ad614SDennis Dalessandro 		sbus_request(dd, ra, 0x07, WRITE_SBUS_RECEIVER, 0x00000010);
1152f48ad614SDennis Dalessandro 		/* turn SPICO enable on */
1153f48ad614SDennis Dalessandro 		sbus_request(dd, ra, 0x07, WRITE_SBUS_RECEIVER, 0x00000002);
1154f48ad614SDennis Dalessandro 	} else {
1155f48ad614SDennis Dalessandro 		turn_off_spicos(dd, SPICO_FABRIC);
1156f48ad614SDennis Dalessandro 		/*
1157f48ad614SDennis Dalessandro 		 * No need for firmware retry - what to download has already
1158f48ad614SDennis Dalessandro 		 * been decided.
1159f48ad614SDennis Dalessandro 		 * No need to pay attention to the load return - the only
1160f48ad614SDennis Dalessandro 		 * failure is a validation failure, which has already been
1161f48ad614SDennis Dalessandro 		 * checked by the initial download.
1162f48ad614SDennis Dalessandro 		 */
1163f48ad614SDennis Dalessandro 		(void)load_fabric_serdes_firmware(dd, &fw_fabric);
1164f48ad614SDennis Dalessandro 	}
1165f48ad614SDennis Dalessandro 
1166f48ad614SDennis Dalessandro 	clear_sbus_fast_mode(dd);
1167f48ad614SDennis Dalessandro 	release_chip_resource(dd, CR_SBUS);
1168f48ad614SDennis Dalessandro }
1169f48ad614SDennis Dalessandro 
1170f48ad614SDennis Dalessandro /* Access to the SBus in this routine should probably be serialized */
sbus_request_slow(struct hfi1_devdata * dd,u8 receiver_addr,u8 data_addr,u8 command,u32 data_in)1171f48ad614SDennis Dalessandro int sbus_request_slow(struct hfi1_devdata *dd,
1172f48ad614SDennis Dalessandro 		      u8 receiver_addr, u8 data_addr, u8 command, u32 data_in)
1173f48ad614SDennis Dalessandro {
1174f48ad614SDennis Dalessandro 	u64 reg, count = 0;
1175f48ad614SDennis Dalessandro 
1176f48ad614SDennis Dalessandro 	/* make sure fast mode is clear */
1177f48ad614SDennis Dalessandro 	clear_sbus_fast_mode(dd);
1178f48ad614SDennis Dalessandro 
1179f48ad614SDennis Dalessandro 	sbus_request(dd, receiver_addr, data_addr, command, data_in);
1180f48ad614SDennis Dalessandro 	write_csr(dd, ASIC_CFG_SBUS_EXECUTE,
1181f48ad614SDennis Dalessandro 		  ASIC_CFG_SBUS_EXECUTE_EXECUTE_SMASK);
1182f48ad614SDennis Dalessandro 	/* Wait for both DONE and RCV_DATA_VALID to go high */
1183f48ad614SDennis Dalessandro 	reg = read_csr(dd, ASIC_STS_SBUS_RESULT);
1184f48ad614SDennis Dalessandro 	while (!((reg & ASIC_STS_SBUS_RESULT_DONE_SMASK) &&
1185f48ad614SDennis Dalessandro 		 (reg & ASIC_STS_SBUS_RESULT_RCV_DATA_VALID_SMASK))) {
1186f48ad614SDennis Dalessandro 		if (count++ >= SBUS_MAX_POLL_COUNT) {
1187f48ad614SDennis Dalessandro 			u64 counts = read_csr(dd, ASIC_STS_SBUS_COUNTERS);
1188f48ad614SDennis Dalessandro 			/*
1189f48ad614SDennis Dalessandro 			 * If the loop has timed out, we are OK if DONE bit
1190f48ad614SDennis Dalessandro 			 * is set and RCV_DATA_VALID and EXECUTE counters
1191f48ad614SDennis Dalessandro 			 * are the same. If not, we cannot proceed.
1192f48ad614SDennis Dalessandro 			 */
1193f48ad614SDennis Dalessandro 			if ((reg & ASIC_STS_SBUS_RESULT_DONE_SMASK) &&
1194f48ad614SDennis Dalessandro 			    (SBUS_COUNTER(counts, RCV_DATA_VALID) ==
1195f48ad614SDennis Dalessandro 			     SBUS_COUNTER(counts, EXECUTE)))
1196f48ad614SDennis Dalessandro 				break;
1197f48ad614SDennis Dalessandro 			return -ETIMEDOUT;
1198f48ad614SDennis Dalessandro 		}
1199f48ad614SDennis Dalessandro 		udelay(1);
1200f48ad614SDennis Dalessandro 		reg = read_csr(dd, ASIC_STS_SBUS_RESULT);
1201f48ad614SDennis Dalessandro 	}
1202f48ad614SDennis Dalessandro 	count = 0;
1203f48ad614SDennis Dalessandro 	write_csr(dd, ASIC_CFG_SBUS_EXECUTE, 0);
1204f48ad614SDennis Dalessandro 	/* Wait for DONE to clear after EXECUTE is cleared */
1205f48ad614SDennis Dalessandro 	reg = read_csr(dd, ASIC_STS_SBUS_RESULT);
1206f48ad614SDennis Dalessandro 	while (reg & ASIC_STS_SBUS_RESULT_DONE_SMASK) {
1207f48ad614SDennis Dalessandro 		if (count++ >= SBUS_MAX_POLL_COUNT)
1208f48ad614SDennis Dalessandro 			return -ETIME;
1209f48ad614SDennis Dalessandro 		udelay(1);
1210f48ad614SDennis Dalessandro 		reg = read_csr(dd, ASIC_STS_SBUS_RESULT);
1211f48ad614SDennis Dalessandro 	}
1212f48ad614SDennis Dalessandro 	return 0;
1213f48ad614SDennis Dalessandro }
1214f48ad614SDennis Dalessandro 
load_fabric_serdes_firmware(struct hfi1_devdata * dd,struct firmware_details * fdet)1215f48ad614SDennis Dalessandro static int load_fabric_serdes_firmware(struct hfi1_devdata *dd,
1216f48ad614SDennis Dalessandro 				       struct firmware_details *fdet)
1217f48ad614SDennis Dalessandro {
1218f48ad614SDennis Dalessandro 	int i, err;
1219f48ad614SDennis Dalessandro 	const u8 ra = fabric_serdes_broadcast[dd->hfi1_id]; /* receiver addr */
1220f48ad614SDennis Dalessandro 
1221f48ad614SDennis Dalessandro 	dd_dev_info(dd, "Downloading fabric firmware\n");
1222f48ad614SDennis Dalessandro 
1223f48ad614SDennis Dalessandro 	/* step 1: load security variables */
1224f48ad614SDennis Dalessandro 	load_security_variables(dd, fdet);
1225f48ad614SDennis Dalessandro 	/* step 2: place SerDes in reset and disable SPICO */
1226f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x07, WRITE_SBUS_RECEIVER, 0x00000011);
1227f48ad614SDennis Dalessandro 	/* wait 100 refclk cycles @ 156.25MHz => 640ns */
1228f48ad614SDennis Dalessandro 	udelay(1);
1229f48ad614SDennis Dalessandro 	/* step 3:  remove SerDes reset */
1230f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x07, WRITE_SBUS_RECEIVER, 0x00000010);
1231f48ad614SDennis Dalessandro 	/* step 4: assert IMEM override */
1232f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x00, WRITE_SBUS_RECEIVER, 0x40000000);
1233f48ad614SDennis Dalessandro 	/* step 5: download SerDes machine code */
1234f48ad614SDennis Dalessandro 	for (i = 0; i < fdet->firmware_len; i += 4) {
1235f48ad614SDennis Dalessandro 		sbus_request(dd, ra, 0x0a, WRITE_SBUS_RECEIVER,
1236f48ad614SDennis Dalessandro 			     *(u32 *)&fdet->firmware_ptr[i]);
1237f48ad614SDennis Dalessandro 	}
1238f48ad614SDennis Dalessandro 	/* step 6: IMEM override off */
1239f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x00, WRITE_SBUS_RECEIVER, 0x00000000);
1240f48ad614SDennis Dalessandro 	/* step 7: turn ECC on */
1241f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x0b, WRITE_SBUS_RECEIVER, 0x000c0000);
1242f48ad614SDennis Dalessandro 
1243f48ad614SDennis Dalessandro 	/* steps 8-11: run the RSA engine */
1244f48ad614SDennis Dalessandro 	err = run_rsa(dd, "fabric serdes", fdet->signature);
1245f48ad614SDennis Dalessandro 	if (err)
1246f48ad614SDennis Dalessandro 		return err;
1247f48ad614SDennis Dalessandro 
1248f48ad614SDennis Dalessandro 	/* step 12: turn SPICO enable on */
1249f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x07, WRITE_SBUS_RECEIVER, 0x00000002);
1250f48ad614SDennis Dalessandro 	/* step 13: enable core hardware interrupts */
1251f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x08, WRITE_SBUS_RECEIVER, 0x00000000);
1252f48ad614SDennis Dalessandro 
1253f48ad614SDennis Dalessandro 	return 0;
1254f48ad614SDennis Dalessandro }
1255f48ad614SDennis Dalessandro 
load_sbus_firmware(struct hfi1_devdata * dd,struct firmware_details * fdet)1256f48ad614SDennis Dalessandro static int load_sbus_firmware(struct hfi1_devdata *dd,
1257f48ad614SDennis Dalessandro 			      struct firmware_details *fdet)
1258f48ad614SDennis Dalessandro {
1259f48ad614SDennis Dalessandro 	int i, err;
1260f48ad614SDennis Dalessandro 	const u8 ra = SBUS_MASTER_BROADCAST; /* receiver address */
1261f48ad614SDennis Dalessandro 
1262f48ad614SDennis Dalessandro 	dd_dev_info(dd, "Downloading SBus firmware\n");
1263f48ad614SDennis Dalessandro 
1264f48ad614SDennis Dalessandro 	/* step 1: load security variables */
1265f48ad614SDennis Dalessandro 	load_security_variables(dd, fdet);
1266f48ad614SDennis Dalessandro 	/* step 2: place SPICO into reset and enable off */
1267f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x01, WRITE_SBUS_RECEIVER, 0x000000c0);
1268f48ad614SDennis Dalessandro 	/* step 3: remove reset, enable off, IMEM_CNTRL_EN on */
1269f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x01, WRITE_SBUS_RECEIVER, 0x00000240);
1270f48ad614SDennis Dalessandro 	/* step 4: set starting IMEM address for burst download */
1271f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x03, WRITE_SBUS_RECEIVER, 0x80000000);
1272f48ad614SDennis Dalessandro 	/* step 5: download the SBus Master machine code */
1273f48ad614SDennis Dalessandro 	for (i = 0; i < fdet->firmware_len; i += 4) {
1274f48ad614SDennis Dalessandro 		sbus_request(dd, ra, 0x14, WRITE_SBUS_RECEIVER,
1275f48ad614SDennis Dalessandro 			     *(u32 *)&fdet->firmware_ptr[i]);
1276f48ad614SDennis Dalessandro 	}
1277f48ad614SDennis Dalessandro 	/* step 6: set IMEM_CNTL_EN off */
1278f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x01, WRITE_SBUS_RECEIVER, 0x00000040);
1279f48ad614SDennis Dalessandro 	/* step 7: turn ECC on */
1280f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x16, WRITE_SBUS_RECEIVER, 0x000c0000);
1281f48ad614SDennis Dalessandro 
1282f48ad614SDennis Dalessandro 	/* steps 8-11: run the RSA engine */
1283f48ad614SDennis Dalessandro 	err = run_rsa(dd, "SBus", fdet->signature);
1284f48ad614SDennis Dalessandro 	if (err)
1285f48ad614SDennis Dalessandro 		return err;
1286f48ad614SDennis Dalessandro 
1287f48ad614SDennis Dalessandro 	/* step 12: set SPICO_ENABLE on */
1288f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x01, WRITE_SBUS_RECEIVER, 0x00000140);
1289f48ad614SDennis Dalessandro 
1290f48ad614SDennis Dalessandro 	return 0;
1291f48ad614SDennis Dalessandro }
1292f48ad614SDennis Dalessandro 
load_pcie_serdes_firmware(struct hfi1_devdata * dd,struct firmware_details * fdet)1293f48ad614SDennis Dalessandro static int load_pcie_serdes_firmware(struct hfi1_devdata *dd,
1294f48ad614SDennis Dalessandro 				     struct firmware_details *fdet)
1295f48ad614SDennis Dalessandro {
1296f48ad614SDennis Dalessandro 	int i;
1297f48ad614SDennis Dalessandro 	const u8 ra = SBUS_MASTER_BROADCAST; /* receiver address */
1298f48ad614SDennis Dalessandro 
1299f48ad614SDennis Dalessandro 	dd_dev_info(dd, "Downloading PCIe firmware\n");
1300f48ad614SDennis Dalessandro 
1301f48ad614SDennis Dalessandro 	/* step 1: load security variables */
1302f48ad614SDennis Dalessandro 	load_security_variables(dd, fdet);
1303f48ad614SDennis Dalessandro 	/* step 2: assert single step (halts the SBus Master spico) */
1304f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x05, WRITE_SBUS_RECEIVER, 0x00000001);
1305f48ad614SDennis Dalessandro 	/* step 3: enable XDMEM access */
1306f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x01, WRITE_SBUS_RECEIVER, 0x00000d40);
1307f48ad614SDennis Dalessandro 	/* step 4: load firmware into SBus Master XDMEM */
1308f48ad614SDennis Dalessandro 	/*
1309f48ad614SDennis Dalessandro 	 * NOTE: the dmem address, write_en, and wdata are all pre-packed,
1310f48ad614SDennis Dalessandro 	 * we only need to pick up the bytes and write them
1311f48ad614SDennis Dalessandro 	 */
1312f48ad614SDennis Dalessandro 	for (i = 0; i < fdet->firmware_len; i += 4) {
1313f48ad614SDennis Dalessandro 		sbus_request(dd, ra, 0x04, WRITE_SBUS_RECEIVER,
1314f48ad614SDennis Dalessandro 			     *(u32 *)&fdet->firmware_ptr[i]);
1315f48ad614SDennis Dalessandro 	}
1316f48ad614SDennis Dalessandro 	/* step 5: disable XDMEM access */
1317f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x01, WRITE_SBUS_RECEIVER, 0x00000140);
1318f48ad614SDennis Dalessandro 	/* step 6: allow SBus Spico to run */
1319f48ad614SDennis Dalessandro 	sbus_request(dd, ra, 0x05, WRITE_SBUS_RECEIVER, 0x00000000);
1320f48ad614SDennis Dalessandro 
1321f48ad614SDennis Dalessandro 	/*
1322f48ad614SDennis Dalessandro 	 * steps 7-11: run RSA, if it succeeds, firmware is available to
1323f48ad614SDennis Dalessandro 	 * be swapped
1324f48ad614SDennis Dalessandro 	 */
1325f48ad614SDennis Dalessandro 	return run_rsa(dd, "PCIe serdes", fdet->signature);
1326f48ad614SDennis Dalessandro }
1327f48ad614SDennis Dalessandro 
1328f48ad614SDennis Dalessandro /*
1329f48ad614SDennis Dalessandro  * Set the given broadcast values on the given list of devices.
1330f48ad614SDennis Dalessandro  */
set_serdes_broadcast(struct hfi1_devdata * dd,u8 bg1,u8 bg2,const u8 * addrs,int count)1331f48ad614SDennis Dalessandro static void set_serdes_broadcast(struct hfi1_devdata *dd, u8 bg1, u8 bg2,
1332f48ad614SDennis Dalessandro 				 const u8 *addrs, int count)
1333f48ad614SDennis Dalessandro {
1334f48ad614SDennis Dalessandro 	while (--count >= 0) {
1335f48ad614SDennis Dalessandro 		/*
1336f48ad614SDennis Dalessandro 		 * Set BROADCAST_GROUP_1 and BROADCAST_GROUP_2, leave
1337f48ad614SDennis Dalessandro 		 * defaults for everything else.  Do not read-modify-write,
1338f48ad614SDennis Dalessandro 		 * per instruction from the manufacturer.
1339f48ad614SDennis Dalessandro 		 *
1340f48ad614SDennis Dalessandro 		 * Register 0xfd:
1341f48ad614SDennis Dalessandro 		 *	bits    what
1342f48ad614SDennis Dalessandro 		 *	-----	---------------------------------
1343f48ad614SDennis Dalessandro 		 *	  0	IGNORE_BROADCAST  (default 0)
1344f48ad614SDennis Dalessandro 		 *	11:4	BROADCAST_GROUP_1 (default 0xff)
1345f48ad614SDennis Dalessandro 		 *	23:16	BROADCAST_GROUP_2 (default 0xff)
1346f48ad614SDennis Dalessandro 		 */
1347f48ad614SDennis Dalessandro 		sbus_request(dd, addrs[count], 0xfd, WRITE_SBUS_RECEIVER,
1348f48ad614SDennis Dalessandro 			     (u32)bg1 << 4 | (u32)bg2 << 16);
1349f48ad614SDennis Dalessandro 	}
1350f48ad614SDennis Dalessandro }
1351f48ad614SDennis Dalessandro 
acquire_hw_mutex(struct hfi1_devdata * dd)1352f48ad614SDennis Dalessandro int acquire_hw_mutex(struct hfi1_devdata *dd)
1353f48ad614SDennis Dalessandro {
1354f48ad614SDennis Dalessandro 	unsigned long timeout;
1355f48ad614SDennis Dalessandro 	int try = 0;
1356f48ad614SDennis Dalessandro 	u8 mask = 1 << dd->hfi1_id;
1357b65c2045SGrzegorz Morys 	u8 user = (u8)read_csr(dd, ASIC_CFG_MUTEX);
1358b65c2045SGrzegorz Morys 
1359b65c2045SGrzegorz Morys 	if (user == mask) {
1360b65c2045SGrzegorz Morys 		dd_dev_info(dd,
1361b65c2045SGrzegorz Morys 			    "Hardware mutex already acquired, mutex mask %u\n",
1362b65c2045SGrzegorz Morys 			    (u32)mask);
1363b65c2045SGrzegorz Morys 		return 0;
1364b65c2045SGrzegorz Morys 	}
1365f48ad614SDennis Dalessandro 
1366f48ad614SDennis Dalessandro retry:
1367f48ad614SDennis Dalessandro 	timeout = msecs_to_jiffies(HM_TIMEOUT) + jiffies;
1368f48ad614SDennis Dalessandro 	while (1) {
1369f48ad614SDennis Dalessandro 		write_csr(dd, ASIC_CFG_MUTEX, mask);
1370f48ad614SDennis Dalessandro 		user = (u8)read_csr(dd, ASIC_CFG_MUTEX);
1371f48ad614SDennis Dalessandro 		if (user == mask)
1372f48ad614SDennis Dalessandro 			return 0; /* success */
1373f48ad614SDennis Dalessandro 		if (time_after(jiffies, timeout))
1374f48ad614SDennis Dalessandro 			break; /* timed out */
1375f48ad614SDennis Dalessandro 		msleep(20);
1376f48ad614SDennis Dalessandro 	}
1377f48ad614SDennis Dalessandro 
1378f48ad614SDennis Dalessandro 	/* timed out */
1379f48ad614SDennis Dalessandro 	dd_dev_err(dd,
1380f48ad614SDennis Dalessandro 		   "Unable to acquire hardware mutex, mutex mask %u, my mask %u (%s)\n",
1381f48ad614SDennis Dalessandro 		   (u32)user, (u32)mask, (try == 0) ? "retrying" : "giving up");
1382f48ad614SDennis Dalessandro 
1383f48ad614SDennis Dalessandro 	if (try == 0) {
1384f48ad614SDennis Dalessandro 		/* break mutex and retry */
1385f48ad614SDennis Dalessandro 		write_csr(dd, ASIC_CFG_MUTEX, 0);
1386f48ad614SDennis Dalessandro 		try++;
1387f48ad614SDennis Dalessandro 		goto retry;
1388f48ad614SDennis Dalessandro 	}
1389f48ad614SDennis Dalessandro 
1390f48ad614SDennis Dalessandro 	return -EBUSY;
1391f48ad614SDennis Dalessandro }
1392f48ad614SDennis Dalessandro 
release_hw_mutex(struct hfi1_devdata * dd)1393f48ad614SDennis Dalessandro void release_hw_mutex(struct hfi1_devdata *dd)
1394f48ad614SDennis Dalessandro {
1395b65c2045SGrzegorz Morys 	u8 mask = 1 << dd->hfi1_id;
1396b65c2045SGrzegorz Morys 	u8 user = (u8)read_csr(dd, ASIC_CFG_MUTEX);
1397b65c2045SGrzegorz Morys 
1398b65c2045SGrzegorz Morys 	if (user != mask)
1399b65c2045SGrzegorz Morys 		dd_dev_warn(dd,
1400b65c2045SGrzegorz Morys 			    "Unable to release hardware mutex, mutex mask %u, my mask %u\n",
1401b65c2045SGrzegorz Morys 			    (u32)user, (u32)mask);
1402b65c2045SGrzegorz Morys 	else
1403f48ad614SDennis Dalessandro 		write_csr(dd, ASIC_CFG_MUTEX, 0);
1404f48ad614SDennis Dalessandro }
1405f48ad614SDennis Dalessandro 
1406f48ad614SDennis Dalessandro /* return the given resource bit(s) as a mask for the given HFI */
resource_mask(u32 hfi1_id,u32 resource)1407f48ad614SDennis Dalessandro static inline u64 resource_mask(u32 hfi1_id, u32 resource)
1408f48ad614SDennis Dalessandro {
1409f48ad614SDennis Dalessandro 	return ((u64)resource) << (hfi1_id ? CR_DYN_SHIFT : 0);
1410f48ad614SDennis Dalessandro }
1411f48ad614SDennis Dalessandro 
fail_mutex_acquire_message(struct hfi1_devdata * dd,const char * func)1412f48ad614SDennis Dalessandro static void fail_mutex_acquire_message(struct hfi1_devdata *dd,
1413f48ad614SDennis Dalessandro 				       const char *func)
1414f48ad614SDennis Dalessandro {
1415f48ad614SDennis Dalessandro 	dd_dev_err(dd,
1416f48ad614SDennis Dalessandro 		   "%s: hardware mutex stuck - suggest rebooting the machine\n",
1417f48ad614SDennis Dalessandro 		   func);
1418f48ad614SDennis Dalessandro }
1419f48ad614SDennis Dalessandro 
1420f48ad614SDennis Dalessandro /*
1421f48ad614SDennis Dalessandro  * Acquire access to a chip resource.
1422f48ad614SDennis Dalessandro  *
1423f48ad614SDennis Dalessandro  * Return 0 on success, -EBUSY if resource busy, -EIO if mutex acquire failed.
1424f48ad614SDennis Dalessandro  */
__acquire_chip_resource(struct hfi1_devdata * dd,u32 resource)1425f48ad614SDennis Dalessandro static int __acquire_chip_resource(struct hfi1_devdata *dd, u32 resource)
1426f48ad614SDennis Dalessandro {
1427f48ad614SDennis Dalessandro 	u64 scratch0, all_bits, my_bit;
1428f48ad614SDennis Dalessandro 	int ret;
1429f48ad614SDennis Dalessandro 
1430f48ad614SDennis Dalessandro 	if (resource & CR_DYN_MASK) {
1431f48ad614SDennis Dalessandro 		/* a dynamic resource is in use if either HFI has set the bit */
1432f48ad614SDennis Dalessandro 		if (dd->pcidev->device == PCI_DEVICE_ID_INTEL0 &&
1433f48ad614SDennis Dalessandro 		    (resource & (CR_I2C1 | CR_I2C2))) {
1434f48ad614SDennis Dalessandro 			/* discrete devices must serialize across both chains */
1435f48ad614SDennis Dalessandro 			all_bits = resource_mask(0, CR_I2C1 | CR_I2C2) |
1436f48ad614SDennis Dalessandro 					resource_mask(1, CR_I2C1 | CR_I2C2);
1437f48ad614SDennis Dalessandro 		} else {
1438f48ad614SDennis Dalessandro 			all_bits = resource_mask(0, resource) |
1439f48ad614SDennis Dalessandro 						resource_mask(1, resource);
1440f48ad614SDennis Dalessandro 		}
1441f48ad614SDennis Dalessandro 		my_bit = resource_mask(dd->hfi1_id, resource);
1442f48ad614SDennis Dalessandro 	} else {
1443f48ad614SDennis Dalessandro 		/* non-dynamic resources are not split between HFIs */
1444f48ad614SDennis Dalessandro 		all_bits = resource;
1445f48ad614SDennis Dalessandro 		my_bit = resource;
1446f48ad614SDennis Dalessandro 	}
1447f48ad614SDennis Dalessandro 
1448f48ad614SDennis Dalessandro 	/* lock against other callers within the driver wanting a resource */
1449f48ad614SDennis Dalessandro 	mutex_lock(&dd->asic_data->asic_resource_mutex);
1450f48ad614SDennis Dalessandro 
1451f48ad614SDennis Dalessandro 	ret = acquire_hw_mutex(dd);
1452f48ad614SDennis Dalessandro 	if (ret) {
1453f48ad614SDennis Dalessandro 		fail_mutex_acquire_message(dd, __func__);
1454f48ad614SDennis Dalessandro 		ret = -EIO;
1455f48ad614SDennis Dalessandro 		goto done;
1456f48ad614SDennis Dalessandro 	}
1457f48ad614SDennis Dalessandro 
1458f48ad614SDennis Dalessandro 	scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
1459f48ad614SDennis Dalessandro 	if (scratch0 & all_bits) {
1460f48ad614SDennis Dalessandro 		ret = -EBUSY;
1461f48ad614SDennis Dalessandro 	} else {
1462f48ad614SDennis Dalessandro 		write_csr(dd, ASIC_CFG_SCRATCH, scratch0 | my_bit);
1463f48ad614SDennis Dalessandro 		/* force write to be visible to other HFI on another OS */
1464f48ad614SDennis Dalessandro 		(void)read_csr(dd, ASIC_CFG_SCRATCH);
1465f48ad614SDennis Dalessandro 	}
1466f48ad614SDennis Dalessandro 
1467f48ad614SDennis Dalessandro 	release_hw_mutex(dd);
1468f48ad614SDennis Dalessandro 
1469f48ad614SDennis Dalessandro done:
1470f48ad614SDennis Dalessandro 	mutex_unlock(&dd->asic_data->asic_resource_mutex);
1471f48ad614SDennis Dalessandro 	return ret;
1472f48ad614SDennis Dalessandro }
1473f48ad614SDennis Dalessandro 
1474f48ad614SDennis Dalessandro /*
1475f48ad614SDennis Dalessandro  * Acquire access to a chip resource, wait up to mswait milliseconds for
1476f48ad614SDennis Dalessandro  * the resource to become available.
1477f48ad614SDennis Dalessandro  *
1478f48ad614SDennis Dalessandro  * Return 0 on success, -EBUSY if busy (even after wait), -EIO if mutex
1479f48ad614SDennis Dalessandro  * acquire failed.
1480f48ad614SDennis Dalessandro  */
acquire_chip_resource(struct hfi1_devdata * dd,u32 resource,u32 mswait)1481f48ad614SDennis Dalessandro int acquire_chip_resource(struct hfi1_devdata *dd, u32 resource, u32 mswait)
1482f48ad614SDennis Dalessandro {
1483f48ad614SDennis Dalessandro 	unsigned long timeout;
1484f48ad614SDennis Dalessandro 	int ret;
1485f48ad614SDennis Dalessandro 
1486f48ad614SDennis Dalessandro 	timeout = jiffies + msecs_to_jiffies(mswait);
1487f48ad614SDennis Dalessandro 	while (1) {
1488f48ad614SDennis Dalessandro 		ret = __acquire_chip_resource(dd, resource);
1489f48ad614SDennis Dalessandro 		if (ret != -EBUSY)
1490f48ad614SDennis Dalessandro 			return ret;
1491f48ad614SDennis Dalessandro 		/* resource is busy, check our timeout */
1492f48ad614SDennis Dalessandro 		if (time_after_eq(jiffies, timeout))
1493f48ad614SDennis Dalessandro 			return -EBUSY;
1494f48ad614SDennis Dalessandro 		usleep_range(80, 120);	/* arbitrary delay */
1495f48ad614SDennis Dalessandro 	}
1496f48ad614SDennis Dalessandro }
1497f48ad614SDennis Dalessandro 
1498f48ad614SDennis Dalessandro /*
1499f48ad614SDennis Dalessandro  * Release access to a chip resource
1500f48ad614SDennis Dalessandro  */
release_chip_resource(struct hfi1_devdata * dd,u32 resource)1501f48ad614SDennis Dalessandro void release_chip_resource(struct hfi1_devdata *dd, u32 resource)
1502f48ad614SDennis Dalessandro {
1503f48ad614SDennis Dalessandro 	u64 scratch0, bit;
1504f48ad614SDennis Dalessandro 
1505f48ad614SDennis Dalessandro 	/* only dynamic resources should ever be cleared */
1506f48ad614SDennis Dalessandro 	if (!(resource & CR_DYN_MASK)) {
1507f48ad614SDennis Dalessandro 		dd_dev_err(dd, "%s: invalid resource 0x%x\n", __func__,
1508f48ad614SDennis Dalessandro 			   resource);
1509f48ad614SDennis Dalessandro 		return;
1510f48ad614SDennis Dalessandro 	}
1511f48ad614SDennis Dalessandro 	bit = resource_mask(dd->hfi1_id, resource);
1512f48ad614SDennis Dalessandro 
1513f48ad614SDennis Dalessandro 	/* lock against other callers within the driver wanting a resource */
1514f48ad614SDennis Dalessandro 	mutex_lock(&dd->asic_data->asic_resource_mutex);
1515f48ad614SDennis Dalessandro 
1516f48ad614SDennis Dalessandro 	if (acquire_hw_mutex(dd)) {
1517f48ad614SDennis Dalessandro 		fail_mutex_acquire_message(dd, __func__);
1518f48ad614SDennis Dalessandro 		goto done;
1519f48ad614SDennis Dalessandro 	}
1520f48ad614SDennis Dalessandro 
1521f48ad614SDennis Dalessandro 	scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
1522f48ad614SDennis Dalessandro 	if ((scratch0 & bit) != 0) {
1523f48ad614SDennis Dalessandro 		scratch0 &= ~bit;
1524f48ad614SDennis Dalessandro 		write_csr(dd, ASIC_CFG_SCRATCH, scratch0);
1525f48ad614SDennis Dalessandro 		/* force write to be visible to other HFI on another OS */
1526f48ad614SDennis Dalessandro 		(void)read_csr(dd, ASIC_CFG_SCRATCH);
1527f48ad614SDennis Dalessandro 	} else {
1528f48ad614SDennis Dalessandro 		dd_dev_warn(dd, "%s: id %d, resource 0x%x: bit not set\n",
1529f48ad614SDennis Dalessandro 			    __func__, dd->hfi1_id, resource);
1530f48ad614SDennis Dalessandro 	}
1531f48ad614SDennis Dalessandro 
1532f48ad614SDennis Dalessandro 	release_hw_mutex(dd);
1533f48ad614SDennis Dalessandro 
1534f48ad614SDennis Dalessandro done:
1535f48ad614SDennis Dalessandro 	mutex_unlock(&dd->asic_data->asic_resource_mutex);
1536f48ad614SDennis Dalessandro }
1537f48ad614SDennis Dalessandro 
1538f48ad614SDennis Dalessandro /*
1539f48ad614SDennis Dalessandro  * Return true if resource is set, false otherwise.  Print a warning
1540f48ad614SDennis Dalessandro  * if not set and a function is supplied.
1541f48ad614SDennis Dalessandro  */
check_chip_resource(struct hfi1_devdata * dd,u32 resource,const char * func)1542f48ad614SDennis Dalessandro bool check_chip_resource(struct hfi1_devdata *dd, u32 resource,
1543f48ad614SDennis Dalessandro 			 const char *func)
1544f48ad614SDennis Dalessandro {
1545f48ad614SDennis Dalessandro 	u64 scratch0, bit;
1546f48ad614SDennis Dalessandro 
1547f48ad614SDennis Dalessandro 	if (resource & CR_DYN_MASK)
1548f48ad614SDennis Dalessandro 		bit = resource_mask(dd->hfi1_id, resource);
1549f48ad614SDennis Dalessandro 	else
1550f48ad614SDennis Dalessandro 		bit = resource;
1551f48ad614SDennis Dalessandro 
1552f48ad614SDennis Dalessandro 	scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
1553f48ad614SDennis Dalessandro 	if ((scratch0 & bit) == 0) {
1554f48ad614SDennis Dalessandro 		if (func)
1555f48ad614SDennis Dalessandro 			dd_dev_warn(dd,
1556f48ad614SDennis Dalessandro 				    "%s: id %d, resource 0x%x, not acquired!\n",
1557f48ad614SDennis Dalessandro 				    func, dd->hfi1_id, resource);
1558f48ad614SDennis Dalessandro 		return false;
1559f48ad614SDennis Dalessandro 	}
1560f48ad614SDennis Dalessandro 	return true;
1561f48ad614SDennis Dalessandro }
1562f48ad614SDennis Dalessandro 
clear_chip_resources(struct hfi1_devdata * dd,const char * func)1563f48ad614SDennis Dalessandro static void clear_chip_resources(struct hfi1_devdata *dd, const char *func)
1564f48ad614SDennis Dalessandro {
1565f48ad614SDennis Dalessandro 	u64 scratch0;
1566f48ad614SDennis Dalessandro 
1567f48ad614SDennis Dalessandro 	/* lock against other callers within the driver wanting a resource */
1568f48ad614SDennis Dalessandro 	mutex_lock(&dd->asic_data->asic_resource_mutex);
1569f48ad614SDennis Dalessandro 
1570f48ad614SDennis Dalessandro 	if (acquire_hw_mutex(dd)) {
1571f48ad614SDennis Dalessandro 		fail_mutex_acquire_message(dd, func);
1572f48ad614SDennis Dalessandro 		goto done;
1573f48ad614SDennis Dalessandro 	}
1574f48ad614SDennis Dalessandro 
1575f48ad614SDennis Dalessandro 	/* clear all dynamic access bits for this HFI */
1576f48ad614SDennis Dalessandro 	scratch0 = read_csr(dd, ASIC_CFG_SCRATCH);
1577f48ad614SDennis Dalessandro 	scratch0 &= ~resource_mask(dd->hfi1_id, CR_DYN_MASK);
1578f48ad614SDennis Dalessandro 	write_csr(dd, ASIC_CFG_SCRATCH, scratch0);
1579f48ad614SDennis Dalessandro 	/* force write to be visible to other HFI on another OS */
1580f48ad614SDennis Dalessandro 	(void)read_csr(dd, ASIC_CFG_SCRATCH);
1581f48ad614SDennis Dalessandro 
1582f48ad614SDennis Dalessandro 	release_hw_mutex(dd);
1583f48ad614SDennis Dalessandro 
1584f48ad614SDennis Dalessandro done:
1585f48ad614SDennis Dalessandro 	mutex_unlock(&dd->asic_data->asic_resource_mutex);
1586f48ad614SDennis Dalessandro }
1587f48ad614SDennis Dalessandro 
init_chip_resources(struct hfi1_devdata * dd)1588f48ad614SDennis Dalessandro void init_chip_resources(struct hfi1_devdata *dd)
1589f48ad614SDennis Dalessandro {
1590f48ad614SDennis Dalessandro 	/* clear any holds left by us */
1591f48ad614SDennis Dalessandro 	clear_chip_resources(dd, __func__);
1592f48ad614SDennis Dalessandro }
1593f48ad614SDennis Dalessandro 
finish_chip_resources(struct hfi1_devdata * dd)1594f48ad614SDennis Dalessandro void finish_chip_resources(struct hfi1_devdata *dd)
1595f48ad614SDennis Dalessandro {
1596f48ad614SDennis Dalessandro 	/* clear any holds left by us */
1597f48ad614SDennis Dalessandro 	clear_chip_resources(dd, __func__);
1598f48ad614SDennis Dalessandro }
1599f48ad614SDennis Dalessandro 
set_sbus_fast_mode(struct hfi1_devdata * dd)1600f48ad614SDennis Dalessandro void set_sbus_fast_mode(struct hfi1_devdata *dd)
1601f48ad614SDennis Dalessandro {
1602f48ad614SDennis Dalessandro 	write_csr(dd, ASIC_CFG_SBUS_EXECUTE,
1603f48ad614SDennis Dalessandro 		  ASIC_CFG_SBUS_EXECUTE_FAST_MODE_SMASK);
1604f48ad614SDennis Dalessandro }
1605f48ad614SDennis Dalessandro 
clear_sbus_fast_mode(struct hfi1_devdata * dd)1606f48ad614SDennis Dalessandro void clear_sbus_fast_mode(struct hfi1_devdata *dd)
1607f48ad614SDennis Dalessandro {
1608f48ad614SDennis Dalessandro 	u64 reg, count = 0;
1609f48ad614SDennis Dalessandro 
1610f48ad614SDennis Dalessandro 	reg = read_csr(dd, ASIC_STS_SBUS_COUNTERS);
1611f48ad614SDennis Dalessandro 	while (SBUS_COUNTER(reg, EXECUTE) !=
1612f48ad614SDennis Dalessandro 	       SBUS_COUNTER(reg, RCV_DATA_VALID)) {
1613f48ad614SDennis Dalessandro 		if (count++ >= SBUS_MAX_POLL_COUNT)
1614f48ad614SDennis Dalessandro 			break;
1615f48ad614SDennis Dalessandro 		udelay(1);
1616f48ad614SDennis Dalessandro 		reg = read_csr(dd, ASIC_STS_SBUS_COUNTERS);
1617f48ad614SDennis Dalessandro 	}
1618f48ad614SDennis Dalessandro 	write_csr(dd, ASIC_CFG_SBUS_EXECUTE, 0);
1619f48ad614SDennis Dalessandro }
1620f48ad614SDennis Dalessandro 
load_firmware(struct hfi1_devdata * dd)1621f48ad614SDennis Dalessandro int load_firmware(struct hfi1_devdata *dd)
1622f48ad614SDennis Dalessandro {
1623f48ad614SDennis Dalessandro 	int ret;
1624f48ad614SDennis Dalessandro 
1625f48ad614SDennis Dalessandro 	if (fw_fabric_serdes_load) {
1626f48ad614SDennis Dalessandro 		ret = acquire_chip_resource(dd, CR_SBUS, SBUS_TIMEOUT);
1627f48ad614SDennis Dalessandro 		if (ret)
1628f48ad614SDennis Dalessandro 			return ret;
1629f48ad614SDennis Dalessandro 
1630f48ad614SDennis Dalessandro 		set_sbus_fast_mode(dd);
1631f48ad614SDennis Dalessandro 
1632f48ad614SDennis Dalessandro 		set_serdes_broadcast(dd, all_fabric_serdes_broadcast,
1633f48ad614SDennis Dalessandro 				     fabric_serdes_broadcast[dd->hfi1_id],
1634f48ad614SDennis Dalessandro 				     fabric_serdes_addrs[dd->hfi1_id],
1635f48ad614SDennis Dalessandro 				     NUM_FABRIC_SERDES);
1636f48ad614SDennis Dalessandro 		turn_off_spicos(dd, SPICO_FABRIC);
1637f48ad614SDennis Dalessandro 		do {
1638f48ad614SDennis Dalessandro 			ret = load_fabric_serdes_firmware(dd, &fw_fabric);
1639f48ad614SDennis Dalessandro 		} while (retry_firmware(dd, ret));
1640f48ad614SDennis Dalessandro 
1641f48ad614SDennis Dalessandro 		clear_sbus_fast_mode(dd);
1642f48ad614SDennis Dalessandro 		release_chip_resource(dd, CR_SBUS);
1643f48ad614SDennis Dalessandro 		if (ret)
1644f48ad614SDennis Dalessandro 			return ret;
1645f48ad614SDennis Dalessandro 	}
1646f48ad614SDennis Dalessandro 
1647f48ad614SDennis Dalessandro 	if (fw_8051_load) {
1648f48ad614SDennis Dalessandro 		do {
1649f48ad614SDennis Dalessandro 			ret = load_8051_firmware(dd, &fw_8051);
1650f48ad614SDennis Dalessandro 		} while (retry_firmware(dd, ret));
1651f48ad614SDennis Dalessandro 		if (ret)
1652f48ad614SDennis Dalessandro 			return ret;
1653f48ad614SDennis Dalessandro 	}
1654f48ad614SDennis Dalessandro 
1655b3bf270bSDean Luick 	dump_fw_version(dd);
1656f48ad614SDennis Dalessandro 	return 0;
1657f48ad614SDennis Dalessandro }
1658f48ad614SDennis Dalessandro 
hfi1_firmware_init(struct hfi1_devdata * dd)1659f48ad614SDennis Dalessandro int hfi1_firmware_init(struct hfi1_devdata *dd)
1660f48ad614SDennis Dalessandro {
1661f48ad614SDennis Dalessandro 	/* only RTL can use these */
1662f48ad614SDennis Dalessandro 	if (dd->icode != ICODE_RTL_SILICON) {
1663f48ad614SDennis Dalessandro 		fw_fabric_serdes_load = 0;
1664f48ad614SDennis Dalessandro 		fw_pcie_serdes_load = 0;
1665f48ad614SDennis Dalessandro 		fw_sbus_load = 0;
1666f48ad614SDennis Dalessandro 	}
1667f48ad614SDennis Dalessandro 
1668f48ad614SDennis Dalessandro 	/* no 8051 or QSFP on simulator */
166976ae6222SJakub Byczkowski 	if (dd->icode == ICODE_FUNCTIONAL_SIMULATOR)
1670f48ad614SDennis Dalessandro 		fw_8051_load = 0;
1671f48ad614SDennis Dalessandro 
1672f48ad614SDennis Dalessandro 	if (!fw_8051_name) {
1673f48ad614SDennis Dalessandro 		if (dd->icode == ICODE_RTL_SILICON)
1674f48ad614SDennis Dalessandro 			fw_8051_name = DEFAULT_FW_8051_NAME_ASIC;
1675f48ad614SDennis Dalessandro 		else
1676f48ad614SDennis Dalessandro 			fw_8051_name = DEFAULT_FW_8051_NAME_FPGA;
1677f48ad614SDennis Dalessandro 	}
1678f48ad614SDennis Dalessandro 	if (!fw_fabric_serdes_name)
1679f48ad614SDennis Dalessandro 		fw_fabric_serdes_name = DEFAULT_FW_FABRIC_NAME;
1680f48ad614SDennis Dalessandro 	if (!fw_sbus_name)
1681f48ad614SDennis Dalessandro 		fw_sbus_name = DEFAULT_FW_SBUS_NAME;
1682f48ad614SDennis Dalessandro 	if (!fw_pcie_serdes_name)
1683f48ad614SDennis Dalessandro 		fw_pcie_serdes_name = DEFAULT_FW_PCIE_NAME;
1684f48ad614SDennis Dalessandro 
1685f48ad614SDennis Dalessandro 	return obtain_firmware(dd);
1686f48ad614SDennis Dalessandro }
1687f48ad614SDennis Dalessandro 
1688f48ad614SDennis Dalessandro /*
1689f48ad614SDennis Dalessandro  * This function is a helper function for parse_platform_config(...) and
1690f48ad614SDennis Dalessandro  * does not check for validity of the platform configuration cache
1691f48ad614SDennis Dalessandro  * (because we know it is invalid as we are building up the cache).
1692f48ad614SDennis Dalessandro  * As such, this should not be called from anywhere other than
1693f48ad614SDennis Dalessandro  * parse_platform_config
1694f48ad614SDennis Dalessandro  */
check_meta_version(struct hfi1_devdata * dd,u32 * system_table)1695f48ad614SDennis Dalessandro static int check_meta_version(struct hfi1_devdata *dd, u32 *system_table)
1696f48ad614SDennis Dalessandro {
1697f48ad614SDennis Dalessandro 	u32 meta_ver, meta_ver_meta, ver_start, ver_len, mask;
1698f48ad614SDennis Dalessandro 	struct platform_config_cache *pcfgcache = &dd->pcfg_cache;
1699f48ad614SDennis Dalessandro 
1700f48ad614SDennis Dalessandro 	if (!system_table)
1701f48ad614SDennis Dalessandro 		return -EINVAL;
1702f48ad614SDennis Dalessandro 
1703f48ad614SDennis Dalessandro 	meta_ver_meta =
1704f48ad614SDennis Dalessandro 	*(pcfgcache->config_tables[PLATFORM_CONFIG_SYSTEM_TABLE].table_metadata
1705f48ad614SDennis Dalessandro 	+ SYSTEM_TABLE_META_VERSION);
1706f48ad614SDennis Dalessandro 
1707f48ad614SDennis Dalessandro 	mask = ((1 << METADATA_TABLE_FIELD_START_LEN_BITS) - 1);
1708f48ad614SDennis Dalessandro 	ver_start = meta_ver_meta & mask;
1709f48ad614SDennis Dalessandro 
1710f48ad614SDennis Dalessandro 	meta_ver_meta >>= METADATA_TABLE_FIELD_LEN_SHIFT;
1711f48ad614SDennis Dalessandro 
1712f48ad614SDennis Dalessandro 	mask = ((1 << METADATA_TABLE_FIELD_LEN_LEN_BITS) - 1);
1713f48ad614SDennis Dalessandro 	ver_len = meta_ver_meta & mask;
1714f48ad614SDennis Dalessandro 
1715f48ad614SDennis Dalessandro 	ver_start /= 8;
1716f48ad614SDennis Dalessandro 	meta_ver = *((u8 *)system_table + ver_start) & ((1 << ver_len) - 1);
1717f48ad614SDennis Dalessandro 
1718621515daSJakub Byczkowski 	if (meta_ver < 4) {
1719f48ad614SDennis Dalessandro 		dd_dev_info(
1720f48ad614SDennis Dalessandro 			dd, "%s:Please update platform config\n", __func__);
1721f48ad614SDennis Dalessandro 		return -EINVAL;
1722f48ad614SDennis Dalessandro 	}
1723f48ad614SDennis Dalessandro 	return 0;
1724f48ad614SDennis Dalessandro }
1725f48ad614SDennis Dalessandro 
parse_platform_config(struct hfi1_devdata * dd)1726f48ad614SDennis Dalessandro int parse_platform_config(struct hfi1_devdata *dd)
1727f48ad614SDennis Dalessandro {
1728f48ad614SDennis Dalessandro 	struct platform_config_cache *pcfgcache = &dd->pcfg_cache;
172991618604SJakub Byczkowski 	struct hfi1_pportdata *ppd = dd->pport;
1730f48ad614SDennis Dalessandro 	u32 *ptr = NULL;
1731f48ad614SDennis Dalessandro 	u32 header1 = 0, header2 = 0, magic_num = 0, crc = 0, file_length = 0;
1732f48ad614SDennis Dalessandro 	u32 record_idx = 0, table_type = 0, table_length_dwords = 0;
1733f48ad614SDennis Dalessandro 	int ret = -EINVAL; /* assume failure */
1734f48ad614SDennis Dalessandro 
1735fe4d9243SEaswar Hariharan 	/*
1736fe4d9243SEaswar Hariharan 	 * For integrated devices that did not fall back to the default file,
1737fe4d9243SEaswar Hariharan 	 * the SI tuning information for active channels is acquired from the
1738fe4d9243SEaswar Hariharan 	 * scratch register bitmap, thus there is no platform config to parse.
1739fe4d9243SEaswar Hariharan 	 * Skip parsing in these situations.
1740fe4d9243SEaswar Hariharan 	 */
174191618604SJakub Byczkowski 	if (ppd->config_from_scratch)
1742fe4d9243SEaswar Hariharan 		return 0;
1743fe4d9243SEaswar Hariharan 
1744f48ad614SDennis Dalessandro 	if (!dd->platform_config.data) {
1745fe4d9243SEaswar Hariharan 		dd_dev_err(dd, "%s: Missing config file\n", __func__);
1746*725349f8SWang Yufen 		ret = -EINVAL;
1747f48ad614SDennis Dalessandro 		goto bail;
1748f48ad614SDennis Dalessandro 	}
1749f48ad614SDennis Dalessandro 	ptr = (u32 *)dd->platform_config.data;
1750f48ad614SDennis Dalessandro 
1751f48ad614SDennis Dalessandro 	magic_num = *ptr;
1752f48ad614SDennis Dalessandro 	ptr++;
1753f48ad614SDennis Dalessandro 	if (magic_num != PLATFORM_CONFIG_MAGIC_NUM) {
1754fe4d9243SEaswar Hariharan 		dd_dev_err(dd, "%s: Bad config file\n", __func__);
1755*725349f8SWang Yufen 		ret = -EINVAL;
1756f48ad614SDennis Dalessandro 		goto bail;
1757f48ad614SDennis Dalessandro 	}
1758f48ad614SDennis Dalessandro 
1759f48ad614SDennis Dalessandro 	/* Field is file size in DWORDs */
1760f48ad614SDennis Dalessandro 	file_length = (*ptr) * 4;
17619773afb9SJakub Byczkowski 
17629773afb9SJakub Byczkowski 	/*
17639773afb9SJakub Byczkowski 	 * Length can't be larger than partition size. Assume platform
17649773afb9SJakub Byczkowski 	 * config format version 4 is being used. Interpret the file size
17659773afb9SJakub Byczkowski 	 * field as header instead by not moving the pointer.
17669773afb9SJakub Byczkowski 	 */
17679773afb9SJakub Byczkowski 	if (file_length > MAX_PLATFORM_CONFIG_FILE_SIZE) {
17689773afb9SJakub Byczkowski 		dd_dev_info(dd,
17699773afb9SJakub Byczkowski 			    "%s:File length out of bounds, using alternative format\n",
17709773afb9SJakub Byczkowski 			    __func__);
17719773afb9SJakub Byczkowski 		file_length = PLATFORM_CONFIG_FORMAT_4_FILE_SIZE;
17729773afb9SJakub Byczkowski 	} else {
1773f48ad614SDennis Dalessandro 		ptr++;
17749773afb9SJakub Byczkowski 	}
1775f48ad614SDennis Dalessandro 
1776f48ad614SDennis Dalessandro 	if (file_length > dd->platform_config.size) {
1777f48ad614SDennis Dalessandro 		dd_dev_info(dd, "%s:File claims to be larger than read size\n",
1778f48ad614SDennis Dalessandro 			    __func__);
1779*725349f8SWang Yufen 		ret = -EINVAL;
1780f48ad614SDennis Dalessandro 		goto bail;
1781f48ad614SDennis Dalessandro 	} else if (file_length < dd->platform_config.size) {
1782f48ad614SDennis Dalessandro 		dd_dev_info(dd,
1783f48ad614SDennis Dalessandro 			    "%s:File claims to be smaller than read size, continuing\n",
1784f48ad614SDennis Dalessandro 			    __func__);
1785f48ad614SDennis Dalessandro 	}
1786f48ad614SDennis Dalessandro 	/* exactly equal, perfection */
1787f48ad614SDennis Dalessandro 
1788f48ad614SDennis Dalessandro 	/*
1789f48ad614SDennis Dalessandro 	 * In both cases where we proceed, using the self-reported file length
17909773afb9SJakub Byczkowski 	 * is the safer option. In case of old format a predefined value is
17919773afb9SJakub Byczkowski 	 * being used.
1792f48ad614SDennis Dalessandro 	 */
1793f48ad614SDennis Dalessandro 	while (ptr < (u32 *)(dd->platform_config.data + file_length)) {
1794f48ad614SDennis Dalessandro 		header1 = *ptr;
1795f48ad614SDennis Dalessandro 		header2 = *(ptr + 1);
1796f48ad614SDennis Dalessandro 		if (header1 != ~header2) {
1797fe4d9243SEaswar Hariharan 			dd_dev_err(dd, "%s: Failed validation at offset %ld\n",
1798f48ad614SDennis Dalessandro 				   __func__, (ptr - (u32 *)
1799f48ad614SDennis Dalessandro 					      dd->platform_config.data));
1800*725349f8SWang Yufen 			ret = -EINVAL;
1801f48ad614SDennis Dalessandro 			goto bail;
1802f48ad614SDennis Dalessandro 		}
1803f48ad614SDennis Dalessandro 
1804f48ad614SDennis Dalessandro 		record_idx = *ptr &
1805f48ad614SDennis Dalessandro 			((1 << PLATFORM_CONFIG_HEADER_RECORD_IDX_LEN_BITS) - 1);
1806f48ad614SDennis Dalessandro 
1807f48ad614SDennis Dalessandro 		table_length_dwords = (*ptr >>
1808f48ad614SDennis Dalessandro 				PLATFORM_CONFIG_HEADER_TABLE_LENGTH_SHIFT) &
1809f48ad614SDennis Dalessandro 		      ((1 << PLATFORM_CONFIG_HEADER_TABLE_LENGTH_LEN_BITS) - 1);
1810f48ad614SDennis Dalessandro 
1811f48ad614SDennis Dalessandro 		table_type = (*ptr >> PLATFORM_CONFIG_HEADER_TABLE_TYPE_SHIFT) &
1812f48ad614SDennis Dalessandro 			((1 << PLATFORM_CONFIG_HEADER_TABLE_TYPE_LEN_BITS) - 1);
1813f48ad614SDennis Dalessandro 
1814f48ad614SDennis Dalessandro 		/* Done with this set of headers */
1815f48ad614SDennis Dalessandro 		ptr += 2;
1816f48ad614SDennis Dalessandro 
1817f48ad614SDennis Dalessandro 		if (record_idx) {
1818f48ad614SDennis Dalessandro 			/* data table */
1819f48ad614SDennis Dalessandro 			switch (table_type) {
1820f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_SYSTEM_TABLE:
1821f48ad614SDennis Dalessandro 				pcfgcache->config_tables[table_type].num_table =
1822f48ad614SDennis Dalessandro 									1;
1823f48ad614SDennis Dalessandro 				ret = check_meta_version(dd, ptr);
1824f48ad614SDennis Dalessandro 				if (ret)
1825f48ad614SDennis Dalessandro 					goto bail;
1826f48ad614SDennis Dalessandro 				break;
1827f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_PORT_TABLE:
1828f48ad614SDennis Dalessandro 				pcfgcache->config_tables[table_type].num_table =
1829f48ad614SDennis Dalessandro 									2;
1830f48ad614SDennis Dalessandro 				break;
1831f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_RX_PRESET_TABLE:
1832f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_TX_PRESET_TABLE:
1833f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
1834f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
1835f48ad614SDennis Dalessandro 				pcfgcache->config_tables[table_type].num_table =
1836f48ad614SDennis Dalessandro 							table_length_dwords;
1837f48ad614SDennis Dalessandro 				break;
1838f48ad614SDennis Dalessandro 			default:
1839fe4d9243SEaswar Hariharan 				dd_dev_err(dd,
1840f48ad614SDennis Dalessandro 					   "%s: Unknown data table %d, offset %ld\n",
1841f48ad614SDennis Dalessandro 					   __func__, table_type,
1842f48ad614SDennis Dalessandro 					   (ptr - (u32 *)
1843f48ad614SDennis Dalessandro 					    dd->platform_config.data));
1844*725349f8SWang Yufen 				ret = -EINVAL;
1845f48ad614SDennis Dalessandro 				goto bail; /* We don't trust this file now */
1846f48ad614SDennis Dalessandro 			}
1847f48ad614SDennis Dalessandro 			pcfgcache->config_tables[table_type].table = ptr;
1848f48ad614SDennis Dalessandro 		} else {
1849f48ad614SDennis Dalessandro 			/* metadata table */
1850f48ad614SDennis Dalessandro 			switch (table_type) {
1851f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_SYSTEM_TABLE:
1852f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_PORT_TABLE:
1853f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_RX_PRESET_TABLE:
1854f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_TX_PRESET_TABLE:
1855f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
1856f48ad614SDennis Dalessandro 			case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
1857f48ad614SDennis Dalessandro 				break;
1858f48ad614SDennis Dalessandro 			default:
1859fe4d9243SEaswar Hariharan 				dd_dev_err(dd,
1860f48ad614SDennis Dalessandro 					   "%s: Unknown meta table %d, offset %ld\n",
1861f48ad614SDennis Dalessandro 					   __func__, table_type,
1862f48ad614SDennis Dalessandro 					   (ptr -
1863f48ad614SDennis Dalessandro 					    (u32 *)dd->platform_config.data));
1864*725349f8SWang Yufen 				ret = -EINVAL;
1865f48ad614SDennis Dalessandro 				goto bail; /* We don't trust this file now */
1866f48ad614SDennis Dalessandro 			}
1867f48ad614SDennis Dalessandro 			pcfgcache->config_tables[table_type].table_metadata =
1868f48ad614SDennis Dalessandro 									ptr;
1869f48ad614SDennis Dalessandro 		}
1870f48ad614SDennis Dalessandro 
1871f48ad614SDennis Dalessandro 		/* Calculate and check table crc */
1872f48ad614SDennis Dalessandro 		crc = crc32_le(~(u32)0, (unsigned char const *)ptr,
1873f48ad614SDennis Dalessandro 			       (table_length_dwords * 4));
1874f48ad614SDennis Dalessandro 		crc ^= ~(u32)0;
1875f48ad614SDennis Dalessandro 
1876f48ad614SDennis Dalessandro 		/* Jump the table */
1877f48ad614SDennis Dalessandro 		ptr += table_length_dwords;
1878f48ad614SDennis Dalessandro 		if (crc != *ptr) {
1879fe4d9243SEaswar Hariharan 			dd_dev_err(dd, "%s: Failed CRC check at offset %ld\n",
1880f48ad614SDennis Dalessandro 				   __func__, (ptr -
1881fe4d9243SEaswar Hariharan 				   (u32 *)dd->platform_config.data));
18824c7d9c69SWang Wensheng 			ret = -EINVAL;
1883f48ad614SDennis Dalessandro 			goto bail;
1884f48ad614SDennis Dalessandro 		}
1885f48ad614SDennis Dalessandro 		/* Jump the CRC DWORD */
1886f48ad614SDennis Dalessandro 		ptr++;
1887f48ad614SDennis Dalessandro 	}
1888f48ad614SDennis Dalessandro 
1889f48ad614SDennis Dalessandro 	pcfgcache->cache_valid = 1;
1890f48ad614SDennis Dalessandro 	return 0;
1891f48ad614SDennis Dalessandro bail:
1892f48ad614SDennis Dalessandro 	memset(pcfgcache, 0, sizeof(struct platform_config_cache));
1893f48ad614SDennis Dalessandro 	return ret;
1894f48ad614SDennis Dalessandro }
1895f48ad614SDennis Dalessandro 
get_integrated_platform_config_field(struct hfi1_devdata * dd,enum platform_config_table_type_encoding table_type,int field_index,u32 * data)1896fe4d9243SEaswar Hariharan static void get_integrated_platform_config_field(
1897fe4d9243SEaswar Hariharan 		struct hfi1_devdata *dd,
1898fe4d9243SEaswar Hariharan 		enum platform_config_table_type_encoding table_type,
1899fe4d9243SEaswar Hariharan 		int field_index, u32 *data)
1900fe4d9243SEaswar Hariharan {
1901fe4d9243SEaswar Hariharan 	struct hfi1_pportdata *ppd = dd->pport;
1902fe4d9243SEaswar Hariharan 	u8 *cache = ppd->qsfp_info.cache;
1903fe4d9243SEaswar Hariharan 	u32 tx_preset = 0;
1904fe4d9243SEaswar Hariharan 
1905fe4d9243SEaswar Hariharan 	switch (table_type) {
1906fe4d9243SEaswar Hariharan 	case PLATFORM_CONFIG_SYSTEM_TABLE:
1907fe4d9243SEaswar Hariharan 		if (field_index == SYSTEM_TABLE_QSFP_POWER_CLASS_MAX)
1908fe4d9243SEaswar Hariharan 			*data = ppd->max_power_class;
1909fe4d9243SEaswar Hariharan 		else if (field_index == SYSTEM_TABLE_QSFP_ATTENUATION_DEFAULT_25G)
1910fe4d9243SEaswar Hariharan 			*data = ppd->default_atten;
1911fe4d9243SEaswar Hariharan 		break;
1912fe4d9243SEaswar Hariharan 	case PLATFORM_CONFIG_PORT_TABLE:
1913fe4d9243SEaswar Hariharan 		if (field_index == PORT_TABLE_PORT_TYPE)
1914fe4d9243SEaswar Hariharan 			*data = ppd->port_type;
1915fe4d9243SEaswar Hariharan 		else if (field_index == PORT_TABLE_LOCAL_ATTEN_25G)
1916fe4d9243SEaswar Hariharan 			*data = ppd->local_atten;
1917fe4d9243SEaswar Hariharan 		else if (field_index == PORT_TABLE_REMOTE_ATTEN_25G)
1918fe4d9243SEaswar Hariharan 			*data = ppd->remote_atten;
1919fe4d9243SEaswar Hariharan 		break;
1920fe4d9243SEaswar Hariharan 	case PLATFORM_CONFIG_RX_PRESET_TABLE:
1921fe4d9243SEaswar Hariharan 		if (field_index == RX_PRESET_TABLE_QSFP_RX_CDR_APPLY)
1922fe4d9243SEaswar Hariharan 			*data = (ppd->rx_preset & QSFP_RX_CDR_APPLY_SMASK) >>
1923fe4d9243SEaswar Hariharan 				QSFP_RX_CDR_APPLY_SHIFT;
1924fe4d9243SEaswar Hariharan 		else if (field_index == RX_PRESET_TABLE_QSFP_RX_EMP_APPLY)
1925fe4d9243SEaswar Hariharan 			*data = (ppd->rx_preset & QSFP_RX_EMP_APPLY_SMASK) >>
1926fe4d9243SEaswar Hariharan 				QSFP_RX_EMP_APPLY_SHIFT;
1927fe4d9243SEaswar Hariharan 		else if (field_index == RX_PRESET_TABLE_QSFP_RX_AMP_APPLY)
1928fe4d9243SEaswar Hariharan 			*data = (ppd->rx_preset & QSFP_RX_AMP_APPLY_SMASK) >>
1929fe4d9243SEaswar Hariharan 				QSFP_RX_AMP_APPLY_SHIFT;
1930fe4d9243SEaswar Hariharan 		else if (field_index == RX_PRESET_TABLE_QSFP_RX_CDR)
1931fe4d9243SEaswar Hariharan 			*data = (ppd->rx_preset & QSFP_RX_CDR_SMASK) >>
1932fe4d9243SEaswar Hariharan 				QSFP_RX_CDR_SHIFT;
1933fe4d9243SEaswar Hariharan 		else if (field_index == RX_PRESET_TABLE_QSFP_RX_EMP)
1934fe4d9243SEaswar Hariharan 			*data = (ppd->rx_preset & QSFP_RX_EMP_SMASK) >>
1935fe4d9243SEaswar Hariharan 				QSFP_RX_EMP_SHIFT;
1936fe4d9243SEaswar Hariharan 		else if (field_index == RX_PRESET_TABLE_QSFP_RX_AMP)
1937fe4d9243SEaswar Hariharan 			*data = (ppd->rx_preset & QSFP_RX_AMP_SMASK) >>
1938fe4d9243SEaswar Hariharan 				QSFP_RX_AMP_SHIFT;
1939fe4d9243SEaswar Hariharan 		break;
1940fe4d9243SEaswar Hariharan 	case PLATFORM_CONFIG_TX_PRESET_TABLE:
1941fe4d9243SEaswar Hariharan 		if (cache[QSFP_EQ_INFO_OFFS] & 0x4)
1942fe4d9243SEaswar Hariharan 			tx_preset = ppd->tx_preset_eq;
1943fe4d9243SEaswar Hariharan 		else
1944fe4d9243SEaswar Hariharan 			tx_preset = ppd->tx_preset_noeq;
1945fe4d9243SEaswar Hariharan 		if (field_index == TX_PRESET_TABLE_PRECUR)
1946fe4d9243SEaswar Hariharan 			*data = (tx_preset & TX_PRECUR_SMASK) >>
1947fe4d9243SEaswar Hariharan 				TX_PRECUR_SHIFT;
1948fe4d9243SEaswar Hariharan 		else if (field_index == TX_PRESET_TABLE_ATTN)
1949fe4d9243SEaswar Hariharan 			*data = (tx_preset & TX_ATTN_SMASK) >>
1950fe4d9243SEaswar Hariharan 				TX_ATTN_SHIFT;
1951fe4d9243SEaswar Hariharan 		else if (field_index == TX_PRESET_TABLE_POSTCUR)
1952fe4d9243SEaswar Hariharan 			*data = (tx_preset & TX_POSTCUR_SMASK) >>
1953fe4d9243SEaswar Hariharan 				TX_POSTCUR_SHIFT;
1954fe4d9243SEaswar Hariharan 		else if (field_index == TX_PRESET_TABLE_QSFP_TX_CDR_APPLY)
1955fe4d9243SEaswar Hariharan 			*data = (tx_preset & QSFP_TX_CDR_APPLY_SMASK) >>
1956fe4d9243SEaswar Hariharan 				QSFP_TX_CDR_APPLY_SHIFT;
1957fe4d9243SEaswar Hariharan 		else if (field_index == TX_PRESET_TABLE_QSFP_TX_EQ_APPLY)
1958fe4d9243SEaswar Hariharan 			*data = (tx_preset & QSFP_TX_EQ_APPLY_SMASK) >>
1959fe4d9243SEaswar Hariharan 				QSFP_TX_EQ_APPLY_SHIFT;
1960fe4d9243SEaswar Hariharan 		else if (field_index == TX_PRESET_TABLE_QSFP_TX_CDR)
1961fe4d9243SEaswar Hariharan 			*data = (tx_preset & QSFP_TX_CDR_SMASK) >>
1962fe4d9243SEaswar Hariharan 				QSFP_TX_CDR_SHIFT;
1963fe4d9243SEaswar Hariharan 		else if (field_index == TX_PRESET_TABLE_QSFP_TX_EQ)
1964fe4d9243SEaswar Hariharan 			*data = (tx_preset & QSFP_TX_EQ_SMASK) >>
1965fe4d9243SEaswar Hariharan 				QSFP_TX_EQ_SHIFT;
1966fe4d9243SEaswar Hariharan 		break;
1967fe4d9243SEaswar Hariharan 	case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
1968fe4d9243SEaswar Hariharan 	case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
1969fe4d9243SEaswar Hariharan 	default:
1970fe4d9243SEaswar Hariharan 		break;
1971fe4d9243SEaswar Hariharan 	}
1972fe4d9243SEaswar Hariharan }
1973fe4d9243SEaswar Hariharan 
get_platform_fw_field_metadata(struct hfi1_devdata * dd,int table,int field,u32 * field_len_bits,u32 * field_start_bits)1974f48ad614SDennis Dalessandro static int get_platform_fw_field_metadata(struct hfi1_devdata *dd, int table,
1975f48ad614SDennis Dalessandro 					  int field, u32 *field_len_bits,
1976f48ad614SDennis Dalessandro 					  u32 *field_start_bits)
1977f48ad614SDennis Dalessandro {
1978f48ad614SDennis Dalessandro 	struct platform_config_cache *pcfgcache = &dd->pcfg_cache;
1979f48ad614SDennis Dalessandro 	u32 *src_ptr = NULL;
1980f48ad614SDennis Dalessandro 
1981f48ad614SDennis Dalessandro 	if (!pcfgcache->cache_valid)
1982f48ad614SDennis Dalessandro 		return -EINVAL;
1983f48ad614SDennis Dalessandro 
1984f48ad614SDennis Dalessandro 	switch (table) {
1985f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_SYSTEM_TABLE:
1986f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_PORT_TABLE:
1987f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_RX_PRESET_TABLE:
1988f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_TX_PRESET_TABLE:
1989f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
1990f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
1991f48ad614SDennis Dalessandro 		if (field && field < platform_config_table_limits[table])
1992f48ad614SDennis Dalessandro 			src_ptr =
1993f48ad614SDennis Dalessandro 			pcfgcache->config_tables[table].table_metadata + field;
1994f48ad614SDennis Dalessandro 		break;
1995f48ad614SDennis Dalessandro 	default:
1996f48ad614SDennis Dalessandro 		dd_dev_info(dd, "%s: Unknown table\n", __func__);
1997f48ad614SDennis Dalessandro 		break;
1998f48ad614SDennis Dalessandro 	}
1999f48ad614SDennis Dalessandro 
2000f48ad614SDennis Dalessandro 	if (!src_ptr)
2001f48ad614SDennis Dalessandro 		return -EINVAL;
2002f48ad614SDennis Dalessandro 
2003f48ad614SDennis Dalessandro 	if (field_start_bits)
2004f48ad614SDennis Dalessandro 		*field_start_bits = *src_ptr &
2005f48ad614SDennis Dalessandro 		      ((1 << METADATA_TABLE_FIELD_START_LEN_BITS) - 1);
2006f48ad614SDennis Dalessandro 
2007f48ad614SDennis Dalessandro 	if (field_len_bits)
2008f48ad614SDennis Dalessandro 		*field_len_bits = (*src_ptr >> METADATA_TABLE_FIELD_LEN_SHIFT)
2009f48ad614SDennis Dalessandro 		       & ((1 << METADATA_TABLE_FIELD_LEN_LEN_BITS) - 1);
2010f48ad614SDennis Dalessandro 
2011f48ad614SDennis Dalessandro 	return 0;
2012f48ad614SDennis Dalessandro }
2013f48ad614SDennis Dalessandro 
2014f48ad614SDennis Dalessandro /* This is the central interface to getting data out of the platform config
2015f48ad614SDennis Dalessandro  * file. It depends on parse_platform_config() having populated the
2016f48ad614SDennis Dalessandro  * platform_config_cache in hfi1_devdata, and checks the cache_valid member to
2017f48ad614SDennis Dalessandro  * validate the sanity of the cache.
2018f48ad614SDennis Dalessandro  *
2019f48ad614SDennis Dalessandro  * The non-obvious parameters:
2020f48ad614SDennis Dalessandro  * @table_index: Acts as a look up key into which instance of the tables the
2021f48ad614SDennis Dalessandro  * relevant field is fetched from.
2022f48ad614SDennis Dalessandro  *
2023f48ad614SDennis Dalessandro  * This applies to the data tables that have multiple instances. The port table
2024f48ad614SDennis Dalessandro  * is an exception to this rule as each HFI only has one port and thus the
2025f48ad614SDennis Dalessandro  * relevant table can be distinguished by hfi_id.
2026f48ad614SDennis Dalessandro  *
2027f48ad614SDennis Dalessandro  * @data: pointer to memory that will be populated with the field requested.
2028f48ad614SDennis Dalessandro  * @len: length of memory pointed by @data in bytes.
2029f48ad614SDennis Dalessandro  */
get_platform_config_field(struct hfi1_devdata * dd,enum platform_config_table_type_encoding table_type,int table_index,int field_index,u32 * data,u32 len)2030f48ad614SDennis Dalessandro int get_platform_config_field(struct hfi1_devdata *dd,
2031f48ad614SDennis Dalessandro 			      enum platform_config_table_type_encoding
2032f48ad614SDennis Dalessandro 			      table_type, int table_index, int field_index,
2033f48ad614SDennis Dalessandro 			      u32 *data, u32 len)
2034f48ad614SDennis Dalessandro {
2035f48ad614SDennis Dalessandro 	int ret = 0, wlen = 0, seek = 0;
2036f48ad614SDennis Dalessandro 	u32 field_len_bits = 0, field_start_bits = 0, *src_ptr = NULL;
2037f48ad614SDennis Dalessandro 	struct platform_config_cache *pcfgcache = &dd->pcfg_cache;
203891618604SJakub Byczkowski 	struct hfi1_pportdata *ppd = dd->pport;
2039f48ad614SDennis Dalessandro 
2040f48ad614SDennis Dalessandro 	if (data)
2041f48ad614SDennis Dalessandro 		memset(data, 0, len);
2042f48ad614SDennis Dalessandro 	else
2043f48ad614SDennis Dalessandro 		return -EINVAL;
2044f48ad614SDennis Dalessandro 
204591618604SJakub Byczkowski 	if (ppd->config_from_scratch) {
2046fe4d9243SEaswar Hariharan 		/*
2047fe4d9243SEaswar Hariharan 		 * Use saved configuration from ppd for integrated platforms
2048fe4d9243SEaswar Hariharan 		 */
2049fe4d9243SEaswar Hariharan 		get_integrated_platform_config_field(dd, table_type,
2050fe4d9243SEaswar Hariharan 						     field_index, data);
2051fe4d9243SEaswar Hariharan 		return 0;
2052fe4d9243SEaswar Hariharan 	}
2053fe4d9243SEaswar Hariharan 
2054f48ad614SDennis Dalessandro 	ret = get_platform_fw_field_metadata(dd, table_type, field_index,
2055f48ad614SDennis Dalessandro 					     &field_len_bits,
2056f48ad614SDennis Dalessandro 					     &field_start_bits);
2057f48ad614SDennis Dalessandro 	if (ret)
2058f48ad614SDennis Dalessandro 		return -EINVAL;
2059f48ad614SDennis Dalessandro 
2060f48ad614SDennis Dalessandro 	/* Convert length to bits */
2061f48ad614SDennis Dalessandro 	len *= 8;
2062f48ad614SDennis Dalessandro 
2063f48ad614SDennis Dalessandro 	/* Our metadata function checked cache_valid and field_index for us */
2064f48ad614SDennis Dalessandro 	switch (table_type) {
2065f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_SYSTEM_TABLE:
2066f48ad614SDennis Dalessandro 		src_ptr = pcfgcache->config_tables[table_type].table;
2067f48ad614SDennis Dalessandro 
2068f48ad614SDennis Dalessandro 		if (field_index != SYSTEM_TABLE_QSFP_POWER_CLASS_MAX) {
2069f48ad614SDennis Dalessandro 			if (len < field_len_bits)
2070f48ad614SDennis Dalessandro 				return -EINVAL;
2071f48ad614SDennis Dalessandro 
2072f48ad614SDennis Dalessandro 			seek = field_start_bits / 8;
2073f48ad614SDennis Dalessandro 			wlen = field_len_bits / 8;
2074f48ad614SDennis Dalessandro 
2075f48ad614SDennis Dalessandro 			src_ptr = (u32 *)((u8 *)src_ptr + seek);
2076f48ad614SDennis Dalessandro 
2077f48ad614SDennis Dalessandro 			/*
2078f48ad614SDennis Dalessandro 			 * We expect the field to be byte aligned and whole byte
2079f48ad614SDennis Dalessandro 			 * lengths if we are here
2080f48ad614SDennis Dalessandro 			 */
2081f48ad614SDennis Dalessandro 			memcpy(data, src_ptr, wlen);
2082f48ad614SDennis Dalessandro 			return 0;
2083f48ad614SDennis Dalessandro 		}
2084f48ad614SDennis Dalessandro 		break;
2085f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_PORT_TABLE:
2086f48ad614SDennis Dalessandro 		/* Port table is 4 DWORDS */
2087f48ad614SDennis Dalessandro 		src_ptr = dd->hfi1_id ?
2088f48ad614SDennis Dalessandro 			pcfgcache->config_tables[table_type].table + 4 :
2089f48ad614SDennis Dalessandro 			pcfgcache->config_tables[table_type].table;
2090f48ad614SDennis Dalessandro 		break;
2091f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_RX_PRESET_TABLE:
2092f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_TX_PRESET_TABLE:
2093f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
2094f48ad614SDennis Dalessandro 	case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
2095f48ad614SDennis Dalessandro 		src_ptr = pcfgcache->config_tables[table_type].table;
2096f48ad614SDennis Dalessandro 
2097f48ad614SDennis Dalessandro 		if (table_index <
2098f48ad614SDennis Dalessandro 			pcfgcache->config_tables[table_type].num_table)
2099f48ad614SDennis Dalessandro 			src_ptr += table_index;
2100f48ad614SDennis Dalessandro 		else
2101f48ad614SDennis Dalessandro 			src_ptr = NULL;
2102f48ad614SDennis Dalessandro 		break;
2103f48ad614SDennis Dalessandro 	default:
2104f48ad614SDennis Dalessandro 		dd_dev_info(dd, "%s: Unknown table\n", __func__);
2105f48ad614SDennis Dalessandro 		break;
2106f48ad614SDennis Dalessandro 	}
2107f48ad614SDennis Dalessandro 
2108f48ad614SDennis Dalessandro 	if (!src_ptr || len < field_len_bits)
2109f48ad614SDennis Dalessandro 		return -EINVAL;
2110f48ad614SDennis Dalessandro 
2111f48ad614SDennis Dalessandro 	src_ptr += (field_start_bits / 32);
2112f48ad614SDennis Dalessandro 	*data = (*src_ptr >> (field_start_bits % 32)) &
2113f48ad614SDennis Dalessandro 			((1 << field_len_bits) - 1);
2114f48ad614SDennis Dalessandro 
2115f48ad614SDennis Dalessandro 	return 0;
2116f48ad614SDennis Dalessandro }
2117f48ad614SDennis Dalessandro 
2118f48ad614SDennis Dalessandro /*
2119f48ad614SDennis Dalessandro  * Download the firmware needed for the Gen3 PCIe SerDes.  An update
2120f48ad614SDennis Dalessandro  * to the SBus firmware is needed before updating the PCIe firmware.
2121f48ad614SDennis Dalessandro  *
2122f48ad614SDennis Dalessandro  * Note: caller must be holding the SBus resource.
2123f48ad614SDennis Dalessandro  */
load_pcie_firmware(struct hfi1_devdata * dd)2124f48ad614SDennis Dalessandro int load_pcie_firmware(struct hfi1_devdata *dd)
2125f48ad614SDennis Dalessandro {
2126f48ad614SDennis Dalessandro 	int ret = 0;
2127f48ad614SDennis Dalessandro 
2128f48ad614SDennis Dalessandro 	/* both firmware loads below use the SBus */
2129f48ad614SDennis Dalessandro 	set_sbus_fast_mode(dd);
2130f48ad614SDennis Dalessandro 
2131f48ad614SDennis Dalessandro 	if (fw_sbus_load) {
2132f48ad614SDennis Dalessandro 		turn_off_spicos(dd, SPICO_SBUS);
2133f48ad614SDennis Dalessandro 		do {
2134f48ad614SDennis Dalessandro 			ret = load_sbus_firmware(dd, &fw_sbus);
2135f48ad614SDennis Dalessandro 		} while (retry_firmware(dd, ret));
2136f48ad614SDennis Dalessandro 		if (ret)
2137f48ad614SDennis Dalessandro 			goto done;
2138f48ad614SDennis Dalessandro 	}
2139f48ad614SDennis Dalessandro 
2140f48ad614SDennis Dalessandro 	if (fw_pcie_serdes_load) {
2141f48ad614SDennis Dalessandro 		dd_dev_info(dd, "Setting PCIe SerDes broadcast\n");
2142f48ad614SDennis Dalessandro 		set_serdes_broadcast(dd, all_pcie_serdes_broadcast,
2143f48ad614SDennis Dalessandro 				     pcie_serdes_broadcast[dd->hfi1_id],
2144f48ad614SDennis Dalessandro 				     pcie_serdes_addrs[dd->hfi1_id],
2145f48ad614SDennis Dalessandro 				     NUM_PCIE_SERDES);
2146f48ad614SDennis Dalessandro 		do {
2147f48ad614SDennis Dalessandro 			ret = load_pcie_serdes_firmware(dd, &fw_pcie);
2148f48ad614SDennis Dalessandro 		} while (retry_firmware(dd, ret));
2149f48ad614SDennis Dalessandro 		if (ret)
2150f48ad614SDennis Dalessandro 			goto done;
2151f48ad614SDennis Dalessandro 	}
2152f48ad614SDennis Dalessandro 
2153f48ad614SDennis Dalessandro done:
2154f48ad614SDennis Dalessandro 	clear_sbus_fast_mode(dd);
2155f48ad614SDennis Dalessandro 
2156f48ad614SDennis Dalessandro 	return ret;
2157f48ad614SDennis Dalessandro }
2158f48ad614SDennis Dalessandro 
2159f48ad614SDennis Dalessandro /*
2160f48ad614SDennis Dalessandro  * Read the GUID from the hardware, store it in dd.
2161f48ad614SDennis Dalessandro  */
read_guid(struct hfi1_devdata * dd)2162f48ad614SDennis Dalessandro void read_guid(struct hfi1_devdata *dd)
2163f48ad614SDennis Dalessandro {
2164f48ad614SDennis Dalessandro 	/* Take the DC out of reset to get a valid GUID value */
2165f48ad614SDennis Dalessandro 	write_csr(dd, CCE_DC_CTRL, 0);
2166f48ad614SDennis Dalessandro 	(void)read_csr(dd, CCE_DC_CTRL);
2167f48ad614SDennis Dalessandro 
2168f48ad614SDennis Dalessandro 	dd->base_guid = read_csr(dd, DC_DC8051_CFG_LOCAL_GUID);
2169f48ad614SDennis Dalessandro 	dd_dev_info(dd, "GUID %llx",
2170f48ad614SDennis Dalessandro 		    (unsigned long long)dd->base_guid);
2171f48ad614SDennis Dalessandro }
2172b3bf270bSDean Luick 
2173b3bf270bSDean Luick /* read and display firmware version info */
dump_fw_version(struct hfi1_devdata * dd)2174b3bf270bSDean Luick static void dump_fw_version(struct hfi1_devdata *dd)
2175b3bf270bSDean Luick {
2176b3bf270bSDean Luick 	u32 pcie_vers[NUM_PCIE_SERDES];
2177b3bf270bSDean Luick 	u32 fabric_vers[NUM_FABRIC_SERDES];
2178b3bf270bSDean Luick 	u32 sbus_vers;
2179b3bf270bSDean Luick 	int i;
2180b3bf270bSDean Luick 	int all_same;
2181b3bf270bSDean Luick 	int ret;
2182b3bf270bSDean Luick 	u8 rcv_addr;
2183b3bf270bSDean Luick 
2184b3bf270bSDean Luick 	ret = acquire_chip_resource(dd, CR_SBUS, SBUS_TIMEOUT);
2185b3bf270bSDean Luick 	if (ret) {
2186b3bf270bSDean Luick 		dd_dev_err(dd, "Unable to acquire SBus to read firmware versions\n");
2187b3bf270bSDean Luick 		return;
2188b3bf270bSDean Luick 	}
2189b3bf270bSDean Luick 
2190b3bf270bSDean Luick 	/* set fast mode */
2191b3bf270bSDean Luick 	set_sbus_fast_mode(dd);
2192b3bf270bSDean Luick 
2193b3bf270bSDean Luick 	/* read version for SBus Master */
2194b3bf270bSDean Luick 	sbus_request(dd, SBUS_MASTER_BROADCAST, 0x02, WRITE_SBUS_RECEIVER, 0);
2195b3bf270bSDean Luick 	sbus_request(dd, SBUS_MASTER_BROADCAST, 0x07, WRITE_SBUS_RECEIVER, 0x1);
2196b3bf270bSDean Luick 	/* wait for interrupt to be processed */
2197b3bf270bSDean Luick 	usleep_range(10000, 11000);
2198b3bf270bSDean Luick 	sbus_vers = sbus_read(dd, SBUS_MASTER_BROADCAST, 0x08, 0x1);
2199b3bf270bSDean Luick 	dd_dev_info(dd, "SBus Master firmware version 0x%08x\n", sbus_vers);
2200b3bf270bSDean Luick 
2201b3bf270bSDean Luick 	/* read version for PCIe SerDes */
2202b3bf270bSDean Luick 	all_same = 1;
2203b3bf270bSDean Luick 	pcie_vers[0] = 0;
2204b3bf270bSDean Luick 	for (i = 0; i < NUM_PCIE_SERDES; i++) {
2205b3bf270bSDean Luick 		rcv_addr = pcie_serdes_addrs[dd->hfi1_id][i];
2206b3bf270bSDean Luick 		sbus_request(dd, rcv_addr, 0x03, WRITE_SBUS_RECEIVER, 0);
2207b3bf270bSDean Luick 		/* wait for interrupt to be processed */
2208b3bf270bSDean Luick 		usleep_range(10000, 11000);
2209b3bf270bSDean Luick 		pcie_vers[i] = sbus_read(dd, rcv_addr, 0x04, 0x0);
2210b3bf270bSDean Luick 		if (i > 0 && pcie_vers[0] != pcie_vers[i])
2211b3bf270bSDean Luick 			all_same = 0;
2212b3bf270bSDean Luick 	}
2213b3bf270bSDean Luick 
2214b3bf270bSDean Luick 	if (all_same) {
2215b3bf270bSDean Luick 		dd_dev_info(dd, "PCIe SerDes firmware version 0x%x\n",
2216b3bf270bSDean Luick 			    pcie_vers[0]);
2217b3bf270bSDean Luick 	} else {
2218b3bf270bSDean Luick 		dd_dev_warn(dd, "PCIe SerDes do not have the same firmware version\n");
2219b3bf270bSDean Luick 		for (i = 0; i < NUM_PCIE_SERDES; i++) {
2220b3bf270bSDean Luick 			dd_dev_info(dd,
2221b3bf270bSDean Luick 				    "PCIe SerDes lane %d firmware version 0x%x\n",
2222b3bf270bSDean Luick 				    i, pcie_vers[i]);
2223b3bf270bSDean Luick 		}
2224b3bf270bSDean Luick 	}
2225b3bf270bSDean Luick 
2226b3bf270bSDean Luick 	/* read version for fabric SerDes */
2227b3bf270bSDean Luick 	all_same = 1;
2228b3bf270bSDean Luick 	fabric_vers[0] = 0;
2229b3bf270bSDean Luick 	for (i = 0; i < NUM_FABRIC_SERDES; i++) {
2230b3bf270bSDean Luick 		rcv_addr = fabric_serdes_addrs[dd->hfi1_id][i];
2231b3bf270bSDean Luick 		sbus_request(dd, rcv_addr, 0x03, WRITE_SBUS_RECEIVER, 0);
2232b3bf270bSDean Luick 		/* wait for interrupt to be processed */
2233b3bf270bSDean Luick 		usleep_range(10000, 11000);
2234b3bf270bSDean Luick 		fabric_vers[i] = sbus_read(dd, rcv_addr, 0x04, 0x0);
2235b3bf270bSDean Luick 		if (i > 0 && fabric_vers[0] != fabric_vers[i])
2236b3bf270bSDean Luick 			all_same = 0;
2237b3bf270bSDean Luick 	}
2238b3bf270bSDean Luick 
2239b3bf270bSDean Luick 	if (all_same) {
2240b3bf270bSDean Luick 		dd_dev_info(dd, "Fabric SerDes firmware version 0x%x\n",
2241b3bf270bSDean Luick 			    fabric_vers[0]);
2242b3bf270bSDean Luick 	} else {
2243b3bf270bSDean Luick 		dd_dev_warn(dd, "Fabric SerDes do not have the same firmware version\n");
2244b3bf270bSDean Luick 		for (i = 0; i < NUM_FABRIC_SERDES; i++) {
2245b3bf270bSDean Luick 			dd_dev_info(dd,
2246b3bf270bSDean Luick 				    "Fabric SerDes lane %d firmware version 0x%x\n",
2247b3bf270bSDean Luick 				    i, fabric_vers[i]);
2248b3bf270bSDean Luick 		}
2249b3bf270bSDean Luick 	}
2250b3bf270bSDean Luick 
2251b3bf270bSDean Luick 	clear_sbus_fast_mode(dd);
2252b3bf270bSDean Luick 	release_chip_resource(dd, CR_SBUS);
2253b3bf270bSDean Luick }
2254