qtce.c (174445B)
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: qsgmiie.c 8 * Purpose: Support Broadcom TSC/Eagle internal SerDes 9 */ 10 11 /* 12 * This module implements an NTSW SDK Phy driver for the TSC/Eagle Serdes. 13 * 14 * LAYERING. 15 * 16 * This driver is built on top of the PHYMOD library, which is a PHY 17 * driver library that can operate on a family of PHYs, including 18 * TSC/Eagle. PHYMOD can be built in a standalone enviroment and be 19 * provided independently from the SDK. PHYMOD APIs consist of 20 * "core" APIs and "phy" APIs. 21 * 22 * 23 * KEY IDEAS AND MAIN FUNCTIONS 24 * 25 * Some key ideas in this architecture are: 26 * 27 * o A PHMOD "phy" consists of one more more lanes, all residing in a single 28 * core. An SDK "phy" is a logical port, which can consist of one or 29 * more lanes in a single core, OR, can consist of multiples lanes in 30 * more than one core. 31 * o PHYMOD code is "stateless" in the sense that all calls to PHYMOD 32 * APIs are fully parameterized and no per-phy state is held by a PHYMOD 33 * driver. 34 * o PHYMOD APIs do not map 1-1 with SDK .pd_control_set or .pd_control_get 35 * APIs (nor ".pd_xx" calls, nor to .phy_qtce_per_lane_control_set and 36 * .phy_qtce_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 * qtce_config_t 60 * Driver specific data. This structure is used by qtce 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 #if defined(INCLUDE_SERDES_QTCE) 113 114 #include <phymod/phymod.h> 115 #include <phymod/phymod_debug.h> 116 #include <phymod/phymod_diagnostics.h> 117 #include <phymod/chip/bcmi_qtce_xgxs_defs.h> 118 #include <phymod/chip/qtce.h> 119 120 int (*_phy_qtce_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int) = { NULL }; 121 122 #define NUM_LANES 4 /* num of lanes per core */ 123 #define MAX_NUM_LANES 4 /* max num of lanes per port */ 124 #define QTCE_NO_CFG_VALUE (-1) 125 126 /* 127 * The DBG_OK macro will bypass the function body and return success 128 * if the PHY simulator is enabled for a particular port. This allows 129 * system initialization to complete even if the driver has not been 130 * fully tested/debugged. As development progresses, we should be able 131 * to remove all instances of this macro. 132 */ 133 #define DBG_OK() do { \ 134 if (soc_property_port_get(unit, port, "qtce_sim", 0)) { \ 135 return SOC_E_NONE; \ 136 } \ 137 } while (0) 138 139 140 #define PHYMOD_IF_CR4 (1 << SOC_PORT_IF_CR4) 141 142 143 typedef struct qtce_speed_config_s { 144 uint32 port_refclk_int; 145 int speed; 146 int port_num_lanes; 147 int port_is_higig; 148 int rxaui_mode; 149 int scrambler_en; 150 int line_interface; 151 int pcs_bypass; 152 int fiber_pref; 153 int phy_supports_dual_rate; 154 } qtce_speed_config_t; 155 156 #define NUM_PATTERN_DATA_INTS 8 157 typedef struct qtce_pattern_s { 158 uint32 pattern_data[NUM_PATTERN_DATA_INTS]; 159 uint32 pattern_length; 160 } qtce_pattern_t; 161 162 #define QTCE_LANE_NAME_LEN 30 163 164 typedef struct { 165 uint16 serdes_id0; 166 char name[QTCE_LANE_NAME_LEN]; 167 } qtce_dev_info_t; 168 169 /* index to TX drive configuration table for each VCO setting. 170 */ 171 typedef enum txdrv_inxs { 172 TXDRV_XFI_INX = 0, /* 10G XFI */ 173 TXDRV_SFI_INX, /* 10G SR fiber mode */ 174 TXDRV_SFIDAC_INX, /* 10G SFI DAC mode */ 175 TXDRV_AN_INX, /* a common entry for autoneg mode */ 176 TXDRV_DFT_INX, /* temp for any missing speed modes */ 177 TXDRV_LAST_INX /* always last */ 178 } TXDRV_INXS_t; 179 180 #define TXDRV_ENTRY_NUM (TXDRV_LAST_INX) 181 182 183 184 /* 185 Config - per logical port 186 */ 187 typedef struct { 188 phymod_polarity_t phy_polarity_config; 189 phymod_phy_reset_t phy_reset_config; 190 qtce_pattern_t pattern; 191 qtce_speed_config_t speed_config; 192 193 int fiber_pref; /* spn_SERDES_FIBER_PREF */ 194 int cl73an; /* spn_PHY_AN_C73 */ 195 int cx4_10g; /* spn_10G_IS_CX4 */ 196 int pdetect1000x; 197 int cl37an; /* spn_PHY_AN_C37 */ 198 int an_cl72; /* spn_PHY_AN_C72 */ 199 int forced_init_cl72; /* spn_FORCED_INIT_CL72 */ 200 int hg_mode; /* higig port */ 201 int an_fec; /*enable FEC for AN mode */ 202 int sgmii_mstr; /* sgmii master mode */ 203 qtce_dev_info_t info; /*serdes id info */ 204 phymod_tx_t tx_drive[TXDRV_ENTRY_NUM]; 205 206 } qtce_config_t; 207 208 #define QTCE_IF_NULL (1 << SOC_PORT_IF_NULL) 209 #define QTCE_IF_SR (1 << SOC_PORT_IF_SR) 210 #define QTCE_IF_KR (1 << SOC_PORT_IF_KR) 211 #define QTCE_IF_KR4 (1 << SOC_PORT_IF_KR4) 212 #define QTCE_IF_CR (1 << SOC_PORT_IF_CR) 213 #define QTCE_IF_CR4 (1 << SOC_PORT_IF_CR4) 214 #define QTCE_IF_XFI (1 << SOC_PORT_IF_XFI) 215 #define QTCE_IF_SFI (1 << SOC_PORT_IF_SFI) 216 #define QTCE_IF_XGMII (1 << SOC_PORT_IF_XGMII) 217 #define QTCE_IF_SGMII (1 << SOC_PORT_IF_SGMII) 218 #define QTCE_IF_GMII (1 << SOC_PORT_IF_GMII) 219 #define QTCE_IF_QSGMII (1 << SOC_PORT_IF_QSGMII) 220 221 222 223 #define TEMOD_CL73_CL37 0x5 224 #define TEMOD_CL73_HPAM 0x4 225 #define TEMOD_CL73_HPAM_VS_SW 0x8 226 #define TEMOD_CL73_WO_BAM 0x2 227 #define TEMOD_CL73_W_BAM 0x1 228 #define TEMOD_CL73_DISABLE 0x0 229 230 #define TEMOD_CL37_HR2SPM_W_10G 5 231 #define TEMOD_CL37_HR2SPM 4 232 #define TEMOD_CL37_W_10G 3 233 #define TEMOD_CL37_WO_BAM 2 234 #define TEMOD_CL37_W_BAM 1 235 #define TEMOD_CL37_DISABLE 0 236 237 STATIC int phy_qtce_ability_advert_set(int unit, soc_port_t port, 238 soc_port_ability_t *ability); 239 STATIC int phy_qtce_an_set(int unit, soc_port_t port, int enable); 240 241 STATIC int phy_qtce_an_get(int unit, soc_port_t port, int *an, int *an_done); 242 243 /* 244 * Function: 245 * _qtce_reg_read 246 * Doc: 247 * register read operations 248 * Parameters: 249 * unit - (IN) unit number 250 * core_addr - (IN) core address 251 * reg_addr - (IN) address to read 252 * val - (OUT) read value 253 */ 254 STATIC int 255 _qtce_reg_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val) 256 { 257 uint16 data16; 258 int rv; 259 soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc; 260 261 rv = core->read(core->unit, core_addr, reg_addr, &data16); 262 *val = data16; 263 264 return rv; 265 } 266 267 /* 268 * Function: 269 * _qtce_reg_write 270 * Doc: 271 * register write operations 272 * Parameters: 273 * unit - (IN) unit number 274 * core_addr - (IN) core address 275 * reg_addr - (IN) address to write 276 * val - (IN) write value 277 */ 278 STATIC int 279 _qtce_reg_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val) 280 { 281 soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc; 282 uint16 data16 = (uint16)val; 283 uint16 mask = (uint16)(val >> 16); 284 285 if (mask) { 286 if (core->wrmask) { 287 return core->wrmask(core->unit, core_addr, reg_addr, data16, mask); 288 } 289 (void)core->read(core->unit, core_addr, reg_addr, &data16); 290 data16 &= ~mask; 291 data16 |= (val & mask); 292 } 293 return core->write(core->unit, core_addr, reg_addr, data16); 294 } 295 296 /* 297 * Function: 298 * tsce_firmware_loader 299 * Purpose: 300 * Download PHY firmware using fast interface such as S-channel. 301 * Parameters: 302 * pm_core - (IN) PHY core oject 303 * fw_len - (IN) Number of bytes to download 304 * fw_data - (IN) Firmware as byte array 305 */ 306 STATIC int 307 qtce_firmware_loader(const phymod_core_access_t *pm_core, 308 uint32 fw_len, const uint8 *fw_data) 309 { 310 soc_phymod_core_t *core; 311 int unit, port; 312 313 if (pm_core == NULL) { 314 return PHYMOD_E_PARAM; 315 } 316 317 /* Retrieve SOC information from PHYMOD object */ 318 core = (soc_phymod_core_t *)(pm_core->access.user_acc); 319 320 if (core == NULL) { 321 return PHYMOD_E_PARAM; 322 } 323 324 /* Get associated unit/port */ 325 unit = core->unit; 326 port = core->port; 327 328 return _phy_qtce_firmware_set_helper[unit](unit, port, 329 (uint8 *)fw_data, fw_len); 330 } 331 332 #define IS_DUAL_LANE_PORT(_pc) ((_pc)->phy_mode == PHYCTRL_DUAL_LANE_PORT) 333 #define IND_LANE_MODE(_pc) (((_pc)->phy_mode == PHYCTRL_DUAL_LANE_PORT) || ((_pc)->phy_mode == PHYCTRL_ONE_LANE_PORT)) 334 #define MAIN0_SERDESID_REV_LETTER_SHIFT (14) 335 #define MAIN0_SERDESID_REV_NUMBER_SHIFT (11) 336 337 /* 338 * Function: 339 * qtce_show_serdes_info 340 * Purpose: 341 * Show SerDes information. 342 * Parameters: 343 * pc - (IN) phyctrl oject 344 * pInfo - (IN) device info object 345 * rev_id - (IN) serdes revid 346 * Returns: 347 * SOC_E_NONE 348 */ 349 STATIC int 350 qtce_show_serdes_info(phy_ctrl_t *pc, qtce_dev_info_t *pInfo, phymod_core_info_t *core_info) 351 { 352 uint32_t serdes_id0, len; 353 354 pInfo->serdes_id0 = core_info->serdes_id ; 355 356 /* This is TSC/Eagle device */ 357 serdes_id0 = pInfo->serdes_id0; 358 sal_strncpy(pInfo->name,"QTCE-", strlen("QTCE-")); 359 len = sal_strlen(pInfo->name); 360 /* add rev letter */ 361 pInfo->name[len++] = 'A' + ((serdes_id0 >> 362 MAIN0_SERDESID_REV_LETTER_SHIFT) & 0x3); 363 /* add rev number */ 364 pInfo->name[len++] = '0' + ((serdes_id0 >> 365 MAIN0_SERDESID_REV_NUMBER_SHIFT) & 0x7); 366 pInfo->name[len++] = '/'; 367 pInfo->name[len++] = (pc->chip_num / 10) % 10 + '0'; 368 pInfo->name[len++] = pc->chip_num % 10 + '0'; 369 pInfo->name[len++] = '/'; 370 371 /* phy_mode: 0 single port mode, port uses all four lanes of Warpcore 372 * 1 dual port mode, port uses 2 lanes 373 * 2 quad port mode, port uses 1 lane 374 */ 375 if (IS_DUAL_LANE_PORT(pc)) { /* dual-xgxs mode */ 376 if (pc->lane_num < 2) { /* the first dual-xgxs port */ 377 pInfo->name[len++] = '0'; 378 pInfo->name[len++] = '-'; 379 pInfo->name[len++] = '1'; 380 } else { 381 pInfo->name[len++] = '2'; 382 pInfo->name[len++] = '-'; 383 pInfo->name[len++] = '3'; 384 } 385 } else if (pc->phy_mode == PHYCTRL_QSGMII_CORE_PORT) { 386 pInfo->name[len++] = pc->lane_num + '0'; 387 } else { 388 /* pInfo->name[len++] = '4'; */ 389 if (pc->lane_num <= 9) { 390 pInfo->name[len++] = pc->lane_num + '0'; 391 } else { 392 pInfo->name[len++] = '1'; 393 pInfo->name[len++] = '0' + pc->lane_num - 10; 394 } 395 } 396 pInfo->name[len] = 0; /* string terminator */ 397 398 if (len > QTCE_LANE_NAME_LEN) { 399 LOG_ERROR(BSL_LS_SOC_COMMON, 400 (BSL_META("QTCE info string length %d exceeds max length 0x%x: u=%d p=%d\n"), 401 len,QTCE_LANE_NAME_LEN, pc->unit, pc->port)); 402 return SOC_E_MEMORY; 403 } 404 return SOC_E_NONE; 405 } 406 407 STATIC int 408 qtce_ref_clk_convert(int port_refclk_int, phymod_ref_clk_t *ref_clk) 409 { 410 switch (port_refclk_int) 411 { 412 case 156: 413 *ref_clk = phymodRefClk156Mhz; 414 break; 415 case 125: 416 *ref_clk = phymodRefClk125Mhz; 417 break; 418 default: 419 *ref_clk = phymodRefClk156Mhz; 420 break; 421 } 422 423 return SOC_E_NONE; 424 } 425 /* 426 * Function: 427 * qtce_speed_to_interface_config_get 428 * Purpose: 429 * Convert speed to interface_config struct 430 * Parameters: 431 * unit - BCM unit number. 432 * port - Port number. 433 * speed - speed to convert 434 * interface_config - output interface config struct 435 * Returns: 436 * SOC_E_NONE 437 */ 438 STATIC int 439 qtce_speed_to_interface_config_get(qtce_speed_config_t* speed_config, phymod_phy_inf_config_t* interface_config) 440 { 441 int fiber_pref; 442 443 SOC_IF_ERROR_RETURN(phymod_phy_inf_config_t_init(interface_config)); 444 445 interface_config->data_rate = speed_config->speed; 446 447 fiber_pref = speed_config->fiber_pref; 448 if (fiber_pref) { 449 PHYMOD_INTF_MODES_FIBER_SET(interface_config); 450 } else { 451 PHYMOD_INTF_MODES_BACKPLANE_SET(interface_config); 452 } 453 454 switch (speed_config->speed) { 455 case 10: 456 interface_config->interface_type = phymodInterfaceSGMII; 457 break; 458 case 100: 459 case 1000: 460 if (speed_config->fiber_pref) { 461 interface_config->interface_type = phymodInterface1000X; 462 } else { 463 interface_config->interface_type = phymodInterfaceSGMII; 464 } 465 break; 466 case 2500: 467 interface_config->interface_type = phymodInterface1000X; 468 break; 469 default: 470 if (speed_config->fiber_pref) { 471 interface_config->interface_type = phymodInterface1000X; 472 } else { 473 interface_config->interface_type = phymodInterfaceSGMII; 474 } 475 break; 476 } 477 478 SOC_IF_ERROR_RETURN( 479 qtce_ref_clk_convert(speed_config->port_refclk_int, &(interface_config->ref_clock))); 480 481 return SOC_E_NONE; 482 } 483 484 /* 485 * Function: 486 * qtce_config_init 487 * Purpose: 488 * Determine phy configuration data for purposes of PHYMOD initialization. 489 * 490 * A side effect of this procedure is to save some per-logical port 491 * information in (qtce_cfg_t *) &pc->driver_data; 492 * 493 * Parameters: 494 * unit - BCM unit number. 495 * port - Port number. 496 * logical_lane_offset - starting logical lane number 497 * Returns: 498 * SOC_E_NONE 499 */ 500 STATIC int 501 qtce_config_init(int unit, soc_port_t port, int logical_lane_offset, 502 phymod_core_init_config_t *core_init_config, 503 phymod_phy_init_config_t *pm_phy_init_config) 504 { 505 phy_ctrl_t *pc; 506 qtce_speed_config_t *speed_config; 507 qtce_config_t *pCfg; 508 phymod_tx_t *p_tx; 509 int port_refclk_int; 510 int port_num_lanes; 511 int core_num; 512 int phy_num_lanes; 513 int port_is_higig; 514 int phy_passthru; 515 int phy_supports_dual_rate; 516 int lane_map_rx, lane_map_tx; 517 int i; 518 int fiber_pref = 0; 519 phymod_firmware_load_method_t fw_ld_method; 520 521 pc = INT_PHY_SW_STATE(unit, port); 522 if (pc == NULL) { 523 return SOC_E_INTERNAL; 524 } 525 pCfg = (qtce_config_t *) pc->driver_data; 526 527 /* extract data from SOC_INFO */ 528 port_refclk_int = SOC_INFO(unit).port_refclk_int[port]; 529 #if 0 530 531 port_refclk_int = soc_property_port_get(unit,port, spn_XGXS_PHY_VCO_FREQ, pCfg->refclk); 532 #endif 533 port_refclk_int = soc_property_port_get(unit, port,spn_XGXS_LCPLL_XTAL_REFCLK, port_refclk_int); 534 port_num_lanes = SOC_INFO(unit).port_num_lanes[port]; 535 port_is_higig = PBMP_MEMBER(PBMP_HG_ALL(unit), port); 536 phy_supports_dual_rate = PHY_IS_SUPPORT_DUAL_RATE(unit, port); 537 538 /* figure out how many lanes are in this phy */ 539 core_num = (logical_lane_offset / 4); 540 phy_num_lanes = (port_num_lanes - logical_lane_offset); 541 if (phy_num_lanes > MAX_NUM_LANES) { 542 phy_num_lanes = MAX_NUM_LANES; 543 } 544 545 /* 546 CORE configuration 547 */ 548 phymod_core_init_config_t_init(core_init_config); 549 fw_ld_method = phymodFirmwareLoadMethodInternal; 550 if (_phy_qtce_firmware_set_helper[unit]) { 551 core_init_config->firmware_loader = qtce_firmware_loader; 552 fw_ld_method = phymodFirmwareLoadMethodExternal; 553 } 554 555 if (soc_property_port_get(pc->unit, pc->port, "qtce_sim", 0) || soc_property_port_get(pc->unit, pc->port, "eagle_sim", 0)) { 556 fw_ld_method = phymodFirmwareLoadMethodNone; 557 } 558 559 560 core_init_config->firmware_load_method = soc_property_port_get(unit, port, 561 spn_LOAD_FIRMWARE, fw_ld_method); 562 core_init_config->firmware_load_method &= 0xff; /* clear checksum bits */ 563 core_init_config->flags = PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY; 564 core_init_config->lane_map.num_of_lanes = NUM_LANES; 565 566 lane_map_rx = soc_property_port_suffix_num_get(unit, port, core_num, 567 spn_XGXS_RX_LANE_MAP, "core", 0x3210); 568 for (i=0; i<NUM_LANES; i++) { 569 core_init_config->lane_map.lane_map_rx[i] = (lane_map_rx >> (i * 4 /*4 bit per lane*/)) & 0xf; 570 } 571 572 lane_map_tx = soc_property_port_suffix_num_get(unit, port, core_num, 573 spn_XGXS_TX_LANE_MAP, "core", 0x3210); 574 for (i=0; i<NUM_LANES; i++) { 575 core_init_config->lane_map.lane_map_tx[i] = (lane_map_tx >> (i * 4 /*4 bit per lane*/)) & 0xf; 576 } 577 578 speed_config = &(pCfg->speed_config); 579 speed_config->port_refclk_int = port_refclk_int; 580 speed_config->speed = soc_property_port_get(unit, port, spn_PORT_INIT_SPEED, 0); 581 speed_config->port_num_lanes = phy_num_lanes; 582 speed_config->port_is_higig = port_is_higig; 583 speed_config->rxaui_mode = soc_property_port_get(unit, port, spn_SERDES_RXAUI_MODE, 1); 584 speed_config->scrambler_en = soc_property_port_get(unit, port, spn_SERDES_SCRAMBLER_ENABLE, 0); 585 speed_config->line_interface = soc_property_port_get(unit, port, spn_SERDES_IF_TYPE, 0); 586 speed_config->fiber_pref = soc_property_port_get(unit, port, spn_SERDES_FIBER_PREF, fiber_pref); 587 pCfg->fiber_pref = speed_config->fiber_pref; 588 speed_config->pcs_bypass = 0; 589 speed_config->phy_supports_dual_rate = phy_supports_dual_rate; 590 SOC_IF_ERROR_RETURN 591 (qtce_speed_to_interface_config_get(speed_config, &(core_init_config->interface))); 592 593 /* 594 PHY configuration 595 */ 596 for (i = 0; i < TXDRV_ENTRY_NUM; i++) { 597 SOC_IF_ERROR_RETURN(phymod_tx_t_init(&pCfg->tx_drive[i])); 598 } 599 /*set the default tx parameters */ 600 p_tx = &pCfg->tx_drive[TXDRV_DFT_INX]; 601 p_tx->amp = 0xc; 602 p_tx->pre = 0x00; 603 p_tx->main = 0x70; 604 p_tx->post = 0x0; 605 p_tx->post2 = 0x00; 606 p_tx->post3 = 0x00; 607 608 p_tx = &pCfg->tx_drive[TXDRV_XFI_INX]; 609 p_tx->amp = 0xc; 610 p_tx->pre = 0x00; 611 p_tx->main = 0x30; 612 p_tx->post = 0x0; 613 p_tx->post2 = 0x00; 614 p_tx->post3 = 0x00; 615 616 p_tx = &pCfg->tx_drive[TXDRV_SFIDAC_INX]; 617 p_tx->amp = 0xc; 618 p_tx->pre = 0x00; 619 p_tx->main = 0x18; 620 p_tx->post = 0x18; 621 p_tx->post2 = 0x00; 622 p_tx->post3 = 0x00; 623 624 p_tx = &pCfg->tx_drive[TXDRV_AN_INX]; 625 p_tx->amp = 0xc; 626 p_tx->pre = 0x00; 627 p_tx->main = 0x70; 628 p_tx->post = 0x00; 629 p_tx->post2 = 0x00; 630 p_tx->post3 = 0x00; 631 632 phymod_phy_init_config_t_init(pm_phy_init_config); 633 /*initialize the tx taps and driver current*/ 634 for (i = 0; i < 4; i++) { 635 pm_phy_init_config->tx[i].pre = 0x00; 636 pm_phy_init_config->tx[i].main = 0x70; 637 pm_phy_init_config->tx[i].post = 0x0; 638 pm_phy_init_config->tx[i].post2 = 0x0; 639 pm_phy_init_config->tx[i].post3 = 0x0; 640 pm_phy_init_config->tx[i].amp = 0xc; 641 } 642 pm_phy_init_config->polarity.rx_polarity 643 = soc_property_port_get(unit, port, 644 spn_PHY_XAUI_RX_POLARITY_FLIP, FALSE); 645 pm_phy_init_config->polarity.tx_polarity 646 = soc_property_port_get(unit, port, 647 spn_PHY_XAUI_TX_POLARITY_FLIP, FALSE); 648 649 for (i = 0; i < MAX_NUM_LANES; i++) { 650 uint32_t preemphasis; 651 preemphasis = soc_property_port_suffix_num_get(unit, port, 652 i + core_num * 4, spn_SERDES_PREEMPHASIS, 653 "lane", QTCE_NO_CFG_VALUE); 654 if (preemphasis != QTCE_NO_CFG_VALUE) { 655 pm_phy_init_config->tx[i].pre = preemphasis & 0xff; 656 pm_phy_init_config->tx[i].main = (preemphasis & 0xff00) >> 8; 657 pm_phy_init_config->tx[i].post = (preemphasis & 0xff0000) >> 16; 658 } 659 } 660 661 for (i = 0; i < MAX_NUM_LANES; i++) { 662 pm_phy_init_config->tx[i].amp = soc_property_port_suffix_num_get(unit, port, 663 i + core_num * 4, spn_SERDES_DRIVER_CURRENT, 664 "lane", pm_phy_init_config->tx[i].amp); 665 } 666 667 668 669 670 pm_phy_init_config->cl72_en = soc_property_port_get(unit, port, spn_PHY_AN_C72, TRUE); 671 pm_phy_init_config->an_en = TRUE; 672 673 /* check the higig port mode, then set the default cl73 mode */ 674 if (port_is_higig) { 675 pCfg->cl73an = FALSE; 676 } else { 677 pCfg->cl73an = PHYMOD_AN_CAP_CL73; 678 } 679 680 /* by default disable cl37 */ 681 pCfg->cl37an = FALSE; 682 pCfg->an_cl72 = TRUE; 683 pCfg->forced_init_cl72 = FALSE; 684 685 pCfg->cl73an = soc_property_port_get(unit, port, 686 spn_PHY_AN_C73, pCfg->cl73an); /* no L: C73, not CL73 */ 687 688 pCfg->cl37an = soc_property_port_get(unit, port, 689 spn_PHY_AN_C37, pCfg->cl37an); /* no L: C37, not CL37 */ 690 691 pCfg->an_cl72 = soc_property_port_get(unit, port, 692 spn_PHY_AN_C72, pCfg->an_cl72); 693 pCfg->forced_init_cl72 = soc_property_port_get(unit, port, 694 spn_PORT_INIT_CL72, pCfg->forced_init_cl72); 695 696 697 /* 698 phy_ctrl_t configuration (LOGICAL PORT BASED) 699 Only do this once, for the first core of the logical port 700 */ 701 if (core_num == 0) { 702 703 /* pc->lane_num, pc->chip_num */ 704 #if 0 705 soc_port_info = &(SOC_DRIVER(unit)->port_info[phy_port]); 706 /* mark it for the assertion of lane_num and chip_num is assigned */ 707 pc->lane_num = soc_port_info->bindex; 708 pc->chip_num = SOC_BLOCK_NUMBER(unit, soc_port_info->blk); 709 #endif 710 711 /* phy_mode, PHYCTRL_MDIO_ADDR_SHARE, PHY_FLAGS_INDEPENDENT_LANE */ 712 if (port_num_lanes == 4) { 713 pc->phy_mode = PHYCTRL_QUAD_LANE_PORT; 714 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_INDEPENDENT_LANE); 715 } else if (port_num_lanes == 2) { 716 pc->phy_mode = PHYCTRL_DUAL_LANE_PORT; 717 pc->flags |= PHYCTRL_MDIO_ADDR_SHARE; 718 PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE); 719 } else if (port_num_lanes == 1) { 720 pc->phy_mode = PHYCTRL_ONE_LANE_PORT; 721 pc->flags |= PHYCTRL_MDIO_ADDR_SHARE; 722 PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE); 723 } 724 725 /* PHY_FLAGS_PASSTHRU */ 726 phy_passthru = 0; 727 if (PHY_EXTERNAL_MODE(unit, port)) { 728 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_PASSTHRU); 729 phy_passthru = soc_property_port_get(unit, port, 730 spn_PHY_PCS_REPEATER, 0); 731 if (phy_passthru) { 732 PHY_FLAGS_SET(unit, port, PHY_FLAGS_PASSTHRU); 733 } 734 } 735 736 /* PHY_FLAGS_FIBER */ 737 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_FIBER); 738 if (!PHY_EXTERNAL_MODE(unit, port)) { 739 740 fiber_pref = FALSE; 741 if (PHY_FIBER_MODE(unit, port) || 742 (phy_passthru) || 743 (!PHY_INDEPENDENT_LANE_MODE(unit, port)) || 744 (pc->speed_max >= 10000)) { 745 fiber_pref = TRUE; 746 } 747 748 fiber_pref = soc_property_port_get(unit, port, 749 spn_SERDES_FIBER_PREF, fiber_pref); 750 if (fiber_pref) { 751 PHY_FLAGS_SET(unit, port, PHY_FLAGS_FIBER); 752 } 753 } 754 755 756 PHY_FLAGS_SET(unit,port,PHY_FLAGS_SERVICE_INT_PHY_LINK_GET); 757 758 759 /* not used */ 760 /* pCfg->cl73an = soc_property_port_get(unit, port, spn_PHY_AN_C73, TSCMOD_CL73_WO_BAM); 761 762 if (!PHY_EXTERNAL_MODE(unit, port)) { 763 if (pCfg->cl73an) { 764 PHY_FLAGS_SET(unit, port, PHY_FLAGS_C73); 765 } 766 } 767 */ 768 769 770 if ((PHY_FIBER_MODE(unit, port) && !PHY_EXTERNAL_MODE(unit, port)) || 771 phy_passthru) { 772 pCfg->pdetect1000x = TRUE; 773 } else { 774 pCfg->pdetect1000x = FALSE; 775 } 776 777 pCfg->cx4_10g = soc_property_port_get(unit, port, spn_10G_IS_CX4, TRUE); 778 } 779 780 return SOC_E_NONE; 781 } 782 783 /* 784 * Function: 785 * phy_qtce_init 786 * 787 * An SDK "phy" is a logical port, which can consist of from 1-10 lanes, 788 * (A phy with more than 4 lanes requires more than one core). 789 * Per-logical port information is saved in (qtce_cfg_t *) &pc->driver_data. 790 * An SDK phy is implemented as one or more PHYMOD "phy"s. 791 * 792 * A PHYMOD "phy" resides completely within a single core, which can be 793 * from 1 to 4 lanes. 794 * Per-phymod phy information is kept in (soc_phymod_ctrl_t) *pc->phymod_ctrl 795 * A phymod phy points to its core. Up to 4 phymod phys can be on a single core 796 * 797 * Purpose: 798 * Initialize a qtce phy 799 * Parameters: 800 * unit - BCM unit number. 801 * port - Port number. 802 * Returns: 803 * SOC_E_NONE 804 */ 805 STATIC int 806 phy_qtce_init(int unit, soc_port_t port) 807 { 808 phy_ctrl_t *pc; 809 soc_phymod_ctrl_t *pmc; 810 soc_phymod_phy_t *phy = NULL; 811 soc_phymod_core_t *core; 812 qtce_config_t *pCfg; 813 qtce_speed_config_t *speed_config; 814 qtce_dev_info_t *pInfo; 815 soc_phy_info_t *pi; 816 phymod_phy_inf_config_t interface_config; 817 phymod_core_status_t core_status; 818 phymod_core_info_t core_info; 819 int idx; 820 int logical_lane_offset; 821 phymod_autoneg_ability_t phymod_autoneg_ability; 822 phymod_autoneg_control_t an; 823 824 phymod_autoneg_ability_t_init(&phymod_autoneg_ability); 825 phymod_autoneg_control_t_init(&an); 826 827 pc = INT_PHY_SW_STATE(unit, port); 828 if (pc == NULL) { 829 return SOC_E_INTERNAL; 830 } 831 pc->driver_data = (void*)(pc+1); 832 pmc = &pc->phymod_ctrl; 833 pCfg = (qtce_config_t *) pc->driver_data; 834 pInfo = &pCfg->info; 835 836 sal_memset(pCfg, 0, sizeof(*pCfg)); 837 speed_config = &(pCfg->speed_config); 838 839 /* Loop through all phymod phys that support this SDK phy */ 840 logical_lane_offset = 0; 841 for (idx = 0; idx < pmc->num_phys; idx++) { 842 phy = pmc->phy[idx]; 843 core = phy->core; 844 845 846 847 /* determine configuration data structure to default values, based on SOC properties */ 848 SOC_IF_ERROR_RETURN 849 (qtce_config_init(unit, port, 850 logical_lane_offset, 851 &core->init_config, &phy->init_config)); 852 853 854 if (!core->init) { 855 core_status.pmd_active = 0; 856 if (!SOC_WARM_BOOT(unit)) { 857 SOC_IF_ERROR_RETURN 858 (phymod_core_init(&core->pm_core, &core->init_config, &core_status)); 859 } 860 core->init = TRUE; 861 } 862 863 if (!SOC_WARM_BOOT(unit)) { 864 SOC_IF_ERROR_RETURN 865 (phymod_phy_init(&phy->pm_phy, &phy->init_config)); 866 } 867 868 /*read serdes id info */ 869 SOC_IF_ERROR_RETURN 870 (phymod_core_info_get(&core->pm_core, &core_info)); 871 872 873 /* for multicore phys, need to ratchet up to the next batch of lanes */ 874 logical_lane_offset += core->init_config.lane_map.num_of_lanes; 875 } 876 877 /*fill up the pInfo table for displaying the serdes driver info */ 878 SOC_IF_ERROR_RETURN 879 (qtce_show_serdes_info(pc, pInfo, &core_info)); 880 881 /* retrieve chip level information for serdes driver info */ 882 pi = &SOC_PHY_INFO(unit, port); 883 884 if (!PHY_EXTERNAL_MODE(unit, port)) { 885 pi->phy_name = pInfo->name; 886 } 887 888 if (SOC_WARM_BOOT(unit)) { 889 return SOC_E_NONE; 890 } 891 /* set the port to its max or init_speed */ 892 SOC_IF_ERROR_RETURN 893 (qtce_speed_to_interface_config_get(speed_config, &interface_config)); 894 SOC_IF_ERROR_RETURN 895 (phymod_phy_interface_config_set(&phy->pm_phy, 896 0 /* flags */, &interface_config)); 897 898 /* next check if qsgmii mode, enable AN */ 899 if (PHYMOD_ACC_F_QMODE_GET(&phy->pm_phy.access)) { 900 SOC_IF_ERROR_RETURN 901 (phymod_phy_autoneg_ability_set(&phy->pm_phy, &phymod_autoneg_ability)); 902 /* enable AN */ 903 an.an_mode = phymod_AN_MODE_CL37; 904 an.enable = 1; 905 an.num_lane_adv = 1; 906 SOC_IF_ERROR_RETURN 907 (phymod_phy_autoneg_set(&phy->pm_phy, &an)); 908 } 909 return SOC_E_NONE; 910 } 911 912 /* 913 * Function: 914 * phy_qtce_link_get 915 * Purpose: 916 * Get layer2 connection status. 917 * Parameters: 918 * unit - BCM unit number. 919 * port - Port number. 920 * link - address of memory to store link up/down state. 921 * Returns: 922 * SOC_E_NONE 923 */ 924 STATIC int 925 phy_qtce_link_get(int unit, soc_port_t port, int *link) 926 { 927 phy_ctrl_t *pc; 928 soc_phymod_ctrl_t *pmc; 929 phymod_phy_access_t *pm_phy; 930 931 *link = 0; 932 /* locate phy control */ 933 pc = INT_PHY_SW_STATE(unit, port); 934 if (pc == NULL) { 935 return SOC_E_INTERNAL; 936 } 937 938 pmc = &pc->phymod_ctrl; 939 pm_phy = &pmc->phy[0]->pm_phy; 940 941 SOC_IF_ERROR_RETURN 942 (phymod_phy_link_status_get(pm_phy, (uint32_t *) link)); 943 return (SOC_E_NONE); 944 } 945 946 /* 947 * Function: 948 * phy_qtce_enable_set 949 * Purpose: 950 * Enable/Disable phy 951 * Parameters: 952 * unit - BCM unit number. 953 * port - Port number. 954 * enable - on/off state to set 955 * Returns: 956 * SOC_E_NONE 957 */ 958 STATIC int 959 phy_qtce_enable_set(int unit, soc_port_t port, int enable) 960 { 961 phy_ctrl_t *pc; 962 soc_phymod_ctrl_t *pmc; 963 phymod_phy_access_t *pm_phy; 964 phymod_phy_tx_lane_control_t tx_control; 965 phymod_phy_rx_lane_control_t rx_control; 966 967 int idx; 968 969 /* locate phy control */ 970 pc = INT_PHY_SW_STATE(unit, port); 971 if (pc == NULL) { 972 return SOC_E_INTERNAL; 973 } 974 975 if (enable) { 976 tx_control = phymodTxSquelchOff; 977 rx_control = phymodRxSquelchOff; 978 } else { 979 tx_control = phymodTxSquelchOn; 980 rx_control = phymodRxSquelchOn; 981 } 982 983 pmc = &pc->phymod_ctrl; 984 for (idx = 0; idx < pmc->num_phys; idx++) { 985 pm_phy = &pmc->phy[idx]->pm_phy; 986 SOC_IF_ERROR_RETURN 987 (phymod_phy_tx_lane_control_set(pm_phy, tx_control)); 988 SOC_IF_ERROR_RETURN 989 (phymod_phy_rx_lane_control_set(pm_phy, rx_control)); 990 } 991 return (SOC_E_NONE); 992 } 993 994 /* 995 * Function: 996 * phy_qtce_enable_get 997 * Purpose: 998 * Enable/Disable phy 999 * Parameters: 1000 * unit - BCM unit number. 1001 * port - Port number. 1002 * enable - on/off state to set 1003 * Returns: 1004 * SOC_E_NONE 1005 */ 1006 STATIC int 1007 phy_qtce_enable_get(int unit, soc_port_t port, int *enable) 1008 { 1009 phy_ctrl_t *pc; 1010 soc_phymod_ctrl_t *pmc; 1011 phymod_phy_access_t *pm_phy; 1012 phymod_phy_tx_lane_control_t tx_control; 1013 phymod_phy_rx_lane_control_t rx_control; 1014 1015 /* locate phy control */ 1016 pc = INT_PHY_SW_STATE(unit, port); 1017 if (pc == NULL) { 1018 return SOC_E_INTERNAL; 1019 } 1020 1021 pmc = &pc->phymod_ctrl; 1022 pm_phy = &pmc->phy[0]->pm_phy; 1023 SOC_IF_ERROR_RETURN 1024 (phymod_phy_tx_lane_control_get(pm_phy, &tx_control)); 1025 SOC_IF_ERROR_RETURN 1026 (phymod_phy_rx_lane_control_get(pm_phy, &rx_control)); 1027 if ((tx_control == phymodTxSquelchOn) && (rx_control == phymodRxSquelchOn)) { 1028 *enable = 0; 1029 } else { 1030 *enable = 1; 1031 } 1032 return (SOC_E_NONE); 1033 } 1034 1035 1036 /* 1037 * Function: 1038 * phy_qtce_duplex_get 1039 * Purpose: 1040 * Get PHY duplex mode 1041 * Parameters: 1042 * unit - BCM unit number. 1043 * port - Port number. 1044 * duplex - current duplex mode 1045 * Returns: 1046 * SOC_E_NONE 1047 */ 1048 STATIC int 1049 phy_qtce_duplex_get(int unit, soc_port_t port, int *duplex) 1050 { 1051 phy_ctrl_t *pc; 1052 soc_phymod_ctrl_t *pmc; 1053 soc_phymod_phy_t *phy; 1054 phymod_autoneg_ability_t phymod_autoneg_ability; 1055 1056 pc = INT_PHY_SW_STATE(unit, port); 1057 if (pc == NULL) { 1058 return SOC_E_INTERNAL; 1059 } 1060 1061 pmc = &pc->phymod_ctrl; 1062 phy = pmc->phy[0]; 1063 if (phy == NULL) { 1064 return SOC_E_INTERNAL; 1065 } 1066 phymod_autoneg_ability_t_init(&phymod_autoneg_ability); 1067 SOC_IF_ERROR_RETURN 1068 (phymod_phy_autoneg_ability_get(&phy->pm_phy, &phymod_autoneg_ability)); 1069 1070 if(PHYMOD_AN_CAP_HALF_DUPLEX_GET(&phymod_autoneg_ability)) { 1071 *duplex = FALSE; 1072 } else { 1073 *duplex = TRUE; 1074 } 1075 1076 return SOC_E_NONE; 1077 } 1078 1079 /* 1080 * Function: 1081 * _phy_qtce_qsgmii_an_get 1082 * Purpose: 1083 * Get QSGMII AN mode enable or not info 1084 * Parameters: 1085 * unit - BCM unit number. 1086 * port - Port number. 1087 * enable - QSGMII AN enabled or not. 1088 * Returns: 1089 * SOC_E_NONE 1090 */ 1091 STATIC int 1092 _phy_qtce_qsgmii_an_get(int unit, soc_port_t port, int *enable) 1093 { 1094 phy_ctrl_t *pc; 1095 soc_phymod_ctrl_t *pmc; 1096 soc_phymod_phy_t *phy; 1097 int an = 0, an_done = 0; 1098 1099 *enable = 0; 1100 pc = INT_PHY_SW_STATE(unit, port); 1101 if (pc == NULL) { 1102 return SOC_E_INTERNAL; 1103 } 1104 pmc = &pc->phymod_ctrl; 1105 if (pmc == NULL) { 1106 return SOC_E_INTERNAL; 1107 } 1108 phy = pmc->phy[0]; 1109 if (phy == NULL) { 1110 return SOC_E_INTERNAL; 1111 } 1112 if (PHYMOD_ACC_F_QMODE_GET(&phy->pm_phy.access)) { 1113 SOC_IF_ERROR_RETURN 1114 (phy_qtce_an_get(unit, port, &an, &an_done)); 1115 if (an) { 1116 *enable = 1; 1117 } 1118 } 1119 return SOC_E_NONE; 1120 } 1121 1122 /* 1123 * Function: 1124 * phy_qtce_interface_set 1125 * Purpose: 1126 * Set PHY interface type 1127 * Parameters: 1128 * unit - BCM unit number. 1129 * port - Port number. 1130 * pif - Interface type 1131 * Returns: 1132 * SOC_E_NONE 1133 */ 1134 1135 STATIC int 1136 phy_qtce_interface_set(int unit, soc_port_t port, soc_port_if_t pif) 1137 { 1138 phy_ctrl_t *pc; 1139 qtce_config_t *pCfg; 1140 1141 /* locate phy control */ 1142 pc = INT_PHY_SW_STATE(unit, port); 1143 if (pc == NULL) { 1144 return SOC_E_INTERNAL; 1145 } 1146 1147 pCfg = (qtce_config_t *) pc->driver_data; 1148 pCfg->speed_config.line_interface = (uint32) pif; 1149 1150 if (pif == SOC_PORT_IF_GMII) { 1151 pCfg->speed_config.fiber_pref = 1; 1152 } else if (pif == SOC_PORT_IF_SGMII) { 1153 pCfg->speed_config.fiber_pref = 0; 1154 } 1155 1156 return (SOC_E_NONE); 1157 } 1158 /* 1159 * Function: 1160 * phy_qtce_interface_get 1161 * Purpose: 1162 * Get PHY interface type 1163 * Parameters: 1164 * unit - BCM unit number. 1165 * port - Port number. 1166 * pif - current interface type 1167 * Returns: 1168 * SOC_E_NONE 1169 */ 1170 STATIC int 1171 phy_qtce_interface_get(int unit, soc_port_t port, soc_port_if_t *pif) 1172 { 1173 phy_ctrl_t *pc; 1174 soc_phymod_ctrl_t *pmc; 1175 soc_phymod_phy_t *phy; 1176 phymod_phy_inf_config_t interface_config; 1177 int flag = 0; 1178 phymod_ref_clk_t ref_clk; 1179 qtce_config_t *pCfg; 1180 1181 /* locate phy control */ 1182 pc = INT_PHY_SW_STATE(unit, port); 1183 if (pc == NULL) { 1184 return SOC_E_INTERNAL; 1185 } 1186 1187 pmc = &pc->phymod_ctrl; 1188 1189 1190 /* now loop through all cores */ 1191 phy = pmc->phy[0]; 1192 if (phy == NULL) { 1193 return SOC_E_INTERNAL; 1194 } 1195 1196 pCfg = (qtce_config_t *) pc->driver_data; 1197 SOC_IF_ERROR_RETURN( 1198 qtce_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clk)); 1199 1200 /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */ 1201 SOC_IF_ERROR_RETURN 1202 (phymod_phy_interface_config_get(&phy->pm_phy, 1203 flag, ref_clk, &interface_config)); 1204 switch (interface_config.interface_type) { 1205 case phymodInterface1000X: 1206 *pif = SOC_PORT_IF_GMII; 1207 break; 1208 case phymodInterfaceSGMII: 1209 *pif = SOC_PORT_IF_SGMII; 1210 break; 1211 default: 1212 *pif = SOC_PORT_IF_SGMII; 1213 break; 1214 } 1215 return (SOC_E_NONE); 1216 } 1217 1218 /* 1219 * Function: 1220 * phy_qtce_speed_set 1221 * Purpose: 1222 * Set PHY speed 1223 * Parameters: 1224 * unit - BCM unit number. 1225 * port - Port number. 1226 * speed - link speed in Mbps 1227 * Returns: 1228 * SOC_E_NONE 1229 */ 1230 1231 STATIC int 1232 phy_qtce_speed_set(int unit, soc_port_t port, int speed) 1233 { 1234 phy_ctrl_t *pc; 1235 qtce_config_t *pCfg; 1236 soc_phymod_ctrl_t *pmc; 1237 soc_phymod_phy_t *phy; 1238 int idx; 1239 qtce_speed_config_t speed_config; 1240 phymod_phy_inf_config_t interface_config; 1241 phymod_autoneg_control_t an_control; 1242 int an_complete; 1243 1244 /* locate phy control */ 1245 pc = INT_PHY_SW_STATE(unit, port); 1246 if (pc == NULL) { 1247 return SOC_E_INTERNAL; 1248 } 1249 1250 if (speed == 0) { 1251 return SOC_E_NONE; 1252 } 1253 1254 if (speed == 0) { 1255 /* coverity[dead_error_line] */ 1256 return SOC_E_NONE; 1257 } 1258 1259 pmc = &pc->phymod_ctrl; 1260 pCfg = (qtce_config_t *) pc->driver_data; 1261 1262 /* take a copy of core and phy configuration values, and set the desired speed */ 1263 sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config)); 1264 speed_config.speed = speed; 1265 1266 /* determine the interface configuration */ 1267 SOC_IF_ERROR_RETURN 1268 (qtce_speed_to_interface_config_get(&speed_config, &interface_config)); 1269 1270 /* now loop through all cores */ 1271 for (idx = 0; idx < pmc->num_phys; idx++) { 1272 phy = pmc->phy[idx]; 1273 if (phy == NULL) { 1274 return SOC_E_INTERNAL; 1275 } 1276 1277 /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */ 1278 SOC_IF_ERROR_RETURN 1279 (phymod_phy_interface_config_set(&phy->pm_phy, 1280 0 /* flags */, &interface_config)); 1281 } 1282 1283 /* record success */ 1284 pCfg->speed_config.speed = speed; 1285 1286 sal_memset(&an_control, 0x0, sizeof(an_control)); 1287 idx = pmc->main_phy; 1288 phy = pmc->phy[idx]; 1289 SOC_IF_ERROR_RETURN 1290 (phymod_phy_autoneg_get(&phy->pm_phy, &an_control, 1291 (uint32_t *) &an_complete)); 1292 1293 if (an_control.enable) { 1294 /* The autoneg might take up to 300 ms to link up. */ 1295 sal_msleep(300); 1296 } 1297 1298 return (SOC_E_NONE); 1299 } 1300 1301 /* 1302 * Function: 1303 * phy_qtce_speed_get 1304 * Purpose: 1305 * Get PHY speed 1306 * Parameters: 1307 * unit - BCM unit number. 1308 * port - Port number. 1309 * speed - current link speed in Mbps 1310 * Returns: 1311 * SOC_E_NONE 1312 */ 1313 STATIC int 1314 phy_qtce_speed_get(int unit, soc_port_t port, int *speed) 1315 { 1316 phy_ctrl_t *pc; 1317 soc_phymod_ctrl_t *pmc; 1318 soc_phymod_phy_t *phy; 1319 phymod_phy_inf_config_t interface_config; 1320 int flag = 0; 1321 phymod_ref_clk_t ref_clk; 1322 qtce_config_t *pCfg; 1323 1324 /* locate phy control */ 1325 pc = INT_PHY_SW_STATE(unit, port); 1326 if (pc == NULL) { 1327 return SOC_E_INTERNAL; 1328 } 1329 1330 pmc = &pc->phymod_ctrl; 1331 1332 /* initialize the data structure */ 1333 interface_config.data_rate = 0; 1334 1335 /* now loop through all cores */ 1336 phy = pmc->phy[0]; 1337 if (phy == NULL) { 1338 return SOC_E_INTERNAL; 1339 } 1340 1341 pCfg = (qtce_config_t *) pc->driver_data; 1342 SOC_IF_ERROR_RETURN( 1343 qtce_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clk)); 1344 1345 /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */ 1346 SOC_IF_ERROR_RETURN 1347 (phymod_phy_interface_config_get(&phy->pm_phy, 1348 flag, ref_clk, &interface_config)); 1349 *speed = interface_config.data_rate; 1350 return (SOC_E_NONE); 1351 } 1352 1353 /* 1354 * Function: 1355 * phy_qtce_an_set 1356 * Purpose: 1357 * Enable or disable auto-negotiation on the specified port. 1358 * Parameters: 1359 * unit - BCM unit number. 1360 * port - Port number. 1361 * an - Boolean, if true, auto-negotiation is enabled 1362 * (and/or restarted). If false, autonegotiation is disabled. 1363 * Returns: 1364 * SOC_E_XXX _soc_triumph_tx 1365 */ 1366 STATIC int 1367 phy_qtce_an_set(int unit, soc_port_t port, int enable) 1368 { 1369 #if 1 1370 phy_ctrl_t *pc; 1371 qtce_config_t *pCfg; 1372 soc_phymod_ctrl_t *pmc; 1373 soc_phymod_phy_t *phy; 1374 phymod_autoneg_control_t an; 1375 #if 0 1376 soc_info_t *si; 1377 #endif 1378 1379 /* locate phy control */ 1380 pc = INT_PHY_SW_STATE(unit, port); 1381 if (pc == NULL) { 1382 return SOC_E_INTERNAL; 1383 } 1384 1385 phymod_autoneg_control_t_init(&an); 1386 pmc = &pc->phymod_ctrl; 1387 pCfg = (qtce_config_t *) pc->driver_data; 1388 #if 0 1389 si = &SOC_INFO(unit); 1390 #endif 1391 1392 /* only request autoneg on the first core */ 1393 phy = pmc->phy[0]; 1394 if (phy == NULL) { 1395 return SOC_E_INTERNAL; 1396 } 1397 an.enable = enable; 1398 an.num_lane_adv = 1; 1399 an.an_mode = phymod_AN_MODE_NONE; 1400 /*first check if qsgmii mode */ 1401 if (pCfg->fiber_pref) { 1402 an.an_mode = phymod_AN_MODE_CL37; 1403 } else { 1404 an.an_mode = phymod_AN_MODE_SGMII; 1405 } 1406 1407 if (pCfg->cl37an == TEMOD_CL37_W_BAM) { 1408 an.an_mode = phymod_AN_MODE_CL37BAM; 1409 } 1410 1411 SOC_IF_ERROR_RETURN 1412 (phymod_phy_autoneg_set(&phy->pm_phy, &an)); 1413 #endif 1414 return (SOC_E_NONE); 1415 } 1416 1417 /* 1418 * Function: 1419 * phy_qtce_an_get 1420 * Purpose: 1421 * Get the current auto-negotiation status (enabled/busy) 1422 * Parameters: 1423 * unit - BCM unit number. 1424 * port - Port number. 1425 * an - (OUT) if true, auto-negotiation is enabled. 1426 * an_done - (OUT) if true, auto-negotiation is complete. This 1427 * value is undefined if an == false. 1428 * Returns: 1429 * SOC_E_XXX 1430 */ 1431 1432 STATIC int 1433 phy_qtce_an_get(int unit, soc_port_t port, int *an, int *an_done) 1434 { 1435 phy_ctrl_t* pc; 1436 soc_phymod_ctrl_t *pmc; 1437 phymod_phy_access_t *pm_phy; 1438 phymod_autoneg_control_t an_control; 1439 int idx, an_complete; 1440 1441 pc = INT_PHY_SW_STATE(unit, port); 1442 pmc = &pc->phymod_ctrl; 1443 1444 sal_memset(&an_control, 0x0, sizeof(an_control)); 1445 1446 idx = pmc->main_phy; 1447 pm_phy = &pmc->phy[idx]->pm_phy; 1448 SOC_IF_ERROR_RETURN 1449 (phymod_phy_autoneg_get(pm_phy, &an_control, (uint32_t *) &an_complete)); 1450 1451 if (an_control.enable) { 1452 *an = 1; 1453 *an_done = an_complete; 1454 } else { 1455 *an = 0; 1456 *an_done = 0; 1457 } 1458 return (SOC_E_NONE); 1459 } 1460 1461 /* 1462 * Function: 1463 * phy_qtce_ability_advert_set 1464 * Purpose: 1465 * Set the current advertisement for auto-negotiation. 1466 * Parameters: 1467 * unit - BCM unit number. 1468 * port - Port number. 1469 * ability - Port mode mask indicating supported options/speeds. 1470 * Returns: 1471 * SOC_E_XXX 1472 * Notes: 1473 * The advertisement is set only for the ACTIVE medium. 1474 * No synchronization performed at this level. 1475 */ 1476 1477 STATIC int 1478 phy_qtce_ability_advert_set(int unit, soc_port_t port, 1479 soc_port_ability_t *ability) 1480 { 1481 phy_ctrl_t *pc; 1482 soc_phymod_ctrl_t *pmc; 1483 soc_phymod_phy_t *phy; 1484 phymod_autoneg_ability_t phymod_autoneg_ability; 1485 1486 /* locate phy control */ 1487 pc = INT_PHY_SW_STATE(unit, port); 1488 if (pc == NULL) { 1489 return SOC_E_INTERNAL; 1490 } 1491 1492 phymod_autoneg_ability_t_init(&phymod_autoneg_ability); 1493 1494 pmc = &pc->phymod_ctrl; 1495 1496 /* only set abilities on the first core */ 1497 phy = pmc->phy[0]; 1498 if (phy == NULL) { 1499 return SOC_E_INTERNAL; 1500 } 1501 1502 1503 1504 switch (ability->pause & (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX)) { 1505 case SOC_PA_PAUSE_TX: 1506 PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability); 1507 break; 1508 case SOC_PA_PAUSE_RX: 1509 /*an_adv |= MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; */ 1510 PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability); 1511 PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability); 1512 break; 1513 case SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX: 1514 PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability); 1515 break; 1516 } 1517 1518 /* also set the sgmii speed */ 1519 if(ability->speed_half_duplex) { 1520 if(ability->speed_half_duplex & SOC_PA_SPEED_1000MB) { 1521 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 1522 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_1000M; 1523 } else if(ability->speed_half_duplex & SOC_PA_SPEED_100MB) { 1524 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 1525 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_100M; 1526 } else if(ability->speed_half_duplex & SOC_PA_SPEED_10MB) { 1527 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 1528 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_10M; 1529 } 1530 PHYMOD_AN_CAP_HALF_DUPLEX_SET(&phymod_autoneg_ability); 1531 } 1532 if(ability->speed_full_duplex) { 1533 if(ability->speed_full_duplex & SOC_PA_SPEED_1000MB) { 1534 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 1535 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_1000M; 1536 } else if(ability->speed_full_duplex & SOC_PA_SPEED_100MB) { 1537 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 1538 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_100M; 1539 } else if(ability->speed_full_duplex & SOC_PA_SPEED_10MB) { 1540 PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability); 1541 phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_10M; 1542 } 1543 if(ability->speed_full_duplex & SOC_PA_SPEED_2500MB) { 1544 PHYMOD_AN_CAP_CL37BAM_SET(&phymod_autoneg_ability); 1545 } 1546 PHYMOD_AN_CAP_HALF_DUPLEX_CLR(&phymod_autoneg_ability); 1547 } 1548 SOC_IF_ERROR_RETURN 1549 (phymod_phy_autoneg_ability_set(&phy->pm_phy, &phymod_autoneg_ability)); 1550 1551 return SOC_E_NONE; 1552 } 1553 1554 /* 1555 * Function: 1556 * phy_qtce_ability_advert_get 1557 * Purpose: 1558 * Get the current advertisement for auto-negotiation. 1559 * Parameters: 1560 * unit - BCM unit number. 1561 * port - Port number. 1562 * ability - (OUT) Port mode mask indicating supported options/speeds. 1563 * Returns: 1564 * SOC_E_XXX 1565 * Notes: 1566 * The advertisement is retrieved for the ACTIVE medium. 1567 * No synchronization performed at this level. 1568 */ 1569 1570 STATIC int 1571 phy_qtce_ability_advert_get(int unit, soc_port_t port, 1572 soc_port_ability_t *ability) 1573 { 1574 phy_ctrl_t *pc; 1575 soc_phymod_ctrl_t *pmc; 1576 soc_phymod_phy_t *phy; 1577 int reg37_ability; 1578 int reg_ability; 1579 _shr_port_mode_t speed_full_duplex; 1580 phymod_autoneg_ability_t phymod_autoneg_ability; 1581 1582 /* locate phy control */ 1583 pc = INT_PHY_SW_STATE(unit, port); 1584 if (pc == NULL) { 1585 return SOC_E_INTERNAL; 1586 } 1587 1588 pmc = &pc->phymod_ctrl; 1589 1590 /* only get abilities from the first core */ 1591 phy = pmc->phy[0]; 1592 if (phy == NULL) { 1593 return SOC_E_INTERNAL; 1594 } 1595 1596 phymod_autoneg_ability_t_init(&phymod_autoneg_ability); 1597 SOC_IF_ERROR_RETURN 1598 (phymod_phy_autoneg_ability_get(&phy->pm_phy, &phymod_autoneg_ability)); 1599 1600 speed_full_duplex = 0; 1601 1602 reg37_ability = phymod_autoneg_ability.cl37bam_cap; 1603 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_2P5G_GET(reg37_ability)? SOC_PA_SPEED_2500MB:0; 1604 1605 reg_ability = phymod_autoneg_ability.capabilities & (PHYMOD_AN_CAP_SYMM_PAUSE|PHYMOD_AN_CAP_ASYM_PAUSE); 1606 1607 ability->pause = 0; 1608 if (reg_ability == PHYMOD_AN_CAP_ASYM_PAUSE) { 1609 ability->pause = SOC_PA_PAUSE_TX; 1610 } else if (reg_ability == (PHYMOD_AN_CAP_SYMM_PAUSE|PHYMOD_AN_CAP_ASYM_PAUSE)) { 1611 ability->pause = SOC_PA_PAUSE_RX; 1612 } else if (reg_ability == PHYMOD_AN_CAP_SYMM_PAUSE) { 1613 ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX); 1614 } 1615 1616 if(PHYMOD_AN_CAP_SGMII_GET(&phymod_autoneg_ability)) { 1617 1618 if(phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_10M) { 1619 speed_full_duplex|= SOC_PA_SPEED_10MB ; 1620 } 1621 if(phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_100M) { 1622 speed_full_duplex|= SOC_PA_SPEED_100MB ; 1623 } 1624 if(phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_1000M) { 1625 speed_full_duplex|= SOC_PA_SPEED_1000MB ; 1626 } 1627 1628 if(PHYMOD_AN_CAP_HALF_DUPLEX_GET(&phymod_autoneg_ability)) { 1629 ability->speed_full_duplex = 0 ; 1630 ability->speed_half_duplex = speed_full_duplex; 1631 } else { 1632 ability->speed_full_duplex = speed_full_duplex; 1633 ability->speed_half_duplex = 0; 1634 } 1635 } else { /* simplify CL37 */ 1636 speed_full_duplex|= SOC_PA_SPEED_1000MB ; 1637 ability->speed_full_duplex = speed_full_duplex; 1638 ability->speed_half_duplex = 0; 1639 } 1640 return SOC_E_NONE; 1641 } 1642 1643 /* 1644 * Function: 1645 * phy_qtce_ability_remote_get 1646 * Purpose: 1647 * Get the current advertisement for auto-negotiation. 1648 * Parameters: 1649 * unit - BCM unit number. 1650 * port - Port number. 1651 * ability - (OUT) Port mode mask indicating supported options/speeds. 1652 * Returns: 1653 * SOC_E_XXX 1654 * Notes: 1655 * The advertisement is retrieved for the ACTIVE medium. 1656 * No synchronization performed at this level. 1657 */ 1658 1659 STATIC int 1660 phy_qtce_ability_remote_get(int unit, soc_port_t port, 1661 soc_port_ability_t *ability) 1662 { 1663 phy_ctrl_t *pc; 1664 soc_phymod_ctrl_t *pmc; 1665 soc_phymod_phy_t *phy; 1666 int reg37_ability; 1667 int reg_ability; 1668 _shr_port_mode_t speed_full_duplex; 1669 phymod_autoneg_ability_t phymod_autoneg_ability; 1670 1671 /* locate phy control */ 1672 pc = INT_PHY_SW_STATE(unit, port); 1673 if (pc == NULL) { 1674 return SOC_E_INTERNAL; 1675 } 1676 1677 pmc = &pc->phymod_ctrl; 1678 1679 /* only get abilities from the first core */ 1680 phy = pmc->phy[0]; 1681 if (phy == NULL) { 1682 return SOC_E_INTERNAL; 1683 } 1684 1685 phymod_autoneg_ability_t_init(&phymod_autoneg_ability); 1686 SOC_IF_ERROR_RETURN 1687 (phymod_phy_autoneg_remote_ability_get(&phy->pm_phy, &phymod_autoneg_ability)); 1688 1689 speed_full_duplex = 0; 1690 reg37_ability = phymod_autoneg_ability.cl37bam_cap; 1691 speed_full_duplex|= PHYMOD_BAM_CL37_CAP_2P5G_GET(reg37_ability)? SOC_PA_SPEED_2500MB:0; 1692 1693 1694 reg_ability = phymod_autoneg_ability.capabilities & (PHYMOD_AN_CAP_SYMM_PAUSE|PHYMOD_AN_CAP_ASYM_PAUSE); 1695 ability->pause = 0; 1696 if (reg_ability == PHYMOD_AN_CAP_ASYM_PAUSE) { 1697 ability->pause = SOC_PA_PAUSE_TX; 1698 } else if (reg_ability == (PHYMOD_AN_CAP_SYMM_PAUSE|PHYMOD_AN_CAP_ASYM_PAUSE)) { 1699 ability->pause = SOC_PA_PAUSE_RX; 1700 } else if (reg_ability == PHYMOD_AN_CAP_SYMM_PAUSE) { 1701 ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX); 1702 } 1703 if(PHYMOD_AN_CAP_SGMII_GET(&phymod_autoneg_ability)) { 1704 if(phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_10M) { 1705 speed_full_duplex|= SOC_PA_SPEED_10MB ; 1706 } 1707 if(phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_100M) { 1708 speed_full_duplex|= SOC_PA_SPEED_100MB ; 1709 } 1710 if(phymod_autoneg_ability.sgmii_speed == phymod_CL37_SGMII_1000M) { 1711 speed_full_duplex|= SOC_PA_SPEED_1000MB ; 1712 } 1713 1714 if(PHYMOD_AN_CAP_HALF_DUPLEX_GET(&phymod_autoneg_ability)) { 1715 ability->speed_full_duplex = 0 ; 1716 ability->speed_half_duplex = speed_full_duplex; 1717 } else { 1718 ability->speed_full_duplex = speed_full_duplex; 1719 ability->speed_half_duplex = 0; 1720 } 1721 } else { /* simplify CL37 */ 1722 speed_full_duplex|= SOC_PA_SPEED_1000MB ; 1723 1724 ability->speed_full_duplex = speed_full_duplex; 1725 ability->speed_half_duplex = 0; 1726 } 1727 return SOC_E_NONE; 1728 } 1729 1730 /* 1731 * Function: 1732 * phy_qtce_lb_set 1733 * Purpose: 1734 * Enable/disable PHY loopback mode 1735 * Parameters: 1736 * unit - BCM unit number. 1737 * port - Port number. 1738 * enable - binary value for on/off (1/0) 1739 * Returns: 1740 * SOC_E_NONE 1741 */ 1742 STATIC int 1743 phy_qtce_lb_set(int unit, soc_port_t port, int enable) 1744 { 1745 phy_ctrl_t* pc; 1746 soc_phymod_ctrl_t *pmc; 1747 phymod_phy_access_t *pm_phy; 1748 int idx; 1749 1750 pc = INT_PHY_SW_STATE(unit, port); 1751 pmc = &pc->phymod_ctrl; 1752 1753 for (idx = 0; idx < pmc->num_phys; idx++) { 1754 pm_phy = &pmc->phy[idx]->pm_phy; 1755 SOC_IF_ERROR_RETURN 1756 (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobal, enable)); 1757 } 1758 1759 return (SOC_E_NONE); 1760 } 1761 1762 /* 1763 * Function: 1764 * phy_qtce_lb_get 1765 * Purpose: 1766 * Get current PHY loopback mode 1767 * Parameters: 1768 * unit - BCM unit number. 1769 * port - Port number. 1770 * enable - address of location to store binary value for on/off (1/0) 1771 * Returns: 1772 * SOC_E_NONE 1773 */ 1774 STATIC int 1775 phy_qtce_lb_get(int unit, soc_port_t port, int *enable) 1776 { 1777 phy_ctrl_t* pc; 1778 soc_phymod_ctrl_t *pmc; 1779 phymod_phy_access_t *pm_phy; 1780 uint32_t lb_enable = 0; 1781 1782 pc = INT_PHY_SW_STATE(unit, port); 1783 pmc = &pc->phymod_ctrl; 1784 1785 *enable = 0; 1786 1787 pm_phy = &pmc->phy[0]->pm_phy; 1788 SOC_IF_ERROR_RETURN 1789 (phymod_phy_loopback_get(pm_phy, phymodLoopbackGlobal, &lb_enable)); 1790 *enable = (int) lb_enable; 1791 return (SOC_E_NONE); 1792 } 1793 1794 /* 1795 * Function: 1796 * phy_qtce_ability_local_get 1797 * Purpose: 1798 * xx 1799 * Parameters: 1800 * unit - BCM unit number. 1801 * port - Port number. 1802 * ability - xx 1803 * Returns: 1804 * SOC_E_NONE 1805 */ 1806 STATIC int 1807 phy_qtce_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability) 1808 { 1809 phy_ctrl_t *pc; 1810 soc_phymod_ctrl_t *pmc; 1811 soc_phymod_phy_t *phy; 1812 qtce_config_t *pCfg; 1813 1814 pc = INT_PHY_SW_STATE(unit, port); 1815 pCfg = (qtce_config_t *) pc->driver_data; 1816 1817 if (NULL == ability) { 1818 return SOC_E_PARAM; 1819 } 1820 if (NULL == pc) { 1821 return SOC_E_INTERNAL; 1822 } 1823 pmc = &pc->phymod_ctrl; 1824 if (NULL == pmc) { 1825 return SOC_E_INTERNAL; 1826 } 1827 phy = pmc->phy[pmc->num_phys - 1]; 1828 if (NULL == phy) { 1829 return SOC_E_INTERNAL; 1830 } 1831 1832 sal_memset(ability, 0, sizeof(*ability)); 1833 1834 ability->loopback = SOC_PA_LB_PHY; 1835 ability->medium = SOC_PA_MEDIUM_COPPER | SOC_PA_MEDIUM_FIBER; 1836 ability->pause = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM; 1837 ability->flags = 0; 1838 1839 if (PHYMOD_ACC_F_QMODE_GET(&phy->pm_phy.access)) { 1840 ability->speed_half_duplex = SOC_PA_SPEED_10MB | 1841 SOC_PA_SPEED_100MB| 1842 SOC_PA_SPEED_1000MB; 1843 1844 ability->speed_full_duplex = SOC_PA_SPEED_10MB | 1845 SOC_PA_SPEED_100MB| 1846 SOC_PA_SPEED_1000MB; 1847 } else { 1848 if (pCfg->fiber_pref) { 1849 ability->speed_full_duplex = SOC_PA_SPEED_1000MB | 1850 SOC_PA_SPEED_2500MB; 1851 } else { 1852 ability->speed_half_duplex = SOC_PA_SPEED_10MB | 1853 SOC_PA_SPEED_100MB| 1854 SOC_PA_SPEED_1000MB; 1855 1856 ability->speed_full_duplex |= SOC_PA_SPEED_10MB | 1857 SOC_PA_SPEED_100MB| 1858 SOC_PA_SPEED_1000MB; 1859 if (pc->speed_max >= 2500) { 1860 ability->speed_full_duplex |= SOC_PA_SPEED_2500MB; 1861 } 1862 } 1863 } 1864 1865 ability->pause = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM; 1866 ability->interface = SOC_PA_INTF_SGMII | SOC_PA_INTF_GMII; 1867 ability->loopback = SOC_PA_LB_PHY; 1868 1869 LOG_INFO(BSL_LS_SOC_PHY, 1870 (BSL_META_U(pc->unit, 1871 "phy_qtce_ability_local_get:unit=%d p=%d sp=%08x\n"), 1872 unit, port, ability->speed_full_duplex)); 1873 return (SOC_E_NONE); 1874 } 1875 1876 /* 1877 * Function: 1878 * qtce_uc_status_dump 1879 * Purpose: 1880 * display all the serdes related parameters 1881 * Parameters: 1882 * unit - BCM unit number. 1883 * port - Port number. 1884 1885 * Returns: 1886 * SOC_E_NONE 1887 */ 1888 STATIC int 1889 qtce_uc_status_dump(int unit, soc_port_t port, void *arg) 1890 { 1891 phy_ctrl_t* pc; 1892 soc_phymod_ctrl_t *pmc; 1893 phymod_phy_access_t *pm_phy; 1894 int idx; 1895 1896 pc = INT_PHY_SW_STATE(unit, port); 1897 pmc = &pc->phymod_ctrl; 1898 1899 for (idx = 0; idx < pmc->num_phys; idx++) { 1900 pm_phy = &pmc->phy[idx]->pm_phy; 1901 SOC_IF_ERROR_RETURN 1902 (phymod_phy_pmd_info_dump(pm_phy, arg)); 1903 } 1904 return (SOC_E_NONE); 1905 } 1906 1907 /* 1908 * Function: 1909 * qtce_pcs_status_dump 1910 * Purpose: 1911 * display all the serdes related parameters 1912 * Parameters: 1913 * unit - BCM unit number. 1914 * port - Port number. 1915 1916 * Returns: 1917 * SOC_E_NONE 1918 */ 1919 STATIC int 1920 qtce_pcs_status_dump(int unit, soc_port_t port, void *arg) 1921 { 1922 phy_ctrl_t* pc; 1923 soc_phymod_ctrl_t *pmc; 1924 phymod_phy_access_t *pm_phy; 1925 int idx; 1926 1927 pc = INT_PHY_SW_STATE(unit, port); 1928 pmc = &pc->phymod_ctrl; 1929 1930 for (idx = 0; idx < pmc->num_phys; idx++) { 1931 pm_phy = &pmc->phy[idx]->pm_phy; 1932 SOC_IF_ERROR_RETURN 1933 (phymod_phy_pcs_info_dump(pm_phy, arg)); 1934 } 1935 return (SOC_E_NONE); 1936 } 1937 1938 /* 1939 * given a pc (phymod_ctrl_t) and logical lane number, 1940 * find the correct soc_phymod_phy_t object and lane 1941 */ 1942 STATIC int 1943 _qtce_find_soc_phy_lane(soc_phymod_ctrl_t *pmc, uint32_t lane, 1944 soc_phymod_phy_t **p_phy, uint32 *lane_map) 1945 { 1946 phymod_phy_access_t *pm_phy; 1947 int idx, lnx, ln_cnt, found; 1948 uint32 lane_map_copy; 1949 1950 /* Traverse lanes belonging to this port */ 1951 found = 0; 1952 ln_cnt = 0; 1953 for (idx = 0; idx < pmc->num_phys; idx++) { 1954 pm_phy = &pmc->phy[idx]->pm_phy; 1955 if (pm_phy == NULL) { 1956 return SOC_E_INTERNAL; 1957 } 1958 lane_map_copy = pm_phy->access.lane_mask; 1959 for (lnx = 0; lnx < 4; lnx++) { 1960 if ((1 << lnx) & lane_map_copy) { 1961 if (ln_cnt == lane) { 1962 found = 1; 1963 break; 1964 } 1965 ln_cnt++; 1966 } 1967 } 1968 if (found) { 1969 *p_phy = pmc->phy[idx]; 1970 *lane_map = (1 << lnx); 1971 break; 1972 } 1973 } 1974 1975 if (!found) { 1976 /* No such lane */ 1977 return SOC_E_PARAM; 1978 } 1979 return (SOC_E_NONE); 1980 } 1981 1982 /* 1983 * qtce_per_lane_preemphasis_set 1984 */ 1985 STATIC int 1986 qtce_per_lane_preemphasis_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 1987 { 1988 soc_phymod_phy_t *p_phy; 1989 uint32 lane_map; 1990 phymod_phy_access_t pm_phy_copy, *pm_phy; 1991 phymod_tx_t phymod_tx; 1992 1993 /* locate the desired phy and lane */ 1994 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 1995 1996 /* Make a copy of the phy access and overwrite the desired lane */ 1997 pm_phy = &p_phy->pm_phy; 1998 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 1999 pm_phy_copy.access.lane_mask = lane_map; 2000 2001 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 2002 phymod_tx.pre = value; 2003 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx)); 2004 2005 return(SOC_E_NONE); 2006 } 2007 2008 /* 2009 * qtce_preemphasis_set 2010 */ 2011 STATIC int 2012 qtce_preemphasis_set(soc_phymod_ctrl_t *pmc, uint32 value) 2013 { 2014 phymod_phy_access_t *pm_phy; 2015 phymod_tx_t phymod_tx; 2016 int idx; 2017 2018 /* loop through all cores */ 2019 for (idx = 0; idx < pmc->num_phys; idx++) { 2020 pm_phy = &pmc->phy[idx]->pm_phy; 2021 2022 if (pm_phy == NULL) { 2023 return SOC_E_INTERNAL; 2024 } 2025 2026 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 2027 phymod_tx.pre = value; 2028 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 2029 2030 2031 } 2032 2033 return(SOC_E_NONE); 2034 } 2035 2036 /* 2037 * qtce_tx_fir_pre_set 2038 */ 2039 STATIC int 2040 qtce_tx_fir_pre_set(soc_phymod_ctrl_t *pmc, uint32 value) 2041 { 2042 phymod_phy_access_t *pm_phy; 2043 phymod_tx_t phymod_tx; 2044 int idx; 2045 2046 /* loop through all cores */ 2047 for (idx = 0; idx < pmc->num_phys; idx++) { 2048 pm_phy = &pmc->phy[idx]->pm_phy; 2049 2050 if (pm_phy == NULL) { 2051 return SOC_E_INTERNAL; 2052 } 2053 2054 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 2055 phymod_tx.pre = value; 2056 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 2057 } 2058 2059 return(SOC_E_NONE); 2060 } 2061 2062 /* 2063 * qtce_tx_fir_main_set 2064 */ 2065 STATIC int 2066 qtce_tx_fir_main_set(soc_phymod_ctrl_t *pmc, uint32 value) 2067 { 2068 phymod_phy_access_t *pm_phy; 2069 phymod_tx_t phymod_tx; 2070 int idx; 2071 2072 /* loop through all cores */ 2073 for (idx = 0; idx < pmc->num_phys; idx++) { 2074 pm_phy = &pmc->phy[idx]->pm_phy; 2075 2076 if (pm_phy == NULL) { 2077 return SOC_E_INTERNAL; 2078 } 2079 2080 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 2081 phymod_tx.main = value; 2082 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 2083 } 2084 2085 return(SOC_E_NONE); 2086 } 2087 2088 /* 2089 * qtce_tx_fir_post_set 2090 */ 2091 STATIC int 2092 qtce_tx_fir_post_set(soc_phymod_ctrl_t *pmc, uint32 value) 2093 { 2094 phymod_phy_access_t *pm_phy; 2095 phymod_tx_t phymod_tx; 2096 int idx; 2097 2098 /* loop through all cores */ 2099 for (idx = 0; idx < pmc->num_phys; idx++) { 2100 pm_phy = &pmc->phy[idx]->pm_phy; 2101 2102 if (pm_phy == NULL) { 2103 return SOC_E_INTERNAL; 2104 } 2105 2106 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 2107 phymod_tx.post = value; 2108 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 2109 } 2110 2111 return(SOC_E_NONE); 2112 } 2113 2114 /* 2115 * qtce_tx_fir_post2_set 2116 */ 2117 STATIC int 2118 qtce_tx_fir_post2_set(soc_phymod_ctrl_t *pmc, uint32 value) 2119 { 2120 phymod_phy_access_t *pm_phy; 2121 phymod_tx_t phymod_tx; 2122 int idx; 2123 2124 /* loop through all cores */ 2125 for (idx = 0; idx < pmc->num_phys; idx++) { 2126 pm_phy = &pmc->phy[idx]->pm_phy; 2127 2128 if (pm_phy == NULL) { 2129 return SOC_E_INTERNAL; 2130 } 2131 2132 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 2133 phymod_tx.post2 = value; 2134 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 2135 } 2136 2137 return(SOC_E_NONE); 2138 } 2139 2140 /* 2141 * qtce_tx_fir_post3_set 2142 */ 2143 STATIC int 2144 qtce_tx_fir_post3_set(soc_phymod_ctrl_t *pmc, uint32 value) 2145 { 2146 phymod_phy_access_t *pm_phy; 2147 phymod_tx_t phymod_tx; 2148 int idx; 2149 2150 /* loop through all cores */ 2151 for (idx = 0; idx < pmc->num_phys; idx++) { 2152 pm_phy = &pmc->phy[idx]->pm_phy; 2153 2154 if (pm_phy == NULL) { 2155 return SOC_E_INTERNAL; 2156 } 2157 2158 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 2159 phymod_tx.post3 = value; 2160 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 2161 } 2162 2163 return(SOC_E_NONE); 2164 } 2165 2166 2167 /* 2168 * qtce_per_lane_driver_current_set 2169 */ 2170 STATIC int 2171 qtce_per_lane_driver_current_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 2172 { 2173 soc_phymod_phy_t *p_phy; 2174 uint32 lane_map; 2175 phymod_phy_access_t pm_phy_copy, *pm_phy; 2176 phymod_tx_t phymod_tx; 2177 2178 /* locate the desired phy and lane */ 2179 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 2180 2181 /* Make a copy of the phy access and overwrite the desired lane */ 2182 pm_phy = &p_phy->pm_phy; 2183 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 2184 pm_phy_copy.access.lane_mask = lane_map; 2185 2186 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 2187 phymod_tx.amp = value; 2188 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx)); 2189 2190 2191 2192 return(SOC_E_NONE); 2193 } 2194 2195 /* 2196 * qtce_driver_current_set 2197 */ 2198 STATIC int 2199 qtce_driver_current_set(soc_phymod_ctrl_t *pmc, uint32 value) 2200 { 2201 phymod_phy_access_t *pm_phy; 2202 phymod_tx_t phymod_tx; 2203 int idx; 2204 2205 /* loop through all cores */ 2206 for (idx = 0; idx < pmc->num_phys; idx++) { 2207 pm_phy = &pmc->phy[idx]->pm_phy; 2208 2209 if (pm_phy == NULL) { 2210 return SOC_E_INTERNAL; 2211 } 2212 2213 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 2214 phymod_tx.amp = value; 2215 SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx)); 2216 } 2217 2218 2219 2220 return(SOC_E_NONE); 2221 } 2222 2223 /* 2224 * qtce_per_lane_rx_dfe_tap_control_set 2225 */ 2226 STATIC int 2227 qtce_per_lane_rx_dfe_tap_control_set(soc_phymod_ctrl_t *pmc, int lane, int tap, int enable, uint32 value) 2228 { 2229 soc_phymod_phy_t *p_phy; 2230 uint32 lane_map; 2231 phymod_phy_access_t pm_phy_copy, *pm_phy; 2232 phymod_rx_t phymod_rx; 2233 2234 /* locate the desired phy and lane */ 2235 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 2236 2237 /* Make a copy of the phy access and overwrite the desired lane */ 2238 pm_phy = &p_phy->pm_phy; 2239 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 2240 pm_phy_copy.access.lane_mask = lane_map; 2241 2242 if ((tap<0)||(tap>(COUNTOF(phymod_rx.dfe) - 1))) { 2243 /* this can only happen with a coding error */ 2244 return SOC_E_INTERNAL; 2245 } 2246 2247 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 2248 phymod_rx.dfe[tap].enable = enable; 2249 phymod_rx.dfe[tap].value = value; 2250 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx)); 2251 2252 return(SOC_E_NONE); 2253 } 2254 2255 2256 /* 2257 * qtce_tx_lane_squelch 2258 */ 2259 STATIC int 2260 qtce_tx_lane_squelch(soc_phymod_ctrl_t *pmc, uint32 value) 2261 { 2262 phymod_phy_access_t *pm_phy; 2263 phymod_phy_power_t phy_power; 2264 int idx; 2265 2266 /* loop through all cores */ 2267 for (idx = 0; idx < pmc->num_phys; idx++) { 2268 pm_phy = &pmc->phy[idx]->pm_phy; 2269 2270 if (pm_phy == NULL) { 2271 return SOC_E_INTERNAL; 2272 } 2273 2274 if (value == 1) { 2275 phy_power.tx = phymodPowerOff; 2276 phy_power.rx = phymodPowerNoChange; 2277 } else { 2278 phy_power.tx = phymodPowerOn; 2279 phy_power.rx = phymodPowerNoChange; 2280 } 2281 SOC_IF_ERROR_RETURN 2282 (phymod_phy_power_set(pm_phy, &phy_power)); 2283 } 2284 return(SOC_E_NONE); 2285 } 2286 2287 /* 2288 * qtce_per_lane_rx_peak_filter_set 2289 */ 2290 STATIC int 2291 qtce_per_lane_rx_peak_filter_set(soc_phymod_ctrl_t *pmc, int lane, int enable, uint32 value) 2292 { 2293 soc_phymod_phy_t *p_phy; 2294 uint32 lane_map; 2295 phymod_phy_access_t pm_phy_copy, *pm_phy; 2296 phymod_rx_t phymod_rx; 2297 2298 /* locate the desired phy and lane */ 2299 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 2300 2301 /* Make a copy of the phy access and overwrite the desired lane */ 2302 pm_phy = &p_phy->pm_phy; 2303 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 2304 pm_phy_copy.access.lane_mask = lane_map; 2305 2306 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 2307 phymod_rx.peaking_filter.enable = TRUE; 2308 phymod_rx.peaking_filter.value = value; 2309 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 2310 2311 return(SOC_E_NONE); 2312 } 2313 2314 /* 2315 * qtce_rx_peak_filter_set 2316 */ 2317 STATIC int 2318 qtce_rx_peak_filter_set(soc_phymod_ctrl_t *pmc, uint32 value) 2319 { 2320 phymod_phy_access_t *pm_phy; 2321 phymod_rx_t phymod_rx; 2322 int idx; 2323 2324 /* loop through all cores */ 2325 for (idx = 0; idx < pmc->num_phys; idx++) { 2326 pm_phy = &pmc->phy[idx]->pm_phy; 2327 2328 if (pm_phy == NULL) { 2329 return SOC_E_INTERNAL; 2330 } 2331 2332 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 2333 phymod_rx.peaking_filter.enable = TRUE; 2334 phymod_rx.peaking_filter.value = value; 2335 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 2336 } 2337 2338 return(SOC_E_NONE); 2339 } 2340 2341 /* 2342 * qtce_per_lane_rx_vga_set 2343 */ 2344 STATIC int 2345 qtce_per_lane_rx_vga_set(soc_phymod_ctrl_t *pmc, int lane, int enable, uint32 value) 2346 { 2347 soc_phymod_phy_t *p_phy; 2348 uint32 lane_map; 2349 phymod_phy_access_t pm_phy_copy, *pm_phy; 2350 phymod_rx_t phymod_rx; 2351 2352 /* locate the desired phy and lane */ 2353 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 2354 2355 /* Make a copy of the phy access and overwrite the desired lane */ 2356 pm_phy = &p_phy->pm_phy; 2357 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 2358 pm_phy_copy.access.lane_mask = lane_map; 2359 2360 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 2361 phymod_rx.vga.enable = TRUE; 2362 phymod_rx.vga.value = value; 2363 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 2364 2365 return(SOC_E_NONE); 2366 } 2367 2368 /* 2369 * qtce_rx_vga_set 2370 */ 2371 STATIC int 2372 qtce_rx_vga_set(soc_phymod_ctrl_t *pmc, uint32 value) 2373 { 2374 phymod_phy_access_t *pm_phy; 2375 phymod_rx_t phymod_rx; 2376 int idx; 2377 2378 /* loop through all cores */ 2379 for (idx = 0; idx < pmc->num_phys; idx++) { 2380 pm_phy = &pmc->phy[idx]->pm_phy; 2381 2382 if (pm_phy == NULL) { 2383 return SOC_E_INTERNAL; 2384 } 2385 2386 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 2387 phymod_rx.vga.enable = TRUE; 2388 phymod_rx.vga.value = value; 2389 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 2390 } 2391 2392 return(SOC_E_NONE); 2393 } 2394 2395 STATIC int 2396 qtce_rx_tap_release(soc_phymod_ctrl_t *pmc, int tap) 2397 { 2398 phymod_phy_access_t *pm_phy; 2399 phymod_rx_t phymod_rx; 2400 int idx; 2401 2402 /* bounds check "tap" */ 2403 if ((tap < 0) || (tap >= COUNTOF(phymod_rx.dfe))) { 2404 return SOC_E_INTERNAL; 2405 } 2406 2407 /* loop through all cores */ 2408 for (idx = 0; idx < pmc->num_phys; idx++) { 2409 pm_phy = &pmc->phy[idx]->pm_phy; 2410 2411 if (pm_phy == NULL) { 2412 return SOC_E_INTERNAL; 2413 } 2414 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 2415 phymod_rx.dfe[tap].enable = FALSE; 2416 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 2417 } 2418 return(SOC_E_NONE); 2419 } 2420 2421 /* 2422 * qtce_rx_tap_set 2423 */ 2424 STATIC int 2425 qtce_rx_tap_set(soc_phymod_ctrl_t *pmc, int tap, uint32 value) 2426 { 2427 phymod_phy_access_t *pm_phy; 2428 phymod_rx_t phymod_rx; 2429 int idx; 2430 2431 /* bounds check "tap" */ 2432 if ((tap < 0) || (tap > COUNTOF(phymod_rx.dfe) - 1)) { 2433 return SOC_E_INTERNAL; 2434 } 2435 2436 /* loop through all cores */ 2437 for (idx = 0; idx < pmc->num_phys; idx++) { 2438 pm_phy = &pmc->phy[idx]->pm_phy; 2439 2440 if (pm_phy == NULL) { 2441 return SOC_E_INTERNAL; 2442 } 2443 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 2444 phymod_rx.dfe[tap].enable = TRUE; 2445 phymod_rx.dfe[tap].value = value; 2446 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 2447 } 2448 2449 return(SOC_E_NONE); 2450 } 2451 2452 /* 2453 * qtce_pi_control_set 2454 */ 2455 STATIC int 2456 qtce_pi_control_set(soc_phymod_ctrl_t *pmc, uint32 value) 2457 { 2458 phymod_phy_access_t *pm_phy; 2459 phymod_tx_override_t tx_override; 2460 int idx; 2461 2462 /* loop through all cores */ 2463 for (idx = 0; idx < pmc->num_phys; idx++) { 2464 pm_phy = &pmc->phy[idx]->pm_phy; 2465 2466 if (pm_phy == NULL) { 2467 return SOC_E_INTERNAL; 2468 } 2469 2470 phymod_tx_override_t_init(&tx_override); 2471 tx_override.phase_interpolator.enable = (value == 0) ? 0 : 1; 2472 tx_override.phase_interpolator.value = value; 2473 SOC_IF_ERROR_RETURN(phymod_phy_tx_override_set(pm_phy, &tx_override)); 2474 } 2475 2476 return(SOC_E_NONE); 2477 } 2478 2479 /* 2480 * qtce_tx_polarity_set 2481 */ 2482 STATIC int 2483 qtce_tx_polarity_set(soc_phymod_ctrl_t *pmc, phymod_polarity_t *cfg_polarity, uint32 value) 2484 { 2485 phymod_phy_access_t *pm_phy; 2486 phymod_polarity_t polarity; 2487 int idx; 2488 2489 /* loop through all cores */ 2490 for (idx = 0; idx < pmc->num_phys; idx++) { 2491 pm_phy = &pmc->phy[idx]->pm_phy; 2492 2493 if (pm_phy == NULL) { 2494 return SOC_E_INTERNAL; 2495 } 2496 2497 sal_memcpy(&polarity, cfg_polarity, sizeof(polarity)); 2498 polarity.tx_polarity = value; 2499 SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(pm_phy, &polarity)); 2500 2501 /* after successfully setting the parity, update the configured value */ 2502 cfg_polarity->tx_polarity = value; 2503 } 2504 2505 return(SOC_E_NONE); 2506 } 2507 2508 /* 2509 * qtce_rx_polarity_set 2510 */ 2511 2512 STATIC int 2513 qtce_rx_polarity_set(soc_phymod_ctrl_t *pmc, phymod_polarity_t *cfg_polarity, uint32 value) 2514 { 2515 phymod_phy_access_t *pm_phy; 2516 phymod_polarity_t polarity; 2517 int idx; 2518 2519 /* loop through all cores */ 2520 for (idx = 0; idx < pmc->num_phys; idx++) { 2521 pm_phy = &pmc->phy[idx]->pm_phy; 2522 2523 if (pm_phy == NULL) { 2524 return SOC_E_INTERNAL; 2525 } 2526 2527 sal_memcpy(&polarity, cfg_polarity, sizeof(polarity)); 2528 polarity.rx_polarity = value; 2529 SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(pm_phy, &polarity)); 2530 2531 /* after successfully setting the parity, update the configured value */ 2532 cfg_polarity->rx_polarity = value; 2533 } 2534 2535 return(SOC_E_NONE); 2536 } 2537 2538 /* 2539 * qtce_rx_reset 2540 */ 2541 STATIC int 2542 qtce_rx_reset(soc_phymod_ctrl_t *pmc, phymod_phy_reset_t *cfg_reset, uint32 value) 2543 { 2544 phymod_phy_access_t *pm_phy; 2545 phymod_phy_reset_t reset; 2546 int idx; 2547 2548 /* loop through all cores */ 2549 for (idx = 0; idx < pmc->num_phys; idx++) { 2550 pm_phy = &pmc->phy[idx]->pm_phy; 2551 2552 if (pm_phy == NULL) { 2553 return SOC_E_INTERNAL; 2554 } 2555 2556 sal_memcpy(&reset, cfg_reset, sizeof(reset)); 2557 reset.rx = (phymod_reset_direction_t) value; 2558 SOC_IF_ERROR_RETURN(phymod_phy_reset_set(pm_phy, &reset)); 2559 2560 /* after successfully setting the parity, update the configured value */ 2561 cfg_reset->rx = (phymod_reset_direction_t) value; 2562 } 2563 2564 return(SOC_E_NONE); 2565 } 2566 2567 /* 2568 * qtce_tx_reset 2569 */ 2570 STATIC int 2571 qtce_tx_reset(soc_phymod_ctrl_t *pmc, phymod_phy_reset_t *cfg_reset, uint32 value) 2572 { 2573 phymod_phy_access_t *pm_phy; 2574 phymod_phy_reset_t reset; 2575 int idx; 2576 2577 /* loop through all cores */ 2578 for (idx = 0; idx < pmc->num_phys; idx++) { 2579 pm_phy = &pmc->phy[idx]->pm_phy; 2580 2581 if (pm_phy == NULL) { 2582 return SOC_E_INTERNAL; 2583 } 2584 2585 sal_memcpy(&reset, cfg_reset, sizeof(reset)); 2586 reset.tx = (phymod_reset_direction_t) value; 2587 SOC_IF_ERROR_RETURN(phymod_phy_reset_set(pm_phy, &reset)); 2588 2589 /* after successfully setting the parity, update the configured value */ 2590 cfg_reset->tx = (phymod_reset_direction_t) value; 2591 } 2592 2593 return(SOC_E_NONE); 2594 } 2595 2596 /* 2597 * qtce_cl72_enable_set 2598 */ 2599 STATIC int 2600 qtce_cl72_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 2601 { 2602 phymod_phy_access_t *pm_phy; 2603 int idx; 2604 2605 /* loop through all cores */ 2606 for (idx = 0; idx < pmc->num_phys; idx++) { 2607 pm_phy = &pmc->phy[idx]->pm_phy; 2608 2609 if (pm_phy == NULL) { 2610 return SOC_E_INTERNAL; 2611 } 2612 2613 SOC_IF_ERROR_RETURN(phymod_phy_cl72_set(pm_phy, value)); 2614 } 2615 2616 return(SOC_E_NONE); 2617 } 2618 2619 STATIC int 2620 qtce_lane_map_set(soc_phymod_ctrl_t *pmc, uint32 value){ 2621 int idx; 2622 phymod_lane_map_t lane_map; 2623 2624 lane_map.num_of_lanes = NUM_LANES; 2625 if(pmc->phy[0] == NULL){ 2626 return(SOC_E_INTERNAL); 2627 } 2628 for (idx=0; idx < NUM_LANES; idx++) { 2629 lane_map.lane_map_rx[idx] = (value >> (idx * 4 /*4 bit per lane*/)) & 0xf; 2630 } 2631 for (idx=0; idx < NUM_LANES; idx++) { 2632 lane_map.lane_map_tx[idx] = (value >> (16 + idx * 4 /*4 bit per lane*/)) & 0xf; 2633 } 2634 SOC_IF_ERROR_RETURN(phymod_core_lane_map_set(&pmc->phy[0]->core->pm_core, &lane_map)); 2635 return(SOC_E_NONE); 2636 } 2637 2638 2639 STATIC int 2640 qtce_lane_map_get(soc_phymod_ctrl_t *pmc, uint32 *value){ 2641 int idx; 2642 phymod_lane_map_t lane_map; 2643 2644 *value = 0; 2645 if(pmc->phy[0] == NULL){ 2646 return(SOC_E_INTERNAL); 2647 } 2648 SOC_IF_ERROR_RETURN(phymod_core_lane_map_get(&pmc->phy[0]->core->pm_core, &lane_map)); 2649 if(lane_map.num_of_lanes != NUM_LANES){ 2650 return SOC_E_INTERNAL; 2651 } 2652 for (idx=0; idx < NUM_LANES; idx++) { 2653 *value += (lane_map.lane_map_rx[idx] << (idx * 4)); 2654 } 2655 for (idx=0; idx < NUM_LANES; idx++) { 2656 *value += (lane_map.lane_map_rx[idx]<< (idx * 4 + 16)); 2657 } 2658 2659 return(SOC_E_NONE); 2660 } 2661 2662 2663 STATIC int 2664 qtce_pattern_len_set(soc_phymod_ctrl_t *pmc, uint32_t value) 2665 { 2666 phymod_phy_access_t *pm_phy; 2667 phymod_pattern_t phymod_pattern; 2668 int idx; 2669 2670 /* loop through all cores */ 2671 for (idx = 0; idx < pmc->num_phys; idx++) { 2672 pm_phy = &pmc->phy[idx]->pm_phy; 2673 2674 if (pm_phy == NULL) { 2675 return SOC_E_INTERNAL; 2676 } 2677 2678 phymod_pattern_t_init(&phymod_pattern); 2679 SOC_IF_ERROR_RETURN 2680 (phymod_phy_pattern_config_get(pm_phy, &phymod_pattern)); 2681 phymod_pattern.pattern_len = value; 2682 SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_set(pm_phy, &phymod_pattern)); 2683 } 2684 return(SOC_E_NONE); 2685 } 2686 2687 STATIC int 2688 qtce_pattern_enable_set(soc_phymod_ctrl_t *pmc, uint32_t value) 2689 { 2690 phymod_phy_access_t *pm_phy; 2691 phymod_pattern_t phymod_pattern; 2692 int idx; 2693 2694 /* loop through all cores */ 2695 for (idx = 0; idx < pmc->num_phys; idx++) { 2696 pm_phy = &pmc->phy[idx]->pm_phy; 2697 2698 if (pm_phy == NULL) { 2699 return SOC_E_INTERNAL; 2700 } 2701 2702 phymod_pattern_t_init(&phymod_pattern); 2703 SOC_IF_ERROR_RETURN 2704 (phymod_phy_pattern_config_get(pm_phy, &phymod_pattern)); 2705 SOC_IF_ERROR_RETURN(phymod_phy_pattern_enable_set(pm_phy, value, &phymod_pattern)); 2706 } 2707 return(SOC_E_NONE); 2708 } 2709 2710 /* 2711 * qtce_pattern_data_set 2712 * Sets 32 bits of the 256 bit data pattern. 2713 */ 2714 STATIC int 2715 qtce_pattern_data_set(int idx, qtce_pattern_t *pattern, uint32 value) 2716 { 2717 if ((idx<0) || (idx >= COUNTOF(pattern->pattern_data))) { 2718 return SOC_E_INTERNAL; 2719 } 2720 2721 /* update pattern data */ 2722 pattern->pattern_data[idx] = value; 2723 2724 return(SOC_E_NONE); 2725 } 2726 2727 /* 2728 * qtce_per_lane_prbs_poly_set 2729 */ 2730 STATIC int 2731 qtce_per_lane_prbs_poly_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 2732 { 2733 return(SOC_E_UNAVAIL); 2734 } 2735 2736 2737 STATIC 2738 int 2739 qtce_sdk_poly_to_phymod_poly(uint32 sdk_poly, phymod_prbs_poly_t *phymod_poly){ 2740 switch(sdk_poly){ 2741 case SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1: 2742 *phymod_poly = phymodPrbsPoly7; 2743 break; 2744 case SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1: 2745 *phymod_poly = phymodPrbsPoly15; 2746 break; 2747 case SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1: 2748 *phymod_poly = phymodPrbsPoly23; 2749 break; 2750 case SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1: 2751 *phymod_poly = phymodPrbsPoly31; 2752 break; 2753 case SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1: 2754 *phymod_poly = phymodPrbsPoly9; 2755 break; 2756 case SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1: 2757 *phymod_poly = phymodPrbsPoly11; 2758 break; 2759 case SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1: 2760 *phymod_poly = phymodPrbsPoly58; 2761 break; 2762 default: 2763 return SOC_E_INTERNAL; 2764 } 2765 return SOC_E_NONE; 2766 } 2767 2768 /* 2769 * qtce_prbs_tx_poly_set 2770 */ 2771 STATIC int 2772 qtce_prbs_tx_poly_set(soc_phymod_ctrl_t *pmc, uint32 value) 2773 { 2774 phymod_phy_access_t *pm_phy; 2775 phymod_prbs_t prbs; 2776 uint32_t flags = 0; 2777 2778 2779 /* just take the value from the first phy */ 2780 if (pmc->phy[0] == NULL) { 2781 return SOC_E_INTERNAL; 2782 } 2783 pm_phy = &pmc->phy[0]->pm_phy; 2784 2785 if (pm_phy == NULL) { 2786 return SOC_E_INTERNAL; 2787 } 2788 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 2789 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 2790 SOC_IF_ERROR_RETURN(qtce_sdk_poly_to_phymod_poly(value, &prbs.poly)); 2791 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs)); 2792 return(SOC_E_NONE); 2793 } 2794 2795 /* 2796 * qtce_prbs_rx_poly_set 2797 */ 2798 STATIC int 2799 qtce_prbs_rx_poly_set(soc_phymod_ctrl_t *pmc, uint32 value) 2800 { 2801 phymod_phy_access_t *pm_phy; 2802 phymod_prbs_t prbs; 2803 uint32_t flags = 0; 2804 2805 /* just take the value from the first phy */ 2806 if (pmc->phy[0] == NULL) { 2807 return SOC_E_INTERNAL; 2808 } 2809 pm_phy = &pmc->phy[0]->pm_phy; 2810 2811 if (pm_phy == NULL) { 2812 return SOC_E_INTERNAL; 2813 } 2814 2815 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 2816 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 2817 SOC_IF_ERROR_RETURN(qtce_sdk_poly_to_phymod_poly(value, &prbs.poly)); 2818 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs)); 2819 return(SOC_E_NONE); 2820 } 2821 2822 2823 /* 2824 * qtce_per_lane_prbs_tx_invert_data_set 2825 */ 2826 STATIC int 2827 qtce_per_lane_prbs_tx_invert_data_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 2828 { 2829 return(SOC_E_UNAVAIL); 2830 } 2831 2832 /* 2833 * qtce_prbs_tx_invert_data_set 2834 */ 2835 STATIC int 2836 qtce_prbs_tx_invert_data_set(soc_phymod_ctrl_t *pmc, uint32 value) 2837 { 2838 phymod_phy_access_t *pm_phy; 2839 phymod_prbs_t prbs; 2840 uint32_t flags = 0; 2841 2842 /* just take the value from the first phy */ 2843 if (pmc->phy[0] == NULL) { 2844 return SOC_E_INTERNAL; 2845 } 2846 pm_phy = &pmc->phy[0]->pm_phy; 2847 2848 if (pm_phy == NULL) { 2849 return SOC_E_INTERNAL; 2850 } 2851 2852 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 2853 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 2854 prbs.invert = value; 2855 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs)); 2856 return(SOC_E_NONE); 2857 } 2858 2859 /* 2860 * qtce_prbs_rx_invert_data_set 2861 */ 2862 STATIC int 2863 qtce_prbs_rx_invert_data_set(soc_phymod_ctrl_t *pmc, uint32 value) 2864 { 2865 phymod_phy_access_t *pm_phy; 2866 phymod_prbs_t prbs; 2867 uint32_t flags = 0; 2868 /* just take the value from the first phy */ 2869 if (pmc->phy[0] == NULL) { 2870 return SOC_E_INTERNAL; 2871 } 2872 pm_phy = &pmc->phy[0]->pm_phy; 2873 2874 if (pm_phy == NULL) { 2875 return SOC_E_INTERNAL; 2876 } 2877 2878 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 2879 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 2880 prbs.invert = value; 2881 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs)); 2882 return(SOC_E_NONE); 2883 } 2884 2885 /* 2886 * qtce_per_lane_prbs_tx_enable_set 2887 */ 2888 STATIC int 2889 qtce_per_lane_prbs_tx_enable_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 2890 { 2891 return(SOC_E_UNAVAIL); 2892 } 2893 /* 2894 * qtce_prbs_tx_enable_set 2895 */ 2896 STATIC int 2897 qtce_prbs_tx_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 2898 { 2899 phymod_phy_access_t *pm_phy; 2900 uint32_t flags = 0; 2901 2902 /* just take the value from the first phy */ 2903 if (pmc->phy[0] == NULL) { 2904 return SOC_E_INTERNAL; 2905 } 2906 pm_phy = &pmc->phy[0]->pm_phy; 2907 2908 if (pm_phy == NULL) { 2909 return SOC_E_INTERNAL; 2910 } 2911 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 2912 SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(pm_phy, flags, value)); 2913 return(SOC_E_NONE); 2914 } 2915 2916 /* 2917 * qtce_prbs_rx_enable_set 2918 */ 2919 STATIC int 2920 qtce_prbs_rx_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 2921 { 2922 phymod_phy_access_t *pm_phy; 2923 uint32_t flags = 0; 2924 2925 /* just take the value from the first phy */ 2926 if (pmc->phy[0] == NULL) { 2927 return SOC_E_INTERNAL; 2928 } 2929 pm_phy = &pmc->phy[0]->pm_phy; 2930 2931 if (pm_phy == NULL) { 2932 return SOC_E_INTERNAL; 2933 } 2934 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 2935 SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(pm_phy, flags, value)); 2936 return(SOC_E_NONE); 2937 } 2938 2939 /* 2940 * qtce_loopback_internal_set 2941 */ 2942 STATIC int 2943 qtce_loopback_internal_set(soc_phymod_ctrl_t *pmc, uint32 value) 2944 { 2945 phymod_phy_access_t *pm_phy; 2946 2947 /* just take the value from the first phy */ 2948 if (pmc->phy[0] == NULL) { 2949 return SOC_E_INTERNAL; 2950 } 2951 pm_phy = &pmc->phy[0]->pm_phy; 2952 2953 if (pm_phy == NULL) { 2954 return SOC_E_INTERNAL; 2955 } 2956 2957 SOC_IF_ERROR_RETURN 2958 (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobal, value)); 2959 2960 return(SOC_E_NONE); 2961 } 2962 2963 /* 2964 * qtce_loopback_internal_pmd_set 2965 */ 2966 STATIC int 2967 qtce_loopback_internal_pmd_set(soc_phymod_ctrl_t *pmc, uint32 value) 2968 { 2969 phymod_phy_access_t *pm_phy; 2970 2971 /* just take the value from the first phy */ 2972 if (pmc->phy[0] == NULL) { 2973 return SOC_E_INTERNAL; 2974 } 2975 pm_phy = &pmc->phy[0]->pm_phy; 2976 2977 if (pm_phy == NULL) { 2978 return SOC_E_INTERNAL; 2979 } 2980 2981 SOC_IF_ERROR_RETURN 2982 (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobalPMD, value)); 2983 2984 return(SOC_E_NONE); 2985 } 2986 2987 /* 2988 * qtce_loopback_remote_set 2989 */ 2990 STATIC int 2991 qtce_loopback_remote_set(soc_phymod_ctrl_t *pmc, uint32 value) 2992 { 2993 phymod_phy_access_t *pm_phy; 2994 2995 /* just take the value from the first phy */ 2996 if (pmc->phy[0] == NULL) { 2997 return SOC_E_INTERNAL; 2998 } 2999 pm_phy = &pmc->phy[0]->pm_phy; 3000 3001 if (pm_phy == NULL) { 3002 return SOC_E_INTERNAL; 3003 } 3004 3005 SOC_IF_ERROR_RETURN 3006 (phymod_phy_loopback_set(pm_phy, phymodLoopbackRemotePMD, value)); 3007 3008 return(SOC_E_NONE); 3009 } 3010 3011 /* 3012 * qtce_loopback_remote_pcs_set 3013 */ 3014 STATIC int 3015 qtce_loopback_remote_pcs_set(soc_phymod_ctrl_t *pmc, uint32 value) 3016 { 3017 phymod_phy_access_t *pm_phy; 3018 3019 /* just take the value from the first phy */ 3020 if (pmc->phy[0] == NULL) { 3021 return SOC_E_INTERNAL; 3022 } 3023 pm_phy = &pmc->phy[0]->pm_phy; 3024 3025 if (pm_phy == NULL) { 3026 return SOC_E_INTERNAL; 3027 } 3028 3029 SOC_IF_ERROR_RETURN 3030 (phymod_phy_loopback_set(pm_phy, phymodLoopbackRemotePCS, value)); 3031 3032 return(SOC_E_NONE); 3033 } 3034 3035 /* 3036 * qtce_fec_enable_set 3037 */ 3038 STATIC int 3039 qtce_fec_enable_set(soc_phymod_ctrl_t *pmc, uint32 value) 3040 { 3041 phymod_phy_access_t *pm_phy; 3042 int idx; 3043 3044 /* loop through all cores */ 3045 for (idx = 0; idx < pmc->num_phys; idx++) { 3046 pm_phy = &pmc->phy[idx]->pm_phy; 3047 3048 if (pm_phy == NULL) { 3049 return SOC_E_INTERNAL; 3050 } 3051 SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_set(pm_phy, value)); 3052 } 3053 return(SOC_E_NONE); 3054 } 3055 3056 /* 3057 * qtce_scrambler_set 3058 */ 3059 STATIC int 3060 qtce_scrambler_set(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 value) 3061 { 3062 phymod_phy_access_t *pm_phy; 3063 phymod_phy_inf_config_t config; 3064 int idx; 3065 phy_ctrl_t *pc; 3066 qtce_config_t *pCfg; 3067 phymod_ref_clk_t ref_clk; 3068 3069 pc = INT_PHY_SW_STATE(pmc->unit, port); 3070 if (pc == NULL) { 3071 return SOC_E_INTERNAL; 3072 } 3073 3074 pCfg = (qtce_config_t *) pc->driver_data; 3075 SOC_IF_ERROR_RETURN( 3076 qtce_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clk)); 3077 3078 /* loop through all cores */ 3079 for (idx = 0; idx < pmc->num_phys; idx++) { 3080 pm_phy = &pmc->phy[idx]->pm_phy; 3081 3082 if (pm_phy == NULL) { 3083 return SOC_E_INTERNAL; 3084 } 3085 3086 SOC_IF_ERROR_RETURN(phymod_phy_interface_config_get(pm_phy, 0 /* flags */, ref_clk, &config)); 3087 PHYMOD_INTF_MODES_SCR_SET(&config); 3088 SOC_IF_ERROR_RETURN(phymod_phy_interface_config_set(pm_phy, PHYMOD_INTF_F_DONT_OVERIDE_TX_PARAMS, &config)); 3089 } 3090 3091 #if 0 3092 /* tscmod had the following side effect; assume this is not needed */ 3093 DEV_CFG_PTR(pc)->scrambler_en = value? TRUE: FALSE; 3094 #endif 3095 3096 return(SOC_E_NONE); 3097 } 3098 3099 /* 3100 * qtce_8b10b_set 3101 */ 3102 STATIC int 3103 qtce_8b10b_set(soc_phymod_ctrl_t *pmc, uint32 value) 3104 { 3105 #if 0 3106 In discussion: whether encoding API should be separate 3107 Setting interface and speed: 3108 typedef struct phymod_phy_inf_config_s { 3109 phymod_interface_t interface_type; 3110 uint32 data_rate; /*Use PHYMOD_DEFAULT_RATE of interface default*/ 3111 uint32 interface_modes; 3112 } phymod_phy_inf_config_t; 3113 3114 #define PHYMOD_DEFAULT_RATE 0xFFFFFFFF 3115 3116 int phymod_phy_interface_config_set(int unit, uint32 phy_id, uint32 flags, const phymod_phy_inf_config_t* config); 3117 int phymod_phy_interface_config_get(int unit, uint32 phy_id, uint32 flags, phymod_phy_inf_config_t* config); 3118 #endif 3119 3120 return(SOC_E_UNAVAIL); 3121 } 3122 3123 /* 3124 * qtce_64b65b_set 3125 */ 3126 STATIC int 3127 qtce_64b65b_set(soc_phymod_ctrl_t *pmc, uint32 value) 3128 { 3129 #if 0 3130 In discussion: whether encoding API should be separate 3131 Setting interface and speed: 3132 typedef struct phymod_phy_inf_config_s { 3133 phymod_interface_t interface_type; 3134 uint32 data_rate; /*Use PHYMOD_DEFAULT_RATE of interface default*/ 3135 uint32 interface_modes; 3136 } phymod_phy_inf_config_t; 3137 3138 #define PHYMOD_DEFAULT_RATE 0xFFFFFFFF 3139 3140 int phymod_phy_interface_config_set(int unit, uint32 phy_id, uint32 flags, const phymod_phy_inf_config_t* config); 3141 int phymod_phy_interface_config_get(int unit, uint32 phy_id, uint32 flags, phymod_phy_inf_config_t* config); 3142 #endif 3143 3144 return(SOC_E_UNAVAIL); 3145 } 3146 3147 /* 3148 * qtce_power_set 3149 */ 3150 STATIC int 3151 qtce_power_set(soc_phymod_ctrl_t *pmc, uint32 value) 3152 { 3153 phymod_phy_access_t *pm_phy; 3154 phymod_phy_power_t power; 3155 int idx; 3156 3157 /* loop through all cores */ 3158 for (idx = 0; idx < pmc->num_phys; idx++) { 3159 pm_phy = &pmc->phy[idx]->pm_phy; 3160 3161 if (pm_phy == NULL) { 3162 return SOC_E_INTERNAL; 3163 } 3164 3165 phymod_phy_power_t_init(&power); 3166 if (value) { 3167 power.tx = phymodPowerOn; 3168 power.rx = phymodPowerOn; 3169 } 3170 else { 3171 power.tx = phymodPowerOff; 3172 power.rx = phymodPowerOff; 3173 } 3174 3175 SOC_IF_ERROR_RETURN(phymod_phy_power_set(pm_phy, &power)); 3176 } 3177 3178 return(SOC_E_NONE); 3179 } 3180 3181 /* 3182 * qtce_per_lane_rx_low_freq_filter_set 3183 */ 3184 STATIC int 3185 qtce_per_lane_rx_low_freq_filter_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value) 3186 { 3187 return(SOC_E_UNAVAIL); 3188 } 3189 3190 /* 3191 * qtce_rx_low_freq_filter_set 3192 */ 3193 STATIC int 3194 qtce_rx_low_freq_filter_set(soc_phymod_ctrl_t *pmc, uint32 value) 3195 { 3196 phymod_phy_access_t *pm_phy; 3197 phymod_rx_t phymod_rx; 3198 int idx; 3199 3200 /* loop through all cores */ 3201 for (idx = 0; idx < pmc->num_phys; idx++) { 3202 pm_phy = &pmc->phy[idx]->pm_phy; 3203 3204 if (pm_phy == NULL) { 3205 return SOC_E_INTERNAL; 3206 } 3207 3208 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 3209 3210 phymod_rx.low_freq_peaking_filter.enable = TRUE; 3211 phymod_rx.low_freq_peaking_filter.value = value; 3212 SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx)); 3213 } 3214 3215 return(SOC_E_NONE); 3216 } 3217 3218 /* 3219 * qtce_tx_ppm_adjust_set 3220 */ 3221 STATIC int 3222 qtce_tx_ppm_adjust_set(soc_phymod_ctrl_t *pmc, uint32 value) 3223 { 3224 phymod_phy_access_t *pm_phy; 3225 phymod_tx_override_t tx_override; 3226 int idx; 3227 3228 /* loop through all cores */ 3229 for (idx = 0; idx < pmc->num_phys; idx++) { 3230 pm_phy = &pmc->phy[idx]->pm_phy; 3231 3232 if (pm_phy == NULL) { 3233 return SOC_E_INTERNAL; 3234 } 3235 3236 tx_override.phase_interpolator.enable = 1; 3237 tx_override.phase_interpolator.value = value; 3238 SOC_IF_ERROR_RETURN(phymod_phy_tx_override_set(pm_phy, &tx_override)); 3239 } 3240 return(SOC_E_NONE); 3241 } 3242 3243 /* 3244 * qtce_vco_freq_set 3245 */ 3246 STATIC int 3247 qtce_vco_freq_set(soc_phymod_ctrl_t *pmc, uint32 value) 3248 { 3249 #if 0 3250 The following 3 controls are used to override pre-defined speed in the phy. 3251 What we discussed in SJ is that in case of rate which is not officially supported the driver will try to 3252 understand this parameters by itself. 3253 Questions: 3254 1. Do we want to support direct configuration of PLL\OS? 3255 2. If yes - same API or new API 3256 3257 phymod_phy_interface_config_set (?) 3258 #endif 3259 3260 return(SOC_E_UNAVAIL); 3261 } 3262 3263 /* 3264 * qtce_pll_divider_set 3265 */ 3266 STATIC int 3267 qtce_pll_divider_set(soc_phymod_ctrl_t *pmc, uint32 value) 3268 { 3269 #if 0 3270 phymod_phy_interface_config_set (?) 3271 #endif 3272 3273 return(SOC_E_UNAVAIL); 3274 } 3275 3276 /* 3277 * qtce_oversample_mode_set 3278 */ 3279 STATIC int 3280 qtce_oversample_mode_set(soc_phymod_ctrl_t *pmc, uint32 value) 3281 { 3282 #if 0 3283 phymod_phy_interface_config_set (?) 3284 #endif 3285 3286 return(SOC_E_UNAVAIL); 3287 } 3288 3289 /* 3290 * qtce_ref_clk_set 3291 */ 3292 STATIC int 3293 qtce_ref_clk_set(soc_phymod_ctrl_t *pmc, uint32 value) 3294 { 3295 #if 0 3296 The control stores the ref clock in SW DB. 3297 As discussed the phymod will be stateless. 3298 So itll be added to interface_config_set as input parameter. 3299 3300 phymod_phy_interface_config_set 3301 #endif 3302 3303 return(SOC_E_UNAVAIL); 3304 } 3305 3306 /* 3307 * qtce_rx_seq_toggle_set 3308 */ 3309 STATIC int 3310 qtce_rx_seq_toggle_set(soc_phymod_ctrl_t *pmc) 3311 { 3312 phymod_phy_access_t *pm_phy; 3313 int idx; 3314 3315 /* loop through all cores */ 3316 for (idx = 0; idx < pmc->num_phys; idx++) { 3317 if (pmc->phy[idx] == NULL) { 3318 return(SOC_E_INTERNAL); 3319 } 3320 3321 pm_phy = &pmc->phy[idx]->pm_phy; 3322 if (pm_phy == NULL) { 3323 return(SOC_E_INTERNAL); 3324 } 3325 SOC_IF_ERROR_RETURN(phymod_phy_rx_restart(pm_phy)); 3326 } 3327 3328 return(SOC_E_NONE); 3329 } 3330 3331 /* 3332 * qtce_eee_set 3333 */ 3334 STATIC int 3335 qtce_eee_set(soc_phymod_ctrl_t *pmc, uint32 value) 3336 { 3337 phymod_phy_access_t *pm_phy; 3338 int idx; 3339 3340 /* loop through all cores */ 3341 for (idx = 0; idx < pmc->num_phys; idx++) { 3342 if (pmc->phy[idx] == NULL) { 3343 return(SOC_E_INTERNAL); 3344 } 3345 3346 pm_phy = &pmc->phy[idx]->pm_phy; 3347 if (pm_phy == NULL) { 3348 return(SOC_E_INTERNAL); 3349 } 3350 SOC_IF_ERROR_RETURN(phymod_phy_eee_set(pm_phy, value)); 3351 } 3352 3353 return(SOC_E_NONE); 3354 } 3355 3356 /* 3357 * qtce_driver_supply_set 3358 */ 3359 STATIC int 3360 qtce_driver_supply_set(soc_phymod_ctrl_t *pmc, uint32 value) 3361 { 3362 #if 0 3363 Can be added as init parameter. 3364 Do you think set\get API are required? 3365 #endif 3366 3367 return(SOC_E_UNAVAIL); 3368 } 3369 3370 /* 3371 * Function: 3372 * phy_qtce_control_set 3373 * Purpose: 3374 * Configure PHY device specific control fucntion. 3375 * Parameters: 3376 * unit - BCM unit number. 3377 * port - Port number. 3378 * type - Control to update 3379 * value - New setting for the control 3380 * Returns: 3381 * SOC_E_NONE 3382 */ 3383 STATIC int 3384 phy_qtce_control_set(int unit, soc_port_t port, soc_phy_control_t type, uint32 value) 3385 { 3386 int rv; 3387 phy_ctrl_t *pc; 3388 soc_phymod_ctrl_t *pmc; 3389 qtce_config_t *pCfg; 3390 3391 rv = SOC_E_UNAVAIL; 3392 3393 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 3394 return (SOC_E_PARAM); 3395 } 3396 3397 /* locate phy control, phymod control, and the configuration data */ 3398 pc = INT_PHY_SW_STATE(unit, port); 3399 if (pc == NULL) { 3400 return SOC_E_INTERNAL; 3401 } 3402 pmc = &pc->phymod_ctrl; 3403 pCfg = (qtce_config_t *) pc->driver_data; 3404 3405 switch(type) { 3406 3407 case SOC_PHY_CONTROL_TX_FIR_PRE: 3408 rv = qtce_tx_fir_pre_set(pmc, value); 3409 break; 3410 case SOC_PHY_CONTROL_TX_FIR_MAIN: 3411 rv = qtce_tx_fir_main_set(pmc, value); 3412 break; 3413 case SOC_PHY_CONTROL_TX_FIR_POST: 3414 rv = qtce_tx_fir_post_set(pmc, value); 3415 break; 3416 case SOC_PHY_CONTROL_TX_FIR_POST2: 3417 rv = qtce_tx_fir_post2_set(pmc, value); 3418 break; 3419 case SOC_PHY_CONTROL_TX_FIR_POST3: 3420 rv = qtce_tx_fir_post3_set(pmc, value); 3421 break; 3422 /* PREEMPHASIS */ 3423 case SOC_PHY_CONTROL_PREEMPHASIS_LANE0: 3424 rv = qtce_per_lane_preemphasis_set(pmc, 0, value); 3425 break; 3426 case SOC_PHY_CONTROL_PREEMPHASIS_LANE1: 3427 rv = qtce_per_lane_preemphasis_set(pmc, 1, value); 3428 break; 3429 case SOC_PHY_CONTROL_PREEMPHASIS_LANE2: 3430 rv = qtce_per_lane_preemphasis_set(pmc, 2, value); 3431 break; 3432 case SOC_PHY_CONTROL_PREEMPHASIS_LANE3: 3433 rv = qtce_per_lane_preemphasis_set(pmc, 3, value); 3434 break; 3435 case SOC_PHY_CONTROL_PREEMPHASIS: 3436 rv = qtce_preemphasis_set(pmc, value); 3437 break; 3438 3439 /* DRIVER CURRENT */ 3440 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0: 3441 rv = qtce_per_lane_driver_current_set(pmc, 0, value); 3442 break; 3443 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1: 3444 rv = qtce_per_lane_driver_current_set(pmc, 1, value); 3445 break; 3446 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2: 3447 rv = qtce_per_lane_driver_current_set(pmc, 2, value); 3448 break; 3449 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3: 3450 rv = qtce_per_lane_driver_current_set(pmc, 3, value); 3451 break; 3452 case SOC_PHY_CONTROL_DRIVER_CURRENT: 3453 rv = qtce_driver_current_set(pmc, value); 3454 break; 3455 3456 /* PRE_DRIVER CURRENT not supported anymore */ 3457 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE0: 3458 rv = SOC_E_UNAVAIL; 3459 break; 3460 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE1: 3461 rv = SOC_E_UNAVAIL; 3462 break; 3463 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE2: 3464 rv = SOC_E_UNAVAIL; 3465 break; 3466 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE3: 3467 rv = SOC_E_UNAVAIL; 3468 break; 3469 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 3470 rv = SOC_E_UNAVAIL; 3471 break; 3472 3473 /* POST2_DRIVER CURRENT not supported anymore */ 3474 case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT: 3475 rv = SOC_E_UNAVAIL; 3476 break; 3477 case SOC_PHY_CONTROL_DUMP: 3478 /* "N/A: will be part of common phymod application" */ 3479 /* was rv = tscmod_uc_status_dump(unit, port); */ 3480 break; 3481 3482 /* TX LANE SQUELCH */ 3483 case SOC_PHY_CONTROL_TX_LANE_SQUELCH: 3484 rv = qtce_tx_lane_squelch(pmc, value); 3485 break; 3486 3487 /* RX PEAK FILTER */ 3488 case SOC_PHY_CONTROL_RX_PEAK_FILTER: 3489 rv = qtce_rx_peak_filter_set(pmc, value); 3490 break; 3491 3492 /* RX VGA */ 3493 case SOC_PHY_CONTROL_RX_VGA: 3494 rv = qtce_rx_vga_set(pmc, value); 3495 break; 3496 case SOC_PHY_CONTROL_RX_VGA_RELEASE: 3497 /* $$$ tbd $$$ */ 3498 break; 3499 3500 /* RX TAP */ 3501 case SOC_PHY_CONTROL_RX_TAP1: 3502 rv = qtce_rx_tap_set(pmc, 0, value); 3503 break; 3504 case SOC_PHY_CONTROL_RX_TAP2: 3505 rv = qtce_rx_tap_set(pmc, 1, value); 3506 break; 3507 case SOC_PHY_CONTROL_RX_TAP3: 3508 rv = qtce_rx_tap_set(pmc, 2, value); 3509 break; 3510 case SOC_PHY_CONTROL_RX_TAP4: 3511 rv = qtce_rx_tap_set(pmc, 3, value); 3512 break; 3513 case SOC_PHY_CONTROL_RX_TAP5: 3514 rv = qtce_rx_tap_set(pmc, 4, value); 3515 break; 3516 case SOC_PHY_CONTROL_RX_TAP1_RELEASE: /* $$$ tbd $$$ */ 3517 rv = qtce_rx_tap_release(pmc, 0); 3518 break; 3519 case SOC_PHY_CONTROL_RX_TAP2_RELEASE: /* $$$ tbd $$$ */ 3520 rv = qtce_rx_tap_release(pmc, 1); 3521 break; 3522 case SOC_PHY_CONTROL_RX_TAP3_RELEASE: /* $$$ tbd $$$ */ 3523 rv = qtce_rx_tap_release(pmc, 2); 3524 break; 3525 case SOC_PHY_CONTROL_RX_TAP4_RELEASE: /* $$$ tbd $$$ */ 3526 rv = qtce_rx_tap_release(pmc, 3); 3527 break; 3528 case SOC_PHY_CONTROL_RX_TAP5_RELEASE: /* $$$ tbd $$$ */ 3529 rv = qtce_rx_tap_release(pmc, 4); 3530 break; 3531 /* RX SLICER */ 3532 case SOC_PHY_CONTROL_RX_PLUS1_SLICER: 3533 rv = SOC_E_UNAVAIL; 3534 break; 3535 case SOC_PHY_CONTROL_RX_MINUS1_SLICER: 3536 rv = SOC_E_UNAVAIL; 3537 break; 3538 case SOC_PHY_CONTROL_RX_D_SLICER: 3539 rv = SOC_E_UNAVAIL; 3540 break; 3541 3542 /* PHASE INTERPOLATOR */ 3543 case SOC_PHY_CONTROL_PHASE_INTERP: 3544 rv = qtce_pi_control_set(pmc, value); 3545 break; 3546 3547 /* POLARITY */ 3548 case SOC_PHY_CONTROL_RX_POLARITY: 3549 rv = qtce_rx_polarity_set(pmc, &pCfg->phy_polarity_config, value);; 3550 break; 3551 case SOC_PHY_CONTROL_TX_POLARITY: 3552 rv = qtce_tx_polarity_set(pmc, &pCfg->phy_polarity_config, value); 3553 break; 3554 3555 /* RESET */ 3556 case SOC_PHY_CONTROL_RX_RESET: 3557 rv = qtce_rx_reset(pmc, &pCfg->phy_reset_config, value); 3558 break; 3559 case SOC_PHY_CONTROL_TX_RESET: 3560 rv = qtce_tx_reset(pmc, &pCfg->phy_reset_config, value); 3561 break; 3562 3563 /* CL72 ENABLE */ 3564 case SOC_PHY_CONTROL_CL72: 3565 rv = qtce_cl72_enable_set(pmc, value); 3566 break; 3567 3568 /* LANE SWAP */ 3569 case SOC_PHY_CONTROL_LANE_SWAP: 3570 rv = qtce_lane_map_set(pmc, value); 3571 break; 3572 3573 /* TX PATTERN */ 3574 case SOC_PHY_CONTROL_TX_PATTERN_20BIT: 3575 rv = SOC_E_UNAVAIL; 3576 break; 3577 case SOC_PHY_CONTROL_TX_PATTERN_256BIT: 3578 rv = SOC_E_UNAVAIL; 3579 break; 3580 case SOC_PHY_CONTROL_TX_PATTERN_LENGTH: 3581 rv = qtce_pattern_len_set(pmc, value); 3582 break; 3583 case SOC_PHY_CONTROL_TX_PATTERN_GEN_ENABLE: 3584 rv = qtce_pattern_enable_set(pmc, value); 3585 break; 3586 case SOC_PHY_CONTROL_TX_PATTERN_DATA0: 3587 rv = qtce_pattern_data_set(0, &pCfg->pattern, value); 3588 break; 3589 case SOC_PHY_CONTROL_TX_PATTERN_DATA1: 3590 rv = qtce_pattern_data_set(1, &pCfg->pattern, value); 3591 break; 3592 case SOC_PHY_CONTROL_TX_PATTERN_DATA2: 3593 rv = qtce_pattern_data_set(2, &pCfg->pattern, value); 3594 break; 3595 case SOC_PHY_CONTROL_TX_PATTERN_DATA3: 3596 rv = qtce_pattern_data_set(3, &pCfg->pattern, value); 3597 break; 3598 case SOC_PHY_CONTROL_TX_PATTERN_DATA4: 3599 rv = qtce_pattern_data_set(4, &pCfg->pattern, value); 3600 break; 3601 case SOC_PHY_CONTROL_TX_PATTERN_DATA5: 3602 rv = qtce_pattern_data_set(5, &pCfg->pattern, value); 3603 break; 3604 case SOC_PHY_CONTROL_TX_PATTERN_DATA6: 3605 rv = qtce_pattern_data_set(6, &pCfg->pattern, value); 3606 break; 3607 case SOC_PHY_CONTROL_TX_PATTERN_DATA7: 3608 rv = qtce_pattern_data_set(7, &pCfg->pattern, value); 3609 break; 3610 3611 /* decoupled PRBS */ 3612 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL: 3613 rv = qtce_prbs_tx_poly_set(pmc, value); 3614 break; 3615 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA: 3616 rv = qtce_prbs_tx_invert_data_set(pmc, value); 3617 break; 3618 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE: 3619 rv = qtce_prbs_tx_enable_set(pmc, value); 3620 break; 3621 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL: 3622 rv = qtce_prbs_rx_poly_set(pmc, value); 3623 break; 3624 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA: 3625 rv = qtce_prbs_rx_invert_data_set(pmc, value); 3626 break; 3627 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE: 3628 rv = qtce_prbs_rx_enable_set(pmc, value); 3629 break; 3630 /*for legacy prbs usage mainly set both tx/rx the same */ 3631 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 3632 rv = qtce_prbs_tx_poly_set(pmc, value); 3633 rv = qtce_prbs_rx_poly_set(pmc, value); 3634 break; 3635 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 3636 rv = qtce_prbs_tx_invert_data_set(pmc, value); 3637 break; 3638 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 3639 rv = qtce_prbs_tx_enable_set(pmc, value); 3640 rv = qtce_prbs_rx_enable_set(pmc, value); 3641 break; 3642 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 3643 rv = qtce_prbs_tx_enable_set(pmc, value); 3644 rv = qtce_prbs_rx_enable_set(pmc, value); 3645 break; 3646 3647 /* LOOPBACK */ 3648 case SOC_PHY_CONTROL_LOOPBACK_INTERNAL: 3649 rv = qtce_loopback_internal_set(pmc, value); 3650 break; 3651 case SOC_PHY_CONTROL_LOOPBACK_PMD: 3652 rv = qtce_loopback_internal_pmd_set(pmc, value); 3653 break; 3654 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: 3655 rv = qtce_loopback_remote_set(pmc, value); 3656 break; 3657 case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS: 3658 rv = qtce_loopback_remote_pcs_set(pmc, value); 3659 break; 3660 3661 /* FEC */ 3662 case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION: 3663 rv = qtce_fec_enable_set(pmc, value); 3664 break; 3665 3666 /* CUSTOM */ 3667 case SOC_PHY_CONTROL_CUSTOM1: 3668 /* Obsolete ?? 3669 DEV_CFG_PTR(pc)->custom1 = value? TRUE: FALSE ; 3670 rv = SOC_E_NONE; */ 3671 rv = SOC_E_UNAVAIL; 3672 break; 3673 3674 /* SCRAMBLER */ 3675 case SOC_PHY_CONTROL_SCRAMBLER: 3676 rv = qtce_scrambler_set(pmc, port, value); 3677 break; 3678 3679 /* 8B10B */ 3680 case SOC_PHY_CONTROL_8B10B: 3681 rv = qtce_8b10b_set(pmc, value); 3682 break; 3683 3684 /* 64B65B */ 3685 case SOC_PHY_CONTROL_64B66B: 3686 rv = qtce_64b65b_set(pmc, value); 3687 break; 3688 3689 /* POWER */ 3690 case SOC_PHY_CONTROL_POWER: 3691 rv = qtce_power_set(pmc, value); 3692 break; 3693 3694 /* RX_LOW_FREQ_PEAK_FILTER */ 3695 case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER: 3696 rv = qtce_rx_low_freq_filter_set(pmc, value); 3697 break; 3698 3699 /* TX_PPM_ADJUST */ 3700 case SOC_PHY_CONTROL_TX_PPM_ADJUST: 3701 rv = qtce_tx_ppm_adjust_set(pmc, value); 3702 break; 3703 3704 /* VCO_FREQ */ 3705 case SOC_PHY_CONTROL_VCO_FREQ: 3706 rv = qtce_vco_freq_set(pmc, value); 3707 break; 3708 3709 /* PLL_DIVIDER */ 3710 case SOC_PHY_CONTROL_PLL_DIVIDER: 3711 rv = qtce_pll_divider_set(pmc, value); 3712 break; 3713 3714 /* OVERSAMPLE_MODE */ 3715 case SOC_PHY_CONTROL_OVERSAMPLE_MODE: 3716 rv = qtce_oversample_mode_set(pmc, value); 3717 break; 3718 3719 /* REF_CLK */ 3720 case SOC_PHY_CONTROL_REF_CLK: 3721 rv = qtce_ref_clk_set(pmc, value); 3722 break; 3723 3724 /* RX_SEQ_TOGGLE */ 3725 case SOC_PHY_CONTROL_RX_SEQ_TOGGLE: 3726 rv = qtce_rx_seq_toggle_set(pmc); 3727 break; 3728 3729 /* DRIVER_SUPPLY */ 3730 case SOC_PHY_CONTROL_DRIVER_SUPPLY: 3731 rv = qtce_driver_supply_set(pmc, value); 3732 break; 3733 3734 /* EEE */ 3735 case SOC_PHY_CONTROL_EEE: 3736 rv = qtce_eee_set(pmc, value); 3737 break; 3738 #ifdef TSC_EEE_SUPPORT 3739 case SOC_PHY_CONTROL_EEE_AUTO: 3740 rv = SOC_E_NONE; /* not supported */ 3741 break; 3742 #endif 3743 #if 0 3744 /* Added to support WA for HW bug; probably not required. */ 3745 case SOC_PHY_CONTROL_SOFTWARE_RX_LOS: 3746 DEV_CFG_PTR(pc)->sw_rx_los.enable = (value == 0? 0: 1); 3747 DEV_CFG_PTR(pc)->sw_rx_los.sys_link = 0; 3748 DEV_CFG_PTR(pc)->sw_rx_los.state = RXLOS_RESET; 3749 DEV_CFG_PTR(pc)->sw_rx_los.link_status = 0; 3750 /* THE FLAG IS SET IN INIT. FOR TSCMOD DRIVER 3751 TO WORK IT'S LINK_GET MUST BE CALLED */ 3752 /* Manage the _SERVICE_INT_PHY_LINK_GET flag so that 3753 if external phy is present link_get for 3754 internal phy is still called to process 3755 software rx los feature 3756 if(value) { 3757 PHY_FLAGS_SET(unit, port, PHY_FLAGS_SERVICE_INT_PHY_LINK_GET); 3758 } else { 3759 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_SERVICE_INT_PHY_LINK_GET); 3760 } 3761 */ 3762 rv = SOC_E_NONE; 3763 break; 3764 case SOC_PHY_CONTROL_FEC_OFF: 3765 rv = qtce_fec_enable_set(pmc, 0); 3766 break; 3767 case SOC_PHY_CONTROL_FEC_ON: 3768 rv = qtce_fec_enable_set(pmc, 1); 3769 break; 3770 3771 /* UNAVAIL */ 3772 case SOC_PHY_CONTROL_LINKDOWN_TRANSMIT: 3773 case SOC_PHY_CONTROL_PARALLEL_DETECTION: 3774 case SOC_PHY_CONTROL_BERT_PATTERN: 3775 case SOC_PHY_CONTROL_BERT_RUN: 3776 case SOC_PHY_CONTROL_BERT_PACKET_SIZE: 3777 case SOC_PHY_CONTROL_BERT_IPG: 3778 case SOC_PHY_CONTROL_RX_PEAK_FILTER_TEMP_COMP: 3779 case SOC_PHY_CONTROL_CL73_FSM_AUTO_RECOVER: 3780 #endif 3781 default: 3782 rv = SOC_E_UNAVAIL; 3783 break; 3784 } 3785 return rv; 3786 } 3787 3788 3789 /* 3790 * qtce_tx_fir_pre_get 3791 */ 3792 STATIC int 3793 qtce_tx_fir_pre_get(soc_phymod_ctrl_t *pmc, uint32 *value) 3794 { 3795 phymod_phy_access_t *pm_phy; 3796 phymod_tx_t phymod_tx; 3797 int idx; 3798 3799 /* loop through all cores */ 3800 for (idx = 0; idx < pmc->num_phys; idx++) { 3801 pm_phy = &pmc->phy[idx]->pm_phy; 3802 3803 if (pm_phy == NULL) { 3804 return SOC_E_INTERNAL; 3805 } 3806 3807 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3808 *value = phymod_tx.pre; 3809 } 3810 3811 return(SOC_E_NONE); 3812 } 3813 3814 /* 3815 * qtce_tx_fir_main_get 3816 */ 3817 STATIC int 3818 qtce_tx_fir_main_get(soc_phymod_ctrl_t *pmc, uint32 *value) 3819 { 3820 phymod_phy_access_t *pm_phy; 3821 phymod_tx_t phymod_tx; 3822 int idx; 3823 3824 /* loop through all cores */ 3825 for (idx = 0; idx < pmc->num_phys; idx++) { 3826 pm_phy = &pmc->phy[idx]->pm_phy; 3827 3828 if (pm_phy == NULL) { 3829 return SOC_E_INTERNAL; 3830 } 3831 3832 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3833 *value = phymod_tx.main; 3834 } 3835 3836 return(SOC_E_NONE); 3837 } 3838 3839 /* 3840 * qtce_tx_fir_post_get 3841 */ 3842 STATIC int 3843 qtce_tx_fir_post_get(soc_phymod_ctrl_t *pmc, uint32 *value) 3844 { 3845 phymod_phy_access_t *pm_phy; 3846 phymod_tx_t phymod_tx; 3847 int idx; 3848 3849 /* loop through all cores */ 3850 for (idx = 0; idx < pmc->num_phys; idx++) { 3851 pm_phy = &pmc->phy[idx]->pm_phy; 3852 3853 if (pm_phy == NULL) { 3854 return SOC_E_INTERNAL; 3855 } 3856 3857 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3858 *value = phymod_tx.post; 3859 } 3860 3861 return(SOC_E_NONE); 3862 } 3863 3864 /* 3865 * qtce_tx_fir_post2_get 3866 */ 3867 STATIC int 3868 qtce_tx_fir_post2_get(soc_phymod_ctrl_t *pmc, uint32 *value) 3869 { 3870 phymod_phy_access_t *pm_phy; 3871 phymod_tx_t phymod_tx; 3872 int idx; 3873 3874 /* loop through all cores */ 3875 for (idx = 0; idx < pmc->num_phys; idx++) { 3876 pm_phy = &pmc->phy[idx]->pm_phy; 3877 3878 if (pm_phy == NULL) { 3879 return SOC_E_INTERNAL; 3880 } 3881 3882 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3883 *value = phymod_tx.post2; 3884 } 3885 3886 return(SOC_E_NONE); 3887 } 3888 3889 /* 3890 * qtce_tx_fir_post3_get 3891 */ 3892 STATIC int 3893 qtce_tx_fir_post3_get(soc_phymod_ctrl_t *pmc, uint32 *value) 3894 { 3895 phymod_phy_access_t *pm_phy; 3896 phymod_tx_t phymod_tx; 3897 int idx; 3898 3899 /* loop through all cores */ 3900 for (idx = 0; idx < pmc->num_phys; idx++) { 3901 pm_phy = &pmc->phy[idx]->pm_phy; 3902 3903 if (pm_phy == NULL) { 3904 return SOC_E_INTERNAL; 3905 } 3906 3907 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3908 *value = phymod_tx.post3; 3909 } 3910 3911 return(SOC_E_NONE); 3912 } 3913 3914 /* 3915 * qtce_per_lane_preemphasis_get 3916 */ 3917 STATIC int 3918 qtce_per_lane_preemphasis_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 3919 { 3920 soc_phymod_phy_t *p_phy; 3921 uint32 lane_map; 3922 phymod_phy_access_t pm_phy_copy, *pm_phy; 3923 phymod_tx_t phymod_tx; 3924 3925 /* locate the desired phy and lane */ 3926 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 3927 3928 /* Make a copy of the phy access and overwrite the desired lane */ 3929 pm_phy = &p_phy->pm_phy; 3930 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3931 pm_phy_copy.access.lane_mask = lane_map; 3932 3933 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 3934 *value = phymod_tx.pre; 3935 3936 return(SOC_E_NONE); 3937 } 3938 3939 STATIC int 3940 qtce_driver_current_get(soc_phymod_ctrl_t *pmc, uint32 *value) 3941 { 3942 phymod_phy_access_t *pm_phy; 3943 phymod_tx_t phymod_tx; 3944 3945 pm_phy = &pmc->phy[0]->pm_phy; 3946 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx)); 3947 *value = phymod_tx.amp; 3948 3949 return(SOC_E_NONE); 3950 } 3951 3952 3953 /* 3954 * qtce_per_lane_driver_current_get 3955 */ 3956 STATIC int 3957 qtce_per_lane_driver_current_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 3958 { 3959 soc_phymod_phy_t *p_phy; 3960 uint32 lane_map; 3961 phymod_phy_access_t pm_phy_copy, *pm_phy; 3962 phymod_tx_t phymod_tx; 3963 3964 /* locate the desired phy and lane */ 3965 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 3966 3967 /* Make a copy of the phy access and overwrite the desired lane */ 3968 pm_phy = &p_phy->pm_phy; 3969 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 3970 pm_phy_copy.access.lane_mask = lane_map; 3971 3972 SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx)); 3973 *value = phymod_tx.amp; 3974 3975 return(SOC_E_NONE); 3976 } 3977 3978 /* 3979 * qtce_per_lane_prbs_poly_get 3980 */ 3981 STATIC int 3982 qtce_per_lane_prbs_poly_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 3983 { 3984 return(SOC_E_UNAVAIL); 3985 } 3986 3987 /* 3988 * qtce_per_lane_prbs_tx_invert_data_get 3989 */ 3990 STATIC int 3991 qtce_per_lane_prbs_tx_invert_data_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 3992 { 3993 return(SOC_E_UNAVAIL); 3994 } 3995 3996 /* 3997 * qtce_per_lane_prbs_tx_enable_get 3998 */ 3999 STATIC int 4000 qtce_per_lane_prbs_tx_enable_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 4001 { 4002 return(SOC_E_UNAVAIL); 4003 } 4004 4005 /* 4006 * qtce_per_lane_prbs_rx_enable_get 4007 */ 4008 STATIC int 4009 qtce_per_lane_prbs_rx_enable_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 4010 { 4011 return(SOC_E_UNAVAIL); 4012 } 4013 4014 /* 4015 * qtce_per_lane_prbs_rx_status_get 4016 */ 4017 STATIC int 4018 qtce_per_lane_prbs_rx_status_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 4019 { 4020 /* $$$ Need to add diagnostic API */ 4021 return(SOC_E_UNAVAIL); 4022 } 4023 4024 /* 4025 * qtce_per_lane_rx_peak_filter_get 4026 */ 4027 STATIC int 4028 qtce_per_lane_rx_peak_filter_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 4029 { 4030 soc_phymod_phy_t *p_phy; 4031 uint32 lane_map; 4032 phymod_phy_access_t pm_phy_copy, *pm_phy; 4033 phymod_rx_t phymod_rx; 4034 4035 *value = 0; 4036 4037 /* locate the desired phy and lane */ 4038 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 4039 4040 /* Make a copy of the phy access and overwrite the desired lane */ 4041 pm_phy = &p_phy->pm_phy; 4042 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 4043 pm_phy_copy.access.lane_mask = lane_map; 4044 4045 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 4046 if (phymod_rx.peaking_filter.enable) 4047 *value = phymod_rx.peaking_filter.value; 4048 4049 return(SOC_E_NONE); 4050 } 4051 4052 /* 4053 * qtce_per_lane_rx_vga_get 4054 */ 4055 STATIC int 4056 qtce_per_lane_rx_vga_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 4057 { 4058 soc_phymod_phy_t *p_phy; 4059 uint32 lane_map; 4060 phymod_phy_access_t pm_phy_copy, *pm_phy; 4061 phymod_rx_t phymod_rx; 4062 4063 *value = 0; 4064 4065 /* locate the desired phy and lane */ 4066 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 4067 4068 /* Make a copy of the phy access and overwrite the desired lane */ 4069 pm_phy = &p_phy->pm_phy; 4070 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 4071 pm_phy_copy.access.lane_mask = lane_map; 4072 4073 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 4074 if (phymod_rx.vga.enable) 4075 *value = phymod_rx.vga.value; 4076 4077 return(SOC_E_NONE); 4078 } 4079 4080 /* 4081 * qtce_per_lane_rx_dfe_tap_control_get 4082 */ 4083 STATIC int 4084 qtce_per_lane_rx_dfe_tap_control_get(soc_phymod_ctrl_t *pmc, int lane, int tap, uint32 *value) 4085 { 4086 soc_phymod_phy_t *p_phy; 4087 uint32 lane_map; 4088 phymod_phy_access_t pm_phy_copy, *pm_phy; 4089 phymod_rx_t phymod_rx; 4090 4091 *value = 0; 4092 4093 /* locate the desired phy and lane */ 4094 SOC_IF_ERROR_RETURN(_qtce_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map)); 4095 4096 /* Make a copy of the phy access and overwrite the desired lane */ 4097 pm_phy = &p_phy->pm_phy; 4098 sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy)); 4099 pm_phy_copy.access.lane_mask = lane_map; 4100 4101 if ((tap<0)||(tap>(COUNTOF(phymod_rx.dfe) -1 ))) { 4102 /* this can only happen with a coding error */ 4103 return SOC_E_INTERNAL; 4104 } 4105 4106 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx)); 4107 if (phymod_rx.dfe[tap].enable) 4108 *value = phymod_rx.dfe[tap].value; 4109 4110 return(SOC_E_NONE); 4111 } 4112 4113 4114 /* 4115 * qtce_per_lane_rx_low_freq_filter_get 4116 */ 4117 STATIC int 4118 qtce_per_lane_rx_low_freq_filter_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value) 4119 { 4120 return(SOC_E_UNAVAIL); 4121 } 4122 4123 /* 4124 * qtce_rx_peak_filter_get 4125 */ 4126 STATIC int 4127 qtce_rx_peak_filter_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4128 { 4129 phymod_phy_access_t *pm_phy; 4130 phymod_rx_t phymod_rx; 4131 4132 /* just take the value from the first phy */ 4133 if (pmc->phy[0] == NULL) { 4134 return SOC_E_INTERNAL; 4135 } 4136 pm_phy = &pmc->phy[0]->pm_phy; 4137 4138 if (pm_phy == NULL) { 4139 return SOC_E_INTERNAL; 4140 } 4141 4142 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 4143 *value = phymod_rx.peaking_filter.value; 4144 4145 return(SOC_E_NONE); 4146 } 4147 4148 /* 4149 * qtce_rx_vga_set 4150 */ 4151 STATIC int 4152 qtce_rx_vga_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4153 { 4154 phymod_phy_access_t *pm_phy; 4155 phymod_rx_t phymod_rx; 4156 4157 /* just take the value from the first phy */ 4158 if (pmc->phy[0] == NULL) { 4159 return SOC_E_INTERNAL; 4160 } 4161 pm_phy = &pmc->phy[0]->pm_phy; 4162 4163 if (pm_phy == NULL) { 4164 return SOC_E_INTERNAL; 4165 } 4166 4167 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 4168 *value = phymod_rx.vga.value; 4169 4170 return(SOC_E_NONE); 4171 } 4172 4173 /* 4174 * qtce_rx_tap_get 4175 */ 4176 STATIC int 4177 qtce_rx_tap_get(soc_phymod_ctrl_t *pmc, int tap, uint32 *value) 4178 { 4179 phymod_phy_access_t *pm_phy; 4180 phymod_rx_t phymod_rx; 4181 4182 if ((tap < 0)||(tap > (COUNTOF(phymod_rx.dfe) - 1))) { 4183 /* this can only happen with a coding error */ 4184 return SOC_E_INTERNAL; 4185 } 4186 /* just take the value from the first phy */ 4187 if (pmc->phy[0] == NULL) { 4188 return SOC_E_INTERNAL; 4189 } 4190 pm_phy = &pmc->phy[0]->pm_phy; 4191 4192 if (pm_phy == NULL) { 4193 return SOC_E_INTERNAL; 4194 } 4195 4196 SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx)); 4197 *value = phymod_rx.dfe[tap].value; 4198 4199 return(SOC_E_NONE); 4200 } 4201 4202 /* 4203 * qtce_pi_control_get 4204 */ 4205 STATIC int 4206 qtce_pi_control_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4207 { 4208 phymod_phy_access_t *pm_phy; 4209 phymod_tx_override_t tx_override; 4210 4211 /* just take the value from the first phy */ 4212 if (pmc->phy[0] == NULL) { 4213 return SOC_E_INTERNAL; 4214 } 4215 pm_phy = &pmc->phy[0]->pm_phy; 4216 4217 if (pm_phy == NULL) { 4218 return SOC_E_INTERNAL; 4219 } 4220 4221 SOC_IF_ERROR_RETURN(phymod_phy_tx_override_get(pm_phy, &tx_override)); 4222 *value = tx_override.phase_interpolator.value; 4223 4224 return(SOC_E_NONE); 4225 } 4226 4227 /* 4228 * qtce_rx_signal_detect_get 4229 */ 4230 STATIC int 4231 qtce_rx_signal_detect_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4232 { 4233 /* $$$ Need to add diagnostic API */ 4234 return(SOC_E_UNAVAIL); 4235 } 4236 4237 /* 4238 * qtce_rx_seq_done_get 4239 */ 4240 STATIC int 4241 qtce_rx_seq_done_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4242 { 4243 phymod_phy_access_t *pm_phy; 4244 4245 /* just take the value from the first phy */ 4246 if (pmc->phy[0] == NULL) { 4247 return SOC_E_INTERNAL; 4248 } 4249 pm_phy = &pmc->phy[0]->pm_phy; 4250 4251 if (pm_phy == NULL) { 4252 return SOC_E_INTERNAL; 4253 } 4254 4255 SOC_IF_ERROR_RETURN(phymod_phy_rx_pmd_locked_get(pm_phy, value)); 4256 4257 return(SOC_E_NONE); 4258 } 4259 4260 /* 4261 * qtce_eee_get 4262 */ 4263 STATIC int 4264 qtce_eee_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4265 { 4266 phymod_phy_access_t *pm_phy; 4267 4268 /* just take the value from the first phy */ 4269 if (pmc->phy[0] == NULL) { 4270 return SOC_E_INTERNAL; 4271 } 4272 pm_phy = &pmc->phy[0]->pm_phy; 4273 4274 if (pm_phy == NULL) { 4275 return SOC_E_INTERNAL; 4276 } 4277 4278 SOC_IF_ERROR_RETURN(phymod_phy_eee_get(pm_phy, value)); 4279 4280 return(SOC_E_NONE); 4281 } 4282 4283 /* 4284 * qtce_rx_ppm_get 4285 */ 4286 STATIC int 4287 qtce_rx_ppm_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4288 { 4289 /* $$$ Need to add diagnostic API */ 4290 return(SOC_E_UNAVAIL); 4291 } 4292 4293 /* 4294 * qtce_cl72_enable_get 4295 */ 4296 STATIC int 4297 qtce_cl72_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4298 { 4299 phymod_phy_access_t *pm_phy; 4300 phymod_cl72_status_t status; 4301 4302 /* just take the value from the first phy */ 4303 if (pmc->phy[0] == NULL) { 4304 return SOC_E_INTERNAL; 4305 } 4306 pm_phy = &pmc->phy[0]->pm_phy; 4307 4308 if (pm_phy == NULL) { 4309 return SOC_E_INTERNAL; 4310 } 4311 4312 SOC_IF_ERROR_RETURN(phymod_phy_cl72_status_get(pm_phy, &status)); 4313 *value = status.enabled; 4314 4315 return(SOC_E_NONE); 4316 } 4317 4318 /* 4319 * qtce_cl72_status_get 4320 */ 4321 STATIC int 4322 qtce_cl72_status_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4323 { 4324 phymod_phy_access_t *pm_phy; 4325 phymod_cl72_status_t status; 4326 4327 /* just take the value from the first phy */ 4328 if (pmc->phy[0] == NULL) { 4329 return SOC_E_INTERNAL; 4330 } 4331 pm_phy = &pmc->phy[0]->pm_phy; 4332 4333 if (pm_phy == NULL) { 4334 return SOC_E_INTERNAL; 4335 } 4336 4337 SOC_IF_ERROR_RETURN(phymod_phy_cl72_status_get(pm_phy, &status)); 4338 *value = status.locked; 4339 4340 return(SOC_E_NONE); 4341 } 4342 4343 /* 4344 * qtce_prbs_tx_poly_get 4345 */ 4346 STATIC int 4347 qtce_prbs_tx_poly_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4348 { 4349 phymod_phy_access_t *pm_phy; 4350 phymod_prbs_t prbs; 4351 uint32_t flags = 0; 4352 4353 /* just take the value from the first phy */ 4354 if (pmc->phy[0] == NULL) { 4355 return SOC_E_INTERNAL; 4356 } 4357 pm_phy = &pmc->phy[0]->pm_phy; 4358 4359 if (pm_phy == NULL) { 4360 return SOC_E_INTERNAL; 4361 } 4362 4363 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 4364 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 4365 4366 *value = (int) prbs.poly; 4367 4368 /* convert from PHYMOD enum to SDK enum */ 4369 switch(prbs.poly){ 4370 case phymodPrbsPoly7: 4371 *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1; 4372 break; 4373 case phymodPrbsPoly9: 4374 *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1; 4375 break; 4376 case phymodPrbsPoly15: 4377 *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1; 4378 break; 4379 case phymodPrbsPoly23: 4380 *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1; 4381 break; 4382 case phymodPrbsPoly31: 4383 *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1; 4384 break; 4385 case phymodPrbsPoly58: 4386 *value = 6; 4387 break; 4388 default: 4389 return SOC_E_INTERNAL; 4390 } 4391 return SOC_E_NONE; 4392 } 4393 /* 4394 * qtce_prbs_rx_poly_get 4395 */ 4396 STATIC int 4397 qtce_prbs_rx_poly_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4398 { 4399 phymod_phy_access_t *pm_phy; 4400 phymod_prbs_t prbs; 4401 uint32_t flags = 0; 4402 4403 /* just take the value from the first phy */ 4404 if (pmc->phy[0] == NULL) { 4405 return SOC_E_INTERNAL; 4406 } 4407 pm_phy = &pmc->phy[0]->pm_phy; 4408 4409 if (pm_phy == NULL) { 4410 return SOC_E_INTERNAL; 4411 } 4412 4413 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 4414 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 4415 4416 *value = (int) prbs.poly; 4417 4418 /* convert from PHYMOD enum to SDK enum */ 4419 switch(prbs.poly){ 4420 case phymodPrbsPoly7: 4421 *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1; 4422 break; 4423 case phymodPrbsPoly11: 4424 *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1; 4425 break; 4426 case phymodPrbsPoly9: 4427 *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1; 4428 break; 4429 case phymodPrbsPoly15: 4430 *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1; 4431 break; 4432 case phymodPrbsPoly23: 4433 *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1; 4434 break; 4435 case phymodPrbsPoly31: 4436 *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1; 4437 break; 4438 case phymodPrbsPoly58: 4439 *value = 6; 4440 break; 4441 default: 4442 return SOC_E_INTERNAL; 4443 } 4444 return SOC_E_NONE; 4445 } 4446 4447 /* 4448 * qtce_prbs_tx_invert_data_get 4449 */ 4450 STATIC int 4451 qtce_prbs_tx_invert_data_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4452 { 4453 phymod_phy_access_t *pm_phy; 4454 phymod_prbs_t prbs; 4455 uint32_t flags = 0; 4456 4457 /* just take the value from the first phy */ 4458 if (pmc->phy[0] == NULL) { 4459 return SOC_E_INTERNAL; 4460 } 4461 pm_phy = &pmc->phy[0]->pm_phy; 4462 4463 if (pm_phy == NULL) { 4464 return SOC_E_INTERNAL; 4465 } 4466 4467 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 4468 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 4469 *value = prbs.invert; 4470 4471 return(SOC_E_NONE); 4472 } 4473 4474 /* 4475 * qtce_prbs_rx_invert_data_get 4476 */ 4477 STATIC int 4478 qtce_prbs_rx_invert_data_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4479 { 4480 phymod_phy_access_t *pm_phy; 4481 phymod_prbs_t prbs; 4482 uint32_t flags = 0; 4483 4484 /* just take the value from the first phy */ 4485 if (pmc->phy[0] == NULL) { 4486 return SOC_E_INTERNAL; 4487 } 4488 pm_phy = &pmc->phy[0]->pm_phy; 4489 4490 if (pm_phy == NULL) { 4491 return SOC_E_INTERNAL; 4492 } 4493 4494 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 4495 SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs)); 4496 *value = prbs.invert; 4497 4498 return(SOC_E_NONE); 4499 } 4500 4501 4502 /* 4503 * qtce_prbs_tx_enable_get 4504 */ 4505 STATIC int 4506 qtce_prbs_tx_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4507 { 4508 phymod_phy_access_t *pm_phy; 4509 uint32_t flags = 0; 4510 4511 /* just take the value from the first phy */ 4512 if (pmc->phy[0] == NULL) { 4513 return SOC_E_INTERNAL; 4514 } 4515 pm_phy = &pmc->phy[0]->pm_phy; 4516 4517 if (pm_phy == NULL) { 4518 return SOC_E_INTERNAL; 4519 } 4520 PHYMOD_PRBS_DIRECTION_TX_SET(flags); 4521 SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(pm_phy, flags, value)); 4522 4523 return(SOC_E_NONE); 4524 } 4525 4526 /* 4527 * qtce_prbs_rx_enable_get 4528 */ 4529 STATIC int 4530 qtce_prbs_rx_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4531 { 4532 phymod_phy_access_t *pm_phy; 4533 uint32_t flags = 0; 4534 /* just take the value from the first phy */ 4535 if (pmc->phy[0] == NULL) { 4536 return SOC_E_INTERNAL; 4537 } 4538 pm_phy = &pmc->phy[0]->pm_phy; 4539 4540 if (pm_phy == NULL) { 4541 return SOC_E_INTERNAL; 4542 } 4543 4544 PHYMOD_PRBS_DIRECTION_RX_SET(flags); 4545 SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(pm_phy, flags, value)); 4546 4547 return(SOC_E_NONE); 4548 } 4549 4550 /* 4551 * qtce_prbs_rx_status_get 4552 */ 4553 STATIC int 4554 qtce_prbs_rx_status_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4555 { 4556 phymod_phy_access_t *pm_phy; 4557 phymod_prbs_status_t prbs_tmp; 4558 4559 /* just take the value from the first phy */ 4560 if (pmc->phy[0] == NULL) { 4561 return SOC_E_INTERNAL; 4562 } 4563 pm_phy = &pmc->phy[0]->pm_phy; 4564 4565 if (pm_phy == NULL) { 4566 return SOC_E_INTERNAL; 4567 } 4568 /* $$$ Need to add diagnostic API */ 4569 SOC_IF_ERROR_RETURN 4570 (phymod_phy_prbs_status_get(pm_phy, 0, &prbs_tmp)); 4571 if (prbs_tmp.prbs_lock == 0) { 4572 *value = -1; 4573 } else if ((prbs_tmp.prbs_lock_loss == 1) && (prbs_tmp.prbs_lock == 1)) { 4574 *value = -2; 4575 } else { 4576 *value = prbs_tmp.error_count; 4577 } 4578 4579 return(SOC_E_NONE); 4580 } 4581 4582 /* 4583 * qtce_loopback_internal_pmd_get (this is the PMD global loopback) 4584 */ 4585 STATIC int 4586 qtce_loopback_internal_pmd_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4587 { 4588 phymod_phy_access_t *pm_phy; 4589 uint32_t enable; 4590 4591 /* just take the value from the first phy */ 4592 if (pmc->phy[0] == NULL) { 4593 return SOC_E_INTERNAL; 4594 } 4595 pm_phy = &pmc->phy[0]->pm_phy; 4596 4597 if (pm_phy == NULL) { 4598 return SOC_E_INTERNAL; 4599 } 4600 4601 SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackGlobalPMD, &enable)); 4602 *value = enable; 4603 return(SOC_E_NONE); 4604 } 4605 4606 4607 /* 4608 * qtce_loopback_remote_get 4609 */ 4610 STATIC int 4611 qtce_loopback_remote_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4612 { 4613 phymod_phy_access_t *pm_phy; 4614 uint32_t enable; 4615 4616 /* just take the value from the first phy */ 4617 if (pmc->phy[0] == NULL) { 4618 return SOC_E_INTERNAL; 4619 } 4620 pm_phy = &pmc->phy[0]->pm_phy; 4621 4622 if (pm_phy == NULL) { 4623 return SOC_E_INTERNAL; 4624 } 4625 4626 SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackRemotePMD, &enable)); 4627 *value = enable; 4628 return(SOC_E_NONE); 4629 } 4630 4631 /* 4632 * qtce_loopback_remote_pcs_get 4633 */ 4634 STATIC int 4635 qtce_loopback_remote_pcs_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4636 { 4637 phymod_phy_access_t *pm_phy; 4638 uint32_t enable; 4639 4640 /* just take the value from the first phy */ 4641 if (pmc->phy[0] == NULL) { 4642 return SOC_E_INTERNAL; 4643 } 4644 pm_phy = &pmc->phy[0]->pm_phy; 4645 4646 if (pm_phy == NULL) { 4647 return SOC_E_INTERNAL; 4648 } 4649 4650 SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackRemotePCS, &enable)); 4651 *value = enable; 4652 return(SOC_E_NONE); 4653 } 4654 4655 /* 4656 * qtce_fec_get 4657 */ 4658 STATIC int 4659 qtce_fec_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value) 4660 { 4661 phymod_phy_access_t *pm_phy; 4662 uint32_t enable; 4663 4664 /* just take the value from the first phy */ 4665 if (pmc->phy[0] == NULL) { 4666 return SOC_E_INTERNAL; 4667 } 4668 pm_phy = &pmc->phy[0]->pm_phy; 4669 4670 if (pm_phy == NULL) { 4671 return SOC_E_INTERNAL; 4672 } 4673 4674 SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_get(pm_phy, &enable)); 4675 *value = enable; 4676 4677 return(SOC_E_NONE); 4678 } 4679 /* 4680 * qtce_pattern_256bit_get 4681 * 4682 * CHECK SEMANTICS: assumption is that this procedure will retrieve the pattern 4683 * from Tier1 and return whether the tx pattern is enabled. Note that this 4684 * is different from the 20 bit pattern retrieval semantics 4685 */ 4686 /* 4687 * qtce_pattern_256bit_get 4688 * 4689 * CHECK SEMANTICS: assumption is that this procedure will retrieve the pattern 4690 * from Tier1 and return whether the tx pattern is enabled. Note that this 4691 * is different from the 20 bit pattern retrieval semantics 4692 */ 4693 STATIC int 4694 qtce_pattern_get(soc_phymod_ctrl_t *pmc, qtce_pattern_t* cfg_pattern) 4695 { 4696 phymod_phy_access_t *pm_phy; 4697 phymod_pattern_t phymod_pattern; 4698 4699 /* just take the value from the first phy */ 4700 if (pmc->phy[0] == NULL) { 4701 return SOC_E_INTERNAL; 4702 } 4703 pm_phy = &pmc->phy[0]->pm_phy; 4704 4705 if (pm_phy == NULL) { 4706 return SOC_E_INTERNAL; 4707 } 4708 4709 SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_get(pm_phy, &phymod_pattern)); 4710 sal_memcpy(cfg_pattern , phymod_pattern.pattern, sizeof(*cfg_pattern)); 4711 return(SOC_E_NONE); 4712 } 4713 4714 STATIC int 4715 qtce_pattern_len_get(soc_phymod_ctrl_t *pmc, uint32_t *value) 4716 { 4717 phymod_phy_access_t *pm_phy; 4718 phymod_pattern_t phymod_pattern; 4719 4720 /* just take the value from the first phy */ 4721 if (pmc->phy[0] == NULL) { 4722 return SOC_E_INTERNAL; 4723 } 4724 pm_phy = &pmc->phy[0]->pm_phy; 4725 4726 if (pm_phy == NULL) { 4727 return SOC_E_INTERNAL; 4728 } 4729 4730 SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_get(pm_phy, &phymod_pattern)); 4731 *value = phymod_pattern.pattern_len; 4732 return(SOC_E_NONE); 4733 } 4734 4735 /* 4736 * qtce_scrambler_get 4737 */ 4738 STATIC int 4739 qtce_scrambler_get(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 *value) 4740 { 4741 phymod_phy_access_t *pm_phy; 4742 phymod_phy_inf_config_t config; 4743 phy_ctrl_t *pc; 4744 qtce_config_t *pCfg; 4745 phymod_ref_clk_t ref_clk; 4746 4747 4748 /* just take the value from the first phy */ 4749 if (pmc->phy[0] == NULL) { 4750 return SOC_E_INTERNAL; 4751 } 4752 pm_phy = &pmc->phy[0]->pm_phy; 4753 4754 if (pm_phy == NULL) { 4755 return SOC_E_INTERNAL; 4756 } 4757 4758 pc = INT_PHY_SW_STATE(pmc->unit, port); 4759 if (pc == NULL) { 4760 return SOC_E_INTERNAL; 4761 } 4762 4763 pCfg = (qtce_config_t *) pc->driver_data; 4764 SOC_IF_ERROR_RETURN( 4765 qtce_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clk)); 4766 4767 4768 SOC_IF_ERROR_RETURN(phymod_phy_interface_config_get(pm_phy, 0 /* flags */, ref_clk, &config)); 4769 *value = PHYMOD_INTF_MODES_SCR_GET(&config); 4770 4771 return(SOC_E_NONE); 4772 } 4773 4774 /* 4775 * Function: 4776 * phy_qtce_control_get 4777 * Purpose: 4778 * Get current control settings of the PHY. 4779 * Parameters: 4780 * unit - BCM unit number. 4781 * port - Port number. 4782 * type - Control to update 4783 * value - (OUT) Current setting for the control 4784 * Returns: 4785 * SOC_E_NONE 4786 */ 4787 STATIC int 4788 phy_qtce_control_get(int unit, soc_port_t port, soc_phy_control_t type, uint32 *value) 4789 { 4790 int rv; 4791 phy_ctrl_t *pc; 4792 soc_phymod_ctrl_t *pmc; 4793 qtce_config_t *pCfg; 4794 4795 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 4796 return (SOC_E_PARAM); 4797 } 4798 4799 /* locate phy control */ 4800 pc = INT_PHY_SW_STATE(unit, port); 4801 if (pc == NULL) { 4802 return SOC_E_INTERNAL; 4803 } 4804 4805 pmc = &pc->phymod_ctrl; 4806 pCfg = (qtce_config_t *) pc->driver_data; 4807 4808 switch(type) { 4809 4810 /* PREEMPHASIS */ 4811 case SOC_PHY_CONTROL_PREEMPHASIS_LANE0: 4812 rv = qtce_per_lane_preemphasis_get(pmc, 0, value); 4813 break; 4814 case SOC_PHY_CONTROL_PREEMPHASIS_LANE1: 4815 rv = qtce_per_lane_preemphasis_get(pmc, 1, value); 4816 break; 4817 case SOC_PHY_CONTROL_PREEMPHASIS_LANE2: 4818 rv = qtce_per_lane_preemphasis_get(pmc, 2, value); 4819 break; 4820 case SOC_PHY_CONTROL_PREEMPHASIS_LANE3: 4821 rv = qtce_per_lane_preemphasis_get(pmc, 3, value); 4822 break; 4823 case SOC_PHY_CONTROL_TX_FIR_PRE: 4824 /* assume they are all the same as lane 0 */ 4825 rv = qtce_tx_fir_pre_get(pmc, value); 4826 break; 4827 case SOC_PHY_CONTROL_TX_FIR_MAIN: 4828 /* assume they are all the same as lane 0 */ 4829 rv = qtce_tx_fir_main_get(pmc, value); 4830 break; 4831 case SOC_PHY_CONTROL_TX_FIR_POST: 4832 /* assume they are all the same as lane 0 */ 4833 rv = qtce_tx_fir_post_get(pmc, value); 4834 break; 4835 case SOC_PHY_CONTROL_TX_FIR_POST2: 4836 /* assume they are all the same as lane 0 */ 4837 rv = qtce_tx_fir_post2_get(pmc, value); 4838 break; 4839 case SOC_PHY_CONTROL_TX_FIR_POST3: 4840 /* assume they are all the same as lane 0 */ 4841 rv = qtce_tx_fir_post3_get(pmc, value); 4842 break; 4843 4844 /* DRIVER CURRENT */ 4845 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0: 4846 rv = qtce_per_lane_driver_current_get(pmc, 0, value); 4847 break; 4848 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1: 4849 rv = qtce_per_lane_driver_current_get(pmc, 1, value); 4850 break; 4851 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2: 4852 rv = qtce_per_lane_driver_current_get(pmc, 2, value); 4853 break; 4854 case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3: 4855 rv = qtce_per_lane_driver_current_get(pmc, 3, value); 4856 break; 4857 case SOC_PHY_CONTROL_DRIVER_CURRENT: 4858 rv = qtce_driver_current_get(pmc, value); 4859 break; 4860 4861 /* PRE-DRIVER CURRENT */ 4862 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE0: 4863 rv = SOC_E_UNAVAIL; 4864 break; 4865 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE1: 4866 rv = SOC_E_UNAVAIL; 4867 break; 4868 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE2: 4869 rv = SOC_E_UNAVAIL; 4870 break; 4871 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE3: 4872 rv = SOC_E_UNAVAIL; 4873 break; 4874 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 4875 rv = SOC_E_UNAVAIL; 4876 break; 4877 4878 /* POST2_DRIVER CURRENT */ 4879 case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT: 4880 rv = SOC_E_UNAVAIL; 4881 break; 4882 4883 /* RX PEAK FILTER */ 4884 case SOC_PHY_CONTROL_RX_PEAK_FILTER: 4885 rv = qtce_rx_peak_filter_get(pmc, value); 4886 break; 4887 4888 /* RX VGA */ 4889 case SOC_PHY_CONTROL_RX_VGA: 4890 rv = qtce_rx_vga_get(pmc, value); 4891 break; 4892 4893 /* RX TAP */ 4894 case SOC_PHY_CONTROL_RX_TAP1: 4895 rv = qtce_rx_tap_get(pmc, 0, value); 4896 break; 4897 case SOC_PHY_CONTROL_RX_TAP2: 4898 rv = qtce_rx_tap_get(pmc, 1, value); 4899 break; 4900 case SOC_PHY_CONTROL_RX_TAP3: 4901 rv = qtce_rx_tap_get(pmc, 2, value); 4902 break; 4903 case SOC_PHY_CONTROL_RX_TAP4: 4904 rv = qtce_rx_tap_get(pmc, 3, value); 4905 break; 4906 case SOC_PHY_CONTROL_RX_TAP5: 4907 rv = qtce_rx_tap_get(pmc, 4, value); 4908 break; 4909 4910 /* RX SLICER */ 4911 case SOC_PHY_CONTROL_RX_PLUS1_SLICER: 4912 rv = SOC_E_UNAVAIL; 4913 break; 4914 case SOC_PHY_CONTROL_RX_MINUS1_SLICER: 4915 rv = SOC_E_UNAVAIL; 4916 break; 4917 case SOC_PHY_CONTROL_RX_D_SLICER: 4918 rv = SOC_E_UNAVAIL; 4919 break; 4920 4921 /* PHASE INTERPOLATOR */ 4922 case SOC_PHY_CONTROL_PHASE_INTERP: 4923 rv = qtce_pi_control_get(pmc, value); 4924 break; 4925 4926 /* RX SIGNAL DETECT */ 4927 case SOC_PHY_CONTROL_RX_SIGNAL_DETECT: 4928 rv = qtce_rx_signal_detect_get(pmc, value); 4929 break; 4930 case SOC_PHY_CONTROL_RX_SEQ_DONE: 4931 rv = qtce_rx_seq_done_get(pmc, value); 4932 break; 4933 case SOC_PHY_CONTROL_RX_PPM: 4934 rv = qtce_rx_ppm_get(pmc, value); 4935 break; 4936 4937 /* CL72 */ 4938 case SOC_PHY_CONTROL_CL72: 4939 rv = qtce_cl72_enable_get(pmc, value); 4940 break; 4941 case SOC_PHY_CONTROL_CL72_STATUS: 4942 rv = qtce_cl72_status_get(pmc, value); 4943 break; 4944 4945 /* PRBS */ 4946 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL: 4947 rv = qtce_prbs_tx_poly_get(pmc, value); 4948 break; 4949 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA: 4950 rv = qtce_prbs_tx_invert_data_get(pmc, value); 4951 break; 4952 case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE: 4953 rv = qtce_prbs_tx_enable_get(pmc, value); 4954 break; 4955 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL: 4956 rv = qtce_prbs_rx_poly_get(pmc, value); 4957 break; 4958 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA: 4959 rv = qtce_prbs_rx_invert_data_get(pmc, value); 4960 break; 4961 case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE: 4962 rv = qtce_prbs_rx_enable_get(pmc, value); 4963 break; 4964 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 4965 rv = qtce_prbs_tx_poly_get(pmc, value); 4966 break; 4967 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 4968 rv = qtce_prbs_tx_invert_data_get(pmc, value); 4969 break; 4970 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 4971 rv = qtce_prbs_tx_enable_get(pmc, value); 4972 break; 4973 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 4974 rv = qtce_prbs_rx_enable_get(pmc, value); 4975 break; 4976 case SOC_PHY_CONTROL_PRBS_RX_STATUS: 4977 rv = qtce_prbs_rx_status_get(pmc, value); 4978 break; 4979 4980 /* LOOPBACK */ 4981 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: 4982 rv = qtce_loopback_remote_get(pmc, value); 4983 break; 4984 case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS: 4985 rv = qtce_loopback_remote_pcs_get(pmc, value); 4986 break; 4987 case SOC_PHY_CONTROL_LOOPBACK_PMD: 4988 rv = qtce_loopback_internal_pmd_get(pmc, value); 4989 break; 4990 4991 /* FEC */ 4992 case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION: 4993 rv = qtce_fec_enable_get(pmc, value); 4994 break; 4995 4996 /* TX PATTERN */ 4997 case SOC_PHY_CONTROL_TX_PATTERN_256BIT: 4998 rv = qtce_pattern_get(pmc, &pCfg->pattern); 4999 break; 5000 case SOC_PHY_CONTROL_TX_PATTERN_LENGTH: 5001 rv = qtce_pattern_len_get(pmc, value); 5002 break; 5003 case SOC_PHY_CONTROL_TX_PATTERN_20BIT: 5004 rv = qtce_pattern_get(pmc, &pCfg->pattern); 5005 break; 5006 5007 /* SCRAMBLER */ 5008 case SOC_PHY_CONTROL_SCRAMBLER: 5009 rv = qtce_scrambler_get(pmc, port, value); 5010 break; 5011 case SOC_PHY_CONTROL_LANE_SWAP: 5012 rv = qtce_lane_map_get(pmc, value); 5013 break; 5014 5015 /* EEE */ 5016 case SOC_PHY_CONTROL_EEE: 5017 rv = qtce_eee_get(pmc, value); 5018 break; 5019 /* UNAVAIL */ 5020 5021 #if 0 5022 /* BERT */ 5023 case SOC_PHY_CONTROL_BERT_TX_PACKETS: /* fall through */ 5024 case SOC_PHY_CONTROL_BERT_RX_PACKETS: /* fall through */ 5025 case SOC_PHY_CONTROL_BERT_RX_ERROR_BITS: /* fall through */ 5026 case SOC_PHY_CONTROL_BERT_RX_ERROR_BYTES: /* fall through */ 5027 case SOC_PHY_CONTROL_BERT_RX_ERROR_PACKETS: /* fall through */ 5028 case SOC_PHY_CONTROL_BERT_PATTERN: /* fall through */ 5029 case SOC_PHY_CONTROL_BERT_PACKET_SIZE: /* fall through */ 5030 case SOC_PHY_CONTROL_BERT_IPG: /* fall through */ 5031 rv = SOC_E_NONE; 5032 break; 5033 5034 /* CUSTOM */ 5035 case SOC_PHY_CONTROL_CUSTOM1: 5036 /* Obsolete ?? 5037 *value = DEV_CFG_PTR(pc)->custom1; 5038 rv = SOC_E_NONE; */ 5039 break; 5040 5041 /* SOFTWARE RX LOS */ 5042 case SOC_PHY_CONTROL_SOFTWARE_RX_LOS: 5043 /* Was 5044 *value = DEV_CFG_PTR(pc)->sw_rx_los.enable ; */ 5045 rv = SOC_E_NONE ; 5046 break ; 5047 5048 /* UNAVAIL */ 5049 case SOC_PHY_CONTROL_LINKDOWN_TRANSMIT: 5050 case SOC_PHY_CONTROL_PARALLEL_DETECTION: 5051 rv = SOC_E_UNAVAIL; 5052 break; 5053 #endif 5054 default: 5055 rv = SOC_E_UNAVAIL; 5056 break; 5057 } 5058 return rv; 5059 } 5060 5061 /* 5062 * Function: 5063 * phy_qtce_per_lane_control_set 5064 * Purpose: 5065 * Configure PHY device specific control fucntion. 5066 * Parameters: 5067 * unit - StrataSwitch unit #. 5068 * port - StrataSwitch port #. 5069 * lane - lane number 5070 * type - Control to update 5071 * value - New setting for the control 5072 * Returns: 5073 * SOC_E_NONE 5074 */ 5075 STATIC int 5076 phy_qtce_per_lane_control_set(int unit, soc_port_t port, int lane, soc_phy_control_t type, uint32 value) 5077 { 5078 int rv; 5079 phy_ctrl_t *pc; 5080 soc_phymod_ctrl_t *pmc; 5081 5082 /* locate phy control, phymod control, and the configuration data */ 5083 pc = INT_PHY_SW_STATE(unit, port); 5084 if (pc == NULL) { 5085 return SOC_E_INTERNAL; 5086 } 5087 pmc = &pc->phymod_ctrl; 5088 5089 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 5090 return SOC_E_PARAM; 5091 } 5092 5093 switch(type) { 5094 case SOC_PHY_CONTROL_PREEMPHASIS: 5095 rv = qtce_per_lane_preemphasis_set(pmc, lane, value); 5096 break; 5097 case SOC_PHY_CONTROL_DRIVER_CURRENT: 5098 rv = qtce_per_lane_driver_current_set(pmc, lane, value); 5099 break; 5100 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 5101 rv = SOC_E_UNAVAIL; 5102 break; 5103 case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT: 5104 rv = SOC_E_UNAVAIL; 5105 break; 5106 case SOC_PHY_CONTROL_RX_TAP1: 5107 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 0 /* tap */, 1 /* enable */, value); 5108 break; 5109 case SOC_PHY_CONTROL_RX_TAP1_RELEASE: 5110 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 0 /* tap */, 0 /* release */, 0x8000); 5111 break; 5112 case SOC_PHY_CONTROL_RX_TAP2: 5113 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 1 /* tap */, 1 /* enable */, value); 5114 break; 5115 case SOC_PHY_CONTROL_RX_TAP2_RELEASE: 5116 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 1 /* tap */, 0 /* release */, 0x8000); 5117 break; 5118 case SOC_PHY_CONTROL_RX_TAP3: 5119 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 2 /* tap */, 1 /* enable */, value); 5120 break; 5121 case SOC_PHY_CONTROL_RX_TAP3_RELEASE: 5122 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 2 /* tap */, 0 /* release */, 0x8000); 5123 break; 5124 case SOC_PHY_CONTROL_RX_TAP4: 5125 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 3 /* tap */, 1 /* enable */, value); 5126 break; 5127 case SOC_PHY_CONTROL_RX_TAP4_RELEASE: 5128 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 3 /* tap */, 0 /* release */, 0x8000); 5129 break; 5130 case SOC_PHY_CONTROL_RX_TAP5: 5131 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 4 /* tap */, 1 /* enable */, value); 5132 break; 5133 case SOC_PHY_CONTROL_RX_TAP5_RELEASE: 5134 rv = qtce_per_lane_rx_dfe_tap_control_set (pmc, lane, 4 /* tap */, 0 /* release */, 0x8000); 5135 break; 5136 5137 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 5138 rv = qtce_per_lane_prbs_poly_set(pmc, lane, value); 5139 break; 5140 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 5141 rv = qtce_per_lane_prbs_tx_invert_data_set(pmc, lane, value); 5142 break; 5143 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 5144 /* TX_ENABLE does both tx and rx */ 5145 rv = qtce_per_lane_prbs_tx_enable_set(pmc, lane, value); 5146 break; 5147 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 5148 rv = SOC_E_NONE; 5149 break; 5150 case SOC_PHY_CONTROL_RX_PEAK_FILTER: 5151 rv = qtce_per_lane_rx_peak_filter_set(pmc, lane, 1 /* enable */, value); 5152 break; 5153 case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER: 5154 rv = qtce_per_lane_rx_low_freq_filter_set(pmc, lane, value); 5155 break; 5156 case SOC_PHY_CONTROL_RX_VGA: 5157 rv = qtce_per_lane_rx_vga_set(pmc, lane, 1 /* enable */, value); 5158 break; 5159 case SOC_PHY_CONTROL_RX_VGA_RELEASE: 5160 rv = qtce_per_lane_rx_vga_set(pmc, lane, 0 /* release */, 0x8000); 5161 break; 5162 case SOC_PHY_CONTROL_RX_PLUS1_SLICER: 5163 rv = SOC_E_UNAVAIL; 5164 break; 5165 case SOC_PHY_CONTROL_RX_MINUS1_SLICER: 5166 rv = SOC_E_UNAVAIL; 5167 break; 5168 case SOC_PHY_CONTROL_RX_D_SLICER: 5169 rv = SOC_E_UNAVAIL; 5170 break; 5171 default: 5172 rv = SOC_E_UNAVAIL; 5173 break; 5174 } 5175 5176 return rv; 5177 } 5178 5179 /* 5180 * Function: 5181 * phy_qtce_per_lane_control_get 5182 * Purpose: 5183 * Configure PHY device specific control fucntion. 5184 * Parameters: 5185 * unit - StrataSwitch unit #. 5186 * port - StrataSwitch port #. 5187 * lane - lane number 5188 * type - Control to update 5189 * value - New setting for the control 5190 * Returns: 5191 * SOC_E_NONE 5192 */ 5193 STATIC int 5194 phy_qtce_per_lane_control_get(int unit, soc_port_t port, int lane, 5195 soc_phy_control_t type, uint32 *value) 5196 { 5197 int rv; 5198 phy_ctrl_t *pc; 5199 soc_phymod_ctrl_t *pmc; 5200 5201 /* locate phy control, phymod control, and the configuration data */ 5202 pc = INT_PHY_SW_STATE(unit, port); 5203 if (pc == NULL) { 5204 return SOC_E_INTERNAL; 5205 } 5206 pmc = &pc->phymod_ctrl; 5207 5208 if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) { 5209 return SOC_E_PARAM; 5210 } 5211 5212 switch(type) { 5213 5214 case SOC_PHY_CONTROL_PREEMPHASIS: 5215 rv = qtce_per_lane_preemphasis_get(pmc, lane, value); 5216 break; 5217 case SOC_PHY_CONTROL_DRIVER_CURRENT: 5218 rv = qtce_per_lane_driver_current_get(pmc, lane, value); 5219 break; 5220 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 5221 rv = SOC_E_UNAVAIL; 5222 break; 5223 case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT: 5224 rv = SOC_E_UNAVAIL; 5225 break; 5226 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 5227 rv = qtce_per_lane_prbs_poly_get(pmc, lane, value); 5228 break; 5229 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 5230 rv = qtce_per_lane_prbs_tx_invert_data_get(pmc, lane, value); 5231 break; 5232 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 5233 rv = qtce_per_lane_prbs_tx_enable_get(pmc, lane, value); 5234 break; 5235 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 5236 rv = qtce_per_lane_prbs_rx_enable_get(pmc, lane, value); 5237 break; 5238 case SOC_PHY_CONTROL_PRBS_RX_STATUS: 5239 rv = qtce_per_lane_prbs_rx_status_get(pmc, lane, value); 5240 break; 5241 case SOC_PHY_CONTROL_RX_PEAK_FILTER: 5242 rv = qtce_per_lane_rx_peak_filter_get(pmc, lane, value); 5243 break; 5244 case SOC_PHY_CONTROL_RX_VGA: 5245 rv = qtce_per_lane_rx_vga_get(pmc, lane, value); 5246 break; 5247 case SOC_PHY_CONTROL_RX_TAP1: 5248 rv = qtce_per_lane_rx_dfe_tap_control_get(pmc, lane, 0, value); 5249 break; 5250 case SOC_PHY_CONTROL_RX_TAP2: 5251 rv = qtce_per_lane_rx_dfe_tap_control_get(pmc, lane, 1, value); 5252 break; 5253 case SOC_PHY_CONTROL_RX_TAP3: 5254 rv = qtce_per_lane_rx_dfe_tap_control_get(pmc, lane, 2, value); 5255 break; 5256 case SOC_PHY_CONTROL_RX_TAP4: 5257 rv = qtce_per_lane_rx_dfe_tap_control_get(pmc, lane, 3, value); 5258 break; 5259 case SOC_PHY_CONTROL_RX_TAP5: 5260 rv = qtce_per_lane_rx_dfe_tap_control_get(pmc, lane, 4, value); 5261 break; 5262 case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER: 5263 rv = qtce_per_lane_rx_low_freq_filter_get(pmc, lane, value); 5264 break; 5265 case SOC_PHY_CONTROL_RX_PLUS1_SLICER: 5266 rv = SOC_E_UNAVAIL; 5267 break; 5268 case SOC_PHY_CONTROL_RX_MINUS1_SLICER: 5269 rv = SOC_E_UNAVAIL; 5270 break; 5271 case SOC_PHY_CONTROL_RX_D_SLICER: 5272 rv = SOC_E_UNAVAIL; 5273 break; 5274 default: 5275 rv = SOC_E_UNAVAIL; 5276 break; 5277 } 5278 return rv; 5279 } 5280 5281 /* 5282 * Function: 5283 * phy_qtce_reg_read 5284 * Purpose: 5285 * Routine to read PHY register 5286 * Parameters: 5287 * unit - BCM unit number 5288 * port - Port number 5289 * flags - Flags which specify the register type 5290 * phy_reg_addr - Encoded register address 5291 * phy_data - (OUT) Value read from PHY register 5292 * Note: 5293 * This register read function is not thread safe. Higher level 5294 * function that calls this function must obtain a per port lock 5295 * to avoid overriding register page mapping between threads. 5296 */ 5297 STATIC int 5298 phy_qtce_reg_read(int unit, soc_port_t port, uint32 flags, 5299 uint32 phy_reg_addr, uint32 *phy_reg_data) 5300 { 5301 phy_ctrl_t *pc; 5302 soc_phymod_ctrl_t *pmc; 5303 phymod_phy_access_t *pm_phy; 5304 5305 pc = INT_PHY_SW_STATE(unit, port); 5306 if (pc == NULL) { 5307 return SOC_E_INTERNAL; 5308 } 5309 5310 pmc = &pc->phymod_ctrl; 5311 pm_phy = &pmc->phy[0]->pm_phy; 5312 SOC_IF_ERROR_RETURN 5313 (phymod_phy_reg_read(pm_phy, phy_reg_addr, phy_reg_data)); 5314 5315 return SOC_E_NONE; 5316 } 5317 5318 /* 5319 * Function: 5320 * phy_qtce_reg_write 5321 * Purpose: 5322 * Routine to write PHY register 5323 * Parameters: 5324 * uint - BCM unit number 5325 * pc - PHY state 5326 * flags - Flags which specify the register type 5327 * phy_reg_addr - Encoded register address 5328 * phy_data - Value write to PHY register 5329 * Note: 5330 * This register read function is not thread safe. Higher level 5331 * function that calls this function must obtain a per port lock 5332 * to avoid overriding register page mapping between threads. 5333 */ 5334 STATIC int 5335 phy_qtce_reg_write(int unit, soc_port_t port, uint32 flags, 5336 uint32 phy_reg_addr, uint32 phy_reg_data) 5337 { 5338 phy_ctrl_t *pc; 5339 soc_phymod_ctrl_t *pmc; 5340 phymod_phy_access_t *pm_phy; 5341 int idx; 5342 5343 pc = INT_PHY_SW_STATE(unit, port); 5344 if (pc == NULL) { 5345 return SOC_E_INTERNAL; 5346 } 5347 5348 pmc = &pc->phymod_ctrl; 5349 for (idx = 0; idx < pmc->num_phys; idx++) { 5350 pm_phy = &pmc->phy[idx]->pm_phy; 5351 SOC_IF_ERROR_RETURN 5352 (phymod_phy_reg_write(pm_phy, phy_reg_addr, phy_reg_data)); 5353 } 5354 return SOC_E_NONE; 5355 } 5356 5357 /* 5358 * Function: 5359 * phy_qtce_reg_modify 5360 * Purpose: 5361 * Routine to write PHY register 5362 * Parameters: 5363 * uint - BCM unit number 5364 * pc - PHY state 5365 * flags - Flags which specify the register type 5366 * phy_reg_addr - Encoded register address 5367 * phy_mo_data - New value for the bits specified in phy_mo_mask 5368 * phy_mo_mask - Bit mask to modify 5369 * Note: 5370 * This function is not thread safe. Higher level 5371 * function that calls this function must obtain a per port lock 5372 * to avoid overriding register page mapping between threads. 5373 */ 5374 STATIC int 5375 phy_qtce_reg_modify(int unit, soc_port_t port, uint32 flags, 5376 uint32 phy_reg_addr, uint32 phy_data, 5377 uint32 phy_data_mask) 5378 { 5379 phy_ctrl_t *pc; 5380 soc_phymod_ctrl_t *pmc; 5381 phymod_phy_access_t *pm_phy; 5382 uint32 data32, tmp; 5383 int idx; 5384 5385 pc = INT_PHY_SW_STATE(unit, port); 5386 if (pc == NULL) { 5387 return SOC_E_INTERNAL; 5388 } 5389 5390 pmc = &pc->phymod_ctrl; 5391 for (idx = 0; idx < pmc->num_phys; idx++) { 5392 pm_phy = &pmc->phy[idx]->pm_phy; 5393 SOC_IF_ERROR_RETURN 5394 (phymod_phy_reg_read(pm_phy, phy_reg_addr, &data32)); 5395 tmp = data32; 5396 data32 &= ~(phy_data_mask); 5397 data32 |= (phy_data & phy_data_mask); 5398 if (data32 != tmp) { 5399 SOC_IF_ERROR_RETURN 5400 (phymod_phy_reg_write(pm_phy, phy_reg_addr, data32)); 5401 } 5402 } 5403 return SOC_E_NONE; 5404 } 5405 5406 STATIC void 5407 phy_qtce_cleanup(soc_phymod_ctrl_t *pmc) 5408 { 5409 int idx; 5410 soc_phymod_phy_t *phy; 5411 soc_phymod_core_t *core; 5412 5413 for (idx = 0; idx < pmc->num_phys ; idx++) { 5414 phy = pmc->phy[idx]; 5415 if (phy == NULL) { 5416 LOG_WARN(BSL_LS_SOC_PHY, 5417 (BSL_META_U(pmc->unit, 5418 "phy object is empty"))); 5419 continue; 5420 } 5421 5422 core = phy->core; 5423 5424 /* Destroy core object if not used anymore */ 5425 if (core && core->ref_cnt) { 5426 if (--core->ref_cnt == 0) { 5427 core->init = FALSE; 5428 soc_phymod_core_destroy(pmc->unit, core); 5429 } 5430 } 5431 5432 /* Destroy phy object */ 5433 if (phy) { 5434 soc_phymod_phy_destroy(pmc->unit, phy); 5435 } 5436 } 5437 pmc->num_phys = 0; 5438 } 5439 5440 STATIC void 5441 phy_qtce_core_init(phy_ctrl_t *pc, soc_phymod_core_t *core, 5442 phymod_bus_t *core_bus, uint32 core_addr) 5443 { 5444 phymod_core_access_t *pm_core; 5445 phymod_access_t *pm_acc; 5446 5447 core->unit = pc->unit; 5448 core->read = pc->read; 5449 core->write = pc->write; 5450 core->wrmask = pc->wrmask; 5451 core->port = pc->port; 5452 5453 pm_core = &core->pm_core; 5454 phymod_core_access_t_init(pm_core); 5455 pm_acc = &pm_core->access; 5456 phymod_access_t_init(pm_acc); 5457 PHYMOD_ACC_USER_ACC(pm_acc) = core; 5458 PHYMOD_ACC_BUS(pm_acc) = core_bus; 5459 PHYMOD_ACC_ADDR(pm_acc) = core_addr; 5460 5461 if (soc_property_port_get(pc->unit, pc->port, "qtce_sim", 0) == 45) { 5462 PHYMOD_ACC_F_CLAUSE45_SET(pm_acc); 5463 } 5464 5465 return; 5466 } 5467 5468 /* 5469 * Function: 5470 * phy_qtce_probe 5471 * Purpose: 5472 * xx 5473 * Parameters: 5474 * pc->phy_id (IN) 5475 * pc->unit (IN) 5476 * pc->port (IN) 5477 * pc->size (OUT) - memory required by phy port 5478 * pc->dev_name (OUT) - set to port device name 5479 * 5480 * Note: 5481 */ 5482 STATIC int 5483 phy_qtce_probe(int unit, phy_ctrl_t *pc) 5484 { 5485 int rv, idx; 5486 uint32 lane_map, num_phys, core_id, phy_id, found; 5487 phymod_bus_t core_bus; 5488 phymod_dispatch_type_t phy_type; 5489 phymod_core_access_t *pm_core; 5490 phymod_phy_access_t *pm_phy; 5491 phymod_access_t *pm_acc; 5492 soc_phymod_ctrl_t *pmc; 5493 soc_phymod_phy_t *phy; 5494 soc_phymod_core_t *core; 5495 soc_phymod_core_t core_probe; 5496 soc_info_t *si; 5497 phyident_core_info_t core_info[8]; 5498 #if 0 /* for QSGMII */ 5499 int array_max = 8; 5500 int array_size = 0; 5501 #endif 5502 int port; 5503 int phy_port; /* physical port number */ 5504 int qmode = 0; 5505 5506 rv = 0; 5507 5508 /* Initialize PHY bus */ 5509 SOC_IF_ERROR_RETURN(phymod_bus_t_init(&core_bus)); 5510 core_bus.bus_name = "qtce_sim"; 5511 core_bus.read = _qtce_reg_read; 5512 core_bus.write = _qtce_reg_write; 5513 5514 /* Configure PHY bus properties */ 5515 if (pc->wrmask) { 5516 PHYMOD_BUS_CAP_WR_MODIFY_SET(&core_bus); 5517 PHYMOD_BUS_CAP_LANE_CTRL_SET(&core_bus); 5518 } 5519 5520 port = pc->port; 5521 pmc = &pc->phymod_ctrl; 5522 si = &SOC_INFO(unit); 5523 if (soc_feature(unit, soc_feature_logical_port_num)) { 5524 phy_port = si->port_l2p_mapping[port]; 5525 } else { 5526 phy_port = port; 5527 } 5528 5529 /* Install clean up function */ 5530 pmc->unit = pc->unit; 5531 pmc->cleanup = phy_qtce_cleanup; 5532 /*pmc->symbols = &bcmi_qtce_serdes_symbols; */ 5533 5534 5535 /* if (SOC_IS_GREYHOUND(unit)) */ { 5536 int i, blk; 5537 blk = -1; 5538 for (i=0; i< SOC_DRIVER(unit)->port_num_blktype; i++){ 5539 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 5540 if (PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), port)){ 5541 break; 5542 } 5543 } 5544 if (blk == -1) { 5545 pc->chip_num = -1; 5546 return SOC_E_NOT_FOUND; 5547 } else { 5548 pc->chip_num = SOC_BLOCK_NUMBER(unit, blk); 5549 } 5550 5551 /* next check if Qmode or sgmii mode */ 5552 if (si->port_num_lanes[port] == 1) { 5553 qmode = 1; 5554 /* current lane number for QSGMII-Eagle is 0-15 */ 5555 /* In QSGMII mode, GH2 has two qtce cores. Each core has 16 lanes 5556 * Block GPORT3-4 is core0. Block GPORT5-6 is core1 */ 5557 if (SOC_IS_GREYHOUND2(unit)) { 5558 pc->lane_num = (SOC_PORT_BINDEX(unit, phy_port) + 5559 ((pc->chip_num % 2) ? 0 : 8)) % 16; 5560 pc->chip_num = (pc->chip_num - 3)/2; 5561 } 5562 else { 5563 pc->lane_num = (SOC_PORT_BINDEX(unit, phy_port) + 5564 ((pc->chip_num % 2) ? 8 : 0)) % 16; 5565 } 5566 } else { 5567 /* current lane number for QSGMII-Eagle is 0-15 */ 5568 /* In SGMII mode, GH2 has two qtce cores. Each core has 4 lanes 5569 * Block GPORT3 is core0. Block GPORT5 is core1 */ 5570 if (SOC_IS_GREYHOUND2(unit)) { 5571 pc->lane_num = SOC_PORT_BINDEX(unit, phy_port); 5572 pc->chip_num = (pc->chip_num - 3)/2; 5573 } 5574 else { 5575 pc->lane_num = (SOC_PORT_BINDEX(unit, phy_port) + 5576 ((pc->chip_num > 0) ? 8 : 0)) % 16; 5577 5578 pc->lane_num %= 8; 5579 } 5580 } 5581 } 5582 5583 /* request memory for the configuration structure */ 5584 pc->size = sizeof(qtce_config_t); 5585 5586 num_phys = 1; 5587 pc->phy_mode = PHYCTRL_QSGMII_CORE_PORT; 5588 lane_map = 1 << pc->lane_num; 5589 core_info[0].mdio_addr = pc->phy_id; 5590 5591 phy_type = phymodDispatchTypeQtce; 5592 5593 /* Probe cores */ 5594 for (idx = 0; idx < num_phys ; idx++) { 5595 phy_qtce_core_init(pc, &core_probe, &core_bus, 5596 core_info[idx].mdio_addr); 5597 /* Check that core is indeed an QTC/Eagle core */ 5598 pm_core = &core_probe.pm_core; 5599 pm_core->type = phy_type; 5600 rv = phymod_core_identify(pm_core, 0, &found); 5601 if (SOC_FAILURE(rv)) { 5602 return rv; 5603 } 5604 if (!found) { 5605 return SOC_E_NOT_FOUND; 5606 } 5607 } 5608 5609 for (idx = 0; idx < num_phys ; idx++) { 5610 /* Set core and phy IDs based on PHY address */ 5611 core_id = pc->phy_id + idx; 5612 phy_id = (lane_map << 16) | core_id; 5613 5614 /* Create PHY object */ 5615 rv = soc_phymod_phy_create(unit, phy_id, &pmc->phy[idx]); 5616 if (SOC_FAILURE(rv)) { 5617 break; 5618 } 5619 pmc->num_phys++; 5620 5621 /* Initialize phy object */ 5622 phy = pmc->phy[idx]; 5623 pm_phy = &phy->pm_phy; 5624 phymod_phy_access_t_init(pm_phy); 5625 5626 /* Find or create associated core object */ 5627 rv = soc_phymod_core_find_by_id(unit, core_id, &phy->core); 5628 if (rv == SOC_E_NOT_FOUND) { 5629 rv = soc_phymod_core_create(unit, core_id, &phy->core); 5630 } 5631 if (SOC_FAILURE(rv)) { 5632 break; 5633 } 5634 } 5635 if (SOC_FAILURE(rv)) { 5636 phy_qtce_cleanup(pmc); 5637 return rv; 5638 } 5639 5640 for (idx = 0; idx < pmc->num_phys ; idx++) { 5641 phy = pmc->phy[idx]; 5642 core = phy->core; 5643 pm_core = &core->pm_core; 5644 5645 /* Initialize core object if newly created */ 5646 if (core->ref_cnt == 0) { 5647 sal_memcpy(&core->pm_bus, &core_bus, sizeof(core->pm_bus)); 5648 phy_qtce_core_init(pc, core, &core->pm_bus, 5649 core_info[idx].mdio_addr); 5650 /* Set dispatch type */ 5651 pm_core->type = phy_type; 5652 if (qmode) { 5653 PHYMOD_ACC_F_QMODE_SET(&pm_core->access); 5654 } 5655 } 5656 core->ref_cnt++; 5657 5658 /* Initialize phy access based on associated core */ 5659 pm_acc = &phy->pm_phy.access; 5660 sal_memcpy(pm_acc, &pm_core->access, sizeof(*pm_acc)); 5661 phy->pm_phy.type = phy_type; 5662 PHYMOD_ACC_LANE_MASK(pm_acc) = lane_map; 5663 } 5664 5665 return SOC_E_NONE; 5666 } 5667 5668 5669 /*********************************************************************** 5670 * 5671 * PASS-THROUGH NOTIFY ROUTINES 5672 */ 5673 5674 /* 5675 * Function: 5676 * _qtce_notify_duplex 5677 * Purpose: 5678 * Program duplex if (and only if) serdesqtce is an intermediate PHY. 5679 * Parameters: 5680 * unit - BCM unit number. 5681 * port - Port number. 5682 * duplex - Boolean, TRUE indicates full duplex, FALSE 5683 * indicates half. 5684 * Returns: 5685 * SOC_E_XXX 5686 * Notes: 5687 * If PHY_FLAGS_FIBER is set, it indicates the PHY is being used to 5688 * talk directly to an external fiber module. 5689 * 5690 * If PHY_FLAGS_FIBER is clear, the PHY is being used in 5691 * pass-through mode to talk to an external SGMII PHY. 5692 * 5693 * When used in pass-through mode, autoneg must be turned off and 5694 * the speed/duplex forced to match that of the external PHY. 5695 */ 5696 5697 STATIC int 5698 _qtce_notify_duplex(int unit, soc_port_t port, uint32 duplex) 5699 { 5700 return SOC_E_NONE; 5701 } 5702 5703 /* 5704 * Function: 5705 * _qtce_stop 5706 * Purpose: 5707 * Put serdesqtce SERDES in or out of reset depending on conditions 5708 */ 5709 5710 STATIC int 5711 _qtce_stop(int unit, soc_port_t port) 5712 { 5713 phy_ctrl_t* pc; 5714 soc_phymod_ctrl_t *pmc; 5715 phymod_phy_access_t *pm_phy; 5716 phymod_phy_power_t phy_power; 5717 int stop, copper; 5718 int enable = 0; 5719 5720 pc = INT_PHY_SW_STATE(unit, port); 5721 pmc = &pc->phymod_ctrl; 5722 pm_phy = &pmc->phy[0]->pm_phy; 5723 5724 copper = (pc->stop & 5725 PHY_STOP_COPPER) != 0; 5726 5727 stop = ((pc->stop & 5728 (PHY_STOP_PHY_DIS | 5729 PHY_STOP_DRAIN)) != 0 || 5730 (copper && 5731 (pc->stop & 5732 (PHY_STOP_MAC_DIS | 5733 PHY_STOP_DUPLEX_CHG | 5734 PHY_STOP_SPEED_CHG)) != 0)); 5735 5736 LOG_INFO(BSL_LS_SOC_PHY, 5737 (BSL_META_U(pc->unit, 5738 "qtce_stop: u=%d p=%d copper=%d stop=%d flg=0x%x\n"), 5739 unit, port, copper, stop, 5740 pc->stop)); 5741 if (stop) { 5742 phy_power.tx = phymodPowerOff; 5743 /* phy_power.tx = phymodPowerOn; */ 5744 phy_power.rx = phymodPowerNoChange; 5745 } else { 5746 phy_power.tx = phymodPowerOn; 5747 phy_power.rx = phymodPowerOn; 5748 } 5749 5750 SOC_IF_ERROR_RETURN 5751 (_phy_qtce_qsgmii_an_get(unit, port, &enable)) ; 5752 5753 if(!enable) { 5754 SOC_IF_ERROR_RETURN 5755 (phymod_phy_power_set(pm_phy, &phy_power)); 5756 } 5757 return SOC_E_NONE; 5758 } 5759 5760 /* 5761 * Function: 5762 * _qtce_notify_stop 5763 * Purpose: 5764 * Add a reason to put serdesqtce PHY in reset. 5765 * Parameters: 5766 * unit - BCM unit number. 5767 * port - Port number. 5768 * flags - Reason to stop 5769 * Returns: 5770 * SOC_E_XXX 5771 */ 5772 5773 STATIC int 5774 _qtce_notify_stop(int unit, soc_port_t port, uint32 flags) 5775 { 5776 INT_PHY_SW_STATE(unit, port)->stop |= flags; 5777 return _qtce_stop(unit, port); 5778 } 5779 5780 /* 5781 * Function: 5782 * _qtce_notify_resume 5783 * Purpose: 5784 * Remove a reason to put serdesqtce PHY in reset. 5785 * Parameters: 5786 * unit - BCM unit number. 5787 * port - Port number. 5788 * flags - Reason to stop 5789 * Returns: 5790 * SOC_E_XXX 5791 */ 5792 5793 STATIC int 5794 _qtce_notify_resume(int unit, soc_port_t port, uint32 flags) 5795 { 5796 INT_PHY_SW_STATE(unit, port)->stop &= ~flags; 5797 return _qtce_stop(unit, port); 5798 } 5799 5800 /* 5801 * Function: 5802 * _qtce_notify_speed 5803 * Purpose: 5804 * Program duplex if (and only if) serdesqtce is an intermediate PHY. 5805 * Parameters: 5806 * unit - BCM unit number. 5807 * port - Port number. 5808 * speed - Speed to program. 5809 * Returns: 5810 * SOC_E_XXX 5811 * Notes: 5812 * If PHY_FLAGS_FIBER is set, it indicates the PHY is being used to 5813 * talk directly to an external fiber module. 5814 * 5815 * If PHY_FLAGS_FIBER is clear, the PHY is being used in 5816 * pass-through mode to talk to an external SGMII PHY. 5817 * 5818 * When used in pass-through mode, autoneg must be turned off and 5819 * the speed/duplex forced to match that of the external PHY. 5820 */ 5821 5822 STATIC int 5823 _qtce_notify_speed(int unit, soc_port_t port, uint32 speed) 5824 { 5825 phy_ctrl_t* pc; 5826 qtce_config_t *pCfg; 5827 int fiber; 5828 int enable = 0; 5829 5830 pc = INT_PHY_SW_STATE(unit, port); 5831 pCfg = (qtce_config_t *) pc->driver_data; 5832 fiber = pCfg->fiber_pref; 5833 5834 LOG_INFO(BSL_LS_SOC_PHY, 5835 (BSL_META_U(pc->unit, 5836 "_qtce_notify_speed: " 5837 "u=%d p=%d speed=%d fiber=%d\n"), 5838 unit, port, speed, fiber)); 5839 5840 if (SAL_BOOT_SIMULATION) { 5841 return SOC_E_NONE; 5842 } 5843 5844 SOC_IF_ERROR_RETURN 5845 (_phy_qtce_qsgmii_an_get(unit, port, &enable)) ; 5846 5847 if(!enable) { /* to avoid the link flap for qsgmii */ 5848 /* Put SERDES PHY in reset */ 5849 SOC_IF_ERROR_RETURN 5850 (_qtce_notify_stop(unit, port, PHY_STOP_SPEED_CHG)); 5851 5852 /* Update speed */ 5853 SOC_IF_ERROR_RETURN 5854 (phy_qtce_speed_set(unit, port, speed)); 5855 5856 /* Take SERDES PHY out of reset */ 5857 SOC_IF_ERROR_RETURN 5858 (_qtce_notify_resume(unit, port, PHY_STOP_SPEED_CHG)); 5859 } 5860 return SOC_E_NONE; 5861 } 5862 5863 /* 5864 * Function: 5865 * qtce_media_setup 5866 * Purpose: 5867 * Configure 5868 * Parameters: 5869 * unit - BCM unit number. 5870 * port - Port number. 5871 * fiber_mode - Configure for fiber mode 5872 * fiber_pref - Fiber preferrred (if fiber mode) 5873 * Returns: 5874 * SOC_E_XXX 5875 */ 5876 STATIC int 5877 _qtce_notify_interface(int unit, soc_port_t port, uint32 intf) 5878 { 5879 return SOC_E_NONE; 5880 } 5881 5882 /* 5883 * Function: 5884 * _qtce_notify_mac_loopback 5885 * Purpose: 5886 * Turn on rx clock compensation in mac loopback mode for 5887 * applicable XGXS devices 5888 * Parameters: 5889 * unit - BCM unit number. 5890 * port - Port number. 5891 * enable - TRUE: In MAC loopback mode, FALSE: Not in MAC loopback mode 5892 * Returns: 5893 * SOC_E_XXX 5894 */ 5895 STATIC int 5896 _qtce_notify_mac_loopback(int unit, soc_port_t port, uint32 enable) 5897 { 5898 return SOC_E_NONE; 5899 } 5900 5901 /* 5902 * Function: 5903 * _qtce_notify_link_wait 5904 * Purpose: 5905 * Waiting the link between external PHY and Serdes 5906 * Parameters: 5907 * unit - BCM unit number. 5908 * port - Port number. 5909 * timeout - timeout in micro-second; 0:use default value. 5910 * Returns: 5911 * SOC_E_XXX 5912 */ 5913 #define QTC_WAIT_LINK_TIMEOUT (500000) /* 500 ms */ 5914 #define QTC_POLL_LINK_INTERVAL (50000) /* 50 ms */ 5915 STATIC int 5916 _qtce_notify_link_wait(int unit, soc_port_t port, uint32 timeout) 5917 { 5918 int rv = SOC_E_NONE; 5919 soc_timeout_t to; 5920 uint32 to_us = (timeout>0 ? timeout : QTC_WAIT_LINK_TIMEOUT); 5921 int link = 0; 5922 5923 soc_timeout_init(&to, to_us, 0); 5924 5925 for (;;) { 5926 rv = phy_qtce_link_get(unit, port, &link); 5927 if (link == 1 || SOC_FAILURE(rv)) { 5928 break; 5929 } 5930 5931 if (soc_timeout_check(&to)) { 5932 rv = SOC_E_TIMEOUT; 5933 break; 5934 } 5935 5936 sal_usleep(QTC_POLL_LINK_INTERVAL); 5937 } 5938 5939 LOG_INFO(BSL_LS_SOC_PHY, 5940 (BSL_META_U(unit, 5941 "rv=%d u=%d p=%d link=%d\n"), 5942 rv, unit, port, link)); 5943 5944 return rv; 5945 } 5946 5947 STATIC int 5948 phy_qtce_notify(int unit, soc_port_t port, 5949 soc_phy_event_t event, uint32 value) 5950 { 5951 int rv; 5952 rv = SOC_E_NONE ; 5953 5954 if (event >= phyEventCount) { 5955 return SOC_E_PARAM; 5956 } 5957 5958 switch(event) { 5959 case phyEventInterface: 5960 rv = (_qtce_notify_interface(unit, port, value)); 5961 break; 5962 case phyEventDuplex: 5963 rv = (_qtce_notify_duplex(unit, port, value)); 5964 break; 5965 case phyEventSpeed: 5966 rv = (_qtce_notify_speed(unit, port, value)); 5967 break; 5968 case phyEventStop: 5969 rv = (_qtce_notify_stop(unit, port, value)); 5970 break; 5971 case phyEventResume: 5972 rv = (_qtce_notify_resume(unit, port, value)); 5973 break; 5974 case phyEventAutoneg: 5975 #if 0 5976 rv = (_qtce_an_set(unit, port, value)); 5977 #endif 5978 break; 5979 case phyEventMacLoopback: 5980 rv = (_qtce_notify_mac_loopback(unit, port, value)); 5981 break; 5982 case phyEventLpiBypass: 5983 PHYMOD_LPI_BYPASS_SET(value); 5984 rv = phy_qtce_control_set(unit, port, SOC_PHY_CONTROL_EEE, value); 5985 break; 5986 case phyEventLinkWait: 5987 rv = (_qtce_notify_link_wait(unit, port, value)); 5988 break; 5989 default: 5990 rv = SOC_E_UNAVAIL; 5991 break; 5992 } 5993 5994 return rv; 5995 } 5996 5997 /* 5998 * Function: 5999 * phy_qtce_diag_ctrl 6000 * Purpose: 6001 * xx 6002 * Parameters: 6003 * unit - BCM unit number. 6004 * port - Port number. 6005 6006 * Returns: 6007 * SOC_E_NONE 6008 */ 6009 6010 STATIC int 6011 phy_qtce_diag_ctrl( 6012 int unit, /* unit */ 6013 soc_port_t port, /* port */ 6014 uint32 inst, /* the specific device block the control action directs to */ 6015 int op_type, /* operation types: read,write or command sequence */ 6016 int op_cmd, /* command code */ 6017 void *arg) /* command argument based on op_type/op_cmd */ 6018 { 6019 switch(op_cmd) { 6020 case PHY_DIAG_CTRL_DSC: 6021 LOG_INFO(BSL_LS_SOC_PHY, 6022 (BSL_META_U(unit, 6023 "phy_tscmod_diag_ctrl: " 6024 "u=%d p=%d PHY_DIAG_CTRL_DSC 0x%x\n"), 6025 unit, port, PHY_DIAG_CTRL_DSC)); 6026 SOC_IF_ERROR_RETURN(qtce_uc_status_dump(unit, port, arg)); 6027 break; 6028 case PHY_DIAG_CTRL_PCS: 6029 LOG_INFO(BSL_LS_SOC_PHY, 6030 (BSL_META_U(unit, 6031 "phy_temod_diag_ctrl: " 6032 "u=%d p=%d PHY_DIAG_CTRL_PCS 0x%x\n"), 6033 unit, port, PHY_DIAG_CTRL_PCS)); 6034 SOC_IF_ERROR_RETURN(qtce_pcs_status_dump(unit, port, arg)); 6035 break; 6036 default: 6037 if (op_type == PHY_DIAG_CTRL_SET) { 6038 SOC_IF_ERROR_RETURN(phy_qtce_control_set(unit,port,op_cmd,PTR_TO_INT(arg))); 6039 } else if (op_type == PHY_DIAG_CTRL_GET) { 6040 SOC_IF_ERROR_RETURN(phy_qtce_control_get(unit,port,op_cmd,(uint32 *)arg)); 6041 } 6042 break ; 6043 } 6044 return (SOC_E_NONE); 6045 } 6046 6047 /* 6048 * Function: 6049 * phy_tsce_master_set 6050 * Purpose: 6051 * Configure master mode 6052 * Parameters: 6053 * unit - StrataSwitch unit #. 6054 * port - StrataSwitch port #. 6055 * master - Master mode. 6056 * Returns: 6057 * SOC_E_NONE/SOC_E_UNAVAIL 6058 */ 6059 STATIC int 6060 phy_qtce_master_set(int unit, soc_port_t port, int master) 6061 { 6062 if (master != SOC_PORT_MS_SLAVE) 6063 return SOC_E_UNAVAIL; 6064 6065 return SOC_E_NONE; 6066 } 6067 6068 /* 6069 * Function: 6070 * phy_tsce_master_get 6071 * Purpose: 6072 * this function is meant for 1000Base-T PHY. Added here to support 6073 * internal PHY regression test 6074 * Parameters: 6075 * unit - StrataSwitch unit #. 6076 * port - StrataSwitch port #. 6077 * master - (OUT) SOC_PORT_MS_* 6078 * Returns: 6079 * SOC_E_NONE 6080 * Notes: 6081 * The master mode is retrieved for the ACTIVE medium. 6082 */ 6083 STATIC int 6084 phy_qtce_master_get(int unit, soc_port_t port, int *master) 6085 { 6086 *master = SOC_PORT_MS_SLAVE; 6087 6088 return SOC_E_NONE; 6089 } 6090 6091 #ifdef BROADCOM_DEBUG 6092 void 6093 qtce_state_dump(int unit, soc_port_t port) 6094 { 6095 /* Show PHY configuration summary */ 6096 /* Lane status */ 6097 /* Show Counters */ 6098 /* Dump Registers */ 6099 } 6100 #endif /* BROADCOM_DEBUG */ 6101 6102 STATIC int 6103 phy_qtce_synce_clk_ctrl_set(int unit, int port, uint32 mode0, uint32 mode1, uint32 sdm_value) 6104 { 6105 phy_ctrl_t* pc; 6106 soc_phymod_ctrl_t *pmc; 6107 phymod_phy_access_t *pm_phy; 6108 phymod_synce_clk_ctrl_t phy_synce_cfg; 6109 6110 pc = INT_PHY_SW_STATE(unit, port); 6111 pmc = &pc->phymod_ctrl; 6112 pm_phy = &pmc->phy[0]->pm_phy; 6113 6114 phymod_synce_clk_ctrl_t_init(&phy_synce_cfg); 6115 phy_synce_cfg.stg0_mode = mode0; 6116 phy_synce_cfg.stg1_mode = mode1; 6117 phy_synce_cfg.sdm_val = sdm_value; 6118 6119 SOC_IF_ERROR_RETURN(phymod_phy_synce_clk_ctrl_set(pm_phy, phy_synce_cfg)); 6120 6121 return SOC_E_NONE; 6122 } 6123 6124 STATIC int 6125 phy_qtce_synce_clk_ctrl_get(int unit, int port, uint32 *mode0, uint32 *mode1, uint32 *sdm_value) 6126 { 6127 phy_ctrl_t* pc; 6128 soc_phymod_ctrl_t *pmc; 6129 phymod_phy_access_t *pm_phy; 6130 phymod_synce_clk_ctrl_t phy_synce_cfg; 6131 6132 pc = INT_PHY_SW_STATE(unit, port); 6133 pmc = &pc->phymod_ctrl; 6134 pm_phy = &pmc->phy[0]->pm_phy; 6135 6136 phymod_synce_clk_ctrl_t_init(&phy_synce_cfg); 6137 6138 SOC_IF_ERROR_RETURN(phymod_phy_synce_clk_ctrl_get(pm_phy, &phy_synce_cfg)); 6139 6140 *mode0 = phy_synce_cfg.stg0_mode; 6141 *mode1 = phy_synce_cfg.stg1_mode; 6142 *sdm_value = phy_synce_cfg.sdm_val; 6143 6144 return SOC_E_NONE; 6145 } 6146 6147 /* 6148 * Variable: 6149 * qtce_drv 6150 * Purpose: 6151 * Phy Driver for TSC/Eagle 6152 */ 6153 phy_driver_t phy_qtce_drv = { 6154 /* .drv_name = */ "TSC/Eagle PHYMOD PHY Driver", 6155 /* .pd_init = */ phy_qtce_init, 6156 /* .pd_reset = */ phy_null_reset, 6157 /* .pd_link_get = */ phy_qtce_link_get, 6158 /* .pd_enable_set = */ phy_qtce_enable_set, 6159 /* .pd_enable_get = */ phy_qtce_enable_get, 6160 /* .pd_duplex_set = */ phy_null_set, 6161 /* .pd_duplex_get = */ phy_qtce_duplex_get, 6162 /* .pd_speed_set = */ phy_qtce_speed_set, 6163 /* .pd_speed_get = */ phy_qtce_speed_get, 6164 /* .pd_master_set = */ phy_qtce_master_set, 6165 /* .pd_master_get = */ phy_qtce_master_get, 6166 /* .pd_an_set = */ phy_qtce_an_set, 6167 /* .pd_an_get = */ phy_qtce_an_get, 6168 /* .pd_adv_local_set = */ NULL, /* Deprecated */ 6169 /* .pd_adv_local_get = */ NULL, /* Deprecated */ 6170 /* .pd_adv_remote_get = */ NULL, /* Deprecated */ 6171 /* .pd_lb_set = */ phy_qtce_lb_set, 6172 /* .pd_lb_get = */ phy_qtce_lb_get, 6173 /* .pd_interface_set = */ phy_qtce_interface_set, 6174 /* .pd_interface_get = */ phy_qtce_interface_get, 6175 /* .pd_ability = */ NULL, /* Deprecated */ 6176 /* .pd_linkup_evt = */ NULL, 6177 /* .pd_linkdn_evt = */ NULL, 6178 /* .pd_mdix_set = */ phy_null_mdix_set, 6179 /* .pd_mdix_get = */ phy_null_mdix_get, 6180 /* .pd_mdix_status_get = */ phy_null_mdix_status_get, 6181 /* .pd_medium_config_set = */ NULL, 6182 /* .pd_medium_config_get = */ NULL, 6183 /* .pd_medium_get = */ phy_null_medium_get, 6184 /* .pd_cable_diag = */ NULL, 6185 /* .pd_link_change = */ NULL, 6186 /* .pd_control_set = */ phy_qtce_control_set, 6187 /* .pd_control_get = */ phy_qtce_control_get, 6188 /* .pd_reg_read = */ phy_qtce_reg_read, 6189 /* .pd_reg_write = */ phy_qtce_reg_write, 6190 /* .pd_reg_modify = */ phy_qtce_reg_modify, 6191 /* .pd_notify = */ phy_qtce_notify, 6192 /* .pd_probe = */ phy_qtce_probe, 6193 /* .pd_ability_advert_set = */ phy_qtce_ability_advert_set, 6194 /* .pd_ability_advert_get = */ phy_qtce_ability_advert_get, 6195 /* .pd_ability_remote_get = */ phy_qtce_ability_remote_get, 6196 /* .pd_ability_local_get = */ phy_qtce_ability_local_get, 6197 /* .pd_firmware_set = */ NULL, 6198 /* .pd_timesync_config_set = */ NULL, 6199 /* .pd_timesync_config_get = */ NULL, 6200 /* .pd_timesync_control_set = */ NULL, 6201 /* .pd_timesync_control_set = */ NULL, 6202 /* .pd_diag_ctrl = */ phy_qtce_diag_ctrl, 6203 /* .pd_lane_control_set = */ phy_qtce_per_lane_control_set, 6204 /* .pd_lane_control_get = */ phy_qtce_per_lane_control_get, 6205 /* .pd_lane_reg_read = */ NULL, 6206 /* .pd_lane_reg_write = */ NULL, 6207 /* .pd_oam_config_set = */ NULL, 6208 /* .pd_oam_config_get = */ NULL, 6209 /* .pd_oam_control_set = */ NULL, 6210 /* .pd_oam_control_get = */ NULL, 6211 /* .pd_timesync_enhanced_capture_get = */ NULL, 6212 /* .pd_multi_get = */ NULL, 6213 /* .pd_precondition_before_probe = */ NULL, 6214 /* .pd_linkfault_get = */ NULL, 6215 /* .pd_synce_clk_ctrl_set = */ phy_qtce_synce_clk_ctrl_set, 6216 /* .pd_synce_clk_ctrl_get = */ phy_qtce_synce_clk_ctrl_get 6217 6218 }; 6219 6220 #else 6221 int _qtce_not_empty; 6222 #endif /* INCLUDE_SERDES_QTCE */ 6223