xref: /linux/drivers/net/ethernet/meta/fbnic/fbnic_fw.c (revision 2ed2e359dea752e7758d29a423033031a0b96584)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
3 
4 #include <linux/bitfield.h>
5 #include <linux/etherdevice.h>
6 #include <linux/delay.h>
7 #include <linux/dev_printk.h>
8 #include <linux/dma-mapping.h>
9 #include <linux/gfp.h>
10 #include <linux/types.h>
11 
12 #include "fbnic.h"
13 #include "fbnic_tlv.h"
14 
__fbnic_mbx_wr_desc(struct fbnic_dev * fbd,int mbx_idx,int desc_idx,u64 desc)15 static void __fbnic_mbx_wr_desc(struct fbnic_dev *fbd, int mbx_idx,
16 				int desc_idx, u64 desc)
17 {
18 	u32 desc_offset = FBNIC_IPC_MBX(mbx_idx, desc_idx);
19 
20 	/* Write the upper 32b and then the lower 32b. Doing this the
21 	 * FW can then read lower, upper, lower to verify that the state
22 	 * of the descriptor wasn't changed mid-transaction.
23 	 */
24 	fw_wr32(fbd, desc_offset + 1, upper_32_bits(desc));
25 	fw_wrfl(fbd);
26 	fw_wr32(fbd, desc_offset, lower_32_bits(desc));
27 }
28 
__fbnic_mbx_invalidate_desc(struct fbnic_dev * fbd,int mbx_idx,int desc_idx,u32 desc)29 static void __fbnic_mbx_invalidate_desc(struct fbnic_dev *fbd, int mbx_idx,
30 					int desc_idx, u32 desc)
31 {
32 	u32 desc_offset = FBNIC_IPC_MBX(mbx_idx, desc_idx);
33 
34 	/* For initialization we write the lower 32b of the descriptor first.
35 	 * This way we can set the state to mark it invalid before we clear the
36 	 * upper 32b.
37 	 */
38 	fw_wr32(fbd, desc_offset, desc);
39 	fw_wrfl(fbd);
40 	fw_wr32(fbd, desc_offset + 1, 0);
41 }
42 
__fbnic_mbx_rd_desc(struct fbnic_dev * fbd,int mbx_idx,int desc_idx)43 u64 __fbnic_mbx_rd_desc(struct fbnic_dev *fbd, int mbx_idx, int desc_idx)
44 {
45 	u32 desc_offset = FBNIC_IPC_MBX(mbx_idx, desc_idx);
46 	u64 desc;
47 
48 	desc = fw_rd32(fbd, desc_offset);
49 	desc |= (u64)fw_rd32(fbd, desc_offset + 1) << 32;
50 
51 	return desc;
52 }
53 
fbnic_mbx_reset_desc_ring(struct fbnic_dev * fbd,int mbx_idx)54 static void fbnic_mbx_reset_desc_ring(struct fbnic_dev *fbd, int mbx_idx)
55 {
56 	int desc_idx;
57 
58 	/* Disable DMA transactions from the device,
59 	 * and flush any transactions triggered during cleaning
60 	 */
61 	switch (mbx_idx) {
62 	case FBNIC_IPC_MBX_RX_IDX:
63 		wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AW_CFG,
64 		     FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH);
65 		break;
66 	case FBNIC_IPC_MBX_TX_IDX:
67 		wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AR_CFG,
68 		     FBNIC_PUL_OB_TLP_HDR_AR_CFG_FLUSH);
69 		break;
70 	}
71 
72 	wrfl(fbd);
73 
74 	/* Initialize first descriptor to all 0s. Doing this gives us a
75 	 * solid stop for the firmware to hit when it is done looping
76 	 * through the ring.
77 	 */
78 	__fbnic_mbx_invalidate_desc(fbd, mbx_idx, 0, 0);
79 
80 	/* We then fill the rest of the ring starting at the end and moving
81 	 * back toward descriptor 0 with skip descriptors that have no
82 	 * length nor address, and tell the firmware that they can skip
83 	 * them and just move past them to the one we initialized to 0.
84 	 */
85 	for (desc_idx = FBNIC_IPC_MBX_DESC_LEN; --desc_idx;)
86 		__fbnic_mbx_invalidate_desc(fbd, mbx_idx, desc_idx,
87 					    FBNIC_IPC_MBX_DESC_FW_CMPL |
88 					    FBNIC_IPC_MBX_DESC_HOST_CMPL);
89 }
90 
fbnic_mbx_init(struct fbnic_dev * fbd)91 void fbnic_mbx_init(struct fbnic_dev *fbd)
92 {
93 	int i;
94 
95 	/* Initialize lock to protect Tx ring */
96 	spin_lock_init(&fbd->fw_tx_lock);
97 
98 	/* Reset FW Capabilities */
99 	memset(&fbd->fw_cap, 0, sizeof(fbd->fw_cap));
100 
101 	/* Reinitialize mailbox memory */
102 	for (i = 0; i < FBNIC_IPC_MBX_INDICES; i++)
103 		memset(&fbd->mbx[i], 0, sizeof(struct fbnic_fw_mbx));
104 
105 	/* Do not auto-clear the FW mailbox interrupt, let SW clear it */
106 	wr32(fbd, FBNIC_INTR_SW_AC_MODE(0), ~(1u << FBNIC_FW_MSIX_ENTRY));
107 
108 	/* Clear any stale causes in vector 0 as that is used for doorbell */
109 	wr32(fbd, FBNIC_INTR_CLEAR(0), 1u << FBNIC_FW_MSIX_ENTRY);
110 
111 	for (i = 0; i < FBNIC_IPC_MBX_INDICES; i++)
112 		fbnic_mbx_reset_desc_ring(fbd, i);
113 }
114 
fbnic_mbx_map_msg(struct fbnic_dev * fbd,int mbx_idx,struct fbnic_tlv_msg * msg,u16 length,u8 eom)115 static int fbnic_mbx_map_msg(struct fbnic_dev *fbd, int mbx_idx,
116 			     struct fbnic_tlv_msg *msg, u16 length, u8 eom)
117 {
118 	struct fbnic_fw_mbx *mbx = &fbd->mbx[mbx_idx];
119 	u8 tail = mbx->tail;
120 	dma_addr_t addr;
121 	int direction;
122 
123 	if (!mbx->ready || !fbnic_fw_present(fbd))
124 		return -ENODEV;
125 
126 	direction = (mbx_idx == FBNIC_IPC_MBX_RX_IDX) ? DMA_FROM_DEVICE :
127 							DMA_TO_DEVICE;
128 
129 	if (mbx->head == ((tail + 1) % FBNIC_IPC_MBX_DESC_LEN))
130 		return -EBUSY;
131 
132 	addr = dma_map_single(fbd->dev, msg, PAGE_SIZE, direction);
133 	if (dma_mapping_error(fbd->dev, addr))
134 		return -ENOSPC;
135 
136 	mbx->buf_info[tail].msg = msg;
137 	mbx->buf_info[tail].addr = addr;
138 
139 	mbx->tail = (tail + 1) % FBNIC_IPC_MBX_DESC_LEN;
140 
141 	fw_wr32(fbd, FBNIC_IPC_MBX(mbx_idx, mbx->tail), 0);
142 
143 	__fbnic_mbx_wr_desc(fbd, mbx_idx, tail,
144 			    FIELD_PREP(FBNIC_IPC_MBX_DESC_LEN_MASK, length) |
145 			    (addr & FBNIC_IPC_MBX_DESC_ADDR_MASK) |
146 			    (eom ? FBNIC_IPC_MBX_DESC_EOM : 0) |
147 			    FBNIC_IPC_MBX_DESC_HOST_CMPL);
148 
149 	return 0;
150 }
151 
fbnic_mbx_unmap_and_free_msg(struct fbnic_dev * fbd,int mbx_idx,int desc_idx)152 static void fbnic_mbx_unmap_and_free_msg(struct fbnic_dev *fbd, int mbx_idx,
153 					 int desc_idx)
154 {
155 	struct fbnic_fw_mbx *mbx = &fbd->mbx[mbx_idx];
156 	int direction;
157 
158 	if (!mbx->buf_info[desc_idx].msg)
159 		return;
160 
161 	direction = (mbx_idx == FBNIC_IPC_MBX_RX_IDX) ? DMA_FROM_DEVICE :
162 							DMA_TO_DEVICE;
163 	dma_unmap_single(fbd->dev, mbx->buf_info[desc_idx].addr,
164 			 PAGE_SIZE, direction);
165 
166 	free_page((unsigned long)mbx->buf_info[desc_idx].msg);
167 	mbx->buf_info[desc_idx].msg = NULL;
168 }
169 
fbnic_mbx_clean_desc_ring(struct fbnic_dev * fbd,int mbx_idx)170 static void fbnic_mbx_clean_desc_ring(struct fbnic_dev *fbd, int mbx_idx)
171 {
172 	int i;
173 
174 	fbnic_mbx_reset_desc_ring(fbd, mbx_idx);
175 
176 	for (i = FBNIC_IPC_MBX_DESC_LEN; i--;)
177 		fbnic_mbx_unmap_and_free_msg(fbd, mbx_idx, i);
178 }
179 
fbnic_mbx_clean(struct fbnic_dev * fbd)180 void fbnic_mbx_clean(struct fbnic_dev *fbd)
181 {
182 	int i;
183 
184 	for (i = 0; i < FBNIC_IPC_MBX_INDICES; i++)
185 		fbnic_mbx_clean_desc_ring(fbd, i);
186 }
187 
188 #define FBNIC_MBX_MAX_PAGE_SIZE	FIELD_MAX(FBNIC_IPC_MBX_DESC_LEN_MASK)
189 #define FBNIC_RX_PAGE_SIZE	min_t(int, PAGE_SIZE, FBNIC_MBX_MAX_PAGE_SIZE)
190 
fbnic_mbx_alloc_rx_msgs(struct fbnic_dev * fbd)191 static int fbnic_mbx_alloc_rx_msgs(struct fbnic_dev *fbd)
192 {
193 	struct fbnic_fw_mbx *rx_mbx = &fbd->mbx[FBNIC_IPC_MBX_RX_IDX];
194 	u8 tail = rx_mbx->tail, head = rx_mbx->head, count;
195 	int err = 0;
196 
197 	/* Do nothing if mailbox is not ready, or we already have pages on
198 	 * the ring that can be used by the firmware
199 	 */
200 	if (!rx_mbx->ready)
201 		return -ENODEV;
202 
203 	/* Fill all but 1 unused descriptors in the Rx queue. */
204 	count = (head - tail - 1) & (FBNIC_IPC_MBX_DESC_LEN - 1);
205 	while (!err && count--) {
206 		struct fbnic_tlv_msg *msg;
207 
208 		msg = (struct fbnic_tlv_msg *)__get_free_page(GFP_KERNEL);
209 		if (!msg) {
210 			err = -ENOMEM;
211 			break;
212 		}
213 
214 		err = fbnic_mbx_map_msg(fbd, FBNIC_IPC_MBX_RX_IDX, msg,
215 					FBNIC_RX_PAGE_SIZE, 0);
216 		if (err)
217 			free_page((unsigned long)msg);
218 	}
219 
220 	return err;
221 }
222 
fbnic_mbx_map_tlv_msg(struct fbnic_dev * fbd,struct fbnic_tlv_msg * msg)223 static int fbnic_mbx_map_tlv_msg(struct fbnic_dev *fbd,
224 				 struct fbnic_tlv_msg *msg)
225 {
226 	unsigned long flags;
227 	int err;
228 
229 	spin_lock_irqsave(&fbd->fw_tx_lock, flags);
230 
231 	err = fbnic_mbx_map_msg(fbd, FBNIC_IPC_MBX_TX_IDX, msg,
232 				le16_to_cpu(msg->hdr.len) * sizeof(u32), 1);
233 
234 	spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
235 
236 	return err;
237 }
238 
fbnic_mbx_set_cmpl_slot(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl_data)239 static int fbnic_mbx_set_cmpl_slot(struct fbnic_dev *fbd,
240 				   struct fbnic_fw_completion *cmpl_data)
241 {
242 	struct fbnic_fw_mbx *tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX];
243 	int free = -EXFULL;
244 	int i;
245 
246 	if (!tx_mbx->ready)
247 		return -ENODEV;
248 
249 	for (i = 0; i < FBNIC_MBX_CMPL_SLOTS; i++) {
250 		if (!fbd->cmpl_data[i])
251 			free = i;
252 		else if (fbd->cmpl_data[i]->msg_type == cmpl_data->msg_type)
253 			return -EEXIST;
254 	}
255 
256 	if (free == -EXFULL)
257 		return -EXFULL;
258 
259 	fbd->cmpl_data[free] = cmpl_data;
260 
261 	return 0;
262 }
263 
fbnic_mbx_clear_cmpl_slot(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl_data)264 static void fbnic_mbx_clear_cmpl_slot(struct fbnic_dev *fbd,
265 				      struct fbnic_fw_completion *cmpl_data)
266 {
267 	int i;
268 
269 	for (i = 0; i < FBNIC_MBX_CMPL_SLOTS; i++) {
270 		if (fbd->cmpl_data[i] == cmpl_data) {
271 			fbd->cmpl_data[i] = NULL;
272 			break;
273 		}
274 	}
275 }
276 
fbnic_mbx_process_tx_msgs(struct fbnic_dev * fbd)277 static void fbnic_mbx_process_tx_msgs(struct fbnic_dev *fbd)
278 {
279 	struct fbnic_fw_mbx *tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX];
280 	u8 head = tx_mbx->head;
281 	u64 desc;
282 
283 	while (head != tx_mbx->tail) {
284 		desc = __fbnic_mbx_rd_desc(fbd, FBNIC_IPC_MBX_TX_IDX, head);
285 		if (!(desc & FBNIC_IPC_MBX_DESC_FW_CMPL))
286 			break;
287 
288 		fbnic_mbx_unmap_and_free_msg(fbd, FBNIC_IPC_MBX_TX_IDX, head);
289 
290 		head++;
291 		head %= FBNIC_IPC_MBX_DESC_LEN;
292 	}
293 
294 	/* Record head for next interrupt */
295 	tx_mbx->head = head;
296 }
297 
fbnic_mbx_set_cmpl(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl_data)298 int fbnic_mbx_set_cmpl(struct fbnic_dev *fbd,
299 		       struct fbnic_fw_completion *cmpl_data)
300 {
301 	unsigned long flags;
302 	int err;
303 
304 	spin_lock_irqsave(&fbd->fw_tx_lock, flags);
305 	err = fbnic_mbx_set_cmpl_slot(fbd, cmpl_data);
306 	spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
307 
308 	return err;
309 }
310 
fbnic_mbx_map_req_w_cmpl(struct fbnic_dev * fbd,struct fbnic_tlv_msg * msg,struct fbnic_fw_completion * cmpl_data)311 static int fbnic_mbx_map_req_w_cmpl(struct fbnic_dev *fbd,
312 				    struct fbnic_tlv_msg *msg,
313 				    struct fbnic_fw_completion *cmpl_data)
314 {
315 	unsigned long flags;
316 	int err;
317 
318 	spin_lock_irqsave(&fbd->fw_tx_lock, flags);
319 	if (cmpl_data) {
320 		err = fbnic_mbx_set_cmpl_slot(fbd, cmpl_data);
321 		if (err)
322 			goto unlock_mbx;
323 	}
324 
325 	err = fbnic_mbx_map_msg(fbd, FBNIC_IPC_MBX_TX_IDX, msg,
326 				le16_to_cpu(msg->hdr.len) * sizeof(u32), 1);
327 
328 	/* If we successfully reserved a completion and msg failed
329 	 * then clear completion data for next caller
330 	 */
331 	if (err && cmpl_data)
332 		fbnic_mbx_clear_cmpl_slot(fbd, cmpl_data);
333 
334 unlock_mbx:
335 	spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
336 
337 	return err;
338 }
339 
fbnic_mbx_clear_cmpl(struct fbnic_dev * fbd,struct fbnic_fw_completion * fw_cmpl)340 void fbnic_mbx_clear_cmpl(struct fbnic_dev *fbd,
341 			  struct fbnic_fw_completion *fw_cmpl)
342 {
343 	unsigned long flags;
344 
345 	spin_lock_irqsave(&fbd->fw_tx_lock, flags);
346 	fbnic_mbx_clear_cmpl_slot(fbd, fw_cmpl);
347 	spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
348 }
349 
fbnic_fw_release_cmpl_data(struct kref * kref)350 static void fbnic_fw_release_cmpl_data(struct kref *kref)
351 {
352 	struct fbnic_fw_completion *cmpl_data;
353 
354 	cmpl_data = container_of(kref, struct fbnic_fw_completion,
355 				 ref_count);
356 	kfree(cmpl_data);
357 }
358 
359 static struct fbnic_fw_completion *
fbnic_fw_get_cmpl_by_type(struct fbnic_dev * fbd,u32 msg_type)360 fbnic_fw_get_cmpl_by_type(struct fbnic_dev *fbd, u32 msg_type)
361 {
362 	struct fbnic_fw_completion *cmpl_data = NULL;
363 	unsigned long flags;
364 	int i;
365 
366 	spin_lock_irqsave(&fbd->fw_tx_lock, flags);
367 	for (i = 0; i < FBNIC_MBX_CMPL_SLOTS; i++) {
368 		if (fbd->cmpl_data[i] &&
369 		    fbd->cmpl_data[i]->msg_type == msg_type) {
370 			cmpl_data = fbd->cmpl_data[i];
371 			kref_get(&cmpl_data->ref_count);
372 			break;
373 		}
374 	}
375 
376 	spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
377 
378 	return cmpl_data;
379 }
380 
381 /**
382  * fbnic_fw_xmit_test_msg - Create and transmit a test message to FW mailbox
383  * @fbd: FBNIC device structure
384  * @cmpl: fw completion struct
385  *
386  * Return: zero on success, negative value on failure
387  *
388  * Generates a single page mailbox test message and places it in the Tx
389  * mailbox queue. Expectation is that the FW will validate that the nested
390  * value matches the external values, and then will echo them back to us.
391  *
392  * Also sets a completion slot for use in the completion wait calls when
393  * the cmpl arg is non-NULL.
394  */
fbnic_fw_xmit_test_msg(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl)395 int fbnic_fw_xmit_test_msg(struct fbnic_dev *fbd,
396 			   struct fbnic_fw_completion *cmpl)
397 {
398 	struct fbnic_tlv_msg *test_msg;
399 	int err;
400 
401 	test_msg = fbnic_tlv_test_create(fbd);
402 	if (!test_msg)
403 		return -ENOMEM;
404 
405 	err = fbnic_mbx_map_req_w_cmpl(fbd, test_msg, cmpl);
406 	if (err)
407 		free_page((unsigned long)test_msg);
408 
409 	return err;
410 }
411 
412 /**
413  * fbnic_fw_xmit_simple_msg - Transmit a simple single TLV message w/o data
414  * @fbd: FBNIC device structure
415  * @msg_type: ENUM value indicating message type to send
416  *
417  * Return:
418  *   One the following values:
419  *	-EOPNOTSUPP: Is not ASIC so mailbox is not supported
420  *	-ENODEV: Device I/O error
421  *	-ENOMEM: Failed to allocate message
422  *	-EBUSY: No space in mailbox
423  *	-ENOSPC: DMA mapping failed
424  *
425  * This function sends a single TLV header indicating the host wants to take
426  * some action. However there are no other side effects which means that any
427  * response will need to be caught via a completion if this action is
428  * expected to kick off a resultant action.
429  */
fbnic_fw_xmit_simple_msg(struct fbnic_dev * fbd,u32 msg_type)430 static int fbnic_fw_xmit_simple_msg(struct fbnic_dev *fbd, u32 msg_type)
431 {
432 	struct fbnic_tlv_msg *msg;
433 	int err = 0;
434 
435 	if (!fbnic_fw_present(fbd))
436 		return -ENODEV;
437 
438 	msg = fbnic_tlv_msg_alloc(msg_type);
439 	if (!msg)
440 		return -ENOMEM;
441 
442 	err = fbnic_mbx_map_tlv_msg(fbd, msg);
443 	if (err)
444 		free_page((unsigned long)msg);
445 
446 	return err;
447 }
448 
fbnic_mbx_init_desc_ring(struct fbnic_dev * fbd,int mbx_idx)449 static int fbnic_mbx_init_desc_ring(struct fbnic_dev *fbd, int mbx_idx)
450 {
451 	u8 tlp_attr = fbd->relaxed_ord ? FBNIC_TLP_ATTR_RO : 0;
452 	struct fbnic_fw_mbx *mbx = &fbd->mbx[mbx_idx];
453 
454 	mbx->ready = true;
455 
456 	switch (mbx_idx) {
457 	case FBNIC_IPC_MBX_RX_IDX:
458 		/* Enable DMA writes from the device */
459 		wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AW_CFG,
460 		     FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME |
461 		     FIELD_PREP(FBNIC_PUL_OB_TLP_HDR_AW_CFG_RDE_ATTR,
462 				tlp_attr) |
463 		     FIELD_PREP(FBNIC_PUL_OB_TLP_HDR_AW_CFG_TQM_ATTR,
464 				tlp_attr));
465 
466 		/* Make sure we have a page for the FW to write to */
467 		return fbnic_mbx_alloc_rx_msgs(fbd);
468 	case FBNIC_IPC_MBX_TX_IDX:
469 		/* Enable DMA reads from the device */
470 		wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AR_CFG,
471 		     FBNIC_PUL_OB_TLP_HDR_AR_CFG_BME |
472 		     FIELD_PREP(FBNIC_PUL_OB_TLP_HDR_AR_CFG_TDE_ATTR,
473 				tlp_attr) |
474 		     FIELD_PREP(FBNIC_PUL_OB_TLP_HDR_AR_CFG_RQM_ATTR,
475 				tlp_attr) |
476 		     FIELD_PREP(FBNIC_PUL_OB_TLP_HDR_AR_CFG_TQM_ATTR,
477 				tlp_attr));
478 		break;
479 	}
480 
481 	return 0;
482 }
483 
fbnic_mbx_event(struct fbnic_dev * fbd)484 static bool fbnic_mbx_event(struct fbnic_dev *fbd)
485 {
486 	/* We only need to do this on the first interrupt following reset.
487 	 * this primes the mailbox so that we will have cleared all the
488 	 * skip descriptors.
489 	 */
490 	if (!(rd32(fbd, FBNIC_INTR_STATUS(0)) & (1u << FBNIC_FW_MSIX_ENTRY)))
491 		return false;
492 
493 	wr32(fbd, FBNIC_INTR_CLEAR(0), 1u << FBNIC_FW_MSIX_ENTRY);
494 
495 	return true;
496 }
497 
498 /**
499  * fbnic_fw_xmit_ownership_msg - Create and transmit a host ownership message
500  * to FW mailbox
501  *
502  * @fbd: FBNIC device structure
503  * @take_ownership: take/release the ownership
504  *
505  * Return: zero on success, negative value on failure
506  *
507  * Notifies the firmware that the driver either takes ownership of the NIC
508  * (when @take_ownership is true) or releases it.
509  */
fbnic_fw_xmit_ownership_msg(struct fbnic_dev * fbd,bool take_ownership)510 int fbnic_fw_xmit_ownership_msg(struct fbnic_dev *fbd, bool take_ownership)
511 {
512 	unsigned long req_time = jiffies;
513 	struct fbnic_tlv_msg *msg;
514 	int err = 0;
515 
516 	if (!fbnic_fw_present(fbd))
517 		return -ENODEV;
518 
519 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_OWNERSHIP_REQ);
520 	if (!msg)
521 		return -ENOMEM;
522 
523 	if (take_ownership) {
524 		err = fbnic_tlv_attr_put_flag(msg, FBNIC_FW_OWNERSHIP_FLAG);
525 		if (err)
526 			goto free_message;
527 	}
528 
529 	/* Initialize heartbeat, set last response to 1 second in the past
530 	 * so that we will trigger a timeout if the firmware doesn't respond
531 	 */
532 	fbd->last_heartbeat_response = req_time - HZ;
533 	fbd->last_heartbeat_request = req_time;
534 
535 	/* Set prev_firmware_time to 0 to avoid triggering firmware crash
536 	 * detection until we receive the second uptime in a heartbeat resp.
537 	 */
538 	fbd->prev_firmware_time = 0;
539 
540 	err = fbnic_mbx_map_tlv_msg(fbd, msg);
541 	if (err)
542 		goto free_message;
543 
544 	/* Set heartbeat detection based on if we are taking ownership */
545 	fbd->fw_heartbeat_enabled = take_ownership;
546 
547 	return err;
548 
549 free_message:
550 	free_page((unsigned long)msg);
551 	return err;
552 }
553 
554 static const struct fbnic_tlv_index fbnic_fw_cap_resp_index[] = {
555 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_VERSION),
556 	FBNIC_TLV_ATTR_FLAG(FBNIC_FW_CAP_RESP_BMC_PRESENT),
557 	FBNIC_TLV_ATTR_MAC_ADDR(FBNIC_FW_CAP_RESP_BMC_MAC_ADDR),
558 	FBNIC_TLV_ATTR_ARRAY(FBNIC_FW_CAP_RESP_BMC_MAC_ARRAY),
559 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_STORED_VERSION),
560 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_ACTIVE_FW_SLOT),
561 	FBNIC_TLV_ATTR_STRING(FBNIC_FW_CAP_RESP_VERSION_COMMIT_STR,
562 			      FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE),
563 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_BMC_ALL_MULTI),
564 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_FW_LINK_SPEED),
565 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_FW_LINK_FEC),
566 	FBNIC_TLV_ATTR_STRING(FBNIC_FW_CAP_RESP_STORED_COMMIT_STR,
567 			      FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE),
568 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_CMRT_VERSION),
569 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_STORED_CMRT_VERSION),
570 	FBNIC_TLV_ATTR_STRING(FBNIC_FW_CAP_RESP_CMRT_COMMIT_STR,
571 			      FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE),
572 	FBNIC_TLV_ATTR_STRING(FBNIC_FW_CAP_RESP_STORED_CMRT_COMMIT_STR,
573 			      FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE),
574 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_UEFI_VERSION),
575 	FBNIC_TLV_ATTR_STRING(FBNIC_FW_CAP_RESP_UEFI_COMMIT_STR,
576 			      FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE),
577 	FBNIC_TLV_ATTR_U32(FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION),
578 	FBNIC_TLV_ATTR_LAST
579 };
580 
fbnic_fw_parse_bmc_addrs(u8 bmc_mac_addr[][ETH_ALEN],struct fbnic_tlv_msg * attr,int len)581 static int fbnic_fw_parse_bmc_addrs(u8 bmc_mac_addr[][ETH_ALEN],
582 				    struct fbnic_tlv_msg *attr, int len)
583 {
584 	int attr_len = le16_to_cpu(attr->hdr.len) / sizeof(u32) - 1;
585 	struct fbnic_tlv_msg *mac_results[8];
586 	int err, i = 0;
587 
588 	/* Make sure we have enough room to process all the MAC addresses */
589 	if (len > 8)
590 		return -ENOSPC;
591 
592 	/* Parse the array */
593 	err = fbnic_tlv_attr_parse_array(&attr[1], attr_len, mac_results,
594 					 fbnic_fw_cap_resp_index,
595 					 FBNIC_FW_CAP_RESP_BMC_MAC_ADDR, len);
596 	if (err)
597 		return err;
598 
599 	/* Copy results into MAC addr array */
600 	for (i = 0; i < len && mac_results[i]; i++)
601 		fbnic_tlv_attr_addr_copy(bmc_mac_addr[i], mac_results[i]);
602 
603 	/* Zero remaining unused addresses */
604 	while (i < len)
605 		eth_zero_addr(bmc_mac_addr[i++]);
606 
607 	return 0;
608 }
609 
fbnic_fw_parse_cap_resp(void * opaque,struct fbnic_tlv_msg ** results)610 static int fbnic_fw_parse_cap_resp(void *opaque, struct fbnic_tlv_msg **results)
611 {
612 	u32 all_multi = 0, version = 0;
613 	struct fbnic_dev *fbd = opaque;
614 	bool bmc_present;
615 	int err;
616 
617 	version = fta_get_uint(results, FBNIC_FW_CAP_RESP_VERSION);
618 	fbd->fw_cap.running.mgmt.version = version;
619 	if (!fbd->fw_cap.running.mgmt.version)
620 		return -EINVAL;
621 
622 	if (fbd->fw_cap.running.mgmt.version < MIN_FW_VER_CODE) {
623 		char required_ver[FBNIC_FW_VER_MAX_SIZE];
624 		char running_ver[FBNIC_FW_VER_MAX_SIZE];
625 
626 		fbnic_mk_fw_ver_str(fbd->fw_cap.running.mgmt.version,
627 				    running_ver);
628 		fbnic_mk_fw_ver_str(MIN_FW_VER_CODE, required_ver);
629 		dev_err(fbd->dev, "Device firmware version(%s) is older than minimum required version(%s)\n",
630 			running_ver, required_ver);
631 		/* Disable TX mailbox to prevent card use until firmware is
632 		 * updated.
633 		 */
634 		fbd->mbx[FBNIC_IPC_MBX_TX_IDX].ready = false;
635 		return -EINVAL;
636 	}
637 
638 	if (fta_get_str(results, FBNIC_FW_CAP_RESP_VERSION_COMMIT_STR,
639 			fbd->fw_cap.running.mgmt.commit,
640 			FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE) <= 0)
641 		dev_warn(fbd->dev, "Firmware did not send mgmt commit!\n");
642 
643 	version = fta_get_uint(results, FBNIC_FW_CAP_RESP_STORED_VERSION);
644 	fbd->fw_cap.stored.mgmt.version = version;
645 	fta_get_str(results, FBNIC_FW_CAP_RESP_STORED_COMMIT_STR,
646 		    fbd->fw_cap.stored.mgmt.commit,
647 		    FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE);
648 
649 	version = fta_get_uint(results, FBNIC_FW_CAP_RESP_CMRT_VERSION);
650 	fbd->fw_cap.running.bootloader.version = version;
651 	fta_get_str(results, FBNIC_FW_CAP_RESP_CMRT_COMMIT_STR,
652 		    fbd->fw_cap.running.bootloader.commit,
653 		    FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE);
654 
655 	version = fta_get_uint(results, FBNIC_FW_CAP_RESP_STORED_CMRT_VERSION);
656 	fbd->fw_cap.stored.bootloader.version = version;
657 	fta_get_str(results, FBNIC_FW_CAP_RESP_STORED_CMRT_COMMIT_STR,
658 		    fbd->fw_cap.stored.bootloader.commit,
659 		    FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE);
660 
661 	version = fta_get_uint(results, FBNIC_FW_CAP_RESP_UEFI_VERSION);
662 	fbd->fw_cap.stored.undi.version = version;
663 	fta_get_str(results, FBNIC_FW_CAP_RESP_UEFI_COMMIT_STR,
664 		    fbd->fw_cap.stored.undi.commit,
665 		    FBNIC_FW_CAP_RESP_COMMIT_MAX_SIZE);
666 
667 	fbd->fw_cap.active_slot =
668 		fta_get_uint(results, FBNIC_FW_CAP_RESP_ACTIVE_FW_SLOT);
669 	fbd->fw_cap.link_speed =
670 		fta_get_uint(results, FBNIC_FW_CAP_RESP_FW_LINK_SPEED);
671 	fbd->fw_cap.link_fec =
672 		fta_get_uint(results, FBNIC_FW_CAP_RESP_FW_LINK_FEC);
673 
674 	bmc_present = !!results[FBNIC_FW_CAP_RESP_BMC_PRESENT];
675 	if (bmc_present) {
676 		struct fbnic_tlv_msg *attr;
677 
678 		attr = results[FBNIC_FW_CAP_RESP_BMC_MAC_ARRAY];
679 		if (!attr)
680 			return -EINVAL;
681 
682 		err = fbnic_fw_parse_bmc_addrs(fbd->fw_cap.bmc_mac_addr,
683 					       attr, 4);
684 		if (err)
685 			return err;
686 
687 		all_multi =
688 			fta_get_uint(results, FBNIC_FW_CAP_RESP_BMC_ALL_MULTI);
689 	} else {
690 		memset(fbd->fw_cap.bmc_mac_addr, 0,
691 		       sizeof(fbd->fw_cap.bmc_mac_addr));
692 	}
693 
694 	fbd->fw_cap.bmc_present = bmc_present;
695 
696 	if (results[FBNIC_FW_CAP_RESP_BMC_ALL_MULTI] || !bmc_present)
697 		fbd->fw_cap.all_multi = all_multi;
698 
699 	fbd->fw_cap.anti_rollback_version =
700 		fta_get_uint(results, FBNIC_FW_CAP_RESP_ANTI_ROLLBACK_VERSION);
701 
702 	/* Always assume we need a BMC reinit */
703 	fbd->fw_cap.need_bmc_tcam_reinit = true;
704 
705 	return 0;
706 }
707 
708 static const struct fbnic_tlv_index fbnic_ownership_resp_index[] = {
709 	FBNIC_TLV_ATTR_U64(FBNIC_FW_OWNERSHIP_TIME),
710 	FBNIC_TLV_ATTR_LAST
711 };
712 
fbnic_fw_parse_ownership_resp(void * opaque,struct fbnic_tlv_msg ** results)713 static int fbnic_fw_parse_ownership_resp(void *opaque,
714 					 struct fbnic_tlv_msg **results)
715 {
716 	struct fbnic_dev *fbd = (struct fbnic_dev *)opaque;
717 
718 	/* Count the ownership response as a heartbeat reply */
719 	fbd->last_heartbeat_response = jiffies;
720 
721 	/* Capture firmware time for logging and firmware crash check */
722 	fbd->firmware_time = fta_get_uint(results, FBNIC_FW_OWNERSHIP_TIME);
723 
724 	return 0;
725 }
726 
727 static const struct fbnic_tlv_index fbnic_heartbeat_resp_index[] = {
728 	FBNIC_TLV_ATTR_U64(FBNIC_FW_HEARTBEAT_UPTIME),
729 	FBNIC_TLV_ATTR_LAST
730 };
731 
fbnic_fw_parse_heartbeat_resp(void * opaque,struct fbnic_tlv_msg ** results)732 static int fbnic_fw_parse_heartbeat_resp(void *opaque,
733 					 struct fbnic_tlv_msg **results)
734 {
735 	struct fbnic_dev *fbd = (struct fbnic_dev *)opaque;
736 
737 	fbd->last_heartbeat_response = jiffies;
738 
739 	/* Capture firmware time for logging and firmware crash check */
740 	fbd->firmware_time = fta_get_uint(results, FBNIC_FW_HEARTBEAT_UPTIME);
741 
742 	return 0;
743 }
744 
fbnic_fw_xmit_heartbeat_message(struct fbnic_dev * fbd)745 static int fbnic_fw_xmit_heartbeat_message(struct fbnic_dev *fbd)
746 {
747 	unsigned long req_time = jiffies;
748 	struct fbnic_tlv_msg *msg;
749 	int err = 0;
750 
751 	if (!fbnic_fw_present(fbd))
752 		return -ENODEV;
753 
754 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_HEARTBEAT_REQ);
755 	if (!msg)
756 		return -ENOMEM;
757 
758 	err = fbnic_mbx_map_tlv_msg(fbd, msg);
759 	if (err)
760 		goto free_message;
761 
762 	fbd->last_heartbeat_request = req_time;
763 	fbd->prev_firmware_time = fbd->firmware_time;
764 
765 	return err;
766 
767 free_message:
768 	free_page((unsigned long)msg);
769 	return err;
770 }
771 
fbnic_fw_heartbeat_current(struct fbnic_dev * fbd)772 static bool fbnic_fw_heartbeat_current(struct fbnic_dev *fbd)
773 {
774 	unsigned long last_response = fbd->last_heartbeat_response;
775 	unsigned long last_request = fbd->last_heartbeat_request;
776 
777 	return !time_before(last_response, last_request);
778 }
779 
fbnic_fw_init_heartbeat(struct fbnic_dev * fbd,bool poll)780 int fbnic_fw_init_heartbeat(struct fbnic_dev *fbd, bool poll)
781 {
782 	int err = -ETIMEDOUT;
783 	int attempts = 50;
784 
785 	if (!fbnic_fw_present(fbd))
786 		return -ENODEV;
787 
788 	while (attempts--) {
789 		msleep(200);
790 		if (poll)
791 			fbnic_mbx_poll(fbd);
792 
793 		if (!fbnic_fw_heartbeat_current(fbd))
794 			continue;
795 
796 		/* Place new message on mailbox to elicit a response */
797 		err = fbnic_fw_xmit_heartbeat_message(fbd);
798 		if (err)
799 			dev_warn(fbd->dev,
800 				 "Failed to send heartbeat message: %d\n",
801 				 err);
802 		break;
803 	}
804 
805 	return err;
806 }
807 
fbnic_fw_check_heartbeat(struct fbnic_dev * fbd)808 void fbnic_fw_check_heartbeat(struct fbnic_dev *fbd)
809 {
810 	unsigned long last_request = fbd->last_heartbeat_request;
811 	int err;
812 
813 	/* Do not check heartbeat or send another request until current
814 	 * period has expired. Otherwise we might start spamming requests.
815 	 */
816 	if (time_is_after_jiffies(last_request + FW_HEARTBEAT_PERIOD))
817 		return;
818 
819 	/* We already reported no mailbox. Wait for it to come back */
820 	if (!fbd->fw_heartbeat_enabled)
821 		return;
822 
823 	/* Was the last heartbeat response long time ago? */
824 	if (!fbnic_fw_heartbeat_current(fbd) ||
825 	    fbd->firmware_time < fbd->prev_firmware_time) {
826 		dev_warn(fbd->dev,
827 			 "Firmware did not respond to heartbeat message\n");
828 		fbd->fw_heartbeat_enabled = false;
829 	}
830 
831 	/* Place new message on mailbox to elicit a response */
832 	err = fbnic_fw_xmit_heartbeat_message(fbd);
833 	if (err)
834 		dev_warn(fbd->dev, "Failed to send heartbeat message\n");
835 }
836 
837 /**
838  * fbnic_fw_xmit_coredump_info_msg - Create and transmit a coredump info message
839  * @fbd: FBNIC device structure
840  * @cmpl_data: Structure to store info in
841  * @force: Force coredump event if one hasn't already occurred
842  *
843  * Return: zero on success, negative errno on failure
844  *
845  * Asks the FW for info related to coredump. If a coredump doesn't exist it
846  * can optionally force one if force is true.
847  */
fbnic_fw_xmit_coredump_info_msg(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl_data,bool force)848 int fbnic_fw_xmit_coredump_info_msg(struct fbnic_dev *fbd,
849 				    struct fbnic_fw_completion *cmpl_data,
850 				    bool force)
851 {
852 	struct fbnic_tlv_msg *msg;
853 	int err = 0;
854 
855 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_COREDUMP_GET_INFO_REQ);
856 	if (!msg)
857 		return -ENOMEM;
858 
859 	if (force) {
860 		err = fbnic_tlv_attr_put_flag(msg, FBNIC_FW_COREDUMP_REQ_INFO_CREATE);
861 		if (err)
862 			goto free_msg;
863 	}
864 
865 	err = fbnic_mbx_map_req_w_cmpl(fbd, msg, cmpl_data);
866 	if (err)
867 		goto free_msg;
868 
869 	return 0;
870 
871 free_msg:
872 	free_page((unsigned long)msg);
873 	return err;
874 }
875 
876 static const struct fbnic_tlv_index fbnic_coredump_info_resp_index[] = {
877 	FBNIC_TLV_ATTR_FLAG(FBNIC_FW_COREDUMP_INFO_AVAILABLE),
878 	FBNIC_TLV_ATTR_U32(FBNIC_FW_COREDUMP_INFO_SIZE),
879 	FBNIC_TLV_ATTR_S32(FBNIC_FW_COREDUMP_INFO_ERROR),
880 	FBNIC_TLV_ATTR_LAST
881 };
882 
883 static int
fbnic_fw_parse_coredump_info_resp(void * opaque,struct fbnic_tlv_msg ** results)884 fbnic_fw_parse_coredump_info_resp(void *opaque, struct fbnic_tlv_msg **results)
885 {
886 	struct fbnic_fw_completion *cmpl_data;
887 	struct fbnic_dev *fbd = opaque;
888 	u32 msg_type;
889 	s32 err;
890 
891 	/* Verify we have a completion pointer to provide with data */
892 	msg_type = FBNIC_TLV_MSG_ID_COREDUMP_GET_INFO_RESP;
893 	cmpl_data = fbnic_fw_get_cmpl_by_type(fbd, msg_type);
894 	if (!cmpl_data)
895 		return -ENOSPC;
896 
897 	err = fta_get_sint(results, FBNIC_FW_COREDUMP_INFO_ERROR);
898 	if (err)
899 		goto msg_err;
900 
901 	if (!results[FBNIC_FW_COREDUMP_INFO_AVAILABLE]) {
902 		err = -ENOENT;
903 		goto msg_err;
904 	}
905 
906 	cmpl_data->u.coredump_info.size =
907 		fta_get_uint(results, FBNIC_FW_COREDUMP_INFO_SIZE);
908 
909 msg_err:
910 	cmpl_data->result = err;
911 	complete(&cmpl_data->done);
912 	fbnic_fw_put_cmpl(cmpl_data);
913 
914 	return err;
915 }
916 
917 /**
918  * fbnic_fw_xmit_coredump_read_msg - Create and transmit a coredump read request
919  * @fbd: FBNIC device structure
920  * @cmpl_data: Completion struct to store coredump
921  * @offset: Offset into coredump requested
922  * @length: Length of section of coredump to fetch
923  *
924  * Return: zero on success, negative errno on failure
925  *
926  * Asks the firmware to provide a section of the coredump back in a message.
927  * The response will have an offset and size matching the values provided.
928  */
fbnic_fw_xmit_coredump_read_msg(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl_data,u32 offset,u32 length)929 int fbnic_fw_xmit_coredump_read_msg(struct fbnic_dev *fbd,
930 				    struct fbnic_fw_completion *cmpl_data,
931 				    u32 offset, u32 length)
932 {
933 	struct fbnic_tlv_msg *msg;
934 	int err = 0;
935 
936 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_COREDUMP_READ_REQ);
937 	if (!msg)
938 		return -ENOMEM;
939 
940 	if (offset) {
941 		err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_COREDUMP_READ_OFFSET,
942 					     offset);
943 		if (err)
944 			goto free_message;
945 	}
946 
947 	if (length) {
948 		err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_COREDUMP_READ_LENGTH,
949 					     length);
950 		if (err)
951 			goto free_message;
952 	}
953 
954 	err = fbnic_mbx_map_req_w_cmpl(fbd, msg, cmpl_data);
955 	if (err)
956 		goto free_message;
957 
958 	return 0;
959 
960 free_message:
961 	free_page((unsigned long)msg);
962 	return err;
963 }
964 
965 static const struct fbnic_tlv_index fbnic_coredump_resp_index[] = {
966 	FBNIC_TLV_ATTR_U32(FBNIC_FW_COREDUMP_READ_OFFSET),
967 	FBNIC_TLV_ATTR_U32(FBNIC_FW_COREDUMP_READ_LENGTH),
968 	FBNIC_TLV_ATTR_RAW_DATA(FBNIC_FW_COREDUMP_READ_DATA),
969 	FBNIC_TLV_ATTR_S32(FBNIC_FW_COREDUMP_READ_ERROR),
970 	FBNIC_TLV_ATTR_LAST
971 };
972 
fbnic_fw_parse_coredump_resp(void * opaque,struct fbnic_tlv_msg ** results)973 static int fbnic_fw_parse_coredump_resp(void *opaque,
974 					struct fbnic_tlv_msg **results)
975 {
976 	struct fbnic_fw_completion *cmpl_data;
977 	u32 index, last_offset, last_length;
978 	struct fbnic_dev *fbd = opaque;
979 	struct fbnic_tlv_msg *data_hdr;
980 	u32 length, offset;
981 	u32 msg_type;
982 	s32 err;
983 
984 	/* Verify we have a completion pointer to provide with data */
985 	msg_type = FBNIC_TLV_MSG_ID_COREDUMP_READ_RESP;
986 	cmpl_data = fbnic_fw_get_cmpl_by_type(fbd, msg_type);
987 	if (!cmpl_data)
988 		return -ENOSPC;
989 
990 	err = fta_get_sint(results, FBNIC_FW_COREDUMP_READ_ERROR);
991 	if (err)
992 		goto msg_err;
993 
994 	data_hdr = results[FBNIC_FW_COREDUMP_READ_DATA];
995 	if (!data_hdr) {
996 		err = -ENODATA;
997 		goto msg_err;
998 	}
999 
1000 	offset = fta_get_uint(results, FBNIC_FW_COREDUMP_READ_OFFSET);
1001 	length = fta_get_uint(results, FBNIC_FW_COREDUMP_READ_LENGTH);
1002 
1003 	if (length > le16_to_cpu(data_hdr->hdr.len) - sizeof(u32)) {
1004 		dev_err(fbd->dev, "length greater than size of message\n");
1005 		err = -EINVAL;
1006 		goto msg_err;
1007 	}
1008 
1009 	/* Only the last offset can have a length != stride */
1010 	last_length =
1011 		(cmpl_data->u.coredump.size % cmpl_data->u.coredump.stride) ? :
1012 		cmpl_data->u.coredump.stride;
1013 	last_offset = cmpl_data->u.coredump.size - last_length;
1014 
1015 	/* Verify offset and length */
1016 	if (offset % cmpl_data->u.coredump.stride || offset > last_offset) {
1017 		dev_err(fbd->dev, "offset %d out of range\n", offset);
1018 		err = -EINVAL;
1019 	} else if (length != ((offset == last_offset) ?
1020 			      last_length : cmpl_data->u.coredump.stride)) {
1021 		dev_err(fbd->dev, "length %d out of range for offset %d\n",
1022 			length, offset);
1023 		err = -EINVAL;
1024 	}
1025 	if (err)
1026 		goto msg_err;
1027 
1028 	/* If data pointer is NULL it is already filled, just skip the copy */
1029 	index = offset / cmpl_data->u.coredump.stride;
1030 	if (!cmpl_data->u.coredump.data[index])
1031 		goto msg_err;
1032 
1033 	/* Copy data and mark index filled by setting pointer to NULL */
1034 	memcpy(cmpl_data->u.coredump.data[index],
1035 	       fbnic_tlv_attr_get_value_ptr(data_hdr), length);
1036 	cmpl_data->u.coredump.data[index] = NULL;
1037 
1038 msg_err:
1039 	cmpl_data->result = err;
1040 	complete(&cmpl_data->done);
1041 	fbnic_fw_put_cmpl(cmpl_data);
1042 
1043 	return err;
1044 }
1045 
fbnic_fw_xmit_fw_start_upgrade(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl_data,unsigned int id,unsigned int len)1046 int fbnic_fw_xmit_fw_start_upgrade(struct fbnic_dev *fbd,
1047 				   struct fbnic_fw_completion *cmpl_data,
1048 				   unsigned int id, unsigned int len)
1049 {
1050 	struct fbnic_tlv_msg *msg;
1051 	int err;
1052 
1053 	if (!fbnic_fw_present(fbd))
1054 		return -ENODEV;
1055 
1056 	if (!len)
1057 		return -EINVAL;
1058 
1059 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ);
1060 	if (!msg)
1061 		return -ENOMEM;
1062 
1063 	err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_START_UPGRADE_SECTION, id);
1064 	if (err)
1065 		goto free_message;
1066 
1067 	err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_START_UPGRADE_IMAGE_LENGTH,
1068 				     len);
1069 	if (err)
1070 		goto free_message;
1071 
1072 	err = fbnic_mbx_map_req_w_cmpl(fbd, msg, cmpl_data);
1073 	if (err)
1074 		goto free_message;
1075 
1076 	return 0;
1077 
1078 free_message:
1079 	free_page((unsigned long)msg);
1080 	return err;
1081 }
1082 
1083 static const struct fbnic_tlv_index fbnic_fw_start_upgrade_resp_index[] = {
1084 	FBNIC_TLV_ATTR_S32(FBNIC_FW_START_UPGRADE_ERROR),
1085 	FBNIC_TLV_ATTR_LAST
1086 };
1087 
fbnic_fw_parse_fw_start_upgrade_resp(void * opaque,struct fbnic_tlv_msg ** results)1088 static int fbnic_fw_parse_fw_start_upgrade_resp(void *opaque,
1089 						struct fbnic_tlv_msg **results)
1090 {
1091 	struct fbnic_fw_completion *cmpl_data;
1092 	struct fbnic_dev *fbd = opaque;
1093 	u32 msg_type;
1094 	s32 err;
1095 
1096 	/* Verify we have a completion pointer */
1097 	msg_type = FBNIC_TLV_MSG_ID_FW_START_UPGRADE_REQ;
1098 	cmpl_data = fbnic_fw_get_cmpl_by_type(fbd, msg_type);
1099 	if (!cmpl_data)
1100 		return -ENOSPC;
1101 
1102 	/* Check for errors */
1103 	err = fta_get_sint(results, FBNIC_FW_START_UPGRADE_ERROR);
1104 
1105 	cmpl_data->result = err;
1106 	complete(&cmpl_data->done);
1107 	fbnic_fw_put_cmpl(cmpl_data);
1108 
1109 	return 0;
1110 }
1111 
fbnic_fw_xmit_fw_write_chunk(struct fbnic_dev * fbd,const u8 * data,u32 offset,u16 length,int cancel_error)1112 int fbnic_fw_xmit_fw_write_chunk(struct fbnic_dev *fbd,
1113 				 const u8 *data, u32 offset, u16 length,
1114 				 int cancel_error)
1115 {
1116 	struct fbnic_tlv_msg *msg;
1117 	int err;
1118 
1119 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_RESP);
1120 	if (!msg)
1121 		return -ENOMEM;
1122 
1123 	/* Report error to FW to cancel upgrade */
1124 	if (cancel_error) {
1125 		err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_WRITE_CHUNK_ERROR,
1126 					     cancel_error);
1127 		if (err)
1128 			goto free_message;
1129 	}
1130 
1131 	if (data) {
1132 		err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_WRITE_CHUNK_OFFSET,
1133 					     offset);
1134 		if (err)
1135 			goto free_message;
1136 
1137 		err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_WRITE_CHUNK_LENGTH,
1138 					     length);
1139 		if (err)
1140 			goto free_message;
1141 
1142 		err = fbnic_tlv_attr_put_value(msg, FBNIC_FW_WRITE_CHUNK_DATA,
1143 					       data + offset, length);
1144 		if (err)
1145 			goto free_message;
1146 	}
1147 
1148 	err = fbnic_mbx_map_tlv_msg(fbd, msg);
1149 	if (err)
1150 		goto free_message;
1151 
1152 	return 0;
1153 
1154 free_message:
1155 	free_page((unsigned long)msg);
1156 	return err;
1157 }
1158 
1159 static const struct fbnic_tlv_index fbnic_fw_write_chunk_req_index[] = {
1160 	FBNIC_TLV_ATTR_U32(FBNIC_FW_WRITE_CHUNK_OFFSET),
1161 	FBNIC_TLV_ATTR_U32(FBNIC_FW_WRITE_CHUNK_LENGTH),
1162 	FBNIC_TLV_ATTR_LAST
1163 };
1164 
fbnic_fw_parse_fw_write_chunk_req(void * opaque,struct fbnic_tlv_msg ** results)1165 static int fbnic_fw_parse_fw_write_chunk_req(void *opaque,
1166 					     struct fbnic_tlv_msg **results)
1167 {
1168 	struct fbnic_fw_completion *cmpl_data;
1169 	struct fbnic_dev *fbd = opaque;
1170 	u32 msg_type;
1171 	u32 offset;
1172 	u32 length;
1173 
1174 	/* Verify we have a completion pointer */
1175 	msg_type = FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ;
1176 	cmpl_data = fbnic_fw_get_cmpl_by_type(fbd, msg_type);
1177 	if (!cmpl_data)
1178 		return -ENOSPC;
1179 
1180 	/* Pull length/offset pair and mark it as complete */
1181 	offset = fta_get_uint(results, FBNIC_FW_WRITE_CHUNK_OFFSET);
1182 	length = fta_get_uint(results, FBNIC_FW_WRITE_CHUNK_LENGTH);
1183 	cmpl_data->u.fw_update.offset = offset;
1184 	cmpl_data->u.fw_update.length = length;
1185 
1186 	complete(&cmpl_data->done);
1187 	fbnic_fw_put_cmpl(cmpl_data);
1188 
1189 	return 0;
1190 }
1191 
1192 static const struct fbnic_tlv_index fbnic_fw_finish_upgrade_req_index[] = {
1193 	FBNIC_TLV_ATTR_S32(FBNIC_FW_FINISH_UPGRADE_ERROR),
1194 	FBNIC_TLV_ATTR_LAST
1195 };
1196 
fbnic_fw_parse_fw_finish_upgrade_req(void * opaque,struct fbnic_tlv_msg ** results)1197 static int fbnic_fw_parse_fw_finish_upgrade_req(void *opaque,
1198 						struct fbnic_tlv_msg **results)
1199 {
1200 	struct fbnic_fw_completion *cmpl_data;
1201 	struct fbnic_dev *fbd = opaque;
1202 	u32 msg_type;
1203 	s32 err;
1204 
1205 	/* Verify we have a completion pointer */
1206 	msg_type = FBNIC_TLV_MSG_ID_FW_WRITE_CHUNK_REQ;
1207 	cmpl_data = fbnic_fw_get_cmpl_by_type(fbd, msg_type);
1208 	if (!cmpl_data)
1209 		return -ENOSPC;
1210 
1211 	/* Check for errors */
1212 	err = fta_get_sint(results, FBNIC_FW_FINISH_UPGRADE_ERROR);
1213 
1214 	/* Close out update by incrementing offset by length which should
1215 	 * match the total size of the component. Set length to 0 since no
1216 	 * new chunks will be requested.
1217 	 */
1218 	cmpl_data->u.fw_update.offset += cmpl_data->u.fw_update.length;
1219 	cmpl_data->u.fw_update.length = 0;
1220 
1221 	cmpl_data->result = err;
1222 	complete(&cmpl_data->done);
1223 	fbnic_fw_put_cmpl(cmpl_data);
1224 
1225 	return 0;
1226 }
1227 
1228 /**
1229  * fbnic_fw_xmit_qsfp_read_msg - Transmit a QSFP read request
1230  * @fbd: FBNIC device structure
1231  * @cmpl_data: Structure to store EEPROM response in
1232  * @page: Refers to page number on page enabled QSFP modules
1233  * @bank: Refers to a collection of pages
1234  * @offset: Offset into QSFP EEPROM requested
1235  * @length: Length of section of QSFP EEPROM to fetch
1236  *
1237  * Return: zero on success, negative value on failure
1238  *
1239  * Asks the firmware to provide a section of the QSFP EEPROM back in a
1240  * message. The response will have an offset and size matching the values
1241  * provided.
1242  */
fbnic_fw_xmit_qsfp_read_msg(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl_data,u32 page,u32 bank,u32 offset,u32 length)1243 int fbnic_fw_xmit_qsfp_read_msg(struct fbnic_dev *fbd,
1244 				struct fbnic_fw_completion *cmpl_data,
1245 				u32 page, u32 bank, u32 offset, u32 length)
1246 {
1247 	struct fbnic_tlv_msg *msg;
1248 	int err = 0;
1249 
1250 	if (!length || length > TLV_MAX_DATA)
1251 		return -EINVAL;
1252 
1253 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_QSFP_READ_REQ);
1254 	if (!msg)
1255 		return -ENOMEM;
1256 
1257 	err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_QSFP_BANK, bank);
1258 	if (err)
1259 		goto free_message;
1260 
1261 	err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_QSFP_PAGE, page);
1262 	if (err)
1263 		goto free_message;
1264 
1265 	err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_QSFP_OFFSET, offset);
1266 	if (err)
1267 		goto free_message;
1268 
1269 	err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_QSFP_LENGTH, length);
1270 	if (err)
1271 		goto free_message;
1272 
1273 	err = fbnic_mbx_map_req_w_cmpl(fbd, msg, cmpl_data);
1274 	if (err)
1275 		goto free_message;
1276 
1277 	return 0;
1278 
1279 free_message:
1280 	free_page((unsigned long)msg);
1281 	return err;
1282 }
1283 
1284 static const struct fbnic_tlv_index fbnic_qsfp_read_resp_index[] = {
1285 	FBNIC_TLV_ATTR_U32(FBNIC_FW_QSFP_BANK),
1286 	FBNIC_TLV_ATTR_U32(FBNIC_FW_QSFP_PAGE),
1287 	FBNIC_TLV_ATTR_U32(FBNIC_FW_QSFP_OFFSET),
1288 	FBNIC_TLV_ATTR_U32(FBNIC_FW_QSFP_LENGTH),
1289 	FBNIC_TLV_ATTR_RAW_DATA(FBNIC_FW_QSFP_DATA),
1290 	FBNIC_TLV_ATTR_S32(FBNIC_FW_QSFP_ERROR),
1291 	FBNIC_TLV_ATTR_LAST
1292 };
1293 
fbnic_fw_parse_qsfp_read_resp(void * opaque,struct fbnic_tlv_msg ** results)1294 static int fbnic_fw_parse_qsfp_read_resp(void *opaque,
1295 					 struct fbnic_tlv_msg **results)
1296 {
1297 	struct fbnic_fw_completion *cmpl_data;
1298 	struct fbnic_dev *fbd = opaque;
1299 	struct fbnic_tlv_msg *data_hdr;
1300 	u32 length, offset, page, bank;
1301 	u8 *data;
1302 	s32 err;
1303 
1304 	/* Verify we have a completion pointer to provide with data */
1305 	cmpl_data = fbnic_fw_get_cmpl_by_type(fbd,
1306 					      FBNIC_TLV_MSG_ID_QSFP_READ_RESP);
1307 	if (!cmpl_data)
1308 		return -ENOSPC;
1309 
1310 	bank = fta_get_uint(results, FBNIC_FW_QSFP_BANK);
1311 	if (bank != cmpl_data->u.qsfp.bank) {
1312 		dev_warn(fbd->dev, "bank not equal to bank requested: %d vs %d\n",
1313 			 bank, cmpl_data->u.qsfp.bank);
1314 		err = -EINVAL;
1315 		goto msg_err;
1316 	}
1317 
1318 	page = fta_get_uint(results, FBNIC_FW_QSFP_PAGE);
1319 	if (page != cmpl_data->u.qsfp.page) {
1320 		dev_warn(fbd->dev, "page not equal to page requested: %d vs %d\n",
1321 			 page, cmpl_data->u.qsfp.page);
1322 		err = -EINVAL;
1323 		goto msg_err;
1324 	}
1325 
1326 	offset = fta_get_uint(results, FBNIC_FW_QSFP_OFFSET);
1327 	length = fta_get_uint(results, FBNIC_FW_QSFP_LENGTH);
1328 
1329 	if (length != cmpl_data->u.qsfp.length ||
1330 	    offset != cmpl_data->u.qsfp.offset) {
1331 		dev_warn(fbd->dev,
1332 			 "offset/length not equal to size requested: %d/%d vs %d/%d\n",
1333 			 offset, length,
1334 			 cmpl_data->u.qsfp.offset, cmpl_data->u.qsfp.length);
1335 		err = -EINVAL;
1336 		goto msg_err;
1337 	}
1338 
1339 	err = fta_get_sint(results, FBNIC_FW_QSFP_ERROR);
1340 	if (err)
1341 		goto msg_err;
1342 
1343 	data_hdr = results[FBNIC_FW_QSFP_DATA];
1344 	if (!data_hdr) {
1345 		err = -ENODATA;
1346 		goto msg_err;
1347 	}
1348 
1349 	/* Copy data */
1350 	data = fbnic_tlv_attr_get_value_ptr(data_hdr);
1351 	memcpy(cmpl_data->u.qsfp.data, data, length);
1352 msg_err:
1353 	cmpl_data->result = err;
1354 	complete(&cmpl_data->done);
1355 	fbnic_fw_put_cmpl(cmpl_data);
1356 
1357 	return err;
1358 }
1359 
1360 /**
1361  * fbnic_fw_xmit_tsene_read_msg - Create and transmit a sensor read request
1362  * @fbd: FBNIC device structure
1363  * @cmpl_data: Completion data structure to store sensor response
1364  *
1365  * Asks the firmware to provide an update with the latest sensor data.
1366  * The response will contain temperature and voltage readings.
1367  *
1368  * Return: 0 on success, negative error value on failure
1369  */
fbnic_fw_xmit_tsene_read_msg(struct fbnic_dev * fbd,struct fbnic_fw_completion * cmpl_data)1370 int fbnic_fw_xmit_tsene_read_msg(struct fbnic_dev *fbd,
1371 				 struct fbnic_fw_completion *cmpl_data)
1372 {
1373 	struct fbnic_tlv_msg *msg;
1374 	int err;
1375 
1376 	if (!fbnic_fw_present(fbd))
1377 		return -ENODEV;
1378 
1379 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_TSENE_READ_REQ);
1380 	if (!msg)
1381 		return -ENOMEM;
1382 
1383 	err = fbnic_mbx_map_req_w_cmpl(fbd, msg, cmpl_data);
1384 	if (err)
1385 		goto free_message;
1386 
1387 	return 0;
1388 
1389 free_message:
1390 	free_page((unsigned long)msg);
1391 	return err;
1392 }
1393 
1394 static const struct fbnic_tlv_index fbnic_tsene_read_resp_index[] = {
1395 	FBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_THERM),
1396 	FBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_VOLT),
1397 	FBNIC_TLV_ATTR_S32(FBNIC_FW_TSENE_ERROR),
1398 	FBNIC_TLV_ATTR_LAST
1399 };
1400 
fbnic_fw_parse_tsene_read_resp(void * opaque,struct fbnic_tlv_msg ** results)1401 static int fbnic_fw_parse_tsene_read_resp(void *opaque,
1402 					  struct fbnic_tlv_msg **results)
1403 {
1404 	struct fbnic_fw_completion *cmpl_data;
1405 	struct fbnic_dev *fbd = opaque;
1406 	s32 err_resp;
1407 	int err = 0;
1408 
1409 	/* Verify we have a completion pointer to provide with data */
1410 	cmpl_data = fbnic_fw_get_cmpl_by_type(fbd,
1411 					      FBNIC_TLV_MSG_ID_TSENE_READ_RESP);
1412 	if (!cmpl_data)
1413 		return -ENOSPC;
1414 
1415 	err_resp = fta_get_sint(results, FBNIC_FW_TSENE_ERROR);
1416 	if (err_resp)
1417 		goto msg_err;
1418 
1419 	if (!results[FBNIC_FW_TSENE_THERM] || !results[FBNIC_FW_TSENE_VOLT]) {
1420 		err = -EINVAL;
1421 		goto msg_err;
1422 	}
1423 
1424 	cmpl_data->u.tsene.millidegrees =
1425 		fta_get_sint(results, FBNIC_FW_TSENE_THERM);
1426 	cmpl_data->u.tsene.millivolts =
1427 		fta_get_sint(results, FBNIC_FW_TSENE_VOLT);
1428 
1429 msg_err:
1430 	cmpl_data->result = err_resp ? : err;
1431 	complete(&cmpl_data->done);
1432 	fbnic_fw_put_cmpl(cmpl_data);
1433 
1434 	return err;
1435 }
1436 
1437 static const struct fbnic_tlv_index fbnic_fw_log_req_index[] = {
1438 	FBNIC_TLV_ATTR_U32(FBNIC_FW_LOG_MSEC),
1439 	FBNIC_TLV_ATTR_U64(FBNIC_FW_LOG_INDEX),
1440 	FBNIC_TLV_ATTR_STRING(FBNIC_FW_LOG_MSG, FBNIC_FW_LOG_MAX_SIZE),
1441 	FBNIC_TLV_ATTR_U32(FBNIC_FW_LOG_LENGTH),
1442 	FBNIC_TLV_ATTR_ARRAY(FBNIC_FW_LOG_MSEC_ARRAY),
1443 	FBNIC_TLV_ATTR_ARRAY(FBNIC_FW_LOG_INDEX_ARRAY),
1444 	FBNIC_TLV_ATTR_ARRAY(FBNIC_FW_LOG_MSG_ARRAY),
1445 	FBNIC_TLV_ATTR_LAST
1446 };
1447 
fbnic_fw_process_log_array(struct fbnic_tlv_msg ** results,u16 length,u16 arr_type_idx,u16 attr_type_idx,struct fbnic_tlv_msg ** tlv_array_out)1448 static int fbnic_fw_process_log_array(struct fbnic_tlv_msg **results,
1449 				      u16 length, u16 arr_type_idx,
1450 				      u16 attr_type_idx,
1451 				      struct fbnic_tlv_msg **tlv_array_out)
1452 {
1453 	struct fbnic_tlv_msg *attr;
1454 	int attr_len;
1455 	int err;
1456 
1457 	if (!results[attr_type_idx])
1458 		return -EINVAL;
1459 
1460 	tlv_array_out[0] = results[attr_type_idx];
1461 
1462 	if (!length)
1463 		return 0;
1464 
1465 	if (!results[arr_type_idx])
1466 		return -EINVAL;
1467 
1468 	attr = results[arr_type_idx];
1469 	attr_len = le16_to_cpu(attr->hdr.len) / sizeof(u32) - 1;
1470 	err = fbnic_tlv_attr_parse_array(&attr[1], attr_len, &tlv_array_out[1],
1471 					 fbnic_fw_log_req_index,
1472 					 attr_type_idx,
1473 					 length);
1474 	if (err)
1475 		return err;
1476 
1477 	return 0;
1478 }
1479 
fbnic_fw_parse_logs(struct fbnic_dev * fbd,struct fbnic_tlv_msg ** msec_tlv,struct fbnic_tlv_msg ** index_tlv,struct fbnic_tlv_msg ** log_tlv,int count)1480 static int fbnic_fw_parse_logs(struct fbnic_dev *fbd,
1481 			       struct fbnic_tlv_msg **msec_tlv,
1482 			       struct fbnic_tlv_msg **index_tlv,
1483 			       struct fbnic_tlv_msg **log_tlv,
1484 			       int count)
1485 {
1486 	int i;
1487 
1488 	for (i = 0; i < count; i++) {
1489 		char log[FBNIC_FW_LOG_MAX_SIZE];
1490 		ssize_t len;
1491 		u64 index;
1492 		u32 msec;
1493 		int err;
1494 
1495 		if (!msec_tlv[i] || !index_tlv[i] || !log_tlv[i]) {
1496 			dev_warn(fbd->dev, "Received log message with missing attributes!\n");
1497 			return -EINVAL;
1498 		}
1499 
1500 		index = fbnic_tlv_attr_get_signed(index_tlv[i], 0);
1501 		msec = fbnic_tlv_attr_get_signed(msec_tlv[i], 0);
1502 		len = fbnic_tlv_attr_get_string(log_tlv[i], log,
1503 						FBNIC_FW_LOG_MAX_SIZE);
1504 		if (len < 0)
1505 			return len;
1506 
1507 		err = fbnic_fw_log_write(fbd, index, msec, log);
1508 		if (err)
1509 			return err;
1510 	}
1511 
1512 	return 0;
1513 }
1514 
fbnic_fw_parse_log_req(void * opaque,struct fbnic_tlv_msg ** results)1515 static int fbnic_fw_parse_log_req(void *opaque,
1516 				  struct fbnic_tlv_msg **results)
1517 {
1518 	struct fbnic_tlv_msg *index_tlv[FBNIC_FW_MAX_LOG_HISTORY];
1519 	struct fbnic_tlv_msg *msec_tlv[FBNIC_FW_MAX_LOG_HISTORY];
1520 	struct fbnic_tlv_msg *log_tlv[FBNIC_FW_MAX_LOG_HISTORY];
1521 	struct fbnic_dev *fbd = opaque;
1522 	u16 length;
1523 	int err;
1524 
1525 	length = fta_get_uint(results, FBNIC_FW_LOG_LENGTH);
1526 	if (length >= FBNIC_FW_MAX_LOG_HISTORY)
1527 		return -E2BIG;
1528 
1529 	err = fbnic_fw_process_log_array(results, length,
1530 					 FBNIC_FW_LOG_MSEC_ARRAY,
1531 					 FBNIC_FW_LOG_MSEC, msec_tlv);
1532 	if (err)
1533 		return err;
1534 
1535 	err = fbnic_fw_process_log_array(results, length,
1536 					 FBNIC_FW_LOG_INDEX_ARRAY,
1537 					 FBNIC_FW_LOG_INDEX, index_tlv);
1538 	if (err)
1539 		return err;
1540 
1541 	err = fbnic_fw_process_log_array(results, length,
1542 					 FBNIC_FW_LOG_MSG_ARRAY,
1543 					 FBNIC_FW_LOG_MSG, log_tlv);
1544 	if (err)
1545 		return err;
1546 
1547 	err = fbnic_fw_parse_logs(fbd, msec_tlv, index_tlv, log_tlv,
1548 				  length + 1);
1549 	if (err)
1550 		return err;
1551 
1552 	return 0;
1553 }
1554 
fbnic_fw_xmit_send_logs(struct fbnic_dev * fbd,bool enable,bool send_log_history)1555 int fbnic_fw_xmit_send_logs(struct fbnic_dev *fbd, bool enable,
1556 			    bool send_log_history)
1557 {
1558 	struct fbnic_tlv_msg *msg;
1559 	int err;
1560 
1561 	if (fbd->fw_cap.running.mgmt.version < MIN_FW_VER_CODE_LOG) {
1562 		dev_warn(fbd->dev, "Firmware version is too old to support firmware logs!\n");
1563 		return -EOPNOTSUPP;
1564 	}
1565 
1566 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_LOG_SEND_LOGS_REQ);
1567 	if (!msg)
1568 		return -ENOMEM;
1569 
1570 	if (enable) {
1571 		err = fbnic_tlv_attr_put_flag(msg, FBNIC_SEND_LOGS);
1572 		if (err)
1573 			goto free_message;
1574 
1575 		/* Report request for version 1 of logs */
1576 		err = fbnic_tlv_attr_put_int(msg, FBNIC_SEND_LOGS_VERSION,
1577 					     FBNIC_FW_LOG_VERSION);
1578 		if (err)
1579 			goto free_message;
1580 
1581 		if (send_log_history) {
1582 			err = fbnic_tlv_attr_put_flag(msg,
1583 						      FBNIC_SEND_LOGS_HISTORY);
1584 			if (err)
1585 				goto free_message;
1586 		}
1587 	}
1588 
1589 	err = fbnic_mbx_map_tlv_msg(fbd, msg);
1590 	if (err)
1591 		goto free_message;
1592 
1593 	return 0;
1594 
1595 free_message:
1596 	free_page((unsigned long)msg);
1597 	return err;
1598 }
1599 
1600 static int
fbnic_fw_parser_test(void * opaque,struct fbnic_tlv_msg ** results)1601 fbnic_fw_parser_test(void *opaque, struct fbnic_tlv_msg **results)
1602 {
1603 	struct fbnic_fw_completion *cmpl;
1604 	struct fbnic_dev *fbd = opaque;
1605 	int err;
1606 
1607 	/* find cmpl */
1608 	cmpl = fbnic_fw_get_cmpl_by_type(fbd, FBNIC_TLV_MSG_ID_TEST);
1609 	if (!cmpl)
1610 		return -ENOSPC;
1611 
1612 	err = fbnic_tlv_parser_test(opaque, results);
1613 
1614 	cmpl->result = err;
1615 	complete(&cmpl->done);
1616 	fbnic_fw_put_cmpl(cmpl);
1617 
1618 	return err;
1619 }
1620 
1621 static const struct fbnic_tlv_parser fbnic_fw_tlv_parser[] = {
1622 	FBNIC_TLV_PARSER(TEST, fbnic_tlv_test_index, fbnic_fw_parser_test),
1623 	FBNIC_TLV_PARSER(FW_CAP_RESP, fbnic_fw_cap_resp_index,
1624 			 fbnic_fw_parse_cap_resp),
1625 	FBNIC_TLV_PARSER(OWNERSHIP_RESP, fbnic_ownership_resp_index,
1626 			 fbnic_fw_parse_ownership_resp),
1627 	FBNIC_TLV_PARSER(HEARTBEAT_RESP, fbnic_heartbeat_resp_index,
1628 			 fbnic_fw_parse_heartbeat_resp),
1629 	FBNIC_TLV_PARSER(COREDUMP_GET_INFO_RESP,
1630 			 fbnic_coredump_info_resp_index,
1631 			 fbnic_fw_parse_coredump_info_resp),
1632 	FBNIC_TLV_PARSER(COREDUMP_READ_RESP, fbnic_coredump_resp_index,
1633 			 fbnic_fw_parse_coredump_resp),
1634 	FBNIC_TLV_PARSER(FW_START_UPGRADE_RESP,
1635 			 fbnic_fw_start_upgrade_resp_index,
1636 			 fbnic_fw_parse_fw_start_upgrade_resp),
1637 	FBNIC_TLV_PARSER(FW_WRITE_CHUNK_REQ,
1638 			 fbnic_fw_write_chunk_req_index,
1639 			 fbnic_fw_parse_fw_write_chunk_req),
1640 	FBNIC_TLV_PARSER(FW_FINISH_UPGRADE_REQ,
1641 			 fbnic_fw_finish_upgrade_req_index,
1642 			 fbnic_fw_parse_fw_finish_upgrade_req),
1643 	FBNIC_TLV_PARSER(QSFP_READ_RESP,
1644 			 fbnic_qsfp_read_resp_index,
1645 			 fbnic_fw_parse_qsfp_read_resp),
1646 	FBNIC_TLV_PARSER(TSENE_READ_RESP,
1647 			 fbnic_tsene_read_resp_index,
1648 			 fbnic_fw_parse_tsene_read_resp),
1649 	FBNIC_TLV_PARSER(LOG_MSG_REQ,
1650 			 fbnic_fw_log_req_index,
1651 			 fbnic_fw_parse_log_req),
1652 	FBNIC_TLV_MSG_ERROR
1653 };
1654 
fbnic_mbx_process_rx_msgs(struct fbnic_dev * fbd)1655 static void fbnic_mbx_process_rx_msgs(struct fbnic_dev *fbd)
1656 {
1657 	struct fbnic_fw_mbx *rx_mbx = &fbd->mbx[FBNIC_IPC_MBX_RX_IDX];
1658 	u8 head = rx_mbx->head, tail = rx_mbx->tail;
1659 	u64 desc, length;
1660 
1661 	while (head != rx_mbx->tail) {
1662 		struct fbnic_tlv_msg *msg;
1663 		int err;
1664 
1665 		desc = __fbnic_mbx_rd_desc(fbd, FBNIC_IPC_MBX_RX_IDX, head);
1666 		if (!(desc & FBNIC_IPC_MBX_DESC_FW_CMPL))
1667 			break;
1668 
1669 		dma_sync_single_for_cpu(fbd->dev, rx_mbx->buf_info[head].addr,
1670 					FBNIC_RX_PAGE_SIZE, DMA_FROM_DEVICE);
1671 
1672 		msg = rx_mbx->buf_info[head].msg;
1673 
1674 		length = FIELD_GET(FBNIC_IPC_MBX_DESC_LEN_MASK, desc);
1675 
1676 		/* Ignore NULL mailbox descriptors */
1677 		if (!length)
1678 			goto next_page;
1679 
1680 		/* Report descriptors with length greater than page size */
1681 		if (length > PAGE_SIZE) {
1682 			dev_warn(fbd->dev,
1683 				 "Invalid mailbox descriptor length: %lld\n",
1684 				 length);
1685 			goto next_page;
1686 		}
1687 
1688 		if (le16_to_cpu(msg->hdr.len) * sizeof(u32) > length)
1689 			dev_warn(fbd->dev, "Mailbox message length mismatch\n");
1690 
1691 		/* If parsing fails dump contents of message to dmesg */
1692 		err = fbnic_tlv_msg_parse(fbd, msg, fbnic_fw_tlv_parser);
1693 		if (err) {
1694 			dev_warn(fbd->dev, "Unable to process message: %d\n",
1695 				 err);
1696 			print_hex_dump(KERN_WARNING, "fbnic:",
1697 				       DUMP_PREFIX_OFFSET, 16, 2,
1698 				       msg, length, true);
1699 		}
1700 
1701 		dev_dbg(fbd->dev, "Parsed msg type %d\n", msg->hdr.type);
1702 next_page:
1703 		fw_wr32(fbd, FBNIC_IPC_MBX(FBNIC_IPC_MBX_RX_IDX, head), 0);
1704 
1705 		rx_mbx->buf_info[tail] = rx_mbx->buf_info[head];
1706 		rx_mbx->buf_info[head].msg = NULL;
1707 		rx_mbx->buf_info[head].addr = 0;
1708 
1709 		__fbnic_mbx_wr_desc(fbd, FBNIC_IPC_MBX_RX_IDX, tail,
1710 				    FIELD_PREP(FBNIC_IPC_MBX_DESC_LEN_MASK,
1711 					       FBNIC_RX_PAGE_SIZE) |
1712 				    (rx_mbx->buf_info[tail].addr &
1713 				     FBNIC_IPC_MBX_DESC_ADDR_MASK) |
1714 				    FBNIC_IPC_MBX_DESC_HOST_CMPL);
1715 
1716 		head = (head + 1) & (FBNIC_IPC_MBX_DESC_LEN - 1);
1717 		tail = (tail + 1) & (FBNIC_IPC_MBX_DESC_LEN - 1);
1718 	}
1719 
1720 	/* Record head for next interrupt */
1721 	rx_mbx->head = head;
1722 	rx_mbx->tail = tail;
1723 }
1724 
fbnic_mbx_poll(struct fbnic_dev * fbd)1725 void fbnic_mbx_poll(struct fbnic_dev *fbd)
1726 {
1727 	fbnic_mbx_event(fbd);
1728 
1729 	fbnic_mbx_process_tx_msgs(fbd);
1730 	fbnic_mbx_process_rx_msgs(fbd);
1731 }
1732 
fbnic_mbx_poll_tx_ready(struct fbnic_dev * fbd)1733 int fbnic_mbx_poll_tx_ready(struct fbnic_dev *fbd)
1734 {
1735 	struct fbnic_fw_mbx *tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX];
1736 	unsigned long timeout = jiffies + 10 * HZ + 1;
1737 	int err, i;
1738 
1739 	do {
1740 		if (!time_is_after_jiffies(timeout))
1741 			return -ETIMEDOUT;
1742 
1743 		/* Force the firmware to trigger an interrupt response to
1744 		 * avoid the mailbox getting stuck closed if the interrupt
1745 		 * is reset.
1746 		 */
1747 		fbnic_mbx_reset_desc_ring(fbd, FBNIC_IPC_MBX_TX_IDX);
1748 
1749 		/* Immediate fail if BAR4 went away */
1750 		if (!fbnic_fw_present(fbd))
1751 			return -ENODEV;
1752 
1753 		msleep(20);
1754 	} while (!fbnic_mbx_event(fbd));
1755 
1756 	/* FW has shown signs of life. Enable DMA and start Tx/Rx */
1757 	for (i = 0; i < FBNIC_IPC_MBX_INDICES; i++) {
1758 		err = fbnic_mbx_init_desc_ring(fbd, i);
1759 		if (err)
1760 			goto clean_mbx;
1761 	}
1762 
1763 	/* Request an update from the firmware. This should overwrite
1764 	 * mgmt.version once we get the actual version from the firmware
1765 	 * in the capabilities request message.
1766 	 */
1767 	err = fbnic_fw_xmit_simple_msg(fbd, FBNIC_TLV_MSG_ID_HOST_CAP_REQ);
1768 	if (err)
1769 		goto clean_mbx;
1770 
1771 	/* Poll until we get a current management firmware version, use "1"
1772 	 * to indicate we entered the polling state waiting for a response
1773 	 */
1774 	for (fbd->fw_cap.running.mgmt.version = 1;
1775 	     fbd->fw_cap.running.mgmt.version < MIN_FW_VER_CODE;) {
1776 		if (!tx_mbx->ready)
1777 			err = -ENODEV;
1778 		if (err)
1779 			goto clean_mbx;
1780 
1781 		msleep(20);
1782 		fbnic_mbx_poll(fbd);
1783 
1784 		/* set err, but wait till mgmt.version check to report it */
1785 		if (!time_is_after_jiffies(timeout))
1786 			err = -ETIMEDOUT;
1787 	}
1788 
1789 	return 0;
1790 clean_mbx:
1791 	/* Cleanup Rx buffers and disable mailbox */
1792 	fbnic_mbx_clean(fbd);
1793 	return err;
1794 }
1795 
__fbnic_fw_evict_cmpl(struct fbnic_fw_completion * cmpl_data)1796 static void __fbnic_fw_evict_cmpl(struct fbnic_fw_completion *cmpl_data)
1797 {
1798 	cmpl_data->result = -EPIPE;
1799 	complete(&cmpl_data->done);
1800 }
1801 
fbnic_mbx_evict_all_cmpl(struct fbnic_dev * fbd)1802 static void fbnic_mbx_evict_all_cmpl(struct fbnic_dev *fbd)
1803 {
1804 	int i;
1805 
1806 	for (i = 0; i < FBNIC_MBX_CMPL_SLOTS; i++) {
1807 		struct fbnic_fw_completion *cmpl_data = fbd->cmpl_data[i];
1808 
1809 		if (cmpl_data)
1810 			__fbnic_fw_evict_cmpl(cmpl_data);
1811 	}
1812 
1813 	memset(fbd->cmpl_data, 0, sizeof(fbd->cmpl_data));
1814 }
1815 
fbnic_mbx_flush_tx(struct fbnic_dev * fbd)1816 void fbnic_mbx_flush_tx(struct fbnic_dev *fbd)
1817 {
1818 	unsigned long timeout = jiffies + 10 * HZ + 1;
1819 	struct fbnic_fw_mbx *tx_mbx;
1820 	u8 tail;
1821 
1822 	/* Record current Rx stats */
1823 	tx_mbx = &fbd->mbx[FBNIC_IPC_MBX_TX_IDX];
1824 
1825 	spin_lock_irq(&fbd->fw_tx_lock);
1826 
1827 	/* Clear ready to prevent any further attempts to transmit */
1828 	tx_mbx->ready = false;
1829 
1830 	/* Read tail to determine the last tail state for the ring */
1831 	tail = tx_mbx->tail;
1832 
1833 	/* Flush any completions as we are no longer processing Rx */
1834 	fbnic_mbx_evict_all_cmpl(fbd);
1835 
1836 	spin_unlock_irq(&fbd->fw_tx_lock);
1837 
1838 	/* Give firmware time to process packet,
1839 	 * we will wait up to 10 seconds which is 500 waits of 20ms.
1840 	 */
1841 	do {
1842 		u8 head = tx_mbx->head;
1843 
1844 		/* Tx ring is empty once head == tail */
1845 		if (head == tail)
1846 			break;
1847 
1848 		msleep(20);
1849 		fbnic_mbx_process_tx_msgs(fbd);
1850 	} while (time_is_after_jiffies(timeout));
1851 }
1852 
1853 /**
1854  * fbnic_fw_mbx_self_test() - verify firmware interface
1855  * @fbd: device to test
1856  *
1857  * This function tests the interfaces to/from the firmware.
1858  *
1859  * Return: See enum fbnic_fw_self_test_codes
1860  **/
fbnic_fw_mbx_self_test(struct fbnic_dev * fbd)1861 enum fbnic_fw_self_test_codes fbnic_fw_mbx_self_test(struct fbnic_dev *fbd)
1862 {
1863 	enum fbnic_fw_self_test_codes err;
1864 	struct fbnic_fw_completion *cmpl;
1865 
1866 	/* Skip test if FW interface is not present */
1867 	if (!fbnic_fw_present(fbd))
1868 		return FBNIC_TEST_FW_NO_FIRMWARE;
1869 
1870 	cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TEST);
1871 	if (!cmpl)
1872 		return FBNIC_TEST_FW_NO_CMPL;
1873 
1874 	/* Load a test message onto the FW mailbox interface
1875 	 * and arm the completion.
1876 	 */
1877 	err = fbnic_fw_xmit_test_msg(fbd, cmpl);
1878 	if (err) {
1879 		err = FBNIC_TEST_FW_NO_XMIT;
1880 		goto exit_free;
1881 	}
1882 
1883 	/* Verify we received a message back */
1884 	if (!fbnic_mbx_wait_for_cmpl(cmpl)) {
1885 		err = FBNIC_TEST_FW_NO_MSG;
1886 		goto exit_cleanup;
1887 	}
1888 
1889 	/* Verify there were no parsing errors */
1890 	if (cmpl->result)
1891 		err = FBNIC_TEST_FW_PARSE;
1892 exit_cleanup:
1893 	fbnic_mbx_clear_cmpl(fbd, cmpl);
1894 exit_free:
1895 	fbnic_fw_put_cmpl(cmpl);
1896 
1897 	return err;
1898 }
1899 
fbnic_fw_xmit_rpc_macda_sync(struct fbnic_dev * fbd)1900 int fbnic_fw_xmit_rpc_macda_sync(struct fbnic_dev *fbd)
1901 {
1902 	struct fbnic_tlv_msg *mac_array;
1903 	int i, addr_count = 0, err;
1904 	struct fbnic_tlv_msg *msg;
1905 	u32 rx_flags = 0;
1906 
1907 	/* Nothing to do if there is no FW to sync with */
1908 	if (!fbd->mbx[FBNIC_IPC_MBX_TX_IDX].ready)
1909 		return 0;
1910 
1911 	msg = fbnic_tlv_msg_alloc(FBNIC_TLV_MSG_ID_RPC_MAC_SYNC_REQ);
1912 	if (!msg)
1913 		return -ENOMEM;
1914 
1915 	mac_array = fbnic_tlv_attr_nest_start(msg,
1916 					      FBNIC_FW_RPC_MAC_SYNC_UC_ARRAY);
1917 	if (!mac_array)
1918 		goto free_message_nospc;
1919 
1920 	/* Populate the unicast MAC addrs and capture PROMISC/ALLMULTI flags */
1921 	for (addr_count = 0, i = FBNIC_RPC_TCAM_MACDA_PROMISC_IDX;
1922 	     i >= fbd->mac_addr_boundary; i--) {
1923 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
1924 
1925 		if (mac_addr->state != FBNIC_TCAM_S_VALID)
1926 			continue;
1927 		if (test_bit(FBNIC_MAC_ADDR_T_ALLMULTI, mac_addr->act_tcam))
1928 			rx_flags |= FW_RPC_MAC_SYNC_RX_FLAGS_ALLMULTI;
1929 		if (test_bit(FBNIC_MAC_ADDR_T_PROMISC, mac_addr->act_tcam))
1930 			rx_flags |= FW_RPC_MAC_SYNC_RX_FLAGS_PROMISC;
1931 		if (!test_bit(FBNIC_MAC_ADDR_T_UNICAST, mac_addr->act_tcam))
1932 			continue;
1933 		if (addr_count == FW_RPC_MAC_SYNC_UC_ARRAY_SIZE) {
1934 			rx_flags |= FW_RPC_MAC_SYNC_RX_FLAGS_PROMISC;
1935 			continue;
1936 		}
1937 
1938 		err = fbnic_tlv_attr_put_value(mac_array,
1939 					       FBNIC_FW_RPC_MAC_SYNC_MAC_ADDR,
1940 					       mac_addr->value.addr8,
1941 					       ETH_ALEN);
1942 		if (err)
1943 			goto free_message;
1944 		addr_count++;
1945 	}
1946 
1947 	/* Close array */
1948 	fbnic_tlv_attr_nest_stop(msg);
1949 
1950 	mac_array = fbnic_tlv_attr_nest_start(msg,
1951 					      FBNIC_FW_RPC_MAC_SYNC_MC_ARRAY);
1952 	if (!mac_array)
1953 		goto free_message_nospc;
1954 
1955 	/* Repeat for multicast addrs, record BROADCAST/ALLMULTI flags */
1956 	for (addr_count = 0, i = FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX;
1957 	     i < fbd->mac_addr_boundary; i++) {
1958 		struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
1959 
1960 		if (mac_addr->state != FBNIC_TCAM_S_VALID)
1961 			continue;
1962 		if (test_bit(FBNIC_MAC_ADDR_T_BROADCAST, mac_addr->act_tcam))
1963 			rx_flags |= FW_RPC_MAC_SYNC_RX_FLAGS_BROADCAST;
1964 		if (test_bit(FBNIC_MAC_ADDR_T_ALLMULTI, mac_addr->act_tcam))
1965 			rx_flags |= FW_RPC_MAC_SYNC_RX_FLAGS_ALLMULTI;
1966 		if (!test_bit(FBNIC_MAC_ADDR_T_MULTICAST, mac_addr->act_tcam))
1967 			continue;
1968 		if (addr_count == FW_RPC_MAC_SYNC_MC_ARRAY_SIZE) {
1969 			rx_flags |= FW_RPC_MAC_SYNC_RX_FLAGS_ALLMULTI;
1970 			continue;
1971 		}
1972 
1973 		err = fbnic_tlv_attr_put_value(mac_array,
1974 					       FBNIC_FW_RPC_MAC_SYNC_MAC_ADDR,
1975 					       mac_addr->value.addr8,
1976 					       ETH_ALEN);
1977 		if (err)
1978 			goto free_message;
1979 		addr_count++;
1980 	}
1981 
1982 	/* Close array */
1983 	fbnic_tlv_attr_nest_stop(msg);
1984 
1985 	/* Report flags at end of list */
1986 	err = fbnic_tlv_attr_put_int(msg, FBNIC_FW_RPC_MAC_SYNC_RX_FLAGS,
1987 				     rx_flags);
1988 	if (err)
1989 		goto free_message;
1990 
1991 	/* Send message off to FW notifying it of current RPC config */
1992 	err = fbnic_mbx_map_tlv_msg(fbd, msg);
1993 	if (err)
1994 		goto free_message;
1995 	return 0;
1996 free_message_nospc:
1997 	err = -ENOSPC;
1998 free_message:
1999 	free_page((unsigned long)msg);
2000 	return err;
2001 }
2002 
fbnic_get_fw_ver_commit_str(struct fbnic_dev * fbd,char * fw_version,const size_t str_sz)2003 void fbnic_get_fw_ver_commit_str(struct fbnic_dev *fbd, char *fw_version,
2004 				 const size_t str_sz)
2005 {
2006 	struct fbnic_fw_ver *mgmt = &fbd->fw_cap.running.mgmt;
2007 	const char *delim = "";
2008 
2009 	if (mgmt->commit[0])
2010 		delim = "_";
2011 
2012 	fbnic_mk_full_fw_ver_str(mgmt->version, delim, mgmt->commit,
2013 				 fw_version, str_sz);
2014 }
2015 
__fbnic_fw_alloc_cmpl(u32 msg_type,size_t priv_size)2016 struct fbnic_fw_completion *__fbnic_fw_alloc_cmpl(u32 msg_type,
2017 						  size_t priv_size)
2018 {
2019 	struct fbnic_fw_completion *cmpl;
2020 
2021 	cmpl = kzalloc(sizeof(*cmpl) + priv_size, GFP_KERNEL);
2022 	if (!cmpl)
2023 		return NULL;
2024 
2025 	cmpl->msg_type = msg_type;
2026 	init_completion(&cmpl->done);
2027 	kref_init(&cmpl->ref_count);
2028 
2029 	return cmpl;
2030 }
2031 
fbnic_fw_alloc_cmpl(u32 msg_type)2032 struct fbnic_fw_completion *fbnic_fw_alloc_cmpl(u32 msg_type)
2033 {
2034 	return __fbnic_fw_alloc_cmpl(msg_type, 0);
2035 }
2036 
fbnic_fw_put_cmpl(struct fbnic_fw_completion * fw_cmpl)2037 void fbnic_fw_put_cmpl(struct fbnic_fw_completion *fw_cmpl)
2038 {
2039 	kref_put(&fw_cmpl->ref_count, fbnic_fw_release_cmpl_data);
2040 }
2041