openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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                &reg_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                &reg_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                &reg_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               &reg_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               &reg_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)), &reg_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), &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &reg_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, &regval));
   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*/