hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/net/ethernet/mellanox/mlxsw/pci.c
....@@ -102,6 +102,7 @@
102102 struct mlxsw_pci {
103103 struct pci_dev *pdev;
104104 u8 __iomem *hw_addr;
105
+ u64 free_running_clock_offset;
105106 struct mlxsw_pci_queue_type_group queues[MLXSW_PCI_QUEUE_TYPE_COUNT];
106107 u32 doorbell_offset;
107108 struct mlxsw_core *core;
....@@ -283,15 +284,22 @@
283284 static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox,
284285 struct mlxsw_pci_queue *q)
285286 {
287
+ int tclass;
288
+ int lp;
286289 int i;
287290 int err;
288291
289292 q->producer_counter = 0;
290293 q->consumer_counter = 0;
294
+ tclass = q->num == MLXSW_PCI_SDQ_EMAD_INDEX ? MLXSW_PCI_SDQ_EMAD_TC :
295
+ MLXSW_PCI_SDQ_CTL_TC;
296
+ lp = q->num == MLXSW_PCI_SDQ_EMAD_INDEX ? MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_IGNORE_WQE :
297
+ MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_WQE;
291298
292299 /* Set CQ of same number of this SDQ. */
293300 mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, q->num);
294
- mlxsw_cmd_mbox_sw2hw_dq_sdq_tclass_set(mbox, 3);
301
+ mlxsw_cmd_mbox_sw2hw_dq_sdq_lp_set(mbox, lp);
302
+ mlxsw_cmd_mbox_sw2hw_dq_sdq_tclass_set(mbox, tclass);
295303 mlxsw_cmd_mbox_sw2hw_dq_log2_dq_sz_set(mbox, 3); /* 8 pages */
296304 for (i = 0; i < MLXSW_PCI_AQ_PAGES; i++) {
297305 dma_addr_t mapaddr = __mlxsw_pci_queue_page_get(q, i);
....@@ -349,12 +357,9 @@
349357 struct sk_buff *skb;
350358 int err;
351359
352
- elem_info->u.rdq.skb = NULL;
353360 skb = netdev_alloc_skb_ip_align(NULL, buf_len);
354361 if (!skb)
355362 return -ENOMEM;
356
-
357
- /* Assume that wqe was previously zeroed. */
358363
359364 err = mlxsw_pci_wqe_frag_map(mlxsw_pci, wqe, 0, skb->data,
360365 buf_len, DMA_FROM_DEVICE);
....@@ -507,17 +512,28 @@
507512 {
508513 struct pci_dev *pdev = mlxsw_pci->pdev;
509514 struct mlxsw_pci_queue_elem_info *elem_info;
515
+ struct mlxsw_tx_info tx_info;
510516 char *wqe;
511517 struct sk_buff *skb;
512518 int i;
513519
514520 spin_lock(&q->lock);
515521 elem_info = mlxsw_pci_queue_elem_info_consumer_get(q);
522
+ tx_info = mlxsw_skb_cb(elem_info->u.sdq.skb)->tx_info;
516523 skb = elem_info->u.sdq.skb;
517524 wqe = elem_info->elem;
518525 for (i = 0; i < MLXSW_PCI_WQE_SG_ENTRIES; i++)
519526 mlxsw_pci_wqe_frag_unmap(mlxsw_pci, wqe, i, DMA_TO_DEVICE);
520
- dev_kfree_skb_any(skb);
527
+
528
+ if (unlikely(!tx_info.is_emad &&
529
+ skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
530
+ mlxsw_core_ptp_transmitted(mlxsw_pci->core, skb,
531
+ tx_info.local_port);
532
+ skb = NULL;
533
+ }
534
+
535
+ if (skb)
536
+ dev_kfree_skb_any(skb);
521537 elem_info->u.sdq.skb = NULL;
522538
523539 if (q->consumer_counter++ != consumer_counter_limit)
....@@ -532,21 +548,26 @@
532548 {
533549 struct pci_dev *pdev = mlxsw_pci->pdev;
534550 struct mlxsw_pci_queue_elem_info *elem_info;
535
- char *wqe;
551
+ struct mlxsw_rx_info rx_info = {};
552
+ char wqe[MLXSW_PCI_WQE_SIZE];
536553 struct sk_buff *skb;
537
- struct mlxsw_rx_info rx_info;
538554 u16 byte_count;
539555 int err;
540556
541557 elem_info = mlxsw_pci_queue_elem_info_consumer_get(q);
542
- skb = elem_info->u.sdq.skb;
543
- if (!skb)
544
- return;
545
- wqe = elem_info->elem;
546
- mlxsw_pci_wqe_frag_unmap(mlxsw_pci, wqe, 0, DMA_FROM_DEVICE);
558
+ skb = elem_info->u.rdq.skb;
559
+ memcpy(wqe, elem_info->elem, MLXSW_PCI_WQE_SIZE);
547560
548561 if (q->consumer_counter++ != consumer_counter_limit)
549562 dev_dbg_ratelimited(&pdev->dev, "Consumer counter does not match limit in RDQ\n");
563
+
564
+ err = mlxsw_pci_rdq_skb_alloc(mlxsw_pci, elem_info);
565
+ if (err) {
566
+ dev_err_ratelimited(&pdev->dev, "Failed to alloc skb for RDQ\n");
567
+ goto out;
568
+ }
569
+
570
+ mlxsw_pci_wqe_frag_unmap(mlxsw_pci, wqe, 0, DMA_FROM_DEVICE);
550571
551572 if (mlxsw_pci_cqe_lag_get(cqe_v, cqe)) {
552573 rx_info.is_lag = true;
....@@ -560,16 +581,26 @@
560581
561582 rx_info.trap_id = mlxsw_pci_cqe_trap_id_get(cqe);
562583
584
+ if (rx_info.trap_id == MLXSW_TRAP_ID_DISCARD_INGRESS_ACL ||
585
+ rx_info.trap_id == MLXSW_TRAP_ID_DISCARD_EGRESS_ACL) {
586
+ u32 cookie_index = 0;
587
+
588
+ if (mlxsw_pci->max_cqe_ver >= MLXSW_PCI_CQE_V2)
589
+ cookie_index = mlxsw_pci_cqe2_user_def_val_orig_pkt_len_get(cqe);
590
+ mlxsw_skb_cb(skb)->cookie_index = cookie_index;
591
+ } else if (rx_info.trap_id >= MLXSW_TRAP_ID_MIRROR_SESSION0 &&
592
+ rx_info.trap_id <= MLXSW_TRAP_ID_MIRROR_SESSION7 &&
593
+ mlxsw_pci->max_cqe_ver >= MLXSW_PCI_CQE_V2) {
594
+ rx_info.mirror_reason = mlxsw_pci_cqe2_mirror_reason_get(cqe);
595
+ }
596
+
563597 byte_count = mlxsw_pci_cqe_byte_count_get(cqe);
564598 if (mlxsw_pci_cqe_crc_get(cqe_v, cqe))
565599 byte_count -= ETH_FCS_LEN;
566600 skb_put(skb, byte_count);
567601 mlxsw_core_skb_receive(mlxsw_pci->core, skb, &rx_info);
568602
569
- memset(wqe, 0, q->elem_size);
570
- err = mlxsw_pci_rdq_skb_alloc(mlxsw_pci, elem_info);
571
- if (err)
572
- dev_dbg_ratelimited(&pdev->dev, "Failed to alloc skb for RDQ\n");
603
+out:
573604 /* Everything is set up, ring doorbell to pass elem to HW */
574605 q->producer_counter++;
575606 mlxsw_pci_queue_doorbell_producer_ring(mlxsw_pci, q);
....@@ -592,9 +623,9 @@
592623 return elem;
593624 }
594625
595
-static void mlxsw_pci_cq_tasklet(unsigned long data)
626
+static void mlxsw_pci_cq_tasklet(struct tasklet_struct *t)
596627 {
597
- struct mlxsw_pci_queue *q = (struct mlxsw_pci_queue *) data;
628
+ struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet);
598629 struct mlxsw_pci *mlxsw_pci = q->pci;
599630 char *cqe;
600631 int items = 0;
....@@ -705,9 +736,9 @@
705736 return elem;
706737 }
707738
708
-static void mlxsw_pci_eq_tasklet(unsigned long data)
739
+static void mlxsw_pci_eq_tasklet(struct tasklet_struct *t)
709740 {
710
- struct mlxsw_pci_queue *q = (struct mlxsw_pci_queue *) data;
741
+ struct mlxsw_pci_queue *q = from_tasklet(q, t, tasklet);
711742 struct mlxsw_pci *mlxsw_pci = q->pci;
712743 u8 cq_count = mlxsw_pci_cq_count(mlxsw_pci);
713744 unsigned long active_cqns[BITS_TO_LONGS(MLXSW_PCI_CQS_MAX)];
....@@ -764,7 +795,7 @@
764795 struct mlxsw_pci_queue *q);
765796 void (*fini)(struct mlxsw_pci *mlxsw_pci,
766797 struct mlxsw_pci_queue *q);
767
- void (*tasklet)(unsigned long data);
798
+ void (*tasklet)(struct tasklet_struct *t);
768799 u16 (*elem_count_f)(const struct mlxsw_pci_queue *q);
769800 u8 (*elem_size_f)(const struct mlxsw_pci_queue *q);
770801 u16 elem_count;
....@@ -827,7 +858,7 @@
827858 q->pci = mlxsw_pci;
828859
829860 if (q_ops->tasklet)
830
- tasklet_init(&q->tasklet, q_ops->tasklet, (unsigned long) q);
861
+ tasklet_setup(&q->tasklet, q_ops->tasklet);
831862
832863 mem_item->size = MLXSW_PCI_AQ_SIZE;
833864 mem_item->buf = pci_alloc_consistent(mlxsw_pci->pdev,
....@@ -835,7 +866,6 @@
835866 &mem_item->mapaddr);
836867 if (!mem_item->buf)
837868 return -ENOMEM;
838
- memset(mem_item->buf, 0, mem_item->size);
839869
840870 q->elem_info = kcalloc(q->count, sizeof(*q->elem_info), GFP_KERNEL);
841871 if (!q->elem_info) {
....@@ -952,6 +982,7 @@
952982 eq_log2sz = mlxsw_cmd_mbox_query_aq_cap_log_max_eq_sz_get(mbox);
953983
954984 if (num_sdqs + num_rdqs > num_cqs ||
985
+ num_sdqs < MLXSW_PCI_SDQS_MIN ||
955986 num_cqs > MLXSW_PCI_CQS_MAX || num_eqs != MLXSW_PCI_EQS_COUNT) {
956987 dev_err(&pdev->dev, "Unsupported number of queues\n");
957988 return -EINVAL;
....@@ -1037,42 +1068,6 @@
10371068 mask |= 2;
10381069 }
10391070 mlxsw_cmd_mbox_config_profile_swid_config_mask_set(mbox, index, mask);
1040
-}
1041
-
1042
-static int mlxsw_pci_resources_query(struct mlxsw_pci *mlxsw_pci, char *mbox,
1043
- struct mlxsw_res *res)
1044
-{
1045
- int index, i;
1046
- u64 data;
1047
- u16 id;
1048
- int err;
1049
-
1050
- if (!res)
1051
- return 0;
1052
-
1053
- mlxsw_cmd_mbox_zero(mbox);
1054
-
1055
- for (index = 0; index < MLXSW_CMD_QUERY_RESOURCES_MAX_QUERIES;
1056
- index++) {
1057
- err = mlxsw_cmd_query_resources(mlxsw_pci->core, mbox, index);
1058
- if (err)
1059
- return err;
1060
-
1061
- for (i = 0; i < MLXSW_CMD_QUERY_RESOURCES_PER_QUERY; i++) {
1062
- id = mlxsw_cmd_mbox_query_resource_id_get(mbox, i);
1063
- data = mlxsw_cmd_mbox_query_resource_data_get(mbox, i);
1064
-
1065
- if (id == MLXSW_CMD_QUERY_RESOURCES_TABLE_END_ID)
1066
- return 0;
1067
-
1068
- mlxsw_res_parse(res, id, data);
1069
- }
1070
- }
1071
-
1072
- /* If after MLXSW_RESOURCES_QUERY_MAX_QUERIES we still didn't get
1073
- * MLXSW_RESOURCES_TABLE_END_ID, something went bad in the FW.
1074
- */
1075
- return -EIO;
10761071 }
10771072
10781073 static int
....@@ -1343,34 +1338,62 @@
13431338 mbox->mapaddr);
13441339 }
13451340
1346
-static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci,
1347
- const struct pci_device_id *id)
1341
+static int mlxsw_pci_sys_ready_wait(struct mlxsw_pci *mlxsw_pci,
1342
+ const struct pci_device_id *id,
1343
+ u32 *p_sys_status)
13481344 {
13491345 unsigned long end;
1350
- char mrsr_pl[MLXSW_REG_MRSR_LEN];
1351
- int err;
1346
+ u32 val;
13521347
1353
- mlxsw_reg_mrsr_pack(mrsr_pl);
1354
- err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl);
1355
- if (err)
1356
- return err;
13571348 if (id->device == PCI_DEVICE_ID_MELLANOX_SWITCHX2) {
13581349 msleep(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS);
13591350 return 0;
13601351 }
13611352
1362
- /* We must wait for the HW to become responsive once again. */
1353
+ /* We must wait for the HW to become responsive. */
13631354 msleep(MLXSW_PCI_SW_RESET_WAIT_MSECS);
13641355
13651356 end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS);
13661357 do {
1367
- u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY);
1368
-
1358
+ val = mlxsw_pci_read32(mlxsw_pci, FW_READY);
13691359 if ((val & MLXSW_PCI_FW_READY_MASK) == MLXSW_PCI_FW_READY_MAGIC)
13701360 return 0;
13711361 cond_resched();
13721362 } while (time_before(jiffies, end));
1363
+
1364
+ *p_sys_status = val & MLXSW_PCI_FW_READY_MASK;
1365
+
13731366 return -EBUSY;
1367
+}
1368
+
1369
+static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci,
1370
+ const struct pci_device_id *id)
1371
+{
1372
+ struct pci_dev *pdev = mlxsw_pci->pdev;
1373
+ char mrsr_pl[MLXSW_REG_MRSR_LEN];
1374
+ u32 sys_status;
1375
+ int err;
1376
+
1377
+ err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status);
1378
+ if (err) {
1379
+ dev_err(&pdev->dev, "Failed to reach system ready status before reset. Status is 0x%x\n",
1380
+ sys_status);
1381
+ return err;
1382
+ }
1383
+
1384
+ mlxsw_reg_mrsr_pack(mrsr_pl);
1385
+ err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl);
1386
+ if (err)
1387
+ return err;
1388
+
1389
+ err = mlxsw_pci_sys_ready_wait(mlxsw_pci, id, &sys_status);
1390
+ if (err) {
1391
+ dev_err(&pdev->dev, "Failed to reach system ready status after reset. Status is 0x%x\n",
1392
+ sys_status);
1393
+ return err;
1394
+ }
1395
+
1396
+ return 0;
13741397 }
13751398
13761399 static int mlxsw_pci_alloc_irq_vectors(struct mlxsw_pci *mlxsw_pci)
....@@ -1398,22 +1421,11 @@
13981421 u16 num_pages;
13991422 int err;
14001423
1401
- mutex_init(&mlxsw_pci->cmd.lock);
1402
- init_waitqueue_head(&mlxsw_pci->cmd.wait);
1403
-
14041424 mlxsw_pci->core = mlxsw_core;
14051425
14061426 mbox = mlxsw_cmd_mbox_alloc();
14071427 if (!mbox)
14081428 return -ENOMEM;
1409
-
1410
- err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
1411
- if (err)
1412
- goto mbox_put;
1413
-
1414
- err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.out_mbox);
1415
- if (err)
1416
- goto err_out_mbox_alloc;
14171429
14181430 err = mlxsw_pci_sw_reset(mlxsw_pci, mlxsw_pci->id);
14191431 if (err)
....@@ -1450,6 +1462,15 @@
14501462 mlxsw_pci->doorbell_offset =
14511463 mlxsw_cmd_mbox_query_fw_doorbell_page_offset_get(mbox);
14521464
1465
+ if (mlxsw_cmd_mbox_query_fw_fr_rn_clk_bar_get(mbox) != 0) {
1466
+ dev_err(&pdev->dev, "Unsupported free running clock BAR queried from hw\n");
1467
+ err = -EINVAL;
1468
+ goto err_fr_rn_clk_bar;
1469
+ }
1470
+
1471
+ mlxsw_pci->free_running_clock_offset =
1472
+ mlxsw_cmd_mbox_query_fw_free_running_clock_offset_get(mbox);
1473
+
14531474 num_pages = mlxsw_cmd_mbox_query_fw_fw_pages_get(mbox);
14541475 err = mlxsw_pci_fw_area_init(mlxsw_pci, mbox, num_pages);
14551476 if (err)
....@@ -1459,7 +1480,7 @@
14591480 if (err)
14601481 goto err_boardinfo;
14611482
1462
- err = mlxsw_pci_resources_query(mlxsw_pci, mbox, res);
1483
+ err = mlxsw_core_resources_query(mlxsw_core, mbox, res);
14631484 if (err)
14641485 goto err_query_resources;
14651486
....@@ -1505,15 +1526,13 @@
15051526 err_boardinfo:
15061527 mlxsw_pci_fw_area_fini(mlxsw_pci);
15071528 err_fw_area_init:
1529
+err_fr_rn_clk_bar:
15081530 err_doorbell_page_bar:
15091531 err_iface_rev:
15101532 err_query_fw:
15111533 mlxsw_pci_free_irq_vectors(mlxsw_pci);
15121534 err_alloc_irq:
15131535 err_sw_reset:
1514
- mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.out_mbox);
1515
-err_out_mbox_alloc:
1516
- mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
15171536 mbox_put:
15181537 mlxsw_cmd_mbox_free(mbox);
15191538 return err;
....@@ -1527,15 +1546,21 @@
15271546 mlxsw_pci_aqs_fini(mlxsw_pci);
15281547 mlxsw_pci_fw_area_fini(mlxsw_pci);
15291548 mlxsw_pci_free_irq_vectors(mlxsw_pci);
1530
- mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.out_mbox);
1531
- mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
15321549 }
15331550
15341551 static struct mlxsw_pci_queue *
15351552 mlxsw_pci_sdq_pick(struct mlxsw_pci *mlxsw_pci,
15361553 const struct mlxsw_tx_info *tx_info)
15371554 {
1538
- u8 sdqn = tx_info->local_port % mlxsw_pci_sdq_count(mlxsw_pci);
1555
+ u8 ctl_sdq_count = mlxsw_pci_sdq_count(mlxsw_pci) - 1;
1556
+ u8 sdqn;
1557
+
1558
+ if (tx_info->is_emad) {
1559
+ sdqn = MLXSW_PCI_SDQ_EMAD_INDEX;
1560
+ } else {
1561
+ BUILD_BUG_ON(MLXSW_PCI_SDQ_EMAD_INDEX != 0);
1562
+ sdqn = 1 + (tx_info->local_port % ctl_sdq_count);
1563
+ }
15391564
15401565 return mlxsw_pci_sdq_get(mlxsw_pci, sdqn);
15411566 }
....@@ -1573,11 +1598,12 @@
15731598 err = -EAGAIN;
15741599 goto unlock;
15751600 }
1601
+ mlxsw_skb_cb(skb)->tx_info = *tx_info;
15761602 elem_info->u.sdq.skb = skb;
15771603
15781604 wqe = elem_info->elem;
15791605 mlxsw_pci_wqe_c_set(wqe, 1); /* always report completion */
1580
- mlxsw_pci_wqe_lp_set(wqe, !!tx_info->is_emad);
1606
+ mlxsw_pci_wqe_lp_set(wqe, 0);
15811607 mlxsw_pci_wqe_type_set(wqe, MLXSW_PCI_WQE_TYPE_ETHERNET);
15821608
15831609 err = mlxsw_pci_wqe_frag_map(mlxsw_pci, wqe, 0, skb->data,
....@@ -1595,6 +1621,9 @@
15951621 if (err)
15961622 goto unmap_frags;
15971623 }
1624
+
1625
+ if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
1626
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
15981627
15991628 /* Set unused sq entries byte count to zero. */
16001629 for (i++; i < MLXSW_PCI_WQE_SG_ENTRIES; i++)
....@@ -1708,6 +1737,24 @@
17081737 return err;
17091738 }
17101739
1740
+static u32 mlxsw_pci_read_frc_h(void *bus_priv)
1741
+{
1742
+ struct mlxsw_pci *mlxsw_pci = bus_priv;
1743
+ u64 frc_offset;
1744
+
1745
+ frc_offset = mlxsw_pci->free_running_clock_offset;
1746
+ return mlxsw_pci_read32(mlxsw_pci, FREE_RUNNING_CLOCK_H(frc_offset));
1747
+}
1748
+
1749
+static u32 mlxsw_pci_read_frc_l(void *bus_priv)
1750
+{
1751
+ struct mlxsw_pci *mlxsw_pci = bus_priv;
1752
+ u64 frc_offset;
1753
+
1754
+ frc_offset = mlxsw_pci->free_running_clock_offset;
1755
+ return mlxsw_pci_read32(mlxsw_pci, FREE_RUNNING_CLOCK_L(frc_offset));
1756
+}
1757
+
17111758 static const struct mlxsw_bus mlxsw_pci_bus = {
17121759 .kind = "pci",
17131760 .init = mlxsw_pci_init,
....@@ -1715,14 +1762,46 @@
17151762 .skb_transmit_busy = mlxsw_pci_skb_transmit_busy,
17161763 .skb_transmit = mlxsw_pci_skb_transmit,
17171764 .cmd_exec = mlxsw_pci_cmd_exec,
1765
+ .read_frc_h = mlxsw_pci_read_frc_h,
1766
+ .read_frc_l = mlxsw_pci_read_frc_l,
17181767 .features = MLXSW_BUS_F_TXRX | MLXSW_BUS_F_RESET,
17191768 };
1769
+
1770
+static int mlxsw_pci_cmd_init(struct mlxsw_pci *mlxsw_pci)
1771
+{
1772
+ int err;
1773
+
1774
+ mutex_init(&mlxsw_pci->cmd.lock);
1775
+ init_waitqueue_head(&mlxsw_pci->cmd.wait);
1776
+
1777
+ err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
1778
+ if (err)
1779
+ goto err_in_mbox_alloc;
1780
+
1781
+ err = mlxsw_pci_mbox_alloc(mlxsw_pci, &mlxsw_pci->cmd.out_mbox);
1782
+ if (err)
1783
+ goto err_out_mbox_alloc;
1784
+
1785
+ return 0;
1786
+
1787
+err_out_mbox_alloc:
1788
+ mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
1789
+err_in_mbox_alloc:
1790
+ mutex_destroy(&mlxsw_pci->cmd.lock);
1791
+ return err;
1792
+}
1793
+
1794
+static void mlxsw_pci_cmd_fini(struct mlxsw_pci *mlxsw_pci)
1795
+{
1796
+ mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.out_mbox);
1797
+ mlxsw_pci_mbox_free(mlxsw_pci, &mlxsw_pci->cmd.in_mbox);
1798
+ mutex_destroy(&mlxsw_pci->cmd.lock);
1799
+}
17201800
17211801 static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
17221802 {
17231803 const char *driver_name = pdev->driver->name;
17241804 struct mlxsw_pci *mlxsw_pci;
1725
- bool called_again = false;
17261805 int err;
17271806
17281807 mlxsw_pci = kzalloc(sizeof(*mlxsw_pci), GFP_KERNEL);
....@@ -1774,23 +1853,20 @@
17741853 mlxsw_pci->pdev = pdev;
17751854 pci_set_drvdata(pdev, mlxsw_pci);
17761855
1856
+ err = mlxsw_pci_cmd_init(mlxsw_pci);
1857
+ if (err)
1858
+ goto err_pci_cmd_init;
1859
+
17771860 mlxsw_pci->bus_info.device_kind = driver_name;
17781861 mlxsw_pci->bus_info.device_name = pci_name(mlxsw_pci->pdev);
17791862 mlxsw_pci->bus_info.dev = &pdev->dev;
1863
+ mlxsw_pci->bus_info.read_frc_capable = true;
17801864 mlxsw_pci->id = id;
17811865
1782
-again:
17831866 err = mlxsw_core_bus_device_register(&mlxsw_pci->bus_info,
17841867 &mlxsw_pci_bus, mlxsw_pci, false,
1785
- NULL);
1786
- /* -EAGAIN is returned in case the FW was updated. FW needs
1787
- * a reset, so lets try to call mlxsw_core_bus_device_register()
1788
- * again.
1789
- */
1790
- if (err == -EAGAIN && !called_again) {
1791
- called_again = true;
1792
- goto again;
1793
- } else if (err) {
1868
+ NULL, NULL);
1869
+ if (err) {
17941870 dev_err(&pdev->dev, "cannot register bus device\n");
17951871 goto err_bus_device_register;
17961872 }
....@@ -1798,6 +1874,8 @@
17981874 return 0;
17991875
18001876 err_bus_device_register:
1877
+ mlxsw_pci_cmd_fini(mlxsw_pci);
1878
+err_pci_cmd_init:
18011879 iounmap(mlxsw_pci->hw_addr);
18021880 err_ioremap:
18031881 err_pci_resource_len_check:
....@@ -1815,6 +1893,7 @@
18151893 struct mlxsw_pci *mlxsw_pci = pci_get_drvdata(pdev);
18161894
18171895 mlxsw_core_bus_device_unregister(mlxsw_pci->core, false);
1896
+ mlxsw_pci_cmd_fini(mlxsw_pci);
18181897 iounmap(mlxsw_pci->hw_addr);
18191898 pci_release_regions(mlxsw_pci->pdev);
18201899 pci_disable_device(mlxsw_pci->pdev);