phy84793.c (236911B)
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: phy84793.c 8 * Purpose: Phys Driver support for Broadcom 84793 100Gig 9 * gearbox. 10 * Note: 11 */ 12 13 #if defined(INCLUDE_PHY_84793) 14 #include <sal/types.h> 15 #include <soc/drv.h> 16 #include <soc/debug.h> 17 #include <soc/error.h> 18 #include <soc/phyreg.h> 19 #include <shared/bsl.h> 20 #include <soc/phy.h> 21 #include <soc/phy/phyctrl.h> 22 #include <soc/phy/drv.h> 23 24 #include "phydefs.h" /* Must include before other phy related includes */ 25 26 #include "phyconfig.h" /* Must be the first phy include after phydefs.h */ 27 #include "phyident.h" 28 #include "phyreg.h" 29 #include "phynull.h" 30 #include "phyxehg.h" 31 #include "phy84793.h" 32 33 #define MSGOUT_BIT_POS (1<< 5) 34 #define PHY84793_ID_84793 0x84793 35 #define PHY84793_ID_84790 0x84790 36 #define PHY84793_ID_84794 0x84794 37 #define PHY84793_DC_HC_RD_WIT_OUT_CLEAR 0 38 #define PHY84793_DC_HC_RD_WIT_CLEAR 1 39 #define PHY84793_FW_DLOAD_OFFSET 0 40 #define PHY84793_FW_DLOAD_RETRY_CNT 5 41 #define PHY84793_CDR_LOCK 1 42 #define PHY84793_CDR_UNLOCK 0 43 #define PHY84793_DC_LANE0 0 44 #define PHY84793_DC_LANE9 9 45 #define PHY84793_HC_LANE0 0 46 #define PHY84793_HC_LANE5 5 47 #define PHY84793_VSR40_LANE0 0 48 #define PHY84793_VSR40_LANE3 3 49 #define PHY84793_LN_MAX_NO_LANE 10 50 #define PHY84793_IF_CAUI 0x2A 51 #define PHY84793_IF_XLAUI 0x22 52 #define PHY84793_IF_SR10 0x29 53 #define PHY84793_IF_SR 0x7 54 #define PHY84793_IF_OTL 0x4 55 #define PHY84793_POL_DND 0xFFFF 56 #define PHY84793_ENABLE_SET_DND 0xFFFF 57 #define PHY84793_SLICE_0 0 58 #define PHY84793_SLICE_1 0x1 59 #define VSR40_TX_ANA_LANE0_BASE 0x9940 60 #define VSR40_TX_ANA_LANE1_BASE 0x9950 61 #define VSR40_TX_ANA_LANE2_BASE 0x9960 62 #define VSR40_TX_ANA_LANE3_BASE 0x9970 63 #define PHY84793_MODE1_SPD 100000 64 #define PHY84793_MODE2_SPD 40000 65 #define PHY84793_MODE3_SPD 100000 66 #define PHY84793_MODE4_SPD 10000 67 #define PHY84793_MODE5_SPD 100000 68 #define PHY84793_ENABLE_ALL_LANES 0x3ff 69 #define PHY84793_DISABLE_ALL_LANES 0x0 70 #define POL_LANE_MASK(lane) (1 << (lane)) 71 #define PHY84793_16BIT_MSB 0xFFFF0000 72 #define PHY84793_16BIT_SHIFT 16 73 #define PHY84793_16BIT_LSB 0x0000FFFF 74 #define PHY84793_HC_RX_BIT 2 75 #define PHY84793_DC_ENABLE 1 76 #define PHY84793_HC_READ_ENABLE 0x12 77 #define PHY84793_HC_WRITE_ENABLE 0xA 78 #define PHY84793_HC_PCB_CLEAR 0x32 79 #define PHY84793_DC_PCB_CLEAR 0x31 80 #define PHY84793_DC_READ_ENABLE 0x11 81 #define PHY84793_DC_WRITE_ENABLE 0x9 82 #define VSR40_RX_ANA_LANE0_BASE 0x9480 83 #define VSR40_RX_ANA_LANE1_BASE 0x9580 84 #define VSR40_RX_ANA_LANE2_BASE 0x9680 85 #define VSR40_RX_ANA_LANE3_BASE 0x9780 86 #define PHY84793_PRBS_INV_BIT_MASK (1<<13) 87 #define PHY84793_PRBS_INV_BIT_POS 13 88 #define PHY84793_EYESCAN_MAX_LEFT_HOFFSET -32 89 #define PHY84793_EYESCAN_MAX_RIGHT_HOFFSET 31 90 #define PHY84793_EYESCAN_MIN_VOFFSET -31 91 #define PHY84793_EYESCAN_MAX_VOFFSET 31 92 #define PHY84793_DC_HC_BROADCAST 0x1FF 93 #define PHY84793_REF_CLK_156_25 0 94 #define PHY84793_REF_CLK_161_132 1 95 #define PHY84793_REF_CLK_174_7 2 96 #define PHY84793_REF_CLK_312_5 3 97 #define PHY84793_REF_CLK_322_265 4 98 #define PHY84793_REF_CLK_349_4 5 99 #define PHY84793_REF_CLK_625_0 6 100 #define PHY84793_REF_CLK_644_531 7 101 #define PHY84793_REF_CLK_698_8 8 102 #define VSR40_RX_ANA_LANE0_BASE 0x9480 103 #define VSR40_RX_ANA_IC_CTRL_REG 0xC 104 #define VSR40_RX_ANA_CTRL1_REG 0xA 105 #define HS_RX_CDR_LANE_BASE 0x9400 106 #define HS_RX_CDR_STAT_INTG_REG 0x15 107 #define HS_RX_CDR_STAT_NCO_RDP 0x16 108 109 /* macros for Eye monitor start */ 110 #define DECA_RT 1 111 #define HEXA_RX 2 112 #define VSR_RX 3 113 #define HEXA_TX 4 114 115 #define ENABLE_EYE_MON 2 116 #define RUN_EYE_MON 4 117 #define DISABLE_EYE_MON 6 118 119 #define BAD_EYE_MON_CORE 3 120 #define BAD_EYE_MON_CMD 5 121 #define BAD_EYE_MON_MODE 7 122 123 #define ALL_LANES_IN_CORE 0x1FF 124 125 /* macros for Eye monitor Ends */ 126 127 #define PHY_84793_HCTX_PCB_WRITE(UNIT, PC, ADDR, VALUE) \ 128 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC, \ 129 CTL_REGS_PCB_ADR_MSW_TYPE, (((ADDR) & PHY84793_16BIT_MSB)>>16)));\ 130 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC,\ 131 CTL_REGS_PCB_ADR_LSW_TYPE, ((ADDR) & PHY84793_16BIT_LSB)));\ 132 sal_usleep(50);\ 133 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC,\ 134 CTL_REGS_PCB_DATA_IN_TYPE, (VALUE)));\ 135 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC,\ 136 CTL_REGS_PCB_CTRL_TYPE, 0x4));\ 137 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC, \ 138 CTL_REGS_PCB_CTRL_TYPE, 0xC));\ 139 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC, \ 140 CTL_REGS_PCB_CTRL_TYPE, 0x0)); 141 142 #define PHY_84793_HCTX_PCB_READ(UNIT, PC, ADDR, VAL) \ 143 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC, \ 144 CTL_REGS_PCB_ADR_MSW_TYPE, (((ADDR) & PHY84793_16BIT_MSB)>>16)));\ 145 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC,\ 146 CTL_REGS_PCB_ADR_LSW_TYPE, ((ADDR) & PHY84793_16BIT_LSB)));\ 147 sal_usleep(50);\ 148 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC, \ 149 CTL_REGS_PCB_CTRL_TYPE, 0x4));\ 150 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC, \ 151 CTL_REGS_PCB_CTRL_TYPE, 0x14));\ 152 SOC_IF_ERROR_RETURN \ 153 (READ_PHY84793_PMA_PMD_REG(UNIT, PC, CTL_REGS_PCB_DATA_OUT_TYPE, VAL));\ 154 SOC_IF_ERROR_RETURN (WRITE_PHY84793_PMA_PMD_REG(UNIT, PC, \ 155 CTL_REGS_PCB_CTRL_TYPE, 0x0)); 156 157 158 #define GET_BIT_VAL(val, msb, lsb) ((val) & (((int32)power(2, \ 159 (msb +1))) - ((int32)power(2,lsb))))/((int32)power(2,lsb)) 160 161 #define SET_PHY84793_SLICE(_unit, _phy_ctrl, _slice) \ 162 WRITE_PHY84793_PMA_PMD_REG(_unit, _phy_ctrl, SLICE_REGS_SLICE , \ 163 _slice) 164 165 #define PHY84793_GET_PORT_MODE(_pc, MODE) \ 166 if ((((phy84793_dev_desc_t *)((_pc) + 1))->intf.type == SOC_PORT_IF_SR) && \ 167 (((phy84793_dev_desc_t *)((_pc) + 1))->intf.speed == PHY84793_MODE4_SPD))\ 168 MODE = PHY84793_MODE_10X10G_TO_10X10G_ASYNC;\ 169 else if ((((phy84793_dev_desc_t *)((_pc) + 1))->intf.type == SOC_PORT_IF_SR4) && \ 170 (((phy84793_dev_desc_t *)((_pc) + 1))->intf.speed == PHY84793_MODE1_SPD))\ 171 MODE = PHY84793_MODE_10X10G_TO_4X25G;\ 172 else if ((((phy84793_dev_desc_t *)((_pc) + 1))->intf.type == SOC_PORT_IF_SR4) && \ 173 (((phy84793_dev_desc_t *)((_pc) + 1))->intf.speed == PHY84793_MODE2_SPD))\ 174 MODE = PHY84793_MODE_4X10G_TO_4X10G;\ 175 else if ((((phy84793_dev_desc_t *)((_pc) + 1))->intf.type == SOC_PORT_IF_SR10) && \ 176 (((phy84793_dev_desc_t *)((_pc) + 1))->intf.speed == PHY84793_MODE3_SPD))\ 177 MODE = PHY84793_MODE_10X10G_TO_10X10G_SYNC;\ 178 else if ((((phy84793_dev_desc_t *)((_pc) + 1))->intf.type == SOC_PORT_IF_OTL) && \ 179 (((phy84793_dev_desc_t *)((_pc) + 1))->intf.speed == PHY84793_MODE5_SPD))\ 180 MODE = PHY84793_MODE_10X10G_TO_4X25G_OTL; 181 182 #define PHY84793_EYE_MON_PARAMS(core, command, lane_mask, PARAMS) \ 183 do { \ 184 PARAMS = core; \ 185 PARAMS = PARAMS << 3; \ 186 PARAMS = PARAMS | command; \ 187 PARAMS = PARAMS <<10; \ 188 PARAMS = PARAMS | lane_mask; \ 189 }while(0) 190 191 extern unsigned char phy84793_ucode_bin[]; 192 extern unsigned int phy84793_ucode_bin_len; 193 static const char *phy84793_intf_names[] = SOC_PORT_IF_NAMES_INITIALIZER; 194 195 soc_port_if_t phy_84793_sys_to_port_if[] = { 196 0, 197 SOC_PORT_IF_SR4, 198 SOC_PORT_IF_SR10, 199 SOC_PORT_IF_SR, 200 SOC_PORT_IF_OTL, 201 }; 202 203 typedef struct phy84793_polarity_cfg { 204 uint16 tx_pol_cfg; 205 uint16 rx_pol_cfg; 206 }phy84793_polarity_cfg; 207 208 typedef struct phy84793_intf_cfg_t { 209 int32 speed; 210 soc_port_if_t type; 211 } phy84793_intf_cfg_t ; 212 213 typedef struct { 214 uint32 devid; 215 phy84793_intf_cfg_t intf; 216 phy84793_polarity_cfg ln_pol_cfg; 217 phy84793_polarity_cfg sys_pol_cfg; 218 uint16 lb_stat; 219 char dev_name_84793[15]; 220 uint16 pol_tx_cfg; 221 uint16 pol_rx_cfg; 222 } phy84793_dev_desc_t; 223 224 #define DEVID(_pc) (((phy84793_dev_desc_t *)((_pc) + 1))->devid) 225 #define INTERFACE(_pc) (((phy84793_dev_desc_t *)((_pc) + 1))->intf) 226 #define SYS_POLARITY(_pc) (((phy84793_dev_desc_t *)((_pc) + 1))->sys_pol_cfg) 227 #define LN_POLARITY(_pc) (((phy84793_dev_desc_t *)((_pc) + 1))->ln_pol_cfg) 228 #define LOOPBACK(_pc) (((phy84793_dev_desc_t *)((_pc) + 1))->lb_stat) 229 #define DEV_NAME(_pc) (((phy84793_dev_desc_t *)((_pc) + 1))->dev_name_84793) 230 #define POL_TX_CFG(_pc) (((phy84793_dev_desc_t *)((_pc) + 1))->pol_tx_cfg) 231 #define POL_RX_CFG(_pc) (((phy84793_dev_desc_t *)((_pc) + 1))->pol_rx_cfg) 232 233 #define CHECK_LANE(_l) \ 234 if (_l > PHY84793_DC_LANE9)\ 235 return SOC_E_PARAM; 236 237 typedef enum PHY84793_CORES { 238 PHY84793_DECA_CORE = 0, 239 PHY84793_HEXA_CORE 240 }PHY84793_CORES; 241 242 typedef enum PHY84793_INTF_SIDE { 243 PHY84793_SYS_SIDE = 0, 244 PHY84793_LINE_SIDE 245 }PHY84793_INTF_SIDE; 246 247 typedef enum PHY84793_MODES { 248 PHY84793_MODE_10X10G_TO_4X25G = 0, /* 10X10G to 4X25G (1 Port)*/ 249 PHY84793_MODE_4X10G_TO_4X10G, /* 4X10G to 4X10G (2 port)*/ 250 PHY84793_MODE_10X10G_TO_10X10G_SYNC, /* 10X10G to 10X10G (1 port)*/ 251 PHY84793_MODE_10X10G_TO_10X10G_ASYNC, /* 10X10G to 10X10G (10 ports)*/ 252 PHY84793_MODE_10X10G_TO_4X25G_OTL 253 }PHY84793_MODES; 254 255 typedef enum PHY84793_PRBS_PATT { 256 PHY84793_PRBS_7, 257 PHY84793_PRBS_15, 258 PHY84793_PRBS_23, 259 PHY84793_PRBS_31, 260 PHY84793_PRBS_9, 261 PHY84793_PRBS_11, 262 PHY84793_PRBS_FIXED_PATT 263 }PHY84793_PRBS_PATT; 264 265 typedef enum PHY84793_PRBS_LOCK { 266 PHY84793_PRBS_LOCKED = 0, 267 PHY84793_PRBS_NOT_LOCKED, 268 PHY84793_PRBS_LL_SET, 269 PHY84793_PRBS_LL_NOT_SET 270 }PHY84793_PRBS_LOCK; 271 272 /* dsc values */ 273 struct phy84793_dsc_cb { 274 int32 tx_pre_cursor; 275 int32 tx_main; 276 int32 tx_post_cursor; 277 int32 postc_metric; 278 int32 pf_ctrl; 279 int32 vga_sum; 280 int32 dfe1_bin; 281 int32 dfe2_bin; 282 int32 dfe3_bin; 283 int32 dfe4_bin; 284 int32 dfe5_bin; 285 int32 integ_reg; 286 int32 integ_reg_xfer; 287 int32 clk90_offset; 288 int32 slicer_target; 289 int32 sig_det; 290 int32 offset_pe; 291 int32 offset_ze; 292 int32 offset_me; 293 int32 offset_po; 294 int32 offset_zo; 295 int32 offset_mo; 296 }; 297 298 /*Functions forward declarations*/ 299 STATIC int32 300 _phy_84793_prbs_gen_get(int32 unit, soc_port_t port, 301 int32 lane, uint16 *tx_gen, uint16 *rx_gen); 302 STATIC int32 303 _phy_84793_prbs_chkr_get(int32 unit, soc_port_t port, 304 int32 lane, uint16 *tx_chk, uint16 *rx_chk); 305 STATIC int32 306 _phy_84793_prbs_gen_enable(int32 unit, soc_port_t port, 307 int32 lane, uint16 en_tx, uint16 en_rx); 308 STATIC int32 309 _phy_84793_prbs_chkr_enable(int32 unit, soc_port_t port, 310 int32 lane, uint16 en_tx, uint16 en_rx); 311 STATIC int32 312 _phy_84793_control_prbs_tx_invert_data_set(int32 unit, 313 soc_port_t port, 314 PHY84793_INTF_SIDE intf_side, 315 int32 invert); 316 STATIC int32 317 _phy_84793_control_prbs_rx_invert_data_set(int32 unit, 318 soc_port_t port, 319 PHY84793_INTF_SIDE intf_side, 320 int32 invert); 321 STATIC int32 322 _phy_84793_per_lane_control_prbs_polynomial_set(int32 unit, 323 soc_port_t port, int32 lane, int32 poly_ctrl); 324 STATIC int32 325 _phy_84793_control_prbs_polynomial_set(int32 unit, 326 soc_port_t port,int32 poly_ctrl); 327 STATIC int32 328 _phy_84793_per_lane_control_prbs_enable_set(int32 unit, 329 soc_port_t port, int32 lane, int32 enable); 330 STATIC int32 331 _phy_84793_control_prbs_enable_set(int32 unit, soc_port_t port, 332 int32 enable); 333 STATIC int32 334 _phy_84793_per_lane_control_prbs_enable_get(int32 unit, 335 soc_port_t port, int32 lane, uint32 *value); 336 STATIC int32 337 _phy_84793_control_prbs_enable_get(int32 unit, soc_port_t port, 338 uint32 *value); 339 STATIC int32 340 _phy_84793_per_lane_control_prbs_polynomial_get(int32 unit, 341 soc_port_t port, int32 lane, uint32 *value); 342 STATIC int32 343 _phy_84793_control_prbs_polynomial_get(int32 unit, 344 soc_port_t port, uint32 *value); 345 STATIC int32 346 _phy_84793_control_prbs_tx_invert_data_get(int32 unit, soc_port_t port, 347 PHY84793_INTF_SIDE intf_side, 348 uint32 *value); 349 STATIC int32 350 _phy_84793_control_prbs_rx_status_get(int32 unit, 351 soc_port_t port, uint32 *value); 352 STATIC int32 353 _phy_84793_per_lane_control_prbs_rx_status_get(int32 unit, 354 soc_port_t port, int32 lane, 355 uint32 *value); 356 STATIC int32 357 phy_84793_diag_ctrl(int32 unit, soc_port_t port, uint32 inst, 358 int32 op_type, int32 op_cmd, void *arg); 359 STATIC int32 360 _phy_84793_dsc_diag(int32 unit, soc_port_t port, 361 int32 intf, int32 lane); 362 STATIC int32 phy_84793_control_set(int32 unit, soc_port_t port, 363 soc_phy_control_t type, uint32 value); 364 STATIC int32 phy_84793_control_get(int32 unit, soc_port_t port, 365 soc_phy_control_t type, uint32 *value); 366 STATIC int32 367 _phy_84793_speed_set(int32 unit, soc_port_t port, int32 speed); 368 STATIC int32 369 phy_84793_per_lane_control_set(int32 unit, soc_port_t port, int32 lane, 370 soc_phy_control_t type, uint32 value); 371 STATIC int32 372 phy_84793_per_lane_control_get(int32 unit, soc_port_t port, int32 lane, 373 soc_phy_control_t type, uint32 *value); 374 STATIC int32 375 _phy_84793_modify_pma_pmd_reg (int32 unit, int32 port, phy_ctrl_t *pc, 376 uint16 address, uint8 msb_pos, uint8 lsb_pos, uint16 data); 377 STATIC int32 378 _phy_84793_rom_firmware_download (int32 unit, int32 port, int32 offset, 379 phy_ctrl_t *pc, uint8 *new_fw, uint32 datalen); 380 STATIC int32 381 _phy_84793_control_tx_preemphsis_set (int32 unit, soc_port_t port, 382 soc_phy_control_t type, 383 PHY84793_INTF_SIDE intf_side, 384 uint32 value); 385 STATIC int32 386 _phy_84793_control_tx_driver_set (int32 unit, soc_port_t port, 387 soc_phy_control_t type, 388 PHY84793_INTF_SIDE intf_side, uint32 value); 389 STATIC int32 390 _phy_84793_per_lane_control_tx_preemphasis_set (int32 unit, soc_port_t port, 391 PHY84793_INTF_SIDE intf_side, 392 uint16 lane, uint32 value); 393 STATIC int32 394 phy_84793_lb_set (int32 unit, soc_port_t port, int32 enable); 395 396 STATIC int32 397 _phy_84793_per_lane_control_tx_driver_set (int32 unit, soc_port_t port, 398 soc_phy_control_t type, 399 PHY84793_INTF_SIDE intf_side, 400 uint16 lane, uint32 value); 401 STATIC int32 402 _phy_84793_per_lane_control_tx_driver_get (int32 unit, soc_port_t port, 403 soc_phy_control_t type, 404 PHY84793_INTF_SIDE intf_side, 405 uint16 lane, uint32 *value); 406 STATIC int32 407 _phy_84793_control_tx_driver_get (int32 unit, soc_port_t port, 408 soc_phy_control_t type, 409 PHY84793_INTF_SIDE intf_side, 410 uint32 *value); 411 STATIC int32 412 _phy_84793_control_tx_preemphsis_get (int32 unit, soc_port_t port, 413 PHY84793_INTF_SIDE intf_side, 414 uint32 *value); 415 STATIC int32 416 _phy_84793_per_lane_control_tx_preemphasis_get (int32 unit, soc_port_t port, 417 PHY84793_INTF_SIDE intf_side, 418 uint16 lane, uint32 *value); 419 STATIC int32 420 phy_84793_lb_get(int32 unit, soc_port_t port, int32 *enable); 421 422 STATIC int32 423 _phy_84793_per_lane_lb_get(int32 unit, soc_port_t port, uint16 lane, 424 uint32 *enable); 425 STATIC int32 426 phy_84793_per_lane_link_get(int32 unit, soc_port_t port, uint16 lane, 427 int32 *link); 428 STATIC 429 int32 _phy_84793_dc_hc_pcb_read (int32 unit, soc_port_t port, phy_ctrl_t *pc, 430 uint16 dc_hc, uint32 addr, uint16 clear_reg, uint16 *rddata); 431 STATIC 432 int32 _phy_84793_system_polarity_flip (int32 unit, soc_port_t port, 433 phy_ctrl_t *pc, uint16 cfg_tx_pol, uint16 cfg_rx_pol); 434 STATIC 435 int32 _phy_84793_line_polarity_flip (int32 unit, soc_port_t port, 436 phy_ctrl_t *pc, 437 uint16 cfg_tx_pol, uint16 cfg_rx_pol); 438 STATIC int32 439 _phy_84793_remote_loopback_set(int32 unit, soc_port_t port, int32 enable); 440 441 STATIC int32 442 _phy_84793_squelch_enable(int32 unit, soc_port_t port, 443 PHY84793_INTF_SIDE intf_side, 444 uint8 enable); 445 STATIC int32 446 _phy_84793_per_lane_remote_lb_get(int32 unit, soc_port_t port, 447 uint16 lane, uint32 *enable); 448 STATIC int32 449 _phy_84793_sys_lane_squelch_enable (int32 unit, soc_port_t port, uint8 lane, 450 uint8 enable); 451 STATIC int32 452 _phy_84793_line_lane_squelch_enable (int32 unit, soc_port_t port, uint8 lane, 453 uint8 enable); 454 STATIC int32 455 phy_84793_interface_set(int32 unit, soc_port_t port, soc_port_if_t pif); 456 457 STATIC int32 458 phy_84793_speed_set(int32 unit, soc_port_t port, int32 speed); 459 460 STATIC int32 461 _phy_84793_div_change(int32 unit, soc_port_t port, uint16 setmode, 462 uint16 refclkin, uint16 mode); 463 464 STATIC int32 465 _phy_84793_rx_seq_done_get(int unit, soc_port_t port, int32 intf, uint32 *value); 466 467 STATIC int32 468 phy_84793_link_get(int32 unit, soc_port_t port, int32 *link); 469 470 STATIC 471 int32 _phy_84793_dc_hc_pcb_write (int32 unit, soc_port_t port, phy_ctrl_t *pc, 472 uint16 dc_hc, uint32 addr, uint16 value); 473 STATIC 474 int32 _phy_84793_pcb_wr_bits(int32 unit, soc_port_t port, phy_ctrl_t *pc, 475 uint16 core_sel, uint16 lane, uint16 addr, 476 uint16 msb, uint16 lsb, uint16 value); 477 STATIC int 478 _phy_84793_debug_info(int unit, soc_port_t port); 479 480 481 STATIC int 482 _phy_84793_per_lane_rx_seq_done_get(int unit, soc_port_t port, 483 int32 intf, 484 int lane, uint32 *value); 485 486 uint32 power(uint16 x, uint16 y) 487 { 488 uint32 temp; 489 if( y == 0) 490 return 1; 491 temp = power(x, y/2); 492 if (y%2 == 0) 493 return temp*temp; 494 else 495 return x*temp*temp; 496 } 497 498 /* 499 * Function: 500 * phy_84793_control_set 501 * Purpose: 502 * Configure PHY device specific control fucntion. 503 504 * Parameters: 505 * unit - StrataSwitch unit #. 506 * port - StrataSwitch port #. 507 * type - Control to update 508 * value - New setting for the control 509 * Returns: 510 * SOC_E_NONE 511 */ 512 STATIC int32 513 phy_84793_control_set(int32 unit, soc_port_t port, 514 soc_phy_control_t type, uint32 value) 515 { 516 517 phy_ctrl_t *pc; /* PHY software state */ 518 int rv = SOC_E_UNAVAIL; 519 520 pc = EXT_PHY_SW_STATE(unit, port); 521 522 PHY_CONTROL_TYPE_CHECK(type); 523 switch (type) { 524 case SOC_PHY_CONTROL_PREEMPHASIS: 525 /* fall through */ 526 rv = _phy_84793_control_tx_preemphsis_set (unit, port, type, 527 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 528 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 529 value); 530 break; 531 case SOC_PHY_CONTROL_DRIVER_CURRENT: 532 /* fall through */ 533 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 534 /* fall through */ 535 rv = _phy_84793_control_tx_driver_set (unit, port, type, 536 (pc->flags & PHYCTRL_SYS_SIDE_CTRL)? 537 PHY84793_SYS_SIDE:PHY84793_LINE_SIDE, 538 value); 539 break; 540 case SOC_PHY_CONTROL_EDC_MODE: 541 return SOC_E_UNAVAIL; 542 case SOC_PHY_CONTROL_CLOCK_ENABLE: 543 return SOC_E_UNAVAIL; 544 case SOC_PHY_CONTROL_CLOCK_FREQUENCY: 545 return SOC_E_UNAVAIL; 546 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 547 rv = _phy_84793_control_prbs_polynomial_set(unit, port, value); 548 break; 549 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 550 rv = _phy_84793_control_prbs_tx_invert_data_set(unit, port, 551 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : 552 PHY84793_LINE_SIDE, value); 553 if (SOC_SUCCESS(rv)) { 554 rv = _phy_84793_control_prbs_rx_invert_data_set(unit, port, 555 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : 556 PHY84793_LINE_SIDE, value); 557 } 558 break; 559 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 560 /* fall through */ 561 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 562 /* tx/rx is enabled at the same time. no seperate control */ 563 rv = _phy_84793_control_prbs_enable_set(unit, port, value); 564 break; 565 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: 566 rv = _phy_84793_remote_loopback_set(unit, port, value); 567 break; 568 case SOC_PHY_CONTROL_PORT_PRIMARY: 569 rv = soc_phyctrl_primary_set(unit, port, (soc_port_t)value); 570 break; 571 case SOC_PHY_CONTROL_PORT_OFFSET: 572 rv = soc_phyctrl_offset_set(unit, port, (int)value); 573 break; 574 case SOC_PHY_CONTROL_SOFTWARE_RX_LOS: 575 return SOC_E_UNAVAIL; 576 case SOC_PHY_CONTROL_DUMP: 577 rv = _phy_84793_debug_info(unit, port); 578 break; 579 case SOC_PHY_CONTROL_RX_POLARITY: 580 if ((pc->flags & PHYCTRL_SYS_SIDE_CTRL)) { 581 rv = _phy_84793_system_polarity_flip (unit, port, 582 pc, PHY84793_POL_DND, (uint16)value); 583 } else { 584 rv = _phy_84793_line_polarity_flip (unit, port, 585 pc, PHY84793_POL_DND, (uint16)value); 586 } 587 break; 588 case SOC_PHY_CONTROL_TX_POLARITY: 589 if ((pc->flags & PHYCTRL_SYS_SIDE_CTRL)) { 590 rv = _phy_84793_system_polarity_flip (unit, port, 591 pc, (uint16)value, PHY84793_POL_DND); 592 } else { 593 rv = _phy_84793_line_polarity_flip (unit, port, 594 pc, (uint16)value, PHY84793_POL_DND); 595 } 596 break; 597 case SOC_PHY_CONTROL_TX_LANE_SQUELCH: 598 rv = _phy_84793_squelch_enable(unit, port, 599 (pc->flags & PHYCTRL_SYS_SIDE_CTRL)? 600 PHY84793_SYS_SIDE:PHY84793_LINE_SIDE, 601 (uint8)value); 602 break; 603 case SOC_PHY_CONTROL_LOOPBACK_INTERNAL: 604 rv = phy_84793_lb_set(unit, port, value); 605 break; 606 default: 607 rv = SOC_E_UNAVAIL; 608 break; 609 610 } 611 return rv; 612 } 613 614 STATIC int 615 _phy_84793_debug_info(int unit, soc_port_t port) 616 { 617 phy_ctrl_t *pc; 618 phy_ctrl_t *int_pc; 619 phy84793_intf_cfg_t *intf; 620 PHY84793_INTF_SIDE side; 621 soc_port_if_t iif; 622 int att =0, ispeed = 0, ilink = 0; 623 uint16 link_sts[PHY84793_LN_MAX_NO_LANE]; 624 uint16 tx_pol_sts[PHY84793_LN_MAX_NO_LANE]; 625 uint16 rx_pol_sts[PHY84793_LN_MAX_NO_LANE]; 626 uint16 drv_cur[PHY84793_LN_MAX_NO_LANE]; 627 uint16 preemph_main[PHY84793_LN_MAX_NO_LANE]; 628 uint16 preemph_post1[PHY84793_LN_MAX_NO_LANE]; 629 uint16 preemph_post2[PHY84793_LN_MAX_NO_LANE]; 630 uint16 data0, data1, data2, data3, data4, lane_idx; 631 uint16 mode = PHY84793_MODE_10X10G_TO_10X10G_ASYNC; 632 uint32 temp = 0, reg_addr = 0; 633 uint16 start_lane = 0; 634 uint16 end_lane = PHY84793_LN_MAX_NO_LANE; 635 uint16 *lane_val = NULL; 636 637 pc = EXT_PHY_SW_STATE(unit, port); 638 int_pc = INT_PHY_SW_STATE(unit, port); 639 640 intf = &(INTERFACE(pc)); 641 PHY84793_GET_PORT_MODE(pc, mode); 642 /* firware rev: 1.F417 */ 643 SOC_IF_ERROR_RETURN 644 (READ_PHY84793_PMA_PMD_REG(unit, pc, 645 CTL_REGS_GPREG0, &data0)); 646 /* Mode select 1.F403 */ 647 SOC_IF_ERROR_RETURN 648 (READ_PHY84793_PMA_PMD_REG(unit, pc, 649 CTL_REGS_USER_MODESEL_REG, &data1)); 650 /* REF clk in 1.F404 */ 651 SOC_IF_ERROR_RETURN 652 (READ_PHY84793_PMA_PMD_REG(unit, pc, 653 CTL_REGS_REFCLK_SEL_REG, &data2)); 654 LOG_CLI((BSL_META_U(unit, 655 "Port %-2d: micro ver(1.%04x)=%04x,Mode Sel(1.%04x)=%04x\n" 656 " Ref Clk(1.%04x)=%04x, mdio=0x%x Mode:%04x \n" 657 " speed: %d interface type: %s\n"), 658 port, CTL_REGS_GPREG0, data0, 659 CTL_REGS_USER_MODESEL_REG, data1, 660 CTL_REGS_REFCLK_SEL_REG, data2, 661 pc->phy_id, mode, intf->speed, phy84793_intf_names[intf->type])); 662 663 /* Interfaces: software, hardware, internal serdes */ 664 for (side = PHY84793_SYS_SIDE; side <= PHY84793_LINE_SIDE; side++) { 665 /* control: 1.0000 */ 666 SOC_IF_ERROR_RETURN(READ_PHY84793_PMA_PMD_REG(unit, pc, 667 IEEE_PMA_PMD_REGS_PMA_PMD_CONTROL_1, &data0)); 668 if (side == PHY84793_SYS_SIDE) { 669 /* Loopback 1.F457 */ 670 SOC_IF_ERROR_RETURN 671 (READ_PHY84793_PMA_PMD_REG(unit, pc, 672 CTL_REGS_SYS_LOOPBACK_EN, &data1)); 673 /*DC Tx disable 1.F449 */ 674 SOC_IF_ERROR_RETURN 675 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_DCTX_PD, &data2)); 676 data2 &= 0x3ff; 677 678 /*DC Rx disable 1.F447 */ 679 SOC_IF_ERROR_RETURN 680 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_DCRX_PD, &data3)); 681 data3 &= 0x3ff; 682 } else { 683 /* Loopback 1.F458 */ 684 SOC_IF_ERROR_RETURN 685 (READ_PHY84793_PMA_PMD_REG(unit, pc, 686 CTL_REGS_LINE_LOOPBACK_EN, &data1)); 687 688 /*VSR Tx disable 1.F44f HC TX 1.F44D */ 689 SOC_IF_ERROR_RETURN 690 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_VSR40_TX_PD, 691 &data2)); 692 data2 &= 0xf; 693 SOC_IF_ERROR_RETURN 694 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_HCTX_PD, &data4)); 695 data2 |= ((data4 & 0x3f) << 4); 696 697 /*VSR Rx disable 1.F451 HC TX 1.F44b */ 698 SOC_IF_ERROR_RETURN 699 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_VSR40_RX_PD, 700 &data3)); 701 data3 &= 0xf; 702 SOC_IF_ERROR_RETURN 703 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_HCRX_PD, &data4)); 704 data3 |= ((data4 & 0x3f) << 4); 705 } 706 /* Single PORT Mode */ 707 if (mode == PHY84793_MODE_10X10G_TO_4X25G || mode == PHY84793_MODE_10X10G_TO_10X10G_SYNC 708 || mode == PHY84793_MODE_10X10G_TO_4X25G_OTL || mode == PHY84793_MODE_4X10G_TO_4X10G) { 709 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 710 start_lane = (pc->lane_num) ? 5 : 0; 711 end_lane = start_lane + 4; 712 } 713 if (side == PHY84793_SYS_SIDE) { 714 for (lane_idx = start_lane; lane_idx < end_lane; lane_idx++) { 715 /* DC.80b0 :: Link sts*/ 716 SOC_IF_ERROR_RETURN 717 (_phy_84793_dc_hc_pcb_read (unit, port, pc, 718 PHY84793_DECA_CORE, (lane_idx << 16)|0x80b1, 0, &data4)); 719 data4 &= (~0x7); 720 SOC_IF_ERROR_RETURN 721 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 722 PHY84793_DECA_CORE, 723 (lane_idx << 16), data4)); 724 SOC_IF_ERROR_RETURN 725 (_phy_84793_dc_hc_pcb_read (unit, port, pc, 726 PHY84793_DECA_CORE, (lane_idx << 16)|0x80b0, 0, &(link_sts[lane_idx]))); 727 728 /* 1. F516 TX polarity*/ 729 SOC_IF_ERROR_RETURN 730 (READ_PHY84793_PMA_PMD_REG (unit, pc, 731 RG_RX_RX_GB_IO_BIT_CTRL, &tx_pol_sts[lane_idx])); 732 733 /* DC.0x80BA RX polarity*/ 734 SOC_IF_ERROR_RETURN 735 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 736 (lane_idx << 16) | 0x80BA, 0, &rx_pol_sts[lane_idx])); 737 SOC_IF_ERROR_RETURN 738 (_phy_84793_per_lane_control_tx_preemphasis_get (unit, port, 739 side, lane_idx, &temp)); 740 preemph_main[lane_idx] = (temp & 0x3f00); 741 preemph_post1[lane_idx] = (temp & 0x01f); 742 preemph_post2[lane_idx] = (temp & 0xe0); 743 744 reg_addr = 0x8065 | (lane_idx << 16); 745 SOC_IF_ERROR_RETURN 746 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 747 reg_addr, 0, &drv_cur[lane_idx])); 748 } 749 } else { 750 for (lane_idx = start_lane; lane_idx < end_lane; lane_idx++) { 751 if (lane_idx <= PHY84793_VSR40_LANE3) { 752 /* 1.9811 : RX pol*/ 753 SOC_IF_ERROR_RETURN 754 (READ_PHY84793_PMA_PMD_REG(unit, pc, 755 VSR40_RX_DIG_REGS_DP_CTRL, &rx_pol_sts[lane_idx])); 756 757 /* 1.9800 : link status*/ 758 SOC_IF_ERROR_RETURN 759 (READ_PHY84793_PMA_PMD_REG(unit, pc, 760 VSR40_RX_DIG_REGS_CDR_CONTROL, &(link_sts[lane_idx]))); 761 SOC_IF_ERROR_RETURN 762 (READ_PHY84793_PMA_PMD_REG(unit, pc, 763 (VSR40_TX_ANA_LANE0_BASE | (lane_idx << 4)), &drv_cur[lane_idx])); 764 765 } else { 766 /* HC.80ba :: rx_pol_sts*/ 767 reg_addr = ((lane_idx-4) << 16) | 0x80BA; 768 SOC_IF_ERROR_RETURN 769 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 770 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rx_pol_sts[lane_idx])); 771 772 /* HC.80b0 :: Link sts*/ 773 SOC_IF_ERROR_RETURN 774 (_phy_84793_dc_hc_pcb_read (unit, port, pc, 775 PHY84793_HEXA_CORE, ((lane_idx-4) << 16)|0x80b1, 0, &data4)); 776 data4 &= (~0x7); 777 SOC_IF_ERROR_RETURN 778 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 779 PHY84793_HEXA_CORE, 780 ((lane_idx-4) << 16), data4)); 781 SOC_IF_ERROR_RETURN 782 (_phy_84793_dc_hc_pcb_read (unit, port, pc, 783 PHY84793_HEXA_CORE, ((lane_idx-4) << 16)|0x80b0, 0, &(link_sts[lane_idx]))); 784 785 reg_addr = 0x8065 | ((lane_idx - 4) << 16); 786 PHY_84793_HCTX_PCB_READ(unit, pc, reg_addr, &drv_cur[lane_idx]); 787 } 788 SOC_IF_ERROR_RETURN 789 (READ_PHY84793_PMA_PMD_REG(unit, pc, 790 RG_TX_TX_GB_IO_BIT_CONTROL, &tx_pol_sts[lane_idx])); 791 SOC_IF_ERROR_RETURN 792 (_phy_84793_per_lane_control_tx_preemphasis_get (unit, port, 793 side, lane_idx, &temp)); 794 preemph_main[lane_idx] = (temp & 0x3f00); 795 preemph_post1[lane_idx] = (temp & 0x01f); 796 preemph_post2[lane_idx] = (temp & 0xe0); 797 if ((mode == PHY84793_MODE_10X10G_TO_4X25G || 798 mode == PHY84793_MODE_10X10G_TO_4X25G_OTL) && 799 lane_idx > PHY84793_VSR40_LANE3) { 800 link_sts[lane_idx] = 0; 801 rx_pol_sts[lane_idx] = 0; 802 tx_pol_sts[lane_idx] = 0; 803 preemph_main[lane_idx] = 0; 804 preemph_post1[lane_idx] = 0; 805 preemph_post2[lane_idx] = 0; 806 drv_cur[lane_idx] = 0; 807 } 808 } 809 } 810 } else { 811 if (side == PHY84793_SYS_SIDE) { 812 /* DC.80b0 :: Link sts*/ 813 SOC_IF_ERROR_RETURN 814 (_phy_84793_dc_hc_pcb_read (unit, port, pc, 815 PHY84793_DECA_CORE, (pc->lane_num << 16)|0x80b1, 0, &data4)); 816 data4 &= (~0x7); 817 SOC_IF_ERROR_RETURN 818 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 819 PHY84793_DECA_CORE, (pc->lane_num << 16), data4)); 820 SOC_IF_ERROR_RETURN 821 (_phy_84793_dc_hc_pcb_read (unit, port, pc, 822 PHY84793_DECA_CORE, (pc->lane_num << 16)|0x80b0, 0, 823 &(link_sts[pc->lane_num]))); 824 825 /* 1. F516 TX polarity*/ 826 SOC_IF_ERROR_RETURN 827 (READ_PHY84793_PMA_PMD_REG (unit, pc, 828 RG_RX_RX_GB_IO_BIT_CTRL, &tx_pol_sts[pc->lane_num])); 829 830 /* DC.0x80BA RX polarity*/ 831 SOC_IF_ERROR_RETURN 832 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 833 (pc->lane_num << 16) | 0x80BA, 0, &rx_pol_sts[pc->lane_num])); 834 SOC_IF_ERROR_RETURN 835 (_phy_84793_per_lane_control_tx_preemphasis_get (unit, port, 836 side, pc->lane_num, &temp)); 837 preemph_main[pc->lane_num] = (temp & 0x3f00); 838 preemph_post1[pc->lane_num] = (temp & 0x01f); 839 preemph_post2[pc->lane_num] = (temp & 0xe0); 840 841 reg_addr = 0x8065 | (pc->lane_num << 16); 842 SOC_IF_ERROR_RETURN 843 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 844 reg_addr, 0, &drv_cur[pc->lane_num])); 845 } else { 846 if (pc->lane_num <= PHY84793_VSR40_LANE3) { 847 /* 1.9811 : RX pol*/ 848 SOC_IF_ERROR_RETURN 849 (READ_PHY84793_PMA_PMD_REG(unit, pc, 850 VSR40_RX_DIG_REGS_DP_CTRL, &rx_pol_sts[pc->lane_num])); 851 852 /* 1.9800 : link status*/ 853 SOC_IF_ERROR_RETURN 854 (READ_PHY84793_PMA_PMD_REG(unit, pc, 855 VSR40_RX_DIG_REGS_CDR_CONTROL, &(link_sts[pc->lane_num]))); 856 857 SOC_IF_ERROR_RETURN 858 (READ_PHY84793_PMA_PMD_REG(unit, pc, 859 (VSR40_TX_ANA_LANE0_BASE | (pc->lane_num << 4)), &drv_cur[pc->lane_num])); 860 } else { 861 /* HC.80ba :: rx_pol_sts*/ 862 reg_addr = ((pc->lane_num-4) << 16) | 0x80BA; 863 SOC_IF_ERROR_RETURN 864 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 865 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rx_pol_sts[pc->lane_num])); 866 867 /* HC.80b0 :: Link sts*/ 868 SOC_IF_ERROR_RETURN 869 (_phy_84793_dc_hc_pcb_read (unit, port, pc, 870 PHY84793_HEXA_CORE, ((pc->lane_num-4) << 16)|0x80b1, 0, &data4)); 871 data4 &= (~0x7); 872 SOC_IF_ERROR_RETURN 873 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 874 PHY84793_HEXA_CORE, 875 ((pc->lane_num-4) << 16), data4)); 876 SOC_IF_ERROR_RETURN 877 (_phy_84793_dc_hc_pcb_read (unit, port, pc, 878 PHY84793_HEXA_CORE, ((pc->lane_num-4)<< 16)|0x80b0, 0, 879 &(link_sts[pc->lane_num]))); 880 881 reg_addr = 0x8065 | ((pc->lane_num - 4) << 16); 882 PHY_84793_HCTX_PCB_READ(unit, pc, reg_addr, &drv_cur[pc->lane_num]); 883 } 884 SOC_IF_ERROR_RETURN 885 (READ_PHY84793_PMA_PMD_REG(unit, pc, 886 RG_TX_TX_GB_IO_BIT_CONTROL, &tx_pol_sts[pc->lane_num])); 887 SOC_IF_ERROR_RETURN 888 (_phy_84793_per_lane_control_tx_preemphasis_get (unit, port, 889 side, pc->lane_num, &temp)); 890 preemph_main[pc->lane_num] = (temp & 0x3f00); 891 preemph_post1[pc->lane_num] = (temp & 0x01f); 892 preemph_post2[pc->lane_num] = (temp & 0xe0); 893 } 894 } 895 start_lane = 0; 896 end_lane = PHY84793_LN_MAX_NO_LANE; 897 if (mode == PHY84793_MODE_10X10G_TO_4X25G || mode == PHY84793_MODE_10X10G_TO_10X10G_SYNC 898 || mode == PHY84793_MODE_10X10G_TO_4X25G_OTL || mode == PHY84793_MODE_4X10G_TO_4X10G) { 899 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 900 start_lane = (pc->lane_num) ? 5 : 0; 901 end_lane = start_lane + 4; 902 } 903 LOG_CLI((BSL_META_U(unit, 904 " %s: pmdctrl(1.%04x)=%04x, lb(1.%04x)=%04x\n"), 905 (side == PHY84793_LINE_SIDE) ? "Line " : "System ", 906 IEEE_PMA_PMD_REGS_PMA_PMD_CONTROL_1, data0, 907 (side == PHY84793_LINE_SIDE) ? CTL_REGS_LINE_LOOPBACK_EN : CTL_REGS_SYS_LOOPBACK_EN, data1)); 908 if (side == PHY84793_SYS_SIDE) { 909 LOG_CLI((BSL_META_U(unit, 910 " txdis(1.%04x)=%04x rxDis(1.%04x) = %04x\n"), 911 CTL_REGS_DCTX_PD, data2, CTL_REGS_DCRX_PD, data3)); 912 } else { 913 LOG_CLI((BSL_META_U(unit, 914 " txdis(1.%04x(HC)/1.%04x(VSR))=%04x rxDis(1.%04x(HC)/1.%04x(VSR)) = %04x\n"), 915 CTL_REGS_HCTX_PD, CTL_REGS_VSR40_TX_PD, data2, 916 CTL_REGS_HCRX_PD, CTL_REGS_VSR40_RX_PD, data3)); 917 } 918 for (att = 0; att < 7; att++) { 919 if (att == 0) { 920 if (side == PHY84793_SYS_SIDE) { 921 LOG_CLI((BSL_META_U(unit, 922 " linksts(DC:80b0) : "))); 923 } else { 924 LOG_CLI((BSL_META_U(unit, 925 " linksts(VSR:9800 HC: 80b0) : "))); 926 } 927 lane_val = link_sts; 928 } else if(att == 1) { 929 if (side == PHY84793_SYS_SIDE) { 930 LOG_CLI((BSL_META_U(unit, 931 " tx_pol(1.f516) : "))); 932 } else { 933 LOG_CLI((BSL_META_U(unit, 934 " tx_pol(1.f633) : "))); 935 } 936 lane_val = tx_pol_sts; 937 } else if(att == 2) { 938 if (side == PHY84793_SYS_SIDE) { 939 LOG_CLI((BSL_META_U(unit, 940 " rx_pol(DC:80BA) : "))); 941 } else { 942 LOG_CLI((BSL_META_U(unit, 943 " rx_pol(HC:80BA/9811) : "))); 944 } 945 lane_val = rx_pol_sts; 946 } else if(att == 3) { 947 LOG_CLI((BSL_META_U(unit, 948 " pre_main : "))); 949 lane_val = preemph_main; 950 } else if(att == 4) { 951 LOG_CLI((BSL_META_U(unit, 952 " pre_post1 : "))); 953 lane_val = preemph_post1; 954 } else if(att == 5) { 955 LOG_CLI((BSL_META_U(unit, 956 " pre_post2 : "))); 957 lane_val = preemph_post2; 958 } else if(att == 6) { 959 if (side == PHY84793_SYS_SIDE) { 960 LOG_CLI((BSL_META_U(unit, 961 " drv_cur(DC:8065) : "))); 962 } else { 963 LOG_CLI((BSL_META_U(unit, 964 " drv_cur(HC:8065/%04x) : "), 965 VSR40_TX_ANA_LANE0_BASE)); 966 } 967 lane_val = drv_cur; 968 } 969 970 for (lane_idx = start_lane; lane_idx < end_lane; lane_idx++) { 971 if ((lane_idx % 4 == 0) && (lane_idx != 0) && 972 (mode != PHY84793_MODE_4X10G_TO_4X10G)) { 973 LOG_CLI((BSL_META_U(unit, "\n"))); 974 LOG_CLI((BSL_META_U(unit, 975 " "))); 976 } 977 if ((mode == PHY84793_MODE_10X10G_TO_4X25G || 978 mode == PHY84793_MODE_10X10G_TO_4X25G_OTL) && 979 lane_idx > PHY84793_VSR40_LANE3 && 980 side == PHY84793_LINE_SIDE) { 981 LOG_CLI((BSL_META_U(unit, 982 "(ln%d=-NA-)"),lane_idx)); 983 } else { 984 LOG_CLI((BSL_META_U(unit, 985 "(ln%d=%04x)"),lane_idx, lane_val[lane_idx])); 986 } 987 } 988 LOG_CLI((BSL_META_U(unit, "\n"))); 989 } 990 } else { 991 LOG_CLI((BSL_META_U(unit, 992 "Lane:%d: %s: pmdctrl(1.%04x)=%04x, lb(1.%04x)=%04x\n"), 993 pc->lane_num, (side == PHY84793_LINE_SIDE) ? "Line " : "System ", 994 IEEE_PMA_PMD_REGS_PMA_PMD_CONTROL_1, data0, 995 (side == PHY84793_LINE_SIDE) ? CTL_REGS_LINE_LOOPBACK_EN : CTL_REGS_SYS_LOOPBACK_EN, data1)); 996 if (side == PHY84793_SYS_SIDE) { 997 LOG_CLI((BSL_META_U(unit, 998 " txdis(1.%04x)=%04x rxDis(1.%04x) = %04x\n"), 999 CTL_REGS_DCTX_PD, data2, CTL_REGS_DCRX_PD, data3)); 1000 LOG_CLI((BSL_META_U(unit, 1001 " link(0x80b0)=%04x, txpol(1.0xf516)=%04x, rxpol(0x80BA)=%04x"), 1002 link_sts[pc->lane_num],tx_pol_sts[pc->lane_num] ,rx_pol_sts[pc->lane_num])); 1003 1004 } else { 1005 LOG_CLI((BSL_META_U(unit, 1006 " txdis(1.%04x(HC)/1.%04x(VSR))=%04x rxDis(1.%04x(HC)/1.%04x(VSR)) = %04x\n"), 1007 CTL_REGS_HCTX_PD, CTL_REGS_VSR40_TX_PD, data2, 1008 CTL_REGS_HCRX_PD, CTL_REGS_VSR40_RX_PD, data3)); 1009 LOG_CLI((BSL_META_U(unit, 1010 " link(1.0x80b0(HC)/1.0x9800(VSR))=%04x, txpol(1.0xF633)=%04x, rxpol(1.0x80ba(HC)/1.0x9811(VSR))=%04x"), 1011 link_sts[pc->lane_num],tx_pol_sts[pc->lane_num] ,rx_pol_sts[pc->lane_num])); 1012 } 1013 LOG_CLI((BSL_META_U(unit, 1014 "\n" 1015 " prem_main=%04x, prem_post1=%04x prem_post2=%04x drv_cur=%04x\n"), 1016 preemph_main[pc->lane_num], preemph_post1[pc->lane_num], 1017 preemph_post2[pc->lane_num], drv_cur[pc->lane_num])); 1018 } 1019 } 1020 if (int_pc) { 1021 SOC_IF_ERROR_RETURN(PHY_INTERFACE_GET(int_pc->pd, unit, port, &iif)); 1022 SOC_IF_ERROR_RETURN(PHY_LINK_GET(int_pc->pd, unit, port, &ilink)); 1023 SOC_IF_ERROR_RETURN(PHY_SPEED_GET(int_pc->pd, unit, port, &ispeed)); 1024 LOG_CLI((BSL_META_U(unit, 1025 " Internal: type=%s, speed=%d, link=%d \n===\n"), 1026 phy84793_intf_names[iif], ispeed, ilink)); 1027 } 1028 return SOC_E_NONE; 1029 } 1030 1031 1032 STATIC int 1033 phy_84793_control_get(int unit, soc_port_t port, 1034 soc_phy_control_t type, uint32 *value) 1035 { 1036 int32 rv = 0; 1037 phy_ctrl_t *pc; /* PHY software state */ 1038 soc_port_t offset = 0; 1039 soc_port_t primary; 1040 1041 1042 pc = EXT_PHY_SW_STATE(unit, port); 1043 1044 PHY_CONTROL_TYPE_CHECK(type); 1045 switch (type) { 1046 case SOC_PHY_CONTROL_PREEMPHASIS: 1047 /* fall through */ 1048 rv = _phy_84793_control_tx_preemphsis_get (unit, port, 1049 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 1050 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 1051 value); 1052 break; 1053 case SOC_PHY_CONTROL_DRIVER_CURRENT: 1054 /* fall through */ 1055 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 1056 /* fall through */ 1057 rv = _phy_84793_control_tx_driver_get(unit, port, type, 1058 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 1059 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 1060 value); 1061 break; 1062 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 1063 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 1064 rv = _phy_84793_control_prbs_enable_get(unit, port, value); 1065 break; 1066 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 1067 rv = _phy_84793_control_prbs_polynomial_get(unit, port, value); 1068 break; 1069 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 1070 rv = _phy_84793_control_prbs_tx_invert_data_get(unit, port, 1071 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 1072 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 1073 value); 1074 break; 1075 case SOC_PHY_CONTROL_PRBS_RX_STATUS: 1076 rv = _phy_84793_control_prbs_rx_status_get(unit, port, value); 1077 break; 1078 case SOC_PHY_CONTROL_PORT_PRIMARY: 1079 SOC_IF_ERROR_RETURN 1080 (soc_phyctrl_primary_get(unit, port, &primary)); 1081 *value = (uint32) primary; 1082 rv = SOC_E_NONE; 1083 break; 1084 case SOC_PHY_CONTROL_PORT_OFFSET: 1085 SOC_IF_ERROR_RETURN 1086 (soc_phyctrl_offset_get(unit, port, &offset)); 1087 *value = (uint32) offset; 1088 rv = SOC_E_NONE; 1089 break; 1090 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: 1091 rv = _phy_84793_per_lane_remote_lb_get(unit, port, pc->lane_num, 1092 value); 1093 break; 1094 case SOC_PHY_CONTROL_LOOPBACK_INTERNAL: 1095 rv = phy_84793_lb_get(unit, port, (int32*)value); 1096 break; 1097 case SOC_PHY_CONTROL_RX_SEQ_DONE: 1098 rv = _phy_84793_rx_seq_done_get(unit, port, 1099 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 1100 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 1101 value); 1102 break; 1103 1104 default: 1105 rv = SOC_E_UNAVAIL; 1106 break; 1107 } 1108 return rv; 1109 } 1110 /* 1111 * Function: 1112 * phy_84793_per_lane_control_set 1113 * Purpose: 1114 * Configure PHY device specific control fucntion. 1115 * Parameters: 1116 * unit - StrataSwitch unit #. 1117 * port - StrataSwitch port #. 1118 * lane - lane number 1119 * type - Control to update 1120 * value - New setting for the control 1121 * Returns: 1122 * SOC_E_NONE 1123 */ 1124 STATIC int 1125 phy_84793_per_lane_control_set(int unit, soc_port_t port , int lane, 1126 soc_phy_control_t type, uint32 value) 1127 { 1128 int32 rv = SOC_E_UNAVAIL; 1129 phy_ctrl_t *pc; /* PHY software state */ 1130 1131 CHECK_LANE (lane); 1132 pc = EXT_PHY_SW_STATE(unit, port); 1133 1134 PHY_CONTROL_TYPE_CHECK(type); 1135 1136 switch(type) { 1137 case SOC_PHY_CONTROL_PREEMPHASIS: 1138 /* fall through */ 1139 rv = _phy_84793_per_lane_control_tx_preemphasis_set (unit, port, 1140 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : 1141 PHY84793_LINE_SIDE, lane, value); 1142 break; 1143 case SOC_PHY_CONTROL_DRIVER_CURRENT: /* fall through */ 1144 /* fall through */ 1145 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 1146 /* fall through */ 1147 rv = _phy_84793_per_lane_control_tx_driver_set (unit, port, 1148 type, (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : 1149 PHY84793_LINE_SIDE, lane, value); 1150 break; 1151 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 1152 rv = _phy_84793_per_lane_control_prbs_polynomial_set(unit, port, 1153 lane, value); 1154 break; 1155 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 1156 rv = _phy_84793_control_prbs_tx_invert_data_set(unit, port, 1157 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : 1158 PHY84793_LINE_SIDE, value); 1159 if (SOC_SUCCESS(rv)) { 1160 rv = _phy_84793_control_prbs_rx_invert_data_set(unit, port, 1161 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : 1162 PHY84793_LINE_SIDE, value); 1163 } 1164 break; 1165 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 1166 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 1167 rv = _phy_84793_per_lane_control_prbs_enable_set(unit, port, 1168 lane, value); 1169 break; 1170 case SOC_PHY_CONTROL_RX_POLARITY: 1171 if ((pc->flags & PHYCTRL_SYS_SIDE_CTRL)) { 1172 rv = _phy_84793_system_polarity_flip (unit, port, 1173 pc, PHY84793_POL_DND, (uint16)value); 1174 } else { 1175 rv = _phy_84793_line_polarity_flip (unit, port, 1176 pc, PHY84793_POL_DND, (uint16)value); 1177 } 1178 break; 1179 case SOC_PHY_CONTROL_TX_POLARITY: 1180 if ((pc->flags & PHYCTRL_SYS_SIDE_CTRL)) { 1181 rv = _phy_84793_system_polarity_flip (unit, port, 1182 pc, (uint16)value, PHY84793_POL_DND); 1183 } else { 1184 rv = _phy_84793_line_polarity_flip (unit, port, 1185 pc, (uint16)value, PHY84793_POL_DND); 1186 } 1187 break; 1188 case SOC_PHY_CONTROL_TX_LANE_SQUELCH: 1189 if (pc->flags & PHYCTRL_SYS_SIDE_CTRL) { 1190 rv = _phy_84793_sys_lane_squelch_enable (unit, port, lane, value); 1191 } else { 1192 rv = _phy_84793_line_lane_squelch_enable (unit, port, lane, value); 1193 } 1194 break; 1195 case SOC_PHY_CONTROL_LOOPBACK_INTERNAL: 1196 rv = phy_84793_lb_set(unit, port, value); 1197 break; 1198 default: 1199 rv = SOC_E_UNAVAIL; 1200 break; 1201 } 1202 return rv; 1203 } 1204 1205 /* 1206 * Function: 1207 * phy_84793_per_lane_control_get 1208 * Purpose: 1209 * Configure PHY device specific control fucntion. 1210 * Parameters: 1211 * unit - StrataSwitch unit #. 1212 * port - StrataSwitch port #. 1213 * lane - lane number 1214 * type - Control to update 1215 * value - New setting for the control 1216 * Returns: 1217 * SOC_E_NONE 1218 */ 1219 STATIC int 1220 phy_84793_per_lane_control_get(int unit, soc_port_t port , int lane, 1221 soc_phy_control_t type, uint32 *value) 1222 { 1223 int32 rv = 0; 1224 phy_ctrl_t *pc; /* PHY software state */ 1225 soc_port_t offset = 0; 1226 soc_port_t primary; 1227 1228 CHECK_LANE (lane); 1229 pc = EXT_PHY_SW_STATE(unit, port); 1230 1231 PHY_CONTROL_TYPE_CHECK(type); 1232 1233 rv = SOC_E_UNAVAIL; 1234 switch(type) { 1235 case SOC_PHY_CONTROL_PREEMPHASIS: 1236 rv = _phy_84793_per_lane_control_tx_preemphasis_get (unit, port, 1237 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 1238 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 1239 lane, value); 1240 break; 1241 case SOC_PHY_CONTROL_DRIVER_CURRENT: 1242 /* fall through */ 1243 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 1244 rv = _phy_84793_per_lane_control_tx_driver_get(unit, port, type, 1245 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 1246 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 1247 lane, value); 1248 break; 1249 case SOC_PHY_CONTROL_EDC_MODE: 1250 return SOC_E_UNAVAIL; 1251 case SOC_PHY_CONTROL_CLOCK_ENABLE: 1252 return SOC_E_UNAVAIL; 1253 case SOC_PHY_CONTROL_PRBS_POLYNOMIAL: 1254 rv = _phy_84793_per_lane_control_prbs_polynomial_get(unit, port, 1255 lane, value); 1256 break; 1257 case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA: 1258 rv = _phy_84793_control_prbs_tx_invert_data_get(unit, port, 1259 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 1260 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 1261 value); 1262 break; 1263 case SOC_PHY_CONTROL_PRBS_TX_ENABLE: 1264 /* fall through */ 1265 case SOC_PHY_CONTROL_PRBS_RX_ENABLE: 1266 rv = _phy_84793_per_lane_control_prbs_enable_get(unit, port, 1267 lane, value); 1268 break; 1269 case SOC_PHY_CONTROL_PRBS_RX_STATUS: 1270 rv = _phy_84793_per_lane_control_prbs_rx_status_get(unit, port, lane, 1271 value); 1272 break; 1273 case SOC_PHY_CONTROL_PORT_PRIMARY: 1274 SOC_IF_ERROR_RETURN 1275 (soc_phyctrl_primary_get(unit, port, &primary)); 1276 *value = (uint32) primary; 1277 rv = SOC_E_NONE; 1278 break; 1279 case SOC_PHY_CONTROL_PORT_OFFSET: 1280 SOC_IF_ERROR_RETURN 1281 (soc_phyctrl_offset_get(unit, port, &offset)); 1282 *value = (uint32) offset; 1283 rv = SOC_E_NONE; 1284 break; 1285 case SOC_PHY_CONTROL_LOOPBACK_REMOTE: 1286 rv = _phy_84793_per_lane_remote_lb_get(unit, port, lane, value); 1287 break; 1288 case SOC_PHY_CONTROL_LOOPBACK_INTERNAL: 1289 rv = _phy_84793_per_lane_lb_get(unit, port, lane, value); 1290 break; 1291 case SOC_PHY_CONTROL_SOFTWARE_RX_LOS: 1292 return SOC_E_UNAVAIL; 1293 case SOC_PHY_CONTROL_RX_SEQ_DONE: 1294 rv = _phy_84793_per_lane_rx_seq_done_get(unit, port, 1295 (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? 1296 PHY84793_SYS_SIDE : PHY84793_LINE_SIDE, 1297 lane, value); 1298 break; 1299 default: 1300 rv = SOC_E_UNAVAIL; 1301 break; 1302 } 1303 1304 return rv; 1305 } 1306 1307 /* 1308 * Function: 1309 * _phy_84793_dsc_diag 1310 * Purpose: 1311 * Diag function for DSC . 1312 * Parameters: 1313 * unit - StrataSwitch unit #. 1314 * port - StrataSwitch port #. 1315 * intf - line/system 1316 * lane - lane number 1317 * type - Control to update 1318 * Returns: 1319 * SOC_E_NONE 1320 */ 1321 STATIC int32 1322 _phy_84793_dsc_diag(int32 unit, soc_port_t port, int32 intf, int32 lane) 1323 { 1324 int32 i = 0; 1325 int32 lanes = 0; 1326 uint32 reg_addr = 0; 1327 uint16 reg_val = 0; 1328 phy_ctrl_t *pc; 1329 int32 side = 0; 1330 uint16 hc_dc = 0, prev_val=0; 1331 struct phy84793_dsc_cb *dsc_cbp; 1332 struct phy84793_dsc_cb dsc_cb[PHY84793_LN_MAX_NO_LANE]; 1333 1334 pc = EXT_PHY_SW_STATE(unit, port); 1335 side = (intf == PHY_DIAG_INTF_LINE) ? PHY84793_LINE_SIDE : 1336 PHY84793_SYS_SIDE; 1337 1338 if (side == PHY84793_LINE_SIDE) { 1339 lanes = PHY84793_HC_LANE5 + 1; 1340 hc_dc = PHY84793_HEXA_CORE; 1341 } else { 1342 lanes = PHY84793_LN_MAX_NO_LANE; 1343 hc_dc = PHY84793_DECA_CORE; 1344 } 1345 sal_memset((char *)&dsc_cb[0], 0, (sizeof(dsc_cb))); 1346 /* display */ 1347 LOG_CLI((BSL_META_U(unit, 1348 "\nDSC parameters for port %d\n"), port)); 1349 if (intf == PHY84793_LINE_SIDE) { 1350 LOG_CLI((BSL_META_U(unit, 1351 "\nVSR core \n"))); 1352 LOG_CLI((BSL_META_U(unit, 1353 "LaneN PPM clk90_ofs PF SL_TRGT LA " 1354 "PREC MAIN POSTC SIG_DET P1 Z1 P0 Z0\n"))); 1355 for (i = 0; i <= PHY84793_VSR40_LANE3; i++) { 1356 dsc_cbp = &(dsc_cb[i]); 1357 /* TX pre MAIN and post tap*/ 1358 SOC_IF_ERROR_RETURN 1359 (READ_PHY84793_PMA_PMD_REG(unit, pc, 1360 ((VSR40_TX_ANA_LANE0_BASE | (i << 4)) + VSR40_TX_ANA25G_CONTROL5), 1361 ®_val)); 1362 dsc_cb[i].tx_pre_cursor = (reg_val & 0x7100) >> 11; 1363 dsc_cb[i].tx_post_cursor = (reg_val & 0x7c0) >> 6; 1364 dsc_cb[i].tx_main = (reg_val & 0x3f); 1365 1366 /* Peeking filter control*/ 1367 SOC_IF_ERROR_RETURN 1368 (READ_PHY84793_PMA_PMD_REG(unit, pc, 1369 ((VSR40_RX_ANA_LANE0_BASE | (i << 8)) + VSR40_RX_ANA_IC_CTRL_REG), 1370 ®_val)); 1371 dsc_cb[i].pf_ctrl = (reg_val & 0xf); 1372 1373 /* Limiting Amplifier*/ 1374 SOC_IF_ERROR_RETURN 1375 (READ_PHY84793_PMA_PMD_REG(unit, pc, 1376 ((VSR40_RX_ANA_LANE0_BASE | (i << 8)) + VSR40_RX_ANA_CTRL1_REG), 1377 ®_val)); 1378 dsc_cb[i].vga_sum = (reg_val & 0x71) >> 3; 1379 1380 /* CDR Inter. status*/ 1381 SOC_IF_ERROR_RETURN 1382 (READ_PHY84793_PMA_PMD_REG(unit, pc, 1383 ((HS_RX_CDR_LANE_BASE | (i <<8)) + HS_RX_CDR_STAT_INTG_REG), 1384 ®_val)); 1385 dsc_cb[i].integ_reg = reg_val; 1386 1387 /* CLK90 offset*/ 1388 SOC_IF_ERROR_RETURN 1389 (READ_PHY84793_PMA_PMD_REG(unit, pc, 1390 ((HS_RX_CDR_LANE_BASE | (i <<8)) + HS_RX_CDR_STAT_NCO_RDP), 1391 ®_val)); 1392 dsc_cb[i].clk90_offset = (reg_val & 0x7f00) >> 8; 1393 1394 /* Slicer target*/ 1395 SOC_IF_ERROR_RETURN 1396 (READ_PHY84793_PMA_PMD_REG(unit, pc, 1397 (VSR40_RX_ANA_LANE0_BASE | (i << 8)), ®_val)); 1398 dsc_cb[i].slicer_target = ((reg_val & 0x1c) >> 2); 1399 SOC_IF_ERROR_RETURN 1400 (READ_PHY84793_PMA_PMD_REG(unit, pc, 1401 ((VSR40_RX_ANA_LANE0_BASE | (i << 8)) + 1), ®_val)); 1402 dsc_cb[i].offset_po = (reg_val & 0xF); 1403 dsc_cb[i].offset_pe = (reg_val & 0xF0)>>4; 1404 dsc_cb[i].offset_zo = (reg_val & 0xF00)>>8; 1405 dsc_cb[i].offset_ze = (reg_val & 0xF000)>>12; 1406 1407 SOC_IF_ERROR_RETURN 1408 (READ_PHY84793_PMA_PMD_REG(unit, pc, 1409 VSR40_RX_DIG_REGS_STATUS, ®_val)); 1410 dsc_cb[i].sig_det = (reg_val & 1411 (1 << (VSR40_RX_DIG_REGS_STATUS_ALOSB_SHIFT + i))) >> 1412 (VSR40_RX_DIG_REGS_STATUS_ALOSB_SHIFT + i); 1413 1414 LOG_CLI((BSL_META_U(unit, 1415 " %02d %05d %04d %04d " 1416 "%04d %04d %04d %04d %04d %04d" 1417 " %02d %02d %02d %02d \n"), 1418 i, dsc_cbp->integ_reg, dsc_cbp->clk90_offset, 1419 dsc_cbp->pf_ctrl, dsc_cbp->slicer_target, dsc_cbp->vga_sum, 1420 dsc_cbp->tx_pre_cursor, dsc_cbp->tx_main, 1421 dsc_cbp->tx_post_cursor,dsc_cbp->sig_det, dsc_cbp->offset_pe, 1422 dsc_cbp->offset_ze, dsc_cbp->offset_po, dsc_cbp->offset_zo)); 1423 1424 } 1425 } 1426 sal_memset((char *)&dsc_cb[0], 0, (sizeof(dsc_cb))); 1427 if (hc_dc == PHY84793_DECA_CORE) { 1428 LOG_CLI((BSL_META_U(unit, "DECA CORE\n"))); 1429 } else { 1430 LOG_CLI((BSL_META_U(unit, "HEXA CORE\n"))); 1431 } 1432 LOG_CLI((BSL_META_U(unit, 1433 "LaneN PPM_XFR clk90_ofs PF SL_TRGT VGA DFE1 DFE2 " 1434 "DFE3 DFE4 DFE5 POST1 MAIN POST2 SIGDET MTRC PE ZE ME PO ZO MO\n"))); 1435 for (i = 0; i < lanes; i++) { 1436 dsc_cbp = &(dsc_cb[i]); 1437 /* vga_sum , dfe1_bin */ 1438 reg_addr = (i << 16) | 0x8225; 1439 SOC_IF_ERROR_RETURN 1440 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1441 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1442 dsc_cbp->vga_sum = (reg_val &0x003f); 1443 dsc_cbp->dfe1_bin = ((reg_val >> 6) & 0x003f); 1444 1445 /* dfe2_bin, dfe3_bin */ 1446 reg_addr = (i << 16) | 0x8226; 1447 SOC_IF_ERROR_RETURN 1448 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1449 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1450 dsc_cbp->dfe2_bin = (reg_val & 0x003f); 1451 dsc_cbp->dfe3_bin = ((reg_val >> 6) & 0x003f); 1452 1453 1454 /* dfe4_bin, dfe5_bin */ 1455 reg_addr = (i << 16) | 0x8227; 1456 SOC_IF_ERROR_RETURN 1457 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1458 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1459 dsc_cbp->dfe4_bin = (reg_val & 0x001f); 1460 dsc_cbp->dfe5_bin = ((reg_val >> 5) & 0x001f); 1461 1462 /* integ_reg_xfer */ 1463 reg_addr = (i << 16) | 0x8220; 1464 SOC_IF_ERROR_RETURN 1465 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1466 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1467 dsc_cbp->integ_reg_xfer = reg_val & 0xffff; 1468 1469 /* postc_metric */ 1470 reg_addr = (i << 16) | 0x8220; 1471 SOC_IF_ERROR_RETURN 1472 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1473 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1474 dsc_cbp->postc_metric = (reg_val & 0x07ff); 1475 1476 /* pf_ctrl */ 1477 reg_addr = (i << 16) | 0x821c; 1478 SOC_IF_ERROR_RETURN 1479 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1480 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1481 dsc_cbp->pf_ctrl = (reg_val & 0x000f); 1482 1483 /* clk90_offset */ 1484 reg_addr = (i << 16) | 0x8223; 1485 SOC_IF_ERROR_RETURN 1486 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1487 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1488 dsc_cbp->clk90_offset = ((reg_val >> 7) & 0x007f); 1489 1490 /* offset_pe, offset_po */ 1491 reg_addr = (i << 16) | 0x822c; 1492 SOC_IF_ERROR_RETURN 1493 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1494 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1495 dsc_cbp->offset_pe = (reg_val & 0x003f); 1496 dsc_cbp->offset_po = ((reg_val >> 6) & 0x003f); 1497 1498 /* offset_ze, offset_zo */ 1499 reg_addr = (i << 16) | 0x822d; 1500 SOC_IF_ERROR_RETURN 1501 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1502 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1503 dsc_cbp->offset_ze = (reg_val & 0x003f); 1504 dsc_cbp->offset_zo = ((reg_val >> 6) & 0x003f); 1505 1506 /* offset_me, offset_zo */ 1507 reg_addr = (i << 16) | 0x822e; 1508 SOC_IF_ERROR_RETURN 1509 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1510 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1511 dsc_cbp->offset_me = (reg_val & 0x003f); 1512 dsc_cbp->offset_mo = ((reg_val >> 6) & 0x003f); 1513 1514 /* SIGGDET*/ 1515 reg_addr = (i << 16) | 0x80b1; 1516 SOC_IF_ERROR_RETURN 1517 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1518 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1519 prev_val = reg_val; 1520 reg_val &= ~0x7; 1521 reg_val |= 0x1; 1522 SOC_IF_ERROR_RETURN 1523 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 1524 hc_dc, reg_addr, reg_val)); 1525 reg_addr = (i << 16) | 0x80b0; 1526 SOC_IF_ERROR_RETURN( 1527 _phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1528 reg_addr, PHY84793_DC_HC_RD_WIT_CLEAR, ®_val)); 1529 dsc_cbp->sig_det = (reg_val & 0x20) >> 5; 1530 1531 reg_addr = (i << 16) | 0x80b1; 1532 SOC_IF_ERROR_RETURN 1533 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 1534 hc_dc, reg_addr, prev_val)); 1535 /* TX post, pre and main cursor*/ 1536 if (hc_dc == PHY84793_DECA_CORE) { 1537 reg_addr = (i << 16) | 0x8067; 1538 SOC_IF_ERROR_RETURN 1539 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 1540 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1541 dsc_cbp->tx_main = ((reg_val & 0x1F8) >> 3); 1542 dsc_cbp->tx_pre_cursor = (reg_val & 0x7)<<2; 1543 1544 reg_addr = (i << 16) | 0x8066; 1545 SOC_IF_ERROR_RETURN 1546 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1547 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, ®_val)); 1548 dsc_cbp->tx_post_cursor = (reg_val & 0x3800) >> 11; 1549 dsc_cbp->tx_pre_cursor |= (reg_val & 0xc000)>>14; 1550 } else { 1551 reg_addr = (i << 16) | 0x8067; 1552 PHY_84793_HCTX_PCB_READ (unit, pc, reg_addr, ®_val); 1553 dsc_cbp->tx_main = ((reg_val & 0x1F8) >> 3); 1554 dsc_cbp->tx_pre_cursor = (reg_val & 0x7)<<2; 1555 1556 reg_addr = (i << 16) | 0x8066; 1557 PHY_84793_HCTX_PCB_READ (unit, pc, reg_addr, ®_val); 1558 dsc_cbp->tx_post_cursor = (reg_val & 0x3800) >> 11; 1559 dsc_cbp->tx_pre_cursor |= (reg_val & 0xc000)>>14; 1560 } 1561 LOG_CLI((BSL_META_U(unit, 1562 " %02d %05d %04d %02d %02d " 1563 "%03d %04d %04d" 1564 " %04d %04d %04d %04d %04d %04d %04d %04d %02d %02d %02d %02d %02d %02d\n"), 1565 i,dsc_cbp->integ_reg_xfer,dsc_cbp->clk90_offset, 1566 dsc_cbp->pf_ctrl,dsc_cbp->slicer_target,dsc_cbp->vga_sum, 1567 dsc_cbp->dfe1_bin,dsc_cbp->dfe2_bin,dsc_cbp->dfe3_bin, 1568 dsc_cbp->dfe4_bin, 1569 dsc_cbp->dfe5_bin,dsc_cbp->tx_pre_cursor,dsc_cbp->tx_main, 1570 dsc_cbp->tx_post_cursor, dsc_cbp->sig_det, 1571 dsc_cbp->postc_metric,dsc_cbp->offset_pe,dsc_cbp->offset_ze, 1572 dsc_cbp->offset_me, 1573 dsc_cbp->offset_po,dsc_cbp->offset_zo,dsc_cbp->offset_mo)); 1574 } 1575 return SOC_E_NONE; 1576 } 1577 1578 /* 1579 * Function: 1580 * phy_84793_cmd_eye_monitor 1581 * Purpose: 1582 * To execute the command for eyemonitor 1583 * Parameters: 1584 * unit - StrataSwitch unit #. 1585 * port - StrataSwitch port #. 1586 * core - deca/hexa/VSR 1587 * command - enable/run/disable 1588 * lane_mask - lane nos for which eyemonitor 1589 * command to be executed 1590 * Returns: 1591 * SOC_E_NONE 1592 */ 1593 int32 phy_84793_cmd_eye_monitor(int32 unit, int32 port, uint8 core, uint8 command, 1594 uint16 lane_mask) 1595 { 1596 uint16 params; 1597 uint16 rddata = 0; 1598 uint16 count = 0; 1599 phy_ctrl_t *pc; 1600 pc = EXT_PHY_SW_STATE(unit, port); 1601 1602 PHY84793_EYE_MON_PARAMS(core, command, lane_mask, params); 1603 1604 /* Write the command and params to GPReg5 */ 1605 SOC_IF_ERROR_RETURN 1606 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG5, params)); 1607 1608 /* Read GPReg5 to check lane bits are cleared by Firmware */ 1609 SOC_IF_ERROR_RETURN 1610 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG5, &rddata)); 1611 1612 while ((rddata & 0x03ff) && count <100) { 1613 sal_usleep(1000); 1614 SOC_IF_ERROR_RETURN 1615 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG5, &rddata)); 1616 count ++; 1617 } 1618 1619 if (count > 100) { 1620 return SOC_E_INTERNAL; 1621 } 1622 1623 /* Read GPReg5 for command status */ 1624 SOC_IF_ERROR_RETURN 1625 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG5, &rddata)); 1626 1627 /* return 0 for success , return error for failure */ 1628 return ((rddata >> 10) & 0x7); 1629 } 1630 1631 /* 1632 * Function: 1633 * _phy_84793_diag_eyescan_livelink_en 1634 * Purpose: 1635 * To enable eyescan livelink 1636 * Parameters: 1637 * unit - StrataSwitch unit #. 1638 * port - StrataSwitch port #. 1639 * en - 1-enable, 0-disable 1640 * Returns: 1641 * SOC_E_NONE 1642 */ 1643 STATIC int32 1644 _phy_84793_diag_eyescan_livelink_en(int unit, soc_port_t port, int16 intf, 1645 int16 lane, int en) 1646 { 1647 uint16 lane_mask = 0; 1648 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 1649 uint8 core_id = 0; /*1.Deca 2.Hexa 3.VSR */ 1650 int32 rv = 0; 1651 uint16 mode = 0; 1652 1653 PHY84793_GET_PORT_MODE(pc, mode); 1654 if (intf == PHY84793_SYS_SIDE) { 1655 core_id = DECA_RT; 1656 } 1657 1658 if (mode == PHY84793_MODE_10X10G_TO_4X25G) { 1659 if (intf == PHY84793_LINE_SIDE) { 1660 if (lane<=3) { 1661 core_id = VSR_RX; 1662 } else { 1663 return SOC_E_PARAM; 1664 } 1665 } 1666 } else { 1667 if (intf == PHY84793_LINE_SIDE) { 1668 if (lane <= 3) { 1669 core_id = VSR_RX; 1670 } else { 1671 lane -= 4; 1672 core_id = HEXA_RX; 1673 } 1674 } 1675 } 1676 1677 lane_mask = 1<<lane; 1678 1679 if (en) { 1680 rv = phy_84793_cmd_eye_monitor(unit, port, core_id, ENABLE_EYE_MON, lane_mask); 1681 } else { 1682 rv = phy_84793_cmd_eye_monitor(unit, port, core_id, DISABLE_EYE_MON, lane_mask); 1683 } 1684 1685 return rv; 1686 } 1687 1688 /* 1689 * Function: 1690 * _phy_84793_diag_eyescan_livelink_clear 1691 * Purpose: 1692 * To clear the eyescan live link 1693 * Parameters: 1694 * unit - StrataSwitch unit #. 1695 * port - StrataSwitch port #. 1696 * unused - 1697 * Returns: 1698 * SOC_E_NONE 1699 */ 1700 STATIC int32 1701 _phy_84793_diag_eyescan_livelink_clear(int unit, soc_port_t port, int unused) 1702 { 1703 return SOC_E_NONE; 1704 } 1705 1706 /* 1707 * Function: 1708 * _phy_84793_diag_eyescan_livelink_start 1709 * Purpose: 1710 * To start the eyescan livelink 1711 * Parameters: 1712 * unit - StrataSwitch unit #. 1713 * port - StrataSwitch port #. 1714 * unused - 1715 * Returns: 1716 * SOC_E_NONE 1717 */ 1718 STATIC int32 1719 _phy_84793_diag_eyescan_livelink_start(int unit, soc_port_t port, int16 intf, 1720 int16 lane) 1721 { 1722 uint16 lane_mask = 0; 1723 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 1724 uint8 core_id = 0; 1725 int32 rv = 0; 1726 uint16 mode = 0; 1727 1728 PHY84793_GET_PORT_MODE(pc, mode); 1729 if (intf == PHY84793_SYS_SIDE) { 1730 core_id = DECA_RT; 1731 } 1732 if (mode == PHY84793_MODE_10X10G_TO_4X25G) { 1733 if (intf == PHY84793_LINE_SIDE) { 1734 if (lane<=3) { 1735 core_id = VSR_RX; 1736 } else { 1737 return SOC_E_PARAM; 1738 } 1739 } 1740 } else { 1741 if (intf == PHY84793_LINE_SIDE) { 1742 if (lane<=3) { 1743 core_id = VSR_RX; 1744 } else { 1745 lane -= 4; 1746 core_id = HEXA_RX; 1747 } 1748 } 1749 } 1750 lane_mask = 1 << lane; 1751 1752 rv = phy_84793_cmd_eye_monitor(unit, port, core_id, RUN_EYE_MON, lane_mask); 1753 1754 return rv; 1755 } 1756 1757 1758 /* 1759 * Function: 1760 * _phy_84793_diag_eyescan_livelink_stop 1761 * Purpose: 1762 * To stop eyescan live link 1763 * Parameters: 1764 * unit - StrataSwitch unit #. 1765 * port - StrataSwitch port #. 1766 * unused - 1767 * Returns: 1768 * SOC_E_NONE 1769 */ 1770 STATIC int32 1771 _phy_84793_diag_eyescan_livelink_stop(int unit, soc_port_t port, int unused) 1772 { 1773 return SOC_E_NONE; 1774 } 1775 1776 /* 1777 * Function: 1778 * _phy_84793_diag_eyescan_livelink_read 1779 * Purpose: 1780 * To read the result/error count 1781 * Parameters: 1782 * unit - StrataSwitch unit #. 1783 * port - StrataSwitch port #. 1784 * err_counter - error counter 1785 * Returns: 1786 * SOC_E_NONE 1787 */ 1788 STATIC int32 1789 _phy_84793_diag_eyescan_livelink_read(int unit, soc_port_t port, int16 intf, 1790 int16 lane, uint32 *err_counter) 1791 { 1792 uint16 rdaddr = 0; 1793 uint16 rddata = 0; 1794 uint16 rddata1 = 0; 1795 int32 core_id = 0; /* 0:VSR 1:Deca core 2: Hexacore */ 1796 uint32 reg_addr = 0; 1797 uint16 hc_dc = 0; 1798 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 1799 uint16 mode = 0; 1800 1801 PHY84793_GET_PORT_MODE(pc, mode); 1802 if (intf == PHY84793_SYS_SIDE) { 1803 core_id = DECA_RT; 1804 hc_dc = PHY84793_DECA_CORE; 1805 } 1806 1807 if (mode == PHY84793_MODE_10X10G_TO_4X25G) { 1808 if (intf == PHY84793_LINE_SIDE) { 1809 if (lane<=3) { 1810 core_id = VSR_RX; 1811 } else { 1812 return SOC_E_PARAM; 1813 } 1814 } 1815 } else { 1816 if (intf == PHY84793_LINE_SIDE) { 1817 if (lane <= 3) { 1818 core_id = VSR_RX; 1819 } else { 1820 lane -= 4; 1821 core_id = HEXA_RX; 1822 hc_dc = PHY84793_HEXA_CORE; 1823 } 1824 } 1825 } 1826 /* For Deca/Hexa core */ 1827 if ((core_id == DECA_RT) || (core_id == HEXA_RX)) { 1828 reg_addr = (lane<<16) | 0x8252; 1829 SOC_IF_ERROR_RETURN 1830 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1831 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 1832 1833 reg_addr = (lane<<16) | 0x8251; 1834 SOC_IF_ERROR_RETURN 1835 (_phy_84793_dc_hc_pcb_read (unit, port, pc, hc_dc, 1836 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata1)); 1837 1838 *err_counter = (rddata << 16) | rddata1; 1839 } else { 1840 rdaddr = 0x9418 | (lane << 8); 1841 SOC_IF_ERROR_RETURN 1842 (READ_PHY84793_PMA_PMD_REG(unit, pc, rdaddr, &rddata)); 1843 SOC_IF_ERROR_RETURN 1844 (READ_PHY84793_PMA_PMD_REG(unit, pc, rdaddr+1, &rddata1)); 1845 1846 *err_counter = (rddata << 16) + rddata1; 1847 } 1848 return SOC_E_NONE; 1849 } 1850 1851 /* 1852 * Function: 1853 * _phy_84793_diag_eyescan_init_voffset_get 1854 * Purpose: 1855 * To get the initial value of the voffset 1856 * Parameters: 1857 * unit - StrataSwitch unit #. 1858 * port - StrataSwitch port #. 1859 * voffset - vertical offset 1860 * Returns: 1861 * SOC_E_NONE 1862 */ 1863 STATIC int32 1864 _phy_84793_diag_eyescan_init_voffset_get(int unit, soc_port_t port, int *voffset) 1865 { 1866 return SOC_E_NONE; 1867 } 1868 1869 /* 1870 * Function: 1871 * _phy_84793_diag_eyescan_hoffset_set 1872 * Purpose: 1873 * To set the horizontal offset 1874 * Parameters: 1875 * unit - StrataSwitch unit #. 1876 * port - StrataSwitch port #. 1877 * hoffset - horizontal offset 1878 * Returns: 1879 * SOC_E_NONE 1880 */ 1881 STATIC int32 1882 _phy_84793_diag_eyescan_hoffset_set(int unit, soc_port_t port, int *hoffset) 1883 { 1884 uint16 hor_ver_offset = 0; 1885 uint16 rddata = 0; 1886 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 1887 1888 hor_ver_offset = (uint8)(*hoffset); 1889 hor_ver_offset <<= 8; 1890 1891 SOC_IF_ERROR_RETURN 1892 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG6, &rddata)); 1893 hor_ver_offset |= (rddata & 0x00FF); 1894 1895 SOC_IF_ERROR_RETURN 1896 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG6, hor_ver_offset)); 1897 1898 return SOC_E_NONE; 1899 } 1900 1901 /* 1902 * Function: 1903 * _phy_84793_diag_eyescan_voffset_set 1904 * Purpose: 1905 * To set the vertical offset 1906 * Parameters: 1907 * unit - StrataSwitch unit #. 1908 * port - StrataSwitch port #. 1909 * voffset - vertical offset 1910 * Returns: 1911 * SOC_E_NONE 1912 */ 1913 STATIC int32 1914 _phy_84793_diag_eyescan_voffset_set(int unit, soc_port_t port, int *voffset) 1915 { 1916 uint16 rddata = 0; 1917 uint16 hor_ver_offset = 0; 1918 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 1919 1920 SOC_IF_ERROR_RETURN 1921 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG6, &rddata)); 1922 hor_ver_offset = ((uint8)(*voffset)); 1923 hor_ver_offset |= (rddata & 0xFF00); 1924 1925 SOC_IF_ERROR_RETURN 1926 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG6, hor_ver_offset)); 1927 1928 return SOC_E_NONE; 1929 } 1930 1931 /* 1932 * Function: 1933 * _phy_84793_diag_eyescan_max_left_hoffset_get 1934 * Purpose: 1935 * To get the left horizontal offset 1936 * Parameters: 1937 * unit - StrataSwitch unit #. 1938 * port - StrataSwitch port #. 1939 * left_hoffset - left horizontal offset 1940 * Returns: 1941 * SOC_E_NONE 1942 */ 1943 STATIC int32 1944 _phy_84793_diag_eyescan_max_left_hoffset_get(int unit, soc_port_t port, 1945 int *left_hoffset) 1946 { 1947 *left_hoffset = PHY84793_EYESCAN_MAX_LEFT_HOFFSET; 1948 return SOC_E_NONE; 1949 } 1950 1951 /* 1952 * Function: 1953 * _phy_84793_diag_eyescan_max_right_hoffset_get 1954 * Purpose: 1955 * To get the max right horizontal offset 1956 * Parameters: 1957 * unit - StrataSwitch unit #. 1958 * port - StrataSwitch port #. 1959 * right_hoffset - right horizontal offset 1960 * Returns: 1961 * SOC_E_NONE 1962 */ 1963 STATIC int32 1964 _phy_84793_diag_eyescan_max_right_hoffset_get(int unit, soc_port_t port, 1965 int *right_hoffset) 1966 { 1967 *right_hoffset = PHY84793_EYESCAN_MAX_RIGHT_HOFFSET; 1968 return SOC_E_NONE; 1969 } 1970 1971 /* 1972 * Function: 1973 * _phy_84793_diag_eyescan_min_voffset_get 1974 * Purpose: 1975 * To get the minimum vertical offset 1976 * Parameters: 1977 * unit - StrataSwitch unit #. 1978 * port - StrataSwitch port #. 1979 * min_voffset - minimum vertical offset 1980 * Returns: 1981 * SOC_E_NONE 1982 */ 1983 STATIC int32 1984 _phy_84793_diag_eyescan_min_voffset_get(int unit, soc_port_t port, 1985 int *min_voffset) 1986 { 1987 *min_voffset = PHY84793_EYESCAN_MIN_VOFFSET; 1988 return SOC_E_NONE; 1989 } 1990 1991 /* 1992 * Function: 1993 * _phy_84793_diag_eyescan_max_voffset_get 1994 * Purpose: 1995 * To get the maximum vertical offset 1996 * Parameters: 1997 * unit - StrataSwitch unit #. 1998 * port - StrataSwitch port #. 1999 * max_voffset - maximum vertical offset 2000 * Returns: 2001 * SOC_E_NONE 2002 */ 2003 STATIC int32 2004 _phy_84793_diag_eyescan_max_voffset_get(int unit, soc_port_t port, 2005 int *max_voffset) 2006 { 2007 *max_voffset = PHY84793_EYESCAN_MAX_VOFFSET; 2008 return SOC_E_NONE; 2009 } 2010 2011 /* 2012 * Function: 2013 * _phy_84793_diag_eyescan 2014 * Purpose: 2015 * Parameters: 2016 * unit - StrataSwitch unit #. 2017 * port - StrataSwitch port #. 2018 * inst - instance 2019 * op_cmd - operational command 2020 * arg - arguments to the command 2021 * Returns: 2022 * SOC_E_NONE 2023 */ 2024 STATIC int32 2025 _phy_84793_diag_eyescan(int32 unit, soc_port_t port, uint32 inst, int32 op_cmd, 2026 void *arg) 2027 { 2028 int32 rv = SOC_E_NONE; 2029 int16 intf = 0; 2030 int16 lane = 0, mode = 0; 2031 phy_ctrl_t *pc; 2032 intf = PHY_DIAG_INST_INTF(inst); 2033 lane = PHY_DIAG_INST_LN(inst); 2034 intf = (intf == PHY_DIAG_INTF_LINE)?PHY84793_LINE_SIDE:PHY84793_SYS_SIDE; 2035 pc = EXT_PHY_SW_STATE(unit, port); 2036 PHY84793_GET_PORT_MODE(pc, mode); 2037 2038 if (mode == PHY84793_MODE_10X10G_TO_10X10G_ASYNC) { 2039 lane = pc->lane_num; 2040 } 2041 switch (op_cmd) { 2042 case PHY_DIAG_CTRL_EYE_ENABLE_LIVELINK: 2043 rv = _phy_84793_diag_eyescan_livelink_en(unit, port, intf , lane, 1); 2044 break; 2045 case PHY_DIAG_CTRL_EYE_START_LIVELINK: 2046 rv = _phy_84793_diag_eyescan_livelink_start(unit, port, intf, lane); 2047 break; 2048 case PHY_DIAG_CTRL_EYE_DISABLE_LIVELINK: 2049 rv = _phy_84793_diag_eyescan_livelink_en(unit, port, intf, lane, 0); 2050 break; 2051 case PHY_DIAG_CTRL_EYE_STOP_LIVELINK: 2052 rv = _phy_84793_diag_eyescan_livelink_stop(unit, port, 0); 2053 break; 2054 case PHY_DIAG_CTRL_EYE_CLEAR_LIVELINK: 2055 rv = _phy_84793_diag_eyescan_livelink_clear(unit, port, 0); 2056 break; 2057 case PHY_DIAG_CTRL_EYE_READ_LIVELINK: 2058 rv = _phy_84793_diag_eyescan_livelink_read(unit, port, intf, lane, (uint32 *) arg); 2059 break; 2060 case PHY_DIAG_CTRL_EYE_GET_INIT_VOFFSET: 2061 rv = _phy_84793_diag_eyescan_init_voffset_get(unit, port, (int *)arg); 2062 break; 2063 case PHY_DIAG_CTRL_EYE_SET_HOFFSET: 2064 rv = _phy_84793_diag_eyescan_hoffset_set(unit, port, (int*)arg); 2065 break; 2066 case PHY_DIAG_CTRL_EYE_SET_VOFFSET: 2067 rv = _phy_84793_diag_eyescan_voffset_set(unit, port, (int*)arg); 2068 break; 2069 case PHY_DIAG_CTRL_EYE_GET_MAX_LEFT_HOFFSET: 2070 rv = _phy_84793_diag_eyescan_max_left_hoffset_get(unit, port, (int *)arg); 2071 break; 2072 case PHY_DIAG_CTRL_EYE_GET_MAX_RIGHT_HOFFSET: 2073 rv = _phy_84793_diag_eyescan_max_right_hoffset_get(unit, port, (int *)arg); 2074 break; 2075 case PHY_DIAG_CTRL_EYE_GET_MIN_VOFFSET: 2076 rv = _phy_84793_diag_eyescan_min_voffset_get(unit, port, (int *)arg); 2077 break; 2078 case PHY_DIAG_CTRL_EYE_GET_MAX_VOFFSET: 2079 rv = _phy_84793_diag_eyescan_max_voffset_get(unit, port, (int *)arg); 2080 break; 2081 } 2082 return rv; 2083 } 2084 2085 /* 2086 * Function: 2087 * phy_84793_diag_ctrl 2088 * Purpose: 2089 * Diagnostics control function. 2090 * Parameters: 2091 * unit - StrataSwitch unit #. 2092 * port - StrataSwitch port #. 2093 * inst - 2094 * op_type - 2095 * op_cmd - 2096 * arg - 2097 * Returns: 2098 * SOC_E_NONE 2099 */ 2100 STATIC int32 2101 phy_84793_diag_ctrl(int32 unit, soc_port_t port, uint32 inst, int32 op_type, 2102 int32 op_cmd, void *arg) 2103 { 2104 int32 lane; 2105 int32 intf; 2106 int32 rv = SOC_E_NONE; 2107 phy_ctrl_t *pc; 2108 2109 pc = EXT_PHY_SW_STATE(unit, port); 2110 LOG_INFO(BSL_LS_SOC_PHY, 2111 (BSL_META_U(unit, 2112 "84793 diag_ctrl: u=%d p=%d ctrl=0x%x\n"), unit, 2113 port, op_cmd)); 2114 lane = PHY_DIAG_INST_LN(inst); 2115 intf = PHY_DIAG_INST_INTF(inst); 2116 2117 if (intf == PHY_DIAG_INTF_SYS) { 2118 pc->flags |= PHYCTRL_SYS_SIDE_CTRL; 2119 } 2120 2121 switch (op_cmd) { 2122 case PHY_DIAG_CTRL_DSC: 2123 SOC_IF_ERROR_RETURN(_phy_84793_dsc_diag(unit, port, intf, lane)); 2124 break; 2125 case PHY_DIAG_CTRL_EYE_ENABLE_LIVELINK: 2126 case PHY_DIAG_CTRL_EYE_DISABLE_LIVELINK: 2127 case PHY_DIAG_CTRL_EYE_CLEAR_LIVELINK: 2128 case PHY_DIAG_CTRL_EYE_START_LIVELINK: 2129 case PHY_DIAG_CTRL_EYE_STOP_LIVELINK: 2130 case PHY_DIAG_CTRL_EYE_READ_LIVELINK: 2131 case PHY_DIAG_CTRL_EYE_GET_INIT_VOFFSET: 2132 case PHY_DIAG_CTRL_EYE_SET_HOFFSET: 2133 case PHY_DIAG_CTRL_EYE_SET_VOFFSET: 2134 case PHY_DIAG_CTRL_EYE_GET_MAX_LEFT_HOFFSET: 2135 case PHY_DIAG_CTRL_EYE_GET_MAX_RIGHT_HOFFSET: 2136 case PHY_DIAG_CTRL_EYE_GET_MIN_VOFFSET: 2137 case PHY_DIAG_CTRL_EYE_GET_MAX_VOFFSET: 2138 rv = _phy_84793_diag_eyescan(unit, port, inst, op_cmd, arg); 2139 break; 2140 case PHY_DIAG_CTRL_EYE_MARGIN_VEYE: 2141 case PHY_DIAG_CTRL_EYE_MARGIN_HEYE_LEFT: 2142 case PHY_DIAG_CTRL_EYE_MARGIN_HEYE_RIGHT: 2143 rv = SOC_E_UNAVAIL; 2144 break; 2145 default: 2146 if (op_type == PHY_DIAG_CTRL_SET) { 2147 SOC_IF_ERROR_RETURN 2148 (phy_84793_control_set(unit, port, 2149 op_cmd, PTR_TO_INT(arg))); 2150 } else if (op_type == PHY_DIAG_CTRL_GET) { 2151 SOC_IF_ERROR_RETURN 2152 (phy_84793_control_get(unit, port, 2153 op_cmd, (uint32 *)arg)); 2154 } else { 2155 LOG_INFO(BSL_LS_SOC_PHY, \ 2156 (BSL_META_U(unit, \ 2157 "84793 diag_ctrl bad operation:\ 2158 u=%d p=%d ctrl=0x%x\n"), unit, port, op_cmd)); 2159 rv = SOC_E_UNAVAIL; 2160 } 2161 break; 2162 } 2163 return rv; 2164 2165 } 2166 /* 2167 * Function: 2168 * _phy_84793_prbs_gen_get 2169 * Purpose: 2170 * To check the status of IEEE PRBS generator whether or not enabled . 2171 * Parameters: 2172 * unit - StrataSwitch unit #. 2173 * port - StrataSwitch port #. 2174 * lane - lane number 2175 * tx_gen - tx gen enable/disable (0/1) 2176 * rx_gen - rx gen enable /disable (0/1) 2177 * Returns: 2178 * SOC_E_NONE 2179 */ 2180 STATIC int32 2181 _phy_84793_prbs_gen_get(int32 unit, soc_port_t port, int32 lane, 2182 uint16 *tx_gen, uint16 *rx_gen) 2183 { 2184 uint16 rddata = 0; 2185 uint16 mode = 0; 2186 int32 reg_addr = 0; 2187 phy_ctrl_t *pc; 2188 uint16 intf = 0; 2189 pc = EXT_PHY_SW_STATE(unit, port); 2190 2191 if ((!tx_gen) || (!rx_gen)) { 2192 return SOC_E_PARAM; 2193 } 2194 PHY84793_GET_PORT_MODE(pc, mode); 2195 if ((mode == PHY84793_MODE_4X10G_TO_4X10G) && (lane == 4 || lane == 9)) { 2196 return SOC_E_PARAM; 2197 } 2198 intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : PHY84793_LINE_SIDE; 2199 if (intf == PHY84793_SYS_SIDE) { 2200 reg_addr = (lane << 16) | 0x8069; 2201 SOC_IF_ERROR_RETURN 2202 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 2203 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2204 2205 if ((rddata & 0x0060) == 0x0060) { 2206 *rx_gen = 1; 2207 } else { 2208 *rx_gen = 0; 2209 } 2210 } else { 2211 if (lane <= PHY84793_VSR40_LANE3) { 2212 SOC_IF_ERROR_RETURN 2213 (READ_PHY84793_PMA_PMD_REG (unit, pc, RG_TX_TX_GB_PRBS_DB_CTRL, 2214 &rddata)); 2215 if (rddata & (1 << (lane + RG_TX_TX_GB_PRBS_DB_CTRL_PRBS_GEN_EN_SHIFT))) { 2216 *tx_gen = 1; 2217 } else { 2218 *tx_gen = 0; 2219 } 2220 } else { 2221 if ((mode == PHY84793_MODE_10X10G_TO_4X25G) || 2222 (mode == PHY84793_MODE_10X10G_TO_4X25G_OTL)) { 2223 return SOC_E_NONE; 2224 } 2225 2226 reg_addr = ((lane-4) << 16) | 0x8069; 2227 PHY_84793_HCTX_PCB_READ (unit, pc, reg_addr, &rddata); 2228 if ((rddata & 0x0060) == 0x0060) { 2229 *tx_gen = 1; 2230 } else { 2231 *tx_gen = 0; 2232 } 2233 } 2234 } 2235 2236 return SOC_E_NONE; 2237 } 2238 2239 /* 2240 * Function: 2241 * _phy_84793_prbs_chkr_get 2242 * Purpose: 2243 * To check the status of PRBS whether or not enabled 2244 * Parameters: 2245 * unit - StrataSwitch unit #. 2246 * port - StrataSwitch port #. 2247 * lane - lane number 2248 * tx_chk - tx checker enable/disable 2249 * rx_chk - rx checker enable/disable 2250 * Returns: 2251 * SOC_E_NONE 2252 */ 2253 STATIC int32 2254 _phy_84793_prbs_chkr_get(int32 unit, soc_port_t port, int32 lane, 2255 uint16 *tx_chk, uint16 *rx_chk) 2256 { 2257 uint16 rddata = 0; 2258 uint16 mode = 0; 2259 phy_ctrl_t *pc; 2260 int32 reg_addr = 0; 2261 uint16 intf = 0; 2262 2263 pc = EXT_PHY_SW_STATE(unit, port); 2264 PHY84793_GET_PORT_MODE(pc, mode); 2265 2266 if ((!tx_chk) || (!rx_chk)) { 2267 return SOC_E_PARAM; 2268 } 2269 PHY84793_GET_PORT_MODE(pc, mode); 2270 2271 intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : PHY84793_LINE_SIDE; 2272 if ((mode == PHY84793_MODE_4X10G_TO_4X10G) && (lane == 4 || lane == 9)) { 2273 return SOC_E_PARAM; 2274 } 2275 if (intf == PHY84793_SYS_SIDE) { 2276 reg_addr = (lane << 16) | 0x80b6; 2277 SOC_IF_ERROR_RETURN 2278 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 2279 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2280 2281 if ((rddata & 0x0060) == 0x0060) { 2282 *tx_chk = 1; 2283 } else { 2284 *tx_chk = 0; 2285 } 2286 } else { 2287 if (lane <= PHY84793_VSR40_LANE3) { 2288 SOC_IF_ERROR_RETURN 2289 (READ_PHY84793_PMA_PMD_REG (unit, pc, RG_RX_RX_GB_TEST_CTRL_LN03, 2290 &rddata)); 2291 if (rddata & (1 << lane)) { 2292 *rx_chk = 1; 2293 } else { 2294 *rx_chk = 0; 2295 } 2296 } else { 2297 if ((mode == PHY84793_MODE_10X10G_TO_4X25G) || 2298 (mode == PHY84793_MODE_10X10G_TO_4X25G_OTL)) { 2299 return SOC_E_NONE; 2300 } 2301 2302 reg_addr = ((lane-4) << 16) | 0x80b6; 2303 SOC_IF_ERROR_RETURN 2304 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 2305 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2306 2307 if ((rddata & 0x0060) == 0x0060) { 2308 *rx_chk = 1; 2309 } else { 2310 *rx_chk = 0; 2311 } 2312 } 2313 } 2314 return SOC_E_NONE; 2315 } 2316 2317 /* 2318 * Function: 2319 * _phy_84793_prbs_gen_enable 2320 * Purpose: 2321 * To enable PRBS generator enable . 2322 * Parameters: 2323 * unit - StrataSwitch unit #. 2324 * port - StrataSwitch port #. 2325 * lane - lane number 2326 * en_tx - enable/disable PRBS generator at tx side 2327 * en_rx - enable/disable PRBS generator at rx side 2328 * Returns: 2329 * SOC_E_NONE 2330 */ 2331 STATIC int32 2332 _phy_84793_prbs_gen_enable(int32 unit, soc_port_t port, int32 lane, 2333 uint16 en_tx, uint16 en_rx) 2334 { 2335 phy_ctrl_t *pc; 2336 uint16 mode = 0, rddata = 0; 2337 int32 reg_addr = 0; 2338 uint16 intf = 0; 2339 pc = EXT_PHY_SW_STATE(unit, port); 2340 2341 PHY84793_GET_PORT_MODE(pc, mode); 2342 intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : PHY84793_LINE_SIDE; 2343 if ((mode == PHY84793_MODE_4X10G_TO_4X10G) && (lane == 4 || lane == 9)) { 2344 return SOC_E_PARAM; 2345 } 2346 if (intf == PHY84793_SYS_SIDE) { 2347 reg_addr = (lane << 16) | 0x8069; 2348 SOC_IF_ERROR_RETURN 2349 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 2350 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2351 rddata &= (~0x60); 2352 rddata |= (en_rx ? (3 << 5):0); 2353 SOC_IF_ERROR_RETURN 2354 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 2355 reg_addr, rddata)); 2356 } else { 2357 if (lane <= PHY84793_VSR40_LANE3) { 2358 SOC_IF_ERROR_RETURN 2359 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, RG_TX_TX_GB_PRBS_DB_CTRL , 2360 RG_TX_TX_GB_PRBS_DB_CTRL_PRBS_GEN_EN_SHIFT + lane, 2361 RG_TX_TX_GB_PRBS_DB_CTRL_PRBS_GEN_EN_SHIFT + lane, 2362 en_tx)); 2363 } else { 2364 if (mode == PHY84793_MODE_10X10G_TO_4X25G || 2365 mode == PHY84793_MODE_10X10G_TO_4X25G_OTL) { 2366 return SOC_E_NONE; 2367 } 2368 reg_addr = ((lane-4) << 16) | 0x8069; 2369 PHY_84793_HCTX_PCB_READ (unit, pc, reg_addr, &rddata); 2370 rddata &= (~0x60); 2371 rddata |= (en_tx ? (3<< 5):0); 2372 PHY_84793_HCTX_PCB_WRITE (unit, pc, reg_addr, rddata); 2373 } 2374 } 2375 2376 return SOC_E_NONE; 2377 } 2378 2379 /* 2380 * Function: 2381 * _phy_84793_prbs_chkr_enable 2382 * Purpose: 2383 * To enable PRBS checker . 2384 * Parameters: 2385 * unit - StrataSwitch unit #. 2386 * port - StrataSwitch port #. 2387 * lane - lane number 2388 * en_tx - tx enable/disable 2389 * en_rx - rx enable/disable 2390 * Returns: 2391 * SOC_E_NONE 2392 */ 2393 STATIC int32 2394 _phy_84793_prbs_chkr_enable(int32 unit, soc_port_t port, int32 lane, 2395 uint16 en_tx, uint16 en_rx) 2396 { 2397 phy_ctrl_t *pc; 2398 uint16 mode = 0, rddata = 0; 2399 int32 reg_addr = 0; 2400 uint16 intf = 0; 2401 2402 pc = EXT_PHY_SW_STATE(unit, port); 2403 PHY84793_GET_PORT_MODE(pc, mode); 2404 intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : PHY84793_LINE_SIDE; 2405 2406 if ((mode == PHY84793_MODE_4X10G_TO_4X10G) && (lane == 4 || lane == 9)) { 2407 return SOC_E_PARAM; 2408 } 2409 if (intf == PHY84793_SYS_SIDE) { 2410 reg_addr = (lane << 16) | 0x80b6; 2411 SOC_IF_ERROR_RETURN 2412 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 2413 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2414 2415 rddata &= (~0x60); 2416 rddata |= (en_tx ? (3 << 5):0); 2417 SOC_IF_ERROR_RETURN 2418 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 2419 reg_addr, rddata)); 2420 } else { 2421 if (lane <= PHY84793_VSR40_LANE3) { 2422 SOC_IF_ERROR_RETURN 2423 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, RG_RX_RX_GB_TEST_CTRL_LN03, 2424 RG_RX_RX_GB_TEST_CTRL_LN03_PRBS_CHK_EN_SHIFT + lane, 2425 RG_RX_RX_GB_TEST_CTRL_LN03_PRBS_CHK_EN_SHIFT + lane, en_rx)); 2426 } else { 2427 if (mode == PHY84793_MODE_10X10G_TO_4X25G || 2428 mode == PHY84793_MODE_10X10G_TO_4X25G_OTL) { 2429 return SOC_E_NONE; 2430 } 2431 reg_addr = ((lane-4) << 16) | 0x80b6; 2432 SOC_IF_ERROR_RETURN 2433 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 2434 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2435 rddata &= (~0x60); 2436 rddata |= (en_rx ? (3 << 5):0); 2437 2438 SOC_IF_ERROR_RETURN 2439 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_HEXA_CORE, 2440 reg_addr,rddata)); 2441 } 2442 /* Setting bit to make LOS of lock work*/ 2443 /* JIRA PHY-1465*/ 2444 SOC_IF_ERROR_RETURN 2445 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_FW_ENABLE_TYPE, 2446 1, 0, en_rx)); 2447 2448 } 2449 2450 return SOC_E_NONE; 2451 } 2452 2453 /* 2454 * Function: 2455 * _phy_84793_control_prbs_tx_invert_data_set 2456 * Purpose: 2457 * To invert the PRBS data at tx side. 2458 * Parameters: 2459 * unit - StrataSwitch unit #. 2460 * port - StrataSwitch port #. 2461 * invert - invert data (0/1) 2462 * Returns: 2463 * SOC_E_NONE 2464 */ 2465 STATIC int32 2466 _phy_84793_control_prbs_tx_invert_data_set(int32 unit, soc_port_t port, 2467 PHY84793_INTF_SIDE intf_side, int32 invert) 2468 { 2469 phy_ctrl_t *pc; 2470 uint16 lane = 0, rddata = 0, mode = 0; 2471 uint32 reg_addr = 0; 2472 2473 pc = EXT_PHY_SW_STATE(unit, port); 2474 PHY84793_GET_PORT_MODE(pc, mode); 2475 if (intf_side == PHY84793_SYS_SIDE) { 2476 for (lane =0; lane <= PHY84793_DC_LANE9; lane ++) { 2477 /* For Systemside(DC) */ 2478 reg_addr = (lane << 16) | 0x80b6; 2479 SOC_IF_ERROR_RETURN 2480 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 2481 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2482 rddata &= (~0x10); 2483 rddata |= ((invert & (1<<lane)) ? (1<<4) :0); 2484 2485 SOC_IF_ERROR_RETURN 2486 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 2487 reg_addr, rddata)); 2488 } 2489 } else { 2490 for (lane =0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 2491 if (lane < PHY84793_VSR40_LANE3) { 2492 /* For VSR*/ 2493 SOC_IF_ERROR_RETURN 2494 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 2495 RG_TX_TX_GB_TEST_GEN_CTRL, 2496 RG_TX_TX_GB_TEST_GEN_CTRL_PRBS_INV_SHIFT + lane, 2497 RG_TX_TX_GB_TEST_GEN_CTRL_PRBS_INV_SHIFT + lane , 2498 (invert & (1<<lane)?1:0))); 2499 } else { 2500 if (mode == PHY84793_MODE_10X10G_TO_4X25G || 2501 mode == PHY84793_MODE_10X10G_TO_4X25G_OTL) { 2502 return SOC_E_NONE; 2503 } 2504 reg_addr = ((lane-4) << 16) | 0x8069; 2505 PHY_84793_HCTX_PCB_READ (unit, pc, reg_addr, &rddata); 2506 rddata &= (~0x10); 2507 rddata |= ((invert & (1<<lane)) ? (1<<4) :0); 2508 2509 PHY_84793_HCTX_PCB_WRITE (unit, pc, reg_addr, rddata); 2510 } 2511 } 2512 } 2513 return SOC_E_NONE; 2514 } 2515 2516 /* 2517 * Function: 2518 * _phy_84793_control_prbs_rx_invert_data_set 2519 * Purpose: 2520 * To invert the PRBS data at rx side 2521 * Parameters: 2522 * unit - StrataSwitch unit #. 2523 * port - StrataSwitch port #. 2524 * invert - invert data (0/1) 2525 * Returns: 2526 * SOC_E_NONE 2527 */ 2528 STATIC int32 2529 _phy_84793_control_prbs_rx_invert_data_set(int32 unit, soc_port_t port, 2530 PHY84793_INTF_SIDE intf_side, int32 invert) 2531 { 2532 phy_ctrl_t *pc; 2533 uint16 lane = 0, rddata = 0, mode =0; 2534 uint32 reg_addr = 0; 2535 pc = EXT_PHY_SW_STATE(unit, port); 2536 2537 PHY84793_GET_PORT_MODE(pc, mode); 2538 if (intf_side == PHY84793_SYS_SIDE) { 2539 for (lane =0; lane <= PHY84793_DC_LANE9; lane ++) { 2540 /* For Systemside(DC) */ 2541 reg_addr = (lane << 16) | 0x8069; 2542 SOC_IF_ERROR_RETURN 2543 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 2544 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2545 rddata &= (~0x10); 2546 rddata |= ((invert & (1<<lane)) ? (1<<4) :0); 2547 2548 SOC_IF_ERROR_RETURN 2549 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 2550 reg_addr, rddata)); 2551 } 2552 } else { 2553 for (lane =0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 2554 if (lane < PHY84793_VSR40_LANE3) { 2555 /* For VSR*/ 2556 SOC_IF_ERROR_RETURN 2557 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, RG_RX_RX_GB_PRBS_INV_IN, 2558 RG_RX_RX_GB_PRBS_INV_IN_PRBS_INV_IN_SHIFT + lane, 2559 RG_RX_RX_GB_PRBS_INV_IN_PRBS_INV_IN_SHIFT + lane, 2560 (invert & (1<<lane)?1:0))); 2561 } else { 2562 if (mode == PHY84793_MODE_10X10G_TO_4X25G || 2563 mode == PHY84793_MODE_10X10G_TO_4X25G_OTL) { 2564 return SOC_E_NONE; 2565 } 2566 reg_addr = ((lane-4) << 16) | 0x80b6; 2567 SOC_IF_ERROR_RETURN 2568 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 2569 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2570 rddata &= (~0x10); 2571 rddata |= ((invert & (1<<lane)) ? (1<<4) :0); 2572 2573 SOC_IF_ERROR_RETURN 2574 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_HEXA_CORE, 2575 reg_addr, rddata)); 2576 } 2577 } 2578 } 2579 return SOC_E_NONE; 2580 } 2581 2582 /* 2583 * Function: 2584 * _phy_84793_per_lane_control_prbs_polynomial_set 2585 * Purpose: 2586 * To set the polynomial per lane basis. 2587 * Parameters: 2588 * unit - StrataSwitch unit #. 2589 * port - StrataSwitch port #. 2590 * lane - lane number 2591 * poly_ctrl - polynomial type 2592 * currently PRBS31 ie poly_ctrl=3 is supported 2593 * There is no PRBS9 support available in SDK 2594 * Returns: 2595 * SOC_E_NONE 2596 */ 2597 STATIC int32 2598 _phy_84793_per_lane_control_prbs_polynomial_set(int32 unit, soc_port_t port, 2599 int32 lane, int32 poly_ctrl) 2600 { 2601 uint16 mode = 0; 2602 uint16 rddata = 0, reg_bit = 0, wrdata = 0; 2603 int32 reg_addr = 0; 2604 uint16 intf = 0; 2605 2606 phy_ctrl_t *pc; 2607 pc = EXT_PHY_SW_STATE(unit, port); 2608 2609 PHY84793_GET_PORT_MODE(pc, mode); 2610 intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : PHY84793_LINE_SIDE; 2611 2612 if ((mode == PHY84793_MODE_4X10G_TO_4X10G) && (lane == 4 || lane == 9)) { 2613 return SOC_E_PARAM; 2614 } 2615 switch (poly_ctrl) { 2616 case PHY84793_PRBS_7: 2617 reg_bit &= (~0x10c); 2618 break; 2619 case PHY84793_PRBS_15: 2620 reg_bit &= (~0x108); 2621 reg_bit |= 0x4; 2622 break; 2623 case PHY84793_PRBS_23: 2624 reg_bit &= (~0x104); 2625 reg_bit |= 0x8; 2626 break; 2627 case PHY84793_PRBS_31: 2628 reg_bit |= 0x000c; 2629 reg_bit &= (~0x100); 2630 break; 2631 case PHY84793_PRBS_9: 2632 reg_bit &= (~0x0c); 2633 reg_bit |= 0x100; 2634 break; 2635 case PHY84793_PRBS_11: 2636 reg_bit &= (~0x08); 2637 reg_bit |= 0x104; 2638 break; 2639 /* 2640 * COVERITY 2641 * This default is unreachable. It is kept intentionally as a defensive 2642 * default for future development. 2643 */ 2644 /* coverity[dead_error_begin] */ 2645 case PHY84793_PRBS_FIXED_PATT: 2646 return SOC_E_UNAVAIL; 2647 } 2648 if ( intf == PHY84793_SYS_SIDE) { 2649 /* System Side polynomial Set*/ 2650 /* Deca Core prbs generator */ 2651 reg_addr = (lane << 16) | 0x8069; 2652 SOC_IF_ERROR_RETURN 2653 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 2654 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2655 2656 rddata &= ~0x10c ; 2657 wrdata = rddata | reg_bit; 2658 2659 SOC_IF_ERROR_RETURN 2660 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 2661 reg_addr, wrdata)); 2662 2663 /* enable checker */ 2664 reg_addr = (lane << 16) | 0x80b6; 2665 SOC_IF_ERROR_RETURN 2666 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 2667 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2668 2669 rddata &= ~0x10c ; 2670 wrdata = rddata | reg_bit; 2671 2672 SOC_IF_ERROR_RETURN 2673 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 2674 reg_addr, wrdata)); 2675 } else { 2676 /* Line Side polynomial Set */ 2677 if (lane <= PHY84793_VSR40_LANE3) { /* VSR */ 2678 switch(poly_ctrl) { 2679 case PHY84793_PRBS_7: 2680 wrdata = 0x1; 2681 break; 2682 case PHY84793_PRBS_15: 2683 wrdata = 0x4; 2684 break; 2685 case PHY84793_PRBS_23: 2686 wrdata = 0x5; 2687 break; 2688 case PHY84793_PRBS_31: 2689 wrdata = 0x6; 2690 break; 2691 case PHY84793_PRBS_9: 2692 wrdata = 0x2; 2693 break; 2694 case PHY84793_PRBS_11: 2695 wrdata = 0x3; 2696 break; 2697 /* 2698 * COVERITY 2699 * This default is unreachable. It is kept intentionally as a defensive 2700 * default for future development. 2701 */ 2702 /* coverity[dead_error_begin] */ 2703 case PHY84793_PRBS_FIXED_PATT: 2704 return SOC_E_UNAVAIL; 2705 } 2706 SOC_IF_ERROR_RETURN 2707 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, RG_TX_TX_GB_TEST_GEN_CTRL, 2708 (lane* 3) +2 , (lane *3), wrdata)); 2709 2710 SOC_IF_ERROR_RETURN 2711 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, RG_RX_RX_GB_PRBS_INV_IN , 2712 (lane* 3) +2 , (lane *3), wrdata)); 2713 } else { 2714 if (mode == PHY84793_MODE_10X10G_TO_4X25G || 2715 mode == PHY84793_MODE_10X10G_TO_4X25G_OTL) { 2716 return SOC_E_NONE; 2717 } 2718 2719 /* Hexa Core prbs generator */ 2720 reg_addr = ((lane -4) << 16) | 0x8069; 2721 PHY_84793_HCTX_PCB_READ (unit, pc, reg_addr, &rddata); 2722 2723 rddata &= ~0x10c ; 2724 wrdata = rddata | reg_bit; 2725 2726 PHY_84793_HCTX_PCB_WRITE (unit, pc, reg_addr, wrdata); 2727 2728 /* enable checker */ 2729 reg_addr = ((lane - 4)<< 16) | 0x80b6; 2730 SOC_IF_ERROR_RETURN 2731 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 2732 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 2733 2734 rddata &= ~0x10c ; 2735 wrdata = rddata | reg_bit; 2736 2737 SOC_IF_ERROR_RETURN 2738 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_HEXA_CORE, 2739 reg_addr, wrdata)); 2740 } 2741 } 2742 return SOC_E_NONE; 2743 } 2744 2745 /* 2746 * Function: 2747 * _phy_84793_control_prbs_polynomial_set 2748 * Purpose: 2749 * To set the polynomial type. 2750 * Parameters: 2751 * unit - StrataSwitch unit #. 2752 * port - StrataSwitch port #. 2753 * poly_ctrl - polynomial type 2754 * Returns: 2755 * SOC_E_NONE 2756 */ 2757 STATIC int32 2758 _phy_84793_control_prbs_polynomial_set(int32 unit, soc_port_t port, 2759 int32 poly_ctrl) 2760 { 2761 uint16 mode = 0; 2762 uint16 start_lane = 0, end_lane =0; 2763 uint32 lane = 0; 2764 2765 phy_ctrl_t *pc; 2766 pc = EXT_PHY_SW_STATE(unit, port); 2767 2768 /* Only PRBS 7, 15,23, 31,9,11 */ 2769 if (poly_ctrl != PHY84793_PRBS_7 && poly_ctrl != PHY84793_PRBS_15 && 2770 poly_ctrl != PHY84793_PRBS_23 && poly_ctrl != PHY84793_PRBS_31 && 2771 poly_ctrl != PHY84793_PRBS_9 && poly_ctrl != PHY84793_PRBS_11) { 2772 return SOC_E_PARAM; 2773 } 2774 2775 PHY84793_GET_PORT_MODE(pc, mode); 2776 2777 switch (mode) { 2778 case PHY84793_MODE_10X10G_TO_4X25G: 2779 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 2780 for (lane = 0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 2781 SOC_IF_ERROR_RETURN 2782 (_phy_84793_per_lane_control_prbs_polynomial_set(unit, port, 2783 lane, poly_ctrl)); 2784 } 2785 break; 2786 case PHY84793_MODE_4X10G_TO_4X10G: 2787 if(pc->lane_num == 0) { 2788 start_lane = 0; 2789 end_lane = PHY84793_VSR40_LANE3; 2790 } else { 2791 start_lane = 5; 2792 end_lane = 8; 2793 } 2794 for (lane = start_lane; lane <= end_lane; lane ++) { 2795 SOC_IF_ERROR_RETURN 2796 (_phy_84793_per_lane_control_prbs_polynomial_set(unit, port, 2797 lane, poly_ctrl)); 2798 } 2799 break; 2800 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 2801 for (lane = 0; lane <= PHY84793_LN_MAX_NO_LANE; lane ++) { 2802 SOC_IF_ERROR_RETURN 2803 (_phy_84793_per_lane_control_prbs_polynomial_set(unit, port, 2804 lane, poly_ctrl)); 2805 } 2806 break; 2807 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 2808 SOC_IF_ERROR_RETURN 2809 (_phy_84793_per_lane_control_prbs_polynomial_set(unit, port, 2810 pc->lane_num, poly_ctrl)); 2811 break; 2812 } 2813 return SOC_E_NONE; 2814 } 2815 2816 /* 2817 * Function: 2818 * _phy_84793_per_lane_control_prbs_enable_set 2819 * Purpose: 2820 * To enable/disable PRBS per lane basis. 2821 * Parameters: 2822 * unit - StrataSwitch unit #. 2823 * port - StrataSwitch port #. 2824 * lane - lane number 2825 * enable - enable/disable 2826 * Returns: 2827 * SOC_E_NONE 2828 */ 2829 STATIC int32 2830 _phy_84793_per_lane_control_prbs_enable_set(int32 unit, soc_port_t port, 2831 int32 lane, int32 enable) 2832 { 2833 uint16 en_tx = 0; 2834 uint16 en_rx = 0; 2835 if (enable) { 2836 en_tx = 1; 2837 en_rx = 1; 2838 } else { 2839 en_tx = 0; 2840 en_rx = 0; 2841 } 2842 2843 SOC_IF_ERROR_RETURN 2844 (_phy_84793_prbs_gen_enable(unit, port, lane, en_tx, en_rx)); 2845 SOC_IF_ERROR_RETURN 2846 (_phy_84793_prbs_chkr_enable(unit, port, lane, en_tx, en_rx)); 2847 2848 return SOC_E_NONE; 2849 } 2850 2851 /* 2852 * Function: 2853 * _phy_84793_control_prbs_enable_set 2854 * Purpose: 2855 * To enable/disable PRBS. 2856 * Parameters: 2857 * unit - StrataSwitch unit #. 2858 * port - StrataSwitch port #. 2859 * enable - enable /disable 2860 * Returns: 2861 * SOC_E_NONE 2862 */ 2863 STATIC int32 2864 _phy_84793_control_prbs_enable_set(int32 unit, soc_port_t port, int32 enable) 2865 { 2866 uint16 mode = 0; 2867 int32 lane = 0, start_lane = 0, end_lane = 0; 2868 2869 phy_ctrl_t *pc; 2870 pc = EXT_PHY_SW_STATE(unit, port); 2871 2872 PHY84793_GET_PORT_MODE(pc, mode) 2873 2874 switch (mode) { 2875 case PHY84793_MODE_10X10G_TO_4X25G: 2876 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 2877 for (lane = 0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 2878 SOC_IF_ERROR_RETURN 2879 (_phy_84793_per_lane_control_prbs_enable_set(unit, port, lane, 2880 enable)); 2881 } 2882 break; 2883 case PHY84793_MODE_4X10G_TO_4X10G: 2884 if(pc->lane_num == 0) { 2885 start_lane = 0; 2886 end_lane = PHY84793_VSR40_LANE3; 2887 } else { 2888 start_lane = 5; 2889 end_lane = 8; 2890 } 2891 for (lane = start_lane; lane <= end_lane; lane ++) { 2892 SOC_IF_ERROR_RETURN 2893 (_phy_84793_per_lane_control_prbs_enable_set(unit, port, lane, 2894 enable)); 2895 } 2896 break; 2897 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 2898 for (lane = start_lane; lane <= end_lane; lane ++) { 2899 SOC_IF_ERROR_RETURN 2900 (_phy_84793_per_lane_control_prbs_enable_set(unit, port, pc->lane_num, 2901 enable)); 2902 } 2903 break; 2904 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 2905 SOC_IF_ERROR_RETURN 2906 (_phy_84793_per_lane_control_prbs_enable_set(unit, port, pc->lane_num, 2907 enable)); 2908 break; 2909 } 2910 return SOC_E_NONE; 2911 } 2912 2913 /* 2914 * Function: 2915 * _phy_84793_per_lane_control_prbs_enable_get 2916 * Purpose: 2917 * Check whether or not PRBS is enable for given lane. 2918 * Parameters: 2919 * unit - StrataSwitch unit #. 2920 * port - StrataSwitch port #. 2921 * lane - lane number 2922 * value - enable/disable 2923 * Returns: 2924 * SOC_E_NONE 2925 */ 2926 STATIC int32 2927 _phy_84793_per_lane_control_prbs_enable_get(int32 unit, soc_port_t port, 2928 int32 lane, uint32 *value) 2929 { 2930 uint16 tx_gen = 0; 2931 uint16 rx_gen = 0; 2932 uint16 tx_chk = 0; 2933 uint16 rx_chk = 0; 2934 2935 SOC_IF_ERROR_RETURN 2936 (_phy_84793_prbs_gen_get(unit, port, lane, &tx_gen, &rx_gen)); 2937 SOC_IF_ERROR_RETURN 2938 (_phy_84793_prbs_chkr_get(unit, port, lane, &tx_chk, &rx_chk)); 2939 2940 if (tx_gen == 1 || rx_gen == 1 || tx_chk == 1 || rx_chk == 1) { 2941 *value = TRUE; 2942 } else { 2943 *value = FALSE; 2944 } 2945 2946 return SOC_E_NONE; 2947 } 2948 2949 /* 2950 * Function: 2951 * _phy_84793_control_prbs_enable_get 2952 * Purpose: 2953 * To check whether or not prbs checker/gen 2954 * is enabled. 2955 * Parameters: 2956 * unit - StrataSwitch unit #. 2957 * port - StrataSwitch port #. 2958 * value - enable / disale 2959 * Returns: 2960 * SOC_E_NONE 2961 */ 2962 STATIC int32 2963 _phy_84793_control_prbs_enable_get(int32 unit, soc_port_t port, uint32 *value) 2964 { 2965 uint16 mode = 0, start_lane = 0, end_lane =0; 2966 int32 lane = 0; 2967 uint32 prbs_sts = 0; 2968 2969 phy_ctrl_t *pc; 2970 pc = EXT_PHY_SW_STATE(unit, port); 2971 2972 PHY84793_GET_PORT_MODE(pc, mode) 2973 *value = 0; 2974 switch (mode) { 2975 case PHY84793_MODE_10X10G_TO_4X25G: 2976 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 2977 for (lane = 0; lane <PHY84793_LN_MAX_NO_LANE; lane ++) { 2978 SOC_IF_ERROR_RETURN 2979 (_phy_84793_per_lane_control_prbs_enable_get(unit, port, lane, 2980 &prbs_sts)); 2981 *value |= prbs_sts; 2982 } 2983 break; 2984 case PHY84793_MODE_4X10G_TO_4X10G: 2985 if (pc->lane_num == 0) { 2986 start_lane = PHY84793_VSR40_LANE0; 2987 end_lane = PHY84793_VSR40_LANE3; 2988 } else { 2989 start_lane = 5; 2990 end_lane = 8; 2991 } 2992 for (lane = start_lane; lane <= end_lane; lane ++) { 2993 SOC_IF_ERROR_RETURN 2994 (_phy_84793_per_lane_control_prbs_enable_get(unit, port, lane, 2995 &prbs_sts)); 2996 *value |= prbs_sts ; 2997 } 2998 break; 2999 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 3000 for (lane = 0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 3001 SOC_IF_ERROR_RETURN 3002 (_phy_84793_per_lane_control_prbs_enable_get(unit, port, lane, 3003 &prbs_sts)); 3004 *value |= prbs_sts; 3005 } 3006 break; 3007 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 3008 SOC_IF_ERROR_RETURN 3009 (_phy_84793_per_lane_control_prbs_enable_get(unit, port, pc->lane_num, 3010 &prbs_sts)); 3011 *value = prbs_sts; 3012 break; 3013 } 3014 return SOC_E_NONE; 3015 } 3016 3017 /* 3018 * Function: 3019 * _phy_84793_per_lane_control_prbs_polynomial_get 3020 * Purpose: 3021 * Configure PHY device specific control fucntion. 3022 * Parameters: 3023 * unit - StrataSwitch unit #. 3024 * port - StrataSwitch port #. 3025 * value - PRBS polynomial type 3026 * Returns: 3027 * SOC_E_NONE 3028 */ 3029 STATIC int32 3030 _phy_84793_per_lane_control_prbs_polynomial_get(int32 unit, soc_port_t port, 3031 int32 lane, uint32 *value) 3032 { 3033 uint16 rddata = 0, poly_ctrl = 0; 3034 uint16 mode = 0; 3035 int32 reg_addr = 0; 3036 phy_ctrl_t *pc; 3037 uint16 intf = 0; 3038 3039 pc = EXT_PHY_SW_STATE(unit, port); 3040 PHY84793_GET_PORT_MODE(pc, mode); 3041 intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : PHY84793_LINE_SIDE; 3042 3043 if ((mode == PHY84793_MODE_4X10G_TO_4X10G) && (lane == 4 || lane == 9)) { 3044 return SOC_E_PARAM; 3045 } 3046 3047 /* Since Both line and system side configured with same polynomial 3048 * its sufficient to get system side alone*/ 3049 if (intf == PHY84793_SYS_SIDE) { 3050 reg_addr = (lane << 16) | 0x8069; 3051 SOC_IF_ERROR_RETURN 3052 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 3053 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 3054 3055 switch ((rddata & 0xc)) { 3056 case 0xC: 3057 *value = PHY84793_PRBS_31; 3058 break; 3059 case 0: 3060 if ((rddata & 0x100) == 0x100) { 3061 *value = PHY84793_PRBS_9; 3062 } else { 3063 *value = PHY84793_PRBS_7; 3064 } 3065 break; 3066 case 4: 3067 if ((rddata & 0x100) == 0x100) { 3068 *value = PHY84793_PRBS_11; 3069 } else { 3070 *value = PHY84793_PRBS_15; 3071 } 3072 break; 3073 case 8: 3074 *value = PHY84793_PRBS_23; 3075 break; 3076 } 3077 } else { 3078 if (lane < PHY84793_VSR40_LANE3) { 3079 SOC_IF_ERROR_RETURN 3080 (READ_PHY84793_PMA_PMD_REG 3081 (unit, pc, RG_TX_TX_GB_TEST_GEN_CTRL, &rddata)); 3082 poly_ctrl = (rddata >> (lane *3)) & 7; 3083 switch(poly_ctrl) { 3084 case 0x1: 3085 *value = PHY84793_PRBS_7; 3086 break; 3087 case 0x4: 3088 *value = PHY84793_PRBS_15; 3089 break; 3090 case 0x5: 3091 *value = PHY84793_PRBS_23; 3092 break; 3093 case 0x6: 3094 *value = PHY84793_PRBS_31; 3095 break; 3096 case 0x2: 3097 *value = PHY84793_PRBS_9; 3098 break; 3099 case 0x3: 3100 *value = PHY84793_PRBS_11; 3101 break; 3102 } 3103 } else { 3104 reg_addr = ((lane - 4) << 16) | 0x8069; 3105 SOC_IF_ERROR_RETURN 3106 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 3107 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 3108 3109 switch ((rddata & 0xc)) { 3110 case 0xC: 3111 *value = PHY84793_PRBS_31; 3112 break; 3113 case 0: 3114 if ((rddata & 0x100) == 0x100) { 3115 *value = PHY84793_PRBS_9; 3116 } else { 3117 *value = PHY84793_PRBS_7; 3118 } 3119 break; 3120 case 4: 3121 if ((rddata & 0x100) == 0x100) { 3122 *value = PHY84793_PRBS_11; 3123 } else { 3124 *value = PHY84793_PRBS_15; 3125 } 3126 break; 3127 case 8: 3128 *value = PHY84793_PRBS_23; 3129 break; 3130 } 3131 } 3132 } 3133 return SOC_E_NONE; 3134 } 3135 3136 /* 3137 * Function: 3138 * _phy_84793_control_prbs_polynomial_get 3139 * Purpose: 3140 * Get PRBS polynomial type 3141 * Parameters: 3142 * unit - StrataSwitch unit #. 3143 * port - StrataSwitch port #. 3144 * value - PRBS polynomial type 3145 * Returns: 3146 * SOC_E_NONE 3147 */ 3148 STATIC int32 3149 _phy_84793_control_prbs_polynomial_get(int32 unit, soc_port_t port, 3150 uint32 *value) 3151 { 3152 uint16 mode = 0, lane = 0; 3153 phy_ctrl_t *pc; 3154 3155 pc = EXT_PHY_SW_STATE(unit, port); 3156 3157 PHY84793_GET_PORT_MODE(pc, mode) 3158 3159 switch (mode) { 3160 case PHY84793_MODE_10X10G_TO_4X25G: 3161 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 3162 SOC_IF_ERROR_RETURN 3163 (_phy_84793_per_lane_control_prbs_polynomial_get(unit, port, 3164 pc->lane_num, value)); 3165 3166 break; 3167 case PHY84793_MODE_4X10G_TO_4X10G: 3168 if (pc->lane_num == 0) { 3169 lane = PHY84793_VSR40_LANE0; 3170 } else { 3171 lane = 5; 3172 } 3173 SOC_IF_ERROR_RETURN 3174 (_phy_84793_per_lane_control_prbs_polynomial_get(unit, port, 3175 lane, value)); 3176 break; 3177 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 3178 SOC_IF_ERROR_RETURN 3179 (_phy_84793_per_lane_control_prbs_polynomial_get(unit, port, 3180 pc->lane_num, value)); 3181 break; 3182 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 3183 SOC_IF_ERROR_RETURN 3184 (_phy_84793_per_lane_control_prbs_polynomial_get(unit, port, 3185 pc->lane_num, value)); 3186 3187 break; 3188 } 3189 return SOC_E_NONE; 3190 } 3191 /* 3192 * Function: 3193 * _phy_84793_control_prbs_tx_invert_data_get 3194 * Purpose: 3195 * To check whether or not invert data enabled. 3196 * Parameters: 3197 * unit - StrataSwitch unit #. 3198 * port - StrataSwitch port #. 3199 * value - enable/disable 3200 * Returns: 3201 * SOC_E_NONE 3202 */ 3203 3204 STATIC int32 3205 _phy_84793_control_prbs_tx_invert_data_get(int32 unit, soc_port_t port, 3206 PHY84793_INTF_SIDE intf, 3207 uint32 *value) 3208 { 3209 uint16 rddata = 0, mode = 0; 3210 phy_ctrl_t *pc; 3211 int32 reg_addr = 0; 3212 uint32 lane = 0; 3213 pc = EXT_PHY_SW_STATE(unit, port); 3214 3215 PHY84793_GET_PORT_MODE(pc, mode); 3216 3217 *value = 0; 3218 if (intf == PHY84793_SYS_SIDE) { 3219 for (lane =0; lane <= PHY84793_DC_LANE9; lane ++) { 3220 /* For Systemside(DC) */ 3221 reg_addr = (lane << 16) | 0x80b6; 3222 SOC_IF_ERROR_RETURN 3223 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 3224 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 3225 *value |= (rddata & 0x10)?(1<<lane):0; 3226 3227 } 3228 } else { 3229 for (lane =0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 3230 if (lane < PHY84793_VSR40_LANE3) { 3231 /* For VSR*/ 3232 SOC_IF_ERROR_RETURN 3233 (READ_PHY84793_PMA_PMD_REG (unit, pc, RG_TX_TX_GB_TEST_GEN_CTRL, 3234 &rddata)); 3235 *value = (rddata >> 12) & 0xF; 3236 } else { 3237 if (mode == PHY84793_MODE_10X10G_TO_4X25G || 3238 mode == PHY84793_MODE_10X10G_TO_4X25G_OTL) { 3239 return SOC_E_NONE; 3240 } 3241 reg_addr = ((lane-4) << 16) | 0x8069; 3242 PHY_84793_HCTX_PCB_READ (unit, pc, reg_addr, &rddata); 3243 *value |= (rddata & 0x10)?(1<<lane):0; 3244 } 3245 } 3246 } 3247 3248 return SOC_E_NONE; 3249 } 3250 3251 /* 3252 * Function: 3253 * phy_84793_control_prbs_rx_status_get 3254 * Purpose: 3255 * Configure PHY device specific control fucntion. 3256 * Parameters: 3257 * unit - StrataSwitch unit #. 3258 * port - StrataSwitch port #. 3259 * lane - lane number 3260 * value - status of the PRBS lock 3261 * Returns: 3262 * SOC_E_NONE 3263 */ 3264 3265 STATIC int32 3266 _phy_84793_control_prbs_rx_status_get(int32 unit, soc_port_t port, 3267 uint32 *value) 3268 { 3269 uint16 mode = 0, start_lane = 0, end_lane=0; 3270 uint32 prbs_sts = 0; 3271 int32 lane = 0; 3272 phy_ctrl_t *pc; 3273 pc = EXT_PHY_SW_STATE(unit, port); 3274 PHY84793_GET_PORT_MODE(pc, mode); 3275 *value = 0; 3276 switch (mode) { 3277 case PHY84793_MODE_10X10G_TO_4X25G: 3278 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 3279 for (lane = 0; lane <= PHY84793_VSR40_LANE3; lane ++) { 3280 SOC_IF_ERROR_RETURN 3281 (_phy_84793_per_lane_control_prbs_rx_status_get(unit, port, 3282 lane, &prbs_sts)); 3283 *value |= prbs_sts; 3284 } 3285 break; 3286 case PHY84793_MODE_4X10G_TO_4X10G: 3287 if (pc->lane_num == 0) { 3288 start_lane = PHY84793_VSR40_LANE0; 3289 end_lane = PHY84793_VSR40_LANE3; 3290 } else { 3291 start_lane = 5; 3292 end_lane = 8; 3293 } 3294 for (lane = start_lane; lane < end_lane; lane ++) { 3295 SOC_IF_ERROR_RETURN 3296 (_phy_84793_per_lane_control_prbs_rx_status_get(unit, port, 3297 lane, &prbs_sts)); 3298 *value |= prbs_sts; 3299 } 3300 break; 3301 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 3302 SOC_IF_ERROR_RETURN 3303 (_phy_84793_per_lane_control_prbs_rx_status_get(unit, port, 3304 pc->lane_num, &prbs_sts)); 3305 *value = prbs_sts; 3306 break; 3307 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 3308 for (lane = 0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 3309 SOC_IF_ERROR_RETURN 3310 (_phy_84793_per_lane_control_prbs_rx_status_get(unit, port, 3311 lane, &prbs_sts)); 3312 *value |= prbs_sts; 3313 } 3314 break; 3315 } 3316 return SOC_E_NONE; 3317 } 3318 3319 /* 3320 * Function: 3321 * _phy_84793_per_lane_control_prbs_rx_status_get 3322 * Purpose: 3323 * Configure PHY device specific control fucntion. 3324 * Parameters: 3325 * unit - StrataSwitch unit #. 3326 * port - StrataSwitch port #. 3327 * lane - lane number 3328 * value - status of the PRBS lock 3329 * Returns: 3330 * SOC_E_NONE 3331 */ 3332 3333 STATIC int32 3334 _phy_84793_per_lane_control_prbs_rx_status_get(int32 unit, soc_port_t port, 3335 int32 lane, uint32 *value) 3336 { 3337 uint16 rddata = 0, prev_val = 0; 3338 uint16 mode = 0; 3339 uint16 err_lsb = 0, err_msb=0; 3340 phy_ctrl_t *pc; 3341 int32 reg_addr = 0; 3342 uint16 intf = 0; 3343 3344 pc = EXT_PHY_SW_STATE(unit, port); 3345 PHY84793_GET_PORT_MODE(pc, mode); 3346 intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY84793_SYS_SIDE : PHY84793_LINE_SIDE; 3347 3348 if ((mode == PHY84793_MODE_4X10G_TO_4X10G) && (lane == 4 || lane == 9)) { 3349 return SOC_E_PARAM; 3350 } 3351 3352 *value = 0; 3353 if (intf == PHY84793_SYS_SIDE) { 3354 reg_addr = (lane << 16) | 0x80b1; 3355 SOC_IF_ERROR_RETURN 3356 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 3357 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 3358 prev_val = rddata; 3359 rddata &= ~0x7; 3360 rddata |= 0x7; 3361 SOC_IF_ERROR_RETURN 3362 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 3363 PHY84793_DECA_CORE, reg_addr, rddata)); 3364 reg_addr = (lane << 16) | 0x80b0; 3365 3366 SOC_IF_ERROR_RETURN( 3367 _phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 3368 reg_addr, PHY84793_DC_HC_RD_WIT_CLEAR, &rddata)); 3369 if (rddata & 0x8000) { 3370 if (rddata & 0x4000) { 3371 /* LOcked Now But lost before*/ 3372 /* LOSS OF LOCK occured once, so one error at least */ 3373 *value = (rddata & 0x3fff); 3374 if (*value == 0) { 3375 *value = -2; /* No Error BUT LOL*/ 3376 } 3377 } else if (rddata & 0x3fff) { 3378 /* Check For Error, but no loss of lock */ 3379 *value = (rddata & 0x3fff); 3380 } else { 3381 *value = 0; 3382 } 3383 } else { 3384 *value = (rddata & 0x3fff); 3385 if (*value == 0) { 3386 *value = -1; /* No Error And NO Lock*/ 3387 } 3388 } 3389 reg_addr = (lane << 16) | 0x80b1; 3390 SOC_IF_ERROR_RETURN 3391 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 3392 PHY84793_DECA_CORE, reg_addr, prev_val)); 3393 } else { 3394 uint16 l_lock = 0; 3395 switch (mode) { 3396 case PHY84793_MODE_10X10G_TO_4X25G: 3397 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 3398 if (lane > PHY84793_VSR40_LANE3) { 3399 return SOC_E_PARAM; 3400 } 3401 SOC_IF_ERROR_RETURN 3402 (READ_PHY84793_PMA_PMD_REG(unit, pc, RG_RX_RX_GB_PRBS_LOCK, &rddata)); 3403 SOC_IF_ERROR_RETURN 3404 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 3405 RG_RX_RX_GB_TEST_MISC_CTRL, 11, 8 , lane)); 3406 SOC_IF_ERROR_RETURN 3407 (READ_PHY84793_PMA_PMD_REG(unit, pc, 3408 RG_RX_RX_GB_LSB_ERR_CNT, &err_lsb)); 3409 SOC_IF_ERROR_RETURN 3410 (READ_PHY84793_PMA_PMD_REG(unit, pc, 3411 RG_RX_RX_GB_MSB_ERR_CNT, &err_msb)); 3412 if (rddata & (1 << lane)) { 3413 SOC_IF_ERROR_RETURN 3414 (READ_PHY84793_PMA_PMD_REG(unit, pc, RG_RX_RX_GB_PRBS_LOCK_LL, &l_lock)); 3415 if (l_lock & (1 << lane)) { 3416 /* LOcked Now But lost before*/ 3417 /* LOSS OF LOCK occured once, so one error at least */ 3418 *value = ((err_lsb | (err_msb<<16)) & 0xffffffff); 3419 if (*value == 0) { 3420 *value = -2; /* No Error but LOL*/ 3421 } 3422 } else if (err_lsb | (err_msb << 16)) { 3423 *value = ((err_lsb | (err_msb<<16)) & 0xffffffff); 3424 } else { 3425 *value = 0; 3426 } 3427 } else { 3428 *value = ((err_lsb | (err_msb<<16)) & 0xffffffff); 3429 if (*value == 0) { 3430 *value = -1; /* No Error And NO Lock*/ 3431 } 3432 } 3433 break; 3434 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 3435 case PHY84793_MODE_4X10G_TO_4X10G: 3436 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 3437 { 3438 if (lane <= PHY84793_VSR40_LANE3) { 3439 SOC_IF_ERROR_RETURN 3440 (READ_PHY84793_PMA_PMD_REG(unit, pc, RG_RX_RX_GB_PRBS_LOCK, 3441 &rddata)); 3442 SOC_IF_ERROR_RETURN 3443 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 3444 RG_RX_RX_GB_TEST_MISC_CTRL, 11, 8 , lane)); 3445 3446 SOC_IF_ERROR_RETURN 3447 (READ_PHY84793_PMA_PMD_REG(unit, pc, 3448 RG_RX_RX_GB_LSB_ERR_CNT,&err_lsb)); 3449 SOC_IF_ERROR_RETURN 3450 (READ_PHY84793_PMA_PMD_REG(unit, pc, 3451 RG_RX_RX_GB_MSB_ERR_CNT,&err_msb)); 3452 if (rddata & (1 << lane)) { 3453 SOC_IF_ERROR_RETURN 3454 (READ_PHY84793_PMA_PMD_REG(unit, pc, RG_RX_RX_GB_PRBS_LOCK_LL, &l_lock)); 3455 if (l_lock & (1 << lane)) { 3456 /* LOcked Now But lost before*/ 3457 /* LOSS OF LOCK occured once, so one error at least */ 3458 *value = ((err_lsb | (err_msb<<16)) & 0xffffffff); 3459 if (*value == 0) { 3460 *value = -2; /* No Error BUT LOL*/ 3461 } 3462 } else if (err_lsb | (err_msb << 16)) { 3463 *value = ((err_lsb | (err_msb<<16)) & 0xffffffff); 3464 } else { 3465 *value = 0; 3466 } 3467 } else { 3468 *value = ((err_lsb | (err_msb<<16)) & 0xffffffff); 3469 if (*value == 0) { 3470 *value = -1; /* No Error And NO Lock*/ 3471 } 3472 } 3473 } else { 3474 reg_addr = ((lane-4) << 16) | 0x80b1; 3475 SOC_IF_ERROR_RETURN 3476 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 3477 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 3478 prev_val = rddata; 3479 rddata &= ~0x7; 3480 rddata |= 0x7; 3481 SOC_IF_ERROR_RETURN 3482 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 3483 PHY84793_HEXA_CORE, reg_addr, rddata)); 3484 reg_addr = ((lane-4) << 16) | 0x80b0; 3485 3486 SOC_IF_ERROR_RETURN( 3487 _phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 3488 reg_addr, PHY84793_DC_HC_RD_WIT_CLEAR, &rddata)); 3489 if (rddata & 0x8000) { 3490 if (rddata & 0x4000) { 3491 /* LOcked Now But lost before*/ 3492 /* LOSS OF LOCK occured once, so one error at least */ 3493 *value = (rddata & 0x3fff); 3494 if (*value == 0) { 3495 *value = -2; /* No Error BUT LOL*/ 3496 } 3497 } else if(rddata & 0x3fff) { 3498 *value = (rddata & 0x3fff); 3499 } else { 3500 *value = 0; 3501 } 3502 } else { 3503 *value = (rddata & 0x3fff); 3504 if (*value == 0) { 3505 *value = -1; /* No Error And NO Lock*/ 3506 } 3507 } 3508 reg_addr = ((lane-4) << 16) | 0x80b1; 3509 SOC_IF_ERROR_RETURN 3510 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 3511 PHY84793_HEXA_CORE, reg_addr, prev_val)); 3512 } 3513 break; 3514 } 3515 } 3516 } 3517 return SOC_E_NONE; 3518 } 3519 3520 STATIC int32 3521 _phy_84793_dev_id_get(int32 unit, soc_port_t port, phy_ctrl_t *pc, 3522 uint32 *chip_id) 3523 { 3524 uint16 chip_id_msb = 0, chip_id_lsb = 0; 3525 3526 SOC_IF_ERROR_RETURN 3527 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_COMMON_REV_ID, 3528 &chip_id_msb)); 3529 chip_id_msb = (chip_id_msb & 0xF000) >> 12; 3530 3531 SOC_IF_ERROR_RETURN 3532 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_COMMON_CHIP_ID, 3533 &chip_id_lsb)); 3534 if (chip_id_msb == 0x8) { 3535 if (chip_id_lsb == 0x4793) { 3536 *chip_id = PHY84793_ID_84793; 3537 } else if(chip_id_lsb == 0x4790) { 3538 *chip_id = PHY84793_ID_84790; 3539 } else if(chip_id_lsb == 0x4794) { 3540 *chip_id = PHY84793_ID_84794; 3541 } 3542 } 3543 3544 return SOC_E_NONE; 3545 } 3546 3547 STATIC 3548 int32 _phy_84793_dc_hc_pcb_read (int32 unit, soc_port_t port, phy_ctrl_t *pc, 3549 uint16 dc_hc, uint32 addr, uint16 clear_reg, uint16 *rddata) 3550 { 3551 SOC_IF_ERROR_RETURN 3552 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_ADR_MSW_TYPE, 3553 (uint16)((addr & PHY84793_16BIT_MSB)>>16))); 3554 SOC_IF_ERROR_RETURN 3555 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_ADR_LSW_TYPE, 3556 (uint16)(addr & PHY84793_16BIT_LSB))); 3557 3558 if (dc_hc == PHY84793_HEXA_CORE) {/* For Rx HC*/ 3559 SOC_IF_ERROR_RETURN 3560 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3561 PHY84793_HC_RX_BIT)); 3562 SOC_IF_ERROR_RETURN 3563 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3564 PHY84793_HC_READ_ENABLE)); 3565 } else { /* FOR DC */ 3566 SOC_IF_ERROR_RETURN 3567 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3568 PHY84793_DC_ENABLE)); 3569 SOC_IF_ERROR_RETURN 3570 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3571 PHY84793_DC_READ_ENABLE)); 3572 } 3573 3574 SOC_IF_ERROR_RETURN 3575 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_DATA_OUT_TYPE, rddata)); 3576 3577 if (clear_reg) { 3578 if (dc_hc == PHY84793_HEXA_CORE) { 3579 SOC_IF_ERROR_RETURN 3580 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3581 PHY84793_HC_PCB_CLEAR)); 3582 SOC_IF_ERROR_RETURN 3583 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3584 PHY84793_HC_READ_ENABLE)); 3585 } else { 3586 SOC_IF_ERROR_RETURN 3587 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3588 PHY84793_DC_PCB_CLEAR)); 3589 SOC_IF_ERROR_RETURN 3590 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3591 PHY84793_DC_READ_ENABLE)); 3592 } 3593 } 3594 SOC_IF_ERROR_RETURN 3595 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 0x0)); 3596 3597 return SOC_E_NONE; 3598 } 3599 3600 STATIC 3601 int32 _phy_84793_dc_hc_pcb_write (int32 unit, soc_port_t port, phy_ctrl_t *pc, 3602 uint16 dc_hc, uint32 addr, uint16 value) 3603 { 3604 SOC_IF_ERROR_RETURN 3605 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_ADR_MSW_TYPE, 3606 (uint16)((addr & PHY84793_16BIT_MSB)>>16))); 3607 SOC_IF_ERROR_RETURN 3608 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_ADR_LSW_TYPE, 3609 (uint16)(addr & PHY84793_16BIT_LSB))); 3610 3611 SOC_IF_ERROR_RETURN 3612 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_DATA_IN_TYPE, value)); 3613 if (dc_hc == PHY84793_HEXA_CORE) { /*for RX HC*/ 3614 SOC_IF_ERROR_RETURN 3615 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3616 PHY84793_HC_RX_BIT)); 3617 SOC_IF_ERROR_RETURN 3618 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3619 PHY84793_HC_WRITE_ENABLE)); 3620 } else { /* For DC*/ 3621 SOC_IF_ERROR_RETURN 3622 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3623 PHY84793_DC_ENABLE)); 3624 SOC_IF_ERROR_RETURN 3625 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 3626 PHY84793_DC_WRITE_ENABLE)); 3627 } 3628 SOC_IF_ERROR_RETURN 3629 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 0x0)); 3630 3631 return SOC_E_NONE; 3632 } 3633 3634 STATIC 3635 int32 _phy_84793_set_refclk_code(int32 unit, soc_port_t port, phy_ctrl_t *pc, 3636 uint16 refclk_freq) 3637 { 3638 uint8 refclk_code = 0; 3639 3640 if (refclk_freq == PHY84793_REF_CLK_156_25) { 3641 refclk_code = 0x0; 3642 } else if(refclk_freq == PHY84793_REF_CLK_161_132) { 3643 refclk_code = 0x5; 3644 } else if(refclk_freq == PHY84793_REF_CLK_174_7) { 3645 refclk_code = 0x3; 3646 } else if(refclk_freq == PHY84793_REF_CLK_312_5) { 3647 refclk_code = 0x1; 3648 } else if(refclk_freq == PHY84793_REF_CLK_322_265) { 3649 refclk_code = 0x6; 3650 } else if(refclk_freq == PHY84793_REF_CLK_349_4) { 3651 refclk_code = 0x2; 3652 } else if(refclk_freq == PHY84793_REF_CLK_625_0) { 3653 refclk_code = 0x8; 3654 } else if(refclk_freq == PHY84793_REF_CLK_644_531) { 3655 refclk_code = 0x7; 3656 } else if(refclk_freq == PHY84793_REF_CLK_698_8) { 3657 refclk_code = 0x4; 3658 } 3659 3660 /* Setting refclk_sel_reg.refclk_code */ 3661 SOC_IF_ERROR_RETURN 3662 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_REFCLK_SEL_REG, 3663 CTL_REGS_REFCLK_SEL_REG_REFCLK_CODE_SHIFT + 3, 3664 CTL_REGS_REFCLK_SEL_REG_REFCLK_CODE_SHIFT, refclk_code)); 3665 3666 return SOC_E_NONE; 3667 } 3668 3669 STATIC 3670 int32 _phy_84793_config_mode (int32 unit, soc_port_t port, phy_ctrl_t *pc, 3671 uint16 mode) 3672 { 3673 uint16 reg_clk = 0; 3674 3675 switch (mode) { 3676 case PHY84793_MODE_10X10G_TO_4X25G: 3677 reg_clk = PHY84793_REF_CLK_156_25; 3678 mode = 0; 3679 break; 3680 case PHY84793_MODE_4X10G_TO_4X10G: 3681 reg_clk = PHY84793_REF_CLK_161_132; 3682 mode = 1; 3683 break; 3684 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 3685 reg_clk = PHY84793_REF_CLK_161_132; 3686 mode = 2; 3687 break; 3688 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 3689 reg_clk = PHY84793_REF_CLK_161_132; 3690 mode = 3; 3691 break; 3692 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 3693 reg_clk = PHY84793_REF_CLK_174_7; 3694 mode = 4; 3695 break; 3696 3697 default: 3698 return SOC_E_FAIL; 3699 } 3700 if (mode == PHY84793_MODE_10X10G_TO_4X25G) { 3701 SOC_IF_ERROR_RETURN 3702 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_USER_MODESEL_REG, 3703 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 3704 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 0)); 3705 3706 SOC_IF_ERROR_RETURN 3707 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_USER_MODESEL_REG, 3708 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT + 2, 3709 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT, mode)); 3710 SOC_IF_ERROR_RETURN 3711 (_phy_84793_set_refclk_code(unit, port, pc, reg_clk)); 3712 3713 SOC_IF_ERROR_RETURN(_phy_84793_div_change(unit, port, 0, 0, mode)); 3714 3715 SOC_IF_ERROR_RETURN 3716 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_USER_MODESEL_REG, 3717 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 3718 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 0)); 3719 SOC_IF_ERROR_RETURN 3720 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_USER_MODESEL_REG, 3721 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT + 2, 3722 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT, mode)); 3723 } else { 3724 SOC_IF_ERROR_RETURN 3725 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_USER_MODESEL_REG, 3726 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 3727 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 1)); 3728 SOC_IF_ERROR_RETURN 3729 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_USER_MODESEL_REG, 3730 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT + 2, 3731 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT, mode)); 3732 3733 SOC_IF_ERROR_RETURN(_phy_84793_div_change(unit, port, 1, 0, mode)); 3734 3735 SOC_IF_ERROR_RETURN 3736 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_USER_MODESEL_REG, 3737 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 3738 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 1)); 3739 3740 SOC_IF_ERROR_RETURN 3741 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_USER_MODESEL_REG, 3742 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT + 2, 3743 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT, mode)); 3744 } 3745 3746 return SOC_E_NONE; 3747 } 3748 3749 STATIC 3750 int32 _phy_84793_system_polarity_flip (int32 unit, soc_port_t port, 3751 phy_ctrl_t *pc, uint16 cfg_tx_pol, uint16 cfg_rx_pol) 3752 { 3753 uint16 lane = 0 , rddata = 0; 3754 uint8 flip = 0; 3755 uint32 reg_addr = 0; 3756 3757 if (PHY84793_POL_DND != cfg_rx_pol) { 3758 /*The function enables system side input (Rx) polarity invert*/ 3759 for (lane = PHY84793_DC_LANE0; lane <= PHY84793_DC_LANE9; lane ++) { 3760 reg_addr = (lane << 16) | 0x80BA; 3761 SOC_IF_ERROR_RETURN 3762 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 3763 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 3764 3765 if ((cfg_rx_pol & POL_LANE_MASK(lane)) == POL_LANE_MASK(lane)) { 3766 rddata |= (1 << 2); 3767 } else { 3768 rddata &= ~(1 << 2); 3769 } 3770 rddata |= (1 << 3); /* Force Rx polarity bit 3*/ 3771 3772 SOC_IF_ERROR_RETURN 3773 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 3774 reg_addr, rddata)); 3775 } 3776 } 3777 if (PHY84793_POL_DND != cfg_tx_pol) { 3778 /*The function enables system side output (Tx) polarity invert*/ 3779 for (lane = PHY84793_DC_LANE0; lane <= PHY84793_DC_LANE9; lane ++) { 3780 if ((cfg_tx_pol & POL_LANE_MASK(lane)) == POL_LANE_MASK(lane)) { 3781 flip = 1; 3782 } else { 3783 flip = 0; 3784 } 3785 SOC_IF_ERROR_RETURN 3786 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 3787 RG_RX_RX_GB_IO_BIT_CTRL, 3788 RG_RX_RX_GB_IO_BIT_CTRL_OUTPUT_INVERT_SHIFT + lane, 3789 RG_RX_RX_GB_IO_BIT_CTRL_OUTPUT_INVERT_SHIFT + lane, flip)); 3790 } 3791 } 3792 return SOC_E_NONE; 3793 } 3794 3795 STATIC 3796 int32 _phy_84793_line_polarity_flip (int32 unit, soc_port_t port, 3797 phy_ctrl_t *pc, 3798 uint16 cfg_tx_pol, uint16 cfg_rx_pol) 3799 { 3800 uint16 lane = 0, rddata = 0; 3801 uint8 flip = 0; 3802 uint32 reg_addr = 0; 3803 3804 if (PHY84793_POL_DND != cfg_rx_pol) { 3805 /*The function enables system side input (Rx) polarity invert*/ 3806 for (lane = PHY84793_HC_LANE0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 3807 if (lane <= PHY84793_VSR40_LANE3) { 3808 if ((cfg_rx_pol & POL_LANE_MASK(lane)) == POL_LANE_MASK(lane)) { 3809 flip = 1; 3810 } else { 3811 flip = 0; 3812 } 3813 SOC_IF_ERROR_RETURN 3814 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3815 VSR40_RX_DIG_REGS_DP_CTRL, 3816 VSR40_RX_DIG_REGS_DP_CTRL_INVERT_DP_SHIFT + lane, 3817 VSR40_RX_DIG_REGS_DP_CTRL_INVERT_DP_SHIFT + lane, flip)); 3818 } else { 3819 3820 reg_addr = ((lane-4) << 16) | 0x80BA; 3821 SOC_IF_ERROR_RETURN 3822 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_HEXA_CORE, 3823 reg_addr, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 3824 if ((cfg_rx_pol & POL_LANE_MASK(lane)) == 3825 POL_LANE_MASK(lane)) { 3826 rddata |= (1 << 2); 3827 } else { 3828 rddata &= ~(1 << 2); 3829 } 3830 rddata |= (1 << 3); /* Force Rx polarity bit 3*/ 3831 SOC_IF_ERROR_RETURN 3832 (_phy_84793_dc_hc_pcb_write (unit, port, pc, 3833 PHY84793_HEXA_CORE, reg_addr, rddata)); 3834 } 3835 } 3836 } 3837 if (PHY84793_POL_DND != cfg_tx_pol) { 3838 /*The function enables line side output (Tx) polarity invert*/ 3839 for (lane = PHY84793_HC_LANE0; lane < PHY84793_LN_MAX_NO_LANE; lane ++) { 3840 if ((cfg_tx_pol & POL_LANE_MASK(lane)) == POL_LANE_MASK(lane)) { 3841 flip = 1; 3842 } else { 3843 flip = 0; 3844 } 3845 SOC_IF_ERROR_RETURN 3846 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3847 RG_TX_TX_GB_IO_BIT_CONTROL, 3848 RG_TX_TX_GB_IO_BIT_CONTROL_OUTPUT_INVERT_SHIFT + lane, 3849 RG_TX_TX_GB_IO_BIT_CONTROL_OUTPUT_INVERT_SHIFT + lane, flip)); 3850 } 3851 } 3852 return SOC_E_NONE; 3853 } 3854 3855 STATIC 3856 int32 _phy_84793_sys_enable_set (int32 unit, soc_port_t port, phy_ctrl_t *pc, 3857 uint16 cfg_tx_set, uint16 cfg_rx_set) 3858 { 3859 uint16 enable = 0, lane = 0, mode = 0; 3860 3861 PHY84793_GET_PORT_MODE(pc, mode); 3862 if (cfg_rx_set != PHY84793_ENABLE_SET_DND) { 3863 for (lane = PHY84793_DC_LANE0; lane <= PHY84793_DC_LANE9; lane ++) { 3864 if ((cfg_rx_set & POL_LANE_MASK(lane)) == POL_LANE_MASK(lane)) { 3865 enable = 0; 3866 } else { 3867 enable = 1; 3868 } 3869 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 3870 if (lane == 4 || lane ==9) { 3871 return SOC_E_NONE; 3872 } 3873 } 3874 SOC_IF_ERROR_RETURN 3875 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_FRC_DCRX_PD, 3876 CTL_REGS_FRC_DCRX_PD_FRC_DCRX_PWRDN_SHIFT + lane, 3877 CTL_REGS_FRC_DCRX_PD_FRC_DCRX_PWRDN_SHIFT + lane, 1)); 3878 SOC_IF_ERROR_RETURN 3879 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_DCRX_PD, 3880 CTL_REGS_DCRX_PD_DCRX_PWRDN_SHIFT + lane, 3881 CTL_REGS_DCRX_PD_DCRX_PWRDN_SHIFT + lane, enable)); 3882 } 3883 } 3884 if (cfg_tx_set != PHY84793_ENABLE_SET_DND) { 3885 for (lane = PHY84793_DC_LANE0; lane <= PHY84793_DC_LANE9; lane ++) { 3886 if ((cfg_tx_set & POL_LANE_MASK(lane)) == POL_LANE_MASK(lane)) { 3887 enable = 0; 3888 } else { 3889 enable = 1; 3890 } 3891 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 3892 if (lane == 4 || lane ==9) { 3893 return SOC_E_NONE; 3894 } 3895 } 3896 3897 SOC_IF_ERROR_RETURN 3898 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_FRC_DCTX_PD, 3899 CTL_REGS_FRC_DCTX_PD_FRC_DCTX_PWRDN_SHIFT + lane, 3900 CTL_REGS_FRC_DCTX_PD_FRC_DCTX_PWRDN_SHIFT + lane, 1)); 3901 SOC_IF_ERROR_RETURN 3902 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_DCTX_PD, 3903 CTL_REGS_DCTX_PD_DCTX_PWRDN_SHIFT + lane, 3904 CTL_REGS_DCTX_PD_DCTX_PWRDN_SHIFT + lane, enable)); 3905 } 3906 } 3907 return SOC_E_NONE; 3908 } 3909 3910 STATIC 3911 int32 _phy_84793_line_enable_set (int32 unit, soc_port_t port, phy_ctrl_t *pc, 3912 uint16 cfg_tx_set, uint16 cfg_rx_set) 3913 { 3914 uint16 enable = 0, lane = 0, mode = 0; 3915 3916 PHY84793_GET_PORT_MODE(pc, mode); 3917 if (cfg_rx_set != PHY84793_ENABLE_SET_DND) { 3918 for (lane = PHY84793_HC_LANE0; lane < PHY84793_LN_MAX_NO_LANE; 3919 lane ++) { 3920 if ((cfg_rx_set & POL_LANE_MASK(lane)) == POL_LANE_MASK(lane)) { 3921 enable = 0; 3922 } else { 3923 enable = 1; 3924 } 3925 if (lane <= PHY84793_VSR40_LANE3) { 3926 SOC_IF_ERROR_RETURN 3927 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3928 CTL_REGS_FRC_VSR40_RX_PD, 3929 CTL_REGS_FRC_VSR40_RX_PD_FRC_VSR40_RX_PWRDN_SHIFT + lane, 3930 CTL_REGS_FRC_VSR40_RX_PD_FRC_VSR40_RX_PWRDN_SHIFT + lane, 1)); 3931 SOC_IF_ERROR_RETURN 3932 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3933 CTL_REGS_VSR40_RX_PD, 3934 CTL_REGS_VSR40_RX_PD_VSR40_RX_PWRDN_SHIFT + lane, 3935 CTL_REGS_VSR40_RX_PD_VSR40_RX_PWRDN_SHIFT + lane, enable)); 3936 } else { 3937 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 3938 if (lane == 4 || lane ==9) { 3939 return SOC_E_NONE; 3940 } 3941 } 3942 SOC_IF_ERROR_RETURN 3943 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3944 CTL_REGS_FRC_HCRX_PD, 3945 (CTL_REGS_FRC_HCRX_PD_FRC_HCRX_PWRDN_SHIFT + (lane-4)), 3946 (CTL_REGS_FRC_HCRX_PD_FRC_HCRX_PWRDN_SHIFT + (lane-4)), 1)); 3947 SOC_IF_ERROR_RETURN 3948 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_HCRX_PD, 3949 (CTL_REGS_HCRX_PD_HCRX_PWRDN_SHIFT + (lane-4)), 3950 (CTL_REGS_HCRX_PD_HCRX_PWRDN_SHIFT + (lane -4)), enable)); 3951 } 3952 } 3953 } 3954 if (cfg_tx_set != PHY84793_ENABLE_SET_DND) { 3955 for (lane = PHY84793_HC_LANE0; lane < PHY84793_LN_MAX_NO_LANE; 3956 lane ++) { 3957 if ((cfg_tx_set & POL_LANE_MASK(lane)) == POL_LANE_MASK(lane)) { 3958 enable = 0; 3959 } else { 3960 enable = 1; 3961 } 3962 if (lane <= PHY84793_VSR40_LANE3) { 3963 SOC_IF_ERROR_RETURN 3964 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3965 CTL_REGS_FRC_VSR40_TX_PD, lane, lane, 1)); 3966 SOC_IF_ERROR_RETURN 3967 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3968 CTL_REGS_VSR40_TX_PD, 3969 (CTL_REGS_VSR40_TX_PD_VSR40_TX_PWRDN_SHIFT + lane), 3970 (CTL_REGS_VSR40_TX_PD_VSR40_TX_PWRDN_SHIFT + lane), enable)); 3971 } else { 3972 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 3973 if (lane == 4 || lane ==9) { 3974 return SOC_E_NONE; 3975 } 3976 } 3977 SOC_IF_ERROR_RETURN 3978 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3979 CTL_REGS_FRC_HCTX_PD, 3980 (CTL_REGS_FRC_HCTX_PD_FRC_HCTX_PWRDN_SHIFT + (lane-4)), 3981 (CTL_REGS_FRC_HCTX_PD_FRC_HCTX_PWRDN_SHIFT + (lane-4)), 1)); 3982 SOC_IF_ERROR_RETURN 3983 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 3984 CTL_REGS_HCTX_PD, (CTL_REGS_HCTX_PD_HCTX_PWRDN_SHIFT + (lane-4)), 3985 (CTL_REGS_HCTX_PD_HCTX_PWRDN_SHIFT + (lane-4)), enable)); 3986 } 3987 } 3988 } 3989 return SOC_E_NONE; 3990 } 3991 3992 /* 3993 * Squelch enable/disable 3994 */ 3995 STATIC int32 3996 _phy_84793_sys_lane_squelch_enable (int32 unit, soc_port_t port, uint8 lane, 3997 uint8 enable) 3998 { 3999 phy_ctrl_t *pc; 4000 uint16 mode = 0; 4001 4002 pc = EXT_PHY_SW_STATE(unit, port); 4003 PHY84793_GET_PORT_MODE(pc, mode); 4004 4005 if(mode == PHY84793_MODE_4X10G_TO_4X10G) { 4006 if (lane == 4 || lane == 9) { 4007 return SOC_E_NONE; 4008 } 4009 } 4010 4011 /* SYStem side Tx squelch */ 4012 SOC_IF_ERROR_RETURN 4013 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_FRC_DCTX_PD, 4014 CTL_REGS_FRC_DCTX_PD_FRC_DCTX_PWRDN_SHIFT + lane, 4015 CTL_REGS_FRC_DCTX_PD_FRC_DCTX_PWRDN_SHIFT + lane, 1)); 4016 SOC_IF_ERROR_RETURN 4017 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_DCTX_PD, 4018 CTL_REGS_DCTX_PD_DCTX_PWRDN_SHIFT + lane, 4019 CTL_REGS_DCTX_PD_DCTX_PWRDN_SHIFT + lane, enable)); 4020 return SOC_E_NONE; 4021 } 4022 4023 STATIC int32 4024 _phy_84793_line_lane_squelch_enable (int32 unit, soc_port_t port, uint8 lane, 4025 uint8 enable) 4026 { 4027 phy_ctrl_t *pc; 4028 uint16 mode = 0; 4029 4030 CHECK_LANE(lane); 4031 pc = EXT_PHY_SW_STATE(unit, port); 4032 PHY84793_GET_PORT_MODE(pc, mode); 4033 4034 if(mode == PHY84793_MODE_4X10G_TO_4X10G) { 4035 if (lane == 4 || lane == 9) { 4036 return SOC_E_NONE; 4037 } 4038 } 4039 4040 if (lane <= PHY84793_VSR40_LANE3) { 4041 SOC_IF_ERROR_RETURN 4042 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_FRC_VSR40_TX_PD, 4043 CTL_REGS_FRC_VSR40_TX_PD_FRC_VSR40_TX_PWRDN_SHIFT + lane, 4044 CTL_REGS_FRC_VSR40_TX_PD_FRC_VSR40_TX_PWRDN_SHIFT + lane, 1)); 4045 SOC_IF_ERROR_RETURN 4046 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_VSR40_TX_PD, 4047 CTL_REGS_VSR40_TX_PD_VSR40_TX_PWRDN_SHIFT + lane, 4048 CTL_REGS_VSR40_TX_PD_VSR40_TX_PWRDN_SHIFT + lane, enable)); 4049 } else { 4050 if (mode != PHY84793_MODE_10X10G_TO_4X25G) { 4051 lane -=4; 4052 SOC_IF_ERROR_RETURN 4053 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_FRC_HCTX_PD, 4054 CTL_REGS_FRC_HCTX_PD_FRC_HCTX_PWRDN_SHIFT + lane, 4055 CTL_REGS_FRC_HCTX_PD_FRC_HCTX_PWRDN_SHIFT + lane, 1)); 4056 SOC_IF_ERROR_RETURN 4057 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_HCTX_PD, 4058 CTL_REGS_HCTX_PD_HCTX_PWRDN_SHIFT + lane, 4059 CTL_REGS_HCTX_PD_HCTX_PWRDN_SHIFT + lane, enable)); 4060 } 4061 } 4062 4063 return SOC_E_NONE; 4064 } 4065 4066 STATIC int32 4067 _phy_84793_squelch_enable(int32 unit, soc_port_t port, 4068 PHY84793_INTF_SIDE intf_side, 4069 uint8 enable) 4070 { 4071 uint16 lane = 0; 4072 if (intf_side == PHY84793_SYS_SIDE) { 4073 for (lane = PHY84793_DC_LANE0; lane<= PHY84793_DC_LANE9; lane ++) { 4074 SOC_IF_ERROR_RETURN 4075 (_phy_84793_sys_lane_squelch_enable (unit, port, lane, enable)); 4076 } 4077 } else if (intf_side == PHY84793_LINE_SIDE) { 4078 for (lane = 0; lane<= 9; lane ++) { 4079 SOC_IF_ERROR_RETURN 4080 (_phy_84793_line_lane_squelch_enable (unit, port, lane, enable)); 4081 } 4082 } else { 4083 return SOC_E_PARAM; 4084 } 4085 4086 return SOC_E_NONE; 4087 } 4088 4089 STATIC int32 4090 _phy_84793_control_tx_preemphsis_get (int32 unit, soc_port_t port, 4091 PHY84793_INTF_SIDE intf_side, 4092 uint32 *value) 4093 { 4094 phy_ctrl_t *pc; 4095 4096 pc = EXT_PHY_SW_STATE(unit, port); 4097 4098 SOC_IF_ERROR_RETURN 4099 (_phy_84793_per_lane_control_tx_preemphasis_get (unit, port, intf_side, 4100 pc->lane_num, value)); 4101 return SOC_E_NONE; 4102 } 4103 4104 4105 4106 STATIC int32 4107 _phy_84793_per_lane_control_tx_preemphasis_get (int32 unit, soc_port_t port, 4108 PHY84793_INTF_SIDE intf_side, 4109 uint16 lane, uint32 *value) 4110 { 4111 uint32 tx_lane_base_add = 0; 4112 uint16 temp = 0; 4113 uint16 rddata = 0, post_cursor1 = 0; 4114 phy_ctrl_t *pc; 4115 4116 CHECK_LANE(lane); 4117 pc = EXT_PHY_SW_STATE(unit, port); 4118 4119 if (intf_side == PHY84793_LINE_SIDE) { 4120 if (lane <= PHY84793_VSR40_LANE3) { 4121 /* Value format: bit 14:11: pre_tap bit 10:06: post_tap 4122 bit 05:00: main_tap */ 4123 switch (lane) { 4124 case 0: 4125 tx_lane_base_add = VSR40_TX_ANA_LANE0_BASE; 4126 break; 4127 case 1: 4128 tx_lane_base_add = VSR40_TX_ANA_LANE1_BASE; 4129 break; 4130 case 2: 4131 tx_lane_base_add = VSR40_TX_ANA_LANE2_BASE; 4132 break; 4133 case 3: 4134 tx_lane_base_add = VSR40_TX_ANA_LANE3_BASE; 4135 break; 4136 } 4137 SOC_IF_ERROR_RETURN 4138 (READ_PHY84793_PMA_PMD_REG(unit, pc,(uint16) (tx_lane_base_add + 4139 VSR40_TX_ANA25G_CONTROL5) , &rddata)); 4140 *value = (rddata & 0x3FFF); 4141 } else { 4142 /* Value format: bit 4:0 - post cursor1 bit7:5 - post cursor2 4143 bit 13:8-main_tap */ 4144 lane = lane -4; 4145 tx_lane_base_add = (lane<<16) | 0x8066; 4146 PHY_84793_HCTX_PCB_READ(unit, pc, tx_lane_base_add, &rddata); 4147 4148 tx_lane_base_add = (lane<<16) | 0x8067; 4149 PHY_84793_HCTX_PCB_READ(unit, pc, tx_lane_base_add, &temp); 4150 post_cursor1 = ((temp & 0x7)<<2)|((rddata & 0xc000) >> 14); 4151 *value = ((temp & 0x1f8) << 5) | ((rddata & 0x3800)>>6) | post_cursor1; 4152 } 4153 } else { 4154 /* Value format: bit 4:0 - post cursor1 bit7:5 - post cursor2 4155 bit 13:8-main_tap */ 4156 tx_lane_base_add = (lane<<16) | 0x8066; 4157 SOC_IF_ERROR_RETURN 4158 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 4159 tx_lane_base_add, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 4160 4161 tx_lane_base_add = (lane << 16) | 0x8067; 4162 SOC_IF_ERROR_RETURN 4163 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 4164 tx_lane_base_add, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &temp)); 4165 4166 post_cursor1 = ((temp & 0x7)<<2)|((rddata & 0xc000) >> 14); 4167 4168 *value = ((temp & 0x1f8) << 5) | ((rddata & 0x3800)>>6) | post_cursor1; 4169 } 4170 return SOC_E_NONE; 4171 } 4172 4173 STATIC int32 4174 _phy_84793_per_lane_control_tx_preemphasis_set (int32 unit, soc_port_t port, 4175 PHY84793_INTF_SIDE intf_side, 4176 uint16 lane, uint32 value) 4177 { 4178 uint32 tx_lane_base_add = 0; 4179 uint16 post_cursor1 = 0, post_cursor2 = 0, main_tap = 0; 4180 uint16 rddata = 0; 4181 phy_ctrl_t *pc; 4182 4183 CHECK_LANE(lane); 4184 pc = EXT_PHY_SW_STATE(unit, port); 4185 4186 if (intf_side == PHY84793_LINE_SIDE) { 4187 if (lane <= PHY84793_VSR40_LANE3) { 4188 /* Value format: bit 14:11: pre_tap bit 10:06: post_tap 4189 bit 05:00: main_tap */ 4190 switch (lane) { 4191 case 0: 4192 tx_lane_base_add = VSR40_TX_ANA_LANE0_BASE; 4193 break; 4194 case 1: 4195 tx_lane_base_add = VSR40_TX_ANA_LANE1_BASE; 4196 break; 4197 case 2: 4198 tx_lane_base_add = VSR40_TX_ANA_LANE2_BASE; 4199 break; 4200 case 3: 4201 tx_lane_base_add = VSR40_TX_ANA_LANE3_BASE; 4202 break; 4203 } 4204 SOC_IF_ERROR_RETURN 4205 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 4206 (uint16)tx_lane_base_add + VSR40_TX_ANA25G_CONTROL5, 4207 VSR40_TX_ANA25G_CONTROL5_PRE_TAP_SHIFT+3, 4208 VSR40_TX_ANA25G_CONTROL5_MAIN_TAP_SHIFT, (uint16)value)); 4209 } else { 4210 /* Value format: bit 4:0 - post cursor1 bit7:5 - post cursor2 4211 bit 13:8-main_tap */ 4212 post_cursor1 = (value & 0x1F); 4213 post_cursor2 = (value & 0xE0) >> 5; 4214 main_tap = (value & 0x3F00) >> 8; 4215 lane = lane-4; 4216 tx_lane_base_add = (lane<<16) | 0x8066; 4217 4218 PHY_84793_HCTX_PCB_READ(unit,pc,tx_lane_base_add, &rddata); 4219 4220 rddata = (rddata & 0x07ff) | ((post_cursor2 & 0x7) <<11)| 4221 ((post_cursor1 & 0x3) << 14); 4222 4223 PHY_84793_HCTX_PCB_WRITE(unit, pc, tx_lane_base_add, rddata); 4224 tx_lane_base_add = (lane<<16) | 0x8067; 4225 4226 PHY_84793_HCTX_PCB_READ(unit,pc,tx_lane_base_add, &rddata); 4227 rddata = (rddata & 0xFE00) | ((main_tap & 0x3F) << 3) | 4228 ((post_cursor1>>2) & 0x7); 4229 4230 PHY_84793_HCTX_PCB_WRITE(unit, pc, tx_lane_base_add, rddata); 4231 } 4232 } else { 4233 /* Value format: bit 4:0 - post cursor1 bit7:5 - post cursor2 4234 bit 13:8-main_tap */ 4235 post_cursor1 = (value & 0x1F); 4236 post_cursor2 = (value & 0xE0) >> 5; 4237 main_tap = (value & 0x3F00) >> 8; 4238 tx_lane_base_add = (lane<<16) | 0x8066; 4239 SOC_IF_ERROR_RETURN 4240 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 4241 tx_lane_base_add, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 4242 rddata = (rddata & 0x07ff) | ((post_cursor2 & 0x7) <<11)| 4243 ((post_cursor1 & 0x3) << 14); 4244 4245 SOC_IF_ERROR_RETURN 4246 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 4247 tx_lane_base_add, rddata)); 4248 4249 tx_lane_base_add = (lane<<16) | 0x8067; 4250 SOC_IF_ERROR_RETURN 4251 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 4252 tx_lane_base_add, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 4253 rddata = (rddata & 0xFE00) | ((main_tap & 0x3F) << 3) | 4254 ((post_cursor1>>2) & 0x7); 4255 4256 SOC_IF_ERROR_RETURN 4257 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 4258 tx_lane_base_add, rddata)); 4259 } 4260 return SOC_E_NONE; 4261 } 4262 4263 STATIC int32 4264 _phy_84793_control_tx_preemphsis_set (int32 unit, soc_port_t port, 4265 soc_phy_control_t type, 4266 PHY84793_INTF_SIDE intf_side, 4267 uint32 value) 4268 { 4269 uint16 lane = 0; 4270 4271 for (lane = 0; lane < PHY84793_LN_MAX_NO_LANE;lane ++) { 4272 SOC_IF_ERROR_RETURN 4273 (_phy_84793_per_lane_control_tx_preemphasis_set (unit, port, intf_side, 4274 lane, value)); 4275 } 4276 return SOC_E_NONE; 4277 } 4278 4279 STATIC int32 4280 _phy_84793_control_tx_driver_set (int32 unit, soc_port_t port, 4281 soc_phy_control_t type, 4282 PHY84793_INTF_SIDE intf_side, uint32 value) 4283 { 4284 uint16 lane = 0; 4285 4286 for (lane = 0; lane < PHY84793_LN_MAX_NO_LANE;lane ++) { 4287 SOC_IF_ERROR_RETURN 4288 (_phy_84793_per_lane_control_tx_driver_set (unit, port, type, 4289 intf_side, lane, value)); 4290 } 4291 return SOC_E_NONE; 4292 } 4293 4294 STATIC int32 4295 _phy_84793_control_tx_driver_get (int32 unit, soc_port_t port, 4296 soc_phy_control_t type, 4297 PHY84793_INTF_SIDE intf_side, 4298 uint32 *value) 4299 { 4300 phy_ctrl_t *pc; 4301 4302 pc = EXT_PHY_SW_STATE(unit, port); 4303 4304 SOC_IF_ERROR_RETURN 4305 (_phy_84793_per_lane_control_tx_driver_get (unit, port, type, intf_side, 4306 pc->lane_num, value)); 4307 return SOC_E_NONE; 4308 } 4309 4310 STATIC int32 4311 _phy_84793_per_lane_control_tx_driver_get (int32 unit, soc_port_t port, 4312 soc_phy_control_t type, 4313 PHY84793_INTF_SIDE intf_side, 4314 uint16 lane, uint32 *value) 4315 { 4316 uint16 start_bit = 0, rddata = 0; 4317 uint32 tx_lane_base_add = 0; 4318 phy_ctrl_t *pc; 4319 4320 CHECK_LANE(lane); 4321 pc = EXT_PHY_SW_STATE(unit, port); 4322 4323 switch (type) { 4324 case SOC_PHY_CONTROL_DRIVER_CURRENT: 4325 start_bit = 0; 4326 type = SOC_PHY_CONTROL_DRIVER_CURRENT; 4327 break; 4328 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 4329 type = SOC_PHY_CONTROL_PRE_DRIVER_CURRENT; 4330 start_bit = VSR40_TX_ANA25G_CONTROL1_IPREDRIVER_SHIFT; 4331 break; 4332 default: 4333 return SOC_E_PARAM; 4334 } 4335 switch (lane) { 4336 case 0: 4337 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4338 VSR40_TX_ANA_LANE0_BASE:((lane<<16)|0x8065); 4339 break; 4340 case 1: 4341 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4342 VSR40_TX_ANA_LANE1_BASE:((lane<<16)|0x8065); 4343 break; 4344 case 2: 4345 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4346 VSR40_TX_ANA_LANE2_BASE:((lane<<16)|0x8065); 4347 break; 4348 case 3: 4349 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4350 VSR40_TX_ANA_LANE3_BASE:((lane<<16)|0x8065); 4351 break; 4352 case 4: 4353 case 5: 4354 case 6: /* FALL THROUGH*/ 4355 case 7: 4356 case 8: 4357 case 9: 4358 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4359 (((lane-4)<<16)|0x8065):((lane<<16)|0x8065); 4360 break; 4361 } 4362 if (intf_side == PHY84793_LINE_SIDE) { 4363 if (lane <= PHY84793_VSR40_LANE3) { 4364 SOC_IF_ERROR_RETURN 4365 (READ_PHY84793_PMA_PMD_REG(unit, pc, (uint16)(tx_lane_base_add 4366 + VSR40_TX_ANA25G_CONTROL1), &rddata)); 4367 *value = GET_BIT_VAL(rddata, start_bit + 3, start_bit); 4368 } else { 4369 uint16 rddata = 0; 4370 PHY_84793_HCTX_PCB_READ(unit, pc, tx_lane_base_add, &rddata); 4371 4372 /* coverity[mixed_enums : FALSE] */ 4373 if (type == SOC_PHY_CONTROL_DRIVER_CURRENT) { 4374 *value = (rddata & 0xf000) >> 12; /*Bit 15:12*/ 4375 } else { 4376 *value = (rddata & 0x0f00) >> 8; /*Bit 11:8*/ 4377 } 4378 } 4379 } else { 4380 uint16 rddata = 0; 4381 SOC_IF_ERROR_RETURN 4382 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 4383 tx_lane_base_add, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 4384 4385 /* coverity[mixed_enums : FALSE] */ 4386 if (type == SOC_PHY_CONTROL_DRIVER_CURRENT) { 4387 *value = (rddata & 0xf000) >> 12; /*Bit 15:12*/ 4388 } else { 4389 *value = (rddata & 0x0f00) >> 8; /*Bit 11:8*/ 4390 } 4391 } 4392 return SOC_E_NONE; 4393 } 4394 4395 STATIC int32 4396 _phy_84793_per_lane_control_tx_driver_set (int32 unit, soc_port_t port, 4397 soc_phy_control_t type, 4398 PHY84793_INTF_SIDE intf_side, 4399 uint16 lane, uint32 value) 4400 { 4401 uint16 tmp = 0, start_bit = 0; 4402 uint32 tx_lane_base_add = 0; 4403 phy_ctrl_t *pc; 4404 4405 CHECK_LANE(lane); 4406 pc = EXT_PHY_SW_STATE(unit, port); 4407 4408 switch (type) { 4409 case SOC_PHY_CONTROL_DRIVER_CURRENT: 4410 tmp = (uint16) (value & VSR40_TX_ANA25G_CONTROL1_IDRIVER_MASK) ; 4411 start_bit = VSR40_TX_ANA25G_CONTROL1_IDRIVER_SHIFT; 4412 type = SOC_PHY_CONTROL_DRIVER_CURRENT; 4413 break; 4414 case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT: 4415 tmp = (uint16) value & 0xf; 4416 type = SOC_PHY_CONTROL_PRE_DRIVER_CURRENT; 4417 start_bit = VSR40_TX_ANA25G_CONTROL1_IPREDRIVER_SHIFT; 4418 break; 4419 default: 4420 return SOC_E_PARAM; 4421 } 4422 switch (lane) { 4423 case 0: 4424 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4425 VSR40_TX_ANA_LANE0_BASE:((lane<<16)|0x8065); 4426 break; 4427 case 1: 4428 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4429 VSR40_TX_ANA_LANE1_BASE:((lane<<16)|0x8065); 4430 break; 4431 case 2: 4432 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4433 VSR40_TX_ANA_LANE2_BASE:((lane<<16)|0x8065); 4434 break; 4435 case 3: 4436 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4437 VSR40_TX_ANA_LANE3_BASE:((lane<<16)|0x8065); 4438 break; 4439 case 4: 4440 case 5: 4441 case 6: 4442 case 7: 4443 case 8: 4444 case 9: 4445 tx_lane_base_add = (intf_side == PHY84793_LINE_SIDE)? 4446 (((lane-4)<<16)|0x8065):((lane<<16)|0x8065); 4447 break; 4448 } 4449 if (intf_side == PHY84793_LINE_SIDE) { 4450 if (lane <= PHY84793_VSR40_LANE3) { 4451 SOC_IF_ERROR_RETURN 4452 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, (uint16)tx_lane_base_add 4453 + VSR40_TX_ANA25G_CONTROL1, start_bit + 3, start_bit, tmp)); 4454 } else { 4455 uint16 rddata = 0; 4456 PHY_84793_HCTX_PCB_READ(unit, pc, tx_lane_base_add, &rddata); 4457 4458 /* coverity[mixed_enums:FALSE] */ 4459 if (type == SOC_PHY_CONTROL_DRIVER_CURRENT) { 4460 rddata &= 0x0fff; 4461 rddata |= tmp << 12; /*Bit 15:12*/ 4462 } else { 4463 rddata &= 0xf0ff; 4464 rddata |= tmp << 8; /*Bit 11:8*/ 4465 } 4466 PHY_84793_HCTX_PCB_WRITE(unit, pc, tx_lane_base_add, rddata); 4467 } 4468 } else { 4469 uint16 rddata = 0; 4470 SOC_IF_ERROR_RETURN 4471 (_phy_84793_dc_hc_pcb_read (unit, port, pc, PHY84793_DECA_CORE, 4472 tx_lane_base_add, PHY84793_DC_HC_RD_WIT_OUT_CLEAR, &rddata)); 4473 4474 /* coverity[mixed_enums:FALSE] */ 4475 if (type == SOC_PHY_CONTROL_DRIVER_CURRENT) { 4476 rddata &= 0x0fff; 4477 rddata |= tmp << 12; /*Bit 15:12*/ 4478 } else { 4479 rddata &= 0xf0ff; 4480 rddata |= tmp << 8; /*Bit 11:8*/ 4481 } 4482 SOC_IF_ERROR_RETURN 4483 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_DECA_CORE, 4484 tx_lane_base_add, rddata)); 4485 } 4486 4487 return SOC_E_NONE; 4488 } 4489 4490 STATIC int 4491 _phy_84793_rx_seq_done_get(int unit, soc_port_t port, int32 intf, uint32 *value) 4492 { 4493 uint16 lane = 0, rxseqdone = 0, rddata = 0; 4494 uint16 mode = 0; 4495 phy_ctrl_t *pc; /* PHY software state */ 4496 4497 pc = EXT_PHY_SW_STATE(unit, port); 4498 PHY84793_GET_PORT_MODE(pc, mode); 4499 4500 if (intf == PHY84793_LINE_SIDE) { 4501 SOC_IF_ERROR_RETURN(phy_84793_link_get(unit, port, (int32*)value)); 4502 } else { 4503 for (lane = 0; lane <=9; lane ++) { 4504 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_read (unit, port,pc, 4505 PHY84793_DECA_CORE , (lane<<16)|0x80b1, 0, &rddata)); 4506 rddata = rddata & (~(0x0007)); 4507 4508 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_write (unit, port, pc, 4509 PHY84793_DECA_CORE, (lane<<16), rddata)); 4510 sal_usleep(1000); 4511 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_read (unit, port,pc, 4512 PHY84793_DECA_CORE , (lane << 16)|0x80b0, 0, &rddata)); 4513 if ((rddata & 0x1000) == 0x1000) { 4514 rxseqdone ++; 4515 } 4516 } 4517 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 4518 *value = (rxseqdone == (lane-2)); 4519 } else { 4520 *value = (rxseqdone == lane); 4521 } 4522 } 4523 return SOC_E_NONE; 4524 } 4525 4526 STATIC int 4527 _phy_84793_per_lane_rx_seq_done_get(int unit, soc_port_t port, 4528 int32 intf, 4529 int lane, uint32 *value) 4530 { 4531 uint16 rddata = 0; 4532 uint16 mode = 0; 4533 phy_ctrl_t *pc; /* PHY software state */ 4534 4535 pc = EXT_PHY_SW_STATE(unit, port); 4536 PHY84793_GET_PORT_MODE(pc, mode); 4537 4538 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 4539 if (pc->lane_num) { 4540 /* If it is 2nd port */ 4541 /* lane should be between 5 to 8 */ 4542 lane = 5 + lane; 4543 } 4544 } 4545 if ((mode == PHY84793_MODE_10X10G_TO_4X25G) && (intf == PHY84793_LINE_SIDE) 4546 && (lane > PHY84793_VSR40_LANE3)) { 4547 return SOC_E_PARAM; 4548 } 4549 if (intf == PHY84793_LINE_SIDE) { 4550 if (lane <= PHY84793_VSR40_LANE3) { 4551 SOC_IF_ERROR_RETURN 4552 (READ_PHY84793_PMA_PMD_REG(unit, pc, 4553 VSR40_RX_DIG_REGS_CDR_CONTROL, &rddata)); 4554 *value = (rddata & 4555 (VSR40_RX_DIG_REGS_CDR_CONTROL_CDRLOCK_STATUS_LN0_MASK << lane)) ? 1 : 0; 4556 } else { 4557 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_read (unit, port,pc, 4558 PHY84793_HEXA_CORE , (lane<<16)|0x80b1, 0, &rddata)); 4559 rddata = rddata & (~(0x0007)); 4560 4561 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_write (unit, port, pc, 4562 PHY84793_HEXA_CORE, (lane<<16), rddata)); 4563 sal_usleep(1000); 4564 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_read (unit, port,pc, 4565 PHY84793_HEXA_CORE , (lane << 16)|0x80b0, 0, &rddata)); 4566 *value = (rddata & 0x1000) ? 1 : 0; 4567 } 4568 } else { 4569 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_read (unit, port,pc, 4570 PHY84793_DECA_CORE , (lane<<16)|0x80b1, 0, &rddata)); 4571 rddata = rddata & (~(0x0007)); 4572 4573 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_write (unit, port, pc, 4574 PHY84793_DECA_CORE, (lane<<16), rddata)); 4575 sal_usleep(1000); 4576 SOC_IF_ERROR_RETURN(_phy_84793_dc_hc_pcb_read (unit, port,pc, 4577 PHY84793_DECA_CORE , (lane << 16)|0x80b0, 0, &rddata)); 4578 *value = (rddata & 0x1000) ? 1 : 0; 4579 } 4580 return SOC_E_NONE; 4581 } 4582 4583 STATIC int32 4584 _phy_84793_remote_loopback_set(int32 unit, soc_port_t port, int32 enable) 4585 { 4586 phy_ctrl_t *pc; 4587 uint16 mode = 0; 4588 4589 pc = EXT_PHY_SW_STATE(unit, port); 4590 PHY84793_GET_PORT_MODE(pc, mode); 4591 4592 /* Squelch System side */ 4593 SOC_IF_ERROR_RETURN 4594 (_phy_84793_squelch_enable (unit, port, PHY84793_SYS_SIDE, enable)); 4595 4596 /*Enable Remote loopback*/ 4597 switch (mode) { 4598 case PHY84793_MODE_10X10G_TO_4X25G: 4599 /* Fall Thru */ 4600 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 4601 /* Fall Thru */ 4602 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 4603 SOC_IF_ERROR_RETURN 4604 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 4605 CTL_REGS_LINE_LOOPBACK_EN, 4606 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + 9, 4607 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT, 4608 enable?0x3ff:0)); 4609 4610 break; 4611 case PHY84793_MODE_4X10G_TO_4X10G: 4612 if (pc->lane_num == 0) { 4613 SOC_IF_ERROR_RETURN 4614 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 4615 CTL_REGS_LINE_LOOPBACK_EN, 4616 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + 3, 4617 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT, 4618 enable?0xf:0)); 4619 } else { 4620 SOC_IF_ERROR_RETURN 4621 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 4622 CTL_REGS_LINE_LOOPBACK_EN, 4623 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT+8, 4624 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT+ 5, 4625 enable?0xf:0)); 4626 } 4627 break; 4628 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 4629 SOC_IF_ERROR_RETURN 4630 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 4631 CTL_REGS_LINE_LOOPBACK_EN, 4632 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + pc->lane_num, 4633 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + pc->lane_num, enable)); 4634 break; 4635 } 4636 return SOC_E_NONE; 4637 } 4638 4639 STATIC int32 4640 _phy_84793_local_loopback_set(int32 unit, soc_port_t port, int32 enable) 4641 { 4642 phy_ctrl_t *pc; 4643 uint16 mode = 0; 4644 uint16 start_lane = 0, end_lane = 0; 4645 4646 pc = EXT_PHY_SW_STATE(unit, port); 4647 PHY84793_GET_PORT_MODE(pc, mode); 4648 4649 /*Enable Line side(Remote)loopback*/ 4650 switch (mode) { 4651 case PHY84793_MODE_10X10G_TO_4X25G: 4652 /* Fall Thru */ 4653 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 4654 /* Fall Thru */ 4655 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 4656 /* Disable(Enable) Squelch when we Enable(Disable) loopback */ 4657 SOC_IF_ERROR_RETURN 4658 (_phy_84793_squelch_enable (unit, port, PHY84793_LINE_SIDE, enable)); 4659 4660 SOC_IF_ERROR_RETURN 4661 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, CTL_REGS_SYS_LOOPBACK_EN, 4662 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + 9 , 4663 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT , enable?0x3ff:0)); 4664 break; 4665 4666 case PHY84793_MODE_4X10G_TO_4X10G: 4667 if (pc->lane_num == PHY84793_VSR40_LANE0) { 4668 start_lane = 0; 4669 end_lane = 3; 4670 } else { 4671 start_lane = 5; 4672 end_lane=8; 4673 } 4674 for (;start_lane <= end_lane; start_lane++) { 4675 /* Disable(Enable) Squelch when we Enable(Disable) loopback */ 4676 SOC_IF_ERROR_RETURN 4677 (_phy_84793_line_lane_squelch_enable (unit, port, start_lane, 4678 enable)); 4679 4680 SOC_IF_ERROR_RETURN 4681 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 4682 CTL_REGS_SYS_LOOPBACK_EN, 4683 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + start_lane , 4684 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + start_lane, 4685 enable)); 4686 } 4687 break; 4688 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 4689 /* Disable(Enable) Squelch when we Enable(Disable) loopback */ 4690 SOC_IF_ERROR_RETURN 4691 (_phy_84793_line_lane_squelch_enable (unit, port, pc->lane_num, 4692 enable)); 4693 4694 SOC_IF_ERROR_RETURN 4695 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, 4696 CTL_REGS_SYS_LOOPBACK_EN, 4697 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + pc->lane_num, 4698 CTL_REGS_SYS_LOOPBACK_EN_SYS_LPBK_EN_SHIFT + pc->lane_num, 4699 enable)); 4700 break; 4701 } 4702 return SOC_E_NONE; 4703 } 4704 4705 /* 4706 * Function: 4707 * phy_84793_lb_set 4708 * Purpose: 4709 * Put 84793 in PHY PMA/PMD loopback 4710 * Parameters: 4711 * unit - StrataSwitch unit #. 4712 * port - StrataSwitch port #. 4713 * enable - binary value for on/off (1/0) 4714 * Returns: 4715 * SOC_E_NONE 4716 */ 4717 4718 STATIC int32 4719 phy_84793_lb_set (int32 unit, soc_port_t port, int32 enable) 4720 { 4721 4722 SOC_IF_ERROR_RETURN 4723 (_phy_84793_local_loopback_set (unit, port, enable)); 4724 return SOC_E_NONE; 4725 } 4726 4727 STATIC 4728 int32 _phy_84793_init_pass2 (int32 unit, soc_port_t port) 4729 { 4730 phy_ctrl_t *pc; 4731 phy84793_intf_cfg_t *interface; 4732 uint16 if_sys_idx = 0; 4733 uint16 force_dload = 0, data16 = 0; 4734 4735 LOG_INFO(BSL_LS_SOC_PHY, 4736 (BSL_META_U(unit, 4737 "PHY84793 init pass2: u=%d p=%d\n"), unit, port)); 4738 pc = EXT_PHY_SW_STATE(unit, port); 4739 4740 /* 4741 * - interfaces are XAUI/XLAUI/SR/SR10 4742 * - line side mode can be changed dynamically 4743 * - configured specifically with interface set and/or by matching speed 4744 * 4745 * port mode system side 4746 * ---------------- ------------------------ 4747 * 100G dflt: CAUI 4748 * 40G XLAUI 4749 * 10G(sync) SR10 4750 * 10G(async) SR 4751 */ 4752 4753 interface = &(INTERFACE(pc)); 4754 sal_memset(interface, 0, sizeof(phy84793_intf_cfg_t)); 4755 4756 pc->flags |= PHYCTRL_INIT_DONE; 4757 force_dload = soc_property_port_get(unit, port, 4758 spn_PHY_FORCE_FIRMWARE_LOAD, FALSE); 4759 if (force_dload) { 4760 SOC_IF_ERROR_RETURN 4761 (_phy_84793_rom_firmware_download (unit, port, 4762 PHY84793_FW_DLOAD_OFFSET, 4763 pc, phy84793_ucode_bin, phy84793_ucode_bin_len)); 4764 } else { 4765 SOC_IF_ERROR_RETURN( 4766 READ_PHY84793_PMA_PMD_REG(unit, pc, COMMON_POR_REGS_BOOT_POR, &data16)); 4767 if ((data16 & 0x2000) != 0x2000) { 4768 SOC_IF_ERROR_RETURN 4769 (_phy_84793_rom_firmware_download (unit, port, 4770 PHY84793_FW_DLOAD_OFFSET, 4771 pc, phy84793_ucode_bin, phy84793_ucode_bin_len)); 4772 } else { 4773 LOG_VERBOSE(BSL_LS_SOC_PHY, 4774 (BSL_META_U(unit, 4775 "FW is already downloaded!!. Use spn_PHY_FORCE_FIRMWARE_LOAD" 4776 "to force download the micro\n"))); 4777 } 4778 } 4779 /* Get configured system interface */ 4780 if_sys_idx = soc_property_port_get(unit, port, spn_PHY_SYS_INTERFACE, 0); 4781 if (if_sys_idx >= (sizeof(phy_84793_sys_to_port_if)/sizeof(soc_port_if_t))) { 4782 LOG_ERROR(BSL_LS_SOC_PHY, \ 4783 (BSL_META_U(unit, \ 4784 "PHY84793 invalid system side\ 4785 interface: u=%d p=%d intf=%d\n" 4786 "Using default interface\n"), 4787 unit, port, if_sys_idx)); 4788 if_sys_idx = 0; 4789 } 4790 4791 interface->type = phy_84793_sys_to_port_if[if_sys_idx]; 4792 if (interface->type == 0) { 4793 /* Set the Default system interface */ 4794 interface->type = SOC_PORT_IF_SR4; 4795 interface->speed = PHY84793_MODE1_SPD; 4796 } else { 4797 switch (interface->type) { 4798 case SOC_PORT_IF_SR4: 4799 /* If interface is SR4 use the configured speed 4800 * dont modify the speed, because SR4 shares 100 and 40G*/ 4801 break; 4802 case SOC_PORT_IF_SR10: 4803 interface->speed = PHY84793_MODE3_SPD; 4804 break; 4805 case SOC_PORT_IF_SR: 4806 interface->speed = PHY84793_MODE4_SPD; 4807 break; 4808 case SOC_PORT_IF_OTL: 4809 interface->speed = PHY84793_MODE5_SPD; 4810 break; 4811 default: 4812 break; 4813 } 4814 SOC_IF_ERROR_RETURN( 4815 _phy_84793_speed_set(unit, port, interface->speed)); 4816 } 4817 return SOC_E_NONE; 4818 } 4819 4820 STATIC int32 4821 _phy_84793_config_update(int32 unit, soc_port_t port) 4822 { 4823 phy_ctrl_t *pc; 4824 pc = EXT_PHY_SW_STATE(unit, port); 4825 4826 LOG_INFO(BSL_LS_SOC_PHY, 4827 (BSL_META_U(unit, 4828 "PHY84793 INIT: u=%d p=%d TX Pol=0x%x RX Pol:0x%x\n"), 4829 unit, port,POL_TX_CFG(pc), POL_RX_CFG(pc))); 4830 return _phy_84793_line_polarity_flip(unit, port, pc, POL_TX_CFG(pc), POL_RX_CFG(pc)); 4831 } 4832 4833 STATIC 4834 int32 phy_84793_init(int32 unit, soc_port_t port) 4835 { 4836 uint32 devid = 0; 4837 phy_ctrl_t *pc; 4838 uint16 len = 0; 4839 soc_phy_info_t *pi; 4840 char *dev_name; 4841 soc_info_t *si; 4842 int phy_port; /* physical port number */ 4843 4844 4845 pc = EXT_PHY_SW_STATE(unit, port); 4846 dev_name = DEV_NAME(pc); 4847 4848 LOG_INFO(BSL_LS_SOC_PHY, 4849 (BSL_META_U(unit, 4850 "PHY84793 init: u=%d p=%d state=%d\n"), 4851 unit, port,PHYCTRL_INIT_STATE(pc))); 4852 4853 if ((PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS1) || 4854 (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_DEFAULT)) { 4855 PHY_FLAGS_SET(unit, port, PHY_FLAGS_FIBER | PHY_FLAGS_C45); 4856 4857 /* READ DEVICE IDENTIFICATION REG TO IDENTIFY THE REG */ 4858 SOC_IF_ERROR_RETURN(_phy_84793_dev_id_get(unit, port, pc, &devid)); 4859 DEVID(pc) = devid; 4860 /* indicate second pass of init is needed */ 4861 PHYCTRL_INIT_STATE_SET(pc,PHYCTRL_INIT_STATE_PASS2); 4862 return SOC_E_NONE; 4863 } 4864 4865 if ((PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS2) || 4866 (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_DEFAULT)) { 4867 LOG_INFO(BSL_LS_SOC_PHY, 4868 (BSL_META_U(unit, 4869 "PHY84793 init pass2: u=%d p=%d\n"), unit, port)); 4870 SOC_IF_ERROR_RETURN(_phy_84793_init_pass2(unit, port)); 4871 } 4872 si = &SOC_INFO(unit); 4873 if (soc_feature(unit, soc_feature_logical_port_num)) { 4874 phy_port = si->port_l2p_mapping[port]; 4875 } else { 4876 phy_port = port; 4877 } 4878 4879 if (SOC_IS_TRIUMPH3(unit)) { 4880 pc->lane_num = SOC_PORT_BINDEX(unit, phy_port); 4881 } else { 4882 /* For trident and other switch*/ 4883 pc->lane_num = SOC_PORT_BINDEX(unit, phy_port) + (4 * SOC_BLOCK_NUMBER(unit, SOC_PORT_BLOCK(unit, port))); 4884 4885 pc->lane_num %= 10; 4886 } 4887 /* convert to phy_ctrl macros */ 4888 if (SOC_PBMP_MEMBER(PBMP_IL_ALL(unit), pc->port)) { 4889 pc->phy_mode = PHYCTRL_MULTI_CORE_PORT; 4890 pc->flags |= PHYCTRL_MDIO_ADDR_SHARE; 4891 } else if (si->port_num_lanes[port] == 4) { 4892 pc->phy_mode = PHYCTRL_QUAD_LANE_PORT; 4893 } else if (si->port_num_lanes[port] == 1) { 4894 pc->phy_mode = PHYCTRL_ONE_LANE_PORT; 4895 pc->flags |= PHYCTRL_MDIO_ADDR_SHARE; 4896 } else if (si->port_num_lanes[port] >= 10) { 4897 pc->phy_mode = PHYCTRL_MULTI_CORE_PORT; 4898 pc->flags |= PHYCTRL_MDIO_ADDR_SHARE; 4899 } 4900 4901 pi = &SOC_PHY_INFO(unit, port); 4902 if (DEVID(pc) == PHY84793_ID_84793) { 4903 /* coverity[secure_coding] */ 4904 sal_strcpy (dev_name, "BCM84793"); 4905 } else if (DEVID(pc) == PHY84793_ID_84790) { 4906 /* coverity[secure_coding] */ 4907 sal_strcpy (dev_name, "BCM84790"); 4908 } else if (DEVID(pc) == PHY84793_ID_84794) { 4909 /* coverity[secure_coding] */ 4910 sal_strcpy (dev_name, "BCM84794"); 4911 } 4912 len = sal_strlen(dev_name); 4913 4914 /* phy_mode: 1 Single port mode, port uses 1 lanes 4915 * 4 quad port mode, port uses 4 lane 4916 */ 4917 if (pc->phy_mode == PHYCTRL_ONE_LANE_PORT) { 4918 dev_name[len++] = '/'; 4919 PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE); 4920 dev_name[len++] = pc->lane_num + '0'; 4921 SOC_IF_ERROR_RETURN(phy_84793_speed_set (unit, port, PHY84793_MODE4_SPD)); 4922 } else if (pc->phy_mode == PHYCTRL_QUAD_LANE_PORT) { 4923 dev_name[len++] = '/'; 4924 dev_name[len++] = pc->lane_num + '0'; 4925 SOC_IF_ERROR_RETURN(phy_84793_speed_set (unit, port, PHY84793_MODE2_SPD)); 4926 } else { 4927 /*pc->dev_name[len++] = '4';*/ 4928 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_INDEPENDENT_LANE); 4929 } 4930 dev_name[len] = 0; 4931 pc->dev_name = dev_name; /* string terminator */ 4932 pi->phy_name = dev_name; 4933 4934 /* Polarity configuration is applied every time interface is configured */ 4935 POL_TX_CFG(pc) = (uint16) soc_property_port_get(unit, port, 4936 spn_PHY_TX_POLARITY_FLIP, PHY84793_POL_DND); 4937 POL_RX_CFG(pc) = (uint16) soc_property_port_get(unit, port, 4938 spn_PHY_RX_POLARITY_FLIP, PHY84793_POL_DND); 4939 4940 /* Push configuration to the device */ 4941 SOC_IF_ERROR_RETURN (_phy_84793_config_update(unit, port)); 4942 4943 return SOC_E_NONE; 4944 } 4945 4946 /* 4947 * Function: 4948 * phy_84793_link_get 4949 * Purpose: 4950 * Get layer2 connection status. 4951 * Parameters: 4952 * unit - StrataSwitch unit #. 4953 * port - StrataSwitch port # 4954 * . 4955 * link - address of memory to store link up/down state. 4956 * Returns: 4957 * SOC_E_NONE 4958 */ 4959 STATIC int32 4960 phy_84793_link_get(int32 unit, soc_port_t port, int32 *link) 4961 { 4962 phy_ctrl_t *pc; 4963 int16 mode = 0, lane = 0; 4964 phy_ctrl_t *int_pc; 4965 int32 int_phy_link; 4966 4967 if (link == NULL) { 4968 return SOC_E_PARAM; 4969 } 4970 4971 if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_DISABLE)) { 4972 *link = FALSE; 4973 return SOC_E_NONE; 4974 } 4975 pc = EXT_PHY_SW_STATE(unit, port); 4976 int_pc = INT_PHY_SW_STATE(unit, port); 4977 PHY84793_GET_PORT_MODE(pc, mode); 4978 4979 if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 4980 if(pc->lane_num == 0) { 4981 lane = 0; 4982 } 4983 else { 4984 lane = 5; 4985 } 4986 } else { 4987 lane = pc->lane_num; 4988 } 4989 /* 4990 * PCS from the internal PHY is used to determine link. 4991 */ 4992 if (int_pc != NULL) { 4993 SOC_IF_ERROR_RETURN(PHY_LINK_GET(int_pc->pd, unit, port, &int_phy_link)); 4994 } else { 4995 *link = 0; 4996 } 4997 4998 SOC_IF_ERROR_RETURN 4999 (phy_84793_per_lane_link_get(unit, port, lane, link)); 5000 5001 /* When CDR lock of 84793 is not Set, Leave the port link as 5002 * CDR status of 84793. When CDR lock of 84793 is set use 5003 * PCS status of internal serdes as port link status. 5004 * When internal serdes is not there use 84793 CDR as link status*/ 5005 if (*link && int_pc) { 5006 *link = int_phy_link; 5007 } 5008 5009 LOG_VERBOSE(BSL_LS_SOC_PHY, 5010 (BSL_META_U(unit, 5011 "phy_84793_link_get: u=%d port%d: link:%s\n"), 5012 unit, port, *link ? "Up": "Down")); 5013 5014 return SOC_E_NONE; 5015 } 5016 5017 STATIC int32 5018 phy_84793_per_lane_link_get(int32 unit, soc_port_t port, uint16 lane, int32 *link) 5019 { 5020 uint16 mode = 0, link_stat = 0; 5021 uint16 rx_seq_done = 0, hclane = 0; 5022 phy_ctrl_t *pc; 5023 pc = EXT_PHY_SW_STATE(unit, port); 5024 5025 PHY84793_GET_PORT_MODE(pc, mode); 5026 5027 switch (mode) { 5028 case PHY84793_MODE_10X10G_TO_4X25G: 5029 /* Fall Thru */ 5030 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 5031 SOC_IF_ERROR_RETURN(SET_PHY84793_SLICE(unit, pc, PHY84793_SLICE_0)); 5032 SOC_IF_ERROR_RETURN 5033 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5034 IEEE_PMA_PMD_REGS_PMA_PMD_STATUS_1, &link_stat)); 5035 5036 *link = GET_BIT_VAL(link_stat, 2, 2); 5037 break; 5038 case PHY84793_MODE_4X10G_TO_4X10G: 5039 if (pc->lane_num <= 3) { 5040 SOC_IF_ERROR_RETURN 5041 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5042 VSR40_RX_DIG_REGS_CDR_CONTROL, &link_stat)); 5043 *link = (((link_stat & 0xF0) == 0xF0)? 1 : 0); 5044 5045 } else { 5046 for (hclane = 1; hclane <=4; hclane ++) { 5047 SOC_IF_ERROR_RETURN 5048 (_phy_84793_dc_hc_pcb_read (unit, port,pc, 5049 PHY84793_HEXA_CORE , (hclane<<16)|0x80b1, 0, &link_stat)); 5050 link_stat = link_stat & (~(0x0007)); 5051 SOC_IF_ERROR_RETURN 5052 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_HEXA_CORE, 5053 (hclane<<16), link_stat)); 5054 SOC_IF_ERROR_RETURN 5055 (_phy_84793_dc_hc_pcb_read (unit, port,pc, 5056 PHY84793_HEXA_CORE , (hclane << 16)|0x80b0, 0, &link_stat)); 5057 if ((link_stat & 0x1000) == 0x1000) { 5058 rx_seq_done ++; 5059 } 5060 } 5061 *link = (rx_seq_done == 4); 5062 } 5063 5064 break; 5065 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 5066 *link =1; 5067 for (lane = 0; lane <=9; lane ++) { 5068 if (lane <4) { 5069 SOC_IF_ERROR_RETURN 5070 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5071 VSR40_RX_DIG_REGS_CDR_CONTROL, &link_stat)); 5072 *link &= ((link_stat & 5073 (1 << (lane+VSR40_RX_DIG_REGS_CDR_CONTROL_CDRLOCK_STATUS_LN0_SHIFT))) 5074 ? 1 : 0); 5075 } else { 5076 SOC_IF_ERROR_RETURN 5077 (_phy_84793_dc_hc_pcb_read (unit, port,pc, 5078 PHY84793_HEXA_CORE , ((lane-4)<<16)|0x80b1, 0, &link_stat)); 5079 link_stat = link_stat & (~(0x0007)); 5080 SOC_IF_ERROR_RETURN 5081 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_HEXA_CORE, 5082 ((lane-4)<<16), link_stat)); 5083 SOC_IF_ERROR_RETURN 5084 (_phy_84793_dc_hc_pcb_read (unit, port,pc, 5085 PHY84793_HEXA_CORE , ((lane-4) << 16)|0x80b0, 0, &link_stat)); 5086 if ((link_stat & 0x1000) == 0x1000) { 5087 *link &= 1; 5088 } else { 5089 *link &= 0; 5090 } 5091 } 5092 } 5093 break; 5094 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 5095 if (lane < 4) { 5096 SOC_IF_ERROR_RETURN 5097 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5098 VSR40_RX_DIG_REGS_CDR_CONTROL, &link_stat)); 5099 *link = ((link_stat & 5100 (1 << (lane + VSR40_RX_DIG_REGS_CDR_CONTROL_CDRLOCK_STATUS_LN0_SHIFT))) 5101 ? 1 : 0); 5102 } else { 5103 SOC_IF_ERROR_RETURN 5104 (_phy_84793_dc_hc_pcb_read (unit, port,pc, 5105 PHY84793_HEXA_CORE , ((lane-4)<<16)|0x80b1, 0, &link_stat)); 5106 link_stat = link_stat & (~(0x0007)); 5107 SOC_IF_ERROR_RETURN 5108 (_phy_84793_dc_hc_pcb_write (unit, port, pc, PHY84793_HEXA_CORE, 5109 ((lane-4)<<16), link_stat)); 5110 SOC_IF_ERROR_RETURN 5111 (_phy_84793_dc_hc_pcb_read (unit, port,pc, 5112 PHY84793_HEXA_CORE , ((lane-4) << 16)|0x80b0, 0, &link_stat)); 5113 if ((link_stat & 0x1000) == 0x1000) { 5114 *link = 1; 5115 } else { 5116 *link = 0; 5117 } 5118 } 5119 break; 5120 } 5121 5122 return SOC_E_NONE; 5123 } 5124 5125 /* 5126 * Function: 5127 * phy_84793_reg_read 5128 * Purpose: 5129 * Routine to read PHY register 5130 * Parameters: 5131 * port - port number 5132 * flags - Flags which specify the register type 5133 * phy_reg_addr - Encoded register address 5134 * phy_data - (OUT) Value read from PHY register 5135 * Note: 5136 * This register read function is not thread safe. Higher level 5137 * function that calls this function must obtain a per port lock 5138 * to avoid overriding register page mapping between threads. 5139 */ 5140 STATIC int32 5141 phy_84793_reg_read(int32 unit, soc_port_t port, uint32 flags, 5142 uint32 phy_reg_addr, uint32 *phy_data) 5143 { 5144 uint16 data16; 5145 phy_ctrl_t *pc; /* PHY software state */ 5146 int32 rv = SOC_E_NONE; 5147 5148 pc = EXT_PHY_SW_STATE(unit, port); 5149 5150 if (flags & SOC_PHY_I2C_DATA8) { 5151 } else if (flags & SOC_PHY_I2C_DATA16) { 5152 } else { 5153 SOC_IF_ERROR_RETURN 5154 (READ_PHY84793_PMA_PMD_REG(unit, pc, phy_reg_addr, &data16)); 5155 *phy_data = data16; 5156 } 5157 5158 return rv; 5159 } 5160 5161 /* 5162 * Function: 5163 * phy_84793_reg_write 5164 * Purpose: 5165 * Routine to write PHY register 5166 * Parameters: 5167 * uint - BCM unit number 5168 * port - port number 5169 * flags - Flags which specify the register type 5170 * phy_reg_addr - Encoded register address 5171 * phy_data - Value write to PHY register 5172 * Note: 5173 * This register read function is not thread safe. Higher level 5174 * function that calls this function must obtain a per port lock 5175 * to avoid overriding register page mapping between threads. 5176 */ 5177 STATIC int32 5178 phy_84793_reg_write(int32 unit, soc_port_t port, uint32 flags, 5179 uint32 phy_reg_addr, uint32 phy_data) 5180 { 5181 phy_ctrl_t *pc; /* PHY software state */ 5182 int32 rv = SOC_E_NONE; 5183 5184 pc = EXT_PHY_SW_STATE(unit, port); 5185 5186 if (flags & SOC_PHY_I2C_DATA8) { 5187 } else if (flags & SOC_PHY_I2C_DATA16) { 5188 } else { 5189 SOC_IF_ERROR_RETURN 5190 (WRITE_PHY84793_PMA_PMD_REG (unit, pc, phy_reg_addr, 5191 (uint16)phy_data)); 5192 } 5193 return rv; 5194 } 5195 5196 STATIC 5197 int32 _phy_84793_modify_pma_pmd_reg (int32 unit, int32 port, phy_ctrl_t *pc, 5198 uint16 address, uint8 msb_pos, 5199 uint8 lsb_pos, uint16 data) 5200 { 5201 uint16 mask = 0, i =0; 5202 5203 for (i = lsb_pos; i<=msb_pos; i++) { 5204 mask |= (1 << i); 5205 } 5206 5207 data = data << lsb_pos; 5208 SOC_IF_ERROR_RETURN 5209 (MODIFY_PHY84793_PMA_PMD_REG(unit, pc, address, 5210 data, mask)); 5211 return 0; 5212 } 5213 5214 STATIC 5215 int32 _phy_84793_enable_msgout_int (int32 unit, int32 port, phy_ctrl_t *pc) 5216 { 5217 uint16 rddata = 0, wrdata = 0; 5218 5219 SOC_IF_ERROR_RETURN 5220 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_MSGOUT, &rddata)); 5221 5222 SOC_IF_ERROR_RETURN 5223 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_EISR, &rddata)); 5224 wrdata = rddata | MSGOUT_BIT_POS; 5225 5226 SOC_IF_ERROR_RETURN 5227 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_EISR, wrdata)); 5228 5229 SOC_IF_ERROR_RETURN 5230 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_EIMR, &rddata)); 5231 wrdata = rddata | MSGOUT_BIT_POS; 5232 5233 SOC_IF_ERROR_RETURN 5234 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_EIMR, wrdata)); 5235 5236 SOC_IF_ERROR_RETURN 5237 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_MSCR, 5238 CTL_REGS_MSCR_GLOBAL_INTR_MASK_SHIFT, 5239 CTL_REGS_MSCR_GLOBAL_INTR_MASK_SHIFT, 1)); 5240 return SOC_E_NONE; 5241 } 5242 5243 STATIC 5244 int32 _phy_84793_wait_micro_msgout (int32 unit, int32 port, phy_ctrl_t *pc) 5245 { 5246 uint16 tmp_data = 0, wrdata = 0; 5247 uint16 retry_cnt = PHY84793_FW_DLOAD_RETRY_CNT; 5248 5249 SOC_IF_ERROR_RETURN 5250 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_EISR, &tmp_data)); 5251 5252 while (((tmp_data & MSGOUT_BIT_POS) == 0) && retry_cnt) { 5253 SOC_IF_ERROR_RETURN 5254 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_EISR, &tmp_data)); 5255 retry_cnt --; 5256 } 5257 if (!retry_cnt) { 5258 return SOC_E_INTERNAL; 5259 } 5260 SOC_IF_ERROR_RETURN 5261 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_EISR, &tmp_data)); 5262 wrdata = tmp_data | MSGOUT_BIT_POS; 5263 5264 SOC_IF_ERROR_RETURN 5265 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_EISR, wrdata)); 5266 5267 return SOC_E_NONE; 5268 } 5269 5270 STATIC 5271 int32 _phy_84793_check_micro_msgout_next (int32 unit, int32 port, phy_ctrl_t *pc) 5272 { 5273 uint16 tmp_data=0; 5274 5275 SOC_IF_ERROR_RETURN 5276 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_MSGOUT, &tmp_data)); 5277 5278 return SOC_E_NONE; 5279 } 5280 5281 STATIC 5282 int32 _phy_84793_micro_soft_reset (int32 unit, int32 port, phy_ctrl_t *pc) 5283 { 5284 5285 SOC_IF_ERROR_RETURN 5286 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_COMMON_CTRL1, 5287 CTL_REGS_COMMON_CTRL1_UC_RSTB_SHIFT, 5288 CTL_REGS_COMMON_CTRL1_UC_RSTB_SHIFT, 0)); 5289 SOC_IF_ERROR_RETURN 5290 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, CTL_REGS_COMMON_CTRL1, 5291 CTL_REGS_COMMON_CTRL1_UC_RSTB_SHIFT, 5292 CTL_REGS_COMMON_CTRL1_UC_RSTB_SHIFT, 1)); 5293 return SOC_E_NONE; 5294 } 5295 5296 STATIC 5297 int32 _phy_84793_rom_firmware_download (int32 unit, int32 port, int32 offset, 5298 phy_ctrl_t *pc, uint8 *new_fw, uint32 datalen) 5299 { 5300 uint32 wr_data = 0, j = 0; 5301 uint16 data16 = 0; 5302 phy84793_intf_cfg_t *interface; 5303 5304 SOC_IF_ERROR_RETURN 5305 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_COMMON_CTRL1, 0xFFFE)); 5306 SOC_IF_ERROR_RETURN 5307 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, COMMON_POR_REGS_BOOT_POR, 5308 COMMON_POR_REGS_BOOT_POR_SPI_PORT_USED_SHIFT, 5309 COMMON_POR_REGS_BOOT_POR_SPI_PORT_USED_SHIFT, 0)); 5310 SOC_IF_ERROR_RETURN 5311 (_phy_84793_modify_pma_pmd_reg(unit, port, pc, COMMON_POR_REGS_BOOT_POR, 5312 COMMON_POR_REGS_BOOT_POR_SER_BOOT_SHIFT, 5313 COMMON_POR_REGS_BOOT_POR_SER_BOOT_SHIFT, 1)); 5314 SOC_IF_ERROR_RETURN 5315 (_phy_84793_enable_msgout_int(unit, port, pc)); 5316 SOC_IF_ERROR_RETURN 5317 (_phy_84793_micro_soft_reset (unit, port, pc)); 5318 SOC_IF_ERROR_RETURN 5319 (_phy_84793_wait_micro_msgout (unit, port, pc)); 5320 SOC_IF_ERROR_RETURN 5321 (_phy_84793_check_micro_msgout_next (unit, port, pc)); 5322 5323 wr_data = 0x8000; /*DEST_RAM_ADDR*/ 5324 SOC_IF_ERROR_RETURN 5325 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_MSGIN, wr_data)); 5326 5327 SOC_IF_ERROR_RETURN 5328 (_phy_84793_wait_micro_msgout (unit, port, pc)); 5329 SOC_IF_ERROR_RETURN 5330 (_phy_84793_check_micro_msgout_next (unit, port, pc)); 5331 5332 wr_data = (datalen)/2; 5333 5334 SOC_IF_ERROR_RETURN 5335 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_MSGIN, wr_data)); 5336 5337 /* Fill in the SRAM */ 5338 wr_data = (datalen - 1); 5339 for (j = 0; j < wr_data; j+=2) { 5340 5341 /*Make sure the word is read by the Micro */ 5342 SOC_IF_ERROR_RETURN 5343 (_phy_84793_wait_micro_msgout (unit, port, pc)); 5344 SOC_IF_ERROR_RETURN 5345 (_phy_84793_check_micro_msgout_next (unit, port, pc)); 5346 5347 data16 = (new_fw[j+1] << 8) | new_fw[j]; 5348 SOC_IF_ERROR_RETURN 5349 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_MSGIN, 5350 data16)); 5351 } 5352 5353 SOC_IF_ERROR_RETURN 5354 (_phy_84793_wait_micro_msgout (unit, port, pc)); 5355 SOC_IF_ERROR_RETURN 5356 (_phy_84793_check_micro_msgout_next (unit, port, pc)); 5357 5358 SOC_IF_ERROR_RETURN 5359 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG4, &data16)); 5360 5361 LOG_VERBOSE(BSL_LS_SOC_PHY, 5362 (BSL_META_U(unit, 5363 "Check Sum: 0x%X \n"), data16)); 5364 if (data16 == 0x600D) { 5365 interface = &(INTERFACE(pc)); 5366 interface->type = SOC_PORT_IF_SR4; 5367 interface->speed = PHY84793_MODE1_SPD; 5368 } 5369 SOC_IF_ERROR_RETURN 5370 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_GPREG0, &data16)); 5371 5372 LOG_VERBOSE(BSL_LS_SOC_PHY, 5373 (BSL_META_U(unit, 5374 "Version: 0x%X\n"), data16)); 5375 return SOC_E_NONE; 5376 } 5377 5378 STATIC 5379 int32 phy_84793_firmware_set(int32 unit, int32 port, int32 offset, 5380 uint8 *array, int32 datalen) 5381 { 5382 phy_ctrl_t *pc; 5383 5384 if (array == NULL) { 5385 return SOC_E_NONE; 5386 } 5387 5388 if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_DISABLE)) { 5389 return SOC_E_NONE; 5390 } 5391 pc = EXT_PHY_SW_STATE(unit, port); 5392 5393 SOC_IF_ERROR_RETURN 5394 (_phy_84793_rom_firmware_download(unit, port, offset, pc, array, datalen)); 5395 5396 return SOC_E_NONE; 5397 } 5398 5399 STATIC int32 5400 phy_84793_probe(int32 unit, phy_ctrl_t *pc) 5401 { 5402 uint32 devid = 0; 5403 5404 SOC_IF_ERROR_RETURN( 5405 _phy_84793_dev_id_get(pc->unit, pc->port, pc, &devid)); 5406 5407 if (devid == PHY84793_ID_84793 || devid == PHY84793_ID_84790 || 5408 devid == PHY84793_ID_84794) { 5409 /*pc->dev_name = dev_name_84793;*/ 5410 } else { /* not found */ 5411 LOG_INFO(BSL_LS_SOC_PHY, 5412 (BSL_META_U(unit, 5413 "port %d: BCM84xxx type" 5414 "PHY device detected, please use" 5415 "phy_84<xxx> config variable to select" 5416 "the specific type\n"), 5417 pc->port)); 5418 return SOC_E_NOT_FOUND; 5419 } 5420 pc->size = sizeof(phy84793_dev_desc_t); 5421 5422 return SOC_E_NONE; 5423 } 5424 5425 /* 5426 * Function: 5427 * phy_84793_ability_advert_set 5428 * Purpose: 5429 * Set the current advertisement for mode1. 5430 * Parameters: 5431 * unit - StrataSwitch unit #. 5432 * port - StrataSwitch port #. 5433 * mode - Port mode mask indicating supported options/speeds. 5434 * Returns: 5435 * SOC_E_XXX 5436 * Notes: 5437 * The advertisement is set only for the ACTIVE medium. 5438 * No synchronization performed at this level. 5439 */ 5440 5441 STATIC int32 5442 phy_84793_ability_advert_set(int32 unit, soc_port_t port, 5443 soc_port_ability_t *ability) 5444 { 5445 /* PHY84793 Doesnt support AN */ 5446 return SOC_E_NONE; 5447 } 5448 5449 /* 5450 * Function: 5451 * phy_84793_ability_advert_get 5452 * Purpose: 5453 * Set the current advertisement for mode1. 5454 * Parameters: 5455 * unit - StrataSwitch unit #. 5456 * port - StrataSwitch port #. 5457 * mode - Port mode mask indicating supported options/speeds. 5458 * Returns: 5459 * SOC_E_XXX 5460 * Notes: 5461 * The advertisement is set only for the ACTIVE medium. 5462 * No synchronization performed at this level. 5463 */ 5464 5465 STATIC int32 5466 phy_84793_ability_advert_get(int32 unit, soc_port_t port, 5467 soc_port_ability_t *ability) 5468 { 5469 if (ability == NULL) { 5470 return SOC_E_PARAM; 5471 } 5472 sal_memset(ability, 0, sizeof(soc_port_ability_t)); 5473 5474 return SOC_E_NONE; 5475 } 5476 5477 /* 5478 * Function: 5479 * phy_84793_enable_set 5480 * Purpose: 5481 * Enable/Disable phy 5482 * Parameters: 5483 * unit - StrataSwitch unit #. 5484 * port - StrataSwitch port #. 5485 * enable - on/off state to set 5486 * Returns: 5487 * SOC_E_NON 5488 */ 5489 5490 STATIC int32 5491 phy_84793_enable_set(int32 unit, soc_port_t port, int32 enable) 5492 { 5493 uint16 mode = 0, tx_data = 0, rx_data = 0; 5494 uint16 tx_sys_data = 0, rx_sys_data = 0; 5495 uint16 vsr_tx_data = 0, vsr_rx_data = 0; 5496 uint16 start_lane =0, end_lane =0, lane = 0; 5497 5498 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 5499 5500 PHY84793_GET_PORT_MODE(pc, mode); 5501 if (mode == PHY84793_MODE_10X10G_TO_10X10G_ASYNC) { 5502 SOC_IF_ERROR_RETURN 5503 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_VSR40_TX_PD, &vsr_tx_data)); 5504 vsr_tx_data = (~vsr_tx_data) & 0xf; 5505 SOC_IF_ERROR_RETURN 5506 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_VSR40_RX_PD, &vsr_rx_data)); 5507 vsr_rx_data = (~vsr_rx_data) & 0xf; 5508 SOC_IF_ERROR_RETURN 5509 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_HCTX_PD, &tx_data)); 5510 tx_data = (((~tx_data) & 0x3f) << 4) | vsr_tx_data; 5511 SOC_IF_ERROR_RETURN 5512 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_HCRX_PD, &rx_data)); 5513 rx_data = (((~rx_data) & 0x3f) << 4) | vsr_rx_data; 5514 5515 SOC_IF_ERROR_RETURN 5516 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_DCTX_PD, &tx_sys_data)); 5517 tx_sys_data = (~tx_sys_data) & 0x3ff; 5518 SOC_IF_ERROR_RETURN 5519 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_DCRX_PD, &rx_sys_data)); 5520 rx_sys_data = (~rx_sys_data) & 0x3ff; 5521 5522 tx_data &= ~(1 << pc->lane_num); 5523 rx_data &= ~(1 << pc->lane_num); 5524 tx_sys_data &= ~(1 << pc->lane_num); 5525 rx_sys_data &= ~(1 << pc->lane_num); 5526 if (enable) { 5527 tx_data |= (1 << pc->lane_num); 5528 rx_data |= (1 << pc->lane_num); 5529 5530 tx_sys_data |= (1 << pc->lane_num); 5531 rx_sys_data |= (1 << pc->lane_num); 5532 } 5533 SOC_IF_ERROR_RETURN(_phy_84793_sys_enable_set (unit, port, pc, 5534 tx_sys_data, rx_sys_data)); 5535 5536 SOC_IF_ERROR_RETURN(_phy_84793_line_enable_set (unit, port, pc, 5537 tx_data, rx_data)); 5538 } else if (mode == PHY84793_MODE_4X10G_TO_4X10G) { 5539 if(pc->lane_num == 0) { 5540 start_lane = PHY84793_VSR40_LANE0; 5541 end_lane = PHY84793_VSR40_LANE3; 5542 } else { 5543 start_lane = 5; 5544 end_lane = 6; 5545 } 5546 for (lane = start_lane; lane <= end_lane ; lane ++) { 5547 SOC_IF_ERROR_RETURN 5548 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_VSR40_TX_PD, 5549 &vsr_tx_data)); 5550 vsr_tx_data = (~vsr_tx_data) & 0xf; 5551 SOC_IF_ERROR_RETURN 5552 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_VSR40_RX_PD, 5553 &vsr_rx_data)); 5554 vsr_rx_data = (~vsr_rx_data) & 0xf; 5555 SOC_IF_ERROR_RETURN 5556 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_HCTX_PD, &tx_data)); 5557 tx_data = (((~tx_data) & 0x3f) << 4) | vsr_tx_data; 5558 SOC_IF_ERROR_RETURN 5559 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_HCRX_PD, &rx_data)); 5560 rx_data = (((~rx_data) & 0x3f) << 4) | vsr_rx_data; 5561 5562 SOC_IF_ERROR_RETURN 5563 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_DCTX_PD, 5564 &tx_sys_data)); 5565 tx_sys_data = (~tx_sys_data) & 0x3ff; 5566 SOC_IF_ERROR_RETURN 5567 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_DCRX_PD, 5568 &rx_sys_data)); 5569 rx_sys_data = (~rx_sys_data) & 0x3ff; 5570 5571 tx_data &= ~(1 << lane); 5572 rx_data &= ~(1 << lane); 5573 tx_sys_data &= ~(1 << lane); 5574 rx_sys_data &= ~(1 << lane); 5575 if (enable) { 5576 tx_data |= (1 << lane); 5577 rx_data |= (1 << lane); 5578 5579 tx_sys_data |= (1 << lane); 5580 rx_sys_data |= (1 << lane); 5581 } 5582 SOC_IF_ERROR_RETURN(_phy_84793_sys_enable_set (unit, port, pc, 5583 tx_sys_data, rx_sys_data)); 5584 5585 SOC_IF_ERROR_RETURN(_phy_84793_line_enable_set (unit, port, pc, 5586 tx_data, rx_data)); 5587 } 5588 } else { 5589 /* Manually power channel up/down in Tx and RX dir of line and system side*/ 5590 SOC_IF_ERROR_RETURN(_phy_84793_sys_enable_set (unit, port, pc, 5591 enable ? PHY84793_ENABLE_ALL_LANES : 0, 5592 enable ? PHY84793_ENABLE_ALL_LANES : 0)); 5593 5594 SOC_IF_ERROR_RETURN(_phy_84793_line_enable_set (unit, port, pc, 5595 enable ? PHY84793_ENABLE_ALL_LANES : 0, 5596 enable ? PHY84793_ENABLE_ALL_LANES : 0)); 5597 } 5598 if (enable) { 5599 PHY_FLAGS_CLR(unit, port, PHY_FLAGS_DISABLE); 5600 } else { 5601 PHY_FLAGS_SET(unit, port, PHY_FLAGS_DISABLE); 5602 } 5603 return SOC_E_NONE; 5604 } 5605 5606 /* 5607 * Function: 5608 * phy_84793_interface_set 5609 * Purpose: 5610 * Set either CR4 interface or SR4/LR4. The valid interface are SOC_PORT_IF_CR4 5611 * and SOC_PORT_IF_SR4 which put device in default mode: SR4/LR4 mode 5612 * Parameters: 5613 * unit - StrataSwitch unit #. 5614 * port - StrataSwitch port #. 5615 * pif - one of SOC_PORT_IF_* 5616 * Returns: 5617 * SOC_E_NONE - success 5618 * SOC_E_UNAVAIL - unsupported interface 5619 */ 5620 5621 STATIC int32 5622 phy_84793_interface_set(int32 unit, soc_port_t port, soc_port_if_t pif) 5623 { 5624 phy_ctrl_t *pc; 5625 phy84793_intf_cfg_t *intf; 5626 5627 if (pif == SOC_PORT_IF_MII || pif == SOC_PORT_IF_XGMII || pif == SOC_PORT_IF_GMII) { 5628 return phy_null_interface_set(unit, port, pif); 5629 } 5630 5631 pc = EXT_PHY_SW_STATE(unit, port); 5632 intf = &(INTERFACE(pc)); 5633 5634 if (pif > SOC_PORT_IF_COUNT) { 5635 return SOC_E_PARAM; 5636 } 5637 5638 /* translate to the mode of operation that supported */ 5639 if (pif==SOC_PORT_IF_CAUI || pif==SOC_PORT_IF_XLAUI) { 5640 pif = SOC_PORT_IF_SR4; 5641 } else if (pif==SOC_PORT_IF_SFI || pif==SOC_PORT_IF_XFI) { 5642 pif = SOC_PORT_IF_SR; 5643 } 5644 5645 5646 switch(pif) 5647 { 5648 case SOC_PORT_IF_SR4: 5649 if (intf->speed == PHY84793_MODE2_SPD) { 5650 LOG_CLI((BSL_META_U(unit, 5651 "PHY84793 MODE2 Configured\n"))); 5652 SOC_IF_ERROR_RETURN 5653 (_phy_84793_config_mode (unit, port, pc, 5654 PHY84793_MODE_4X10G_TO_4X10G)); 5655 } else { 5656 LOG_CLI((BSL_META_U(unit, 5657 "PHY84793 MODE1 Configured\n"))); 5658 SOC_IF_ERROR_RETURN 5659 (_phy_84793_config_mode (unit, port, pc, 5660 PHY84793_MODE_10X10G_TO_4X25G)); 5661 intf->speed = PHY84793_MODE1_SPD; 5662 } 5663 break; 5664 case SOC_PORT_IF_SR10: 5665 LOG_CLI((BSL_META_U(unit, 5666 "PHY84793 MODE3 Configured\n"))); 5667 SOC_IF_ERROR_RETURN 5668 (_phy_84793_config_mode (unit, port, pc, 5669 PHY84793_MODE_10X10G_TO_10X10G_SYNC)); 5670 intf->speed = PHY84793_MODE3_SPD; 5671 5672 break; 5673 case SOC_PORT_IF_SR: 5674 LOG_CLI((BSL_META_U(unit, 5675 "PHY84793 MODE4 Configured\n"))); 5676 SOC_IF_ERROR_RETURN 5677 (_phy_84793_config_mode (unit, port, pc, 5678 PHY84793_MODE_10X10G_TO_10X10G_ASYNC)); 5679 intf->speed = PHY84793_MODE4_SPD; 5680 break; 5681 case SOC_PORT_IF_OTL: 5682 LOG_CLI((BSL_META_U(unit, 5683 "PHY84793 MODE5 Configured\n"))); 5684 SOC_IF_ERROR_RETURN 5685 (_phy_84793_config_mode (unit, port, pc, 5686 PHY84793_MODE_10X10G_TO_4X25G_OTL)); 5687 intf->speed = PHY84793_MODE5_SPD; 5688 break; 5689 default: 5690 return SOC_E_PARAM; 5691 } 5692 intf->type = pif; 5693 return SOC_E_NONE; 5694 } 5695 5696 /* 5697 * Function: 5698 * phy_84793_ability_local_get 5699 * Purpose: 5700 * Get the device's complete abilities. 5701 * Parameters: 5702 * unit - StrataSwitch unit #. 5703 * port - StrataSwitch port #. 5704 * ability - return device's abilities. 5705 * Returns: 5706 * SOC_E_XXX 5707 */ 5708 5709 STATIC int32 5710 phy_84793_ability_local_get(int32 unit, soc_port_t port, soc_port_ability_t *ability) 5711 { 5712 uint32 pa_speed = 0; 5713 phy84793_intf_cfg_t *intf; 5714 5715 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 5716 if (ability == NULL) { 5717 return SOC_E_PARAM; 5718 } 5719 sal_memset(ability, 0, sizeof(soc_port_ability_t)); 5720 5721 intf = &(INTERFACE(pc)); 5722 if (intf->speed == PHY84793_MODE1_SPD) { 5723 pa_speed = SOC_PA_SPEED_100GB; 5724 } else if (intf->speed == PHY84793_MODE2_SPD) { 5725 pa_speed = SOC_PA_SPEED_40GB; 5726 } else if (intf->speed == PHY84793_MODE4_SPD) { 5727 pa_speed = SOC_PA_SPEED_10GB; 5728 } 5729 ability->speed_full_duplex = pa_speed; 5730 ability->speed_half_duplex = SOC_PA_ABILITY_NONE; 5731 ability->pause = 0; 5732 ability->medium = SOC_PA_MEDIUM_FIBER; 5733 ability->loopback = SOC_PA_LB_PHY; 5734 5735 LOG_INFO(BSL_LS_SOC_PHY, 5736 (BSL_META_U(unit, 5737 "phy_84793_ability_local_get: u=%d p=%d speed=0x%x\n"), 5738 unit, port, ability->speed_full_duplex)); 5739 5740 return SOC_E_NONE; 5741 } 5742 5743 /* 5744 * Function: 5745 * phy_84793_speed_get 5746 * Purpose: 5747 * Get PHY speed 5748 * Parameters: 5749 * unit - StrataSwitch unit #. 5750 * port - StrataSwitch port #. 5751 * speed - current link speed in Mbps 5752 * Returns: 5753 * SOC_E_NONE 5754 */ 5755 5756 STATIC int32 5757 phy_84793_speed_get(int32 unit, soc_port_t port, int32 *speed) 5758 { 5759 phy84793_intf_cfg_t *intf; 5760 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 5761 5762 intf = &(INTERFACE(pc)); 5763 5764 *speed = intf->speed; 5765 5766 return SOC_E_NONE; 5767 } 5768 5769 /* 5770 * Function: 5771 * phy_84793_interface_get 5772 * Purpose: 5773 * Get the current operating mode of the PHY. 5774 * Parameters: 5775 * unit - StrataSwitch unit #. 5776 * port - StrataSwitch port #. 5777 * pif - (OUT) one of SOC_PORT_IF_* 5778 * Returns: 5779 * SOC_E_NONE 5780 */ 5781 5782 STATIC int32 5783 phy_84793_interface_get(int32 unit, soc_port_t port, soc_port_if_t *pif) 5784 { 5785 phy84793_intf_cfg_t *intf; 5786 phy_ctrl_t *pc = EXT_PHY_SW_STATE(unit, port); 5787 5788 intf = &(INTERFACE(pc)); 5789 5790 *pif = intf->type; 5791 return SOC_E_NONE; 5792 } 5793 5794 /* 5795 * Function: 5796 * phy_84793_lb_get 5797 * Purpose: 5798 * Get 84793 PHY loopback state 5799 * Parameters: 5800 * unit - StrataSwitch unit #. 5801 * port - StrataSwitch port #. 5802 * enable - address of location to store binary value for on/off (1/0) 5803 * Returns: 5804 * SOC_E_NONE 5805 */ 5806 5807 STATIC int32 5808 phy_84793_lb_get(int32 unit, soc_port_t port, int32 *enable) 5809 { 5810 phy_ctrl_t *pc; 5811 5812 pc = EXT_PHY_SW_STATE(unit, port); 5813 5814 SOC_IF_ERROR_RETURN 5815 (_phy_84793_per_lane_lb_get(unit, port, pc->lane_num , (uint32*)enable)); 5816 5817 LOG_INFO(BSL_LS_SOC_PHY, 5818 (BSL_META_U(unit, 5819 "phy_84793_lb_get: u=%d port%d: loopback:%s\n"), 5820 unit, port, *enable ? "Enabled": "Disabled")); 5821 5822 return SOC_E_NONE; 5823 } 5824 5825 STATIC int32 5826 _phy_84793_per_lane_lb_get(int32 unit, soc_port_t port, uint16 lane, uint32 *enable) 5827 { 5828 uint16 mode = 0, tmp = 0; 5829 phy_ctrl_t *pc; 5830 pc = EXT_PHY_SW_STATE(unit, port); 5831 5832 PHY84793_GET_PORT_MODE(pc, mode); 5833 5834 /*Get local loopback*/ 5835 switch (mode) { 5836 case PHY84793_MODE_10X10G_TO_4X25G: 5837 /* Fall Thru */ 5838 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 5839 /* Fall Thru */ 5840 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 5841 SOC_IF_ERROR_RETURN 5842 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5843 CTL_REGS_SYS_LOOPBACK_EN, &tmp)); 5844 5845 *enable = (tmp & 0x3ff) ? TRUE : FALSE; 5846 break; 5847 case PHY84793_MODE_4X10G_TO_4X10G: 5848 if (lane <=3) { 5849 SOC_IF_ERROR_RETURN 5850 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5851 CTL_REGS_SYS_LOOPBACK_EN, &tmp)); 5852 *enable = ( tmp & 0xF)?TRUE:FALSE; 5853 5854 } else { 5855 SOC_IF_ERROR_RETURN 5856 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5857 CTL_REGS_SYS_LOOPBACK_EN, &tmp)); 5858 5859 *enable = (tmp & 0x1e0)?TRUE:FALSE; 5860 } 5861 break; 5862 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 5863 SOC_IF_ERROR_RETURN 5864 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_SYS_LOOPBACK_EN, &tmp)); 5865 *enable = (tmp & (1 <<lane)) ? TRUE : FALSE; 5866 break; 5867 } 5868 return SOC_E_NONE; 5869 } 5870 5871 STATIC int32 5872 _phy_84793_per_lane_remote_lb_get(int32 unit, soc_port_t port, uint16 lane, 5873 uint32 *enable) 5874 { 5875 uint16 mode = 0, tmp = 0; 5876 phy_ctrl_t *pc; 5877 pc = EXT_PHY_SW_STATE(unit, port); 5878 5879 PHY84793_GET_PORT_MODE(pc, mode); 5880 5881 /*Enable Line side(Remote)loopback*/ 5882 switch (mode) { 5883 case PHY84793_MODE_10X10G_TO_4X25G: 5884 /* Fall Thru */ 5885 case PHY84793_MODE_10X10G_TO_4X25G_OTL: 5886 SOC_IF_ERROR_RETURN 5887 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5888 CTL_REGS_LINE_LOOPBACK_EN , &tmp)); 5889 5890 *enable = (tmp & 0xf)? TRUE : FALSE; 5891 break; 5892 case PHY84793_MODE_4X10G_TO_4X10G: 5893 if (lane <=3) { 5894 SOC_IF_ERROR_RETURN 5895 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5896 CTL_REGS_LINE_LOOPBACK_EN , &tmp)); 5897 *enable = (tmp & 0xf) == 0xf? TRUE:FALSE; 5898 } else { 5899 SOC_IF_ERROR_RETURN 5900 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5901 CTL_REGS_LINE_LOOPBACK_EN , &tmp)); 5902 *enable = (tmp & 0x1e0) == 0x1e0? TRUE:FALSE; 5903 } 5904 break; 5905 case PHY84793_MODE_10X10G_TO_10X10G_SYNC: 5906 case PHY84793_MODE_10X10G_TO_10X10G_ASYNC: 5907 SOC_IF_ERROR_RETURN 5908 (READ_PHY84793_PMA_PMD_REG(unit, pc, 5909 CTL_REGS_LINE_LOOPBACK_EN , &tmp)); 5910 *enable = (tmp & 0x3ff) ? TRUE : FALSE; 5911 5912 break; 5913 } 5914 return SOC_E_NONE; 5915 } 5916 5917 /* 5918 * Function: 5919 * phy_84793_speed_set 5920 * Purpose: 5921 * Set PHY speed 5922 * Parameters: 5923 * unit - StrataSwitch unit #. 5924 * port - StrataSwitch port #. 5925 * speed - link speed in Mbps 5926 * Returns: 5927 * SOC_E_NONE 5928 */ 5929 5930 STATIC int32 5931 phy_84793_speed_set(int32 unit, soc_port_t port, int32 speed) 5932 { 5933 int32 rv = 0; 5934 phy_ctrl_t *pc; 5935 phy84793_intf_cfg_t *intf; 5936 5937 pc = EXT_PHY_SW_STATE(unit, port); 5938 intf = &(INTERFACE(pc)); 5939 LOG_INFO(BSL_LS_SOC_PHY, 5940 (BSL_META_U(unit, 5941 "phy_84793_speed_set: u=%d p=%d speed=%d\n"), 5942 unit, port, speed)); 5943 switch (speed) { 5944 case PHY84793_MODE1_SPD: 5945 break; 5946 case PHY84793_MODE4_SPD: 5947 /* Line side 10GX10 system 10 X10G */ 5948 intf->type = SOC_PORT_IF_SR; 5949 break; 5950 case PHY84793_MODE2_SPD: 5951 /* Line side 10GX4X2port System 10GX4X2port*/ 5952 intf->type = SOC_PORT_IF_SR4; 5953 break; 5954 default: 5955 return SOC_E_FAIL; 5956 } 5957 intf->speed = speed; 5958 rv = _phy_84793_speed_set(unit, port, speed); 5959 if (SOC_FAILURE(rv)) { 5960 LOG_ERROR(BSL_LS_SOC_PHY, 5961 (BSL_META_U(unit, 5962 "84793 %s failed: u=%d p=%d\n"), 5963 FUNCTION_NAME(), unit, port)); 5964 } 5965 return rv; 5966 } 5967 5968 STATIC int32 5969 _phy_84793_speed_set(int32 unit, soc_port_t port, int32 speed) 5970 { 5971 phy_ctrl_t *pc; 5972 phy84793_intf_cfg_t *intf; 5973 5974 pc = EXT_PHY_SW_STATE(unit, port); 5975 intf = &(INTERFACE(pc)); 5976 5977 intf->speed = speed; 5978 5979 switch (speed) { 5980 case PHY84793_MODE1_SPD: 5981 if (intf->type == SOC_PORT_IF_SR4) { 5982 LOG_CLI((BSL_META_U(unit, 5983 "PHY84793 MODE1 Configured\n"))); 5984 SOC_IF_ERROR_RETURN 5985 (_phy_84793_config_mode (unit, port, pc, 5986 PHY84793_MODE_10X10G_TO_4X25G)); 5987 } 5988 if (intf->type == SOC_PORT_IF_OTL) { 5989 LOG_CLI((BSL_META_U(unit, 5990 "PHY84793 MODE5 Configured\n"))); 5991 SOC_IF_ERROR_RETURN 5992 (_phy_84793_config_mode (unit, port, pc, 5993 PHY84793_MODE_10X10G_TO_4X25G_OTL)); 5994 } 5995 if (intf->type == SOC_PORT_IF_SR10 ) { 5996 LOG_CLI((BSL_META_U(unit, 5997 "PHY84793 MODE3 Configured\n"))); 5998 SOC_IF_ERROR_RETURN 5999 (_phy_84793_config_mode (unit, port, pc, 6000 PHY84793_MODE_10X10G_TO_10X10G_SYNC)); 6001 } 6002 break; 6003 case PHY84793_MODE4_SPD: 6004 if (intf->type == SOC_PORT_IF_SR) { 6005 LOG_CLI((BSL_META_U(unit, 6006 "PHY84793 MODE4 Configured\n"))); 6007 SOC_IF_ERROR_RETURN 6008 (_phy_84793_config_mode (unit, port, pc, 6009 PHY84793_MODE_10X10G_TO_10X10G_ASYNC)); 6010 } 6011 break; 6012 case PHY84793_MODE2_SPD: 6013 if (intf->type == SOC_PORT_IF_SR4) { 6014 LOG_CLI((BSL_META_U(unit, 6015 "PHY84793 MODE2 Configured\n"))); 6016 SOC_IF_ERROR_RETURN 6017 (_phy_84793_config_mode (unit, port, pc, 6018 PHY84793_MODE_4X10G_TO_4X10G)); 6019 } 6020 break; 6021 } 6022 return SOC_E_NONE; 6023 } 6024 6025 /* 6026 * Function: 6027 * phy_84793_an_set 6028 * Purpose: 6029 * Enable or disabled auto-negotiation on the specified port. 6030 * Parameters: 6031 * unit - StrataSwitch unit #. 6032 * port - StrataSwitch port #. 6033 * an - Boolean, if true, auto-negotiation is enabled 6034 * (and/or restarted). If false, autonegotiation is disabled. 6035 * Returns: 6036 * SOC_E_XXX 6037 */ 6038 STATIC int32 6039 phy_84793_an_set(int32 unit, soc_port_t port, int32 an) 6040 { 6041 return SOC_E_NONE; 6042 } 6043 6044 STATIC 6045 int32 _phy_84793_dev_mode_config (int32 unit, soc_port_t port, phy_ctrl_t *pc, 6046 uint16 modesel, uint16 refclk_code, uint16 sysPllRst) 6047 { 6048 uint8 frcMode = 0; 6049 6050 if (modesel == 0) { 6051 frcMode = 0; 6052 } else { 6053 frcMode = 1; 6054 } 6055 6056 SOC_IF_ERROR_RETURN 6057 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6058 CTL_REGS_USER_MODESEL_REG, CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, 6059 CTL_REGS_USER_MODESEL_REG_USER_MODESEL_FRC_SHIFT, frcMode)); 6060 6061 SOC_IF_ERROR_RETURN 6062 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6063 CTL_REGS_USER_MODESEL_REG, 2, CTL_REGS_USER_MODESEL_REG_USER_MODESEL_SHIFT, 6064 modesel)); 6065 SOC_IF_ERROR_RETURN 6066 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6067 CTL_REGS_REFCLK_SEL_REG, CTL_REGS_REFCLK_SEL_REG_REFCLK_CODE_SHIFT + 3, 6068 CTL_REGS_REFCLK_SEL_REG_REFCLK_CODE_SHIFT, refclk_code)); 6069 6070 if (sysPllRst == 1) { 6071 SOC_IF_ERROR_RETURN(_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6072 CTL_REGS_DC_RESET, CTL_REGS_DC_RESET_FRC_DC_PLL_RSTB_SHIFT, 6073 CTL_REGS_DC_RESET_DC_PLL_RSTB_SHIFT, 0x3)); 6074 SOC_IF_ERROR_RETURN(_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6075 CTL_REGS_DC_RESET, CTL_REGS_DC_RESET_FRC_DC_PLL_RSTB_SHIFT, 6076 CTL_REGS_DC_RESET_DC_PLL_RSTB_SHIFT, 0x2)); 6077 SOC_IF_ERROR_RETURN(_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6078 CTL_REGS_DC_RESET, CTL_REGS_DC_RESET_FRC_DC_PLL_RSTB_SHIFT, 6079 CTL_REGS_DC_RESET_DC_PLL_RSTB_SHIFT, 0x3)); 6080 SOC_IF_ERROR_RETURN(_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6081 CTL_REGS_DC_RESET, CTL_REGS_DC_RESET_FRC_DC_PLL_RSTB_SHIFT, 6082 CTL_REGS_DC_RESET_DC_PLL_RSTB_SHIFT, 0x1)); 6083 } 6084 return SOC_E_NONE; 6085 } 6086 6087 STATIC 6088 uint16 _phy84793_get_val(uint16 regval, uint16 msb, uint16 lsb) 6089 { 6090 uint16 mask =0; 6091 uint16 status = 0; 6092 6093 mask = (power(2,(msb+1))) - (power (2,lsb)); 6094 status = (regval & mask)/(power(2,lsb)); 6095 return status; 6096 } 6097 6098 STATIC 6099 int32 _phy84793_pcb_bus_read (int32 unit, soc_port_t port, phy_ctrl_t *pc, 6100 uint16 core_sel,uint16 lane, uint16 addr, 6101 uint16 clr_reg, uint16 *data) 6102 { 6103 uint16 msb = 0, lsb = 0, rddata = 0; 6104 6105 msb = _phy84793_get_val(lane,15,0); 6106 lsb = _phy84793_get_val(addr,15,0); 6107 6108 if (core_sel >= 3) { 6109 return SOC_E_FAIL; 6110 } 6111 SOC_IF_ERROR_RETURN 6112 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_ADR_MSW_TYPE, msb)); 6113 SOC_IF_ERROR_RETURN 6114 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_ADR_LSW_TYPE, lsb)); 6115 sal_udelay(10); 6116 6117 /*assert read bit F452.4 and enable bit F452.0*/ 6118 SOC_IF_ERROR_RETURN 6119 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 6120 power(2,core_sel))); 6121 SOC_IF_ERROR_RETURN 6122 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 6123 (0x10 + power(2,core_sel)))); 6124 6125 SOC_IF_ERROR_RETURN 6126 (READ_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_DATA_OUT_TYPE, &rddata)); 6127 6128 if (clr_reg) { 6129 /*clear, read And enable bits asserted*/ 6130 SOC_IF_ERROR_RETURN 6131 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 0x31)); 6132 /* read and enable bits asserted*/ 6133 SOC_IF_ERROR_RETURN 6134 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 0x11)); 6135 } 6136 SOC_IF_ERROR_RETURN 6137 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 0x0)); 6138 sal_udelay(10); 6139 *data = rddata; 6140 6141 return SOC_E_NONE; 6142 } 6143 6144 STATIC 6145 int32 pcb_bus_write (int32 unit, soc_port_t port, phy_ctrl_t *pc, 6146 uint16 core_sel, uint16 lane, uint16 addr, uint16 value) 6147 { 6148 uint16 msb = 0, lsb = 0; 6149 6150 msb = _phy84793_get_val(lane,15,0); 6151 lsb = _phy84793_get_val(addr,15,0); 6152 6153 if (core_sel >= 3) { 6154 return SOC_E_FAIL; 6155 } 6156 6157 SOC_IF_ERROR_RETURN 6158 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_ADR_MSW_TYPE, msb)); 6159 SOC_IF_ERROR_RETURN 6160 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_ADR_LSW_TYPE, lsb)); 6161 SOC_IF_ERROR_RETURN 6162 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_DATA_IN_TYPE, value)); 6163 6164 SOC_IF_ERROR_RETURN 6165 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 6166 power(2, core_sel))); 6167 SOC_IF_ERROR_RETURN 6168 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 6169 (0x8 + power(2,core_sel)))); 6170 6171 SOC_IF_ERROR_RETURN 6172 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_PCB_CTRL_TYPE, 0x0)); 6173 sal_udelay(10); 6174 6175 return SOC_E_NONE; 6176 } 6177 6178 STATIC 6179 int32 _phy_84793_pcb_wr_bits(int32 unit, soc_port_t port, phy_ctrl_t *pc, 6180 uint16 core_sel, uint16 lane, uint16 addr, 6181 uint16 msb, uint16 lsb, uint16 value) 6182 { 6183 uint16 regval = 0, mask = 0, maskr = 0, shift_val = 0; 6184 6185 SOC_IF_ERROR_RETURN 6186 (_phy84793_pcb_bus_read(unit, port, pc, core_sel, lane, 6187 addr, 0, ®val)); 6188 6189 mask = (power(2,(msb+1)) - power(2,lsb)); 6190 maskr = 65535 & ((-1) ^ mask); 6191 shift_val = (power(2,lsb)) * value; 6192 regval = (regval & maskr) + (shift_val & mask); 6193 6194 SOC_IF_ERROR_RETURN(pcb_bus_write(unit, port, pc, 6195 core_sel, lane, addr, regval)); 6196 6197 return SOC_E_NONE; 6198 } 6199 6200 STATIC int32 6201 _phy_84793_div_change(int32 unit, soc_port_t port, uint16 setmode, 6202 uint16 refclkin, uint16 mode) 6203 { 6204 uint16 rxRefDiv = 0; 6205 uint16 rxFbDiv = 0; 6206 uint16 rx25gMode = 0; 6207 uint16 initRefclkMode = 0; 6208 phy_ctrl_t *pc; 6209 6210 pc = EXT_PHY_SW_STATE(unit, port); 6211 if (refclkin == 1) { 6212 rxRefDiv = 1; 6213 initRefclkMode = 6; 6214 } else if(refclkin == 0){ 6215 rxRefDiv = 0; 6216 initRefclkMode = 5; 6217 } else { 6218 LOG_CLI((BSL_META_U(unit, 6219 "Error\n"))); 6220 return SOC_E_FAIL; 6221 } 6222 6223 rxFbDiv = 2; 6224 rx25gMode = 0; 6225 if(mode == PHY84793_MODE_10X10G_TO_4X25G) { 6226 initRefclkMode = 0; 6227 } 6228 6229 6230 /* 6231 * Set mode to Mode 2, 3 or 4 first with 161M REFCLK 6232 */ 6233 SOC_IF_ERROR_RETURN 6234 (_phy_84793_dev_mode_config(unit,port, pc, mode, initRefclkMode, 1)); 6235 6236 /*Overwrite the RX PLL divider settings to support Div 132*/ 6237 /* Force for refDiv*/ 6238 SOC_IF_ERROR_RETURN 6239 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_RX_PLL_CONTROL1, 6240 VSR40_RX_PLL_CONTROL1_SUSM_RX_REF_DIV_FRC_SHIFT, 6241 VSR40_RX_PLL_CONTROL1_SUSM_RX_REF_DIV_FRC_SHIFT, setmode )); 6242 6243 SOC_IF_ERROR_RETURN 6244 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_RX_PLL_CONTROL1, 6245 VSR40_RX_PLL_CONTROL1_SUSM_RX_REF_DIV_SHIFT+1, 6246 VSR40_RX_PLL_CONTROL1_SUSM_RX_REF_DIV_SHIFT, rxRefDiv)); 6247 /* Force for rxFbDiv(1)*/ 6248 SOC_IF_ERROR_RETURN 6249 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_RX_PLL_CONTROL4, 6250 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_E100G_FRC_SHIFT, 6251 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_E100G_FRC_SHIFT, setmode)); 6252 6253 /* Force for rxFbDiv(0)*/ 6254 SOC_IF_ERROR_RETURN 6255 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_RX_PLL_CONTROL4, 6256 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_25G_FRC_SHIFT, 6257 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_25G_FRC_SHIFT, setmode)); 6258 SOC_IF_ERROR_RETURN 6259 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_RX_PLL_CONTROL4, 6260 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_E100G_SHIFT, 6261 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_E100G_SHIFT, 6262 _phy84793_get_val(rxFbDiv, 1, 1))); 6263 SOC_IF_ERROR_RETURN 6264 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_RX_PLL_CONTROL4, 6265 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_25G_SHIFT, 6266 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_25G_SHIFT, 6267 _phy84793_get_val(rxFbDiv, 0, 0))); 6268 /* Force for 20g mode*/ 6269 SOC_IF_ERROR_RETURN 6270 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_RX_PLL_CONTROL2, 6271 VSR40_RX_PLL_CONTROL2_SUSM_RX_VCO_EN25G_FRC_SHIFT, 6272 VSR40_RX_PLL_CONTROL2_SUSM_RX_VCO_EN25G_FRC_SHIFT, setmode)); 6273 /* Force for 20g mode*/ 6274 SOC_IF_ERROR_RETURN 6275 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_RX_PLL_CONTROL2, 6276 VSR40_RX_PLL_CONTROL2_SUSM_RX_VCO_EN25G_SHIFT, 6277 VSR40_RX_PLL_CONTROL2_SUSM_RX_VCO_EN25G_SHIFT, rx25gMode)); 6278 /* Assert RX CMU Reset*/ 6279 SOC_IF_ERROR_RETURN 6280 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6281 VSR40_RX_DIG_REGS_RESET_CONTROL, 6282 VSR40_RX_DIG_REGS_RESET_CONTROL_CAL_RSTB_SHIFT, 6283 VSR40_RX_DIG_REGS_RESET_CONTROL_CAL_RSTB_SHIFT, 0x0)); 6284 SOC_IF_ERROR_RETURN 6285 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6286 VSR40_RX_DIG_REGS_RESET_CONTROL, 6287 VSR40_RX_DIG_REGS_RESET_CONTROL_CAL_RSTB_SHIFT, 6288 VSR40_RX_DIG_REGS_RESET_CONTROL_CAL_RSTB_SHIFT, 0x1)); 6289 /* Assert RX CMU Lkdet Reset*/ 6290 SOC_IF_ERROR_RETURN 6291 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6292 VSR40_RX_DIG_REGS_RESET_CONTROL, 6293 VSR40_RX_DIG_REGS_RESET_CONTROL_LKDT_RSTB_SHIFT, 6294 VSR40_RX_DIG_REGS_RESET_CONTROL_LKDT_RSTB_SHIFT, 0x0)); 6295 SOC_IF_ERROR_RETURN 6296 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6297 VSR40_RX_DIG_REGS_RESET_CONTROL, 6298 VSR40_RX_DIG_REGS_RESET_CONTROL_LKDT_RSTB_SHIFT, 6299 VSR40_RX_DIG_REGS_RESET_CONTROL_LKDT_RSTB_SHIFT, 0x1)); 6300 6301 /* Overwrite the TX PLL divider settings*/ 6302 /* Force for refDiv*/ 6303 SOC_IF_ERROR_RETURN(_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6304 VSR40_TX_PLL_CONTROL1, 6305 VSR40_RX_PLL_CONTROL1_SUSM_RX_REF_DIV_FRC_SHIFT, 6306 VSR40_RX_PLL_CONTROL1_SUSM_RX_REF_DIV_FRC_SHIFT, setmode)); 6307 SOC_IF_ERROR_RETURN(_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6308 VSR40_TX_PLL_CONTROL1, 6309 VSR40_RX_PLL_CONTROL1_SUSM_RX_REF_DIV_SHIFT+1 , 6310 VSR40_RX_PLL_CONTROL1_SUSM_RX_REF_DIV_SHIFT, rxRefDiv)); 6311 /*Force for rxFbDiv(1)*/ 6312 SOC_IF_ERROR_RETURN 6313 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_TX_PLL_CONTROL4, 6314 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_E100G_FRC_SHIFT, 6315 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_E100G_FRC_SHIFT, setmode)); 6316 /*Force for rxFbDiv(0)*/ 6317 SOC_IF_ERROR_RETURN 6318 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_TX_PLL_CONTROL4, 6319 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_25G_FRC_SHIFT, 6320 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_25G_FRC_SHIFT, setmode)); 6321 SOC_IF_ERROR_RETURN 6322 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_TX_PLL_CONTROL4, 6323 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_E100G_SHIFT, 6324 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_E100G_SHIFT, 6325 _phy84793_get_val(rxFbDiv, 1, 1))); 6326 SOC_IF_ERROR_RETURN 6327 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_TX_PLL_CONTROL4, 6328 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_25G_SHIFT, 6329 VSR40_RX_PLL_CONTROL4_SUSM_RX_EN_25G_SHIFT, 6330 _phy84793_get_val(rxFbDiv, 0, 0))); 6331 /*Force for 20g mode*/ 6332 SOC_IF_ERROR_RETURN 6333 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_TX_PLL_CONTROL2, 6334 VSR40_RX_PLL_CONTROL2_SUSM_RX_VCO_EN25G_FRC_SHIFT, 6335 VSR40_RX_PLL_CONTROL2_SUSM_RX_VCO_EN25G_FRC_SHIFT, setmode)); 6336 /*Force for 20g mode*/ 6337 SOC_IF_ERROR_RETURN 6338 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, VSR40_TX_PLL_CONTROL2, 6339 VSR40_RX_PLL_CONTROL2_SUSM_RX_VCO_EN25G_SHIFT, 6340 VSR40_RX_PLL_CONTROL2_SUSM_RX_VCO_EN25G_SHIFT, rx25gMode)); 6341 6342 SOC_IF_ERROR_RETURN 6343 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6344 VSR40_TX_DIG_REGS_RESET_CONTROL, 6345 VSR40_TX_DIG_REGS_RESET_CONTROL_CAL_RSTB_SHIFT, 6346 VSR40_TX_DIG_REGS_RESET_CONTROL_CAL_RSTB_SHIFT, 6347 0x0 )); /*Assert TX CMU Reset*/ 6348 SOC_IF_ERROR_RETURN 6349 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6350 VSR40_TX_DIG_REGS_RESET_CONTROL, 6351 VSR40_TX_DIG_REGS_RESET_CONTROL_CAL_RSTB_SHIFT, 6352 VSR40_TX_DIG_REGS_RESET_CONTROL_CAL_RSTB_SHIFT, 0x1 )); 6353 /*Assert TX CMU Lkdet Reset*/ 6354 SOC_IF_ERROR_RETURN 6355 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6356 VSR40_TX_DIG_REGS_RESET_CONTROL, 6357 VSR40_TX_DIG_REGS_RESET_CONTROL_LKDT_RSTB_SHIFT, 6358 VSR40_TX_DIG_REGS_RESET_CONTROL_LKDT_RSTB_SHIFT, 0x0 )); 6359 SOC_IF_ERROR_RETURN 6360 (_phy_84793_modify_pma_pmd_reg (unit, port, pc, 6361 VSR40_TX_DIG_REGS_RESET_CONTROL, 6362 VSR40_TX_DIG_REGS_RESET_CONTROL_LKDT_RSTB_SHIFT, 6363 VSR40_TX_DIG_REGS_RESET_CONTROL_LKDT_RSTB_SHIFT, 0x1 )); 6364 /*Set input divider*/ 6365 SOC_IF_ERROR_RETURN 6366 (_phy_84793_pcb_wr_bits(unit, port, pc, 0, PHY84793_DC_HC_BROADCAST, 6367 0x805e, 11, 10, rxRefDiv)); 6368 /* Set /66 divider*/ 6369 SOC_IF_ERROR_RETURN 6370 (_phy_84793_pcb_wr_bits(unit, port, pc, 0, PHY84793_DC_HC_BROADCAST, 6371 0x805b, 10, 9, 0x2)); 6372 /* Set /66 divider*/ 6373 SOC_IF_ERROR_RETURN 6374 (_phy_84793_pcb_wr_bits( unit, port, pc, 0, PHY84793_DC_HC_BROADCAST, 6375 0x805a, 14, 12, 0x4)); 6376 /* Select CTRL bus input*/ 6377 SOC_IF_ERROR_RETURN 6378 (_phy_84793_pcb_wr_bits( unit, port, pc, 0, PHY84793_DC_HC_BROADCAST, 6379 0x8059, 9, 9, 0x1)); 6380 /* PLL Restart*/ 6381 SOC_IF_ERROR_RETURN 6382 (_phy_84793_pcb_wr_bits( unit, port, pc, 0, 0, 6383 0x8051, 15, 15, 0x0)); 6384 SOC_IF_ERROR_RETURN 6385 (_phy_84793_pcb_wr_bits(unit, port, pc, 0, 0, 6386 0x8051, 15, 15, 0x1)); 6387 6388 return SOC_E_NONE; 6389 } 6390 6391 int32 phy_84793_hw_reset(int32 unit, soc_port_t port, void *not_used) 6392 { 6393 phy_ctrl_t *pc; 6394 6395 pc = EXT_PHY_SW_STATE(unit, port); 6396 6397 LOG_INFO(BSL_LS_SOC_PHY, 6398 (BSL_META_U(unit, 6399 "84793 HW Reset.....\n"))); 6400 6401 /* Hard Reset */ 6402 SOC_IF_ERROR_RETURN 6403 (WRITE_PHY84793_PMA_PMD_REG(unit, pc, CTL_REGS_COMMON_CTRL1, 0xFFFE)); 6404 6405 SOC_IF_ERROR_RETURN 6406 (_phy_84793_rom_firmware_download (unit, port, 6407 PHY84793_FW_DLOAD_OFFSET, pc, 6408 phy84793_ucode_bin, phy84793_ucode_bin_len)); 6409 6410 SOC_IF_ERROR_RETURN (_phy_84793_config_update(unit, port)); 6411 6412 return SOC_E_NONE; 6413 } 6414 6415 /* 6416 * Variable: 6417 * phy_84793_drv 6418 * Purpose: 6419 * Phy Driver for 100G PHY. 6420 */ 6421 phy_driver_t phy_84793drv_ce = { 6422 "84793 100-Gigabit PHY Driver", 6423 phy_84793_init, /* Init */ 6424 phy_84793_hw_reset, /* Reset */ 6425 phy_84793_link_get, /* Link get */ 6426 phy_84793_enable_set, /* Enable set */ 6427 phy_null_enable_get, /* Enable get */ 6428 phy_null_set, /* Duplex set */ 6429 phy_null_one_get, /* Duplex get */ 6430 phy_84793_speed_set, /* Speed set */ 6431 phy_84793_speed_get, /* Speed get */ 6432 phy_null_set, /* Master set */ 6433 phy_null_zero_get, /* Master get */ 6434 phy_84793_an_set, /* ANA set */ /* Return NONE*/ 6435 phy_null_an_get, /* ANA get */ 6436 NULL, /* Local Advert set */ 6437 NULL, /* Local Advert get */ 6438 phy_null_mode_get, /* Remote Advert get */ 6439 phy_84793_lb_set, /* PHY loopback set */ 6440 phy_84793_lb_get, /* PHY loopback get */ 6441 phy_84793_interface_set, /* IO Interface set */ 6442 phy_84793_interface_get, /* IO Interface get */ 6443 NULL, /* PHY abilities mask */ 6444 NULL, 6445 NULL, 6446 phy_null_mdix_set, 6447 phy_null_mdix_get, 6448 phy_null_mdix_status_get, 6449 NULL, 6450 NULL, 6451 phy_null_medium_get, 6452 NULL, /* phy_cable_diag */ 6453 NULL, /* phy_link_change */ 6454 phy_84793_control_set, /* phy_control_set */ 6455 phy_84793_control_get, /* phy_control_get */ 6456 phy_84793_reg_read, /* phy_reg_read */ 6457 phy_84793_reg_write, /* phy_reg_write */ 6458 NULL, /* phy_reg_modify */ 6459 NULL, /* phy_notify */ 6460 phy_84793_probe, /* pd_probe */ 6461 phy_84793_ability_advert_set, /* pd_ability_advert_set */ /* Return NONE*/ 6462 phy_84793_ability_advert_get, /* pd_ability_advert_get */ /* Return NONE*/ 6463 NULL, /* pd_ability_remote_get */ 6464 phy_84793_ability_local_get, /* pd_ability_local_get */ /* Return NONE*/ 6465 phy_84793_firmware_set, /* pd_firmware_set */ 6466 NULL, /* pd_timesync_config_set */ 6467 NULL, /* pd_timesync_config_get */ 6468 NULL, /* pd_timesync_control_set */ 6469 NULL, /* pd_timesync_control_get */ 6470 phy_84793_diag_ctrl, /* .pd_diag_ctrl */ 6471 phy_84793_per_lane_control_set, /* .pd_lane_control_set*/ 6472 phy_84793_per_lane_control_get /* .pd_lane_control_get*/ 6473 6474 }; 6475 #else /* INCLUDE_PHY_84793 */ 6476 int _phy_84793_not_empty; 6477 #endif /*INCLUDE_PHY_84793*/