10399ff9dSTomasz Duszynski /* SPDX-License-Identifier: BSD-3-Clause 20399ff9dSTomasz Duszynski * Copyright(C) 2021 Marvell. 30399ff9dSTomasz Duszynski */ 40399ff9dSTomasz Duszynski 5857721d6STomasz Duszynski #include <pthread.h> 60399ff9dSTomasz Duszynski 7857721d6STomasz Duszynski #include "roc_api.h" 8857721d6STomasz Duszynski #include "roc_priv.h" 9857721d6STomasz Duszynski 102c19694cSTomasz Duszynski #define CGX_CMRX_CONFIG 0x00 112c19694cSTomasz Duszynski #define CGX_CMRX_CONFIG_DATA_PKT_RX_EN BIT_ULL(54) 122c19694cSTomasz Duszynski #define CGX_CMRX_CONFIG_DATA_PKT_TX_EN BIT_ULL(53) 13857721d6STomasz Duszynski #define CGX_CMRX_INT 0x40 14857721d6STomasz Duszynski #define CGX_CMRX_INT_OVERFLW BIT_ULL(1) 150399ff9dSTomasz Duszynski /* 160399ff9dSTomasz Duszynski * CN10K stores number of lmacs in 4 bit filed 177be78d02SJosh Soref * in contrary to CN9K which uses only 3 bits. 180399ff9dSTomasz Duszynski * 190399ff9dSTomasz Duszynski * In theory masks should differ yet on CN9K 200399ff9dSTomasz Duszynski * bits beyond specified range contain zeros. 210399ff9dSTomasz Duszynski * 220399ff9dSTomasz Duszynski * Hence common longer mask may be used. 230399ff9dSTomasz Duszynski */ 240399ff9dSTomasz Duszynski #define CGX_CMRX_RX_LMACS 0x128 250399ff9dSTomasz Duszynski #define CGX_CMRX_RX_LMACS_LMACS GENMASK_ULL(3, 0) 26857721d6STomasz Duszynski #define CGX_CMRX_SCRATCH0 0x1050 27857721d6STomasz Duszynski #define CGX_CMRX_SCRATCH1 0x1058 288d3ba6bfSTomasz Duszynski #define CGX_MTI_MAC100X_COMMAND_CONFIG 0x8010 298d3ba6bfSTomasz Duszynski #define CGX_MTI_MAC100X_COMMAND_CONFIG_RX_ENA BIT_ULL(1) 308d3ba6bfSTomasz Duszynski #define CGX_MTI_MAC100X_COMMAND_CONFIG_TX_ENA BIT_ULL(0) 310399ff9dSTomasz Duszynski 320399ff9dSTomasz Duszynski static uint64_t 330399ff9dSTomasz Duszynski roc_bphy_cgx_read(struct roc_bphy_cgx *roc_cgx, uint64_t lmac, uint64_t offset) 340399ff9dSTomasz Duszynski { 350399ff9dSTomasz Duszynski int shift = roc_model_is_cn10k() ? 20 : 18; 360399ff9dSTomasz Duszynski uint64_t base = (uint64_t)roc_cgx->bar0_va; 370399ff9dSTomasz Duszynski 380399ff9dSTomasz Duszynski return plt_read64(base + (lmac << shift) + offset); 390399ff9dSTomasz Duszynski } 400399ff9dSTomasz Duszynski 41857721d6STomasz Duszynski static void 42857721d6STomasz Duszynski roc_bphy_cgx_write(struct roc_bphy_cgx *roc_cgx, uint64_t lmac, uint64_t offset, 43857721d6STomasz Duszynski uint64_t value) 44857721d6STomasz Duszynski { 45857721d6STomasz Duszynski int shift = roc_model_is_cn10k() ? 20 : 18; 46857721d6STomasz Duszynski uint64_t base = (uint64_t)roc_cgx->bar0_va; 47857721d6STomasz Duszynski 48857721d6STomasz Duszynski plt_write64(value, base + (lmac << shift) + offset); 49857721d6STomasz Duszynski } 50857721d6STomasz Duszynski 51857721d6STomasz Duszynski static void 52857721d6STomasz Duszynski roc_bphy_cgx_ack(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 53857721d6STomasz Duszynski uint64_t *scr0) 54857721d6STomasz Duszynski { 55857721d6STomasz Duszynski uint64_t val; 56857721d6STomasz Duszynski 57857721d6STomasz Duszynski /* clear interrupt */ 58857721d6STomasz Duszynski val = roc_bphy_cgx_read(roc_cgx, lmac, CGX_CMRX_INT); 59857721d6STomasz Duszynski val |= FIELD_PREP(CGX_CMRX_INT_OVERFLW, 1); 60857721d6STomasz Duszynski roc_bphy_cgx_write(roc_cgx, lmac, CGX_CMRX_INT, val); 61857721d6STomasz Duszynski 62857721d6STomasz Duszynski /* ack fw response */ 63857721d6STomasz Duszynski *scr0 &= ~SCR0_ETH_EVT_STS_S_ACK; 64857721d6STomasz Duszynski roc_bphy_cgx_write(roc_cgx, lmac, CGX_CMRX_SCRATCH0, *scr0); 65857721d6STomasz Duszynski } 66857721d6STomasz Duszynski 67857721d6STomasz Duszynski static int 68857721d6STomasz Duszynski roc_bphy_cgx_wait_for_ownership(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 69857721d6STomasz Duszynski uint64_t *scr0) 70857721d6STomasz Duszynski { 71857721d6STomasz Duszynski int tries = 5000; 72857721d6STomasz Duszynski uint64_t scr1; 73857721d6STomasz Duszynski 74857721d6STomasz Duszynski do { 75857721d6STomasz Duszynski *scr0 = roc_bphy_cgx_read(roc_cgx, lmac, CGX_CMRX_SCRATCH0); 76857721d6STomasz Duszynski scr1 = roc_bphy_cgx_read(roc_cgx, lmac, CGX_CMRX_SCRATCH1); 77857721d6STomasz Duszynski 78857721d6STomasz Duszynski if (FIELD_GET(SCR1_OWN_STATUS, scr1) == ETH_OWN_NON_SECURE_SW && 79857721d6STomasz Duszynski FIELD_GET(SCR0_ETH_EVT_STS_S_ACK, *scr0) == 0) 80857721d6STomasz Duszynski break; 81857721d6STomasz Duszynski 82857721d6STomasz Duszynski /* clear async events if any */ 83857721d6STomasz Duszynski if (FIELD_GET(SCR0_ETH_EVT_STS_S_EVT_TYPE, *scr0) == 84857721d6STomasz Duszynski ETH_EVT_ASYNC && 85857721d6STomasz Duszynski FIELD_GET(SCR0_ETH_EVT_STS_S_ACK, *scr0)) 86857721d6STomasz Duszynski roc_bphy_cgx_ack(roc_cgx, lmac, scr0); 87857721d6STomasz Duszynski 88857721d6STomasz Duszynski plt_delay_ms(1); 89857721d6STomasz Duszynski } while (--tries); 90857721d6STomasz Duszynski 91857721d6STomasz Duszynski return tries ? 0 : -ETIMEDOUT; 92857721d6STomasz Duszynski } 93857721d6STomasz Duszynski 94857721d6STomasz Duszynski static int 95857721d6STomasz Duszynski roc_bphy_cgx_wait_for_ack(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 96857721d6STomasz Duszynski uint64_t *scr0) 97857721d6STomasz Duszynski { 98857721d6STomasz Duszynski int tries = 5000; 99857721d6STomasz Duszynski uint64_t scr1; 100857721d6STomasz Duszynski 101857721d6STomasz Duszynski do { 102857721d6STomasz Duszynski *scr0 = roc_bphy_cgx_read(roc_cgx, lmac, CGX_CMRX_SCRATCH0); 103857721d6STomasz Duszynski scr1 = roc_bphy_cgx_read(roc_cgx, lmac, CGX_CMRX_SCRATCH1); 104857721d6STomasz Duszynski 105857721d6STomasz Duszynski if (FIELD_GET(SCR1_OWN_STATUS, scr1) == ETH_OWN_NON_SECURE_SW && 106857721d6STomasz Duszynski FIELD_GET(SCR0_ETH_EVT_STS_S_ACK, *scr0)) 107857721d6STomasz Duszynski break; 108857721d6STomasz Duszynski 109857721d6STomasz Duszynski plt_delay_ms(1); 110857721d6STomasz Duszynski } while (--tries); 111857721d6STomasz Duszynski 112857721d6STomasz Duszynski return tries ? 0 : -ETIMEDOUT; 113857721d6STomasz Duszynski } 114857721d6STomasz Duszynski 1151fa00451STomasz Duszynski static int 116857721d6STomasz Duszynski roc_bphy_cgx_intf_req(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 117857721d6STomasz Duszynski uint64_t scr1, uint64_t *scr0) 118857721d6STomasz Duszynski { 119857721d6STomasz Duszynski uint8_t cmd_id = FIELD_GET(SCR1_ETH_CMD_ID, scr1); 120857721d6STomasz Duszynski int ret; 121857721d6STomasz Duszynski 122857721d6STomasz Duszynski pthread_mutex_lock(&roc_cgx->lock); 123857721d6STomasz Duszynski 124857721d6STomasz Duszynski /* wait for ownership */ 125857721d6STomasz Duszynski ret = roc_bphy_cgx_wait_for_ownership(roc_cgx, lmac, scr0); 126857721d6STomasz Duszynski if (ret) { 127857721d6STomasz Duszynski plt_err("timed out waiting for ownership"); 128857721d6STomasz Duszynski goto out; 129857721d6STomasz Duszynski } 130857721d6STomasz Duszynski 131857721d6STomasz Duszynski /* write command */ 132857721d6STomasz Duszynski scr1 |= FIELD_PREP(SCR1_OWN_STATUS, ETH_OWN_FIRMWARE); 133857721d6STomasz Duszynski roc_bphy_cgx_write(roc_cgx, lmac, CGX_CMRX_SCRATCH1, scr1); 134857721d6STomasz Duszynski 135857721d6STomasz Duszynski /* wait for command ack */ 136857721d6STomasz Duszynski ret = roc_bphy_cgx_wait_for_ack(roc_cgx, lmac, scr0); 137857721d6STomasz Duszynski if (ret) { 138857721d6STomasz Duszynski plt_err("timed out waiting for response"); 139857721d6STomasz Duszynski goto out; 140857721d6STomasz Duszynski } 141857721d6STomasz Duszynski 142857721d6STomasz Duszynski if (cmd_id == ETH_CMD_INTF_SHUTDOWN) 143857721d6STomasz Duszynski goto out; 144857721d6STomasz Duszynski 145857721d6STomasz Duszynski if (FIELD_GET(SCR0_ETH_EVT_STS_S_EVT_TYPE, *scr0) != ETH_EVT_CMD_RESP) { 146857721d6STomasz Duszynski plt_err("received async event instead of cmd resp event"); 147857721d6STomasz Duszynski ret = -EIO; 148857721d6STomasz Duszynski goto out; 149857721d6STomasz Duszynski } 150857721d6STomasz Duszynski 151857721d6STomasz Duszynski if (FIELD_GET(SCR0_ETH_EVT_STS_S_ID, *scr0) != cmd_id) { 152857721d6STomasz Duszynski plt_err("received resp for cmd %d expected for cmd %d", 153857721d6STomasz Duszynski (int)FIELD_GET(SCR0_ETH_EVT_STS_S_ID, *scr0), cmd_id); 154857721d6STomasz Duszynski ret = -EIO; 155857721d6STomasz Duszynski goto out; 156857721d6STomasz Duszynski } 157857721d6STomasz Duszynski 158857721d6STomasz Duszynski if (FIELD_GET(SCR0_ETH_EVT_STS_S_STAT, *scr0) != ETH_STAT_SUCCESS) { 159857721d6STomasz Duszynski plt_err("cmd %d failed on cgx%u lmac%u with errcode %d", cmd_id, 160857721d6STomasz Duszynski roc_cgx->id, lmac, 161857721d6STomasz Duszynski (int)FIELD_GET(SCR0_ETH_LNK_STS_S_ERR_TYPE, *scr0)); 162857721d6STomasz Duszynski ret = -EIO; 163857721d6STomasz Duszynski } 164857721d6STomasz Duszynski 165857721d6STomasz Duszynski out: 166857721d6STomasz Duszynski roc_bphy_cgx_ack(roc_cgx, lmac, scr0); 167857721d6STomasz Duszynski 168857721d6STomasz Duszynski pthread_mutex_unlock(&roc_cgx->lock); 169857721d6STomasz Duszynski 170857721d6STomasz Duszynski return ret; 171857721d6STomasz Duszynski } 172857721d6STomasz Duszynski 1730399ff9dSTomasz Duszynski static unsigned int 1740399ff9dSTomasz Duszynski roc_bphy_cgx_dev_id(struct roc_bphy_cgx *roc_cgx) 1750399ff9dSTomasz Duszynski { 17681388ad1STomasz Duszynski uint64_t cgx_id; 17781388ad1STomasz Duszynski 17881388ad1STomasz Duszynski if (roc_model_is_cnf10kb()) 17981388ad1STomasz Duszynski cgx_id = GENMASK_ULL(27, 24); 18081388ad1STomasz Duszynski else if (roc_model_is_cn10k()) 18181388ad1STomasz Duszynski cgx_id = GENMASK_ULL(26, 24); 18281388ad1STomasz Duszynski else 18381388ad1STomasz Duszynski cgx_id = GENMASK_ULL(25, 24); 1840399ff9dSTomasz Duszynski 1850399ff9dSTomasz Duszynski return FIELD_GET(cgx_id, roc_cgx->bar0_pa); 1860399ff9dSTomasz Duszynski } 1870399ff9dSTomasz Duszynski 1880399ff9dSTomasz Duszynski int 1890399ff9dSTomasz Duszynski roc_bphy_cgx_dev_init(struct roc_bphy_cgx *roc_cgx) 1900399ff9dSTomasz Duszynski { 1910399ff9dSTomasz Duszynski uint64_t val; 1920399ff9dSTomasz Duszynski 1930399ff9dSTomasz Duszynski if (!roc_cgx || !roc_cgx->bar0_va || !roc_cgx->bar0_pa) 1940399ff9dSTomasz Duszynski return -EINVAL; 1950399ff9dSTomasz Duszynski 196*6169517cSAriel Otilibili pthread_mutex_init(&roc_cgx->lock, NULL); 197857721d6STomasz Duszynski 1980399ff9dSTomasz Duszynski val = roc_bphy_cgx_read(roc_cgx, 0, CGX_CMRX_RX_LMACS); 1990399ff9dSTomasz Duszynski val = FIELD_GET(CGX_CMRX_RX_LMACS_LMACS, val); 2000399ff9dSTomasz Duszynski if (roc_model_is_cn9k()) 2010399ff9dSTomasz Duszynski val = GENMASK_ULL(val - 1, 0); 2020399ff9dSTomasz Duszynski roc_cgx->lmac_bmap = val; 2030399ff9dSTomasz Duszynski roc_cgx->id = roc_bphy_cgx_dev_id(roc_cgx); 2040399ff9dSTomasz Duszynski 2050399ff9dSTomasz Duszynski return 0; 2060399ff9dSTomasz Duszynski } 2070399ff9dSTomasz Duszynski 2080399ff9dSTomasz Duszynski int 2090399ff9dSTomasz Duszynski roc_bphy_cgx_dev_fini(struct roc_bphy_cgx *roc_cgx) 2100399ff9dSTomasz Duszynski { 2110399ff9dSTomasz Duszynski if (!roc_cgx) 2120399ff9dSTomasz Duszynski return -EINVAL; 2130399ff9dSTomasz Duszynski 214857721d6STomasz Duszynski pthread_mutex_destroy(&roc_cgx->lock); 215857721d6STomasz Duszynski 2160399ff9dSTomasz Duszynski return 0; 2170399ff9dSTomasz Duszynski } 2181fa00451STomasz Duszynski 2191fa00451STomasz Duszynski static bool 2201fa00451STomasz Duszynski roc_bphy_cgx_lmac_exists(struct roc_bphy_cgx *roc_cgx, unsigned int lmac) 2211fa00451STomasz Duszynski { 2221fa00451STomasz Duszynski return (lmac < MAX_LMACS_PER_CGX) && 2231fa00451STomasz Duszynski (roc_cgx->lmac_bmap & BIT_ULL(lmac)); 2241fa00451STomasz Duszynski } 2251fa00451STomasz Duszynski 2266c870ee8STomasz Duszynski static int 2272c19694cSTomasz Duszynski roc_bphy_cgx_start_stop_rxtx(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 2282c19694cSTomasz Duszynski bool start) 2292c19694cSTomasz Duszynski { 2308d3ba6bfSTomasz Duszynski uint64_t val, reg, rx_field, tx_field; 2312c19694cSTomasz Duszynski 2322c19694cSTomasz Duszynski if (!roc_cgx) 2332c19694cSTomasz Duszynski return -EINVAL; 2342c19694cSTomasz Duszynski 2352c19694cSTomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 2362c19694cSTomasz Duszynski return -ENODEV; 2372c19694cSTomasz Duszynski 2388d3ba6bfSTomasz Duszynski if (roc_model_is_cnf10kb()) { 2398d3ba6bfSTomasz Duszynski reg = CGX_MTI_MAC100X_COMMAND_CONFIG; 2408d3ba6bfSTomasz Duszynski rx_field = CGX_MTI_MAC100X_COMMAND_CONFIG_RX_ENA; 2418d3ba6bfSTomasz Duszynski tx_field = CGX_MTI_MAC100X_COMMAND_CONFIG_TX_ENA; 2428d3ba6bfSTomasz Duszynski } else { 2438d3ba6bfSTomasz Duszynski reg = CGX_CMRX_CONFIG; 2448d3ba6bfSTomasz Duszynski rx_field = CGX_CMRX_CONFIG_DATA_PKT_RX_EN; 2458d3ba6bfSTomasz Duszynski tx_field = CGX_CMRX_CONFIG_DATA_PKT_TX_EN; 2468d3ba6bfSTomasz Duszynski } 2478d3ba6bfSTomasz Duszynski 2482c19694cSTomasz Duszynski pthread_mutex_lock(&roc_cgx->lock); 2498d3ba6bfSTomasz Duszynski val = roc_bphy_cgx_read(roc_cgx, lmac, reg); 2508d3ba6bfSTomasz Duszynski val &= ~(rx_field | tx_field); 2512c19694cSTomasz Duszynski 2522c19694cSTomasz Duszynski if (start) 2538d3ba6bfSTomasz Duszynski val |= FIELD_PREP(rx_field, 1) | FIELD_PREP(tx_field, 1); 2542c19694cSTomasz Duszynski 2558d3ba6bfSTomasz Duszynski roc_bphy_cgx_write(roc_cgx, lmac, reg, val); 2562c19694cSTomasz Duszynski pthread_mutex_unlock(&roc_cgx->lock); 2572c19694cSTomasz Duszynski 2582c19694cSTomasz Duszynski return 0; 2592c19694cSTomasz Duszynski } 2602c19694cSTomasz Duszynski 2612c19694cSTomasz Duszynski static int 2626c870ee8STomasz Duszynski roc_bphy_cgx_intlbk_ena_dis(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 2636c870ee8STomasz Duszynski bool enable) 2646c870ee8STomasz Duszynski { 2656c870ee8STomasz Duszynski uint64_t scr1, scr0; 2666c870ee8STomasz Duszynski 2676c870ee8STomasz Duszynski if (!roc_cgx) 2686c870ee8STomasz Duszynski return -EINVAL; 2696c870ee8STomasz Duszynski 2706c870ee8STomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 2716c870ee8STomasz Duszynski return -ENODEV; 2726c870ee8STomasz Duszynski 2736c870ee8STomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_INTERNAL_LBK) | 2746c870ee8STomasz Duszynski FIELD_PREP(SCR1_ETH_CTL_ARGS_ENABLE, enable); 2756c870ee8STomasz Duszynski 2766c870ee8STomasz Duszynski return roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 2776c870ee8STomasz Duszynski } 2786c870ee8STomasz Duszynski 27972096a47STomasz Duszynski static int 28072096a47STomasz Duszynski roc_bphy_cgx_ptp_rx_ena_dis(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 28172096a47STomasz Duszynski bool enable) 28272096a47STomasz Duszynski { 28372096a47STomasz Duszynski uint64_t scr1, scr0; 28472096a47STomasz Duszynski 28572096a47STomasz Duszynski if (!roc_cgx) 28672096a47STomasz Duszynski return -EINVAL; 28772096a47STomasz Duszynski 28872096a47STomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 28972096a47STomasz Duszynski return -ENODEV; 29072096a47STomasz Duszynski 29172096a47STomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_SET_PTP_MODE) | 29272096a47STomasz Duszynski FIELD_PREP(SCR1_ETH_CTL_ARGS_ENABLE, enable); 29372096a47STomasz Duszynski 29472096a47STomasz Duszynski return roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 29572096a47STomasz Duszynski } 29672096a47STomasz Duszynski 2971fa00451STomasz Duszynski int 2982c19694cSTomasz Duszynski roc_bphy_cgx_start_rxtx(struct roc_bphy_cgx *roc_cgx, unsigned int lmac) 2992c19694cSTomasz Duszynski { 3002c19694cSTomasz Duszynski return roc_bphy_cgx_start_stop_rxtx(roc_cgx, lmac, true); 3012c19694cSTomasz Duszynski } 3022c19694cSTomasz Duszynski 3032c19694cSTomasz Duszynski int 3042c19694cSTomasz Duszynski roc_bphy_cgx_stop_rxtx(struct roc_bphy_cgx *roc_cgx, unsigned int lmac) 3052c19694cSTomasz Duszynski { 3062c19694cSTomasz Duszynski return roc_bphy_cgx_start_stop_rxtx(roc_cgx, lmac, false); 3072c19694cSTomasz Duszynski } 3082c19694cSTomasz Duszynski 3092c19694cSTomasz Duszynski int 3107fb5075aSTomasz Duszynski roc_bphy_cgx_set_link_state(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 3116576ef65STomasz Duszynski struct roc_bphy_cgx_link_state *state) 3127fb5075aSTomasz Duszynski { 3137fb5075aSTomasz Duszynski uint64_t scr1, scr0; 3147fb5075aSTomasz Duszynski 3157fb5075aSTomasz Duszynski if (!roc_cgx) 3167fb5075aSTomasz Duszynski return -EINVAL; 3177fb5075aSTomasz Duszynski 3187fb5075aSTomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 3197fb5075aSTomasz Duszynski return -ENODEV; 3207fb5075aSTomasz Duszynski 3216576ef65STomasz Duszynski if (!state) 3226576ef65STomasz Duszynski return -EINVAL; 3236576ef65STomasz Duszynski 3246576ef65STomasz Duszynski scr1 = (state->state ? FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_LINK_BRING_UP) : 3256576ef65STomasz Duszynski FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_LINK_BRING_DOWN)) | 3266576ef65STomasz Duszynski FIELD_PREP(SCR1_CGX_LINK_BRINGUP_ARGS_TIMEOUT, state->timeout) | 3276576ef65STomasz Duszynski FIELD_PREP(SCR1_CGX_LINK_BRINGUP_ARGS_RX_TX_DIS, state->rx_tx_dis); 3287fb5075aSTomasz Duszynski 3297fb5075aSTomasz Duszynski return roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 3307fb5075aSTomasz Duszynski } 3317fb5075aSTomasz Duszynski 3327fb5075aSTomasz Duszynski int 3331fa00451STomasz Duszynski roc_bphy_cgx_get_linkinfo(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 3341fa00451STomasz Duszynski struct roc_bphy_cgx_link_info *info) 3351fa00451STomasz Duszynski { 3361fa00451STomasz Duszynski uint64_t scr1, scr0; 3371fa00451STomasz Duszynski int ret; 3381fa00451STomasz Duszynski 3391fa00451STomasz Duszynski if (!roc_cgx) 3401fa00451STomasz Duszynski return -EINVAL; 3411fa00451STomasz Duszynski 3421fa00451STomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 3431fa00451STomasz Duszynski return -ENODEV; 3441fa00451STomasz Duszynski 3451fa00451STomasz Duszynski if (!info) 3461fa00451STomasz Duszynski return -EINVAL; 3471fa00451STomasz Duszynski 3481fa00451STomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_GET_LINK_STS); 3491fa00451STomasz Duszynski ret = roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 3501fa00451STomasz Duszynski if (ret) 3511fa00451STomasz Duszynski return ret; 3521fa00451STomasz Duszynski 3531fa00451STomasz Duszynski info->link_up = FIELD_GET(SCR0_ETH_LNK_STS_S_LINK_UP, scr0); 3541fa00451STomasz Duszynski info->full_duplex = FIELD_GET(SCR0_ETH_LNK_STS_S_FULL_DUPLEX, scr0); 3551fa00451STomasz Duszynski info->speed = FIELD_GET(SCR0_ETH_LNK_STS_S_SPEED, scr0); 3561fa00451STomasz Duszynski info->an = FIELD_GET(SCR0_ETH_LNK_STS_S_AN, scr0); 3571fa00451STomasz Duszynski info->fec = FIELD_GET(SCR0_ETH_LNK_STS_S_FEC, scr0); 3581fa00451STomasz Duszynski info->mode = FIELD_GET(SCR0_ETH_LNK_STS_S_MODE, scr0); 3591fa00451STomasz Duszynski 3601fa00451STomasz Duszynski return 0; 3611fa00451STomasz Duszynski } 3626c870ee8STomasz Duszynski 3636c870ee8STomasz Duszynski int 364ba901d33STomasz Duszynski roc_bphy_cgx_set_link_mode(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 365ba901d33STomasz Duszynski struct roc_bphy_cgx_link_mode *mode) 366ba901d33STomasz Duszynski { 367ba901d33STomasz Duszynski uint64_t scr1, scr0; 368ba901d33STomasz Duszynski 369bd2fd34aSTomasz Duszynski if (roc_model_is_cn9k() && 370bd2fd34aSTomasz Duszynski (mode->use_portm_idx || mode->portm_idx || mode->mode_group_idx)) { 371ba901d33STomasz Duszynski return -ENOTSUP; 372bd2fd34aSTomasz Duszynski } 373ba901d33STomasz Duszynski 374ba901d33STomasz Duszynski if (!roc_cgx) 375ba901d33STomasz Duszynski return -EINVAL; 376ba901d33STomasz Duszynski 377ba901d33STomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 378ba901d33STomasz Duszynski return -ENODEV; 379ba901d33STomasz Duszynski 380ba901d33STomasz Duszynski if (!mode) 381ba901d33STomasz Duszynski return -EINVAL; 382ba901d33STomasz Duszynski 383ba901d33STomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_MODE_CHANGE) | 384ba901d33STomasz Duszynski FIELD_PREP(SCR1_ETH_MODE_CHANGE_ARGS_SPEED, mode->speed) | 385ba901d33STomasz Duszynski FIELD_PREP(SCR1_ETH_MODE_CHANGE_ARGS_DUPLEX, mode->full_duplex) | 386ba901d33STomasz Duszynski FIELD_PREP(SCR1_ETH_MODE_CHANGE_ARGS_AN, mode->an) | 387bd2fd34aSTomasz Duszynski FIELD_PREP(SCR1_ETH_MODE_CHANGE_ARGS_USE_PORTM_IDX, 388bd2fd34aSTomasz Duszynski mode->use_portm_idx) | 389bd2fd34aSTomasz Duszynski FIELD_PREP(SCR1_ETH_MODE_CHANGE_ARGS_PORTM_IDX, 390bd2fd34aSTomasz Duszynski mode->portm_idx) | 391bd2fd34aSTomasz Duszynski FIELD_PREP(SCR1_ETH_MODE_CHANGE_ARGS_MODE_GROUP_IDX, 392bd2fd34aSTomasz Duszynski mode->mode_group_idx) | 393ba901d33STomasz Duszynski FIELD_PREP(SCR1_ETH_MODE_CHANGE_ARGS_MODE, BIT_ULL(mode->mode)); 394ba901d33STomasz Duszynski 395ba901d33STomasz Duszynski return roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 396ba901d33STomasz Duszynski } 397ba901d33STomasz Duszynski 398ba901d33STomasz Duszynski int 3996c870ee8STomasz Duszynski roc_bphy_cgx_intlbk_enable(struct roc_bphy_cgx *roc_cgx, unsigned int lmac) 4006c870ee8STomasz Duszynski { 4016c870ee8STomasz Duszynski return roc_bphy_cgx_intlbk_ena_dis(roc_cgx, lmac, true); 4026c870ee8STomasz Duszynski } 4036c870ee8STomasz Duszynski 4046c870ee8STomasz Duszynski int 4056c870ee8STomasz Duszynski roc_bphy_cgx_intlbk_disable(struct roc_bphy_cgx *roc_cgx, unsigned int lmac) 4066c870ee8STomasz Duszynski { 4076c870ee8STomasz Duszynski return roc_bphy_cgx_intlbk_ena_dis(roc_cgx, lmac, false); 4086c870ee8STomasz Duszynski } 40972096a47STomasz Duszynski 41072096a47STomasz Duszynski int 41172096a47STomasz Duszynski roc_bphy_cgx_ptp_rx_enable(struct roc_bphy_cgx *roc_cgx, unsigned int lmac) 41272096a47STomasz Duszynski { 41372096a47STomasz Duszynski return roc_bphy_cgx_ptp_rx_ena_dis(roc_cgx, lmac, true); 41472096a47STomasz Duszynski } 41572096a47STomasz Duszynski 41672096a47STomasz Duszynski int 41772096a47STomasz Duszynski roc_bphy_cgx_ptp_rx_disable(struct roc_bphy_cgx *roc_cgx, unsigned int lmac) 41872096a47STomasz Duszynski { 41972096a47STomasz Duszynski return roc_bphy_cgx_ptp_rx_ena_dis(roc_cgx, lmac, false); 42072096a47STomasz Duszynski } 4217ab475a0STomasz Duszynski 4227ab475a0STomasz Duszynski int 42359cdf690STomasz Duszynski roc_bphy_cgx_fec_set(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 42459cdf690STomasz Duszynski enum roc_bphy_cgx_eth_link_fec fec) 42559cdf690STomasz Duszynski { 42659cdf690STomasz Duszynski uint64_t scr1, scr0; 42759cdf690STomasz Duszynski 42859cdf690STomasz Duszynski if (!roc_cgx) 42959cdf690STomasz Duszynski return -EINVAL; 43059cdf690STomasz Duszynski 43159cdf690STomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 432b816b6f4STomasz Duszynski return -ENODEV; 43359cdf690STomasz Duszynski 43459cdf690STomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_SET_FEC) | 43559cdf690STomasz Duszynski FIELD_PREP(SCR1_ETH_SET_FEC_ARGS, fec); 43659cdf690STomasz Duszynski 43759cdf690STomasz Duszynski return roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 43859cdf690STomasz Duszynski } 43959cdf690STomasz Duszynski 44059cdf690STomasz Duszynski int 4417ab475a0STomasz Duszynski roc_bphy_cgx_fec_supported_get(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 4427ab475a0STomasz Duszynski enum roc_bphy_cgx_eth_link_fec *fec) 4437ab475a0STomasz Duszynski { 4447ab475a0STomasz Duszynski uint64_t scr1, scr0; 4457ab475a0STomasz Duszynski int ret; 4467ab475a0STomasz Duszynski 4477ab475a0STomasz Duszynski if (!roc_cgx || !fec) 4487ab475a0STomasz Duszynski return -EINVAL; 4497ab475a0STomasz Duszynski 4507ab475a0STomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 451b816b6f4STomasz Duszynski return -ENODEV; 4527ab475a0STomasz Duszynski 4537ab475a0STomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_GET_SUPPORTED_FEC); 4547ab475a0STomasz Duszynski 4557ab475a0STomasz Duszynski ret = roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 4567ab475a0STomasz Duszynski if (ret) 4577ab475a0STomasz Duszynski return ret; 4587ab475a0STomasz Duszynski 4597ab475a0STomasz Duszynski scr0 = FIELD_GET(SCR0_ETH_FEC_TYPES_S_FEC, scr0); 4607ab475a0STomasz Duszynski *fec = (enum roc_bphy_cgx_eth_link_fec)scr0; 4617ab475a0STomasz Duszynski 4627ab475a0STomasz Duszynski return 0; 4637ab475a0STomasz Duszynski } 4647af3e7aaSTomasz Duszynski 4657af3e7aaSTomasz Duszynski int 4667af3e7aaSTomasz Duszynski roc_bphy_cgx_cpri_mode_change(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 4677af3e7aaSTomasz Duszynski struct roc_bphy_cgx_cpri_mode_change *mode) 4687af3e7aaSTomasz Duszynski { 4697af3e7aaSTomasz Duszynski uint64_t scr1, scr0; 4707af3e7aaSTomasz Duszynski 4717af3e7aaSTomasz Duszynski if (!(roc_model_is_cnf95xxn_a0() || 4727af3e7aaSTomasz Duszynski roc_model_is_cnf95xxn_a1() || 4737af3e7aaSTomasz Duszynski roc_model_is_cnf95xxn_b0())) 4747af3e7aaSTomasz Duszynski return -ENOTSUP; 4757af3e7aaSTomasz Duszynski 4767af3e7aaSTomasz Duszynski if (!roc_cgx) 4777af3e7aaSTomasz Duszynski return -EINVAL; 4787af3e7aaSTomasz Duszynski 4797af3e7aaSTomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 4807af3e7aaSTomasz Duszynski return -ENODEV; 4817af3e7aaSTomasz Duszynski 4827af3e7aaSTomasz Duszynski if (!mode) 4837af3e7aaSTomasz Duszynski return -EINVAL; 4847af3e7aaSTomasz Duszynski 4857af3e7aaSTomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_CPRI_MODE_CHANGE) | 4867af3e7aaSTomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_CHANGE_ARGS_GSERC_IDX, 4877af3e7aaSTomasz Duszynski mode->gserc_idx) | 4887af3e7aaSTomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_CHANGE_ARGS_LANE_IDX, mode->lane_idx) | 4897af3e7aaSTomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_CHANGE_ARGS_RATE, mode->rate) | 4907af3e7aaSTomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_CHANGE_ARGS_DISABLE_LEQ, 4917af3e7aaSTomasz Duszynski mode->disable_leq) | 4927af3e7aaSTomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_CHANGE_ARGS_DISABLE_DFE, 4937af3e7aaSTomasz Duszynski mode->disable_dfe); 4947af3e7aaSTomasz Duszynski 4957af3e7aaSTomasz Duszynski return roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 4967af3e7aaSTomasz Duszynski } 497283c9175STomasz Duszynski 498283c9175STomasz Duszynski int 499283c9175STomasz Duszynski roc_bphy_cgx_cpri_mode_tx_control(struct roc_bphy_cgx *roc_cgx, 500283c9175STomasz Duszynski unsigned int lmac, 501283c9175STomasz Duszynski struct roc_bphy_cgx_cpri_mode_tx_ctrl *mode) 502283c9175STomasz Duszynski { 503283c9175STomasz Duszynski uint64_t scr1, scr0; 504283c9175STomasz Duszynski 505283c9175STomasz Duszynski if (!(roc_model_is_cnf95xxn_a0() || 506283c9175STomasz Duszynski roc_model_is_cnf95xxn_a1() || 507283c9175STomasz Duszynski roc_model_is_cnf95xxn_b0())) 508283c9175STomasz Duszynski return -ENOTSUP; 509283c9175STomasz Duszynski 510283c9175STomasz Duszynski if (!roc_cgx) 511283c9175STomasz Duszynski return -EINVAL; 512283c9175STomasz Duszynski 513283c9175STomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 514283c9175STomasz Duszynski return -ENODEV; 515283c9175STomasz Duszynski 516283c9175STomasz Duszynski if (!mode) 517283c9175STomasz Duszynski return -EINVAL; 518283c9175STomasz Duszynski 519283c9175STomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_CPRI_TX_CONTROL) | 520283c9175STomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_TX_CTRL_ARGS_GSERC_IDX, 521283c9175STomasz Duszynski mode->gserc_idx) | 522283c9175STomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_TX_CTRL_ARGS_LANE_IDX, 523283c9175STomasz Duszynski mode->lane_idx) | 524283c9175STomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_TX_CTRL_ARGS_ENABLE, mode->enable); 525283c9175STomasz Duszynski 526283c9175STomasz Duszynski return roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 527283c9175STomasz Duszynski } 528888123a6STomasz Duszynski 529888123a6STomasz Duszynski int 530888123a6STomasz Duszynski roc_bphy_cgx_cpri_mode_misc(struct roc_bphy_cgx *roc_cgx, unsigned int lmac, 531888123a6STomasz Duszynski struct roc_bphy_cgx_cpri_mode_misc *mode) 532888123a6STomasz Duszynski { 533888123a6STomasz Duszynski uint64_t scr1, scr0; 534888123a6STomasz Duszynski 535888123a6STomasz Duszynski if (!(roc_model_is_cnf95xxn_a0() || 536888123a6STomasz Duszynski roc_model_is_cnf95xxn_a1() || 537888123a6STomasz Duszynski roc_model_is_cnf95xxn_b0())) 538888123a6STomasz Duszynski return -ENOTSUP; 539888123a6STomasz Duszynski 540888123a6STomasz Duszynski if (!roc_cgx) 541888123a6STomasz Duszynski return -EINVAL; 542888123a6STomasz Duszynski 543888123a6STomasz Duszynski if (!roc_bphy_cgx_lmac_exists(roc_cgx, lmac)) 544888123a6STomasz Duszynski return -ENODEV; 545888123a6STomasz Duszynski 546888123a6STomasz Duszynski if (!mode) 547888123a6STomasz Duszynski return -EINVAL; 548888123a6STomasz Duszynski 549888123a6STomasz Duszynski scr1 = FIELD_PREP(SCR1_ETH_CMD_ID, ETH_CMD_CPRI_MISC) | 550888123a6STomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_MISC_ARGS_GSERC_IDX, 551888123a6STomasz Duszynski mode->gserc_idx) | 552888123a6STomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_MISC_ARGS_LANE_IDX, 553888123a6STomasz Duszynski mode->lane_idx) | 554888123a6STomasz Duszynski FIELD_PREP(SCR1_CPRI_MODE_MISC_ARGS_FLAGS, mode->flags); 555888123a6STomasz Duszynski 556888123a6STomasz Duszynski return roc_bphy_cgx_intf_req(roc_cgx, lmac, scr1, &scr0); 557888123a6STomasz Duszynski } 558