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