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, 23b9d0fedcSHariprasad Kelam .dmac_filter_count = 32, 2491c6945eSHariprasad Kelam .get_nr_lmacs = rpm_get_nr_lmacs, 253ad3f8f9SHariprasad Kelam .get_lmac_type = rpm_get_lmac_type, 26459f326eSSunil Goutham .lmac_fifo_len = rpm_get_lmac_fifo_len, 273ad3f8f9SHariprasad Kelam .mac_lmac_intl_lbk = rpm_lmac_internal_loopback, 28ce7a6c31SHariprasad Kelam .mac_get_rx_stats = rpm_get_rx_stats, 29ce7a6c31SHariprasad Kelam .mac_get_tx_stats = rpm_get_tx_stats, 3084ad3642SHariprasad Kelam .get_fec_stats = rpm_get_fec_stats, 311845ada4SRakesh Babu .mac_enadis_rx_pause_fwding = rpm_lmac_enadis_rx_pause_fwding, 321845ada4SRakesh Babu .mac_get_pause_frm_status = rpm_lmac_get_pause_frm_status, 331845ada4SRakesh Babu .mac_enadis_pause_frm = rpm_lmac_enadis_pause_frm, 341845ada4SRakesh Babu .mac_pause_frm_config = rpm_lmac_pause_frm_config, 35d1489208SHariprasad Kelam .mac_enadis_ptp_config = rpm_lmac_ptp_config, 36fae80edeSGeetha sowjanya .mac_rx_tx_enable = rpm_lmac_rx_tx_enable, 37fae80edeSGeetha sowjanya .mac_tx_enable = rpm_lmac_tx_enable, 381121f6b0SSunil Kumar Kori .pfc_config = rpm_lmac_pfc_config, 39e7400038SHariprasad Kelam .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg, 40*2e3e94c2SHariprasad Kelam .mac_reset = rpm_lmac_reset, 4191c6945eSHariprasad Kelam }; 4291c6945eSHariprasad Kelam 43b9d0fedcSHariprasad Kelam static struct mac_ops rpm2_mac_ops = { 44b9d0fedcSHariprasad Kelam .name = "rpm", 45b9d0fedcSHariprasad Kelam .csr_offset = RPM2_CSR_OFFSET, 46b9d0fedcSHariprasad Kelam .lmac_offset = 20, 47b9d0fedcSHariprasad Kelam .int_register = RPM2_CMRX_SW_INT, 48b9d0fedcSHariprasad Kelam .int_set_reg = RPM2_CMRX_SW_INT_ENA_W1S, 49b9d0fedcSHariprasad Kelam .irq_offset = 1, 50b9d0fedcSHariprasad Kelam .int_ena_bit = BIT_ULL(0), 514c5a331cSHariprasad Kelam .lmac_fwi = RPM2_LMAC_FWI, 52b9d0fedcSHariprasad Kelam .non_contiguous_serdes_lane = true, 53b9d0fedcSHariprasad Kelam .rx_stats_cnt = 43, 54b9d0fedcSHariprasad Kelam .tx_stats_cnt = 34, 55b9d0fedcSHariprasad Kelam .dmac_filter_count = 64, 56b9d0fedcSHariprasad Kelam .get_nr_lmacs = rpm2_get_nr_lmacs, 57b9d0fedcSHariprasad Kelam .get_lmac_type = rpm_get_lmac_type, 58b9d0fedcSHariprasad Kelam .lmac_fifo_len = rpm2_get_lmac_fifo_len, 59b9d0fedcSHariprasad Kelam .mac_lmac_intl_lbk = rpm_lmac_internal_loopback, 60b9d0fedcSHariprasad Kelam .mac_get_rx_stats = rpm_get_rx_stats, 61b9d0fedcSHariprasad Kelam .mac_get_tx_stats = rpm_get_tx_stats, 6284ad3642SHariprasad Kelam .get_fec_stats = rpm_get_fec_stats, 63b9d0fedcSHariprasad Kelam .mac_enadis_rx_pause_fwding = rpm_lmac_enadis_rx_pause_fwding, 64b9d0fedcSHariprasad Kelam .mac_get_pause_frm_status = rpm_lmac_get_pause_frm_status, 65b9d0fedcSHariprasad Kelam .mac_enadis_pause_frm = rpm_lmac_enadis_pause_frm, 66b9d0fedcSHariprasad Kelam .mac_pause_frm_config = rpm_lmac_pause_frm_config, 67b9d0fedcSHariprasad Kelam .mac_enadis_ptp_config = rpm_lmac_ptp_config, 68b9d0fedcSHariprasad Kelam .mac_rx_tx_enable = rpm_lmac_rx_tx_enable, 69b9d0fedcSHariprasad Kelam .mac_tx_enable = rpm_lmac_tx_enable, 70b9d0fedcSHariprasad Kelam .pfc_config = rpm_lmac_pfc_config, 71b9d0fedcSHariprasad Kelam .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg, 72*2e3e94c2SHariprasad Kelam .mac_reset = rpm_lmac_reset, 73b9d0fedcSHariprasad Kelam }; 74b9d0fedcSHariprasad Kelam 75b9d0fedcSHariprasad Kelam bool is_dev_rpm2(void *rpmd) 7691c6945eSHariprasad Kelam { 77b9d0fedcSHariprasad Kelam rpm_t *rpm = rpmd; 78b9d0fedcSHariprasad Kelam 79b9d0fedcSHariprasad Kelam return (rpm->pdev->device == PCI_DEVID_CN10KB_RPM); 80b9d0fedcSHariprasad Kelam } 81b9d0fedcSHariprasad Kelam 82b9d0fedcSHariprasad Kelam struct mac_ops *rpm_get_mac_ops(rpm_t *rpm) 83b9d0fedcSHariprasad Kelam { 84b9d0fedcSHariprasad Kelam if (is_dev_rpm2(rpm)) 85b9d0fedcSHariprasad Kelam return &rpm2_mac_ops; 86b9d0fedcSHariprasad Kelam else 8791c6945eSHariprasad Kelam return &rpm_mac_ops; 8891c6945eSHariprasad Kelam } 8991c6945eSHariprasad Kelam 901845ada4SRakesh Babu static void rpm_write(rpm_t *rpm, u64 lmac, u64 offset, u64 val) 911845ada4SRakesh Babu { 921845ada4SRakesh Babu cgx_write(rpm, lmac, offset, val); 931845ada4SRakesh Babu } 941845ada4SRakesh Babu 9591c6945eSHariprasad Kelam static u64 rpm_read(rpm_t *rpm, u64 lmac, u64 offset) 9691c6945eSHariprasad Kelam { 9791c6945eSHariprasad Kelam return cgx_read(rpm, lmac, offset); 9891c6945eSHariprasad Kelam } 9991c6945eSHariprasad Kelam 100b9d0fedcSHariprasad Kelam /* Read HW major version to determine RPM 101b9d0fedcSHariprasad Kelam * MAC type 100/USX 102b9d0fedcSHariprasad Kelam */ 103b9d0fedcSHariprasad Kelam static bool is_mac_rpmusx(void *rpmd) 104b9d0fedcSHariprasad Kelam { 105b9d0fedcSHariprasad Kelam rpm_t *rpm = rpmd; 106b9d0fedcSHariprasad Kelam 107b9d0fedcSHariprasad Kelam return rpm_read(rpm, 0, RPMX_CONST1) & 0x700ULL; 108b9d0fedcSHariprasad Kelam } 109b9d0fedcSHariprasad Kelam 11091c6945eSHariprasad Kelam int rpm_get_nr_lmacs(void *rpmd) 11191c6945eSHariprasad Kelam { 11291c6945eSHariprasad Kelam rpm_t *rpm = rpmd; 11391c6945eSHariprasad Kelam 11491c6945eSHariprasad Kelam return hweight8(rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS) & 0xFULL); 11591c6945eSHariprasad Kelam } 1161845ada4SRakesh Babu 117b9d0fedcSHariprasad Kelam int rpm2_get_nr_lmacs(void *rpmd) 118b9d0fedcSHariprasad Kelam { 119b9d0fedcSHariprasad Kelam rpm_t *rpm = rpmd; 120b9d0fedcSHariprasad Kelam 121b9d0fedcSHariprasad Kelam return hweight8(rpm_read(rpm, 0, RPM2_CMRX_RX_LMACS) & 0xFFULL); 122b9d0fedcSHariprasad Kelam } 123b9d0fedcSHariprasad Kelam 124fae80edeSGeetha sowjanya int rpm_lmac_tx_enable(void *rpmd, int lmac_id, bool enable) 125fae80edeSGeetha sowjanya { 126fae80edeSGeetha sowjanya rpm_t *rpm = rpmd; 127fae80edeSGeetha sowjanya u64 cfg, last; 128fae80edeSGeetha sowjanya 129fae80edeSGeetha sowjanya if (!is_lmac_valid(rpm, lmac_id)) 130fae80edeSGeetha sowjanya return -ENODEV; 131fae80edeSGeetha sowjanya 132fae80edeSGeetha sowjanya cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 133fae80edeSGeetha sowjanya last = cfg; 134fae80edeSGeetha sowjanya if (enable) 135fae80edeSGeetha sowjanya cfg |= RPM_TX_EN; 136fae80edeSGeetha sowjanya else 137fae80edeSGeetha sowjanya cfg &= ~(RPM_TX_EN); 138fae80edeSGeetha sowjanya 139fae80edeSGeetha sowjanya if (cfg != last) 140fae80edeSGeetha sowjanya rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 141fae80edeSGeetha sowjanya return !!(last & RPM_TX_EN); 142fae80edeSGeetha sowjanya } 143fae80edeSGeetha sowjanya 144fae80edeSGeetha sowjanya int rpm_lmac_rx_tx_enable(void *rpmd, int lmac_id, bool enable) 145fae80edeSGeetha sowjanya { 146fae80edeSGeetha sowjanya rpm_t *rpm = rpmd; 147fae80edeSGeetha sowjanya u64 cfg; 148fae80edeSGeetha sowjanya 149fae80edeSGeetha sowjanya if (!is_lmac_valid(rpm, lmac_id)) 150fae80edeSGeetha sowjanya return -ENODEV; 151fae80edeSGeetha sowjanya 152fae80edeSGeetha sowjanya cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 153fae80edeSGeetha sowjanya if (enable) 154fae80edeSGeetha sowjanya cfg |= RPM_RX_EN | RPM_TX_EN; 155fae80edeSGeetha sowjanya else 156fae80edeSGeetha sowjanya cfg &= ~(RPM_RX_EN | RPM_TX_EN); 157fae80edeSGeetha sowjanya rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 158fae80edeSGeetha sowjanya return 0; 159fae80edeSGeetha sowjanya } 160fae80edeSGeetha sowjanya 1611845ada4SRakesh Babu void rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable) 1621845ada4SRakesh Babu { 163ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 164e7400038SHariprasad Kelam struct lmac *lmac; 1651845ada4SRakesh Babu u64 cfg; 1661845ada4SRakesh Babu 1671845ada4SRakesh Babu if (!rpm) 1681845ada4SRakesh Babu return; 1691845ada4SRakesh Babu 170e7400038SHariprasad Kelam lmac = lmac_pdata(lmac_id, rpm); 171e7400038SHariprasad Kelam if (!lmac) 172e7400038SHariprasad Kelam return; 173e7400038SHariprasad Kelam 174e7400038SHariprasad Kelam /* Pause frames are not enabled just return */ 175e7400038SHariprasad Kelam if (!bitmap_weight(lmac->rx_fc_pfvf_bmap.bmap, lmac->rx_fc_pfvf_bmap.max)) 176e7400038SHariprasad Kelam return; 177e7400038SHariprasad Kelam 1781845ada4SRakesh Babu if (enable) { 1791845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 1801845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 1811845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 1821845ada4SRakesh Babu } else { 1831845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 1841845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 1851845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 1861845ada4SRakesh Babu } 1871845ada4SRakesh Babu } 1881845ada4SRakesh Babu 1891845ada4SRakesh Babu int rpm_lmac_get_pause_frm_status(void *rpmd, int lmac_id, 1901845ada4SRakesh Babu u8 *tx_pause, u8 *rx_pause) 1911845ada4SRakesh Babu { 1921845ada4SRakesh Babu rpm_t *rpm = rpmd; 1931845ada4SRakesh Babu u64 cfg; 1941845ada4SRakesh Babu 1951845ada4SRakesh Babu if (!is_lmac_valid(rpm, lmac_id)) 1961845ada4SRakesh Babu return -ENODEV; 1971845ada4SRakesh Babu 1981845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 199e7400038SHariprasad Kelam if (!(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE)) { 2001845ada4SRakesh Babu *rx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE); 2011845ada4SRakesh Babu *tx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE); 202e7400038SHariprasad Kelam } 203e7400038SHariprasad Kelam 2041845ada4SRakesh Babu return 0; 2051845ada4SRakesh Babu } 2061845ada4SRakesh Babu 2075f7dc7d4SHariprasad Kelam static void rpm_cfg_pfc_quanta_thresh(rpm_t *rpm, int lmac_id, 2085f7dc7d4SHariprasad Kelam unsigned long pfc_en, 2091121f6b0SSunil Kumar Kori bool enable) 2101121f6b0SSunil Kumar Kori { 2111121f6b0SSunil Kumar Kori u64 quanta_offset = 0, quanta_thresh = 0, cfg; 2121121f6b0SSunil Kumar Kori int i, shift; 2131121f6b0SSunil Kumar Kori 2141121f6b0SSunil Kumar Kori /* Set pause time and interval */ 2155f7dc7d4SHariprasad Kelam for_each_set_bit(i, &pfc_en, 16) { 2161121f6b0SSunil Kumar Kori switch (i) { 2171121f6b0SSunil Kumar Kori case 0: 2181121f6b0SSunil Kumar Kori case 1: 2191121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA; 2201121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL01_QUANTA_THRESH; 2211121f6b0SSunil Kumar Kori break; 2221121f6b0SSunil Kumar Kori case 2: 2231121f6b0SSunil Kumar Kori case 3: 2241121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL23_PAUSE_QUANTA; 2251121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL23_QUANTA_THRESH; 2261121f6b0SSunil Kumar Kori break; 2271121f6b0SSunil Kumar Kori case 4: 2281121f6b0SSunil Kumar Kori case 5: 2291121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL45_PAUSE_QUANTA; 2301121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL45_QUANTA_THRESH; 2311121f6b0SSunil Kumar Kori break; 2321121f6b0SSunil Kumar Kori case 6: 2331121f6b0SSunil Kumar Kori case 7: 2341121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL67_PAUSE_QUANTA; 2351121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL67_QUANTA_THRESH; 2361121f6b0SSunil Kumar Kori break; 2371121f6b0SSunil Kumar Kori case 8: 2381121f6b0SSunil Kumar Kori case 9: 2391121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA; 2401121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL89_QUANTA_THRESH; 2411121f6b0SSunil Kumar Kori break; 2421121f6b0SSunil Kumar Kori case 10: 2431121f6b0SSunil Kumar Kori case 11: 2441121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1011_PAUSE_QUANTA; 2451121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1011_QUANTA_THRESH; 2461121f6b0SSunil Kumar Kori break; 2471121f6b0SSunil Kumar Kori case 12: 2481121f6b0SSunil Kumar Kori case 13: 2491121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1213_PAUSE_QUANTA; 2501121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1213_QUANTA_THRESH; 2511121f6b0SSunil Kumar Kori break; 2521121f6b0SSunil Kumar Kori case 14: 2531121f6b0SSunil Kumar Kori case 15: 2541121f6b0SSunil Kumar Kori quanta_offset = RPMX_MTI_MAC100X_CL1415_PAUSE_QUANTA; 2551121f6b0SSunil Kumar Kori quanta_thresh = RPMX_MTI_MAC100X_CL1415_QUANTA_THRESH; 2561121f6b0SSunil Kumar Kori break; 2571121f6b0SSunil Kumar Kori } 2581121f6b0SSunil Kumar Kori 2591121f6b0SSunil Kumar Kori if (!quanta_offset || !quanta_thresh) 2601121f6b0SSunil Kumar Kori continue; 2611121f6b0SSunil Kumar Kori 2621121f6b0SSunil Kumar Kori shift = (i % 2) ? 1 : 0; 2631121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, quanta_offset); 2641121f6b0SSunil Kumar Kori if (enable) { 2651121f6b0SSunil Kumar Kori cfg |= ((u64)RPM_DEFAULT_PAUSE_TIME << shift * 16); 2661121f6b0SSunil Kumar Kori } else { 2671121f6b0SSunil Kumar Kori if (!shift) 2681121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(15, 0); 2691121f6b0SSunil Kumar Kori else 2701121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(31, 16); 2711121f6b0SSunil Kumar Kori } 2721121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, quanta_offset, cfg); 2731121f6b0SSunil Kumar Kori 2741121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, quanta_thresh); 2751121f6b0SSunil Kumar Kori if (enable) { 2761121f6b0SSunil Kumar Kori cfg |= ((u64)(RPM_DEFAULT_PAUSE_TIME / 2) << shift * 16); 2771121f6b0SSunil Kumar Kori } else { 2781121f6b0SSunil Kumar Kori if (!shift) 2791121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(15, 0); 2801121f6b0SSunil Kumar Kori else 2811121f6b0SSunil Kumar Kori cfg &= ~GENMASK_ULL(31, 16); 2821121f6b0SSunil Kumar Kori } 2831121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, quanta_thresh, cfg); 2841121f6b0SSunil Kumar Kori } 2851121f6b0SSunil Kumar Kori } 2861121f6b0SSunil Kumar Kori 287b9d0fedcSHariprasad Kelam static void rpm2_lmac_cfg_bp(rpm_t *rpm, int lmac_id, u8 tx_pause, u8 rx_pause) 288b9d0fedcSHariprasad Kelam { 289b9d0fedcSHariprasad Kelam u64 cfg; 290b9d0fedcSHariprasad Kelam 291b9d0fedcSHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPM2_CMR_RX_OVR_BP); 292b9d0fedcSHariprasad Kelam if (tx_pause) { 293b9d0fedcSHariprasad Kelam /* Configure CL0 Pause Quanta & threshold 294b9d0fedcSHariprasad Kelam * for 802.3X frames 295b9d0fedcSHariprasad Kelam */ 296b9d0fedcSHariprasad Kelam rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 1, true); 297b9d0fedcSHariprasad Kelam cfg &= ~RPM2_CMR_RX_OVR_BP_EN; 298b9d0fedcSHariprasad Kelam } else { 299b9d0fedcSHariprasad Kelam /* Disable all Pause Quanta & threshold values */ 300b9d0fedcSHariprasad Kelam rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false); 301b9d0fedcSHariprasad Kelam cfg |= RPM2_CMR_RX_OVR_BP_EN; 302b9d0fedcSHariprasad Kelam cfg &= ~RPM2_CMR_RX_OVR_BP_BP; 303b9d0fedcSHariprasad Kelam } 304b9d0fedcSHariprasad Kelam rpm_write(rpm, lmac_id, RPM2_CMR_RX_OVR_BP, cfg); 305b9d0fedcSHariprasad Kelam } 306b9d0fedcSHariprasad Kelam 307b9d0fedcSHariprasad Kelam static void rpm_lmac_cfg_bp(rpm_t *rpm, int lmac_id, u8 tx_pause, u8 rx_pause) 308b9d0fedcSHariprasad Kelam { 309b9d0fedcSHariprasad Kelam u64 cfg; 310b9d0fedcSHariprasad Kelam 311b9d0fedcSHariprasad Kelam cfg = rpm_read(rpm, 0, RPMX_CMR_RX_OVR_BP); 312b9d0fedcSHariprasad Kelam if (tx_pause) { 313b9d0fedcSHariprasad Kelam /* Configure CL0 Pause Quanta & threshold for 314b9d0fedcSHariprasad Kelam * 802.3X frames 315b9d0fedcSHariprasad Kelam */ 316b9d0fedcSHariprasad Kelam rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 1, true); 317b9d0fedcSHariprasad Kelam cfg &= ~RPMX_CMR_RX_OVR_BP_EN(lmac_id); 318b9d0fedcSHariprasad Kelam } else { 319b9d0fedcSHariprasad Kelam /* Disable all Pause Quanta & threshold values */ 320b9d0fedcSHariprasad Kelam rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false); 321b9d0fedcSHariprasad Kelam cfg |= RPMX_CMR_RX_OVR_BP_EN(lmac_id); 322b9d0fedcSHariprasad Kelam cfg &= ~RPMX_CMR_RX_OVR_BP_BP(lmac_id); 323b9d0fedcSHariprasad Kelam } 324b9d0fedcSHariprasad Kelam rpm_write(rpm, 0, RPMX_CMR_RX_OVR_BP, cfg); 325b9d0fedcSHariprasad Kelam } 326b9d0fedcSHariprasad Kelam 3271845ada4SRakesh Babu int rpm_lmac_enadis_pause_frm(void *rpmd, int lmac_id, u8 tx_pause, 3281845ada4SRakesh Babu u8 rx_pause) 3291845ada4SRakesh Babu { 3301845ada4SRakesh Babu rpm_t *rpm = rpmd; 3311845ada4SRakesh Babu u64 cfg; 3321845ada4SRakesh Babu 3331845ada4SRakesh Babu if (!is_lmac_valid(rpm, lmac_id)) 3341845ada4SRakesh Babu return -ENODEV; 3351845ada4SRakesh Babu 3361845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 3371845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 3381845ada4SRakesh Babu cfg |= rx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 3391845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 3401845ada4SRakesh Babu cfg |= rx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 3411845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 3421845ada4SRakesh Babu 3431845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 3441845ada4SRakesh Babu cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 3451845ada4SRakesh Babu cfg |= tx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 3461845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 3471845ada4SRakesh Babu 348b9d0fedcSHariprasad Kelam if (is_dev_rpm2(rpm)) 349b9d0fedcSHariprasad Kelam rpm2_lmac_cfg_bp(rpm, lmac_id, tx_pause, rx_pause); 350b9d0fedcSHariprasad Kelam else 351b9d0fedcSHariprasad Kelam rpm_lmac_cfg_bp(rpm, lmac_id, tx_pause, rx_pause); 352b9d0fedcSHariprasad Kelam 3531845ada4SRakesh Babu return 0; 3541845ada4SRakesh Babu } 3551845ada4SRakesh Babu 3561845ada4SRakesh Babu void rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable) 3571845ada4SRakesh Babu { 3581845ada4SRakesh Babu rpm_t *rpm = rpmd; 3591845ada4SRakesh Babu u64 cfg; 3601845ada4SRakesh Babu 3611845ada4SRakesh Babu /* ALL pause frames received are completely ignored */ 3621845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 3631845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 3641845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 3651845ada4SRakesh Babu 3661845ada4SRakesh Babu /* Disable forward pause to TX block */ 3671845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 3681845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 3691845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 3701845ada4SRakesh Babu 3711845ada4SRakesh Babu /* Disable pause frames transmission */ 3721845ada4SRakesh Babu cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 3731845ada4SRakesh Babu cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 3741845ada4SRakesh Babu rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 3758e151457SHariprasad Kelam 376b9d0fedcSHariprasad Kelam /* Enable channel mask for all LMACS */ 377b9d0fedcSHariprasad Kelam if (is_dev_rpm2(rpm)) 378b9d0fedcSHariprasad Kelam rpm_write(rpm, lmac_id, RPM2_CMR_CHAN_MSK_OR, 0xffff); 379b9d0fedcSHariprasad Kelam else 380b9d0fedcSHariprasad Kelam rpm_write(rpm, 0, RPMX_CMR_CHAN_MSK_OR, ~0ULL); 381b9d0fedcSHariprasad Kelam 3828e151457SHariprasad Kelam /* Disable all PFC classes */ 3838e151457SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL); 3848e151457SHariprasad Kelam cfg = FIELD_SET(RPM_PFC_CLASS_MASK, 0, cfg); 3858e151457SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL, cfg); 3861845ada4SRakesh Babu } 387ce7a6c31SHariprasad Kelam 388ce7a6c31SHariprasad Kelam int rpm_get_rx_stats(void *rpmd, int lmac_id, int idx, u64 *rx_stat) 389ce7a6c31SHariprasad Kelam { 390ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 391ce7a6c31SHariprasad Kelam u64 val_lo, val_hi; 392ce7a6c31SHariprasad Kelam 393b9d0fedcSHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 394ce7a6c31SHariprasad Kelam return -ENODEV; 395ce7a6c31SHariprasad Kelam 396ce7a6c31SHariprasad Kelam mutex_lock(&rpm->lock); 397ce7a6c31SHariprasad Kelam 398ce7a6c31SHariprasad Kelam /* Update idx to point per lmac Rx statistics page */ 399ce7a6c31SHariprasad Kelam idx += lmac_id * rpm->mac_ops->rx_stats_cnt; 400ce7a6c31SHariprasad Kelam 401ce7a6c31SHariprasad Kelam /* Read lower 32 bits of counter */ 402ce7a6c31SHariprasad Kelam val_lo = rpm_read(rpm, 0, RPMX_MTI_STAT_RX_STAT_PAGES_COUNTERX + 403ce7a6c31SHariprasad Kelam (idx * 8)); 404ce7a6c31SHariprasad Kelam 405ce7a6c31SHariprasad Kelam /* upon read of lower 32 bits, higher 32 bits are written 406ce7a6c31SHariprasad Kelam * to RPMX_MTI_STAT_DATA_HI_CDC 407ce7a6c31SHariprasad Kelam */ 408ce7a6c31SHariprasad Kelam val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 409ce7a6c31SHariprasad Kelam 410ce7a6c31SHariprasad Kelam *rx_stat = (val_hi << 32 | val_lo); 411ce7a6c31SHariprasad Kelam 412ce7a6c31SHariprasad Kelam mutex_unlock(&rpm->lock); 413ce7a6c31SHariprasad Kelam return 0; 414ce7a6c31SHariprasad Kelam } 415ce7a6c31SHariprasad Kelam 416ce7a6c31SHariprasad Kelam int rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat) 417ce7a6c31SHariprasad Kelam { 418ce7a6c31SHariprasad Kelam rpm_t *rpm = rpmd; 419ce7a6c31SHariprasad Kelam u64 val_lo, val_hi; 420ce7a6c31SHariprasad Kelam 421b9d0fedcSHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 422ce7a6c31SHariprasad Kelam return -ENODEV; 423ce7a6c31SHariprasad Kelam 424ce7a6c31SHariprasad Kelam mutex_lock(&rpm->lock); 425ce7a6c31SHariprasad Kelam 426ce7a6c31SHariprasad Kelam /* Update idx to point per lmac Tx statistics page */ 427ce7a6c31SHariprasad Kelam idx += lmac_id * rpm->mac_ops->tx_stats_cnt; 428ce7a6c31SHariprasad Kelam 429ce7a6c31SHariprasad Kelam val_lo = rpm_read(rpm, 0, RPMX_MTI_STAT_TX_STAT_PAGES_COUNTERX + 430ce7a6c31SHariprasad Kelam (idx * 8)); 431ce7a6c31SHariprasad Kelam val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 432ce7a6c31SHariprasad Kelam 433ce7a6c31SHariprasad Kelam *tx_stat = (val_hi << 32 | val_lo); 434ce7a6c31SHariprasad Kelam 435ce7a6c31SHariprasad Kelam mutex_unlock(&rpm->lock); 436ce7a6c31SHariprasad Kelam return 0; 437ce7a6c31SHariprasad Kelam } 4383ad3f8f9SHariprasad Kelam 4393ad3f8f9SHariprasad Kelam u8 rpm_get_lmac_type(void *rpmd, int lmac_id) 4403ad3f8f9SHariprasad Kelam { 4413ad3f8f9SHariprasad Kelam rpm_t *rpm = rpmd; 4423ad3f8f9SHariprasad Kelam u64 req = 0, resp; 4433ad3f8f9SHariprasad Kelam int err; 4443ad3f8f9SHariprasad Kelam 4453ad3f8f9SHariprasad Kelam req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_LINK_STS, req); 4463ad3f8f9SHariprasad Kelam err = cgx_fwi_cmd_generic(req, &resp, rpm, 0); 4473ad3f8f9SHariprasad Kelam if (!err) 4483ad3f8f9SHariprasad Kelam return FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, resp); 4493ad3f8f9SHariprasad Kelam return err; 4503ad3f8f9SHariprasad Kelam } 4513ad3f8f9SHariprasad Kelam 452459f326eSSunil Goutham u32 rpm_get_lmac_fifo_len(void *rpmd, int lmac_id) 453459f326eSSunil Goutham { 454459f326eSSunil Goutham rpm_t *rpm = rpmd; 455459f326eSSunil Goutham u64 hi_perf_lmac; 456459f326eSSunil Goutham u8 num_lmacs; 457459f326eSSunil Goutham u32 fifo_len; 458459f326eSSunil Goutham 459459f326eSSunil Goutham fifo_len = rpm->mac_ops->fifo_len; 460459f326eSSunil Goutham num_lmacs = rpm->mac_ops->get_nr_lmacs(rpm); 461459f326eSSunil Goutham 462459f326eSSunil Goutham switch (num_lmacs) { 463459f326eSSunil Goutham case 1: 464459f326eSSunil Goutham return fifo_len; 465459f326eSSunil Goutham case 2: 466459f326eSSunil Goutham return fifo_len / 2; 467459f326eSSunil Goutham case 3: 468459f326eSSunil Goutham /* LMAC marked as hi_perf gets half of the FIFO and rest 1/4th */ 469459f326eSSunil Goutham hi_perf_lmac = rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS); 470459f326eSSunil Goutham hi_perf_lmac = (hi_perf_lmac >> 4) & 0x3ULL; 471459f326eSSunil Goutham if (lmac_id == hi_perf_lmac) 472459f326eSSunil Goutham return fifo_len / 2; 473459f326eSSunil Goutham return fifo_len / 4; 474459f326eSSunil Goutham case 4: 475459f326eSSunil Goutham default: 476459f326eSSunil Goutham return fifo_len / 4; 477459f326eSSunil Goutham } 478459f326eSSunil Goutham return 0; 479459f326eSSunil Goutham } 480459f326eSSunil Goutham 481b9d0fedcSHariprasad Kelam static int rpmusx_lmac_internal_loopback(rpm_t *rpm, int lmac_id, bool enable) 482b9d0fedcSHariprasad Kelam { 483b9d0fedcSHariprasad Kelam u64 cfg; 484b9d0fedcSHariprasad Kelam 485b9d0fedcSHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPM2_USX_PCSX_CONTROL1); 486b9d0fedcSHariprasad Kelam 487b9d0fedcSHariprasad Kelam if (enable) 488b9d0fedcSHariprasad Kelam cfg |= RPM2_USX_PCS_LBK; 489b9d0fedcSHariprasad Kelam else 490b9d0fedcSHariprasad Kelam cfg &= ~RPM2_USX_PCS_LBK; 491b9d0fedcSHariprasad Kelam rpm_write(rpm, lmac_id, RPM2_USX_PCSX_CONTROL1, cfg); 492b9d0fedcSHariprasad Kelam 493b9d0fedcSHariprasad Kelam return 0; 494b9d0fedcSHariprasad Kelam } 495b9d0fedcSHariprasad Kelam 496b9d0fedcSHariprasad Kelam u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id) 497b9d0fedcSHariprasad Kelam { 498b9d0fedcSHariprasad Kelam u64 hi_perf_lmac, lmac_info; 499b9d0fedcSHariprasad Kelam rpm_t *rpm = rpmd; 500b9d0fedcSHariprasad Kelam u8 num_lmacs; 501b9d0fedcSHariprasad Kelam u32 fifo_len; 502b9d0fedcSHariprasad Kelam 503b9d0fedcSHariprasad Kelam lmac_info = rpm_read(rpm, 0, RPM2_CMRX_RX_LMACS); 504b9d0fedcSHariprasad Kelam /* LMACs are divided into two groups and each group 505b9d0fedcSHariprasad Kelam * gets half of the FIFO 506b9d0fedcSHariprasad Kelam * Group0 lmac_id range {0..3} 507b9d0fedcSHariprasad Kelam * Group1 lmac_id range {4..7} 508b9d0fedcSHariprasad Kelam */ 509b9d0fedcSHariprasad Kelam fifo_len = rpm->mac_ops->fifo_len / 2; 510b9d0fedcSHariprasad Kelam 511b9d0fedcSHariprasad Kelam if (lmac_id < 4) { 512b9d0fedcSHariprasad Kelam num_lmacs = hweight8(lmac_info & 0xF); 513b9d0fedcSHariprasad Kelam hi_perf_lmac = (lmac_info >> 8) & 0x3ULL; 514b9d0fedcSHariprasad Kelam } else { 515b9d0fedcSHariprasad Kelam num_lmacs = hweight8(lmac_info & 0xF0); 516b9d0fedcSHariprasad Kelam hi_perf_lmac = (lmac_info >> 10) & 0x3ULL; 517b9d0fedcSHariprasad Kelam hi_perf_lmac += 4; 518b9d0fedcSHariprasad Kelam } 519b9d0fedcSHariprasad Kelam 520b9d0fedcSHariprasad Kelam switch (num_lmacs) { 521b9d0fedcSHariprasad Kelam case 1: 522b9d0fedcSHariprasad Kelam return fifo_len; 523b9d0fedcSHariprasad Kelam case 2: 524b9d0fedcSHariprasad Kelam return fifo_len / 2; 525b9d0fedcSHariprasad Kelam case 3: 526b9d0fedcSHariprasad Kelam /* LMAC marked as hi_perf gets half of the FIFO 527b9d0fedcSHariprasad Kelam * and rest 1/4th 528b9d0fedcSHariprasad Kelam */ 529b9d0fedcSHariprasad Kelam if (lmac_id == hi_perf_lmac) 530b9d0fedcSHariprasad Kelam return fifo_len / 2; 531b9d0fedcSHariprasad Kelam return fifo_len / 4; 532b9d0fedcSHariprasad Kelam case 4: 533b9d0fedcSHariprasad Kelam default: 534b9d0fedcSHariprasad Kelam return fifo_len / 4; 535b9d0fedcSHariprasad Kelam } 536b9d0fedcSHariprasad Kelam return 0; 537b9d0fedcSHariprasad Kelam } 538b9d0fedcSHariprasad Kelam 5393ad3f8f9SHariprasad Kelam int rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable) 5403ad3f8f9SHariprasad Kelam { 5413ad3f8f9SHariprasad Kelam rpm_t *rpm = rpmd; 542*2e3e94c2SHariprasad Kelam struct lmac *lmac; 5433ad3f8f9SHariprasad Kelam u64 cfg; 5443ad3f8f9SHariprasad Kelam 545b9d0fedcSHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 5463ad3f8f9SHariprasad Kelam return -ENODEV; 547df66b6ebSGeetha sowjanya 548*2e3e94c2SHariprasad Kelam lmac = lmac_pdata(lmac_id, rpm); 549*2e3e94c2SHariprasad Kelam if (lmac->lmac_type == LMAC_MODE_QSGMII || 550*2e3e94c2SHariprasad Kelam lmac->lmac_type == LMAC_MODE_SGMII) { 551df66b6ebSGeetha sowjanya dev_err(&rpm->pdev->dev, "loopback not supported for LPC mode\n"); 552df66b6ebSGeetha sowjanya return 0; 553df66b6ebSGeetha sowjanya } 554df66b6ebSGeetha sowjanya 555b9d0fedcSHariprasad Kelam if (is_dev_rpm2(rpm) && is_mac_rpmusx(rpm)) 556b9d0fedcSHariprasad Kelam return rpmusx_lmac_internal_loopback(rpm, lmac_id, enable); 557b9d0fedcSHariprasad Kelam 5583ad3f8f9SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1); 5593ad3f8f9SHariprasad Kelam 5603ad3f8f9SHariprasad Kelam if (enable) 5613ad3f8f9SHariprasad Kelam cfg |= RPMX_MTI_PCS_LBK; 5623ad3f8f9SHariprasad Kelam else 5633ad3f8f9SHariprasad Kelam cfg &= ~RPMX_MTI_PCS_LBK; 5643ad3f8f9SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1, cfg); 5653ad3f8f9SHariprasad Kelam 5663ad3f8f9SHariprasad Kelam return 0; 5673ad3f8f9SHariprasad Kelam } 568d1489208SHariprasad Kelam 569d1489208SHariprasad Kelam void rpm_lmac_ptp_config(void *rpmd, int lmac_id, bool enable) 570d1489208SHariprasad Kelam { 571d1489208SHariprasad Kelam rpm_t *rpm = rpmd; 572d1489208SHariprasad Kelam u64 cfg; 573d1489208SHariprasad Kelam 574d1489208SHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 575d1489208SHariprasad Kelam return; 576d1489208SHariprasad Kelam 577d1489208SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_CFG); 5782958d17aSHariprasad Kelam if (enable) { 579d1489208SHariprasad Kelam cfg |= RPMX_RX_TS_PREPEND; 5802958d17aSHariprasad Kelam cfg |= RPMX_TX_PTP_1S_SUPPORT; 5812958d17aSHariprasad Kelam } else { 582d1489208SHariprasad Kelam cfg &= ~RPMX_RX_TS_PREPEND; 5832958d17aSHariprasad Kelam cfg &= ~RPMX_TX_PTP_1S_SUPPORT; 5842958d17aSHariprasad Kelam } 5852958d17aSHariprasad Kelam 586d1489208SHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_CMRX_CFG, cfg); 5872958d17aSHariprasad Kelam 5882958d17aSHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_XIF_MODE); 5892958d17aSHariprasad Kelam 5902958d17aSHariprasad Kelam if (enable) { 5912958d17aSHariprasad Kelam cfg |= RPMX_ONESTEP_ENABLE; 5922958d17aSHariprasad Kelam cfg &= ~RPMX_TS_BINARY_MODE; 5932958d17aSHariprasad Kelam } else { 5942958d17aSHariprasad Kelam cfg &= ~RPMX_ONESTEP_ENABLE; 5952958d17aSHariprasad Kelam } 5962958d17aSHariprasad Kelam 5972958d17aSHariprasad Kelam rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_XIF_MODE, cfg); 598d1489208SHariprasad Kelam } 5991121f6b0SSunil Kumar Kori 6001121f6b0SSunil Kumar Kori int rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 pfc_en) 6011121f6b0SSunil Kumar Kori { 602b9d0fedcSHariprasad Kelam u64 cfg, class_en, pfc_class_mask_cfg; 6031121f6b0SSunil Kumar Kori rpm_t *rpm = rpmd; 6041121f6b0SSunil Kumar Kori 6051121f6b0SSunil Kumar Kori if (!is_lmac_valid(rpm, lmac_id)) 6061121f6b0SSunil Kumar Kori return -ENODEV; 6071121f6b0SSunil Kumar Kori 6081121f6b0SSunil Kumar Kori cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 6098e151457SHariprasad Kelam class_en = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL); 6108e151457SHariprasad Kelam pfc_en |= FIELD_GET(RPM_PFC_CLASS_MASK, class_en); 6111121f6b0SSunil Kumar Kori 6121121f6b0SSunil Kumar Kori if (rx_pause) { 6131121f6b0SSunil Kumar Kori cfg &= ~(RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | 6141121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE | 6151121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD); 6161121f6b0SSunil Kumar Kori } else { 6171121f6b0SSunil Kumar Kori cfg |= (RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | 6181121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE | 6191121f6b0SSunil Kumar Kori RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD); 6201121f6b0SSunil Kumar Kori } 6211121f6b0SSunil Kumar Kori 6221121f6b0SSunil Kumar Kori if (tx_pause) { 6231121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, pfc_en, true); 6241121f6b0SSunil Kumar Kori cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 6258e151457SHariprasad Kelam class_en = FIELD_SET(RPM_PFC_CLASS_MASK, pfc_en, class_en); 6261121f6b0SSunil Kumar Kori } else { 6271121f6b0SSunil Kumar Kori rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xfff, false); 6281121f6b0SSunil Kumar Kori cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 6298e151457SHariprasad Kelam class_en = FIELD_SET(RPM_PFC_CLASS_MASK, 0, class_en); 6301121f6b0SSunil Kumar Kori } 6311121f6b0SSunil Kumar Kori 6321121f6b0SSunil Kumar Kori if (!rx_pause && !tx_pause) 6331121f6b0SSunil Kumar Kori cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; 6341121f6b0SSunil Kumar Kori else 6351121f6b0SSunil Kumar Kori cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; 6361121f6b0SSunil Kumar Kori 6371121f6b0SSunil Kumar Kori rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 6381121f6b0SSunil Kumar Kori 639b9d0fedcSHariprasad Kelam pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL : 640b9d0fedcSHariprasad Kelam RPMX_CMRX_PRT_CBFC_CTL; 641b9d0fedcSHariprasad Kelam 642b9d0fedcSHariprasad Kelam rpm_write(rpm, lmac_id, pfc_class_mask_cfg, class_en); 6431121f6b0SSunil Kumar Kori 6441121f6b0SSunil Kumar Kori return 0; 6451121f6b0SSunil Kumar Kori } 646e7400038SHariprasad Kelam 647e7400038SHariprasad Kelam int rpm_lmac_get_pfc_frm_cfg(void *rpmd, int lmac_id, u8 *tx_pause, u8 *rx_pause) 648e7400038SHariprasad Kelam { 649e7400038SHariprasad Kelam rpm_t *rpm = rpmd; 650e7400038SHariprasad Kelam u64 cfg; 651e7400038SHariprasad Kelam 652e7400038SHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 653e7400038SHariprasad Kelam return -ENODEV; 654e7400038SHariprasad Kelam 655e7400038SHariprasad Kelam cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 656e7400038SHariprasad Kelam if (cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE) { 657e7400038SHariprasad Kelam *rx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE); 658e7400038SHariprasad Kelam *tx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE); 659e7400038SHariprasad Kelam } 660e7400038SHariprasad Kelam 661e7400038SHariprasad Kelam return 0; 662e7400038SHariprasad Kelam } 66384ad3642SHariprasad Kelam 66484ad3642SHariprasad Kelam int rpm_get_fec_stats(void *rpmd, int lmac_id, struct cgx_fec_stats_rsp *rsp) 66584ad3642SHariprasad Kelam { 66684ad3642SHariprasad Kelam u64 val_lo, val_hi; 66784ad3642SHariprasad Kelam rpm_t *rpm = rpmd; 66884ad3642SHariprasad Kelam u64 cfg; 66984ad3642SHariprasad Kelam 67084ad3642SHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 67184ad3642SHariprasad Kelam return -ENODEV; 67284ad3642SHariprasad Kelam 67384ad3642SHariprasad Kelam if (rpm->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_NONE) 67484ad3642SHariprasad Kelam return 0; 67584ad3642SHariprasad Kelam 67684ad3642SHariprasad Kelam if (rpm->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_BASER) { 67784ad3642SHariprasad Kelam val_lo = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_VL0_CCW_LO); 67884ad3642SHariprasad Kelam val_hi = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_CW_HI); 67984ad3642SHariprasad Kelam rsp->fec_corr_blks = (val_hi << 16 | val_lo); 68084ad3642SHariprasad Kelam 68184ad3642SHariprasad Kelam val_lo = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_VL0_NCCW_LO); 68284ad3642SHariprasad Kelam val_hi = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_CW_HI); 68384ad3642SHariprasad Kelam rsp->fec_uncorr_blks = (val_hi << 16 | val_lo); 68484ad3642SHariprasad Kelam 68584ad3642SHariprasad Kelam /* 50G uses 2 Physical serdes lines */ 68684ad3642SHariprasad Kelam if (rpm->lmac_idmap[lmac_id]->link_info.lmac_type_id == 68784ad3642SHariprasad Kelam LMAC_MODE_50G_R) { 68884ad3642SHariprasad Kelam val_lo = rpm_read(rpm, lmac_id, 68984ad3642SHariprasad Kelam RPMX_MTI_FCFECX_VL1_CCW_LO); 69084ad3642SHariprasad Kelam val_hi = rpm_read(rpm, lmac_id, 69184ad3642SHariprasad Kelam RPMX_MTI_FCFECX_CW_HI); 69284ad3642SHariprasad Kelam rsp->fec_corr_blks += (val_hi << 16 | val_lo); 69384ad3642SHariprasad Kelam 69484ad3642SHariprasad Kelam val_lo = rpm_read(rpm, lmac_id, 69584ad3642SHariprasad Kelam RPMX_MTI_FCFECX_VL1_NCCW_LO); 69684ad3642SHariprasad Kelam val_hi = rpm_read(rpm, lmac_id, 69784ad3642SHariprasad Kelam RPMX_MTI_FCFECX_CW_HI); 69884ad3642SHariprasad Kelam rsp->fec_uncorr_blks += (val_hi << 16 | val_lo); 69984ad3642SHariprasad Kelam } 70084ad3642SHariprasad Kelam } else { 70184ad3642SHariprasad Kelam /* enable RS-FEC capture */ 70284ad3642SHariprasad Kelam cfg = rpm_read(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL); 70384ad3642SHariprasad Kelam cfg |= RPMX_RSFEC_RX_CAPTURE | BIT(lmac_id); 70484ad3642SHariprasad Kelam rpm_write(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL, cfg); 70584ad3642SHariprasad Kelam 70684ad3642SHariprasad Kelam val_lo = rpm_read(rpm, 0, 70784ad3642SHariprasad Kelam RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_2); 70884ad3642SHariprasad Kelam val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 70984ad3642SHariprasad Kelam rsp->fec_corr_blks = (val_hi << 32 | val_lo); 71084ad3642SHariprasad Kelam 71184ad3642SHariprasad Kelam val_lo = rpm_read(rpm, 0, 71284ad3642SHariprasad Kelam RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_3); 71384ad3642SHariprasad Kelam val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 71484ad3642SHariprasad Kelam rsp->fec_uncorr_blks = (val_hi << 32 | val_lo); 71584ad3642SHariprasad Kelam } 71684ad3642SHariprasad Kelam 71784ad3642SHariprasad Kelam return 0; 71884ad3642SHariprasad Kelam } 719*2e3e94c2SHariprasad Kelam 720*2e3e94c2SHariprasad Kelam int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr) 721*2e3e94c2SHariprasad Kelam { 722*2e3e94c2SHariprasad Kelam u64 rx_logl_xon, cfg; 723*2e3e94c2SHariprasad Kelam rpm_t *rpm = rpmd; 724*2e3e94c2SHariprasad Kelam 725*2e3e94c2SHariprasad Kelam if (!is_lmac_valid(rpm, lmac_id)) 726*2e3e94c2SHariprasad Kelam return -ENODEV; 727*2e3e94c2SHariprasad Kelam 728*2e3e94c2SHariprasad Kelam /* Resetting PFC related CSRs */ 729*2e3e94c2SHariprasad Kelam rx_logl_xon = is_dev_rpm2(rpm) ? RPM2_CMRX_RX_LOGL_XON : 730*2e3e94c2SHariprasad Kelam RPMX_CMRX_RX_LOGL_XON; 731*2e3e94c2SHariprasad Kelam cfg = 0xff; 732*2e3e94c2SHariprasad Kelam 733*2e3e94c2SHariprasad Kelam rpm_write(rpm, lmac_id, rx_logl_xon, cfg); 734*2e3e94c2SHariprasad Kelam 735*2e3e94c2SHariprasad Kelam if (pf_req_flr) 736*2e3e94c2SHariprasad Kelam rpm_lmac_internal_loopback(rpm, lmac_id, false); 737*2e3e94c2SHariprasad Kelam 738*2e3e94c2SHariprasad Kelam return 0; 739*2e3e94c2SHariprasad Kelam } 740