quadra28_diagnostics.c (8554B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 10 #include <phymod/phymod.h> 11 #include <phymod/phymod_system.h> 12 #include <phymod/phymod_diagnostics.h> 13 #include <phymod/phymod_diagnostics_dispatch.h> 14 15 16 #ifdef PHYMOD_QUADRA28_SUPPORT 17 18 #include <phymod/chip/quadra28.h> 19 20 /* To be defined */ 21 #include "../tier1/quadra28_types.h" 22 #include "../tier1/quadra28_cfg_seq.h" 23 #include "../tier1/quadra28_reg_access.h" 24 #include "../tier1/bcmi_quadra28_defs.h" 25 26 27 /** Convert PHYMOD poly to falcon poly type 28 * This function converts PHYMOD polynomial type to falcon polynomial type 29 * 30 * @param phymod_poly phymod polynomial type 31 * @param falcon_poly falcon polynomial type 32 * 33 * @return PHYMOD_E_NONE successful function execution 34 */ 35 STATIC 36 int _quadra28_prbs_poly_phymod_to_merlin(phymod_prbs_poly_t phymod_poly, 37 enum srds_prbs_polynomial_enum *merlin_poly) 38 { 39 switch(phymod_poly) { 40 case phymodPrbsPoly7: 41 *merlin_poly= SRDS_PRBS_7; 42 break; 43 case phymodPrbsPoly9: 44 *merlin_poly= SRDS_PRBS_9; 45 break; 46 case phymodPrbsPoly11: 47 *merlin_poly= SRDS_PRBS_11; 48 break; 49 case phymodPrbsPoly15: 50 *merlin_poly= SRDS_PRBS_15; 51 break; 52 case phymodPrbsPoly23: 53 *merlin_poly= SRDS_PRBS_23; 54 break; 55 case phymodPrbsPoly31: 56 *merlin_poly= SRDS_PRBS_31; 57 break; 58 case phymodPrbsPoly58: 59 *merlin_poly= SRDS_PRBS_58; 60 break; 61 default: 62 PHYMOD_RETURN_WITH_ERR 63 (PHYMOD_E_PARAM,\ 64 (_PHYMOD_MSG("unsupported poly for q28"))); 65 break; 66 } 67 return PHYMOD_E_NONE; 68 } 69 70 /** Convert falcon poly to PHYMOD poly type 71 * This function converts falcon polynomial type to PHYMOD polynomial type 72 * 73 * @param falcon_poly falcon polynomial type 74 * @param phymod_poly phymod polynomial type 75 * 76 * @return PHYMOD_E_NONE successful function execution 77 */ 78 STATIC 79 int _quadra28_prbs_poly_merlin_to_phymod(enum srds_prbs_polynomial_enum merlin_poly, 80 phymod_prbs_poly_t *phymod_poly) 81 { 82 switch(merlin_poly) { 83 case SRDS_PRBS_7: 84 *phymod_poly = phymodPrbsPoly7; 85 break; 86 case SRDS_PRBS_9: 87 *phymod_poly = phymodPrbsPoly9; 88 break; 89 case SRDS_PRBS_11: 90 *phymod_poly = phymodPrbsPoly11; 91 break; 92 case SRDS_PRBS_15: 93 *phymod_poly = phymodPrbsPoly15; 94 break; 95 case SRDS_PRBS_23: 96 *phymod_poly = phymodPrbsPoly23; 97 break; 98 case SRDS_PRBS_31: 99 *phymod_poly = phymodPrbsPoly31; 100 break; 101 case SRDS_PRBS_58: 102 *phymod_poly = phymodPrbsPoly58; 103 break; 104 default: 105 PHYMOD_RETURN_WITH_ERR 106 (PHYMOD_E_INTERNAL,\ 107 (_PHYMOD_MSG("uknown poly"))); 108 break; 109 } 110 return PHYMOD_E_NONE; 111 } 112 113 /** PRBS Polynomial Enum */ 114 int quadra28_phy_prbs_config_set(const phymod_phy_access_t* phy, uint32_t flags , const phymod_prbs_t* prbs) 115 { 116 enum srds_prbs_polynomial_enum merlin_poly; 117 118 PHYMOD_IF_ERR_RETURN 119 (_quadra28_prbs_poly_phymod_to_merlin(prbs->poly, &merlin_poly)); 120 PHYMOD_IF_ERR_RETURN( 121 quara28_prbs_config_set(phy, 122 flags, 123 merlin_poly, 124 prbs->invert)); 125 return PHYMOD_E_NONE; 126 127 } 128 129 int quadra28_phy_prbs_config_get(const phymod_phy_access_t* phy, uint32_t flags , phymod_prbs_t* prbs) 130 { 131 enum srds_prbs_polynomial_enum merlin_poly; 132 133 PHYMOD_IF_ERR_RETURN( 134 quadra28_prbs_config_get(phy, 135 flags, 136 &merlin_poly, &prbs->invert)); 137 PHYMOD_IF_ERR_RETURN 138 (_quadra28_prbs_poly_merlin_to_phymod(merlin_poly, &prbs->poly)); 139 140 return PHYMOD_E_NONE; 141 142 } 143 144 145 int quadra28_phy_prbs_enable_set(const phymod_phy_access_t* phy, uint32_t flags , uint32_t enable) 146 { 147 148 PHYMOD_IF_ERR_RETURN( 149 quadra28_prbs_enable_set(phy, flags, enable)); 150 151 return PHYMOD_E_NONE; 152 153 } 154 155 int quadra28_phy_prbs_enable_get(const phymod_phy_access_t* phy, uint32_t flags , uint32_t* enable) 156 { 157 PHYMOD_IF_ERR_RETURN( 158 quadra28_prbs_enable_get(phy, flags, enable)); 159 160 return PHYMOD_E_NONE; 161 162 } 163 164 165 int quadra28_phy_prbs_status_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_prbs_status_t* prbs_status) 166 { 167 PHYMOD_IF_ERR_RETURN( 168 quadra28_prbs_status_get(phy, 169 &prbs_status->prbs_lock, 170 &prbs_status->prbs_lock_loss, 171 &prbs_status->error_count)); 172 173 return PHYMOD_E_NONE; 174 175 } 176 177 178 int quadra28_phy_diagnostics_get(const phymod_phy_access_t* phy, phymod_phy_diagnostics_t* diag) 179 { 180 PHYMOD_IF_ERR_RETURN( 181 _quadra28_phy_diagnostics_get(phy, diag)); 182 return PHYMOD_E_NONE; 183 184 } 185 186 187 int quadra28_phy_eyescan_run(const phymod_phy_access_t* phy, uint32_t flags, phymod_eyescan_mode_t mode, const phymod_phy_eyescan_options_t* eyescan_options) 188 { 189 /* Added condition to solve printing eye trice from PHYMOD layer*/ 190 if (PHYMOD_EYESCAN_F_DONE_GET(flags)) { 191 switch(mode) { 192 case phymodEyescanModeFast: 193 return quadra28_display_eye_scan(phy); 194 break; 195 case phymodEyescanModeBERProj: 196 return quadra28_ber_proj(phy, eyescan_options); 197 break; 198 default: 199 return quadra28_display_eye_scan(phy); 200 break; 201 } 202 203 } else { 204 return PHYMOD_E_NONE; 205 } 206 207 } 208 209 int quadra28_phy_link_mon_enable_set(const phymod_phy_access_t* phy, phymod_link_monitor_mode_t link_mon_mode, uint32_t enable) 210 { 211 uint32_t retime_get = 0; 212 213 PHYMOD_IF_ERR_RETURN( 214 _quadra28_phy_retimer_enable_get(&phy->access, &retime_get)); 215 if (retime_get != 1) { 216 return PHYMOD_E_CONFIG; 217 } 218 return PHYMOD_E_NONE; 219 } 220 221 int quadra28_phy_link_mon_enable_get(const phymod_phy_access_t* phy, phymod_link_monitor_mode_t link_mon_mode, uint32_t* enable) 222 { 223 return _quadra28_phy_retimer_enable_get(&phy->access, enable); 224 } 225 226 227 int quadra28_phy_link_mon_status_get(const phymod_phy_access_t* phy, uint32_t* lock_status, uint32_t* lock_lost_lh, uint32_t* error_count) 228 { 229 uint32_t acc_flags = 0; 230 int pkg_side = 0; 231 int num_lanes = QUADRA28_MAX_LANE; 232 int lane_map = 0; 233 int lane_index = 0; 234 BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val; 235 BCMI_QUADRA28_PCS_STATUS1r_t pcs_status1_reg_val; 236 phymod_access_t acc_cpy; 237 int pmd_mode = 0; 238 uint32_t speed = 0; 239 240 241 PHYMOD_MEMSET(&side_sel_reg_val, 0, sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t)); 242 PHYMOD_MEMSET(&pcs_status1_reg_val, 0, sizeof(BCMI_QUADRA28_PCS_STATUS1r_t)); 243 PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t)); 244 245 Q28_GET_PMD_MODE(&acc_cpy, pmd_mode); 246 Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy); 247 248 acc_flags = PHYMOD_ACC_FLAGS(&acc_cpy); 249 QUADRA28_GET_IF_SIDE(acc_flags, pkg_side); 250 lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy); 251 252 QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val,pkg_side); 253 *lock_status = 1; 254 255 if (pmd_mode == Q28_SINGLE_PMD) { 256 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 257 if (((lane_map >> lane_index) & 1) == 0x1) { 258 /* select a lane */ 259 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index)); 260 PHYMOD_IF_ERR_RETURN(BCMI_QUADRA28_READ_PCS_STATUS1r(&acc_cpy, &pcs_status1_reg_val)); 261 *lock_status &= BCMI_QUADRA28_PCS_STATUS1r_PCS_RECEIVE_LINK_STATUSf_GET(pcs_status1_reg_val); 262 } 263 } 264 } else { 265 PHYMOD_IF_ERR_RETURN(BCMI_QUADRA28_READ_PCS_STATUS1r(&acc_cpy, &pcs_status1_reg_val)); 266 *lock_status &= BCMI_QUADRA28_PCS_STATUS1r_PCS_RECEIVE_LINK_STATUSf_GET(pcs_status1_reg_val); 267 } 268 269 /* restore Q28_INTF_LINE side */ 270 QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val,Q28_INTF_LINE); 271 return PHYMOD_E_NONE; 272 273 } 274 275 int quadra28_phy_pmd_info_dump(const phymod_phy_access_t* phy, const char* type) 276 { 277 PHYMOD_IF_ERR_RETURN( 278 _quadra28_phy_status_dump(phy)); 279 return PHYMOD_E_NONE; 280 281 } 282 #endif /* PHYMOD_QUADRA28_SUPPORT */