Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'octeontx2-af-CGX-LMAC-link-bringup-and-cleanups'

Linu Cherian says:

====================
octeontx2-af: CGX LMAC link bringup and cleanups

Patch 1: Code cleanup
Patch 2: Adds support for an unhandled hardware configuration
Patch 3: Preparatory patch for enabling cgx lmac links
Patch 4: Support for enabling cgx lmac links
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+214 -65
+101 -7
drivers/net/ethernet/marvell/octeontx2/af/cgx.c
··· 31 31 * @resp: command response 32 32 * @link_info: link related information 33 33 * @event_cb: callback for linkchange events 34 + * @event_cb_lock: lock for serializing callback with unregister 34 35 * @cmd_pend: flag set before new command is started 35 36 * flag cleared after command response is received 36 37 * @cgx: parent cgx port ··· 44 43 u64 resp; 45 44 struct cgx_link_user_info link_info; 46 45 struct cgx_event_cb event_cb; 46 + spinlock_t event_cb_lock; 47 47 bool cmd_pend; 48 48 struct cgx *cgx; 49 49 u8 lmac_id; ··· 57 55 u8 cgx_id; 58 56 u8 lmac_count; 59 57 struct lmac *lmac_idmap[MAX_LMAC_PER_CGX]; 58 + struct work_struct cgx_cmd_work; 59 + struct workqueue_struct *cgx_cmd_workq; 60 60 struct list_head cgx_list; 61 61 }; 62 62 ··· 69 65 70 66 /* Convert firmware lmac type encoding to string */ 71 67 static char *cgx_lmactype_string[LMAC_MODE_MAX]; 68 + 69 + /* CGX PHY management internal APIs */ 70 + static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool en); 72 71 73 72 /* Supported devices */ 74 73 static const struct pci_device_id cgx_id_table[] = { ··· 99 92 return cgx->lmac_idmap[lmac_id]; 100 93 } 101 94 102 - int cgx_get_cgx_cnt(void) 95 + int cgx_get_cgxcnt_max(void) 103 96 { 104 97 struct cgx *cgx_dev; 105 - int count = 0; 98 + int idmax = -ENODEV; 106 99 107 100 list_for_each_entry(cgx_dev, &cgx_list, cgx_list) 108 - count++; 101 + if (cgx_dev->cgx_id > idmax) 102 + idmax = cgx_dev->cgx_id; 109 103 110 - return count; 104 + if (idmax < 0) 105 + return 0; 106 + 107 + return idmax + 1; 111 108 } 112 - EXPORT_SYMBOL(cgx_get_cgx_cnt); 109 + EXPORT_SYMBOL(cgx_get_cgxcnt_max); 113 110 114 111 int cgx_get_lmac_cnt(void *cgxd) 115 112 { ··· 456 445 lmac->link_info = event.link_uinfo; 457 446 linfo = &lmac->link_info; 458 447 448 + /* Ensure callback doesn't get unregistered until we finish it */ 449 + spin_lock(&lmac->event_cb_lock); 450 + 459 451 if (!lmac->event_cb.notify_link_chg) { 460 452 dev_dbg(dev, "cgx port %d:%d Link change handler null", 461 453 cgx->cgx_id, lmac->lmac_id); ··· 469 455 dev_info(dev, "cgx port %d:%d Link is %s %d Mbps\n", 470 456 cgx->cgx_id, lmac->lmac_id, 471 457 linfo->link_up ? "UP" : "DOWN", linfo->speed); 472 - return; 458 + goto err; 473 459 } 474 460 475 461 if (lmac->event_cb.notify_link_chg(&event, lmac->event_cb.data)) 476 462 dev_err(dev, "event notification failure\n"); 463 + err: 464 + spin_unlock(&lmac->event_cb_lock); 477 465 } 478 466 479 467 static inline bool cgx_cmdresp_is_linkevent(u64 event) ··· 564 548 } 565 549 EXPORT_SYMBOL(cgx_lmac_evh_register); 566 550 551 + int cgx_lmac_evh_unregister(void *cgxd, int lmac_id) 552 + { 553 + struct lmac *lmac; 554 + unsigned long flags; 555 + struct cgx *cgx = cgxd; 556 + 557 + lmac = lmac_pdata(lmac_id, cgx); 558 + if (!lmac) 559 + return -ENODEV; 560 + 561 + spin_lock_irqsave(&lmac->event_cb_lock, flags); 562 + lmac->event_cb.notify_link_chg = NULL; 563 + lmac->event_cb.data = NULL; 564 + spin_unlock_irqrestore(&lmac->event_cb_lock, flags); 565 + 566 + return 0; 567 + } 568 + EXPORT_SYMBOL(cgx_lmac_evh_unregister); 569 + 570 + static int cgx_fwi_link_change(struct cgx *cgx, int lmac_id, bool enable) 571 + { 572 + u64 req = 0; 573 + u64 resp; 574 + 575 + if (enable) 576 + req = FIELD_SET(CMDREG_ID, CGX_CMD_LINK_BRING_UP, req); 577 + else 578 + req = FIELD_SET(CMDREG_ID, CGX_CMD_LINK_BRING_DOWN, req); 579 + 580 + return cgx_fwi_cmd_generic(req, &resp, cgx, lmac_id); 581 + } 582 + 567 583 static inline int cgx_fwi_read_version(u64 *resp, struct cgx *cgx) 568 584 { 569 585 u64 req = 0; ··· 629 581 return 0; 630 582 } 631 583 584 + static void cgx_lmac_linkup_work(struct work_struct *work) 585 + { 586 + struct cgx *cgx = container_of(work, struct cgx, cgx_cmd_work); 587 + struct device *dev = &cgx->pdev->dev; 588 + int i, err; 589 + 590 + /* Do Link up for all the lmacs */ 591 + for (i = 0; i < cgx->lmac_count; i++) { 592 + err = cgx_fwi_link_change(cgx, i, true); 593 + if (err) 594 + dev_info(dev, "cgx port %d:%d Link up command failed\n", 595 + cgx->cgx_id, i); 596 + } 597 + } 598 + 599 + int cgx_lmac_linkup_start(void *cgxd) 600 + { 601 + struct cgx *cgx = cgxd; 602 + 603 + if (!cgx) 604 + return -ENODEV; 605 + 606 + queue_work(cgx->cgx_cmd_workq, &cgx->cgx_cmd_work); 607 + 608 + return 0; 609 + } 610 + EXPORT_SYMBOL(cgx_lmac_linkup_start); 611 + 632 612 static int cgx_lmac_init(struct cgx *cgx) 633 613 { 634 614 struct lmac *lmac; ··· 678 602 lmac->cgx = cgx; 679 603 init_waitqueue_head(&lmac->wq_cmd_cmplt); 680 604 mutex_init(&lmac->cmd_lock); 605 + spin_lock_init(&lmac->event_cb_lock); 681 606 err = request_irq(pci_irq_vector(cgx->pdev, 682 607 CGX_LMAC_FWI + i * 9), 683 608 cgx_fwi_event_handler, 0, lmac->name, lmac); ··· 700 623 { 701 624 struct lmac *lmac; 702 625 int i; 626 + 627 + if (cgx->cgx_cmd_workq) { 628 + flush_workqueue(cgx->cgx_cmd_workq); 629 + destroy_workqueue(cgx->cgx_cmd_workq); 630 + cgx->cgx_cmd_workq = NULL; 631 + } 703 632 704 633 /* Free all lmac related resources */ 705 634 for (i = 0; i < cgx->lmac_count; i++) { ··· 762 679 goto err_release_regions; 763 680 } 764 681 682 + cgx->cgx_id = (pci_resource_start(pdev, PCI_CFG_REG_BAR_NUM) >> 24) 683 + & CGX_ID_MASK; 684 + 685 + /* init wq for processing linkup requests */ 686 + INIT_WORK(&cgx->cgx_cmd_work, cgx_lmac_linkup_work); 687 + cgx->cgx_cmd_workq = alloc_workqueue("cgx_cmd_workq", 0, 0); 688 + if (!cgx->cgx_cmd_workq) { 689 + dev_err(dev, "alloc workqueue failed for cgx cmd"); 690 + err = -ENOMEM; 691 + goto err_release_regions; 692 + } 693 + 765 694 list_add(&cgx->cgx_list, &cgx_list); 766 - cgx->cgx_id = cgx_get_cgx_cnt() - 1; 767 695 768 696 cgx_link_usertable_init(); 769 697
+18 -16
drivers/net/ethernet/marvell/octeontx2/af/cgx.h
··· 20 20 /* PCI BAR nos */ 21 21 #define PCI_CFG_REG_BAR_NUM 0 22 22 23 - #define MAX_CGX 3 23 + #define CGX_ID_MASK 0x7 24 24 #define MAX_LMAC_PER_CGX 4 25 25 #define CGX_FIFO_LEN 65536 /* 64K for both Rx & Tx */ 26 26 #define CGX_OFFSET(x) ((x) * MAX_LMAC_PER_CGX) 27 27 28 28 /* Registers */ 29 29 #define CGXX_CMRX_CFG 0x00 30 - #define CMR_EN BIT_ULL(55) 31 - #define DATA_PKT_TX_EN BIT_ULL(53) 32 - #define DATA_PKT_RX_EN BIT_ULL(54) 33 - #define CGX_LMAC_TYPE_SHIFT 40 34 - #define CGX_LMAC_TYPE_MASK 0xF 30 + #define CMR_EN BIT_ULL(55) 31 + #define DATA_PKT_TX_EN BIT_ULL(53) 32 + #define DATA_PKT_RX_EN BIT_ULL(54) 33 + #define CGX_LMAC_TYPE_SHIFT 40 34 + #define CGX_LMAC_TYPE_MASK 0xF 35 35 #define CGXX_CMRX_INT 0x040 36 - #define FW_CGX_INT BIT_ULL(1) 36 + #define FW_CGX_INT BIT_ULL(1) 37 37 #define CGXX_CMRX_INT_ENA_W1S 0x058 38 38 #define CGXX_CMRX_RX_ID_MAP 0x060 39 39 #define CGXX_CMRX_RX_STAT0 0x070 40 40 #define CGXX_CMRX_RX_LMACS 0x128 41 41 #define CGXX_CMRX_RX_DMAC_CTL0 0x1F8 42 - #define CGX_DMAC_CTL0_CAM_ENABLE BIT_ULL(3) 43 - #define CGX_DMAC_CAM_ACCEPT BIT_ULL(3) 44 - #define CGX_DMAC_MCAST_MODE BIT_ULL(1) 45 - #define CGX_DMAC_BCAST_MODE BIT_ULL(0) 42 + #define CGX_DMAC_CTL0_CAM_ENABLE BIT_ULL(3) 43 + #define CGX_DMAC_CAM_ACCEPT BIT_ULL(3) 44 + #define CGX_DMAC_MCAST_MODE BIT_ULL(1) 45 + #define CGX_DMAC_BCAST_MODE BIT_ULL(0) 46 46 #define CGXX_CMRX_RX_DMAC_CAM0 0x200 47 - #define CGX_DMAC_CAM_ADDR_ENABLE BIT_ULL(48) 47 + #define CGX_DMAC_CAM_ADDR_ENABLE BIT_ULL(48) 48 48 #define CGXX_CMRX_RX_DMAC_CAM1 0x400 49 - #define CGX_RX_DMAC_ADR_MASK GENMASK_ULL(47, 0) 49 + #define CGX_RX_DMAC_ADR_MASK GENMASK_ULL(47, 0) 50 50 #define CGXX_CMRX_TX_STAT0 0x700 51 51 #define CGXX_SCRATCH0_REG 0x1050 52 52 #define CGXX_SCRATCH1_REG 0x1058 53 53 #define CGX_CONST 0x2000 54 54 #define CGXX_SPUX_CONTROL1 0x10000 55 - #define CGXX_SPUX_CONTROL1_LBK BIT_ULL(14) 55 + #define CGXX_SPUX_CONTROL1_LBK BIT_ULL(14) 56 56 #define CGXX_GMP_PCS_MRX_CTL 0x30000 57 - #define CGXX_GMP_PCS_MRX_CTL_LBK BIT_ULL(14) 57 + #define CGXX_GMP_PCS_MRX_CTL_LBK BIT_ULL(14) 58 58 59 59 #define CGX_COMMAND_REG CGXX_SCRATCH1_REG 60 60 #define CGX_EVENT_REG CGXX_SCRATCH0_REG ··· 95 95 96 96 extern struct pci_driver cgx_driver; 97 97 98 - int cgx_get_cgx_cnt(void); 98 + int cgx_get_cgxcnt_max(void); 99 99 int cgx_get_lmac_cnt(void *cgxd); 100 100 void *cgx_get_pdata(int cgx_id); 101 101 int cgx_set_pkind(void *cgxd, u8 lmac_id, int pkind); 102 102 int cgx_lmac_evh_register(struct cgx_event_cb *cb, void *cgxd, int lmac_id); 103 + int cgx_lmac_evh_unregister(void *cgxd, int lmac_id); 103 104 int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat); 104 105 int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat); 105 106 int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable); ··· 110 109 int cgx_lmac_internal_loopback(void *cgxd, int lmac_id, bool enable); 111 110 int cgx_get_link_info(void *cgxd, int lmac_id, 112 111 struct cgx_link_user_info *linfo); 112 + int cgx_lmac_linkup_start(void *cgxd); 113 113 #endif /* CGX_H */
-2
drivers/net/ethernet/marvell/octeontx2/af/cgx_fw_if.h
··· 78 78 CGX_CMD_LINK_STATE_CHANGE, 79 79 CGX_CMD_MODE_CHANGE, /* hot plug support */ 80 80 CGX_CMD_INTF_SHUTDOWN, 81 - CGX_CMD_IRQ_ENABLE, 82 - CGX_CMD_IRQ_DISABLE, 83 81 }; 84 82 85 83 /* async event ids */
+15 -11
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
··· 811 811 812 812 err = rvu_npc_init(rvu); 813 813 if (err) 814 - return err; 814 + goto exit; 815 + 816 + err = rvu_cgx_init(rvu); 817 + if (err) 818 + goto exit; 815 819 816 820 err = rvu_npa_init(rvu); 817 821 if (err) 818 - return err; 822 + goto cgx_err; 819 823 820 824 err = rvu_nix_init(rvu); 821 825 if (err) 822 - return err; 826 + goto cgx_err; 823 827 824 828 return 0; 829 + 830 + cgx_err: 831 + rvu_cgx_exit(rvu); 832 + exit: 833 + return err; 825 834 } 826 835 827 836 /* NPA and NIX admin queue APIs */ ··· 2428 2419 if (err) 2429 2420 goto err_hwsetup; 2430 2421 2431 - err = rvu_cgx_probe(rvu); 2432 - if (err) 2433 - goto err_mbox; 2434 - 2435 2422 err = rvu_flr_init(rvu); 2436 2423 if (err) 2437 - goto err_cgx; 2424 + goto err_mbox; 2438 2425 2439 2426 err = rvu_register_interrupts(rvu); 2440 2427 if (err) ··· 2446 2441 rvu_unregister_interrupts(rvu); 2447 2442 err_flr: 2448 2443 rvu_flr_wq_destroy(rvu); 2449 - err_cgx: 2450 - rvu_cgx_wq_destroy(rvu); 2451 2444 err_mbox: 2452 2445 rvu_mbox_destroy(&rvu->afpf_wq_info); 2453 2446 err_hwsetup: 2447 + rvu_cgx_exit(rvu); 2454 2448 rvu_reset_all_blocks(rvu); 2455 2449 rvu_free_hw_resources(rvu); 2456 2450 err_release_regions: ··· 2469 2465 2470 2466 rvu_unregister_interrupts(rvu); 2471 2467 rvu_flr_wq_destroy(rvu); 2472 - rvu_cgx_wq_destroy(rvu); 2468 + rvu_cgx_exit(rvu); 2473 2469 rvu_mbox_destroy(&rvu->afpf_wq_info); 2474 2470 rvu_disable_sriov(rvu); 2475 2471 rvu_reset_all_blocks(rvu);
+3 -3
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
··· 226 226 /* CGX */ 227 227 #define PF_CGXMAP_BASE 1 /* PF 0 is reserved for RVU PF */ 228 228 u8 cgx_mapped_pfs; 229 - u8 cgx_cnt; /* available cgx ports */ 229 + u8 cgx_cnt_max; /* CGX port count max */ 230 230 u8 *pf2cgxlmac_map; /* pf to cgx_lmac map */ 231 231 u16 *cgxlmac2pf_map; /* bitmap of mapped pfs for 232 232 * every cgx lmac port ··· 316 316 *lmac_id = (map & 0xF); 317 317 } 318 318 319 - int rvu_cgx_probe(struct rvu *rvu); 320 - void rvu_cgx_wq_destroy(struct rvu *rvu); 319 + int rvu_cgx_init(struct rvu *rvu); 320 + int rvu_cgx_exit(struct rvu *rvu); 321 321 void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu); 322 322 int rvu_cgx_config_rxtx(struct rvu *rvu, u16 pcifunc, bool start); 323 323 int rvu_mbox_handler_cgx_start_rxtx(struct rvu *rvu, struct msg_req *req,
+73 -24
drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
··· 52 52 53 53 void *rvu_cgx_pdata(u8 cgx_id, struct rvu *rvu) 54 54 { 55 - if (cgx_id >= rvu->cgx_cnt) 55 + if (cgx_id >= rvu->cgx_cnt_max) 56 56 return NULL; 57 57 58 58 return rvu->cgx_idmap[cgx_id]; ··· 61 61 static int rvu_map_cgx_lmac_pf(struct rvu *rvu) 62 62 { 63 63 struct npc_pkind *pkind = &rvu->hw->pkind; 64 - int cgx_cnt = rvu->cgx_cnt; 64 + int cgx_cnt_max = rvu->cgx_cnt_max; 65 65 int cgx, lmac_cnt, lmac; 66 66 int pf = PF_CGXMAP_BASE; 67 67 int size, free_pkind; 68 68 69 - if (!cgx_cnt) 69 + if (!cgx_cnt_max) 70 70 return 0; 71 71 72 - if (cgx_cnt > 0xF || MAX_LMAC_PER_CGX > 0xF) 72 + if (cgx_cnt_max > 0xF || MAX_LMAC_PER_CGX > 0xF) 73 73 return -EINVAL; 74 74 75 75 /* Alloc map table 76 76 * An additional entry is required since PF id starts from 1 and 77 77 * hence entry at offset 0 is invalid. 78 78 */ 79 - size = (cgx_cnt * MAX_LMAC_PER_CGX + 1) * sizeof(u8); 80 - rvu->pf2cgxlmac_map = devm_kzalloc(rvu->dev, size, GFP_KERNEL); 79 + size = (cgx_cnt_max * MAX_LMAC_PER_CGX + 1) * sizeof(u8); 80 + rvu->pf2cgxlmac_map = devm_kmalloc(rvu->dev, size, GFP_KERNEL); 81 81 if (!rvu->pf2cgxlmac_map) 82 82 return -ENOMEM; 83 83 84 - /* Initialize offset 0 with an invalid cgx and lmac id */ 85 - rvu->pf2cgxlmac_map[0] = 0xFF; 84 + /* Initialize all entries with an invalid cgx and lmac id */ 85 + memset(rvu->pf2cgxlmac_map, 0xFF, size); 86 86 87 87 /* Reverse map table */ 88 88 rvu->cgxlmac2pf_map = devm_kzalloc(rvu->dev, 89 - cgx_cnt * MAX_LMAC_PER_CGX * sizeof(u16), 89 + cgx_cnt_max * MAX_LMAC_PER_CGX * sizeof(u16), 90 90 GFP_KERNEL); 91 91 if (!rvu->cgxlmac2pf_map) 92 92 return -ENOMEM; 93 93 94 94 rvu->cgx_mapped_pfs = 0; 95 - for (cgx = 0; cgx < cgx_cnt; cgx++) { 95 + for (cgx = 0; cgx < cgx_cnt_max; cgx++) { 96 + if (!rvu_cgx_pdata(cgx, rvu)) 97 + continue; 96 98 lmac_cnt = cgx_get_lmac_cnt(rvu_cgx_pdata(cgx, rvu)); 97 99 for (lmac = 0; lmac < lmac_cnt; lmac++, pf++) { 98 100 rvu->pf2cgxlmac_map[pf] = cgxlmac_id_to_bmap(cgx, lmac); ··· 218 216 } while (1); 219 217 } 220 218 221 - static void cgx_lmac_event_handler_init(struct rvu *rvu) 219 + static int cgx_lmac_event_handler_init(struct rvu *rvu) 222 220 { 223 221 struct cgx_event_cb cb; 224 222 int cgx, lmac, err; ··· 230 228 rvu->cgx_evh_wq = alloc_workqueue("rvu_evh_wq", 0, 0); 231 229 if (!rvu->cgx_evh_wq) { 232 230 dev_err(rvu->dev, "alloc workqueue failed"); 233 - return; 231 + return -ENOMEM; 234 232 } 235 233 236 234 cb.notify_link_chg = cgx_lmac_postevent; /* link change call back */ 237 235 cb.data = rvu; 238 236 239 - for (cgx = 0; cgx < rvu->cgx_cnt; cgx++) { 237 + for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) { 240 238 cgxd = rvu_cgx_pdata(cgx, rvu); 239 + if (!cgxd) 240 + continue; 241 241 for (lmac = 0; lmac < cgx_get_lmac_cnt(cgxd); lmac++) { 242 242 err = cgx_lmac_evh_register(&cb, cgxd, lmac); 243 243 if (err) ··· 248 244 cgx, lmac); 249 245 } 250 246 } 247 + 248 + return 0; 251 249 } 252 250 253 - void rvu_cgx_wq_destroy(struct rvu *rvu) 251 + static void rvu_cgx_wq_destroy(struct rvu *rvu) 254 252 { 255 253 if (rvu->cgx_evh_wq) { 256 254 flush_workqueue(rvu->cgx_evh_wq); ··· 261 255 } 262 256 } 263 257 264 - int rvu_cgx_probe(struct rvu *rvu) 258 + int rvu_cgx_init(struct rvu *rvu) 265 259 { 266 - int i, err; 260 + int cgx, err; 261 + void *cgxd; 267 262 268 - /* find available cgx ports */ 269 - rvu->cgx_cnt = cgx_get_cgx_cnt(); 270 - if (!rvu->cgx_cnt) { 263 + /* CGX port id starts from 0 and are not necessarily contiguous 264 + * Hence we allocate resources based on the maximum port id value. 265 + */ 266 + rvu->cgx_cnt_max = cgx_get_cgxcnt_max(); 267 + if (!rvu->cgx_cnt_max) { 271 268 dev_info(rvu->dev, "No CGX devices found!\n"); 272 269 return -ENODEV; 273 270 } 274 271 275 - rvu->cgx_idmap = devm_kzalloc(rvu->dev, rvu->cgx_cnt * sizeof(void *), 276 - GFP_KERNEL); 272 + rvu->cgx_idmap = devm_kzalloc(rvu->dev, rvu->cgx_cnt_max * 273 + sizeof(void *), GFP_KERNEL); 277 274 if (!rvu->cgx_idmap) 278 275 return -ENOMEM; 279 276 280 277 /* Initialize the cgxdata table */ 281 - for (i = 0; i < rvu->cgx_cnt; i++) 282 - rvu->cgx_idmap[i] = cgx_get_pdata(i); 278 + for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++) 279 + rvu->cgx_idmap[cgx] = cgx_get_pdata(cgx); 283 280 284 281 /* Map CGX LMAC interfaces to RVU PFs */ 285 282 err = rvu_map_cgx_lmac_pf(rvu); ··· 290 281 return err; 291 282 292 283 /* Register for CGX events */ 293 - cgx_lmac_event_handler_init(rvu); 284 + err = cgx_lmac_event_handler_init(rvu); 285 + if (err) 286 + return err; 287 + 288 + /* Ensure event handler registration is completed, before 289 + * we turn on the links 290 + */ 291 + mb(); 292 + 293 + /* Do link up for all CGX ports */ 294 + for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) { 295 + cgxd = rvu_cgx_pdata(cgx, rvu); 296 + if (!cgxd) 297 + continue; 298 + err = cgx_lmac_linkup_start(cgxd); 299 + if (err) 300 + dev_err(rvu->dev, 301 + "Link up process failed to start on cgx %d\n", 302 + cgx); 303 + } 304 + 305 + return 0; 306 + } 307 + 308 + int rvu_cgx_exit(struct rvu *rvu) 309 + { 310 + int cgx, lmac; 311 + void *cgxd; 312 + 313 + for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) { 314 + cgxd = rvu_cgx_pdata(cgx, rvu); 315 + if (!cgxd) 316 + continue; 317 + for (lmac = 0; lmac < cgx_get_lmac_cnt(cgxd); lmac++) 318 + cgx_lmac_evh_unregister(cgxd, lmac); 319 + } 320 + 321 + /* Ensure event handler unregister is completed */ 322 + mb(); 323 + 324 + rvu_cgx_wq_destroy(rvu); 294 325 return 0; 295 326 } 296 327
+4 -2
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
··· 2107 2107 2108 2108 status = rvu_read64(rvu, blkaddr, NIX_AF_STATUS); 2109 2109 /* Check if CGX devices are ready */ 2110 - for (idx = 0; idx < cgx_get_cgx_cnt(); idx++) { 2111 - if (status & (BIT_ULL(16 + idx))) 2110 + for (idx = 0; idx < rvu->cgx_cnt_max; idx++) { 2111 + /* Skip when cgx port is not available */ 2112 + if (!rvu_cgx_pdata(idx, rvu) || 2113 + (status & (BIT_ULL(16 + idx)))) 2112 2114 continue; 2113 2115 dev_err(rvu->dev, 2114 2116 "CGX%d didn't respond to NIX X2P calibration\n", idx);