tsce.c (291802B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: tsce.c 8 * Purpose: Support Broadcom TSC/Eagle internal SerDes 9 */ 10 11 /* 12 * This module implements an NTSW SDK Phy driver for the TSC/Eagle Serdes. 13 * 14 * LAYERING. 15 * 16 * This driver is built on top of the PHYMOD library, which is a PHY 17 * driver library that can operate on a family of PHYs, including 18 * TSC/Eagle. PHYMOD can be built in a standalone enviroment and be 19 * provided independently from the SDK. PHYMOD APIs consist of 20 * "core" APIs and "phy" APIs. 21 * 22 * 23 * KEY IDEAS AND MAIN FUNCTIONS 24 * 25 * Some key ideas in this architecture are: 26 * 27 * o A PHMOD "phy" consists of one more more lanes, all residing in a single 28 * core. An SDK "phy" is a logical port, which can consist of one or 29 * more lanes in a single core, OR, can consist of multiples lanes in 30 * more than one core. 31 * o PHYMOD code is "stateless" in the sense that all calls to PHYMOD 32 * APIs are fully parameterized and no per-phy state is held by a PHYMOD 33 * driver. 34 * o PHYMOD APIs do not map 1-1 with SDK .pd_control_set or .pd_control_get 35 * APIs (nor ".pd_xx" calls, nor to .phy_tsce_per_lane_control_set and 36 * .phy_tsce_per_lane_control_get APIs. 37 * 38 * The purpose of this code, then, is to provide the necessary translations 39 * between the SDK interfaces and the PHYMOD interfaces. This includes: 40 * 41 * o Looping over the cores in a logical PHY in order to operate on the 42 * supporting PHMOD PHYs 43 * o Determining the configuration data for the phy, based on programmed 44 * defaults and SOC properties. 45 * o Managing the allocation and freeing of phy data structures required for 46 * working storage. Locating these structures on procedure invocation. 47 * o Mapping SDK API concepts to PHYMOD APIs. In some cases, local state is 48 * required in this module in order to present the legacy API. 49 * 50 * 51 * MAIN DATA STRUCTURES 52 * 53 * phy_ctrl_t 54 * The PHY control structure defines the SDK notion of a PHY 55 * (existing) structure owned by SDK phy driver modules. In order 56 * to support PHYMOD PHYs, one addition was made to this structure 57 * (soc_phymod_ctrl_t phymod_ctrl;) 58 * 59 * tsce_config_t 60 * Driver specific data. This structure is used by tsce to hold 61 * logical port specific working storage. 62 * 63 * soc_phymod_ctrl_t 64 * PHYMOD drivers. Resides in phy_ctrl_t specifies how many cores 65 * are in this phy and contains an array of pointers to 66 * soc_phymod_phy_t structures, which define a PHYMOD PHY. 67 * 68 * soc_phymod_phy_t 69 * This structure contains a pointer to phymod_phy_access_t and a 70 * pointer to the associated soc_phymod_core_t. Instances if this 71 * structure are created during device probe/init and are maintained 72 * by the SOC. 73 * 74 * soc_phymod_core_t 75 * This structure contains per-core information. Multiple PHYMOD 76 * PHYS can point to a single core. 77 * 78 * phymod_phy_access_t 79 * This structure contains information about how to read/write PHY 80 * registers. A required parameter for PHYMOD PHY APIs 81 * 82 * phymod_core_access_t 83 * This structure contains information about how to read/write PHY 84 * registers. A required parameter for PHYMOD core APIs. 85 */ 86 87 #include <shared/bsl.h> 88 89 #include <sal/types.h> 90 #include <sal/types.h> 91 #include <sal/core/spl.h> 92 #include <shared/bsl.h> 93 #include <soc/drv.h> 94 #include <soc/debug.h> 95 #include <soc/error.h> 96 #include <soc/phyreg.h> 97 #include <soc/port_ability.h> 98 #include <soc/phy.h> 99 #include <soc/phy/phyctrl.h> 100 #include <soc/phy/drv.h> 101 #include <soc/phy/phymod_ids.h> 102 103 #include "phydefs.h" /* Must include before other phy related includes */ 104 105 #include "phyconfig.h" /* Must include before other phy related includes */ 106 #include "phyident.h" 107 #include "phyreg.h" 108 #include "phynull.h" 109 #include "xgxs.h" 110 #include "serdesid.h" 111 112 113 114 int (*_phy_tsce_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int) = { NULL }; 115 116 #if defined(INCLUDE_XGXS_TSCE) 117 118 #include <phymod/phymod.h> 119 #include <phymod/phymod_debug.h> 120 #include <phymod/phymod_diagnostics.h> 121 #include <phymod/phymod_util.h> 122 #include <phymod/chip/bcmi_tsce_xgxs_sym.h> 123 #include <phymod/chip/tsce.h> 124 125 #include "../../../libs/phymod/chip/tsce/tier1/temod_device.h" 126 127 128 #define NUM_LANES 4 /* num of lanes per core */ 129 #define MAX_NUM_LANES 4 /* max num of lanes per port */ 130 #define TSCE_NO_CFG_VALUE (-1) 131 #define TOTAL_MAX_NUM_LANES 12 132 133 typedef struct tsce_speed_config_s { 134 uint32 port_refclk_int; 135 int speed; 136 int port_num_lanes; 137 int port_is_higig; 138 int rxaui_mode; 139 int scrambler_en; 140 uint32 line_interface; 141 int pcs_bypass; 142 int fiber_pref; 143 int phy_supports_dual_rate; 144 int port_is_triple_core ; 145 int triple_core_mode ; 146 int pll_divider_req ; 147 temod_device_aux_modes_t *core_device_aux_modes ; 148 } tsce_speed_config_t; 149 150 #define NUM_PATTERN_DATA_INTS 8 151 typedef struct tsce_pattern_s { 152 uint32 pattern_data[NUM_PATTERN_DATA_INTS]; 153 uint32 pattern_length; 154 } tsce_pattern_t; 155 156 #define TSCE_LANE_NAME_LEN 30 157 158 typedef struct { 159 uint16 serdes_id0; 160 char name[TSCE_LANE_NAME_LEN]; 161 } tsce_dev_info_t; 162 163 /* index to TX drive configuration table for each VCO setting. 164 */ 165 typedef enum txdrv_inxs { 166 TXDRV_XFI_INX = 0, /* 10G XFI */ 167 TXDRV_XLAUI_INX, /* 40G XLAUI mode */ 168 TXDRV_SFI_INX, /* 10G SR fiber mode */ 169 TXDRV_SFIDAC_INX, /* 10G SFI DAC mode */ 170 TXDRV_SR4_INX, /* 40G SR4 */ 171 TXDRV_AN_INX, /* a common entry for autoneg mode */ 172 TXDRV_DFT_INX, /* temp for any missing speed modes */ 173 TXDRV_LAST_INX /* always last */ 174 } TXDRV_INXS_t; 175 176 #define TXDRV_ENTRY_NUM (TXDRV_LAST_INX) 177 178 179 180 /* 181 Config - per logical port 182 */ 183 typedef struct { 184 phymod_polarity_t phy_polarity_config; 185 phymod_phy_reset_t phy_reset_config; 186 tsce_pattern_t pattern; 187 tsce_speed_config_t speed_config; 188 189 int fiber_pref; /* spn_SERDES_FIBER_PREF */ 190 int cl73an; /* spn_PHY_AN_C73 */ 191 int cx4_10g; /* spn_10G_IS_CX4 */ 192 int pdetect1000x; 193 int pdetect10g; 194 int cl37an; /* spn_PHY_AN_C37 */ 195 int cl37_sgmii_war ; 196 int cl37_sgmii_cnt ; 197 int cl37_sgmii_RESTART_CNT ; 198 int an_cl72; /* spn_PHY_AN_C72 */ 199 int forced_init_cl72; /* spn_FORCED_INIT_CL72 */ 200 int hg_mode; /* higig port */ 201 int an_fec; /*enable FEC for AN mode */ 202 int sgmii_mstr; /* sgmii master mode */ 203 int serdes_1000x_at_6250_vco; /* 1g speed at 6250 vco*/ 204 tsce_dev_info_t info; /*serdes id info */ 205 phymod_tx_t tx_drive[TXDRV_ENTRY_NUM]; 206 phymod_tx_t ln_txparam[TOTAL_MAX_NUM_LANES] ; 207 208 int pcs_table_override ; 209 temod_device_aux_modes_t *core_device_aux_modes ; 210 int fec_enable; /* this parameter is to specify FEC to enable during init */ 211 212 } tsce_config_t; 213 214 /* 215 #define TSCE_IF_NULL (1 << SOC_PORT_IF_NULL) 216 #define TSCE_IF_SR (1 << SOC_PORT_IF_SR) 217 #define TSCE_IF_SR4 (1 << SOC_PORT_IF_SR4) 218 #define TSCE_IF_KR (1 << SOC_PORT_IF_KR) 219 #define TSCE_IF_KR4 (1 << SOC_PORT_IF_KR4) 220 #define TSCE_IF_CR (1 << SOC_PORT_IF_CR) 221 #define TSCE_IF_CR4 (1 << SOC_PORT_IF_CR4) 222 #define TSCE_IF_XFI (1 << SOC_PORT_IF_XFI) 223 #define TSCE_IF_SFI (1 << SOC_PORT_IF_SFI) 224 #define TSCE_IF_XLAUI (1 << SOC_PORT_IF_XLAUI) 225 #define TSCE_IF_XGMII (1 << SOC_PORT_IF_XGMII) 226 #define TSCE_IF_ILKN (1 << SOC_PORT_IF_ILKN) 227 */ 228 229 #define TSCE_40G_10G_INTF(_if) ((_if) == SOC_PORT_IF_KR4 || (_if) == SOC_PORT_IF_XLAUI || (_if) == SOC_PORT_IF_SR4 ||\ 230 (_if) == SOC_PORT_IF_CR4 || (_if) == SOC_PORT_IF_SR || \ 231 (_if) == SOC_PORT_IF_KR || (_if) == SOC_PORT_IF_CR || \ 232 (_if) == SOC_PORT_IF_XFI || (_if) == SOC_PORT_IF_SFI) 233 234 #define TSCE_40G_10G_INTF_ALL (TSCE_IF_KR4 | TSCE_IF_XLAUI | TSCE_IF_CR4 | TSCE_IF_SR | TSCE_IF_SR4 |\ 235 TSCE_IF_KR | TSCE_IF_CR | TSCE_IF_XFI | TSCE_IF_SFI) 236 237 238 #define TEMOD_CL73_CL37 0x5 239 #define TEMOD_CL73_HPAM 0x4 240 #define TEMOD_CL73_HPAM_VS_SW 0x8 241 #define TEMOD_CL73_WO_BAM 0x2 242 #define TEMOD_CL73_W_BAM 0x1 243 #define TEMOD_CL73_DISABLE 0x0 244 245 #define TEMOD_CL37_SGMII_COMBO 6 246 #define TEMOD_CL37_HR2SPM_W_10G 5 247 #define TEMOD_CL37_HR2SPM 4 248 #define TEMOD_CL37_W_10G 3 249 #define TEMOD_CL37_WO_BAM 2 250 #define TEMOD_CL37_W_BAM 1 251 #define TEMOD_CL37_DISABLE 0 252 253 #define PATTERN_MAX_SIZE (8) 254 255 /* following defines is for FEC init value */ 256 #define TSCE_FEC_OFF 0x0 257 #define TSCE_FEC_CL74 0x1 258 259 #define TSCE_FW_CHECK_MASK 0xff00 260 #define TSCE_FW_MODE_MASK 0x00ff 261 #define TSCE_FW_TO_VERIFY 0x0100 262 #define TSCE_FW_NO_VERIFY 0x0000 263 264 STATIC int tsce_fec_enable_set(soc_phymod_ctrl_t *pmc, uint32 value); 265 STATIC int tsce_cl72_enable_set(soc_phymod_ctrl_t *pmc, uint32 value); 266 STATIC int phy_tsce_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability); 267 STATIC int phy_tsce_ability_advert_set(int unit, soc_port_t port, 268 soc_port_ability_t *ability); 269 STATIC int phy_tsce_speed_get(int unit, soc_port_t port, int *speed); 270 STATIC int phy_tsce_interface_get(int unit, soc_port_t port, soc_port_if_t *pif); 271 272 /* 273 * Function: 274 * _tsce_reg_read 275 * Doc: 276 * register read operations 277 * Parameters: 278 * unit - (IN) unit number 279 * core_addr - (IN) core address 280 * reg_addr - (IN) address to read 281 * val - (OUT) read value 282 */ 283 STATIC int 284 _tsce_reg_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val) 285 { 286 uint16 data16; 287 int rv; 288 soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc; 289 290 rv = core->read(core->unit, core_addr, reg_addr, &data16); 291 *val = data16; 292 return rv; 293 } 294 295 /* 296 * Function: 297 * _tsce_reg_write 298 * Doc: 299 * register write operations 300 * Parameters: 301 * unit - (IN) unit number 302 * core_addr - (IN) core address 303 * reg_addr - (IN) address to write 304 * val - (IN) write value 305 */ 306 STATIC int 307 _tsce_reg_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val) 308 { 309 soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc; 310 uint16 data16 = (uint16)val; 311 uint16 mask = (uint16)(val >> 16); 312 if (mask) { 313 if (core->wrmask) { 314 return core->wrmask(core->unit, core_addr, reg_addr, data16, mask); 315 } 316 (void)core->read(core->unit, core_addr, reg_addr, &data16); 317 data16 &= ~mask; 318 data16 |= (val & mask); 319 } 320 return core->write(core->unit, core_addr, reg_addr, data16); 321 } 322 323 /* 324 * Function: 325 * tsce_firmware_loader 326 * Purpose: 327 * Download PHY firmware using fast interface such as S-channel. 328 * Parameters: 329 * pm_core - (IN) PHY core oject 330 * fw_len - (IN) Number of bytes to download 331 * fw_data - (IN) Firmware as byte array 332 */ 333 STATIC int 334 tsce_firmware_loader(const phymod_core_access_t *pm_core, 335 uint32 fw_len, const uint8 *fw_data) 336 { 337 soc_phymod_core_t *core; 338 int unit, port; 339 340 if (pm_core == NULL) { 341 return PHYMOD_E_PARAM; 342 } 343 344 /* Retrieve SOC information from PHYMOD object */ 345 core = (soc_phymod_core_t *)(pm_core->access.user_acc); 346 347 if (core == NULL) { 348 return PHYMOD_E_PARAM; 349 } 350 351 /* Get associated unit/port */ 352 unit = core->unit; 353 port = core->port; 354 355 return _phy_tsce_firmware_set_helper[unit](unit, port, 356 (uint8 *)fw_data, fw_len); 357 } 358 359 360 #define IS_DUAL_LANE_PORT(_pc) ((_pc)->phy_mode == PHYCTRL_DUAL_LANE_PORT) 361 #define IND_LANE_MODE(_pc) (((_pc)->phy_mode == PHYCTRL_DUAL_LANE_PORT) || ((_pc)->phy_mode == PHYCTRL_ONE_LANE_PORT)) 362 #define MAIN0_SERDESID_REV_LETTER_SHIFT (14) 363 #define MAIN0_SERDESID_REV_NUMBER_SHIFT (11) 364 365 /* 366 * Function: 367 * tsce_firmware_loader 368 * Purpose: 369 * Download PHY firmware using fast interface such as S-channel. 370 * Parameters: 371 * pc - (IN) phyctrl oject 372 * pInfo - (IN) device info object 373 * rev_id - (IN) serdes revid 374 * Returns: 375 * SOC_E_NONE 376 */ 377 STATIC int 378 tsce_show_serdes_info(phy_ctrl_t *pc, tsce_dev_info_t *pInfo, phymod_core_info_t *core_info) 379 { 380 uint32_t serdes_id0, len; 381 382 pInfo->serdes_id0 = core_info->serdes_id ; 383 384 /* This is TSC/Eagle device */ 385 serdes_id0 = pInfo->serdes_id0; 386 if (core_info->core_version == phymodCoreVersionTsce4A0) { 387 sal_strcpy(pInfo->name,"TSCE4-"); 388 } else if (core_info->core_version == phymodCoreVersionTsceDpll){ 389 sal_strcpy(pInfo->name,"TSCE_GEN3-"); 390 } else { 391 sal_strcpy(pInfo->name,"TSCE12-"); 392 } 393 len = sal_strlen(pInfo->name); 394 /* add rev letter */ 395 pInfo->name[len++] = 'A' + ((serdes_id0 >> 396 MAIN0_SERDESID_REV_LETTER_SHIFT) & 0x3); 397 /* add rev number */ 398 pInfo->name[len++] = '0' + ((serdes_id0 >> 399 MAIN0_SERDESID_REV_NUMBER_SHIFT) & 0x7); 400 pInfo->name[len++] = '/'; 401 pInfo->name[len++] = (pc->chip_num / 10) % 10 + '0'; 402 pInfo->name[len++] = pc->chip_num % 10 + '0'; 403 pInfo->name[len++] = '/'; 404 405 /* phy_mode: 0 single port mode, port uses all four lanes of Warpcore 406 * 1 dual port mode, port uses 2 lanes 407 * 2 quad port mode, port uses 1 lane 408 */ 409 if (IS_DUAL_LANE_PORT(pc)) { /* dual-xgxs mode */ 410 if (pc->lane_num < 2) { /* the first dual-xgxs port */ 411 pInfo->name[len++] = '0'; 412 pInfo->name[len++] = '-'; 413 pInfo->name[len++] = '1'; 414 } else { 415 pInfo->name[len++] = '2'; 416 pInfo->name[len++] = '-'; 417 pInfo->name[len++] = '3'; 418 } 419 } else if (pc->phy_mode == PHYCTRL_ONE_LANE_PORT) { 420 pInfo->name[len++] = pc->lane_num + '0'; 421 } else { 422 pInfo->name[len++] = '4'; 423 } 424 pInfo->name[len] = 0; /* string terminator */ 425 426 if (len > TSCE_LANE_NAME_LEN) { 427 LOG_ERROR(BSL_LS_SOC_COMMON, 428 (BSL_META("TSCE info string length %d exceeds max length 0x%x: u=%d p=%d\n"), 429 len,TSCE_LANE_NAME_LEN, pc->unit, pc->port)); 430 return SOC_E_MEMORY; 431 } 432 return SOC_E_NONE; 433 } 434 435 STATIC int 436 tsce_ref_clk_convert(int port_refclk_int, phymod_ref_clk_t *ref_clk) 437 { 438 switch (port_refclk_int) 439 { 440 case 156: 441 *ref_clk = phymodRefClk156Mhz; 442 break; 443 case 125: 444 *ref_clk = phymodRefClk125Mhz; 445 break; 446 default: 447 return SOC_E_PARAM; 448 break; 449 } 450 451 return SOC_E_NONE; 452 } 453 454 /* 455 * Function: 456 * tsce_speed_to_interface_config_get 457 * Purpose: 458 * Convert speed to interface_config struct 459 * Parameters: 460 * unit - BCM unit number. 461 * port - Port number. 462 * speed - speed to convert 463 * interface_config - output interface config struct 464 * Returns: 465 * SOC_E_NONE 466 */ 467 STATIC int 468 tsce_speed_to_interface_config_get(const phymod_phy_access_t *phy, tsce_speed_config_t* speed_config, phymod_phy_inf_config_t* interface_config, TXDRV_INXS_t* tx_index) 469 { 470 int port_is_higig; 471 int port_num_lanes; 472 int scr_enabled; 473 int fiber_pref; 474 port_num_lanes = speed_config->port_num_lanes; 475 port_is_higig = speed_config->port_is_higig; 476 scr_enabled = speed_config->scrambler_en; 477 fiber_pref = speed_config->fiber_pref; 478 479 SOC_IF_ERROR_RETURN(phymod_phy_inf_config_t_init(interface_config)); 480 481 interface_config->interface_modes = 0; 482 interface_config->data_rate = speed_config->speed; 483 interface_config->pll_divider_req = speed_config->pll_divider_req ; 484 interface_config->device_aux_modes= speed_config->core_device_aux_modes ; 485 486 *tx_index = TXDRV_DFT_INX; 487 488 if (port_is_higig) { 489 PHYMOD_INTF_MODES_HIGIG_SET(interface_config); 490 } 491 if (fiber_pref) { 492 PHYMOD_INTF_MODES_FIBER_SET(interface_config); 493 } 494 if(speed_config->port_is_triple_core) { 495 PHYMOD_INTF_MODES_TRIPLE_CORE_SET(interface_config) ; 496 switch(speed_config->triple_core_mode) { 497 case phymodTripleCore244: PHYMOD_INTF_MODES_TC_244_SET(interface_config) ; break ; 498 case phymodTripleCore343: PHYMOD_INTF_MODES_TC_343_SET(interface_config) ; break ; 499 case phymodTripleCore442: PHYMOD_INTF_MODES_TC_442_SET(interface_config) ; break ; 500 default: 501 break ; 502 } 503 } 504 switch (speed_config->speed) { 505 case 0: 506 case 10: 507 interface_config->interface_type = phymodInterfaceSGMII; 508 *tx_index = TXDRV_DFT_INX; 509 break; 510 case 100: 511 case 1000: 512 if (speed_config->fiber_pref) { 513 interface_config->interface_type = phymodInterface1000X; 514 *tx_index = TXDRV_SFI_INX; 515 516 } else { 517 interface_config->interface_type = phymodInterfaceSGMII; 518 *tx_index = TXDRV_DFT_INX; 519 } 520 break; 521 case 2500: 522 interface_config->interface_type = phymodInterface1000X; 523 *tx_index = TXDRV_SFI_INX; 524 break; 525 case 5000: 526 if (speed_config->fiber_pref) { 527 interface_config->interface_type = phymodInterface1000X; 528 } else { 529 interface_config->interface_type = phymodInterfaceXFI; 530 } 531 *tx_index = TXDRV_XFI_INX; 532 break; 533 case 3125: 534 case 5750: 535 interface_config->interface_type = phymodInterfaceBypass; 536 break; 537 case 6250: 538 interface_config->interface_type = phymodInterfaceBypass; 539 if(speed_config->phy_supports_dual_rate) { /* for dual rate OS2 is required */ 540 PHYMOD_INTF_MODES_OS2_SET(interface_config); 541 } 542 break; 543 case 8125: 544 case 8500: 545 interface_config->interface_type = phymodInterfaceBypass; 546 break; 547 case 10000: 548 if (port_num_lanes == 4) { 549 /*The SOC_PORT_IF_XAUI is defined as _SHR_PORT_IF_XGMII. 550 If use the MACRO SOC_PORT_IF_XAUI, the interface showed in "ps" will be XGMII. 551 */ 552 if ((speed_config->line_interface == _SHR_PORT_IF_XAUI) && (!port_is_higig)) { 553 interface_config->interface_type = phymodInterfaceXAUI; 554 } else { 555 interface_config->interface_type = phymodInterfaceXGMII; 556 } 557 } else if (port_num_lanes == 2) { 558 if (speed_config->rxaui_mode == 0x2) { 559 interface_config->interface_type = phymodInterfaceRXAUI; 560 } 561 else if (speed_config->rxaui_mode) { 562 interface_config->interface_type = phymodInterfaceX2; 563 } else { 564 interface_config->interface_type = phymodInterfaceRXAUI; 565 } 566 if (scr_enabled) { 567 PHYMOD_INTF_MODES_SCR_SET(interface_config); 568 } 569 } else { 570 if ((speed_config->line_interface ==SOC_PORT_IF_SFI) || 571 (speed_config->line_interface ==SOC_PORT_IF_SR) || 572 (speed_config->line_interface ==SOC_PORT_IF_LR)) { 573 interface_config->interface_type = phymodInterfaceSFI; 574 } else if(speed_config->line_interface ==SOC_PORT_IF_CR) { 575 interface_config->interface_type = phymodInterfaceSFPDAC; 576 *tx_index = TXDRV_SFIDAC_INX; 577 } else if(speed_config->line_interface ==SOC_PORT_IF_KR) { 578 interface_config->interface_type = phymodInterfaceKR; 579 *tx_index = TXDRV_XFI_INX; 580 } else { 581 if (fiber_pref) { 582 interface_config->interface_type = phymodInterfaceSFI; 583 *tx_index = TXDRV_SFI_INX; 584 } else { 585 interface_config->interface_type = phymodInterfaceXFI; 586 *tx_index = TXDRV_XFI_INX; 587 } 588 } 589 } 590 break; 591 case 10312: 592 interface_config->interface_type = phymodInterfaceBypass; 593 break; 594 case 10500: 595 break ; 596 case 10937: 597 interface_config->interface_type = phymodInterfaceBypass; 598 break; 599 case 11000: 600 interface_config->interface_type = phymodInterfaceXFI; 601 *tx_index = TXDRV_XFI_INX; 602 break; 603 case 11250: 604 interface_config->interface_type = phymodInterfaceBypass; 605 break; 606 case 11500: 607 if (speed_config->pcs_bypass) { 608 interface_config->interface_type = phymodInterfaceBypass; 609 } else { 610 interface_config->interface_type = phymodInterfaceXFI; 611 *tx_index = TXDRV_XFI_INX; 612 } 613 break; 614 case 12000: 615 if (port_num_lanes == 2) { 616 interface_config->interface_type = phymodInterfaceRXAUI; 617 } else { 618 interface_config->interface_type = phymodInterfaceXFI; 619 *tx_index = TXDRV_XFI_INX; 620 } 621 break ; 622 case 12500: 623 if (speed_config->pcs_bypass) { 624 interface_config->interface_type = phymodInterfaceBypass; 625 } else { 626 interface_config->interface_type = phymodInterfaceXFI; 627 *tx_index = TXDRV_XFI_INX; 628 } 629 break; 630 case 12773: /* 12733Mbps */ 631 case 12700: /* 12733Mbps */ 632 interface_config->interface_type = phymodInterfaceRXAUI; 633 break ; 634 case 13000: 635 if (port_num_lanes == 4) { 636 interface_config->interface_type = phymodInterfaceXGMII; 637 } else if (port_num_lanes == 2) { 638 interface_config->interface_type = phymodInterfaceRXAUI; 639 } 640 break; 641 case 15000: 642 interface_config->interface_type = phymodInterfaceXGMII; 643 break; 644 case 15750: 645 case 16000: /* setting RX66_CONTROL_CC_EN/CC_DATA_SEL failed this 16000 HI_DXGXS mode */ 646 if (port_num_lanes == 4){ 647 interface_config->interface_type = phymodInterfaceXGMII; 648 } else if (port_num_lanes == 2) { 649 interface_config->interface_type = phymodInterfaceRXAUI; 650 } 651 break ; 652 /* WCMOD_SPD_21G_HI_DXGXS ?? */ 653 case 20000: 654 if (port_num_lanes == 4) { 655 if (scr_enabled) { 656 PHYMOD_INTF_MODES_SCR_SET(interface_config); 657 } 658 interface_config->interface_type = phymodInterfaceXGMII; 659 } else if(port_num_lanes == 2) { 660 if (port_is_higig) { 661 interface_config->interface_type = phymodInterfaceRXAUI; 662 663 if( (speed_config->line_interface ==SOC_PORT_IF_KR2) || 664 (speed_config->line_interface ==SOC_PORT_IF_KR) ) { 665 interface_config->interface_type = phymodInterfaceKR2; 666 *tx_index = TXDRV_XFI_INX; 667 } else if( (speed_config->line_interface ==SOC_PORT_IF_CR2) || 668 (speed_config->line_interface ==SOC_PORT_IF_CR) ) { 669 interface_config->interface_type = phymodInterfaceCR2; 670 *tx_index = TXDRV_SFIDAC_INX; 671 } 672 } else { 673 interface_config->interface_type = phymodInterfaceKR2; 674 *tx_index = TXDRV_XFI_INX; 675 if( (speed_config->line_interface ==SOC_PORT_IF_CR2) || 676 (speed_config->line_interface ==SOC_PORT_IF_CR) ) { 677 interface_config->interface_type = phymodInterfaceCR2; 678 *tx_index = TXDRV_SFIDAC_INX; 679 } 680 } 681 } 682 break ; 683 case 21000: 684 if (port_num_lanes == 4) { 685 interface_config->interface_type = phymodInterfaceXGMII; 686 }else if(port_num_lanes == 2) { 687 if (port_is_higig) { 688 interface_config->interface_type = phymodInterfaceRXAUI; 689 690 if( (speed_config->line_interface ==SOC_PORT_IF_KR2) || 691 (speed_config->line_interface ==SOC_PORT_IF_KR) ) { 692 interface_config->interface_type = phymodInterfaceKR2; 693 *tx_index = TXDRV_XFI_INX; 694 } else if( (speed_config->line_interface ==SOC_PORT_IF_CR2) || 695 (speed_config->line_interface ==SOC_PORT_IF_CR) ) { 696 interface_config->interface_type = phymodInterfaceCR2; 697 *tx_index = TXDRV_SFIDAC_INX; 698 } 699 } else { 700 interface_config->interface_type = phymodInterfaceKR2; 701 *tx_index = TXDRV_XFI_INX; 702 if( (speed_config->line_interface ==SOC_PORT_IF_CR2) || 703 (speed_config->line_interface ==SOC_PORT_IF_CR) ) { 704 interface_config->interface_type = phymodInterfaceCR2; 705 *tx_index = TXDRV_SFIDAC_INX; 706 } 707 } 708 } 709 break ; 710 case 23000: 711 if (port_num_lanes == 2) { 712 interface_config->interface_type = phymodInterfaceX2; 713 *tx_index = TXDRV_XFI_INX; 714 } 715 break ; 716 case 25000: 717 case 25455: 718 if (port_num_lanes == 1) { 719 interface_config->interface_type = phymodInterfaceKR; 720 } else if (port_num_lanes == 2) { 721 interface_config->interface_type = phymodInterfaceKR2; 722 } else { 723 interface_config->interface_type = phymodInterfaceKR4; 724 } 725 break ; 726 case 30000: 727 case 31500: 728 interface_config->interface_type = phymodInterfaceXGMII; 729 break; 730 case 40000: 731 if (port_is_higig) { 732 if (speed_config->line_interface == SOC_PORT_IF_KR4) { 733 interface_config->interface_type = phymodInterfaceKR4; 734 *tx_index = TXDRV_XLAUI_INX; 735 } else { 736 interface_config->interface_type = phymodInterfaceXGMII; 737 *tx_index = TXDRV_XLAUI_INX; 738 } 739 } else { 740 if (fiber_pref) { 741 PHYMOD_INTF_MODES_FIBER_SET(interface_config); 742 interface_config->interface_type = phymodInterfaceSR4; 743 *tx_index = TXDRV_SR4_INX; 744 } else { 745 if (speed_config->line_interface == SOC_PORT_IF_KR4) { 746 interface_config->interface_type = phymodInterfaceKR4; 747 *tx_index = TXDRV_SR4_INX; 748 } else if (speed_config->line_interface == SOC_PORT_IF_CR4) { 749 interface_config->interface_type = phymodInterfaceCR4; 750 *tx_index = TXDRV_SR4_INX; 751 } else { 752 interface_config->interface_type = phymodInterfaceXLAUI; 753 *tx_index = TXDRV_XLAUI_INX; 754 } 755 } 756 } 757 break; 758 case 42000: 759 if (port_is_higig) { 760 if (speed_config->line_interface == SOC_PORT_IF_KR4) { 761 interface_config->interface_type = phymodInterfaceKR4; 762 *tx_index = TXDRV_SR4_INX; 763 } else if (speed_config->line_interface == SOC_PORT_IF_CR4){ 764 interface_config->interface_type = phymodInterfaceCR4; 765 *tx_index = TXDRV_SR4_INX; 766 } else { 767 interface_config->interface_type = phymodInterfaceXGMII; 768 *tx_index = TXDRV_XLAUI_INX; 769 } 770 } else { 771 interface_config->interface_type = phymodInterfaceKR4; 772 *tx_index = TXDRV_SR4_INX; 773 } 774 break; 775 case 100000: 776 case 107000: 777 case 120000: 778 case 127000: 779 interface_config->interface_type = phymodInterfaceCR10; 780 *tx_index = TXDRV_XLAUI_INX; 781 break ; 782 default: 783 return SOC_E_PARAM; 784 } 785 786 SOC_IF_ERROR_RETURN 787 (tsce_ref_clk_convert(speed_config->port_refclk_int, &(interface_config->ref_clock))); 788 789 return SOC_E_NONE; 790 } 791 792 /* 793 * Function: 794 * tsce_chip_bonding_swap 795 * Purpose: 796 * Determine phy lane swap due to bump flipping or package wire bonding swap. 797 * This info is chip dependent. 798 * 799 * Parameters: 800 * unit - BCM unit number. 801 * port - Port number. 802 * is_tx - is TX or RX. 803 * offset - starting logical lane number 804 * Returns: 805 * 1 is the swap (3,2,1,0) <-> (0,1,2,3) is required. 0 means no swap. 806 */ 807 STATIC int 808 tsce_chip_bonding_swap(int unit, soc_port_t port, int is_tx, int offset) 809 { 810 soc_info_t *si; 811 int phy_port; 812 si = &SOC_INFO(unit); 813 if (soc_feature(unit, soc_feature_logical_port_num)) { 814 phy_port = si->port_l2p_mapping[port] + offset ; 815 } else { 816 phy_port = port + offset ; 817 } 818 if(SOC_IS_TD2P_TT2P(unit)) { 819 if((phy_port/16)%2) { /* even mod 16 block */ 820 if((phy_port/4)%2){ /* even mod 4 sub-block */ 821 if(is_tx) { 822 return 0 ; 823 } else { 824 return 1 ; 825 } 826 } else { 827 if(is_tx) { 828 return 1 ; 829 } else { 830 return 0 ; 831 } 832 } 833 } else { 834 if((phy_port/4)%2){ /* even mod 4 sub-block */ 835 if(is_tx) { 836 return 0 ; 837 } else { 838 return 1 ; 839 } 840 } else { 841 if(is_tx) { 842 return 1 ; 843 } else { 844 return 0 ; 845 } 846 } 847 } 848 /* return 1 if bonding swapped */ 849 /* return 0 if nothing */ 850 } else { 851 return 0 ; 852 } 853 } 854 855 /* 856 * Function: 857 * tsce_config_init 858 * Purpose: 859 * Determine phy configuration data for purposes of PHYMOD initialization. 860 * 861 * A side effect of this procedure is to save some per-logical port 862 * information in (tsce_cfg_t *) &pc->driver_data; 863 * 864 * Parameters: 865 * unit - BCM unit number. 866 * port - Port number. 867 * logical_lane_offset - starting logical lane number 868 * Returns: 869 * SOC_E_NONE 870 */ 871 872 STATIC int 873 tsce_config_init(int unit, soc_port_t port, const phymod_phy_access_t* phy, 874 int logical_lane_offset, 875 phymod_core_init_config_t *core_init_config, 876 phymod_phy_init_config_t *pm_phy_init_config) 877 { 878 phy_ctrl_t *pc; 879 tsce_speed_config_t *speed_config; 880 tsce_config_t *pCfg; 881 phymod_tx_t *p_tx; 882 phymod_firmware_load_method_t fw_ld_method; 883 int port_refclk_int; 884 int port_num_lanes; 885 int core_num; 886 soc_info_t *si; /* SOC_IS_TRIDENT2PLUS(unit)*/ 887 int phy_num_lanes; 888 int port_is_higig; 889 int lane_config_mode = 0; 890 int phy_passthru; 891 int phy_supports_dual_rate; 892 int lane_map_rx, lane_map_tx, chip_bonding_swap; 893 int i; 894 int fiber_pref = 1; 895 int is_tx, lane_map_rx_l = 0 ; 896 int amp ; 897 uint32_t preemphasis; 898 TXDRV_INXS_t tx_index = TXDRV_DFT_INX; 899 900 pc = INT_PHY_SW_STATE(unit, port); 901 if (pc == NULL) { 902 return SOC_E_INTERNAL; 903 } 904 pCfg = (tsce_config_t *) pc->driver_data; 905 906 si = &SOC_INFO(unit); /* SOC_IS_TRIDENT2PLUS(unit)*/ 907 /* determine physical port (mapping logical to physical if necessary) */ 908 /* if (soc_feature(unit, soc_feature_logical_port_num)) { 909 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 910 } else { 911 phy_port = port; 912 } */ 913 914 /* extract data from SOC_INFO */ 915 /*port_refclk_int = SOC_INFO(unit).port_refclk_int[port];*/ 916 #if 0 917 918 port_refclk_int = soc_property_port_get(unit,port, spn_XGXS_PHY_VCO_FREQ, pCfg->refclk); 919 #endif 920 port_refclk_int = 156; 921 port_refclk_int = soc_property_port_get(unit, port,spn_XGXS_LCPLL_XTAL_REFCLK, port_refclk_int); 922 port_num_lanes = SOC_INFO(unit).port_num_lanes[port]; 923 port_is_higig = PBMP_MEMBER(PBMP_HG_ALL(unit), port); 924 phy_supports_dual_rate = PHY_IS_SUPPORT_DUAL_RATE(unit, port); 925 926 /* figure out how many lanes are in this phy */ 927 core_num = (logical_lane_offset / 4); 928 phy_num_lanes = port_num_lanes ; 929 if (phy_num_lanes > MAX_NUM_LANES) { 930 phy_num_lanes = MAX_NUM_LANES; 931 } 932 933 /* 934 CORE configuration 935 */ 936 phymod_core_init_config_t_init(core_init_config); 937 fw_ld_method = phymodFirmwareLoadMethodInternal; 938 if (_phy_tsce_firmware_set_helper[unit]) { 939 core_init_config->firmware_loader = tsce_firmware_loader; 940 fw_ld_method = phymodFirmwareLoadMethodExternal; 941 } 942 if (soc_property_port_get(pc->unit, pc->port, "tsce_sim", 0) || soc_property_port_get(pc->unit, pc->port, "eagle_sim", 0)) { 943 fw_ld_method = phymodFirmwareLoadMethodNone; 944 } 945 946 947 fw_ld_method |= TSCE_FW_TO_VERIFY ; /* as default to verify */ 948 core_init_config->firmware_load_method = soc_property_port_get(unit, port, 949 spn_LOAD_FIRMWARE, fw_ld_method); 950 if((core_init_config->firmware_load_method & TSCE_FW_CHECK_MASK) != TSCE_FW_NO_VERIFY) { 951 PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_SET(core_init_config); 952 } else { 953 PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_CLR(core_init_config); 954 } 955 core_init_config->firmware_load_method &= TSCE_FW_MODE_MASK; /* clear checksum bits */ 956 core_init_config->lane_map.num_of_lanes = NUM_LANES; 957 958 /* For TSC-E/F family, both lane_map_rx and lane_map_tx are logic lane base */ 959 /* Also both internal data structures are logic lane base */ 960 lane_map_rx = soc_property_port_suffix_num_get(unit, port, core_num, 961 spn_XGXS_RX_LANE_MAP, "core", 0x3210); 962 lane_map_rx_l = lane_map_rx ; 963 /* TD2/TD2+ xgxs_rx_lane_map is phy-lane base */ 964 if(SOC_IS_TD2P_TT2P(unit)) { 965 lane_map_rx_l = 0 ; 966 for (i=0; i<NUM_LANES; i++) { 967 lane_map_rx_l |= i << 4*((lane_map_rx >> (i*4)) & 0xf) ; 968 } 969 } 970 971 is_tx = 0 ; 972 chip_bonding_swap = tsce_chip_bonding_swap(unit, port, is_tx, logical_lane_offset) ; 973 for (i=0; i<NUM_LANES; i++) { 974 if(chip_bonding_swap) { 975 core_init_config->lane_map.lane_map_rx[i] = (lane_map_rx_l >> ((3-i) * 4 /* 4 bit per lane */)) & 0xf; 976 } else { 977 core_init_config->lane_map.lane_map_rx[i] = (lane_map_rx_l >> (i * 4 /* 4 bit per lane */)) & 0xf; 978 } 979 } 980 981 lane_map_tx = soc_property_port_suffix_num_get(unit, port, core_num, 982 spn_XGXS_TX_LANE_MAP, "core", 0x3210); 983 is_tx = 1 ; 984 chip_bonding_swap = tsce_chip_bonding_swap(unit, port, is_tx, logical_lane_offset) ; 985 for (i=0; i<NUM_LANES; i++) { 986 if(chip_bonding_swap) { 987 core_init_config->lane_map.lane_map_tx[i] = (lane_map_tx >> ((3-i) * 4 /*4 bit per lane*/)) & 0xf; 988 } else { 989 core_init_config->lane_map.lane_map_tx[i] = (lane_map_tx >> (i * 4 /*4 bit per lane*/)) & 0xf; 990 } 991 } 992 993 /* next get the tx/rx polairty info */ 994 pm_phy_init_config->polarity.tx_polarity = soc_property_port_get(unit, port, 995 spn_PHY_XAUI_TX_POLARITY_FLIP, 0); 996 pm_phy_init_config->polarity.rx_polarity = soc_property_port_get(unit, port, 997 spn_PHY_XAUI_RX_POLARITY_FLIP, 0); 998 999 speed_config = &(pCfg->speed_config); 1000 speed_config->port_refclk_int = port_refclk_int; 1001 speed_config->speed = soc_property_port_get(unit, port, spn_PORT_INIT_SPEED, pc->speed_max); 1002 speed_config->port_num_lanes = phy_num_lanes; 1003 speed_config->port_is_higig = port_is_higig; 1004 speed_config->rxaui_mode = soc_property_port_get(unit, port, spn_SERDES_RXAUI_MODE, 1); 1005 speed_config->scrambler_en = soc_property_port_get(unit, port, spn_SERDES_SCRAMBLER_ENABLE, 0); 1006 speed_config->line_interface = soc_property_port_get(unit, port, spn_SERDES_IF_TYPE, 0); 1007 speed_config->fiber_pref = soc_property_port_get(unit, port, spn_SERDES_FIBER_PREF, fiber_pref); 1008 speed_config->pcs_bypass = 0; 1009 speed_config->phy_supports_dual_rate = phy_supports_dual_rate; 1010 speed_config->pll_divider_req = soc_property_port_get(unit, port, spn_XGXS_PHY_PLL_DIVIDER, 0); 1011 speed_config->core_device_aux_modes = pCfg->core_device_aux_modes ; 1012 if (speed_config->speed == -1) { 1013 /* if port init speed disabled (equals -1) use speed = 12500*/ 1014 speed_config->speed = 12500; 1015 } 1016 if(SOC_IS_TD2P_TT2P(unit)) { 1017 if(SOC_INFO(unit).port_num_lanes[port]==10) { 1018 speed_config->port_is_triple_core = TRUE ; 1019 lane_config_mode = si->port_100g_lane_config[port] ; 1020 switch(lane_config_mode) { 1021 case SOC_LANE_CONFIG_100G_4_4_2: 1022 speed_config->triple_core_mode = phymodTripleCore442 ; 1023 break ; 1024 case SOC_LANE_CONFIG_100G_2_4_4: 1025 speed_config->triple_core_mode = phymodTripleCore244 ; 1026 break ; 1027 case SOC_LANE_CONFIG_100G_3_4_3: 1028 speed_config->triple_core_mode = phymodTripleCore343 ; 1029 break ; 1030 default: 1031 speed_config->triple_core_mode = phymodTripleCore343 ; 1032 break ; 1033 } 1034 } else if(SOC_INFO(unit).port_num_lanes[port]==12) { 1035 speed_config->port_is_triple_core = TRUE ; 1036 speed_config->triple_core_mode = phymodTripleCore444 ; 1037 } else { 1038 speed_config->port_is_triple_core = FALSE ; 1039 } 1040 } 1041 if (port_num_lanes == 1) { 1042 if (PHY_EXTERNAL_MODE(unit, port) || !(speed_config->fiber_pref)) { 1043 speed_config->line_interface = SOC_PORT_IF_XFI; 1044 } else { 1045 speed_config->line_interface = SOC_PORT_IF_SFI; 1046 } 1047 } else { 1048 if ((speed_config -> speed == 10000) && (!port_is_higig) && 1049 (port_num_lanes == 4)) { 1050 speed_config->line_interface = _SHR_PORT_IF_XAUI; 1051 } else { 1052 speed_config->line_interface = SOC_PORT_IF_XLAUI; 1053 } 1054 } 1055 1056 SOC_IF_ERROR_RETURN 1057 (tsce_speed_to_interface_config_get(phy, speed_config, &(core_init_config->interface), &tx_index)); 1058 1059 /* 1060 PHY configuration 1061 */ 1062 for (i=0; i<MAX_NUM_LANES; i++) { 1063 pCfg->ln_txparam[i+logical_lane_offset].amp = -1 ; 1064 pCfg->ln_txparam[i+logical_lane_offset].main = -1 ; 1065 pCfg->ln_txparam[i+logical_lane_offset].post = -1 ; 1066 pCfg->ln_txparam[i+logical_lane_offset].post2 = -1 ; 1067 pCfg->ln_txparam[i+logical_lane_offset].post3 = -1 ; 1068 pCfg->ln_txparam[i+logical_lane_offset].pre = -1 ; 1069 pCfg->ln_txparam[i+logical_lane_offset].drivermode = -1 ; 1070 } 1071 1072 for (i = 0; i < TXDRV_ENTRY_NUM; i++) { 1073 p_tx = &pCfg->tx_drive[i]; 1074 SOC_IF_ERROR_RETURN(phymod_tx_t_init(p_tx)); 1075 } 1076 /* set the default tx parameters */ 1077 p_tx = &pCfg->tx_drive[TXDRV_DFT_INX]; 1078 p_tx->amp = 0xc; 1079 p_tx->pre = 0xc; 1080 p_tx->main = 0x64; 1081 p_tx->post = 0x0; 1082 p_tx->post2 = 0x00; 1083 p_tx->post3 = 0x00; 1084 p_tx->drivermode = -1 ; 1085 1086 p_tx = &pCfg->tx_drive[TXDRV_XFI_INX]; 1087 p_tx->amp = 0xc; 1088 p_tx->pre = 0xc; 1089 p_tx->main = 0x64; 1090 p_tx->post = 0x00; 1091 p_tx->post2 = 0x00; 1092 p_tx->post3 = 0x00; 1093 p_tx->drivermode = -1 ; 1094 1095 p_tx = &pCfg->tx_drive[TXDRV_SFI_INX]; 1096 p_tx->amp = 0xc; 1097 p_tx->pre = 0xc; 1098 p_tx->main = 0x64; 1099 p_tx->post = 0x00; 1100 p_tx->post2 = 0x00; 1101 p_tx->post3 = 0x00; 1102 p_tx->drivermode = -1 ; 1103 1104 p_tx = &pCfg->tx_drive[TXDRV_SFIDAC_INX]; 1105 p_tx->amp = 0xc; 1106 p_tx->pre = 0xc; 1107 p_tx->main = 0x64; 1108 p_tx->post = 0x00; 1109 p_tx->post2 = 0x00; 1110 p_tx->post3 = 0x00; 1111 p_tx->drivermode = -1 ; 1112 1113 p_tx = &pCfg->tx_drive[TXDRV_AN_INX]; 1114 p_tx->amp = 0xc; 1115 p_tx->pre = 0xc; 1116 p_tx->main = 0x64; 1117 p_tx->post = 0x00; 1118 p_tx->post2 = 0x00; 1119 p_tx->post3 = 0x00; 1120 p_tx->drivermode = -1 ; 1121 1122 p_tx = &pCfg->tx_drive[TXDRV_SR4_INX]; 1123 p_tx->amp = 0xc; 1124 p_tx->pre = 0xc; 1125 p_tx->main = 0x64; 1126 p_tx->post = 0x00; 1127 p_tx->post2 = 0x00; 1128 p_tx->post3 = 0x00; 1129 p_tx->drivermode = -1 ; 1130 1131 p_tx = &pCfg->tx_drive[TXDRV_XLAUI_INX]; 1132 p_tx->amp = 0xc; 1133 p_tx->pre = 0xc; 1134 p_tx->main = 0x64; 1135 p_tx->post = 0x00; 1136 p_tx->post2 = 0x00; 1137 p_tx->post3 = 0x00; 1138 p_tx->drivermode = -1 ; 1139 1140 phymod_phy_init_config_t_init(pm_phy_init_config); 1141 /* initialize the tx taps and driver current */ 1142 for (i = 0; i < 4; i++) { 1143 pm_phy_init_config->tx[i].pre = pCfg->tx_drive[tx_index].pre; 1144 pm_phy_init_config->tx[i].main = pCfg->tx_drive[tx_index].main; 1145 pm_phy_init_config->tx[i].post = pCfg->tx_drive[tx_index].post; 1146 pm_phy_init_config->tx[i].post2 = pCfg->tx_drive[tx_index].post2; 1147 pm_phy_init_config->tx[i].post3 = pCfg->tx_drive[tx_index].post3; 1148 pm_phy_init_config->tx[i].amp = pCfg->tx_drive[tx_index].amp; 1149 } 1150 1151 pm_phy_init_config->polarity.rx_polarity 1152 = soc_property_port_get(unit, port, 1153 spn_PHY_XAUI_RX_POLARITY_FLIP, 1154 pm_phy_init_config->polarity.rx_polarity); 1155 pm_phy_init_config->polarity.tx_polarity 1156 = soc_property_port_get(unit, port, 1157 spn_PHY_XAUI_TX_POLARITY_FLIP, 1158 pm_phy_init_config->polarity.tx_polarity); 1159 1160 for (i = 0; i < MAX_NUM_LANES; i++) { 1161 /*first get the preemphasis */ 1162 preemphasis = 0; 1163 preemphasis = soc_property_port_suffix_num_get(unit, port, 1164 i + core_num * 4, spn_SERDES_PREEMPHASIS, 1165 "lane", preemphasis); 1166 if(preemphasis != 0) { 1167 pCfg->ln_txparam[i+logical_lane_offset].pre = preemphasis & 0xff; 1168 pCfg->ln_txparam[i+logical_lane_offset].main = (preemphasis & 0xff00) >> 8; 1169 pCfg->ln_txparam[i+logical_lane_offset].post = (preemphasis & 0xff0000) >> 16; 1170 } else { 1171 preemphasis = pm_phy_init_config->tx[i].pre | 1172 pm_phy_init_config->tx[i].main << 8 | 1173 pm_phy_init_config->tx[i].post << 16; 1174 } 1175 pm_phy_init_config->tx[i].pre = preemphasis & 0xff; 1176 pm_phy_init_config->tx[i].main = (preemphasis & 0xff00) >> 8; 1177 pm_phy_init_config->tx[i].post = (preemphasis & 0xff0000) >> 16; 1178 } 1179 1180 for (i = 0; i < MAX_NUM_LANES; i++) { 1181 amp = -1; 1182 amp = soc_property_port_suffix_num_get(unit, port, 1183 i + core_num * 4, spn_SERDES_DRIVER_CURRENT, 1184 "lane", amp) ; 1185 if(amp < 0) { 1186 amp = pm_phy_init_config->tx[i].amp; 1187 } else { 1188 pCfg->ln_txparam[i+logical_lane_offset].amp = amp; 1189 } 1190 pm_phy_init_config->tx[i].amp = amp ; 1191 } 1192 1193 1194 pm_phy_init_config->cl72_en = soc_property_port_get(unit, port, spn_PHY_AN_C72, TRUE); 1195 pm_phy_init_config->an_en = TRUE; 1196 1197 pCfg->serdes_1000x_at_6250_vco = 0; 1198 pCfg->serdes_1000x_at_6250_vco = soc_property_port_get(unit, port, 1199 spn_SERDES_1000X_AT_6250_VCO, 1200 pCfg->serdes_1000x_at_6250_vco); 1201 1202 /* check the higig port mode, then set the default cl73 mode */ 1203 if (port_is_higig) { 1204 pCfg->cl73an = FALSE; 1205 } else { 1206 pCfg->cl73an = PHYMOD_AN_CAP_CL73; 1207 } 1208 1209 /* by default disable cl37 */ 1210 pCfg->cl37an = FALSE; 1211 pCfg->cl37_sgmii_war = 0 ; 1212 pCfg->cl37_sgmii_cnt = 0 ; 1213 pCfg->cl37_sgmii_RESTART_CNT = 2 ; 1214 pCfg->an_cl72 = TRUE; 1215 pCfg->forced_init_cl72 = FALSE; 1216 pCfg->an_fec = FALSE; 1217 pCfg->fec_enable = FALSE; 1218 1219 1220 pCfg->cl73an = soc_property_port_get(unit, port, 1221 spn_PHY_AN_C73, pCfg->cl73an); /* no L: C73, not CL73 */ 1222 1223 pCfg->cl37an = soc_property_port_get(unit, port, 1224 spn_PHY_AN_C37, pCfg->cl37an); /* no L: C37, not CL37 */ 1225 1226 pCfg->an_cl72 = soc_property_port_get(unit, port, 1227 spn_PHY_AN_C72, pCfg->an_cl72); 1228 pCfg->an_fec = soc_property_port_get(unit, port, 1229 spn_PHY_AN_FEC, pCfg->an_fec); 1230 pCfg->forced_init_cl72 = soc_property_port_get(unit, port, 1231 spn_PORT_INIT_CL72, pCfg->forced_init_cl72); 1232 1233 pCfg->fec_enable = soc_property_port_get(unit, port, 1234 spn_SERDES_FEC_ENABLE, pCfg->fec_enable); 1235 pCfg->cl37_sgmii_RESTART_CNT = soc_property_port_get(unit, port, 1236 spn_SERDES_CL37_SGMII_RESTART_COUNT, pCfg->cl37_sgmii_RESTART_CNT); 1237 1238 1239 /* 1240 phy_ctrl_t configuration (LOGICAL PORT BASED) 1241 Only do this once, for the first core of the logical port 1242 */ 1243 if (core_num == 0) { 1244 1245 1246 /* phy_mode, PHYCTRL_MDIO_ADDR_SHARE, PHY_FLAGS_INDEPENDENT_LANE */ 1247 if (port_num_lanes == 4) { 1248 pc->phy_mode = PHYCTRL_QUAD_LANE_PORT; 1249 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_INDEPENDENT_LANE); 1250 } else if (port_num_lanes == 2) { 1251 pc->phy_mode = PHYCTRL_DUAL_LANE_PORT; 1252 pc->flags |= PHYCTRL_MDIO_ADDR_SHARE; 1253 PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE); 1254 } else if (port_num_lanes == 1) { 1255 pc->phy_mode = PHYCTRL_ONE_LANE_PORT; 1256 pc->flags |= PHYCTRL_MDIO_ADDR_SHARE; 1257 PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE); 1258 } 1259 1260 /* PHY_FLAGS_PASSTHRU */ 1261 phy_passthru = 0; 1262 if (PHY_EXTERNAL_MODE(unit, port)) { 1263 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_PASSTHRU); 1264 phy_passthru = soc_property_port_get(unit, port, 1265 spn_PHY_PCS_REPEATER, 0); 1266 if (phy_passthru) { 1267 PHY_FLAGS_SET(unit, port, PHY_FLAGS_PASSTHRU); 1268 } 1269 } 1270 1271 /* PHY_FLAGS_FIBER */ 1272 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_FIBER); 1273 if (!PHY_EXTERNAL_MODE(unit, port)) { 1274 1275 fiber_pref = FALSE; 1276 if (PHY_FIBER_MODE(unit, port) || 1277 (phy_passthru) || 1278 (!PHY_INDEPENDENT_LANE_MODE(unit, port)) || 1279 (pc->speed_max >= 10000)) { 1280 fiber_pref = TRUE; 1281 } 1282 1283 fiber_pref = soc_property_port_get(unit, port, 1284 spn_SERDES_FIBER_PREF, fiber_pref); 1285 if (fiber_pref) { 1286 PHY_FLAGS_SET(unit, port, PHY_FLAGS_FIBER); 1287 } 1288 } 1289 1290 1291 PHY_FLAGS_SET(unit,port,PHY_FLAGS_SERVICE_INT_PHY_LINK_GET); 1292 1293 1294 /* not used */ 1295 /* pCfg->cl73an = soc_property_port_get(unit, port, spn_PHY_AN_C73, TSCMOD_CL73_WO_BAM); 1296 1297 if (!PHY_EXTERNAL_MODE(unit, port)) { 1298 if (pCfg->cl73an) { 1299 PHY_FLAGS_SET(unit, port, PHY_FLAGS_C73); 1300 } 1301 } 1302 */ 1303 1304 1305 if ((PHY_FIBER_MODE(unit, port) && !PHY_EXTERNAL_MODE(unit, port)) || 1306 phy_passthru) { 1307 pCfg->pdetect1000x = TRUE; 1308 } else { 1309 pCfg->pdetect1000x = FALSE; 1310 } 1311 1312 pCfg->pdetect10g = soc_property_port_get(unit, port, spn_XGXS_PDETECT_10G, 0); 1313 1314 pCfg->cx4_10g = soc_property_port_get(unit, port, spn_10G_IS_CX4, TRUE); 1315 } 1316 1317 return SOC_E_NONE; 1318 } 1319 1320 STATIC int 1321 _tsce_device_print(temod_device_aux_modes_t *device, soc_phymod_core_t *core) 1322 { 1323 phymod_core_access_t *pm_core; 1324 phymod_access_t *pm_acc; 1325 1326 pm_core = &core->pm_core; 1327 pm_acc = &pm_core->access; 1328 1329 if(device && core) { 1330 PHYMOD_VDBG(TEMOD_DBG_MEM, pm_acc, ("core_id=%0x this=%p st_current_entry=%0d\n", device->core_id, (void *)device, device->st_current_entry)) ; 1331 PHYMOD_VDBG(TEMOD_DBG_MEM, pm_acc, ("ref_cnt=%0d core_p=%p\n", core->ref_cnt, (void *)core)) ; 1332 } else { 1333 PHYMOD_VDBG(TEMOD_DBG_MEM, pm_acc, ("Error: no defined device aux modes.\n")); 1334 } 1335 return SOC_E_NONE; 1336 } 1337 1338 /* 1339 * Function: 1340 * phy_tsce_init 1341 * 1342 * An SDK "phy" is a logical port, which can consist of from 1-10 lanes, 1343 * (A phy with more than 4 lanes requires more than one core). 1344 * Per-logical port information is saved in (tsce_cfg_t *) &pc->driver_data. 1345 * An SDK phy is implemented as one or more PHYMOD "phy"s. 1346 * 1347 * A PHYMOD "phy" resides completely within a single core, which can be 1348 * from 1 to 4 lanes. 1349 * Per-phymod phy information is kept in (soc_phymod_ctrl_t) *pc->phymod_ctrl 1350 * A phymod phy points to its core. Up to 4 phymod phys can be on a single core 1351 * 1352 * Purpose: 1353 * Initialize a tsce phy 1354 * Parameters: 1355 * unit - BCM unit number. 1356 * port - Port number. 1357 * Returns: 1358 * SOC_E_NONE 1359 */ 1360 STATIC int 1361 phy_tsce_init(int unit, soc_port_t port) 1362 { 1363 phy_ctrl_t *pc; 1364 soc_phymod_ctrl_t *pmc; 1365 soc_phymod_phy_t *phy = NULL; 1366 soc_phymod_core_t *core; 1367 tsce_config_t *pCfg; 1368 tsce_speed_config_t *speed_config; 1369 tsce_dev_info_t *pInfo; 1370 soc_phy_info_t *pi; 1371 phymod_phy_inf_config_t interface_config; 1372 phymod_core_status_t core_status; 1373 phymod_core_info_t core_info; 1374 int idx; 1375 int logical_lane_offset; 1376 soc_port_ability_t ability; 1377 phymod_firmware_load_method_t fw_ld_method; 1378 TXDRV_INXS_t tx_index = TXDRV_DFT_INX; 1379 1380 pc = INT_PHY_SW_STATE(unit, port); 1381 if (pc == NULL) { 1382 return SOC_E_INTERNAL; 1383 } 1384 pc->driver_data = (void*)(pc+1); 1385 pmc = &pc->phymod_ctrl; 1386 pCfg = (tsce_config_t *) pc->driver_data; 1387 pInfo = &pCfg->info; 1388 1389 sal_memset(pCfg, 0, sizeof(*pCfg)); 1390 speed_config = &(pCfg->speed_config); 1391 1392 sal_memset(&ability, 0, sizeof(ability)); 1393 1394 /* Loop through all phymod phys that support this SDK phy */ 1395 logical_lane_offset = 0; 1396 for (idx = 0; idx < pmc->num_phys; idx++) { 1397 phy = pmc->phy[idx]; 1398 core = phy->core; 1399 pCfg->core_device_aux_modes = (temod_device_aux_modes_t *)(core->device_aux_modes) ; 1400 _tsce_device_print(pCfg->core_device_aux_modes, core) ; 1401 1402 1403 /* determine configuration data structure to default values, based on SOC properties */ 1404 SOC_IF_ERROR_RETURN 1405 (tsce_config_init(unit, port, &phy->pm_phy, 1406 logical_lane_offset, 1407 &core->init_config, &phy->init_config)); 1408 1409 1410 1411 if(pc->flags & PHYCTRL_INIT_DONE) { 1412 core->init = TRUE; 1413 } 1414 1415 fw_ld_method = phymodFirmwareLoadMethodInternal; 1416 if (_phy_tsce_firmware_set_helper[unit]) { 1417 fw_ld_method = phymodFirmwareLoadMethodExternal; 1418 } 1419 if (soc_property_port_get(pc->unit, pc->port, "tsce_sim", 0) || soc_property_port_get(pc->unit, pc->port, "eagle_sim", 0)) { 1420 fw_ld_method = phymodFirmwareLoadMethodNone; 1421 } 1422 1423 fw_ld_method = soc_property_port_get(unit, port, 1424 spn_LOAD_FIRMWARE, fw_ld_method); 1425 1426 1427 if (!core->init && SOC_IS_ARDON(unit)) { 1428 if (fw_ld_method != phymodFirmwareLoadMethodExternal) { 1429 if (pc->flags & ARDON_FABRIC_INIT_STG_2) { 1430 core->init = TRUE; 1431 } else if (pc->flags & ARDON_FABRIC_INIT_START) { 1432 if (core->flags & ARDON_CORE_INIT_CALLED_2) { 1433 return SOC_E_NONE; 1434 } 1435 pc->flags = pc->flags ^ ARDON_FABRIC_INIT_START; 1436 pc->flags |= ARDON_FABRIC_INIT_STG_2; 1437 core_status.pmd_active = 0; 1438 if (!SOC_WARM_BOOT(unit)) { 1439 SOC_IF_ERROR_RETURN 1440 (phymod_core_init(&core->pm_core, &core->init_config, &core_status)); 1441 } 1442 core->flags |= ARDON_CORE_INIT_CALLED_2; 1443 return SOC_E_NONE; 1444 } 1445 } else { 1446 if (pc->flags & ARDON_FABRIC_INIT_STG_2) { 1447 core->init = TRUE; 1448 } else if (pc->flags & ARDON_FABRIC_INIT_STG_1) { 1449 if (core->flags & ARDON_CORE_INIT_CALLED_2) { 1450 return SOC_E_NONE; 1451 } 1452 pc->flags = pc->flags ^ ARDON_FABRIC_INIT_STG_1; 1453 pc->flags |= ARDON_FABRIC_INIT_STG_2; 1454 core_status.pmd_active = 0; 1455 core->init_config.flags |= PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD; 1456 if (!SOC_WARM_BOOT(unit)) { 1457 SOC_IF_ERROR_RETURN 1458 (phymod_core_init(&core->pm_core, &core->init_config, &core_status)); 1459 } 1460 core->flags |= ARDON_CORE_INIT_CALLED_2; 1461 return SOC_E_NONE; 1462 } else if (pc->flags & ARDON_FABRIC_INIT_START) { 1463 if (core->flags & ARDON_CORE_INIT_CALLED_1) { 1464 return SOC_E_NONE; 1465 } 1466 pc->flags = pc->flags ^ ARDON_FABRIC_INIT_START; 1467 pc->flags |= ARDON_FABRIC_INIT_STG_1; 1468 core_status.pmd_active = 0; 1469 core->init_config.flags |= PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD; 1470 if (!SOC_WARM_BOOT(unit)) { 1471 SOC_IF_ERROR_RETURN 1472 (phymod_core_init(&core->pm_core, &core->init_config, &core_status)); 1473 } 1474 core->flags |= ARDON_CORE_INIT_CALLED_1; 1475 return SOC_E_NONE; 1476 } 1477 } 1478 } 1479 1480 1481 if (!core->init) { 1482 core_status.pmd_active = 0; 1483 if (!SOC_WARM_BOOT(unit)) { 1484 /* PLL0 default VCO is 10.3125G and PLL1 is 6.25G in TSCE DPLL(Gen=3)*/ 1485 core->init_config.pll0_div_init_value = phymod_TSCE_PLL_DIV66; 1486 core->init_config.pll1_div_init_value = phymod_TSCE_PLL_DIV40; 1487 SOC_IF_ERROR_RETURN 1488 (phymod_core_init(&core->pm_core, &core->init_config, &core_status)); 1489 } 1490 core->init = TRUE; 1491 } 1492 pc->flags |= PHYCTRL_INIT_DONE; 1493 1494 if (!SOC_WARM_BOOT(unit)) { 1495 SOC_IF_ERROR_RETURN 1496 (phymod_phy_init(&phy->pm_phy, &phy->init_config)); 1497 } 1498 1499 /*read serdes id info */ 1500 SOC_IF_ERROR_RETURN 1501 (phymod_core_info_get(&core->pm_core, &core_info)); 1502 1503 1504 /* for multicore phys, need to ratchet up to the next batch of lanes */ 1505 logical_lane_offset += core->init_config.lane_map.num_of_lanes; 1506 } 1507 1508 /* fill up the pInfo table for displaying the serdes driver info */ 1509 SOC_IF_ERROR_RETURN 1510 (tsce_show_serdes_info(pc, pInfo, &core_info)); 1511 1512 /* retrieve chip level information for serdes driver info */ 1513 pi = &SOC_PHY_INFO(unit, port); 1514 1515 if (!PHY_EXTERNAL_MODE(unit, port)) { 1516 pi->phy_name = pInfo->name; 1517 } 1518 1519 if (SOC_WARM_BOOT(unit)) { 1520 return SOC_E_NONE; 1521 } 1522 1523 /*next check if we need to run 1G at 6.25VCO */ 1524 if (pCfg->serdes_1000x_at_6250_vco) { 1525 speed_config->pll_divider_req = 40; 1526 } 1527 1528 /* set the port to its max or init_speed */ 1529 SOC_IF_ERROR_RETURN 1530 (tsce_speed_to_interface_config_get(&phy->pm_phy, speed_config, &interface_config, &tx_index)); 1531 1532 SOC_IF_ERROR_RETURN 1533 (phymod_phy_interface_config_set(&phy->pm_phy, 1534 0 /* flags */, &interface_config)); 1535 1536 /*next check if FEC (cl74) needs to be enabled */ 1537 if (pCfg->fec_enable) { 1538 SOC_IF_ERROR_RETURN 1539 (tsce_fec_enable_set(pmc, pCfg->fec_enable)); 1540 } 1541 1542 1543 /*next check if cl72 needs to be enabled */ 1544 if (pCfg->forced_init_cl72) { 1545 SOC_IF_ERROR_RETURN 1546 (tsce_cl72_enable_set(pmc, 1)); 1547 } 1548 1549 /* setup the port's an cap */ 1550 SOC_IF_ERROR_RETURN 1551 (phy_tsce_ability_local_get(unit, port, &ability)); 1552 1553 SOC_IF_ERROR_RETURN 1554 (phy_tsce_ability_advert_set(unit, port, &ability)); 1555 1556 LOG_INFO(BSL_LS_SOC_PHY, 1557 (BSL_META_U(pc->unit, 1558 "phy_tsce_init: u=%d p=%d\n"), unit, port)); 1559 return SOC_E_NONE; 1560 } 1561 1562 /* 1563 * Function: 1564 * phy_tsce_link_get 1565 * Purpose: 1566 * Get layer2 connection status. 1567 * Parameters: 1568 * unit - BCM unit number. 1569 * port - Port number. 1570 * link - address of memory to store link up/down state. 1571 * Returns: 1572 * SOC_E_NONE 1573 */ 1574 STATIC int 1575 phy_tsce_link_get(int unit, soc_port_t port, int *link) 1576 { 1577 phy_ctrl_t *pc; 1578 tsce_config_t *pCfg; 1579 soc_phymod_ctrl_t *pmc; 1580 phymod_phy_access_t *pm_phy; 1581 phymod_autoneg_control_t an; 1582 1583 *link = 0; 1584 /* locate phy control */ 1585 pc = INT_PHY_SW_STATE(unit, port); 1586 if (pc == NULL) { 1587 return SOC_E_INTERNAL; 1588 } 1589 1590 pmc = &pc->phymod_ctrl; 1591 pm_phy = &pmc->phy[pmc->main_phy]->pm_phy; 1592 1593 SOC_IF_ERROR_RETURN 1594 (phymod_phy_link_status_get(pm_phy, (uint32_t *) link)); 1595 if(*link == 0) { 1596 pCfg = (tsce_config_t *) pc->driver_data; 1597 if(pCfg->cl37_sgmii_war) { 1598 if(++pCfg->cl37_sgmii_cnt>=pCfg->cl37_sgmii_RESTART_CNT) { 1599 pCfg->cl37_sgmii_cnt = 0 ; 1600 phymod_autoneg_control_t_init(&an); 1601 1602 an.an_mode = phymod_AN_MODE_CL37_SGMII; 1603 SOC_IF_ERROR_RETURN 1604 (phymod_phy_autoneg_restart_set(pm_phy, &an)); 1605 } 1606 } 1607 } 1608 return (SOC_E_NONE); 1609 } 1610 1611 /* 1612 * Function: 1613 * phy_tsce_enable_set 1614 * Purpose: 1615 * Enable/Disable phy 1616 * Parameters: 1617 * unit - BCM unit number. 1618 * port - Port number. 1619 * enable - on/off state to set 1620 * Returns: 1621 * SOC_E_NONE 1622 */ 1623 STATIC int 1624 phy_tsce_enable_set(int unit, soc_port_t port, int enable) 1625 { 1626 phy_ctrl_t *pc; 1627 soc_phymod_ctrl_t *pmc; 1628 phymod_phy_access_t *pm_phy; 1629 phymod_phy_tx_lane_control_t tx_control; 1630 phymod_phy_rx_lane_control_t rx_control; 1631 1632 int idx; 1633 1634 /* locate phy control */ 1635 pc = INT_PHY_SW_STATE(unit, port); 1636 if (pc == NULL) { 1637 return SOC_E_INTERNAL; 1638 } 1639 1640 if (enable) { 1641 tx_control = phymodTxSquelchOff; 1642 rx_control = phymodRxSquelchOff; 1643 } else { 1644 tx_control = phymodTxSquelchOn; 1645 rx_control = phymodRxSquelchOn; 1646 } 1647 1648 pmc = &pc->phymod_ctrl; 1649 for (idx = 0; idx < pmc->num_phys; idx++) { 1650 pm_phy = &pmc->phy[idx]->pm_phy; 1651 SOC_IF_ERROR_RETURN 1652 (phymod_phy_tx_lane_control_set(pm_phy, tx_control)); 1653 SOC_IF_ERROR_RETURN 1654 (phymod_phy_rx_lane_control_set(pm_phy, rx_control)); 1655 } 1656 return (SOC_E_NONE); 1657 } 1658 1659 /* 1660 * Function: 1661 * phy_tsce_enable_get 1662 * Purpose: 1663 * Enable/Disable phy 1664 * Parameters: 1665 * unit - BCM unit number. 1666 * port - Port number. 1667 * enable - on/off state to set 1668 * Returns: 1669 * SOC_E_NONE 1670 */ 1671 STATIC int 1672 phy_tsce_enable_get(int unit, soc_port_t port, int *enable) 1673 { 1674 phy_ctrl_t *pc; 1675 soc_phymod_ctrl_t *pmc; 1676 phymod_phy_access_t *pm_phy; 1677 phymod_phy_tx_lane_control_t tx_control; 1678 phymod_phy_rx_lane_control_t rx_control; 1679 1680 /* locate phy control */ 1681 pc = INT_PHY_SW_STATE(unit, port); 1682 if (pc == NULL) { 1683 return SOC_E_INTERNAL; 1684 } 1685 1686 pmc = &pc->phymod_ctrl; 1687 pm_phy = &pmc->phy[pmc->main_phy]->pm_phy; 1688 SOC_IF_ERROR_RETURN 1689 (phymod_phy_tx_lane_control_get(pm_phy, &tx_control)); 1690 SOC_IF_ERROR_RETURN 1691 (phymod_phy_rx_lane_control_get(pm_phy, &rx_control)); 1692 if ((tx_control == phymodTxSquelchOn) && (rx_control == phymodRxSquelchOn)) { 1693 *enable = 0; 1694 } else { 1695 *enable = 1; 1696 } 1697 return (SOC_E_NONE); 1698 } 1699 1700 1701 /* 1702 * Function: 1703 * phy_tsce_duplex_get 1704 * Purpose: 1705 * Get PHY duplex mode 1706 * Parameters: 1707 * unit - BCM unit number. 1708 * port - Port number. 1709 * duplex - current duplex mode 1710 * Returns: 1711 * SOC_E_NONE 1712 */ 1713 STATIC int 1714 phy_tsce_duplex_get(int unit, soc_port_t port, int *duplex) 1715 { 1716 *duplex = TRUE; 1717 return SOC_E_NONE; 1718 } 1719 1720 /* 1721 * Function: 1722 * phy_tsce_speed_set 1723 * Purpose: 1724 * Set PHY speed 1725 * Parameters: 1726 * unit - BCM unit number. 1727 * port - Port number. 1728 * speed - link speed in Mbps 1729 * Returns: 1730 * SOC_E_NONE 1731 */ 1732 1733 STATIC int 1734 phy_tsce_speed_set(int unit, soc_port_t port, int speed) 1735 { 1736 phy_ctrl_t *pc; 1737 tsce_config_t *pCfg; 1738 soc_phymod_ctrl_t *pmc; 1739 soc_phymod_phy_t *phy; 1740 int idx, ln; 1741 tsce_speed_config_t speed_config; 1742 phymod_phy_inf_config_t interface_config; 1743 TXDRV_INXS_t tx_index = TXDRV_DFT_INX; 1744 phymod_tx_t phymod_tx; 1745 phymod_phy_access_t pm_phy_copy; 1746 int start_lane, num_lane ; 1747 int do_not_update_tx = 0; 1748 int prev_speed = 0; 1749 1750 /* locate phy control */ 1751 pc = INT_PHY_SW_STATE(unit, port); 1752 if (pc == NULL) { 1753 return SOC_E_INTERNAL; 1754 } 1755 1756 if (speed == 0) { 1757 return SOC_E_NONE; 1758 } 1759 1760 pmc = &pc->phymod_ctrl; 1761 pCfg = (tsce_config_t *) pc->driver_data; 1762 1763 /* first check if previous speed is the same as the requested*/ 1764 SOC_IF_ERROR_RETURN 1765 (phy_tsce_speed_get(unit, port, &prev_speed)); 1766 if (prev_speed == speed) { 1767 do_not_update_tx = 1; 1768 } 1769 1770 /* take a copy of core and phy configuration values, and set the desired speed */ 1771 sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config)); 1772 speed_config.speed = speed; 1773 if ((speed_config.line_interface == SOC_PORT_IF_SFI) || 1774 (speed_config.line_interface == SOC_PORT_IF_SR4) || 1775 (speed_config.line_interface == SOC_PORT_IF_LR4) || 1776 (speed_config.line_interface == SOC_PORT_IF_SR) || 1777 (speed_config.line_interface == SOC_PORT_IF_LR) || 1778 (speed_config.line_interface == SOC_PORT_IF_GMII)) { 1779 speed_config.fiber_pref = 1; 1780 } else if ((speed_config.line_interface == SOC_PORT_IF_XFI) || 1781 (speed_config.line_interface == SOC_PORT_IF_KR4) || 1782 (speed_config.line_interface == SOC_PORT_IF_CR4) || 1783 (speed_config.line_interface == SOC_PORT_IF_KR) || 1784 (speed_config.line_interface == SOC_PORT_IF_KR2) || 1785 (speed_config.line_interface == SOC_PORT_IF_SGMII) || 1786 (speed_config.line_interface == SOC_PORT_IF_XLAUI)) { 1787 speed_config.fiber_pref = 0; 1788 } 1789 1790 SOC_IF_ERROR_RETURN(phymod_tx_t_init(&phymod_tx)); 1791 1792 /*next check if we need to run 1G at 6.25VCO */ 1793 if (pCfg->serdes_1000x_at_6250_vco) { 1794 speed_config.pll_divider_req = 40; 1795 } 1796 1797 /* determine the interface configuration */ 1798 phy = pmc->phy[0]; 1799 SOC_IF_ERROR_RETURN 1800 (tsce_speed_to_interface_config_get(&phy->pm_phy, &speed_config, &interface_config, &tx_index)); 1801 1802 /* now loop through all cores */ 1803 for (idx = 0; idx < pmc->num_phys; idx++) { 1804 phy = pmc->phy[idx]; 1805 if (phy == NULL) { 1806 return SOC_E_INTERNAL; 1807 } 1808 1809 if (!do_not_update_tx) { 1810 sal_memcpy(&pm_phy_copy, &phy->pm_phy, sizeof(pm_phy_copy)); 1811 PHYMOD_IF_ERR_RETURN 1812 (phymod_util_lane_config_get(&pm_phy_copy.access, &start_lane, &num_lane)); 1813 1814 for(ln=0; ln<num_lane; ln++) { 1815 pm_phy_copy.access.lane_mask = 1 << (start_lane +ln) ; 1816 1817 phymod_tx.amp = pCfg->tx_drive[tx_index].amp; 1818 phymod_tx.main = pCfg->tx_drive[tx_index].main; 1819 phymod_tx.post = pCfg->tx_drive[tx_index].post; 1820 phymod_tx.post2 = pCfg->tx_drive[tx_index].post2; 1821 phymod_tx.post3 = pCfg->tx_drive[tx_index].post3; 1822 phymod_tx.pre = pCfg->tx_drive[tx_index].pre; 1823 1824 if( pCfg->ln_txparam[4*idx+ln].amp >=0) { 1825 phymod_tx.amp = pCfg->ln_txparam[4*idx+ln].amp; 1826 } 1827 if( pCfg->ln_txparam[4*idx+ln].main >=0) { 1828 phymod_tx.main = pCfg->ln_txparam[4*idx+ln].main; 1829 } 1830 if( pCfg->ln_txparam[4*idx+ln].post >=0) { 1831 phymod_tx.post = pCfg->ln_txparam[4*idx+ln].post; 1832 } 1833 if( pCfg->ln_txparam[4*idx+ln].pre >=0) { 1834 phymod_tx.pre = pCfg->ln_txparam[4*idx+ln].pre; 1835 } 1836 if( pCfg->ln_txparam[4*idx+ln].post2 >=0) { 1837 phymod_tx.post2 = pCfg->ln_txparam[4*idx+ln].post2; 1838 } 1839 if( pCfg->ln_txparam[4*idx+ln].post3 >=0) { 1840 phymod_tx.post3 = pCfg->ln_txparam[4*idx+ln].post3; 1841 } 1842 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx)); 1843 } 1844 } 1845 1846 /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */ 1847 SOC_IF_ERROR_RETURN 1848 (phymod_phy_interface_config_set(&phy->pm_phy, 1849 0 /* flags */, &interface_config)); 1850 } 1851 1852 /* record success */ 1853 pCfg->speed_config.speed = speed; 1854 1855 return (SOC_E_NONE); 1856 } 1857 1858 /* 1859 * Function: 1860 * phy_tsce_speed_get 1861 * Purpose: 1862 * Get PHY speed 1863 * Parameters: 1864 * unit - BCM unit number. 1865 * port - Port number. 1866 * speed - current link speed in Mbps 1867 * Returns: 1868 * SOC_E_NONE 1869 */ 1870 STATIC int 1871 phy_tsce_speed_get(int unit, soc_port_t port, int *speed) 1872 { 1873 phy_ctrl_t *pc; 1874 soc_phymod_ctrl_t *pmc; 1875 soc_phymod_phy_t *phy; 1876 phymod_phy_inf_config_t interface_config; 1877 tsce_config_t *pCfg; 1878 int flag = 0; 1879 phymod_ref_clk_t ref_clock; 1880 1881 /* locate phy control */ 1882 pc = INT_PHY_SW_STATE(unit, port); 1883 if (pc == NULL) { 1884 return SOC_E_INTERNAL; 1885 } 1886 pCfg = (tsce_config_t *) pc->driver_data; 1887 1888 pmc = &pc->phymod_ctrl; 1889 1890 /* initialize the data structure */ 1891 interface_config.data_rate = 0; 1892 1893 /* now loop through all cores */ 1894 phy = pmc->phy[pmc->main_phy]; 1895 if (phy == NULL) { 1896 return SOC_E_INTERNAL; 1897 } 1898 1899 SOC_IF_ERROR_RETURN( 1900 tsce_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clock)); 1901 1902 /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */ 1903 SOC_IF_ERROR_RETURN 1904 (phymod_phy_interface_config_get(&phy->pm_phy, 1905 flag, ref_clock, &interface_config)); 1906 *speed = interface_config.data_rate; 1907 return (SOC_E_NONE); 1908 } 1909 1910 /* 1911 * Function: 1912 * phy_tsce_an_set 1913 * Purpose: 1914 * Enable or disable auto-negotiation on the specified port. 1915 * Parameters: 1916 * unit - BCM unit number. 1917 * port - Port number. 1918 * an - Boolean, if true, auto-negotiation is enabled 1919 * (and/or restarted). If false, autonegotiation is disabled. 1920 * Returns: 1921 * SOC_E_XXX _soc_triumph_tx 1922 */ 1923 STATIC int 1924 phy_tsce_an_set(int unit, soc_port_t port, int enable) 1925 { 1926 phy_ctrl_t *pc; 1927 tsce_config_t *pCfg; 1928 soc_phymod_ctrl_t *pmc; 1929 soc_phymod_phy_t *phy; 1930 phymod_autoneg_control_t an; 1931 soc_info_t *si; 1932 1933 /* locate phy control */ 1934 pc = INT_PHY_SW_STATE(unit, port); 1935 if (pc == NULL) { 1936 return SOC_E_INTERNAL; 1937 } 1938 1939 phymod_autoneg_control_t_init(&an); 1940 pmc = &pc->phymod_ctrl; 1941 pCfg = (tsce_config_t *) pc->driver_data; 1942 si = &SOC_INFO(unit); 1943 1944 /* only request autoneg on the first core */ 1945 phy = pmc->phy[pmc->main_phy]; 1946 if (phy == NULL) { 1947 return SOC_E_INTERNAL; 1948 } 1949 1950 an.enable = enable; 1951 an.num_lane_adv = si->port_num_lanes[port]; 1952 an.an_mode = phymod_AN_MODE_NONE; 1953 an.flags = 0; 1954 1955 if (pCfg->pdetect1000x==TRUE) { 1956 PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_SET(&an); 1957 } else { 1958 PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_CLR(&an); 1959 } 1960 if (pCfg->pdetect10g==TRUE) { 1961 PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_SET(&an); 1962 } else { 1963 PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_CLR(&an); 1964 } 1965 1966 pCfg->cl37_sgmii_war = 0 ; 1967 if(pCfg->cl73an) { 1968 switch (pCfg->cl73an) { 1969 case TEMOD_CL73_W_BAM: 1970 an.an_mode = phymod_AN_MODE_CL73BAM; 1971 break ; 1972 case TEMOD_CL73_WO_BAM: 1973 an.an_mode = phymod_AN_MODE_CL73; 1974 break ; 1975 case TEMOD_CL73_HPAM_VS_SW: 1976 an.an_mode = phymod_AN_MODE_HPAM; 1977 break ; /* against TD+ */ 1978 case TEMOD_CL73_HPAM: 1979 an.an_mode = phymod_AN_MODE_HPAM; 1980 break ; /* against TR3 */ 1981 case TEMOD_CL73_CL37: 1982 an.an_mode = phymod_AN_MODE_CL73; 1983 break ; 1984 default: 1985 break; 1986 } 1987 } else if (pCfg->cl37an) { 1988 switch (pCfg->cl37an) { 1989 case TEMOD_CL37_WO_BAM: 1990 if(pCfg->speed_config.fiber_pref) { 1991 an.an_mode = phymod_AN_MODE_CL37; 1992 } else { 1993 an.an_mode = phymod_AN_MODE_SGMII; 1994 } 1995 break; 1996 case TEMOD_CL37_W_BAM: 1997 an.an_mode = phymod_AN_MODE_CL37BAM; 1998 break; 1999 case (TEMOD_CL37_SGMII_COMBO): 2000 an.an_mode = phymod_AN_MODE_CL37_SGMII ; 2001 if(enable){pCfg->cl37_sgmii_war = 1;} 2002 else {pCfg->cl37_sgmii_war = 0;} 2003 break ; 2004 default: 2005 break; 2006 } 2007 } else { 2008 if(pCfg->hg_mode) { 2009 an.an_mode = phymod_AN_MODE_CL37BAM; /* default mode */ 2010 } else { 2011 if (pCfg->speed_config.fiber_pref) { 2012 an.an_mode = phymod_AN_MODE_CL37; 2013 } else { 2014 an.an_mode = phymod_AN_MODE_SGMII; 2015 } 2016 } 2017 } 2018 SOC_IF_ERROR_RETURN 2019 (phymod_phy_autoneg_set(&phy->pm_phy, &an)); 2020 2021 return (SOC_E_NONE); 2022 } 2023 2024 /* 2025 * Function: 2026 * phy_tsce_an_get 2027 * Purpose: 2028 * Get the current auto-negotiation status (enabled/busy) 2029 * Parameters: 2030 * unit - BCM unit number. 2031 * port - Port number. 2032 * an - (OUT) if true, auto-negotiation is enabled. 2033 * an_done - (OUT) if true, auto-negotiation is complete. This 2034 * value is undefined if an == false. 2035 * Returns: 2036 * SOC_E_XXX 2037 */ 2038 2039 STATIC int 2040 phy_tsce_an_get(int unit, soc_port_t port, int *an, int *an_done) 2041 { 2042 phy_ctrl_t* pc; 2043 soc_phymod_ctrl_t *pmc; 2044 phymod_phy_access_t *pm_phy; 2045 phymod_autoneg_control_t an_control; 2046 int idx, an_complete; 2047 2048 pc = INT_PHY_SW_STATE(unit, port); 2049 pmc = &pc->phymod_ctrl; 2050 2051 sal_memset(&an_control, 0x0, sizeof(an_control)); 2052 2053 idx = pmc->main_phy; 2054 pm_phy = &pmc->phy[idx]->pm_phy; 2055 SOC_IF_ERROR_RETURN 2056 (phymod_phy_autoneg_get(pm_phy, &an_control, (uint32_t *) &an_complete)); 2057 2058 if (an_control.enable) { 2059 *an = 1; 2060 *an_done = an_complete; 2061 } else { 2062 *an = 0; 2063 *an_done = 0; 2064 } 2065 2066 return (SOC_E_NONE); 2067 } 2068 2069 /* 2070 * Function: 2071 * phy_tsce_ability_advert_set 2072 * Purpose: 2073 * Set the current advertisement for auto-negotiation. 2074 * Parameters: 2075 * unit - BCM unit number. 2076 * port - Port number. 2077 * ability - Port mode mask indicating supported options/speeds. 2078 * Returns: 2079 * SOC_E_XXX 2080 * Notes: 2081 * The advertisement is set only for the ACTIVE medium. 2082 * No synchronization performed at this level. 2083 */ 2084 2085 STATIC int 2086 phy_tsce_ability_advert_set(int unit, soc_port_t port, 2087 soc_port_ability_t *ability) 2088 { 2089 phy_ctrl_t *pc; 2090 tsce_config_t *pCfg; 2091 soc_phymod_ctrl_t *pmc; 2092 soc_phymod_phy_t *phy; 2093 int port_num_lanes; 2094 int line_interface; 2095 uint32_t an_tech_ability; 2096 uint32_t an_bam37_ability; 2097 uint32_t an_bam73_ability; 2098 soc_port_mode_t speed_full_duplex; 2099 phymod_autoneg_ability_t phymod_autoneg_ability; 2100 2101 /* locate phy control */ 2102 pc = INT_PHY_SW_STATE(unit, port); 2103 if (pc == NULL) { 2104 return SOC_E_INTERNAL; 2105 } 2106 2107 phymod_autoneg_ability_t_init(&phymod_autoneg_ability); 2108 2109 pmc = &pc->phymod_ctrl; 2110 pCfg = (tsce_config_t *) pc->driver_data; 2111 2112 /* only set abilities on the first core */ 2113 phy = pmc->phy[pmc->main_phy]; 2114 if (phy == NULL) { 2115 return SOC_E_INTERNAL; 2116 } 2117 2118 pCfg = (tsce_config_t *) pc->driver_data; 2119 port_num_lanes = pCfg->speed_config.port_num_lanes; 2120 line_interface = pCfg->speed_config.line_interface; 2121 2122 an_tech_ability = 0; 2123 an_bam37_ability = 0; 2124 an_bam73_ability = 0; 2125 speed_full_duplex = ability->speed_full_duplex; 2126 2127 /* 2128 * an_tech_ability/an_bam73_ability 2129 */ 2130 if (port_num_lanes == 4) { 2131 if (speed_full_duplex & SOC_PA_SPEED_40GB) { 2132 if (ability->medium) { 2133 if (ability->medium & SOC_PA_MEDIUM_BACKPLANE) { 2134 PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability); 2135 } else if (ability->medium & SOC_PA_MEDIUM_COPPER) { 2136 PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability); 2137 } else { 2138 PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability); 2139 } 2140 } else { 2141 if (line_interface ==SOC_PORT_IF_CR4) { 2142 PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability); 2143 } else { 2144 PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability); 2145 } 2146 } 2147 } 2148 if (speed_full_duplex & SOC_PA_SPEED_10GB) { 2149 PHYMOD_AN_CAP_10G_KX4_SET(an_tech_ability); 2150 } 2151 } else if (port_num_lanes == 2) { 2152 if (speed_full_duplex & SOC_PA_SPEED_20GB) { 2153 if (ability->medium) { 2154 if (ability->medium & SOC_PA_MEDIUM_BACKPLANE) { 2155 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability); 2156 } else if (ability->medium & SOC_PA_MEDIUM_COPPER) { 2157 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_bam73_ability); 2158 } else { 2159 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability); 2160 } 2161 } else { 2162 if (line_interface ==SOC_PORT_IF_CR2) { 2163 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_bam73_ability); 2164 } else { 2165 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_bam73_ability); 2166 } 2167 } 2168 } 2169 } else { /* 1 lane */ 2170 if (speed_full_duplex & SOC_PA_SPEED_10GB) { 2171 PHYMOD_AN_CAP_10G_KR_SET(an_tech_ability); 2172 } 2173 if (speed_full_duplex & SOC_PA_SPEED_2500MB) { 2174 PHYMOD_AN_CAP_2P5G_X_SET(an_tech_ability); 2175 } 2176 if (speed_full_duplex & SOC_PA_SPEED_5000MB) { 2177 PHYMOD_AN_CAP_5G_KR1_SET(an_tech_ability); 2178 } 2179 if (speed_full_duplex & SOC_PA_SPEED_1000MB) { 2180 PHYMOD_AN_CAP_1G_KX_SET(an_tech_ability); 2181 } 2182 } 2183 2184 /* 2185 an_bam37_ability 2186 */ 2187 if (port_num_lanes == 4) { /* 4 lanes */ 2188 2189 if (speed_full_duplex & SOC_PA_SPEED_40GB) { 2190 PHYMOD_BAM_CL37_CAP_40G_SET(an_bam37_ability); 2191 } 2192 /* if(speed_full_duplex & SOC_PA_SPEED_33GB) 2193 an_bam37_ability |= (1<<PHYMOD_BAM37ABL_32P7G); */ 2194 if (speed_full_duplex & SOC_PA_SPEED_30GB) { 2195 PHYMOD_BAM_CL37_CAP_31P5G_SET(an_bam37_ability); 2196 } 2197 if (speed_full_duplex & SOC_PA_SPEED_25GB) { 2198 PHYMOD_BAM_CL37_CAP_25P455G_SET(an_bam37_ability); 2199 } 2200 if (speed_full_duplex & SOC_PA_SPEED_21GB) { 2201 PHYMOD_BAM_CL37_CAP_21G_X4_SET(an_bam37_ability); 2202 } 2203 if (speed_full_duplex & SOC_PA_SPEED_20GB) { 2204 PHYMOD_BAM_CL37_CAP_20G_X4_SET(an_bam37_ability); 2205 PHYMOD_BAM_CL37_CAP_20G_X4_CX4_SET(an_bam37_ability); 2206 } 2207 if (speed_full_duplex & SOC_PA_SPEED_16GB) { 2208 PHYMOD_BAM_CL37_CAP_16G_X4_SET(an_bam37_ability); 2209 } 2210 if (speed_full_duplex & SOC_PA_SPEED_15GB) { 2211 PHYMOD_BAM_CL37_CAP_15G_X4_SET(an_bam37_ability); 2212 } 2213 if (speed_full_duplex & SOC_PA_SPEED_13GB) { 2214 PHYMOD_BAM_CL37_CAP_13G_X4_SET(an_bam37_ability); 2215 } 2216 if (speed_full_duplex & SOC_PA_SPEED_12P5GB) { 2217 PHYMOD_BAM_CL37_CAP_12P5_X4_SET(an_bam37_ability); 2218 } 2219 if (speed_full_duplex & SOC_PA_SPEED_12GB) { 2220 PHYMOD_BAM_CL37_CAP_12G_X4_SET(an_bam37_ability); 2221 } 2222 if (speed_full_duplex & SOC_PA_SPEED_10GB) { 2223 if (pCfg->cx4_10g) { 2224 PHYMOD_BAM_CL37_CAP_10G_CX4_SET(an_bam37_ability); 2225 } else { 2226 PHYMOD_BAM_CL37_CAP_10G_HIGIG_SET(an_bam37_ability); 2227 } 2228 } 2229 if (speed_full_duplex & SOC_PA_SPEED_6000MB) { 2230 PHYMOD_BAM_CL37_CAP_6G_X4_SET(an_bam37_ability); 2231 } 2232 if (speed_full_duplex & SOC_PA_SPEED_5000MB) { 2233 PHYMOD_BAM_CL37_CAP_5G_X4_SET(an_bam37_ability); 2234 } 2235 } else if (port_num_lanes == 2) { /* 2 lanes */ 2236 2237 if (speed_full_duplex & SOC_PA_SPEED_20GB) { 2238 PHYMOD_BAM_CL37_CAP_20G_X2_SET(an_bam37_ability); 2239 PHYMOD_BAM_CL37_CAP_20G_X2_CX4_SET(an_bam37_ability); 2240 } 2241 if (speed_full_duplex & SOC_PA_SPEED_16GB) { 2242 PHYMOD_BAM_CL37_CAP_15P75G_R2_SET(an_bam37_ability); 2243 } 2244 if (speed_full_duplex & SOC_PA_SPEED_13GB) { 2245 PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_bam37_ability); 2246 } 2247 if (speed_full_duplex & SOC_PA_SPEED_11GB) { 2248 PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_SET(an_bam37_ability); 2249 } 2250 if (speed_full_duplex & SOC_PA_SPEED_10GB) { 2251 PHYMOD_BAM_CL37_CAP_10G_X2_CX4_SET(an_bam37_ability); 2252 PHYMOD_BAM_CL37_CAP_10G_DXGXS_SET(an_bam37_ability); 2253 } 2254 } else { 2255 if (speed_full_duplex & SOC_PA_SPEED_2500MB) { 2256 PHYMOD_BAM_CL37_CAP_2P5G_SET(an_bam37_ability); 2257 } 2258 } 2259 phymod_autoneg_ability.an_cap = an_tech_ability; 2260 phymod_autoneg_ability.cl73bam_cap = an_bam73_ability; 2261 phymod_autoneg_ability.cl37bam_cap = an_bam37_ability; 2262 2263 2264 2265 switch (ability->pause & (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX)) { 2266 case SOC_PA_PAUSE_TX: 2267 PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability); 2268 break; 2269 case SOC_PA_PAUSE_RX: 2270 /* an_adv |= MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; */ 2271 PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability); 2272 PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability); 2273 break; 2274 case SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX: 2275 PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability); 2276 break; 2277 } 2278 2279 /* also set the sgmii speed */ 2280 if(ability->speed_full_duplex & SOC_PA_SPEED_1000MB) { 2281 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 2282 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_1000M; 2283 } else if(ability->speed_full_duplex & SOC_PA_SPEED_100MB) { 2284 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 2285 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_100M; 2286 } else if(ability->speed_full_duplex & SOC_PA_SPEED_10MB) { 2287 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 2288 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_10M; 2289 } else { 2290 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 2291 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_1000M; 2292 } 2293 2294 /* next check if we need to set cl37 attribute */ 2295 if (pCfg->an_cl72) { 2296 phymod_autoneg_ability.an_cl72 = 1; 2297 } 2298 if (pCfg->hg_mode) { 2299 phymod_autoneg_ability.an_hg2 = 1; 2300 } 2301 if ((pCfg->an_fec) || (ability->fec & SOC_PA_FEC_CL74 )) { 2302 PHYMOD_AN_FEC_CL74_SET(phymod_autoneg_ability.an_fec); 2303 } else { 2304 PHYMOD_AN_FEC_OFF_SET(phymod_autoneg_ability.an_fec); 2305 } 2306 SOC_IF_ERROR_RETURN 2307 (phymod_phy_autoneg_ability_set(&phy->pm_phy, &phymod_autoneg_ability)); 2308 2309 return SOC_E_NONE; 2310 } 2311 2312 /* 2313 * Function: 2314 * phy_tsce_ability_advert_get 2315 * Purpose: 2316 * Get the current advertisement for auto-negotiation. 2317 * Parameters: 2318 * unit - BCM unit number. 2319 * port - Port number. 2320 * ability - (OUT) Port mode mask indicating supported options/speeds. 2321 * Returns: 2322 * SOC_E_XXX 2323 * Notes: 2324 * The advertisement is retrieved for the ACTIVE medium. 2325 * No synchronization performed at this level. 2326 */ 2327 2328 STATIC int 2329 phy_tsce_ability_advert_get(int unit, soc_port_t port, 2330 soc_port_ability_t *ability) 2331 { 2332 phy_ctrl_t *pc; 2333 soc_phymod_ctrl_t *pmc; 2334 soc_phymod_phy_t *phy; 2335 int reg37_ability; 2336 int reg73_ability; 2337 int reg_ability; 2338 _shr_port_mode_t speed_full_duplex; 2339 phymod_autoneg_ability_t phymod_autoneg_ability; 2340 int all=0, cl73grp=0, cl37grp=0, sgmiigrp = 0; 2341 2342 /* locate phy control */ 2343 pc = INT_PHY_SW_STATE(unit, port); 2344 if (pc == NULL) { 2345 return SOC_E_INTERNAL; 2346 } 2347 2348 pmc = &pc->phymod_ctrl; 2349 2350 /* only get abilities from the first core */ 2351 phy = pmc->phy[pmc->main_phy]; 2352 if (phy == NULL) { 2353 return SOC_E_INTERNAL; 2354 } 2355 2356 phymod_autoneg_ability_t_init(&phymod_autoneg_ability); 2357 SOC_IF_ERROR_RETURN 2358 (phymod_phy_autoneg_ability_get(&phy->pm_phy, &phymod_autoneg_ability)); 2359 2360 speed_full_duplex = 0; 2361 if (PHYMOD_AN_CAP_CL73_GET(&phymod_autoneg_ability) || 2362 PHYMOD_AN_CAP_CL73BAM_GET(&phymod_autoneg_ability) || 2363 PHYMOD_AN_CAP_HPAM_GET(&phymod_autoneg_ability)) { 2364 cl73grp = 1; 2365 } else if (PHYMOD_AN_CAP_CL37_GET(&phymod_autoneg_ability) || 2366 PHYMOD_AN_CAP_CL37BAM_GET(&phymod_autoneg_ability)) { 2367 cl37grp = 1; 2368 } else if (PHYMOD_AN_CAP_SGMII_GET(&phymod_autoneg_ability)){ 2369 sgmiigrp = 1; 2370 } else { 2371 all = 1; 2372 } 2373 2374 /* retrieve CL73 abilities */ 2375 reg73_ability = phymod_autoneg_ability.an_cap; 2376 if(all || cl73grp) { 2377 speed_full_duplex|= PHYMOD_AN_CAP_40G_CR4_GET(reg73_ability) ?SOC_PA_SPEED_40GB:0; 2378 speed_full_duplex|= PHYMOD_AN_CAP_40G_KR4_GET(reg73_ability) ?SOC_PA_SPEED_40GB:0; 2379 speed_full_duplex|= PHYMOD_AN_CAP_10G_KR_GET(reg73_ability) ?SOC_PA_SPEED_10GB:0; 2380 speed_full_duplex|= PHYMOD_AN_CAP_10G_KX4_GET(reg73_ability) ?SOC_PA_SPEED_10GB:0; 2381 speed_full_duplex|= PHYMOD_AN_CAP_1G_KX_GET(reg73_ability) ?SOC_PA_SPEED_1000MB:0; 2382 speed_full_duplex|= PHYMOD_AN_CAP_2P5G_X_GET(reg73_ability) ?SOC_PA_SPEED_2500MB:0; 2383 speed_full_duplex|= PHYMOD_AN_CAP_5G_KR1_GET(reg73_ability) ?SOC_PA_SPEED_5000MB:0; 2384 2385 2386 /* retrieve CL73bam abilities */ 2387 reg73_ability = phymod_autoneg_ability.cl73bam_cap; 2388 speed_full_duplex|= PHYMOD_BAM_CL73_CAP_20G_CR2_GET(reg73_ability) ?SOC_PA_SPEED_20GB:0; 2389 speed_full_duplex|= PHYMOD_BAM_CL73_CAP_20G_KR2_GET(reg73_ability) ?SOC_PA_SPEED_20GB:0; 2390 /* retrieve "Medium" abilities */ 2391 if (PHYMOD_AN_CAP_40G_CR4_GET(phymod_autoneg_ability.an_cap) || 2392 PHYMOD_BAM_CL73_CAP_20G_CR2_GET(phymod_autoneg_ability.cl73bam_cap)) { 2393 ability->medium = SOC_PA_MEDIUM_COPPER; 2394 } else { 2395 ability->medium = SOC_PA_MEDIUM_BACKPLANE; 2396 } 2397 } 2398 /* retrieve CL37 abilities */ 2399 reg37_ability = phymod_autoneg_ability.cl37bam_cap; 2400 if(all || cl37grp) { 2401 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_40G_GET(reg37_ability) ? SOC_PA_SPEED_40GB:0; 2402 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_31P5G_GET(reg37_ability)? SOC_PA_SPEED_30GB:0; 2403 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_32P7G_GET(reg37_ability)? SOC_PA_SPEED_32GB:0; 2404 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_25P455G_GET(reg37_ability) ? SOC_PA_SPEED_25GB:0; 2405 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_21G_X4_GET(reg37_ability)? SOC_PA_SPEED_21GB:0; 2406 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X2_CX4_GET(reg37_ability)? SOC_PA_SPEED_20GB:0; 2407 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X2_GET(reg37_ability)? SOC_PA_SPEED_20GB:0; 2408 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X4_GET(reg37_ability)? SOC_PA_SPEED_20GB:0; 2409 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X4_CX4_GET(reg37_ability)? SOC_PA_SPEED_20GB:0; 2410 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_16G_X4_GET(reg37_ability)? SOC_PA_SPEED_16GB:0; 2411 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_15P75G_R2_GET(reg37_ability)? SOC_PA_SPEED_16GB:0; 2412 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_15G_X4_GET(reg37_ability)? SOC_PA_SPEED_15GB:0; 2413 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_13G_X4_GET(reg37_ability)? SOC_PA_SPEED_13GB:0; 2414 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12P7_DXGXS_GET(reg37_ability)? SOC_PA_SPEED_13GB:0; 2415 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12P5_X4_GET(reg37_ability)? SOC_PA_SPEED_12P5GB:0; 2416 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12G_X4_GET(reg37_ability)? SOC_PA_SPEED_12GB:0; 2417 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_GET(reg37_ability)?SOC_PA_SPEED_11GB:0; 2418 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_X2_CX4_GET(reg37_ability)? SOC_PA_SPEED_10GB:0; 2419 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_DXGXS_GET(reg37_ability)? SOC_PA_SPEED_10GB:0; 2420 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_CX4_GET(reg37_ability)? SOC_PA_SPEED_10GB:0; 2421 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_HIGIG_GET(reg37_ability)? SOC_PA_SPEED_10GB:0; /* 4-lane */ 2422 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_6G_X4_GET(reg37_ability)? SOC_PA_SPEED_6000MB:0; 2423 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_5G_X4_GET(reg37_ability)? SOC_PA_SPEED_5000MB:0; 2424 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_2P5G_GET(reg37_ability)? SOC_PA_SPEED_2500MB:0; 2425 /* retrieve "Medium" abilities */ 2426 if (PHYMOD_AN_CAP_CL37_GET(&phymod_autoneg_ability)) { 2427 speed_full_duplex|= SOC_PA_SPEED_1000MB ; 2428 ability->medium = SOC_PA_MEDIUM_FIBER; 2429 } else { 2430 ability->medium = SOC_PA_MEDIUM_BACKPLANE; 2431 } 2432 } 2433 /*retrieve sgmii abilities*/ 2434 if (all || sgmiigrp) { 2435 ability->medium = SOC_PA_MEDIUM_BACKPLANE; 2436 if (phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_10M) { 2437 speed_full_duplex |= SOC_PA_SPEED_10MB; 2438 } else if (phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_100M) { 2439 speed_full_duplex |= SOC_PA_SPEED_100MB; 2440 } else { 2441 speed_full_duplex |= SOC_PA_SPEED_1000MB; 2442 } 2443 } 2444 /* retrieve "pause" abilities */ 2445 reg_ability = phymod_autoneg_ability.capabilities & (PHYMOD_AN_CAP_ASYM_PAUSE | PHYMOD_AN_CAP_SYMM_PAUSE); 2446 ability->pause = 0; 2447 if (reg_ability == PHYMOD_AN_CAP_ASYM_PAUSE) { 2448 ability->pause = SOC_PA_PAUSE_TX; 2449 } else if (reg_ability == (PHYMOD_AN_CAP_SYMM_PAUSE|PHYMOD_AN_CAP_ASYM_PAUSE)) { 2450 ability->pause = SOC_PA_PAUSE_RX; 2451 } else if (reg_ability == PHYMOD_AN_CAP_SYMM_PAUSE) { 2452 ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX); 2453 } 2454 2455 ability->speed_full_duplex = speed_full_duplex; 2456 /* retrieve "FEC" abilities */ 2457 ability->fec = 0; 2458 if (PHYMOD_AN_FEC_OFF_GET(phymod_autoneg_ability.an_fec)) { 2459 ability->fec = SOC_PA_FEC_NONE; 2460 } else { 2461 ability->fec = SOC_PA_FEC_CL74; 2462 } 2463 2464 /* retrieve "Channel" abilities */ 2465 ability->channel = SOC_PA_CHANNEL_LONG; 2466 2467 return SOC_E_NONE; 2468 } 2469 2470 /* 2471 * Function: 2472 * phy_tsce_ability_remote_get 2473 * Purpose: 2474 * Get the current advertisement for auto-negotiation. 2475 * Parameters: 2476 * unit - BCM unit number. 2477 * port - Port number. 2478 * ability - (OUT) Port mode mask indicating supported options/speeds. 2479 * Returns: 2480 * SOC_E_XXX 2481 * Notes: 2482 * The advertisement is retrieved for the ACTIVE medium. 2483 * No synchronization performed at this level. 2484 */ 2485 2486 STATIC int 2487 phy_tsce_ability_remote_get(int unit, soc_port_t port, 2488 soc_port_ability_t *ability) 2489 { 2490 phy_ctrl_t *pc; 2491 soc_phymod_ctrl_t *pmc; 2492 soc_phymod_phy_t *phy; 2493 int reg37_ability; 2494 int reg73_ability; 2495 int reg_ability; 2496 _shr_port_mode_t speed_full_duplex; 2497 phymod_autoneg_ability_t phymod_autoneg_ability; 2498 2499 /* locate phy control */ 2500 pc = INT_PHY_SW_STATE(unit, port); 2501 if (pc == NULL) { 2502 return SOC_E_INTERNAL; 2503 } 2504 2505 pmc = &pc->phymod_ctrl; 2506 2507 /* only get abilities from the first core */ 2508 phy = pmc->phy[pmc->main_phy]; 2509 if (phy == NULL) { 2510 return SOC_E_INTERNAL; 2511 } 2512 2513 phymod_autoneg_ability_t_init(&phymod_autoneg_ability); 2514 SOC_IF_ERROR_RETURN 2515 (phymod_phy_autoneg_remote_ability_get(&phy->pm_phy, &phymod_autoneg_ability)); 2516 2517 2518 speed_full_duplex = 0; 2519 2520 /* retrieve CL73 abilities */ 2521 reg73_ability = phymod_autoneg_ability.an_cap; 2522 speed_full_duplex|= PHYMOD_AN_CAP_40G_CR4_GET(reg73_ability) ?SOC_PA_SPEED_40GB:0; 2523 speed_full_duplex|= PHYMOD_AN_CAP_40G_KR4_GET(reg73_ability) ?SOC_PA_SPEED_40GB:0; 2524 speed_full_duplex|= PHYMOD_AN_CAP_10G_KR_GET(reg73_ability) ?SOC_PA_SPEED_10GB:0; 2525 speed_full_duplex|= PHYMOD_AN_CAP_10G_KX4_GET(reg73_ability) ?SOC_PA_SPEED_10GB:0; 2526 speed_full_duplex|= PHYMOD_AN_CAP_1G_KX_GET(reg73_ability) ?SOC_PA_SPEED_1000MB:0; 2527 speed_full_duplex|= PHYMOD_AN_CAP_2P5G_X_GET(reg73_ability) ?SOC_PA_SPEED_2500MB:0; 2528 speed_full_duplex|= PHYMOD_AN_CAP_5G_KR1_GET(reg73_ability) ?SOC_PA_SPEED_5000MB:0; 2529 2530 /* retrieve CL37 abilities */ 2531 reg73_ability = phymod_autoneg_ability.cl73bam_cap; 2532 speed_full_duplex|= PHYMOD_BAM_CL73_CAP_20G_CR2_GET(reg73_ability) ?SOC_PA_SPEED_20GB:0; 2533 speed_full_duplex|= PHYMOD_BAM_CL73_CAP_20G_KR2_GET(reg73_ability) ?SOC_PA_SPEED_20GB:0; 2534 2535 /* retrieve CL37 abilities */ 2536 reg37_ability = phymod_autoneg_ability.cl37bam_cap; 2537 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_40G_GET(reg37_ability) ? SOC_PA_SPEED_40GB:0; 2538 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_31P5G_GET(reg37_ability)? SOC_PA_SPEED_30GB:0; 2539 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_32P7G_GET(reg37_ability)? SOC_PA_SPEED_32GB:0; 2540 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_25P455G_GET(reg37_ability) ? SOC_PA_SPEED_25GB:0; 2541 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_21G_X4_GET(reg37_ability)? SOC_PA_SPEED_21GB:0; 2542 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X2_CX4_GET(reg37_ability)? SOC_PA_SPEED_20GB:0; 2543 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X2_GET(reg37_ability)? SOC_PA_SPEED_20GB:0; 2544 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X4_GET(reg37_ability)? SOC_PA_SPEED_20GB:0; 2545 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X4_CX4_GET(reg37_ability)? SOC_PA_SPEED_20GB:0; 2546 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_16G_X4_GET(reg37_ability)? SOC_PA_SPEED_16GB:0; 2547 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_15P75G_R2_GET(reg37_ability)? SOC_PA_SPEED_16GB:0; 2548 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_15G_X4_GET(reg37_ability)? SOC_PA_SPEED_15GB:0; 2549 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_13G_X4_GET(reg37_ability)? SOC_PA_SPEED_13GB:0; 2550 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12P7_DXGXS_GET(reg37_ability)? SOC_PA_SPEED_13GB:0; 2551 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12P5_X4_GET(reg37_ability)? SOC_PA_SPEED_12P5GB:0; 2552 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12G_X4_GET(reg37_ability)? SOC_PA_SPEED_12GB:0; 2553 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_GET(reg37_ability)?SOC_PA_SPEED_11GB:0; 2554 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_X2_CX4_GET(reg37_ability)? SOC_PA_SPEED_10GB:0; 2555 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_DXGXS_GET(reg37_ability)? SOC_PA_SPEED_10GB:0; 2556 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_CX4_GET(reg37_ability)? SOC_PA_SPEED_10GB:0; 2557 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_HIGIG_GET(reg37_ability)? SOC_PA_SPEED_10GB:0; /* 4-lane */ 2558 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_6G_X4_GET(reg37_ability)? SOC_PA_SPEED_6000MB:0; 2559 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_5G_X4_GET(reg37_ability)? SOC_PA_SPEED_5000MB:0; 2560 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_2P5G_GET(reg37_ability)? SOC_PA_SPEED_2500MB:0; 2561 if (PHYMOD_AN_CAP_CL37_GET(&phymod_autoneg_ability)) { 2562 speed_full_duplex|= SOC_PA_SPEED_1000MB ; 2563 } 2564 /*retrieve sgmii abilities*/ 2565 if (PHYMOD_AN_CAP_SGMII_GET(&phymod_autoneg_ability)) { 2566 if (phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_10M) { 2567 speed_full_duplex |= SOC_PA_SPEED_10MB; 2568 } else if (phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_100M) { 2569 speed_full_duplex |= SOC_PA_SPEED_100MB; 2570 } else { 2571 speed_full_duplex |= SOC_PA_SPEED_1000MB; 2572 } 2573 } 2574 /* retrieve "pause" abilities */ 2575 reg_ability = phymod_autoneg_ability.capabilities & (PHYMOD_AN_CAP_ASYM_PAUSE | PHYMOD_AN_CAP_SYMM_PAUSE); 2576 ability->pause = 0; 2577 if (reg_ability == PHYMOD_AN_CAP_ASYM_PAUSE) { 2578 ability->pause = SOC_PA_PAUSE_TX; 2579 } else if (reg_ability == (PHYMOD_AN_CAP_SYMM_PAUSE|PHYMOD_AN_CAP_ASYM_PAUSE)) { 2580 ability->pause = SOC_PA_PAUSE_RX; 2581 } else if (reg_ability == PHYMOD_AN_CAP_SYMM_PAUSE) { 2582 ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX); 2583 } 2584 2585 ability->speed_full_duplex = speed_full_duplex; 2586 2587 /* retrieve "FEC" abilities */ 2588 ability->fec = 0; 2589 if (PHYMOD_AN_FEC_OFF_GET(phymod_autoneg_ability.an_fec)) { 2590 ability->fec = SOC_PA_FEC_NONE; 2591 } else { 2592 ability->fec |= SOC_PA_FEC_CL74; 2593 } 2594 2595 /* retrieve "Channel" abilities */ 2596 ability->channel = SOC_PA_CHANNEL_LONG; 2597 2598 /* retrieve "Medium type" abilities */ 2599 if (PHYMOD_AN_CAP_40G_CR4_GET(phymod_autoneg_ability.an_cap) || 2600 PHYMOD_BAM_CL73_CAP_20G_CR2_GET(phymod_autoneg_ability.cl73bam_cap)) { 2601 ability->medium = SOC_PA_MEDIUM_COPPER; 2602 } else if (PHYMOD_AN_CAP_CL37_GET(&phymod_autoneg_ability)) { 2603 ability->medium = SOC_PA_MEDIUM_FIBER; 2604 } else { 2605 ability->medium = SOC_PA_MEDIUM_BACKPLANE; 2606 } 2607 2608 return SOC_E_NONE; 2609 } 2610 2611 /* 2612 * Function: 2613 * phy_tsce_lb_set 2614 * Purpose: 2615 * Enable/disable PHY loopback mode 2616 * Parameters: 2617 * unit - BCM unit number. 2618 * port - Port number. 2619 * enable - binary value for on/off (1/0) 2620 * Returns: 2621 * SOC_E_NONE 2622 */ 2623 STATIC int 2624 phy_tsce_lb_set(int unit, soc_port_t port, int enable) 2625 { 2626 phy_ctrl_t* pc; 2627 soc_phymod_ctrl_t *pmc; 2628 phymod_phy_access_t *pm_phy; 2629 int idx; 2630 2631 pc = INT_PHY_SW_STATE(unit, port); 2632 pmc = &pc->phymod_ctrl; 2633 2634 for (idx = 0; idx < pmc->num_phys; idx++) { 2635 pm_phy = &pmc->phy[idx]->pm_phy; 2636 SOC_IF_ERROR_RETURN 2637 (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobal, enable)); 2638 } 2639 2640 return (SOC_E_NONE); 2641 } 2642 2643 /* 2644 * Function: 2645 * phy_tsce_lb_get 2646 * Purpose: 2647 * Get current PHY loopback mode 2648 * Parameters: 2649 * unit - BCM unit number. 2650 * port - Port number. 2651 * enable - address of location to store binary value for on/off (1/0) 2652 * Returns: 2653 * SOC_E_NONE 2654 */ 2655 STATIC int 2656 phy_tsce_lb_get(int unit, soc_port_t port, int *enable) 2657 { 2658 phy_ctrl_t* pc; 2659 soc_phymod_ctrl_t *pmc; 2660 phymod_phy_access_t *pm_phy; 2661 uint32 lb_enable; 2662 int idx; 2663 2664 pc = INT_PHY_SW_STATE(unit, port); 2665 pmc = &pc->phymod_ctrl; 2666 2667 *enable = 0; 2668 2669 for (idx = 0; idx < pmc->num_phys; idx++) { 2670 pm_phy = &pmc->phy[idx]->pm_phy; 2671 SOC_IF_ERROR_RETURN 2672 (phymod_phy_loopback_get(pm_phy, phymodLoopbackGlobal, &lb_enable)); 2673 if (lb_enable) { 2674 *enable = 1; 2675 } 2676 /* Check first PHY only */ 2677 break; 2678 } 2679 2680 return (SOC_E_NONE); 2681 } 2682 2683 /* 2684 * Function: 2685 * phy_tsce_ability_local_get 2686 * Purpose: 2687 * xx 2688 * Parameters: 2689 * unit - BCM unit number. 2690 * port - Port number. 2691 * ability - xx 2692 * Returns: 2693 * SOC_E_NONE 2694 */ 2695 STATIC int 2696 phy_tsce_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability) 2697 { 2698 phy_ctrl_t *pc; 2699 /*int hg_mode; 2700 int max_speed; 2701 int cfg_init_speed; 2702 */ 2703 tsce_config_t *pCfg; 2704 phymod_core_version_t core_version; 2705 phymod_core_info_t info; 2706 phymod_core_access_t *pm_core; 2707 2708 pc = INT_PHY_SW_STATE(unit, port); 2709 pCfg = (tsce_config_t *) pc->driver_data; 2710 pm_core = &pc->phymod_ctrl.phy[0]->core->pm_core; 2711 SOC_IF_ERROR_RETURN 2712 (phymod_core_info_get(pm_core, &info)); 2713 core_version = info.core_version; 2714 2715 if (NULL == ability) { 2716 return SOC_E_PARAM; 2717 } 2718 2719 sal_memset(ability, 0, sizeof(*ability)); 2720 2721 ability->loopback = SOC_PA_LB_PHY; 2722 ability->medium = SOC_PA_MEDIUM_FIBER | SOC_PA_MEDIUM_COPPER | SOC_PA_MEDIUM_BACKPLANE; 2723 ability->pause = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM; 2724 ability->flags = SOC_PA_AUTONEG; 2725 ability->channel = SOC_PA_CHANNEL_LONG; 2726 ability->fec = SOC_PA_FEC_CL74 | SOC_PA_FEC_NONE; 2727 2728 if (IND_LANE_MODE(pc)) { 2729 ability->speed_full_duplex = SOC_PA_SPEED_1000MB; 2730 ability->speed_full_duplex |= SOC_PA_SPEED_2500MB; 2731 if (pCfg->speed_config.fiber_pref) { 2732 ability->speed_full_duplex |= SOC_PA_SPEED_10GB; 2733 ability->speed_full_duplex |= SOC_PA_SPEED_100MB; 2734 ability->speed_half_duplex = SOC_PA_SPEED_100MB; 2735 } else { 2736 ability->speed_half_duplex = SOC_PA_SPEED_10MB | 2737 SOC_PA_SPEED_100MB; 2738 ability->speed_full_duplex |= SOC_PA_SPEED_10MB | 2739 SOC_PA_SPEED_100MB; 2740 } 2741 switch(pc->speed_max) { /* must include all the supported speedss */ 2742 case 25000: 2743 ability->speed_full_duplex |= SOC_PA_SPEED_25GB; 2744 case 21000: 2745 ability->speed_full_duplex |= SOC_PA_SPEED_21GB; 2746 /* fall through */ 2747 case 20000: 2748 ability->speed_full_duplex |= SOC_PA_SPEED_20GB; 2749 /* fall through */ 2750 case 16000: 2751 if (!(core_version == phymodCoreVersionTsceDpll)) { 2752 ability->speed_full_duplex |= SOC_PA_SPEED_16GB; 2753 } 2754 /* fall through */ 2755 /* not supported speed 2756 case 15750: 2757 ability->speed_full_duplex |= SOC_PA_SPEED_15P75GB; */ 2758 /* fall through */ 2759 case 15000: 2760 if (!(core_version == phymodCoreVersionTsceDpll)) { 2761 ability->speed_full_duplex |= SOC_PA_SPEED_15GB; 2762 } 2763 /* fall through */ 2764 /* not supported speed 2765 case 12730: 2766 ability->speed_full_duplex |= SOC_PA_SPEED_12P73GB; */ 2767 /* fall through */ 2768 case 13000: 2769 if (!(core_version == phymodCoreVersionTsceDpll)) { 2770 ability->speed_full_duplex |= SOC_PA_SPEED_13GB; 2771 } 2772 /* fall through */ 2773 case 12000: 2774 if (core_version == phymodCoreVersionTsceDpll) { 2775 if (pCfg->speed_config.port_num_lanes == 1) { 2776 ability->speed_full_duplex |= SOC_PA_SPEED_12GB; 2777 } 2778 } else { 2779 ability->speed_full_duplex |= SOC_PA_SPEED_12GB; 2780 } 2781 /* fall through */ 2782 case 11000: 2783 ability->speed_full_duplex |= SOC_PA_SPEED_11GB; 2784 /* not supported speed 2785 case 10500: 2786 2787 ability->speed_full_duplex |= SOC_PA_SPEED_10P5GB; */ 2788 /* fall through */ 2789 case 10000: 2790 ability->speed_full_duplex |= SOC_PA_SPEED_10GB; 2791 /* fall through */ 2792 case 5000: 2793 if (!(PBMP_MEMBER(PBMP_HG_ALL(unit), port))) { 2794 ability->speed_full_duplex |= SOC_PA_SPEED_5000MB; 2795 } 2796 /* fall through */ 2797 default: 2798 break; 2799 } 2800 ability->pause = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM; 2801 ability->interface = SOC_PA_INTF_GMII | SOC_PA_INTF_SGMII; 2802 if (pc->speed_max >= 10000) { 2803 ability->interface |= SOC_PA_INTF_XGMII; 2804 } 2805 ability->loopback = SOC_PA_LB_PHY; 2806 /* if dual lane port */ 2807 if (IS_DUAL_LANE_PORT(pc)) { 2808 ability->flags = 0; 2809 } else { 2810 ability->flags = SOC_PA_AUTONEG; 2811 } 2812 } else { 2813 ability->speed_half_duplex = SOC_PA_ABILITY_NONE; 2814 ability->speed_full_duplex = SOC_PA_SPEED_1000MB; 2815 if (pCfg->fiber_pref) { 2816 ability->speed_full_duplex |= SOC_PA_SPEED_2500MB; 2817 ability->speed_full_duplex |= SOC_PA_SPEED_100MB; 2818 ability->speed_half_duplex = SOC_PA_SPEED_100MB; 2819 } else { 2820 ability->speed_half_duplex = SOC_PA_SPEED_10MB | 2821 SOC_PA_SPEED_100MB; 2822 ability->speed_full_duplex |= SOC_PA_SPEED_10MB | 2823 SOC_PA_SPEED_100MB; 2824 } 2825 switch(pc->speed_max) { 2826 case 127000: 2827 if (core_version != phymodCoreVersionTsceDpll) { 2828 ability->speed_full_duplex |= SOC_PA_SPEED_127GB; 2829 } 2830 case 106000: 2831 if (core_version != phymodCoreVersionTsceDpll) { 2832 ability->speed_full_duplex |= SOC_PA_SPEED_106GB; 2833 } 2834 case 120000: 2835 if (core_version != phymodCoreVersionTsceDpll) { 2836 ability->speed_full_duplex |= SOC_PA_SPEED_120GB; 2837 } 2838 case 100000: 2839 if (core_version != phymodCoreVersionTsceDpll) { 2840 ability->speed_full_duplex |= SOC_PA_SPEED_100GB; 2841 } 2842 case 42000: 2843 ability->speed_full_duplex |= SOC_PA_SPEED_42GB; 2844 case 40000: 2845 ability->speed_full_duplex |= SOC_PA_SPEED_40GB; 2846 case 30000: 2847 if (core_version != phymodCoreVersionTsceDpll) { 2848 ability->speed_full_duplex |= SOC_PA_SPEED_30GB; 2849 } 2850 case 25000: 2851 if (core_version != phymodCoreVersionTsceDpll) { 2852 ability->speed_full_duplex |= SOC_PA_SPEED_25GB; 2853 } 2854 case 21000: 2855 ability->speed_full_duplex |= SOC_PA_SPEED_21GB; 2856 case 20000: 2857 ability->speed_full_duplex |= SOC_PA_SPEED_20GB; 2858 /* fall through */ 2859 case 16000: 2860 if (core_version != phymodCoreVersionTsceDpll) { 2861 ability->speed_full_duplex |= SOC_PA_SPEED_16GB; 2862 } 2863 /* fall through */ 2864 case 15000: 2865 if (core_version != phymodCoreVersionTsceDpll) { 2866 ability->speed_full_duplex |= SOC_PA_SPEED_15GB; 2867 } 2868 /* fall through */ 2869 case 13000: 2870 if (core_version != phymodCoreVersionTsceDpll) { 2871 ability->speed_full_duplex |= SOC_PA_SPEED_13GB; 2872 } 2873 /* fall through */ 2874 default: 2875 ability->speed_full_duplex |= SOC_PA_SPEED_10GB; 2876 break; 2877 } 2878 ability->pause = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM; 2879 ability->interface = SOC_PA_INTF_XGMII; 2880 ability->loopback = SOC_PA_LB_PHY; 2881 ability->flags = SOC_PA_AUTONEG; 2882 } 2883 2884 LOG_INFO(BSL_LS_SOC_PHY, 2885 (BSL_META_U(pc->unit, 2886 "phy_tsce_ability_local_get:unit=%d p=%d sp=%08x\n"), 2887 unit, port, ability->speed_full_duplex)); 2888 return (SOC_E_NONE); 2889 } 2890 2891 /* 2892 * Function: 2893 * phy_tsce_firmware_set 2894 * Purpose: 2895 * xx 2896 * Parameters: 2897 * unit - BCM unit number. 2898 * port - Port number. 2899 2900 * Returns: 2901 * SOC_E_NONE 2902 */ 2903 2904 STATIC int 2905 phy_tsce_firmware_set(int unit, soc_port_t port, int x, uint8 *y, int z) 2906 { 2907 return (SOC_E_NONE); 2908 } 2909 2910 STATIC int 2911 phy_tsce_interface_set(int unit, soc_port_t port, soc_port_if_t pif) 2912 { 2913 phy_ctrl_t *pc; 2914 tsce_config_t *pCfg; 2915 soc_phymod_ctrl_t *pmc; 2916 soc_phymod_phy_t *phy; 2917 tsce_speed_config_t speed_config; 2918 phymod_phy_access_t pm_phy_copy; 2919 phymod_phy_inf_config_t interface_config; 2920 TXDRV_INXS_t tx_index = TXDRV_DFT_INX; 2921 phymod_tx_t phymod_tx; 2922 int speed, start_lane, num_lane; 2923 int ln, idx=0; 2924 uint32 do_not_update_tx = 0; 2925 soc_port_if_t prev_pif; 2926 2927 /* locate phy control */ 2928 pc = INT_PHY_SW_STATE(unit, port); 2929 if (pc == NULL) { 2930 return SOC_E_INTERNAL; 2931 } 2932 2933 pmc = &pc->phymod_ctrl; 2934 pCfg = (tsce_config_t *) pc->driver_data; 2935 2936 2937 pCfg->speed_config.line_interface = (uint32) pif; 2938 2939 2940 if ((pif == SOC_PORT_IF_SFI) || 2941 (pif == SOC_PORT_IF_SR4) || 2942 (pif == SOC_PORT_IF_LR4) || 2943 (pif == SOC_PORT_IF_SR) || 2944 (pif == SOC_PORT_IF_LR) || 2945 (pif == SOC_PORT_IF_GMII)) { 2946 pCfg->speed_config.fiber_pref = 1; 2947 } else if ((pif == SOC_PORT_IF_XFI) || 2948 (pif == SOC_PORT_IF_KR4) || 2949 (pif == SOC_PORT_IF_CR4) || 2950 (pif == SOC_PORT_IF_KR) || 2951 (pif == SOC_PORT_IF_KR2) || 2952 (pif == SOC_PORT_IF_SGMII)) { 2953 pCfg->speed_config.fiber_pref = 0; 2954 } 2955 2956 /* first check if the current intf */ 2957 SOC_IF_ERROR_RETURN 2958 (phy_tsce_interface_get(unit, port, &prev_pif)); 2959 if (prev_pif == pif) { 2960 do_not_update_tx = 1; 2961 } 2962 2963 /* take a copy of core and phy configuration values, and set the desired speed */ 2964 sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config)); 2965 /* get the current speed */ 2966 SOC_IF_ERROR_RETURN 2967 (phy_tsce_speed_get(unit, port, &speed)); 2968 speed_config.speed = speed; 2969 2970 phy = pmc->phy[idx]; /* to support one core currently */ 2971 2972 if (phy == NULL) { 2973 return SOC_E_INTERNAL; 2974 } 2975 2976 sal_memcpy(&pm_phy_copy, &phy->pm_phy, sizeof(pm_phy_copy)); 2977 2978 /* determine the interface configuration */ 2979 SOC_IF_ERROR_RETURN 2980 (tsce_speed_to_interface_config_get(&pm_phy_copy, &speed_config, &interface_config, &tx_index)); 2981 2982 SOC_IF_ERROR_RETURN(phymod_tx_t_init(&phymod_tx)); 2983 2984 if (!do_not_update_tx) { 2985 /* get the start lane and num of lane info */ 2986 2987 SOC_IF_ERROR_RETURN 2988 (phymod_util_lane_config_get(&pm_phy_copy.access, &start_lane, &num_lane)); 2989 2990 for(ln=0; ln<num_lane; ln++) { 2991 pm_phy_copy.access.lane_mask = 1 << (start_lane +ln) ; 2992 2993 phymod_tx.amp = pCfg->tx_drive[tx_index].amp; 2994 phymod_tx.main = pCfg->tx_drive[tx_index].main; 2995 phymod_tx.post = pCfg->tx_drive[tx_index].post; 2996 phymod_tx.post2 = pCfg->tx_drive[tx_index].post2; 2997 phymod_tx.post3 = pCfg->tx_drive[tx_index].post3; 2998 phymod_tx.pre = pCfg->tx_drive[tx_index].pre; 2999 3000 if( pCfg->ln_txparam[4*idx+ln].amp >=0) { 3001 phymod_tx.amp = pCfg->ln_txparam[4*idx+ln].amp; 3002 } 3003 if( pCfg->ln_txparam[4*idx+ln].main >=0) { 3004 phymod_tx.main = pCfg->ln_txparam[4*idx+ln].main; 3005 } 3006 if( pCfg->ln_txparam[4*idx+ln].post >=0) { 3007 phymod_tx.post = pCfg->ln_txparam[4*idx+ln].post; 3008 } 3009 if( pCfg->ln_txparam[4*idx+ln].pre >=0) { 3010 phymod_tx.pre = pCfg->ln_txparam[4*idx+ln].pre; 3011 } 3012 if( pCfg->ln_txparam[4*idx+ln].post2 >=0) { 3013 phymod_tx.post2 = pCfg->ln_txparam[4*idx+ln].post2; 3014 } 3015 if( pCfg->ln_txparam[4*idx+ln].post3 >=0) { 3016 phymod_tx.post3 = pCfg->ln_txparam[4*idx+ln].post3; 3017 } 3018 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx)); 3019 } 3020 } 3021 3022 /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */ 3023 3024 if (!SOC_WARM_BOOT(unit)) { 3025 SOC_IF_ERROR_RETURN 3026 (phymod_phy_interface_config_set(&phy->pm_phy, 3027 0 /* flags */, &interface_config)); 3028 } 3029 /* record success */ 3030 pCfg->speed_config.speed = speed; 3031 3032 return SOC_E_NONE; 3033 } 3034 3035 STATIC int 3036 phy_tsce_interface_get(int unit, soc_port_t port, soc_port_if_t *pif) 3037 { 3038 phy_ctrl_t *pc; 3039 soc_phymod_ctrl_t *pmc; 3040 soc_phymod_phy_t *phy; 3041 phymod_phy_inf_config_t interface_config; 3042 tsce_config_t *pCfg; 3043 int flag = 0; 3044 phymod_ref_clk_t ref_clock; 3045 3046 /* locate phy control */ 3047 pc = INT_PHY_SW_STATE(unit, port); 3048 if (pc == NULL) { 3049 return SOC_E_INTERNAL; 3050 } 3051 pCfg = (tsce_config_t *) pc->driver_data; 3052 3053 pmc = &pc->phymod_ctrl; 3054 3055 /* initialize the data structure */ 3056 sal_memset(&interface_config, 0x0, sizeof(phymod_phy_inf_config_t)); 3057 3058 /* now loop through all cores */ 3059 phy = pmc->phy[pmc->main_phy]; 3060 if (phy == NULL) { 3061 return SOC_E_INTERNAL; 3062 } 3063 3064 SOC_IF_ERROR_RETURN( 3065 tsce_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clock)); 3066 3067 /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */ 3068 SOC_IF_ERROR_RETURN 3069 (phymod_phy_interface_config_get(&phy->pm_phy, 3070 flag, ref_clock, &interface_config)); 3071 switch (interface_config.interface_type) { 3072 case phymodInterfaceXFI: 3073 if (pCfg->speed_config.line_interface == SOC_PORT_IF_KR) { 3074 *pif = SOC_PORT_IF_KR; 3075 } else { 3076 *pif = SOC_PORT_IF_XFI; 3077 } 3078 break; 3079 case phymodInterfaceSFI: 3080 if (pCfg->speed_config.line_interface == SOC_PORT_IF_SR) { 3081 *pif = SOC_PORT_IF_SR; 3082 } else if (pCfg->speed_config.line_interface == SOC_PORT_IF_LR) { 3083 *pif = SOC_PORT_IF_LR; 3084 } else { 3085 *pif = SOC_PORT_IF_SFI; 3086 } 3087 break; 3088 case phymodInterfaceXLAUI: 3089 *pif = SOC_PORT_IF_XLAUI; 3090 break; 3091 case phymodInterface1000X: 3092 *pif = SOC_PORT_IF_GMII; 3093 break; 3094 case phymodInterfaceKX: 3095 *pif = SOC_PORT_IF_KX; 3096 break; 3097 case phymodInterfaceSGMII: 3098 *pif = SOC_PORT_IF_SGMII; 3099 break; 3100 case phymodInterfaceRXAUI: 3101 *pif = SOC_PORT_IF_RXAUI; 3102 break; 3103 case phymodInterfaceX2: 3104 *pif = SOC_PORT_IF_RXAUI; /* BRCM RXAUI */ 3105 break; 3106 case phymodInterfaceXGMII: 3107 *pif = SOC_PORT_IF_XGMII; 3108 break; 3109 case phymodInterfaceKR4: 3110 *pif = SOC_PORT_IF_KR4; 3111 break; 3112 case phymodInterfaceKR: 3113 *pif = SOC_PORT_IF_KR; 3114 break; 3115 case phymodInterfaceSR: 3116 *pif = SOC_PORT_IF_SR; 3117 break; 3118 case phymodInterfaceCR: 3119 *pif = SOC_PORT_IF_CR; 3120 break; 3121 case phymodInterfaceKR2: 3122 *pif = SOC_PORT_IF_KR2; 3123 break; 3124 case phymodInterfaceCR2: 3125 *pif = SOC_PORT_IF_CR2; 3126 break; 3127 case phymodInterfaceCR4: 3128 *pif = SOC_PORT_IF_CR4; 3129 break; 3130 case phymodInterfaceCR10: 3131 case phymodInterfaceCAUI: 3132 *pif = SOC_PORT_IF_CAUI; 3133 break; 3134 case phymodInterfaceSR4: 3135 if (pCfg->speed_config.line_interface == SOC_PORT_IF_LR4) { 3136 *pif = SOC_PORT_IF_LR4; 3137 } else { 3138 *pif = SOC_PORT_IF_SR4; 3139 } 3140 break; 3141 case phymodInterfaceBypass: 3142 *pif = SOC_PORT_IF_ILKN; 3143 break; 3144 case phymodInterfaceKX4: 3145 if (pCfg->speed_config.line_interface == _SHR_PORT_IF_XAUI) { 3146 /*The SOC_PORT_IF_XAUI is defined as _SHR_PORT_IF_XGMII. 3147 If use the MACRO SOC_PORT_IF_XAUI, the interface showed in "ps" will be XGMII. 3148 */ 3149 *pif = _SHR_PORT_IF_XAUI; 3150 } else { 3151 *pif = SOC_PORT_IF_XGMII; 3152 } 3153 break; 3154 default: 3155 *pif = SOC_PORT_IF_XGMII; 3156 break; 3157 } 3158 return (SOC_E_NONE); 3159 3160 } 3161 3162 3163 /* 3164 * Function: 3165 * tsce_uc_status_dump 3166 * Purpose: 3167 * display all the serdes related parameters 3168 * Parameters: 3169 * unit - BCM unit number. 3170 * port - Port number. 3171 3172 * Returns: 3173 * SOC_E_NONE 3174 */ 3175 STATIC int 3176 tsce_uc_status_dump(int unit, soc_port_t port, void *arg) 3177 { 3178 phy_ctrl_t* pc; 3179 soc_phymod_ctrl_t *pmc; 3180 phymod_phy_access_t *pm_phy; 3181 int idx; 3182 3183 3184 3185 3186 pc = INT_PHY_SW_STATE(unit, port); 3187 pmc = &pc->phymod_ctrl; 3188 3189 for (idx = 0; idx < pmc->num_phys; idx++) { 3190 pm_phy = &pmc->phy[idx]->pm_phy; 3191 SOC_IF_ERROR_RETURN 3192 (phymod_phy_pmd_info_dump(pm_phy, arg)); 3193 } 3194 return (SOC_E_NONE); 3195 } 3196 3197 /* 3198 * Function: 3199 * tsce_pcs_status_dump 3200 * Purpose: 3201 * display all the serdes related parameters 3202 * Parameters: 3203 * unit - BCM unit number. 3204 * port - Port number. 3205 3206 * Returns: 3207 * SOC_E_NONE 3208 */ 3209 STATIC int 3210 tsce_pcs_status_dump(int unit, soc_port_t port, void *arg) 3211 { 3212 phy_ctrl_t* pc; 3213 soc_phymod_ctrl_t *pmc; 3214 phymod_phy_access_t *pm_phy; 3215 int idx; 3216 3217 pc = INT_PHY_SW_STATE(unit, port); 3218 pmc = &pc->phymod_ctrl; 3219 3220 for (idx = 0; idx < pmc->num_phys; idx++) { 3221 pm_phy = &pmc->phy[idx]->pm_phy; 3222 SOC_IF_ERROR_RETURN 3223 (phymod_phy_pcs_info_dump(pm_phy, arg)); 3224 } 3225 return (SOC_E_NONE); 3226 } 3227 3228 3229 /* 3230 * given a pc (phymod_ctrl_t) and logical lane number, 3231 * find the correct soc_phymod_phy_t object and lane 3232 */ 3233 STATIC int 3234 _tsce_find_soc_phy_lane(soc_phymod_ctrl_t *pmc, uint32_t lane, 3235 soc_phymod_phy_t **p_phy, uint32 *lane_map) 3236 { 3237 phymod_phy_access_t *pm_phy; 3238 int idx, lnx, ln_cnt, found; 3239 uint32 lane_map_copy; 3240 3241 /* Traverse lanes belonging to this port */ 3242 found = 0; 3243 ln_cnt = 0; 3244 for (idx = 0; idx < pmc->num_phys; idx++) { 3245 pm_phy = &pmc->phy[idx]->pm_phy; 3246 if (pm_phy == NULL) { 3247 return SOC_E_INTERNAL; 3248 } 3249 lane_map_copy = pm_phy->access.lane_mask; 3250 for (lnx = 0; lnx < 4; lnx++) { 3251 if ((1 << lnx) & lane_map_copy) { 3252 if (ln_cnt == lane) { 3253 found = 1; 3254 break; 3255 } 3256 ln_cnt++; 3257 } 3258 } 3259 if (found) { 3260 *p_phy = pmc->phy[idx]; 3261 *lane_map = (1 << lnx); 3262 break; 3263 } 3264 } 3265 3266 if (!found) { 3267 /* No such lane */ 3268 return SOC_E_PARAM; 3269 } 3270 return (SOC_E_NONE); 3271 } 3272 3273 /* 3274 * tsce_per_lane_preemphasis_set 3275 */ 3276 STATIC int 3277 tsce_per_lane_preemphasis_set(soc_phymod_ctrl_t *pmc, tsce_config_t *pCfg, int lane, uint32 value) 3278 { 3279 soc_phymod_phy_t *p_phy; 3280 uint32 lane_map; 3281 phymod_phy_access_t pm_phy_copy, *pm_phy; 3282 phymod_tx_t phymod_tx; 3283 3284 /* locate the desired phy and lane */ 3285 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 3286 3287 /* Make a copy of the phy access and overwrite the desired lane */ 3288 pm_phy = &p_phy->pm_phy; 3289 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3290 pm_phy_copy.access.lane_mask = lane_map; 3291 3292 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 3293 phymod_tx.pre = value & 0xff; 3294 phymod_tx.main = (value >> 8) & 0xff; 3295 phymod_tx.post = (value >> 16) & 0xff; 3296 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx)); 3297 3298 pCfg->ln_txparam[lane].pre = phymod_tx.pre ; 3299 pCfg->ln_txparam[lane].main= phymod_tx.main ; 3300 pCfg->ln_txparam[lane].post= phymod_tx.post ; 3301 3302 return(SOC_E_NONE); 3303 } 3304 3305 /* 3306 * tsce_preemphasis_set 3307 */ 3308 STATIC int 3309 tsce_preemphasis_set(soc_phymod_ctrl_t *pmc, tsce_config_t *pCfg, uint32 value) 3310 { 3311 phymod_phy_access_t *pm_phy; 3312 phymod_tx_t phymod_tx; 3313 int idx; 3314 3315 /* loop through all cores */ 3316 for (idx = 0; idx < pmc->num_phys; idx++) { 3317 pm_phy = &pmc->phy[idx]->pm_phy; 3318 3319 if (pm_phy == NULL) { 3320 return SOC_E_INTERNAL; 3321 } 3322 3323 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3324 phymod_tx.pre = value & 0xff; 3325 phymod_tx.main = (value >> 8) & 0xff; 3326 phymod_tx.post = (value >> 16) & 0xff; 3327 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 3328 } 3329 3330 return(SOC_E_NONE); 3331 } 3332 3333 /* 3334 * tsce_tx_fir_pre_set 3335 */ 3336 STATIC int 3337 tsce_tx_fir_pre_set(soc_phymod_ctrl_t *pmc, uint32 value) 3338 { 3339 phymod_phy_access_t *pm_phy; 3340 phymod_tx_t phymod_tx; 3341 int idx; 3342 3343 /* loop through all cores */ 3344 for (idx = 0; idx < pmc->num_phys; idx++) { 3345 pm_phy = &pmc->phy[idx]->pm_phy; 3346 3347 if (pm_phy == NULL) { 3348 return SOC_E_INTERNAL; 3349 } 3350 3351 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3352 phymod_tx.pre = value; 3353 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 3354 } 3355 3356 return(SOC_E_NONE); 3357 } 3358 3359 /* 3360 * tsce_tx_fir_main_set 3361 */ 3362 STATIC int 3363 tsce_tx_fir_main_set(soc_phymod_ctrl_t *pmc, uint32 value) 3364 { 3365 phymod_phy_access_t *pm_phy; 3366 phymod_tx_t phymod_tx; 3367 int idx; 3368 3369 /* loop through all cores */ 3370 for (idx = 0; idx < pmc->num_phys; idx++) { 3371 pm_phy = &pmc->phy[idx]->pm_phy; 3372 3373 if (pm_phy == NULL) { 3374 return SOC_E_INTERNAL; 3375 } 3376 3377 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3378 phymod_tx.main = value; 3379 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 3380 } 3381 3382 return(SOC_E_NONE); 3383 } 3384 3385 /* 3386 * tsce_tx_fir_post_set 3387 */ 3388 STATIC int 3389 tsce_tx_fir_post_set(soc_phymod_ctrl_t *pmc, uint32 value) 3390 { 3391 phymod_phy_access_t *pm_phy; 3392 phymod_tx_t phymod_tx; 3393 int idx; 3394 3395 /* loop through all cores */ 3396 for (idx = 0; idx < pmc->num_phys; idx++) { 3397 pm_phy = &pmc->phy[idx]->pm_phy; 3398 3399 if (pm_phy == NULL) { 3400 return SOC_E_INTERNAL; 3401 } 3402 3403 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3404 phymod_tx.post = value; 3405 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 3406 } 3407 3408 return(SOC_E_NONE); 3409 } 3410 3411 /* 3412 * tsce_tx_fir_post2_set 3413 */ 3414 STATIC int 3415 tsce_tx_fir_post2_set(soc_phymod_ctrl_t *pmc, uint32 value) 3416 { 3417 phymod_phy_access_t *pm_phy; 3418 phymod_tx_t phymod_tx; 3419 int idx; 3420 3421 /* loop through all cores */ 3422 for (idx = 0; idx < pmc->num_phys; idx++) { 3423 pm_phy = &pmc->phy[idx]->pm_phy; 3424 3425 if (pm_phy == NULL) { 3426 return SOC_E_INTERNAL; 3427 } 3428 3429 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3430 phymod_tx.post2 = value; 3431 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 3432 } 3433 3434 return(SOC_E_NONE); 3435 } 3436 3437 /* 3438 * tsce_tx_fir_post3_set 3439 */ 3440 STATIC int 3441 tsce_tx_fir_post3_set(soc_phymod_ctrl_t *pmc, uint32 value) 3442 { 3443 phymod_phy_access_t *pm_phy; 3444 phymod_tx_t phymod_tx; 3445 int idx; 3446 3447 /* loop through all cores */ 3448 for (idx = 0; idx < pmc->num_phys; idx++) { 3449 pm_phy = &pmc->phy[idx]->pm_phy; 3450 3451 if (pm_phy == NULL) { 3452 return SOC_E_INTERNAL; 3453 } 3454 3455 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3456 phymod_tx.post3 = value; 3457 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 3458 } 3459 3460 return(SOC_E_NONE); 3461 } 3462 3463 3464 /* 3465 * tsce_per_lane_driver_current_set 3466 */ 3467 STATIC int 3468 tsce_per_lane_driver_current_set(soc_phymod_ctrl_t *pmc, tsce_config_t *pCfg, int lane, uint32 value) 3469 { 3470 soc_phymod_phy_t *p_phy; 3471 uint32 lane_map; 3472 phymod_phy_access_t pm_phy_copy, *pm_phy; 3473 phymod_tx_t phymod_tx; 3474 3475 /* locate the desired phy and lane */ 3476 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 3477 3478 /* Make a copy of the phy access and overwrite the desired lane */ 3479 pm_phy = &p_phy->pm_phy; 3480 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3481 pm_phy_copy.access.lane_mask = lane_map; 3482 3483 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 3484 phymod_tx.amp = value; 3485 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx)); 3486 3487 pCfg->ln_txparam[lane].amp = value ; 3488 return(SOC_E_NONE); 3489 } 3490 3491 /* 3492 * tsce_driver_current_set 3493 */ 3494 STATIC int 3495 tsce_driver_current_set(soc_phymod_ctrl_t *pmc, tsce_config_t *pCfg, uint32 value) 3496 { 3497 phymod_phy_access_t *pm_phy; 3498 phymod_tx_t phymod_tx; 3499 int idx, ln; 3500 int start_lane, num_lane ; 3501 phymod_phy_access_t pm_phy_copy; 3502 3503 /* loop through all cores */ 3504 for (idx = 0; idx < pmc->num_phys; idx++) { 3505 pm_phy = &pmc->phy[idx]->pm_phy; 3506 3507 if (pm_phy == NULL) { 3508 return SOC_E_INTERNAL; 3509 } 3510 3511 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3512 phymod_tx.amp = value; 3513 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 3514 3515 /* handle state */ 3516 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3517 PHYMOD_IF_ERR_RETURN 3518 (phymod_util_lane_config_get(&pm_phy_copy.access, &start_lane, &num_lane)); 3519 3520 for(ln=0; ln<num_lane; ln++) { 3521 pCfg->ln_txparam[4*idx+ln].amp = phymod_tx.amp ; 3522 } 3523 } 3524 3525 return(SOC_E_NONE); 3526 } 3527 3528 3529 /* 3530 * tsce_per_lane_tx_fir_drivermode_set 3531 */ 3532 STATIC int 3533 tsce_per_lane_tx_fir_drivermode_set(soc_phymod_ctrl_t *pmc, tsce_config_t *pCfg, int lane, uint32 value) 3534 { 3535 soc_phymod_phy_t *p_phy; 3536 uint32 lane_map; 3537 phymod_phy_access_t pm_phy_copy, *pm_phy; 3538 phymod_tx_t phymod_tx; 3539 3540 /* locate the desired phy and lane */ 3541 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 3542 3543 /* Make a copy of the phy access and overwrite the desired lane */ 3544 pm_phy = &p_phy->pm_phy; 3545 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3546 pm_phy_copy.access.lane_mask = lane_map; 3547 3548 PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE_SET(&pm_phy_copy); 3549 3550 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 3551 phymod_tx.drivermode = value; 3552 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx)); 3553 3554 pCfg->ln_txparam[lane].drivermode = value ; 3555 return(SOC_E_NONE); 3556 } 3557 3558 /* 3559 * tsce_driver_current_set 3560 */ 3561 STATIC int 3562 tsce_tx_fir_drivermode_set(soc_phymod_ctrl_t *pmc, tsce_config_t *pCfg, uint32 value) 3563 { 3564 phymod_phy_access_t *pm_phy; 3565 phymod_tx_t phymod_tx; 3566 int idx, ln; 3567 int start_lane, num_lane ; 3568 phymod_phy_access_t pm_phy_copy; 3569 int drivermode; 3570 3571 /* loop through all cores */ 3572 for (idx = 0; idx < pmc->num_phys; idx++) { 3573 pm_phy = &pmc->phy[idx]->pm_phy; 3574 3575 if (pm_phy == NULL) { 3576 return SOC_E_INTERNAL; 3577 } 3578 if(PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE_GET(pm_phy)) { 3579 drivermode = 1; 3580 } else { 3581 drivermode = 0; 3582 PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE_SET(pm_phy); 3583 } 3584 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3585 phymod_tx.drivermode = value; 3586 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 3587 3588 if(drivermode == 0) { 3589 PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE_CLR(pm_phy) ; 3590 } 3591 3592 /* handle state */ 3593 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3594 PHYMOD_IF_ERR_RETURN 3595 (phymod_util_lane_config_get(&pm_phy_copy.access, &start_lane, &num_lane)); 3596 3597 for(ln=0; ln<num_lane; ln++) { 3598 pCfg->ln_txparam[4*idx+ln].drivermode = phymod_tx.drivermode ; 3599 } 3600 } 3601 3602 return(SOC_E_NONE); 3603 } 3604 3605 3606 /* 3607 * tsce_per_lane_rx_dfe_tap_control_set 3608 */ 3609 STATIC int 3610 tsce_per_lane_rx_dfe_tap_control_set(soc_phymod_ctrl_t *pmc, int lane, int tap, int enable, uint32 value) 3611 { 3612 soc_phymod_phy_t *p_phy; 3613 uint32 lane_map; 3614 phymod_phy_access_t pm_phy_copy, *pm_phy; 3615 phymod_rx_t phymod_rx; 3616 3617 /* locate the desired phy and lane */ 3618 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 3619 3620 /* Make a copy of the phy access and overwrite the desired lane */ 3621 pm_phy = &p_phy->pm_phy; 3622 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3623 pm_phy_copy.access.lane_mask = lane_map; 3624 3625 if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) { 3626 /* this can only happen with a coding error */ 3627 return SOC_E_INTERNAL; 3628 } 3629 3630 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 3631 phymod_rx.dfe[tap].enable = enable; 3632 phymod_rx.dfe[tap].value = value; 3633 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx)); 3634 3635 return(SOC_E_NONE); 3636 } 3637 3638 3639 /* 3640 * tsce_tx_lane_squelch 3641 */ 3642 STATIC int 3643 tsce_tx_lane_squelch(soc_phymod_ctrl_t *pmc, uint32 value) 3644 { 3645 phymod_phy_access_t *pm_phy; 3646 phymod_phy_tx_lane_control_t tx_control; 3647 int idx; 3648 3649 /* loop through all cores */ 3650 for (idx = 0; idx < pmc->num_phys; idx++) { 3651 pm_phy = &pmc->phy[idx]->pm_phy; 3652 3653 if (pm_phy == NULL) { 3654 return SOC_E_INTERNAL; 3655 } 3656 3657 if (value == 1) { 3658 tx_control = phymodTxSquelchOn; 3659 } else { 3660 tx_control = phymodTxSquelchOff; 3661 } 3662 SOC_IF_ERROR_RETURN 3663 (phymod_phy_tx_lane_control_set(pm_phy, tx_control)); 3664 } 3665 return(SOC_E_NONE); 3666 } 3667 3668 /* tx_lane_squelch get function */ 3669 STATIC int 3670 tsce_tx_lane_squelch_get(soc_phymod_ctrl_t *pmc, uint32 *value) 3671 { 3672 phymod_phy_access_t *pm_phy; 3673 phymod_phy_tx_lane_control_t tx_control; 3674 int idx; 3675 3676 3677 idx = 0; 3678 pm_phy = &pmc->phy[idx]->pm_phy; 3679 3680 if (pm_phy == NULL) { 3681 return SOC_E_INTERNAL; 3682 } 3683 3684 tx_control = phymodTxSquelchOn; 3685 SOC_IF_ERROR_RETURN(phymod_phy_tx_lane_control_get(pm_phy, &tx_control)); 3686 *value = (tx_control == phymodTxSquelchOn)? 1 : 0; 3687 3688 return SOC_E_NONE; 3689 } 3690 3691 /* 3692 * tsce_rx_lane_squelch 3693 */ 3694 STATIC int 3695 tsce_rx_lane_squelch(soc_phymod_ctrl_t *pmc, uint32 value) 3696 { 3697 phymod_phy_access_t *pm_phy; 3698 phymod_phy_rx_lane_control_t rx_control; 3699 int idx; 3700 3701 /* loop through all cores */ 3702 for (idx = 0; idx < pmc->num_phys; idx++) { 3703 pm_phy = &pmc->phy[idx]->pm_phy; 3704 3705 if (pm_phy == NULL) { 3706 return SOC_E_INTERNAL; 3707 } 3708 3709 if (value == 1) { 3710 rx_control = phymodRxSquelchOn; 3711 } else { 3712 rx_control = phymodRxSquelchOff; 3713 } 3714 SOC_IF_ERROR_RETURN 3715 (phymod_phy_rx_lane_control_set(pm_phy, rx_control)); 3716 } 3717 return(SOC_E_NONE); 3718 } 3719 3720 /* rx_lane_squelch get function */ 3721 STATIC int 3722 tsce_rx_lane_squelch_get(soc_phymod_ctrl_t *pmc, uint32 *value) 3723 { 3724 phymod_phy_access_t *pm_phy; 3725 phymod_phy_rx_lane_control_t rx_control; 3726 int idx; 3727 3728 3729 idx = 0; 3730 pm_phy = &pmc->phy[idx]->pm_phy; 3731 3732 if (pm_phy == NULL) { 3733 return SOC_E_INTERNAL; 3734 } 3735 3736 rx_control = phymodTxSquelchOn; 3737 SOC_IF_ERROR_RETURN(phymod_phy_rx_lane_control_get(pm_phy, &rx_control)); 3738 *value = (rx_control == phymodRxSquelchOn)? 1 : 0; 3739 3740 return SOC_E_NONE; 3741 } 3742 3743 /* 3744 * tsce_per_lane_rx_peak_filter_set 3745 */ 3746 STATIC int 3747 tsce_per_lane_rx_peak_filter_set(soc_phymod_ctrl_t *pmc, int lane, int enable, uint32 value) 3748 { 3749 soc_phymod_phy_t *p_phy; 3750 uint32 lane_map; 3751 phymod_phy_access_t pm_phy_copy, *pm_phy; 3752 phymod_rx_t phymod_rx; 3753 3754 /* locate the desired phy and lane */ 3755 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 3756 3757 /* Make a copy of the phy access and overwrite the desired lane */ 3758 pm_phy = &p_phy->pm_phy; 3759 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3760 pm_phy_copy.access.lane_mask = lane_map; 3761 3762 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 3763 phymod_rx.peaking_filter.enable = TRUE; 3764 phymod_rx.peaking_filter.value = value; 3765 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 3766 3767 return(SOC_E_NONE); 3768 } 3769 3770 /* 3771 * tsce_rx_peak_filter_set 3772 */ 3773 STATIC int 3774 tsce_rx_peak_filter_set(soc_phymod_ctrl_t *pmc, uint32 value) 3775 { 3776 phymod_phy_access_t *pm_phy; 3777 phymod_rx_t phymod_rx; 3778 int idx; 3779 3780 /* loop through all cores */ 3781 for (idx = 0; idx < pmc->num_phys; idx++) { 3782 pm_phy = &pmc->phy[idx]->pm_phy; 3783 3784 if (pm_phy == NULL) { 3785 return SOC_E_INTERNAL; 3786 } 3787 3788 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 3789 phymod_rx.peaking_filter.enable = TRUE; 3790 phymod_rx.peaking_filter.value = value; 3791 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 3792 } 3793 3794 return(SOC_E_NONE); 3795 } 3796 3797 /* 3798 * tsce_per_lane_rx_vga_set 3799 */ 3800 STATIC int 3801 tsce_per_lane_rx_vga_set(soc_phymod_ctrl_t *pmc, int lane, int enable, uint32 value) 3802 { 3803 soc_phymod_phy_t *p_phy; 3804 uint32 lane_map; 3805 phymod_phy_access_t pm_phy_copy, *pm_phy; 3806 phymod_rx_t phymod_rx; 3807 3808 /* locate the desired phy and lane */ 3809 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 3810 3811 /* Make a copy of the phy access and overwrite the desired lane */ 3812 pm_phy = &p_phy->pm_phy; 3813 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3814 pm_phy_copy.access.lane_mask = lane_map; 3815 3816 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 3817 phymod_rx.vga.enable = TRUE; 3818 phymod_rx.vga.value = value; 3819 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 3820 3821 return(SOC_E_NONE); 3822 } 3823 3824 /* 3825 * tsce_rx_vga_set 3826 */ 3827 STATIC int 3828 tsce_rx_vga_set(soc_phymod_ctrl_t *pmc, uint32 value) 3829 { 3830 phymod_phy_access_t *pm_phy; 3831 phymod_rx_t phymod_rx; 3832 int idx; 3833 3834 /* loop through all cores */ 3835 for (idx = 0; idx < pmc->num_phys; idx++) { 3836 pm_phy = &pmc->phy[idx]->pm_phy; 3837 3838 if (pm_phy == NULL) { 3839 return SOC_E_INTERNAL; 3840 } 3841 3842 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 3843 phymod_rx.vga.enable = TRUE; 3844 phymod_rx.vga.value = value; 3845 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 3846 } 3847 3848 return(SOC_E_NONE); 3849 } 3850 3851 STATIC int 3852 tsce_rx_tap_release(soc_phymod_ctrl_t *pmc, int tap) 3853 { 3854 phymod_phy_access_t *pm_phy; 3855 phymod_rx_t phymod_rx; 3856 int idx; 3857 3858 /* bounds check "tap" */ 3859 if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) { 3860 return SOC_E_INTERNAL; 3861 } 3862 3863 /* loop through all cores */ 3864 for (idx = 0; idx < pmc->num_phys; idx++) { 3865 pm_phy = &pmc->phy[idx]->pm_phy; 3866 3867 if (pm_phy == NULL) { 3868 return SOC_E_INTERNAL; 3869 } 3870 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 3871 phymod_rx.dfe[tap].enable = FALSE; 3872 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 3873 } 3874 return(SOC_E_NONE); 3875 } 3876 3877 /* 3878 * tsce_rx_tap_set 3879 */ 3880 STATIC int 3881 tsce_rx_tap_set(soc_phymod_ctrl_t *pmc, int tap, uint32 value) 3882 { 3883 phymod_phy_access_t *pm_phy; 3884 phymod_rx_t phymod_rx; 3885 int idx; 3886 3887 /* bounds check "tap" */ 3888 if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) { 3889 return SOC_E_INTERNAL; 3890 } 3891 3892 /* loop through all cores */ 3893 for (idx = 0; idx < pmc->num_phys; idx++) { 3894 pm_phy = &pmc->phy[idx]->pm_phy; 3895 3896 if (pm_phy == NULL) { 3897 return SOC_E_INTERNAL; 3898 } 3899 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 3900 phymod_rx.dfe[tap].enable = TRUE; 3901 phymod_rx.dfe[tap].value = value; 3902 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 3903 } 3904 3905 return(SOC_E_NONE); 3906 } 3907 3908 /* 3909 * tsce_pi_control_set 3910 */ 3911 STATIC int 3912 tsce_pi_control_set(soc_phymod_ctrl_t *pmc, uint32 value) 3913 { 3914 phymod_phy_access_t *pm_phy; 3915 phymod_tx_override_t tx_override; 3916 int idx; 3917 3918 /* loop through all cores */ 3919 for (idx = 0; idx < pmc->num_phys; idx++) { 3920 pm_phy = &pmc->phy[idx]->pm_phy; 3921 3922 if (pm_phy == NULL) { 3923 return SOC_E_INTERNAL; 3924 } 3925 3926 phymod_tx_override_t_init(&tx_override); 3927 tx_override.phase_interpolator.enable = (value == 0) ? 0 : 1; 3928 tx_override.phase_interpolator.value = value; 3929 SOC_IF_ERROR_RETURN(phymod_phy_tx_override_set(pm_phy, &tx_override)); 3930 } 3931 3932 return(SOC_E_NONE); 3933 } 3934 3935 /* 3936 * tsce_tx_polarity_set 3937 */ 3938 STATIC int 3939 tsce_tx_polarity_set(soc_phymod_ctrl_t *pmc, phymod_polarity_t *cfg_polarity, uint32 value) 3940 { 3941 phymod_phy_access_t *pm_phy; 3942 phymod_polarity_t polarity; 3943 int idx; 3944 3945 /* loop through all cores */ 3946 for (idx = 0; idx < pmc->num_phys; idx++) { 3947 pm_phy = &pmc->phy[idx]->pm_phy; 3948 3949 if (pm_phy == NULL) { 3950 return SOC_E_INTERNAL; 3951 } 3952 3953 sal_memcpy(&polarity, cfg_polarity, sizeof(polarity)); 3954 polarity.tx_polarity = value; 3955 SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(pm_phy, &polarity)); 3956 3957 /* after successfully setting the parity, update the configured value */ 3958 cfg_polarity->tx_polarity = value; 3959 } 3960 3961 return(SOC_E_NONE); 3962 } 3963 3964 /* 3965 * tsce_rx_polarity_set 3966 */ 3967 3968 STATIC int 3969 tsce_rx_polarity_set(soc_phymod_ctrl_t *pmc, phymod_polarity_t *cfg_polarity, uint32 value) 3970 { 3971 phymod_phy_access_t *pm_phy; 3972 phymod_polarity_t polarity; 3973 int idx; 3974 3975 /* loop through all cores */ 3976 for (idx = 0; idx < pmc->num_phys; idx++) { 3977 pm_phy = &pmc->phy[idx]->pm_phy; 3978 3979 if (pm_phy == NULL) { 3980 return SOC_E_INTERNAL; 3981 } 3982 3983 sal_memcpy(&polarity, cfg_polarity, sizeof(polarity)); 3984 polarity.rx_polarity = value; 3985 SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(pm_phy, &polarity)); 3986 3987 /* after successfully setting the parity, update the configured value */ 3988 cfg_polarity->rx_polarity = value; 3989 } 3990 3991 return(SOC_E_NONE); 3992 } 3993 3994 /* 3995 * tsce_tx_polarity_get 3996 */ 3997 3998 STATIC int 3999 tsce_tx_polarity_get(soc_phymod_ctrl_t *pmc, phymod_polarity_t *cfg_polarity, uint32 *value) 4000 { 4001 phymod_phy_access_t *pm_phy; 4002 phymod_polarity_t polarity; 4003 int idx; 4004 4005 /* loop through all cores */ 4006 for (idx = 0; idx < pmc->num_phys; idx++) { 4007 pm_phy = &pmc->phy[idx]->pm_phy; 4008 4009 if (pm_phy == NULL) { 4010 return SOC_E_INTERNAL; 4011 } 4012 4013 sal_memcpy(&polarity, cfg_polarity, sizeof(polarity)); 4014 SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(pm_phy, &polarity)); 4015 4016 *value = polarity.tx_polarity ; 4017 cfg_polarity->tx_polarity = *value; 4018 } 4019 4020 return(SOC_E_NONE); 4021 } 4022 4023 /* 4024 * tsce_rx_polarity_get 4025 */ 4026 4027 STATIC int 4028 tsce_rx_polarity_get(soc_phymod_ctrl_t *pmc, phymod_polarity_t *cfg_polarity, uint32 *value) 4029 { 4030 phymod_phy_access_t *pm_phy; 4031 phymod_polarity_t polarity; 4032 int idx; 4033 4034 /* loop through all cores */ 4035 for (idx = 0; idx < pmc->num_phys; idx++) { 4036 pm_phy = &pmc->phy[idx]->pm_phy; 4037 4038 if (pm_phy == NULL) { 4039 return SOC_E_INTERNAL; 4040 } 4041 4042 sal_memcpy(&polarity, cfg_polarity, sizeof(polarity)); 4043 4044 SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(pm_phy, &polarity)); 4045 4046 *value = polarity.rx_polarity ; 4047 cfg_polarity->rx_polarity = *value; 4048 } 4049 4050 return(SOC_E_NONE); 4051 } 4052 4053 4054 4055 /* 4056 * tsce_rx_reset 4057 */ 4058 STATIC int 4059 tsce_rx_reset(soc_phymod_ctrl_t *pmc, phymod_phy_reset_t *cfg_reset, uint32 value) 4060 { 4061 phymod_phy_access_t *pm_phy; 4062 phymod_phy_reset_t reset; 4063 int idx; 4064 4065 /* loop through all cores */ 4066 for (idx = 0; idx < pmc->num_phys; idx++) { 4067 pm_phy = &pmc->phy[idx]->pm_phy; 4068 4069 if (pm_phy == NULL) { 4070 return SOC_E_INTERNAL; 4071 } 4072 4073 sal_memcpy(&reset, cfg_reset, sizeof(reset)); 4074 reset.rx = (phymod_reset_direction_t) value; 4075 SOC_IF_ERROR_RETURN(phymod_phy_reset_set(pm_phy, &reset)); 4076 4077 /* after successfully setting the parity, update the configured value */ 4078 cfg_reset->rx = (phymod_reset_direction_t) value; 4079 } 4080 4081 return(SOC_E_NONE); 4082 } 4083 4084 /* 4085 * tsce_tx_reset 4086 */ 4087 STATIC int 4088 tsce_tx_reset(soc_phymod_ctrl_t *pmc, phymod_phy_reset_t *cfg_reset, uint32 value) 4089 { 4090 phymod_phy_access_t *pm_phy; 4091 phymod_phy_reset_t reset; 4092 int idx; 4093 4094 /* loop through all cores */ 4095 for (idx = 0; idx < pmc->num_phys; idx++) { 4096 pm_phy = &pmc->phy[idx]->pm_phy; 4097 4098 if (pm_phy == NULL) { 4099 return SOC_E_INTERNAL; 4100 } 4101 4102 sal_memcpy(&reset, cfg_reset, sizeof(reset)); 4103 reset.tx = (phymod_reset_direction_t) value; 4104 SOC_IF_ERROR_RETURN(phymod_phy_reset_set(pm_phy, &reset)); 4105 4106 /* after successfully setting the parity, update the configured value */ 4107 cfg_reset->tx = (phymod_reset_direction_t) value; 4108 } 4109 4110 return(SOC_E_NONE); 4111 } 4112 4113 /* 4114 * tsce_cl72_enable_set 4115 */ 4116 STATIC int 4117 tsce_cl72_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 4118 { 4119 phymod_phy_access_t *pm_phy; 4120 int idx; 4121 4122 /* loop through all cores */ 4123 for (idx = 0; idx < pmc->num_phys; idx++) { 4124 pm_phy = &pmc->phy[idx]->pm_phy; 4125 4126 if (pm_phy == NULL) { 4127 return SOC_E_INTERNAL; 4128 } 4129 4130 SOC_IF_ERROR_RETURN(phymod_phy_cl72_set(pm_phy, value)); 4131 } 4132 4133 return(SOC_E_NONE); 4134 } 4135 4136 STATIC int 4137 tsce_lane_map_set(soc_phymod_ctrl_t *pmc, uint32 value){ 4138 int idx; 4139 phymod_lane_map_t lane_map; 4140 4141 lane_map.num_of_lanes = NUM_LANES; 4142 if(pmc->phy[0] == NULL){ 4143 return(SOC_E_INTERNAL); 4144 } 4145 for (idx=0; idx < NUM_LANES; idx++) { 4146 lane_map.lane_map_rx[idx] = (value >> (idx * 4 /* 4 bit per lane */)) & 0xf; 4147 } 4148 for (idx=0; idx < NUM_LANES; idx++) { 4149 lane_map.lane_map_tx[idx] = (value >> (16 + idx * 4 /* 4 bit per lane */)) & 0xf; 4150 } 4151 SOC_IF_ERROR_RETURN(phymod_core_lane_map_set(&pmc->phy[0]->core->pm_core, &lane_map)); 4152 return(SOC_E_NONE); 4153 } 4154 4155 4156 STATIC int 4157 tsce_lane_map_get(soc_phymod_ctrl_t *pmc, uint32 *value){ 4158 int idx; 4159 phymod_lane_map_t lane_map; 4160 4161 *value = 0; 4162 if(pmc->phy[0] == NULL){ 4163 return(SOC_E_INTERNAL); 4164 } 4165 SOC_IF_ERROR_RETURN(phymod_core_lane_map_get(&pmc->phy[0]->core->pm_core, &lane_map)); 4166 if(lane_map.num_of_lanes != NUM_LANES){ 4167 return SOC_E_INTERNAL; 4168 } 4169 for (idx=0; idx < NUM_LANES; idx++) { 4170 *value += (lane_map.lane_map_rx[idx] << (idx * 4)); 4171 } 4172 for (idx=0; idx < NUM_LANES; idx++) { 4173 *value += (lane_map.lane_map_tx[idx]<< (idx * 4 + 16)); 4174 } 4175 4176 return(SOC_E_NONE); 4177 } 4178 4179 /* 4180 * tsce_firmware_mode_set 4181 */ 4182 STATIC int 4183 tsce_firmware_mode_set(soc_phymod_ctrl_t *pmc, uint32 value) 4184 { 4185 phymod_phy_access_t *pm_phy; 4186 phymod_firmware_lane_config_t fw_config; 4187 int idx; 4188 4189 /* loop through all cores */ 4190 for (idx = 0; idx < pmc->num_phys; idx++) { 4191 if (pmc->phy[idx] == NULL) { 4192 return(SOC_E_INTERNAL); 4193 } 4194 4195 pm_phy = &pmc->phy[idx]->pm_phy; 4196 if (pm_phy == NULL) { 4197 return(SOC_E_INTERNAL); 4198 } 4199 4200 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 4201 4202 4203 switch (value) { 4204 case SOC_PHY_FIRMWARE_DEFAULT: 4205 fw_config.LaneConfigFromPCS = 0; 4206 fw_config.DfeOn = 0; 4207 fw_config.ForceBrDfe = 0; 4208 break; 4209 case SOC_PHY_FIRMWARE_FORCE_OSDFE: 4210 fw_config.DfeOn = 1; 4211 fw_config.ForceBrDfe = 0; 4212 break; 4213 case SOC_PHY_FIRMWARE_FORCE_BRDFE: 4214 fw_config.DfeOn = 1; 4215 fw_config.ForceBrDfe = 1; 4216 break; 4217 case SOC_PHY_FIRMWARE_SFP_DAC: 4218 fw_config.MediaType = phymodFirmwareMediaTypeCopperCable; 4219 break; 4220 case SOC_PHY_FIRMWARE_XLAUI: 4221 fw_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 4222 break; 4223 case SOC_PHY_FIRMWARE_SFP_OPT_SR4: 4224 fw_config.MediaType = phymodFirmwareMediaTypeOptics; 4225 break; 4226 default: 4227 fw_config.LaneConfigFromPCS = 0; 4228 break; 4229 } 4230 4231 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(pm_phy, fw_config)); 4232 } 4233 4234 return(SOC_E_NONE); 4235 } 4236 4237 /* 4238 * tsce_firmware_mode_set 4239 */ 4240 STATIC int 4241 tsce_firmware_br_dfe_enable_set(soc_phymod_ctrl_t *pmc, uint32 enable) 4242 { 4243 phymod_phy_access_t *pm_phy; 4244 phymod_firmware_lane_config_t fw_config; 4245 int idx; 4246 4247 /* loop through all cores */ 4248 for (idx = 0; idx < pmc->num_phys; idx++) { 4249 if (pmc->phy[idx] == NULL) { 4250 return(SOC_E_INTERNAL); 4251 } 4252 4253 pm_phy = &pmc->phy[idx]->pm_phy; 4254 if (pm_phy == NULL) { 4255 return(SOC_E_INTERNAL); 4256 } 4257 4258 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 4259 4260 if (enable) { 4261 fw_config.DfeOn = 1; 4262 fw_config.ForceBrDfe = 1; 4263 } else { 4264 fw_config.ForceBrDfe = 0; 4265 } 4266 4267 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(pm_phy, fw_config)); 4268 } 4269 4270 return(SOC_E_NONE); 4271 } 4272 4273 /* 4274 * tscefirmware_mode_set 4275 */ 4276 STATIC int 4277 tsce_firmware_dfe_enable_set(soc_phymod_ctrl_t *pmc, uint32 enable) 4278 { 4279 phymod_phy_access_t *pm_phy; 4280 phymod_firmware_lane_config_t fw_config; 4281 int idx; 4282 4283 /* loop through all cores */ 4284 for (idx = 0; idx < pmc->num_phys; idx++) { 4285 if (pmc->phy[idx] == NULL) { 4286 return(SOC_E_INTERNAL); 4287 } 4288 4289 pm_phy = &pmc->phy[idx]->pm_phy; 4290 if (pm_phy == NULL) { 4291 return(SOC_E_INTERNAL); 4292 } 4293 4294 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 4295 4296 if (enable) { 4297 fw_config.DfeOn = 1; 4298 } else { 4299 fw_config.DfeOn = 0; 4300 } 4301 4302 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(pm_phy, fw_config)); 4303 } 4304 4305 return(SOC_E_NONE); 4306 } 4307 4308 /* 4309 * tscefirmware_mode_set 4310 */ 4311 STATIC int 4312 tsce_firmware_cl72_restart_timeout_enable_set(soc_phymod_ctrl_t *pmc, uint32 enable) 4313 { 4314 phymod_phy_access_t *pm_phy; 4315 phymod_firmware_lane_config_t fw_config; 4316 int idx; 4317 4318 /* loop through all cores */ 4319 for (idx = 0; idx < pmc->num_phys; idx++) { 4320 if (pmc->phy[idx] == NULL) { 4321 return(SOC_E_INTERNAL); 4322 } 4323 4324 pm_phy = &pmc->phy[idx]->pm_phy; 4325 if (pm_phy == NULL) { 4326 return(SOC_E_INTERNAL); 4327 } 4328 4329 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 4330 4331 if (enable) { 4332 fw_config.Cl72RestTO = 1; 4333 } else { 4334 fw_config.Cl72RestTO = 0; 4335 } 4336 4337 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(pm_phy, fw_config)); 4338 } 4339 4340 return(SOC_E_NONE); 4341 } 4342 4343 /* 4344 * tscefirmware_mode_set 4345 */ 4346 STATIC int 4347 tsce_firmware_cl72_auto_polarity_enable_set(soc_phymod_ctrl_t *pmc, uint32 enable) 4348 { 4349 phymod_phy_access_t *pm_phy; 4350 phymod_firmware_lane_config_t fw_config; 4351 int idx; 4352 4353 /* loop through all cores */ 4354 for (idx = 0; idx < pmc->num_phys; idx++) { 4355 if (pmc->phy[idx] == NULL) { 4356 return(SOC_E_INTERNAL); 4357 } 4358 4359 pm_phy = &pmc->phy[idx]->pm_phy; 4360 if (pm_phy == NULL) { 4361 return(SOC_E_INTERNAL); 4362 } 4363 4364 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 4365 4366 if (enable) { 4367 fw_config.Cl72AutoPolEn = 1; 4368 } else { 4369 fw_config.Cl72AutoPolEn = 0; 4370 } 4371 4372 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(pm_phy, fw_config)); 4373 } 4374 4375 return(SOC_E_NONE); 4376 } 4377 4378 4379 4380 4381 STATIC int 4382 tsce_pattern_len_set(soc_phymod_ctrl_t *pmc, tsce_pattern_t *pattern, uint32_t value) 4383 { 4384 phymod_phy_access_t *pm_phy; 4385 phymod_pattern_t phymod_pattern; 4386 int idx; 4387 4388 /* loop through all cores */ 4389 for (idx = 0; idx < pmc->num_phys; idx++) { 4390 pm_phy = &pmc->phy[idx]->pm_phy; 4391 4392 if (pm_phy == NULL) { 4393 return SOC_E_INTERNAL; 4394 } 4395 4396 phymod_pattern_t_init(&phymod_pattern); 4397 phymod_pattern.pattern = pattern->pattern_data; 4398 /* SOC_IF_ERROR_RETURN */ 4399 /* (phymod_phy_pattern_config_get(pm_phy, &phymod_pattern));*/ 4400 phymod_pattern.pattern_len = value; 4401 SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_set(pm_phy, &phymod_pattern)); 4402 } 4403 return(SOC_E_NONE); 4404 } 4405 4406 STATIC int 4407 tsce_pattern_enable_set(soc_phymod_ctrl_t *pmc, uint32_t value) 4408 { 4409 phymod_phy_access_t *pm_phy; 4410 phymod_pattern_t phymod_pattern; 4411 int idx; 4412 uint32_t pattern_arr[PATTERN_MAX_SIZE]; 4413 4414 4415 /* loop through all cores */ 4416 for (idx = 0; idx < pmc->num_phys; idx++) { 4417 pm_phy = &pmc->phy[idx]->pm_phy; 4418 4419 if (pm_phy == NULL) { 4420 return SOC_E_INTERNAL; 4421 } 4422 4423 phymod_pattern.pattern = pattern_arr; 4424 4425 SOC_IF_ERROR_RETURN 4426 (phymod_phy_pattern_config_get(pm_phy, &phymod_pattern)); 4427 SOC_IF_ERROR_RETURN(phymod_phy_pattern_enable_set(pm_phy, value, &phymod_pattern)); 4428 } 4429 return(SOC_E_NONE); 4430 } 4431 4432 /* 4433 * tsce_pattern_data_set 4434 * Sets 32 bits of the 256 bit data pattern. 4435 */ 4436 STATIC int 4437 tsce_pattern_data_set(int idx, tsce_pattern_t *pattern, uint32 value) 4438 { 4439 if ((idx<0) || (idx >= COUNTOF(pattern->pattern_data))) { 4440 return SOC_E_INTERNAL; 4441 } 4442 4443 /* update pattern data */ 4444 pattern->pattern_data[idx] = value; 4445 4446 return(SOC_E_NONE); 4447 } 4448 4449 /* 4450 * tsce_per_lane_prbs_poly_set 4451 */ 4452 STATIC int 4453 tsce_per_lane_prbs_poly_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 4454 { 4455 return(SOC_E_UNAVAIL); 4456 } 4457 4458 4459 STATIC 4460 int 4461 tsce_sdk_poly_to_phymod_poly(uint32 sdk_poly, phymod_prbs_poly_t *phymod_poly){ 4462 switch(sdk_poly){ 4463 case SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1: 4464 *phymod_poly = phymodPrbsPoly7; 4465 break; 4466 case SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1: 4467 *phymod_poly = phymodPrbsPoly15; 4468 break; 4469 case SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1: 4470 *phymod_poly = phymodPrbsPoly23; 4471 break; 4472 case SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1: 4473 *phymod_poly = phymodPrbsPoly31; 4474 break; 4475 case SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1: 4476 *phymod_poly = phymodPrbsPoly9; 4477 break; 4478 case SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1: 4479 *phymod_poly = phymodPrbsPoly11; 4480 break; 4481 case SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1: 4482 *phymod_poly = phymodPrbsPoly58; 4483 break; 4484 default: 4485 return SOC_E_INTERNAL; 4486 } 4487 return SOC_E_NONE; 4488 } 4489 4490 /* 4491 * tsce_prbs_tx_poly_set 4492 */ 4493 STATIC int 4494 tsce_prbs_tx_poly_set(soc_phymod_ctrl_t *pmc, uint32 value) 4495 { 4496 phymod_phy_access_t *pm_phy; 4497 phymod_prbs_t prbs; 4498 uint32_t flags = 0; 4499 int idx; 4500 4501 for (idx = 0; idx < pmc->num_phys; idx++) { 4502 if (pmc->phy[idx] == NULL) { 4503 return SOC_E_INTERNAL; 4504 } 4505 pm_phy = &pmc->phy[idx]->pm_phy; 4506 if (pm_phy == NULL) { 4507 return SOC_E_INTERNAL; 4508 } 4509 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 4510 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 4511 SOC_IF_ERROR_RETURN(tsce_sdk_poly_to_phymod_poly(value, &prbs.poly)); 4512 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs)); 4513 } 4514 return(SOC_E_NONE); 4515 } 4516 4517 /* 4518 * tsce_prbs_rx_poly_set 4519 */ 4520 STATIC int 4521 tsce_prbs_rx_poly_set(soc_phymod_ctrl_t *pmc, uint32 value) 4522 { 4523 phymod_phy_access_t *pm_phy; 4524 phymod_prbs_t prbs; 4525 uint32_t flags = 0; 4526 int idx; 4527 4528 for (idx = 0; idx < pmc->num_phys; idx++) { 4529 if (pmc->phy[idx] == NULL) { 4530 return SOC_E_INTERNAL; 4531 } 4532 pm_phy = &pmc->phy[idx]->pm_phy; 4533 if (pm_phy == NULL) { 4534 return SOC_E_INTERNAL; 4535 } 4536 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 4537 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 4538 SOC_IF_ERROR_RETURN(tsce_sdk_poly_to_phymod_poly(value, &prbs.poly)); 4539 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs)); 4540 } 4541 return(SOC_E_NONE); 4542 } 4543 4544 4545 /* 4546 * tsce_per_lane_prbs_tx_invert_data_set 4547 */ 4548 STATIC int 4549 tsce_per_lane_prbs_tx_invert_data_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 4550 { 4551 return(SOC_E_UNAVAIL); 4552 } 4553 4554 /* 4555 * tsce_prbs_tx_invert_data_set 4556 */ 4557 STATIC int 4558 tsce_prbs_tx_invert_data_set(soc_phymod_ctrl_t *pmc, uint32 value) 4559 { 4560 phymod_phy_access_t *pm_phy; 4561 phymod_prbs_t prbs; 4562 uint32_t flags = 0; 4563 int idx; 4564 4565 for (idx = 0; idx < pmc->num_phys; idx++) { 4566 if (pmc->phy[idx] == NULL) { 4567 return SOC_E_INTERNAL; 4568 } 4569 pm_phy = &pmc->phy[idx]->pm_phy; 4570 if (pm_phy == NULL) { 4571 return SOC_E_INTERNAL; 4572 } 4573 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 4574 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 4575 prbs.invert = value; 4576 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs)); 4577 } 4578 return(SOC_E_NONE); 4579 } 4580 4581 /* 4582 * tsce_prbs_rx_invert_data_set 4583 */ 4584 STATIC int 4585 tsce_prbs_rx_invert_data_set(soc_phymod_ctrl_t *pmc, uint32 value) 4586 { 4587 phymod_phy_access_t *pm_phy; 4588 phymod_prbs_t prbs; 4589 uint32_t flags = 0; 4590 int idx; 4591 4592 for (idx = 0; idx < pmc->num_phys; idx++) { 4593 if (pmc->phy[idx] == NULL) { 4594 return SOC_E_INTERNAL; 4595 } 4596 pm_phy = &pmc->phy[idx]->pm_phy; 4597 if (pm_phy == NULL) { 4598 return SOC_E_INTERNAL; 4599 } 4600 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 4601 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 4602 prbs.invert = value; 4603 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs)); 4604 } 4605 return(SOC_E_NONE); 4606 } 4607 4608 /* 4609 * tsce_per_lane_prbs_tx_enable_set 4610 */ 4611 STATIC int 4612 tsce_per_lane_prbs_tx_enable_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 4613 { 4614 return(SOC_E_UNAVAIL); 4615 } 4616 /* 4617 * tsce_prbs_tx_enable_set 4618 */ 4619 STATIC int 4620 tsce_prbs_tx_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 4621 { 4622 phymod_phy_access_t *pm_phy; 4623 uint32_t flags = 0; 4624 int idx; 4625 4626 for (idx = 0; idx < pmc->num_phys; idx++) { 4627 if (pmc->phy[idx] == NULL) { 4628 return SOC_E_INTERNAL; 4629 } 4630 pm_phy = &pmc->phy[idx]->pm_phy; 4631 if (pm_phy == NULL) { 4632 return SOC_E_INTERNAL; 4633 } 4634 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 4635 SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(pm_phy, flags, value)); 4636 } 4637 return(SOC_E_NONE); 4638 } 4639 4640 /* 4641 * tsce_prbs_rx_enable_set 4642 */ 4643 STATIC int 4644 tsce_prbs_rx_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 4645 { 4646 phymod_phy_access_t *pm_phy; 4647 uint32_t flags = 0; 4648 int idx; 4649 4650 for (idx = 0; idx < pmc->num_phys; idx++) { 4651 if (pmc->phy[idx] == NULL) { 4652 return SOC_E_INTERNAL; 4653 } 4654 pm_phy = &pmc->phy[idx]->pm_phy; 4655 if (pm_phy == NULL) { 4656 return SOC_E_INTERNAL; 4657 } 4658 4659 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 4660 SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(pm_phy, flags, value)); 4661 } 4662 return(SOC_E_NONE); 4663 } 4664 4665 /* 4666 * tsce_loopback_internal_set 4667 */ 4668 STATIC int 4669 tsce_loopback_internal_set(soc_phymod_ctrl_t *pmc, uint32 value) 4670 { 4671 phymod_phy_access_t *pm_phy; 4672 int idx; 4673 4674 for (idx = 0; idx < pmc->num_phys; idx++) { 4675 if (pmc->phy[idx] == NULL) { 4676 return SOC_E_INTERNAL; 4677 } 4678 pm_phy = &pmc->phy[idx]->pm_phy; 4679 if (pm_phy == NULL) { 4680 return SOC_E_INTERNAL; 4681 } 4682 4683 SOC_IF_ERROR_RETURN 4684 (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobal, value)); 4685 } 4686 return(SOC_E_NONE); 4687 } 4688 4689 /* 4690 * tsce_loopback_internal_pmd_set 4691 */ 4692 STATIC int 4693 tsce_loopback_internal_pmd_set(soc_phymod_ctrl_t *pmc, uint32 value) 4694 { 4695 phymod_phy_access_t *pm_phy; 4696 int idx; 4697 4698 for (idx = 0; idx < pmc->num_phys; idx++) { 4699 if (pmc->phy[idx] == NULL) { 4700 return SOC_E_INTERNAL; 4701 } 4702 pm_phy = &pmc->phy[idx]->pm_phy; 4703 if (pm_phy == NULL) { 4704 return SOC_E_INTERNAL; 4705 } 4706 4707 SOC_IF_ERROR_RETURN 4708 (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobalPMD, value)); 4709 } 4710 return(SOC_E_NONE); 4711 } 4712 4713 /* 4714 * tsce_loopback_remote_set 4715 */ 4716 STATIC int 4717 tsce_loopback_remote_set(soc_phymod_ctrl_t *pmc, uint32 value) 4718 { 4719 phymod_phy_access_t *pm_phy; 4720 int idx; 4721 4722 for (idx = 0; idx < pmc->num_phys; idx++) { 4723 if (pmc->phy[idx] == NULL) { 4724 return SOC_E_INTERNAL; 4725 } 4726 pm_phy = &pmc->phy[idx]->pm_phy; 4727 if (pm_phy == NULL) { 4728 return SOC_E_INTERNAL; 4729 } 4730 4731 SOC_IF_ERROR_RETURN 4732 (phymod_phy_loopback_set(pm_phy, phymodLoopbackRemotePMD, value)); 4733 } 4734 return(SOC_E_NONE); 4735 } 4736 4737 #if 0 4738 /* 4739 * tsce_loopback_remote_pcs_set 4740 */ 4741 STATIC int 4742 tsce_loopback_remote_pcs_set(soc_phymod_ctrl_t *pmc, uint32 value) 4743 { 4744 phymod_phy_access_t *pm_phy; 4745 int idx; 4746 4747 for (idx = 0; idx < pmc->num_phys; idx++) { 4748 if (pmc->phy[idx] == NULL) { 4749 return SOC_E_INTERNAL; 4750 } 4751 pm_phy = &pmc->phy[idx]->pm_phy; 4752 if (pm_phy == NULL) { 4753 return SOC_E_INTERNAL; 4754 } 4755 4756 SOC_IF_ERROR_RETURN 4757 (phymod_phy_loopback_set(pm_phy, phymodLoopbackRemotePCS, value)); 4758 } 4759 return(SOC_E_NONE); 4760 } 4761 #endif 4762 4763 /* 4764 * tsce_fec_enable_set 4765 */ 4766 STATIC int 4767 tsce_fec_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 4768 { 4769 phymod_phy_access_t *pm_phy; 4770 int idx; 4771 4772 /* loop through all cores */ 4773 for (idx = 0; idx < pmc->num_phys; idx++) { 4774 pm_phy = &pmc->phy[idx]->pm_phy; 4775 4776 if (pm_phy == NULL) { 4777 return SOC_E_INTERNAL; 4778 } 4779 SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_set(pm_phy, value)); 4780 } 4781 return(SOC_E_NONE); 4782 } 4783 4784 /* 4785 * tsce_scrambler_set 4786 */ 4787 STATIC int 4788 tsce_scrambler_set(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 value) 4789 { 4790 phymod_phy_access_t *pm_phy; 4791 phymod_phy_inf_config_t config; 4792 int idx; 4793 phy_ctrl_t *pc; 4794 tsce_config_t *pCfg; 4795 phymod_ref_clk_t ref_clock; 4796 4797 /* locate phy control */ 4798 pc = INT_PHY_SW_STATE(pmc->unit, port); 4799 if (pc == NULL) { 4800 return SOC_E_INTERNAL; 4801 } 4802 pCfg = (tsce_config_t *) pc->driver_data; 4803 4804 SOC_IF_ERROR_RETURN( 4805 tsce_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clock)); 4806 4807 /* loop through all cores */ 4808 for (idx = 0; idx < pmc->num_phys; idx++) { 4809 pm_phy = &pmc->phy[idx]->pm_phy; 4810 4811 if (pm_phy == NULL) { 4812 return SOC_E_INTERNAL; 4813 } 4814 4815 SOC_IF_ERROR_RETURN(phymod_phy_interface_config_get(pm_phy, 0 /* flags */, ref_clock, &config)); 4816 PHYMOD_INTF_MODES_SCR_SET(&config); 4817 SOC_IF_ERROR_RETURN(phymod_phy_interface_config_set(pm_phy, PHYMOD_INTF_F_DONT_OVERIDE_TX_PARAMS, &config)); 4818 } 4819 4820 return(SOC_E_NONE); 4821 } 4822 4823 /* 4824 * tsce_8b10b_set 4825 */ 4826 STATIC int 4827 tsce_8b10b_set(soc_phymod_ctrl_t *pmc, uint32 value) 4828 { 4829 return(SOC_E_UNAVAIL); 4830 } 4831 4832 /* 4833 * tsce_64b65b_set 4834 */ 4835 STATIC int 4836 tsce_64b65b_set(soc_phymod_ctrl_t *pmc, uint32 value) 4837 { 4838 4839 return(SOC_E_UNAVAIL); 4840 } 4841 4842 /* 4843 * tsce_power_set 4844 */ 4845 STATIC int 4846 tsce_power_set(soc_phymod_ctrl_t *pmc, uint32 value) 4847 { 4848 phymod_phy_access_t *pm_phy; 4849 phymod_phy_power_t power; 4850 int idx; 4851 4852 /* loop through all cores */ 4853 for (idx = 0; idx < pmc->num_phys; idx++) { 4854 pm_phy = &pmc->phy[idx]->pm_phy; 4855 4856 if (pm_phy == NULL) { 4857 return SOC_E_INTERNAL; 4858 } 4859 4860 phymod_phy_power_t_init(&power); 4861 if (value) { 4862 power.tx = phymodPowerOn; 4863 power.rx = phymodPowerOn; 4864 } 4865 else { 4866 power.tx = phymodPowerOff; 4867 power.rx = phymodPowerOff; 4868 } 4869 4870 SOC_IF_ERROR_RETURN(phymod_phy_power_set(pm_phy, &power)); 4871 } 4872 4873 return(SOC_E_NONE); 4874 } 4875 4876 /* 4877 * tsce_per_lane_rx_low_freq_filter_set 4878 */ 4879 STATIC int 4880 tsce_per_lane_rx_low_freq_filter_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 4881 { 4882 return(SOC_E_UNAVAIL); 4883 } 4884 4885 /* 4886 * tsce_rx_low_freq_filter_set 4887 */ 4888 STATIC int 4889 tsce_rx_low_freq_filter_set(soc_phymod_ctrl_t *pmc, uint32 value) 4890 { 4891 phymod_phy_access_t *pm_phy; 4892 phymod_rx_t phymod_rx; 4893 int idx; 4894 4895 /* loop through all cores */ 4896 for (idx = 0; idx < pmc->num_phys; idx++) { 4897 pm_phy = &pmc->phy[idx]->pm_phy; 4898 4899 if (pm_phy == NULL) { 4900 return SOC_E_INTERNAL; 4901 } 4902 4903 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 4904 4905 phymod_rx.low_freq_peaking_filter.enable = TRUE; 4906 phymod_rx.low_freq_peaking_filter.value = value; 4907 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 4908 } 4909 4910 return(SOC_E_NONE); 4911 } 4912 4913 /* 4914 * tsce_tx_ppm_adjust_set 4915 */ 4916 STATIC int 4917 tsce_tx_ppm_adjust_set(soc_phymod_ctrl_t *pmc, uint32 value) 4918 { 4919 phymod_phy_access_t *pm_phy; 4920 phymod_tx_override_t tx_override; 4921 int idx; 4922 4923 /* loop through all cores */ 4924 for (idx = 0; idx < pmc->num_phys; idx++) { 4925 pm_phy = &pmc->phy[idx]->pm_phy; 4926 4927 if (pm_phy == NULL) { 4928 return SOC_E_INTERNAL; 4929 } 4930 4931 tx_override.phase_interpolator.enable = 1; 4932 tx_override.phase_interpolator.value = value; 4933 SOC_IF_ERROR_RETURN(phymod_phy_tx_override_set(pm_phy, &tx_override)); 4934 } 4935 return(SOC_E_NONE); 4936 } 4937 4938 /* 4939 * tsce_vco_freq_set 4940 */ 4941 STATIC int 4942 tsce_vco_freq_set(soc_phymod_ctrl_t *pmc, uint32 value) 4943 { 4944 /* 4945 The following 3 controls are used to override pre-defined speed in the phy. 4946 What we discussed in SJ is that in case of rate which is not officially supported the driver will try to 4947 understand this parameters by itself. 4948 Questions: 4949 1. Do we want to support direct configuration of PLL\OS? 4950 2. If yes - same API or new API 4951 4952 phymod_phy_interface_config_set (?) 4953 */ 4954 4955 return(SOC_E_UNAVAIL); 4956 } 4957 4958 /* 4959 * tsce_pll_divider_set 4960 */ 4961 STATIC int 4962 tsce_pll_divider_set(soc_phymod_ctrl_t *pmc, uint32 value) 4963 { 4964 return(SOC_E_UNAVAIL); 4965 } 4966 4967 /* 4968 * tsce_oversample_mode_set 4969 */ 4970 STATIC int 4971 tsce_oversample_mode_set(soc_phymod_ctrl_t *pmc, uint32 value) 4972 { 4973 return(SOC_E_UNAVAIL); 4974 } 4975 4976 /* 4977 * tsce_ref_clk_set 4978 */ 4979 STATIC int 4980 tsce_ref_clk_set(soc_phymod_ctrl_t *pmc, uint32 value) 4981 { 4982 return(SOC_E_UNAVAIL); 4983 } 4984 4985 /* 4986 * tsce_rx_seq_toggle_set 4987 */ 4988 STATIC int 4989 tsce_rx_seq_toggle_set(soc_phymod_ctrl_t *pmc) 4990 { 4991 phymod_phy_access_t *pm_phy; 4992 int idx; 4993 4994 /* loop through all cores */ 4995 for (idx = 0; idx < pmc->num_phys; idx++) { 4996 if (pmc->phy[idx] == NULL) { 4997 return(SOC_E_INTERNAL); 4998 } 4999 5000 pm_phy = &pmc->phy[idx]->pm_phy; 5001 if (pm_phy == NULL) { 5002 return(SOC_E_INTERNAL); 5003 } 5004 SOC_IF_ERROR_RETURN(phymod_phy_rx_restart(pm_phy)); 5005 } 5006 5007 return(SOC_E_NONE); 5008 } 5009 5010 /* 5011 * tsce_eee_set 5012 */ 5013 STATIC int 5014 tsce_eee_set(soc_phymod_ctrl_t *pmc, uint32 value) 5015 { 5016 phymod_phy_access_t *pm_phy; 5017 int idx; 5018 5019 /* loop through all cores */ 5020 for (idx = 0; idx < pmc->num_phys; idx++) { 5021 if (pmc->phy[idx] == NULL) { 5022 return(SOC_E_INTERNAL); 5023 } 5024 5025 pm_phy = &pmc->phy[idx]->pm_phy; 5026 if (pm_phy == NULL) { 5027 return(SOC_E_INTERNAL); 5028 } 5029 SOC_IF_ERROR_RETURN(phymod_phy_eee_set(pm_phy, value)); 5030 } 5031 5032 return(SOC_E_NONE); 5033 } 5034 5035 /* 5036 * tsce_hg2_codec_enable_set 5037 */ 5038 STATIC int 5039 tsce_hg2_codec_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 5040 { 5041 phymod_phy_access_t *pm_phy; 5042 int idx; 5043 phymod_phy_hg2_codec_t local_copy; 5044 5045 5046 /* loop through all cores */ 5047 for (idx = 0; idx < pmc->num_phys; idx++) { 5048 if (pmc->phy[idx] == NULL) { 5049 return(SOC_E_INTERNAL); 5050 } 5051 5052 pm_phy = &pmc->phy[idx]->pm_phy; 5053 if (pm_phy == NULL) { 5054 return(SOC_E_INTERNAL); 5055 } 5056 switch (value) { 5057 case SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE_OFF: 5058 local_copy = phymodBcmHG2CodecOff; 5059 break; 5060 case SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE_ON_WITH_8BYTE_IPG: 5061 local_copy = phymodBcmHG2CodecOnWith8ByteIPG; 5062 break; 5063 case SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE_ON_WITH_9BYTE_IPG: 5064 local_copy = phymodBcmHG2CodecOnWith9ByteIPG; 5065 break; 5066 default: 5067 local_copy = phymodBcmHG2CodecOff; 5068 break; 5069 } 5070 SOC_IF_ERROR_RETURN(phymod_phy_hg2_codec_control_set(pm_phy, local_copy)); 5071 } 5072 5073 return(SOC_E_NONE); 5074 } 5075 5076 /* 5077 * tsce_driver_supply_set 5078 */ 5079 STATIC int 5080 tsce_driver_supply_set(soc_phymod_ctrl_t *pmc, uint32 value) 5081 { 5082 return(SOC_E_UNAVAIL); 5083 } 5084 5085 5086 STATIC int 5087 tsce_user_speed_set(soc_phymod_ctrl_t *pmc, 5088 temod_device_aux_modes_t *device, 5089 phymod_pcs_userspeed_mode_t mode, 5090 phymod_pcs_userspeed_param_t param, 5091 uint32 value) 5092 { 5093 phymod_phy_access_t *pm_phy; 5094 soc_phymod_phy_t *p_phy; 5095 phymod_pcs_userspeed_config_t config ; 5096 int idx; 5097 uint32 lane_map; 5098 5099 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, 0, &p_phy, &lane_map)); 5100 config.mode = mode ; 5101 config.param = param ; 5102 config.current_entry = (lane_map&0x1)? 0:((lane_map&0x2)? 1:((lane_map&0x4)? 2: ((lane_map&0x8)? 3:0))); 5103 config.value = value ; 5104 5105 if(mode==phymodPcsUserSpeedModeST) { 5106 if(device !=NULL) { 5107 config.current_entry = device->st_current_entry ; 5108 } 5109 } 5110 if(device!=NULL) { 5111 switch(param) { 5112 case phymodPcsUserSpeedParamEntry: 5113 if(mode==phymodPcsUserSpeedModeST && value<4 ) { 5114 device->st_current_entry = value ; 5115 } 5116 return (SOC_E_NONE); 5117 break ; 5118 case phymodPcsUserSpeedParamHCD: 5119 if(mode==phymodPcsUserSpeedModeST) { 5120 device->st_hcd[device->st_current_entry] = value ; 5121 } 5122 /* need to program HW */ 5123 break ; 5124 case phymodPcsUserSpeedParamClear: 5125 if(mode==phymodPcsUserSpeedModeST) { 5126 device->st_hcd[device->st_current_entry] = 0xff ; 5127 } else { 5128 device->hto_enable[config.current_entry] = 0 ; 5129 } 5130 /* need to program HW */ 5131 break ; 5132 case phymodPcsUserSpeedParamPllDiv: 5133 if(mode==phymodPcsUserSpeedModeHTO) { 5134 device->hto_enable[config.current_entry] =1 ; 5135 device->hto_pll_div[config.current_entry] =value ; 5136 } else { 5137 device->st_pll_div[config.current_entry] =value ; 5138 } 5139 return (SOC_E_NONE); 5140 break ; 5141 case phymodPcsUserSpeedParamPmaOS: 5142 if(mode==phymodPcsUserSpeedModeHTO) { 5143 device->hto_enable[config.current_entry] =1 ; 5144 device->hto_os[config.current_entry] =value ; 5145 } else { 5146 device->st_os[config.current_entry] =value ; 5147 } 5148 return (SOC_E_NONE); 5149 break ; 5150 default: 5151 break ; 5152 } 5153 } 5154 /* loop through all cores */ 5155 for (idx = 0; idx < pmc->num_phys; idx++) { 5156 if (pmc->phy[idx] == NULL) { 5157 return(SOC_E_INTERNAL); 5158 } 5159 5160 pm_phy = &pmc->phy[idx]->pm_phy; 5161 if (pm_phy == NULL) { 5162 return(SOC_E_INTERNAL); 5163 } 5164 5165 if(mode==phymodPcsUserSpeedModeST) { 5166 if(device !=NULL) { 5167 config.current_entry = device->st_current_entry ; 5168 } 5169 } 5170 SOC_IF_ERROR_RETURN(phymod_phy_pcs_userspeed_set(pm_phy, &config)); 5171 } 5172 5173 return(SOC_E_NONE); 5174 } 5175 5176 STATIC int 5177 tsce_user_speed_get(soc_phymod_ctrl_t *pmc, 5178 temod_device_aux_modes_t *device, 5179 phymod_pcs_userspeed_mode_t mode, 5180 phymod_pcs_userspeed_param_t param, 5181 uint32 *value) 5182 { 5183 phymod_phy_access_t *pm_phy; 5184 soc_phymod_phy_t *p_phy; 5185 phymod_pcs_userspeed_config_t config ; 5186 int idx; 5187 uint32 lane_map; 5188 5189 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, 0, &p_phy, &lane_map)); 5190 config.mode = mode ; 5191 config.param = param ; 5192 config.current_entry = (lane_map&0x1)? 0:((lane_map&0x2)? 1:((lane_map&0x4)? 2: ((lane_map&0x8)? 3:0))); 5193 config.value = 0 ; 5194 5195 if(mode==phymodPcsUserSpeedModeST) { 5196 if(device !=NULL) { 5197 config.current_entry = device->st_current_entry ; 5198 } 5199 } 5200 5201 *value = 0 ; 5202 /* current device_aux_modes is per logic port even for multi-core port */ 5203 if(device!=NULL) { 5204 switch(param) { 5205 case phymodPcsUserSpeedParamEntry: 5206 if(mode==phymodPcsUserSpeedModeST) { 5207 * value = device->st_current_entry; 5208 } 5209 return (SOC_E_NONE); 5210 break ; 5211 case phymodPcsUserSpeedParamHCD: 5212 if(mode==phymodPcsUserSpeedModeST) { 5213 *value = device->st_hcd[device->st_current_entry] ; 5214 } 5215 /* need to double check with HW */ 5216 break ; 5217 case phymodPcsUserSpeedParamClear: 5218 if(mode==phymodPcsUserSpeedModeHTO) { 5219 *value = device->hto_enable[config.current_entry] ; 5220 } 5221 /* do we need to double check with HW ? */ 5222 return (SOC_E_NONE); 5223 break ; 5224 case phymodPcsUserSpeedParamPllDiv: 5225 if(mode==phymodPcsUserSpeedModeHTO) { 5226 if(device->hto_enable[config.current_entry]) { 5227 *value = device->hto_pll_div[config.current_entry] ; 5228 } 5229 } else { 5230 *value = device->st_pll_div[config.current_entry] ; 5231 } 5232 /* do we need to double check with HW ? */ 5233 return (SOC_E_NONE); 5234 break ; 5235 case phymodPcsUserSpeedParamPmaOS: 5236 if(mode==phymodPcsUserSpeedModeHTO) { 5237 if(device->hto_enable[config.current_entry] ==1){ 5238 *value = device->hto_os[config.current_entry] ; 5239 } 5240 } else { 5241 *value = device->st_os[config.current_entry] ; 5242 } 5243 /* do we need to double check with HW ? */ 5244 return (SOC_E_NONE); 5245 break ; 5246 default: 5247 break ; 5248 } 5249 } 5250 /* loop through all cores */ 5251 for (idx = 0; idx < pmc->num_phys; idx++) { 5252 if (pmc->phy[idx] == NULL) { 5253 return(SOC_E_INTERNAL); 5254 } 5255 5256 pm_phy = &pmc->phy[idx]->pm_phy; 5257 if (pm_phy == NULL) { 5258 return(SOC_E_INTERNAL); 5259 } 5260 5261 SOC_IF_ERROR_RETURN(phymod_phy_pcs_userspeed_get(pm_phy, &config)); 5262 *value = config.value ; 5263 } 5264 5265 return(SOC_E_NONE); 5266 } 5267 5268 5269 STATIC int 5270 tsce_unreliable_los_set(soc_phymod_ctrl_t *pmc, uint32 value) 5271 { 5272 phymod_phy_access_t *pm_phy; 5273 int idx; 5274 phymod_firmware_lane_config_t config ; 5275 /* loop through all cores */ 5276 for (idx = 0; idx < pmc->num_phys; idx++) { 5277 pm_phy = &pmc->phy[idx]->pm_phy; 5278 5279 if (pm_phy == NULL) { 5280 return SOC_E_INTERNAL; 5281 } 5282 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &config)) ; 5283 config.UnreliableLos = value ; 5284 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(pm_phy, config)) ; 5285 } 5286 return(SOC_E_NONE); 5287 } 5288 5289 STATIC int 5290 tsce_unreliable_los_get(soc_phymod_ctrl_t *pmc, uint32 *value) 5291 { 5292 phymod_phy_access_t *pm_phy; 5293 phymod_firmware_lane_config_t config ; 5294 pm_phy = &pmc->phy[0]->pm_phy; 5295 5296 if (pm_phy == NULL) { 5297 return SOC_E_INTERNAL; 5298 } 5299 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &config)) ; 5300 *value = config.UnreliableLos ; 5301 5302 return(SOC_E_NONE); 5303 } 5304 5305 STATIC int 5306 tsce_bond_in_pwrdn_override(soc_phymod_ctrl_t *pmc, uint32 enable) 5307 { 5308 phymod_phy_access_t *pm_phy; 5309 int idx; 5310 /* loop through all cores */ 5311 for (idx = 0; idx < pmc->num_phys; idx++) { 5312 pm_phy = &pmc->phy[idx]->pm_phy; 5313 5314 if (pm_phy == NULL) { 5315 return SOC_E_INTERNAL; 5316 } 5317 SOC_IF_ERROR_RETURN 5318 (phymod_phy_bond_in_pwrdn_override(pm_phy, enable)) ; 5319 } 5320 return(SOC_E_NONE); 5321 } 5322 5323 /* 5324 * Function: 5325 * phy_tsce_control_set 5326 * Purpose: 5327 * Configure PHY device specific control fucntion. 5328 * Parameters: 5329 * unit - BCM unit number. 5330 * port - Port number. 5331 * type - Control to update 5332 * value - New setting for the control 5333 * Returns: 5334 * SOC_E_NONE 5335 */ 5336 STATIC int 5337 phy_tsce_control_set(int unit, soc_port_t port, soc_phy_control_t type, uint32 value) 5338 { 5339 int rv; 5340 phy_ctrl_t *pc; 5341 soc_phymod_ctrl_t *pmc; 5342 tsce_config_t *pCfg; 5343 5344 rv = SOC_E_UNAVAIL; 5345 5346 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 5347 return (SOC_E_PARAM); 5348 } 5349 5350 /* locate phy control, phymod control, and the configuration data */ 5351 pc = INT_PHY_SW_STATE(unit, port); 5352 if (pc == NULL) { 5353 return SOC_E_INTERNAL; 5354 } 5355 pmc = &pc->phymod_ctrl; 5356 pCfg = (tsce_config_t *) pc->driver_data; 5357 5358 switch(type) { 5359 case SOC_PHY_CONTROL_INTERFACE: 5360 rv = phy_tsce_interface_set(unit, port, value); 5361 break; 5362 case SOC_PHY_CONTROL_TX_FIR_PRE: 5363 rv = tsce_tx_fir_pre_set(pmc, value); 5364 break; 5365 case SOC_PHY_CONTROL_TX_FIR_MAIN: 5366 rv = tsce_tx_fir_main_set(pmc, value); 5367 break; 5368 case SOC_PHY_CONTROL_TX_FIR_POST: 5369 rv = tsce_tx_fir_post_set(pmc, value); 5370 break; 5371 case SOC_PHY_CONTROL_TX_FIR_POST2: 5372 rv = tsce_tx_fir_post2_set(pmc, value); 5373 break; 5374 case SOC_PHY_CONTROL_TX_FIR_POST3: 5375 rv = tsce_tx_fir_post3_set(pmc, value); 5376 break; 5377 /* PREEMPHASIS */ 5378 case SOC_PHY_CONTROL_PREEMPHASIS_LANE0: 5379 rv = tsce_per_lane_preemphasis_set(pmc, pCfg, 0, value); 5380 break; 5381 case SOC_PHY_CONTROL_PREEMPHASIS_LANE1: 5382 rv = tsce_per_lane_preemphasis_set(pmc, pCfg, 1, value); 5383 break; 5384 case SOC_PHY_CONTROL_PREEMPHASIS_LANE2: 5385 rv = tsce_per_lane_preemphasis_set(pmc, pCfg, 2, value); 5386 break; 5387 case SOC_PHY_CONTROL_PREEMPHASIS_LANE3: 5388 rv = tsce_per_lane_preemphasis_set(pmc, pCfg, 3, value); 5389 break; 5390 case SOC_PHY_CONTROL_PREEMPHASIS: 5391 rv = tsce_preemphasis_set(pmc, pCfg, value); 5392 break; 5393 5394 /* DRIVER CURRENT */ 5395 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0: 5396 rv = tsce_per_lane_driver_current_set(pmc, pCfg, 0, value); 5397 break; 5398 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1: 5399 rv = tsce_per_lane_driver_current_set(pmc, pCfg, 1, value); 5400 break; 5401 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2: 5402 rv = tsce_per_lane_driver_current_set(pmc, pCfg, 2, value); 5403 break; 5404 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3: 5405 rv = tsce_per_lane_driver_current_set(pmc, pCfg, 3, value); 5406 break; 5407 case SOC_PHY_CONTROL_DRIVER_CURRENT: 5408 rv = tsce_driver_current_set(pmc, pCfg, value); 5409 break; 5410 5411 /* PRE_DRIVER CURRENT not supported anymore */ 5412 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE0: 5413 rv = SOC_E_UNAVAIL; 5414 break; 5415 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE1: 5416 rv = SOC_E_UNAVAIL; 5417 break; 5418 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE2: 5419 rv = SOC_E_UNAVAIL; 5420 break; 5421 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE3: 5422 rv = SOC_E_UNAVAIL; 5423 break; 5424 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 5425 rv = SOC_E_UNAVAIL; 5426 break; 5427 5428 /* POST2_DRIVER CURRENT not supported anymore */ 5429 case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT: 5430 rv = SOC_E_UNAVAIL; 5431 break; 5432 case SOC_PHY_CONTROL_TX_FIR_DRIVERMODE: 5433 rv = tsce_tx_fir_drivermode_set(pmc, pCfg, value); 5434 break; 5435 case SOC_PHY_CONTROL_DUMP: 5436 /* "N/A: will be part of common phymod application" */ 5437 /* was rv = tscmod_uc_status_dump(unit, port); */ 5438 break; 5439 5440 /* TX LANE SQUELCH */ 5441 case SOC_PHY_CONTROL_TX_LANE_SQUELCH: 5442 rv = tsce_tx_lane_squelch(pmc, value); 5443 break; 5444 /* RX LANE SQUELCH */ 5445 case SOC_PHY_CONTROL_RX_LANE_SQUELCH: 5446 rv = tsce_rx_lane_squelch(pmc, value); 5447 break; 5448 5449 /* RX PEAK FILTER */ 5450 case SOC_PHY_CONTROL_RX_PEAK_FILTER: 5451 rv = tsce_rx_peak_filter_set(pmc, value); 5452 break; 5453 5454 /* RX VGA */ 5455 case SOC_PHY_CONTROL_RX_VGA: 5456 rv = tsce_rx_vga_set(pmc, value); 5457 break; 5458 case SOC_PHY_CONTROL_RX_VGA_RELEASE: 5459 /* $$$ tbd $$$ */ 5460 break; 5461 5462 /* RX TAP */ 5463 case SOC_PHY_CONTROL_RX_TAP1: 5464 rv = tsce_rx_tap_set(pmc, 0, value); 5465 break; 5466 case SOC_PHY_CONTROL_RX_TAP2: 5467 rv = tsce_rx_tap_set(pmc, 1, value); 5468 break; 5469 case SOC_PHY_CONTROL_RX_TAP3: 5470 rv = tsce_rx_tap_set(pmc, 2, value); 5471 break; 5472 case SOC_PHY_CONTROL_RX_TAP4: 5473 rv = tsce_rx_tap_set(pmc, 3, value); 5474 break; 5475 case SOC_PHY_CONTROL_RX_TAP5: 5476 rv = tsce_rx_tap_set(pmc, 4, value); 5477 break; 5478 case SOC_PHY_CONTROL_RX_TAP1_RELEASE: /* $$$ tbd $$$ */ 5479 rv = tsce_rx_tap_release(pmc, 0); 5480 break; 5481 case SOC_PHY_CONTROL_RX_TAP2_RELEASE: /* $$$ tbd $$$ */ 5482 rv = tsce_rx_tap_release(pmc, 1); 5483 break; 5484 case SOC_PHY_CONTROL_RX_TAP3_RELEASE: /* $$$ tbd $$$ */ 5485 rv = tsce_rx_tap_release(pmc, 2); 5486 break; 5487 case SOC_PHY_CONTROL_RX_TAP4_RELEASE: /* $$$ tbd $$$ */ 5488 rv = tsce_rx_tap_release(pmc, 3); 5489 break; 5490 case SOC_PHY_CONTROL_RX_TAP5_RELEASE: /* $$$ tbd $$$ */ 5491 rv = tsce_rx_tap_release(pmc, 4); 5492 break; 5493 /* RX SLICER */ 5494 case SOC_PHY_CONTROL_RX_PLUS1_SLICER: 5495 rv = SOC_E_UNAVAIL; 5496 break; 5497 case SOC_PHY_CONTROL_RX_MINUS1_SLICER: 5498 rv = SOC_E_UNAVAIL; 5499 break; 5500 case SOC_PHY_CONTROL_RX_D_SLICER: 5501 rv = SOC_E_UNAVAIL; 5502 break; 5503 5504 /* PHASE INTERPOLATOR */ 5505 case SOC_PHY_CONTROL_PHASE_INTERP: 5506 rv = tsce_pi_control_set(pmc, value); 5507 break; 5508 5509 /* POLARITY */ 5510 case SOC_PHY_CONTROL_RX_POLARITY: 5511 rv = tsce_rx_polarity_set(pmc, &pCfg->phy_polarity_config, value); 5512 break; 5513 case SOC_PHY_CONTROL_TX_POLARITY: 5514 rv = tsce_tx_polarity_set(pmc, &pCfg->phy_polarity_config, value); 5515 break; 5516 5517 /* RESET */ 5518 case SOC_PHY_CONTROL_RX_RESET: 5519 rv = tsce_rx_reset(pmc, &pCfg->phy_reset_config, value); 5520 break; 5521 case SOC_PHY_CONTROL_TX_RESET: 5522 rv = tsce_tx_reset(pmc, &pCfg->phy_reset_config, value); 5523 break; 5524 5525 /* CL72 ENABLE */ 5526 case SOC_PHY_CONTROL_CL72: 5527 rv = tsce_cl72_enable_set(pmc, value); 5528 break; 5529 5530 /* LANE SWAP */ 5531 case SOC_PHY_CONTROL_LANE_SWAP: 5532 rv = tsce_lane_map_set(pmc, value); 5533 break; 5534 5535 /* FIRMWARE MODE */ 5536 case SOC_PHY_CONTROL_FIRMWARE_MODE: 5537 rv = tsce_firmware_mode_set(pmc, value); 5538 break; 5539 case SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE: 5540 rv = tsce_firmware_dfe_enable_set(pmc, value); 5541 break; 5542 case SOC_PHY_CONTROL_FIRMWARE_BR_DFE_ENABLE: 5543 rv = tsce_firmware_br_dfe_enable_set(pmc, value); 5544 break; 5545 case SOC_PHY_CONTROL_FIRMWARE_CL72_RESTART_TIMEOUT_ENABLE: 5546 rv = tsce_firmware_cl72_restart_timeout_enable_set(pmc, value); 5547 break; 5548 case SOC_PHY_CONTROL_FIRMWARE_CL72_AUTO_POLARITY_ENABLE: 5549 rv = tsce_firmware_cl72_auto_polarity_enable_set(pmc, value); 5550 break; 5551 5552 /* TX PATTERN */ 5553 case SOC_PHY_CONTROL_TX_PATTERN_20BIT: 5554 rv = SOC_E_UNAVAIL; 5555 break; 5556 case SOC_PHY_CONTROL_TX_PATTERN_256BIT: 5557 rv = SOC_E_UNAVAIL; 5558 break; 5559 case SOC_PHY_CONTROL_TX_PATTERN_LENGTH: 5560 rv = tsce_pattern_len_set(pmc, &pCfg->pattern,value); 5561 break; 5562 case SOC_PHY_CONTROL_TX_PATTERN_GEN_ENABLE: 5563 rv = tsce_pattern_enable_set(pmc, value); 5564 break; 5565 case SOC_PHY_CONTROL_TX_PATTERN_DATA0: 5566 rv = tsce_pattern_data_set(0, &pCfg->pattern, value); 5567 break; 5568 case SOC_PHY_CONTROL_TX_PATTERN_DATA1: 5569 rv = tsce_pattern_data_set(1, &pCfg->pattern, value); 5570 break; 5571 case SOC_PHY_CONTROL_TX_PATTERN_DATA2: 5572 rv = tsce_pattern_data_set(2, &pCfg->pattern, value); 5573 break; 5574 case SOC_PHY_CONTROL_TX_PATTERN_DATA3: 5575 rv = tsce_pattern_data_set(3, &pCfg->pattern, value); 5576 break; 5577 case SOC_PHY_CONTROL_TX_PATTERN_DATA4: 5578 rv = tsce_pattern_data_set(4, &pCfg->pattern, value); 5579 break; 5580 case SOC_PHY_CONTROL_TX_PATTERN_DATA5: 5581 rv = tsce_pattern_data_set(5, &pCfg->pattern, value); 5582 break; 5583 case SOC_PHY_CONTROL_TX_PATTERN_DATA6: 5584 rv = tsce_pattern_data_set(6, &pCfg->pattern, value); 5585 break; 5586 case SOC_PHY_CONTROL_TX_PATTERN_DATA7: 5587 rv = tsce_pattern_data_set(7, &pCfg->pattern, value); 5588 break; 5589 5590 /* decoupled PRBS */ 5591 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL: 5592 rv = tsce_prbs_tx_poly_set(pmc, value); 5593 break; 5594 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA: 5595 rv = tsce_prbs_tx_invert_data_set(pmc, value); 5596 break; 5597 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE: 5598 rv = tsce_prbs_tx_enable_set(pmc, value); 5599 break; 5600 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL: 5601 rv = tsce_prbs_rx_poly_set(pmc, value); 5602 break; 5603 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA: 5604 rv = tsce_prbs_rx_invert_data_set(pmc, value); 5605 break; 5606 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE: 5607 rv = tsce_prbs_rx_enable_set(pmc, value); 5608 break; 5609 /* for legacy prbs usage mainly set both tx/rx the same */ 5610 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 5611 rv = tsce_prbs_tx_poly_set(pmc, value); 5612 rv = tsce_prbs_rx_poly_set(pmc, value); 5613 break; 5614 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 5615 rv = tsce_prbs_tx_invert_data_set(pmc, value); 5616 break; 5617 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 5618 rv = tsce_prbs_tx_enable_set(pmc, value); 5619 rv = tsce_prbs_rx_enable_set(pmc, value); 5620 break; 5621 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 5622 rv = tsce_prbs_tx_enable_set(pmc, value); 5623 rv = tsce_prbs_rx_enable_set(pmc, value); 5624 break; 5625 5626 /* LOOPBACK */ 5627 case SOC_PHY_CONTROL_LOOPBACK_INTERNAL: 5628 rv = tsce_loopback_internal_set(pmc, value); 5629 break; 5630 case SOC_PHY_CONTROL_LOOPBACK_PMD: 5631 rv = tsce_loopback_internal_pmd_set(pmc, value); 5632 break; 5633 /* keep the design only for GH and TH */ 5634 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: /* is for remote PCS loopback */ 5635 rv = tsce_loopback_remote_set(pmc, value); /* calling remote PMD loopback */ 5636 break; 5637 case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS: /* is for remote PMD loopback */ 5638 rv = tsce_loopback_remote_set(pmc, value); /* calling remote PMD loopback */ 5639 /* rv = tsce_loopback_remote_pcs_set(pmc, value); */ /* calling remote PCS loopback */ 5640 break; 5641 5642 /* FEC */ 5643 case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION: 5644 rv = tsce_fec_enable_set(pmc, value); 5645 break; 5646 5647 /* CUSTOM */ 5648 case SOC_PHY_CONTROL_CUSTOM1: 5649 /* Obsolete ?? 5650 DEV_CFG_PTR(pc)->custom1 = value? TRUE: FALSE ; 5651 rv = SOC_E_NONE; */ 5652 rv = SOC_E_UNAVAIL; 5653 break; 5654 5655 /* SCRAMBLER */ 5656 case SOC_PHY_CONTROL_SCRAMBLER: 5657 rv = tsce_scrambler_set(pmc, port, value); 5658 break; 5659 5660 /* 8B10B */ 5661 case SOC_PHY_CONTROL_8B10B: 5662 rv = tsce_8b10b_set(pmc, value); 5663 break; 5664 5665 /* 64B65B */ 5666 case SOC_PHY_CONTROL_64B66B: 5667 rv = tsce_64b65b_set(pmc, value); 5668 break; 5669 5670 /* POWER */ 5671 case SOC_PHY_CONTROL_POWER: 5672 rv = tsce_power_set(pmc, value); 5673 break; 5674 5675 /* RX_LOW_FREQ_PEAK_FILTER */ 5676 case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER: 5677 rv = tsce_rx_low_freq_filter_set(pmc, value); 5678 break; 5679 5680 /* TX_PPM_ADJUST */ 5681 case SOC_PHY_CONTROL_TX_PPM_ADJUST: 5682 rv = tsce_tx_ppm_adjust_set(pmc, value); 5683 break; 5684 5685 /* VCO_FREQ */ 5686 case SOC_PHY_CONTROL_VCO_FREQ: 5687 rv = tsce_vco_freq_set(pmc, value); 5688 break; 5689 5690 /* PLL_DIVIDER */ 5691 case SOC_PHY_CONTROL_PLL_DIVIDER: 5692 rv = tsce_pll_divider_set(pmc, value); 5693 break; 5694 5695 /* OVERSAMPLE_MODE */ 5696 case SOC_PHY_CONTROL_OVERSAMPLE_MODE: 5697 rv = tsce_oversample_mode_set(pmc, value); 5698 break; 5699 5700 /* REF_CLK */ 5701 case SOC_PHY_CONTROL_REF_CLK: 5702 rv = tsce_ref_clk_set(pmc, value); 5703 break; 5704 5705 /* RX_SEQ_TOGGLE */ 5706 case SOC_PHY_CONTROL_RX_SEQ_TOGGLE: 5707 rv = tsce_rx_seq_toggle_set(pmc); 5708 break; 5709 /* HG codec config */ 5710 case SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE: 5711 rv = tsce_hg2_codec_enable_set(pmc, value); 5712 break; 5713 /* DRIVER_SUPPLY */ 5714 case SOC_PHY_CONTROL_DRIVER_SUPPLY: 5715 rv = tsce_driver_supply_set(pmc, value); 5716 break; 5717 /* EEE */ 5718 case SOC_PHY_CONTROL_EEE: 5719 rv = tsce_eee_set(pmc, value); 5720 break; 5721 5722 /* EEE */ 5723 #ifdef TSC_EEE_SUPPORT 5724 case SOC_PHY_CONTROL_EEE: 5725 case SOC_PHY_CONTROL_EEE_AUTO: 5726 rv = SOC_E_NONE; /* not supported */ 5727 break; 5728 #endif 5729 #if 0 5730 /* Added to support WA for HW bug; probably not required. */ 5731 case SOC_PHY_CONTROL_SOFTWARE_RX_LOS: 5732 DEV_CFG_PTR(pc)->sw_rx_los.enable = (value == 0? 0: 1); 5733 DEV_CFG_PTR(pc)->sw_rx_los.sys_link = 0; 5734 DEV_CFG_PTR(pc)->sw_rx_los.state = RXLOS_RESET; 5735 DEV_CFG_PTR(pc)->sw_rx_los.link_status = 0; 5736 /* THE FLAG IS SET IN INIT. FOR TSCMOD DRIVER 5737 TO WORK IT'S LINK_GET MUST BE CALLED */ 5738 /* Manage the _SERVICE_INT_PHY_LINK_GET flag so that 5739 if external phy is present link_get for 5740 internal phy is still called to process 5741 software rx los feature 5742 if(value) { 5743 PHY_FLAGS_SET(unit, port, PHY_FLAGS_SERVICE_INT_PHY_LINK_GET); 5744 } else { 5745 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_SERVICE_INT_PHY_LINK_GET); 5746 } 5747 */ 5748 rv = SOC_E_NONE; 5749 break; 5750 /* UNAVAIL */ 5751 case SOC_PHY_CONTROL_BERT_PATTERN: 5752 case SOC_PHY_CONTROL_BERT_RUN: 5753 case SOC_PHY_CONTROL_BERT_PACKET_SIZE: 5754 case SOC_PHY_CONTROL_BERT_IPG: 5755 case SOC_PHY_CONTROL_RX_PEAK_FILTER_TEMP_COMP: 5756 case SOC_PHY_CONTROL_CL73_FSM_AUTO_RECOVER: 5757 #endif 5758 case SOC_PHY_CONTROL_LINKDOWN_TRANSMIT: 5759 rv = SOC_E_NONE ; 5760 break ; 5761 case SOC_PHY_CONTROL_PCS_SPEED_ST_ENTRY: 5762 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamEntry, value) ; 5763 rv = SOC_E_NONE ; 5764 break ; 5765 case SOC_PHY_CONTROL_PCS_SPEED_ST_HCD: 5766 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamHCD, value) ; 5767 rv = SOC_E_NONE ; 5768 break ; 5769 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CLEAR: 5770 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamClear, value) ; 5771 rv = SOC_E_NONE ; 5772 break ; 5773 case SOC_PHY_CONTROL_PCS_SPEED_ST_NUM_OF_LANES: 5774 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamNumOfLanes, value) ; 5775 rv = SOC_E_NONE ; 5776 break ; 5777 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PLL_DIVIDER: 5778 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamPllDiv, value) ; 5779 rv = SOC_E_NONE ; 5780 break ; 5781 case SOC_PHY_CONTROL_PCS_SPEED_ST_PLL_DIVIDER: 5782 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamPllDiv, value) ; 5783 rv = SOC_E_NONE ; 5784 break ; 5785 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PMA_OS: 5786 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamPmaOS, value) ; 5787 rv = SOC_E_NONE ; 5788 break ; 5789 case SOC_PHY_CONTROL_PCS_SPEED_ST_PMA_OS: 5790 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamPmaOS, value) ; 5791 rv = SOC_E_NONE ; 5792 break ; 5793 case SOC_PHY_CONTROL_PCS_SPEED_HTO_SCR_MODE: 5794 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamScramble, value) ; 5795 rv = SOC_E_NONE ; 5796 break ; 5797 case SOC_PHY_CONTROL_PCS_SPEED_ST_SCR_MODE: 5798 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamScramble, value) ; 5799 rv = SOC_E_NONE ; 5800 break ; 5801 case SOC_PHY_CONTROL_PCS_SPEED_HTO_ENCODE_MODE: 5802 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamEncode, value) ; 5803 rv = SOC_E_NONE ; 5804 break ; 5805 case SOC_PHY_CONTROL_PCS_SPEED_ST_ENCODE_MODE: 5806 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamEncode, value) ; 5807 rv = SOC_E_NONE ; 5808 break ; 5809 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CL48_CHECK_END: 5810 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamCl48CheckEnd, value) ; 5811 rv = SOC_E_NONE ; 5812 break ; 5813 case SOC_PHY_CONTROL_PCS_SPEED_ST_CL48_CHECK_END: 5814 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamCl48CheckEnd, value) ; 5815 rv = SOC_E_NONE ; 5816 break ; 5817 case SOC_PHY_CONTROL_PCS_SPEED_HTO_BLK_SYNC_MODE: 5818 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamBlkSync, value) ; 5819 rv = SOC_E_NONE ; 5820 break ; 5821 case SOC_PHY_CONTROL_PCS_SPEED_ST_BLK_SYNC_MODE: 5822 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamBlkSync, value) ; 5823 rv = SOC_E_NONE ; 5824 break ; 5825 case SOC_PHY_CONTROL_PCS_SPEED_HTO_REORDER_MODE: 5826 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamReorder, value) ; 5827 rv = SOC_E_NONE ; 5828 break ; 5829 case SOC_PHY_CONTROL_PCS_SPEED_ST_REORDER_MODE: 5830 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamReorder, value) ; 5831 rv = SOC_E_NONE ; 5832 break ; 5833 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CL36_EN: 5834 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamCl36Enable, value) ; 5835 rv = SOC_E_NONE ; 5836 break ; 5837 case SOC_PHY_CONTROL_PCS_SPEED_ST_CL36_EN: 5838 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamCl36Enable, value) ; 5839 rv = SOC_E_NONE ; 5840 break ; 5841 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DESCR1_MODE: 5842 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDescr1, value) ; 5843 rv = SOC_E_NONE ; 5844 break ; 5845 case SOC_PHY_CONTROL_PCS_SPEED_ST_DESCR1_MODE: 5846 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDescr1, value) ; 5847 rv = SOC_E_NONE ; 5848 break ; 5849 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DEC1_MODE: 5850 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDecode1, value) ; 5851 rv = SOC_E_NONE ; 5852 break ; 5853 case SOC_PHY_CONTROL_PCS_SPEED_ST_DEC1_MODE: 5854 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDecode1, value) ; 5855 rv = SOC_E_NONE ; 5856 break ; 5857 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DESKEW_MODE: 5858 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDeskew, value) ; 5859 rv = SOC_E_NONE ; 5860 break ; 5861 case SOC_PHY_CONTROL_PCS_SPEED_ST_DESKEW_MODE: 5862 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDeskew, value) ; 5863 rv = SOC_E_NONE ; 5864 break ; 5865 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DESC2_MODE: 5866 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDescr2, value) ; 5867 rv = SOC_E_NONE ; 5868 break ; 5869 case SOC_PHY_CONTROL_PCS_SPEED_ST_DESC2_MODE: 5870 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDescr2, value) ; 5871 rv = SOC_E_NONE ; 5872 break ; 5873 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DESC2_BYTE_DEL: 5874 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDescr2ByteDel, value) ; 5875 rv = SOC_E_NONE ; 5876 break ; 5877 case SOC_PHY_CONTROL_PCS_SPEED_ST_DESC2_BYTE_DEL: 5878 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDescr2ByteDel, value) ; 5879 rv = SOC_E_NONE ; 5880 break ; 5881 case SOC_PHY_CONTROL_PCS_SPEED_HTO_BRCM64B66_DESCR: 5882 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamBrcm64B66, value) ; 5883 rv = SOC_E_NONE ; 5884 break ; 5885 case SOC_PHY_CONTROL_PCS_SPEED_ST_BRCM64B66_DESCR: 5886 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamBrcm64B66, value) ; 5887 rv = SOC_E_NONE ; 5888 break ; 5889 case SOC_PHY_CONTROL_PCS_SPEED_HTO_SGMII_MODE: 5890 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamSgmii, value) ; 5891 rv = SOC_E_NONE ; 5892 break ; 5893 case SOC_PHY_CONTROL_PCS_SPEED_ST_SGMII_MODE: 5894 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamSgmii, value) ; 5895 rv = SOC_E_NONE ; 5896 break ; 5897 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CLKCNT0: 5898 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamClkcnt0, value) ; 5899 rv = SOC_E_NONE ; 5900 break ; 5901 case SOC_PHY_CONTROL_PCS_SPEED_ST_CLKCNT0: 5902 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamClkcnt0, value) ; 5903 rv = SOC_E_NONE ; 5904 break ; 5905 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CLKCNT1: 5906 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamClkcnt1, value) ; 5907 rv = SOC_E_NONE ; 5908 break ; 5909 case SOC_PHY_CONTROL_PCS_SPEED_ST_CLKCNT1: 5910 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamClkcnt1, value) ; 5911 rv = SOC_E_NONE ; 5912 break ; 5913 case SOC_PHY_CONTROL_PCS_SPEED_HTO_LPCNT0: 5914 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamLpcnt0, value) ; 5915 rv = SOC_E_NONE ; 5916 break ; 5917 case SOC_PHY_CONTROL_PCS_SPEED_ST_LPCNT0: 5918 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamLpcnt0, value) ; 5919 rv = SOC_E_NONE ; 5920 break ; 5921 case SOC_PHY_CONTROL_PCS_SPEED_HTO_LPCNT1: 5922 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamLpcnt1, value) ; 5923 rv = SOC_E_NONE ; 5924 break ; 5925 case SOC_PHY_CONTROL_PCS_SPEED_ST_LPCNT1: 5926 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamLpcnt1, value) ; 5927 rv = SOC_E_NONE ; 5928 break ; 5929 case SOC_PHY_CONTROL_PCS_SPEED_HTO_MAC_CGC: 5930 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamMacCGC, value) ; 5931 rv = SOC_E_NONE ; 5932 break ; 5933 case SOC_PHY_CONTROL_PCS_SPEED_ST_MAC_CGC: 5934 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamMacCGC, value) ; 5935 rv = SOC_E_NONE ; 5936 break ; 5937 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PCS_REPCNT: 5938 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamRepcnt, value) ; 5939 rv = SOC_E_NONE ; 5940 break ; 5941 case SOC_PHY_CONTROL_PCS_SPEED_ST_PCS_REPCNT: 5942 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamRepcnt, value) ; 5943 rv = SOC_E_NONE ; 5944 break ; 5945 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PCS_CREDTEN: 5946 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamCrdtEn, value) ; 5947 rv = SOC_E_NONE ; 5948 break ; 5949 case SOC_PHY_CONTROL_PCS_SPEED_ST_PCS_CREDTEN: 5950 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamCrdtEn, value) ; 5951 rv = SOC_E_NONE ; 5952 break ; 5953 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PCS_CLKCNT: 5954 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamPcsClkcnt, value) ; 5955 rv = SOC_E_NONE ; 5956 break ; 5957 case SOC_PHY_CONTROL_PCS_SPEED_ST_PCS_CLKCNT: 5958 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamPcsClkcnt, value) ; 5959 rv = SOC_E_NONE ; 5960 break ; 5961 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PCS_CGC: 5962 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamPcsCGC, value) ; 5963 rv = SOC_E_NONE ; 5964 break ; 5965 case SOC_PHY_CONTROL_PCS_SPEED_ST_PCS_CGC: 5966 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamPcsCGC, value) ; 5967 rv = SOC_E_NONE ; 5968 break ; 5969 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CL72_EN: 5970 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamCl72En, value) ; 5971 rv = SOC_E_NONE ; 5972 break ; 5973 case SOC_PHY_CONTROL_PCS_SPEED_ST_CL72_EN: 5974 tsce_user_speed_set(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamCl72En, value) ; 5975 rv = SOC_E_NONE ; 5976 break ; 5977 case SOC_PHY_CONTROL_UNRELIABLE_LOS: 5978 rv = tsce_unreliable_los_set(pmc, value) ; 5979 break ; 5980 case SOC_PHY_CONTROL_PARALLEL_DETECTION: 5981 pCfg->pdetect1000x = value; 5982 /* call AN SET to activate this mode */ 5983 rv = SOC_E_NONE ; 5984 break ; 5985 case SOC_PHY_CONTROL_PARALLEL_DETECTION_10G: 5986 pCfg->pdetect10g = value; 5987 /* call AN SET to activate this mode */ 5988 rv = SOC_E_NONE ; 5989 break; 5990 case SOC_PHY_CONTROL_BOND_IN_PWRDN_OVERRIDE: 5991 rv = tsce_bond_in_pwrdn_override(pmc, value); 5992 break; 5993 default: 5994 rv = SOC_E_UNAVAIL; 5995 break; 5996 } 5997 return rv; 5998 } 5999 6000 6001 /* 6002 * tsce_tx_fir_pre_get 6003 */ 6004 STATIC int 6005 tsce_tx_fir_pre_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6006 { 6007 phymod_phy_access_t *pm_phy; 6008 phymod_tx_t phymod_tx; 6009 int idx; 6010 6011 /* loop through all cores */ 6012 for (idx = 0; idx < pmc->num_phys; idx++) { 6013 pm_phy = &pmc->phy[idx]->pm_phy; 6014 6015 if (pm_phy == NULL) { 6016 return SOC_E_INTERNAL; 6017 } 6018 6019 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 6020 *value = phymod_tx.pre; 6021 } 6022 6023 return(SOC_E_NONE); 6024 } 6025 6026 /* 6027 * tsce_tx_fir_main_get 6028 */ 6029 STATIC int 6030 tsce_tx_fir_main_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6031 { 6032 phymod_phy_access_t *pm_phy; 6033 phymod_tx_t phymod_tx; 6034 int idx; 6035 6036 /* loop through all cores */ 6037 for (idx = 0; idx < pmc->num_phys; idx++) { 6038 pm_phy = &pmc->phy[idx]->pm_phy; 6039 6040 if (pm_phy == NULL) { 6041 return SOC_E_INTERNAL; 6042 } 6043 6044 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 6045 *value = phymod_tx.main; 6046 } 6047 6048 return(SOC_E_NONE); 6049 } 6050 6051 /* 6052 * tsce_tx_fir_post_get 6053 */ 6054 STATIC int 6055 tsce_tx_fir_post_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6056 { 6057 phymod_phy_access_t *pm_phy; 6058 phymod_tx_t phymod_tx; 6059 int idx; 6060 6061 /* loop through all cores */ 6062 for (idx = 0; idx < pmc->num_phys; idx++) { 6063 pm_phy = &pmc->phy[idx]->pm_phy; 6064 6065 if (pm_phy == NULL) { 6066 return SOC_E_INTERNAL; 6067 } 6068 6069 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 6070 *value = phymod_tx.post; 6071 } 6072 6073 return(SOC_E_NONE); 6074 } 6075 6076 /* 6077 * tsce_tx_fir_post2_get 6078 */ 6079 STATIC int 6080 tsce_tx_fir_post2_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6081 { 6082 phymod_phy_access_t *pm_phy; 6083 phymod_tx_t phymod_tx; 6084 int idx; 6085 6086 /* loop through all cores */ 6087 for (idx = 0; idx < pmc->num_phys; idx++) { 6088 pm_phy = &pmc->phy[idx]->pm_phy; 6089 6090 if (pm_phy == NULL) { 6091 return SOC_E_INTERNAL; 6092 } 6093 6094 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 6095 *value = phymod_tx.post2; 6096 } 6097 6098 return(SOC_E_NONE); 6099 } 6100 6101 /* 6102 * tsce_tx_fir_post3_get 6103 */ 6104 STATIC int 6105 tsce_tx_fir_post3_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6106 { 6107 phymod_phy_access_t *pm_phy; 6108 phymod_tx_t phymod_tx; 6109 int idx; 6110 6111 /* loop through all cores */ 6112 for (idx = 0; idx < pmc->num_phys; idx++) { 6113 pm_phy = &pmc->phy[idx]->pm_phy; 6114 6115 if (pm_phy == NULL) { 6116 return SOC_E_INTERNAL; 6117 } 6118 6119 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 6120 *value = phymod_tx.post3; 6121 } 6122 6123 return(SOC_E_NONE); 6124 } 6125 6126 /* 6127 * tsce_per_lane_preemphasis_get 6128 */ 6129 STATIC int 6130 tsce_per_lane_preemphasis_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6131 { 6132 soc_phymod_phy_t *p_phy; 6133 uint32 lane_map; 6134 phymod_phy_access_t pm_phy_copy, *pm_phy; 6135 phymod_tx_t phymod_tx; 6136 6137 /* locate the desired phy and lane */ 6138 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 6139 6140 /* Make a copy of the phy access and overwrite the desired lane */ 6141 pm_phy = &p_phy->pm_phy; 6142 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 6143 pm_phy_copy.access.lane_mask = lane_map; 6144 6145 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 6146 *value = phymod_tx.pre | (phymod_tx.main << 8) | (phymod_tx.post << 16); 6147 6148 return(SOC_E_NONE); 6149 } 6150 6151 /* 6152 * tscf_preemphasis_set 6153 */ 6154 STATIC int 6155 tsce_preemphasis_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6156 { 6157 phymod_phy_access_t *pm_phy; 6158 phymod_tx_t phymod_tx; 6159 int idx; 6160 6161 /* loop through all cores */ 6162 for (idx = 0; idx < pmc->num_phys; idx++) { 6163 pm_phy = &pmc->phy[idx]->pm_phy; 6164 6165 if (pm_phy == NULL) { 6166 return SOC_E_INTERNAL; 6167 } 6168 6169 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 6170 *value = phymod_tx.pre | (phymod_tx.main << 8) | (phymod_tx.post << 16); 6171 } 6172 6173 return(SOC_E_NONE); 6174 } 6175 6176 /* 6177 * tsce_per_lane_driver_current_get 6178 */ 6179 STATIC int 6180 tsce_per_lane_driver_current_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6181 { 6182 soc_phymod_phy_t *p_phy; 6183 uint32 lane_map; 6184 phymod_phy_access_t pm_phy_copy, *pm_phy; 6185 phymod_tx_t phymod_tx; 6186 6187 /* locate the desired phy and lane */ 6188 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 6189 6190 /* Make a copy of the phy access and overwrite the desired lane */ 6191 pm_phy = &p_phy->pm_phy; 6192 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 6193 pm_phy_copy.access.lane_mask = lane_map; 6194 6195 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 6196 *value = phymod_tx.amp; 6197 6198 return(SOC_E_NONE); 6199 } 6200 6201 /* 6202 * tsce_per_lane_tx_drivermode_get 6203 */ 6204 STATIC int 6205 tsce_per_lane_tx_fir_drivermode_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6206 { 6207 soc_phymod_phy_t *p_phy; 6208 uint32 lane_map; 6209 phymod_phy_access_t pm_phy_copy, *pm_phy; 6210 phymod_tx_t phymod_tx; 6211 6212 /* locate the desired phy and lane */ 6213 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 6214 6215 /* Make a copy of the phy access and overwrite the desired lane */ 6216 pm_phy = &p_phy->pm_phy; 6217 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 6218 pm_phy_copy.access.lane_mask = lane_map; 6219 6220 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 6221 *value = phymod_tx.drivermode ; 6222 return(SOC_E_NONE); 6223 } 6224 6225 /* 6226 * tscf_preemphasis_set 6227 */ 6228 STATIC int 6229 tsce_tx_fir_drivermode_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6230 { 6231 phymod_phy_access_t *pm_phy; 6232 phymod_tx_t phymod_tx; 6233 int idx; 6234 6235 /* loop through all cores */ 6236 idx = 0; 6237 pm_phy = &pmc->phy[idx]->pm_phy; 6238 6239 if (pm_phy == NULL) { 6240 return SOC_E_INTERNAL; 6241 } 6242 6243 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 6244 *value = phymod_tx.drivermode ; 6245 6246 return(SOC_E_NONE); 6247 } 6248 6249 /* 6250 * tsce_per_lane_prbs_poly_get 6251 */ 6252 STATIC int 6253 tsce_per_lane_prbs_poly_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6254 { 6255 return(SOC_E_UNAVAIL); 6256 } 6257 6258 /* 6259 * tsce_per_lane_prbs_tx_invert_data_get 6260 */ 6261 STATIC int 6262 tsce_per_lane_prbs_tx_invert_data_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6263 { 6264 return(SOC_E_UNAVAIL); 6265 } 6266 6267 /* 6268 * tsce_per_lane_prbs_tx_enable_get 6269 */ 6270 STATIC int 6271 tsce_per_lane_prbs_tx_enable_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6272 { 6273 return(SOC_E_UNAVAIL); 6274 } 6275 6276 /* 6277 * tsce_per_lane_prbs_rx_enable_get 6278 */ 6279 STATIC int 6280 tsce_per_lane_prbs_rx_enable_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6281 { 6282 return(SOC_E_UNAVAIL); 6283 } 6284 6285 /* 6286 * tsce_per_lane_prbs_rx_status_get 6287 */ 6288 STATIC int 6289 tsce_per_lane_prbs_rx_status_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6290 { 6291 /* $$$ Need to add diagnostic API */ 6292 return(SOC_E_UNAVAIL); 6293 } 6294 6295 /* 6296 * tsce_per_lane_rx_peak_filter_get 6297 */ 6298 STATIC int 6299 tsce_per_lane_rx_peak_filter_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6300 { 6301 soc_phymod_phy_t *p_phy; 6302 uint32 lane_map; 6303 phymod_phy_access_t pm_phy_copy, *pm_phy; 6304 phymod_rx_t phymod_rx; 6305 6306 *value = 0; 6307 6308 /* locate the desired phy and lane */ 6309 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 6310 6311 /* Make a copy of the phy access and overwrite the desired lane */ 6312 pm_phy = &p_phy->pm_phy; 6313 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 6314 pm_phy_copy.access.lane_mask = lane_map; 6315 6316 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 6317 if (phymod_rx.peaking_filter.enable) 6318 *value = phymod_rx.peaking_filter.value; 6319 6320 return(SOC_E_NONE); 6321 } 6322 6323 /* 6324 * tsce_per_lane_rx_vga_get 6325 */ 6326 STATIC int 6327 tsce_per_lane_rx_vga_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6328 { 6329 soc_phymod_phy_t *p_phy; 6330 uint32 lane_map; 6331 phymod_phy_access_t pm_phy_copy, *pm_phy; 6332 phymod_rx_t phymod_rx; 6333 6334 *value = 0; 6335 6336 /* locate the desired phy and lane */ 6337 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 6338 6339 /* Make a copy of the phy access and overwrite the desired lane */ 6340 pm_phy = &p_phy->pm_phy; 6341 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 6342 pm_phy_copy.access.lane_mask = lane_map; 6343 6344 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 6345 if (phymod_rx.vga.enable) 6346 *value = phymod_rx.vga.value; 6347 6348 return(SOC_E_NONE); 6349 } 6350 6351 /* 6352 * tsce_per_lane_rx_dfe_tap_control_get 6353 */ 6354 STATIC int 6355 tsce_per_lane_rx_dfe_tap_control_get(soc_phymod_ctrl_t *pmc, int lane, int tap, uint32 *value) 6356 { 6357 soc_phymod_phy_t *p_phy; 6358 uint32 lane_map; 6359 phymod_phy_access_t pm_phy_copy, *pm_phy; 6360 phymod_rx_t phymod_rx; 6361 6362 *value = 0; 6363 6364 /* locate the desired phy and lane */ 6365 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 6366 6367 /* Make a copy of the phy access and overwrite the desired lane */ 6368 pm_phy = &p_phy->pm_phy; 6369 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 6370 pm_phy_copy.access.lane_mask = lane_map; 6371 6372 if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) { 6373 /* this can only happen with a coding error */ 6374 return SOC_E_INTERNAL; 6375 } 6376 6377 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 6378 if (phymod_rx.dfe[tap].enable) 6379 *value = phymod_rx.dfe[tap].value; 6380 6381 return(SOC_E_NONE); 6382 } 6383 6384 6385 /* 6386 * tsce_per_lane_rx_low_freq_filter_get 6387 */ 6388 STATIC int 6389 tsce_per_lane_rx_low_freq_filter_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6390 { 6391 return(SOC_E_UNAVAIL); 6392 } 6393 6394 /* 6395 * tsce_rx_peak_filter_get 6396 */ 6397 STATIC int 6398 tsce_rx_peak_filter_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6399 { 6400 phymod_phy_access_t *pm_phy; 6401 phymod_rx_t phymod_rx; 6402 6403 /* just take the value from the first phy */ 6404 if (pmc->phy[0] == NULL) { 6405 return SOC_E_INTERNAL; 6406 } 6407 pm_phy = &pmc->phy[0]->pm_phy; 6408 6409 if (pm_phy == NULL) { 6410 return SOC_E_INTERNAL; 6411 } 6412 6413 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 6414 *value = phymod_rx.peaking_filter.value; 6415 6416 return(SOC_E_NONE); 6417 } 6418 6419 /* 6420 * tsce_rx_vga_set 6421 */ 6422 STATIC int 6423 tsce_rx_vga_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6424 { 6425 phymod_phy_access_t *pm_phy; 6426 phymod_rx_t phymod_rx; 6427 6428 /* just take the value from the first phy */ 6429 if (pmc->phy[0] == NULL) { 6430 return SOC_E_INTERNAL; 6431 } 6432 pm_phy = &pmc->phy[0]->pm_phy; 6433 6434 if (pm_phy == NULL) { 6435 return SOC_E_INTERNAL; 6436 } 6437 6438 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 6439 *value = phymod_rx.vga.value; 6440 6441 return(SOC_E_NONE); 6442 } 6443 6444 /* 6445 * tsce_rx_tap_get 6446 */ 6447 STATIC int 6448 tsce_rx_tap_get(soc_phymod_ctrl_t *pmc, int tap, uint32 *value) 6449 { 6450 phymod_phy_access_t *pm_phy; 6451 phymod_rx_t phymod_rx; 6452 6453 if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) { 6454 /* this can only happen with a coding error */ 6455 return SOC_E_INTERNAL; 6456 } 6457 /* just take the value from the first phy */ 6458 if (pmc->phy[0] == NULL) { 6459 return SOC_E_INTERNAL; 6460 } 6461 pm_phy = &pmc->phy[0]->pm_phy; 6462 6463 if (pm_phy == NULL) { 6464 return SOC_E_INTERNAL; 6465 } 6466 6467 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 6468 *value = phymod_rx.dfe[tap].value; 6469 6470 return(SOC_E_NONE); 6471 } 6472 6473 /* 6474 * tsce_pi_control_get 6475 */ 6476 STATIC int 6477 tsce_pi_control_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6478 { 6479 phymod_phy_access_t *pm_phy; 6480 phymod_tx_override_t tx_override; 6481 6482 /* just take the value from the first phy */ 6483 if (pmc->phy[0] == NULL) { 6484 return SOC_E_INTERNAL; 6485 } 6486 pm_phy = &pmc->phy[0]->pm_phy; 6487 6488 if (pm_phy == NULL) { 6489 return SOC_E_INTERNAL; 6490 } 6491 6492 SOC_IF_ERROR_RETURN(phymod_phy_tx_override_get(pm_phy, &tx_override)); 6493 *value = tx_override.phase_interpolator.value; 6494 6495 return(SOC_E_NONE); 6496 } 6497 6498 /* 6499 * tsce_per_lane_rx_signal_detect_get 6500 */ 6501 STATIC int 6502 tsce_per_lane_rx_signal_detect_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6503 { 6504 soc_phymod_phy_t *p_phy; 6505 uint32 lane_map; 6506 phymod_phy_access_t pm_phy_copy, *pm_phy; 6507 6508 /* locate the desired phy and lane */ 6509 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 6510 6511 /* Make a copy of the phy access and overwrite the desired lane */ 6512 pm_phy = &p_phy->pm_phy; 6513 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 6514 pm_phy_copy.access.lane_mask = lane_map; 6515 6516 SOC_IF_ERROR_RETURN(phymod_phy_rx_signal_detect_get(&pm_phy_copy, value)); 6517 6518 return(SOC_E_NONE); 6519 } 6520 6521 /* 6522 * tsce_rx_signal_detect_get 6523 */ 6524 STATIC int 6525 tsce_rx_signal_detect_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6526 { 6527 phymod_phy_access_t *pm_phy; 6528 6529 /* just take the value from the first phy */ 6530 if (pmc->phy[0] == NULL) { 6531 return SOC_E_INTERNAL; 6532 } 6533 pm_phy = &pmc->phy[0]->pm_phy; 6534 6535 if (pm_phy == NULL) { 6536 return SOC_E_INTERNAL; 6537 } 6538 6539 SOC_IF_ERROR_RETURN(phymod_phy_rx_signal_detect_get(pm_phy, value)); 6540 6541 return(SOC_E_NONE); 6542 } 6543 6544 /* 6545 * tsce_per_lane_rx_seq_done_get 6546 */ 6547 STATIC int 6548 tsce_per_lane_rx_seq_done_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 6549 { 6550 soc_phymod_phy_t *p_phy; 6551 uint32 lane_map; 6552 phymod_phy_access_t pm_phy_copy, *pm_phy; 6553 6554 /* locate the desired phy and lane */ 6555 SOC_IF_ERROR_RETURN(_tsce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 6556 6557 /* Make a copy of the phy access and overwrite the desired lane */ 6558 pm_phy = &p_phy->pm_phy; 6559 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 6560 pm_phy_copy.access.lane_mask = lane_map; 6561 6562 SOC_IF_ERROR_RETURN(phymod_phy_rx_pmd_locked_get(&pm_phy_copy, value)); 6563 6564 return(SOC_E_NONE); 6565 } 6566 6567 /* 6568 * tsce_rx_seq_done_get 6569 */ 6570 STATIC int 6571 tsce_rx_seq_done_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6572 { 6573 phymod_phy_access_t *pm_phy; 6574 6575 /* just take the value from the first phy */ 6576 if (pmc->phy[pmc->main_phy] == NULL) { 6577 return SOC_E_INTERNAL; 6578 } 6579 pm_phy = &pmc->phy[pmc->main_phy]->pm_phy; 6580 6581 if (pm_phy == NULL) { 6582 return SOC_E_INTERNAL; 6583 } 6584 6585 SOC_IF_ERROR_RETURN(phymod_phy_rx_pmd_locked_get(pm_phy, value)); 6586 6587 return(SOC_E_NONE); 6588 } 6589 6590 /* 6591 * tsce_eee_get 6592 */ 6593 STATIC int 6594 tsce_eee_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6595 { 6596 phymod_phy_access_t *pm_phy; 6597 6598 /* just take the value from the first phy */ 6599 if (pmc->phy[0] == NULL) { 6600 return SOC_E_INTERNAL; 6601 } 6602 pm_phy = &pmc->phy[0]->pm_phy; 6603 6604 if (pm_phy == NULL) { 6605 return SOC_E_INTERNAL; 6606 } 6607 6608 SOC_IF_ERROR_RETURN(phymod_phy_eee_get(pm_phy, value)); 6609 6610 return(SOC_E_NONE); 6611 } 6612 6613 6614 /* 6615 * tsce_rx_ppm_get 6616 */ 6617 STATIC int 6618 tsce_rx_ppm_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6619 { 6620 /* $$$ Need to add diagnostic API */ 6621 return(SOC_E_UNAVAIL); 6622 } 6623 6624 /* 6625 * tsce_cl72_enable_get 6626 */ 6627 STATIC int 6628 tsce_cl72_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6629 { 6630 phymod_phy_access_t *pm_phy; 6631 6632 /* just take the value from the first phy */ 6633 if (pmc->phy[pmc->main_phy] == NULL) { 6634 return SOC_E_INTERNAL; 6635 } 6636 pm_phy = &pmc->phy[pmc->main_phy]->pm_phy; 6637 6638 if (pm_phy == NULL) { 6639 return SOC_E_INTERNAL; 6640 } 6641 6642 SOC_IF_ERROR_RETURN(phymod_phy_cl72_get(pm_phy, value)); 6643 6644 return(SOC_E_NONE); 6645 } 6646 6647 /* 6648 * tsce_cl72_status_get 6649 */ 6650 STATIC int 6651 tsce_cl72_status_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6652 { 6653 phymod_phy_access_t *pm_phy; 6654 phymod_cl72_status_t status; 6655 6656 /* just take the value from the first phy */ 6657 if (pmc->phy[pmc->main_phy] == NULL) { 6658 return SOC_E_INTERNAL; 6659 } 6660 pm_phy = &pmc->phy[pmc->main_phy]->pm_phy; 6661 6662 if (pm_phy == NULL) { 6663 return SOC_E_INTERNAL; 6664 } 6665 6666 SOC_IF_ERROR_RETURN(phymod_phy_cl72_status_get(pm_phy, &status)); 6667 *value = status.locked; 6668 6669 return(SOC_E_NONE); 6670 } 6671 6672 /* 6673 * tsce_prbs_tx_poly_get 6674 */ 6675 STATIC int 6676 tsce_prbs_tx_poly_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6677 { 6678 phymod_phy_access_t *pm_phy; 6679 phymod_prbs_t prbs; 6680 uint32_t flags = 0; 6681 6682 /* just take the value from the first phy */ 6683 if (pmc->phy[0] == NULL) { 6684 return SOC_E_INTERNAL; 6685 } 6686 pm_phy = &pmc->phy[0]->pm_phy; 6687 6688 if (pm_phy == NULL) { 6689 return SOC_E_INTERNAL; 6690 } 6691 6692 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 6693 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 6694 6695 *value = (int) prbs.poly; 6696 6697 /* convert from PHYMOD enum to SDK enum */ 6698 switch(prbs.poly){ 6699 case phymodPrbsPoly7: 6700 *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1; 6701 break; 6702 case phymodPrbsPoly9: 6703 *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1; 6704 break; 6705 case phymodPrbsPoly15: 6706 *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1; 6707 break; 6708 case phymodPrbsPoly23: 6709 *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1; 6710 break; 6711 case phymodPrbsPoly31: 6712 *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1; 6713 break; 6714 case phymodPrbsPoly11: 6715 *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1; 6716 break; 6717 case phymodPrbsPoly58: 6718 *value = SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1; 6719 break; 6720 default: 6721 return SOC_E_INTERNAL; 6722 } 6723 return SOC_E_NONE; 6724 } 6725 /* 6726 * tsce_prbs_rx_poly_get 6727 */ 6728 STATIC int 6729 tsce_prbs_rx_poly_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6730 { 6731 phymod_phy_access_t *pm_phy; 6732 phymod_prbs_t prbs; 6733 uint32_t flags = 0; 6734 6735 /* just take the value from the first phy */ 6736 if (pmc->phy[0] == NULL) { 6737 return SOC_E_INTERNAL; 6738 } 6739 pm_phy = &pmc->phy[0]->pm_phy; 6740 6741 if (pm_phy == NULL) { 6742 return SOC_E_INTERNAL; 6743 } 6744 6745 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 6746 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 6747 6748 *value = (int) prbs.poly; 6749 6750 /* convert from PHYMOD enum to SDK enum */ 6751 switch(prbs.poly){ 6752 case phymodPrbsPoly7: 6753 *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1; 6754 break; 6755 case phymodPrbsPoly9: 6756 *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1; 6757 break; 6758 case phymodPrbsPoly15: 6759 *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1; 6760 break; 6761 case phymodPrbsPoly23: 6762 *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1; 6763 break; 6764 case phymodPrbsPoly31: 6765 *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1; 6766 break; 6767 case phymodPrbsPoly11: 6768 *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1; 6769 break; 6770 case phymodPrbsPoly58: 6771 *value = SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1; 6772 break; 6773 default: 6774 return SOC_E_INTERNAL; 6775 } 6776 return SOC_E_NONE; 6777 } 6778 6779 /* 6780 * tsce_prbs_tx_invert_data_get 6781 */ 6782 STATIC int 6783 tsce_prbs_tx_invert_data_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6784 { 6785 phymod_phy_access_t *pm_phy; 6786 phymod_prbs_t prbs; 6787 uint32_t flags = 0; 6788 6789 /* just take the value from the first phy */ 6790 if (pmc->phy[0] == NULL) { 6791 return SOC_E_INTERNAL; 6792 } 6793 pm_phy = &pmc->phy[0]->pm_phy; 6794 6795 if (pm_phy == NULL) { 6796 return SOC_E_INTERNAL; 6797 } 6798 6799 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 6800 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 6801 *value = prbs.invert; 6802 6803 return(SOC_E_NONE); 6804 } 6805 6806 /* 6807 * tsce_prbs_rx_invert_data_get 6808 */ 6809 STATIC int 6810 tsce_prbs_rx_invert_data_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6811 { 6812 phymod_phy_access_t *pm_phy; 6813 phymod_prbs_t prbs; 6814 uint32_t flags = 0; 6815 6816 /* just take the value from the first phy */ 6817 if (pmc->phy[0] == NULL) { 6818 return SOC_E_INTERNAL; 6819 } 6820 pm_phy = &pmc->phy[0]->pm_phy; 6821 6822 if (pm_phy == NULL) { 6823 return SOC_E_INTERNAL; 6824 } 6825 6826 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 6827 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 6828 *value = prbs.invert; 6829 6830 return(SOC_E_NONE); 6831 } 6832 6833 6834 /* 6835 * tsce_prbs_tx_enable_get 6836 */ 6837 STATIC int 6838 tsce_prbs_tx_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6839 { 6840 phymod_phy_access_t *pm_phy; 6841 uint32_t flags = 0; 6842 6843 /* just take the value from the first phy */ 6844 if (pmc->phy[0] == NULL) { 6845 return SOC_E_INTERNAL; 6846 } 6847 pm_phy = &pmc->phy[0]->pm_phy; 6848 6849 if (pm_phy == NULL) { 6850 return SOC_E_INTERNAL; 6851 } 6852 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 6853 SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(pm_phy, flags, value)); 6854 6855 return(SOC_E_NONE); 6856 } 6857 6858 /* 6859 * tsce_prbs_rx_enable_get 6860 */ 6861 STATIC int 6862 tsce_prbs_rx_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6863 { 6864 phymod_phy_access_t *pm_phy; 6865 uint32_t flags = 0; 6866 6867 /* just take the value from the first phy */ 6868 if (pmc->phy[0] == NULL) { 6869 return SOC_E_INTERNAL; 6870 } 6871 pm_phy = &pmc->phy[0]->pm_phy; 6872 6873 if (pm_phy == NULL) { 6874 return SOC_E_INTERNAL; 6875 } 6876 6877 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 6878 SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(pm_phy, flags, value)); 6879 6880 return(SOC_E_NONE); 6881 } 6882 6883 /* 6884 * tsce_prbs_rx_status_get 6885 */ 6886 STATIC int 6887 tsce_prbs_rx_status_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6888 { 6889 phymod_phy_access_t *pm_phy; 6890 phymod_prbs_status_t prbs_tmp; 6891 int idx, prbs_lock, lock_loss, error_count ; 6892 6893 /* just take the value from the first phy */ 6894 if (pmc->phy[0] == NULL) { 6895 return SOC_E_INTERNAL; 6896 } 6897 6898 prbs_lock = 1 ; 6899 lock_loss = 0 ; 6900 error_count = 0 ; 6901 for (idx = 0; idx < pmc->num_phys; idx++) { 6902 pm_phy = &pmc->phy[idx]->pm_phy; 6903 6904 if (pm_phy == NULL) { 6905 return SOC_E_INTERNAL; 6906 } 6907 /* $$$ Need to add diagnostic API */ 6908 SOC_IF_ERROR_RETURN 6909 (phymod_phy_prbs_status_get(pm_phy, 0, &prbs_tmp)); 6910 6911 if(prbs_tmp.prbs_lock==0) { 6912 prbs_lock = 0 ; 6913 } else { 6914 if(prbs_tmp.prbs_lock_loss) { 6915 lock_loss = 1 ; 6916 } else { 6917 error_count += prbs_tmp.error_count; 6918 } 6919 } 6920 } 6921 6922 if (prbs_lock == 0) { 6923 *value = -1; 6924 } else if ((lock_loss == 1) && (prbs_lock == 1)) { 6925 *value = -2; 6926 } else { 6927 *value = error_count; 6928 } 6929 return(SOC_E_NONE); 6930 } 6931 6932 /* 6933 * tsce_loopback_internal_pmd_get (this is the PMD global loopback) 6934 */ 6935 STATIC int 6936 tsce_loopback_internal_pmd_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6937 { 6938 phymod_phy_access_t *pm_phy; 6939 uint32_t enable; 6940 6941 /* just take the value from the first phy */ 6942 if (pmc->phy[0] == NULL) { 6943 return SOC_E_INTERNAL; 6944 } 6945 pm_phy = &pmc->phy[0]->pm_phy; 6946 6947 if (pm_phy == NULL) { 6948 return SOC_E_INTERNAL; 6949 } 6950 6951 SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackGlobalPMD, &enable)); 6952 *value = enable; 6953 return(SOC_E_NONE); 6954 } 6955 6956 6957 /* 6958 * tsce_loopback_remote_get 6959 */ 6960 STATIC int 6961 tsce_loopback_remote_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6962 { 6963 phymod_phy_access_t *pm_phy; 6964 uint32_t enable; 6965 6966 /* just take the value from the first phy */ 6967 if (pmc->phy[0] == NULL) { 6968 return SOC_E_INTERNAL; 6969 } 6970 pm_phy = &pmc->phy[0]->pm_phy; 6971 6972 if (pm_phy == NULL) { 6973 return SOC_E_INTERNAL; 6974 } 6975 6976 SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackRemotePMD, &enable)); 6977 *value = enable; 6978 return(SOC_E_NONE); 6979 } 6980 6981 #if 0 6982 /* 6983 * tsce_loopback_remote_pcs_get 6984 */ 6985 STATIC int 6986 tsce_loopback_remote_pcs_get(soc_phymod_ctrl_t *pmc, uint32 *value) 6987 { 6988 phymod_phy_access_t *pm_phy; 6989 uint32_t enable; 6990 6991 /* just take the value from the first phy */ 6992 if (pmc->phy[0] == NULL) { 6993 return SOC_E_INTERNAL; 6994 } 6995 pm_phy = &pmc->phy[0]->pm_phy; 6996 6997 if (pm_phy == NULL) { 6998 return SOC_E_INTERNAL; 6999 } 7000 7001 SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackRemotePCS, &enable)); 7002 *value = enable; 7003 return(SOC_E_NONE); 7004 } 7005 #endif 7006 7007 /* 7008 * tsce_fec_get 7009 */ 7010 STATIC int 7011 tsce_fec_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 7012 { 7013 phymod_phy_access_t *pm_phy; 7014 uint32_t enable; 7015 7016 /* just take the value from the first phy */ 7017 if (pmc->phy[0] == NULL) { 7018 return SOC_E_INTERNAL; 7019 } 7020 pm_phy = &pmc->phy[0]->pm_phy; 7021 7022 if (pm_phy == NULL) { 7023 return SOC_E_INTERNAL; 7024 } 7025 7026 SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_get(pm_phy, &enable)); 7027 *value = enable; 7028 7029 return(SOC_E_NONE); 7030 } 7031 /* 7032 * tsce_pattern_256bit_get 7033 * 7034 * CHECK SEMANTICS: assumption is that this procedure will retrieve the pattern 7035 * from Tier1 and return whether the tx pattern is enabled. Note that this 7036 * is different from the 20 bit pattern retrieval semantics 7037 */ 7038 /* 7039 * tsce_pattern_256bit_get 7040 * 7041 * CHECK SEMANTICS: assumption is that this procedure will retrieve the pattern 7042 * from Tier1 and return whether the tx pattern is enabled. Note that this 7043 * is different from the 20 bit pattern retrieval semantics 7044 */ 7045 STATIC int 7046 tsce_pattern_get(soc_phymod_ctrl_t *pmc, tsce_pattern_t* cfg_pattern) 7047 { 7048 phymod_phy_access_t *pm_phy; 7049 phymod_pattern_t phymod_pattern; 7050 uint32_t *temp_data; 7051 uint32_t pattern_arr[PATTERN_MAX_SIZE]; 7052 7053 /* just take the value from the first phy */ 7054 if (pmc->phy[0] == NULL) { 7055 return SOC_E_INTERNAL; 7056 } 7057 pm_phy = &pmc->phy[0]->pm_phy; 7058 7059 if (pm_phy == NULL) { 7060 return SOC_E_INTERNAL; 7061 } 7062 7063 phymod_pattern.pattern = pattern_arr; 7064 SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_get(pm_phy, &phymod_pattern)); 7065 temp_data = phymod_pattern.pattern; 7066 cfg_pattern->pattern_data[0] = *temp_data; 7067 cfg_pattern->pattern_length = phymod_pattern.pattern_len; 7068 /* sal_memcpy(cfg_pattern , phymod_pattern.pattern, sizeof(*cfg_pattern)); */ 7069 return(SOC_E_NONE); 7070 } 7071 7072 STATIC int 7073 tsce_pattern_len_get(soc_phymod_ctrl_t *pmc, uint32_t *value) 7074 { 7075 phymod_phy_access_t *pm_phy; 7076 phymod_pattern_t phymod_pattern; 7077 uint32_t pattern_arr[PATTERN_MAX_SIZE]; 7078 7079 7080 /* just take the value from the first phy */ 7081 if (pmc->phy[0] == NULL) { 7082 return SOC_E_INTERNAL; 7083 } 7084 pm_phy = &pmc->phy[0]->pm_phy; 7085 7086 if (pm_phy == NULL) { 7087 return SOC_E_INTERNAL; 7088 } 7089 7090 phymod_pattern.pattern = pattern_arr; 7091 SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_get(pm_phy, &phymod_pattern)); 7092 *value = phymod_pattern.pattern_len; 7093 return(SOC_E_NONE); 7094 } 7095 7096 7097 STATIC int 7098 tsce_pattern_enable_get(soc_phymod_ctrl_t *pmc, uint32_t *value) 7099 { 7100 phymod_phy_access_t *pm_phy; 7101 7102 /* just take the value from the first phy */ 7103 if (pmc->phy[0] == NULL) { 7104 return SOC_E_INTERNAL; 7105 } 7106 pm_phy = &pmc->phy[0]->pm_phy; 7107 7108 if (pm_phy == NULL) { 7109 return SOC_E_INTERNAL; 7110 } 7111 7112 SOC_IF_ERROR_RETURN(phymod_phy_pattern_enable_get(pm_phy, value)); 7113 7114 return(SOC_E_NONE); 7115 } 7116 7117 7118 7119 /* 7120 * tsce_scrambler_get 7121 */ 7122 STATIC int 7123 tsce_scrambler_get(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 *value) 7124 { 7125 phymod_phy_access_t *pm_phy; 7126 phymod_phy_inf_config_t config; 7127 phy_ctrl_t *pc; 7128 tsce_config_t *pCfg; 7129 phymod_ref_clk_t ref_clock; 7130 7131 /* locate phy control */ 7132 pc = INT_PHY_SW_STATE(pmc->unit, port); 7133 if (pc == NULL) { 7134 return SOC_E_INTERNAL; 7135 } 7136 pCfg = (tsce_config_t *) pc->driver_data; 7137 7138 SOC_IF_ERROR_RETURN( 7139 tsce_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clock)); 7140 7141 /* just take the value from the first phy */ 7142 if (pmc->phy[0] == NULL) { 7143 return SOC_E_INTERNAL; 7144 } 7145 pm_phy = &pmc->phy[0]->pm_phy; 7146 7147 if (pm_phy == NULL) { 7148 return SOC_E_INTERNAL; 7149 } 7150 7151 SOC_IF_ERROR_RETURN(phymod_phy_interface_config_get(pm_phy, 0 /* flags */, ref_clock, &config)); 7152 *value = PHYMOD_INTF_MODES_SCR_GET(&config); 7153 7154 return(SOC_E_NONE); 7155 } 7156 7157 /* 7158 * tsce_firmware_mode_get 7159 */ 7160 STATIC int 7161 tsce_firmware_mode_get(soc_phymod_ctrl_t *pmc, uint32 *value) 7162 { 7163 phymod_phy_access_t *pm_phy; 7164 phymod_firmware_lane_config_t fw_config; 7165 7166 /* just take the value from the first phy */ 7167 if (pmc->phy[0] == NULL) { 7168 return SOC_E_INTERNAL; 7169 } 7170 7171 pm_phy = &pmc->phy[0]->pm_phy; 7172 if (pm_phy == NULL) { 7173 return SOC_E_INTERNAL; 7174 } 7175 7176 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 7177 7178 if (fw_config.LaneConfigFromPCS) { 7179 *value = SOC_PHY_FIRMWARE_DEFAULT; 7180 } else if (fw_config.DfeOn) { 7181 *value = SOC_PHY_FIRMWARE_FORCE_OSDFE; 7182 } else if (fw_config.ForceBrDfe) { 7183 *value = SOC_PHY_FIRMWARE_FORCE_BRDFE; 7184 } else if (SOC_PHY_FIRMWARE_CL72_WITHOUT_AN) { 7185 *value = SOC_PHY_FIRMWARE_CL72_WITHOUT_AN; 7186 } else { 7187 /*leave it blank for now */ 7188 } 7189 7190 return(SOC_E_NONE); 7191 } 7192 /* 7193 * tsce_firmware_br_dfe_enable_get 7194 */ 7195 STATIC int 7196 tsce_firmware_br_dfe_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 7197 { 7198 phymod_phy_access_t *pm_phy; 7199 phymod_firmware_lane_config_t fw_config; 7200 7201 /* just take the value from the first phy */ 7202 if (pmc->phy[0] == NULL) { 7203 return SOC_E_INTERNAL; 7204 } 7205 7206 pm_phy = &pmc->phy[0]->pm_phy; 7207 if (pm_phy == NULL) { 7208 return SOC_E_INTERNAL; 7209 } 7210 7211 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 7212 7213 if (fw_config.ForceBrDfe) { 7214 *value = 1; 7215 } else { 7216 *value = 0; 7217 } 7218 7219 return(SOC_E_NONE); 7220 } 7221 7222 /* 7223 * tsce_firmware_dfe_enable_get 7224 */ 7225 STATIC int 7226 tsce_firmware_dfe_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 7227 { 7228 phymod_phy_access_t *pm_phy; 7229 phymod_firmware_lane_config_t fw_config; 7230 7231 /* just take the value from the first phy */ 7232 if (pmc->phy[0] == NULL) { 7233 return SOC_E_INTERNAL; 7234 } 7235 7236 pm_phy = &pmc->phy[0]->pm_phy; 7237 if (pm_phy == NULL) { 7238 return SOC_E_INTERNAL; 7239 } 7240 7241 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 7242 7243 if (fw_config.DfeOn) { 7244 *value = 1; 7245 } else { 7246 *value = 0; 7247 } 7248 7249 return(SOC_E_NONE); 7250 } 7251 7252 /* 7253 * tsce_firmware_cl72_restart_timeout_enable_get 7254 */ 7255 STATIC int 7256 tsce_firmware_cl72_restart_timeout_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 7257 { 7258 phymod_phy_access_t *pm_phy; 7259 phymod_firmware_lane_config_t fw_config; 7260 7261 /* just take the value from the first phy */ 7262 if (pmc->phy[0] == NULL) { 7263 return SOC_E_INTERNAL; 7264 } 7265 7266 pm_phy = &pmc->phy[0]->pm_phy; 7267 if (pm_phy == NULL) { 7268 return SOC_E_INTERNAL; 7269 } 7270 7271 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 7272 7273 if (fw_config.Cl72RestTO) { 7274 *value = 1; 7275 } else { 7276 *value = 0; 7277 } 7278 7279 return(SOC_E_NONE); 7280 } 7281 7282 /* 7283 * tsce_firmware_cl72_restart_timeout_enable_get 7284 */ 7285 STATIC int 7286 tsce_firmware_cl72_auto_polarity_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 7287 { 7288 phymod_phy_access_t *pm_phy; 7289 phymod_firmware_lane_config_t fw_config; 7290 7291 /* just take the value from the first phy */ 7292 if (pmc->phy[0] == NULL) { 7293 return SOC_E_INTERNAL; 7294 } 7295 7296 pm_phy = &pmc->phy[0]->pm_phy; 7297 if (pm_phy == NULL) { 7298 return SOC_E_INTERNAL; 7299 } 7300 7301 SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(pm_phy, &fw_config)); 7302 7303 if (fw_config.Cl72AutoPolEn) { 7304 *value = 1; 7305 } else { 7306 *value = 0; 7307 } 7308 7309 return(SOC_E_NONE); 7310 } 7311 7312 /* 7313 * tsce_hg2_codec_enable_get 7314 */ 7315 STATIC int 7316 tsce_hg2_codec_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 7317 { 7318 phymod_phy_access_t *pm_phy; 7319 int idx; 7320 phymod_phy_hg2_codec_t local_copy; 7321 7322 7323 /* loop through all cores */ 7324 for (idx = 0; idx < pmc->num_phys; idx++) { 7325 if (pmc->phy[idx] == NULL) { 7326 return(SOC_E_INTERNAL); 7327 } 7328 7329 pm_phy = &pmc->phy[idx]->pm_phy; 7330 if (pm_phy == NULL) { 7331 return(SOC_E_INTERNAL); 7332 } 7333 7334 SOC_IF_ERROR_RETURN(phymod_phy_hg2_codec_control_get(pm_phy, &local_copy)); 7335 7336 switch (local_copy) { 7337 case phymodBcmHG2CodecOff: 7338 *value = SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE_OFF; 7339 break; 7340 case phymodBcmHG2CodecOnWith8ByteIPG: 7341 *value = SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE_ON_WITH_8BYTE_IPG; 7342 break; 7343 case phymodBcmHG2CodecOnWith9ByteIPG: 7344 *value = SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE_ON_WITH_9BYTE_IPG; 7345 break; 7346 default: 7347 *value = SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE_OFF; 7348 break; 7349 } 7350 } 7351 7352 return(SOC_E_NONE); 7353 } 7354 7355 /* 7356 * tsce_tx_ppm_adjust_get 7357 */ 7358 STATIC int 7359 tsce_tx_ppm_adjust_get(soc_phymod_ctrl_t *pmc, uint32 *value) 7360 { 7361 phymod_phy_access_t *pm_phy; 7362 phymod_tx_override_t tx_override; 7363 int idx; 7364 7365 /* loop through all cores */ 7366 for (idx = 0; idx < pmc->num_phys; idx++) { 7367 pm_phy = &pmc->phy[idx]->pm_phy; 7368 7369 if (pm_phy == NULL) { 7370 return SOC_E_INTERNAL; 7371 } 7372 7373 phymod_tx_override_t_init(&tx_override); 7374 SOC_IF_ERROR_RETURN(phymod_phy_tx_override_get(pm_phy, &tx_override)); 7375 *value = tx_override.phase_interpolator.value; 7376 } 7377 return(SOC_E_NONE); 7378 } 7379 7380 /* 7381 * Function: 7382 * phy_tsce_control_get 7383 * Purpose: 7384 * Get current control settings of the PHY. 7385 * Parameters: 7386 * unit - BCM unit number. 7387 * port - Port number. 7388 * type - Control to update 7389 * value - (OUT) Current setting for the control 7390 * Returns: 7391 * SOC_E_NONE 7392 */ 7393 STATIC int 7394 phy_tsce_control_get(int unit, soc_port_t port, soc_phy_control_t type, uint32 *value) 7395 { 7396 int rv; 7397 phy_ctrl_t *pc; 7398 soc_phymod_ctrl_t *pmc; 7399 tsce_config_t *pCfg; 7400 7401 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 7402 return (SOC_E_PARAM); 7403 } 7404 7405 /* locate phy control */ 7406 pc = INT_PHY_SW_STATE(unit, port); 7407 if (pc == NULL) { 7408 return SOC_E_INTERNAL; 7409 } 7410 7411 pmc = &pc->phymod_ctrl; 7412 pCfg = (tsce_config_t *) pc->driver_data; 7413 7414 switch(type) { 7415 case SOC_PHY_CONTROL_INTERFACE: 7416 rv = phy_tsce_interface_get(unit, port, (soc_port_if_t *)value); 7417 break; 7418 /* PREEMPHASIS */ 7419 case SOC_PHY_CONTROL_PREEMPHASIS_LANE0: 7420 rv = tsce_per_lane_preemphasis_get(pmc, 0, value); 7421 break; 7422 case SOC_PHY_CONTROL_PREEMPHASIS_LANE1: 7423 rv = tsce_per_lane_preemphasis_get(pmc, 1, value); 7424 break; 7425 case SOC_PHY_CONTROL_PREEMPHASIS_LANE2: 7426 rv = tsce_per_lane_preemphasis_get(pmc, 2, value); 7427 break; 7428 case SOC_PHY_CONTROL_PREEMPHASIS_LANE3: 7429 rv = tsce_per_lane_preemphasis_get(pmc, 3, value); 7430 break; 7431 case SOC_PHY_CONTROL_PREEMPHASIS: 7432 rv = tsce_preemphasis_get(pmc, value); 7433 break; 7434 case SOC_PHY_CONTROL_TX_FIR_PRE: 7435 /* assume they are all the same as lane 0 */ 7436 rv = tsce_tx_fir_pre_get(pmc, value); 7437 break; 7438 case SOC_PHY_CONTROL_TX_FIR_MAIN: 7439 /* assume they are all the same as lane 0 */ 7440 rv = tsce_tx_fir_main_get(pmc, value); 7441 break; 7442 case SOC_PHY_CONTROL_TX_FIR_POST: 7443 /* assume they are all the same as lane 0 */ 7444 rv = tsce_tx_fir_post_get(pmc, value); 7445 break; 7446 case SOC_PHY_CONTROL_TX_FIR_POST2: 7447 /* assume they are all the same as lane 0 */ 7448 rv = tsce_tx_fir_post2_get(pmc, value); 7449 break; 7450 case SOC_PHY_CONTROL_TX_FIR_POST3: 7451 /* assume they are all the same as lane 0 */ 7452 rv = tsce_tx_fir_post3_get(pmc, value); 7453 break; 7454 7455 /* DRIVER CURRENT */ 7456 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0: 7457 rv = tsce_per_lane_driver_current_get(pmc, 0, value); 7458 break; 7459 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1: 7460 rv = tsce_per_lane_driver_current_get(pmc, 1, value); 7461 break; 7462 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2: 7463 rv = tsce_per_lane_driver_current_get(pmc, 2, value); 7464 break; 7465 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3: 7466 rv = tsce_per_lane_driver_current_get(pmc, 3, value); 7467 break; 7468 case SOC_PHY_CONTROL_DRIVER_CURRENT: 7469 rv = tsce_per_lane_driver_current_get(pmc, 0, value); 7470 break; 7471 7472 /* PRE-DRIVER CURRENT */ 7473 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE0: 7474 rv = SOC_E_UNAVAIL; 7475 break; 7476 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE1: 7477 rv = SOC_E_UNAVAIL; 7478 break; 7479 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE2: 7480 rv = SOC_E_UNAVAIL; 7481 break; 7482 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE3: 7483 rv = SOC_E_UNAVAIL; 7484 break; 7485 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 7486 rv = SOC_E_UNAVAIL; 7487 break; 7488 7489 /* POST2_DRIVER CURRENT */ 7490 case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT: 7491 rv = SOC_E_UNAVAIL; 7492 break; 7493 case SOC_PHY_CONTROL_TX_FIR_DRIVERMODE: 7494 rv = tsce_tx_fir_drivermode_get(pmc, value); 7495 break; 7496 /* TX LANE SQUELCH */ 7497 case SOC_PHY_CONTROL_TX_LANE_SQUELCH: 7498 rv = tsce_tx_lane_squelch_get(pmc, value); 7499 break; 7500 /* RX LANE SQUELCH */ 7501 case SOC_PHY_CONTROL_RX_LANE_SQUELCH: 7502 rv = tsce_rx_lane_squelch_get(pmc, value); 7503 break; 7504 7505 /* RX PEAK FILTER */ 7506 case SOC_PHY_CONTROL_RX_PEAK_FILTER: 7507 rv = tsce_rx_peak_filter_get(pmc, value); 7508 break; 7509 7510 /* RX VGA */ 7511 case SOC_PHY_CONTROL_RX_VGA: 7512 rv = tsce_rx_vga_get(pmc, value); 7513 break; 7514 7515 /* RX TAP */ 7516 case SOC_PHY_CONTROL_RX_TAP1: 7517 rv = tsce_rx_tap_get(pmc, 0, value); 7518 break; 7519 case SOC_PHY_CONTROL_RX_TAP2: 7520 rv = tsce_rx_tap_get(pmc, 1, value); 7521 break; 7522 case SOC_PHY_CONTROL_RX_TAP3: 7523 rv = tsce_rx_tap_get(pmc, 2, value); 7524 break; 7525 case SOC_PHY_CONTROL_RX_TAP4: 7526 rv = tsce_rx_tap_get(pmc, 3, value); 7527 break; 7528 case SOC_PHY_CONTROL_RX_TAP5: 7529 rv = tsce_rx_tap_get(pmc, 4, value); 7530 break; 7531 7532 /* RX SLICER */ 7533 case SOC_PHY_CONTROL_RX_PLUS1_SLICER: 7534 rv = SOC_E_UNAVAIL; 7535 break; 7536 case SOC_PHY_CONTROL_RX_MINUS1_SLICER: 7537 rv = SOC_E_UNAVAIL; 7538 break; 7539 case SOC_PHY_CONTROL_RX_D_SLICER: 7540 rv = SOC_E_UNAVAIL; 7541 break; 7542 7543 /* PHASE INTERPOLATOR */ 7544 case SOC_PHY_CONTROL_PHASE_INTERP: 7545 rv = tsce_pi_control_get(pmc, value); 7546 break; 7547 7548 /* RX SIGNAL DETECT */ 7549 case SOC_PHY_CONTROL_RX_SIGNAL_DETECT: 7550 rv = tsce_rx_signal_detect_get(pmc, value); 7551 break; 7552 case SOC_PHY_CONTROL_RX_SEQ_DONE: 7553 rv = tsce_rx_seq_done_get(pmc, value); 7554 break; 7555 case SOC_PHY_CONTROL_RX_PPM: 7556 rv = tsce_rx_ppm_get(pmc, value); 7557 break; 7558 7559 /* POLARITY */ 7560 case SOC_PHY_CONTROL_RX_POLARITY: 7561 rv = tsce_rx_polarity_get(pmc, &pCfg->phy_polarity_config, value);; 7562 break; 7563 case SOC_PHY_CONTROL_TX_POLARITY: 7564 rv = tsce_tx_polarity_get(pmc, &pCfg->phy_polarity_config, value); 7565 break; 7566 7567 /* CL72 */ 7568 case SOC_PHY_CONTROL_CL72: 7569 rv = tsce_cl72_enable_get(pmc, value); 7570 break; 7571 case SOC_PHY_CONTROL_CL72_STATUS: 7572 rv = tsce_cl72_status_get(pmc, value); 7573 break; 7574 7575 /* FIRMWARE MODE */ 7576 case SOC_PHY_CONTROL_FIRMWARE_MODE: 7577 rv = tsce_firmware_mode_get(pmc, value); 7578 break; 7579 case SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE: 7580 rv = tsce_firmware_dfe_enable_get(pmc, value); 7581 break; 7582 case SOC_PHY_CONTROL_FIRMWARE_BR_DFE_ENABLE: 7583 rv = tsce_firmware_br_dfe_enable_get(pmc, value); 7584 break; 7585 case SOC_PHY_CONTROL_FIRMWARE_CL72_RESTART_TIMEOUT_ENABLE: 7586 rv = tsce_firmware_cl72_restart_timeout_enable_get(pmc, value); 7587 break; 7588 case SOC_PHY_CONTROL_FIRMWARE_CL72_AUTO_POLARITY_ENABLE: 7589 rv = tsce_firmware_cl72_auto_polarity_enable_get(pmc, value); 7590 break; 7591 7592 /* PRBS */ 7593 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL: 7594 rv = tsce_prbs_tx_poly_get(pmc, value); 7595 break; 7596 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA: 7597 rv = tsce_prbs_tx_invert_data_get(pmc, value); 7598 break; 7599 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE: 7600 rv = tsce_prbs_tx_enable_get(pmc, value); 7601 break; 7602 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL: 7603 rv = tsce_prbs_rx_poly_get(pmc, value); 7604 break; 7605 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA: 7606 rv = tsce_prbs_rx_invert_data_get(pmc, value); 7607 break; 7608 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE: 7609 rv = tsce_prbs_rx_enable_get(pmc, value); 7610 break; 7611 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 7612 rv = tsce_prbs_tx_poly_get(pmc, value); 7613 break; 7614 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 7615 rv = tsce_prbs_tx_invert_data_get(pmc, value); 7616 break; 7617 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 7618 rv = tsce_prbs_tx_enable_get(pmc, value); 7619 break; 7620 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 7621 rv = tsce_prbs_rx_enable_get(pmc, value); 7622 break; 7623 case SOC_PHY_CONTROL_PRBS_RX_STATUS: 7624 rv = tsce_prbs_rx_status_get(pmc, value); 7625 break; 7626 7627 /* LOOPBACK */ 7628 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: 7629 rv = tsce_loopback_remote_get(pmc, value); 7630 break; 7631 case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS: 7632 rv = tsce_loopback_remote_get(pmc, value); 7633 /* rv = tsce_loopback_remote_pcs_get(pmc, value); */ 7634 break; 7635 case SOC_PHY_CONTROL_LOOPBACK_PMD: 7636 rv = tsce_loopback_internal_pmd_get(pmc, value); 7637 break; 7638 7639 /* FEC */ 7640 case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION: 7641 rv = tsce_fec_enable_get(pmc, value); 7642 break; 7643 7644 /* TX PATTERN */ 7645 case SOC_PHY_CONTROL_TX_PATTERN_256BIT: 7646 rv = tsce_pattern_get(pmc, &pCfg->pattern); 7647 break; 7648 case SOC_PHY_CONTROL_TX_PATTERN_LENGTH: 7649 rv = tsce_pattern_len_get(pmc, value); 7650 break; 7651 case SOC_PHY_CONTROL_TX_PATTERN_GEN_ENABLE: 7652 rv = tsce_pattern_enable_get(pmc, value); 7653 break; 7654 7655 case SOC_PHY_CONTROL_TX_PATTERN_20BIT: 7656 rv = tsce_pattern_get(pmc, &pCfg->pattern); 7657 break; 7658 7659 /* SCRAMBLER */ 7660 case SOC_PHY_CONTROL_SCRAMBLER: 7661 rv = tsce_scrambler_get(pmc, port, value); 7662 break; 7663 case SOC_PHY_CONTROL_LANE_SWAP: 7664 rv = tsce_lane_map_get(pmc, value); 7665 break; 7666 /* HG codec config */ 7667 case SOC_PHY_CONTROL_HG2_BCM_CODEC_ENABLE: 7668 rv = tsce_hg2_codec_enable_get(pmc, value); 7669 break; 7670 /* EEE */ 7671 case SOC_PHY_CONTROL_EEE: 7672 rv = tsce_eee_get(pmc, value); 7673 break; 7674 7675 /* UNAVAIL */ 7676 7677 #if 0 7678 /* BERT */ 7679 case SOC_PHY_CONTROL_BERT_TX_PACKETS: /* fall through */ 7680 case SOC_PHY_CONTROL_BERT_RX_PACKETS: /* fall through */ 7681 case SOC_PHY_CONTROL_BERT_RX_ERROR_BITS: /* fall through */ 7682 case SOC_PHY_CONTROL_BERT_RX_ERROR_BYTES: /* fall through */ 7683 case SOC_PHY_CONTROL_BERT_RX_ERROR_PACKETS: /* fall through */ 7684 case SOC_PHY_CONTROL_BERT_PATTERN: /* fall through */ 7685 case SOC_PHY_CONTROL_BERT_PACKET_SIZE: /* fall through */ 7686 case SOC_PHY_CONTROL_BERT_IPG: /* fall through */ 7687 rv = SOC_E_NONE; 7688 break; 7689 7690 /* CUSTOM */ 7691 case SOC_PHY_CONTROL_CUSTOM1: 7692 /* Obsolete ?? 7693 *value = DEV_CFG_PTR(pc)->custom1; 7694 rv = SOC_E_NONE; */ 7695 break; 7696 7697 /* SOFTWARE RX LOS */ 7698 case SOC_PHY_CONTROL_SOFTWARE_RX_LOS: 7699 /* Was 7700 *value = DEV_CFG_PTR(pc)->sw_rx_los.enable ; */ 7701 rv = SOC_E_NONE ; 7702 break ; 7703 7704 /* UNAVAIL */ 7705 #endif 7706 case SOC_PHY_CONTROL_LINKDOWN_TRANSMIT: 7707 rv = SOC_E_NONE ; 7708 break ; 7709 case SOC_PHY_CONTROL_PCS_SPEED_ST_ENTRY: 7710 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamEntry, value) ; 7711 rv = SOC_E_NONE ; 7712 break ; 7713 case SOC_PHY_CONTROL_PCS_SPEED_ST_HCD: 7714 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamHCD, value) ; 7715 rv = SOC_E_NONE ; 7716 break ; 7717 /* 7718 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CLEAR: 7719 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamClear, value) ; 7720 rv = SOC_E_NONE ; 7721 break ; 7722 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PLL_DIVIDER: 7723 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamPllDiv, value) ; 7724 rv = SOC_E_NONE ; 7725 break ; 7726 case SOC_PHY_CONTROL_PCS_SPEED_ST_PLL_DIVIDER: 7727 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamPllDiv, value) ; 7728 rv = SOC_E_NONE ; 7729 break ; 7730 */ 7731 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PMA_OS: 7732 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamPmaOS, value) ; 7733 rv = SOC_E_NONE ; 7734 break ; 7735 case SOC_PHY_CONTROL_PCS_SPEED_ST_PMA_OS: 7736 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamPmaOS, value) ; 7737 rv = SOC_E_NONE ; 7738 break ; 7739 case SOC_PHY_CONTROL_PCS_SPEED_HTO_SCR_MODE: 7740 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamScramble, value) ; 7741 rv = SOC_E_NONE ; 7742 break ; 7743 case SOC_PHY_CONTROL_PCS_SPEED_ST_SCR_MODE: 7744 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamScramble, value) ; 7745 rv = SOC_E_NONE ; 7746 break ; 7747 case SOC_PHY_CONTROL_PCS_SPEED_HTO_ENCODE_MODE: 7748 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamEncode, value) ; 7749 rv = SOC_E_NONE ; 7750 break ; 7751 case SOC_PHY_CONTROL_PCS_SPEED_ST_ENCODE_MODE: 7752 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamEncode, value) ; 7753 rv = SOC_E_NONE ; 7754 break ; 7755 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CL48_CHECK_END: 7756 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamCl48CheckEnd, value) ; 7757 rv = SOC_E_NONE ; 7758 break ; 7759 case SOC_PHY_CONTROL_PCS_SPEED_ST_CL48_CHECK_END: 7760 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamCl48CheckEnd, value) ; 7761 rv = SOC_E_NONE ; 7762 break ; 7763 case SOC_PHY_CONTROL_PCS_SPEED_HTO_BLK_SYNC_MODE: 7764 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamBlkSync, value) ; 7765 rv = SOC_E_NONE ; 7766 break ; 7767 case SOC_PHY_CONTROL_PCS_SPEED_ST_BLK_SYNC_MODE: 7768 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamBlkSync, value) ; 7769 rv = SOC_E_NONE ; 7770 break ; 7771 case SOC_PHY_CONTROL_PCS_SPEED_HTO_REORDER_MODE: 7772 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamReorder, value) ; 7773 rv = SOC_E_NONE ; 7774 break ; 7775 case SOC_PHY_CONTROL_PCS_SPEED_ST_REORDER_MODE: 7776 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamReorder, value) ; 7777 rv = SOC_E_NONE ; 7778 break ; 7779 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CL36_EN: 7780 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamCl36Enable, value) ; 7781 rv = SOC_E_NONE ; 7782 break ; 7783 case SOC_PHY_CONTROL_PCS_SPEED_ST_CL36_EN: 7784 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamCl36Enable, value) ; 7785 rv = SOC_E_NONE ; 7786 break ; 7787 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DESCR1_MODE: 7788 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDescr1, value) ; 7789 rv = SOC_E_NONE ; 7790 break ; 7791 case SOC_PHY_CONTROL_PCS_SPEED_ST_DESCR1_MODE: 7792 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDescr1, value) ; 7793 rv = SOC_E_NONE ; 7794 break ; 7795 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DEC1_MODE: 7796 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDecode1, value) ; 7797 rv = SOC_E_NONE ; 7798 break ; 7799 case SOC_PHY_CONTROL_PCS_SPEED_ST_DEC1_MODE: 7800 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDecode1, value) ; 7801 rv = SOC_E_NONE ; 7802 break ; 7803 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DESKEW_MODE: 7804 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDeskew, value) ; 7805 rv = SOC_E_NONE ; 7806 break ; 7807 case SOC_PHY_CONTROL_PCS_SPEED_ST_DESKEW_MODE: 7808 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDeskew, value) ; 7809 rv = SOC_E_NONE ; 7810 break ; 7811 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DESC2_MODE: 7812 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDescr2, value) ; 7813 rv = SOC_E_NONE ; 7814 break ; 7815 case SOC_PHY_CONTROL_PCS_SPEED_ST_DESC2_MODE: 7816 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDescr2, value) ; 7817 rv = SOC_E_NONE ; 7818 break ; 7819 case SOC_PHY_CONTROL_PCS_SPEED_HTO_DESC2_BYTE_DEL: 7820 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamDescr2ByteDel, value) ; 7821 rv = SOC_E_NONE ; 7822 break ; 7823 case SOC_PHY_CONTROL_PCS_SPEED_ST_DESC2_BYTE_DEL: 7824 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamDescr2ByteDel, value) ; 7825 rv = SOC_E_NONE ; 7826 break ; 7827 case SOC_PHY_CONTROL_PCS_SPEED_HTO_BRCM64B66_DESCR: 7828 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamBrcm64B66, value) ; 7829 rv = SOC_E_NONE ; 7830 break ; 7831 case SOC_PHY_CONTROL_PCS_SPEED_ST_BRCM64B66_DESCR: 7832 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamBrcm64B66, value) ; 7833 rv = SOC_E_NONE ; 7834 break ; 7835 case SOC_PHY_CONTROL_PCS_SPEED_HTO_SGMII_MODE: 7836 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamSgmii, value) ; 7837 rv = SOC_E_NONE ; 7838 break ; 7839 case SOC_PHY_CONTROL_PCS_SPEED_ST_SGMII_MODE: 7840 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamSgmii, value) ; 7841 rv = SOC_E_NONE ; 7842 break ; 7843 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CLKCNT0: 7844 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamClkcnt0, value) ; 7845 rv = SOC_E_NONE ; 7846 break ; 7847 case SOC_PHY_CONTROL_PCS_SPEED_ST_CLKCNT0: 7848 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamClkcnt0, value) ; 7849 rv = SOC_E_NONE ; 7850 break ; 7851 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CLKCNT1: 7852 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamClkcnt1, value) ; 7853 rv = SOC_E_NONE ; 7854 break ; 7855 case SOC_PHY_CONTROL_PCS_SPEED_ST_CLKCNT1: 7856 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamClkcnt1, value) ; 7857 rv = SOC_E_NONE ; 7858 break ; 7859 case SOC_PHY_CONTROL_PCS_SPEED_HTO_LPCNT0: 7860 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamLpcnt0, value) ; 7861 rv = SOC_E_NONE ; 7862 break ; 7863 case SOC_PHY_CONTROL_PCS_SPEED_ST_LPCNT0: 7864 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamLpcnt0, value) ; 7865 rv = SOC_E_NONE ; 7866 break ; 7867 case SOC_PHY_CONTROL_PCS_SPEED_HTO_LPCNT1: 7868 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamLpcnt1, value) ; 7869 rv = SOC_E_NONE ; 7870 break ; 7871 case SOC_PHY_CONTROL_PCS_SPEED_ST_LPCNT1: 7872 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamLpcnt1, value) ; 7873 rv = SOC_E_NONE ; 7874 break ; 7875 case SOC_PHY_CONTROL_PCS_SPEED_HTO_MAC_CGC: 7876 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamMacCGC, value) ; 7877 rv = SOC_E_NONE ; 7878 break ; 7879 case SOC_PHY_CONTROL_PCS_SPEED_ST_MAC_CGC: 7880 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamMacCGC, value) ; 7881 rv = SOC_E_NONE ; 7882 break ; 7883 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PCS_REPCNT: 7884 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamRepcnt, value) ; 7885 rv = SOC_E_NONE ; 7886 break ; 7887 case SOC_PHY_CONTROL_PCS_SPEED_ST_PCS_REPCNT: 7888 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamRepcnt, value) ; 7889 rv = SOC_E_NONE ; 7890 break ; 7891 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PCS_CREDTEN: 7892 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamCrdtEn, value) ; 7893 rv = SOC_E_NONE ; 7894 break ; 7895 case SOC_PHY_CONTROL_PCS_SPEED_ST_PCS_CREDTEN: 7896 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamCrdtEn, value) ; 7897 rv = SOC_E_NONE ; 7898 break ; 7899 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PCS_CLKCNT: 7900 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamPcsClkcnt, value) ; 7901 rv = SOC_E_NONE ; 7902 break ; 7903 case SOC_PHY_CONTROL_PCS_SPEED_ST_PCS_CLKCNT: 7904 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamPcsClkcnt, value) ; 7905 rv = SOC_E_NONE ; 7906 break ; 7907 case SOC_PHY_CONTROL_PCS_SPEED_HTO_PCS_CGC: 7908 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamPcsCGC, value) ; 7909 rv = SOC_E_NONE ; 7910 break ; 7911 case SOC_PHY_CONTROL_PCS_SPEED_ST_PCS_CGC: 7912 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamPcsCGC, value) ; 7913 rv = SOC_E_NONE ; 7914 break ; 7915 case SOC_PHY_CONTROL_PCS_SPEED_HTO_CL72_EN: 7916 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeHTO, phymodPcsUserSpeedParamCl72En, value) ; 7917 rv = SOC_E_NONE ; 7918 break ; 7919 case SOC_PHY_CONTROL_PCS_SPEED_ST_CL72_EN: 7920 tsce_user_speed_get(pmc, pCfg->core_device_aux_modes, phymodPcsUserSpeedModeST, phymodPcsUserSpeedParamCl72En, value) ; 7921 rv = SOC_E_NONE ; 7922 break ; 7923 case SOC_PHY_CONTROL_UNRELIABLE_LOS: 7924 rv = tsce_unreliable_los_get(pmc, value) ; 7925 break ; 7926 case SOC_PHY_CONTROL_TX_PPM_ADJUST: 7927 rv = tsce_tx_ppm_adjust_get(pmc, value); 7928 break; 7929 case SOC_PHY_CONTROL_PARALLEL_DETECTION: 7930 *value = pCfg->pdetect1000x; 7931 rv = SOC_E_NONE ; 7932 break; 7933 case SOC_PHY_CONTROL_PARALLEL_DETECTION_10G: 7934 *value = pCfg->pdetect10g; 7935 rv = SOC_E_NONE ; 7936 break; 7937 default: 7938 rv = SOC_E_UNAVAIL; 7939 break; 7940 } 7941 return rv; 7942 } 7943 7944 /* 7945 * Function: 7946 * phy_tsce_per_lane_control_set 7947 * Purpose: 7948 * Configure PHY device specific control fucntion. 7949 * Parameters: 7950 * unit - StrataSwitch unit #. 7951 * port - StrataSwitch port #. 7952 * lane - lane number 7953 * type - Control to update 7954 * value - New setting for the control 7955 * Returns: 7956 * SOC_E_NONE 7957 */ 7958 STATIC int 7959 phy_tsce_per_lane_control_set(int unit, soc_port_t port, int lane, soc_phy_control_t type, uint32 value) 7960 { 7961 int rv; 7962 phy_ctrl_t *pc; 7963 soc_phymod_ctrl_t *pmc; 7964 tsce_config_t *pCfg; 7965 7966 /* locate phy control, phymod control, and the configuration data */ 7967 pc = INT_PHY_SW_STATE(unit, port); 7968 if (pc == NULL) { 7969 return SOC_E_INTERNAL; 7970 } 7971 pmc = &pc->phymod_ctrl; 7972 pCfg = (tsce_config_t *) pc->driver_data; 7973 7974 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 7975 return SOC_E_PARAM; 7976 } 7977 7978 switch(type) { 7979 case SOC_PHY_CONTROL_PREEMPHASIS: 7980 rv = tsce_per_lane_preemphasis_set(pmc, pCfg, lane, value); 7981 break; 7982 case SOC_PHY_CONTROL_DRIVER_CURRENT: 7983 rv = tsce_per_lane_driver_current_set(pmc, pCfg, lane, value); 7984 break; 7985 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 7986 rv = SOC_E_UNAVAIL; 7987 break; 7988 case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT: 7989 rv = SOC_E_UNAVAIL; 7990 break; 7991 case SOC_PHY_CONTROL_TX_FIR_DRIVERMODE: 7992 rv = tsce_per_lane_tx_fir_drivermode_set(pmc, pCfg, lane, value); 7993 break; 7994 case SOC_PHY_CONTROL_RX_TAP1: 7995 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 0 /* tap */, 1 /* enable */, value); 7996 break; 7997 case SOC_PHY_CONTROL_RX_TAP1_RELEASE: 7998 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 0 /* tap */, 0 /* release */, 0x8000); 7999 break; 8000 case SOC_PHY_CONTROL_RX_TAP2: 8001 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 1 /* tap */, 1 /* enable */, value); 8002 break; 8003 case SOC_PHY_CONTROL_RX_TAP2_RELEASE: 8004 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 1 /* tap */, 0 /* release */, 0x8000); 8005 break; 8006 case SOC_PHY_CONTROL_RX_TAP3: 8007 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 2 /* tap */, 1 /* enable */, value); 8008 break; 8009 case SOC_PHY_CONTROL_RX_TAP3_RELEASE: 8010 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 2 /* tap */, 0 /* release */, 0x8000); 8011 break; 8012 case SOC_PHY_CONTROL_RX_TAP4: 8013 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 3 /* tap */, 1 /* enable */, value); 8014 break; 8015 case SOC_PHY_CONTROL_RX_TAP4_RELEASE: 8016 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 3 /* tap */, 0 /* release */, 0x8000); 8017 break; 8018 case SOC_PHY_CONTROL_RX_TAP5: 8019 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 4 /* tap */, 1 /* enable */, value); 8020 break; 8021 case SOC_PHY_CONTROL_RX_TAP5_RELEASE: 8022 rv = tsce_per_lane_rx_dfe_tap_control_set (pmc, lane, 4 /* tap */, 0 /* release */, 0x8000); 8023 break; 8024 8025 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 8026 rv = tsce_per_lane_prbs_poly_set(pmc, lane, value); 8027 break; 8028 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 8029 rv = tsce_per_lane_prbs_tx_invert_data_set(pmc, lane, value); 8030 break; 8031 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 8032 /* TX_ENABLE does both tx and rx */ 8033 rv = tsce_per_lane_prbs_tx_enable_set(pmc, lane, value); 8034 break; 8035 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 8036 rv = SOC_E_NONE; 8037 break; 8038 case SOC_PHY_CONTROL_RX_PEAK_FILTER: 8039 rv = tsce_per_lane_rx_peak_filter_set(pmc, lane, 1 /* enable */, value); 8040 break; 8041 case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER: 8042 rv = tsce_per_lane_rx_low_freq_filter_set(pmc, lane, value); 8043 break; 8044 case SOC_PHY_CONTROL_RX_VGA: 8045 rv = tsce_per_lane_rx_vga_set(pmc, lane, 1 /* enable */, value); 8046 break; 8047 case SOC_PHY_CONTROL_RX_VGA_RELEASE: 8048 rv = tsce_per_lane_rx_vga_set(pmc, lane, 0 /* release */, 0x8000); 8049 break; 8050 case SOC_PHY_CONTROL_RX_PLUS1_SLICER: 8051 rv = SOC_E_UNAVAIL; 8052 break; 8053 case SOC_PHY_CONTROL_RX_MINUS1_SLICER: 8054 rv = SOC_E_UNAVAIL; 8055 break; 8056 case SOC_PHY_CONTROL_RX_D_SLICER: 8057 rv = SOC_E_UNAVAIL; 8058 break; 8059 default: 8060 rv = SOC_E_UNAVAIL; 8061 break; 8062 } 8063 8064 return rv; 8065 } 8066 8067 /* 8068 * Function: 8069 * phy_tsce_per_lane_control_get 8070 * Purpose: 8071 * Configure PHY device specific control fucntion. 8072 * Parameters: 8073 * unit - StrataSwitch unit #. 8074 * port - StrataSwitch port #. 8075 * lane - lane number 8076 * type - Control to update 8077 * value - New setting for the control 8078 * Returns: 8079 * SOC_E_NONE 8080 */ 8081 STATIC int 8082 phy_tsce_per_lane_control_get(int unit, soc_port_t port, int lane, 8083 soc_phy_control_t type, uint32 *value) 8084 { 8085 int rv; 8086 phy_ctrl_t *pc; 8087 soc_phymod_ctrl_t *pmc; 8088 8089 /* locate phy control, phymod control, and the configuration data */ 8090 pc = INT_PHY_SW_STATE(unit, port); 8091 if (pc == NULL) { 8092 return SOC_E_INTERNAL; 8093 } 8094 pmc = &pc->phymod_ctrl; 8095 8096 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 8097 return SOC_E_PARAM; 8098 } 8099 8100 switch(type) { 8101 8102 case SOC_PHY_CONTROL_PREEMPHASIS: 8103 rv = tsce_per_lane_preemphasis_get(pmc, lane, value); 8104 break; 8105 case SOC_PHY_CONTROL_DRIVER_CURRENT: 8106 rv = tsce_per_lane_driver_current_get(pmc, lane, value); 8107 break; 8108 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 8109 rv = SOC_E_UNAVAIL; 8110 break; 8111 case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT: 8112 rv = SOC_E_UNAVAIL; 8113 break; 8114 case SOC_PHY_CONTROL_TX_FIR_DRIVERMODE: 8115 rv = tsce_per_lane_tx_fir_drivermode_get(pmc, lane, value); 8116 break; 8117 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 8118 rv = tsce_per_lane_prbs_poly_get(pmc, lane, value); 8119 break; 8120 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 8121 rv = tsce_per_lane_prbs_tx_invert_data_get(pmc, lane, value); 8122 break; 8123 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 8124 rv = tsce_per_lane_prbs_tx_enable_get(pmc, lane, value); 8125 break; 8126 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 8127 rv = tsce_per_lane_prbs_rx_enable_get(pmc, lane, value); 8128 break; 8129 case SOC_PHY_CONTROL_PRBS_RX_STATUS: 8130 rv = tsce_per_lane_prbs_rx_status_get(pmc, lane, value); 8131 break; 8132 case SOC_PHY_CONTROL_RX_PEAK_FILTER: 8133 rv = tsce_per_lane_rx_peak_filter_get(pmc, lane, value); 8134 break; 8135 case SOC_PHY_CONTROL_RX_VGA: 8136 rv = tsce_per_lane_rx_vga_get(pmc, lane, value); 8137 break; 8138 case SOC_PHY_CONTROL_RX_TAP1: 8139 rv = tsce_per_lane_rx_dfe_tap_control_get(pmc, lane, 0, value); 8140 break; 8141 case SOC_PHY_CONTROL_RX_TAP2: 8142 rv = tsce_per_lane_rx_dfe_tap_control_get(pmc, lane, 1, value); 8143 break; 8144 case SOC_PHY_CONTROL_RX_TAP3: 8145 rv = tsce_per_lane_rx_dfe_tap_control_get(pmc, lane, 2, value); 8146 break; 8147 case SOC_PHY_CONTROL_RX_TAP4: 8148 rv = tsce_per_lane_rx_dfe_tap_control_get(pmc, lane, 3, value); 8149 break; 8150 case SOC_PHY_CONTROL_RX_TAP5: 8151 rv = tsce_per_lane_rx_dfe_tap_control_get(pmc, lane, 4, value); 8152 break; 8153 case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER: 8154 rv = tsce_per_lane_rx_low_freq_filter_get(pmc, lane, value); 8155 break; 8156 case SOC_PHY_CONTROL_RX_PLUS1_SLICER: 8157 rv = SOC_E_UNAVAIL; 8158 break; 8159 case SOC_PHY_CONTROL_RX_MINUS1_SLICER: 8160 rv = SOC_E_UNAVAIL; 8161 break; 8162 case SOC_PHY_CONTROL_RX_D_SLICER: 8163 rv = SOC_E_UNAVAIL; 8164 break; 8165 case SOC_PHY_CONTROL_RX_SIGNAL_DETECT: 8166 rv = tsce_per_lane_rx_signal_detect_get(pmc, lane, value); 8167 break; 8168 case SOC_PHY_CONTROL_RX_SEQ_DONE: 8169 rv = tsce_per_lane_rx_seq_done_get(pmc, lane, value); 8170 break; 8171 default: 8172 rv = SOC_E_UNAVAIL; 8173 break; 8174 } 8175 return rv; 8176 } 8177 8178 /* 8179 * Function: 8180 * phy_tsce_reg_read 8181 * Purpose: 8182 * Routine to read PHY register 8183 * Parameters: 8184 * unit - BCM unit number 8185 * port - Port number 8186 * flags - Flags which specify the register type 8187 * phy_reg_addr - Encoded register address 8188 * phy_data - (OUT) Value read from PHY register 8189 * Note: 8190 * This register read function is not thread safe. Higher level 8191 * function that calls this function must obtain a per port lock 8192 * to avoid overriding register page mapping between threads. 8193 */ 8194 STATIC int 8195 phy_tsce_reg_read(int unit, soc_port_t port, uint32 flags, 8196 uint32 phy_reg_addr, uint32 *phy_reg_data) 8197 { 8198 phy_ctrl_t *pc; 8199 soc_phymod_ctrl_t *pmc; 8200 phymod_phy_access_t *pm_phy; 8201 int idx; 8202 8203 pc = INT_PHY_SW_STATE(unit, port); 8204 if (pc == NULL) { 8205 return SOC_E_INTERNAL; 8206 } 8207 8208 pmc = &pc->phymod_ctrl; 8209 idx = pmc->main_phy ; 8210 pm_phy = &pmc->phy[idx]->pm_phy; 8211 8212 return phymod_phy_reg_read(pm_phy, phy_reg_addr, phy_reg_data); 8213 } 8214 8215 /* 8216 * Function: 8217 * phy_tsce_reg_write 8218 * Purpose: 8219 * Routine to write PHY register 8220 * Parameters: 8221 * uint - BCM unit number 8222 * pc - PHY state 8223 * flags - Flags which specify the register type 8224 * phy_reg_addr - Encoded register address 8225 * phy_data - Value write to PHY register 8226 * Note: 8227 * This register read function is not thread safe. Higher level 8228 * function that calls this function must obtain a per port lock 8229 * to avoid overriding register page mapping between threads. 8230 */ 8231 STATIC int 8232 phy_tsce_reg_write(int unit, soc_port_t port, uint32 flags, 8233 uint32 phy_reg_addr, uint32 phy_reg_data) 8234 { 8235 phy_ctrl_t *pc; 8236 soc_phymod_ctrl_t *pmc; 8237 phymod_phy_access_t *pm_phy; 8238 int idx; 8239 8240 pc = INT_PHY_SW_STATE(unit, port); 8241 if (pc == NULL) { 8242 return SOC_E_INTERNAL; 8243 } 8244 8245 pmc = &pc->phymod_ctrl; 8246 for (idx = 0; idx < pmc->num_phys; idx++) { 8247 pm_phy = &pmc->phy[idx]->pm_phy; 8248 SOC_IF_ERROR_RETURN 8249 (phymod_phy_reg_write(pm_phy, phy_reg_addr, phy_reg_data)); 8250 } 8251 return SOC_E_NONE; 8252 } 8253 8254 /* 8255 * Function: 8256 * phy_tsce_reg_modify 8257 * Purpose: 8258 * Routine to write PHY register 8259 * Parameters: 8260 * uint - BCM unit number 8261 * pc - PHY state 8262 * flags - Flags which specify the register type 8263 * phy_reg_addr - Encoded register address 8264 * phy_mo_data - New value for the bits specified in phy_mo_mask 8265 * phy_mo_mask - Bit mask to modify 8266 * Note: 8267 * This function is not thread safe. Higher level 8268 * function that calls this function must obtain a per port lock 8269 * to avoid overriding register page mapping between threads. 8270 */ 8271 STATIC int 8272 phy_tsce_reg_modify(int unit, soc_port_t port, uint32 flags, 8273 uint32 phy_reg_addr, uint32 phy_data, 8274 uint32 phy_data_mask) 8275 { 8276 phy_ctrl_t *pc; 8277 soc_phymod_ctrl_t *pmc; 8278 phymod_phy_access_t *pm_phy; 8279 uint32 data32, tmp; 8280 int idx; 8281 8282 pc = INT_PHY_SW_STATE(unit, port); 8283 if (pc == NULL) { 8284 return SOC_E_INTERNAL; 8285 } 8286 8287 pmc = &pc->phymod_ctrl; 8288 for (idx = 0; idx < pmc->num_phys; idx++) { 8289 pm_phy = &pmc->phy[idx]->pm_phy; 8290 SOC_IF_ERROR_RETURN 8291 (phymod_phy_reg_read(pm_phy, phy_reg_addr, &data32)); 8292 tmp = data32; 8293 data32 &= ~(phy_data_mask); 8294 data32 |= (phy_data & phy_data_mask); 8295 if (data32 != tmp) { 8296 SOC_IF_ERROR_RETURN 8297 (phymod_phy_reg_write(pm_phy, phy_reg_addr, data32)); 8298 } 8299 } 8300 return SOC_E_NONE; 8301 } 8302 8303 STATIC int 8304 _tsce_device_destroy(temod_device_aux_modes_t *device) 8305 { 8306 if (device == NULL) { 8307 return SOC_E_PARAM; 8308 } 8309 sal_free(device); 8310 8311 return SOC_E_NONE; 8312 } 8313 8314 STATIC void 8315 phy_tsce_cleanup(soc_phymod_ctrl_t *pmc) 8316 { 8317 int idx; 8318 soc_phymod_phy_t *phy; 8319 soc_phymod_core_t *core; 8320 temod_device_aux_modes_t *device ; 8321 8322 for (idx = 0; idx < pmc->num_phys ; idx++) { 8323 phy = pmc->phy[idx]; 8324 if (phy == NULL) { 8325 LOG_WARN(BSL_LS_SOC_PHY, 8326 (BSL_META_U(pmc->unit, 8327 "phy object is empty"))); 8328 continue; 8329 } 8330 8331 core = phy->core; 8332 /* Destroy core object if not used anymore */ 8333 if (core && core->ref_cnt) { 8334 if (--core->ref_cnt == 0) { 8335 device = (temod_device_aux_modes_t *)core->device_aux_modes ; 8336 PHYMOD_VDBG(TEMOD_DBG_MEM, NULL,("clean_up device=%p core_p=%p\n", (void *)device, (void *)core)) ; 8337 _tsce_device_destroy(device) ; 8338 soc_phymod_core_destroy(pmc->unit, core); 8339 } 8340 } 8341 8342 /* Destroy phy object */ 8343 if (phy) { 8344 PHYMOD_VDBG(TEMOD_DBG_MEM, NULL,("clean_up phy=%p\n", (void *)phy)) ; 8345 soc_phymod_phy_destroy(pmc->unit, phy); 8346 } 8347 } 8348 pmc->num_phys = 0; 8349 } 8350 8351 STATIC void 8352 phy_tsce_core_init(phy_ctrl_t *pc, soc_phymod_core_t *core, 8353 phymod_bus_t *core_bus, uint32 core_addr) 8354 { 8355 phymod_core_access_t *pm_core; 8356 phymod_access_t *pm_acc; 8357 8358 core->unit = pc->unit; 8359 core->port = pc->port; 8360 core->read = pc->read; 8361 core->write = pc->write; 8362 core->wrmask = pc->wrmask; 8363 8364 pm_core = &core->pm_core; 8365 phymod_core_access_t_init(pm_core); 8366 pm_acc = &pm_core->access; 8367 phymod_access_t_init(pm_acc); 8368 PHYMOD_ACC_USER_ACC(pm_acc) = core; 8369 PHYMOD_ACC_BUS(pm_acc) = core_bus; 8370 PHYMOD_ACC_ADDR(pm_acc) = core_addr; 8371 8372 if (soc_property_port_get(pc->unit, pc->port, "tsce_sim", 0) == 45) { 8373 PHYMOD_ACC_F_CLAUSE45_SET(pm_acc); 8374 } 8375 8376 if (SOC_IS_ARDON(core->unit)) { 8377 PHYMOD_ACC_DEVAD(pm_acc) = 0 | PHYMOD_ACC_DEVAD_FORCE_MASK; 8378 if ((soc_property_port_get(pc->unit, pc->port, "port_phy_clause", 22) == 45)) { 8379 PHYMOD_ACC_F_CLAUSE45_SET(pm_acc); 8380 } 8381 } 8382 8383 return; 8384 } 8385 8386 STATIC int 8387 _tsce_device_create_attach(soc_phymod_core_t *core, uint32_t core_id) 8388 { 8389 temod_device_aux_modes_t *new_device ; 8390 new_device = sal_alloc(sizeof(temod_device_aux_modes_t), "temod_device_aux_modes"); 8391 if (new_device == NULL) { 8392 return SOC_E_MEMORY; 8393 } 8394 sal_memset(new_device, 0 ,sizeof(temod_device_aux_modes_t)); 8395 8396 new_device->core_id = core_id ; 8397 core->device_aux_modes = (void *)new_device ; 8398 return SOC_E_NONE; 8399 } 8400 8401 /* 8402 * Function: 8403 * phy_tsce_probe 8404 * Purpose: 8405 * xx 8406 * Parameters: 8407 * pc->phy_id (IN) 8408 * pc->unit (IN) 8409 * pc->port (IN) 8410 * pc->size (OUT) - memory required by phy port 8411 * pc->dev_name (OUT) - set to port device name 8412 * 8413 * Note: 8414 */ 8415 STATIC int 8416 phy_tsce_probe(int unit, phy_ctrl_t *pc) 8417 { 8418 int rv, idx; 8419 uint32 lane_map[3], num_phys, core_id, phy_id, found; 8420 phymod_bus_t core_bus; 8421 phymod_dispatch_type_t phy_type; 8422 phymod_core_access_t *pm_core; 8423 phymod_phy_access_t *pm_phy; 8424 phymod_access_t *pm_acc; 8425 soc_phymod_ctrl_t *pmc; 8426 soc_phymod_phy_t *phy; 8427 soc_phymod_core_t *core; 8428 soc_phymod_core_t core_probe; 8429 soc_info_t *si; 8430 phyident_core_info_t core_info[8]; 8431 int array_max = 8; 8432 int array_size = 0; 8433 int port; 8434 int phy_port; /* physical port number */ 8435 soc_100g_lane_config_t s100g_config ; 8436 8437 if (SOC_IS_ARDON(unit)) { 8438 pc->flags |= ARDON_FABRIC_INIT_START; 8439 } 8440 8441 /* Initialize PHY bus */ 8442 SOC_IF_ERROR_RETURN(phymod_bus_t_init(&core_bus)); 8443 if (SOC_IS_ARDON(unit)) { 8444 core_bus.bus_name = "eagle_sim"; 8445 core_bus.read = _tsce_reg_read; 8446 core_bus.write = _tsce_reg_write; 8447 } else { 8448 core_bus.bus_name = "tsce_sim"; 8449 core_bus.read = _tsce_reg_read; 8450 core_bus.write = _tsce_reg_write; 8451 } 8452 8453 s100g_config = SOC_LANE_CONFIG_100G_4_4_2 ; 8454 /* Configure PHY bus properties */ 8455 if (pc->wrmask) { 8456 PHYMOD_BUS_CAP_WR_MODIFY_SET(&core_bus); 8457 PHYMOD_BUS_CAP_LANE_CTRL_SET(&core_bus); 8458 } 8459 8460 port = pc->port; 8461 pmc = &pc->phymod_ctrl; 8462 si = &SOC_INFO(unit); 8463 if (soc_feature(unit, soc_feature_logical_port_num)) { 8464 phy_port = si->port_l2p_mapping[port]; 8465 } else { 8466 phy_port = port; 8467 } 8468 8469 /* Install clean up function */ 8470 pmc->unit = pc->unit; 8471 pmc->cleanup = phy_tsce_cleanup; 8472 pmc->symbols = &bcmi_tsce_xgxs_symbols; 8473 pmc->main_phy= 0; 8474 8475 8476 if (SOC_IS_GREYHOUND(unit)) { 8477 int i, blk; 8478 blk = -1; 8479 pc->lane_num = (phy_port + 2) % 4; 8480 for (i=0; i< SOC_DRIVER(unit)->port_num_blktype; i++){ 8481 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 8482 if (PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), port)){ 8483 break; 8484 } 8485 } 8486 if (blk == -1) { 8487 pc->chip_num = -1; 8488 } else { 8489 pc->chip_num = SOC_BLOCK_NUMBER(unit, blk); 8490 } 8491 } else if(SOC_IS_TD2P_TT2P(unit)) { 8492 s100g_config = si->port_100g_lane_config[port] ; 8493 pmc->main_phy = si->port_fallback_lane[port] ; 8494 } else if(SOC_IS_ARDON(unit)) { 8495 pc->lane_num = SOC_PORT_BINDEX(unit, phy_port) % 4; 8496 pc->chip_num = SOC_BLOCK_NUMBER(unit, SOC_PORT_BLOCK(unit, phy_port)); 8497 } else { 8498 pc->lane_num = SOC_PORT_BINDEX(unit, phy_port); 8499 pc->chip_num = SOC_BLOCK_NUMBER(unit, SOC_PORT_BLOCK(unit, phy_port)); 8500 } 8501 8502 /* request memory for the configuration structure */ 8503 pc->size = sizeof(tsce_config_t); 8504 8505 /* Bit N corresponds to lane N in lane_map */ 8506 lane_map[0] = 0xf; 8507 lane_map[1] = 0 ; 8508 lane_map[2] = 0 ; 8509 num_phys = 1; 8510 switch (si->port_num_lanes[port]) { 8511 case 12: 8512 num_phys = 3; 8513 pc->phy_mode = PHYCTRL_MULTI_CORE_PORT; 8514 lane_map[1] = 0xf ; 8515 lane_map[2] = 0xf ; 8516 break; 8517 case 10: 8518 num_phys = 3; 8519 pc->phy_mode = PHYCTRL_MULTI_CORE_PORT; 8520 /* SOC_IS_TRIDENT2PLUS(unit)*/ 8521 switch(s100g_config) { 8522 case SOC_LANE_CONFIG_100G_4_4_2: 8523 lane_map[1] = 0xf ; 8524 lane_map[2] = 0x3 ; 8525 break ; 8526 case SOC_LANE_CONFIG_100G_2_4_4: 8527 lane_map[0] = 0x3 ; 8528 lane_map[1] = 0xf ; 8529 lane_map[2] = 0xf ; 8530 break ; 8531 case SOC_LANE_CONFIG_100G_3_4_3: 8532 lane_map[0] = 0x7 ; 8533 lane_map[1] = 0xf ; 8534 lane_map[2] = 0x7 ; 8535 break ; 8536 default: 8537 lane_map[0] = 0x7 ; 8538 lane_map[1] = 0xf ; 8539 lane_map[2] = 0x7 ; 8540 break ; 8541 } 8542 break; 8543 case 4: 8544 pc->phy_mode = PHYCTRL_QUAD_LANE_PORT; 8545 break; 8546 case 2: 8547 lane_map[0] = 0x3; 8548 pc->phy_mode = PHYCTRL_DUAL_LANE_PORT; 8549 break; 8550 case 1: 8551 case 0: 8552 lane_map[0] = 0x1; 8553 pc->phy_mode = PHYCTRL_ONE_LANE_PORT; 8554 8555 break; 8556 default: 8557 return SOC_E_CONFIG; 8558 } 8559 lane_map[0] <<= pc->lane_num; 8560 8561 /* we need to get the other core id if more than 1 core per port */ 8562 if (num_phys > 1) { 8563 /* get the other core address */ 8564 SOC_IF_ERROR_RETURN 8565 (soc_phy_addr_multi_get(unit, port, array_max, &array_size, &core_info[0])); 8566 } else { 8567 core_info[0].mdio_addr = pc->phy_id; 8568 } 8569 8570 if (SOC_IS_ARDON(unit)) { 8571 phy_type = phymodDispatchTypeEagle; 8572 } else if (SOC_IS_GREYHOUND2(unit)){ 8573 phy_type = phymodDispatchTypeTsce_dpll; 8574 } else { 8575 phy_type = phymodDispatchTypeTsce; 8576 } 8577 8578 /* Probe cores */ 8579 for (idx = 0; idx < num_phys ; idx++) { 8580 phy_tsce_core_init(pc, &core_probe, &core_bus, 8581 core_info[idx].mdio_addr); 8582 /* Check that core is indeed an TSC/Eagle core */ 8583 pm_core = &core_probe.pm_core; 8584 pm_core->type = phy_type; 8585 rv = phymod_core_identify(pm_core, 0, &found); 8586 if (SOC_FAILURE(rv)) { 8587 return rv; 8588 } 8589 if (!found) { 8590 return SOC_E_NOT_FOUND; 8591 } 8592 } 8593 8594 rv = SOC_E_NONE; 8595 for (idx = 0; idx < num_phys ; idx++) { 8596 /* Set core and phy IDs based on PHY address */ 8597 core_id = pc->phy_id + idx; 8598 phy_id = (lane_map[idx] << 16) | core_id; 8599 8600 /* Create PHY object */ 8601 rv = soc_phymod_phy_create(unit, phy_id, &pmc->phy[idx]); 8602 if (SOC_FAILURE(rv)) { 8603 break; 8604 } 8605 pmc->num_phys++; 8606 8607 /* Initialize phy object */ 8608 phy = pmc->phy[idx]; 8609 pm_phy = &phy->pm_phy; 8610 phymod_phy_access_t_init(pm_phy); 8611 8612 /* Find or create associated core object */ 8613 rv = soc_phymod_core_find_by_id(unit, core_id, &phy->core); 8614 if (rv == SOC_E_NOT_FOUND) { 8615 rv = soc_phymod_core_create(unit, core_id, &phy->core); 8616 rv |= _tsce_device_create_attach(phy->core, core_id) ; 8617 } 8618 if (SOC_FAILURE(rv)) { 8619 break; 8620 } 8621 } 8622 if (SOC_FAILURE(rv)) { 8623 phy_tsce_cleanup(pmc); 8624 return rv; 8625 } 8626 8627 for (idx = 0; idx < pmc->num_phys ; idx++) { 8628 phy = pmc->phy[idx]; 8629 core = phy->core; 8630 pm_core = &core->pm_core; 8631 8632 /* Initialize core object if newly created */ 8633 if (core->ref_cnt == 0) { 8634 sal_memcpy(&core->pm_bus, &core_bus, sizeof(core->pm_bus)); 8635 phy_tsce_core_init(pc, core, &core->pm_bus, 8636 core_info[idx].mdio_addr); 8637 /* Set dispatch type */ 8638 pm_core->type = phy_type; 8639 } 8640 core->ref_cnt++; 8641 8642 /* Initialize phy access based on associated core */ 8643 pm_acc = &phy->pm_phy.access; 8644 sal_memcpy(pm_acc, &pm_core->access, sizeof(*pm_acc)); 8645 phy->pm_phy.type = phy_type; 8646 PHYMOD_ACC_LANE_MASK(pm_acc) = lane_map[idx]; 8647 } 8648 8649 if (INT_PHY_SW_STATE(unit, port) != NULL){ 8650 /* keep the init done flag from previous state */ 8651 if (INT_PHY_SW_STATE(unit, port)->flags & PHYCTRL_INIT_DONE) { 8652 pc->flags = PHYCTRL_INIT_DONE; 8653 } 8654 } 8655 return SOC_E_NONE; 8656 } 8657 8658 8659 /*********************************************************************** 8660 * 8661 * PASS-THROUGH NOTIFY ROUTINES 8662 */ 8663 8664 /* 8665 * Function: 8666 * _tsce_notify_duplex 8667 * Purpose: 8668 * Program duplex if (and only if) serdestsce is an intermediate PHY. 8669 * Parameters: 8670 * unit - BCM unit number. 8671 * port - Port number. 8672 * duplex - Boolean, TRUE indicates full duplex, FALSE 8673 * indicates half. 8674 * Returns: 8675 * SOC_E_XXX 8676 * Notes: 8677 * If PHY_FLAGS_FIBER is set, it indicates the PHY is being used to 8678 * talk directly to an external fiber module. 8679 * 8680 * If PHY_FLAGS_FIBER is clear, the PHY is being used in 8681 * pass-through mode to talk to an external SGMII PHY. 8682 * 8683 * When used in pass-through mode, autoneg must be turned off and 8684 * the speed/duplex forced to match that of the external PHY. 8685 */ 8686 8687 STATIC int 8688 _tsce_notify_duplex(int unit, soc_port_t port, uint32 duplex) 8689 { 8690 return SOC_E_NONE; 8691 } 8692 8693 /* 8694 * Function: 8695 * _tsce_stop 8696 * Purpose: 8697 * Put serdestsce SERDES in or out of reset depending on conditions 8698 */ 8699 8700 STATIC int 8701 _tsce_stop(int unit, soc_port_t port) 8702 { 8703 phy_ctrl_t* pc; 8704 soc_phymod_ctrl_t *pmc; 8705 phymod_phy_access_t *pm_phy; 8706 phymod_phy_power_t phy_power; 8707 int stop, copper, speed; 8708 8709 pc = INT_PHY_SW_STATE(unit, port); 8710 pmc = &pc->phymod_ctrl; 8711 pm_phy = &pmc->phy[pmc->main_phy]->pm_phy; 8712 8713 if (pc->phy_mode != PHYCTRL_ONE_LANE_PORT) { 8714 return SOC_E_NONE; 8715 } 8716 8717 /* 'Stop' only for speeds < 10G. */ 8718 SOC_IF_ERROR_RETURN 8719 (phy_tsce_speed_get(unit,port,&speed)); 8720 if(10000 <= speed) { 8721 return SOC_E_NONE; 8722 } 8723 copper = (pc->stop & 8724 PHY_STOP_COPPER) != 0; 8725 8726 stop = ((pc->stop & 8727 (PHY_STOP_PHY_DIS | 8728 PHY_STOP_DRAIN)) != 0 || 8729 (copper && 8730 (pc->stop & 8731 (PHY_STOP_MAC_DIS | 8732 PHY_STOP_DUPLEX_CHG | 8733 PHY_STOP_SPEED_CHG)) != 0)); 8734 8735 LOG_INFO(BSL_LS_SOC_PHY, 8736 (BSL_META_U(pc->unit, 8737 "qsgmiie_stop: u=%d p=%d copper=%d stop=%d flg=0x%x\n"), 8738 unit, port, copper, stop, 8739 pc->stop)); 8740 if (stop) { 8741 phy_power.tx = phymodPowerOff; 8742 phy_power.rx = phymodPowerOff; 8743 } else { 8744 phy_power.tx = phymodPowerOn; 8745 phy_power.rx = phymodPowerOn; 8746 } 8747 SOC_IF_ERROR_RETURN 8748 (phymod_phy_power_set(pm_phy, &phy_power)); 8749 return SOC_E_NONE; 8750 } 8751 8752 /* 8753 * Function: 8754 * _tsce_notify_stop 8755 * Purpose: 8756 * Add a reason to put serdestsce PHY in reset. 8757 * Parameters: 8758 * unit - BCM unit number. 8759 * port - Port number. 8760 * flags - Reason to stop 8761 * Returns: 8762 * SOC_E_XXX 8763 */ 8764 8765 STATIC int 8766 _tsce_notify_stop(int unit, soc_port_t port, uint32 flags) 8767 { 8768 INT_PHY_SW_STATE(unit, port)->stop |= flags; 8769 return _tsce_stop(unit, port); 8770 } 8771 8772 /* 8773 * Function: 8774 * _tsce_notify_resume 8775 * Purpose: 8776 * Remove a reason to put serdestsce PHY in reset. 8777 * Parameters: 8778 * unit - BCM unit number. 8779 * port - Port number. 8780 * flags - Reason to stop 8781 * Returns: 8782 * SOC_E_XXX 8783 */ 8784 8785 STATIC int 8786 _tsce_notify_resume(int unit, soc_port_t port, uint32 flags) 8787 { 8788 INT_PHY_SW_STATE(unit, port)->stop &= ~flags; 8789 return _tsce_stop(unit, port); 8790 } 8791 8792 /* 8793 * Function: 8794 * _tsce_notify_speed 8795 * Purpose: 8796 * Program duplex if (and only if) serdestsce is an intermediate PHY. 8797 * Parameters: 8798 * unit - BCM unit number. 8799 * port - Port number. 8800 * speed - Speed to program. 8801 * Returns: 8802 * SOC_E_XXX 8803 * Notes: 8804 * If PHY_FLAGS_FIBER is set, it indicates the PHY is being used to 8805 * talk directly to an external fiber module. 8806 * 8807 * If PHY_FLAGS_FIBER is clear, the PHY is being used in 8808 * pass-through mode to talk to an external SGMII PHY. 8809 * 8810 * When used in pass-through mode, autoneg must be turned off and 8811 * the speed/duplex forced to match that of the external PHY. 8812 */ 8813 8814 STATIC int 8815 _tsce_notify_speed(int unit, soc_port_t port, uint32 speed) 8816 { 8817 phy_ctrl_t* pc; 8818 tsce_config_t *pCfg; 8819 int fiber; 8820 8821 pc = INT_PHY_SW_STATE(unit, port); 8822 pCfg = (tsce_config_t *) pc->driver_data; 8823 fiber = pCfg->fiber_pref; 8824 8825 LOG_INFO(BSL_LS_SOC_PHY, 8826 (BSL_META_U(pc->unit, 8827 "_qsgmiie_notify_speed: " 8828 "u=%d p=%d speed=%d fiber=%d\n"), 8829 unit, port, speed, fiber)); 8830 8831 if (SAL_BOOT_SIMULATION) { 8832 return SOC_E_NONE; 8833 } 8834 8835 /* Put SERDES PHY in reset */ 8836 SOC_IF_ERROR_RETURN 8837 (_tsce_notify_stop(unit, port, PHY_STOP_SPEED_CHG)); 8838 8839 /* Update speed */ 8840 SOC_IF_ERROR_RETURN 8841 (phy_tsce_speed_set(unit, port, speed)); 8842 8843 /* Take SERDES PHY out of reset */ 8844 SOC_IF_ERROR_RETURN 8845 (_tsce_notify_resume(unit, port, PHY_STOP_SPEED_CHG)); 8846 8847 /* Autonegotiation must be turned off to talk to external PHY */ 8848 if (!PHY_SGMII_AUTONEG_MODE(unit, port) && PHY_EXTERNAL_MODE(unit, port)) { 8849 SOC_IF_ERROR_RETURN 8850 (phy_tsce_an_set(unit, port, FALSE)); 8851 } 8852 return SOC_E_NONE; 8853 } 8854 8855 /* 8856 * Function: 8857 * tsce_media_setup 8858 * Purpose: 8859 * Configure 8860 * Parameters: 8861 * unit - BCM unit number. 8862 * port - Port number. 8863 * fiber_mode - Configure for fiber mode 8864 * fiber_pref - Fiber preferrred (if fiber mode) 8865 * Returns: 8866 * SOC_E_XXX 8867 */ 8868 STATIC int 8869 _tsce_notify_interface(int unit, soc_port_t port, uint32 intf) 8870 { 8871 return SOC_E_NONE; 8872 } 8873 8874 /* 8875 * Function: 8876 * _tsce_notify_mac_loopback 8877 * Purpose: 8878 * Turn on rx clock compensation in mac loopback mode for 8879 * applicable XGXS devices 8880 * Parameters: 8881 * unit - BCM unit number. 8882 * port - Port number. 8883 * enable - TRUE: In MAC loopback mode, FALSE: Not in MAC loopback mode 8884 * Returns: 8885 * SOC_E_XXX 8886 */ 8887 STATIC int 8888 _tsce_notify_mac_loopback(int unit, soc_port_t port, uint32 enable) 8889 { 8890 return SOC_E_NONE; 8891 } 8892 8893 STATIC int 8894 phy_tsce_notify(int unit, soc_port_t port, 8895 soc_phy_event_t event, uint32 value) 8896 { 8897 int rv; 8898 rv = SOC_E_NONE ; 8899 if (event >= phyEventCount) { 8900 return SOC_E_PARAM; 8901 } 8902 8903 switch(event) { 8904 case phyEventInterface: 8905 rv = (_tsce_notify_interface(unit, port, value)); 8906 break; 8907 case phyEventDuplex: 8908 rv = (_tsce_notify_duplex(unit, port, value)); 8909 break; 8910 case phyEventSpeed: 8911 rv = (_tsce_notify_speed(unit, port, value)); 8912 break; 8913 case phyEventStop: 8914 rv = (_tsce_notify_stop(unit, port, value)); 8915 break; 8916 case phyEventResume: 8917 rv = (_tsce_notify_resume(unit, port, value)); 8918 break; 8919 case phyEventAutoneg: 8920 #if 0 8921 rv = (_tsce_an_set(unit, port, value)); 8922 #endif 8923 break; 8924 case phyEventMacLoopback: 8925 rv = (_tsce_notify_mac_loopback(unit, port, value)); 8926 break; 8927 case phyEventLpiBypass: 8928 PHYMOD_LPI_BYPASS_SET(value); 8929 rv = phy_tsce_control_set(unit, port, SOC_PHY_CONTROL_EEE, value); 8930 break; 8931 default: 8932 rv = SOC_E_UNAVAIL; 8933 break; 8934 } 8935 8936 return rv; 8937 } 8938 8939 /* 8940 * Function: 8941 * phy_tsce_diag_ctrl 8942 * Purpose: 8943 * xx 8944 * Parameters: 8945 * unit - BCM unit number. 8946 * port - Port number. 8947 8948 * Returns: 8949 * SOC_E_NONE 8950 */ 8951 8952 STATIC int 8953 phy_tsce_diag_ctrl( 8954 int unit, /* unit */ 8955 soc_port_t port, /* port */ 8956 uint32 inst, /* the specific device block the control action directs to */ 8957 int op_type, /* operation types: read,write or command sequence */ 8958 int op_cmd, /* command code */ 8959 void *arg) /* command argument based on op_type/op_cmd */ 8960 { 8961 switch(op_cmd) { 8962 case PHY_DIAG_CTRL_DSC: 8963 LOG_INFO(BSL_LS_SOC_PHY, 8964 (BSL_META_U(unit, 8965 "phy_temod_diag_ctrl: " 8966 "u=%d p=%d PHY_DIAG_CTRL_DSC 0x%x\n"), 8967 unit, port, PHY_DIAG_CTRL_DSC)); 8968 SOC_IF_ERROR_RETURN(tsce_uc_status_dump(unit, port, arg)); 8969 break; 8970 case PHY_DIAG_CTRL_PCS: 8971 LOG_INFO(BSL_LS_SOC_PHY, 8972 (BSL_META_U(unit, 8973 "phy_temod_diag_ctrl: " 8974 "u=%d p=%d PHY_DIAG_CTRL_PCS 0x%x\n"), 8975 unit, port, PHY_DIAG_CTRL_PCS)); 8976 SOC_IF_ERROR_RETURN(tsce_pcs_status_dump(unit, port, arg)); 8977 break; 8978 default: 8979 if (op_type == PHY_DIAG_CTRL_SET) { 8980 SOC_IF_ERROR_RETURN(phy_tsce_control_set(unit,port,op_cmd,PTR_TO_INT(arg))); 8981 } else if (op_type == PHY_DIAG_CTRL_GET) { 8982 SOC_IF_ERROR_RETURN(phy_tsce_control_get(unit,port,op_cmd,(uint32 *)arg)); 8983 } 8984 break ; 8985 } 8986 return (SOC_E_NONE); 8987 } 8988 8989 8990 /* 8991 * Function: 8992 * phy_tsce_master_set 8993 * Purpose: 8994 * Configure master mode 8995 * Parameters: 8996 * unit - StrataSwitch unit #. 8997 * port - StrataSwitch port #. 8998 * master - Master mode. 8999 * Returns: 9000 * SOC_E_NONE/SOC_E_UNAVAIL 9001 */ 9002 STATIC int 9003 phy_tsce_master_set(int unit, soc_port_t port, int master) 9004 { 9005 if (master != SOC_PORT_MS_SLAVE) 9006 return SOC_E_UNAVAIL; 9007 9008 return SOC_E_NONE; 9009 } 9010 9011 /* 9012 * Function: 9013 * phy_tsce_master_get 9014 * Purpose: 9015 * this function is meant for 1000Base-T PHY. Added here to support 9016 * internal PHY regression test 9017 * Parameters: 9018 * unit - StrataSwitch unit #. 9019 * port - StrataSwitch port #. 9020 * master - (OUT) SOC_PORT_MS_* 9021 * Returns: 9022 * SOC_E_NONE 9023 * Notes: 9024 * The master mode is retrieved for the ACTIVE medium. 9025 */ 9026 STATIC int 9027 phy_tsce_master_get(int unit, soc_port_t port, int *master) 9028 { 9029 *master = SOC_PORT_MS_SLAVE; 9030 9031 return SOC_E_NONE; 9032 } 9033 9034 9035 #ifdef BROADCOM_DEBUG 9036 void 9037 tsce_state_dump(int unit, soc_port_t port) 9038 { 9039 /* Show PHY configuration summary */ 9040 /* Lane status */ 9041 /* Show Counters */ 9042 /* Dump Registers */ 9043 } 9044 #endif /* BROADCOM_DEBUG */ 9045 9046 STATIC int 9047 phy_tsce_timesync_config_set(int unit, soc_port_t port, 9048 soc_port_phy_timesync_config_t *conf) 9049 { 9050 phy_ctrl_t* pc; 9051 soc_phymod_ctrl_t *pmc; 9052 phymod_phy_access_t *pm_phy; 9053 uint32_t enable = 0; 9054 9055 pc = INT_PHY_SW_STATE(unit, port); 9056 pmc = &pc->phymod_ctrl; 9057 9058 /*Enable 1588 rxtx*/ 9059 enable = (conf->flags & SOC_PORT_PHY_TIMESYNC_ENABLE) ? 1 : 0 ; 9060 pm_phy = &pmc->phy[0]->pm_phy; 9061 SOC_IF_ERROR_RETURN 9062 (phymod_timesync_enable_set(pm_phy, 0, enable)); 9063 return SOC_E_NONE; 9064 } 9065 9066 STATIC int 9067 phy_tsce_timesync_config_get(int unit, soc_port_t port, 9068 soc_port_phy_timesync_config_t *conf) 9069 { 9070 phy_ctrl_t* pc; 9071 soc_phymod_ctrl_t *pmc; 9072 phymod_phy_access_t *pm_phy; 9073 uint32_t enable = 0; 9074 9075 pc = INT_PHY_SW_STATE(unit, port); 9076 pmc = &pc->phymod_ctrl; 9077 9078 /* 1588 Enable get*/ 9079 pm_phy = &pmc->phy[0]->pm_phy; 9080 SOC_IF_ERROR_RETURN 9081 (phymod_timesync_enable_get(pm_phy, 0, &enable)); 9082 conf->flags |= enable; 9083 return SOC_E_NONE; 9084 } 9085 9086 STATIC int 9087 phy_tsce_timesync_control_set(int unit, soc_port_t port, 9088 soc_port_control_phy_timesync_t type, 9089 uint64 value) 9090 { 9091 phy_ctrl_t* pc; 9092 soc_phymod_ctrl_t *pmc; 9093 phymod_core_access_t *pm_core; 9094 phymod_phy_access_t *pm_phy; 9095 phymod_timesync_compensation_mode_t timesync_am_norm_mode; 9096 9097 pc = INT_PHY_SW_STATE(unit, port); 9098 pmc = &pc->phymod_ctrl; 9099 switch (type) { 9100 case SOC_PORT_CONTROL_PHY_TIMESYNC_TIMESTAMP_OFFSET: 9101 pm_core = &pmc->phy[0]->core->pm_core; 9102 SOC_IF_ERROR_RETURN 9103 (phymod_timesync_offset_set(pm_core, COMPILER_64_LO(value))); 9104 break; 9105 case SOC_PORT_CONTROL_PHY_TIMESYNC_TIMESTAMP_ADJUST: 9106 timesync_am_norm_mode = COMPILER_64_LO(value); 9107 pm_phy = &pmc->phy[0]->pm_phy; 9108 SOC_IF_ERROR_RETURN 9109 (phymod_timesync_adjust_set(pm_phy, timesync_am_norm_mode)); 9110 break; 9111 default: 9112 return SOC_E_UNAVAIL; 9113 break; 9114 } 9115 return SOC_E_NONE; 9116 } 9117 9118 STATIC int 9119 phy_tsce_synce_clk_ctrl_set(int unit, int port, uint32 mode0, uint32 mode1, uint32 sdm_value) 9120 { 9121 phy_ctrl_t* pc; 9122 soc_phymod_ctrl_t *pmc; 9123 phymod_phy_access_t *pm_phy; 9124 phymod_synce_clk_ctrl_t phy_synce_cfg; 9125 9126 pc = INT_PHY_SW_STATE(unit, port); 9127 pmc = &pc->phymod_ctrl; 9128 pm_phy = &pmc->phy[0]->pm_phy; 9129 9130 phymod_synce_clk_ctrl_t_init(&phy_synce_cfg); 9131 phy_synce_cfg.stg0_mode = mode0; 9132 phy_synce_cfg.stg1_mode = mode1; 9133 phy_synce_cfg.sdm_val = sdm_value; 9134 9135 SOC_IF_ERROR_RETURN(phymod_phy_synce_clk_ctrl_set(pm_phy, phy_synce_cfg)); 9136 9137 return SOC_E_NONE; 9138 } 9139 9140 STATIC int 9141 phy_tsce_synce_clk_ctrl_get(int unit, int port, uint32 *mode0, uint32 *mode1, uint32 *sdm_value) 9142 { 9143 phy_ctrl_t* pc; 9144 soc_phymod_ctrl_t *pmc; 9145 phymod_phy_access_t *pm_phy; 9146 phymod_synce_clk_ctrl_t phy_synce_cfg; 9147 9148 pc = INT_PHY_SW_STATE(unit, port); 9149 pmc = &pc->phymod_ctrl; 9150 pm_phy = &pmc->phy[0]->pm_phy; 9151 9152 phymod_synce_clk_ctrl_t_init(&phy_synce_cfg); 9153 9154 SOC_IF_ERROR_RETURN(phymod_phy_synce_clk_ctrl_get(pm_phy, &phy_synce_cfg)); 9155 9156 *mode0 = phy_synce_cfg.stg0_mode; 9157 *mode1 = phy_synce_cfg.stg1_mode; 9158 *sdm_value = phy_synce_cfg.sdm_val; 9159 9160 return SOC_E_NONE; 9161 } 9162 9163 /* 9164 * Variable: 9165 * tsce_drv 9166 * Purpose: 9167 * Phy Driver for TSC/Eagle 9168 */ 9169 phy_driver_t phy_tsce_drv = { 9170 /* .drv_name = */ "TSC/Eagle PHYMOD PHY Driver", 9171 /* .pd_init = */ phy_tsce_init, 9172 /* .pd_reset = */ phy_null_reset, 9173 /* .pd_link_get = */ phy_tsce_link_get, 9174 /* .pd_enable_set = */ phy_tsce_enable_set, 9175 /* .pd_enable_get = */ phy_tsce_enable_get, 9176 /* .pd_duplex_set = */ phy_null_set, 9177 /* .pd_duplex_get = */ phy_tsce_duplex_get, 9178 /* .pd_speed_set = */ phy_tsce_speed_set, 9179 /* .pd_speed_get = */ phy_tsce_speed_get, 9180 /* .pd_master_set = */ phy_tsce_master_set, 9181 /* .pd_master_get = */ phy_tsce_master_get, 9182 /* .pd_an_set = */ phy_tsce_an_set, 9183 /* .pd_an_get = */ phy_tsce_an_get, 9184 /* .pd_adv_local_set = */ NULL, /* Deprecated */ 9185 /* .pd_adv_local_get = */ NULL, /* Deprecated */ 9186 /* .pd_adv_remote_get = */ NULL, /* Deprecated */ 9187 /* .pd_lb_set = */ phy_tsce_lb_set, 9188 /* .pd_lb_get = */ phy_tsce_lb_get, 9189 /* .pd_interface_set = */ phy_tsce_interface_set, 9190 /* .pd_interface_get = */ phy_tsce_interface_get, 9191 /* .pd_ability = */ NULL, /* Deprecated */ 9192 /* .pd_linkup_evt = */ NULL, 9193 /* .pd_linkdn_evt = */ NULL, 9194 /* .pd_mdix_set = */ phy_null_mdix_set, 9195 /* .pd_mdix_get = */ phy_null_mdix_get, 9196 /* .pd_mdix_status_get = */ phy_null_mdix_status_get, 9197 /* .pd_medium_config_set = */ NULL, 9198 /* .pd_medium_config_get = */ NULL, 9199 /* .pd_medium_get = */ phy_null_medium_get, 9200 /* .pd_cable_diag = */ NULL, 9201 /* .pd_link_change = */ NULL, 9202 /* .pd_control_set = */ phy_tsce_control_set, 9203 /* .pd_control_get = */ phy_tsce_control_get, 9204 /* .pd_reg_read = */ phy_tsce_reg_read, 9205 /* .pd_reg_write = */ phy_tsce_reg_write, 9206 /* .pd_reg_modify = */ phy_tsce_reg_modify, 9207 /* .pd_notify = */ phy_tsce_notify, 9208 /* .pd_probe = */ phy_tsce_probe, 9209 /* .pd_ability_advert_set = */ phy_tsce_ability_advert_set, 9210 /* .pd_ability_advert_get = */ phy_tsce_ability_advert_get, 9211 /* .pd_ability_remote_get = */ phy_tsce_ability_remote_get, 9212 /* .pd_ability_local_get = */ phy_tsce_ability_local_get, 9213 /* .pd_firmware_set = */ phy_tsce_firmware_set, 9214 /* .pd_timesync_config_set = */ phy_tsce_timesync_config_set, 9215 /* .pd_timesync_config_get = */ phy_tsce_timesync_config_get, 9216 /* .pd_timesync_control_set = */ phy_tsce_timesync_control_set, 9217 /* .pd_timesync_control_get = */ NULL, 9218 /* .pd_diag_ctrl = */ phy_tsce_diag_ctrl, 9219 /* .pd_lane_control_set = */ phy_tsce_per_lane_control_set, 9220 /* .pd_lane_control_get = */ phy_tsce_per_lane_control_get, 9221 /* .pd_lane_reg_read = */ NULL, 9222 /* .pd_lane_reg_write = */ NULL, 9223 /* .pd_oam_config_set = */ NULL, 9224 /* .pd_oam_config_get = */ NULL, 9225 /* .pd_oam_control_set = */ NULL, 9226 /* .pd_oam_control_get = */ NULL, 9227 /* .pd_timesync_enhanced_capture_get = */ NULL, 9228 /* .pd_multi_get = */ NULL, 9229 /* .pd_precondition_before_probe = */ NULL, 9230 /* .pd_linkfault_get = */ NULL, 9231 /* .pd_synce_clk_ctrl_set = */ phy_tsce_synce_clk_ctrl_set, 9232 /* .pd_synce_clk_ctrl_get = */ phy_tsce_synce_clk_ctrl_get 9233 }; 9234 9235 #else 9236 int _tsce_not_empty; 9237 #endif /* INCLUDE_XGXS_TSCE */ 9238