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, 253ad3f8f9SHariprasad Kelam .mac_lmac_intl_lbk = rpm_lmac_internal_loopback, 26ce7a6c31SHariprasad Kelam .mac_get_rx_stats = rpm_get_rx_stats, 27ce7a6c31SHariprasad Kelam .mac_get_tx_stats = rpm_get_tx_stats, 281845ada4SRakesh Babu .mac_enadis_rx_pause_fwding = rpm_lmac_enadis_rx_pause_fwding, 291845ada4SRakesh Babu .mac_get_pause_frm_status = rpm_lmac_get_pause_frm_status, 301845ada4SRakesh Babu .mac_enadis_pause_frm = rpm_lmac_enadis_pause_frm, 311845ada4SRakesh Babu .mac_pause_frm_config = rpm_lmac_pause_frm_config, 32d1489208SHariprasad Kelam .mac_enadis_ptp_config = rpm_lmac_ptp_config, 33fae80edeSGeetha sowjanya .mac_rx_tx_enable = rpm_lmac_rx_tx_enable, 34fae80edeSGeetha sowjanya .mac_tx_enable = rpm_lmac_tx_enable, 351121f6b0SSunil Kumar Kori .pfc_config = rpm_lmac_pfc_config, 36*e7400038SHariprasad Kelam .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg, 3791c6945eSHariprasad Kelam }; 3891c6945eSHariprasad Kelam 3991c6945eSHariprasad Kelam struct mac_ops *rpm_get_mac_ops(void) 4091c6945eSHariprasad Kelam { 4191c6945eSHariprasad Kelam return &rpm_mac_ops; 4291c6945eSHariprasad Kelam } 4391c6945eSHariprasad Kelam 441845ada4SRakesh Babu static void rpm_write(rpm_t *rpm, u64 lmac, u64 offset, u64 val) 451845ada4SRakesh Babu { 461845ada4SRakesh Babu cgx_write(rpm, lmac, offset, val); 471845ada4SRakesh Babu } 481845ada4SRakesh Babu 4991c6945eSHariprasad Kelam static u64 rpm_read(rpm_t *rpm, u64 lmac, u64 offset) 5091c6945eSHariprasad Kelam { 5191c6945eSHariprasad Kelam return cgx_read(rpm, lmac, offset); 5291c6945eSHariprasad Kelam } 5391c6945eSHariprasad Kelam 5491c6945eSHariprasad Kelam int rpm_get_nr_lmacs(void *rpmd) 5591c6945eSHariprasad Kelam { 5691c6945eSHariprasad Kelam rpm_t *rpm = rpmd; 5791c6945eSHariprasad Kelam 5891c6945eSHariprasad Kelam return hweight8(rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS) & 0xFULL); 5991c6945eSHariprasad Kelam } 601845ada4SRakesh Babu 61fae80edeSGeetha sowjanya int rpm_lmac_tx_enable(void *rpmd, int lmac_id, bool enable) 62fae80edeSGeetha sowjanya { 63fae80edeSGeetha sowjanya rpm_t *rpm = rpmd; 64fae80edeSGeetha sowjanya u64 cfg, last; 65fae80edeSGeetha sowjanya 66fae80edeSGeetha sowjanya if (!is_lmac_valid(rpm, lmac_id)) 67fae80edeSGeetha sowjanya return -ENODEV; 68fae80edeSGeetha sowjanya 69fae80edeSGeetha sowjanya cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 70fae80edeSGeetha sowjanya last = cfg; 71fae80edeSGeetha sowjanya if (enable) 72fae80edeSGeetha sowjanya cfg |= RPM_TX_EN; 73fae80edeSGeetha sowjanya else 74fae80edeSGeetha sowjanya cfg &= ~(RPM_TX_EN); 75fae80edeSGeetha sowjanya 76fae80edeSGeetha sowjanya if (cfg != last) 77fae80edeSGeetha sowjanya rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 78fae80edeSGeetha sowjanya return !!(last & RPM_TX_EN); 79fae80edeSGeetha sowjanya } 80fae80edeSGeetha sowjanya 81fae80edeSGeetha sowjanya int rpm_lmac_rx_tx_enable(void *rpmd, int lmac_id, bool enable) 82fae80edeSGeetha sowjanya { 83fae80edeSGeetha sowjanya rpm_t *rpm = rpmd; 84fae80edeSGeetha sowjanya u64 cfg; 85fae80edeSGeetha sowjanya 86fae80edeSGeetha sowjanya if (!is_lmac_valid(rpm, lmac_id)) 87fae80edeSGeetha sowjanya return -ENODEV; 88fae80edeSGeetha sowjanya 89fae80edeSGeetha sowjanya cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 90fae80edeSGeetha sowjanya if (enable) 91fae80edeSGeetha sowjanya cfg |= RPM_RX_EN | RPM_TX_EN; 92fae80edeSGeetha sowjanya else 93fae80edeSGeetha sowjanya cfg &= ~(RPM_RX_EN | RPM_TX_EN); 94fae80edeSGeetha sowjanya rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 95fae80edeSGeetha sowjanya return 0; 96fae80edeSGeetha sowjanya } 97fae80edeSGeetha sowjanya 981845ada4SRakesh Babu void rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable) 991845ada4SRakesh Babu { 100ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 101*e7400038SHariprasad Kelam struct lmac *lmac; 1021845ada4SRakesh Babu u64 cfg; 1031845ada4SRakesh Babu 1041845ada4SRakesh Babu if (!rpm) 1051845ada4SRakesh Babu return; 1061845ada4SRakesh Babu 107*e7400038SHariprasad Kelam lmac = lmac_pdata(lmac_id, rpm); 108*e7400038SHariprasad Kelam if (!lmac) 109*e7400038SHariprasad Kelam return; 110*e7400038SHariprasad Kelam 111*e7400038SHariprasad Kelam /* Pause frames are not enabled just return */ 112*e7400038SHariprasad Kelam if (!bitmap_weight(lmac->rx_fc_pfvf_bmap.bmap, lmac->rx_fc_pfvf_bmap.max)) 113*e7400038SHariprasad Kelam return; 114*e7400038SHariprasad Kelam 1151845ada4SRakesh Babu if (enable) { 1161845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 1171845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 1181845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 1191845ada4SRakesh Babu } else { 1201845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 1211845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 1221845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 1231845ada4SRakesh Babu } 1241845ada4SRakesh Babu } 1251845ada4SRakesh Babu 1261845ada4SRakesh Babu int rpm_lmac_get_pause_frm_status(void *rpmd, int lmac_id, 1271845ada4SRakesh Babu u8 *tx_pause, u8 *rx_pause) 1281845ada4SRakesh Babu { 1291845ada4SRakesh Babu rpm_t *rpm = rpmd; 1301845ada4SRakesh Babu u64 cfg; 1311845ada4SRakesh Babu 1321845ada4SRakesh Babu if (!is_lmac_valid(rpm, lmac_id)) 1331845ada4SRakesh Babu return -ENODEV; 1341845ada4SRakesh Babu 1351845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 136*e7400038SHariprasad Kelam if (!(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE)) { 1371845ada4SRakesh Babu *rx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE); 1381845ada4SRakesh Babu *tx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE); 139*e7400038SHariprasad Kelam } 140*e7400038SHariprasad Kelam 1411845ada4SRakesh Babu return 0; 1421845ada4SRakesh Babu } 1431845ada4SRakesh Babu 1441121f6b0SSunil Kumar Kori static void rpm_cfg_pfc_quanta_thresh(rpm_t *rpm, int lmac_id, u16 pfc_en, 1451121f6b0SSunil Kumar Kori bool enable) 1461121f6b0SSunil Kumar Kori { 1471121f6b0SSunil Kumar Kori u64 quanta_offset = 0, quanta_thresh = 0, cfg; 1481121f6b0SSunil Kumar Kori int i, shift; 1491121f6b0SSunil Kumar Kori 1501121f6b0SSunil Kumar Kori /* Set pause time and interval */ 1511121f6b0SSunil Kumar Kori for_each_set_bit(i, (unsigned long *)&pfc_en, 16) { 1521121f6b0SSunil Kumar Kori switch (i) { 1531121f6b0SSunil Kumar Kori case 0: 1541121f6b0SSunil Kumar Kori case 1: 1551121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA; 1561121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL01_QUANTA_THRESH; 1571121f6b0SSunil Kumar Kori break; 1581121f6b0SSunil Kumar Kori case 2: 1591121f6b0SSunil Kumar Kori case 3: 1601121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL23_PAUSE_QUANTA; 1611121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL23_QUANTA_THRESH; 1621121f6b0SSunil Kumar Kori break; 1631121f6b0SSunil Kumar Kori case 4: 1641121f6b0SSunil Kumar Kori case 5: 1651121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL45_PAUSE_QUANTA; 1661121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL45_QUANTA_THRESH; 1671121f6b0SSunil Kumar Kori break; 1681121f6b0SSunil Kumar Kori case 6: 1691121f6b0SSunil Kumar Kori case 7: 1701121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL67_PAUSE_QUANTA; 1711121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL67_QUANTA_THRESH; 1721121f6b0SSunil Kumar Kori break; 1731121f6b0SSunil Kumar Kori case 8: 1741121f6b0SSunil Kumar Kori case 9: 1751121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA; 1761121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL89_QUANTA_THRESH; 1771121f6b0SSunil Kumar Kori break; 1781121f6b0SSunil Kumar Kori case 10: 1791121f6b0SSunil Kumar Kori case 11: 1801121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1011_PAUSE_QUANTA; 1811121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1011_QUANTA_THRESH; 1821121f6b0SSunil Kumar Kori break; 1831121f6b0SSunil Kumar Kori case 12: 1841121f6b0SSunil Kumar Kori case 13: 1851121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1213_PAUSE_QUANTA; 1861121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1213_QUANTA_THRESH; 1871121f6b0SSunil Kumar Kori break; 1881121f6b0SSunil Kumar Kori case 14: 1891121f6b0SSunil Kumar Kori case 15: 1901121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1415_PAUSE_QUANTA; 1911121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1415_QUANTA_THRESH; 1921121f6b0SSunil Kumar Kori break; 1931121f6b0SSunil Kumar Kori } 1941121f6b0SSunil Kumar Kori 1951121f6b0SSunil Kumar Kori if (!quanta_offset || !quanta_thresh) 1961121f6b0SSunil Kumar Kori continue; 1971121f6b0SSunil Kumar Kori 1981121f6b0SSunil Kumar Kori shift = (i % 2) ? 1 : 0; 1991121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, quanta_offset); 2001121f6b0SSunil Kumar Kori if (enable) { 2011121f6b0SSunil Kumar Kori cfg |= ((u64)RPM_DEFAULT_PAUSE_TIME << shift * 16); 2021121f6b0SSunil Kumar Kori } else { 2031121f6b0SSunil Kumar Kori if (!shift) 2041121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(15, 0); 2051121f6b0SSunil Kumar Kori else 2061121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(31, 16); 2071121f6b0SSunil Kumar Kori } 2081121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, quanta_offset, cfg); 2091121f6b0SSunil Kumar Kori 2101121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, quanta_thresh); 2111121f6b0SSunil Kumar Kori if (enable) { 2121121f6b0SSunil Kumar Kori cfg |= ((u64)(RPM_DEFAULT_PAUSE_TIME / 2) << shift * 16); 2131121f6b0SSunil Kumar Kori } else { 2141121f6b0SSunil Kumar Kori if (!shift) 2151121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(15, 0); 2161121f6b0SSunil Kumar Kori else 2171121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(31, 16); 2181121f6b0SSunil Kumar Kori } 2191121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, quanta_thresh, cfg); 2201121f6b0SSunil Kumar Kori } 2211121f6b0SSunil Kumar Kori } 2221121f6b0SSunil Kumar Kori 2231845ada4SRakesh Babu int rpm_lmac_enadis_pause_frm(void *rpmd, int lmac_id, u8 tx_pause, 2241845ada4SRakesh Babu u8 rx_pause) 2251845ada4SRakesh Babu { 2261845ada4SRakesh Babu rpm_t *rpm = rpmd; 2271845ada4SRakesh Babu u64 cfg; 2281845ada4SRakesh Babu 2291845ada4SRakesh Babu if (!is_lmac_valid(rpm, lmac_id)) 2301845ada4SRakesh Babu return -ENODEV; 2311845ada4SRakesh Babu 2321845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2331845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 2341845ada4SRakesh Babu cfg |= rx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 2351845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 2361845ada4SRakesh Babu cfg |= rx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 2371845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2381845ada4SRakesh Babu 2391845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2401845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 2411845ada4SRakesh Babu cfg |= tx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 2421845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2431845ada4SRakesh Babu 2441845ada4SRakesh Babu cfg = rpm_read(rpm, 0, RPMX_CMR_RX_OVR_BP); 2451845ada4SRakesh Babu if (tx_pause) { 2461121f6b0SSunil Kumar Kori /* Configure CL0 Pause Quanta & threshold for 802.3X frames */ 2471121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 1, true); 2481845ada4SRakesh Babu cfg &= ~RPMX_CMR_RX_OVR_BP_EN(lmac_id); 2491845ada4SRakesh Babu } else { 2501121f6b0SSunil Kumar Kori /* Disable all Pause Quanta & threshold values */ 2511121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false); 2521845ada4SRakesh Babu cfg |= RPMX_CMR_RX_OVR_BP_EN(lmac_id); 2531845ada4SRakesh Babu cfg &= ~RPMX_CMR_RX_OVR_BP_BP(lmac_id); 2541845ada4SRakesh Babu } 2551845ada4SRakesh Babu rpm_write(rpm, 0, RPMX_CMR_RX_OVR_BP, cfg); 2561845ada4SRakesh Babu return 0; 2571845ada4SRakesh Babu } 2581845ada4SRakesh Babu 2591845ada4SRakesh Babu void rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable) 2601845ada4SRakesh Babu { 2611845ada4SRakesh Babu rpm_t *rpm = rpmd; 2621845ada4SRakesh Babu u64 cfg; 2631845ada4SRakesh Babu 2641845ada4SRakesh Babu /* ALL pause frames received are completely ignored */ 2651845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2661845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 2671845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2681845ada4SRakesh Babu 2691845ada4SRakesh Babu /* Disable forward pause to TX block */ 2701845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2711845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 2721845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2731845ada4SRakesh Babu 2741845ada4SRakesh Babu /* Disable pause frames transmission */ 2751845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 2761845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 2771845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 2781845ada4SRakesh Babu } 279ce7a6c31SHariprasad Kelam 280ce7a6c31SHariprasad Kelam int rpm_get_rx_stats(void *rpmd, int lmac_id, int idx, u64 *rx_stat) 281ce7a6c31SHariprasad Kelam { 282ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 283ce7a6c31SHariprasad Kelam u64 val_lo, val_hi; 284ce7a6c31SHariprasad Kelam 285ce7a6c31SHariprasad Kelam if (!rpm || lmac_id >= rpm->lmac_count) 286ce7a6c31SHariprasad Kelam return -ENODEV; 287ce7a6c31SHariprasad Kelam 288ce7a6c31SHariprasad Kelam mutex_lock(&rpm->lock); 289ce7a6c31SHariprasad Kelam 290ce7a6c31SHariprasad Kelam /* Update idx to point per lmac Rx statistics page */ 291ce7a6c31SHariprasad Kelam idx += lmac_id * rpm->mac_ops->rx_stats_cnt; 292ce7a6c31SHariprasad Kelam 293ce7a6c31SHariprasad Kelam /* Read lower 32 bits of counter */ 294ce7a6c31SHariprasad Kelam val_lo = rpm_read(rpm, 0, RPMX_MTI_STAT_RX_STAT_PAGES_COUNTERX + 295ce7a6c31SHariprasad Kelam (idx * 8)); 296ce7a6c31SHariprasad Kelam 297ce7a6c31SHariprasad Kelam /* upon read of lower 32 bits, higher 32 bits are written 298ce7a6c31SHariprasad Kelam * to RPMX_MTI_STAT_DATA_HI_CDC 299ce7a6c31SHariprasad Kelam */ 300ce7a6c31SHariprasad Kelam val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 301ce7a6c31SHariprasad Kelam 302ce7a6c31SHariprasad Kelam *rx_stat = (val_hi << 32 | val_lo); 303ce7a6c31SHariprasad Kelam 304ce7a6c31SHariprasad Kelam mutex_unlock(&rpm->lock); 305ce7a6c31SHariprasad Kelam return 0; 306ce7a6c31SHariprasad Kelam } 307ce7a6c31SHariprasad Kelam 308ce7a6c31SHariprasad Kelam int rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat) 309ce7a6c31SHariprasad Kelam { 310ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 311ce7a6c31SHariprasad Kelam u64 val_lo, val_hi; 312ce7a6c31SHariprasad Kelam 313ce7a6c31SHariprasad Kelam if (!rpm || lmac_id >= rpm->lmac_count) 314ce7a6c31SHariprasad Kelam return -ENODEV; 315ce7a6c31SHariprasad Kelam 316ce7a6c31SHariprasad Kelam mutex_lock(&rpm->lock); 317ce7a6c31SHariprasad Kelam 318ce7a6c31SHariprasad Kelam /* Update idx to point per lmac Tx statistics page */ 319ce7a6c31SHariprasad Kelam idx += lmac_id * rpm->mac_ops->tx_stats_cnt; 320ce7a6c31SHariprasad Kelam 321ce7a6c31SHariprasad Kelam val_lo = rpm_read(rpm, 0, RPMX_MTI_STAT_TX_STAT_PAGES_COUNTERX + 322ce7a6c31SHariprasad Kelam (idx * 8)); 323ce7a6c31SHariprasad Kelam val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 324ce7a6c31SHariprasad Kelam 325ce7a6c31SHariprasad Kelam *tx_stat = (val_hi << 32 | val_lo); 326ce7a6c31SHariprasad Kelam 327ce7a6c31SHariprasad Kelam mutex_unlock(&rpm->lock); 328ce7a6c31SHariprasad Kelam return 0; 329ce7a6c31SHariprasad Kelam } 3303ad3f8f9SHariprasad Kelam 3313ad3f8f9SHariprasad Kelam u8 rpm_get_lmac_type(void *rpmd, int lmac_id) 3323ad3f8f9SHariprasad Kelam { 3333ad3f8f9SHariprasad Kelam rpm_t *rpm = rpmd; 3343ad3f8f9SHariprasad Kelam u64 req = 0, resp; 3353ad3f8f9SHariprasad Kelam int err; 3363ad3f8f9SHariprasad Kelam 3373ad3f8f9SHariprasad Kelam req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_LINK_STS, req); 3383ad3f8f9SHariprasad Kelam err = cgx_fwi_cmd_generic(req, &resp, rpm, 0); 3393ad3f8f9SHariprasad Kelam if (!err) 3403ad3f8f9SHariprasad Kelam return FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, resp); 3413ad3f8f9SHariprasad Kelam return err; 3423ad3f8f9SHariprasad Kelam } 3433ad3f8f9SHariprasad Kelam 3443ad3f8f9SHariprasad Kelam int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable) 3453ad3f8f9SHariprasad Kelam { 3463ad3f8f9SHariprasad Kelam rpm_t *rpm = rpmd; 3473ad3f8f9SHariprasad Kelam u8 lmac_type; 3483ad3f8f9SHariprasad Kelam u64 cfg; 3493ad3f8f9SHariprasad Kelam 3503ad3f8f9SHariprasad Kelam if (!rpm || lmac_id >= rpm->lmac_count) 3513ad3f8f9SHariprasad Kelam return -ENODEV; 3523ad3f8f9SHariprasad Kelam lmac_type = rpm->mac_ops->get_lmac_type(rpm, lmac_id); 353df66b6ebSGeetha sowjanya 354df66b6ebSGeetha sowjanya if (lmac_type == LMAC_MODE_QSGMII || lmac_type == LMAC_MODE_SGMII) { 355df66b6ebSGeetha sowjanya dev_err(&rpm->pdev->dev, "loopback not supported for LPC mode\n"); 356df66b6ebSGeetha sowjanya return 0; 357df66b6ebSGeetha sowjanya } 358df66b6ebSGeetha sowjanya 3593ad3f8f9SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1); 3603ad3f8f9SHariprasad Kelam 3613ad3f8f9SHariprasad Kelam if (enable) 3623ad3f8f9SHariprasad Kelam cfg |= RPMX_MTI_PCS_LBK; 3633ad3f8f9SHariprasad Kelam else 3643ad3f8f9SHariprasad Kelam cfg &= ~RPMX_MTI_PCS_LBK; 3653ad3f8f9SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1, cfg); 3663ad3f8f9SHariprasad Kelam 3673ad3f8f9SHariprasad Kelam return 0; 3683ad3f8f9SHariprasad Kelam } 369d1489208SHariprasad Kelam 370d1489208SHariprasad Kelam void rpm_lmac_ptp_config(void *rpmd, int lmac_id, bool enable) 371d1489208SHariprasad Kelam { 372d1489208SHariprasad Kelam rpm_t *rpm = rpmd; 373d1489208SHariprasad Kelam u64 cfg; 374d1489208SHariprasad Kelam 375d1489208SHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 376d1489208SHariprasad Kelam return; 377d1489208SHariprasad Kelam 378d1489208SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_CFG); 379d1489208SHariprasad Kelam if (enable) 380d1489208SHariprasad Kelam cfg |= RPMX_RX_TS_PREPEND; 381d1489208SHariprasad Kelam else 382d1489208SHariprasad Kelam cfg &= ~RPMX_RX_TS_PREPEND; 383d1489208SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_CMRX_CFG, cfg); 384d1489208SHariprasad Kelam } 3851121f6b0SSunil Kumar Kori 3861121f6b0SSunil Kumar Kori int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 pfc_en) 3871121f6b0SSunil Kumar Kori { 3881121f6b0SSunil Kumar Kori rpm_t *rpm = rpmd; 3891121f6b0SSunil Kumar Kori u64 cfg; 3901121f6b0SSunil Kumar Kori 3911121f6b0SSunil Kumar Kori if (!is_lmac_valid(rpm, lmac_id)) 3921121f6b0SSunil Kumar Kori return -ENODEV; 3931121f6b0SSunil Kumar Kori 3941121f6b0SSunil Kumar Kori /* reset PFC class quanta and threshold */ 3951121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false); 3961121f6b0SSunil Kumar Kori 3971121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 3981121f6b0SSunil Kumar Kori 3991121f6b0SSunil Kumar Kori if (rx_pause) { 4001121f6b0SSunil Kumar Kori cfg &= ~(RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | 4011121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE | 4021121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD); 4031121f6b0SSunil Kumar Kori } else { 4041121f6b0SSunil Kumar Kori cfg |= (RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | 4051121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE | 4061121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD); 4071121f6b0SSunil Kumar Kori } 4081121f6b0SSunil Kumar Kori 4091121f6b0SSunil Kumar Kori if (tx_pause) { 4101121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, pfc_en, true); 4111121f6b0SSunil Kumar Kori cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 4121121f6b0SSunil Kumar Kori } else { 4131121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xfff, false); 4141121f6b0SSunil Kumar Kori cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 4151121f6b0SSunil Kumar Kori } 4161121f6b0SSunil Kumar Kori 4171121f6b0SSunil Kumar Kori if (!rx_pause && !tx_pause) 4181121f6b0SSunil Kumar Kori cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; 4191121f6b0SSunil Kumar Kori else 4201121f6b0SSunil Kumar Kori cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; 4211121f6b0SSunil Kumar Kori 4221121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 4231121f6b0SSunil Kumar Kori 4241121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL); 4251121f6b0SSunil Kumar Kori cfg = FIELD_SET(RPM_PFC_CLASS_MASK, pfc_en, cfg); 4261121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL, cfg); 4271121f6b0SSunil Kumar Kori 4281121f6b0SSunil Kumar Kori return 0; 4291121f6b0SSunil Kumar Kori } 430*e7400038SHariprasad Kelam 431*e7400038SHariprasad Kelam int rpm_lmac_get_pfc_frm_cfg(void *rpmd, int lmac_id, u8 *tx_pause, u8 *rx_pause) 432*e7400038SHariprasad Kelam { 433*e7400038SHariprasad Kelam rpm_t *rpm = rpmd; 434*e7400038SHariprasad Kelam u64 cfg; 435*e7400038SHariprasad Kelam 436*e7400038SHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 437*e7400038SHariprasad Kelam return -ENODEV; 438*e7400038SHariprasad Kelam 439*e7400038SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 440*e7400038SHariprasad Kelam if (cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE) { 441*e7400038SHariprasad Kelam *rx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE); 442*e7400038SHariprasad Kelam *tx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE); 443*e7400038SHariprasad Kelam } 444*e7400038SHariprasad Kelam 445*e7400038SHariprasad Kelam return 0; 446*e7400038SHariprasad Kelam } 447