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