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