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