162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Marvell CN10K RPM driver 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2020 Marvell. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "cgx.h" 962306a36Sopenharmony_ci#include "lmac_common.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cistatic struct mac_ops rpm_mac_ops = { 1262306a36Sopenharmony_ci .name = "rpm", 1362306a36Sopenharmony_ci .csr_offset = 0x4e00, 1462306a36Sopenharmony_ci .lmac_offset = 20, 1562306a36Sopenharmony_ci .int_register = RPMX_CMRX_SW_INT, 1662306a36Sopenharmony_ci .int_set_reg = RPMX_CMRX_SW_INT_ENA_W1S, 1762306a36Sopenharmony_ci .irq_offset = 1, 1862306a36Sopenharmony_ci .int_ena_bit = BIT_ULL(0), 1962306a36Sopenharmony_ci .lmac_fwi = RPM_LMAC_FWI, 2062306a36Sopenharmony_ci .non_contiguous_serdes_lane = true, 2162306a36Sopenharmony_ci .rx_stats_cnt = 43, 2262306a36Sopenharmony_ci .tx_stats_cnt = 34, 2362306a36Sopenharmony_ci .dmac_filter_count = 32, 2462306a36Sopenharmony_ci .get_nr_lmacs = rpm_get_nr_lmacs, 2562306a36Sopenharmony_ci .get_lmac_type = rpm_get_lmac_type, 2662306a36Sopenharmony_ci .lmac_fifo_len = rpm_get_lmac_fifo_len, 2762306a36Sopenharmony_ci .mac_lmac_intl_lbk = rpm_lmac_internal_loopback, 2862306a36Sopenharmony_ci .mac_get_rx_stats = rpm_get_rx_stats, 2962306a36Sopenharmony_ci .mac_get_tx_stats = rpm_get_tx_stats, 3062306a36Sopenharmony_ci .get_fec_stats = rpm_get_fec_stats, 3162306a36Sopenharmony_ci .mac_enadis_rx_pause_fwding = rpm_lmac_enadis_rx_pause_fwding, 3262306a36Sopenharmony_ci .mac_get_pause_frm_status = rpm_lmac_get_pause_frm_status, 3362306a36Sopenharmony_ci .mac_enadis_pause_frm = rpm_lmac_enadis_pause_frm, 3462306a36Sopenharmony_ci .mac_pause_frm_config = rpm_lmac_pause_frm_config, 3562306a36Sopenharmony_ci .mac_enadis_ptp_config = rpm_lmac_ptp_config, 3662306a36Sopenharmony_ci .mac_rx_tx_enable = rpm_lmac_rx_tx_enable, 3762306a36Sopenharmony_ci .mac_tx_enable = rpm_lmac_tx_enable, 3862306a36Sopenharmony_ci .pfc_config = rpm_lmac_pfc_config, 3962306a36Sopenharmony_ci .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg, 4062306a36Sopenharmony_ci .mac_reset = rpm_lmac_reset, 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic struct mac_ops rpm2_mac_ops = { 4462306a36Sopenharmony_ci .name = "rpm", 4562306a36Sopenharmony_ci .csr_offset = RPM2_CSR_OFFSET, 4662306a36Sopenharmony_ci .lmac_offset = 20, 4762306a36Sopenharmony_ci .int_register = RPM2_CMRX_SW_INT, 4862306a36Sopenharmony_ci .int_set_reg = RPM2_CMRX_SW_INT_ENA_W1S, 4962306a36Sopenharmony_ci .irq_offset = 1, 5062306a36Sopenharmony_ci .int_ena_bit = BIT_ULL(0), 5162306a36Sopenharmony_ci .lmac_fwi = RPM2_LMAC_FWI, 5262306a36Sopenharmony_ci .non_contiguous_serdes_lane = true, 5362306a36Sopenharmony_ci .rx_stats_cnt = 43, 5462306a36Sopenharmony_ci .tx_stats_cnt = 34, 5562306a36Sopenharmony_ci .dmac_filter_count = 64, 5662306a36Sopenharmony_ci .get_nr_lmacs = rpm2_get_nr_lmacs, 5762306a36Sopenharmony_ci .get_lmac_type = rpm_get_lmac_type, 5862306a36Sopenharmony_ci .lmac_fifo_len = rpm2_get_lmac_fifo_len, 5962306a36Sopenharmony_ci .mac_lmac_intl_lbk = rpm_lmac_internal_loopback, 6062306a36Sopenharmony_ci .mac_get_rx_stats = rpm_get_rx_stats, 6162306a36Sopenharmony_ci .mac_get_tx_stats = rpm_get_tx_stats, 6262306a36Sopenharmony_ci .get_fec_stats = rpm_get_fec_stats, 6362306a36Sopenharmony_ci .mac_enadis_rx_pause_fwding = rpm_lmac_enadis_rx_pause_fwding, 6462306a36Sopenharmony_ci .mac_get_pause_frm_status = rpm_lmac_get_pause_frm_status, 6562306a36Sopenharmony_ci .mac_enadis_pause_frm = rpm_lmac_enadis_pause_frm, 6662306a36Sopenharmony_ci .mac_pause_frm_config = rpm_lmac_pause_frm_config, 6762306a36Sopenharmony_ci .mac_enadis_ptp_config = rpm_lmac_ptp_config, 6862306a36Sopenharmony_ci .mac_rx_tx_enable = rpm_lmac_rx_tx_enable, 6962306a36Sopenharmony_ci .mac_tx_enable = rpm_lmac_tx_enable, 7062306a36Sopenharmony_ci .pfc_config = rpm_lmac_pfc_config, 7162306a36Sopenharmony_ci .mac_get_pfc_frm_cfg = rpm_lmac_get_pfc_frm_cfg, 7262306a36Sopenharmony_ci .mac_reset = rpm_lmac_reset, 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cibool is_dev_rpm2(void *rpmd) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci rpm_t *rpm = rpmd; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci return (rpm->pdev->device == PCI_DEVID_CN10KB_RPM); 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistruct mac_ops *rpm_get_mac_ops(rpm_t *rpm) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci if (is_dev_rpm2(rpm)) 8562306a36Sopenharmony_ci return &rpm2_mac_ops; 8662306a36Sopenharmony_ci else 8762306a36Sopenharmony_ci return &rpm_mac_ops; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic void rpm_write(rpm_t *rpm, u64 lmac, u64 offset, u64 val) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci cgx_write(rpm, lmac, offset, val); 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic u64 rpm_read(rpm_t *rpm, u64 lmac, u64 offset) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci return cgx_read(rpm, lmac, offset); 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci/* Read HW major version to determine RPM 10162306a36Sopenharmony_ci * MAC type 100/USX 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_cistatic bool is_mac_rpmusx(void *rpmd) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci rpm_t *rpm = rpmd; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci return rpm_read(rpm, 0, RPMX_CONST1) & 0x700ULL; 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ciint rpm_get_nr_lmacs(void *rpmd) 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci rpm_t *rpm = rpmd; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci return hweight8(rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS) & 0xFULL); 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ciint rpm2_get_nr_lmacs(void *rpmd) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci rpm_t *rpm = rpmd; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci return hweight8(rpm_read(rpm, 0, RPM2_CMRX_RX_LMACS) & 0xFFULL); 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ciint rpm_lmac_tx_enable(void *rpmd, int lmac_id, bool enable) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci rpm_t *rpm = rpmd; 12762306a36Sopenharmony_ci u64 cfg, last; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 13062306a36Sopenharmony_ci return -ENODEV; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 13362306a36Sopenharmony_ci last = cfg; 13462306a36Sopenharmony_ci if (enable) 13562306a36Sopenharmony_ci cfg |= RPM_TX_EN; 13662306a36Sopenharmony_ci else 13762306a36Sopenharmony_ci cfg &= ~(RPM_TX_EN); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci if (cfg != last) 14062306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 14162306a36Sopenharmony_ci return !!(last & RPM_TX_EN); 14262306a36Sopenharmony_ci} 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ciint rpm_lmac_rx_tx_enable(void *rpmd, int lmac_id, bool enable) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci rpm_t *rpm = rpmd; 14762306a36Sopenharmony_ci u64 cfg; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 15062306a36Sopenharmony_ci return -ENODEV; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 15362306a36Sopenharmony_ci if (enable) 15462306a36Sopenharmony_ci cfg |= RPM_RX_EN | RPM_TX_EN; 15562306a36Sopenharmony_ci else 15662306a36Sopenharmony_ci cfg &= ~(RPM_RX_EN | RPM_TX_EN); 15762306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 15862306a36Sopenharmony_ci return 0; 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_civoid rpm_lmac_enadis_rx_pause_fwding(void *rpmd, int lmac_id, bool enable) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci rpm_t *rpm = rpmd; 16462306a36Sopenharmony_ci struct lmac *lmac; 16562306a36Sopenharmony_ci u64 cfg; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci if (!rpm) 16862306a36Sopenharmony_ci return; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci lmac = lmac_pdata(lmac_id, rpm); 17162306a36Sopenharmony_ci if (!lmac) 17262306a36Sopenharmony_ci return; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* Pause frames are not enabled just return */ 17562306a36Sopenharmony_ci if (!bitmap_weight(lmac->rx_fc_pfvf_bmap.bmap, lmac->rx_fc_pfvf_bmap.max)) 17662306a36Sopenharmony_ci return; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci if (enable) { 17962306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 18062306a36Sopenharmony_ci cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 18162306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 18262306a36Sopenharmony_ci } else { 18362306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 18462306a36Sopenharmony_ci cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 18562306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 18662306a36Sopenharmony_ci } 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ciint rpm_lmac_get_pause_frm_status(void *rpmd, int lmac_id, 19062306a36Sopenharmony_ci u8 *tx_pause, u8 *rx_pause) 19162306a36Sopenharmony_ci{ 19262306a36Sopenharmony_ci rpm_t *rpm = rpmd; 19362306a36Sopenharmony_ci u64 cfg; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 19662306a36Sopenharmony_ci return -ENODEV; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 19962306a36Sopenharmony_ci if (!(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE)) { 20062306a36Sopenharmony_ci *rx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE); 20162306a36Sopenharmony_ci *tx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE); 20262306a36Sopenharmony_ci } 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci return 0; 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic void rpm_cfg_pfc_quanta_thresh(rpm_t *rpm, int lmac_id, 20862306a36Sopenharmony_ci unsigned long pfc_en, 20962306a36Sopenharmony_ci bool enable) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci u64 quanta_offset = 0, quanta_thresh = 0, cfg; 21262306a36Sopenharmony_ci int i, shift; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci /* Set pause time and interval */ 21562306a36Sopenharmony_ci for_each_set_bit(i, &pfc_en, 16) { 21662306a36Sopenharmony_ci switch (i) { 21762306a36Sopenharmony_ci case 0: 21862306a36Sopenharmony_ci case 1: 21962306a36Sopenharmony_ci quanta_offset = RPMX_MTI_MAC100X_CL01_PAUSE_QUANTA; 22062306a36Sopenharmony_ci quanta_thresh = RPMX_MTI_MAC100X_CL01_QUANTA_THRESH; 22162306a36Sopenharmony_ci break; 22262306a36Sopenharmony_ci case 2: 22362306a36Sopenharmony_ci case 3: 22462306a36Sopenharmony_ci quanta_offset = RPMX_MTI_MAC100X_CL23_PAUSE_QUANTA; 22562306a36Sopenharmony_ci quanta_thresh = RPMX_MTI_MAC100X_CL23_QUANTA_THRESH; 22662306a36Sopenharmony_ci break; 22762306a36Sopenharmony_ci case 4: 22862306a36Sopenharmony_ci case 5: 22962306a36Sopenharmony_ci quanta_offset = RPMX_MTI_MAC100X_CL45_PAUSE_QUANTA; 23062306a36Sopenharmony_ci quanta_thresh = RPMX_MTI_MAC100X_CL45_QUANTA_THRESH; 23162306a36Sopenharmony_ci break; 23262306a36Sopenharmony_ci case 6: 23362306a36Sopenharmony_ci case 7: 23462306a36Sopenharmony_ci quanta_offset = RPMX_MTI_MAC100X_CL67_PAUSE_QUANTA; 23562306a36Sopenharmony_ci quanta_thresh = RPMX_MTI_MAC100X_CL67_QUANTA_THRESH; 23662306a36Sopenharmony_ci break; 23762306a36Sopenharmony_ci case 8: 23862306a36Sopenharmony_ci case 9: 23962306a36Sopenharmony_ci quanta_offset = RPMX_MTI_MAC100X_CL89_PAUSE_QUANTA; 24062306a36Sopenharmony_ci quanta_thresh = RPMX_MTI_MAC100X_CL89_QUANTA_THRESH; 24162306a36Sopenharmony_ci break; 24262306a36Sopenharmony_ci case 10: 24362306a36Sopenharmony_ci case 11: 24462306a36Sopenharmony_ci quanta_offset = RPMX_MTI_MAC100X_CL1011_PAUSE_QUANTA; 24562306a36Sopenharmony_ci quanta_thresh = RPMX_MTI_MAC100X_CL1011_QUANTA_THRESH; 24662306a36Sopenharmony_ci break; 24762306a36Sopenharmony_ci case 12: 24862306a36Sopenharmony_ci case 13: 24962306a36Sopenharmony_ci quanta_offset = RPMX_MTI_MAC100X_CL1213_PAUSE_QUANTA; 25062306a36Sopenharmony_ci quanta_thresh = RPMX_MTI_MAC100X_CL1213_QUANTA_THRESH; 25162306a36Sopenharmony_ci break; 25262306a36Sopenharmony_ci case 14: 25362306a36Sopenharmony_ci case 15: 25462306a36Sopenharmony_ci quanta_offset = RPMX_MTI_MAC100X_CL1415_PAUSE_QUANTA; 25562306a36Sopenharmony_ci quanta_thresh = RPMX_MTI_MAC100X_CL1415_QUANTA_THRESH; 25662306a36Sopenharmony_ci break; 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ci if (!quanta_offset || !quanta_thresh) 26062306a36Sopenharmony_ci continue; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci shift = (i % 2) ? 1 : 0; 26362306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, quanta_offset); 26462306a36Sopenharmony_ci if (enable) { 26562306a36Sopenharmony_ci cfg |= ((u64)RPM_DEFAULT_PAUSE_TIME << shift * 16); 26662306a36Sopenharmony_ci } else { 26762306a36Sopenharmony_ci if (!shift) 26862306a36Sopenharmony_ci cfg &= ~GENMASK_ULL(15, 0); 26962306a36Sopenharmony_ci else 27062306a36Sopenharmony_ci cfg &= ~GENMASK_ULL(31, 16); 27162306a36Sopenharmony_ci } 27262306a36Sopenharmony_ci rpm_write(rpm, lmac_id, quanta_offset, cfg); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, quanta_thresh); 27562306a36Sopenharmony_ci if (enable) { 27662306a36Sopenharmony_ci cfg |= ((u64)(RPM_DEFAULT_PAUSE_TIME / 2) << shift * 16); 27762306a36Sopenharmony_ci } else { 27862306a36Sopenharmony_ci if (!shift) 27962306a36Sopenharmony_ci cfg &= ~GENMASK_ULL(15, 0); 28062306a36Sopenharmony_ci else 28162306a36Sopenharmony_ci cfg &= ~GENMASK_ULL(31, 16); 28262306a36Sopenharmony_ci } 28362306a36Sopenharmony_ci rpm_write(rpm, lmac_id, quanta_thresh, cfg); 28462306a36Sopenharmony_ci } 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic void rpm2_lmac_cfg_bp(rpm_t *rpm, int lmac_id, u8 tx_pause, u8 rx_pause) 28862306a36Sopenharmony_ci{ 28962306a36Sopenharmony_ci u64 cfg; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPM2_CMR_RX_OVR_BP); 29262306a36Sopenharmony_ci if (tx_pause) { 29362306a36Sopenharmony_ci /* Configure CL0 Pause Quanta & threshold 29462306a36Sopenharmony_ci * for 802.3X frames 29562306a36Sopenharmony_ci */ 29662306a36Sopenharmony_ci rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 1, true); 29762306a36Sopenharmony_ci cfg &= ~RPM2_CMR_RX_OVR_BP_EN; 29862306a36Sopenharmony_ci } else { 29962306a36Sopenharmony_ci /* Disable all Pause Quanta & threshold values */ 30062306a36Sopenharmony_ci rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false); 30162306a36Sopenharmony_ci cfg |= RPM2_CMR_RX_OVR_BP_EN; 30262306a36Sopenharmony_ci cfg &= ~RPM2_CMR_RX_OVR_BP_BP; 30362306a36Sopenharmony_ci } 30462306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPM2_CMR_RX_OVR_BP, cfg); 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_cistatic void rpm_lmac_cfg_bp(rpm_t *rpm, int lmac_id, u8 tx_pause, u8 rx_pause) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci u64 cfg; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci cfg = rpm_read(rpm, 0, RPMX_CMR_RX_OVR_BP); 31262306a36Sopenharmony_ci if (tx_pause) { 31362306a36Sopenharmony_ci /* Configure CL0 Pause Quanta & threshold for 31462306a36Sopenharmony_ci * 802.3X frames 31562306a36Sopenharmony_ci */ 31662306a36Sopenharmony_ci rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 1, true); 31762306a36Sopenharmony_ci cfg &= ~RPMX_CMR_RX_OVR_BP_EN(lmac_id); 31862306a36Sopenharmony_ci } else { 31962306a36Sopenharmony_ci /* Disable all Pause Quanta & threshold values */ 32062306a36Sopenharmony_ci rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xffff, false); 32162306a36Sopenharmony_ci cfg |= RPMX_CMR_RX_OVR_BP_EN(lmac_id); 32262306a36Sopenharmony_ci cfg &= ~RPMX_CMR_RX_OVR_BP_BP(lmac_id); 32362306a36Sopenharmony_ci } 32462306a36Sopenharmony_ci rpm_write(rpm, 0, RPMX_CMR_RX_OVR_BP, cfg); 32562306a36Sopenharmony_ci} 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ciint rpm_lmac_enadis_pause_frm(void *rpmd, int lmac_id, u8 tx_pause, 32862306a36Sopenharmony_ci u8 rx_pause) 32962306a36Sopenharmony_ci{ 33062306a36Sopenharmony_ci rpm_t *rpm = rpmd; 33162306a36Sopenharmony_ci u64 cfg; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 33462306a36Sopenharmony_ci return -ENODEV; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 33762306a36Sopenharmony_ci cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 33862306a36Sopenharmony_ci cfg |= rx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 33962306a36Sopenharmony_ci cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 34062306a36Sopenharmony_ci cfg |= rx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 34162306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 34462306a36Sopenharmony_ci cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 34562306a36Sopenharmony_ci cfg |= tx_pause ? 0x0 : RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 34662306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (is_dev_rpm2(rpm)) 34962306a36Sopenharmony_ci rpm2_lmac_cfg_bp(rpm, lmac_id, tx_pause, rx_pause); 35062306a36Sopenharmony_ci else 35162306a36Sopenharmony_ci rpm_lmac_cfg_bp(rpm, lmac_id, tx_pause, rx_pause); 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci return 0; 35462306a36Sopenharmony_ci} 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_civoid rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable) 35762306a36Sopenharmony_ci{ 35862306a36Sopenharmony_ci u64 cfg, pfc_class_mask_cfg; 35962306a36Sopenharmony_ci rpm_t *rpm = rpmd; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci /* ALL pause frames received are completely ignored */ 36262306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 36362306a36Sopenharmony_ci cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE; 36462306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci /* Disable forward pause to TX block */ 36762306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 36862306a36Sopenharmony_ci cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE; 36962306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci /* Disable pause frames transmission */ 37262306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 37362306a36Sopenharmony_ci cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 37462306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci /* Disable forward pause to driver */ 37762306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 37862306a36Sopenharmony_ci cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_FWD; 37962306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci /* Enable channel mask for all LMACS */ 38262306a36Sopenharmony_ci if (is_dev_rpm2(rpm)) 38362306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPM2_CMR_CHAN_MSK_OR, 0xffff); 38462306a36Sopenharmony_ci else 38562306a36Sopenharmony_ci rpm_write(rpm, 0, RPMX_CMR_CHAN_MSK_OR, ~0ULL); 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci /* Disable all PFC classes */ 38862306a36Sopenharmony_ci pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL : 38962306a36Sopenharmony_ci RPMX_CMRX_PRT_CBFC_CTL; 39062306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, pfc_class_mask_cfg); 39162306a36Sopenharmony_ci cfg = FIELD_SET(RPM_PFC_CLASS_MASK, 0, cfg); 39262306a36Sopenharmony_ci rpm_write(rpm, lmac_id, pfc_class_mask_cfg, cfg); 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ciint rpm_get_rx_stats(void *rpmd, int lmac_id, int idx, u64 *rx_stat) 39662306a36Sopenharmony_ci{ 39762306a36Sopenharmony_ci rpm_t *rpm = rpmd; 39862306a36Sopenharmony_ci u64 val_lo, val_hi; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 40162306a36Sopenharmony_ci return -ENODEV; 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci mutex_lock(&rpm->lock); 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci /* Update idx to point per lmac Rx statistics page */ 40662306a36Sopenharmony_ci idx += lmac_id * rpm->mac_ops->rx_stats_cnt; 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci /* Read lower 32 bits of counter */ 40962306a36Sopenharmony_ci val_lo = rpm_read(rpm, 0, RPMX_MTI_STAT_RX_STAT_PAGES_COUNTERX + 41062306a36Sopenharmony_ci (idx * 8)); 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci /* upon read of lower 32 bits, higher 32 bits are written 41362306a36Sopenharmony_ci * to RPMX_MTI_STAT_DATA_HI_CDC 41462306a36Sopenharmony_ci */ 41562306a36Sopenharmony_ci val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci *rx_stat = (val_hi << 32 | val_lo); 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci mutex_unlock(&rpm->lock); 42062306a36Sopenharmony_ci return 0; 42162306a36Sopenharmony_ci} 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_ciint rpm_get_tx_stats(void *rpmd, int lmac_id, int idx, u64 *tx_stat) 42462306a36Sopenharmony_ci{ 42562306a36Sopenharmony_ci rpm_t *rpm = rpmd; 42662306a36Sopenharmony_ci u64 val_lo, val_hi; 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 42962306a36Sopenharmony_ci return -ENODEV; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci mutex_lock(&rpm->lock); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci /* Update idx to point per lmac Tx statistics page */ 43462306a36Sopenharmony_ci idx += lmac_id * rpm->mac_ops->tx_stats_cnt; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci val_lo = rpm_read(rpm, 0, RPMX_MTI_STAT_TX_STAT_PAGES_COUNTERX + 43762306a36Sopenharmony_ci (idx * 8)); 43862306a36Sopenharmony_ci val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci *tx_stat = (val_hi << 32 | val_lo); 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci mutex_unlock(&rpm->lock); 44362306a36Sopenharmony_ci return 0; 44462306a36Sopenharmony_ci} 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ciu8 rpm_get_lmac_type(void *rpmd, int lmac_id) 44762306a36Sopenharmony_ci{ 44862306a36Sopenharmony_ci rpm_t *rpm = rpmd; 44962306a36Sopenharmony_ci u64 req = 0, resp; 45062306a36Sopenharmony_ci int err; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_LINK_STS, req); 45362306a36Sopenharmony_ci err = cgx_fwi_cmd_generic(req, &resp, rpm, 0); 45462306a36Sopenharmony_ci if (!err) 45562306a36Sopenharmony_ci return FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, resp); 45662306a36Sopenharmony_ci return err; 45762306a36Sopenharmony_ci} 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ciu32 rpm_get_lmac_fifo_len(void *rpmd, int lmac_id) 46062306a36Sopenharmony_ci{ 46162306a36Sopenharmony_ci rpm_t *rpm = rpmd; 46262306a36Sopenharmony_ci u64 hi_perf_lmac; 46362306a36Sopenharmony_ci u8 num_lmacs; 46462306a36Sopenharmony_ci u32 fifo_len; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci fifo_len = rpm->mac_ops->fifo_len; 46762306a36Sopenharmony_ci num_lmacs = rpm->mac_ops->get_nr_lmacs(rpm); 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci switch (num_lmacs) { 47062306a36Sopenharmony_ci case 1: 47162306a36Sopenharmony_ci return fifo_len; 47262306a36Sopenharmony_ci case 2: 47362306a36Sopenharmony_ci return fifo_len / 2; 47462306a36Sopenharmony_ci case 3: 47562306a36Sopenharmony_ci /* LMAC marked as hi_perf gets half of the FIFO and rest 1/4th */ 47662306a36Sopenharmony_ci hi_perf_lmac = rpm_read(rpm, 0, CGXX_CMRX_RX_LMACS); 47762306a36Sopenharmony_ci hi_perf_lmac = (hi_perf_lmac >> 4) & 0x3ULL; 47862306a36Sopenharmony_ci if (lmac_id == hi_perf_lmac) 47962306a36Sopenharmony_ci return fifo_len / 2; 48062306a36Sopenharmony_ci return fifo_len / 4; 48162306a36Sopenharmony_ci case 4: 48262306a36Sopenharmony_ci default: 48362306a36Sopenharmony_ci return fifo_len / 4; 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci return 0; 48662306a36Sopenharmony_ci} 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_cistatic int rpmusx_lmac_internal_loopback(rpm_t *rpm, int lmac_id, bool enable) 48962306a36Sopenharmony_ci{ 49062306a36Sopenharmony_ci u64 cfg; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPM2_USX_PCSX_CONTROL1); 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci if (enable) 49562306a36Sopenharmony_ci cfg |= RPM2_USX_PCS_LBK; 49662306a36Sopenharmony_ci else 49762306a36Sopenharmony_ci cfg &= ~RPM2_USX_PCS_LBK; 49862306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPM2_USX_PCSX_CONTROL1, cfg); 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci return 0; 50162306a36Sopenharmony_ci} 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ciu32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id) 50462306a36Sopenharmony_ci{ 50562306a36Sopenharmony_ci u64 hi_perf_lmac, lmac_info; 50662306a36Sopenharmony_ci rpm_t *rpm = rpmd; 50762306a36Sopenharmony_ci u8 num_lmacs; 50862306a36Sopenharmony_ci u32 fifo_len; 50962306a36Sopenharmony_ci u16 max_lmac; 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci lmac_info = rpm_read(rpm, 0, RPM2_CMRX_RX_LMACS); 51262306a36Sopenharmony_ci /* LMACs are divided into two groups and each group 51362306a36Sopenharmony_ci * gets half of the FIFO 51462306a36Sopenharmony_ci * Group0 lmac_id range {0..3} 51562306a36Sopenharmony_ci * Group1 lmac_id range {4..7} 51662306a36Sopenharmony_ci */ 51762306a36Sopenharmony_ci max_lmac = (rpm_read(rpm, 0, CGX_CONST) >> 24) & 0xFF; 51862306a36Sopenharmony_ci if (max_lmac > 4) 51962306a36Sopenharmony_ci fifo_len = rpm->mac_ops->fifo_len / 2; 52062306a36Sopenharmony_ci else 52162306a36Sopenharmony_ci fifo_len = rpm->mac_ops->fifo_len; 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci if (lmac_id < 4) { 52462306a36Sopenharmony_ci num_lmacs = hweight8(lmac_info & 0xF); 52562306a36Sopenharmony_ci hi_perf_lmac = (lmac_info >> 8) & 0x3ULL; 52662306a36Sopenharmony_ci } else { 52762306a36Sopenharmony_ci num_lmacs = hweight8(lmac_info & 0xF0); 52862306a36Sopenharmony_ci hi_perf_lmac = (lmac_info >> 10) & 0x3ULL; 52962306a36Sopenharmony_ci hi_perf_lmac += 4; 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci switch (num_lmacs) { 53362306a36Sopenharmony_ci case 1: 53462306a36Sopenharmony_ci return fifo_len; 53562306a36Sopenharmony_ci case 2: 53662306a36Sopenharmony_ci return fifo_len / 2; 53762306a36Sopenharmony_ci case 3: 53862306a36Sopenharmony_ci /* LMAC marked as hi_perf gets half of the FIFO 53962306a36Sopenharmony_ci * and rest 1/4th 54062306a36Sopenharmony_ci */ 54162306a36Sopenharmony_ci if (lmac_id == hi_perf_lmac) 54262306a36Sopenharmony_ci return fifo_len / 2; 54362306a36Sopenharmony_ci return fifo_len / 4; 54462306a36Sopenharmony_ci case 4: 54562306a36Sopenharmony_ci default: 54662306a36Sopenharmony_ci return fifo_len / 4; 54762306a36Sopenharmony_ci } 54862306a36Sopenharmony_ci return 0; 54962306a36Sopenharmony_ci} 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ciint rpm_lmac_internal_loopback(void *rpmd, int lmac_id, bool enable) 55262306a36Sopenharmony_ci{ 55362306a36Sopenharmony_ci rpm_t *rpm = rpmd; 55462306a36Sopenharmony_ci struct lmac *lmac; 55562306a36Sopenharmony_ci u64 cfg; 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 55862306a36Sopenharmony_ci return -ENODEV; 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci lmac = lmac_pdata(lmac_id, rpm); 56162306a36Sopenharmony_ci if (lmac->lmac_type == LMAC_MODE_QSGMII || 56262306a36Sopenharmony_ci lmac->lmac_type == LMAC_MODE_SGMII) { 56362306a36Sopenharmony_ci dev_err(&rpm->pdev->dev, "loopback not supported for LPC mode\n"); 56462306a36Sopenharmony_ci return 0; 56562306a36Sopenharmony_ci } 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci if (is_dev_rpm2(rpm) && is_mac_rpmusx(rpm)) 56862306a36Sopenharmony_ci return rpmusx_lmac_internal_loopback(rpm, lmac_id, enable); 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1); 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci if (enable) 57362306a36Sopenharmony_ci cfg |= RPMX_MTI_PCS_LBK; 57462306a36Sopenharmony_ci else 57562306a36Sopenharmony_ci cfg &= ~RPMX_MTI_PCS_LBK; 57662306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_PCS100X_CONTROL1, cfg); 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci return 0; 57962306a36Sopenharmony_ci} 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_civoid rpm_lmac_ptp_config(void *rpmd, int lmac_id, bool enable) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci rpm_t *rpm = rpmd; 58462306a36Sopenharmony_ci u64 cfg; 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 58762306a36Sopenharmony_ci return; 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_CFG); 59062306a36Sopenharmony_ci if (enable) { 59162306a36Sopenharmony_ci cfg |= RPMX_RX_TS_PREPEND; 59262306a36Sopenharmony_ci cfg |= RPMX_TX_PTP_1S_SUPPORT; 59362306a36Sopenharmony_ci } else { 59462306a36Sopenharmony_ci cfg &= ~RPMX_RX_TS_PREPEND; 59562306a36Sopenharmony_ci cfg &= ~RPMX_TX_PTP_1S_SUPPORT; 59662306a36Sopenharmony_ci } 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_CMRX_CFG, cfg); 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_XIF_MODE); 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci if (enable) { 60362306a36Sopenharmony_ci cfg |= RPMX_ONESTEP_ENABLE; 60462306a36Sopenharmony_ci cfg &= ~RPMX_TS_BINARY_MODE; 60562306a36Sopenharmony_ci } else { 60662306a36Sopenharmony_ci cfg &= ~RPMX_ONESTEP_ENABLE; 60762306a36Sopenharmony_ci } 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_XIF_MODE, cfg); 61062306a36Sopenharmony_ci} 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ciint rpm_lmac_pfc_config(void *rpmd, int lmac_id, u8 tx_pause, u8 rx_pause, u16 pfc_en) 61362306a36Sopenharmony_ci{ 61462306a36Sopenharmony_ci u64 cfg, class_en, pfc_class_mask_cfg; 61562306a36Sopenharmony_ci rpm_t *rpm = rpmd; 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 61862306a36Sopenharmony_ci return -ENODEV; 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL : 62162306a36Sopenharmony_ci RPMX_CMRX_PRT_CBFC_CTL; 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 62462306a36Sopenharmony_ci class_en = rpm_read(rpm, lmac_id, pfc_class_mask_cfg); 62562306a36Sopenharmony_ci pfc_en |= FIELD_GET(RPM_PFC_CLASS_MASK, class_en); 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci if (rx_pause) { 62862306a36Sopenharmony_ci cfg &= ~(RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | 62962306a36Sopenharmony_ci RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE); 63062306a36Sopenharmony_ci } else { 63162306a36Sopenharmony_ci cfg |= (RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE | 63262306a36Sopenharmony_ci RPMX_MTI_MAC100X_COMMAND_CONFIG_PAUSE_IGNORE); 63362306a36Sopenharmony_ci } 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci if (tx_pause) { 63662306a36Sopenharmony_ci rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, pfc_en, true); 63762306a36Sopenharmony_ci cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 63862306a36Sopenharmony_ci class_en = FIELD_SET(RPM_PFC_CLASS_MASK, pfc_en, class_en); 63962306a36Sopenharmony_ci } else { 64062306a36Sopenharmony_ci rpm_cfg_pfc_quanta_thresh(rpm, lmac_id, 0xfff, false); 64162306a36Sopenharmony_ci cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE; 64262306a36Sopenharmony_ci class_en = FIELD_SET(RPM_PFC_CLASS_MASK, 0, class_en); 64362306a36Sopenharmony_ci } 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci if (!rx_pause && !tx_pause) 64662306a36Sopenharmony_ci cfg &= ~RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; 64762306a36Sopenharmony_ci else 64862306a36Sopenharmony_ci cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); 65162306a36Sopenharmony_ci rpm_write(rpm, lmac_id, pfc_class_mask_cfg, class_en); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci return 0; 65462306a36Sopenharmony_ci} 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ciint rpm_lmac_get_pfc_frm_cfg(void *rpmd, int lmac_id, u8 *tx_pause, u8 *rx_pause) 65762306a36Sopenharmony_ci{ 65862306a36Sopenharmony_ci rpm_t *rpm = rpmd; 65962306a36Sopenharmony_ci u64 cfg; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 66262306a36Sopenharmony_ci return -ENODEV; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); 66562306a36Sopenharmony_ci if (cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE) { 66662306a36Sopenharmony_ci *rx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_RX_P_DISABLE); 66762306a36Sopenharmony_ci *tx_pause = !(cfg & RPMX_MTI_MAC100X_COMMAND_CONFIG_TX_P_DISABLE); 66862306a36Sopenharmony_ci } 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci return 0; 67162306a36Sopenharmony_ci} 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ciint rpm_get_fec_stats(void *rpmd, int lmac_id, struct cgx_fec_stats_rsp *rsp) 67462306a36Sopenharmony_ci{ 67562306a36Sopenharmony_ci u64 val_lo, val_hi; 67662306a36Sopenharmony_ci rpm_t *rpm = rpmd; 67762306a36Sopenharmony_ci u64 cfg; 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 68062306a36Sopenharmony_ci return -ENODEV; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci if (rpm->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_NONE) 68362306a36Sopenharmony_ci return 0; 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci if (rpm->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_BASER) { 68662306a36Sopenharmony_ci val_lo = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_VL0_CCW_LO); 68762306a36Sopenharmony_ci val_hi = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_CW_HI); 68862306a36Sopenharmony_ci rsp->fec_corr_blks = (val_hi << 16 | val_lo); 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci val_lo = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_VL0_NCCW_LO); 69162306a36Sopenharmony_ci val_hi = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_CW_HI); 69262306a36Sopenharmony_ci rsp->fec_uncorr_blks = (val_hi << 16 | val_lo); 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci /* 50G uses 2 Physical serdes lines */ 69562306a36Sopenharmony_ci if (rpm->lmac_idmap[lmac_id]->link_info.lmac_type_id == 69662306a36Sopenharmony_ci LMAC_MODE_50G_R) { 69762306a36Sopenharmony_ci val_lo = rpm_read(rpm, lmac_id, 69862306a36Sopenharmony_ci RPMX_MTI_FCFECX_VL1_CCW_LO); 69962306a36Sopenharmony_ci val_hi = rpm_read(rpm, lmac_id, 70062306a36Sopenharmony_ci RPMX_MTI_FCFECX_CW_HI); 70162306a36Sopenharmony_ci rsp->fec_corr_blks += (val_hi << 16 | val_lo); 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci val_lo = rpm_read(rpm, lmac_id, 70462306a36Sopenharmony_ci RPMX_MTI_FCFECX_VL1_NCCW_LO); 70562306a36Sopenharmony_ci val_hi = rpm_read(rpm, lmac_id, 70662306a36Sopenharmony_ci RPMX_MTI_FCFECX_CW_HI); 70762306a36Sopenharmony_ci rsp->fec_uncorr_blks += (val_hi << 16 | val_lo); 70862306a36Sopenharmony_ci } 70962306a36Sopenharmony_ci } else { 71062306a36Sopenharmony_ci /* enable RS-FEC capture */ 71162306a36Sopenharmony_ci cfg = rpm_read(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL); 71262306a36Sopenharmony_ci cfg |= RPMX_RSFEC_RX_CAPTURE | BIT(lmac_id); 71362306a36Sopenharmony_ci rpm_write(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL, cfg); 71462306a36Sopenharmony_ci 71562306a36Sopenharmony_ci val_lo = rpm_read(rpm, 0, 71662306a36Sopenharmony_ci RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_2); 71762306a36Sopenharmony_ci val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 71862306a36Sopenharmony_ci rsp->fec_corr_blks = (val_hi << 32 | val_lo); 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci val_lo = rpm_read(rpm, 0, 72162306a36Sopenharmony_ci RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_3); 72262306a36Sopenharmony_ci val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC); 72362306a36Sopenharmony_ci rsp->fec_uncorr_blks = (val_hi << 32 | val_lo); 72462306a36Sopenharmony_ci } 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci return 0; 72762306a36Sopenharmony_ci} 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ciint rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr) 73062306a36Sopenharmony_ci{ 73162306a36Sopenharmony_ci u64 rx_logl_xon, cfg; 73262306a36Sopenharmony_ci rpm_t *rpm = rpmd; 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_ci if (!is_lmac_valid(rpm, lmac_id)) 73562306a36Sopenharmony_ci return -ENODEV; 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci /* Resetting PFC related CSRs */ 73862306a36Sopenharmony_ci rx_logl_xon = is_dev_rpm2(rpm) ? RPM2_CMRX_RX_LOGL_XON : 73962306a36Sopenharmony_ci RPMX_CMRX_RX_LOGL_XON; 74062306a36Sopenharmony_ci cfg = 0xff; 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci rpm_write(rpm, lmac_id, rx_logl_xon, cfg); 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci if (pf_req_flr) 74562306a36Sopenharmony_ci rpm_lmac_internal_loopback(rpm, lmac_id, false); 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci return 0; 74862306a36Sopenharmony_ci} 749