portmod_chain.c (187125B)
1 2 /* 3 * 4 * 5 * 6 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 7 * 8 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 9 */ 10 11 #include <shared/bsl.h> 12 #include <soc/drv.h> 13 #include <soc/types.h> 14 #include <soc/error.h> 15 #include <soc/phyreg.h> 16 #include <soc/wb_engine.h> 17 #include <soc/portmod/portmod_internal.h> 18 #include <soc/portmod/portmod.h> 19 #include <soc/portmod/portmod_common.h> 20 #include <soc/portmod/portmod_dispatch.h> 21 #include <soc/portmod/portmod_legacy_phy.h> 22 #include <soc/portmod/portmod_chain.h> 23 24 #ifdef _ERR_MSG_MODULE_NAME 25 #error "_ERR_MSG_MODULE_NAME redefined" 26 #endif 27 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT 28 29 #define PM_EXTPHY_ITER(rv, phy_idx) while((PHYMOD_E_UNAVAIL== rv) && (phy_idx >= 0)) 30 #define PM_ALLPHY_ITER(rv, phy_idx) while(((rv == PHYMOD_E_NONE) || (rv == PHYMOD_E_UNAVAIL)) && (phy_idx >= 0)) 31 32 typedef enum xphy_wb_vars { 33 xphy_wb_is_initialized, /* keep track of xphy initialization state. */ 34 xphy_wb_phy_type, /* xphy probed phy type information. */ 35 xphy_wb_legacy_phy_present, /* indicates if port has legacy external phy */ 36 xphy_wb_ref_clk, /* xphy ref clk */ 37 xphy_wb_fw_load_method, /* xphy firmware load method. */ 38 xphy_wb_force_fw_load, /* xphy force firmware load indication. */ 39 xphy_wb_polarity, /* xphy polarity information. */ 40 xphy_wb_lane_map, /* xphy lane map information. */ 41 xphy_wb_device_op_mode, /* xphy device_op_mode of core_access. */ 42 xphy_wb_primary_core_num, /* xphy primary core information. */ 43 xphy_wb_core_probed, /* indicate xphy core has been probed or not */ 44 xphy_wb_active_lanes, /* indicate xphy lanes that are connected/used. */ 45 xphy_wb_num_var 46 }xphy_wb_vars_t; 47 48 typedef struct portmod_xphy_info_s { 49 phymod_core_access_t core_access; /**< core access */ 50 int wb_var_ids[xphy_wb_num_var]; 51 } portmod_xphy_info_t; 52 53 #define XPHY_WB_BUFFER_VERSION (4) 54 #define XPHY_IS_INITIALIZED_SET(unit, xphy_info, is_initialized) \ 55 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_is_initialized], &is_initialized); 56 #define XPHY_IS_INITIALIZED_GET(unit, xphy_info, is_initialized) \ 57 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_is_initialized], is_initialized); 58 59 #define XPHY_PHY_TYPE_SET(unit, xphy_info, phy_type) \ 60 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_phy_type], &phy_type); 61 #define XPHY_PHY_TYPE_GET(unit, xphy_info, phy_type) \ 62 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_phy_type], phy_type); 63 64 #define XPHY_LEGACY_PHY_PRESENT_SET(unit, xphy_info, leagacy_phy_present) \ 65 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_legacy_phy_present], &leagacy_phy_present); 66 #define XPHY_LEGACY_PHY_PRESENT_GET(unit, xphy_info, leagacy_phy_present) \ 67 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_legacy_phy_present], leagacy_phy_present); 68 69 #define XPHY_REF_CLK_SET(unit, xphy_info, ref_clk) \ 70 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_ref_clk], &ref_clk); 71 #define XPHY_REF_CLK_GET(unit, xphy_info, ref_clk) \ 72 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_ref_clk], ref_clk ); 73 74 #define XPHY_FW_LOAD_METHOD_SET(unit, xphy_info, fw_load_method) \ 75 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_fw_load_method], &fw_load_method); 76 #define XPHY_FW_LOAD_METHOD_GET(unit, xphy_info, fw_load_method) \ 77 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_fw_load_method], fw_load_method); 78 79 #define XPHY_FORCE_FW_LOAD_SET(unit, xphy_info, force_fw_load) \ 80 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_force_fw_load], &force_fw_load); 81 #define XPHY_FORCE_FW_LOAD_GET(unit, xphy_info, force_fw_load) \ 82 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_force_fw_load], force_fw_load); 83 84 #define XPHY_POLARITY_SET(unit, xphy_info, polarity) \ 85 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_polarity], &polarity); 86 #define XPHY_POLARITY_GET(unit, xphy_info, polarity) \ 87 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_polarity], polarity); 88 89 #define XPHY_LANE_MAP_SET(unit, xphy_info, lane_map) \ 90 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_lane_map], &lane_map); 91 #define XPHY_LANE_MAP_GET(unit, xphy_info, lane_map) \ 92 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_lane_map], lane_map ); 93 94 #define XPHY_DEVICE_OP_MODE_SET(unit, xphy_info, device_op_mode) \ 95 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_device_op_mode], &device_op_mode); 96 #define XPHY_DEVICE_OP_MODE_GET(unit, xphy_info, device_op_mode) \ 97 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_device_op_mode], device_op_mode); 98 99 #define XPHY_PRIMARY_CORE_NUM_SET(unit, xphy_info, primary_core_num ) \ 100 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_primary_core_num], &primary_core_num); 101 #define XPHY_PRIMARY_CORE_NUM_GET(unit, xphy_info, primary_core_num) \ 102 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_primary_core_num], primary_core_num); 103 104 #define XPHY_CORE_PROBED_SET(unit, xphy_info, core_probed) \ 105 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_core_probed], &core_probed); 106 #define XPHY_CORE_PROBED_GET(unit, xphy_info, core_probed) \ 107 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_core_probed], core_probed); 108 109 #define XPHY_ACTIVE_LANES_SET(unit, xphy_info, active_lanes) \ 110 SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_active_lanes], &active_lanes); 111 #define XPHY_ACTIVE_LANES_GET(unit, xphy_info, active_lanes) \ 112 SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, xphy_info->wb_var_ids[xphy_wb_active_lanes], active_lanes); 113 114 portmod_ext_phy_core_info_t *_ext_phy_info[SOC_MAX_NUM_DEVICES][MAX_PHYN][SOC_MAX_NUM_PORTS] = {{{NULL}}}; 115 116 STATIC 117 portmod_xphy_info_t* _xphy_info[SOC_MAX_NUM_DEVICES][PORTMOD_MAX_NUM_XPHY_SUPPORTED]; 118 119 STATIC void* _xphy_user_access[SOC_MAX_NUM_DEVICES * PORTMOD_MAX_NUM_XPHY_SUPPORTED] = {NULL}; 120 121 STATIC 122 phymod_core_init_config_t _xphy_core_config[SOC_MAX_NUM_DEVICES][PORTMOD_MAX_NUM_XPHY_SUPPORTED]; 123 124 STATIC 125 int _xphy_addr[SOC_MAX_NUM_DEVICES][PORTMOD_MAX_NUM_XPHY_SUPPORTED]; 126 127 int portmod_xphy_addr_set(int unit, int idx, int xphy_addr) 128 { 129 _xphy_addr[unit][idx] = xphy_addr; 130 return SOC_E_NONE; 131 } 132 133 int portmod_phychain_ext_phy_info_set(int unit, int phyn, int core_index, const portmod_ext_phy_core_info_t* core_info) 134 { 135 SOC_INIT_FUNC_DEFS; 136 137 if (((1 + MAX_PHYN) <= phyn) || (0 >= phyn)){ 138 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("phyn is out of the range of allowed external phys"))); 139 } 140 if(NULL == _ext_phy_info[unit][phyn - 1][core_index]){ 141 _ext_phy_info[unit][phyn - 1][core_index] = sal_alloc(sizeof(portmod_ext_phy_core_info_t), "core_info"); 142 if(NULL == _ext_phy_info[unit][phyn - 1][core_index]){ 143 _SOC_EXIT_WITH_ERR(SOC_E_MEMORY, (_SOC_MSG("phyn core info mem allocation failed"))); 144 } 145 } 146 sal_memcpy(_ext_phy_info[unit][phyn - 1][core_index], core_info, sizeof(portmod_ext_phy_core_info_t)); 147 148 exit: 149 SOC_FUNC_RETURN; 150 } 151 152 int portmod_phychain_ext_phy_info_get(int unit, int phyn, int core_index, portmod_ext_phy_core_info_t* core_info) 153 { 154 SOC_INIT_FUNC_DEFS; 155 156 if (((1 + MAX_PHYN) <= phyn) || (0 >= phyn)){ 157 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("phyn is out of the range of allowed external phys"))); 158 } 159 if(NULL == _ext_phy_info[unit][phyn - 1][core_index]){ 160 _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("for phyn core,the information is not available"))); 161 } 162 sal_memcpy(core_info, _ext_phy_info[unit][phyn - 1][core_index], sizeof(portmod_ext_phy_core_info_t)); 163 164 exit: 165 SOC_FUNC_RETURN; 166 } 167 168 int portmod_ext_phy_core_info_t_init(int unit, portmod_ext_phy_core_info_t* portmod_ext_phy_core_info) 169 { 170 SOC_INIT_FUNC_DEFS; 171 172 if(portmod_ext_phy_core_info == NULL){ 173 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, ("portmod_ext_phy_core_info NULL parameter")); 174 } 175 sal_memset(portmod_ext_phy_core_info, 0, sizeof(portmod_ext_phy_core_info_t)); 176 phymod_core_access_t_init(&portmod_ext_phy_core_info->core_access); 177 portmod_ext_phy_core_info->is_initialized = 0; 178 179 exit: 180 SOC_FUNC_RETURN; 181 } 182 183 int portmod_xphy_wb_buffer_init(int unit, uint32 wb_buffer_index, portmod_xphy_info_t* xphy_core_info) 184 { 185 /* Declare the common variables needed for warmboot */ 186 WB_ENGINE_INIT_TABLES_DEFS; 187 int wb_var_id, rv = 0; 188 int buffer_id = wb_buffer_index; /*required by SOC_WB_ENGINE_ADD_ Macros*/ 189 SOC_INIT_FUNC_DEFS; 190 191 COMPILER_REFERENCE(buffer_is_dynamic); 192 SOC_WB_ENGINE_ADD_BUFF(SOC_WB_ENGINE_PORTMOD, wb_buffer_index, "xphy", NULL, NULL, XPHY_WB_BUFFER_VERSION, 1, SOC_WB_ENGINE_PRE_RELEASE); 193 _SOC_IF_ERR_EXIT(rv); 194 195 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 196 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_initialized", wb_buffer_index, sizeof(uint32), NULL, VERSION(1)); 197 _SOC_IF_ERR_EXIT(rv); 198 xphy_core_info->wb_var_ids[xphy_wb_is_initialized ]= wb_var_id; 199 200 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 201 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "phy_type", wb_buffer_index, sizeof(uint32), NULL, VERSION(1)); 202 _SOC_IF_ERR_EXIT(rv); 203 xphy_core_info->wb_var_ids[xphy_wb_phy_type]= wb_var_id; 204 205 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 206 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_legacy_ext_phy", wb_buffer_index, sizeof(uint32), NULL, VERSION(2)); 207 _SOC_IF_ERR_EXIT(rv); 208 xphy_core_info->wb_var_ids[xphy_wb_legacy_phy_present]= wb_var_id; 209 210 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 211 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_ref_clk", wb_buffer_index, sizeof(phymod_ref_clk_t), NULL, VERSION(3)); 212 _SOC_IF_ERR_EXIT(rv); 213 xphy_core_info->wb_var_ids[xphy_wb_ref_clk]= wb_var_id; 214 215 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 216 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_fw_load_method", wb_buffer_index, sizeof(phymod_firmware_load_method_t ), NULL, VERSION(3)); 217 _SOC_IF_ERR_EXIT(rv); 218 xphy_core_info->wb_var_ids[xphy_wb_fw_load_method]= wb_var_id; 219 220 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 221 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_force_fw_load", wb_buffer_index, sizeof(int), NULL, VERSION(3)); 222 _SOC_IF_ERR_EXIT(rv); 223 xphy_core_info->wb_var_ids[xphy_wb_force_fw_load]= wb_var_id; 224 225 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 226 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_polarity", wb_buffer_index, sizeof(phymod_polarity_t ), NULL, VERSION(3)); 227 _SOC_IF_ERR_EXIT(rv); 228 xphy_core_info->wb_var_ids[xphy_wb_polarity]= wb_var_id; 229 230 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 231 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_lane_map", wb_buffer_index, sizeof(phymod_lane_map_t), NULL, VERSION(3)); 232 _SOC_IF_ERR_EXIT(rv); 233 xphy_core_info->wb_var_ids[xphy_wb_lane_map]= wb_var_id; 234 235 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 236 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_device_op_mode", wb_buffer_index, sizeof(uint32), NULL, VERSION(3)); 237 _SOC_IF_ERR_EXIT(rv); 238 xphy_core_info->wb_var_ids[xphy_wb_device_op_mode]= wb_var_id; 239 240 241 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 242 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_primary_core_num", wb_buffer_index, sizeof(uint32), NULL, VERSION(3)); 243 _SOC_IF_ERR_EXIT(rv); 244 xphy_core_info->wb_var_ids[xphy_wb_primary_core_num]= wb_var_id; 245 246 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 247 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_core_probed", wb_buffer_index, sizeof(int), NULL, VERSION(3)); 248 xphy_core_info->wb_var_ids[xphy_wb_core_probed]= wb_var_id; 249 _SOC_IF_ERR_EXIT(rv); 250 251 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 252 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "xphy_wb_active_lanes", wb_buffer_index, sizeof(uint32), NULL, VERSION(4)); 253 xphy_core_info->wb_var_ids[xphy_wb_active_lanes]= wb_var_id; 254 _SOC_IF_ERR_EXIT(rv); 255 256 _SOC_IF_ERR_EXIT(soc_wb_engine_init_buffer(unit, SOC_WB_ENGINE_PORTMOD, wb_buffer_index, FALSE)); 257 258 exit: 259 SOC_FUNC_RETURN; 260 } 261 262 STATIC 263 int _xphy_find_index(int unit, int xphy_addr, int* xphy_id) 264 { 265 int idx; 266 267 *xphy_id = PORTMOD_MAX_NUM_XPHY_SUPPORTED; 268 for (idx=0; idx<PORTMOD_MAX_NUM_XPHY_SUPPORTED; idx++) { 269 if (_xphy_info[unit][idx] != NULL) { 270 if (_xphy_info[unit][idx]->core_access.access.addr == xphy_addr) { 271 *xphy_id = idx; 272 return SOC_E_NONE; 273 } 274 } else { 275 if (*xphy_id == PORTMOD_MAX_NUM_XPHY_SUPPORTED) 276 *xphy_id = idx; 277 } 278 } 279 280 return SOC_E_PARAM; 281 } 282 283 int portmod_chain_xphy_add_by_index(int unit, int xphy_idx, int xphy_addr, const phymod_core_access_t* core_access) 284 { 285 int rv; 286 int max_pms=0; 287 uint32 wb_buffer_index; 288 phymod_dispatch_type_t phy_type; 289 phymod_ref_clk_t ref_clk; 290 phymod_firmware_load_method_t fw_load_method; 291 int is_initialized; 292 int core_probed; 293 uint32 active_lanes; 294 295 SOC_INIT_FUNC_DEFS; 296 297 /* if new one need to be added, create one. */ 298 if( NULL == _xphy_info[unit][xphy_idx]){ 299 300 _xphy_info[unit][xphy_idx] = sal_alloc(sizeof(portmod_xphy_info_t), "xphy_info"); 301 302 if(NULL == _xphy_info[unit][xphy_idx]){ 303 _SOC_EXIT_WITH_ERR(SOC_E_MEMORY, (_SOC_MSG("xphy core info mem allocation failed"))); 304 } 305 /* start with clean memory. */ 306 sal_memset(_xphy_info[unit][xphy_idx], 0, sizeof(portmod_xphy_info_t)); 307 308 } else { 309 /* existing one, does not need any action. */ 310 SOC_EXIT; 311 } 312 313 sal_memcpy(&_xphy_info[unit][xphy_idx]->core_access, core_access, sizeof(phymod_core_access_t)); 314 _xphy_info[unit][xphy_idx]->core_access.access.addr = xphy_addr; 315 316 /* initialize the warmboot variables */ 317 portmod_max_pms_get(unit, &max_pms); 318 wb_buffer_index = xphy_idx + max_pms + 1; 319 _SOC_IF_ERR_EXIT(portmod_xphy_wb_buffer_init(unit, wb_buffer_index, _xphy_info[unit][xphy_idx])); 320 321 /* if warmboot, restore the probed phy type into the phymod core_access. */ 322 if(SOC_WARM_BOOT(unit)){ 323 324 rv = XPHY_PHY_TYPE_GET(unit,_xphy_info[unit][xphy_idx], 325 &_xphy_info[unit][xphy_idx]->core_access.type); 326 _SOC_IF_ERR_EXIT(rv); 327 328 rv = XPHY_DEVICE_OP_MODE_GET(unit,_xphy_info[unit][xphy_idx], 329 &_xphy_info[unit][xphy_idx]->core_access.device_op_mode); 330 _SOC_IF_ERR_EXIT(rv); 331 332 } 333 334 if(!SOC_WARM_BOOT(unit)){ 335 portmod_xphy_db_addr_set(unit, xphy_idx, xphy_addr); 336 337 phy_type = phymodDispatchTypeInvalid; 338 rv = XPHY_PHY_TYPE_SET(unit,_xphy_info[unit][xphy_idx], phy_type); 339 _SOC_IF_ERR_EXIT(rv); 340 341 is_initialized =0; 342 rv = XPHY_IS_INITIALIZED_SET(unit,_xphy_info[unit][xphy_idx],is_initialized); 343 _SOC_IF_ERR_EXIT(rv); 344 345 ref_clk = phymodRefClkCount; 346 rv = XPHY_REF_CLK_SET(unit,_xphy_info[unit][xphy_idx],ref_clk); 347 _SOC_IF_ERR_EXIT(rv); 348 349 fw_load_method = phymodFirmwareLoadMethodCount; 350 rv = XPHY_FW_LOAD_METHOD_SET(unit,_xphy_info[unit][xphy_idx],fw_load_method); 351 _SOC_IF_ERR_EXIT(rv); 352 353 core_probed = 0; 354 rv = XPHY_CORE_PROBED_SET(unit,_xphy_info[unit][xphy_idx],core_probed); 355 _SOC_IF_ERR_EXIT(rv); 356 357 /* 358 * clear all the active lanes. 359 */ 360 active_lanes = 0; 361 rv = XPHY_ACTIVE_LANES_SET(unit,_xphy_info[unit][xphy_idx],active_lanes); 362 _SOC_IF_ERR_EXIT(rv); 363 364 } 365 exit: 366 SOC_FUNC_RETURN; 367 } 368 369 int portmod_chain_xphy_add(int unit, int xphy_addr, const phymod_core_access_t* core_access, int *xphy_idx_out) 370 { 371 int xphy_idx ; 372 SOC_INIT_FUNC_DEFS; 373 374 /* looking for the matching valid one, if found, skip and return. */ 375 *xphy_idx_out = PORTMOD_MAX_NUM_XPHY_SUPPORTED; 376 if (_xphy_find_index(unit,xphy_addr, xphy_idx_out) == SOC_E_NONE){ 377 /* 378 * if the xphy is already in database, the user_acc need to be 379 * release from caller. 380 */ 381 382 *xphy_idx_out = PORTMOD_XPHY_EXISTING_IDX; 383 SOC_EXIT; 384 } 385 xphy_idx = *xphy_idx_out; 386 387 if ( PORTMOD_MAX_NUM_XPHY_SUPPORTED <= xphy_idx){ 388 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("xphy_idx is out of the range of allowed external phys - 0- %d"), (PORTMOD_MAX_NUM_XPHY_SUPPORTED-1))); 389 } 390 391 _SOC_IF_ERR_EXIT(portmod_chain_xphy_add_by_index(unit, xphy_idx, xphy_addr, core_access)); 392 exit: 393 SOC_FUNC_RETURN; 394 } 395 396 int portmod_chain_xphy_user_access_store(int unit, int xphy_idx, void* user_acc) 397 { 398 _xphy_user_access[(unit * PORTMOD_MAX_NUM_XPHY_SUPPORTED)+xphy_idx] = user_acc; 399 return SOC_E_NONE; 400 } 401 402 403 void portmod_chain_xphy_user_access_release(int unit) 404 { 405 int idx; 406 portmod_default_user_access_t *local_user_access; 407 408 for (idx=0; idx<PORTMOD_MAX_NUM_XPHY_SUPPORTED; idx++) { 409 local_user_access = (portmod_default_user_access_t*)_xphy_user_access[(unit * PORTMOD_MAX_NUM_XPHY_SUPPORTED)+idx]; 410 if(local_user_access != NULL) { 411 if(local_user_access->mutex != NULL) { 412 sal_mutex_destroy(local_user_access->mutex); 413 } 414 sal_free(local_user_access); 415 _xphy_user_access[(unit * PORTMOD_MAX_NUM_XPHY_SUPPORTED)+idx] = NULL; 416 } 417 } 418 } 419 420 int _xphy_resource_release(int unit, int xphy_idx) 421 { 422 423 portmod_xphy_info_t* xphy_info; 424 SOC_INIT_FUNC_DEFS; 425 426 xphy_info = _xphy_info[unit][xphy_idx]; 427 428 if( xphy_info != NULL ) { 429 sal_free(_xphy_info[unit][xphy_idx]); 430 _xphy_info[unit][xphy_idx] = NULL ; 431 /* How to remove wb data for the xphy? */ 432 } 433 SOC_FUNC_RETURN; 434 } 435 436 int portmod_chain_xphy_delete(int unit, int xphy_addr) 437 { 438 int xphy_idx; 439 440 SOC_INIT_FUNC_DEFS; 441 442 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 443 _SOC_IF_ERR_EXIT(portmod_xphy_valid_phy_set (unit, xphy_idx, FALSE)); 444 445 /* release all resource of xphy_info */ 446 _SOC_IF_ERR_EXIT(_xphy_resource_release(unit, xphy_idx)); 447 448 exit: 449 SOC_FUNC_RETURN; 450 } 451 452 int portmod_chain_xphy_delete_all(int unit) 453 { 454 int xphy_idx; 455 456 SOC_INIT_FUNC_DEFS; 457 458 for(xphy_idx = 0; xphy_idx < PORTMOD_MAX_NUM_XPHY_SUPPORTED; xphy_idx++){ 459 /* release all resource of xphy_info */ 460 _SOC_IF_ERR_EXIT(_xphy_resource_release(unit, xphy_idx)); 461 } 462 exit: 463 SOC_FUNC_RETURN; 464 } 465 466 int portmod_xphy_core_access_set(int unit, uint32 xphy_addr, phymod_core_access_t *core_access, int is_legacy_phy) 467 { 468 int xphy_idx, rv; 469 SOC_INIT_FUNC_DEFS; 470 471 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 472 473 sal_memcpy( &_xphy_info[unit][xphy_idx]->core_access, core_access, sizeof(phymod_core_access_t)); 474 475 rv = XPHY_PHY_TYPE_SET(unit,_xphy_info[unit][xphy_idx], core_access->type); 476 _SOC_IF_ERR_EXIT(rv); 477 478 rv = XPHY_LEGACY_PHY_PRESENT_SET(unit,_xphy_info[unit][xphy_idx], is_legacy_phy); 479 _SOC_IF_ERR_EXIT(rv); 480 481 rv = XPHY_DEVICE_OP_MODE_SET(unit,_xphy_info[unit][xphy_idx], core_access->device_op_mode); 482 _SOC_IF_ERR_EXIT(rv); 483 484 exit: 485 SOC_FUNC_RETURN; 486 } 487 488 int portmod_xphy_core_access_get(int unit, uint32 xphy_addr, phymod_core_access_t *core_access, int* is_legacy_phy) 489 { 490 int rv; 491 int xphy_idx; 492 SOC_INIT_FUNC_DEFS; 493 494 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 495 sal_memcpy( core_access, &_xphy_info[unit][xphy_idx]->core_access, sizeof(phymod_core_access_t)); 496 497 rv = XPHY_PHY_TYPE_GET(unit,_xphy_info[unit][xphy_idx], &core_access->type); 498 _SOC_IF_ERR_EXIT(rv); 499 500 rv = XPHY_LEGACY_PHY_PRESENT_GET(unit,_xphy_info[unit][xphy_idx], is_legacy_phy); 501 _SOC_IF_ERR_EXIT(rv); 502 503 rv = XPHY_DEVICE_OP_MODE_GET(unit,_xphy_info[unit][xphy_idx], &core_access->device_op_mode); 504 _SOC_IF_ERR_EXIT(rv); 505 exit: 506 SOC_FUNC_RETURN; 507 } 508 509 int portmod_xphy_core_config_set(int unit, uint32 xphy_addr, phymod_core_init_config_t* core_config) 510 { 511 int xphy_idx ; 512 SOC_INIT_FUNC_DEFS; 513 514 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 515 sal_memcpy( &_xphy_core_config[unit][xphy_idx], core_config, sizeof(phymod_core_init_config_t)); 516 517 exit: 518 SOC_FUNC_RETURN; 519 } 520 521 int portmod_xphy_core_config_get(int unit, uint32 xphy_addr,phymod_core_init_config_t* core_config) 522 { 523 int xphy_idx ; 524 SOC_INIT_FUNC_DEFS; 525 526 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 527 sal_memcpy( core_config, &_xphy_core_config[unit][xphy_idx], sizeof(phymod_core_init_config_t)); 528 529 exit: 530 SOC_FUNC_RETURN; 531 } 532 533 534 int portmod_xphy_is_initialized_set(int unit, uint32 xphy_addr, int is_initialized) 535 { 536 int xphy_idx, rv; 537 SOC_INIT_FUNC_DEFS; 538 539 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 540 rv = XPHY_IS_INITIALIZED_SET(unit,_xphy_info[unit][xphy_idx], is_initialized); 541 _SOC_IF_ERR_EXIT(rv); 542 543 exit: 544 SOC_FUNC_RETURN; 545 } 546 547 int portmod_xphy_is_initialized_get(int unit, uint32 xphy_addr, int* is_initialized) 548 { 549 int xphy_idx, rv; 550 SOC_INIT_FUNC_DEFS; 551 552 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 553 rv = XPHY_IS_INITIALIZED_GET(unit,_xphy_info[unit][xphy_idx], is_initialized); 554 _SOC_IF_ERR_EXIT(rv); 555 556 exit: 557 SOC_FUNC_RETURN; 558 } 559 560 int portmod_xphy_phy_type_set(int unit, uint32 xphy_addr, phymod_dispatch_type_t phy_type) 561 { 562 int xphy_idx, rv; 563 SOC_INIT_FUNC_DEFS; 564 565 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 566 rv = XPHY_PHY_TYPE_SET(unit,_xphy_info[unit][xphy_idx], phy_type); 567 _SOC_IF_ERR_EXIT(rv); 568 569 exit: 570 SOC_FUNC_RETURN; 571 } 572 573 int portmod_xphy_phy_type_get(int unit, uint32 xphy_addr, phymod_dispatch_type_t* phy_type) 574 { 575 int xphy_idx, rv; 576 SOC_INIT_FUNC_DEFS; 577 578 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 579 rv = XPHY_PHY_TYPE_GET(unit,_xphy_info[unit][xphy_idx], phy_type); 580 _SOC_IF_ERR_EXIT(rv); 581 582 exit: 583 SOC_FUNC_RETURN; 584 } 585 586 int portmod_xphy_is_legacy_phy_set(int unit, uint32 xphy_addr, int is_legacy_phy) 587 { 588 int xphy_idx, rv; 589 SOC_INIT_FUNC_DEFS; 590 591 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 592 rv = XPHY_LEGACY_PHY_PRESENT_SET(unit,_xphy_info[unit][xphy_idx], is_legacy_phy); 593 _SOC_IF_ERR_EXIT(rv); 594 595 exit: 596 SOC_FUNC_RETURN; 597 } 598 599 int portmod_xphy_is_legacy_phy_get(int unit, uint32 xphy_addr, int* is_legacy_phy) 600 { 601 int xphy_idx, rv; 602 SOC_INIT_FUNC_DEFS; 603 604 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 605 rv = XPHY_LEGACY_PHY_PRESENT_GET(unit,_xphy_info[unit][xphy_idx], is_legacy_phy); 606 _SOC_IF_ERR_EXIT(rv); 607 608 exit: 609 SOC_FUNC_RETURN; 610 } 611 612 int portmod_xphy_ref_clk_set(int unit, uint32 xphy_addr, phymod_ref_clk_t ref_clk) 613 { 614 int xphy_idx, rv; 615 SOC_INIT_FUNC_DEFS; 616 617 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 618 rv = XPHY_REF_CLK_SET(unit,_xphy_info[unit][xphy_idx],ref_clk); 619 _SOC_IF_ERR_EXIT(rv); 620 621 exit: 622 SOC_FUNC_RETURN; 623 } 624 625 int portmod_xphy_ref_clk_get(int unit, uint32 xphy_addr, phymod_ref_clk_t* ref_clk) 626 { 627 int xphy_idx, rv; 628 SOC_INIT_FUNC_DEFS; 629 630 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 631 rv = XPHY_REF_CLK_GET(unit,_xphy_info[unit][xphy_idx],ref_clk); 632 _SOC_IF_ERR_EXIT(rv); 633 634 exit: 635 SOC_FUNC_RETURN; 636 } 637 638 int portmod_xphy_fw_load_method_set(int unit, uint32 xphy_addr, phymod_firmware_load_method_t fw_load_method) 639 { 640 int xphy_idx, rv; 641 SOC_INIT_FUNC_DEFS; 642 643 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 644 rv = XPHY_FW_LOAD_METHOD_SET(unit,_xphy_info[unit][xphy_idx], fw_load_method); 645 _SOC_IF_ERR_EXIT(rv); 646 647 exit: 648 SOC_FUNC_RETURN; 649 } 650 651 int portmod_xphy_fw_load_method_get(int unit, uint32 xphy_addr, phymod_firmware_load_method_t* fw_load_method) 652 { 653 int xphy_idx, rv; 654 SOC_INIT_FUNC_DEFS; 655 656 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 657 rv = XPHY_FW_LOAD_METHOD_GET(unit,_xphy_info[unit][xphy_idx], fw_load_method); 658 _SOC_IF_ERR_EXIT(rv); 659 660 exit: 661 SOC_FUNC_RETURN; 662 } 663 664 int portmod_xphy_force_fw_load_set(int unit, uint32 xphy_addr, int force_fw_load) 665 { 666 int xphy_idx, rv; 667 SOC_INIT_FUNC_DEFS; 668 669 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 670 rv = XPHY_FORCE_FW_LOAD_SET(unit,_xphy_info[unit][xphy_idx], force_fw_load); 671 _SOC_IF_ERR_EXIT(rv); 672 673 exit: 674 SOC_FUNC_RETURN; 675 } 676 677 int portmod_xphy_force_fw_load_get(int unit, uint32 xphy_addr, int* force_fw_load) 678 { 679 int xphy_idx, rv; 680 SOC_INIT_FUNC_DEFS; 681 682 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 683 rv = XPHY_FORCE_FW_LOAD_GET(unit,_xphy_info[unit][xphy_idx], force_fw_load); 684 _SOC_IF_ERR_EXIT(rv); 685 686 exit: 687 SOC_FUNC_RETURN; 688 } 689 690 int portmod_xphy_polarity_set(int unit, uint32 xphy_addr, phymod_polarity_t polarity) 691 { 692 int xphy_idx, rv; 693 SOC_INIT_FUNC_DEFS; 694 695 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 696 rv = XPHY_POLARITY_SET(unit,_xphy_info[unit][xphy_idx], polarity); 697 _SOC_IF_ERR_EXIT(rv); 698 699 exit: 700 SOC_FUNC_RETURN; 701 } 702 703 int portmod_xphy_polarity_get(int unit, uint32 xphy_addr, phymod_polarity_t* polarity) 704 { 705 int xphy_idx, rv; 706 SOC_INIT_FUNC_DEFS; 707 708 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 709 rv = XPHY_POLARITY_GET(unit,_xphy_info[unit][xphy_idx], polarity); 710 _SOC_IF_ERR_EXIT(rv); 711 712 exit: 713 SOC_FUNC_RETURN; 714 } 715 716 int portmod_xphy_lane_map_set(int unit, uint32 xphy_addr, phymod_lane_map_t lane_map) 717 { 718 int xphy_idx, rv; 719 SOC_INIT_FUNC_DEFS; 720 721 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 722 rv = XPHY_LANE_MAP_SET(unit,_xphy_info[unit][xphy_idx], lane_map); 723 _SOC_IF_ERR_EXIT(rv); 724 725 exit: 726 SOC_FUNC_RETURN; 727 } 728 729 int portmod_xphy_lane_map_get(int unit, uint32 xphy_addr, phymod_lane_map_t* lane_map) 730 { 731 int xphy_idx, rv; 732 SOC_INIT_FUNC_DEFS; 733 734 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 735 rv = XPHY_LANE_MAP_GET(unit,_xphy_info[unit][xphy_idx], lane_map); 736 _SOC_IF_ERR_EXIT(rv); 737 738 exit: 739 SOC_FUNC_RETURN; 740 } 741 742 int portmod_xphy_device_op_mode_set(int unit, uint32 xphy_addr, uint32 device_op_mode) 743 { 744 int xphy_idx, rv; 745 SOC_INIT_FUNC_DEFS; 746 747 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 748 rv = XPHY_DEVICE_OP_MODE_SET(unit,_xphy_info[unit][xphy_idx], device_op_mode); 749 _SOC_IF_ERR_EXIT(rv); 750 751 exit: 752 SOC_FUNC_RETURN; 753 } 754 755 int portmod_xphy_device_op_mode_get(int unit, uint32 xphy_addr, uint32* device_op_mode) 756 { 757 int xphy_idx, rv; 758 SOC_INIT_FUNC_DEFS; 759 760 _SOC_IF_ERR_EXIT(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 761 rv = XPHY_DEVICE_OP_MODE_GET(unit,_xphy_info[unit][xphy_idx], device_op_mode); 762 _SOC_IF_ERR_EXIT(rv); 763 764 exit: 765 SOC_FUNC_RETURN; 766 } 767 768 int portmod_xphy_primary_core_num_set(int unit, uint32 xphy_addr, uint32 primary_core_num) 769 { 770 int xphy_idx, rv; 771 SOC_INIT_FUNC_DEFS; 772 773 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 774 rv = XPHY_PRIMARY_CORE_NUM_SET(unit,_xphy_info[unit][xphy_idx], primary_core_num); 775 _SOC_IF_ERR_EXIT(rv); 776 777 exit: 778 SOC_FUNC_RETURN; 779 } 780 781 int portmod_xphy_primary_core_num_get(int unit, uint32 xphy_addr, uint32* primary_core_num) 782 { 783 int xphy_idx, rv; 784 SOC_INIT_FUNC_DEFS; 785 786 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 787 rv = XPHY_PRIMARY_CORE_NUM_GET(unit,_xphy_info[unit][xphy_idx], primary_core_num); 788 _SOC_IF_ERR_EXIT(rv); 789 790 exit: 791 SOC_FUNC_RETURN; 792 } 793 794 int portmod_xphy_core_probed_set(int unit, uint32 xphy_addr, int core_probed) 795 { 796 int xphy_idx, rv; 797 SOC_INIT_FUNC_DEFS; 798 799 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 800 rv = XPHY_CORE_PROBED_SET(unit,_xphy_info[unit][xphy_idx], core_probed); 801 _SOC_IF_ERR_EXIT(rv); 802 803 exit: 804 SOC_FUNC_RETURN; 805 } 806 807 int portmod_xphy_core_probed_get(int unit, uint32 xphy_addr, int* core_probed) 808 { 809 int xphy_idx, rv; 810 SOC_INIT_FUNC_DEFS; 811 812 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 813 rv = XPHY_CORE_PROBED_GET(unit,_xphy_info[unit][xphy_idx], core_probed); 814 _SOC_IF_ERR_EXIT(rv); 815 816 exit: 817 SOC_FUNC_RETURN; 818 } 819 820 int portmod_xphy_active_lane_set (int unit, uint32 xphy_addr, uint32 active_lanes) 821 { 822 int xphy_idx, rv; 823 SOC_INIT_FUNC_DEFS; 824 825 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 826 rv = XPHY_ACTIVE_LANES_SET(unit, _xphy_info[unit][xphy_idx], active_lanes) 827 _SOC_IF_ERR_EXIT(rv); 828 exit: 829 SOC_FUNC_RETURN; 830 } 831 832 int portmod_xphy_active_lane_get (int unit, uint32 xphy_addr, uint32 *active_lanes) 833 { 834 int xphy_idx, rv; 835 SOC_INIT_FUNC_DEFS; 836 837 SOC_IF_ERROR_RETURN(_xphy_find_index(unit,xphy_addr,&xphy_idx)); 838 rv = XPHY_ACTIVE_LANES_GET(unit, _xphy_info[unit][xphy_idx], active_lanes) 839 _SOC_IF_ERR_EXIT(rv); 840 exit: 841 SOC_FUNC_RETURN; 842 } 843 844 /* 845 * This function is used to get the working operation mode from ext-phy. 846 * It is mainly used to differ 1G pass thru mode and other modes like 847 *pcs_repeater/retimer mode. 848 */ 849 int portmod_port_phychain_operation_mode_get(int unit, int port, const phymod_phy_access_t* phy_access, 850 const int chain_length, 851 phymod_operation_mode_t* phy_op_mode) 852 { 853 int rv = PHYMOD_E_UNAVAIL; 854 int phy_index; 855 int is_legacy_phy = 0; 856 phymod_operation_mode_t op_mode = phymodOperationModeRetimer; 857 858 /* start from the most external phy. */ 859 phy_index = chain_length - 1; 860 861 /* if it is external phy, check to see if it is legacy phy. */ 862 if (phy_index > 0) { 863 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 864 if (rv != PHYMOD_E_NONE) return rv; 865 if (is_legacy_phy) { 866 rv = portmod_port_legacy_op_mode_get(unit, port, &op_mode); 867 } else { 868 if (phy_access[phy_index].access.lane_mask) { 869 rv = phymod_phy_op_mode_get(&phy_access[phy_index], &op_mode); 870 } else { 871 rv = PHYMOD_E_UNAVAIL; 872 } 873 } 874 } else { 875 op_mode = phymodOperationModeCount; 876 } 877 878 *phy_op_mode = op_mode; 879 880 return (rv); 881 } 882 883 int portmod_port_phychain_core_access_set(int unit, int phyn, int core_index, const phymod_core_access_t* core_access) 884 { 885 SOC_INIT_FUNC_DEFS; 886 887 if (((1 + MAX_PHYN) <= phyn) || (0 >= phyn)){ 888 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("phyn is out of the range of allowed external phys"))); 889 } 890 if(NULL != _ext_phy_info[unit][phyn - 1][core_index]){ 891 sal_memcpy(&(_ext_phy_info[unit][phyn - 1][core_index]->core_access), core_access, sizeof(phymod_core_access_t)); 892 } 893 894 exit: 895 SOC_FUNC_RETURN; 896 897 } 898 899 int portmod_port_phychain_core_access_get(int unit, int port, const int chain_length, int max_cores, phymod_core_access_t* core_access) 900 { 901 int phyn = 0; 902 int nof_cores = 0; 903 int is_most_ext = 0; 904 SOC_INIT_FUNC_DEFS; 905 906 if (((1 + MAX_PHYN) <= chain_length) || (0 >= chain_length)){ 907 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("chain_length is out of the range of allowed external phys"))); 908 } 909 for (phyn = 0; phyn < chain_length; phyn++) { 910 _SOC_IF_ERR_EXIT(portmod_port_core_access_get(unit, port, phyn, max_cores, &core_access[phyn], &nof_cores, &is_most_ext)); 911 } 912 913 exit: 914 SOC_FUNC_RETURN; 915 } 916 917 int portmod_port_phychain_core_probe(int unit, int port, phymod_core_access_t* core, 918 const int chain_length) 919 { 920 int rv = PHYMOD_E_UNAVAIL; 921 int phy_index; 922 int phy_addr = 0x0; 923 int is_phymod_probed=0; 924 int is_legacy_phy = 0; 925 926 PHYMOD_NULL_CHECK(core); 927 928 /* Most EXT first. */ 929 phy_index = chain_length - 1; 930 931 /* ALL PHYS */ 932 while(((rv == PHYMOD_E_NONE) || (rv == PHYMOD_E_UNAVAIL)) && (phy_index >= 0)) { 933 /* currently portmod supports only one external phy (1(int) + 1(ext)) 934 * external phy is the outermost one. check for legacy ext phy if present */ 935 if (phy_index) { 936 rv = phymod_core_probe(&(core[phy_index].access), &(core[phy_index].type), &is_phymod_probed); 937 938 if ( (rv == PHYMOD_E_NONE) && (!is_phymod_probed) ) 939 { 940 if(portmod_port_legacy_phy_probe(unit, port)) 941 { 942 is_legacy_phy = 1; 943 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 944 if (rv != PHYMOD_E_NONE) return rv; 945 /* Update the phy address in core access struct -- used by phy info */ 946 phy_addr = portmod_port_legacy_phy_addr_get(unit, port); 947 core[phy_index].access.addr = phy_addr; 948 rv = PHYMOD_E_NONE; 949 } 950 } 951 } else { 952 rv = phymod_core_probe( &(core[phy_index].access), &(core[phy_index].type), &is_phymod_probed); 953 } 954 phy_index--; 955 } 956 957 return(rv); 958 } 959 960 int portmod_port_phychain_core_identify (int unit, phymod_core_access_t* core, 961 const int chain_length, 962 uint32_t core_id, 963 uint32_t* identified) 964 { 965 int rv = PHYMOD_E_UNAVAIL; 966 return(rv); 967 } 968 969 int portmod_port_phychain_core_lane_map_get(int unit ,const phymod_core_access_t* core, 970 const int chain_length, 971 phymod_lane_map_t* lane_map) 972 { 973 int rv = PHYMOD_E_UNAVAIL; 974 int phy_index; 975 int is_legacy_phy = 0; 976 977 PHYMOD_NULL_CHECK(core); 978 979 /* Most EXT first. */ 980 phy_index = chain_length - 1; 981 982 /* Most EXT */ 983 while( (PHYMOD_E_UNAVAIL == rv) && (phy_index >= 0)) { 984 if (phy_index) { 985 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 986 if (rv != PHYMOD_E_NONE) return rv; 987 } 988 if (!is_legacy_phy) { 989 rv = phymod_core_lane_map_get(&core[phy_index], lane_map); 990 } 991 phy_index--; 992 } 993 return(rv); 994 } 995 996 int portmod_port_phychain_core_reset_set(int unit, const phymod_core_access_t* core, 997 const int chain_length, 998 phymod_reset_mode_t reset_mode, 999 phymod_reset_direction_t direction) 1000 { 1001 int rv = PHYMOD_E_UNAVAIL; 1002 int phy_index; 1003 int is_legacy_phy = 0; 1004 1005 PHYMOD_NULL_CHECK(core); 1006 1007 /* Most EXT first. */ 1008 phy_index = chain_length - 1; 1009 1010 /* ALL PHYS */ 1011 while(((rv == PHYMOD_E_NONE) || (rv == PHYMOD_E_UNAVAIL)) && (phy_index >= 0)) { 1012 if (phy_index) { 1013 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 1014 if (rv != PHYMOD_E_NONE) return rv; 1015 } 1016 if (!is_legacy_phy) { 1017 rv = phymod_core_reset_set(&core[phy_index], reset_mode, direction); 1018 } 1019 phy_index--; 1020 } 1021 return(rv); 1022 } 1023 1024 int portmod_port_phychain_core_reset_get(int unit, const phymod_core_access_t* core, 1025 const int chain_length, 1026 phymod_reset_mode_t reset_mode, 1027 phymod_reset_direction_t* direction ) 1028 { 1029 int rv = PHYMOD_E_UNAVAIL; 1030 int phy_index; 1031 int is_legacy_phy = 0; 1032 1033 PHYMOD_NULL_CHECK(core); 1034 1035 /* Most EXT first. */ 1036 phy_index = chain_length - 1; 1037 1038 /* Most EXT */ 1039 while((rv == PHYMOD_E_UNAVAIL) && (phy_index >= 0)) { 1040 if (phy_index) { 1041 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 1042 if (rv != PHYMOD_E_NONE) return rv; 1043 } 1044 if (!is_legacy_phy) { 1045 rv = phymod_core_reset_get(&core[phy_index], reset_mode, direction); 1046 } 1047 phy_index--; 1048 } 1049 1050 return(rv); 1051 } 1052 1053 int portmod_port_phychain_core_firmware_info_get(int unit, const phymod_core_access_t* core, 1054 const int chain_length, 1055 phymod_core_firmware_info_t* fw_info) 1056 { 1057 int rv = PHYMOD_E_UNAVAIL; 1058 int phy_index; 1059 int is_legacy_phy = 0; 1060 1061 PHYMOD_NULL_CHECK(core); 1062 1063 /* Most EXT first. */ 1064 phy_index = chain_length - 1; 1065 1066 /* Most EXT */ 1067 while((PHYMOD_E_UNAVAIL == rv) && (phy_index >= 0)) { 1068 if (phy_index) { 1069 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 1070 if (rv != PHYMOD_E_NONE) return rv; 1071 } 1072 if (!is_legacy_phy) { 1073 rv = phymod_core_firmware_info_get(&core[phy_index], fw_info); 1074 } 1075 phy_index--; 1076 } 1077 return(rv); 1078 } 1079 1080 1081 int portmod_port_phychain_loopback_get(int unit, int port, const phymod_phy_access_t* phy_access, 1082 const int chain_length, 1083 phymod_loopback_mode_t loopback, 1084 uint32_t *enable) 1085 { 1086 int rv = PHYMOD_E_UNAVAIL; 1087 int phy_index; 1088 int is_legacy_phy = 0; 1089 1090 PHYMOD_NULL_CHECK(phy_access); 1091 1092 /* Most EXT first. */ 1093 phy_index = chain_length - 1; 1094 1095 /* Most EXT */ 1096 while((PHYMOD_E_UNAVAIL == rv) && (phy_index >= 0)) { 1097 1098 is_legacy_phy = 0; 1099 1100 /* if it is external phy, check to see if it is legacy phy. */ 1101 if (phy_index > 0) { 1102 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1103 if (rv != PHYMOD_E_NONE) return rv; 1104 } 1105 1106 if (is_legacy_phy) { 1107 rv = portmod_port_legacy_loopback_get(unit, port, loopback, enable); 1108 1109 } else { 1110 if(phy_access[phy_index].access.lane_mask){ 1111 rv = phymod_phy_loopback_get(&phy_access[phy_index], loopback, enable); 1112 } else { 1113 rv = PHYMOD_E_NONE; 1114 } 1115 } 1116 phy_index--; 1117 } 1118 return(rv); 1119 } 1120 1121 int portmod_port_phychain_loopback_set(int unit, int port, const phymod_phy_access_t* phy_access, 1122 const int chain_length, 1123 phymod_loopback_mode_t loopback, 1124 uint32_t enable) 1125 { 1126 int rv = PHYMOD_E_UNAVAIL; 1127 int phy_index; 1128 int is_legacy_phy = 0; 1129 1130 PHYMOD_NULL_CHECK(phy_access); 1131 1132 /* Most EXT first. */ 1133 phy_index = chain_length - 1; 1134 1135 1136 /* Loopback should be enabled always on the outermost phy */ 1137 /* Most EXT */ 1138 while((PHYMOD_E_UNAVAIL == rv) && (phy_index >= 0)) { 1139 1140 is_legacy_phy = 0; 1141 1142 /* if it is external phy, check to see if it is legacy phy. */ 1143 if (phy_index > 0) { 1144 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1145 if (rv != PHYMOD_E_NONE) return rv; 1146 } 1147 1148 if (is_legacy_phy) { 1149 rv = portmod_port_legacy_loopback_set(unit, port, loopback, enable); 1150 } else { 1151 if(phy_access[phy_index].access.lane_mask){ 1152 rv = phymod_phy_loopback_set(&phy_access[phy_index], loopback, enable); 1153 } else { 1154 rv = PHYMOD_E_NONE; 1155 } 1156 1157 } 1158 1159 if (rv == PHYMOD_E_UNAVAIL) { 1160 if (enable != 0){ 1161 LOG_CLI((BSL_META_U(unit, 1162 "phy_index=%d Loopback=%d Unavail - try next in chain\n"), 1163 phy_index, loopback)); 1164 } 1165 } 1166 phy_index--; 1167 } 1168 return(rv); 1169 } 1170 1171 int portmod_port_phychain_firmware_core_config_set(int unit, const phymod_phy_access_t* phy_access, 1172 const int chain_length, 1173 phymod_firmware_core_config_t fw_core_config) 1174 { 1175 int rv = PHYMOD_E_UNAVAIL; 1176 int phy_index; 1177 int is_legacy_phy = 0; 1178 PHYMOD_NULL_CHECK(phy_access); 1179 1180 /* start from the most external phy. */ 1181 phy_index = chain_length - 1; 1182 1183 /* ALL PHYS */ 1184 while(((rv == PHYMOD_E_NONE) || (rv == PHYMOD_E_UNAVAIL)) && (phy_index >= 0)) { 1185 if (phy_index){ 1186 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1187 if (rv != PHYMOD_E_NONE) return rv; 1188 } 1189 if (!is_legacy_phy) { 1190 rv = phymod_phy_firmware_core_config_set(&phy_access[phy_index], fw_core_config); 1191 } 1192 phy_index--; 1193 } 1194 return(rv); 1195 } 1196 1197 1198 int phymod_chain_phy_firmware_core_config_get(int unit, const phymod_phy_access_t* phy_access, 1199 const int chain_length, 1200 phymod_firmware_core_config_t *fw_core_config) 1201 { 1202 int rv = PHYMOD_E_UNAVAIL; 1203 int phy_index; 1204 int is_legacy_phy = 0; 1205 1206 /* start from the most external phy. */ 1207 phy_index = chain_length - 1; 1208 1209 /* Most EXT */ 1210 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1211 if (phy_index){ 1212 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1213 if (rv != PHYMOD_E_NONE) return rv; 1214 } 1215 if (!is_legacy_phy) { 1216 rv = phymod_phy_firmware_core_config_get(&phy_access[phy_index], fw_core_config); 1217 } 1218 phy_index--; 1219 } 1220 return(rv); 1221 } 1222 1223 int portmod_port_phychain_firmware_lane_config_set(int unit, const phymod_phy_access_t* phy_access, 1224 const int chain_length, 1225 phymod_firmware_lane_config_t fw_lane_config) 1226 { 1227 int rv = PHYMOD_E_UNAVAIL; 1228 int phy_index; 1229 int is_legacy_phy = 0; 1230 1231 /* start from the most external phy. */ 1232 phy_index = chain_length - 1; 1233 1234 /* Most EXT */ 1235 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1236 if (phy_index){ 1237 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1238 if (rv != PHYMOD_E_NONE) return rv; 1239 } 1240 if (!is_legacy_phy) { 1241 rv = phymod_phy_firmware_lane_config_set(&phy_access[phy_index], fw_lane_config); 1242 } 1243 phy_index--; 1244 } 1245 return(rv); 1246 } 1247 1248 int portmod_port_phychain_firmware_lane_config_get(int unit, const phymod_phy_access_t* phy_access, 1249 const int chain_length, 1250 phymod_firmware_lane_config_t *fw_lane_config) 1251 { 1252 int rv = PHYMOD_E_UNAVAIL; 1253 int phy_index; 1254 int is_legacy_phy = 0; 1255 1256 /* start from the most external phy. */ 1257 phy_index = chain_length - 1; 1258 1259 /* Most EXT */ 1260 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1261 if (phy_index){ 1262 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1263 if (rv != PHYMOD_E_NONE) return rv; 1264 } 1265 if (!is_legacy_phy) { 1266 rv = phymod_phy_firmware_lane_config_get(&phy_access[phy_index], fw_lane_config); 1267 } 1268 phy_index--; 1269 } 1270 return(rv); 1271 } 1272 1273 int portmod_port_phychain_core_pll_sequencer_restart(int unit, const phymod_core_access_t* core, 1274 const int chain_length, 1275 uint32_t flags, 1276 phymod_sequencer_operation_t operation) 1277 { 1278 int rv = PHYMOD_E_UNAVAIL; 1279 int phy_index; 1280 int is_legacy_phy = 0; 1281 1282 /* start from the most external phy. */ 1283 phy_index = chain_length - 1; 1284 1285 /* ALL PHYS */ 1286 while(((rv == PHYMOD_E_NONE) || (rv == PHYMOD_E_UNAVAIL)) && (phy_index >= 0)) { 1287 if (phy_index){ 1288 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 1289 if (rv != PHYMOD_E_NONE) return rv; 1290 } 1291 if (!is_legacy_phy) { 1292 rv = phymod_core_pll_sequencer_restart(&core[phy_index], flags, operation); 1293 } 1294 phy_index--; 1295 } 1296 return(rv); 1297 } 1298 1299 int phymod_chain_core_wait_event(int unit, const phymod_core_access_t* core, 1300 const int chain_length, 1301 phymod_core_event_t event, 1302 uint32_t timeout) 1303 { 1304 int rv = PHYMOD_E_UNAVAIL; 1305 int phy_index; 1306 int is_legacy_phy = 0; 1307 1308 /* start from the most external phy. */ 1309 phy_index = chain_length - 1; 1310 1311 /* Most EXT */ 1312 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1313 if (phy_index){ 1314 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 1315 if (rv != PHYMOD_E_NONE) return rv; 1316 } 1317 if (!is_legacy_phy) { 1318 rv = phymod_core_wait_event(&core[phy_index], event, timeout); 1319 } 1320 phy_index--; 1321 } 1322 return(rv); 1323 } 1324 1325 int portmod_port_phychain_rx_restart(int unit, const phymod_phy_access_t* phy_access, 1326 const int chain_length) 1327 { 1328 int rv = PHYMOD_E_UNAVAIL; 1329 int phy_index; 1330 int is_legacy_phy = 0; 1331 1332 /* start from the most external phy. */ 1333 phy_index = chain_length - 1; 1334 1335 /* Most EXT */ 1336 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1337 if (phy_index){ 1338 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1339 if (rv != PHYMOD_E_NONE) return rv; 1340 } 1341 if (!is_legacy_phy) { 1342 rv = phymod_phy_rx_restart(&phy_access[phy_index]); 1343 } 1344 phy_index--; 1345 } 1346 return(rv); 1347 } 1348 1349 int portmod_port_phychain_polarity_set(int unit, const phymod_phy_access_t* phy_access, 1350 const int chain_length, 1351 const phymod_polarity_t* polarity) 1352 { 1353 int rv = PHYMOD_E_UNAVAIL; 1354 int phy_index; 1355 int is_legacy_phy = 0; 1356 1357 /* start from the most external phy. */ 1358 phy_index = chain_length - 1; 1359 1360 /* Most EXT */ 1361 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1362 if (phy_index){ 1363 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1364 if (rv != PHYMOD_E_NONE) return rv; 1365 } 1366 if (!is_legacy_phy) { 1367 rv = phymod_phy_polarity_set(&phy_access[phy_index], polarity); 1368 } 1369 phy_index--; 1370 } 1371 return(rv); 1372 } 1373 1374 1375 int portmod_port_phychain_polarity_get(int unit, const phymod_phy_access_t* phy_access, 1376 const int chain_length, 1377 phymod_polarity_t* polarity) 1378 { 1379 int rv = PHYMOD_E_UNAVAIL; 1380 int phy_index; 1381 int is_legacy_phy = 0; 1382 1383 /* start from the most external phy. */ 1384 phy_index = chain_length - 1; 1385 1386 /* Most EXT */ 1387 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1388 if (phy_index){ 1389 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1390 if (rv != PHYMOD_E_NONE) return rv; 1391 } 1392 if (!is_legacy_phy) { 1393 rv = phymod_phy_polarity_get(&phy_access[phy_index], polarity); 1394 } 1395 phy_index--; 1396 } 1397 return(rv); 1398 } 1399 1400 int portmod_port_phychain_tx_set(int unit, const phymod_phy_access_t* phy_access, 1401 const int chain_length, 1402 const phymod_tx_t tx[]) 1403 { 1404 int rv = PHYMOD_E_UNAVAIL; 1405 int phy_index; 1406 int i, port_start_lane=-1; 1407 phymod_phy_access_t phy_acc_copy; 1408 int is_legacy_phy = 0; 1409 1410 /* start from the most external phy. */ 1411 phy_index = chain_length - 1; 1412 1413 /* Most EXT */ 1414 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1415 is_legacy_phy = 0; 1416 1417 /* if it is external phy, check to see if it is legacy phy. */ 1418 if (phy_index > 0) { 1419 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1420 if (rv != PHYMOD_E_NONE) return rv; 1421 } 1422 1423 if (is_legacy_phy) { 1424 rv = portmod_port_legacy_tx_set(phy_access, chain_length, tx); 1425 } else { 1426 if(phy_access[phy_index].access.lane_mask){ 1427 sal_memcpy(&phy_acc_copy, &phy_access[phy_index], sizeof(phy_acc_copy)); 1428 /* set tx parameters for each lane of the core */ 1429 for(i=0; i<PHYMOD_MAX_LANES_PER_CORE; i++){ 1430 phy_acc_copy.access.lane_mask = 0x1 << i; 1431 if(phy_acc_copy.access.lane_mask & phy_access[phy_index].access.lane_mask){ 1432 /* port_start_lane is the index of the very first lane of the current 1433 * core. port_start_lane is not always 0. However, the tx[] data always 1434 * starts from index 0. For instance, a Dino 40G port could have its 1435 * first lane at 0b00010000 in phy_access.access.lane_mask. In this 1436 * case, tx[0] should be given to this fifth lane instead of tx[4]. 1437 */ 1438 if (port_start_lane == -1){ 1439 port_start_lane = i; 1440 } 1441 rv = phymod_phy_tx_set(&phy_acc_copy, &tx[i-port_start_lane]); 1442 SOC_IF_ERROR_RETURN(rv); 1443 } 1444 } 1445 } else { 1446 rv = PHYMOD_E_NONE; 1447 } 1448 } 1449 phy_index--; 1450 } 1451 return(rv); 1452 } 1453 1454 int portmod_port_phychain_tx_get(int unit, const phymod_phy_access_t* phy_access, 1455 const int chain_length, 1456 phymod_tx_t* tx) 1457 { 1458 int rv = PHYMOD_E_UNAVAIL; 1459 int phy_index; 1460 int i, port_start_lane=-1; 1461 phymod_phy_access_t phy_acc_copy; 1462 int is_legacy_phy = 0; 1463 1464 /* start from the most external phy. */ 1465 phy_index = chain_length - 1; 1466 1467 /* Most EXT */ 1468 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1469 if (phy_index){ 1470 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1471 if (rv != PHYMOD_E_NONE) return rv; 1472 } 1473 if (!is_legacy_phy) { 1474 if(phy_access[phy_index].access.lane_mask){ 1475 sal_memcpy(&phy_acc_copy, &phy_access[phy_index], sizeof(phy_acc_copy)); 1476 for(i=0; i<PHYMOD_MAX_LANES_PER_CORE; i++){ 1477 phy_acc_copy.access.lane_mask = 0x1 << i; 1478 if(phy_acc_copy.access.lane_mask & phy_access[phy_index].access.lane_mask){ 1479 /* See comments in portmod_port_phychain_tx_set for why there is a 1480 * discrepancy between lane_mask and tx[] in terms of lane index. 1481 */ 1482 if (port_start_lane == -1){ 1483 port_start_lane = i; 1484 } 1485 rv = phymod_phy_tx_get(&phy_acc_copy, &tx[i-port_start_lane]); 1486 if(rv!=PHYMOD_E_NONE){ 1487 return rv; 1488 } 1489 } 1490 } 1491 } 1492 } 1493 phy_index--; 1494 } 1495 return(rv); 1496 } 1497 1498 int portmod_port_phychain_media_type_tx_get(int unit, const phymod_phy_access_t* phy_access, 1499 const int chain_length, 1500 phymod_media_typed_t media, 1501 phymod_tx_t* tx) 1502 { 1503 int rv = PHYMOD_E_UNAVAIL; 1504 int phy_index; 1505 int is_legacy_phy = 0; 1506 1507 /* start from the most external phy. */ 1508 phy_index = chain_length - 1; 1509 1510 /* Most EXT */ 1511 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1512 if (phy_index) { 1513 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1514 if (rv != PHYMOD_E_NONE) return rv; 1515 } 1516 if (!is_legacy_phy){ 1517 rv = phymod_phy_media_type_tx_get(&phy_access[phy_index], media, tx); 1518 } 1519 phy_index--; 1520 } 1521 return(rv); 1522 } 1523 1524 int portmod_port_phychain_tx_override_set(int unit, const phymod_phy_access_t* phy_access, 1525 const int chain_length, 1526 const phymod_tx_override_t* tx_override) 1527 { 1528 int rv = PHYMOD_E_UNAVAIL; 1529 int phy_index; 1530 int is_legacy_phy = 0; 1531 1532 /* start from the most external phy. */ 1533 phy_index = chain_length - 1; 1534 1535 /* Most EXT */ 1536 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1537 if (phy_index){ 1538 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1539 if (rv != PHYMOD_E_NONE) return rv; 1540 } 1541 if (!is_legacy_phy) { 1542 rv = phymod_phy_tx_override_set(&phy_access[phy_index], tx_override); 1543 } 1544 phy_index--; 1545 } 1546 return(rv); 1547 } 1548 1549 int portmod_port_phychain_tx_override_get(int unit, const phymod_phy_access_t* phy_access, 1550 const int chain_length, 1551 phymod_tx_override_t* tx_override) 1552 { 1553 int rv = PHYMOD_E_UNAVAIL; 1554 int phy_index; 1555 int is_legacy_phy = 0; 1556 1557 /* start from the most external phy. */ 1558 phy_index = chain_length - 1; 1559 1560 /* Most EXT */ 1561 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1562 if (phy_index){ 1563 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1564 if (rv != PHYMOD_E_NONE) return rv; 1565 } 1566 if (!is_legacy_phy) { 1567 rv = phymod_phy_tx_override_get(&phy_access[phy_index], tx_override); 1568 } 1569 phy_index--; 1570 } 1571 return(rv); 1572 } 1573 1574 int portmod_port_phychain_txpi_config_set(int unit, const phymod_phy_access_t* phy_access, 1575 const int chain_length, 1576 const phymod_txpi_config_t* config) 1577 { 1578 int rv = PHYMOD_E_UNAVAIL; 1579 int phy_index; 1580 int is_legacy_phy = 0; 1581 1582 /* start from the most external phy. */ 1583 phy_index = chain_length - 1; 1584 1585 /* Most EXT */ 1586 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1587 if (phy_index){ 1588 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1589 if (rv != PHYMOD_E_NONE) return rv; 1590 } 1591 if (!is_legacy_phy) { 1592 rv = phymod_phy_txpi_config_set(&phy_access[phy_index], config); 1593 } 1594 phy_index--; 1595 } 1596 return(rv); 1597 } 1598 1599 int portmod_port_phychain_txpi_config_get(int unit, const phymod_phy_access_t* phy_access, 1600 const int chain_length, 1601 phymod_txpi_config_t* config) 1602 { 1603 int rv = PHYMOD_E_UNAVAIL; 1604 int phy_index; 1605 int is_legacy_phy = 0; 1606 1607 /* start from the most external phy. */ 1608 phy_index = chain_length - 1; 1609 1610 /* Most EXT */ 1611 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1612 if (phy_index){ 1613 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1614 if (rv != PHYMOD_E_NONE) return rv; 1615 } 1616 if (!is_legacy_phy) { 1617 rv = phymod_phy_txpi_config_get(&phy_access[phy_index], config); 1618 } 1619 phy_index--; 1620 } 1621 return(rv); 1622 } 1623 1624 int portmod_port_phychain_rx_set(int unit, const phymod_phy_access_t* phy_access, 1625 const int chain_length, 1626 const phymod_rx_t* rx) 1627 { 1628 int rv = PHYMOD_E_UNAVAIL; 1629 int phy_index; 1630 int is_legacy_phy = 0; 1631 1632 /* start from the most external phy. */ 1633 phy_index = chain_length - 1; 1634 1635 /* Most EXT */ 1636 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1637 if (phy_index){ 1638 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1639 if (rv != PHYMOD_E_NONE) return rv; 1640 } 1641 if (!is_legacy_phy) { 1642 rv = phymod_phy_rx_set(&phy_access[phy_index], rx); 1643 } 1644 phy_index--; 1645 } 1646 return(rv); 1647 } 1648 1649 int portmod_port_phychain_rx_get(int unit, const phymod_phy_access_t* phy_access, 1650 const int chain_length, 1651 phymod_rx_t* rx) 1652 { 1653 int rv = PHYMOD_E_UNAVAIL; 1654 int phy_index; 1655 int is_legacy_phy = 0; 1656 1657 /* start from the most external phy. */ 1658 phy_index = chain_length - 1; 1659 1660 /* Most EXT */ 1661 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1662 if (phy_index){ 1663 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1664 if (rv != PHYMOD_E_NONE) return rv; 1665 } 1666 if (!is_legacy_phy) { 1667 if (phy_index && (phy_access[phy_index].access.lane_mask == 0)) { 1668 rv = PHYMOD_E_NONE; 1669 } else { 1670 rv = phymod_phy_rx_get(&phy_access[phy_index], rx); 1671 } 1672 } 1673 phy_index--; 1674 } 1675 return(rv); 1676 } 1677 1678 int portmod_port_phychain_reset_set(int unit, int port, const phymod_phy_access_t* phy_access, 1679 const int chain_length, 1680 const phymod_phy_reset_t* reset) 1681 { 1682 int rv = PHYMOD_E_UNAVAIL; 1683 int phy_index; 1684 int is_legacy_phy = 0; 1685 1686 /* start from the most external phy. */ 1687 phy_index = chain_length - 1; 1688 1689 /* Most EXT */ 1690 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1691 1692 is_legacy_phy = 0; 1693 1694 /* if it is external phy, check to see if it is legacy phy. */ 1695 if (phy_index > 0) { 1696 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1697 if (rv != PHYMOD_E_NONE) return rv; 1698 } 1699 1700 1701 if (is_legacy_phy) { 1702 rv = portmod_port_legacy_phy_reset_set(unit, port); 1703 } else { 1704 if((phy_access[phy_index].access.lane_mask == 0) && phy_index) { 1705 rv = PHYMOD_E_NONE; 1706 } else { 1707 rv = phymod_phy_reset_set(&phy_access[phy_index], reset); 1708 } 1709 } 1710 phy_index--; 1711 } 1712 return(rv); 1713 } 1714 1715 int portmod_port_phychain_reset_get(int unit, const phymod_phy_access_t* phy_access, 1716 const int chain_length, 1717 phymod_phy_reset_t* reset) 1718 { 1719 int rv = PHYMOD_E_UNAVAIL; 1720 int phy_index; 1721 int is_legacy_phy = 0; 1722 1723 /* start from the most external phy. */ 1724 phy_index = chain_length - 1; 1725 1726 /* Most EXT */ 1727 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1728 if (phy_index){ 1729 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1730 if (rv != PHYMOD_E_NONE) return rv; 1731 } 1732 if (!is_legacy_phy) { 1733 rv = phymod_phy_reset_get(&phy_access[phy_index], reset); 1734 } 1735 phy_index--; 1736 } 1737 return(rv); 1738 } 1739 1740 int portmod_port_phychain_power_set(int unit, int port, const phymod_phy_access_t* phy_access, 1741 const int chain_length, uint32 flags, 1742 const phymod_phy_power_t* power) 1743 { 1744 int rv = PHYMOD_E_UNAVAIL; 1745 int phy_index; 1746 int is_legacy_phy = 0; 1747 1748 /* start from the most external phy. */ 1749 phy_index = chain_length - 1; 1750 1751 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 1752 return phymod_phy_power_set(&phy_access[0], power); 1753 } 1754 1755 /* Most EXT */ 1756 while((PHYMOD_E_UNAVAIL == rv) && (phy_index >= 0)) { 1757 is_legacy_phy = 0; 1758 1759 /* if it is external phy, check to see if it is legacy phy. */ 1760 if (phy_index > 0) { 1761 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1762 if (rv != PHYMOD_E_NONE) return rv; 1763 } 1764 1765 if (is_legacy_phy) { 1766 rv = portmod_port_legacy_power_set(unit, port, power); 1767 } else { 1768 if(phy_access[phy_index].access.lane_mask){ 1769 rv = phymod_phy_power_set(&phy_access[phy_index], power); 1770 } else { 1771 rv = PHYMOD_E_NONE; 1772 } 1773 } 1774 phy_index--; 1775 } 1776 return(rv); 1777 } 1778 1779 int portmod_port_phychain_power_get(int unit, int port, const phymod_phy_access_t* phy_access, 1780 const int chain_length, uint32 flags, 1781 phymod_phy_power_t* power) 1782 { 1783 int rv = PHYMOD_E_UNAVAIL; 1784 int phy_index; 1785 int is_legacy_phy = 0; 1786 1787 /* start from the most external phy. */ 1788 phy_index = chain_length - 1; 1789 1790 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 1791 return phymod_phy_power_get(&phy_access[0], power); 1792 } 1793 1794 /* Most EXT */ 1795 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1796 is_legacy_phy = 0; 1797 1798 /* if it is external phy, check to see if it is legacy phy. */ 1799 if (phy_index > 0) { 1800 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1801 if (rv != PHYMOD_E_NONE) return rv; 1802 } 1803 1804 if (is_legacy_phy) { 1805 rv = portmod_port_legacy_power_get(unit, port, power); 1806 } else { 1807 if(phy_access[phy_index].access.lane_mask){ 1808 rv = phymod_phy_power_get(&phy_access[phy_index], power); 1809 } else { 1810 rv = PHYMOD_E_NONE; 1811 } 1812 1813 } 1814 phy_index--; 1815 } 1816 return(rv); 1817 } 1818 1819 int portmod_port_phychain_tx_lane_control_set(int unit, int port, const phymod_phy_access_t* phy_access, 1820 const int chain_length, uint32 flags, 1821 phymod_phy_tx_lane_control_t tx_control) 1822 { 1823 int rv = PHYMOD_E_UNAVAIL; 1824 int phy_index; 1825 int is_legacy_phy = 0; 1826 1827 /* start from the most external phy. */ 1828 phy_index = chain_length - 1; 1829 1830 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 1831 return phymod_phy_tx_lane_control_set(&phy_access[0], tx_control); 1832 } 1833 1834 /* Most EXT */ 1835 /* Program only the outer most phy */ 1836 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1837 1838 is_legacy_phy = 0; 1839 1840 /* if it is external phy, check to see if it is legacy phy. */ 1841 if (phy_index > 0) { 1842 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1843 if (rv != PHYMOD_E_NONE) return rv; 1844 } 1845 1846 if (is_legacy_phy) { 1847 rv = portmod_port_legacy_tx_ln_ctrl_set(unit, port, &tx_control); 1848 } else { 1849 if(phy_access[phy_index].access.lane_mask){ 1850 rv = phymod_phy_tx_lane_control_set(&phy_access[phy_index], tx_control); 1851 } else { 1852 rv = PHYMOD_E_NONE; 1853 } 1854 1855 } 1856 phy_index--; 1857 } 1858 return(rv); 1859 } 1860 1861 int portmod_port_phychain_tx_lane_control_get(int unit, int port, const phymod_phy_access_t* phy_access, 1862 const int chain_length, uint32 flags, 1863 phymod_phy_tx_lane_control_t *tx_control) 1864 { 1865 int rv = PHYMOD_E_UNAVAIL; 1866 int phy_index; 1867 int is_legacy_phy = 0; 1868 1869 /* start from the most external phy. */ 1870 phy_index = chain_length - 1; 1871 1872 1873 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 1874 return phymod_phy_tx_lane_control_get(&phy_access[0], tx_control); 1875 } 1876 1877 /* Most EXT */ 1878 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1879 1880 is_legacy_phy = 0; 1881 1882 /* if it is external phy, check to see if it is legacy phy. */ 1883 if (phy_index > 0) { 1884 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1885 if (rv != PHYMOD_E_NONE) return rv; 1886 } 1887 1888 if (is_legacy_phy) { 1889 rv = portmod_port_legacy_tx_ln_ctrl_get(unit, port, tx_control); 1890 } else { 1891 if(phy_access[phy_index].access.lane_mask){ 1892 rv = phymod_phy_tx_lane_control_get(&phy_access[phy_index], tx_control); 1893 } else { 1894 rv = PHYMOD_E_NONE; 1895 } 1896 return rv; 1897 } 1898 /* 1899 * COVERITY 1900 * 1901 * This default is unreachable. It is kept intentionally as a defensive default for future 1902 * development. 1903 */ 1904 /* coverity[unreachable] */ 1905 phy_index--; 1906 } 1907 return(rv); 1908 } 1909 1910 int portmod_port_phychain_rx_lane_control_set(int unit, int port, const phymod_phy_access_t* phy_access, 1911 const int chain_length, uint32 flags, 1912 phymod_phy_rx_lane_control_t rx_control) 1913 { 1914 int rv = PHYMOD_E_UNAVAIL; 1915 int phy_index; 1916 int is_legacy_phy = 0; 1917 1918 /* start from the most external phy. */ 1919 phy_index = chain_length - 1; 1920 1921 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 1922 return phymod_phy_rx_lane_control_set(&phy_access[0], rx_control); 1923 } 1924 1925 /* Most EXT */ 1926 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1927 is_legacy_phy = 0; 1928 1929 /* if it is external phy, check to see if it is legacy phy. */ 1930 if (phy_index > 0) { 1931 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1932 if (rv != PHYMOD_E_NONE) return rv; 1933 } 1934 1935 if (is_legacy_phy) { 1936 rv = portmod_port_legacy_rx_ln_ctrl_set(unit, port, &rx_control); 1937 } else { 1938 if(phy_access[phy_index].access.lane_mask){ 1939 rv = phymod_phy_rx_lane_control_set(&phy_access[phy_index], rx_control); 1940 } else { 1941 rv = PHYMOD_E_NONE; 1942 } 1943 } 1944 phy_index--; 1945 } 1946 return(rv); 1947 } 1948 1949 int portmod_port_phychain_rx_lane_control_get(int unit, int port, const phymod_phy_access_t* phy_access, 1950 const int chain_length, uint32 flags, 1951 phymod_phy_rx_lane_control_t *rx_control) 1952 { 1953 int rv = PHYMOD_E_UNAVAIL; 1954 int phy_index; 1955 int is_legacy_phy = 0; 1956 1957 /* start from the most external phy. */ 1958 phy_index = chain_length - 1; 1959 1960 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 1961 return phymod_phy_rx_lane_control_get(&phy_access[0], rx_control); 1962 } 1963 1964 /* Most EXT */ 1965 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 1966 is_legacy_phy = 0; 1967 1968 /* if it is external phy, check to see if it is legacy phy. */ 1969 if (phy_index > 0) { 1970 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 1971 if (rv != PHYMOD_E_NONE) return rv; 1972 } 1973 1974 if (is_legacy_phy) { 1975 rv = portmod_port_legacy_rx_ln_ctrl_get(unit, port, rx_control); 1976 } else { 1977 if ((phy_access[phy_index].access.lane_mask == 0) && phy_index) { 1978 rv = PHYMOD_E_NONE; 1979 } else { 1980 rv = phymod_phy_rx_lane_control_get(&phy_access[phy_index], rx_control); 1981 } 1982 return rv; 1983 } 1984 /* 1985 * COVERITY 1986 * 1987 * This default is unreachable. It is kept intentionally as a defensive default for future 1988 * development. 1989 */ 1990 /* coverity[unreachable] */ 1991 phy_index--; 1992 } 1993 return(rv); 1994 } 1995 1996 int portmod_port_phychain_fec_enable_set(int unit, int port, const phymod_phy_access_t* phy_access, 1997 const int chain_length, uint32 flags, 1998 uint32_t enable) 1999 { 2000 int rv = PHYMOD_E_UNAVAIL; 2001 int phy_index; 2002 int is_legacy_phy = 0; 2003 2004 /* start from the most external phy. */ 2005 phy_index = chain_length - 1; 2006 2007 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 2008 return phymod_phy_fec_enable_set(&phy_access[0], enable); 2009 } 2010 2011 /* Most EXT */ 2012 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2013 is_legacy_phy = 0; 2014 2015 /* if it is external phy, check to see if it is legacy phy. */ 2016 if (phy_index > 0) { 2017 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2018 if (rv != PHYMOD_E_NONE) return rv; 2019 } 2020 2021 if (is_legacy_phy) { 2022 rv = portmod_port_legacy_fec_set(unit, port, enable); 2023 return rv; 2024 } else { 2025 rv = phymod_phy_fec_enable_set(&phy_access[phy_index], enable); 2026 return rv; 2027 } 2028 2029 /* 2030 * COVERITY 2031 * 2032 * This default is unreachable. It is kept intentionally as a defensive default for future 2033 * development. 2034 */ 2035 /* coverity[unreachable] */ 2036 phy_index--; 2037 } 2038 return(rv); 2039 } 2040 2041 int portmod_port_phychain_fec_enable_get(int unit, int port, const phymod_phy_access_t* phy_access, 2042 const int chain_length, uint32 flags, 2043 uint32_t *enable) 2044 { 2045 int rv = PHYMOD_E_UNAVAIL; 2046 int phy_index; 2047 int is_legacy_phy = 0; 2048 2049 /* start from the most external phy. */ 2050 phy_index = chain_length - 1; 2051 2052 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 2053 return phymod_phy_fec_enable_get(&phy_access[0], enable); 2054 } 2055 2056 /* Most EXT */ 2057 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2058 is_legacy_phy = 0; 2059 2060 /* if it is external phy, check to see if it is legacy phy. */ 2061 if (phy_index > 0) { 2062 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2063 if (rv != PHYMOD_E_NONE) return rv; 2064 } 2065 2066 if (is_legacy_phy) { 2067 rv = portmod_port_legacy_fec_get(unit, port, enable); 2068 return rv; 2069 } else { 2070 rv = phymod_phy_fec_enable_get(&phy_access[phy_index], enable); 2071 return rv; 2072 } 2073 /* 2074 * COVERITY 2075 * 2076 * This default is unreachable. It is kept intentionally as a defensive default for future 2077 * development. 2078 */ 2079 /* coverity[unreachable] */ 2080 phy_index--; 2081 } 2082 return(rv); 2083 } 2084 2085 int portmod_port_phychain_eee_set(int unit, int port, const phymod_phy_access_t* phy_access, 2086 const int chain_length, 2087 uint32_t enable) 2088 { 2089 int rv = PHYMOD_E_UNAVAIL; 2090 int phy_index; 2091 int is_legacy_phy = 0; 2092 2093 /* start from the most external phy. */ 2094 phy_index = chain_length - 1; 2095 2096 /* Most EXT */ 2097 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2098 2099 is_legacy_phy = 0; 2100 2101 /* if it is external phy, check to see if it is legacy phy. */ 2102 if (phy_index > 0) { 2103 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2104 if (rv != PHYMOD_E_NONE) return rv; 2105 } 2106 2107 if (is_legacy_phy) { 2108 rv = portmod_port_legacy_eee_set(unit, port, enable); 2109 return rv; 2110 } else { 2111 rv = phymod_phy_eee_set(&phy_access[phy_index], enable); 2112 return rv; 2113 } 2114 /* 2115 * COVERITY 2116 * 2117 * This default is unreachable. It is kept intentionally as a defensive default for future 2118 * development. 2119 */ 2120 /* coverity[unreachable] */ 2121 phy_index--; 2122 } 2123 return(rv); 2124 } 2125 2126 int portmod_port_phychain_eee_get(int unit, int port, const phymod_phy_access_t* phy_access, 2127 const int chain_length, 2128 uint32_t *enable) 2129 { 2130 int rv = PHYMOD_E_UNAVAIL; 2131 int phy_index; 2132 int is_legacy_phy = 0; 2133 2134 /* start from the most external phy. */ 2135 phy_index = chain_length - 1; 2136 2137 /* Most EXT */ 2138 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2139 is_legacy_phy = 0; 2140 2141 /* if it is external phy, check to see if it is legacy phy. */ 2142 if (phy_index > 0) { 2143 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2144 if (rv != PHYMOD_E_NONE) return rv; 2145 } 2146 2147 if (is_legacy_phy) { 2148 rv = portmod_port_legacy_eee_get(unit, port, enable); 2149 return rv; 2150 } else { 2151 rv = phymod_phy_eee_get(&phy_access[phy_index], enable); 2152 return rv; 2153 } 2154 /* 2155 * COVERITY 2156 * 2157 * This default is unreachable. It is kept intentionally as a defensive default for future 2158 * development. 2159 */ 2160 /* coverity[unreachable] */ 2161 phy_index--; 2162 } 2163 return(rv); 2164 } 2165 2166 int portmod_port_phychain_interface_config_set(int unit, int port, const phymod_phy_access_t* phy_access, 2167 const int chain_length, 2168 uint32_t flags, 2169 const phymod_phy_inf_config_t* config, 2170 phymod_interface_t serdes_interface, 2171 int ref_clk, 2172 const uint32 phy_init_flags) 2173 { 2174 int rv = PHYMOD_E_NONE; 2175 int phy_index; 2176 phymod_phy_inf_config_t int_config = *(phymod_phy_inf_config_t*)config; 2177 phymod_autoneg_control_t an; 2178 uint32_t an_done; 2179 int is_legacy_phy = 0; 2180 soc_port_if_t interface = SOC_PORT_IF_NULL; 2181 SOC_INIT_FUNC_DEFS; 2182 2183 /* start from the most external phy. */ 2184 phy_index = chain_length - 1; 2185 2186 if(phy_init_flags == PORTMOD_INIT_F_ALL_PHYS) { 2187 /* ALL PHYS */ 2188 while(((rv == PHYMOD_E_NONE) || (rv == PHYMOD_E_UNAVAIL)) && (phy_index >= 0)) { 2189 2190 is_legacy_phy = 0; 2191 2192 /* if it is external phy, check to see if it is legacy phy. */ 2193 if (phy_index > 0) { 2194 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2195 if (rv != PHYMOD_E_NONE) return rv; 2196 } 2197 2198 if (is_legacy_phy) { 2199 if (flags & PHYMOD_INTF_F_UPDATE_SPEED_LINKUP) { 2200 rv = portmod_port_legacy_an_get(unit, port, &an, &an_done); 2201 if (rv != PHYMOD_E_NONE) { 2202 return rv; 2203 } 2204 if (an.enable) { 2205 phy_index--; 2206 continue; 2207 } 2208 } 2209 rv = portmod_port_legacy_interface_config_set(unit, port, config); 2210 } else { 2211 if (phy_access[phy_index].access.lane_mask) { 2212 if (flags & PHYMOD_INTF_F_UPDATE_SPEED_LINKUP){ 2213 rv = phymod_phy_autoneg_get(&phy_access[phy_index], &an, &an_done); 2214 if (rv != PHYMOD_E_NONE) { 2215 return rv; 2216 } 2217 if (an.enable) { 2218 phy_index--; 2219 continue; 2220 } 2221 } 2222 if (phy_index < (chain_length-1)) { 2223 if ((serdes_interface != phymodInterfaceCount) && (phy_index == 0)) { 2224 /* if user specify the serdes_interface, it will get priority. */ 2225 int_config.interface_type = serdes_interface; 2226 2227 /* update the medium type within interface_mode according to the new interface type */ 2228 _SOC_IF_ERR_EXIT(portmod_intf_from_phymod_intf(unit, serdes_interface, &interface)); 2229 _SOC_IF_ERR_EXIT(portmod_media_type_from_port_intf(unit, interface, &int_config)); 2230 } else { 2231 rv = portmod_port_line_to_sys_intf_map(unit, &phy_access[phy_index+1], &phy_access[phy_index], port, 2232 config, ref_clk, phy_init_flags, 2233 int_config.interface_type, &int_config.interface_type); 2234 } 2235 if (rv) return (rv); 2236 } 2237 rv = phymod_phy_interface_config_set(&phy_access[phy_index], flags, &int_config); 2238 } 2239 } 2240 phy_index--; 2241 } 2242 } else if (phy_init_flags == PORTMOD_INIT_F_EXTERNAL_MOST_ONLY) { 2243 /* Most EXT, reprogram the internal and intermediate phy with existing setting. */ 2244 while((PHYMOD_E_NONE == rv) && (phy_index >= 0)) { 2245 2246 is_legacy_phy = 0; 2247 2248 /* if it is external phy, check to see if it is legacy phy. */ 2249 if (phy_index > 0) { 2250 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2251 if (rv != PHYMOD_E_NONE) return rv; 2252 } 2253 2254 if (is_legacy_phy) { 2255 rv = portmod_port_legacy_interface_config_set(unit, port, config); 2256 } else { 2257 if ((phy_index == (chain_length - 1)) || (!(flags & PHYMOD_INTF_F_SET_SPD_NO_TRIGGER))) { 2258 if (phy_index < (chain_length-1)) { 2259 if ((serdes_interface != phymodInterfaceCount) && (phy_index == 0)) { 2260 /* if user specify the serdes_interface, it will get priority. */ 2261 int_config.interface_type = serdes_interface; 2262 2263 /* update the medium type within interface_mode according to the new interface type */ 2264 _SOC_IF_ERR_EXIT(portmod_intf_from_phymod_intf(unit, serdes_interface, &interface)); 2265 _SOC_IF_ERR_EXIT(portmod_media_type_from_port_intf(unit, interface, &int_config)); 2266 } else { 2267 rv = portmod_port_line_to_sys_intf_map(unit, &phy_access[phy_index+1], &phy_access[phy_index], port, 2268 config, ref_clk, phy_init_flags, 2269 int_config.interface_type, &int_config.interface_type); 2270 } 2271 if (rv) return (rv); 2272 } 2273 2274 if(phy_access[phy_index].access.lane_mask){ 2275 rv = phymod_phy_interface_config_set(&phy_access[phy_index], flags, &int_config); 2276 } 2277 } 2278 } 2279 phy_index--; 2280 } 2281 } else if (phy_init_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 2282 while(phy_index >= 0) { 2283 if (phy_index < (chain_length-1)) { 2284 if ((serdes_interface != phymodInterfaceCount) && (phy_index == 0)) { 2285 /* if user specify the serdes_interface, it will get priority. */ 2286 int_config.interface_type = serdes_interface; 2287 2288 /* update the medium type within interface_mode according to the new interface type */ 2289 _SOC_IF_ERR_EXIT(portmod_intf_from_phymod_intf(unit, serdes_interface, &interface)); 2290 _SOC_IF_ERR_EXIT(portmod_media_type_from_port_intf(unit, interface, &int_config)); 2291 } else { 2292 rv = portmod_port_line_to_sys_intf_map(unit, &phy_access[phy_index+1], &phy_access[phy_index], port, 2293 config, ref_clk, phy_init_flags, 2294 int_config.interface_type, &int_config.interface_type); 2295 } 2296 if (rv) return (rv); 2297 } 2298 phy_index--; 2299 } 2300 rv = phymod_phy_interface_config_set(&phy_access[0], flags, &int_config); 2301 } 2302 return(rv); 2303 2304 exit: 2305 SOC_FUNC_RETURN; 2306 } 2307 2308 int portmod_port_phychain_interface_config_get(int unit, int port, const phymod_phy_access_t* phy_access, 2309 const int chain_length, 2310 uint32_t flags, 2311 phymod_ref_clk_t ref_clock, 2312 phymod_phy_inf_config_t* config, 2313 const uint32 phy_init_flags) 2314 { 2315 int rv = PHYMOD_E_UNAVAIL; 2316 int phy_index; 2317 int is_legacy_phy = 0; 2318 phymod_operation_mode_t op_mode = phymodOperationModeRetimer; 2319 int interface_available = 1; 2320 2321 /* start from the most external phy. */ 2322 phy_index = chain_length - 1; 2323 2324 2325 if (phy_init_flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) { 2326 return phymod_phy_interface_config_get(&phy_access[0], flags, ref_clock, config); 2327 } 2328 2329 /* Most EXT */ 2330 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2331 2332 is_legacy_phy = 0; 2333 2334 /* if it is external phy, check to see if it is legacy phy. */ 2335 if (phy_index > 0) { 2336 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2337 if (rv != PHYMOD_E_NONE) return rv; 2338 } 2339 2340 if (is_legacy_phy) { 2341 rv = portmod_port_legacy_interface_config_get(unit, port, config); 2342 return rv; 2343 } else { 2344 if ((phy_access[phy_index].access.lane_mask == 0) & phy_index) { 2345 rv = PHYMOD_E_NONE; 2346 } else { 2347 /* 2348 * If external phy, check to see if it is in Passthru mode, get 2349 * the interface information only when it is not in Passthru mode. 2350 * Otherwise, back off to the internal serdes. 2351 */ 2352 2353 interface_available = TRUE; 2354 if(phy_index){ 2355 rv = phymod_phy_op_mode_get(&phy_access[phy_index], &op_mode); 2356 if ((rv == PHYMOD_E_NONE) && (op_mode == phymodOperationModePassthru)) { 2357 interface_available = FALSE; 2358 } 2359 } 2360 2361 if (interface_available){ 2362 rv = phymod_phy_interface_config_get(&phy_access[phy_index], flags, ref_clock, config); 2363 } else { 2364 rv = PHYMOD_E_UNAVAIL; 2365 } 2366 } 2367 } 2368 /* 2369 * COVERITY 2370 * 2371 * This default is unreachable. It is kept intentionally as a defensive default for future 2372 * development. 2373 */ 2374 /* coverity[unreachable] */ 2375 phy_index--; 2376 } 2377 return(rv); 2378 } 2379 2380 int portmod_port_phychain_cl72_set(int unit, int port, const phymod_phy_access_t* phy_access, 2381 const int chain_length, 2382 uint32_t cl72_en) 2383 { 2384 int rv = PHYMOD_E_UNAVAIL; 2385 int phy_index; 2386 int is_legacy_phy = 0; 2387 2388 /* start from the most external phy. */ 2389 phy_index = chain_length - 1; 2390 2391 /* Most EXT */ 2392 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2393 is_legacy_phy = 0; 2394 2395 /* if it is external phy, check to see if it is legacy phy. */ 2396 if (phy_index > 0) { 2397 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2398 if (rv != PHYMOD_E_NONE) return rv; 2399 } 2400 2401 if (is_legacy_phy) { 2402 rv = portmod_port_legacy_cl72_set(unit, port, cl72_en); 2403 return rv; 2404 } else { 2405 if (phy_access[phy_index].access.lane_mask) { 2406 rv = phymod_phy_cl72_set(&phy_access[phy_index], cl72_en); 2407 } else { 2408 rv = PHYMOD_E_NONE; 2409 } 2410 return rv; 2411 } 2412 /* 2413 * COVERITY 2414 * 2415 * This default is unreachable. It is kept intentionally as a defensive default for future 2416 * development. 2417 */ 2418 /* coverity[unreachable] */ 2419 phy_index--; 2420 } 2421 return(rv); 2422 } 2423 2424 int portmod_port_phychain_cl72_get(int unit, const phymod_phy_access_t* phy_access, 2425 const int chain_length, 2426 uint32_t *cl72_en) 2427 { 2428 int rv = PHYMOD_E_UNAVAIL; 2429 int phy_index; 2430 int is_legacy_phy = 0; 2431 2432 /* start from the most external phy. */ 2433 phy_index = chain_length - 1; 2434 2435 /* Most EXT */ 2436 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2437 if (phy_index) { 2438 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2439 if (rv != PHYMOD_E_NONE) return rv; 2440 } 2441 if (!is_legacy_phy) { 2442 if(phy_access[phy_index].access.lane_mask){ 2443 rv = phymod_phy_cl72_get(&phy_access[phy_index], cl72_en); 2444 } else { 2445 rv = PHYMOD_E_NONE; 2446 } 2447 return rv; 2448 } 2449 phy_index--; 2450 } 2451 return(rv); 2452 } 2453 2454 int portmod_port_phychain_cl72_status_get(int unit, const phymod_phy_access_t* phy_access, 2455 const int chain_length, 2456 phymod_cl72_status_t *status) 2457 { 2458 int rv = PHYMOD_E_UNAVAIL; 2459 int phy_index; 2460 int is_legacy_phy = 0; 2461 2462 /* start from the most external phy. */ 2463 phy_index = chain_length - 1; 2464 2465 /* Most EXT */ 2466 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2467 if (phy_index) { 2468 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2469 if (rv != PHYMOD_E_NONE) return rv; 2470 } 2471 if (!is_legacy_phy) { 2472 rv = phymod_phy_cl72_status_get(&phy_access[phy_index], status); 2473 return rv; 2474 } 2475 phy_index--; 2476 } 2477 return(rv); 2478 } 2479 2480 int portmod_port_phychain_autoneg_ability_set(int unit, int port, const phymod_phy_access_t* phy_access, 2481 const int chain_length, uint32 flags, 2482 const phymod_autoneg_ability_t* an_ability, 2483 const portmod_port_ability_t * port_ability) 2484 { 2485 int rv = PHYMOD_E_UNAVAIL; 2486 int phy_index; 2487 int is_legacy_phy = 0; 2488 phymod_operation_mode_t phy_op_mode = phymodOperationModeRetimer; 2489 2490 rv = portmod_port_phychain_operation_mode_get(unit, port, phy_access, chain_length, &phy_op_mode); 2491 2492 if ((flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) || ((phy_op_mode == phymodOperationModePassthru) && 2493 (rv == PHYMOD_E_NONE))) { 2494 return phymod_phy_autoneg_ability_set(&phy_access[0], an_ability); 2495 } 2496 2497 /* start from the most external phy. */ 2498 phy_index = chain_length - 1; 2499 rv = PHYMOD_E_UNAVAIL; 2500 2501 /* Most EXT */ 2502 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2503 2504 is_legacy_phy = 0; 2505 2506 /* if it is external phy, check to see if it is legacy phy. */ 2507 if (phy_index > 0) { 2508 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2509 if (rv != PHYMOD_E_NONE) return rv; 2510 } 2511 2512 if (is_legacy_phy) { 2513 rv = portmod_port_legacy_advert_set(unit, port, port_ability); 2514 } else { 2515 if (phy_access[phy_index].access.lane_mask) { 2516 rv = phymod_phy_autoneg_ability_set(&phy_access[phy_index], an_ability); 2517 } else { 2518 rv = PHYMOD_E_NONE; 2519 } 2520 } 2521 phy_index--; 2522 } 2523 return(rv); 2524 } 2525 2526 int portmod_port_phychain_autoneg_ability_get(int unit, int port, const phymod_phy_access_t* phy_access, 2527 const int chain_length, uint32 flags, 2528 phymod_autoneg_ability_t* an_ability, 2529 portmod_port_ability_t * port_ability) 2530 { 2531 int rv = PHYMOD_E_UNAVAIL; 2532 int phy_index; 2533 int is_legacy_phy = 0; 2534 phymod_operation_mode_t phy_op_mode = phymodOperationModeRetimer; 2535 2536 rv = portmod_port_phychain_operation_mode_get(unit, port, phy_access, chain_length, &phy_op_mode); 2537 2538 /* When flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY returns 1, 2539 * it means that the current function is called by a legacy external 2540 * PHY API through the portmod callback function. In this case, 2541 * the target to retrieve information is always the internal PHY. 2542 */ 2543 if ((flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) || ((phy_op_mode == phymodOperationModePassthru) && 2544 (rv == PHYMOD_E_NONE))) { 2545 rv = phymod_phy_autoneg_ability_get(&phy_access[0], an_ability); 2546 2547 /* when there a legacy ext PHY attaching to a port, the caller of this function 2548 * expects that the retrieved abilities are stored in port_ability. 2549 */ 2550 portmod_common_phy_to_port_ability(an_ability, port_ability); 2551 return(rv); 2552 } 2553 2554 /* start from the most external phy. */ 2555 phy_index = chain_length - 1; 2556 rv = PHYMOD_E_UNAVAIL; 2557 2558 /* Most EXT */ 2559 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2560 2561 is_legacy_phy = 0; 2562 2563 /* if it is external phy, check to see if it is legacy phy. */ 2564 if (phy_index > 0) { 2565 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2566 if (rv != PHYMOD_E_NONE) return rv; 2567 } 2568 2569 if (is_legacy_phy) { 2570 rv = portmod_port_legacy_advert_get(unit, port, port_ability); 2571 } else { 2572 rv = phymod_phy_autoneg_ability_get(&phy_access[phy_index], an_ability); 2573 } 2574 phy_index--; 2575 } 2576 return(rv); 2577 } 2578 int portmod_port_phychain_local_ability_get(int unit, int port, const phymod_phy_access_t* phy_access, 2579 const int chain_length, 2580 portmod_port_ability_t* port_ability) 2581 { 2582 int rv = PHYMOD_E_UNAVAIL; 2583 int phy_index; 2584 int is_legacy_phy = 0; 2585 2586 /* start from the most external phy. */ 2587 phy_index = chain_length - 1; 2588 2589 /* Most EXT */ 2590 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2591 if (phy_index) { 2592 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2593 if (rv != PHYMOD_E_NONE) return rv; 2594 if (is_legacy_phy) { 2595 rv = portmod_port_legacy_ability_local_get(unit, port, port_ability); 2596 } else { 2597 return rv; 2598 } 2599 } else { 2600 return rv; 2601 } 2602 phy_index--; 2603 } 2604 return(rv); 2605 } 2606 int portmod_port_phychain_autoneg_restart_set(int unit, const phymod_phy_access_t* phy_access, 2607 const int chain_length) 2608 { 2609 int rv = PHYMOD_E_UNAVAIL; 2610 int phy_index; 2611 phymod_autoneg_control_t an; 2612 int is_legacy_phy = 0; 2613 2614 /* start from the most external phy. */ 2615 phy_index = chain_length - 1; 2616 2617 /* Most EXT */ 2618 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2619 if (phy_index) { 2620 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2621 if (rv != PHYMOD_E_NONE) return rv; 2622 } 2623 if (!is_legacy_phy) { 2624 phymod_autoneg_control_t_init(&an); 2625 an.an_mode = phymod_AN_MODE_CL37_SGMII; 2626 rv = phymod_phy_autoneg_restart_set(&phy_access[phy_index], &an); 2627 } 2628 phy_index--; 2629 } 2630 return(rv); 2631 2632 } 2633 2634 int portmod_port_phychain_autoneg_remote_ability_get(int unit, int port, const phymod_phy_access_t* phy_access, 2635 const int chain_length, uint32 flags, 2636 phymod_autoneg_ability_t* an_ability, 2637 portmod_port_ability_t * port_ability) 2638 { 2639 int rv = PHYMOD_E_UNAVAIL; 2640 int phy_index; 2641 int is_legacy_phy = 0; 2642 phymod_operation_mode_t phy_op_mode = phymodOperationModeRetimer; 2643 2644 rv = portmod_port_phychain_operation_mode_get(unit, port, phy_access, chain_length, &phy_op_mode); 2645 2646 /* When flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY returns 1, 2647 * it means that the current function is called by a legacy external 2648 * PHY API through the portmod callback function. In this case, 2649 * the target to retrieve information is always the internal PHY. 2650 */ 2651 if ((flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) || ((phy_op_mode == phymodOperationModePassthru) && 2652 (rv == PHYMOD_E_NONE))) { 2653 rv = phymod_phy_autoneg_remote_ability_get(&phy_access[0], an_ability); 2654 /* when there a legacy ext PHY attaching to a port, the caller of this function 2655 * expects that the retrieved abilities are stored in port_ability. 2656 */ 2657 portmod_common_phy_to_port_ability(an_ability, port_ability); 2658 return(rv); 2659 } 2660 2661 /* start from the most external phy. */ 2662 phy_index = chain_length - 1; 2663 rv = PHYMOD_E_UNAVAIL; 2664 2665 /* Most EXT */ 2666 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2667 is_legacy_phy = 0; 2668 2669 /* if it is external phy, check to see if it is legacy phy. */ 2670 if (phy_index > 0) { 2671 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2672 if (rv != PHYMOD_E_NONE) return rv; 2673 } 2674 2675 if (is_legacy_phy) { 2676 rv = portmod_port_legacy_ability_remote_get(unit, port, port_ability); 2677 } else { 2678 rv = phymod_phy_autoneg_remote_ability_get(&phy_access[phy_index], an_ability); 2679 } 2680 phy_index--; 2681 } 2682 return(rv); 2683 } 2684 2685 int portmod_port_phychain_autoneg_set(int unit, int port, const phymod_phy_access_t* phy_access, 2686 const int chain_length, uint32 flags, 2687 const phymod_autoneg_control_t *an_config) 2688 { 2689 int rv = PHYMOD_E_UNAVAIL; 2690 int phy_index; 2691 int is_legacy_phy = 0; 2692 phymod_operation_mode_t phy_op_mode = phymodOperationModeRetimer; 2693 2694 rv = portmod_port_phychain_operation_mode_get(unit, port, phy_access, chain_length, &phy_op_mode); 2695 2696 if ((flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) || ((phy_op_mode == phymodOperationModePassthru) && 2697 (rv == PHYMOD_E_NONE))) { 2698 return phymod_phy_autoneg_set(&phy_access[0], an_config); 2699 } 2700 2701 /* start from the most external phy. */ 2702 phy_index = chain_length - 1; 2703 rv = PHYMOD_E_UNAVAIL; 2704 2705 /* Most EXT */ 2706 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2707 2708 is_legacy_phy = 0; 2709 2710 /* if it is external phy, check to see if it is legacy phy. */ 2711 if (phy_index > 0) { 2712 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2713 if (rv != PHYMOD_E_NONE) return rv; 2714 } 2715 2716 if (is_legacy_phy) { 2717 rv = portmod_port_legacy_an_set(unit, port, an_config); 2718 } else { 2719 if (phy_access[phy_index].access.lane_mask) { 2720 rv = phymod_phy_autoneg_set(&phy_access[phy_index], an_config); 2721 } else { 2722 rv = PHYMOD_E_NONE; 2723 } 2724 } 2725 phy_index--; 2726 } 2727 return(rv); 2728 } 2729 2730 int portmod_port_phychain_autoneg_get(int unit, int port, const phymod_phy_access_t* phy_access, 2731 const int chain_length, uint32 flags, 2732 phymod_autoneg_control_t *an_config, 2733 uint32_t * an_done) 2734 { 2735 int rv = PHYMOD_E_UNAVAIL; 2736 int phy_index; 2737 int is_legacy_phy = 0; 2738 phymod_operation_mode_t phy_op_mode = phymodOperationModeRetimer; 2739 2740 rv = portmod_port_phychain_operation_mode_get(unit, port, phy_access, chain_length, &phy_op_mode); 2741 2742 if ((flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY) || ((phy_op_mode == phymodOperationModePassthru) && 2743 (rv == PHYMOD_E_NONE))) { 2744 return phymod_phy_autoneg_get(&phy_access[0], an_config, an_done); 2745 } 2746 2747 /* start from the most external phy. */ 2748 phy_index = chain_length - 1; 2749 rv = PHYMOD_E_UNAVAIL; 2750 2751 /* Most EXT */ 2752 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2753 is_legacy_phy = 0; 2754 2755 /* if it is external phy, check to see if it is legacy phy. */ 2756 if (phy_index > 0) { 2757 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2758 if (rv != PHYMOD_E_NONE) return rv; 2759 } 2760 2761 if (is_legacy_phy) { 2762 rv = portmod_port_legacy_an_get(unit, port, an_config, an_done); 2763 } else { 2764 if (phy_access[phy_index].access.lane_mask) { 2765 rv = phymod_phy_autoneg_get(&phy_access[phy_index], an_config, an_done); 2766 } else { 2767 rv = PHYMOD_E_NONE; 2768 *an_done = 1; 2769 } 2770 } 2771 phy_index--; 2772 } 2773 return(rv); 2774 } 2775 2776 int portmod_port_phychain_autoneg_status_get(int unit, int port, const phymod_phy_access_t* phy_access, 2777 const int chain_length, 2778 phymod_autoneg_status_t *status) 2779 { 2780 int rv = PHYMOD_E_UNAVAIL; 2781 int phy_index; 2782 phymod_autoneg_control_t an; 2783 uint32 an_done; 2784 int is_legacy_phy = 0; 2785 phymod_operation_mode_t phy_op_mode = phymodOperationModeRetimer; 2786 2787 rv = portmod_port_phychain_operation_mode_get(unit, port, phy_access, chain_length, &phy_op_mode); 2788 if ((phy_op_mode == phymodOperationModePassthru) && (rv == PHYMOD_E_NONE)) { 2789 rv = phymod_phy_autoneg_get(&phy_access[0], &an, &an_done); 2790 if (!rv) { 2791 status->enabled = an.enable; 2792 status->locked = an_done; 2793 } 2794 return rv; 2795 } 2796 2797 /* start from the most external phy. */ 2798 phy_index = chain_length - 1; 2799 rv = PHYMOD_E_UNAVAIL; 2800 2801 /* Most EXT */ 2802 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2803 is_legacy_phy = 0; 2804 2805 /* if it is external phy, check to see if it is legacy phy. */ 2806 if (phy_index > 0) { 2807 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2808 if (rv != PHYMOD_E_NONE) return rv; 2809 } 2810 2811 if (is_legacy_phy) { 2812 rv = portmod_port_legacy_an_get(unit, port, &an, &an_done); 2813 } else { 2814 rv = phymod_phy_autoneg_get(&phy_access[phy_index], &an, &an_done); 2815 } 2816 2817 phy_index--; 2818 if (!rv) { 2819 status->enabled = an.enable; 2820 status->locked = an_done; 2821 } 2822 return rv; 2823 } 2824 return(rv); 2825 } 2826 2827 int portmod_port_phychain_core_init(int unit, const phymod_core_access_t* core, 2828 const int chain_length, 2829 const phymod_core_init_config_t* init_config, 2830 const phymod_core_status_t* core_status) 2831 { 2832 int rv = PHYMOD_E_UNAVAIL; 2833 int phy_index; 2834 phymod_core_init_config_t core_config; 2835 int lane; 2836 phymod_core_access_t core_access; 2837 phymod_firmware_load_method_t fw_load_method; 2838 int force_fw_load; 2839 phymod_lane_map_t lane_map; 2840 int is_legacy_phy = 0; 2841 2842 /* start from the most external phy. */ 2843 phy_index = chain_length - 1; 2844 2845 /* ALL PHYS */ 2846 while(((rv == PHYMOD_E_NONE) || (rv == PHYMOD_E_UNAVAIL)) && (phy_index >= 0)) { 2847 if (phy_index) { 2848 /* core init for the legacy phys are done as part of phy init */ 2849 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 2850 if (rv != PHYMOD_E_NONE) return rv; 2851 } 2852 2853 if (!is_legacy_phy) { 2854 sal_memcpy(&core_config, init_config,sizeof(phymod_core_init_config_t)); 2855 if(phy_index > 0) { /* external phy */ 2856 2857 SOC_IF_ERROR_RETURN(portmod_xphy_core_access_get(unit, core[phy_index].access.addr, &core_access, &is_legacy_phy)); 2858 SOC_IF_ERROR_RETURN(portmod_xphy_fw_load_method_get(unit, core[phy_index].access.addr, &fw_load_method)); 2859 SOC_IF_ERROR_RETURN(portmod_xphy_force_fw_load_get(unit, core[phy_index].access.addr, &force_fw_load)); 2860 SOC_IF_ERROR_RETURN(portmod_xphy_lane_map_get(unit, core[phy_index].access.addr, &lane_map)); 2861 /* for external phys, FW load method is default to Internal 2862 unless it is force to NONE. */ 2863 core_config.firmware_load_method = fw_load_method; 2864 core_config.firmware_loader = NULL; 2865 if (force_fw_load == phymodFirmwareLoadForce) { 2866 PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&core_config); 2867 } 2868 else if (force_fw_load == phymodFirmwareLoadAuto) { 2869 PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&core_config); 2870 } 2871 2872 2873 /* config "no swap" for external phys.set later using APIs*/ 2874 for(lane=0 ; lane < lane_map.num_of_lanes; lane++) { 2875 core_config.lane_map.lane_map_rx[lane] = lane_map.lane_map_rx[lane]; 2876 core_config.lane_map.lane_map_tx[lane] = lane_map.lane_map_tx[lane]; 2877 } 2878 } 2879 rv = phymod_core_init(&core[phy_index], &core_config, core_status); 2880 } 2881 phy_index--; 2882 } 2883 return(rv); 2884 } 2885 2886 int portmod_port_phychain_pll_multiplier_get(int unit, const phymod_phy_access_t* phy_access, 2887 const int chain_length, 2888 uint32_t *core_vco_pll_multiplier) 2889 { 2890 int rv = PHYMOD_E_UNAVAIL; 2891 int phy_index; 2892 int is_legacy_phy = 0; 2893 2894 /* start from the most external phy. */ 2895 phy_index = chain_length - 1; 2896 2897 /* Most EXT */ 2898 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2899 if (phy_index) { 2900 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2901 if (rv != PHYMOD_E_NONE) return rv; 2902 } 2903 if (!is_legacy_phy) { 2904 rv = phymod_phy_pll_multiplier_get(&phy_access[phy_index], core_vco_pll_multiplier); 2905 } 2906 phy_index--; 2907 } 2908 return(rv); 2909 } 2910 2911 int portmod_port_phychain_phy_init(int unit, const phymod_phy_access_t* phy_access, 2912 const int chain_length, 2913 const phymod_phy_init_config_t* init_config) 2914 { 2915 int rv = PHYMOD_E_NONE; 2916 int tx_rv = PHYMOD_E_NONE; 2917 int phy_index; 2918 phymod_phy_init_config_t local_init_config; 2919 phymod_polarity_t polarity; 2920 phymod_tx_t phymod_tx; 2921 int i; 2922 int is_legacy_phy = 0; 2923 2924 sal_memcpy(&local_init_config, init_config, sizeof(phymod_phy_init_config_t)); 2925 2926 /* start from the most external phy. */ 2927 phy_index = chain_length - 1; 2928 2929 /* ALL PHYS */ 2930 while(((rv == PHYMOD_E_NONE) || (rv == PHYMOD_E_UNAVAIL)) && (phy_index >= 0)) { 2931 is_legacy_phy = 0; 2932 2933 /* if it is external phy, check to see if it is legacy phy. */ 2934 if (phy_index > 0) { 2935 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 2936 if (rv != PHYMOD_E_NONE) return rv; 2937 } 2938 2939 if (is_legacy_phy) { 2940 phy_index--; 2941 sal_memcpy(&local_init_config, init_config, sizeof(phymod_phy_init_config_t)); 2942 /* get default tx paramters for internal and intermediary phys. */ 2943 tx_rv = phymod_phy_media_type_tx_get(&phy_access[phy_index], phymodMediaTypeChipToChip, &phymod_tx); 2944 /* if we can get the custom default tx paramter, use it. Otherwise, use whatever it has in there. */ 2945 if( tx_rv == PHYMOD_E_NONE ) { 2946 for(i=0 ; i<PHYMOD_MAX_LANES_PER_CORE; i++) { 2947 local_init_config.tx[i].pre = phymod_tx.pre ; 2948 local_init_config.tx[i].main = phymod_tx.main ; 2949 local_init_config.tx[i].post = phymod_tx.post ; 2950 local_init_config.tx[i].post2= phymod_tx.post2; 2951 local_init_config.tx[i].post3= phymod_tx.post3; 2952 local_init_config.tx[i].amp = phymod_tx.amp ; 2953 } 2954 } 2955 2956 } else { 2957 sal_memcpy(&local_init_config, init_config, sizeof(phymod_phy_init_config_t)); 2958 2959 if(phy_index != 0 ){ 2960 phymod_polarity_t_init(&local_init_config.polarity); 2961 rv = portmod_xphy_polarity_get(unit, phy_access[phy_index].access.addr, &polarity); 2962 if (rv == PHYMOD_E_NONE) { 2963 sal_memcpy(&(local_init_config.polarity), &(polarity), sizeof(phymod_polarity_t)); 2964 2965 /* overwrite tx params if set by config. phymod_phy_init only use tx, not ext_phy_tx */ 2966 for(i=0 ; i<PHYMOD_MAX_LANES_PER_CORE; i++) { 2967 local_init_config.tx[i].pre = init_config->ext_phy_tx[i].pre ; 2968 local_init_config.tx[i].main = init_config->ext_phy_tx[i].main ; 2969 local_init_config.tx[i].post = init_config->ext_phy_tx[i].post ; 2970 local_init_config.tx[i].post2 = init_config->ext_phy_tx[i].post2 ; 2971 local_init_config.tx[i].post3 = init_config->ext_phy_tx[i].post3 ; 2972 local_init_config.tx[i].amp = init_config->ext_phy_tx[i].amp ; 2973 } 2974 } else return (rv); 2975 } 2976 2977 if(phy_access[phy_index].access.lane_mask){ 2978 rv = phymod_phy_init(&phy_access[phy_index], &local_init_config); 2979 } 2980 2981 phy_index--; 2982 } 2983 } /* while */ 2984 return(rv); 2985 } 2986 int portmod_port_phychain_rx_pmd_locked_get(int unit, const phymod_phy_access_t* phy_access, 2987 const int chain_length, 2988 uint32_t *rx_pmd_locked) 2989 { 2990 int rv = PHYMOD_E_UNAVAIL; 2991 int phy_index; 2992 int is_legacy_phy = 0; 2993 2994 /* start from the most external phy. */ 2995 phy_index = chain_length - 1; 2996 2997 /* Most EXT */ 2998 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 2999 if (phy_index) { 3000 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3001 if (rv != PHYMOD_E_NONE) return rv; 3002 } 3003 if (!is_legacy_phy) { 3004 rv = phymod_phy_rx_pmd_locked_get(&phy_access[phy_index], rx_pmd_locked); 3005 } 3006 phy_index--; 3007 } 3008 return(rv); 3009 } 3010 3011 int portmod_port_phychain_link_status_get(int unit, int port, const phymod_phy_access_t* phy_access, 3012 const int chain_length, uint32 flags, 3013 uint32_t *link_status) 3014 { 3015 int rv = PHYMOD_E_UNAVAIL; 3016 int phy_index; 3017 uint32_t link_status_chain = 0; 3018 int psc_repeater_mode = 0; 3019 int is_legacy_phy = 0; 3020 3021 /* start from the most external phy. */ 3022 phy_index = chain_length - 1; 3023 psc_repeater_mode = PHYMOD_INTF_CONFIG_PHY_PSC_REPEATER_MODE_GET(&phy_access[chain_length - 1]) ; 3024 3025 /* Check if the phy access is targetted for internal phy only */ 3026 if (flags == PORTMOD_INIT_F_INTERNAL_SERDES_ONLY){ 3027 return phymod_phy_link_status_get(&phy_access[0], link_status); 3028 } 3029 /*if external PHY is working on psc_repeater Most EXT & SerDes else Most EXT */ 3030 while(((PHYMOD_E_UNAVAIL== rv) || psc_repeater_mode) && (phy_index >= 0)) { 3031 is_legacy_phy = 0; 3032 3033 /* if it is external phy, check to see if it is legacy phy. */ 3034 if (phy_index > 0) { 3035 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3036 if (rv != PHYMOD_E_NONE) return rv; 3037 } 3038 3039 if (is_legacy_phy) { 3040 rv = portmod_port_legacy_phy_link_get(unit, port, link_status); 3041 } else { 3042 if (phy_access[phy_index].access.lane_mask) { 3043 rv = phymod_phy_link_status_get(&phy_access[phy_index], &link_status_chain); 3044 if (psc_repeater_mode) { 3045 if (phy_index == chain_length -1) { 3046 *link_status = link_status_chain ; 3047 } else { 3048 *link_status &= link_status_chain; 3049 } 3050 } else { 3051 *link_status = link_status_chain; 3052 } 3053 } else { 3054 rv = PHYMOD_E_NONE; 3055 *link_status = 1; 3056 } 3057 } 3058 phy_index--; 3059 } 3060 return(rv); 3061 } 3062 3063 int portmod_port_phychain_pcs_userspeed_set(int unit, const phymod_phy_access_t* phy_access, 3064 const int chain_length, 3065 const phymod_pcs_userspeed_config_t* config) 3066 { 3067 int rv = PHYMOD_E_UNAVAIL; 3068 int phy_index; 3069 int is_legacy_phy = 0; 3070 3071 /* start from the most external phy. */ 3072 phy_index = chain_length - 1; 3073 3074 /* Most EXT */ 3075 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3076 if (phy_index) { 3077 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3078 if (rv != PHYMOD_E_NONE) return rv; 3079 } 3080 if (!is_legacy_phy) { 3081 rv = phymod_phy_pcs_userspeed_set(&phy_access[phy_index], config); 3082 } 3083 phy_index--; 3084 } 3085 return(rv); 3086 } 3087 3088 int portmod_port_phychain_pcs_userspeed_get(int unit, const phymod_phy_access_t* phy_access, 3089 const int chain_length, 3090 phymod_pcs_userspeed_config_t* config) 3091 { 3092 int rv = PHYMOD_E_UNAVAIL; 3093 int phy_index; 3094 int is_legacy_phy = 0; 3095 3096 /* start from the most external phy. */ 3097 phy_index = chain_length - 1; 3098 3099 /* Most EXT */ 3100 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3101 if (phy_index) { 3102 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3103 if (rv != PHYMOD_E_NONE) return rv; 3104 }if (!is_legacy_phy) { 3105 rv = phymod_phy_pcs_userspeed_get(&phy_access[phy_index], config); 3106 } 3107 phy_index--; 3108 } 3109 return(rv); 3110 } 3111 3112 int portmod_port_phychain_reg_write(int unit, int port, const phymod_phy_access_t* phy_access, 3113 const int chain_length, 3114 int lane, 3115 uint32_t flags, 3116 uint32_t reg_addr, 3117 uint32_t reg_val) 3118 { 3119 int rv = PHYMOD_E_UNAVAIL; 3120 int phy_index; 3121 uint8 data8; 3122 int is_legacy_phy = 0; 3123 3124 if (flags & SOC_PHY_INTERNAL) { 3125 phy_index = 0; 3126 } else { 3127 /* start from the most external phy. */ 3128 phy_index = chain_length - 1; 3129 } 3130 3131 /* Most EXT if internal is not specified */ 3132 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3133 is_legacy_phy = 0; 3134 3135 /* if it is external phy, check to see if it is legacy phy. */ 3136 if (phy_index > 0) { 3137 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3138 if (rv != PHYMOD_E_NONE) return rv; 3139 } 3140 3141 if (is_legacy_phy) { 3142 rv = portmod_port_legacy_reg_write(unit, port, flags, reg_addr, reg_val); 3143 } else { 3144 if (flags & BCM_PORT_PHY_I2C_DATA8) { 3145 data8 = reg_val & 0xFF; 3146 rv = phymod_phy_i2c_write( &phy_access[phy_index], 0, 3147 BCM_PORT_PHY_I2C_DEVAD(reg_addr), 3148 BCM_PORT_PHY_I2C_REGAD(reg_addr), 3149 1,&data8 ); 3150 } else { 3151 if (lane >= 0) { 3152 reg_addr |= PHYMOD_REG_ACC_AER_IBLK_FORCE_LANE; 3153 reg_addr &= ~(0x7 << PHYMOD_REG_ACCESS_FLAGS_SHIFT); 3154 reg_addr |= ((lane & 0x7) << PHYMOD_REG_ACCESS_FLAGS_SHIFT); 3155 } 3156 rv = phymod_phy_reg_write(&phy_access[phy_index], reg_addr, reg_val); 3157 } 3158 } 3159 phy_index--; 3160 } 3161 return(rv); 3162 } 3163 3164 int portmod_port_phychain_reg_read(int unit, int port, const phymod_phy_access_t* phy_access, 3165 const int chain_length, 3166 int lane, 3167 uint32_t flags, 3168 uint32_t reg_addr, 3169 uint32_t *reg_val) 3170 { 3171 int rv = PHYMOD_E_UNAVAIL; 3172 int phy_index; 3173 uint8 data8; 3174 int is_legacy_phy = 0; 3175 3176 if (flags & SOC_PHY_INTERNAL) { 3177 phy_index = 0; 3178 } else { 3179 /* start from the most external phy. */ 3180 phy_index = chain_length - 1; 3181 } 3182 3183 /* Most EXT if internal is not specified */ 3184 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3185 is_legacy_phy = 0; 3186 3187 /* if it is external phy, check to see if it is legacy phy. */ 3188 if (phy_index > 0) { 3189 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3190 if (rv != PHYMOD_E_NONE) return rv; 3191 } 3192 3193 if (is_legacy_phy) { 3194 rv = portmod_port_legacy_reg_read(unit, port, flags, reg_addr, reg_val); 3195 } else { 3196 if (flags & BCM_PORT_PHY_I2C_DATA8) { 3197 rv = phymod_phy_i2c_read( &phy_access[phy_index], 0, 3198 BCM_PORT_PHY_I2C_DEVAD(reg_addr), 3199 BCM_PORT_PHY_I2C_REGAD(reg_addr), 3200 1, &data8); 3201 *reg_val = data8; 3202 } else { 3203 if (lane >= 0) { 3204 reg_addr |= PHYMOD_REG_ACC_AER_IBLK_FORCE_LANE; 3205 reg_addr &= ~(0x7 << PHYMOD_REG_ACCESS_FLAGS_SHIFT); 3206 reg_addr |= ((lane & 0x7) << PHYMOD_REG_ACCESS_FLAGS_SHIFT); 3207 } 3208 rv = phymod_phy_reg_read(&phy_access[phy_index], reg_addr, reg_val); 3209 } 3210 } 3211 phy_index--; 3212 } 3213 return(rv); 3214 } 3215 3216 int portmod_port_phychain_rx_slicer_position_set(int unit, const phymod_phy_access_t* phy_access, 3217 const int chain_length, 3218 uint32_t flags, 3219 const phymod_slicer_position_t* position) 3220 { 3221 int rv = PHYMOD_E_UNAVAIL; 3222 int phy_index; 3223 int is_legacy_phy = 0; 3224 3225 /* start from the most external phy. */ 3226 phy_index = chain_length - 1; 3227 3228 /* Most EXT */ 3229 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3230 if (phy_index) { 3231 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3232 if (rv != PHYMOD_E_NONE) return rv; 3233 } 3234 if (!is_legacy_phy) { 3235 rv = phymod_phy_rx_slicer_position_set(&phy_access[phy_index], flags, position); 3236 } 3237 phy_index--; 3238 } 3239 return(rv); 3240 } 3241 3242 int portmod_port_phychain_rx_slicer_position_get(int unit, const phymod_phy_access_t* phy_access, 3243 const int chain_length, 3244 uint32_t flags, 3245 phymod_slicer_position_t* position) 3246 { 3247 int rv = PHYMOD_E_UNAVAIL; 3248 int phy_index; 3249 int is_legacy_phy = 0; 3250 3251 /* start from the most external phy. */ 3252 phy_index = chain_length - 1; 3253 3254 /* Most EXT */ 3255 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3256 if (phy_index) { 3257 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3258 if (rv != PHYMOD_E_NONE) return rv; 3259 } 3260 if (!is_legacy_phy) { 3261 rv = phymod_phy_rx_slicer_position_get(&phy_access[phy_index], flags, position); 3262 } 3263 phy_index--; 3264 } 3265 return(rv); 3266 } 3267 3268 int portmod_port_phychain_rx_slicer_position_max_get(int unit, const phymod_phy_access_t* phy_access, 3269 const int chain_length, 3270 uint32_t flags, 3271 phymod_slicer_position_t* position_min, 3272 phymod_slicer_position_t* position_max) 3273 { 3274 int rv = PHYMOD_E_UNAVAIL; 3275 int phy_index; 3276 int is_legacy_phy = 0; 3277 3278 /* start from the most external phy. */ 3279 phy_index = chain_length - 1; 3280 3281 /* Most EXT */ 3282 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3283 if (phy_index) { 3284 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3285 if (rv != PHYMOD_E_NONE) return rv; 3286 } 3287 if (!is_legacy_phy) { 3288 rv = phymod_phy_rx_slicer_position_max_get(&phy_access[phy_index], flags, position_min, position_max); 3289 } 3290 phy_index--; 3291 } 3292 return(rv); 3293 } 3294 3295 int portmod_port_phychain_prbs_config_set(int unit, const phymod_phy_access_t* phy_access, 3296 const int chain_length, 3297 uint32_t flags, 3298 const phymod_prbs_t* prbs) 3299 { 3300 int rv = PHYMOD_E_UNAVAIL; 3301 int phy_index; 3302 int is_legacy_phy = 0; 3303 3304 /* start from the most external phy. */ 3305 phy_index = chain_length - 1; 3306 3307 /* Most EXT */ 3308 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3309 if (phy_index) { 3310 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3311 if (rv != PHYMOD_E_NONE) return rv; 3312 } 3313 if (!is_legacy_phy) { 3314 rv = phymod_phy_prbs_config_set(&phy_access[phy_index], flags, prbs); 3315 } 3316 phy_index--; 3317 } 3318 return(rv); 3319 } 3320 3321 int portmod_port_phychain_prbs_config_get(int unit, const phymod_phy_access_t* phy_access, 3322 const int chain_length, 3323 uint32_t flags, 3324 phymod_prbs_t* prbs) 3325 { 3326 int rv = PHYMOD_E_UNAVAIL; 3327 int phy_index; 3328 int is_legacy_phy = 0; 3329 3330 /* start from the most external phy. */ 3331 phy_index = chain_length - 1; 3332 3333 /* Most EXT */ 3334 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3335 if (phy_index) { 3336 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3337 if (rv != PHYMOD_E_NONE) return rv; 3338 } 3339 if (!is_legacy_phy) { 3340 rv = phymod_phy_prbs_config_get(&phy_access[phy_index], flags, prbs); 3341 } 3342 phy_index--; 3343 } 3344 return(rv); 3345 } 3346 3347 int portmod_port_phychain_prbs_enable_set(int unit, const phymod_phy_access_t* phy_access, 3348 const int chain_length, 3349 uint32_t flags, 3350 uint32_t enable) 3351 { 3352 int rv = PHYMOD_E_UNAVAIL; 3353 int phy_index; 3354 int is_legacy_phy = 0; 3355 3356 /* start from the most external phy. */ 3357 phy_index = chain_length - 1; 3358 3359 /* Most EXT */ 3360 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3361 if (phy_index) { 3362 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3363 if (rv != PHYMOD_E_NONE) return rv; 3364 } 3365 if (!is_legacy_phy) { 3366 rv = phymod_phy_prbs_enable_set(&phy_access[phy_index], flags, enable); 3367 } 3368 phy_index--; 3369 } 3370 return(rv); 3371 } 3372 3373 int portmod_port_phychain_prbs_enable_get(int unit, const phymod_phy_access_t* phy_access, 3374 const int chain_length, 3375 uint32_t flags, 3376 uint32_t *enable) 3377 { 3378 int rv = PHYMOD_E_UNAVAIL; 3379 int phy_index; 3380 int is_legacy_phy = 0; 3381 3382 /* start from the most external phy. */ 3383 phy_index = chain_length - 1; 3384 3385 /* Most EXT */ 3386 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3387 if (phy_index) { 3388 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3389 if (rv != PHYMOD_E_NONE) return rv; 3390 } 3391 if (!is_legacy_phy) { 3392 rv = phymod_phy_prbs_enable_get(&phy_access[phy_index], flags, enable); 3393 } 3394 phy_index--; 3395 } 3396 return(rv); 3397 } 3398 3399 int portmod_port_phychain_prbs_status_get(int unit, const phymod_phy_access_t* phy_access, 3400 const int chain_length, 3401 uint32_t flags, 3402 phymod_prbs_status_t *prbs_status) 3403 { 3404 int rv = PHYMOD_E_UNAVAIL; 3405 int phy_index; 3406 int is_legacy_phy = 0; 3407 3408 /* start from the most external phy. */ 3409 phy_index = chain_length - 1; 3410 3411 /* Most EXT */ 3412 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3413 if (phy_index) { 3414 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3415 if (rv != PHYMOD_E_NONE) return rv; 3416 } 3417 if (!is_legacy_phy) { 3418 rv = phymod_phy_prbs_status_get(&phy_access[phy_index], flags, prbs_status); 3419 } 3420 phy_index--; 3421 } 3422 return(rv); 3423 } 3424 3425 3426 int portmod_port_phychain_pattern_config_set(int unit, const phymod_phy_access_t* phy_access, 3427 const int chain_length, 3428 const phymod_pattern_t* pattern) 3429 { 3430 int rv = PHYMOD_E_UNAVAIL; 3431 int phy_index; 3432 int is_legacy_phy = 0; 3433 3434 /* start from the most external phy. */ 3435 phy_index = chain_length - 1; 3436 3437 /* Most EXT */ 3438 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3439 if (phy_index) { 3440 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3441 if (rv != PHYMOD_E_NONE) return rv; 3442 } 3443 if (!is_legacy_phy) { 3444 rv = phymod_phy_pattern_config_set(&phy_access[phy_index], pattern); 3445 } 3446 phy_index--; 3447 } 3448 return(rv); 3449 } 3450 3451 int portmod_port_phychain_pattern_config_get(int unit, const phymod_phy_access_t* phy_access, 3452 const int chain_length, 3453 phymod_pattern_t* pattern) 3454 { 3455 int rv = PHYMOD_E_UNAVAIL; 3456 int phy_index; 3457 int is_legacy_phy = 0; 3458 3459 /* start from the most external phy. */ 3460 phy_index = chain_length - 1; 3461 3462 /* Most EXT */ 3463 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3464 if (phy_index) { 3465 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3466 if (rv != PHYMOD_E_NONE) return rv; 3467 } 3468 if (!is_legacy_phy) { 3469 rv = phymod_phy_pattern_config_get(&phy_access[phy_index], pattern); 3470 } 3471 phy_index--; 3472 } 3473 return(rv); 3474 } 3475 3476 int portmod_port_phychain_pattern_enable_set(int unit, const phymod_phy_access_t* phy_access, 3477 const int chain_length, 3478 uint32_t enable, 3479 phymod_pattern_t* pattern) 3480 { 3481 int rv = PHYMOD_E_UNAVAIL; 3482 int phy_index; 3483 int is_legacy_phy = 0; 3484 3485 /* start from the most external phy. */ 3486 phy_index = chain_length - 1; 3487 3488 /* Most EXT */ 3489 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3490 if (phy_index) { 3491 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3492 if (rv != PHYMOD_E_NONE) return rv; 3493 } 3494 if (!is_legacy_phy) { 3495 rv = phymod_phy_pattern_enable_set(&phy_access[phy_index], enable, pattern); 3496 } 3497 phy_index--; 3498 } 3499 return(rv); 3500 } 3501 3502 int portmod_port_phychain_pattern_enable_get(int unit, const phymod_phy_access_t* phy_access, 3503 const int chain_length, 3504 uint32_t *enable) 3505 { 3506 int rv = PHYMOD_E_UNAVAIL; 3507 int phy_index; 3508 int is_legacy_phy = 0; 3509 3510 /* start from the most external phy. */ 3511 phy_index = chain_length - 1; 3512 3513 /* Most EXT */ 3514 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3515 if (phy_index) { 3516 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3517 if (rv != PHYMOD_E_NONE) return rv; 3518 } 3519 if (!is_legacy_phy) { 3520 rv = phymod_phy_pattern_enable_get(&phy_access[phy_index], enable); 3521 } 3522 phy_index--; 3523 } 3524 return(rv); 3525 } 3526 3527 int portmod_port_phychain_core_diagnostics_get(int unit, const phymod_core_access_t* core, 3528 const int chain_length, 3529 phymod_core_diagnostics_t* diag) 3530 { 3531 int rv = PHYMOD_E_UNAVAIL; 3532 int phy_index; 3533 int is_legacy_phy = 0; 3534 3535 PHYMOD_NULL_CHECK(core); 3536 3537 /* Most EXT first. */ 3538 phy_index = chain_length - 1; 3539 3540 /* Most EXT */ 3541 while( (PHYMOD_E_UNAVAIL == rv) && (phy_index >= 0)) { 3542 if (phy_index) { 3543 rv = portmod_xphy_is_legacy_phy_get(unit, core[phy_index].access.addr, &is_legacy_phy); 3544 if (rv != PHYMOD_E_NONE) return rv; 3545 } 3546 if (!is_legacy_phy) { 3547 rv = phymod_core_diagnostics_get(&core[phy_index], diag); 3548 } 3549 phy_index--; 3550 } 3551 3552 return(rv); 3553 } 3554 3555 int portmod_port_phychain_phy_diagnostics_get(int unit, const phymod_phy_access_t* phy_access, 3556 const int chain_length, 3557 phymod_phy_diagnostics_t *diag) 3558 { 3559 int rv = PHYMOD_E_UNAVAIL; 3560 int phy_index; 3561 int is_legacy_phy = 0; 3562 3563 /* start from the most external phy. */ 3564 phy_index = chain_length - 1; 3565 3566 /* Most EXT */ 3567 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3568 if (phy_index) { 3569 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3570 if (rv != PHYMOD_E_NONE) return rv; 3571 } 3572 if (!is_legacy_phy) { 3573 rv = phymod_phy_diagnostics_get(&phy_access[phy_index], diag); 3574 } 3575 phy_index--; 3576 } 3577 return(rv); 3578 } 3579 3580 int portmod_port_phychain_pmd_info_dump(int unit, const phymod_phy_access_t* phy_access, 3581 const int chain_length, 3582 char *type) 3583 { 3584 int rv = PHYMOD_E_UNAVAIL; 3585 int phy_index; 3586 int is_legacy_phy = 0; 3587 3588 /* start from the most external phy. */ 3589 phy_index = chain_length - 1; 3590 3591 /* Most EXT */ 3592 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3593 if (phy_index) { 3594 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3595 if (rv != PHYMOD_E_NONE) return rv; 3596 } 3597 if (!is_legacy_phy) { 3598 if(phy_access[phy_index].access.lane_mask){ 3599 rv = phymod_phy_pmd_info_dump(&phy_access[phy_index], type); 3600 } else { 3601 rv = PHYMOD_E_NONE; 3602 } 3603 } 3604 phy_index--; 3605 } 3606 return(rv); 3607 } 3608 3609 int portmod_port_phychain_pcs_info_dump(int unit, const phymod_phy_access_t* phy_access, 3610 const int chain_length, 3611 char *type) 3612 { 3613 int rv = PHYMOD_E_UNAVAIL; 3614 int phy_index; 3615 int is_legacy_phy = 0; 3616 3617 /* start from the most external phy. */ 3618 phy_index = chain_length - 1; 3619 3620 /* Most EXT */ 3621 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3622 if (phy_index) { 3623 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3624 if (rv != PHYMOD_E_NONE) return rv; 3625 } 3626 if (!is_legacy_phy) { 3627 if(phy_access[phy_index].access.lane_mask) { 3628 rv = phymod_phy_pcs_info_dump(&phy_access[phy_index], type); 3629 } else { 3630 rv = PHYMOD_E_NONE; 3631 } 3632 } 3633 phy_index--; 3634 } 3635 return(rv); 3636 } 3637 3638 #ifdef _OLD_EYE_ 3639 int portmod_port_phychain_meas_lowber_eye(int unit, const phymod_phy_access_t* phy_access, 3640 const int chain_length, 3641 phymod_phy_eyescan_options_t eyescan_options, 3642 uint32_t *buffer) 3643 { 3644 int rv = PHYMOD_E_UNAVAIL; 3645 int phy_index; 3646 int is_legacy_phy = 0; 3647 3648 /* start from the most external phy. */ 3649 phy_index = chain_length - 1; 3650 3651 /* Most EXT */ 3652 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3653 if (phy_index) { 3654 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3655 if (rv != PHYMOD_E_NONE) return rv; 3656 } 3657 if (!is_legacy_phy) { 3658 rv = phymod_phy_meas_lowber_eye(&phy_access[phy_index], eyescan_options, buffer); 3659 } 3660 phy_index--; 3661 } 3662 return(rv); 3663 } 3664 int portmod_port_phychain_display_lowber_eye(int unit, const phymod_phy_access_t* phy_access, 3665 const int chain_length, 3666 phymod_phy_eyescan_options_t eyescan_options, 3667 uint32_t *buffer) 3668 { 3669 int rv = PHYMOD_E_UNAVAIL; 3670 int phy_index; 3671 int is_legacy_phy = 0; 3672 3673 /* start from the most external phy. */ 3674 phy_index = chain_length - 1; 3675 3676 /* Most EXT */ 3677 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3678 if (phy_index) { 3679 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3680 if (rv != PHYMOD_E_NONE) return rv; 3681 } 3682 if (!is_legacy_phy) { 3683 rv = phymod_phy_display_lowber_eye(&phy_access[phy_index], eyescan_options, buffer); 3684 } 3685 phy_index--; 3686 } 3687 return(rv); 3688 } 3689 3690 3691 int portmod_port_phychain_pmd_ber_end_cmd(int unit, const phymod_phy_access_t* phy_access, 3692 const int chain_length, 3693 uint8_t supp_info, 3694 uint32_t timeout_ms) 3695 { 3696 int rv = PHYMOD_E_UNAVAIL; 3697 int phy_index; 3698 int is_legacy_phy = 0; 3699 3700 /* start from the most external phy. */ 3701 phy_index = chain_length - 1; 3702 3703 /* Most EXT */ 3704 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3705 if (phy_index) { 3706 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3707 if (rv != PHYMOD_E_NONE) return rv; 3708 } 3709 if (!is_legacy_phy) { 3710 rv = phymod_phy_pmd_ber_end_cmd(&phy_access[phy_index], supp_info, timeout_ms); 3711 } 3712 phy_index--; 3713 } 3714 return(rv); 3715 } 3716 3717 int portmod_port_phychain_meas_eye_scan_start(int unit, const phymod_phy_access_t* phy_access, 3718 const int chain_length, 3719 uint8_t direction) 3720 { 3721 int rv = PHYMOD_E_UNAVAIL; 3722 int phy_index; 3723 int is_legacy_phy = 0; 3724 3725 /* start from the most external phy. */ 3726 phy_index = chain_length - 1; 3727 3728 /* Most EXT */ 3729 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3730 if (phy_index) { 3731 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3732 if (rv != PHYMOD_E_NONE) return rv; 3733 } 3734 if (!is_legacy_phy) { 3735 rv = phymod_phy_meas_eye_scan_start(&phy_access[phy_index], direction); 3736 } 3737 phy_index--; 3738 } 3739 return(rv); 3740 } 3741 3742 int portmod_port_phychain_meas_eye_scan_done(int unit, const phymod_phy_access_t* phy_access, 3743 const int chain_length) 3744 { 3745 int rv = PHYMOD_E_UNAVAIL; 3746 int phy_index; 3747 int is_legacy_phy = 0; 3748 3749 /* start from the most external phy. */ 3750 phy_index = chain_length - 1; 3751 3752 /* Most EXT */ 3753 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3754 if (phy_index) { 3755 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3756 if (rv != PHYMOD_E_NONE) return rv; 3757 } 3758 if (!is_legacy_phy) { 3759 rv = phymod_phy_meas_eye_scan_done(&phy_access[phy_index]); 3760 } 3761 phy_index--; 3762 } 3763 return(rv); 3764 } 3765 3766 int portmod_port_phychain_read_eye_scan_stripe(int unit, const phymod_phy_access_t* phy_access, 3767 const int chain_length, 3768 uint32_t *buffer, 3769 uint16_t *status) 3770 { 3771 int rv = PHYMOD_E_UNAVAIL; 3772 int phy_index; 3773 int is_legacy_phy = 0; 3774 3775 /* start from the most external phy. */ 3776 phy_index = chain_length - 1; 3777 3778 /* Most EXT */ 3779 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3780 if (phy_index) { 3781 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3782 if (rv != PHYMOD_E_NONE) return rv; 3783 } 3784 if (!is_legacy_phy) { 3785 rv = phymod_phy_read_eye_scan_stripe(&phy_access[phy_index], buffer, status); 3786 } 3787 phy_index--; 3788 } 3789 return(rv); 3790 } 3791 3792 int portmod_port_phychain_display_eye_scan_header(int unit, const phymod_phy_access_t* phy_access, 3793 const int chain_length, 3794 uint8_t index) 3795 { 3796 int rv = PHYMOD_E_UNAVAIL; 3797 int phy_index; 3798 int is_legacy_phy = 0; 3799 3800 /* start from the most external phy. */ 3801 phy_index = chain_length - 1; 3802 3803 /* Most EXT */ 3804 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3805 if (phy_index) { 3806 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3807 if (rv != PHYMOD_E_NONE) return rv; 3808 } 3809 if (!is_legacy_phy) { 3810 rv = phymod_phy_display_eye_scan_header(&phy_access[phy_index], index); 3811 } 3812 phy_index--; 3813 } 3814 return(rv); 3815 } 3816 3817 int portmod_port_phychain_display_eye_scan_footer(int unit, const phymod_phy_access_t* phy_access, 3818 const int chain_length, 3819 uint8_t index) 3820 { 3821 int rv = PHYMOD_E_UNAVAIL; 3822 int phy_index; 3823 int is_legacy_phy = 0; 3824 3825 /* start from the most external phy. */ 3826 phy_index = chain_length - 1; 3827 3828 /* Most EXT */ 3829 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3830 if (phy_index) { 3831 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3832 if (rv != PHYMOD_E_NONE) return rv; 3833 } 3834 if (!is_legacy_phy) { 3835 rv = phymod_phy_display_eye_scan_footer(&phy_access[phy_index], index); 3836 } 3837 phy_index--; 3838 } 3839 return(rv); 3840 } 3841 3842 int portmod_port_phychain_display_eye_scan_stripe(int unit, const phymod_phy_access_t* phy_access, 3843 const int chain_length, 3844 uint8_t index, 3845 uint32_t *buffer) 3846 { 3847 int rv = PHYMOD_E_UNAVAIL; 3848 int phy_index; 3849 int is_legacy_phy = 0; 3850 3851 /* start from the most external phy. */ 3852 phy_index = chain_length - 1; 3853 3854 /* Most EXT */ 3855 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3856 if (phy_index) { 3857 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3858 if (rv != PHYMOD_E_NONE) return rv; 3859 } 3860 if (!is_legacy_phy) { 3861 rv = phymod_phy_display_eye_scan_stripe(&phy_access[phy_index], index,buffer); 3862 } 3863 phy_index--; 3864 } 3865 return(rv); 3866 } 3867 3868 int portmod_port_phychain_eye_scan_debug_info_dump(int unit, const phymod_phy_access_t* phy_access, 3869 const int chain_length) 3870 { 3871 int rv = PHYMOD_E_UNAVAIL; 3872 int phy_index; 3873 int is_legacy_phy = 0; 3874 3875 /* start from the most external phy. */ 3876 phy_index = chain_length - 1; 3877 3878 /* Most EXT */ 3879 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3880 if (phy_index) { 3881 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3882 if (rv != PHYMOD_E_NONE) return rv; 3883 } 3884 if (!is_legacy_phy) { 3885 rv = phymod_phy_eye_scan_debug_info_dump(&phy_access[phy_index]); 3886 } 3887 phy_index--; 3888 } 3889 return(rv); 3890 } 3891 #else 3892 /* add phy_eyescan_run here */ 3893 3894 #endif /* _OLD_EYE_ */ 3895 3896 int portmod_port_phychain_timesync_tx_info_get(int unit, int port, const phymod_phy_access_t* phy_access, 3897 const int chain_length, 3898 phymod_ts_fifo_status_t* ts_tx_info) 3899 { 3900 int rv = PHYMOD_E_UNAVAIL; 3901 int phy_index; 3902 int is_legacy_phy = 0; 3903 3904 /* start from the most external phy. */ 3905 phy_index = chain_length - 1; 3906 3907 /* Most EXT */ 3908 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3909 3910 is_legacy_phy = 0; 3911 3912 /* if it is external phy, check to see if it is legacy phy. */ 3913 if (phy_index > 0) { 3914 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3915 if (rv != PHYMOD_E_NONE) return rv; 3916 } 3917 3918 if (!is_legacy_phy) { 3919 rv = phymod_timesync_tx_info_get(&phy_access[phy_index], ts_tx_info); 3920 } 3921 3922 phy_index--; 3923 } 3924 3925 return(rv); 3926 } 3927 3928 int portmod_port_phychain_timesync_config_set(int unit, int port, const phymod_phy_access_t* phy_access, 3929 const int chain_length, 3930 const portmod_phy_timesync_config_t* config) 3931 { 3932 int rv = PHYMOD_E_UNAVAIL; 3933 int phy_index; 3934 int is_legacy_phy = 0; 3935 uint32_t enable = 0; 3936 3937 /* start from the most external phy. */ 3938 phy_index = chain_length - 1; 3939 3940 /* Most EXT */ 3941 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3942 is_legacy_phy = 0; 3943 3944 /* if it is external phy, check to see if it is legacy phy. */ 3945 if (phy_index > 0) { 3946 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3947 if (rv != PHYMOD_E_NONE) return rv; 3948 } 3949 3950 if (is_legacy_phy) { 3951 rv = portmod_port_legacy_timesync_config_set(unit, port, config); 3952 } else { 3953 if (phy_access[phy_index].access.lane_mask) { 3954 enable = (config->flags & SOC_PORT_PHY_TIMESYNC_ENABLE) ? 1 : 0; 3955 rv = phymod_timesync_enable_set(&phy_access[phy_index], 0, enable); 3956 } else { 3957 rv = PHYMOD_E_NONE; 3958 } 3959 } 3960 phy_index--; 3961 } 3962 return(rv); 3963 } 3964 3965 int portmod_port_phychain_timesync_config_get(int unit, int port, const phymod_phy_access_t* phy_access, 3966 const int chain_length, 3967 portmod_phy_timesync_config_t* config) 3968 { 3969 int rv = PHYMOD_E_UNAVAIL; 3970 int phy_index; 3971 int is_legacy_phy = 0; 3972 uint32_t enable = 0; 3973 3974 /* start from the most external phy. */ 3975 phy_index = chain_length - 1; 3976 3977 /* Most EXT */ 3978 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 3979 3980 is_legacy_phy = 0; 3981 3982 /* if it is external phy, check to see if it is legacy phy. */ 3983 if (phy_index > 0) { 3984 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 3985 if (rv != PHYMOD_E_NONE) return rv; 3986 } 3987 3988 if (is_legacy_phy) { 3989 rv = portmod_port_legacy_timesync_config_get(unit, port, config); 3990 } else { 3991 if (phy_access[phy_index].access.lane_mask) { 3992 rv = phymod_timesync_enable_get(&phy_access[phy_index], 0, &enable); 3993 config->flags |= enable ? SOC_PORT_PHY_TIMESYNC_ENABLE : 0; 3994 } else { 3995 rv = PHYMOD_E_NONE; 3996 } 3997 } 3998 phy_index--; 3999 } 4000 4001 return(rv); 4002 } 4003 4004 4005 int portmod_port_phychain_timesync_enable_set(int unit, const phymod_phy_access_t* phy_access, 4006 const int chain_length, uint32 enable) 4007 { 4008 int rv = PHYMOD_E_UNAVAIL; 4009 int phy_index; 4010 int is_legacy_phy = 0; 4011 4012 /* start from the most external phy. */ 4013 phy_index = chain_length - 1; 4014 4015 /* Most EXT */ 4016 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4017 if (phy_index) { 4018 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4019 if (rv != PHYMOD_E_NONE) return rv; 4020 } 4021 if (!is_legacy_phy) { 4022 rv = phymod_timesync_enable_set(&phy_access[phy_index], 0, enable); 4023 } 4024 phy_index--; 4025 } 4026 return(rv); 4027 } 4028 4029 int portmod_port_phychain_timesync_enable_get(int unit, const phymod_phy_access_t* phy_access, 4030 const int chain_length, uint32* enable) 4031 { 4032 int rv = PHYMOD_E_UNAVAIL; 4033 int phy_index; 4034 int is_legacy_phy = 0; 4035 4036 /* start from the most external phy. */ 4037 phy_index = chain_length - 1; 4038 4039 /* Most EXT */ 4040 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4041 if (phy_index) { 4042 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4043 if (rv != PHYMOD_E_NONE) return rv; 4044 } 4045 if (!is_legacy_phy) { 4046 rv = phymod_timesync_enable_get(&phy_access[phy_index], 0, enable); 4047 } 4048 phy_index--; 4049 } 4050 return(rv); 4051 } 4052 4053 int portmod_port_phychain_timesync_nco_addend_set(int unit, const phymod_phy_access_t* phy_access, 4054 const int chain_length, uint32 freq_step) 4055 { 4056 int rv = PHYMOD_E_UNAVAIL; 4057 int phy_index; 4058 int is_legacy_phy = 0; 4059 4060 /* start from the most external phy. */ 4061 phy_index = chain_length - 1; 4062 4063 /* Most EXT */ 4064 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4065 if (phy_index) { 4066 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4067 if (rv != PHYMOD_E_NONE) return rv; 4068 } 4069 if (!is_legacy_phy) { 4070 rv = phymod_timesync_nco_addend_set(&phy_access[phy_index], freq_step); 4071 } 4072 phy_index--; 4073 } 4074 return(rv); 4075 } 4076 4077 int portmod_port_phychain_timesync_nco_addend_get(int unit, const phymod_phy_access_t* phy_access, 4078 const int chain_length, 4079 uint32* freq_step) 4080 { 4081 int rv = PHYMOD_E_UNAVAIL; 4082 int phy_index; 4083 int is_legacy_phy = 0; 4084 4085 /* start from the most external phy. */ 4086 phy_index = chain_length - 1; 4087 4088 /* Most EXT */ 4089 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4090 if (phy_index) { 4091 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4092 if (rv != PHYMOD_E_NONE) return rv; 4093 } 4094 if (!is_legacy_phy) { 4095 rv = phymod_timesync_nco_addend_get(&phy_access[phy_index], freq_step); 4096 } 4097 phy_index--; 4098 } 4099 return(rv); 4100 } 4101 4102 int portmod_port_phychain_timesync_framesync_mode_set(int unit, const phymod_phy_access_t* phy_access, 4103 const int chain_length, 4104 const portmod_timesync_framesync_t* framesync) 4105 { 4106 int rv = PHYMOD_E_UNAVAIL; 4107 int phy_index; 4108 int is_legacy_phy = 0; 4109 4110 phymod_timesync_framesync_t phymod_framesync; 4111 4112 /* start from the most external phy. */ 4113 phy_index = chain_length - 1; 4114 sal_memcpy(&phymod_framesync, framesync, sizeof(phymod_timesync_framesync_t)); 4115 /* Most EXT */ 4116 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4117 if (phy_index) { 4118 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4119 if (rv != PHYMOD_E_NONE) return rv; 4120 } 4121 if (!is_legacy_phy) { 4122 rv = phymod_timesync_framesync_mode_set(&phy_access[phy_index], &phymod_framesync); 4123 } 4124 phy_index--; 4125 } 4126 return(rv); 4127 } 4128 4129 int portmod_port_phychain_timesync_framesync_mode_get(int unit, const phymod_phy_access_t* phy_access, 4130 const int chain_length, 4131 phymod_timesync_framesync_t* framesync) 4132 { 4133 int rv = PHYMOD_E_UNAVAIL; 4134 int phy_index; 4135 int is_legacy_phy = 0; 4136 4137 phymod_timesync_framesync_t phymod_framesync; 4138 4139 sal_memset(&phymod_framesync, 0, sizeof(phymod_timesync_framesync_t)); 4140 /* start from the most external phy. */ 4141 phy_index = chain_length - 1; 4142 4143 /* Most EXT */ 4144 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4145 if (phy_index) { 4146 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4147 if (rv != PHYMOD_E_NONE) return rv; 4148 } 4149 if (!is_legacy_phy) { 4150 rv = phymod_timesync_framesync_mode_get(&phy_access[phy_index], &phymod_framesync); 4151 } 4152 phy_index--; 4153 } 4154 sal_memcpy(framesync,&phymod_framesync, sizeof(phymod_timesync_framesync_t)); 4155 4156 return(rv); 4157 } 4158 4159 int portmod_port_phychain_timesync_local_time_set(int unit, const phymod_phy_access_t* phy_access, 4160 const int chain_length, 4161 const uint64 local_time) 4162 { 4163 int rv = PHYMOD_E_UNAVAIL; 4164 int phy_index; 4165 int is_legacy_phy = 0; 4166 4167 /* start from the most external phy. */ 4168 phy_index = chain_length - 1; 4169 4170 /* Most EXT */ 4171 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4172 if (phy_index) { 4173 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4174 if (rv != PHYMOD_E_NONE) return rv; 4175 } 4176 if (!is_legacy_phy) { 4177 rv = phymod_timesync_local_time_set(&phy_access[phy_index], local_time); 4178 } 4179 phy_index--; 4180 } 4181 return(rv); 4182 } 4183 4184 int portmod_port_phychain_timesync_local_time_get(int unit, const phymod_phy_access_t* phy_access, 4185 const int chain_length, 4186 uint64* local_time) 4187 { 4188 int rv = PHYMOD_E_UNAVAIL; 4189 int phy_index; 4190 int is_legacy_phy = 0; 4191 4192 /* start from the most external phy. */ 4193 phy_index = chain_length - 1; 4194 4195 /* Most EXT */ 4196 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4197 if (phy_index) { 4198 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4199 if (rv != PHYMOD_E_NONE) return rv; 4200 } 4201 if (!is_legacy_phy) { 4202 rv = phymod_timesync_local_time_get(&phy_access[phy_index], local_time); 4203 } 4204 phy_index--; 4205 } 4206 return(rv); 4207 } 4208 4209 int portmod_port_phychain_timesync_load_ctrl_set(int unit, const phymod_phy_access_t* phy_access, 4210 const int chain_length, 4211 uint32 load_once, 4212 uint32 load_always) 4213 { 4214 int rv = PHYMOD_E_UNAVAIL; 4215 int phy_index; 4216 int is_legacy_phy = 0; 4217 4218 /* start from the most external phy. */ 4219 phy_index = chain_length - 1; 4220 4221 /* Most EXT */ 4222 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4223 if (phy_index) { 4224 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4225 if (rv != PHYMOD_E_NONE) return rv; 4226 } 4227 if (!is_legacy_phy) { 4228 rv = phymod_timesync_load_ctrl_set(&phy_access[phy_index], load_once, 4229 load_always); 4230 } 4231 phy_index--; 4232 } 4233 return(rv); 4234 } 4235 4236 int portmod_port_phychain_timesync_load_ctrl_get(int unit, const phymod_phy_access_t* phy_access, 4237 const int chain_length, 4238 uint32* load_once, 4239 uint32* load_always) 4240 { 4241 int rv = PHYMOD_E_UNAVAIL; 4242 int phy_index; 4243 int is_legacy_phy = 0; 4244 4245 /* start from the most external phy. */ 4246 phy_index = chain_length - 1; 4247 4248 /* Most EXT */ 4249 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4250 if (phy_index) { 4251 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4252 if (rv != PHYMOD_E_NONE) return rv; 4253 } 4254 if (!is_legacy_phy) { 4255 rv = phymod_timesync_load_ctrl_get(&phy_access[phy_index], load_once, 4256 load_always); 4257 } 4258 phy_index--; 4259 } 4260 return(rv); 4261 } 4262 4263 int portmod_port_phychain_timesync_tx_timestamp_offset_set(int unit, const phymod_phy_access_t* phy_access, 4264 const int chain_length, 4265 uint32 ts_offset) 4266 { 4267 int rv = PHYMOD_E_UNAVAIL; 4268 int phy_index; 4269 int is_legacy_phy = 0; 4270 4271 /* start from the most external phy. */ 4272 phy_index = chain_length - 1; 4273 4274 /* Most EXT */ 4275 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4276 if (phy_index) { 4277 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4278 if (rv != PHYMOD_E_NONE) return rv; 4279 } 4280 if (!is_legacy_phy) { 4281 rv = phymod_timesync_tx_timestamp_offset_set(&phy_access[phy_index],ts_offset); 4282 } 4283 phy_index--; 4284 } 4285 return(rv); 4286 } 4287 4288 int portmod_port_phychain_timesync_tx_timestamp_offset_get(int unit, const phymod_phy_access_t* phy_access, 4289 const int chain_length, 4290 uint32* ts_offset) 4291 { 4292 int rv = PHYMOD_E_UNAVAIL; 4293 int phy_index; 4294 int is_legacy_phy = 0; 4295 4296 /* start from the most external phy. */ 4297 phy_index = chain_length - 1; 4298 4299 /* Most EXT */ 4300 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4301 if (phy_index) { 4302 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4303 if (rv != PHYMOD_E_NONE) return rv; 4304 } 4305 if (!is_legacy_phy) { 4306 rv = phymod_timesync_tx_timestamp_offset_get(&phy_access[phy_index],ts_offset); 4307 } 4308 phy_index--; 4309 } 4310 return(rv); 4311 } 4312 4313 int portmod_port_phychain_timesync_rx_timestamp_offset_set(int unit, const phymod_phy_access_t* phy_access, 4314 const int chain_length, 4315 uint32 ts_offset) 4316 { 4317 int rv = PHYMOD_E_UNAVAIL; 4318 int phy_index; 4319 int is_legacy_phy = 0; 4320 4321 /* start from the most external phy. */ 4322 phy_index = chain_length - 1; 4323 4324 /* Most EXT */ 4325 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4326 if (phy_index) { 4327 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4328 if (rv != PHYMOD_E_NONE) return rv; 4329 } 4330 if (!is_legacy_phy) { 4331 rv = phymod_timesync_rx_timestamp_offset_set(&phy_access[phy_index],ts_offset); 4332 } 4333 phy_index--; 4334 } 4335 return(rv); 4336 } 4337 4338 int portmod_port_phychain_timesync_rx_timestamp_offset_get(int unit, const phymod_phy_access_t* phy_access, 4339 const int chain_length, 4340 uint32* ts_offset) 4341 { 4342 int rv = PHYMOD_E_UNAVAIL; 4343 int phy_index; 4344 int is_legacy_phy = 0; 4345 4346 /* start from the most external phy. */ 4347 phy_index = chain_length - 1; 4348 4349 /* Most EXT */ 4350 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4351 if (phy_index) { 4352 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4353 if (rv != PHYMOD_E_NONE) return rv; 4354 } 4355 if (!is_legacy_phy) { 4356 rv = phymod_timesync_rx_timestamp_offset_get(&phy_access[phy_index],ts_offset); 4357 } 4358 phy_index--; 4359 } 4360 return(rv); 4361 } 4362 4363 int portmod_port_phychain_phy_intr_enable_set(int unit, const phymod_phy_access_t* phy_access, 4364 const int chain_length, 4365 uint32_t enable) 4366 { 4367 int rv = PHYMOD_E_UNAVAIL; 4368 int phy_index; 4369 int is_legacy_phy = 0; 4370 4371 /* start from the most external phy. */ 4372 phy_index = chain_length - 1; 4373 4374 /* Most EXT */ 4375 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4376 if (phy_index) { 4377 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4378 if (rv != PHYMOD_E_NONE) return rv; 4379 } 4380 if (!is_legacy_phy){ 4381 rv = phymod_phy_intr_enable_set(&phy_access[phy_index], enable); 4382 } 4383 phy_index--; 4384 } 4385 return(rv); 4386 } 4387 4388 int portmod_port_phychain_phy_intr_enable_get(int unit, const phymod_phy_access_t* phy_access, 4389 const int chain_length, 4390 uint32_t* enable) 4391 { 4392 int rv = PHYMOD_E_UNAVAIL; 4393 int phy_index; 4394 int is_legacy_phy = 0; 4395 4396 /* start from the most external phy. */ 4397 phy_index = chain_length - 1; 4398 4399 /* Most EXT */ 4400 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4401 if (phy_index) { 4402 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4403 if (rv != PHYMOD_E_NONE) return rv; 4404 } 4405 if (!is_legacy_phy) { 4406 rv = phymod_phy_intr_enable_get(&phy_access[phy_index],enable); 4407 } 4408 phy_index--; 4409 } 4410 return(rv); 4411 } 4412 4413 int portmod_port_phychain_phy_intr_status_get(int unit, const phymod_phy_access_t* phy_access, 4414 const int chain_length, 4415 uint32_t* enable) 4416 { 4417 int rv = PHYMOD_E_UNAVAIL; 4418 int phy_index; 4419 int is_legacy_phy = 0; 4420 4421 /* start from the most external phy. */ 4422 phy_index = chain_length - 1; 4423 4424 /* Most EXT */ 4425 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4426 if (phy_index) { 4427 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4428 if (rv != PHYMOD_E_NONE) return rv; 4429 } 4430 if (!is_legacy_phy) { 4431 rv = phymod_phy_intr_status_get(&phy_access[phy_index],enable); 4432 } 4433 phy_index--; 4434 } 4435 return(rv); 4436 } 4437 4438 int portmod_port_phychain_phy_intr_status_clear(int unit, const phymod_phy_access_t* phy_access, 4439 const int chain_length) 4440 { 4441 int rv = PHYMOD_E_UNAVAIL; 4442 int phy_index; 4443 uint32_t enable=0; 4444 int is_legacy_phy = 0; 4445 4446 /* start from the most external phy. */ 4447 phy_index = chain_length - 1; 4448 4449 /* Most EXT */ 4450 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4451 if (phy_index) { 4452 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4453 if (rv != PHYMOD_E_NONE) return rv; 4454 } 4455 if (!is_legacy_phy) { 4456 rv = phymod_phy_intr_status_get(&phy_access[phy_index], &enable); 4457 if (rv) return (rv); 4458 4459 rv = phymod_phy_intr_status_clear(&phy_access[phy_index], enable); 4460 } 4461 phy_index--; 4462 } 4463 return(rv); 4464 } 4465 4466 int portmod_port_phychain_phy_timesync_do_sync(int unit, const phymod_phy_access_t* phy_access, 4467 const int chain_length ) 4468 { 4469 int rv = PHYMOD_E_UNAVAIL; 4470 int phy_index; 4471 int is_legacy_phy = 0; 4472 4473 4474 /* start from the most external phy. */ 4475 phy_index = chain_length - 1; 4476 4477 /* Most EXT */ 4478 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4479 if (phy_index) { 4480 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4481 if (rv != PHYMOD_E_NONE) return rv; 4482 } 4483 if (!is_legacy_phy) { 4484 rv = phymod_timesync_do_sync(&phy_access[phy_index]); 4485 } 4486 phy_index--; 4487 } 4488 return(rv); 4489 } 4490 4491 int portmod_port_phychain_timesync_capture_timestamp_get(int unit, const phymod_phy_access_t* phy_access, 4492 const int chain_length, uint64* cap_ts) 4493 { 4494 int rv = PHYMOD_E_UNAVAIL; 4495 int phy_index; 4496 int is_legacy_phy = 0; 4497 4498 /* start from the most external phy. */ 4499 phy_index = chain_length - 1; 4500 4501 /* Most EXT */ 4502 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4503 if (phy_index) { 4504 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4505 if (rv != PHYMOD_E_NONE) return rv; 4506 } 4507 if (!is_legacy_phy) { 4508 rv = phymod_timesync_capture_timestamp_get(&phy_access[phy_index],cap_ts); 4509 } 4510 phy_index--; 4511 } 4512 return(rv); 4513 } 4514 4515 int portmod_port_phychain_timesync_heartbeat_timestamp_get(int unit, const phymod_phy_access_t* phy_access, 4516 const int chain_length, uint64* hb_ts) 4517 { 4518 int rv = PHYMOD_E_UNAVAIL; 4519 int phy_index; 4520 int is_legacy_phy = 0; 4521 4522 /* start from the most external phy. */ 4523 phy_index = chain_length - 1; 4524 4525 /* Most EXT */ 4526 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4527 if (phy_index) { 4528 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4529 if (rv != PHYMOD_E_NONE) return rv; 4530 } 4531 if (!is_legacy_phy) { 4532 rv = phymod_timesync_heartbeat_timestamp_get(&phy_access[phy_index],hb_ts); 4533 } 4534 phy_index--; 4535 } 4536 return(rv); 4537 } 4538 int portmod_port_phychain_edc_config_set(int unit, const phymod_phy_access_t* phy_access, 4539 const int chain_length, 4540 const phymod_edc_config_t* config) 4541 { 4542 int rv = PHYMOD_E_UNAVAIL; 4543 int phy_index; 4544 int is_legacy_phy = 0; 4545 4546 phymod_edc_config_t phymod_config; 4547 4548 /* start from the most external phy. */ 4549 phy_index = chain_length - 1; 4550 4551 sal_memcpy(&phymod_config, config, sizeof(phymod_edc_config_t)); 4552 /* Most EXT */ 4553 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4554 if (phy_index) { 4555 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4556 if (rv != PHYMOD_E_NONE) return rv; 4557 } 4558 if (!is_legacy_phy) { 4559 rv = phymod_edc_config_set(&phy_access[phy_index],&phymod_config); 4560 } 4561 phy_index--; 4562 } 4563 return(rv); 4564 } 4565 4566 int portmod_port_phychain_edc_config_get(int unit, const phymod_phy_access_t* phy_access, 4567 const int chain_length, 4568 phymod_edc_config_t* config) 4569 { 4570 int rv = PHYMOD_E_UNAVAIL; 4571 int phy_index; 4572 int is_legacy_phy = 0; 4573 phymod_edc_config_t phymod_config; 4574 4575 /* start from the most external phy. */ 4576 phy_index = chain_length - 1; 4577 4578 sal_memset(&phymod_config,0,sizeof(phymod_edc_config_t)); 4579 4580 /* Most EXT */ 4581 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4582 if (phy_index) { 4583 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4584 if (rv != PHYMOD_E_NONE) return rv; 4585 } 4586 if (!is_legacy_phy) { 4587 rv = phymod_edc_config_get(&phy_access[phy_index],&phymod_config); 4588 } 4589 phy_index--; 4590 } 4591 sal_memcpy(config,&phymod_config, sizeof(phymod_edc_config_t)); 4592 return(rv); 4593 } 4594 4595 int portmod_port_phychain_failover_mode_get(int unit, const phymod_phy_access_t *phy_access, 4596 int chain_length, phymod_failover_mode_t *failover) 4597 { 4598 int rv = PHYMOD_E_UNAVAIL; 4599 int phy_index; 4600 int is_legacy_phy = 0; 4601 4602 /* start from the most external phy. */ 4603 phy_index = chain_length - 1; 4604 4605 /* Most EXT */ 4606 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4607 if (phy_index) { 4608 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4609 if (rv != PHYMOD_E_NONE) return rv; 4610 } 4611 if (!is_legacy_phy) { 4612 rv = phymod_failover_mode_get(&phy_access[phy_index], failover); 4613 } 4614 phy_index--; 4615 } 4616 4617 return(rv); 4618 } 4619 4620 int portmod_port_phychain_failover_mode_set(int unit, const phymod_phy_access_t *phy_access, 4621 int chain_length, phymod_failover_mode_t failover) 4622 { 4623 int rv = PHYMOD_E_UNAVAIL; 4624 int phy_index; 4625 int is_legacy_phy = 0; 4626 4627 /* start from the most external phy. */ 4628 phy_index = chain_length - 1; 4629 4630 /* Most EXT */ 4631 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4632 if (phy_index) { 4633 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4634 if (rv != PHYMOD_E_NONE) return rv; 4635 } 4636 if (!is_legacy_phy) { 4637 rv = phymod_failover_mode_set(&phy_access[phy_index], failover); 4638 } 4639 phy_index--; 4640 } 4641 4642 return(rv); 4643 } 4644 4645 int portmod_port_phychain_phy_link_up_event(int unit, int port, const phymod_phy_access_t* phy_access, 4646 const int chain_length) 4647 { 4648 int rv = PHYMOD_E_UNAVAIL; 4649 int phy_index; 4650 int is_legacy_phy = 0; 4651 4652 /* start from the most external phy. */ 4653 phy_index = chain_length - 1; 4654 4655 /* Most EXT */ 4656 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4657 if (phy_index) { 4658 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4659 if (rv != PHYMOD_E_NONE) return rv; 4660 if (is_legacy_phy) { 4661 rv = portmod_port_legacy_phy_link_up_event(unit, port); 4662 } else { 4663 rv = PHYMOD_E_NONE; 4664 } 4665 } else { 4666 rv = PHYMOD_E_NONE; 4667 } 4668 phy_index--; 4669 } 4670 return(rv); 4671 } 4672 4673 int portmod_port_phychain_phy_link_down_event(int unit, int port, const phymod_phy_access_t* phy_access, 4674 const int chain_length) 4675 { 4676 int rv = PHYMOD_E_UNAVAIL; 4677 int phy_index; 4678 int is_legacy_phy = 0; 4679 4680 /* start from the most external phy. */ 4681 phy_index = chain_length - 1; 4682 4683 /* Most EXT */ 4684 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 4685 if (phy_index) { 4686 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 4687 if (rv != PHYMOD_E_NONE) return rv; 4688 if (is_legacy_phy) { 4689 rv = portmod_port_legacy_phy_link_down_event(unit, port); 4690 } else { 4691 rv = PHYMOD_E_NONE; 4692 } 4693 } else { 4694 rv = PHYMOD_E_NONE; 4695 } 4696 phy_index--; 4697 } 4698 return(rv); 4699 } 4700 4701 /* 4702 * common routines between pm4x10 and pm4x25 4703 */ 4704 4705 int portmod_phy_port_diag_ctrl(int unit, soc_port_t port, phymod_phy_access_t *phy_access, 4706 int nof_phys, uint32 inst, int op_type, int op_cmd, const void *arg) 4707 { 4708 phymod_tx_t ln_txparam[PHYMOD_MAX_LANES_PER_CORE]; 4709 uint32 lane_map = phy_access[0].access.lane_mask; 4710 int i; 4711 4712 for (i = 0; i < PHYMOD_MAX_LANES_PER_CORE; i++) { 4713 SOC_IF_ERROR_RETURN(phymod_tx_t_init(&ln_txparam[i])); 4714 } 4715 4716 switch(op_cmd) { 4717 case PHY_DIAG_CTRL_DSC: 4718 LOG_INFO(BSL_LS_SOC_PHY, 4719 (BSL_META_U(unit, 4720 "portmod_phy_port_diag_ctrl: " 4721 "u=%d p=%d PHY_DIAG_CTRL_DSC 0x%x\n"), 4722 unit, port, PHY_DIAG_CTRL_DSC)); 4723 4724 SOC_IF_ERROR_RETURN 4725 (portmod_port_phychain_pmd_info_dump(unit, phy_access, nof_phys, 4726 (void*)arg)); 4727 4728 break; 4729 4730 case PHY_DIAG_CTRL_PCS: 4731 LOG_INFO(BSL_LS_SOC_PHY, 4732 (BSL_META_U(unit, 4733 "portmod_phy_port_diag_ctrl: " 4734 "u=%d p=%d PHY_DIAG_CTRL_PCS 0x%x\n"), 4735 unit, port, PHY_DIAG_CTRL_PCS)); 4736 4737 SOC_IF_ERROR_RETURN 4738 (portmod_port_phychain_pcs_info_dump(unit, phy_access, nof_phys, 4739 (void*)arg)); 4740 break; 4741 4742 case PHY_DIAG_CTRL_LINKMON_MODE: 4743 LOG_INFO(BSL_LS_SOC_PHY, 4744 (BSL_META_U(unit, 4745 "portmod_phy_port_diag_ctrl: " 4746 "u=%d p=%d PHY_DIAG_CTRL_LINKMON_MODE 0x%x\n"), 4747 unit, port, PHY_DIAG_CTRL_LINKMON_MODE)); 4748 4749 if (phy_access[0].access.lane_mask) { 4750 SOC_IF_ERROR_RETURN 4751 (portmod_pm_phy_link_mon_enable_set(phy_access, nof_phys, PTR_TO_INT(arg))); 4752 } 4753 break; 4754 4755 case PHY_DIAG_CTRL_LINKMON_STATUS: 4756 LOG_INFO(BSL_LS_SOC_PHY, 4757 (BSL_META_U(unit, 4758 "portmod_phy_port_diag_ctrl: " 4759 "u=%d p=%d PHY_DIAG_CTRL_LINKMON_STATUS 0x%x\n"), 4760 unit, port, PHY_DIAG_CTRL_LINKMON_STATUS)); 4761 4762 if (phy_access[0].access.lane_mask) { 4763 SOC_IF_ERROR_RETURN 4764 (portmod_pm_phy_link_mon_status_get(phy_access, nof_phys)); 4765 } 4766 break; 4767 case PHY_DIAG_CTRL_BER_PROJ: 4768 LOG_INFO(BSL_LS_SOC_PHY, 4769 (BSL_META_U(unit, 4770 "portmod_phy_port_diag_ctrl: " 4771 "u=%d p=%d PHY_DIAG_CTRL_BER_PROJ 0x%x\n"), 4772 unit, port, PHY_DIAG_CTRL_BER_PROJ)); 4773 4774 if (phy_access[0].access.lane_mask) { 4775 SOC_IF_ERROR_RETURN 4776 (portmod_pm_phy_ber_proj(phy_access, (soc_port_phy_ber_proj_params_t*)arg)); 4777 } 4778 break; 4779 case PHY_DIAG_CTRL_RSFEC_SYMB_ERR: 4780 LOG_INFO(BSL_LS_SOC_PHY, 4781 (BSL_META_U(unit, 4782 "portmod_phy_port_diag_ctrl: " 4783 "u=%d p=%d PHY_DIAG_CTRL_RSFEC_SYMB_ERR 0x%x\n"), 4784 unit, port, PHY_DIAG_CTRL_RSFEC_SYMB_ERR)); 4785 4786 if (phy_access[0].access.lane_mask) { 4787 SOC_IF_ERROR_RETURN 4788 (portmod_pm_phy_rsfec_symb_err_get(phy_access, 4789 (soc_port_phy_rsfec_symb_errcnt_t*)arg)); 4790 } 4791 break; 4792 default: 4793 if (op_type == PHY_DIAG_CTRL_SET) { 4794 LOG_INFO(BSL_LS_SOC_PHY, 4795 (BSL_META_U(unit, 4796 "portmod_phy_port_diag_ctrl: " 4797 "u=%d p=%d PHY_DIAG_CTRL_SET 0x%x\n"), 4798 unit, port, PHY_DIAG_CTRL_SET)); 4799 if (!SAL_BOOT_SIMULATION) { 4800 if (!(phy_access->access.lane_mask == 0)) { 4801 SOC_IF_ERROR_RETURN(portmod_pm_phy_control_set(phy_access, nof_phys, 4802 op_cmd, ln_txparam, lane_map, PTR_TO_INT(arg))); 4803 } 4804 } 4805 } else if (op_type == PHY_DIAG_CTRL_GET) { 4806 LOG_INFO(BSL_LS_SOC_PHY, 4807 (BSL_META_U(unit, 4808 "portmod_phy_port_diag_ctrl: " 4809 "u=%d p=%d PHY_DIAG_CTRL_GET 0x%x\n"), 4810 unit, port, PHY_DIAG_CTRL_GET)); 4811 if (!SAL_BOOT_SIMULATION) { 4812 if (!(phy_access->access.lane_mask == 0)) { 4813 SOC_IF_ERROR_RETURN(portmod_pm_phy_control_get(phy_access,nof_phys, 4814 op_cmd, ln_txparam, lane_map, (uint32 *)arg)); 4815 } else { 4816 *(uint32 *)arg = 0; 4817 } 4818 } 4819 } else { 4820 return (SOC_E_UNAVAIL); 4821 } 4822 4823 break; 4824 } 4825 4826 return (SOC_E_NONE); 4827 } 4828 4829 int portmod_phy_port_reset_get (int unit, int port, pm_info_t pm_info, 4830 int reset_mode, int opcode, int* direction) 4831 { 4832 phymod_core_access_t core_access[1+MAX_PHYN]; 4833 int nof_phys; 4834 phymod_reset_direction_t reset_direction; 4835 4836 SOC_INIT_FUNC_DEFS; 4837 4838 _SOC_IF_ERR_EXIT 4839 (portmod_port_chain_core_access_get(unit, port, pm_info, 4840 core_access, (1+MAX_PHYN), 4841 &nof_phys)); 4842 4843 _SOC_IF_ERR_EXIT 4844 (portmod_port_phychain_core_reset_get(unit, core_access, nof_phys, 4845 reset_mode, 4846 &reset_direction)); 4847 *direction = reset_direction; 4848 4849 exit: 4850 SOC_FUNC_RETURN; 4851 } 4852 4853 int portmod_phy_port_reset_set (int unit, int port, pm_info_t pm_info, 4854 int reset_mode, int opcode, int direction) 4855 { 4856 phymod_core_access_t core_access[1+MAX_PHYN]; 4857 int nof_phys; 4858 4859 SOC_INIT_FUNC_DEFS; 4860 4861 _SOC_IF_ERR_EXIT 4862 (portmod_port_chain_core_access_get(unit, port, pm_info, 4863 core_access, (1+MAX_PHYN), 4864 &nof_phys)); 4865 4866 _SOC_IF_ERR_EXIT 4867 (portmod_port_phychain_core_reset_set(unit, core_access, nof_phys, 4868 reset_mode, 4869 direction)); 4870 exit: 4871 SOC_FUNC_RETURN; 4872 } 4873 4874 int portmod_phy_port_prbs_config_set (int unit, int port, pm_info_t pm_info, 4875 portmod_prbs_mode_t mode, int flags, 4876 const phymod_prbs_t* config) 4877 { 4878 phymod_phy_access_t phy_access[1+MAX_PHYN]; 4879 int nof_phys; 4880 4881 SOC_INIT_FUNC_DEFS; 4882 4883 if(mode == 1 /*MAC*/) { 4884 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("MAC PRBS is not supported"))); 4885 } 4886 4887 _SOC_IF_ERR_EXIT 4888 (portmod_port_chain_phy_access_get(unit, port, pm_info, 4889 phy_access ,(1+MAX_PHYN), 4890 &nof_phys)); 4891 _SOC_IF_ERR_EXIT 4892 (portmod_port_phychain_prbs_config_set(unit, phy_access, nof_phys, flags, config)); 4893 4894 exit: 4895 SOC_FUNC_RETURN; 4896 } 4897 4898 int portmod_phy_port_prbs_config_get (int unit, int port, pm_info_t pm_info, 4899 portmod_prbs_mode_t mode, int flags, 4900 phymod_prbs_t* config) 4901 { 4902 phymod_phy_access_t phy_access[1+MAX_PHYN]; 4903 int nof_phys; 4904 SOC_INIT_FUNC_DEFS; 4905 4906 if(mode == 1 /*MAC*/) { 4907 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, 4908 (_SOC_MSG("MAC PRBS is not supported for PM4x25"))); 4909 } 4910 4911 _SOC_IF_ERR_EXIT 4912 (portmod_port_chain_phy_access_get(unit, port, pm_info, 4913 phy_access ,(1+MAX_PHYN), 4914 &nof_phys)); 4915 _SOC_IF_ERR_EXIT 4916 (portmod_port_phychain_prbs_config_get(unit, phy_access, nof_phys, flags, config)); 4917 4918 exit: 4919 SOC_FUNC_RETURN; 4920 } 4921 4922 4923 int portmod_phy_port_prbs_enable_set(int unit, int port, pm_info_t pm_info, 4924 portmod_prbs_mode_t mode, int flags, int enable) 4925 { 4926 phymod_phy_access_t phy_access[1+MAX_PHYN]; 4927 int nof_phys; 4928 SOC_INIT_FUNC_DEFS; 4929 4930 if(mode == 1 /*MAC*/) { 4931 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, ( 4932 _SOC_MSG("MAC PRBS is not supported for PM4x25"))); 4933 } 4934 4935 _SOC_IF_ERR_EXIT 4936 (portmod_port_chain_phy_access_get(unit, port, pm_info, 4937 phy_access ,(1+MAX_PHYN), 4938 &nof_phys)); 4939 _SOC_IF_ERR_EXIT 4940 (portmod_port_phychain_prbs_enable_set(unit, phy_access, nof_phys, flags, enable)); 4941 4942 exit: 4943 SOC_FUNC_RETURN; 4944 } 4945 4946 int portmod_phy_port_prbs_enable_get(int unit, int port, pm_info_t pm_info, 4947 portmod_prbs_mode_t mode, int flags, int* enable) 4948 { 4949 phymod_phy_access_t phy_access[1+MAX_PHYN]; 4950 uint32 is_enabled; 4951 int nof_phys; 4952 SOC_INIT_FUNC_DEFS; 4953 4954 if(mode == 1 /*MAC*/) { 4955 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, 4956 (_SOC_MSG("MAC PRBS is not supported for PM4x25"))); 4957 } 4958 4959 _SOC_IF_ERR_EXIT 4960 (portmod_port_chain_phy_access_get(unit, port, pm_info, 4961 phy_access ,(1+MAX_PHYN), 4962 &nof_phys)); 4963 4964 _SOC_IF_ERR_EXIT 4965 (portmod_port_phychain_prbs_enable_get(unit, phy_access, nof_phys, flags, &is_enabled)); 4966 4967 (*enable) = (is_enabled ? 1 : 0); 4968 4969 exit: 4970 SOC_FUNC_RETURN; 4971 } 4972 4973 4974 int portmod_phy_port_prbs_status_get(int unit, int port, pm_info_t pm_info, 4975 portmod_prbs_mode_t mode, int flags, 4976 phymod_prbs_status_t* status) 4977 { 4978 phymod_phy_access_t phy_access[1+MAX_PHYN]; 4979 int nof_phys; 4980 SOC_INIT_FUNC_DEFS; 4981 4982 if(mode == 1 /*MAC*/) { 4983 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, 4984 (_SOC_MSG("MAC PRBS is not supported for PM4x25"))); 4985 } 4986 4987 _SOC_IF_ERR_EXIT 4988 (portmod_port_chain_phy_access_get(unit, port, pm_info, 4989 phy_access ,(1+MAX_PHYN), 4990 &nof_phys)); 4991 _SOC_IF_ERR_EXIT 4992 (portmod_port_phychain_prbs_status_get(unit, phy_access, nof_phys, flags, status)); 4993 4994 exit: 4995 SOC_FUNC_RETURN; 4996 } 4997 4998 int portmod_phy_port_link_get(int unit, int port, pm_info_t pm_info, int* link) 4999 { 5000 phymod_phy_access_t phy_access[1+MAX_PHYN]; 5001 int nof_phys; 5002 5003 SOC_INIT_FUNC_DEFS; 5004 5005 _SOC_IF_ERR_EXIT 5006 (portmod_port_chain_phy_access_get(unit, port, pm_info, 5007 phy_access ,(1+MAX_PHYN), 5008 &nof_phys)); 5009 5010 _SOC_IF_ERR_EXIT 5011 (portmod_port_phychain_link_status_get(unit, port, phy_access, nof_phys, PORTMOD_INIT_F_EXTERNAL_MOST_ONLY, (uint32_t*) link)); 5012 5013 exit: 5014 SOC_FUNC_RETURN; 5015 } 5016 5017 int portmod_phy_port_autoneg_status_get (int unit, int port, pm_info_t pm_info, 5018 phymod_autoneg_status_t* an_status) 5019 { 5020 phymod_phy_access_t phy_access[1+MAX_PHYN]; 5021 int nof_phys; 5022 5023 SOC_INIT_FUNC_DEFS; 5024 5025 _SOC_IF_ERR_EXIT 5026 (portmod_port_chain_phy_access_get(unit, port, pm_info, 5027 phy_access ,(1+MAX_PHYN), 5028 &nof_phys)); 5029 _SOC_IF_ERR_EXIT 5030 (portmod_port_phychain_autoneg_status_get(unit, port, phy_access, nof_phys, an_status)); 5031 5032 exit: 5033 SOC_FUNC_RETURN; 5034 } 5035 5036 int portmod_port_phychain_control_phy_timesync_set(int unit, int port, const phymod_phy_access_t* phy_access, 5037 const int chain_length, 5038 const portmod_port_control_phy_timesync_t type, 5039 uint64_t value) 5040 { 5041 int rv = PHYMOD_E_UNAVAIL; 5042 int phy_index; 5043 int is_legacy_phy = 0; 5044 5045 PHYMOD_NULL_CHECK(phy_access); 5046 5047 /* Most EXT first. */ 5048 phy_index = chain_length - 1; 5049 5050 /* Most EXT */ 5051 rv = PHYMOD_E_UNAVAIL; 5052 while((PHYMOD_E_UNAVAIL == rv) && (phy_index >= 0)) { 5053 is_legacy_phy = 0; 5054 5055 /* if it is external phy, check to see if it is legacy phy. */ 5056 if (phy_index > 0) { 5057 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 5058 if (rv != PHYMOD_E_NONE) return rv; 5059 } 5060 5061 if (is_legacy_phy) { 5062 rv = portmod_port_legacy_control_phy_timesync_set(unit, port, type, value); 5063 } else { 5064 if (phy_access[phy_index].access.lane_mask) { 5065 rv = portmod_common_control_phy_timesync_set(&phy_access[phy_index], type, value); 5066 } else { 5067 rv = PHYMOD_E_NONE; 5068 } 5069 } 5070 phy_index--; 5071 } 5072 return(rv); 5073 } 5074 5075 int portmod_port_phychain_control_phy_timesync_get(int unit, int port, const phymod_phy_access_t* phy_access, 5076 const int chain_length, 5077 const portmod_port_control_phy_timesync_t type, 5078 uint64_t* value) 5079 { 5080 int rv = PHYMOD_E_UNAVAIL; 5081 int phy_index; 5082 int is_legacy_phy = 0; 5083 5084 PHYMOD_NULL_CHECK(phy_access); 5085 5086 /* Most EXT first. */ 5087 phy_index = chain_length - 1; 5088 5089 /* Most EXT */ 5090 rv = PHYMOD_E_UNAVAIL; 5091 while((PHYMOD_E_UNAVAIL == rv) && (phy_index >= 0)) { 5092 is_legacy_phy = 0; 5093 5094 /* if it is external phy, check to see if it is legacy phy. */ 5095 if (phy_index > 0) { 5096 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 5097 if (rv != PHYMOD_E_NONE) return rv; 5098 } 5099 5100 if (is_legacy_phy) { 5101 rv = portmod_port_legacy_control_phy_timesync_get(unit, port, type, value); 5102 } else { 5103 if (phy_access[phy_index].access.lane_mask) { 5104 rv = portmod_common_control_phy_timesync_get(&phy_access[phy_index], type, value); 5105 } else { 5106 rv = PHYMOD_E_NONE; 5107 } 5108 } 5109 phy_index--; 5110 } 5111 return(rv); 5112 } 5113 5114 int portmod_port_phychain_medium_config_set(int unit, int port, soc_port_medium_t medium, 5115 soc_phy_config_t* config) 5116 { 5117 return portmod_port_legacy_medium_config_set(unit, port, medium, config); 5118 } 5119 5120 int portmod_port_phychain_medium_config_get(int unit, int port, soc_port_medium_t medium, 5121 soc_phy_config_t* config) 5122 { 5123 return portmod_port_legacy_medium_config_get(unit, port, medium, config); 5124 } 5125 5126 int portmod_port_phychain_medium_get(int unit, int port, soc_port_medium_t* medium) 5127 { 5128 return portmod_port_legacy_medium_get(unit, port, medium); 5129 } 5130 5131 int portmod_port_phychain_multi_get(int unit, int port, const phymod_phy_access_t* phy_access, 5132 const int chain_length, 5133 portmod_multi_get_t* multi_get) 5134 { 5135 int rv = PHYMOD_E_UNAVAIL; 5136 int phy_index; 5137 int is_legacy_phy = 0; 5138 phymod_multi_data_t datablk ; 5139 5140 /* start from the most external phy. */ 5141 phy_index = chain_length - 1; 5142 5143 /* Most EXT */ 5144 while((PHYMOD_E_UNAVAIL== rv) && (phy_index >= 0)) { 5145 is_legacy_phy = 0; 5146 5147 /* if it is external phy, check to see if it is legacy phy. */ 5148 if (phy_index > 0) { 5149 rv = portmod_xphy_is_legacy_phy_get(unit, phy_access[phy_index].access.addr, &is_legacy_phy); 5150 if (rv != PHYMOD_E_NONE) return rv; 5151 } 5152 5153 if (is_legacy_phy) { 5154 rv = portmod_port_legacy_multi_get(unit, port, 5155 multi_get->flags, 5156 multi_get->dev_addr, 5157 multi_get->offset, 5158 multi_get->max_size, 5159 multi_get->data, 5160 (int *) multi_get->actual_size); 5161 5162 } else { 5163 datablk.flags = multi_get->flags; 5164 datablk.dev_addr = multi_get->dev_addr ; 5165 datablk.offset = multi_get->offset ; 5166 datablk.max_size = multi_get->max_size ; 5167 datablk.data = multi_get->data ; 5168 datablk.actual_size = multi_get->actual_size ; 5169 5170 rv = phymod_phy_multi_get(&phy_access[phy_index], &datablk) ; 5171 } 5172 phy_index--; 5173 } 5174 return(rv); 5175 } 5176 5177 int portmod_port_phychain_master_set(int unit, int port, pm_info_t pm_info, int master_mode) 5178 { 5179 phymod_phy_access_t phy_access_arr[1+MAX_PHYN]; 5180 int xphy_id; 5181 int is_legacy_phy; 5182 int nof_phys; 5183 phymod_master_mode_t ms_mode = phymodMSNone; 5184 5185 SOC_INIT_FUNC_DEFS; 5186 5187 _SOC_IF_ERR_EXIT 5188 (portmod_port_chain_phy_access_get(unit, port, pm_info, 5189 phy_access_arr ,(1+MAX_PHYN), 5190 &nof_phys)); 5191 5192 if (nof_phys == 1) { 5193 switch (master_mode) { 5194 case SOC_PORT_MS_SLAVE: 5195 ms_mode = phymodMSSlave; 5196 break; 5197 case SOC_PORT_MS_MASTER: 5198 ms_mode = phymodMSMaster; 5199 break; 5200 case SOC_PORT_MS_AUTO: 5201 ms_mode = phymodMSAuto; 5202 break; 5203 default: 5204 return PHYMOD_E_PARAM; 5205 } 5206 _SOC_IF_ERR_EXIT 5207 (phymod_phy_master_set(&phy_access_arr[0], ms_mode)); 5208 } else { 5209 xphy_id = phy_access_arr[nof_phys-1].access.addr; 5210 _SOC_IF_ERR_EXIT 5211 (portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy)); 5212 5213 if (is_legacy_phy) { 5214 _SOC_IF_ERR_EXIT 5215 (portmod_port_legacy_master_set(unit, port, master_mode)); 5216 } else { 5217 return PHYMOD_E_UNAVAIL; 5218 } 5219 } 5220 5221 exit: 5222 SOC_FUNC_RETURN; 5223 } 5224 5225 /* 5226 * This function retrieves the SGMII AN mode (master/slave/auto/none). 5227 * Currently it only retrieves the register value for the legacy PHYs. 5228 * For internal PHY, master mode is hard-coded as slave mode. 5229 */ 5230 int portmod_port_phychain_master_get(int unit, int port, pm_info_t pm_info, int* master_mode) 5231 { 5232 phymod_phy_access_t phy_access_arr[1+MAX_PHYN]; 5233 int xphy_id; 5234 int is_legacy_phy; 5235 int nof_phys; 5236 int rv = PHYMOD_E_NONE; 5237 phymod_master_mode_t ms_mode = phymodMSNone; 5238 5239 SOC_INIT_FUNC_DEFS; 5240 5241 _SOC_IF_ERR_EXIT 5242 (portmod_port_chain_phy_access_get(unit, port, pm_info, 5243 phy_access_arr ,(1+MAX_PHYN), 5244 &nof_phys)); 5245 5246 if (nof_phys == 1) { 5247 rv = phymod_phy_master_get(&phy_access_arr[0], &ms_mode); 5248 /*The internal PHY is mainly in slave mode */ 5249 if (rv == PHYMOD_E_UNAVAIL) { 5250 *master_mode = SOC_PORT_MS_SLAVE; 5251 } else { 5252 switch (ms_mode) { 5253 case phymodMSNone: 5254 *master_mode = SOC_PORT_MS_NONE; 5255 break; 5256 case phymodMSSlave: 5257 *master_mode = SOC_PORT_MS_SLAVE; 5258 break; 5259 case phymodMSMaster: 5260 *master_mode = SOC_PORT_MS_MASTER; 5261 break; 5262 case phymodMSAuto: 5263 *master_mode = SOC_PORT_MS_AUTO; 5264 break; 5265 default: 5266 *master_mode = SOC_PORT_MS_NONE; 5267 break; 5268 } 5269 } 5270 } else { 5271 xphy_id = phy_access_arr[nof_phys-1].access.addr; 5272 _SOC_IF_ERR_EXIT 5273 (portmod_xphy_is_legacy_phy_get(unit, xphy_id, &is_legacy_phy)); 5274 5275 if (is_legacy_phy) { 5276 _SOC_IF_ERR_EXIT 5277 (portmod_port_legacy_master_get(unit, port, master_mode)); 5278 } else { 5279 /* 5280 * PHYMOD-based ext PHYs have not implemented the matser_get API, 5281 * so we follow the convention of bcmi_esw_portctrl_master_get() 5282 * to make master_mode BCM_PORT_MS_NONE when the API is not supported. 5283 * Otherwise there will be error messages popping up during init 5284 * and ps. 5285 */ 5286 *master_mode = BCM_PORT_MS_NONE; 5287 } 5288 } 5289 5290 exit: 5291 SOC_FUNC_RETURN; 5292 }