191c6945eSHariprasad Kelam // SPDX-License-Identifier: GPL-2.0 2c7cd6c5aSSunil Goutham /* Marvell CN10K RPM driver 391c6945eSHariprasad Kelam * 491c6945eSHariprasad Kelam * Copyright (C) 2020 Marvell. 591c6945eSHariprasad Kelam * 691c6945eSHariprasad Kelam */ 791c6945eSHariprasad Kelam 891c6945eSHariprasad Kelam #include "cgx.h" 991c6945eSHariprasad Kelam #include "lmac_common.h" 1091c6945eSHariprasad Kelam 1191c6945eSHariprasad Kelam static struct mac_ops rpm_mac_ops = { 1291c6945eSHariprasad Kelam .name = "rpm", 1391c6945eSHariprasad Kelam .csr_offset = 0x4e00, 1491c6945eSHariprasad Kelam .lmac_offset = 20, 1591c6945eSHariprasad Kelam .int_register = RPMX_CMRX_SW_INT, 1691c6945eSHariprasad Kelam .int_set_reg = RPMX_CMRX_SW_INT_ENA_W1S, 1791c6945eSHariprasad Kelam .irq_offset = 1, 1891c6945eSHariprasad Kelam .int_ena_bit = BIT_ULL(0), 1991c6945eSHariprasad Kelam .lmac_fwi = RPM_LMAC_FWI, 2091c6945eSHariprasad Kelam .non_contiguous_serdes_lane = true, 21ce7a6c31SHariprasad Kelam .rx_stats_cnt = 43, 22ce7a6c31SHariprasad Kelam .tx_stats_cnt = 34, 2391c6945eSHariprasad Kelam .get_nr_lmacs = rpm_get_nr_lmacs, 243ad3f8f9SHariprasad Kelam .get_lmac_type = rpm_get_lmac_type, 25459f326eSSunil Goutham .lmac_fifo_len = rpm_get_lmac_fifo_len, 263ad3f8f9SHariprasad Kelam .mac_lmac_intl_lbk = rpm_lmac_internal_loopback, 27ce7a6c31SHariprasad Kelam .mac_get_rx_stats = rpm_get_rx_stats, 28ce7a6c31SHariprasad Kelam .mac_get_tx_stats = rpm_get_tx_stats, 291845ada4SRakesh Babu .mac_enadis_rx_pause_fwding = rpm_lmac_enadis_rx_pause_fwding, 301845ada4SRakesh Babu .mac_get_pause_frm_status = rpm_lmac_get_pause_frm_status, 311845ada4SRakesh Babu .mac_enadis_pause_frm = rpm_lmac_enadis_pause_frm, 321845ada4SRakesh Babu .mac_pause_frm_config = rpm_lmac_pause_frm_config, 33d1489208SHariprasad Kelam .mac_enadis_ptp_config = rpm_lmac_ptp_config, 34fae80edeSGeetha sowjanya .mac_rx_tx_enable = rpm_lmac_rx_tx_enable, 35fae80edeSGeetha sowjanya .mac_tx_enable = rpm_lmac_tx_enable, 361121f6b0SSunil Kumar Kori .pfc_config = rpm_lmac_pfc_config, 37e7400038SHariprasad Kelam .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg, 3891c6945eSHariprasad Kelam }; 3991c6945eSHariprasad Kelam 4091c6945eSHariprasad Kelam struct mac_ops *rpm_get_mac_ops(void) 4191c6945eSHariprasad Kelam { 4291c6945eSHariprasad Kelam return &rpm_mac_ops; 4391c6945eSHariprasad Kelam } 4491c6945eSHariprasad Kelam 451845ada4SRakesh Babu static void rpm_write(rpm_t *rpm, u64 lmac, u64 offset, u64 val) 461845ada4SRakesh Babu { 471845ada4SRakesh Babu cgx_write(rpm, lmac, offset, val); 481845ada4SRakesh Babu } 491845ada4SRakesh Babu 5091c6945eSHariprasad Kelam static u64 rpm_read(rpm_t *rpm, u64 lmac, u64 offset) 5191c6945eSHariprasad Kelam { 5291c6945eSHariprasad Kelam return cgx_read(rpm, lmac, offset); 5391c6945eSHariprasad Kelam } 5491c6945eSHariprasad Kelam 5591c6945eSHariprasad Kelam int rpm_get_nr_lmacs(void *rpmd) 5691c6945eSHariprasad Kelam { 5791c6945eSHariprasad Kelam rpm_t *rpm = rpmd; 5891c6945eSHariprasad Kelam 5991c6945eSHariprasad Kelam return hweight8(rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS) & 0xFULL); 6091c6945eSHariprasad Kelam } 611845ada4SRakesh Babu 62fae80edeSGeetha sowjanya int rpm_lmac_tx_enable(void *rpmd, int lmac_id, bool enable) 63fae80edeSGeetha sowjanya { 64fae80edeSGeetha sowjanya rpm_t *rpm = rpmd; 65fae80edeSGeetha sowjanya u64 cfg, last; 66fae80edeSGeetha sowjanya 67fae80edeSGeetha sowjanya if (!is_lmac_valid(rpm, lmac_id)) 68fae80edeSGeetha sowjanya return -ENODEV; 69fae80edeSGeetha sowjanya 70fae80edeSGeetha sowjanya cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 71fae80edeSGeetha sowjanya last = cfg; 72fae80edeSGeetha sowjanya if (enable) 73fae80edeSGeetha sowjanya cfg |= RPM_TX_EN; 74fae80edeSGeetha sowjanya else 75fae80edeSGeetha sowjanya cfg &= ~(RPM_TX_EN); 76fae80edeSGeetha sowjanya 77fae80edeSGeetha sowjanya if (cfg != last) 78fae80edeSGeetha sowjanya rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 79fae80edeSGeetha sowjanya return !!(last & RPM_TX_EN); 80fae80edeSGeetha sowjanya } 81fae80edeSGeetha sowjanya 82fae80edeSGeetha sowjanya int rpm_lmac_rx_tx_enable(void *rpmd, int lmac_id, bool enable) 83fae80edeSGeetha sowjanya { 84fae80edeSGeetha sowjanya rpm_t *rpm = rpmd; 85fae80edeSGeetha sowjanya u64 cfg; 86fae80edeSGeetha sowjanya 87fae80edeSGeetha sowjanya if (!is_lmac_valid(rpm, lmac_id)) 88fae80edeSGeetha sowjanya return -ENODEV; 89fae80edeSGeetha sowjanya 90fae80edeSGeetha sowjanya cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 91fae80edeSGeetha sowjanya if (enable) 92fae80edeSGeetha sowjanya cfg |= RPM_RX_EN | RPM_TX_EN; 93fae80edeSGeetha sowjanya else 94fae80edeSGeetha sowjanya cfg &= ~(RPM_RX_EN | RPM_TX_EN); 95fae80edeSGeetha sowjanya rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 96fae80edeSGeetha sowjanya return 0; 97fae80edeSGeetha sowjanya } 98fae80edeSGeetha sowjanya 991845ada4SRakesh Babu void rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable) 1001845ada4SRakesh Babu { 101ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 102e7400038SHariprasad Kelam struct lmac *lmac; 1031845ada4SRakesh Babu u64 cfg; 1041845ada4SRakesh Babu 1051845ada4SRakesh Babu if (!rpm) 1061845ada4SRakesh Babu return; 1071845ada4SRakesh Babu 108e7400038SHariprasad Kelam lmac = lmac_pdata(lmac_id, rpm); 109e7400038SHariprasad Kelam if (!lmac) 110e7400038SHariprasad Kelam return; 111e7400038SHariprasad Kelam 112e7400038SHariprasad Kelam /* Pause frames are not enabled just return */ 113e7400038SHariprasad Kelam if (!bitmap_weight(lmac->rx_fc_pfvf_bmap.bmap, lmac->rx_fc_pfvf_bmap.max)) 114e7400038SHariprasad Kelam return; 115e7400038SHariprasad Kelam 1161845ada4SRakesh Babu if (enable) { 1171845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 1181845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 1191845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 1201845ada4SRakesh Babu } else { 1211845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 1221845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 1231845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 1241845ada4SRakesh Babu } 1251845ada4SRakesh Babu } 1261845ada4SRakesh Babu 1271845ada4SRakesh Babu int rpm_lmac_get_pause_frm_status(void *rpmd, int lmac_id, 1281845ada4SRakesh Babu u8 *tx_pause, u8 *rx_pause) 1291845ada4SRakesh Babu { 1301845ada4SRakesh Babu rpm_t *rpm = rpmd; 1311845ada4SRakesh Babu u64 cfg; 1321845ada4SRakesh Babu 1331845ada4SRakesh Babu if (!is_lmac_valid(rpm, lmac_id)) 1341845ada4SRakesh Babu return -ENODEV; 1351845ada4SRakesh Babu 1361845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 137e7400038SHariprasad Kelam if (!(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE)) { 1381845ada4SRakesh Babu *rx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE); 1391845ada4SRakesh Babu *tx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE); 140e7400038SHariprasad Kelam } 141e7400038SHariprasad Kelam 1421845ada4SRakesh Babu return 0; 1431845ada4SRakesh Babu } 1441845ada4SRakesh Babu 1455f7dc7d4SHariprasad Kelam static void rpm_cfg_pfc_quanta_thresh(rpm_t *rpm, int lmac_id, 1465f7dc7d4SHariprasad Kelam unsigned long pfc_en, 1471121f6b0SSunil Kumar Kori bool enable) 1481121f6b0SSunil Kumar Kori { 1491121f6b0SSunil Kumar Kori u64 quanta_offset = 0, quanta_thresh = 0, cfg; 1501121f6b0SSunil Kumar Kori int i, shift; 1511121f6b0SSunil Kumar Kori 1521121f6b0SSunil Kumar Kori /* Set pause time and interval */ 1535f7dc7d4SHariprasad Kelam for_each_set_bit(i, &pfc_en, 16) { 1541121f6b0SSunil Kumar Kori switch (i) { 1551121f6b0SSunil Kumar Kori case 0: 1561121f6b0SSunil Kumar Kori case 1: 1571121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA; 1581121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL01_QUANTA_THRESH; 1591121f6b0SSunil Kumar Kori break; 1601121f6b0SSunil Kumar Kori case 2: 1611121f6b0SSunil Kumar Kori case 3: 1621121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL23_PAUSE_QUANTA; 1631121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL23_QUANTA_THRESH; 1641121f6b0SSunil Kumar Kori break; 1651121f6b0SSunil Kumar Kori case 4: 1661121f6b0SSunil Kumar Kori case 5: 1671121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL45_PAUSE_QUANTA; 1681121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL45_QUANTA_THRESH; 1691121f6b0SSunil Kumar Kori break; 1701121f6b0SSunil Kumar Kori case 6: 1711121f6b0SSunil Kumar Kori case 7: 1721121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL67_PAUSE_QUANTA; 1731121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL67_QUANTA_THRESH; 1741121f6b0SSunil Kumar Kori break; 1751121f6b0SSunil Kumar Kori case 8: 1761121f6b0SSunil Kumar Kori case 9: 1771121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA; 1781121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL89_QUANTA_THRESH; 1791121f6b0SSunil Kumar Kori break; 1801121f6b0SSunil Kumar Kori case 10: 1811121f6b0SSunil Kumar Kori case 11: 1821121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1011_PAUSE_QUANTA; 1831121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1011_QUANTA_THRESH; 1841121f6b0SSunil Kumar Kori break; 1851121f6b0SSunil Kumar Kori case 12: 1861121f6b0SSunil Kumar Kori case 13: 1871121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1213_PAUSE_QUANTA; 1881121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1213_QUANTA_THRESH; 1891121f6b0SSunil Kumar Kori break; 1901121f6b0SSunil Kumar Kori case 14: 1911121f6b0SSunil Kumar Kori case 15: 1921121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1415_PAUSE_QUANTA; 1931121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1415_QUANTA_THRESH; 1941121f6b0SSunil Kumar Kori break; 1951121f6b0SSunil Kumar Kori } 1961121f6b0SSunil Kumar Kori 1971121f6b0SSunil Kumar Kori if (!quanta_offset || !quanta_thresh) 1981121f6b0SSunil Kumar Kori continue; 1991121f6b0SSunil Kumar Kori 2001121f6b0SSunil Kumar Kori shift = (i % 2) ? 1 : 0; 2011121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, quanta_offset); 2021121f6b0SSunil Kumar Kori if (enable) { 2031121f6b0SSunil Kumar Kori cfg |= ((u64)RPM_DEFAULT_PAUSE_TIME << shift * 16); 2041121f6b0SSunil Kumar Kori } else { 2051121f6b0SSunil Kumar Kori if (!shift) 2061121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(15, 0); 2071121f6b0SSunil Kumar Kori else 2081121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(31, 16); 2091121f6b0SSunil Kumar Kori } 2101121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, quanta_offset, cfg); 2111121f6b0SSunil Kumar Kori 2121121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, quanta_thresh); 2131121f6b0SSunil Kumar Kori if (enable) { 2141121f6b0SSunil Kumar Kori cfg |= ((u64)(RPM_DEFAULT_PAUSE_TIME / 2) << shift * 16); 2151121f6b0SSunil Kumar Kori } else { 2161121f6b0SSunil Kumar Kori if (!shift) 2171121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(15, 0); 2181121f6b0SSunil Kumar Kori else 2191121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(31, 16); 2201121f6b0SSunil Kumar Kori } 2211121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, quanta_thresh, cfg); 2221121f6b0SSunil Kumar Kori } 2231121f6b0SSunil Kumar Kori } 2241121f6b0SSunil Kumar Kori 2251845ada4SRakesh Babu int rpm_lmac_enadis_pause_frm(void *rpmd, int lmac_id, u8 tx_pause, 2261845ada4SRakesh Babu u8 rx_pause) 2271845ada4SRakesh Babu { 2281845ada4SRakesh Babu rpm_t *rpm = rpmd; 2291845ada4SRakesh Babu u64 cfg; 2301845ada4SRakesh Babu 2311845ada4SRakesh Babu if (!is_lmac_valid(rpm, lmac_id)) 2321845ada4SRakesh Babu return -ENODEV; 2331845ada4SRakesh Babu 2341845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2351845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 2361845ada4SRakesh Babu cfg |= rx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 2371845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 2381845ada4SRakesh Babu cfg |= rx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 2391845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2401845ada4SRakesh Babu 2411845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2421845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 2431845ada4SRakesh Babu cfg |= tx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 2441845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2451845ada4SRakesh Babu 2461845ada4SRakesh Babu cfg = rpm_read(rpm, 0, RPMX_CMR_RX_OVR_BP); 2471845ada4SRakesh Babu if (tx_pause) { 2481121f6b0SSunil Kumar Kori /* Configure CL0 Pause Quanta & threshold for 802.3X frames */ 2491121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 1, true); 2501845ada4SRakesh Babu cfg &= ~RPMX_CMR_RX_OVR_BP_EN(lmac_id); 2511845ada4SRakesh Babu } else { 2521121f6b0SSunil Kumar Kori /* Disable all Pause Quanta & threshold values */ 2531121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false); 2541845ada4SRakesh Babu cfg |= RPMX_CMR_RX_OVR_BP_EN(lmac_id); 2551845ada4SRakesh Babu cfg &= ~RPMX_CMR_RX_OVR_BP_BP(lmac_id); 2561845ada4SRakesh Babu } 2571845ada4SRakesh Babu rpm_write(rpm, 0, RPMX_CMR_RX_OVR_BP, cfg); 2581845ada4SRakesh Babu return 0; 2591845ada4SRakesh Babu } 2601845ada4SRakesh Babu 2611845ada4SRakesh Babu void rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable) 2621845ada4SRakesh Babu { 2631845ada4SRakesh Babu rpm_t *rpm = rpmd; 2641845ada4SRakesh Babu u64 cfg; 2651845ada4SRakesh Babu 2661845ada4SRakesh Babu /* ALL pause frames received are completely ignored */ 2671845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2681845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 2691845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2701845ada4SRakesh Babu 2711845ada4SRakesh Babu /* Disable forward pause to TX block */ 2721845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2731845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 2741845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2751845ada4SRakesh Babu 2761845ada4SRakesh Babu /* Disable pause frames transmission */ 2771845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2781845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 2791845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2808e151457SHariprasad Kelam 2818e151457SHariprasad Kelam /* Disable all PFC classes */ 2828e151457SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL); 2838e151457SHariprasad Kelam cfg = FIELD_SET(RPM_PFC_CLASS_MASK, 0, cfg); 2848e151457SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL, cfg); 2853e35d198SHariprasad Kelam 2863e35d198SHariprasad Kelam /* Enable channel mask for all LMACS */ 2873e35d198SHariprasad Kelam rpm_write(rpm, 0, RPMX_CMR_CHAN_MSK_OR, ~0ULL); 2881845ada4SRakesh Babu } 289ce7a6c31SHariprasad Kelam 290ce7a6c31SHariprasad Kelam int rpm_get_rx_stats(void *rpmd, int lmac_id, int idx, u64 *rx_stat) 291ce7a6c31SHariprasad Kelam { 292ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 293ce7a6c31SHariprasad Kelam u64 val_lo, val_hi; 294ce7a6c31SHariprasad Kelam 295ce7a6c31SHariprasad Kelam if (!rpm || lmac_id >= rpm->lmac_count) 296ce7a6c31SHariprasad Kelam return -ENODEV; 297ce7a6c31SHariprasad Kelam 298ce7a6c31SHariprasad Kelam mutex_lock(&rpm->lock); 299ce7a6c31SHariprasad Kelam 300ce7a6c31SHariprasad Kelam /* Update idx to point per lmac Rx statistics page */ 301ce7a6c31SHariprasad Kelam idx += lmac_id * rpm->mac_ops->rx_stats_cnt; 302ce7a6c31SHariprasad Kelam 303ce7a6c31SHariprasad Kelam /* Read lower 32 bits of counter */ 304ce7a6c31SHariprasad Kelam val_lo = rpm_read(rpm, 0, RPMX_MTI_STAT_RX_STAT_PAGES_COUNTERX + 305ce7a6c31SHariprasad Kelam (idx * 8)); 306ce7a6c31SHariprasad Kelam 307ce7a6c31SHariprasad Kelam /* upon read of lower 32 bits, higher 32 bits are written 308ce7a6c31SHariprasad Kelam * to RPMX_MTI_STAT_DATA_HI_CDC 309ce7a6c31SHariprasad Kelam */ 310ce7a6c31SHariprasad Kelam val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 311ce7a6c31SHariprasad Kelam 312ce7a6c31SHariprasad Kelam *rx_stat = (val_hi << 32 | val_lo); 313ce7a6c31SHariprasad Kelam 314ce7a6c31SHariprasad Kelam mutex_unlock(&rpm->lock); 315ce7a6c31SHariprasad Kelam return 0; 316ce7a6c31SHariprasad Kelam } 317ce7a6c31SHariprasad Kelam 318ce7a6c31SHariprasad Kelam int rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat) 319ce7a6c31SHariprasad Kelam { 320ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 321ce7a6c31SHariprasad Kelam u64 val_lo, val_hi; 322ce7a6c31SHariprasad Kelam 323ce7a6c31SHariprasad Kelam if (!rpm || lmac_id >= rpm->lmac_count) 324ce7a6c31SHariprasad Kelam return -ENODEV; 325ce7a6c31SHariprasad Kelam 326ce7a6c31SHariprasad Kelam mutex_lock(&rpm->lock); 327ce7a6c31SHariprasad Kelam 328ce7a6c31SHariprasad Kelam /* Update idx to point per lmac Tx statistics page */ 329ce7a6c31SHariprasad Kelam idx += lmac_id * rpm->mac_ops->tx_stats_cnt; 330ce7a6c31SHariprasad Kelam 331ce7a6c31SHariprasad Kelam val_lo = rpm_read(rpm, 0, RPMX_MTI_STAT_TX_STAT_PAGES_COUNTERX + 332ce7a6c31SHariprasad Kelam (idx * 8)); 333ce7a6c31SHariprasad Kelam val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 334ce7a6c31SHariprasad Kelam 335ce7a6c31SHariprasad Kelam *tx_stat = (val_hi << 32 | val_lo); 336ce7a6c31SHariprasad Kelam 337ce7a6c31SHariprasad Kelam mutex_unlock(&rpm->lock); 338ce7a6c31SHariprasad Kelam return 0; 339ce7a6c31SHariprasad Kelam } 3403ad3f8f9SHariprasad Kelam 3413ad3f8f9SHariprasad Kelam u8 rpm_get_lmac_type(void *rpmd, int lmac_id) 3423ad3f8f9SHariprasad Kelam { 3433ad3f8f9SHariprasad Kelam rpm_t *rpm = rpmd; 3443ad3f8f9SHariprasad Kelam u64 req = 0, resp; 3453ad3f8f9SHariprasad Kelam int err; 3463ad3f8f9SHariprasad Kelam 3473ad3f8f9SHariprasad Kelam req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_LINK_STS, req); 3483ad3f8f9SHariprasad Kelam err = cgx_fwi_cmd_generic(req, &resp, rpm, 0); 3493ad3f8f9SHariprasad Kelam if (!err) 3503ad3f8f9SHariprasad Kelam return FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, resp); 3513ad3f8f9SHariprasad Kelam return err; 3523ad3f8f9SHariprasad Kelam } 3533ad3f8f9SHariprasad Kelam 354459f326eSSunil Goutham u32 rpm_get_lmac_fifo_len(void *rpmd, int lmac_id) 355459f326eSSunil Goutham { 356459f326eSSunil Goutham rpm_t *rpm = rpmd; 357459f326eSSunil Goutham u64 hi_perf_lmac; 358459f326eSSunil Goutham u8 num_lmacs; 359459f326eSSunil Goutham u32 fifo_len; 360459f326eSSunil Goutham 361459f326eSSunil Goutham fifo_len = rpm->mac_ops->fifo_len; 362459f326eSSunil Goutham num_lmacs = rpm->mac_ops->get_nr_lmacs(rpm); 363459f326eSSunil Goutham 364459f326eSSunil Goutham switch (num_lmacs) { 365459f326eSSunil Goutham case 1: 366459f326eSSunil Goutham return fifo_len; 367459f326eSSunil Goutham case 2: 368459f326eSSunil Goutham return fifo_len / 2; 369459f326eSSunil Goutham case 3: 370459f326eSSunil Goutham /* LMAC marked as hi_perf gets half of the FIFO and rest 1/4th */ 371459f326eSSunil Goutham hi_perf_lmac = rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS); 372459f326eSSunil Goutham hi_perf_lmac = (hi_perf_lmac >> 4) & 0x3ULL; 373459f326eSSunil Goutham if (lmac_id == hi_perf_lmac) 374459f326eSSunil Goutham return fifo_len / 2; 375459f326eSSunil Goutham return fifo_len / 4; 376459f326eSSunil Goutham case 4: 377459f326eSSunil Goutham default: 378459f326eSSunil Goutham return fifo_len / 4; 379459f326eSSunil Goutham } 380459f326eSSunil Goutham return 0; 381459f326eSSunil Goutham } 382459f326eSSunil Goutham 3833ad3f8f9SHariprasad Kelam int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable) 3843ad3f8f9SHariprasad Kelam { 3853ad3f8f9SHariprasad Kelam rpm_t *rpm = rpmd; 3863ad3f8f9SHariprasad Kelam u8 lmac_type; 3873ad3f8f9SHariprasad Kelam u64 cfg; 3883ad3f8f9SHariprasad Kelam 3893ad3f8f9SHariprasad Kelam if (!rpm || lmac_id >= rpm->lmac_count) 3903ad3f8f9SHariprasad Kelam return -ENODEV; 3913ad3f8f9SHariprasad Kelam lmac_type = rpm->mac_ops->get_lmac_type(rpm, lmac_id); 392df66b6ebSGeetha sowjanya 393df66b6ebSGeetha sowjanya if (lmac_type == LMAC_MODE_QSGMII || lmac_type == LMAC_MODE_SGMII) { 394df66b6ebSGeetha sowjanya dev_err(&rpm->pdev->dev, "loopback not supported for LPC mode\n"); 395df66b6ebSGeetha sowjanya return 0; 396df66b6ebSGeetha sowjanya } 397df66b6ebSGeetha sowjanya 3983ad3f8f9SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1); 3993ad3f8f9SHariprasad Kelam 4003ad3f8f9SHariprasad Kelam if (enable) 4013ad3f8f9SHariprasad Kelam cfg |= RPMX_MTI_PCS_LBK; 4023ad3f8f9SHariprasad Kelam else 4033ad3f8f9SHariprasad Kelam cfg &= ~RPMX_MTI_PCS_LBK; 4043ad3f8f9SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1, cfg); 4053ad3f8f9SHariprasad Kelam 4063ad3f8f9SHariprasad Kelam return 0; 4073ad3f8f9SHariprasad Kelam } 408d1489208SHariprasad Kelam 409d1489208SHariprasad Kelam void rpm_lmac_ptp_config(void *rpmd, int lmac_id, bool enable) 410d1489208SHariprasad Kelam { 411d1489208SHariprasad Kelam rpm_t *rpm = rpmd; 412d1489208SHariprasad Kelam u64 cfg; 413d1489208SHariprasad Kelam 414d1489208SHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 415d1489208SHariprasad Kelam return; 416d1489208SHariprasad Kelam 417d1489208SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_CFG); 418*2958d17aSHariprasad Kelam if (enable) { 419d1489208SHariprasad Kelam cfg |= RPMX_RX_TS_PREPEND; 420*2958d17aSHariprasad Kelam cfg |= RPMX_TX_PTP_1S_SUPPORT; 421*2958d17aSHariprasad Kelam } else { 422d1489208SHariprasad Kelam cfg &= ~RPMX_RX_TS_PREPEND; 423*2958d17aSHariprasad Kelam cfg &= ~RPMX_TX_PTP_1S_SUPPORT; 424*2958d17aSHariprasad Kelam } 425*2958d17aSHariprasad Kelam 426d1489208SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_CMRX_CFG, cfg); 427*2958d17aSHariprasad Kelam 428*2958d17aSHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_XIF_MODE); 429*2958d17aSHariprasad Kelam 430*2958d17aSHariprasad Kelam if (enable) { 431*2958d17aSHariprasad Kelam cfg |= RPMX_ONESTEP_ENABLE; 432*2958d17aSHariprasad Kelam cfg &= ~RPMX_TS_BINARY_MODE; 433*2958d17aSHariprasad Kelam } else { 434*2958d17aSHariprasad Kelam cfg &= ~RPMX_ONESTEP_ENABLE; 435*2958d17aSHariprasad Kelam } 436*2958d17aSHariprasad Kelam 437*2958d17aSHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_XIF_MODE, cfg); 438d1489208SHariprasad Kelam } 4391121f6b0SSunil Kumar Kori 4401121f6b0SSunil Kumar Kori int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 pfc_en) 4411121f6b0SSunil Kumar Kori { 4421121f6b0SSunil Kumar Kori rpm_t *rpm = rpmd; 4438e151457SHariprasad Kelam u64 cfg, class_en; 4441121f6b0SSunil Kumar Kori 4451121f6b0SSunil Kumar Kori if (!is_lmac_valid(rpm, lmac_id)) 4461121f6b0SSunil Kumar Kori return -ENODEV; 4471121f6b0SSunil Kumar Kori 4481121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 4498e151457SHariprasad Kelam class_en = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL); 4508e151457SHariprasad Kelam pfc_en |= FIELD_GET(RPM_PFC_CLASS_MASK, class_en); 4511121f6b0SSunil Kumar Kori 4521121f6b0SSunil Kumar Kori if (rx_pause) { 4531121f6b0SSunil Kumar Kori cfg &= ~(RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | 4541121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE | 4551121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD); 4561121f6b0SSunil Kumar Kori } else { 4571121f6b0SSunil Kumar Kori cfg |= (RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | 4581121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE | 4591121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD); 4601121f6b0SSunil Kumar Kori } 4611121f6b0SSunil Kumar Kori 4621121f6b0SSunil Kumar Kori if (tx_pause) { 4631121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, pfc_en, true); 4641121f6b0SSunil Kumar Kori cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 4658e151457SHariprasad Kelam class_en = FIELD_SET(RPM_PFC_CLASS_MASK, pfc_en, class_en); 4661121f6b0SSunil Kumar Kori } else { 4671121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xfff, false); 4681121f6b0SSunil Kumar Kori cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 4698e151457SHariprasad Kelam class_en = FIELD_SET(RPM_PFC_CLASS_MASK, 0, class_en); 4701121f6b0SSunil Kumar Kori } 4711121f6b0SSunil Kumar Kori 4721121f6b0SSunil Kumar Kori if (!rx_pause && !tx_pause) 4731121f6b0SSunil Kumar Kori cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; 4741121f6b0SSunil Kumar Kori else 4751121f6b0SSunil Kumar Kori cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; 4761121f6b0SSunil Kumar Kori 4771121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 4781121f6b0SSunil Kumar Kori 4798e151457SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL, class_en); 4801121f6b0SSunil Kumar Kori 4811121f6b0SSunil Kumar Kori return 0; 4821121f6b0SSunil Kumar Kori } 483e7400038SHariprasad Kelam 484e7400038SHariprasad Kelam int rpm_lmac_get_pfc_frm_cfg(void *rpmd, int lmac_id, u8 *tx_pause, u8 *rx_pause) 485e7400038SHariprasad Kelam { 486e7400038SHariprasad Kelam rpm_t *rpm = rpmd; 487e7400038SHariprasad Kelam u64 cfg; 488e7400038SHariprasad Kelam 489e7400038SHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 490e7400038SHariprasad Kelam return -ENODEV; 491e7400038SHariprasad Kelam 492e7400038SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 493e7400038SHariprasad Kelam if (cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE) { 494e7400038SHariprasad Kelam *rx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE); 495e7400038SHariprasad Kelam *tx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE); 496e7400038SHariprasad Kelam } 497e7400038SHariprasad Kelam 498e7400038SHariprasad Kelam return 0; 499e7400038SHariprasad Kelam } 500