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

phy82764.c (240588B)


      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:        phy82764.c
      8  * Purpose:     Support for sesto external PHY 
      9  */
     10 
     11 /*
     12  *   This module implements an NTSW SDK Phy driver for the phy82764 External PHY.
     13  *  
     14  *   LAYERING.
     15  *
     16  *   This driver is built on top of the PHYMOD library, which is a PHY
     17  *   driver library that can operate on a family of PHYs, including
     18  *   phy82764 and Sesto and etc..,  PHYMOD can be built in a standalone enviroment and be
     19  *   provided independently from the SDK.  PHYMOD APIs consist of
     20  *   "core" APIs and "phy" APIs.
     21  *
     22  *
     23  *   KEY IDEAS AND MAIN FUNCTIONS
     24  *
     25  *   Some key ideas in this architecture are:
     26  *
     27  *   o A PHMOD "phy" consists of one more more lanes, all residing in a single
     28  *     core.  An SDK "phy" is a logical port, which can consist of one or
     29  *     more lanes in a single core, OR, can consist of multiples lanes in
     30  *     more than one core.
     31  *   o PHYMOD code is "stateless" in the sense that all calls to PHYMOD
     32  *     APIs are fully parameterized and no per-phy state is held by a PHYMOD
     33  *     driver.
     34  *   o PHYMOD APIs do not map 1-1 with SDK .pd_control_set or .pd_control_get
     35  *     APIs (nor ".pd_xx" calls, nor to .phy82764_per_lane_control_set and
     36  *     .phy82764_per_lane_control_get APIs.
     37  *
     38  *   The purpose of this code, then, is to provide the necessary translations
     39  *   between the SDK interfaces and the PHYMOD interfaces.  This includes:
     40  * 
     41  *   o Looping over the cores in a logical PHY in order to operate on the
     42  *     supporting PHMOD PHYs
     43  *   o Determining the configuration data for the phy, based on programmed
     44  *     defaults and SOC properties.
     45  *   o Managing the allocation and freeing of phy data structures required for
     46  *     working storage.  Locating these structures on procedure invocation.
     47  *   o Mapping SDK API concepts to PHYMOD APIs.  In some cases, local state is
     48  *     required in this module in order to present the legacy API.
     49  *
     50  * 
     51  *   MAIN DATA STRUCTURES
     52  * 
     53  *   phy_ctrl_t
     54  *   The PHY control structure defines the SDK notion of a PHY
     55  *   (existing) structure owned by SDK phy driver modules.  In order
     56  *   to support PHYMOD PHYs, one addition was made to this structure
     57  *   (soc_phymod_ctrl_t phymod_ctrl;)
     58  *
     59  *   sesto_config_t
     60  *   Driver specific data.  This structure is used by sesto to hold
     61  *   logical port specific working storage.
     62  *
     63  *   soc_phymod_ctrl_t
     64  *   PHYMOD drivers.  Resides in phy_ctrl_t specifies how many cores
     65  *   are in this phy and contains an array of pointers to
     66  *   soc_phymod_phy_t structures, which define a PHYMOD PHY.
     67  *
     68  *   soc_phymod_phy_t
     69  *   This structure contains a pointer to phymod_phy_access_t and a
     70  *   pointer to the associated soc_phymod_core_t.  Instances if this
     71  *   structure are created during device probe/init and are maintained
     72  *   by the SOC.
     73  *
     74  *   soc_phymod_core_t
     75  *   This structure contains per-core information.  Multiple PHYMOD
     76  *   PHYS can point to a single core.
     77  *
     78  *   phymod_phy_access_t
     79  *   This structure contains information about how to read/write PHY
     80  *   registers.  A required parameter for PHYMOD PHY APIs
     81  * 
     82  *   phymod_core_access_t
     83  *   This structure contains information about how to read/write PHY
     84  *   registers.  A required parameter for PHYMOD core APIs.
     85  */
     86 
     87 #include <shared/bsl.h>
     88 
     89 #include <sal/types.h>
     90 #include <sal/core/spl.h>
     91 #include <shared/bsl.h>
     92 #include <soc/drv.h>
     93 #include <soc/debug.h>
     94 #include <soc/error.h>
     95 #include <soc/phyreg.h>
     96 #include <soc/eyescan.h>
     97 #include <soc/port_ability.h>
     98 #include <soc/phy.h>
     99 #include <soc/phy/phyctrl.h>
    100 #include <soc/phy/drv.h>
    101 #include <soc/phy/phymod_ids.h>
    102 
    103 #include "phydefs.h"      /* Must include before other phy related includes */ 
    104 
    105 #include "phyconfig.h"     /* Must include before other phy related includes */
    106 #include "phyident.h"
    107 #include "phyreg.h"
    108 #include "phynull.h"
    109 #include "xgxs.h"
    110 
    111 
    112 #define PHYMOD_SESTO_SUPPORT
    113 
    114 
    115 #if defined(INCLUDE_PHY_82764)
    116 
    117 #include <phymod/phymod.h>
    118 #include <phymod/phymod_debug.h>
    119 #include <phymod/phymod_diagnostics.h>
    120 #include <phymod/chip/sesto.h>
    121 
    122 
    123 #define NUM_LANES                           8     /* num of lanes per core */
    124 #define MAX_NUM_LANES                       4     /* max num of lanes per port */
    125 #define PHY82764_NO_CFG_VALUE               (-1)
    126 #define PHY82764_DBG_REGACC                 0x2
    127 #define PHY82764_DBG_MEM                    0x3
    128 #define PHY82764_PORT_NO_LANES_4            4
    129 #define PHY82764_PORT_NO_LANES_2            2
    130 #define PHY82764_PORT_NO_LANES_1            1
    131 #define PHY82764_SPD_1G                     1000
    132 #define PHY82764_SPD_10G                    10000
    133 #define PHY82764_SPD_11G                    11000
    134 #define PHY82764_SPD_20G                    20000
    135 #define PHY82764_SPD_21G                    21000
    136 #define PHY82764_SPD_25G                    25000
    137 #define PHY82764_SPD_40G                    40000
    138 #define PHY82764_SPD_42G                    42000
    139 #define PHY82764_SPD_50G                    50000
    140 #define PHY82764_SPD_100G                   100000
    141 #define PHY82764_SPD_106G                   106000
    142 #define SESTO_ID_82764                      0x82764
    143 #define PHY82764_CHIP_ID_SIZE               25
    144 
    145 typedef enum PHY82764_CORE_TYPE {
    146     PHY82764_10G_CORE = 0,
    147     PHY82764_25G_CORE = 1
    148 }PHY82764_CORE_TYPE;
    149 
    150 typedef struct phy82764_device_cfg_aux_mode{
    151     uint8 gearbox_enable;
    152     uint8 pin_compatibility_enable;
    153     uint8 phy_mode_reverse;
    154 }phy82764_device_cfg_aux_mode_t;
    155 
    156 typedef struct phy82764_device_aux_mode {
    157     uint32_t repeater;
    158     uint32_t core_id;
    159 } phy82764_device_aux_mode_t;
    160 
    161 typedef struct phy82764_speed_config_s {
    162     uint32  port_refclk_int;
    163     int     speed;
    164     int     port_num_lanes;
    165     uint32  line_interface;
    166     int     pll_divider_req  ;
    167     int     higig_port;
    168     int     otn_port;
    169 } phy82764_speed_config_t;
    170 
    171 typedef enum PHY82764_INTF_SIDE {
    172     PHY82764_NO_LOC,
    173     PHY82764_LINE_SIDE,
    174     PHY82764_SYS_SIDE 
    175 }PHY82764_INTF_SIDE;
    176 
    177 /*
    178    Config - per logical port
    179 */
    180 typedef struct {
    181     phymod_polarity_t               phy_polarity_config;
    182     phymod_phy_reset_t              phy_reset_config;
    183     phy82764_speed_config_t         speed_config;
    184     int                             an_master_lane;
    185     int                             ull_datapath;
    186     int                             devid;
    187     char                            dev_name[PHY82764_CHIP_ID_SIZE];
    188     int                             auto_mod_detect;
    189     int                             sys_lane_map;  
    190     phy82764_device_aux_mode_t      *device_aux_modes;
    191     phy82764_device_cfg_aux_mode_t  device_cfg_aux_modes;
    192 } phy82764_config_t;
    193 
    194 #define DEVID(_pc)           (((phy82764_config_t *)((_pc) + 1))->devid)
    195 #define DEV_NAME(_pc)        (((phy82764_config_t *)((_pc) + 1))->dev_name)
    196 
    197 int eye_scan_enabled = 0;
    198 
    199 STATIC int
    200 phy_82764_ability_advert_set(int unit, soc_port_t port,
    201                           soc_port_ability_t *ability);
    202 
    203 STATIC int
    204 phy_82764_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability);
    205 STATIC int
    206 _phy_82764_find_soc_phy_lane(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32_t lane,
    207                              soc_phymod_phy_t **p_phy, uint32 *lane_map);
    208 
    209 STATIC int
    210 phy_82764_power_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    211 STATIC int
    212 phy_82764_power_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value);
    213 STATIC int
    214 phy_82764_per_lane_tx_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, soc_phy_control_t type, int lane, uint32 *value);
    215 STATIC int
    216 phy_82764_per_lane_tx_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, soc_phy_control_t type, int lane, uint32 value);
    217 STATIC int
    218 phy_82764_per_lane_short_chn_mode_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value);
    219 STATIC int
    220 phy_82764_per_lane_short_chn_mode_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value);
    221 STATIC int
    222 phy_82764_per_lane_short_chn_mode_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value);
    223 STATIC int
    224 phy_82764_per_lane_cl72_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value);
    225 STATIC int
    226 phy_82764_per_lane_cl72_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value);
    227 STATIC int
    228 phy_82764_per_lane_cl72_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value);
    229 STATIC int
    230 phy_82764_cl72_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value);
    231 STATIC int
    232 phy_82764_cl72_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value);
    233 STATIC int
    234 phy_82764_cl72_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    235 STATIC int
    236 phy_82764_per_lane_tx_lane_squelch_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value);
    237 STATIC int
    238 phy_82764_loopback_internal_pmd_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value);
    239 STATIC int
    240 phy_82764_loopback_internal_pmd_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    241 STATIC int
    242 phy_82764_link_monitor_status_get (soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int32 lane);
    243 STATIC int
    244 phy_82764_link_monitor_set (soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int32 lane, uint32 value);
    245 STATIC int
    246 phy_82764_intr_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    247 STATIC int
    248 phy_82764_intr_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value);
    249 STATIC int
    250 phy_82764_intr_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value);
    251 STATIC int
    252 phy_82764_tx_fir_post_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    253 STATIC int
    254 phy_82764_driver_current_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    255 STATIC int
    256 phy_82764_tx_fir_main_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    257 STATIC int
    258 phy_82764_tx_fir_pre_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    259 STATIC int
    260 phy_82764_tx_fir_post2_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value);
    261 STATIC int
    262 phy_82764_firmware_lp_dfe_enable_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 *value);
    263 STATIC int
    264 phy_82764_unreliable_los_get(phy_ctrl_t *pc, soc_port_t port, int32 intf,  uint32 *value);
    265 STATIC int
    266 phy_82764_firmware_dfe_enable_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 *value);
    267 STATIC int
    268 phy_82764_firmware_mode_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 *value);
    269 STATIC int
    270 phy_82764_firmware_lp_dfe_enable_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 enable);
    271 STATIC int
    272 phy_82764_unreliable_los_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 enable);
    273 STATIC int
    274 phy_82764_firmware_dfe_enable_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 enable);
    275 STATIC int
    276 phy_82764_firmware_mode_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 value);
    277 STATIC int
    278 _phy82764_speed_to_lane_map_get(phy_ctrl_t *pc, uint32 *line_lane_map, uint32 *sys_lane_map);
    279 STATIC int
    280 phy_82764_per_lane_control_set(int unit, soc_port_t port, int lane, soc_phy_control_t type, uint32 value);
    281 STATIC int
    282 phy_82764_per_lane_control_get(int unit, soc_port_t port, int lane, soc_phy_control_t type, uint32 *value);
    283 
    284 /* C To Interger */
    285 STATIC int my_ctoi(const char *s, int lane)
    286 {
    287     if (s == 0) {
    288         return 0;
    289     }
    290 
    291     if (*s == '0') {
    292         s++;
    293         if (*s == 'x' || *s == 'X') {
    294             s++;
    295         }
    296     }
    297     s = s + (sal_strlen(s) - (lane + 1));
    298 
    299     return (*s -'0');
    300 }
    301 /* no of lanes on line side per port */
    302 int port_num_lanes_line_side_get(int unit, soc_port_t port, int speed_max)
    303 {
    304     if (speed_max == PHY82764_SPD_100G || speed_max == PHY82764_SPD_106G) {
    305         return 10;
    306     } else if (speed_max == PHY82764_SPD_40G || speed_max == PHY82764_SPD_42G) {
    307         return 4;
    308     } else if (speed_max == PHY82764_SPD_20G || speed_max == PHY82764_SPD_21G) {
    309         return 2;
    310     } else {
    311         return 1;
    312     }
    313 }
    314 
    315 /*
    316  * Function:
    317  *      _phy82764_sys_side_lane_map_get
    318  * Purpose:
    319  *      Mapping to speed to lane map based on config
    320  * Parameters:
    321  *      unit - BCM unit number.
    322  *      port - Port number.
    323  *      phymod_phy_access_t - [OUT] Line Lane map
    324  * Returns:
    325  *      SOC_E_NONE
    326  */
    327 
    328 
    329 STATIC int
    330 _phy82764_sys_side_lane_map_get(int unit, soc_port_t port, phymod_phy_access_t *pm_phy_copy)
    331 {
    332     phy_ctrl_t *pc;
    333     phy82764_config_t *pCfg;
    334 
    335     pc = EXT_PHY_SW_STATE(unit, port);
    336 
    337     if (pc == NULL) {
    338         return SOC_E_INTERNAL;
    339     }
    340     pCfg = (phy82764_config_t *) pc->driver_data;
    341 
    342     pm_phy_copy->access.lane_mask = pCfg->sys_lane_map;
    343 
    344     return SOC_E_NONE;
    345 }
    346 
    347 /*
    348  * Function:
    349  *      _phy82764_reg_read
    350  * Doc:
    351  *      register read operations
    352  * Parameters:
    353  *      unit            - (IN)  unit number
    354  *      core_addr       - (IN)  core address
    355  *      reg_addr        - (IN)  address to read
    356  *      val             - (OUT) read value
    357  */
    358 STATIC int 
    359 _phy82764_reg_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
    360 {
    361     uint16 data16 = 0;
    362     int rv = 0;
    363     soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc;
    364 
    365     rv = core->read(core->unit, core_addr, reg_addr, &data16);
    366     *val = data16;
    367     PHYMOD_VDBG(PHY82764_DBG_REGACC, NULL,("-22%s: core_addr: 0x%08x reg_addr: 0x%08x, data: 0x%04x\n", __func__, core_addr, reg_addr, *val ));
    368 
    369     return rv;
    370 }
    371 
    372 /*
    373  * Function:
    374  *      _phy82764_reg_write
    375  * Doc:
    376  *      register write operations
    377  * Parameters:
    378  *      unit            - (IN)  unit number
    379  *      core_addr       - (IN)  core address
    380  *      reg_addr        - (IN)  address to write
    381  *      val             - (IN)  write value
    382  */
    383 STATIC int 
    384 _phy82764_reg_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
    385 {
    386     soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc;
    387     uint16 data16 = (uint16)val;
    388     uint16 mask = (uint16)(val >> 16);
    389 
    390     if (mask) {
    391         if (core->wrmask) {
    392             return core->wrmask(core->unit, core_addr, reg_addr, data16, mask);
    393         }
    394         (void)core->read(core->unit, core_addr, reg_addr, &data16);
    395         data16 &= ~mask;
    396         data16 |= (val & mask);
    397     }
    398     PHYMOD_VDBG(PHY82764_DBG_REGACC, NULL,("-22%s: core_addr: 0x%08x reg_addr: 0x%08x, data: 0x%04x\n", __func__, core_addr, reg_addr, val ));
    399     return core->write(core->unit, core_addr, reg_addr, data16);
    400 }
    401 
    402 /*
    403  * Function:
    404  *      phy82764_speed_to_interface_config_get
    405  * Purpose:     
    406  *      Convert speed to interface_config struct
    407  * Parameters:
    408  *      unit                - BCM unit number.
    409  *      port                - Port number.
    410  *      speed               - speed to convert
    411  *      interface_config    - output interface config struct
    412  * Returns:     
    413  *      SOC_E_NONE
    414  */
    415 STATIC int 
    416 phy82764_speed_to_interface_config_get(phy82764_speed_config_t* speed_config, phymod_phy_inf_config_t* interface_config)
    417 {
    418     SOC_IF_ERROR_RETURN(phymod_phy_inf_config_t_init(interface_config));
    419 
    420     interface_config->interface_modes = 0;
    421     interface_config->data_rate       = speed_config->speed;
    422     interface_config->pll_divider_req = speed_config->pll_divider_req ;
    423 
    424     switch (speed_config->speed) {
    425         case PHY82764_SPD_1G:
    426             switch(speed_config->line_interface) {
    427                 case SOC_PORT_IF_SR:
    428                     interface_config->interface_type = phymodInterfaceSR;
    429                 break;
    430                 default:
    431                     return SOC_E_PARAM;
    432 
    433             }
    434         break;
    435         case PHY82764_SPD_10G:
    436         case PHY82764_SPD_11G:
    437         case PHY82764_SPD_25G:
    438             switch(speed_config->line_interface) {
    439                 case SOC_PORT_IF_KR:
    440                     interface_config->interface_type = phymodInterfaceKR;
    441                 break;
    442                 case SOC_PORT_IF_LR:
    443                     interface_config->interface_type = phymodInterfaceLR;
    444                 break;
    445                 case SOC_PORT_IF_ER:
    446                     interface_config->interface_type = phymodInterfaceER;
    447                 break;
    448                 case SOC_PORT_IF_SR:
    449                     interface_config->interface_type = phymodInterfaceSR;
    450                 break;
    451                 case SOC_PORT_IF_CX:
    452                     interface_config->interface_type = phymodInterfaceCX;
    453                 break;
    454                 case SOC_PORT_IF_CR:
    455                     interface_config->interface_type = phymodInterfaceCR;
    456                 break;
    457                 case SOC_PORT_IF_SFI:
    458                     interface_config->interface_type = phymodInterfaceSFI;
    459                 break;
    460                 case SOC_PORT_IF_XFI:
    461                     interface_config->interface_type = phymodInterfaceXFI;
    462                 break;
    463                 default:
    464                     return SOC_E_PARAM;
    465                     
    466             }
    467         break;
    468         case PHY82764_SPD_20G:
    469         case PHY82764_SPD_21G:
    470             switch(speed_config->line_interface) {
    471                 case SOC_PORT_IF_KR2:
    472                     interface_config->interface_type = phymodInterfaceKR2;
    473                 break;
    474                 case SOC_PORT_IF_LR2:
    475                     interface_config->interface_type = phymodInterfaceLR2;
    476                 break;
    477                 case SOC_PORT_IF_SR2:
    478                     interface_config->interface_type = phymodInterfaceSR2;
    479                 break;
    480                 case SOC_PORT_IF_CR2:
    481                     interface_config->interface_type = phymodInterfaceCR2;
    482                 break;
    483                 case SOC_PORT_IF_ER2:
    484                     interface_config->interface_type = phymodInterfaceER2;
    485                 break;
    486                 /* This changes are to support speed change from 2 lane 20G to 40G and vice versa */
    487                 case SOC_PORT_IF_KR4:
    488                     interface_config->interface_type = phymodInterfaceKR2;
    489                 break;
    490                 case SOC_PORT_IF_LR4:
    491                     interface_config->interface_type = phymodInterfaceLR2;
    492                 break;
    493                 case SOC_PORT_IF_SR4:
    494                     interface_config->interface_type = phymodInterfaceSR2;
    495                 break;
    496                 case SOC_PORT_IF_CR4:
    497                     interface_config->interface_type = phymodInterfaceCR2;
    498                 break;
    499                 case SOC_PORT_IF_ER4:
    500                     interface_config->interface_type = phymodInterfaceER2;
    501                 break;
    502                 default:
    503                     return SOC_E_PARAM;
    504 
    505             }
    506         break;
    507         case PHY82764_SPD_40G:
    508         case PHY82764_SPD_42G:
    509         case PHY82764_SPD_50G:
    510             switch(speed_config->line_interface) {
    511                 case SOC_PORT_IF_KR4:
    512                     interface_config->interface_type = phymodInterfaceKR4;
    513                 break;
    514                 case SOC_PORT_IF_LR4:
    515                     interface_config->interface_type = phymodInterfaceLR4;
    516                 break;
    517                 case SOC_PORT_IF_SR4:
    518                     interface_config->interface_type = phymodInterfaceSR4;
    519                 break;
    520                 case SOC_PORT_IF_CR4:
    521                     interface_config->interface_type = phymodInterfaceCR4;
    522                 break;
    523                 case SOC_PORT_IF_ER4:
    524                     interface_config->interface_type = phymodInterfaceER4;
    525                 break;
    526                 case SOC_PORT_IF_XLAUI:
    527                     interface_config->interface_type = phymodInterfaceXLAUI;
    528                 break;
    529                 case SOC_PORT_IF_XLPPI:
    530                     interface_config->interface_type = phymodInterfaceXLPPI;
    531                 break;
    532                 /* This changes are to support speed change from 2 lane 20G to 40G and vice versa */
    533                 case SOC_PORT_IF_KR2:
    534                     interface_config->interface_type = phymodInterfaceKR4;
    535                 break;
    536                 case SOC_PORT_IF_SR2:
    537                     interface_config->interface_type = phymodInterfaceSR4;
    538                 break;
    539                 case SOC_PORT_IF_CR2:
    540                     interface_config->interface_type = phymodInterfaceCR4;
    541                 break;
    542                 case SOC_PORT_IF_ER2:
    543                     interface_config->interface_type = phymodInterfaceER4;
    544                 break;
    545                 case SOC_PORT_IF_LR2:
    546                     interface_config->interface_type = phymodInterfaceLR4;
    547                 break;
    548                 default:
    549                     return SOC_E_PARAM;
    550                     
    551             }    
    552         break;
    553         case PHY82764_SPD_100G:
    554         case PHY82764_SPD_106G:
    555             switch(speed_config->line_interface) {
    556                 case SOC_PORT_IF_SR10:
    557                     interface_config->interface_type = phymodInterfaceSR10;
    558                 break;
    559                 case SOC_PORT_IF_KR10:
    560                     interface_config->interface_type = phymodInterfaceKR10;
    561                 break;
    562                 case SOC_PORT_IF_LR10:
    563                     interface_config->interface_type = phymodInterfaceLR10;
    564                 break;
    565                 case SOC_PORT_IF_CR10:
    566                     interface_config->interface_type = phymodInterfaceCR10;
    567                 break;
    568                 case SOC_PORT_IF_CAUI:
    569                     interface_config->interface_type = phymodInterfaceCAUI;
    570                 break;
    571                 case SOC_PORT_IF_VSR:
    572                     interface_config->interface_type = phymodInterfaceVSR;
    573                 break;
    574                 case SOC_PORT_IF_CAUI_C2C:
    575                     interface_config->interface_type = phymodInterfaceCAUI4_C2C;
    576                 break;
    577                 case SOC_PORT_IF_CAUI_C2M:
    578                     interface_config->interface_type = phymodInterfaceCAUI4_C2M;
    579                 break;
    580                 case SOC_PORT_IF_KR4:
    581                     interface_config->interface_type = phymodInterfaceKR4;
    582                 break;
    583                 case SOC_PORT_IF_LR4:
    584                     interface_config->interface_type = phymodInterfaceLR4;
    585                 break;
    586                 case SOC_PORT_IF_SR4:
    587                     interface_config->interface_type = phymodInterfaceSR4;
    588                 break;
    589                 case SOC_PORT_IF_CR4:
    590                     interface_config->interface_type = phymodInterfaceCR4;
    591                 break;
    592                 case SOC_PORT_IF_ER4:
    593                     interface_config->interface_type = phymodInterfaceER4;
    594                 break;
    595                 case SOC_PORT_IF_XLAUI:
    596                     interface_config->interface_type = phymodInterfaceXLAUI;
    597                 break;
    598                 default:
    599                     return SOC_E_PARAM;
    600             }
    601         break;
    602         default:
    603             return SOC_E_PARAM;
    604     }
    605 
    606     switch (speed_config->port_refclk_int) {
    607         case 106:
    608             interface_config->ref_clock = phymodRefClk106Mhz;
    609         break;
    610         case 156:
    611             interface_config->ref_clock = phymodRefClk156Mhz;
    612         break;
    613         case 125:
    614             interface_config->ref_clock = phymodRefClk125Mhz;
    615         break;
    616         case 161:
    617             interface_config->ref_clock = phymodRefClk161Mhz;
    618         break;
    619         case 174:
    620             interface_config->ref_clock = phymodRefClk174Mhz;
    621         break;
    622         case 312:
    623             interface_config->ref_clock = phymodRefClk312Mhz;
    624         break;
    625         case 322:
    626             interface_config->ref_clock = phymodRefClk322Mhz;
    627         break;
    628         case 644:
    629             interface_config->ref_clock = phymodRefClk644Mhz;
    630         break;
    631         case 349:
    632             interface_config->ref_clock = phymodRefClk349Mhz;
    633         break;
    634         case 698:
    635             interface_config->ref_clock = phymodRefClk698Mhz;
    636         break;
    637         default:
    638             return SOC_E_PARAM;
    639     }
    640     if (speed_config->higig_port) {
    641         PHYMOD_INTF_MODES_HIGIG_SET(interface_config);
    642     }
    643     if (speed_config->otn_port) {
    644         PHYMOD_INTF_MODES_OTN_SET(interface_config);
    645     }
    646 
    647     return SOC_E_NONE;
    648 }
    649 
    650 /*
    651  * Function:
    652  *      phy82764_speed_set
    653  * Purpose:
    654  *      Set PHY speed
    655  * Parameters:
    656  *      unit - BCM unit number.
    657  *      port - Port number. 
    658  *      speed - link speed in Mbps
    659  * Returns:     
    660  *      SOC_E_NONE
    661  */
    662 
    663 STATIC int
    664 phy82764_speed_set(int unit, soc_port_t port, int speed)
    665 {
    666     phy_ctrl_t                *pc;
    667     phy_ctrl_t                *int_pc;
    668     phy82764_config_t         *pCfg;
    669     soc_phymod_ctrl_t         *pmc;
    670     soc_phymod_phy_t          *phy;
    671     int                       idx;
    672     int                       int_speed;
    673     phy82764_speed_config_t   speed_config;
    674     phymod_phy_inf_config_t   interface_config;
    675     phymod_phy_inf_config_t   intf_config;
    676     phy82764_device_cfg_aux_mode_t *device_cfg_aux_modes;
    677     uint32 line_lane_map, sys_lane_map;
    678 
    679     /* locate phy control */
    680     pc = EXT_PHY_SW_STATE(unit, port);
    681     int_pc = INT_PHY_SW_STATE(unit, port);
    682     if (pc == NULL || int_pc == NULL) {
    683         return SOC_E_INTERNAL;
    684     }
    685 
    686     if (speed == 0) {
    687         return SOC_E_NONE; 
    688     }
    689     SOC_IF_ERROR_RETURN(PHY_SPEED_GET(int_pc->pd, unit, port, &int_speed));
    690     if (int_speed != speed) {
    691        SOC_IF_ERROR_RETURN(PHY_SPEED_SET(int_pc->pd, unit, port, speed));
    692        SOC_IF_ERROR_RETURN(PHY_SPEED_GET(int_pc->pd, unit, port, &int_speed));
    693        if (int_speed != speed) {
    694            return SOC_E_CONFIG;
    695        }
    696     }
    697     pmc = &pc->phymod_ctrl;
    698     pCfg = (phy82764_config_t *) pc->driver_data;
    699     device_cfg_aux_modes = &(pCfg->device_cfg_aux_modes);
    700 
    701     /* take a copy of core and phy configuration values, and set the desired speed */
    702     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
    703     speed_config.speed = speed;
    704 
    705     /* determine the interface configuration */
    706     SOC_IF_ERROR_RETURN
    707         (phy82764_speed_to_interface_config_get(&speed_config, &interface_config));
    708 
    709     /* now loop through all cores */
    710     for (idx = 0; idx < pmc->num_phys; idx++) {
    711         phy = pmc->phy[idx];
    712         if (phy == NULL) {
    713             return SOC_E_INTERNAL;
    714         }
    715 
    716         phy->pm_phy.device_op_mode = 0;
    717         /* soc read for phy device operation mode */
    718         device_cfg_aux_modes->gearbox_enable = (soc_property_port_get(unit, port, spn_PHY_GEARBOX_ENABLE, FALSE));
    719         device_cfg_aux_modes->pin_compatibility_enable = soc_property_port_get(unit, port,
    720                                    spn_PHY_PIN_COMPATIBILITY_ENABLE, FALSE);
    721         device_cfg_aux_modes->phy_mode_reverse = soc_property_port_get(unit, port, spn_PORT_PHY_MODE_REVERSE, 0);
    722 
    723         /* copy the soc config to phymod_core_access */
    724         /* bit 0 is for gearbox_enable */
    725         /* bit 1 is for pin_compatibility_enable */
    726         /* bit 2 is for phy_mode_reverse */
    727         phy->pm_phy.device_op_mode |= device_cfg_aux_modes->gearbox_enable;
    728         phy->pm_phy.device_op_mode |= (device_cfg_aux_modes->pin_compatibility_enable << 1);
    729         phy->pm_phy.device_op_mode |= (device_cfg_aux_modes->phy_mode_reverse << 2);
    730 
    731         if (pc->speed_max != speed) {
    732             pc->speed_max = speed;
    733         }
    734         SOC_IF_ERROR_RETURN
    735             (_phy82764_speed_to_lane_map_get(pc, &line_lane_map, &sys_lane_map));
    736         pCfg->sys_lane_map = sys_lane_map;
    737         phy->pm_phy.access.lane_mask = line_lane_map;
    738 
    739         SOC_IF_ERROR_RETURN
    740             (phymod_phy_interface_config_set(&phy->pm_phy,
    741                                              0 /* flags */, &interface_config));
    742         SOC_IF_ERROR_RETURN
    743             (phymod_phy_interface_config_get(&phy->pm_phy,
    744                                              0 /* flags */,  0, &intf_config));
    745     }
    746 
    747     /* record success */
    748     pCfg->speed_config.speed = speed;
    749 
    750     /* speed notify form ext phy */
    751     if (speed != intf_config.data_rate) {
    752         speed = intf_config.data_rate;
    753         SOC_IF_ERROR_RETURN(PHY_SPEED_SET(int_pc->pd, unit, port, speed));
    754         SOC_IF_ERROR_RETURN(PHY_SPEED_GET(int_pc->pd, unit, port, &int_speed));
    755         if (int_speed != speed) {
    756             return SOC_E_CONFIG;
    757         }
    758 
    759         /* record success on speed notify form ext phy*/
    760         pCfg->speed_config.speed = speed;
    761     }
    762 
    763     return (SOC_E_NONE);
    764 }
    765 
    766 /*
    767  * Function:
    768  *      phy82764_speed_get
    769  * Purpose:
    770  *      Get PHY speed
    771  * Parameters:
    772  *      unit - BCM unit number.
    773  *      port - Port number. 
    774  *      speed - current link speed in Mbps
    775  * Returns:     
    776  *      SOC_E_NONE
    777  */
    778 STATIC int
    779 phy82764_speed_get(int unit, soc_port_t port, int *speed)
    780 {
    781     phy_ctrl_t                *pc;
    782     soc_phymod_ctrl_t         *pmc;
    783     soc_phymod_phy_t          *phy;
    784     phy82764_config_t         *pCfg;
    785     phymod_phy_inf_config_t   interface_config;
    786     phy82764_speed_config_t   speed_config;
    787     phymod_ref_clk_t ref_clock;
    788     int flag = 0;
    789     ref_clock = 0;
    790     /* locate phy control */
    791     pc = EXT_PHY_SW_STATE(unit, port);
    792     if (pc == NULL) {
    793         return SOC_E_INTERNAL;
    794     }
    795 
    796     pmc = &pc->phymod_ctrl;
    797 
    798     pCfg = (phy82764_config_t *) pc->driver_data;
    799 
    800     /* take a copy of core and phy configuration values, and set the desired speed */
    801     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
    802     /* initialize the data structure */
    803     interface_config.data_rate = 0;
    804 
    805     /* now loop through all cores */
    806     phy = pmc->phy[pmc->main_phy];
    807     if (phy == NULL) {
    808         return SOC_E_INTERNAL;
    809     }
    810 
    811     /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */
    812     SOC_IF_ERROR_RETURN
    813         (phymod_phy_interface_config_get(&phy->pm_phy, flag,
    814                                          ref_clock, 
    815                                          &interface_config));
    816     if(speed_config.speed != interface_config.data_rate) {
    817         *speed = speed_config.speed;
    818     } else {
    819         *speed = interface_config.data_rate;
    820     }
    821 
    822     return (SOC_E_NONE);
    823 }
    824 
    825 
    826 STATIC int
    827 phy82764_interface_set(int unit, soc_port_t port, soc_port_if_t pif)
    828 {
    829     phy_ctrl_t      *pc;
    830     phy82764_config_t *pCfg;
    831     phy82764_speed_config_t   speed_config;
    832     phymod_phy_inf_config_t   interface_config;
    833     soc_phymod_ctrl_t         *pmc;
    834     soc_phymod_phy_t          *phy;
    835     int                       idx = 0;
    836     phy82764_device_cfg_aux_mode_t *device_cfg_aux_modes;
    837 
    838     pc = EXT_PHY_SW_STATE(unit, port);
    839     if (pc == NULL) {
    840         return SOC_E_INTERNAL;
    841     }
    842     pCfg = (phy82764_config_t *) pc->driver_data;
    843     pmc = &pc->phymod_ctrl;
    844     device_cfg_aux_modes = &(pCfg->device_cfg_aux_modes);
    845 
    846     if (pif >= SOC_PORT_IF_COUNT) {
    847         return SOC_E_PARAM;
    848     }
    849     if (pif == SOC_PORT_IF_MII || pif == SOC_PORT_IF_XGMII || pif == SOC_PORT_IF_GMII) {
    850 		return phy_null_interface_set(unit, port, pif);
    851 	}
    852 
    853     /*Work around for to support flex of 10G To 40G Mux as part of jira PHY-1805 */
    854     if (((pc->speed_max == PHY82764_SPD_20G) && (device_cfg_aux_modes->gearbox_enable == TRUE)) ||
    855         (pc->speed_max == PHY82764_SPD_25G) || (pc->speed_max == PHY82764_SPD_50G)){
    856         return SOC_E_NONE;
    857     }
    858 
    859     /* take a copy of core and phy configuration values, and set the desired speed */
    860     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
    861     speed_config.line_interface = pif;
    862     SOC_IF_ERROR_RETURN
    863         (phy82764_speed_to_interface_config_get(&speed_config, &interface_config));
    864 
    865     /* now loop through all cores */
    866     for (idx = 0; idx < pmc->num_phys; idx++) {
    867         phy = pmc->phy[idx];
    868         if (phy == NULL) {
    869             return SOC_E_INTERNAL;
    870         }
    871         SOC_IF_ERROR_RETURN
    872             (phymod_phy_interface_config_set(&phy->pm_phy,
    873                                        0 /* flags */, &interface_config));
    874     }
    875 
    876     pCfg->speed_config.line_interface = pif;
    877 
    878     return SOC_E_NONE;
    879 }
    880 
    881 STATIC int
    882 phy82764_interface_get(int unit, soc_port_t port, soc_port_if_t *pif)
    883 {
    884     phy_ctrl_t                *pc;
    885     phy82764_config_t         *pCfg;
    886     soc_phymod_ctrl_t         *pmc;
    887     soc_phymod_phy_t          *phy;
    888     phymod_phy_inf_config_t   interface_config;
    889     phymod_ref_clk_t          ref_clock;
    890     phy82764_speed_config_t   speed_config;
    891     int flag = 0;
    892     ref_clock = 0;
    893 
    894     /* locate phy control */
    895     pc = EXT_PHY_SW_STATE(unit, port);
    896     if (pc == NULL) {
    897         return SOC_E_INTERNAL;
    898     }
    899 
    900     pmc = &pc->phymod_ctrl;
    901     pCfg = (phy82764_config_t *) pc->driver_data;
    902     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
    903 
    904     /* initialize the data structure */
    905     sal_memset(&interface_config, 0x0, sizeof(phymod_phy_inf_config_t));
    906 
    907     /* now loop through all cores */
    908     phy = pmc->phy[pmc->main_phy];
    909     if (phy == NULL) {
    910         return SOC_E_INTERNAL;
    911     }
    912     /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */
    913     SOC_IF_ERROR_RETURN
    914         (phymod_phy_interface_config_get(&phy->pm_phy, ref_clock,
    915                                          flag, &interface_config));
    916     switch (interface_config.interface_type) {
    917         case phymodInterfaceKX:
    918             *pif = SOC_PORT_IF_KX;
    919         break;
    920         case phymodInterfaceKR:
    921             if ((speed_config.speed == PHY82764_SPD_100G) || (speed_config.speed == PHY82764_SPD_40G) ||
    922                 (speed_config.speed == PHY82764_SPD_106G) || (speed_config.speed == PHY82764_SPD_42G)) {
    923                 *pif = SOC_PORT_IF_KR4;
    924             } else {
    925                 *pif = SOC_PORT_IF_KR;
    926             }
    927         break;
    928         case phymodInterfaceSR:
    929             if ((speed_config.speed == PHY82764_SPD_100G) || (speed_config.speed == PHY82764_SPD_40G) ||
    930                 (speed_config.speed == PHY82764_SPD_106G) || (speed_config.speed == PHY82764_SPD_42G)) {
    931                 *pif = SOC_PORT_IF_SR4;
    932             } else {
    933                 *pif = SOC_PORT_IF_SR;
    934             }
    935         break;
    936         case phymodInterfaceLR:
    937             if ((speed_config.speed == PHY82764_SPD_100G) || (speed_config.speed == PHY82764_SPD_40G) ||
    938                 (speed_config.speed == PHY82764_SPD_106G) || (speed_config.speed == PHY82764_SPD_42G)) {
    939                 *pif = SOC_PORT_IF_LR4;
    940             } else {
    941                 *pif = SOC_PORT_IF_LR;
    942             }
    943         break;
    944         case phymodInterfaceCR:
    945             if ((speed_config.speed == PHY82764_SPD_100G) || (speed_config.speed == PHY82764_SPD_40G) ||
    946                 (speed_config.speed == PHY82764_SPD_106G) || (speed_config.speed == PHY82764_SPD_42G)) {
    947                 *pif = SOC_PORT_IF_CR4;
    948             } else {
    949                 *pif = SOC_PORT_IF_CR;
    950             }
    951         break;
    952         case phymodInterfaceER:
    953             if ((speed_config.speed == PHY82764_SPD_100G) || (speed_config.speed == PHY82764_SPD_40G) ||
    954                 (speed_config.speed == PHY82764_SPD_106G) || (speed_config.speed == PHY82764_SPD_42G)) {
    955                 *pif = SOC_PORT_IF_ER4;
    956             } else {
    957                 *pif = SOC_PORT_IF_ER;
    958             }
    959         break;
    960         case phymodInterfaceSR2:
    961             *pif = SOC_PORT_IF_SR2;
    962         break;
    963         case phymodInterfaceLR2:
    964             *pif = SOC_PORT_IF_LR2;
    965         break;
    966         case phymodInterfaceKR2:
    967             *pif = SOC_PORT_IF_KR2;
    968         break;
    969         case phymodInterfaceCR2:
    970             *pif = SOC_PORT_IF_CR2;
    971         break;
    972         case phymodInterfaceER2:
    973             *pif = SOC_PORT_IF_ER2;
    974         break;
    975         case phymodInterfaceKR4:
    976             *pif = SOC_PORT_IF_KR4;
    977         break;
    978         case phymodInterfaceCR4:
    979             *pif = SOC_PORT_IF_CR4;
    980         break;
    981         case phymodInterfaceSR4:
    982             *pif = SOC_PORT_IF_SR4;
    983         break;
    984         case phymodInterfaceER4:
    985             *pif = SOC_PORT_IF_ER4;
    986         break;
    987         case phymodInterfaceLR4:
    988             *pif = SOC_PORT_IF_LR4;
    989         break;
    990         case phymodInterfaceSR10:
    991             *pif = SOC_PORT_IF_SR10;
    992         break;
    993         case phymodInterfaceKR10:
    994             *pif = SOC_PORT_IF_KR10;
    995         break;
    996         case phymodInterfaceLR10:
    997             *pif = SOC_PORT_IF_LR10;
    998         break;
    999         case phymodInterfaceCR10:
   1000             *pif = SOC_PORT_IF_CR10;
   1001         break;
   1002         case phymodInterfaceVSR:
   1003             *pif = SOC_PORT_IF_VSR;
   1004         break;
   1005         case phymodInterfaceCAUI4_C2C:
   1006             *pif = SOC_PORT_IF_CAUI_C2C;
   1007         break;
   1008         case phymodInterfaceCAUI4_C2M:
   1009             *pif = SOC_PORT_IF_CAUI_C2M;
   1010         break;
   1011         case phymodInterfaceSFI:
   1012             *pif = SOC_PORT_IF_SFI;
   1013         break;
   1014         case phymodInterfaceXFI:
   1015             *pif = SOC_PORT_IF_XFI;
   1016         break;
   1017         case phymodInterfaceCAUI:
   1018             *pif = SOC_PORT_IF_CAUI;
   1019         break;
   1020         case phymodInterfaceXLAUI:
   1021             *pif = SOC_PORT_IF_XLAUI;
   1022         break;
   1023         case phymodInterfaceXLPPI:
   1024             *pif = SOC_PORT_IF_XLPPI;
   1025         break;
   1026         case phymodInterfaceXLAUI2:
   1027             *pif = SOC_PORT_IF_XLAUI2;
   1028         break;
   1029         default:
   1030         break;
   1031     }
   1032 
   1033     return (SOC_E_NONE);
   1034 }
   1035 
   1036 /*
   1037  * Function:
   1038  *      phy82764_reg_read
   1039  * Purpose:
   1040  *      Routine to read PHY register
   1041  * Parameters:
   1042  *      unit         - BCM unit number
   1043  *      port         - Port number
   1044  *      flags        - Flags which specify the register type
   1045  *      phy_reg_addr - Encoded register address
   1046  *      phy_data     - (OUT) Value read from PHY register
   1047  * Note:
   1048  *      This register read function is not thread safe. Higher level
   1049  * function that calls this function must obtain a per port lock
   1050  * to avoid overriding register page mapping between threads.
   1051  */
   1052 STATIC int
   1053 phy82764_reg_read(int unit, soc_port_t port, uint32 flags,
   1054                   uint32 phy_reg_addr, uint32 *phy_reg_data)
   1055 {
   1056     phy_ctrl_t *pc;
   1057     soc_phymod_ctrl_t *pmc;
   1058     phymod_phy_access_t *pm_phy;
   1059     int idx = 0;
   1060     uint8 data8 = 0;
   1061 
   1062     pc = EXT_PHY_SW_STATE(unit, port);
   1063     if (pc == NULL) {
   1064         return SOC_E_INTERNAL;
   1065     }
   1066 
   1067     pmc = &pc->phymod_ctrl;
   1068     idx = pmc->main_phy ;
   1069     pm_phy = &pmc->phy[idx]->pm_phy;
   1070 
   1071     if (flags & SOC_PHY_I2C_DATA8) {
   1072         SOC_IF_ERROR_RETURN
   1073             (phymod_phy_i2c_read(pm_phy, 0, SOC_PHY_I2C_DEVAD(phy_reg_addr), SOC_PHY_I2C_REGAD(phy_reg_addr), 1, &data8));
   1074         *phy_reg_data = data8;
   1075     } else {
   1076         SOC_IF_ERROR_RETURN
   1077             (phymod_phy_reg_read(pm_phy, phy_reg_addr, phy_reg_data));
   1078     }
   1079     return SOC_E_NONE;
   1080 }
   1081 
   1082 /*
   1083  * Function:
   1084  *      phy82764_reg_write
   1085  * Purpose:
   1086  *      Routine to write PHY register
   1087  * Parameters:
   1088  *      uint         - BCM unit number
   1089  *      pc           - PHY state
   1090  *      flags        - Flags which specify the register type
   1091  *      phy_reg_addr - Encoded register address
   1092  *      phy_data     - Value write to PHY register
   1093  * Note:
   1094  *      This register read function is not thread safe. Higher level
   1095  * function that calls this function must obtain a per port lock
   1096  * to avoid overriding register page mapping between threads.
   1097  */
   1098 STATIC int
   1099 phy82764_reg_write(int unit, soc_port_t port, uint32 flags,
   1100                    uint32 phy_reg_addr, uint32 phy_reg_data)
   1101 {
   1102     phy_ctrl_t *pc;
   1103     soc_phymod_ctrl_t *pmc;
   1104     phymod_phy_access_t *pm_phy;
   1105     int idx;
   1106     uint8 data8 = 0;
   1107     data8 = phy_reg_data & 0xFF;
   1108 
   1109     pc = EXT_PHY_SW_STATE(unit, port);
   1110     if (pc == NULL) {
   1111         return SOC_E_INTERNAL;
   1112     }
   1113 
   1114     pmc = &pc->phymod_ctrl;
   1115     for (idx = 0; idx < pmc->num_phys; idx++) {
   1116         pm_phy = &pmc->phy[idx]->pm_phy;
   1117         if (flags & SOC_PHY_I2C_DATA8) {
   1118             SOC_IF_ERROR_RETURN
   1119                 (phymod_phy_i2c_write(pm_phy, 0, SOC_PHY_I2C_DEVAD(phy_reg_addr), SOC_PHY_I2C_REGAD(phy_reg_addr), 1, &data8));
   1120         } else {
   1121             SOC_IF_ERROR_RETURN
   1122                 (phymod_phy_reg_write(pm_phy, phy_reg_addr, phy_reg_data));
   1123         }
   1124     }
   1125 
   1126     return SOC_E_NONE;
   1127 }
   1128 
   1129 /*
   1130  * Function:
   1131  *      phy82764_reg_modify
   1132  * Purpose:
   1133  *      Routine to write PHY register
   1134  * Parameters:
   1135  *      uint         - BCM unit number
   1136  *      pc           - PHY state
   1137  *      flags        - Flags which specify the register type
   1138  *      phy_reg_addr - Encoded register address
   1139  *      phy_mo_data  - New value for the bits specified in phy_mo_mask
   1140  *      phy_mo_mask  - Bit mask to modify
   1141  * Note:
   1142  *      This function is not thread safe. Higher level
   1143  * function that calls this function must obtain a per port lock
   1144  * to avoid overriding register page mapping between threads.
   1145  */
   1146 STATIC int
   1147 phy82764_reg_modify(int unit, soc_port_t port, uint32 flags,
   1148                     uint32 phy_reg_addr, uint32 phy_data,
   1149                     uint32 phy_data_mask)
   1150 {
   1151     phy_ctrl_t *pc;
   1152     soc_phymod_ctrl_t *pmc;
   1153     phymod_phy_access_t *pm_phy;
   1154     uint32 data32 = 0, tmp = 0;
   1155     int idx = 0;
   1156 
   1157     pc = EXT_PHY_SW_STATE(unit, port);
   1158     if (pc == NULL) {
   1159         return SOC_E_INTERNAL;
   1160     }
   1161 
   1162     pmc = &pc->phymod_ctrl;
   1163     for (idx = 0; idx < pmc->num_phys; idx++) {
   1164         pm_phy = &pmc->phy[idx]->pm_phy;
   1165         SOC_IF_ERROR_RETURN
   1166             (phymod_phy_reg_read(pm_phy, phy_reg_addr, &data32));
   1167         tmp = data32;
   1168         data32 &= ~(phy_data_mask);
   1169         data32 |= (phy_data & phy_data_mask);
   1170         if (data32 != tmp) {
   1171             SOC_IF_ERROR_RETURN
   1172                 (phymod_phy_reg_write(pm_phy, phy_reg_addr, data32));
   1173         }
   1174     }
   1175 
   1176     return SOC_E_NONE;
   1177 }
   1178 
   1179 STATIC void
   1180 phy82764_core_init(phy_ctrl_t *pc, soc_phymod_core_t *core,
   1181                    phymod_bus_t *core_bus, uint32 core_addr)
   1182 {
   1183     phymod_core_access_t *pm_core;
   1184     phymod_access_t *pm_acc;
   1185 
   1186     core->unit = pc->unit;
   1187     core->port = pc->port;
   1188     core->read = pc->read;
   1189     core->write = pc->wb_write ? pc->wb_write : pc->write;
   1190     core->wrmask = pc->wrmask;
   1191 
   1192     pm_core = &core->pm_core;
   1193     phymod_core_access_t_init(pm_core);
   1194     pm_acc = &pm_core->access;
   1195     phymod_access_t_init(pm_acc);
   1196     PHYMOD_ACC_USER_ACC(pm_acc) = core;
   1197     PHYMOD_ACC_BUS(pm_acc) = core_bus;
   1198     PHYMOD_ACC_ADDR(pm_acc) = core_addr;
   1199 
   1200     if (soc_property_port_get(pc->unit, pc->port, "phy82764", 0) == 45) {
   1201         PHYMOD_ACC_F_CLAUSE45_SET(pm_acc);
   1202     }
   1203 
   1204     return;
   1205 }
   1206 
   1207 STATIC int
   1208 _phy82764_device_create_attach(soc_phymod_core_t *core, uint32_t core_id) 
   1209 {
   1210     phy82764_device_aux_mode_t *new_device ;
   1211     new_device = sal_alloc(sizeof(phy82764_device_aux_mode_t), "phy82764_device_aux_mode");
   1212     if (new_device == NULL) {
   1213         return SOC_E_MEMORY;
   1214     }
   1215     sal_memset(new_device, 0 ,sizeof(phy82764_device_aux_mode_t));
   1216     
   1217     new_device->core_id = core_id ;
   1218     core->device_aux_modes = (void *)new_device ;
   1219 
   1220     return SOC_E_NONE;
   1221 }
   1222 
   1223 STATIC int
   1224 _phy82764_device_destroy(phy82764_device_aux_mode_t *device)
   1225 {
   1226     if (device == NULL) {
   1227         return SOC_E_PARAM;
   1228     }
   1229     sal_free(device);
   1230 
   1231     return SOC_E_NONE;    
   1232 }
   1233 
   1234 STATIC void
   1235 phy82764_cleanup(soc_phymod_ctrl_t *pmc)
   1236 {
   1237     int idx = 0;
   1238     soc_phymod_phy_t *phy;
   1239     soc_phymod_core_t *core;
   1240     phy82764_device_aux_mode_t *device ;
   1241 
   1242     for (idx = 0; idx < pmc->num_phys ; idx++) {
   1243         phy = pmc->phy[idx];
   1244         if (phy == NULL) {
   1245             LOG_WARN(BSL_LS_SOC_PHY,
   1246                      (BSL_META_U(pmc->unit,
   1247                                  "phy object is empty")));
   1248             continue;
   1249         }
   1250 
   1251         core = phy->core;
   1252         if (core != NULL) {
   1253             device = (phy82764_device_aux_mode_t *)core->device_aux_modes ;
   1254         }
   1255         /* Destroy core object if not used anymore */
   1256         if (core && core->ref_cnt) {
   1257             if (--core->ref_cnt == 0) {
   1258                 PHYMOD_VDBG(PHY82764_DBG_MEM, NULL,("clean_up device=%p core_p=%p\n", (void *)device, (void *)core)) ;
   1259                 _phy82764_device_destroy(device) ;
   1260                 soc_phymod_core_destroy(pmc->unit, core);
   1261             }
   1262         }
   1263 
   1264         /* Destroy phy object */
   1265         if (phy) {
   1266             PHYMOD_VDBG(PHY82764_DBG_MEM, NULL,("clean_up phy=%p\n", (void *)phy)) ;
   1267             soc_phymod_phy_destroy(pmc->unit, phy);
   1268         }
   1269     }
   1270     pmc->num_phys = 0;
   1271 }
   1272 
   1273 STATIC int32
   1274 _phy_82764_chip_id_get(phymod_phy_access_t *pm_phy, uint32 *chip_id)
   1275 {
   1276     uint32 chip_id_msb = 0, chip_id_lsb = 0;
   1277     
   1278 
   1279     SOC_IF_ERROR_RETURN(
   1280        phymod_phy_reg_read(pm_phy, 0x8a01, &chip_id_msb));
   1281 
   1282     chip_id_msb = (chip_id_msb & 0xF000) >> 12;
   1283  
   1284     SOC_IF_ERROR_RETURN(
   1285        phymod_phy_reg_read(pm_phy, 0x8a00, &chip_id_lsb));
   1286 
   1287     if (chip_id_msb == 0x8) {
   1288         if (chip_id_lsb == 0x2764) {
   1289             *chip_id = 0x82764;
   1290         } 
   1291     }
   1292 
   1293     return SOC_E_NONE;
   1294 }
   1295 
   1296 /*
   1297  * Function:
   1298  *      phy82764_speed_to_lane_map_get
   1299  * Purpose:
   1300  *      Mapping to speed to lane map based on config
   1301  * Parameters:
   1302  *      pc                  - phy_ctrl_t
   1303  *      line_lane_map       - [OUT] Line Lane map
   1304  *      sys_lane_map        - [OUT] Sys Lane map
   1305  * Returns:
   1306  *      SOC_E_NONE
   1307  */
   1308 
   1309 
   1310 STATIC int
   1311 _phy82764_speed_to_lane_map_get(phy_ctrl_t *pc, uint32 *line_lane_map, uint32 *sys_lane_map)
   1312 {
   1313     int lane = 0;
   1314     int phy_gearbox_enable = 0;
   1315     int phy_pin_compatibility_enable = 0;
   1316     char                *lane_swap = NULL;
   1317 
   1318     phy_gearbox_enable = soc_property_port_get(pc->unit, pc->port, spn_PHY_GEARBOX_ENABLE, FALSE);
   1319     phy_pin_compatibility_enable = soc_property_port_get(pc->unit, pc->port, spn_PHY_PIN_COMPATIBILITY_ENABLE, FALSE);
   1320     lane_swap = soc_property_port_get_str(pc->unit, pc->port, spn_PHY_XSW_LANE_MAP);
   1321 
   1322     /* phy_gearbox_enable should be "1" or "0" */
   1323     /* phy_pin_compatibility_enable should be "1" or "0" */
   1324     if (((phy_gearbox_enable != TRUE) && (phy_gearbox_enable != FALSE)) ||
   1325         ((phy_pin_compatibility_enable != TRUE) && (phy_pin_compatibility_enable != FALSE))) {
   1326         LOG_ERROR(BSL_LS_SOC_PHY,(BSL_META_U(0,
   1327                         "Error: Could not set port %d information: Invalid parameter.\n"),
   1328                          pc->port));
   1329         return SOC_E_PARAM;
   1330     }
   1331 
   1332     *line_lane_map = 0xF;
   1333     *sys_lane_map = 0xF;
   1334     switch(pc->speed_max) {
   1335         case PHY82764_SPD_100G:
   1336         case PHY82764_SPD_106G:
   1337             *line_lane_map = 0x3ff;
   1338             *sys_lane_map = 0xf;
   1339         break;
   1340         case PHY82764_SPD_40G:
   1341         case PHY82764_SPD_42G:
   1342         case PHY82764_SPD_50G:
   1343             /* phy_gearbox_enable should be "1" or "0" */
   1344             /* phy_pin_compatibility_enable should be "1" or "0" */
   1345             /* phy_pin_compatibility_enable = 1 is valid only when pass_thru is set */
   1346             if ((phy_gearbox_enable != TRUE) && (phy_pin_compatibility_enable != TRUE)) {
   1347                 *line_lane_map = 0x33;
   1348                 *sys_lane_map = 0xf; 
   1349                 pc->phy_mode = PHYCTRL_QUAD_LANE_PORT;
   1350             } else if ((phy_gearbox_enable != TRUE) && (phy_pin_compatibility_enable == TRUE)) {
   1351                 *line_lane_map = 0xf;
   1352                 *sys_lane_map = 0xf;
   1353                 pc->phy_mode = PHYCTRL_QUAD_LANE_PORT;
   1354             } else if ((phy_gearbox_enable == TRUE) && (phy_pin_compatibility_enable != TRUE)) {
   1355                 if (pc->lane_num > 1) {
   1356                     *line_lane_map = 0xf0;
   1357                     *sys_lane_map = 0xc;
   1358                 } else {
   1359                     *line_lane_map = 0xf;
   1360                     *sys_lane_map = 0x3;
   1361                 }  
   1362                 pc->phy_mode = PHYCTRL_QUAD_LANE_PORT;
   1363             } else {
   1364                 LOG_ERROR(BSL_LS_SOC_PHY,(BSL_META_U(0,
   1365                         "Error: Could not set port %d information: Invalid parameter.\n"),
   1366                          pc->port));
   1367                 return SOC_E_PARAM;
   1368             }
   1369         break;
   1370         case PHY82764_SPD_20G:
   1371         case PHY82764_SPD_21G:
   1372             /* phy_gearbox_enable should be "1" or "0" */
   1373             if (phy_gearbox_enable != TRUE) {
   1374                 if (pc->lane_num > 1) {
   1375                     *line_lane_map = 0x30;
   1376                     *sys_lane_map = 0xc;
   1377                 } else {
   1378                     *line_lane_map = 0x3;
   1379                     *sys_lane_map = 0x3;
   1380                 }
   1381                 pc->phy_mode = PHYCTRL_DUAL_LANE_PORT;
   1382             } else if (phy_gearbox_enable == TRUE) {
   1383                 if (pc->lane_num > 1) {
   1384                     *line_lane_map = 0x30;
   1385                     *sys_lane_map = 0x4;
   1386                 } else {
   1387                     *line_lane_map = 0x3;
   1388                     *sys_lane_map = 0x1;
   1389                 }
   1390                 pc->phy_mode = PHYCTRL_DUAL_LANE_PORT;
   1391             } else {
   1392                 LOG_ERROR(BSL_LS_SOC_PHY,(BSL_META_U(0,
   1393                         "Error: Could not set port %d information: Invalid parameter.\n"),
   1394                          pc->port));
   1395                 return SOC_E_PARAM;
   1396             }
   1397         break;
   1398         case PHY82764_SPD_1G:
   1399         case PHY82764_SPD_10G:
   1400         case PHY82764_SPD_11G:
   1401         case PHY82764_SPD_25G:
   1402             if (lane_swap != NULL) {
   1403                 lane = my_ctoi(lane_swap, lane);
   1404             }
   1405             if (phy_pin_compatibility_enable == TRUE) {
   1406               *line_lane_map = 0x1;
   1407               *sys_lane_map = 0x1;
   1408               *line_lane_map <<= ((lane_swap != NULL) ? lane : pc->lane_num);
   1409               *sys_lane_map <<= pc->lane_num;
   1410             } else {
   1411                 if (pc->lane_num > 1) {
   1412                     *line_lane_map = 0x10;
   1413                     *line_lane_map <<= ((lane_swap != NULL) ? (lane - 2): (pc->lane_num - 2));
   1414                     *sys_lane_map = 0x1;
   1415                     *sys_lane_map <<= pc->lane_num;
   1416                 } else {
   1417                     *line_lane_map = 0x1;
   1418                     *line_lane_map <<= ((lane_swap != NULL) ? lane : pc->lane_num);
   1419                     *sys_lane_map = 0x1;
   1420                     *sys_lane_map <<= pc->lane_num;
   1421                 }
   1422             }
   1423             pc->phy_mode = PHYCTRL_ONE_LANE_PORT;
   1424         break;
   1425         default:
   1426             /* changed default case retrun value from SOC_E_PARAM to SOC_E_NONE as per jira PHY-1805 */
   1427             /* As upper layers does not handle errors retruned incase of Unsupported speed */
   1428             LOG_ERROR(BSL_LS_SOC_PHY,(BSL_META_U(0,
   1429                     "Error: Could not set port %d information: Unsupported speed.\n"),
   1430                      pc->port));
   1431             return SOC_E_NONE;
   1432     }
   1433 
   1434     return SOC_E_NONE;
   1435 }
   1436 
   1437 /*
   1438  * Function:
   1439  *      phy82764_probe
   1440  * Purpose:
   1441  *      xx
   1442  * Parameters:
   1443  *      pc->phy_id   (IN)
   1444  *      pc->unit     (IN)
   1445  *      pc->port     (IN)
   1446  *      pc->size     (OUT) - memory required by phy port
   1447  *      pc->dev_name (OUT) - set to port device name
   1448  *  
   1449  * Note:
   1450  */
   1451 STATIC int
   1452 phy82764_probe(int unit, phy_ctrl_t *pc)
   1453 {
   1454     int rv, idx;
   1455     uint32 num_phys, core_id, phy_id, found = 0;
   1456     uint32 line_lane_map, sys_lane_map;
   1457     phymod_bus_t core_bus;
   1458     phymod_dispatch_type_t phy_type;
   1459     phymod_core_access_t *pm_core;
   1460     phymod_phy_access_t *pm_phy;
   1461     phymod_access_t *pm_acc;
   1462     soc_phymod_ctrl_t *pmc;
   1463     soc_phymod_phy_t *phy;
   1464     soc_phymod_core_t *core;
   1465     soc_phymod_core_t core_probe;
   1466     soc_info_t *si;
   1467     phyident_core_info_t core_info[8];  
   1468     int array_max = 8;
   1469     int array_size = 0;
   1470     int port;
   1471     int phy_port;  /* physical port number */
   1472     /* Initialize PHY bus */
   1473     SOC_IF_ERROR_RETURN(phymod_bus_t_init(&core_bus));
   1474     core_bus.bus_name = "phy82764"; 
   1475     core_bus.read = _phy82764_reg_read; 
   1476     core_bus.write = _phy82764_reg_write;
   1477 
   1478 #ifdef PORTMOD_SUPPORT
   1479     /* If portmod feature is enabled let the 
   1480      *      * PM take care of phy control*/
   1481 
   1482      if (soc_feature(unit, soc_feature_portmod)) {
   1483         return SOC_E_NOT_FOUND;
   1484      }
   1485 #endif/* PORTMOD_SUPPORT */      
   1486 
   1487     /* Configure PHY bus properties */
   1488     if (pc->wrmask) {
   1489         PHYMOD_BUS_CAP_WR_MODIFY_SET(&core_bus);
   1490         PHYMOD_BUS_CAP_LANE_CTRL_SET(&core_bus);
   1491     }
   1492 
   1493     port = pc->port;
   1494     pmc = &pc->phymod_ctrl;
   1495     si = &SOC_INFO(unit);
   1496     if (soc_feature(unit, soc_feature_logical_port_num)) {
   1497         phy_port = si->port_l2p_mapping[port];
   1498     } else {
   1499         phy_port = port;
   1500     }
   1501 
   1502     /* Install clean up function */
   1503     pmc->unit = pc->unit;
   1504     pmc->cleanup = phy82764_cleanup;
   1505     /*pmc->symbols = &bcmi_tscf_xgxs_symbols;*/ 
   1506 
   1507     
   1508     pc->lane_num = SOC_PORT_BINDEX(unit, phy_port);
   1509     pc->chip_num = SOC_BLOCK_NUMBER(unit, SOC_PORT_BLOCK(unit, phy_port));
   1510 
   1511     /* request memory for the configuration structure */
   1512     pc->size = sizeof(phy82764_config_t);
   1513 
   1514     /* Bit N corresponds to lane N in lane_map */
   1515     num_phys = 1;
   1516     SOC_IF_ERROR_RETURN
   1517           (_phy82764_speed_to_lane_map_get(pc, &line_lane_map, &sys_lane_map));
   1518 
   1519     /* we need to get the other core id if more than 1 core per port */
   1520     if (num_phys > 1) {
   1521         /* get the other core address */
   1522         SOC_IF_ERROR_RETURN
   1523             /*
   1524              * COVERITY
   1525              * This is unreachable. It is kept intentionally as a defensive 
   1526              * default for future development.
   1527              */
   1528             /* coverity[dead_error_begin] */
   1529             (soc_phy_addr_multi_get(unit, port, array_max, &array_size, &core_info[0]));
   1530     } else {
   1531         core_info[0].mdio_addr = pc->phy_id;
   1532     }
   1533 
   1534     phy_type = phymodDispatchTypeSesto;
   1535 
   1536     /* Probe cores */
   1537     for (idx = 0; idx < num_phys ; idx++) {
   1538         phy82764_core_init(pc, &core_probe, &core_bus,
   1539                            core_info[idx].mdio_addr);
   1540         /* Check that core is indeed an sesto core */
   1541         pm_core = &core_probe.pm_core;
   1542         pm_core->type = phy_type;
   1543         rv = phymod_core_identify(pm_core, 0, &found);
   1544         if (SOC_FAILURE(rv)) {
   1545             LOG_WARN(BSL_LS_SOC_PHY,
   1546                  (BSL_META_U(unit,
   1547                              "port %d: ERROR!!!\n"),
   1548                   pc->port));
   1549 
   1550             return rv;
   1551         }
   1552         if (!found) {
   1553             LOG_WARN(BSL_LS_SOC_PHY,
   1554                  (BSL_META_U(unit,
   1555                              "port %d: NOT FOUND!!\n"),
   1556                   pc->port));
   1557 
   1558             return SOC_E_NOT_FOUND;
   1559         }
   1560     }
   1561 
   1562     rv = SOC_E_NONE;
   1563     for (idx = 0; idx < num_phys ; idx++) {
   1564         /* Set core and phy IDs based on PHY address */
   1565         core_id = pc->phy_id + idx;
   1566         phy_id = (line_lane_map << 16) | core_id;
   1567 
   1568         /* Create PHY object */
   1569         rv = soc_phymod_phy_create(unit, phy_id, &pmc->phy[idx]);
   1570         if (SOC_FAILURE(rv)) {
   1571             break;
   1572         }
   1573         pmc->num_phys++;
   1574 
   1575         /* Initialize phy object */
   1576         phy = pmc->phy[idx];
   1577         pm_phy = &phy->pm_phy;
   1578         phymod_phy_access_t_init(pm_phy);
   1579 
   1580         /* Find or create associated core object */
   1581         rv = soc_phymod_core_find_by_id(unit, core_id, &phy->core);
   1582         if (rv == SOC_E_NOT_FOUND) {
   1583             rv = soc_phymod_core_create(unit, core_id, &phy->core);
   1584             rv |= _phy82764_device_create_attach(phy->core, core_id) ;
   1585         }
   1586         if (SOC_FAILURE(rv)) {
   1587             break;
   1588         }        
   1589     }
   1590     if (SOC_FAILURE(rv)) {
   1591         phy82764_cleanup(pmc);
   1592         return rv;
   1593     }
   1594 
   1595     for (idx = 0; idx < pmc->num_phys ; idx++) {
   1596         phy = pmc->phy[idx];
   1597         core = phy->core;
   1598         pm_core = &core->pm_core;
   1599 
   1600         /* Initialize core object if newly created */
   1601         if (core->ref_cnt == 0) {
   1602             sal_memcpy(&core->pm_bus, &core_bus, sizeof(core->pm_bus));
   1603             phy82764_core_init(pc, core, &core->pm_bus,
   1604                                core_info[idx].mdio_addr);
   1605             /* Set dispatch type */
   1606             pm_core->type = phy_type;
   1607         }
   1608         core->ref_cnt++;        
   1609 
   1610         /* Initialize phy access based on associated core */
   1611         pm_acc = &phy->pm_phy.access;
   1612         sal_memcpy(pm_acc, &pm_core->access, sizeof(*pm_acc));
   1613         phy->pm_phy.type = phy_type;
   1614         pm_core->access.lane_mask = line_lane_map;
   1615         PHYMOD_ACC_LANE_MASK(pm_acc) = line_lane_map;
   1616     }
   1617 
   1618     return SOC_E_NONE;
   1619 }
   1620 
   1621 
   1622 /*
   1623  * Function:
   1624  *      phy82764_config_init
   1625  * Purpose:     
   1626  *      Determine phy configuration data for purposes of PHYMOD initialization.
   1627  * 
   1628  *      A side effect of this procedure is to save some per-logical port
   1629  *      information in (phy82764_cfg_t *) &pc->driver_data;
   1630  *
   1631  * Parameters:
   1632  *      unit                  - BCM unit number.
   1633  *      port                  - Port number.
   1634  *      logical_lane_offset   - starting logical lane number
   1635  * Returns:     
   1636  *      SOC_E_NONE
   1637  */
   1638 STATIC int
   1639 phy82764_config_init(int unit, soc_port_t port, int logical_lane_offset,
   1640                  phymod_core_init_config_t *core_init_config, 
   1641                  phymod_phy_init_config_t  *pm_phy_init_config)
   1642 {
   1643     phy_ctrl_t *pc;
   1644     phy82764_speed_config_t *speed_config;
   1645     phy82764_config_t *pCfg;
   1646     int port_num_lanes;
   1647     int core_num;
   1648     int phy_num_lanes;
   1649      uint32_t preemphasis, driver_current,i;
   1650 
   1651 
   1652     pc = EXT_PHY_SW_STATE(unit, port);
   1653     if (pc == NULL) {
   1654         return SOC_E_INTERNAL;
   1655     }
   1656     pCfg = (phy82764_config_t *) pc->driver_data;
   1657 
   1658     port_num_lanes = SOC_INFO(unit).port_num_lanes[port];
   1659 
   1660     /* figure out how many lanes are in this phy */
   1661     core_num = (logical_lane_offset / 4);
   1662     phy_num_lanes = (port_num_lanes - logical_lane_offset);
   1663     if (phy_num_lanes > MAX_NUM_LANES) {
   1664        phy_num_lanes = MAX_NUM_LANES;
   1665     }
   1666     
   1667     /*CORE configuration*/
   1668     phymod_core_init_config_t_init(core_init_config);
   1669 
   1670     core_init_config->flags = PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY;
   1671     core_init_config->firmware_load_method &= 0xff; /* clear checksum bits */
   1672     core_init_config->lane_map.num_of_lanes = NUM_LANES;
   1673     
   1674     speed_config = &(pCfg->speed_config);
   1675     speed_config->port_refclk_int  = 156;
   1676     speed_config->port_num_lanes   = phy_num_lanes;
   1677     speed_config->speed = pc->speed_max;
   1678 
   1679     if (port_num_lanes == 4) {
   1680         if (pc->speed_max == PHY82764_SPD_40G || pc->speed_max == PHY82764_SPD_42G) {
   1681             speed_config->line_interface =  SOC_PORT_IF_SR4;
   1682         } else if (pc->speed_max == PHY82764_SPD_100G || pc->speed_max == PHY82764_SPD_106G) {
   1683             speed_config->line_interface =  SOC_PORT_IF_SR10;
   1684         } else {
   1685             speed_config->line_interface = SOC_PORT_IF_SR4;
   1686         }
   1687     } else if (port_num_lanes == 1) {
   1688         if (pc->speed_max == PHY82764_SPD_20G || pc->speed_max == PHY82764_SPD_21G) {
   1689             speed_config->line_interface =  SOC_PORT_IF_SR2;
   1690         } else if (pc->speed_max == PHY82764_SPD_10G || pc->speed_max == PHY82764_SPD_11G) {
   1691             speed_config->line_interface =  SOC_PORT_IF_SR;
   1692         } else {
   1693             speed_config->line_interface =  SOC_PORT_IF_SR;
   1694         }
   1695     } else if (port_num_lanes == 2) {
   1696         if (pc->speed_max == PHY82764_SPD_40G || pc->speed_max == PHY82764_SPD_42G) {
   1697             speed_config->line_interface =  SOC_PORT_IF_SR4;
   1698         } else if (pc->speed_max == PHY82764_SPD_20G || pc->speed_max == PHY82764_SPD_21G) {
   1699             speed_config->line_interface =  SOC_PORT_IF_SR2;
   1700         } else {
   1701             speed_config->line_interface = SOC_PORT_IF_SR4;
   1702         }
   1703     } else {
   1704         LOG_CLI((BSL_META_U(unit,"Invalid number of lanes:%d\n "), port_num_lanes));
   1705         return SOC_E_CONFIG;
   1706     }
   1707 
   1708     /* PHY configuration */
   1709     phymod_phy_init_config_t_init(pm_phy_init_config);
   1710 
   1711     pm_phy_init_config->polarity.rx_polarity
   1712                                  = soc_property_port_get(unit, port,
   1713                                    spn_PHY_RX_POLARITY_FLIP, 0);
   1714     pm_phy_init_config->polarity.tx_polarity
   1715                                  = soc_property_port_get(unit, port,
   1716                                    spn_PHY_TX_POLARITY_FLIP, 0);
   1717     preemphasis = 0x0;
   1718     preemphasis = soc_property_port_get(unit, port,
   1719             spn_PHY_PREEMPHASIS,
   1720             0x007F7F7F);
   1721 
   1722     driver_current = 0x0;
   1723     driver_current = soc_property_port_get(unit, port,
   1724             spn_PHY_DRIVER_CURRENT,
   1725             0xF);
   1726     
   1727     for (i = 0; i < MAX_NUM_LANES; i++) {
   1728         pm_phy_init_config->tx[i].pre = preemphasis & 0xff;
   1729         pm_phy_init_config->tx[i].main = (preemphasis & 0xff00) >> 8;
   1730         pm_phy_init_config->tx[i].post = (preemphasis & 0xff0000) >> 16;
   1731         pm_phy_init_config->tx[i].amp = driver_current;
   1732     }
   1733 
   1734 
   1735     /* phy_ctrl_t configuration (LOGICAL PORT BASED)
   1736      * Only do this once, for the first core of the logical port*/
   1737     if (core_num == 0) {
   1738         /* phy_mode, PHYCTRL_MDIO_ADDR_SHARE, PHY_FLAGS_INDEPENDENT_LANE */
   1739         if (port_num_lanes == 4) {
   1740             pc->phy_mode = PHYCTRL_QUAD_LANE_PORT;
   1741             PHY_FLAGS_CLR(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
   1742         } else if (port_num_lanes == 2) {
   1743             pc->phy_mode = PHYCTRL_QUAD_LANE_PORT;
   1744             pc->flags |= PHYCTRL_MDIO_ADDR_SHARE;
   1745             PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
   1746         } else if (port_num_lanes == 1) {
   1747             pc->phy_mode = PHYCTRL_ONE_LANE_PORT;
   1748             pc->flags |= PHYCTRL_MDIO_ADDR_SHARE;
   1749             PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
   1750         }
   1751 
   1752     }
   1753 
   1754     return SOC_E_NONE;
   1755 }
   1756 
   1757 STATIC int
   1758 _phy_82764_init_pass1(int unit, soc_port_t port)
   1759 {
   1760     phy_ctrl_t *pc; 
   1761     soc_phymod_ctrl_t *pmc;
   1762     soc_phymod_phy_t *phy = NULL;
   1763     soc_phymod_core_t *core;
   1764     phy82764_config_t *pCfg;
   1765     phy82764_speed_config_t *speed_config;
   1766     phy82764_device_cfg_aux_mode_t *device_cfg_aux_modes;
   1767     phymod_phy_inf_config_t interface_config;
   1768     phymod_core_status_t core_status;
   1769     phymod_core_info_t core_info;
   1770     int idx, logical_lane_offset;
   1771     soc_port_ability_t ability;
   1772     soc_phy_info_t *pi;
   1773     char *dev_name;
   1774     int len = 0;
   1775     uint32 chip_id = 0, is_identified = 0;
   1776     int phy_force_dload = 0, fw_ld_method = 0;
   1777 
   1778     pc = EXT_PHY_SW_STATE(unit, port);
   1779 
   1780     if (pc == NULL) {
   1781         return SOC_E_INTERNAL;
   1782     }
   1783 
   1784     pc->driver_data = (void*)(pc+1);
   1785     pmc = &pc->phymod_ctrl;
   1786     pCfg = (phy82764_config_t *) pc->driver_data;
   1787     
   1788     sal_memset(pCfg, 0, sizeof(*pCfg));
   1789     speed_config = &(pCfg->speed_config);
   1790     device_cfg_aux_modes = &(pCfg->device_cfg_aux_modes);
   1791 
   1792     sal_memset(&ability, 0, sizeof(ability));
   1793 
   1794     dev_name = DEV_NAME(pc);
   1795 
   1796     phy = pmc->phy[0];
   1797 
   1798     SOC_IF_ERROR_RETURN(
   1799          _phy_82764_chip_id_get(&phy->pm_phy, &chip_id));
   1800     DEVID(pc) = chip_id;
   1801 
   1802     pi = &SOC_PHY_INFO(unit, port);
   1803     if (DEVID(pc) == SESTO_ID_82764) { 
   1804         /* coverity[secure_coding] */
   1805         sal_strncpy (dev_name, "BCM82764", sal_strlen("BCM82764"));
   1806     } else {
   1807         /* coverity[secure_coding] */
   1808         sal_strncpy (dev_name, "Sesto", sal_strlen("Sesto"));
   1809     }
   1810     
   1811     len = sal_strlen(dev_name);
   1812 
   1813     dev_name[len++] = '/';
   1814     dev_name[len++] = pc->lane_num + '0';
   1815     dev_name[len] = 0;
   1816     pc->dev_name = dev_name;  /* string terminator */
   1817     pi->phy_name = dev_name;
   1818 
   1819     /* Loop through all phymod phys that support this SDK phy */
   1820     logical_lane_offset = 0;
   1821     for (idx = 0; idx < pmc->num_phys; idx++) {
   1822         phy = pmc->phy[idx];
   1823         core = phy->core;
   1824 
   1825         pCfg->device_aux_modes = (phy82764_device_aux_mode_t *)(core->device_aux_modes) ;
   1826         pCfg->device_aux_modes->repeater = soc_property_port_get(unit, port, spn_PHY_PCS_REPEATER, TRUE);
   1827 
   1828         /* determine configuration data structure to default values, based on SOC properties */
   1829         SOC_IF_ERROR_RETURN
   1830             (phy82764_config_init(unit, port,
   1831                               logical_lane_offset,
   1832                               &core->init_config, &phy->init_config));
   1833         speed_config->higig_port = PBMP_MEMBER(PBMP_HG_ALL(unit), port);
   1834 
   1835         /* set the port to its max or init_speed */
   1836         SOC_IF_ERROR_RETURN
   1837              (phy82764_speed_to_interface_config_get(speed_config, &interface_config));
   1838         sal_memcpy(&core->init_config.interface, &interface_config, sizeof(interface_config));
   1839         sal_memcpy(&phy->init_config.interface, &interface_config, sizeof(interface_config));
   1840 
   1841         core->pm_core.device_op_mode = 0;
   1842         /* soc read for phy device operation mode */
   1843         device_cfg_aux_modes->gearbox_enable = (soc_property_port_get(unit, port, spn_PHY_GEARBOX_ENABLE, FALSE));
   1844         device_cfg_aux_modes->pin_compatibility_enable = soc_property_port_get(unit, port,
   1845                                    spn_PHY_PIN_COMPATIBILITY_ENABLE, FALSE);
   1846         device_cfg_aux_modes->phy_mode_reverse = soc_property_port_get(unit, port, spn_PORT_PHY_MODE_REVERSE, 0);
   1847 
   1848         /* copy the soc config to phymod_core_access */
   1849         /* bit 0 is for gearbox_enable */
   1850         /* bit 1 is for pin_compatibility_enable */
   1851         /* bit 2 is for phy_mode_reverse */
   1852         core->pm_core.device_op_mode |= device_cfg_aux_modes->gearbox_enable;
   1853         core->pm_core.device_op_mode |= (device_cfg_aux_modes->pin_compatibility_enable << 1);
   1854         core->pm_core.device_op_mode |= (device_cfg_aux_modes->phy_mode_reverse << 2);
   1855         sal_memcpy(&phy->pm_phy.device_op_mode, &core->pm_core.device_op_mode, sizeof(core->pm_core.device_op_mode));
   1856 
   1857 
   1858         /*lower nibble to represent Force FW load and upper nibble to represent load method */
   1859         phy_force_dload = 0x11;
   1860         phy_force_dload = soc_property_port_get(unit, port,
   1861                                          spn_PHY_FORCE_FIRMWARE_LOAD, phy_force_dload);
   1862 
   1863         fw_ld_method = ((phy_force_dload & 0xF0) >> 4);
   1864         phy_force_dload &= 0xf;
   1865         switch (fw_ld_method) {
   1866             case 0:
   1867                 core->init_config.firmware_load_method = phymodFirmwareLoadMethodNone;
   1868             break;
   1869             case 1:
   1870                 core->init_config.firmware_load_method = phymodFirmwareLoadMethodInternal;
   1871             break;
   1872             case 2:
   1873                 core->init_config.firmware_load_method = phymodFirmwareLoadMethodProgEEPROM;
   1874             break;
   1875             default:
   1876                 core->init_config.firmware_load_method = phymodFirmwareLoadMethodInternal;
   1877             break;
   1878         }
   1879         if ((!core->init) && !SOC_WARM_BOOT(unit)) {
   1880            core_status.pmd_active = 0;
   1881            SOC_IF_ERROR_RETURN(phymod_core_identify(&core->pm_core, 0, &is_identified));
   1882            if ((is_identified & 0x80000000) &&
   1883                (core->init_config.firmware_load_method == phymodFirmwareLoadMethodInternal)) {
   1884                 pc->flags |= PHYCTRL_MDIO_BCST;
   1885            } else if (core->init_config.firmware_load_method == phymodFirmwareLoadMethodNone) {
   1886                phymod_core_firmware_info_t fw_info;
   1887                SOC_IF_ERROR_RETURN (
   1888                    phymod_core_firmware_info_get(&core->pm_core, &fw_info));
   1889                 if (fw_info.fw_version == 0x1) {
   1890                    LOG_CLI((BSL_META_U(unit, "No FW found on the chip, Please use "
   1891                                  "spn_PHY_FORCE_FIRMWARE_LOAD as 0x11 to download FW to chip\n")));
   1892                    return SOC_E_UNAVAIL;
   1893                 }
   1894             } else {
   1895                if (core->init_config.firmware_load_method == phymodFirmwareLoadMethodInternal) {
   1896                    if (phy_force_dload == phymodFirmwareLoadForce) {
   1897                        PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&(core->init_config));
   1898                    } else if(phy_force_dload == phymodFirmwareLoadAuto) {
   1899                        PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&(core->init_config));
   1900                    }
   1901                }
   1902                PHYMOD_CORE_INIT_F_EXECUTE_PASS1_SET(&(core->init_config));
   1903                SOC_IF_ERROR_RETURN
   1904                    (phymod_core_init(&core->pm_core, &core->init_config, &core_status));
   1905                PHYMOD_CORE_INIT_F_EXECUTE_PASS1_CLR(&(core->init_config));
   1906            }
   1907            core->init = TRUE;
   1908         }
   1909 
   1910         /*read serdes id info */
   1911         SOC_IF_ERROR_RETURN
   1912             (phymod_core_info_get(&core->pm_core, &core_info)); 
   1913 
   1914         /* for multicore phys, need to ratchet up to the next batch of lanes */
   1915         logical_lane_offset += core->init_config.lane_map.num_of_lanes;
   1916     }
   1917 
   1918     /* indicate second pass of init is needed */
   1919     if (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS1) {
   1920         PHYCTRL_INIT_STATE_SET(pc,PHYCTRL_INIT_STATE_PASS2);
   1921     }
   1922 
   1923     return SOC_E_NONE;
   1924 }
   1925 void phy82764_phyctrl_to_phymod_interface (uint16_t sys_if, phymod_interface_t *sys_intf)
   1926 {
   1927     switch (sys_if)
   1928     {
   1929         case SOC_PORT_IF_SFI:
   1930             *sys_intf = phymodInterfaceSFI;
   1931         break;
   1932         case SOC_PORT_IF_XFI:
   1933             *sys_intf = phymodInterfaceXFI;
   1934         break;
   1935         case SOC_PORT_IF_KR:
   1936             *sys_intf = phymodInterfaceKR;
   1937         break;
   1938         case SOC_PORT_IF_KR4:
   1939             *sys_intf = phymodInterfaceKR4;
   1940         break;
   1941         case SOC_PORT_IF_CR:
   1942             *sys_intf = phymodInterfaceCR;
   1943         break;
   1944         case SOC_PORT_IF_CR4:
   1945             *sys_intf = phymodInterfaceCR4;
   1946         break;
   1947         case SOC_PORT_IF_XLAUI:
   1948             *sys_intf = phymodInterfaceXLAUI;
   1949         break;
   1950         case SOC_PORT_IF_XLPPI:
   1951             *sys_intf = phymodInterfaceXLPPI;
   1952         break;
   1953         case SOC_PORT_IF_SR:
   1954             *sys_intf = phymodInterfaceSR;
   1955         break;
   1956         case SOC_PORT_IF_CAUI:
   1957             *sys_intf = phymodInterfaceCAUI;
   1958         break;
   1959         case SOC_PORT_IF_LR:
   1960             *sys_intf = phymodInterfaceLR;
   1961         break;
   1962         case SOC_PORT_IF_LR4:
   1963             *sys_intf = phymodInterfaceLR4;
   1964         break;
   1965         case SOC_PORT_IF_ER4:
   1966             *sys_intf = phymodInterfaceER4;
   1967         break;
   1968         case SOC_PORT_IF_SR4:
   1969             *sys_intf = phymodInterfaceSR4;
   1970         break;
   1971         case SOC_PORT_IF_KX:
   1972             *sys_intf = phymodInterfaceKX;
   1973         break;
   1974         case SOC_PORT_IF_KR2:
   1975             *sys_intf = phymodInterfaceKR2;
   1976         break;
   1977         case SOC_PORT_IF_CR2:
   1978             *sys_intf = phymodInterfaceCR2;
   1979         break;
   1980         case SOC_PORT_IF_XLAUI2:
   1981             *sys_intf = phymodInterfaceXLAUI2;
   1982         break;
   1983         case SOC_PORT_IF_CAUI_C2C:
   1984             *sys_intf = phymodInterfaceCAUI4_C2C;
   1985         break;
   1986 
   1987         default:
   1988             *sys_intf = phymodInterfaceKR;
   1989     }
   1990 
   1991 }
   1992 
   1993 STATIC int
   1994 _phy_82764_init_pass2(int unit, soc_port_t port)
   1995 {
   1996     phy_ctrl_t *pc;
   1997     soc_phymod_ctrl_t *pmc;
   1998     soc_phymod_phy_t *phy = NULL;
   1999     phy82764_config_t *pCfg;
   2000     phy82764_speed_config_t *speed_config;
   2001     phymod_phy_inf_config_t interface_config;
   2002     phy82764_device_cfg_aux_mode_t *device_cfg_aux_modes;
   2003     soc_port_ability_t ability;
   2004     uint16_t sys_if = 0;
   2005     phymod_interface_t sys_intf = 0;
   2006     uint32 line_lane_map, sys_lane_map;
   2007 
   2008     pc = EXT_PHY_SW_STATE(unit, port);
   2009 
   2010     if (pc == NULL) {
   2011         return SOC_E_INTERNAL;
   2012     }
   2013 
   2014     sal_memset(&ability, 0, sizeof(ability));
   2015     pc->driver_data = (void*)(pc+1);
   2016     pmc = &pc->phymod_ctrl;
   2017     pCfg = (phy82764_config_t *) pc->driver_data;
   2018     
   2019     speed_config = &(pCfg->speed_config);
   2020     device_cfg_aux_modes = &(pCfg->device_cfg_aux_modes);
   2021     phy = pmc->phy[0];
   2022 
   2023     /*Work around for to support flex of 10G To 40G Mux as part of jira PHY-1805 */
   2024     if (((pc->speed_max == PHY82764_SPD_20G) && (device_cfg_aux_modes->gearbox_enable == TRUE)) ||
   2025         (pc->speed_max == PHY82764_SPD_25G) || (pc->speed_max == PHY82764_SPD_50G)){
   2026         return SOC_E_NONE;
   2027     }
   2028 
   2029     if (!SOC_WARM_BOOT(unit)) {
   2030         SOC_IF_ERROR_RETURN(
   2031             phy_82764_driver_current_set(pmc, port, PHY82764_LINE_SIDE, 0xf));
   2032         SOC_IF_ERROR_RETURN(
   2033             phy_82764_tx_fir_pre_set(pmc, port, PHY82764_LINE_SIDE, 0));
   2034         SOC_IF_ERROR_RETURN(
   2035             phy_82764_tx_fir_post_set(pmc, port, PHY82764_LINE_SIDE, 0));
   2036         SOC_IF_ERROR_RETURN(
   2037             phy_82764_tx_fir_post2_set(pmc, port, PHY82764_LINE_SIDE, 0));
   2038         SOC_IF_ERROR_RETURN(
   2039             phy_82764_tx_fir_main_set(pmc, port, PHY82764_LINE_SIDE, 0x3c));
   2040 
   2041 
   2042 
   2043         phy->init_config.op_mode = pCfg->device_aux_modes->repeater;
   2044         SOC_IF_ERROR_RETURN
   2045             (phymod_phy_init(&phy->pm_phy, &phy->init_config));
   2046 
   2047 
   2048         SOC_IF_ERROR_RETURN
   2049              (phy82764_speed_to_interface_config_get(speed_config, &interface_config));
   2050 
   2051         SOC_IF_ERROR_RETURN
   2052                (_phy82764_speed_to_lane_map_get(pc, &line_lane_map, &sys_lane_map));
   2053         pCfg->sys_lane_map = sys_lane_map;
   2054         phy->pm_phy.access.lane_mask = line_lane_map;
   2055 
   2056         SOC_IF_ERROR_RETURN
   2057             (phymod_phy_interface_config_set(&phy->pm_phy,
   2058                                  0 /* flags */, &interface_config));
   2059         /* Config Sys interface*/
   2060         sys_if = soc_property_port_get(unit, port, spn_PHY_SYS_INTERFACE, 0);
   2061         if (sys_if) {
   2062             phy82764_phyctrl_to_phymod_interface(sys_if, &sys_intf);
   2063             if (sys_intf == 0) {
   2064                 return SOC_E_PARAM;
   2065             }
   2066             phy->pm_phy.port_loc = phymodPortLocSys;
   2067             phy->pm_phy.access.lane_mask = sys_lane_map;
   2068             interface_config.interface_type = sys_intf;
   2069 
   2070             SOC_IF_ERROR_RETURN
   2071                (phymod_phy_interface_config_set(&phy->pm_phy,
   2072                                  0 /* flags */, &interface_config));
   2073 
   2074             phy->pm_phy.port_loc = phymodPortLocLine;
   2075             phy->pm_phy.access.lane_mask = line_lane_map;
   2076         }
   2077 
   2078         /* setup the port's an cap */
   2079         SOC_IF_ERROR_RETURN
   2080             (phy_82764_ability_local_get(unit, port, &ability));
   2081     } /* !SOC_WARM_BOOT  */
   2082 
   2083     LOG_INFO(BSL_LS_SOC_PHY,
   2084              (BSL_META_U(pc->unit,
   2085                          "phy82764_init_pass2: u=%d p=%d\n"), unit, port));
   2086 
   2087     if (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS2) {
   2088         /* indicate third  pass of init is needed */
   2089         PHYCTRL_INIT_STATE_SET(pc,PHYCTRL_INIT_STATE_PASS3);
   2090     }
   2091 
   2092     return SOC_E_NONE;
   2093 }
   2094 
   2095 STATIC int
   2096 _phy_82764_init_pass3(int unit, soc_port_t port)
   2097 {
   2098     phy_ctrl_t *pc; 
   2099     phy82764_config_t *pCfg;
   2100 
   2101     pc = EXT_PHY_SW_STATE(unit, port);
   2102 
   2103     if (pc == NULL) {
   2104         return SOC_E_INTERNAL;
   2105     }
   2106 
   2107     pc->driver_data = (void*)(pc+1);
   2108     pCfg = (phy82764_config_t *) pc->driver_data;
   2109     
   2110     LOG_INFO(BSL_LS_SOC_PHY,
   2111              (BSL_META_U(unit,
   2112                          "PHY82764 init pass3: u=%d p=%d\n"), unit, port));
   2113 
   2114     /* If configured, enable module auto detection */
   2115     pCfg->auto_mod_detect = soc_property_port_get(unit, port, spn_PHY_MOD_AUTO_DETECT, 0);
   2116     if (pCfg->auto_mod_detect) {
   2117 
   2118     }
   2119 
   2120 	return SOC_E_NONE;
   2121 }
   2122 
   2123 /*
   2124  * Function:
   2125  *      phy_82764_init
   2126  *  
   2127  *      An SDK "phy" is a logical port, which can consist of from 1-10 lanes,
   2128  *          (A phy with more than 4 lanes requires more than one core).
   2129  *      Per-logical port information is saved in &pc->driver_data.
   2130  *      An SDK phy is implemented as one or more PHYMOD "phy"s.
   2131  *  
   2132  *      A PHYMOD "phy" resides completely within a single core, which can be
   2133  *      from 1 to 8 lanes.
   2134  *      Per-phymod phy information is kept in (soc_phymod_ctrl_t) *pc->phymod_ctrl
   2135  *      A phymod phy points to its core.  Up to 4 phymod phys can be on a single core
   2136  *  
   2137  * Purpose:     
   2138  *      Initialize a phy82764
   2139  * Parameters:
   2140  *      unit - BCM unit number.
   2141  *      port - Port number. 
   2142  * Returns:     
   2143  *      SOC_E_NONE
   2144  */
   2145 STATIC int
   2146 phy_82764_init(int unit, soc_port_t port)
   2147 {
   2148     phy_ctrl_t *pc; 
   2149 
   2150     pc = EXT_PHY_SW_STATE(unit, port);
   2151     if (pc == NULL) {
   2152         return SOC_E_INTERNAL;
   2153     }
   2154      
   2155     if ((PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS1) ||
   2156         (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_DEFAULT)) {
   2157         PHY_FLAGS_SET(unit, port,  PHY_FLAGS_FIBER | PHY_FLAGS_C45 | PHY_FLAGS_REPEATER);
   2158         SOC_IF_ERROR_RETURN(_phy_82764_init_pass1(unit, port));
   2159 
   2160         if (PHYCTRL_INIT_STATE(pc) != PHYCTRL_INIT_STATE_DEFAULT) {
   2161             return SOC_E_NONE;
   2162         }
   2163     }
   2164     if ((PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS2) ||
   2165         (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_DEFAULT)) {
   2166 
   2167         SOC_IF_ERROR_RETURN( _phy_82764_init_pass2(unit, port));
   2168 
   2169         LOG_INFO(BSL_LS_SOC_PHY,
   2170                  (BSL_META_U(unit,
   2171                              "82764 init pass2 completed: u=%d p=%d\n"), unit, port));
   2172         if (PHYCTRL_INIT_STATE(pc) != PHYCTRL_INIT_STATE_DEFAULT) {
   2173             return SOC_E_NONE;
   2174         }
   2175     }
   2176 
   2177     if ((PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS3) ||
   2178         (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_DEFAULT)) {
   2179 
   2180         SOC_IF_ERROR_RETURN(_phy_82764_init_pass3(unit, port));
   2181 
   2182         LOG_INFO(BSL_LS_SOC_PHY,
   2183                  (BSL_META_U(unit,
   2184                              "PHY82764 init pass3 completed: u=%d p=%d\n"), unit, port));
   2185         PHYCTRL_INIT_STATE_SET(pc, PHYCTRL_INIT_STATE_DEFAULT);
   2186         return SOC_E_NONE;
   2187     }
   2188 
   2189     return SOC_E_NONE;
   2190 }
   2191 
   2192 /*
   2193  * Function:
   2194  *      phy_82764_ability_local_get
   2195  * Purpose:
   2196  *      xx
   2197  * Parameters:
   2198  *      unit - BCM unit number.
   2199  *      port - Port number. 
   2200  *      ability - xx
   2201  * Returns:     
   2202  *      SOC_E_NONE
   2203  */
   2204 STATIC int
   2205 phy_82764_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability)
   2206 {
   2207     phy_ctrl_t *pc; 
   2208     uint32_t   pa_speed = 0;
   2209 
   2210     pc = EXT_PHY_SW_STATE(unit, port);
   2211 
   2212     if (NULL == ability) {
   2213         return SOC_E_PARAM;
   2214     }
   2215 
   2216     sal_memset(ability, 0, sizeof(*ability));
   2217     if ((pc->speed_max == PHY82764_SPD_106G) ||
   2218         (pc->speed_max == PHY82764_SPD_100G)) {
   2219         pa_speed = SOC_PA_SPEED_106GB | SOC_PA_SPEED_100GB |
   2220                    SOC_PA_SPEED_42GB | SOC_PA_SPEED_40GB |
   2221                    SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB |
   2222                    SOC_PA_SPEED_11GB  | SOC_PA_SPEED_10GB;
   2223     } else if ((pc->speed_max == PHY82764_SPD_42G) ||
   2224                 (pc->speed_max == PHY82764_SPD_40G)) {
   2225         pa_speed = SOC_PA_SPEED_42GB | SOC_PA_SPEED_40GB |
   2226                    SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB |
   2227                    SOC_PA_SPEED_11GB  | SOC_PA_SPEED_10GB;
   2228     } else if ((pc->speed_max == PHY82764_SPD_20G) ||
   2229                (pc->speed_max == PHY82764_SPD_20G)) {
   2230         pa_speed = SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB |
   2231                    SOC_PA_SPEED_11GB  | SOC_PA_SPEED_10GB;
   2232     } else if ((pc->speed_max == PHY82764_SPD_11G) ||
   2233                (pc->speed_max == PHY82764_SPD_10G)) {
   2234         pa_speed = SOC_PA_SPEED_10GB;
   2235     } else {
   2236         pa_speed = SOC_PA_SPEED_106GB | SOC_PA_SPEED_100GB |
   2237                    SOC_PA_SPEED_42GB | SOC_PA_SPEED_40GB |
   2238                    SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB |
   2239                    SOC_PA_SPEED_11GB  | SOC_PA_SPEED_10GB;
   2240     }
   2241 
   2242     ability->loopback  = SOC_PA_LB_PHY;
   2243     ability->medium    = SOC_PA_MEDIUM_COPPER;
   2244     ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   2245     ability->interface = SOC_PA_INTF_XGMII;
   2246     ability->flags     = SOC_PA_AUTONEG;
   2247     ability->speed_full_duplex = pa_speed;
   2248 
   2249     LOG_INFO(BSL_LS_SOC_PHY,
   2250              (BSL_META_U(pc->unit,
   2251                          "phy82764_ability_local_get:unit=%d p=%d sp=%08x\n"),
   2252               unit, port, ability->speed_full_duplex));
   2253 
   2254     return (SOC_E_NONE);
   2255 }
   2256 
   2257 STATIC int
   2258 phy_82764_link_get(int unit, soc_port_t port, int *link)
   2259 {
   2260     phy_ctrl_t                *pc;
   2261     soc_phymod_ctrl_t         *pmc;
   2262     phymod_phy_access_t       *pm_phy;
   2263     phy_ctrl_t *int_pc;
   2264     int32 int_phy_link = 0;
   2265     int32 speed = 0;
   2266     soc_port_if_t interface = 0;
   2267     *link = 0;
   2268     int_pc = INT_PHY_SW_STATE(unit, port);
   2269     pc = EXT_PHY_SW_STATE(unit, port);
   2270     if (pc == NULL) {
   2271         return SOC_E_INTERNAL;
   2272     }
   2273     pmc = &pc->phymod_ctrl;
   2274     pm_phy = &pmc->phy[pmc->main_phy]->pm_phy;
   2275     if (eye_scan_enabled) {
   2276         /* Return Success if eyescan is in progress*/
   2277         if (int_pc != NULL) {
   2278 		    SOC_IF_ERROR_RETURN(PHY_LINK_GET(int_pc->pd, unit, port, &int_phy_link));
   2279         }
   2280         *link = int_phy_link;
   2281 #ifdef PHY82764_DEBUG    
   2282         if (*link == 0) {
   2283             LOG_CLI((BSL_META_U(unit,"PCS Down: port:%d\n "), port));
   2284         }
   2285 #endif        
   2286         return SOC_E_NONE;
   2287     }
   2288 
   2289     if (int_pc != NULL) {
   2290 		SOC_IF_ERROR_RETURN(PHY_LINK_GET(int_pc->pd, unit, port, &int_phy_link));
   2291         SOC_IF_ERROR_RETURN(PHY_SPEED_GET(int_pc->pd, unit, port, &speed));
   2292         SOC_IF_ERROR_RETURN(PHY_INTERFACE_GET(int_pc->pd, unit, port, &interface));
   2293     } 
   2294     
   2295     SOC_IF_ERROR_RETURN
   2296         (phymod_phy_link_status_get(pm_phy, (uint32_t *) link));
   2297 
   2298     /* When PMD lock of 82764 is not Set, Leave the port link as
   2299      * PMD status of 82764. When PMD lock of 82764 is set use
   2300      * PCS status of internal serdes as port link status.
   2301      * When internal serdes is not there use 82764 PMS as link status*/
   2302 #ifdef PHY82764_DEBUG    
   2303     if (*link == 1 && int_phy_link == 0) {
   2304         LOG_CLI((BSL_META_U(unit,"PMD UP PCS Down: port:%d\n "), port));
   2305     }
   2306     if (*link == 0 && int_phy_link == 1) {
   2307         LOG_CLI((BSL_META_U(unit,"PMD DOWN PCS UP port:%d\n "), port));
   2308     }
   2309 #endif
   2310     if (*link && int_pc) {
   2311         *link = int_phy_link;
   2312     }
   2313 
   2314     return SOC_E_NONE;
   2315 }
   2316 
   2317 STATIC int
   2318 phy_82764_enable_set(int unit, soc_port_t port, int enable)
   2319 {
   2320     phy_ctrl_t                *pc;
   2321     soc_phymod_ctrl_t         *pmc;
   2322     int32 intf;
   2323 
   2324     /* locate phy control */
   2325     pc = EXT_PHY_SW_STATE(unit, port);
   2326     if (pc == NULL) {
   2327         return SOC_E_INTERNAL;
   2328     }
   2329 
   2330     if (eye_scan_enabled) {
   2331         /* Return Success if eyescan is in progress*/
   2332         return SOC_E_NONE;
   2333     }
   2334     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82764_SYS_SIDE : PHY82764_LINE_SIDE; 
   2335 
   2336     pmc = &pc->phymod_ctrl;
   2337 
   2338     SOC_IF_ERROR_RETURN
   2339         (phy_82764_power_set(pmc, port, intf, enable));
   2340 
   2341     if (enable) {
   2342         PHY_FLAGS_CLR(unit, port, PHY_FLAGS_DISABLE);
   2343     } else {
   2344         PHY_FLAGS_SET(unit, port, PHY_FLAGS_DISABLE);
   2345     }
   2346 
   2347     return SOC_E_NONE;
   2348 }
   2349 
   2350 STATIC int
   2351 phy_82764_enable_get(int unit, soc_port_t port, int *enable)
   2352 {
   2353     phy_ctrl_t                *pc;
   2354     soc_phymod_ctrl_t         *pmc;
   2355     int32 intf;
   2356     uint32_t ena_dis;
   2357     *enable = 0;
   2358 
   2359     /* locate phy control */
   2360     pc = EXT_PHY_SW_STATE(unit, port);
   2361     if (pc == NULL) {
   2362         return SOC_E_INTERNAL;
   2363     }
   2364     pmc = &pc->phymod_ctrl;
   2365     if (eye_scan_enabled) {
   2366         /* Return Success if eyescan is in progress*/
   2367         *enable =1;
   2368         return SOC_E_NONE;
   2369     }
   2370     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82764_SYS_SIDE : PHY82764_LINE_SIDE; 
   2371     SOC_IF_ERROR_RETURN
   2372         (phy_82764_power_get(pmc, port, intf, &ena_dis));
   2373     *enable = ena_dis;
   2374 
   2375     return SOC_E_NONE;
   2376 }
   2377 
   2378 STATIC int
   2379 phy_82764_lb_set(int unit, soc_port_t port, int enable)
   2380 {
   2381     phy_ctrl_t* pc; 
   2382     soc_phymod_ctrl_t *pmc;
   2383 
   2384     pc = EXT_PHY_SW_STATE(unit, port);
   2385     pmc = &pc->phymod_ctrl;
   2386     SOC_IF_ERROR_RETURN (
   2387         phy_82764_loopback_internal_pmd_set(pmc, port, PHY82764_LINE_SIDE, enable));
   2388 
   2389     return SOC_E_NONE;
   2390 }
   2391 
   2392 STATIC int
   2393 phy_82764_firmware_set(int unit, int port, int cmd, uint8 *array,int datalen)
   2394 {
   2395     phy_ctrl_t                *pc;
   2396     soc_phymod_core_t *pmc_core;
   2397     phymod_core_access_t *pm_core;
   2398     soc_phymod_ctrl_t *pmc;
   2399     phymod_core_status_t core_status;
   2400     int phy_force_dload = 0;
   2401 
   2402     /* locate phy control */
   2403     pc = EXT_PHY_SW_STATE(unit, port);
   2404     if (pc == NULL) {
   2405         return SOC_E_INTERNAL;
   2406     }
   2407     pmc = &pc->phymod_ctrl;
   2408 
   2409     pmc_core = pmc->phy[0]->core;
   2410     pm_core = &pmc_core->pm_core;
   2411     if (pm_core == NULL) {
   2412         return SOC_E_INTERNAL;
   2413     }
   2414 
   2415     phy_force_dload = 0x11;
   2416     phy_force_dload = soc_property_port_get(unit, port,
   2417                                     spn_PHY_FORCE_FIRMWARE_LOAD, phy_force_dload);
   2418     phy_force_dload &= 0xf;
   2419 
   2420     if(phy_force_dload == phymodFirmwareLoadForce) {
   2421         PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_SET(&(pmc_core->init_config));
   2422     } else if(phy_force_dload == phymodFirmwareLoadAuto) {
   2423         PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_SET(&(pmc_core->init_config));
   2424     }
   2425 
   2426     if (array == NULL) {
   2427         if (cmd == PHYCTRL_UCODE_BCST_SETUP) {
   2428             PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD_SET(&(pmc_core->init_config));
   2429             SOC_IF_ERROR_RETURN (
   2430               phymod_core_init(pm_core, &pmc_core->init_config, &core_status));
   2431             PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD_CLR(&(pmc_core->init_config));
   2432             return SOC_E_NONE;
   2433         } else if (cmd == PHYCTRL_UCODE_BCST_uC_SETUP) {
   2434             return SOC_E_NONE;
   2435         } else if (cmd == PHYCTRL_UCODE_BCST_ENABLE) {
   2436             PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_SET(&(pmc_core->init_config));
   2437             SOC_IF_ERROR_RETURN (
   2438               phymod_core_init(pm_core, &pmc_core->init_config, &core_status));
   2439             PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_CLR(&(pmc_core->init_config));
   2440             return SOC_E_NONE;
   2441         } else if (cmd == PHYCTRL_UCODE_BCST_LOAD) {
   2442             PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_SET(&(pmc_core->init_config));
   2443             SOC_IF_ERROR_RETURN (
   2444               phymod_core_init(pm_core, &pmc_core->init_config, &core_status));
   2445             PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_CLR(&(pmc_core->init_config));
   2446             return SOC_E_NONE;
   2447         } else if (cmd == PHYCTRL_UCODE_BCST_END) {
   2448             PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_SET(&(pmc_core->init_config));
   2449             SOC_IF_ERROR_RETURN (
   2450               phymod_core_init(pm_core, &pmc_core->init_config, &core_status));
   2451             PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_CLR(&(pmc_core->init_config));
   2452             return SOC_E_NONE;
   2453         }
   2454     } else {
   2455         return SOC_E_UNAVAIL;
   2456     }
   2457 
   2458     return SOC_E_NONE;
   2459 }
   2460 
   2461 /* 
   2462  * phy_82764_per_lane_loopback_internal_pmd_get (this is the PMD global loopback)
   2463  */
   2464 STATIC int 
   2465 phy_82764_per_lane_loopback_internal_pmd_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2466 {
   2467     phymod_phy_access_t    *pm_phy;
   2468     uint32_t               enable;
   2469     soc_phymod_phy_t    *p_phy;
   2470     uint32              lane_map;
   2471     phymod_phy_access_t pm_phy_copy;
   2472 
   2473     /* locate the desired phy and lane */
   2474     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2475 
   2476     /* Make a copy of the phy access and overwrite the desired lane */
   2477     pm_phy = &p_phy->pm_phy;
   2478     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2479     pm_phy_copy.access.lane_mask = lane_map;
   2480     pm_phy_copy.port_loc = phymodPortLocLine;
   2481     if(intf == PHY82764_SYS_SIDE) {
   2482         pm_phy_copy.port_loc = phymodPortLocSys;
   2483     } 
   2484 
   2485     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(&pm_phy_copy, phymodLoopbackGlobalPMD, &enable));
   2486     *value = enable;
   2487 
   2488     return(SOC_E_NONE);
   2489 }
   2490 /* 
   2491  * phy_82764_loopback_internal_pmd_get (this is the PMD global loopback)
   2492  */
   2493 STATIC int 
   2494 phy_82764_loopback_internal_pmd_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value)
   2495 {
   2496     phymod_phy_access_t    *pm_phy;
   2497     uint32_t               enable;
   2498     phymod_phy_access_t pm_phy_copy;
   2499 
   2500     /* just take the value from the first phy */
   2501     if (pmc->phy[0] == NULL) {
   2502         return SOC_E_INTERNAL;
   2503     }
   2504     pm_phy = &pmc->phy[0]->pm_phy;
   2505 
   2506     if (pm_phy == NULL) {
   2507         return SOC_E_INTERNAL;
   2508     }
   2509 
   2510     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2511     pm_phy_copy.port_loc = phymodPortLocLine;
   2512     if(intf == PHY82764_SYS_SIDE) {
   2513         pm_phy_copy.port_loc = phymodPortLocSys;
   2514         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   2515     } 
   2516     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(&pm_phy_copy, phymodLoopbackGlobalPMD, &enable));
   2517     *value = enable;
   2518 
   2519     return(SOC_E_NONE);
   2520 }
   2521 
   2522 /* 
   2523  * phy_82764_per_lane_loopback_remote_get
   2524  */
   2525 STATIC int 
   2526 phy_82764_per_lane_loopback_remote_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2527 {
   2528     phymod_phy_access_t    *pm_phy;
   2529     uint32_t               enable;
   2530     soc_phymod_phy_t    *p_phy;
   2531     uint32              lane_map;
   2532     phymod_phy_access_t pm_phy_copy;
   2533 
   2534     /* locate the desired phy and lane */
   2535     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2536 
   2537     /* Make a copy of the phy access and overwrite the desired lane */
   2538     pm_phy = &p_phy->pm_phy;
   2539     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2540     pm_phy_copy.access.lane_mask = lane_map;
   2541     pm_phy_copy.port_loc = phymodPortLocLine;
   2542     if(intf == PHY82764_SYS_SIDE) {
   2543         pm_phy_copy.port_loc = phymodPortLocSys;
   2544     } 
   2545 
   2546     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(&pm_phy_copy, phymodLoopbackRemotePMD, &enable));
   2547     *value = enable;
   2548 
   2549     return(SOC_E_NONE);
   2550 }
   2551 
   2552 /* 
   2553  * phy_82764_per_lane_prbs_tx_poly_get
   2554  */
   2555 STATIC int
   2556 phy_82764_per_lane_prbs_tx_poly_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2557 {
   2558     phymod_phy_access_t  *pm_phy;
   2559     phymod_prbs_t        prbs;
   2560     uint32_t flags = 0;
   2561 
   2562 
   2563     soc_phymod_phy_t    *p_phy;
   2564     uint32              lane_map;
   2565     phymod_phy_access_t pm_phy_copy;
   2566 
   2567     /* locate the desired phy and lane */
   2568     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2569 
   2570     /* Make a copy of the phy access and overwrite the desired lane */
   2571     pm_phy = &p_phy->pm_phy;
   2572     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2573     pm_phy_copy.access.lane_mask = lane_map;
   2574     pm_phy_copy.port_loc = phymodPortLocLine;
   2575     if(intf == PHY82764_SYS_SIDE) {
   2576         pm_phy_copy.port_loc = phymodPortLocSys;
   2577     } 
   2578     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2579     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2580 
   2581     *value = (int) prbs.poly;
   2582 
   2583     /* convert from PHYMOD enum to SDK enum */
   2584     switch(prbs.poly){
   2585     case phymodPrbsPoly7:
   2586         *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1;
   2587         break;
   2588     case phymodPrbsPoly9:
   2589         *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1;
   2590         break;
   2591     case phymodPrbsPoly15:
   2592         *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1;
   2593         break;
   2594     case phymodPrbsPoly23:
   2595         *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1;
   2596         break;
   2597     case phymodPrbsPoly31:
   2598         *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1;
   2599         break;
   2600     case phymodPrbsPoly11:
   2601         *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1;
   2602         break;
   2603     case phymodPrbsPoly58:
   2604         *value = SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1; 
   2605         break;
   2606     default:
   2607         return SOC_E_INTERNAL;
   2608     }
   2609 
   2610     return SOC_E_NONE;
   2611 }
   2612 /* 
   2613  * phy_82764_per_lane_prbs_rx_poly_get
   2614  */
   2615 STATIC int
   2616 phy_82764_per_lane_prbs_rx_poly_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2617 {
   2618     phymod_phy_access_t  *pm_phy;
   2619     phymod_prbs_t        prbs;
   2620     uint32_t flags = 0;
   2621 
   2622 
   2623     soc_phymod_phy_t    *p_phy;
   2624     uint32              lane_map;
   2625     phymod_phy_access_t pm_phy_copy;
   2626 
   2627     /* locate the desired phy and lane */
   2628     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2629 
   2630     /* Make a copy of the phy access and overwrite the desired lane */
   2631     pm_phy = &p_phy->pm_phy;
   2632     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2633     pm_phy_copy.access.lane_mask = lane_map;
   2634     pm_phy_copy.port_loc = phymodPortLocLine;
   2635     if(intf == PHY82764_SYS_SIDE) {
   2636         pm_phy_copy.port_loc = phymodPortLocSys;
   2637     } 
   2638     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   2639     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2640 
   2641     *value = (int) prbs.poly;
   2642 
   2643     /* convert from PHYMOD enum to SDK enum */
   2644     switch(prbs.poly){
   2645     case phymodPrbsPoly7:
   2646         *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1;
   2647         break;
   2648     case phymodPrbsPoly9:
   2649         *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1;
   2650         break;
   2651     case phymodPrbsPoly15:
   2652         *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1;
   2653         break;
   2654     case phymodPrbsPoly23:
   2655         *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1;
   2656         break;
   2657     case phymodPrbsPoly31:
   2658         *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1;
   2659         break;
   2660     case phymodPrbsPoly11:
   2661         *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1;
   2662         break;
   2663     case phymodPrbsPoly58:
   2664         *value = SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1;
   2665         break;
   2666     default:
   2667         return SOC_E_INTERNAL;
   2668     }
   2669 
   2670     return SOC_E_NONE;
   2671 }
   2672 
   2673 /* 
   2674  * phy_82764_per_lane_prbs_tx_invert_data_get
   2675  */
   2676 STATIC int
   2677 phy_82764_per_lane_prbs_tx_invert_data_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2678 {
   2679     phymod_phy_access_t  *pm_phy;
   2680     phymod_prbs_t        prbs;
   2681     uint32_t flags = 0;
   2682 
   2683     soc_phymod_phy_t    *p_phy;
   2684     uint32              lane_map;
   2685     phymod_phy_access_t pm_phy_copy;
   2686 
   2687     /* locate the desired phy and lane */
   2688     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2689 
   2690     /* Make a copy of the phy access and overwrite the desired lane */
   2691     pm_phy = &p_phy->pm_phy;
   2692     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2693     pm_phy_copy.access.lane_mask = lane_map;
   2694     pm_phy_copy.port_loc = phymodPortLocLine;
   2695     if(intf == PHY82764_SYS_SIDE) {
   2696         pm_phy_copy.port_loc = phymodPortLocSys;
   2697     } 
   2698 
   2699     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2700     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2701     *value = prbs.invert;
   2702 
   2703     return(SOC_E_NONE);
   2704 }
   2705 
   2706 /* 
   2707  * phy_82764_per_lane_prbs_rx_invert_data_get
   2708  */
   2709 STATIC int
   2710 phy_82764_per_lane_prbs_rx_invert_data_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2711 {
   2712     phymod_phy_access_t  *pm_phy;
   2713     phymod_prbs_t        prbs;
   2714     uint32_t flags = 0;
   2715     soc_phymod_phy_t    *p_phy;
   2716     uint32              lane_map;
   2717     phymod_phy_access_t pm_phy_copy;
   2718 
   2719     /* locate the desired phy and lane */
   2720     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2721 
   2722     /* Make a copy of the phy access and overwrite the desired lane */
   2723     pm_phy = &p_phy->pm_phy;
   2724     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2725     pm_phy_copy.access.lane_mask = lane_map;
   2726     pm_phy_copy.port_loc = phymodPortLocLine;
   2727     if(intf == PHY82764_SYS_SIDE) {
   2728         pm_phy_copy.port_loc = phymodPortLocSys;
   2729     } 
   2730 
   2731     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   2732     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2733     *value = prbs.invert;
   2734 
   2735     return(SOC_E_NONE);
   2736 }
   2737 
   2738 /* 
   2739  * phy_82764_per_lane_prbs_tx_enable_get
   2740  */
   2741 STATIC int
   2742 phy_82764_per_lane_prbs_tx_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2743 {
   2744     phymod_phy_access_t  *pm_phy;
   2745     uint32_t flags = 0;
   2746     soc_phymod_phy_t    *p_phy;
   2747     uint32              lane_map;
   2748     phymod_phy_access_t pm_phy_copy;
   2749 
   2750     /* locate the desired phy and lane */
   2751     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2752 
   2753     /* Make a copy of the phy access and overwrite the desired lane */
   2754     pm_phy = &p_phy->pm_phy;
   2755     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2756     pm_phy_copy.access.lane_mask = lane_map;
   2757     pm_phy_copy.port_loc = phymodPortLocLine;
   2758     if(intf == PHY82764_SYS_SIDE) {
   2759         pm_phy_copy.port_loc = phymodPortLocSys;
   2760     } 
   2761 
   2762     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2763     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(&pm_phy_copy, flags, value));
   2764 
   2765     return(SOC_E_NONE);
   2766 }
   2767 
   2768 /* 
   2769  * phy_82764_per_lane_prbs_rx_enable_get
   2770  */
   2771 STATIC int
   2772 phy_82764_per_lane_prbs_rx_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2773 {
   2774     phymod_phy_access_t  *pm_phy;
   2775     uint32_t flags = 0;
   2776     soc_phymod_phy_t    *p_phy;
   2777     uint32              lane_map;
   2778     phymod_phy_access_t pm_phy_copy;
   2779 
   2780     /* locate the desired phy and lane */
   2781     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2782 
   2783     /* Make a copy of the phy access and overwrite the desired lane */
   2784     pm_phy = &p_phy->pm_phy;
   2785     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2786     pm_phy_copy.access.lane_mask = lane_map;
   2787     pm_phy_copy.port_loc = phymodPortLocLine;
   2788     if(intf == PHY82764_SYS_SIDE) {
   2789         pm_phy_copy.port_loc = phymodPortLocSys;
   2790     } 
   2791 
   2792     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   2793     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(&pm_phy_copy, flags, value));
   2794 
   2795     return(SOC_E_NONE);
   2796 }
   2797 
   2798 /* 
   2799  * phy_82764_per_lane_prbs_rx_status_get
   2800  */
   2801 STATIC int
   2802 phy_82764_per_lane_prbs_rx_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2803 {
   2804     phymod_phy_access_t    *pm_phy;
   2805     phymod_prbs_status_t   prbs_tmp;
   2806     int prbs_lock, lock_loss, error_count ;
   2807     soc_phymod_phy_t    *p_phy;
   2808     uint32              lane_map;
   2809     phymod_phy_access_t pm_phy_copy;
   2810 
   2811     prbs_lock   = 1 ; 
   2812     lock_loss   = 0 ;
   2813     error_count = 0 ;
   2814     /* locate the desired phy and lane */
   2815     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2816 
   2817     /* Make a copy of the phy access and overwrite the desired lane */
   2818     pm_phy = &p_phy->pm_phy;
   2819     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2820     pm_phy_copy.access.lane_mask = lane_map;
   2821     pm_phy_copy.port_loc = phymodPortLocLine;
   2822     if(intf == PHY82764_SYS_SIDE) {
   2823         pm_phy_copy.port_loc = phymodPortLocSys;
   2824     } 
   2825     /* $$$ Need to add diagnostic API */
   2826     SOC_IF_ERROR_RETURN
   2827         (phymod_phy_prbs_status_get(&pm_phy_copy, 0, &prbs_tmp));
   2828 
   2829     if(prbs_tmp.prbs_lock==0) {
   2830         prbs_lock = 0 ;
   2831     } else {
   2832         if(prbs_tmp.prbs_lock_loss) {
   2833             lock_loss = 1 ;
   2834         } else {
   2835             error_count += prbs_tmp.error_count;
   2836         }
   2837     }
   2838     
   2839     if (prbs_lock == 0) {
   2840         *value = -1;
   2841     } else if ((lock_loss == 1) && (prbs_lock == 1)) {
   2842         *value = -2;
   2843     } else {
   2844         *value = error_count;
   2845     }
   2846 
   2847     return(SOC_E_NONE);
   2848 }
   2849 /* 
   2850  * phy_82764_per_lane_rx_peak_filter_get
   2851  */
   2852 STATIC int
   2853 phy_82764_per_lane_rx_peak_filter_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2854 {
   2855     soc_phymod_phy_t    *p_phy;
   2856     uint32              lane_map;
   2857     phymod_phy_access_t pm_phy_copy, *pm_phy;
   2858     phymod_rx_t         phymod_rx;
   2859 
   2860     *value = 0;
   2861 
   2862     /* locate the desired phy and lane */
   2863     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2864 
   2865     /* Make a copy of the phy access and overwrite the desired lane */
   2866     pm_phy = &p_phy->pm_phy;
   2867     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2868     pm_phy_copy.access.lane_mask = lane_map;
   2869     pm_phy_copy.port_loc = phymodPortLocLine;
   2870     if(intf == PHY82764_SYS_SIDE) {
   2871         pm_phy_copy.port_loc = phymodPortLocSys;
   2872     } 
   2873 
   2874     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   2875         *value = phymod_rx.peaking_filter.value;
   2876 
   2877     return(SOC_E_NONE);
   2878 }
   2879 
   2880 /* 
   2881  * phy_82764_per_lane_rx_vga_get
   2882  */
   2883 STATIC int
   2884 phy_82764_per_lane_rx_vga_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2885 {
   2886     soc_phymod_phy_t    *p_phy;
   2887     uint32              lane_map;
   2888     phymod_phy_access_t pm_phy_copy, *pm_phy;
   2889     phymod_rx_t         phymod_rx;
   2890 
   2891     *value = 0;
   2892 
   2893     /* locate the desired phy and lane */
   2894     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2895 
   2896     /* Make a copy of the phy access and overwrite the desired lane */
   2897     pm_phy = &p_phy->pm_phy;
   2898     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2899     pm_phy_copy.access.lane_mask = lane_map;
   2900     pm_phy_copy.port_loc = phymodPortLocLine;
   2901     if(intf == PHY82764_SYS_SIDE) {
   2902         pm_phy_copy.port_loc = phymodPortLocSys;
   2903     } 
   2904 
   2905     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   2906         *value = phymod_rx.vga.value;
   2907 
   2908     return(SOC_E_NONE);
   2909 }
   2910 
   2911 /* 
   2912  * phy_82764_per_lane_rx_dfe_tap_control_get
   2913  */
   2914 STATIC int
   2915 phy_82764_per_lane_rx_dfe_tap_control_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, int tap, uint32 *value)
   2916 {
   2917     soc_phymod_phy_t    *p_phy;
   2918     uint32              lane_map;
   2919     phymod_phy_access_t pm_phy_copy, *pm_phy;
   2920     phymod_rx_t          phymod_rx;
   2921 
   2922     *value = 0;
   2923 
   2924     /* locate the desired phy and lane */
   2925     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2926 
   2927     /* Make a copy of the phy access and overwrite the desired lane */
   2928     pm_phy = &p_phy->pm_phy;
   2929     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2930     pm_phy_copy.access.lane_mask = lane_map;
   2931     pm_phy_copy.port_loc = phymodPortLocLine;
   2932     if(intf == PHY82764_SYS_SIDE) {
   2933         pm_phy_copy.port_loc = phymodPortLocSys;
   2934     } 
   2935 
   2936     if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) {
   2937         /* this can only happen with a coding error */
   2938         return SOC_E_INTERNAL;
   2939     }
   2940 
   2941     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   2942     *value = phymod_rx.dfe[tap].value;
   2943 
   2944     return(SOC_E_NONE);
   2945 }
   2946 
   2947 
   2948 /* 
   2949  * phy_82764_per_lane_rx_low_freq_filter_get
   2950  */
   2951 STATIC int
   2952 phy_82764_per_lane_rx_low_freq_filter_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2953 {
   2954     soc_phymod_phy_t    *p_phy;
   2955     uint32              lane_map;
   2956     phymod_phy_access_t pm_phy_copy, *pm_phy;
   2957     phymod_rx_t          phymod_rx;
   2958 
   2959     *value = 0;
   2960 
   2961     /* locate the desired phy and lane */
   2962     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   2963 
   2964     /* Make a copy of the phy access and overwrite the desired lane */
   2965     pm_phy = &p_phy->pm_phy;
   2966     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2967     pm_phy_copy.access.lane_mask = lane_map;
   2968     pm_phy_copy.port_loc = phymodPortLocLine;
   2969     if(intf == PHY82764_SYS_SIDE) {
   2970         pm_phy_copy.port_loc = phymodPortLocSys;
   2971     } 
   2972 
   2973     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   2974     *value = phymod_rx.low_freq_peaking_filter.value;
   2975 
   2976     return(SOC_E_NONE);
   2977 }
   2978 
   2979 /* 
   2980  * phy_82764_pi_control_get
   2981  */
   2982 STATIC int 
   2983 phy_82764_pi_control_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value)
   2984 {
   2985     phymod_phy_access_t  *pm_phy;
   2986     phymod_tx_override_t tx_override;
   2987     phymod_phy_access_t pm_phy_copy;
   2988 
   2989     /* just take the value from the first phy */
   2990     if (pmc->phy[0] == NULL) {
   2991         return SOC_E_INTERNAL;
   2992     }
   2993     pm_phy = &pmc->phy[0]->pm_phy;
   2994 
   2995     if (pm_phy == NULL) {
   2996         return SOC_E_INTERNAL;
   2997     }
   2998     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2999     pm_phy_copy.port_loc = phymodPortLocLine;
   3000     if(intf == PHY82764_SYS_SIDE) {
   3001         pm_phy_copy.port_loc = phymodPortLocSys;
   3002         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   3003     } 
   3004 
   3005     SOC_IF_ERROR_RETURN(phymod_phy_tx_override_get(&pm_phy_copy, &tx_override));
   3006     *value = tx_override.phase_interpolator.value;
   3007 
   3008     return(SOC_E_NONE);
   3009 }
   3010 /*
   3011  * phy_82764_per_lane_rx_seq_done_get
   3012  */
   3013 STATIC int
   3014 phy_82764_per_lane_rx_seq_done_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   3015 {
   3016     soc_phymod_phy_t    *p_phy;
   3017     uint32              lane_map;
   3018     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3019 
   3020     /* locate the desired phy and lane */
   3021     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   3022 
   3023     /* Make a copy of the phy access and overwrite the desired lane */
   3024     pm_phy = &p_phy->pm_phy;
   3025     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3026     pm_phy_copy.access.lane_mask = lane_map;
   3027     pm_phy_copy.port_loc = phymodPortLocLine;
   3028     if(intf == PHY82764_SYS_SIDE) {
   3029         pm_phy_copy.port_loc = phymodPortLocSys;
   3030     }
   3031 
   3032     SOC_IF_ERROR_RETURN(phymod_phy_rx_pmd_locked_get(&pm_phy_copy, value));
   3033 
   3034     return(SOC_E_NONE);
   3035 }
   3036 
   3037 /* 
   3038  * phy_82764_fec_get
   3039  */
   3040 STATIC int 
   3041 phy_82764_fec_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value)
   3042 {
   3043     phymod_phy_access_t *pm_phy;
   3044     phymod_phy_access_t pm_phy_copy;
   3045 
   3046     pm_phy = &pmc->phy[0]->pm_phy;
   3047 
   3048     if (pm_phy == NULL) {
   3049         return SOC_E_INTERNAL;
   3050     }
   3051     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3052     pm_phy_copy.port_loc = phymodPortLocLine;
   3053     if(intf == PHY82764_SYS_SIDE) {
   3054         pm_phy_copy.port_loc = phymodPortLocSys;
   3055         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   3056     }
   3057 
   3058     SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_get(&pm_phy_copy, value));
   3059 
   3060     return(SOC_E_NONE);
   3061 }
   3062 
   3063 /* 
   3064  * phy_82764_per_lane_driver_current_get
   3065  */
   3066 STATIC int
   3067 phy_82764_per_lane_driver_current_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   3068 {
   3069     soc_phymod_phy_t    *p_phy;
   3070     uint32              lane_map;
   3071     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3072     phymod_tx_t         phymod_tx;
   3073 
   3074     /* locate the desired phy and lane */
   3075     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   3076 
   3077     /* Make a copy of the phy access and overwrite the desired lane */
   3078     pm_phy = &p_phy->pm_phy;
   3079     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3080     pm_phy_copy.access.lane_mask = lane_map;
   3081     pm_phy_copy.port_loc = phymodPortLocLine;
   3082     if(intf == PHY82764_SYS_SIDE) {
   3083         pm_phy_copy.port_loc = phymodPortLocSys;
   3084     } 
   3085 
   3086     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3087     *value = phymod_tx.amp;
   3088 
   3089     return(SOC_E_NONE);
   3090 }
   3091 
   3092 /* 
   3093  * phy_82764_per_lane_preemphasis_get
   3094  */
   3095 STATIC int
   3096 phy_82764_per_lane_preemphasis_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   3097 {
   3098     soc_phymod_phy_t    *p_phy;
   3099     uint32              lane_map;
   3100     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3101     phymod_tx_t         phymod_tx;
   3102 
   3103     /* locate the desired phy and lane */
   3104     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   3105 
   3106     /* Make a copy of the phy access and overwrite the desired lane */
   3107     pm_phy = &p_phy->pm_phy;
   3108     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3109     pm_phy_copy.access.lane_mask = lane_map;
   3110     pm_phy_copy.port_loc = phymodPortLocLine;
   3111     if(intf == PHY82764_SYS_SIDE) {
   3112         pm_phy_copy.port_loc = phymodPortLocSys;
   3113     } 
   3114 
   3115     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3116     *value = phymod_tx.pre;
   3117 
   3118     return(SOC_E_NONE);
   3119 }
   3120 
   3121 /* 
   3122  * phy_82764_per_lane_rx_low_freq_filter_set
   3123  */
   3124 STATIC int
   3125 phy_82764_per_lane_rx_low_freq_filter_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   3126 {
   3127     soc_phymod_phy_t    *p_phy;
   3128     uint32              lane_map;
   3129     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3130     phymod_rx_t          phymod_rx;
   3131 
   3132     /* locate the desired phy and lane */
   3133     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   3134 
   3135     /* Make a copy of the phy access and overwrite the desired lane */
   3136     pm_phy = &p_phy->pm_phy;
   3137     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3138     pm_phy_copy.access.lane_mask = lane_map;
   3139     pm_phy_copy.port_loc = phymodPortLocLine;
   3140     if(intf == PHY82764_SYS_SIDE) {
   3141         pm_phy_copy.port_loc = phymodPortLocSys;
   3142     } 
   3143 
   3144     sal_memset(&phymod_rx, 0, sizeof(phymod_rx_t));
   3145     phymod_rx.low_freq_peaking_filter.enable = TRUE;
   3146     phymod_rx.low_freq_peaking_filter.value = value;
   3147     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   3148 
   3149     return(SOC_E_NONE);
   3150 }
   3151 /* 
   3152  * phy_82764_per_lane_power_get
   3153  */
   3154 STATIC int
   3155 phy_82764_per_lane_power_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   3156 {
   3157     phymod_phy_access_t *pm_phy;
   3158     phymod_phy_power_t  power;
   3159     soc_phymod_phy_t    *p_phy;
   3160     uint32              lane_map;
   3161     phymod_phy_access_t pm_phy_copy;
   3162 
   3163     /* locate the desired phy and lane */
   3164     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   3165 
   3166     /* Make a copy of the phy access and overwrite the desired lane */
   3167     pm_phy = &p_phy->pm_phy;
   3168     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3169     pm_phy_copy.access.lane_mask = lane_map;
   3170     pm_phy_copy.port_loc = phymodPortLocLine;
   3171     if(intf == PHY82764_SYS_SIDE) {
   3172         pm_phy_copy.port_loc = phymodPortLocSys;
   3173     } 
   3174 
   3175     phymod_phy_power_t_init(&power);
   3176 
   3177     SOC_IF_ERROR_RETURN(phymod_phy_power_get(&pm_phy_copy, &power));
   3178 
   3179     if(power.tx == phymodPowerOn && power.rx == phymodPowerOn) {
   3180         *value = 1;
   3181     } else {
   3182         *value = 0;
   3183     } 
   3184 
   3185     return(SOC_E_NONE);
   3186 }
   3187 /* 
   3188  * phy_82764_power_get
   3189  */
   3190 STATIC int
   3191 phy_82764_power_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value)
   3192 {
   3193     phymod_phy_access_t     *pm_phy;
   3194     phymod_phy_power_t      power;
   3195     phymod_phy_access_t pm_phy_copy;
   3196 
   3197     /* just take the value from the first phy */
   3198     if (pmc->phy[0] == NULL) {
   3199         return SOC_E_INTERNAL;
   3200     }
   3201     pm_phy = &pmc->phy[0]->pm_phy;
   3202 
   3203     if (pm_phy == NULL) {
   3204         return SOC_E_INTERNAL;
   3205     }
   3206 
   3207     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3208     phymod_phy_power_t_init(&power);
   3209     pm_phy_copy.port_loc = phymodPortLocLine;
   3210     if(intf == PHY82764_SYS_SIDE) {
   3211         pm_phy_copy.port_loc = phymodPortLocSys;
   3212         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   3213     } 
   3214 
   3215     SOC_IF_ERROR_RETURN(phymod_phy_power_get(&pm_phy_copy, &power));
   3216 
   3217     if(power.tx == phymodPowerOn && power.rx == phymodPowerOn) {
   3218         *value = 1;
   3219     } else {
   3220         *value = 0;
   3221     } 
   3222 
   3223     return(SOC_E_NONE);
   3224 }
   3225 /* 
   3226  * phy_82764_per_lane_tx_polarity_get
   3227  */
   3228 STATIC int 
   3229 phy_82764_per_lane_tx_polarity_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   3230 {
   3231     phymod_phy_access_t  *pm_phy;
   3232     phymod_polarity_t    polarity;
   3233     soc_phymod_phy_t    *p_phy;
   3234     uint32              lane_map;
   3235     phymod_phy_access_t pm_phy_copy;
   3236 
   3237     /* locate the desired phy and lane */
   3238     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   3239 
   3240     /* Make a copy of the phy access and overwrite the desired lane */
   3241     pm_phy = &p_phy->pm_phy;
   3242     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3243     pm_phy_copy.access.lane_mask = lane_map;
   3244     pm_phy_copy.port_loc = phymodPortLocLine;
   3245     if(intf == PHY82764_SYS_SIDE) {
   3246         pm_phy_copy.port_loc = phymodPortLocSys;
   3247     } 
   3248 
   3249     phymod_polarity_t_init(&polarity);
   3250     SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(&pm_phy_copy, &polarity));
   3251 
   3252     *value = polarity.tx_polarity;
   3253 
   3254     return(SOC_E_NONE);
   3255 }
   3256 
   3257 /* 
   3258  * phy_82764_per_lane_rx_polarity_get
   3259  */
   3260 STATIC int 
   3261 phy_82764_per_lane_rx_polarity_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   3262 {
   3263     phymod_phy_access_t  *pm_phy;
   3264     phymod_polarity_t    polarity;
   3265     soc_phymod_phy_t    *p_phy;
   3266     uint32              lane_map;
   3267     phymod_phy_access_t pm_phy_copy;
   3268 
   3269     /* locate the desired phy and lane */
   3270     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   3271 
   3272     /* Make a copy of the phy access and overwrite the desired lane */
   3273     pm_phy = &p_phy->pm_phy;
   3274     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3275     pm_phy_copy.access.lane_mask = lane_map;
   3276     pm_phy_copy.port_loc = phymodPortLocLine;
   3277     if(intf == PHY82764_SYS_SIDE) {
   3278         pm_phy_copy.port_loc = phymodPortLocSys;
   3279     } 
   3280 
   3281     phymod_polarity_t_init(&polarity);
   3282     SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(&pm_phy_copy, &polarity));
   3283 
   3284     *value = polarity.rx_polarity;
   3285 
   3286     return(SOC_E_NONE);
   3287 }
   3288 
   3289 /*
   3290  * phy_82764_gpio_config_get
   3291  */
   3292 STATIC int
   3293 phy_82764_gpio_config_get(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 *value)
   3294 {
   3295     phymod_phy_access_t  *pm_phy;
   3296     phymod_phy_access_t pm_phy_copy;
   3297     phymod_gpio_mode_t gpio_mode;
   3298     int gpio_pin_no = 0;
   3299     *value = 0;
   3300 
   3301     /* just take the value from the first phy */
   3302     if (pmc->phy[0] == NULL) {
   3303         return SOC_E_INTERNAL;
   3304     }
   3305     pm_phy = &pmc->phy[0]->pm_phy;
   3306 
   3307     if (pm_phy == NULL) {
   3308         return SOC_E_INTERNAL;
   3309     }
   3310     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3311 
   3312     for (gpio_pin_no = 0; gpio_pin_no < 4; gpio_pin_no++) {
   3313         SOC_IF_ERROR_RETURN(phymod_phy_gpio_config_get(&pm_phy_copy, gpio_pin_no, &gpio_mode));
   3314         *value |= (gpio_mode << (4 * gpio_pin_no));
   3315     }
   3316 
   3317     return(SOC_E_NONE);
   3318 }
   3319 
   3320 /*
   3321  * phy_82764_gpio_value_get
   3322  */
   3323 STATIC int
   3324 phy_82764_gpio_value_get(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 *value)
   3325 {
   3326     phymod_phy_access_t  *pm_phy;
   3327     phymod_phy_access_t pm_phy_copy;
   3328     int gpio_pin_no = 0;
   3329     int pin_value = 0;
   3330     *value = 0;
   3331 
   3332     /* just take the value from the first phy */
   3333     if (pmc->phy[0] == NULL) {
   3334         return SOC_E_INTERNAL;
   3335     }
   3336     pm_phy = &pmc->phy[0]->pm_phy;
   3337 
   3338     if (pm_phy == NULL) {
   3339         return SOC_E_INTERNAL;
   3340     }
   3341 
   3342     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3343 
   3344     for (gpio_pin_no = 0; gpio_pin_no < 4; gpio_pin_no++) {
   3345         SOC_IF_ERROR_RETURN(phymod_phy_gpio_pin_value_get(&pm_phy_copy, gpio_pin_no, &pin_value));
   3346         *value |= (pin_value << (4 * gpio_pin_no));
   3347     }
   3348 
   3349     return(SOC_E_NONE);
   3350 }
   3351 /*
   3352  * Function:
   3353  *     phy_82764_per_lane_eye_margin_est_get
   3354  * Parameters:
   3355  *     pmc             -   Phymod control
   3356  *     port            -   Port no
   3357  *     intf            -   Interface side Line/System side
   3358  *     lane            -   Lane number
   3359  *     eye_margin_mode -   eyescan mode type (left/right/upper/lower)
   3360  *     value           -   Value (Out)
   3361  */ 
   3362 
   3363 int phy_82764_per_lane_eye_margin_est_get(soc_phymod_ctrl_t *pmc,
   3364                         soc_port_t port,
   3365                         int32 intf,
   3366                         int lane, 
   3367                         phymod_eye_margin_mode_t eye_margin_mode,
   3368                         uint32 *value) 
   3369 {
   3370       
   3371     phymod_phy_access_t  *pm_phy;
   3372     phymod_phy_access_t pm_phy_copy;
   3373     soc_phymod_phy_t    *p_phy;
   3374     uint32              lane_map;
   3375     /* locate the desired phy and lane */
   3376     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   3377 
   3378     /* Make a copy of the phy access and overwrite the desired lane */
   3379     pm_phy = &p_phy->pm_phy;
   3380     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3381     pm_phy_copy.access.lane_mask = lane_map;
   3382     pm_phy_copy.port_loc = phymodPortLocLine;
   3383     if(intf == PHY82764_SYS_SIDE) {
   3384         pm_phy_copy.port_loc = phymodPortLocSys;
   3385     }
   3386     SOC_IF_ERROR_RETURN(phymod_phy_eye_margin_est_get(&pm_phy_copy, eye_margin_mode, value));
   3387     return (SOC_E_NONE); 
   3388 }
   3389 
   3390 /*
   3391  * Function:
   3392  *      phy82764_control_get
   3393  * Purpose:
   3394  *      Get current control settings of the PHY. 
   3395  * Parameters:
   3396  *      unit  - BCM unit number.
   3397  *      port  - Port number. 
   3398  *      type  - Control to update 
   3399  *      value - (OUT) Current setting for the control 
   3400  * Returns:     
   3401  *      SOC_E_NONE
   3402  */
   3403 STATIC int
   3404 phy_82764_control_get(int unit, soc_port_t port, soc_phy_control_t type, uint32 *value)
   3405 {
   3406     int                 rv = 0;
   3407     phy_ctrl_t          *pc;
   3408     soc_phymod_ctrl_t   *pmc;
   3409     int32               intf;
   3410     uint32              val;
   3411     int                 lane = 0, num_lanes = 0;
   3412 
   3413     PHY_CONTROL_TYPE_CHECK(type);
   3414 
   3415     /* locate phy control */
   3416     pc = EXT_PHY_SW_STATE(unit, port);
   3417     if (pc == NULL) {
   3418         return SOC_E_INTERNAL;
   3419     }
   3420 
   3421     pmc = &pc->phymod_ctrl;
   3422     *value = 0;
   3423     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82764_SYS_SIDE : PHY82764_LINE_SIDE; 
   3424     /* get number of lanes per port on line side */
   3425     num_lanes = (intf == PHY82764_LINE_SIDE) ? port_num_lanes_line_side_get(unit, port, pc->speed_max):
   3426                                                SOC_INFO(unit).port_num_lanes[port];
   3427   if (!((type == SOC_PHY_CONTROL_INTR_MASK) || (type == SOC_PHY_CONTROL_GPIO_CONFIG) ||
   3428         (type == SOC_PHY_CONTROL_GPIO_VALUE) || (type == SOC_PHY_CONTROL_FIRMWARE_MODE) ||
   3429         (type == SOC_PHY_CONTROL_INTR_STATUS) || (type == SOC_PHY_CONTROL_PHASE_INTERP) ||
   3430         (type == SOC_PHY_CONTROL_POWER) || (type == SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION) ||
   3431         (type == SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE) || (type == SOC_PHY_CONTROL_FIRMWARE_LP_DFE_ENABLE) ||
   3432         (type == SOC_PHY_CONTROL_PREEMPHASIS_LANE0) || (type == SOC_PHY_CONTROL_PREEMPHASIS_LANE1) ||
   3433         (type == SOC_PHY_CONTROL_PREEMPHASIS_LANE2) || (type == SOC_PHY_CONTROL_PREEMPHASIS_LANE3) ||
   3434         (type == SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0) || (type == SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1) ||
   3435         (type == SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2) || (type == SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3) ||
   3436         (type == SOC_PHY_CONTROL_CL72) || (type == SOC_PHY_CONTROL_CL72_STATUS) ||
   3437         (type == SOC_PHY_CONTROL_UNRELIABLE_LOS))) {
   3438       for (lane = 0; lane < num_lanes; lane++) {
   3439          rv |= phy_82764_per_lane_control_get(unit, port, lane, type, &val);
   3440          *value |= val;
   3441          if (rv != 0) {
   3442              return SOC_E_UNAVAIL;
   3443          }
   3444       }
   3445   } else {
   3446     switch(type) {
   3447     case SOC_PHY_CONTROL_CL72:
   3448         rv = phy_82764_cl72_enable_get(pmc, port, intf, value);
   3449         break;
   3450     case SOC_PHY_CONTROL_CL72_STATUS:
   3451         rv = phy_82764_cl72_status_get(pmc, port, intf, value);
   3452         break;
   3453     /* PREEMPHASIS */
   3454     case SOC_PHY_CONTROL_PREEMPHASIS_LANE0:
   3455         rv = phy_82764_per_lane_preemphasis_get(pmc, port, intf, 0, value);
   3456         break;
   3457     case SOC_PHY_CONTROL_PREEMPHASIS_LANE1:
   3458         rv = phy_82764_per_lane_preemphasis_get(pmc, port, intf, 1, value);
   3459         break;
   3460     case SOC_PHY_CONTROL_PREEMPHASIS_LANE2:
   3461         rv = phy_82764_per_lane_preemphasis_get(pmc, port, intf, 2, value);
   3462         break;
   3463     case SOC_PHY_CONTROL_PREEMPHASIS_LANE3:
   3464         rv = phy_82764_per_lane_preemphasis_get(pmc, port, intf, 3, value);
   3465         break;
   3466     /* DRIVER CURRENT */
   3467     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0:
   3468         rv = phy_82764_per_lane_driver_current_get(pmc, port, intf, 0, value);
   3469         break;
   3470     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1:
   3471         rv = phy_82764_per_lane_driver_current_get(pmc, port, intf, 1, value);
   3472         break;
   3473     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2:
   3474         rv = phy_82764_per_lane_driver_current_get(pmc, port, intf, 2, value);
   3475         break;
   3476     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3:
   3477         rv = phy_82764_per_lane_driver_current_get(pmc, port, intf, 3, value);
   3478         break;
   3479     /* PHASE INTERPOLATOR */
   3480     case SOC_PHY_CONTROL_PHASE_INTERP:
   3481         rv = phy_82764_pi_control_get(pmc, port, intf, value);
   3482         break;
   3483     /* FEC */
   3484     case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION:
   3485       rv = phy_82764_fec_enable_get(pmc, port, intf, value);
   3486       break;
   3487     /* POWER */
   3488     case SOC_PHY_CONTROL_POWER:
   3489        rv = phy_82764_power_get(pmc, port, intf, value);
   3490        break;
   3491     case SOC_PHY_CONTROL_INTR_MASK:
   3492         rv = phy_82764_intr_enable_get(pmc, port, intf, value);
   3493         break;
   3494     case SOC_PHY_CONTROL_INTR_STATUS:
   3495         rv = phy_82764_intr_status_get(pmc, port, intf, value);
   3496         break;
   3497     case SOC_PHY_CONTROL_GPIO_CONFIG:
   3498         rv = phy_82764_gpio_config_get(pmc, port, value);
   3499         break;
   3500     case SOC_PHY_CONTROL_GPIO_VALUE:
   3501         rv = phy_82764_gpio_value_get(pmc, port, value);
   3502         break;
   3503     /* FIRMWARE MODE */
   3504     case SOC_PHY_CONTROL_FIRMWARE_MODE:
   3505        rv = phy_82764_firmware_mode_get(pc, port, intf, value);
   3506        break;
   3507     case SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE:
   3508        rv = phy_82764_firmware_dfe_enable_get(pc, port, intf, value);
   3509        break;
   3510     case SOC_PHY_CONTROL_FIRMWARE_LP_DFE_ENABLE:
   3511        rv = phy_82764_firmware_lp_dfe_enable_get(pc, port, intf, value);
   3512        break;
   3513     case SOC_PHY_CONTROL_UNRELIABLE_LOS:
   3514         rv = phy_82764_unreliable_los_get(pc, port, intf, value);
   3515         break;
   3516        /*
   3517         * COVERITY
   3518         * This is unreachable. It is kept intentionally as a defensive
   3519         * default for future development.
   3520         */
   3521        /* coverity[dead_error_begin] */
   3522     default:
   3523        rv = SOC_E_UNAVAIL;
   3524        break;
   3525     }
   3526   }
   3527 
   3528     return rv;
   3529 }
   3530 
   3531 /*
   3532  * Function:
   3533  *      phy_82764_per_lane_control_get
   3534  * Purpose:
   3535  *      Configure PHY device specific control fucntion. 
   3536  * Parameters:
   3537  *      unit  - StrataSwitch unit #.
   3538  *      port  - StrataSwitch port #. 
   3539  *      lane  - lane number
   3540  *      type  - Control to update 
   3541  *      value - New setting for the control 
   3542  * Returns:     
   3543  *      SOC_E_NONE
   3544  */
   3545 STATIC int
   3546 phy_82764_per_lane_control_get(int unit, soc_port_t port, int lane,
   3547                      soc_phy_control_t type, uint32 *value)
   3548 {
   3549     int                 rv = SOC_E_UNAVAIL;
   3550     phy_ctrl_t          *pc;
   3551     soc_phymod_ctrl_t   *pmc;
   3552     int32 intf;
   3553 
   3554     /* locate phy control, phymod control, and the configuration data */
   3555     pc = EXT_PHY_SW_STATE(unit, port);
   3556     if (pc == NULL) {
   3557         return SOC_E_INTERNAL;
   3558     }
   3559     pmc = &pc->phymod_ctrl;
   3560 
   3561     PHY_CONTROL_TYPE_CHECK(type);
   3562 
   3563     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82764_SYS_SIDE : PHY82764_LINE_SIDE; 
   3564 
   3565     switch(type) {
   3566     /* RM PMD LOCK */
   3567     case SOC_PHY_CONTROL_RX_SEQ_DONE:
   3568         rv = phy_82764_per_lane_rx_seq_done_get(pmc, port, intf, lane, value);
   3569         break;
   3570     case SOC_PHY_CONTROL_PREEMPHASIS:
   3571         rv = phy_82764_per_lane_preemphasis_get(pmc, port, intf, lane, value);
   3572         break; 
   3573     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   3574         rv = phy_82764_per_lane_driver_current_get(pmc, port, intf, lane, value);
   3575         break;
   3576     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL:
   3577         rv = phy_82764_per_lane_prbs_tx_poly_get(pmc, port, intf, lane, value);
   3578         break;
   3579     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA:
   3580         rv = phy_82764_per_lane_prbs_tx_invert_data_get(pmc, port, intf, lane, value);
   3581         break;
   3582     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE:
   3583         rv = phy_82764_per_lane_prbs_tx_enable_get(pmc, port, intf, lane, value);
   3584         break;
   3585     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL:
   3586         rv = phy_82764_per_lane_prbs_rx_poly_get(pmc, port, intf, lane, value);
   3587         break;
   3588     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA:
   3589         rv = phy_82764_per_lane_prbs_rx_invert_data_get(pmc, port, intf, lane, value);
   3590         break;
   3591     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE:
   3592         rv = phy_82764_per_lane_prbs_rx_enable_get(pmc, port, intf, lane, value);
   3593         break;
   3594     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   3595         rv = phy_82764_per_lane_prbs_tx_poly_get(pmc, port, intf, lane, value);
   3596         rv = phy_82764_per_lane_prbs_rx_poly_get(pmc, port, intf, lane, value);
   3597         break;
   3598     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   3599         rv = phy_82764_per_lane_prbs_tx_invert_data_get(pmc, port, intf, lane, value);
   3600         break;
   3601     case SOC_PHY_CONTROL_PRBS_RX_INVERT_DATA:
   3602         rv = phy_82764_per_lane_prbs_rx_invert_data_get(pmc, port, intf, lane, value);
   3603         break;
   3604     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   3605         rv = phy_82764_per_lane_prbs_tx_enable_get(pmc, port, intf, lane, value);
   3606         rv = phy_82764_per_lane_prbs_rx_enable_get(pmc, port, intf, lane, value);
   3607         break;
   3608     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   3609         rv = phy_82764_per_lane_prbs_rx_enable_get(pmc, port, intf, lane, value);
   3610         rv = phy_82764_per_lane_prbs_tx_enable_get(pmc, port, intf, lane, value);
   3611         break;
   3612     case SOC_PHY_CONTROL_PRBS_RX_STATUS:
   3613         rv = phy_82764_per_lane_prbs_rx_status_get(pmc, port, intf, lane, value);
   3614         break;
   3615     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   3616         rv = phy_82764_per_lane_rx_peak_filter_get(pmc, port, intf, lane, value);
   3617         break;
   3618     case SOC_PHY_CONTROL_RX_VGA:
   3619         rv = phy_82764_per_lane_rx_vga_get(pmc, port, intf, lane, value);
   3620         break;
   3621     case SOC_PHY_CONTROL_RX_TAP1:
   3622         rv = phy_82764_per_lane_rx_dfe_tap_control_get(pmc, port, intf, lane, 0, value);
   3623         break;
   3624     case SOC_PHY_CONTROL_RX_TAP2:
   3625         rv = phy_82764_per_lane_rx_dfe_tap_control_get(pmc, port, intf, lane, 1, value);
   3626         break;
   3627     case SOC_PHY_CONTROL_RX_TAP3:
   3628         rv = phy_82764_per_lane_rx_dfe_tap_control_get(pmc, port, intf, lane, 2, value);
   3629         break;
   3630     case SOC_PHY_CONTROL_RX_TAP4:
   3631         rv = phy_82764_per_lane_rx_dfe_tap_control_get(pmc, port, intf, lane, 3, value);
   3632         break;
   3633     case SOC_PHY_CONTROL_RX_TAP5:
   3634         rv = phy_82764_per_lane_rx_dfe_tap_control_get(pmc, port, intf, lane, 4, value);
   3635         break;
   3636     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   3637         rv = phy_82764_per_lane_rx_low_freq_filter_get(pmc, port, intf, lane, value);
   3638         break;
   3639     /* LOOPBACK */
   3640     case SOC_PHY_CONTROL_LOOPBACK_REMOTE:
   3641     case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS:
   3642        rv = phy_82764_per_lane_loopback_remote_get(pmc, port, intf, lane, value);
   3643        break;
   3644     case SOC_PHY_CONTROL_LOOPBACK_PMD:
   3645        rv = phy_82764_per_lane_loopback_internal_pmd_get(pmc, port, intf, lane, value);
   3646        break;
   3647     case SOC_PHY_CONTROL_RX_POLARITY:
   3648         rv = phy_82764_per_lane_rx_polarity_get(pmc, port, intf, lane, value);
   3649         break;
   3650     case SOC_PHY_CONTROL_TX_POLARITY:
   3651         rv = phy_82764_per_lane_tx_polarity_get(pmc, port, intf, lane, value);
   3652         break;
   3653     /* POWER */
   3654     case SOC_PHY_CONTROL_POWER:
   3655        rv = phy_82764_per_lane_power_get(pmc, port, intf, lane, value);
   3656        break;
   3657     case SOC_PHY_CONTROL_TX_FIR_PRE:
   3658     case SOC_PHY_CONTROL_TX_FIR_MAIN:
   3659     case SOC_PHY_CONTROL_TX_FIR_POST:
   3660     case SOC_PHY_CONTROL_TX_FIR_POST2:
   3661     case SOC_PHY_CONTROL_TX_FIR_POST3:
   3662         rv = phy_82764_per_lane_tx_get(pmc, port, intf, type, lane, value);
   3663         break;
   3664     case SOC_PHY_CONTROL_TX_LANE_SQUELCH:
   3665         rv = phy_82764_per_lane_tx_lane_squelch_get(pmc, port, intf, lane, value);
   3666         break;
   3667     case SOC_PHY_CONTROL_CL72:
   3668         rv = phy_82764_per_lane_cl72_enable_get(pmc, port, intf, lane, value);
   3669     break;
   3670     case SOC_PHY_CONTROL_CL72_STATUS:
   3671         rv = phy_82764_per_lane_cl72_status_get(pmc, port, intf, lane,  value);
   3672     break;
   3673     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE:
   3674         rv = phy_82764_per_lane_short_chn_mode_enable_get(pmc, port, intf, lane, value);
   3675     break;
   3676     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE_STATUS:
   3677         rv = phy_82764_per_lane_short_chn_mode_status_get(pmc, port, intf, lane, value);
   3678     break;
   3679     case SOC_PHY_CONTROL_EYE_VAL_HZ_L:
   3680         rv=phy_82764_per_lane_eye_margin_est_get(pmc,port,intf,lane, phymod_eye_marign_HZ_L, value);
   3681         break ;
   3682     case SOC_PHY_CONTROL_EYE_VAL_HZ_R:
   3683         rv=phy_82764_per_lane_eye_margin_est_get(pmc,port,intf,lane, phymod_eye_marign_HZ_R, value);
   3684         break ;
   3685     case SOC_PHY_CONTROL_EYE_VAL_VT_D:
   3686         rv=phy_82764_per_lane_eye_margin_est_get(pmc,port,intf,lane, phymod_eye_marign_VT_D, value);
   3687         break ;
   3688     case SOC_PHY_CONTROL_EYE_VAL_VT_U:
   3689         rv=phy_82764_per_lane_eye_margin_est_get(pmc,port,intf,lane, phymod_eye_marign_VT_U, value);
   3690         break ;
   3691     default:
   3692         rv = SOC_E_UNAVAIL;
   3693         break; 
   3694     }
   3695 
   3696     return rv;
   3697 }
   3698 
   3699 /*
   3700  * Function:
   3701  *      phy82764_duplex_get
   3702  * Purpose:
   3703  *      Get PHY duplex mode
   3704  * Parameters:
   3705  *      unit - BCM unit number.
   3706  *      port - Port number. 
   3707  *      duplex - current duplex mode
   3708  * Returns:     
   3709  *      SOC_E_NONE
   3710  */
   3711 STATIC int
   3712 phy82764_duplex_get(int unit, soc_port_t port, int *duplex)
   3713 {
   3714     *duplex = TRUE;
   3715     return SOC_E_NONE;
   3716 }
   3717 
   3718 /*
   3719  * Function:    
   3720  *      phy_82764_an_set
   3721  * Purpose:     
   3722  *      Enable or disable auto-negotiation on the specified port.
   3723  * Parameters:
   3724  *      unit - BCM unit number.
   3725  *      port - Port number. 
   3726  *      an   - Boolean, if true, auto-negotiation is enabled 
   3727  *              (and/or restarted). If false, autonegotiation is disabled.
   3728  * Returns:     
   3729  *      SOC_E_XXX  _soc_triumph_tx
   3730  */
   3731 STATIC int
   3732 phy_82764_an_set(int unit, soc_port_t port, int enable)
   3733 {
   3734     phy_ctrl_t                *pc;
   3735     soc_phymod_ctrl_t         *pmc;
   3736     soc_phymod_phy_t          *phy;
   3737     phymod_autoneg_control_t  an;
   3738     soc_info_t *si;
   3739 
   3740     /* locate phy control */
   3741     pc = EXT_PHY_SW_STATE(unit, port);
   3742     if (pc == NULL) {
   3743         return SOC_E_INTERNAL;
   3744     }
   3745 
   3746     phymod_autoneg_control_t_init(&an);
   3747     pmc = &pc->phymod_ctrl;
   3748     si = &SOC_INFO(unit);
   3749 
   3750     /* only request autoneg on the first core */
   3751     phy = pmc->phy[pmc->main_phy];
   3752     if (phy == NULL) {
   3753         return SOC_E_INTERNAL;
   3754     }
   3755     an.enable = enable;
   3756     an.num_lane_adv = si->port_num_lanes[port];
   3757     an.an_mode = phymod_AN_MODE_CL73;
   3758     SOC_IF_ERROR_RETURN
   3759         (phymod_phy_autoneg_set(&phy->pm_phy, &an));
   3760 
   3761     return (SOC_E_NONE);
   3762 }
   3763 /*
   3764  * Function:    
   3765  *      phy_82764_an_get
   3766  * Purpose:     
   3767  *      Get the current auto-negotiation status (enabled/busy)
   3768  * Parameters:
   3769  *      unit - BCM unit number.
   3770  *      port - Port number. 
   3771  *      an   - (OUT) if true, auto-negotiation is enabled.
   3772  *      an_done - (OUT) if true, auto-negotiation is complete. This
   3773  *              value is undefined if an == false.
   3774  * Returns:     
   3775  *      SOC_E_XXX
   3776  */
   3777 
   3778 STATIC int
   3779 phy_82764_an_get(int unit, soc_port_t port, int *an, int *an_done)
   3780 {
   3781     phy_ctrl_t* pc;
   3782     soc_phymod_ctrl_t *pmc;
   3783     phymod_phy_access_t *pm_phy;
   3784     phymod_autoneg_control_t an_control;
   3785     int idx, an_complete;
   3786 
   3787     *an = 0;
   3788     *an_done = 0;
   3789 
   3790     pc = EXT_PHY_SW_STATE(unit, port);
   3791     pmc = &pc->phymod_ctrl;
   3792 
   3793     sal_memset(&an_control, 0x0, sizeof(an_control));
   3794 
   3795     idx = pmc->main_phy;
   3796     pm_phy = &pmc->phy[idx]->pm_phy;
   3797 
   3798     SOC_IF_ERROR_RETURN
   3799         (phymod_phy_autoneg_get(pm_phy, &an_control, (uint32_t *) &an_complete));
   3800 
   3801     if (an_control.enable) {
   3802         *an = 1;
   3803         *an_done = an_complete;
   3804 #ifdef PHY82764_DEBUG
   3805         LOG_CLI((BSL_META_U(unit,"AN complete:%d\n "),*an_done));
   3806 #endif
   3807     } else {
   3808         *an = 0;
   3809         *an_done = 0;
   3810     }
   3811 
   3812     return SOC_E_NONE;
   3813 }
   3814 /*
   3815  * Function:
   3816  *      phy_82764_ability_advert_set
   3817  * Purpose:
   3818  *      Set the current advertisement for auto-negotiation.
   3819  * Parameters:
   3820  *      unit - BCM unit number.
   3821  *      port - Port number.
   3822  *      ability - Port mode mask indicating supported options/speeds.
   3823  * Returns:
   3824  *      SOC_E_XXX
   3825  * Notes:
   3826  *      The advertisement is set only for the ACTIVE medium.
   3827  *      No synchronization performed at this level.
   3828  */
   3829 
   3830 STATIC int
   3831 phy_82764_ability_advert_set(int unit, soc_port_t port,
   3832                           soc_port_ability_t *ability)
   3833 {
   3834     phy_ctrl_t                *pc;
   3835     soc_phymod_ctrl_t         *pmc;
   3836     soc_phymod_phy_t          *phy;
   3837     soc_port_if_t             line_interface;
   3838     int                       an = 0, an_done = 0;
   3839     uint8_t                   an_enabled = 0;
   3840     uint32_t                  an_tech_ability;
   3841     uint32_t                  an_bam37_ability;
   3842     uint32_t                  an_bam73_ability;
   3843     _shr_port_mode_t          speed_full_duplex;
   3844     phymod_autoneg_ability_t  phymod_autoneg_ability;
   3845 
   3846     /* locate phy control */
   3847     pc = EXT_PHY_SW_STATE(unit, port);
   3848     if (pc == NULL) {
   3849         return SOC_E_INTERNAL;
   3850     }
   3851 
   3852     phymod_autoneg_ability_t_init(&phymod_autoneg_ability);
   3853 
   3854     pmc = &pc->phymod_ctrl;
   3855 
   3856     /* only set abilities on the first core */
   3857     phy = pmc->phy[pmc->main_phy];
   3858     if (phy == NULL) {
   3859         return SOC_E_INTERNAL;
   3860     }
   3861 
   3862     an_tech_ability  = 0;
   3863     an_bam37_ability = 0;
   3864     an_bam73_ability = 0;
   3865     speed_full_duplex = ability->speed_full_duplex;
   3866     line_interface = ability->interface;
   3867 
   3868     /* if ability->interface is NULL, get the configured interface */
   3869     if (!line_interface) {
   3870         SOC_IF_ERROR_RETURN(phy82764_interface_get(unit, port, &line_interface));
   3871     }
   3872     /* When ability_advert_set called disable AN and set the ability */
   3873     SOC_IF_ERROR_RETURN(phy_82764_an_get(unit, port, &an, &an_done));
   3874     if (an) {
   3875         SOC_IF_ERROR_RETURN(phy_82764_an_set(unit, port, FALSE));
   3876         an_enabled = 1;
   3877     }
   3878 
   3879     if (speed_full_duplex & SOC_PA_SPEED_40GB) {
   3880         if (line_interface == SOC_PORT_IF_KR4) {
   3881             PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
   3882         } else {
   3883             PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability);
   3884         }
   3885     } else if(speed_full_duplex & SOC_PA_SPEED_100GB) {
   3886         if (line_interface == SOC_PORT_IF_KR4) {
   3887             PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
   3888         } else {
   3889             PHYMOD_AN_CAP_100G_CR4_SET(an_tech_ability);
   3890         }
   3891     } else if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   3892         PHYMOD_AN_CAP_10G_KR_SET(an_tech_ability);
   3893     } else {
   3894         an_tech_ability = 0;
   3895     }
   3896 
   3897     phymod_autoneg_ability.an_cap = an_tech_ability;
   3898     phymod_autoneg_ability.cl73bam_cap = an_bam73_ability;
   3899     phymod_autoneg_ability.cl37bam_cap = an_bam37_ability;
   3900 #ifdef PHY82764_DEBUG
   3901     LOG_CLI((BSL_META_U(unit,"AN:abilitySet =%x tech ability:%x pause:%d\n"), speed_full_duplex, an_tech_ability,ability->pause));
   3902 #endif
   3903     switch (ability->pause & (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX)) {
   3904         case SOC_PA_PAUSE_TX:
   3905             PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability);
   3906         break;
   3907         case SOC_PA_PAUSE_RX:
   3908             /* an_adv |= MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; */
   3909             PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability);
   3910             PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability);
   3911         break;
   3912         case SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX:
   3913             PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability);
   3914         break;
   3915     }
   3916 
   3917     
   3918     phymod_autoneg_ability.an_master_lane = soc_property_port_get(unit, port,
   3919                                                 "phy_autoneg_master_lane",
   3920                                                 phymod_autoneg_ability.an_master_lane);
   3921     phymod_autoneg_ability.sgmii_speed = 2;
   3922     phymod_autoneg_ability.an_cl72 = soc_property_port_get(unit, port, spn_PHY_AN_C72, TRUE);
   3923 
   3924     SOC_IF_ERROR_RETURN
   3925         (phymod_phy_autoneg_ability_set(&phy->pm_phy, &phymod_autoneg_ability));
   3926 
   3927     /* Enable the AN after ability set */
   3928     if (an_enabled) {
   3929         SOC_IF_ERROR_RETURN(phy_82764_an_set(unit, port, TRUE));
   3930     }
   3931 
   3932     return SOC_E_NONE;
   3933 }
   3934 
   3935 /*
   3936  * Function:
   3937  *      phy_82764_ability_advert_get
   3938  * Purpose:
   3939  *      Get the current advertisement for auto-negotiation.
   3940  * Parameters:
   3941  *      unit - BCM unit number.
   3942  *      port - Port number.
   3943  *      ability - (OUT) Port mode mask indicating supported options/speeds.
   3944  * Returns:
   3945  *      SOC_E_XXX
   3946  * Notes:
   3947  *      The advertisement is retrieved for the ACTIVE medium.
   3948  *      No synchronization performed at this level.
   3949  */
   3950 
   3951 STATIC int
   3952 phy_82764_ability_advert_get(int unit, soc_port_t port,
   3953                               soc_port_ability_t *ability)
   3954 {
   3955     phy_ctrl_t                *pc;
   3956     soc_phymod_ctrl_t         *pmc;
   3957     soc_phymod_phy_t          *phy;
   3958     int                       reg73_ability;
   3959     int                       reg_ability;
   3960     _shr_port_mode_t          speed_full_duplex;
   3961     phymod_autoneg_ability_t  phymod_autoneg_ability;
   3962 
   3963     /* locate phy control */
   3964     pc = EXT_PHY_SW_STATE(unit, port);
   3965     if (pc == NULL) {
   3966         return SOC_E_INTERNAL;
   3967     }
   3968 
   3969     pmc = &pc->phymod_ctrl;
   3970 
   3971     /* only get abilities from the first core */
   3972     phy = pmc->phy[0];
   3973     if (phy == NULL) {
   3974         return SOC_E_INTERNAL;
   3975     }
   3976 
   3977     phymod_autoneg_ability_t_init(&phymod_autoneg_ability);
   3978 
   3979     SOC_IF_ERROR_RETURN
   3980         (phymod_phy_autoneg_ability_get(&phy->pm_phy, &phymod_autoneg_ability));
   3981 
   3982 
   3983     speed_full_duplex = 0;
   3984 
   3985     /* retrieve CL73 abilities */
   3986     reg73_ability = phymod_autoneg_ability.an_cap;
   3987     speed_full_duplex |= PHYMOD_AN_CAP_100G_CR4_GET(reg73_ability) ? SOC_PA_SPEED_100GB : 0;
   3988     speed_full_duplex |= PHYMOD_AN_CAP_100G_KR4_GET(reg73_ability) ? SOC_PA_SPEED_100GB : 0;
   3989     speed_full_duplex |= PHYMOD_AN_CAP_40G_CR4_GET(reg73_ability) ? SOC_PA_SPEED_40GB : 0;
   3990     speed_full_duplex |= PHYMOD_AN_CAP_40G_KR4_GET(reg73_ability) ? SOC_PA_SPEED_40GB : 0;
   3991     speed_full_duplex |= PHYMOD_AN_CAP_10G_KR_GET (reg73_ability)  ? SOC_PA_SPEED_10GB : 0;
   3992 
   3993     if (speed_full_duplex & SOC_PA_SPEED_100GB) {
   3994         if (PHYMOD_AN_CAP_100G_CR4_GET(reg73_ability)) {
   3995             ability->interface = SOC_PORT_IF_CR4;
   3996         } else {
   3997             ability->interface = SOC_PORT_IF_KR4;
   3998         }
   3999     } else if (speed_full_duplex & SOC_PA_SPEED_40GB) {
   4000         if (PHYMOD_AN_CAP_40G_CR4_GET(reg73_ability)) {
   4001             ability->interface = SOC_PORT_IF_CR4;
   4002         } else {
   4003             ability->interface = SOC_PORT_IF_KR4;
   4004         }
   4005     } else if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   4006         ability->interface = SOC_PORT_IF_KR;
   4007     } else {
   4008         ability->interface = 0;
   4009     }
   4010 
   4011 
   4012     /* retrieve "pause" abilities */
   4013     reg_ability = phymod_autoneg_ability.capabilities;
   4014 
   4015     ability->pause = 0;
   4016     if (reg_ability == PHYMOD_AN_CAP_ASYM_PAUSE) {
   4017         ability->pause = SOC_PA_PAUSE_TX;
   4018     } else if (reg_ability == (PHYMOD_AN_CAP_SYMM_PAUSE | PHYMOD_AN_CAP_ASYM_PAUSE)) {
   4019         ability->pause = SOC_PA_PAUSE_RX;
   4020     } else if (reg_ability == PHYMOD_AN_CAP_SYMM_PAUSE) {
   4021         ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX);
   4022     }
   4023 
   4024     ability->speed_full_duplex = speed_full_duplex;
   4025 
   4026     return SOC_E_NONE;
   4027 }
   4028 
   4029 /*
   4030  * Function:
   4031  *      phy82764_lb_get
   4032  * Purpose:
   4033  *      Get current PHY loopback mode
   4034  * Parameters:
   4035  *      unit - BCM unit number.
   4036  *      port - Port number. 
   4037  *      enable - address of location to store binary value for on/off (1/0)
   4038  * Returns:     
   4039  *      SOC_E_NONE
   4040  */
   4041 STATIC int
   4042 phy82764_lb_get(int unit, soc_port_t port, int *enable)
   4043 {
   4044     phy_ctrl_t* pc; 
   4045     soc_phymod_ctrl_t *pmc;
   4046     uint32 out_en;
   4047 
   4048     pc = EXT_PHY_SW_STATE(unit, port);
   4049     pmc = &pc->phymod_ctrl;
   4050     SOC_IF_ERROR_RETURN(
   4051         phy_82764_loopback_internal_pmd_get(pmc, port, PHY82764_LINE_SIDE, &out_en));
   4052     *enable = (int) out_en;
   4053 
   4054     return SOC_E_NONE;
   4055 }
   4056 
   4057 /* 
   4058  * phy_82764_per_lane_loopback_internal_pmd_set
   4059  */
   4060 STATIC int 
   4061 phy_82764_per_lane_loopback_internal_pmd_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4062 {
   4063     phymod_phy_access_t  *pm_phy;
   4064     uint32              lane_map;
   4065     phymod_phy_access_t pm_phy_copy;
   4066     soc_phymod_phy_t    *p_phy;
   4067 
   4068     /* locate the desired phy and lane */
   4069     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4070 
   4071     /* Make a copy of the phy access and overwrite the desired lane */
   4072     pm_phy = &p_phy->pm_phy;
   4073     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4074     pm_phy_copy.access.lane_mask = lane_map;
   4075     pm_phy_copy.port_loc = phymodPortLocLine;
   4076     if(intf == PHY82764_SYS_SIDE) {
   4077         pm_phy_copy.port_loc = phymodPortLocSys;
   4078     } 
   4079 
   4080     SOC_IF_ERROR_RETURN
   4081         (phymod_phy_loopback_set(&pm_phy_copy, phymodLoopbackGlobalPMD, value));
   4082 
   4083     return(SOC_E_NONE);
   4084 }
   4085 
   4086 /* 
   4087  * phy_82764_loopback_internal_pmd_set
   4088  */
   4089 STATIC int 
   4090 phy_82764_loopback_internal_pmd_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   4091 {
   4092     phymod_phy_access_t  *pm_phy;
   4093     int                    idx;
   4094     phymod_phy_access_t pm_phy_copy;
   4095 
   4096     for (idx = 0; idx < pmc->num_phys; idx++) {
   4097         if (pmc->phy[idx] == NULL) {
   4098             return SOC_E_INTERNAL;
   4099         }
   4100         pm_phy = &pmc->phy[idx]->pm_phy;
   4101         if (pm_phy == NULL) {
   4102             return SOC_E_INTERNAL;
   4103         }
   4104 
   4105         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4106         pm_phy_copy.port_loc = phymodPortLocLine;
   4107         if(intf == PHY82764_SYS_SIDE) {
   4108             pm_phy_copy.port_loc = phymodPortLocSys;
   4109             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   4110         } 
   4111 
   4112         SOC_IF_ERROR_RETURN
   4113             (phymod_phy_loopback_set(&pm_phy_copy, phymodLoopbackGlobalPMD, value));
   4114     }
   4115 
   4116     return(SOC_E_NONE);
   4117 }
   4118 
   4119 /* 
   4120  * phy_82764_per_lane_loopback_remote_set
   4121  */
   4122 STATIC int 
   4123 phy_82764_per_lane_loopback_remote_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4124 {
   4125     phymod_phy_access_t  *pm_phy;
   4126     uint32              lane_map;
   4127     phymod_phy_access_t pm_phy_copy;
   4128     soc_phymod_phy_t    *p_phy;
   4129 
   4130     /* locate the desired phy and lane */
   4131     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4132 
   4133     /* Make a copy of the phy access and overwrite the desired lane */
   4134     pm_phy = &p_phy->pm_phy;
   4135     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4136     pm_phy_copy.access.lane_mask = lane_map;
   4137     pm_phy_copy.port_loc = phymodPortLocLine;
   4138     if(intf == PHY82764_SYS_SIDE) {
   4139         pm_phy_copy.port_loc = phymodPortLocSys;
   4140     } 
   4141 
   4142     SOC_IF_ERROR_RETURN
   4143         (phymod_phy_loopback_set(&pm_phy_copy, phymodLoopbackRemotePMD, value));
   4144 
   4145     return(SOC_E_NONE);
   4146 }
   4147 
   4148 /* 
   4149  * phy_82764_fec_enable_set
   4150  */
   4151 STATIC int 
   4152 phy_82764_fec_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   4153 {
   4154     phymod_phy_access_t  *pm_phy;
   4155     int                    idx;
   4156     phymod_phy_access_t pm_phy_copy;
   4157 
   4158     for (idx = 0; idx < pmc->num_phys; idx++) {
   4159         if (pmc->phy[idx] == NULL) {
   4160             return SOC_E_INTERNAL;
   4161         }
   4162         pm_phy = &pmc->phy[idx]->pm_phy;
   4163         if (pm_phy == NULL) {
   4164             return SOC_E_INTERNAL;
   4165         }
   4166         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4167         pm_phy_copy.port_loc = phymodPortLocLine;
   4168         if(intf == PHY82764_SYS_SIDE) {
   4169             pm_phy_copy.port_loc = phymodPortLocSys;
   4170             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   4171         }
   4172 
   4173         SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_set(&pm_phy_copy, value));
   4174     }
   4175 
   4176     return(SOC_E_NONE);
   4177 }
   4178 
   4179 STATIC int
   4180 phy_82764_sdk_poly_to_phymod_poly(uint32 sdk_poly, phymod_prbs_poly_t *phymod_poly){
   4181     switch(sdk_poly){
   4182     case SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1:
   4183         *phymod_poly = phymodPrbsPoly7;
   4184         break;
   4185     case SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1:
   4186         *phymod_poly = phymodPrbsPoly15;
   4187         break;
   4188     case SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1:
   4189         *phymod_poly = phymodPrbsPoly23;
   4190         break;
   4191     case SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1:
   4192         *phymod_poly = phymodPrbsPoly31;
   4193         break;
   4194     case SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1:
   4195         *phymod_poly = phymodPrbsPoly9;
   4196         break;
   4197     case SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1:
   4198         *phymod_poly = phymodPrbsPoly11;
   4199         break;
   4200     case SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1:
   4201         *phymod_poly = phymodPrbsPoly58;
   4202         break;
   4203     default:
   4204         return SOC_E_INTERNAL;
   4205     }
   4206 
   4207     return SOC_E_NONE;
   4208 }
   4209 /* 
   4210  * phy_82764_per_lane_prbs_tx_poly_set
   4211  */
   4212 STATIC int
   4213 phy_82764_per_lane_prbs_tx_poly_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4214 {
   4215     phymod_phy_access_t  *pm_phy;
   4216     phymod_prbs_t        prbs;
   4217     uint32_t flags = 0;
   4218     uint32              lane_map;
   4219     phymod_phy_access_t pm_phy_copy;
   4220     soc_phymod_phy_t    *p_phy;
   4221 
   4222     /* locate the desired phy and lane */
   4223     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4224 
   4225     /* Make a copy of the phy access and overwrite the desired lane */
   4226     pm_phy = &p_phy->pm_phy;
   4227     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4228     pm_phy_copy.access.lane_mask = lane_map;
   4229     pm_phy_copy.port_loc = phymodPortLocLine;
   4230     if(intf == PHY82764_SYS_SIDE) {
   4231         pm_phy_copy.port_loc = phymodPortLocSys;
   4232     } 
   4233     
   4234     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   4235     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy,  flags, &prbs));
   4236     SOC_IF_ERROR_RETURN(phy_82764_sdk_poly_to_phymod_poly(value, &prbs.poly));
   4237     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   4238 
   4239     return(SOC_E_NONE);
   4240 }
   4241 /* 
   4242  * phy_82764_per_lane_prbs_rx_poly_set
   4243  */
   4244 STATIC int
   4245 phy_82764_per_lane_prbs_rx_poly_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4246 {
   4247     phymod_phy_access_t  *pm_phy;
   4248     phymod_prbs_t        prbs;
   4249     uint32_t flags = 0;
   4250     uint32              lane_map;
   4251     phymod_phy_access_t pm_phy_copy;
   4252     soc_phymod_phy_t    *p_phy;
   4253 
   4254     /* locate the desired phy and lane */
   4255     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4256 
   4257     /* Make a copy of the phy access and overwrite the desired lane */
   4258     pm_phy = &p_phy->pm_phy;
   4259     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4260     pm_phy_copy.access.lane_mask = lane_map;
   4261     pm_phy_copy.port_loc = phymodPortLocLine;
   4262     if(intf == PHY82764_SYS_SIDE) {
   4263         pm_phy_copy.port_loc = phymodPortLocSys;
   4264     } 
   4265 
   4266     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   4267     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   4268     SOC_IF_ERROR_RETURN(phy_82764_sdk_poly_to_phymod_poly(value, &prbs.poly));
   4269     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   4270 
   4271     return(SOC_E_NONE);
   4272 }
   4273 
   4274 /* 
   4275  * phy_82764_per_lane_prbs_tx_invert_data_set
   4276  */
   4277 STATIC int
   4278 phy_82764_per_lane_prbs_tx_invert_data_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4279 {
   4280     phymod_phy_access_t  *pm_phy;
   4281     phymod_prbs_t        prbs;
   4282     uint32_t flags = 0;
   4283     
   4284     uint32              lane_map;
   4285     phymod_phy_access_t pm_phy_copy;
   4286     soc_phymod_phy_t    *p_phy;
   4287 
   4288     /* locate the desired phy and lane */
   4289     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4290 
   4291     /* Make a copy of the phy access and overwrite the desired lane */
   4292     pm_phy = &p_phy->pm_phy;
   4293     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4294     pm_phy_copy.access.lane_mask = lane_map;
   4295     pm_phy_copy.port_loc = phymodPortLocLine;
   4296     if(intf == PHY82764_SYS_SIDE) {
   4297         pm_phy_copy.port_loc = phymodPortLocSys;
   4298     } 
   4299     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   4300     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   4301     prbs.invert = value;
   4302     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags,  &prbs));
   4303 
   4304     return(SOC_E_NONE);
   4305 }
   4306 
   4307 /* 
   4308  * phy_82764_per_lane_prbs_rx_invert_data_set
   4309  */
   4310 STATIC int
   4311 phy_82764_per_lane_prbs_rx_invert_data_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4312 {
   4313     phymod_phy_access_t  *pm_phy;
   4314     phymod_prbs_t        prbs;
   4315     uint32_t flags = 0;
   4316     uint32              lane_map;
   4317     phymod_phy_access_t pm_phy_copy;
   4318     soc_phymod_phy_t    *p_phy;
   4319 
   4320     /* locate the desired phy and lane */
   4321     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4322 
   4323     /* Make a copy of the phy access and overwrite the desired lane */
   4324     pm_phy = &p_phy->pm_phy;
   4325     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4326     pm_phy_copy.access.lane_mask = lane_map;
   4327     pm_phy_copy.port_loc = phymodPortLocLine;
   4328     if(intf == PHY82764_SYS_SIDE) {
   4329         pm_phy_copy.port_loc = phymodPortLocSys;
   4330     } 
   4331 
   4332     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   4333     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags,  &prbs));
   4334     prbs.invert = value;
   4335     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   4336 
   4337     return(SOC_E_NONE);
   4338 }
   4339 
   4340 /* 
   4341  * phy_82764_per_lane_prbs_tx_enable_set
   4342  */
   4343 STATIC int
   4344 phy_82764_per_lane_prbs_tx_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4345 {
   4346     phymod_phy_access_t  *pm_phy;
   4347     uint32_t flags = 0;
   4348     uint32              lane_map;
   4349     phymod_phy_access_t pm_phy_copy;
   4350     soc_phymod_phy_t    *p_phy;
   4351 
   4352     /* locate the desired phy and lane */
   4353     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4354 
   4355     /* Make a copy of the phy access and overwrite the desired lane */
   4356     pm_phy = &p_phy->pm_phy;
   4357     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4358     pm_phy_copy.access.lane_mask = lane_map;
   4359     pm_phy_copy.port_loc = phymodPortLocLine;
   4360     if(intf == PHY82764_SYS_SIDE) {
   4361         pm_phy_copy.port_loc = phymodPortLocSys;
   4362     } 
   4363 
   4364     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   4365     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(&pm_phy_copy, flags, value));
   4366 
   4367     return(SOC_E_NONE);
   4368 }
   4369 
   4370 /* 
   4371  * phy_82764_per_lane_prbs_rx_enable_set
   4372  */
   4373 STATIC int
   4374 phy_82764_per_lane_prbs_rx_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4375 {
   4376     phymod_phy_access_t  *pm_phy;
   4377     uint32_t flags = 0;
   4378 
   4379     uint32              lane_map;
   4380     phymod_phy_access_t pm_phy_copy;
   4381     soc_phymod_phy_t    *p_phy;
   4382 
   4383     /* locate the desired phy and lane */
   4384     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4385 
   4386     /* Make a copy of the phy access and overwrite the desired lane */
   4387     pm_phy = &p_phy->pm_phy;
   4388     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4389     pm_phy_copy.access.lane_mask = lane_map;
   4390     pm_phy_copy.port_loc = phymodPortLocLine;
   4391     if(intf == PHY82764_SYS_SIDE) {
   4392         pm_phy_copy.port_loc = phymodPortLocSys;
   4393     } 
   4394     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   4395     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(&pm_phy_copy, flags,  value));
   4396 
   4397     return(SOC_E_NONE);
   4398 }
   4399 
   4400 /* 
   4401  * given a pc (phymod_ctrl_t) and logical lane number, 
   4402  *    find the correct soc_phymod_phy_t object and lane
   4403  */
   4404 STATIC int
   4405 _phy_82764_find_soc_phy_lane(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32_t lane, 
   4406                              soc_phymod_phy_t **p_phy, uint32 *lane_map)
   4407 {
   4408     phy82764_config_t   *pCfg;
   4409     phy_ctrl_t          *pc;
   4410     uint32_t            intf;
   4411     int                 idx, found = 0;
   4412     char                *lane_swap = NULL;
   4413     phy82764_device_cfg_aux_mode_t *device_cfg_aux_modes;
   4414 
   4415     /* locate phy control, phymod control, and the configuration data */
   4416     pc = EXT_PHY_SW_STATE(pmc->unit, port);
   4417     if (pc == NULL) {
   4418         return SOC_E_INTERNAL;
   4419     }
   4420 
   4421     pCfg = (phy82764_config_t *) pc->driver_data;
   4422     device_cfg_aux_modes = &(pCfg->device_cfg_aux_modes);
   4423     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82764_SYS_SIDE : PHY82764_LINE_SIDE;
   4424 
   4425     if (intf == PHY82764_LINE_SIDE) {
   4426         lane_swap = (soc_property_port_get_str(pmc->unit, port, spn_PHY_XSW_LANE_MAP));
   4427         if (lane_swap != NULL) {
   4428             lane = my_ctoi(lane_swap, lane);
   4429         }
   4430     }
   4431 
   4432     /* Traverse lanes belonging to this port */
   4433     for (idx = 0; idx < pmc->num_phys; idx++) {
   4434         if(intf == PHY82764_SYS_SIDE) {
   4435             switch (pc->speed_max) {    
   4436                 case PHY82764_SPD_100G:
   4437                 case PHY82764_SPD_106G:
   4438                     if (lane > 3) {
   4439                         return SOC_E_CONFIG;
   4440                     }
   4441                     *lane_map = 0x1 << lane;
   4442                     found = 1;
   4443                 break;
   4444                 case PHY82764_SPD_40G: 
   4445                 case PHY82764_SPD_42G:
   4446                     if ((!device_cfg_aux_modes->gearbox_enable) ||
   4447                         (device_cfg_aux_modes->pin_compatibility_enable)) {
   4448                         if (lane > 3) {
   4449                             return SOC_E_CONFIG;
   4450                         }
   4451                         *lane_map = 0x1 << lane; 
   4452                         found = 1;
   4453                     } else {
   4454                         if (lane > 1) {
   4455                             return SOC_E_CONFIG;
   4456                         }
   4457                         if (pc->lane_num > 1) {   
   4458                             *lane_map = 0x4 << lane;      
   4459                             found = 1;
   4460                         } else {
   4461                             *lane_map = 0x1 << lane;
   4462                             found = 1;
   4463                         }
   4464                     }
   4465                 break;
   4466                 case PHY82764_SPD_20G:
   4467                 case PHY82764_SPD_21G:
   4468                     if (!device_cfg_aux_modes->gearbox_enable) {
   4469                         if (lane > 1) {
   4470                             return SOC_E_CONFIG;
   4471                         }
   4472                         if (pc->lane_num > 1) {
   4473                             *lane_map = 0x4 << lane;
   4474                             found = 1;
   4475                         } else {
   4476                             *lane_map = 0x1 << lane;
   4477                             found = 1;
   4478                         }
   4479                     } else {
   4480                         if (lane > 0) {
   4481                             return SOC_E_CONFIG;
   4482                         }
   4483                         if (pc->lane_num > 0) {
   4484                             *lane_map = 0x4;
   4485                             found = 1;
   4486                         } else {
   4487                             *lane_map = 0x1;
   4488                             found = 1;
   4489                         }
   4490                     }
   4491                 break;
   4492                 case PHY82764_SPD_1G:
   4493                 case PHY82764_SPD_10G:
   4494                 case PHY82764_SPD_11G:
   4495                     if (lane > 0) {
   4496                         return SOC_E_CONFIG;
   4497                     }
   4498                     *lane_map = 0x1 << pc->lane_num;
   4499                     found = 1;
   4500                 break;
   4501                 default:
   4502                     return SOC_E_CONFIG;
   4503                    
   4504             }
   4505         } else {
   4506             switch (pc->speed_max) {    
   4507                 case PHY82764_SPD_100G:
   4508                 case PHY82764_SPD_106G:
   4509                     if (lane > 9) {
   4510                         return SOC_E_CONFIG;
   4511                     }
   4512                     *lane_map = 0x1 << lane;
   4513                     found = 1;
   4514                 break;
   4515                 case PHY82764_SPD_40G: 
   4516                 case PHY82764_SPD_42G:
   4517                     if (lane > 3) {
   4518                         return SOC_E_CONFIG;
   4519                     }
   4520                     if ((!device_cfg_aux_modes->gearbox_enable) &&
   4521                         (!device_cfg_aux_modes->pin_compatibility_enable)) {
   4522                         if (lane > 1) {
   4523                             *lane_map = 0x10 << (lane - 2);
   4524                             found = 1;
   4525                         } else {
   4526                             *lane_map = 0x1 << lane; 
   4527                             found = 1;
   4528                         }
   4529                     } else if (device_cfg_aux_modes->pin_compatibility_enable) {
   4530                         *lane_map = 0x1 << lane;   
   4531                         found = 1;
   4532                     } else {
   4533                         if (pc->lane_num > 1) {
   4534                             *lane_map = 0x10 << lane;
   4535                             found = 1;
   4536                         } else {
   4537                             *lane_map = 0x1 << lane;
   4538                             found = 1;
   4539                         }
   4540                     }     
   4541                 break;
   4542                 case PHY82764_SPD_20G:
   4543                 case PHY82764_SPD_21G:
   4544                     if (!device_cfg_aux_modes->gearbox_enable) {
   4545                         if (pc->lane_num > 1) {
   4546                             *lane_map = 0x10 << ((lane_swap != NULL) ? (lane - 2) : lane);
   4547                             found = 1;
   4548                         } else {
   4549                             *lane_map = 0x1 << lane;
   4550                             found = 1;
   4551                         }
   4552                     } else {
   4553                         if (pc->lane_num > 0) {
   4554                             *lane_map = 0x10 << ((lane_swap != NULL) ? (lane - 2) : lane);
   4555                             found = 1;
   4556                         } else {
   4557                             *lane_map = 0x1 << lane;
   4558                             found = 1;
   4559                         }
   4560                     }
   4561                 break;
   4562                 case PHY82764_SPD_1G:
   4563                 case PHY82764_SPD_10G:
   4564                 case PHY82764_SPD_11G:
   4565                     if (device_cfg_aux_modes->pin_compatibility_enable) {
   4566                         *lane_map = 0x1 << ((lane_swap != NULL) ? lane : pc->lane_num);
   4567                         found = 1;
   4568                     } else {
   4569                         if (pc->lane_num > 1) {
   4570                             *lane_map = 0x10 << ((lane_swap != NULL) ? (lane - 2) : (pc->lane_num - 2));
   4571                             found = 1;
   4572                         } else {
   4573                             *lane_map = 0x1 << (pc->lane_num);
   4574                             found = 1;
   4575                         }
   4576                     }
   4577                 break;
   4578                 default:
   4579                     return SOC_E_CONFIG;
   4580             }
   4581         }
   4582         /* coverity[dead_error_condition] */ 
   4583         if (found) {
   4584             *p_phy = pmc->phy[idx];
   4585             break;
   4586         }
   4587     }
   4588 
   4589     if (!found) {
   4590         LOG_CLI((BSL_META_U(pmc->unit,"\nInvalid lane \n")));
   4591         /* No such lane */
   4592         return SOC_E_PARAM;
   4593     }
   4594 
   4595     return (SOC_E_NONE);
   4596 }
   4597 
   4598 /* 
   4599  * phy_82764_per_lane_preemphasis_set
   4600  */
   4601 STATIC int
   4602 phy_82764_per_lane_preemphasis_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4603 {
   4604     soc_phymod_phy_t    *p_phy;
   4605     uint32              lane_map;
   4606     phymod_phy_access_t pm_phy_copy, *pm_phy;
   4607     phymod_tx_t         phymod_tx;
   4608 
   4609     /* locate the desired phy and lane */
   4610     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4611 
   4612     /* Make a copy of the phy access and overwrite the desired lane */
   4613     pm_phy = &p_phy->pm_phy;
   4614     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4615     pm_phy_copy.access.lane_mask = lane_map;
   4616     pm_phy_copy.port_loc = phymodPortLocLine;
   4617     if(intf == PHY82764_SYS_SIDE) {
   4618         pm_phy_copy.port_loc = phymodPortLocSys;
   4619     } 
   4620 
   4621     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4622     phymod_tx.pre = value;
   4623     SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   4624 
   4625     return(SOC_E_NONE);
   4626 }
   4627 
   4628 /* 
   4629  * phy_82764_tx_fir_pre_set
   4630  */
   4631 STATIC int
   4632 phy_82764_tx_fir_pre_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   4633 {
   4634     phymod_phy_access_t *pm_phy;
   4635     phymod_tx_t         phymod_tx;
   4636     int                 idx;
   4637     phymod_phy_access_t pm_phy_copy;
   4638     /* loop through all cores */
   4639     for (idx = 0; idx < pmc->num_phys; idx++) {
   4640         pm_phy = &pmc->phy[idx]->pm_phy;
   4641 
   4642         if (pm_phy == NULL) {
   4643             return SOC_E_INTERNAL;
   4644         }
   4645         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4646         pm_phy_copy.port_loc = phymodPortLocLine;
   4647         if(intf == PHY82764_SYS_SIDE) {
   4648             pm_phy_copy.port_loc = phymodPortLocSys;
   4649             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   4650         } 
   4651 
   4652         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4653         phymod_tx.pre = value;
   4654         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   4655     }
   4656 
   4657     return(SOC_E_NONE);
   4658 }
   4659 
   4660 /* 
   4661  * phy_82764_tx_fir_main_set
   4662  */
   4663 STATIC int
   4664 phy_82764_tx_fir_main_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   4665 {
   4666     phymod_phy_access_t *pm_phy;
   4667     phymod_tx_t         phymod_tx;
   4668     int                 idx;
   4669     phymod_phy_access_t pm_phy_copy;
   4670     /* loop through all cores */
   4671     for (idx = 0; idx < pmc->num_phys; idx++) {
   4672         pm_phy = &pmc->phy[idx]->pm_phy;
   4673 
   4674         if (pm_phy == NULL) {
   4675             return SOC_E_INTERNAL;
   4676         }
   4677         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4678         pm_phy_copy.port_loc = phymodPortLocLine;
   4679         if(intf == PHY82764_SYS_SIDE) {
   4680             pm_phy_copy.port_loc = phymodPortLocSys;
   4681             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   4682         } 
   4683 
   4684         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4685         phymod_tx.main = value;
   4686         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   4687     }
   4688 
   4689     return(SOC_E_NONE);
   4690 }
   4691 
   4692 /* 
   4693  * phy_82764_tx_fir_post_set
   4694  */
   4695 STATIC int
   4696 phy_82764_tx_fir_post_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   4697 {
   4698     phymod_phy_access_t *pm_phy;
   4699     phymod_tx_t         phymod_tx;
   4700     int                 idx;
   4701     phymod_phy_access_t pm_phy_copy;
   4702 
   4703     /* loop through all cores */
   4704     for (idx = 0; idx < pmc->num_phys; idx++) {
   4705         pm_phy = &pmc->phy[idx]->pm_phy;
   4706 
   4707         if (pm_phy == NULL) {
   4708             return SOC_E_INTERNAL;
   4709         }
   4710         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4711         pm_phy_copy.port_loc = phymodPortLocLine;
   4712         if(intf == PHY82764_SYS_SIDE) {
   4713             pm_phy_copy.port_loc = phymodPortLocSys;
   4714             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   4715         } 
   4716 
   4717         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4718         phymod_tx.post = value;
   4719         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   4720     }
   4721 
   4722     return(SOC_E_NONE);
   4723 }
   4724 
   4725 /* 
   4726  * phy_82764_tx_fir_post2_set
   4727  */
   4728 STATIC int
   4729 phy_82764_tx_fir_post2_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   4730 {
   4731     phymod_phy_access_t *pm_phy;
   4732     phymod_tx_t         phymod_tx;
   4733     int                 idx;
   4734     phymod_phy_access_t pm_phy_copy;
   4735 
   4736     /* loop through all cores */
   4737     for (idx = 0; idx < pmc->num_phys; idx++) {
   4738         pm_phy = &pmc->phy[idx]->pm_phy;
   4739 
   4740         if (pm_phy == NULL) {
   4741             return SOC_E_INTERNAL;
   4742         }
   4743         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4744         pm_phy_copy.port_loc = phymodPortLocLine;
   4745         if(intf == PHY82764_SYS_SIDE) {
   4746             pm_phy_copy.port_loc = phymodPortLocSys;
   4747             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   4748         } 
   4749 
   4750         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4751         phymod_tx.post2 = value;
   4752         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   4753     }
   4754 
   4755     return(SOC_E_NONE);
   4756 }
   4757 
   4758 /* 
   4759  * phy_82764_per_lane_driver_current_set
   4760  */
   4761 STATIC int
   4762 phy_82764_per_lane_driver_current_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4763 {
   4764     soc_phymod_phy_t    *p_phy;
   4765     uint32              lane_map;
   4766     phymod_phy_access_t pm_phy_copy, *pm_phy;
   4767     phymod_tx_t         phymod_tx;
   4768 
   4769     /* locate the desired phy and lane */
   4770     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4771 
   4772     /* Make a copy of the phy access and overwrite the desired lane */
   4773     pm_phy = &p_phy->pm_phy;
   4774     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4775     pm_phy_copy.access.lane_mask = lane_map;
   4776     pm_phy_copy.port_loc = phymodPortLocLine;
   4777     if(intf == PHY82764_SYS_SIDE) {
   4778         pm_phy_copy.port_loc = phymodPortLocSys;
   4779     } 
   4780 
   4781     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4782     phymod_tx.amp = value;
   4783     SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   4784 
   4785     return(SOC_E_NONE);
   4786 }
   4787 
   4788 /* 
   4789  * phy_82764_driver_current_set
   4790  */
   4791 STATIC int
   4792 phy_82764_driver_current_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   4793 {
   4794     phymod_phy_access_t *pm_phy;
   4795     phymod_tx_t         phymod_tx;
   4796     int                 idx;
   4797     phymod_phy_access_t pm_phy_copy;
   4798 
   4799     /* loop through all cores */
   4800     for (idx = 0; idx < pmc->num_phys; idx++) {
   4801         pm_phy = &pmc->phy[idx]->pm_phy;
   4802 
   4803         if (pm_phy == NULL) {
   4804             return SOC_E_INTERNAL;
   4805         }
   4806         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4807         pm_phy_copy.port_loc = phymodPortLocLine;
   4808         if(intf == PHY82764_SYS_SIDE) {
   4809             pm_phy_copy.port_loc = phymodPortLocSys;
   4810             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   4811         } 
   4812 
   4813         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4814         phymod_tx.amp = value;
   4815         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   4816     }
   4817 
   4818     return(SOC_E_NONE);
   4819 }
   4820 
   4821 /* 
   4822  * phy_82764_per_lane_rx_dfe_tap_control_set
   4823  */
   4824 STATIC int
   4825 phy_82764_per_lane_rx_dfe_tap_control_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, int tap, int enable, uint32 value)
   4826 {
   4827     soc_phymod_phy_t    *p_phy;
   4828     uint32              lane_map;
   4829     phymod_phy_access_t pm_phy_copy, *pm_phy;
   4830     phymod_rx_t          phymod_rx;
   4831 
   4832     /* locate the desired phy and lane */
   4833     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4834 
   4835     /* Make a copy of the phy access and overwrite the desired lane */
   4836     pm_phy = &p_phy->pm_phy;
   4837     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4838     pm_phy_copy.access.lane_mask = lane_map;
   4839     pm_phy_copy.port_loc = phymodPortLocLine;
   4840     if(intf == PHY82764_SYS_SIDE) {
   4841         pm_phy_copy.port_loc = phymodPortLocSys;
   4842     } 
   4843 
   4844     if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) {
   4845         /* this can only happen with a coding error */
   4846         return SOC_E_INTERNAL;
   4847     }
   4848     sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   4849     phymod_rx.dfe[tap].enable = enable;
   4850     phymod_rx.dfe[tap].value = value;
   4851     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   4852     if (!enable) {
   4853         SOC_IF_ERROR_RETURN(phymod_phy_rx_adaptation_resume(&pm_phy_copy));
   4854     }
   4855 
   4856     return(SOC_E_NONE);
   4857 }
   4858 /*
   4859  * phy_82764_per_lane_tx_lane_squelch
   4860  */
   4861 STATIC int
   4862 phy_82764_per_lane_tx_lane_squelch(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   4863 {
   4864     phymod_phy_access_t *pm_phy;
   4865     phymod_phy_tx_lane_control_t  tx_control;
   4866     int                 idx;
   4867     phymod_phy_access_t pm_phy_copy;
   4868     soc_phymod_phy_t    *p_phy;
   4869     uint32              lane_map;
   4870 
   4871     /* locate the desired phy and lane */
   4872     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4873 
   4874     /* loop through all cores */
   4875     for (idx = 0; idx < pmc->num_phys; idx++) {
   4876         pm_phy = &pmc->phy[idx]->pm_phy;
   4877 
   4878         if (pm_phy == NULL) {
   4879             return SOC_E_INTERNAL;
   4880         }
   4881         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4882         pm_phy_copy.access.lane_mask = lane_map;
   4883         pm_phy_copy.port_loc = phymodPortLocLine;
   4884         if(intf == PHY82764_SYS_SIDE) {
   4885             pm_phy_copy.port_loc = phymodPortLocSys;
   4886         } 
   4887 
   4888         if (value == 1) {
   4889             tx_control = phymodTxSquelchOn;
   4890         } else {
   4891             tx_control = phymodTxSquelchOff;
   4892         }
   4893         SOC_IF_ERROR_RETURN
   4894             (phymod_phy_tx_lane_control_set(&pm_phy_copy, tx_control));
   4895 
   4896     }
   4897 
   4898     return(SOC_E_NONE);
   4899 } 
   4900 
   4901 STATIC int
   4902 phy_82764_per_lane_tx_lane_squelch_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   4903 {
   4904     phymod_phy_access_t *pm_phy;
   4905     phymod_phy_tx_lane_control_t  tx_control;
   4906     phymod_phy_access_t pm_phy_copy;
   4907     soc_phymod_phy_t    *p_phy;
   4908     uint32              lane_map;
   4909 
   4910     /* locate the desired phy and lane */
   4911     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4912 
   4913     /* Make a copy of the phy access and overwrite the desired lane */
   4914     pm_phy = &p_phy->pm_phy;
   4915 
   4916     if (pm_phy == NULL) {
   4917         return SOC_E_INTERNAL;
   4918     }
   4919     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4920     pm_phy_copy.access.lane_mask = lane_map;
   4921     pm_phy_copy.port_loc = phymodPortLocLine;
   4922     if(intf == PHY82764_SYS_SIDE) {
   4923         pm_phy_copy.port_loc = phymodPortLocSys;
   4924     }
   4925 
   4926     tx_control = phymodTxSquelchOn;
   4927     SOC_IF_ERROR_RETURN
   4928         (phymod_phy_tx_lane_control_get(&pm_phy_copy, &tx_control));
   4929     if (tx_control == phymodTxSquelchOn) {
   4930         *value = 1;
   4931     } else {
   4932         *value = 0;
   4933     }
   4934 
   4935     return(SOC_E_NONE);
   4936 } 
   4937 
   4938 /* 
   4939  * phy_82764_per_lane_rx_peak_filter_set
   4940  */
   4941 STATIC int
   4942 phy_82764_per_lane_rx_peak_filter_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, int enable, uint32 value)
   4943 {
   4944     soc_phymod_phy_t    *p_phy;
   4945     uint32              lane_map;
   4946     phymod_phy_access_t pm_phy_copy, *pm_phy;
   4947     phymod_rx_t         phymod_rx;
   4948 
   4949     /* locate the desired phy and lane */
   4950     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4951 
   4952     /* Make a copy of the phy access and overwrite the desired lane */
   4953     pm_phy = &p_phy->pm_phy;
   4954     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4955     pm_phy_copy.access.lane_mask = lane_map;
   4956     pm_phy_copy.port_loc = phymodPortLocLine;
   4957     if(intf == PHY82764_SYS_SIDE) {
   4958         pm_phy_copy.port_loc = phymodPortLocSys;
   4959     } 
   4960     sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   4961     phymod_rx.peaking_filter.enable = TRUE;
   4962     phymod_rx.peaking_filter.value = value;
   4963     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   4964 
   4965     return(SOC_E_NONE);
   4966 }
   4967 
   4968 /* 
   4969  * phy_82764_per_lane_rx_vga_set
   4970  */
   4971 STATIC int
   4972 phy_82764_per_lane_rx_vga_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, int enable, uint32 value)
   4973 {
   4974     soc_phymod_phy_t    *p_phy;
   4975     uint32              lane_map;
   4976     phymod_phy_access_t pm_phy_copy, *pm_phy;
   4977     phymod_rx_t         phymod_rx;
   4978 
   4979     /* locate the desired phy and lane */
   4980     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   4981 
   4982     /* Make a copy of the phy access and overwrite the desired lane */
   4983     pm_phy = &p_phy->pm_phy;
   4984     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4985     pm_phy_copy.access.lane_mask = lane_map;
   4986     pm_phy_copy.port_loc = phymodPortLocLine;
   4987     if(intf == PHY82764_SYS_SIDE) {
   4988         pm_phy_copy.port_loc = phymodPortLocSys;
   4989     } 
   4990 
   4991     sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   4992     phymod_rx.vga.enable = TRUE;
   4993     phymod_rx.vga.value = value;
   4994     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   4995     if (!enable) {
   4996         SOC_IF_ERROR_RETURN(phymod_phy_rx_adaptation_resume(&pm_phy_copy));
   4997     }
   4998 
   4999     return(SOC_E_NONE);
   5000 }
   5001 
   5002 /* 
   5003  * phy_82764_pi_control_set
   5004  */
   5005 STATIC int 
   5006 phy_82764_pi_control_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   5007 {
   5008     phymod_phy_access_t  *pm_phy;
   5009     phymod_tx_override_t tx_override;
   5010     int                  idx;
   5011     phymod_phy_access_t pm_phy_copy;
   5012 
   5013     /* loop through all cores */
   5014     for (idx = 0; idx < pmc->num_phys; idx++) {
   5015         pm_phy = &pmc->phy[idx]->pm_phy;
   5016 
   5017         if (pm_phy == NULL) {
   5018             return SOC_E_INTERNAL;
   5019         }
   5020         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5021         pm_phy_copy.port_loc = phymodPortLocLine;
   5022         if(intf == PHY82764_SYS_SIDE) {
   5023             pm_phy_copy.port_loc = phymodPortLocSys;
   5024             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5025         } 
   5026 
   5027         phymod_tx_override_t_init(&tx_override);
   5028         tx_override.phase_interpolator.enable = (value == 0) ? 0 : 1;
   5029         tx_override.phase_interpolator.value = value;
   5030         SOC_IF_ERROR_RETURN(phymod_phy_tx_override_set(&pm_phy_copy, &tx_override));
   5031     }
   5032 
   5033     return(SOC_E_NONE);
   5034 }
   5035 
   5036 STATIC int 
   5037 phy_82764_per_lane_tx_polarity_set(soc_phymod_ctrl_t *pmc, soc_port_t port, phymod_polarity_t *cfg_polarity, int32 intf, int lane, uint32 value)
   5038 {
   5039     phymod_phy_access_t  *pm_phy;
   5040     phymod_polarity_t    polarity;
   5041     uint32              lane_map;
   5042     phymod_phy_access_t pm_phy_copy;
   5043     soc_phymod_phy_t    *p_phy;
   5044 
   5045     /* locate the desired phy and lane */
   5046     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   5047 
   5048     /* Make a copy of the phy access and overwrite the desired lane */
   5049     pm_phy = &p_phy->pm_phy;
   5050     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5051     pm_phy_copy.access.lane_mask = lane_map;
   5052     pm_phy_copy.port_loc = phymodPortLocLine;
   5053     if(intf == PHY82764_SYS_SIDE) {
   5054         pm_phy_copy.port_loc = phymodPortLocSys;
   5055     } 
   5056 
   5057     sal_memcpy(&polarity, cfg_polarity, sizeof(polarity));
   5058     SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(&pm_phy_copy, &polarity));
   5059     polarity.tx_polarity = value;
   5060     SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(&pm_phy_copy, &polarity));
   5061 
   5062     /* after successfully setting the parity, update the configured value */
   5063     cfg_polarity->tx_polarity = value;
   5064 
   5065     return(SOC_E_NONE);
   5066 }
   5067 
   5068 /* 
   5069  * phy_82764_per_lane_rx_polarity_set
   5070  */
   5071 STATIC int 
   5072 phy_82764_per_lane_rx_polarity_set(soc_phymod_ctrl_t *pmc, soc_port_t port, phymod_polarity_t *cfg_polarity, int32 intf, int lane, uint32 value)
   5073 {
   5074     phymod_phy_access_t  *pm_phy;
   5075     phymod_polarity_t    polarity;
   5076     uint32              lane_map;
   5077     phymod_phy_access_t pm_phy_copy;
   5078     soc_phymod_phy_t    *p_phy;
   5079 
   5080     /* locate the desired phy and lane */
   5081     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   5082 
   5083     /* Make a copy of the phy access and overwrite the desired lane */
   5084     pm_phy = &p_phy->pm_phy;
   5085     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5086     pm_phy_copy.access.lane_mask = lane_map;
   5087     pm_phy_copy.port_loc = phymodPortLocLine;
   5088     if(intf == PHY82764_SYS_SIDE) {
   5089         pm_phy_copy.port_loc = phymodPortLocSys;
   5090     } 
   5091 
   5092     sal_memcpy(&polarity, cfg_polarity, sizeof(polarity));
   5093     SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(&pm_phy_copy, &polarity));
   5094     polarity.rx_polarity = value;
   5095     SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(&pm_phy_copy, &polarity));
   5096 
   5097     /* after successfully setting the parity, update the configured value */
   5098     cfg_polarity->rx_polarity = value;
   5099 
   5100     return(SOC_E_NONE);
   5101 }
   5102 
   5103 /* 
   5104  * phy_82764_rx_reset
   5105  */
   5106 STATIC int
   5107 phy_82764_rx_reset(soc_phymod_ctrl_t *pmc, soc_port_t port, phymod_phy_reset_t *cfg_reset, int32 intf, uint32 value)
   5108 {
   5109     phymod_phy_access_t *pm_phy;
   5110     phymod_phy_reset_t  reset;
   5111     int                 idx;
   5112     phymod_phy_access_t pm_phy_copy;
   5113 
   5114     /* loop through all cores */
   5115     for (idx = 0; idx < pmc->num_phys; idx++) {
   5116         pm_phy = &pmc->phy[idx]->pm_phy;
   5117 
   5118         if (pm_phy == NULL) {
   5119             return SOC_E_INTERNAL;
   5120         }
   5121         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5122         pm_phy_copy.port_loc = phymodPortLocLine;
   5123         if(intf == PHY82764_SYS_SIDE) {
   5124             pm_phy_copy.port_loc = phymodPortLocSys;
   5125             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5126         } 
   5127 
   5128         sal_memcpy(&reset, cfg_reset, sizeof(reset));
   5129         reset.rx = (phymod_reset_direction_t) value;
   5130         SOC_IF_ERROR_RETURN(phymod_phy_reset_set(&pm_phy_copy, &reset));
   5131 
   5132         /* after successfully setting the parity, update the configured value */
   5133         cfg_reset->rx = (phymod_reset_direction_t) value;
   5134     }
   5135 
   5136     return(SOC_E_NONE);
   5137 }
   5138 
   5139 /* 
   5140  * phy_82764_tx_reset
   5141  */
   5142 STATIC int
   5143 phy_82764_tx_reset(soc_phymod_ctrl_t *pmc, soc_port_t port, phymod_phy_reset_t *cfg_reset, int32 intf, uint32 value)
   5144 {
   5145     phymod_phy_access_t *pm_phy;
   5146     phymod_phy_reset_t  reset;
   5147     int                 idx;
   5148     phymod_phy_access_t pm_phy_copy;
   5149 
   5150     /* loop through all cores */
   5151     for (idx = 0; idx < pmc->num_phys; idx++) {
   5152         pm_phy = &pmc->phy[idx]->pm_phy;
   5153 
   5154         if (pm_phy == NULL) {
   5155             return SOC_E_INTERNAL;
   5156         }
   5157         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5158         pm_phy_copy.port_loc = phymodPortLocLine;
   5159         if(intf == PHY82764_SYS_SIDE) {
   5160             pm_phy_copy.port_loc = phymodPortLocSys;
   5161             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5162         } 
   5163 
   5164         sal_memcpy(&reset, cfg_reset, sizeof(reset));
   5165         reset.tx = (phymod_reset_direction_t) value;
   5166         SOC_IF_ERROR_RETURN(phymod_phy_reset_set(&pm_phy_copy, &reset));
   5167 
   5168         /* after successfully setting the parity, update the configured value */
   5169         cfg_reset->tx = (phymod_reset_direction_t) value;
   5170     }
   5171 
   5172     return(SOC_E_NONE);
   5173 }
   5174 
   5175 
   5176 /* 
   5177  * phy_82764_per_lane_power_set
   5178  */
   5179 STATIC int
   5180 phy_82764_per_lane_power_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   5181 {
   5182     phymod_phy_access_t  *pm_phy;
   5183     phymod_phy_power_t   power;
   5184     uint32               lane_map;
   5185     phymod_phy_access_t  pm_phy_copy;
   5186     soc_phymod_phy_t     *p_phy;
   5187 
   5188     /* locate the desired phy and lane */
   5189     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   5190 
   5191     /* Make a copy of the phy access and overwrite the desired lane */
   5192     pm_phy = &p_phy->pm_phy;
   5193     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5194     pm_phy_copy.access.lane_mask = lane_map;
   5195     pm_phy_copy.port_loc = phymodPortLocLine;
   5196     if(intf == PHY82764_SYS_SIDE) {
   5197         pm_phy_copy.port_loc = phymodPortLocSys;
   5198     } 
   5199 
   5200     phymod_phy_power_t_init(&power);
   5201     if (value) {
   5202         power.tx = phymodPowerOn;
   5203         power.rx = phymodPowerOn;
   5204     } 
   5205     else {
   5206         power.tx = phymodPowerOff;
   5207         power.rx = phymodPowerOff;
   5208     }
   5209 
   5210     SOC_IF_ERROR_RETURN(phymod_phy_power_set(&pm_phy_copy, &power));
   5211 
   5212     return(SOC_E_NONE);
   5213 }
   5214 /* 
   5215  * phy_82764_power_set
   5216  */
   5217 STATIC int
   5218 phy_82764_power_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   5219 {
   5220     phymod_phy_access_t     *pm_phy;
   5221     phymod_phy_power_t      power;
   5222     int                     idx;
   5223     phymod_phy_access_t     pm_phy_copy;
   5224 
   5225     /* loop through all cores */
   5226     for (idx = 0; idx < pmc->num_phys; idx++) {
   5227         pm_phy = &pmc->phy[idx]->pm_phy;
   5228 
   5229         if (pm_phy == NULL) {
   5230             return SOC_E_INTERNAL;
   5231         }
   5232 
   5233         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5234         pm_phy_copy.port_loc = phymodPortLocLine;
   5235         if(intf == PHY82764_SYS_SIDE) {
   5236             pm_phy_copy.port_loc = phymodPortLocSys;
   5237             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5238         }
   5239  
   5240         phymod_phy_power_t_init(&power);
   5241         if (value) {
   5242             power.tx = phymodPowerOn;
   5243             power.rx = phymodPowerOn;
   5244         } 
   5245         else {
   5246             power.tx = phymodPowerOff;
   5247             power.rx = phymodPowerOff;
   5248         }
   5249 
   5250         SOC_IF_ERROR_RETURN(phymod_phy_power_set(&pm_phy_copy, &power));
   5251     }
   5252 
   5253     return(SOC_E_NONE);
   5254 }
   5255 
   5256 STATIC int 
   5257 phy_82764_rx_seq_restart(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   5258 {
   5259     int                  idx;
   5260     uint32_t             flags = 0;
   5261     soc_phymod_core_t    *pmc_core;
   5262     phymod_core_access_t *pm_core;
   5263     phymod_core_access_t pm_core_copy;
   5264     phymod_phy_access_t  pm_phy_copy;
   5265     phymod_sequencer_operation_t seq_operation;
   5266 
   5267     /* loop through all cores */
   5268     for (idx = 0; idx < pmc->num_phys; idx++) {
   5269         pmc_core = pmc->phy[idx]->core;
   5270         pm_core = &pmc_core->pm_core;
   5271         if (pm_core == NULL) {
   5272             return SOC_E_INTERNAL;
   5273         }
   5274 
   5275         sal_memcpy(&pm_core_copy, pm_core, sizeof(pm_core_copy));
   5276         pm_core_copy.port_loc = phymodPortLocLine; 
   5277         if(intf == PHY82764_SYS_SIDE) {
   5278             pm_core_copy.port_loc = phymodPortLocSys; 
   5279             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5280             pm_core_copy.access.lane_mask = pm_phy_copy.access.lane_mask;
   5281         } 
   5282         seq_operation = phymodSeqOpRestart; 
   5283         SOC_IF_ERROR_RETURN(phymod_core_pll_sequencer_restart(&pm_core_copy, flags, seq_operation));
   5284     }
   5285 
   5286     return(SOC_E_NONE);
   5287 }
   5288 
   5289 STATIC int
   5290 phy_82764_per_lane_phy_dump(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane)
   5291 {
   5292     phymod_phy_access_t *pm_phy;
   5293     uint32              lane_map;
   5294     phymod_phy_access_t pm_phy_copy;
   5295     soc_phymod_phy_t    *p_phy;
   5296 
   5297     /* locate the desired phy and lane */
   5298     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   5299 
   5300     /* Make a copy of the phy access and overwrite the desired lane */
   5301     pm_phy = &p_phy->pm_phy;
   5302     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5303     pm_phy_copy.access.lane_mask = lane_map;
   5304     pm_phy_copy.port_loc = phymodPortLocLine;
   5305     if(intf == PHY82764_SYS_SIDE) {
   5306         pm_phy_copy.port_loc = phymodPortLocSys;
   5307     } 
   5308 
   5309     SOC_IF_ERROR_RETURN(phymod_phy_status_dump(&pm_phy_copy));
   5310 
   5311     return(SOC_E_NONE);
   5312 }
   5313 /*
   5314  * phy_82764_gpio_config_set
   5315  */
   5316 STATIC int
   5317 phy_82764_gpio_config_set(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 value)
   5318 {
   5319     phymod_phy_access_t  *pm_phy;
   5320     int                  idx;
   5321     phymod_phy_access_t pm_phy_copy;
   5322     int gpio_mode = 0;
   5323     int gpio_pin_no = 0;
   5324 
   5325     /* loop through all cores */
   5326     for (idx = 0; idx < pmc->num_phys; idx++) {
   5327         pm_phy = &pmc->phy[idx]->pm_phy;
   5328 
   5329         if (pm_phy == NULL) {
   5330             return SOC_E_INTERNAL;
   5331         }
   5332 
   5333         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5334 
   5335         for (gpio_pin_no = 0; gpio_pin_no < 4; gpio_pin_no++) {
   5336             gpio_mode = (value >> (4 * gpio_pin_no)) & 0xF;
   5337             SOC_IF_ERROR_RETURN(phymod_phy_gpio_config_set(&pm_phy_copy, gpio_pin_no, (phymod_gpio_mode_t)gpio_mode));
   5338         }
   5339     }
   5340 
   5341     return(SOC_E_NONE);
   5342 }
   5343 
   5344 /*
   5345  * phy_82764_gpio_value_set
   5346  */
   5347 STATIC int
   5348 phy_82764_gpio_value_set(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 value)
   5349 {
   5350     phymod_phy_access_t  *pm_phy;
   5351     int                  idx;
   5352     phymod_phy_access_t pm_phy_copy;
   5353     int pin_value = 0;
   5354     int gpio_pin_no = 0;
   5355 
   5356     /* loop through all cores */
   5357     for (idx = 0; idx < pmc->num_phys; idx++) {
   5358         pm_phy = &pmc->phy[idx]->pm_phy;
   5359 
   5360         if (pm_phy == NULL) {
   5361             return SOC_E_INTERNAL;
   5362         }
   5363 
   5364         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5365 
   5366         for (gpio_pin_no = 0; gpio_pin_no < 4; gpio_pin_no++) {
   5367             pin_value = (value >> (4 * gpio_pin_no)) & 0xF;
   5368             SOC_IF_ERROR_RETURN(phymod_phy_gpio_pin_value_set(&pm_phy_copy, gpio_pin_no, pin_value));
   5369         }
   5370     }
   5371 
   5372     return(SOC_E_NONE);
   5373 }
   5374 
   5375 /*
   5376  * Function:
   5377  *      phy_82764_control_set
   5378  * Purpose:
   5379  *      Configure PHY device specific control fucntion. 
   5380  * Parameters:
   5381  *      unit  - BCM unit number.
   5382  *      port  - Port number. 
   5383  *      type  - Control to update 
   5384  *      value - New setting for the control 
   5385  * Returns:     
   5386  *      SOC_E_NONE
   5387  */
   5388 STATIC int
   5389 phy_82764_control_set(int unit, soc_port_t port, soc_phy_control_t type, uint32 value)
   5390 {
   5391     int                 rv = 0;
   5392     int32               intf;
   5393     phy_ctrl_t          *pc;
   5394     soc_phymod_ctrl_t   *pmc;
   5395     phy82764_config_t   *pCfg;
   5396     int                 lane, num_lanes;
   5397 
   5398     PHY_CONTROL_TYPE_CHECK(type);
   5399 
   5400     /* locate phy control, phymod control, and the configuration data */
   5401     pc = EXT_PHY_SW_STATE(unit, port);
   5402     if (pc == NULL) {
   5403         return SOC_E_INTERNAL;
   5404     }
   5405     pmc = &pc->phymod_ctrl;
   5406     pCfg = (phy82764_config_t *) pc->driver_data;
   5407     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82764_SYS_SIDE : PHY82764_LINE_SIDE; 
   5408 
   5409     /* get number of lanes per port on line side */
   5410     num_lanes = (intf == PHY82764_LINE_SIDE) ? port_num_lanes_line_side_get(unit, port, pc->speed_max):
   5411                                                SOC_INFO(unit).port_num_lanes[port];
   5412   if (!((type == SOC_PHY_CONTROL_RX_RESET) || (type == SOC_PHY_CONTROL_TX_RESET) ||
   5413         (type == SOC_PHY_CONTROL_INTR_MASK) || (type == SOC_PHY_CONTROL_GPIO_CONFIG) ||
   5414         (type == SOC_PHY_CONTROL_GPIO_VALUE) || (type == SOC_PHY_CONTROL_FIRMWARE_MODE) ||
   5415         (type == SOC_PHY_CONTROL_RX_SEQ_TOGGLE) || (type == SOC_PHY_CONTROL_PHASE_INTERP) ||
   5416         (type == SOC_PHY_CONTROL_POWER) || (type == SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION) ||
   5417         (type == SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE) || (type == SOC_PHY_CONTROL_FIRMWARE_LP_DFE_ENABLE) ||
   5418         (type == SOC_PHY_CONTROL_PREEMPHASIS_LANE0) || (type == SOC_PHY_CONTROL_PREEMPHASIS_LANE1) ||
   5419         (type == SOC_PHY_CONTROL_PREEMPHASIS_LANE2) || (type == SOC_PHY_CONTROL_PREEMPHASIS_LANE3) ||
   5420         (type == SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0) || (type == SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1) ||
   5421         (type == SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2) || (type == SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3) ||
   5422         (type == SOC_PHY_CONTROL_CL72) || (type == SOC_PHY_CONTROL_UNRELIABLE_LOS))) {
   5423       for (lane = 0; lane < num_lanes; lane++) {
   5424          rv |= phy_82764_per_lane_control_set(unit, port, lane, type, value);
   5425       }
   5426   } else {
   5427     switch(type) {
   5428     case SOC_PHY_CONTROL_CL72:
   5429         rv = phy_82764_cl72_enable_set(pmc, port, intf, value);
   5430         break;
   5431     /* PREEMPHASIS */
   5432     case SOC_PHY_CONTROL_PREEMPHASIS_LANE0:
   5433         rv = phy_82764_per_lane_preemphasis_set(pmc, port, intf, 0, value);
   5434         break;
   5435     case SOC_PHY_CONTROL_PREEMPHASIS_LANE1:
   5436         rv = phy_82764_per_lane_preemphasis_set(pmc, port, intf, 1, value);
   5437         break;
   5438     case SOC_PHY_CONTROL_PREEMPHASIS_LANE2:
   5439         rv = phy_82764_per_lane_preemphasis_set(pmc, port, intf, 2, value);
   5440         break;
   5441     case SOC_PHY_CONTROL_PREEMPHASIS_LANE3:
   5442         rv = phy_82764_per_lane_preemphasis_set(pmc, port, intf, 3, value);
   5443         break;
   5444     /* DRIVER CURRENT */
   5445     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0:
   5446         rv = phy_82764_per_lane_driver_current_set(pmc, port, intf, 0, value);
   5447         break;
   5448     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1:
   5449         rv = phy_82764_per_lane_driver_current_set(pmc, port, intf, 1, value);
   5450         break;
   5451     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2:
   5452         rv = phy_82764_per_lane_driver_current_set(pmc, port, intf, 2, value);
   5453         break;
   5454     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3:
   5455         rv = phy_82764_per_lane_driver_current_set(pmc, port, intf, 3, value);
   5456         break;
   5457     /* PHASE INTERPOLATOR */
   5458     case SOC_PHY_CONTROL_PHASE_INTERP:
   5459         rv = phy_82764_pi_control_set(pmc, port, intf, value);
   5460         break;
   5461     /* RESET */
   5462     case SOC_PHY_CONTROL_RX_RESET:
   5463         rv = phy_82764_rx_reset(pmc, port, &pCfg->phy_reset_config, intf, value);
   5464         break;
   5465     case SOC_PHY_CONTROL_TX_RESET:
   5466         rv = phy_82764_tx_reset(pmc, port, &pCfg->phy_reset_config, intf, value);
   5467         break;
   5468     /* POWER */
   5469     case SOC_PHY_CONTROL_POWER:
   5470        {
   5471            phy_ctrl_t                *int_pc;
   5472            int_pc = INT_PHY_SW_STATE(unit, port);
   5473            if (int_pc != NULL) {
   5474                SOC_IF_ERROR_RETURN(PHY_ENABLE_SET(int_pc->pd, unit, port, value));
   5475                rv = phy_82764_power_set(pmc, port, intf, value);
   5476            }
   5477        }
   5478        break;
   5479     case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION:
   5480        rv = phy_82764_fec_enable_set(pmc, port, intf, value);
   5481        break;
   5482     case SOC_PHY_CONTROL_RX_SEQ_TOGGLE:
   5483         rv = phy_82764_rx_seq_restart(pmc, port, intf, value);
   5484     break;
   5485     case SOC_PHY_CONTROL_INTR_MASK:
   5486         rv = phy_82764_intr_enable_set(pmc, port, intf, value);
   5487     break;
   5488     case SOC_PHY_CONTROL_GPIO_CONFIG:
   5489         rv = phy_82764_gpio_config_set(pmc, port, value);
   5490     break;
   5491     case SOC_PHY_CONTROL_GPIO_VALUE:
   5492         rv = phy_82764_gpio_value_set(pmc, port, value);
   5493     break;
   5494     /* FIRMWARE MODE */
   5495     case SOC_PHY_CONTROL_FIRMWARE_MODE:
   5496         rv = phy_82764_firmware_mode_set(pc, port, intf, value);
   5497         break;
   5498     case SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE:
   5499         rv = phy_82764_firmware_dfe_enable_set(pc, port, intf, value);
   5500         break;
   5501     case SOC_PHY_CONTROL_FIRMWARE_LP_DFE_ENABLE:
   5502         rv = phy_82764_firmware_lp_dfe_enable_set(pc, port, intf, value);
   5503         break;
   5504     case SOC_PHY_CONTROL_UNRELIABLE_LOS:
   5505         rv = phy_82764_unreliable_los_set(pc, port, intf, value);
   5506         break;
   5507        /*
   5508         * COVERITY
   5509         * This is unreachable. It is kept intentionally as a defensive
   5510         * default for future development.
   5511         */
   5512        /* coverity[dead_error_begin] */
   5513     default:
   5514         rv = SOC_E_UNAVAIL;
   5515         break; 
   5516     }
   5517   }
   5518 
   5519     return rv;
   5520 }
   5521 /*
   5522  * Function:
   5523  *      phy_82764_per_lane_control_set
   5524  * Purpose:
   5525  *      Configure PHY device specific control fucntion. 
   5526  * Parameters:
   5527  *      unit  - StrataSwitch unit #.
   5528  *      port  - StrataSwitch port #. 
   5529  *      lane  - lane number
   5530  *      type  - Control to update 
   5531  *      value - New setting for the control 
   5532  * Returns:     
   5533  *      SOC_E_NONE
   5534  */
   5535 STATIC int
   5536 phy_82764_per_lane_control_set(int unit, soc_port_t port, int lane, soc_phy_control_t type, uint32 value)
   5537 {
   5538     int                 rv = -1;
   5539     int32               intf;
   5540     phy_ctrl_t          *pc;
   5541     soc_phymod_ctrl_t   *pmc;
   5542     phy82764_config_t   *pCfg;
   5543 
   5544     /* locate phy control, phymod control, and the configuration data */
   5545     pc = EXT_PHY_SW_STATE(unit, port);
   5546     if (pc == NULL) {
   5547         return SOC_E_INTERNAL;
   5548     }
   5549     pmc = &pc->phymod_ctrl;
   5550     pCfg = (phy82764_config_t *) pc->driver_data;
   5551 
   5552     PHY_CONTROL_TYPE_CHECK(type);
   5553 
   5554     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82764_SYS_SIDE : PHY82764_LINE_SIDE; 
   5555 
   5556     switch(type) {
   5557     case SOC_PHY_CONTROL_PREEMPHASIS:
   5558         rv = phy_82764_per_lane_preemphasis_set(pmc, port, intf, lane, value);
   5559         break; 
   5560     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   5561         rv = phy_82764_per_lane_driver_current_set(pmc, port, intf, lane, value);
   5562         break;
   5563     case SOC_PHY_CONTROL_RX_TAP1:
   5564         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 0 /* tap */, 1 /* enable */, value);
   5565         break;
   5566     case SOC_PHY_CONTROL_RX_TAP1_RELEASE:
   5567         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 0 /* tap */, 0 /* release */, 0x8000);
   5568         break;
   5569     case SOC_PHY_CONTROL_RX_TAP2:
   5570         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 1 /* tap */, 1 /* enable */, value);
   5571         break;
   5572     case SOC_PHY_CONTROL_RX_TAP2_RELEASE:
   5573         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 1 /* tap */, 0 /* release */, 0x8000);
   5574         break;
   5575     case SOC_PHY_CONTROL_RX_TAP3:
   5576         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 2 /* tap */, 1 /* enable */, value);
   5577         break;
   5578     case SOC_PHY_CONTROL_RX_TAP3_RELEASE:
   5579         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 2 /* tap */, 0 /* release */, 0x8000);
   5580         break;
   5581     case SOC_PHY_CONTROL_RX_TAP4:
   5582         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 3 /* tap */, 1 /* enable */, value);
   5583         break;
   5584     case SOC_PHY_CONTROL_RX_TAP4_RELEASE:
   5585         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 3 /* tap */, 0 /* release */, 0x8000);
   5586         break;
   5587     case SOC_PHY_CONTROL_RX_TAP5:
   5588         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 4 /* tap */, 1 /* enable */, value);
   5589         break;
   5590     case SOC_PHY_CONTROL_RX_TAP5_RELEASE:
   5591         rv = phy_82764_per_lane_rx_dfe_tap_control_set (pmc, port, intf, lane, 4 /* tap */, 0 /* release */, 0x8000);
   5592         break;
   5593     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL:
   5594         rv = phy_82764_per_lane_prbs_tx_poly_set(pmc, port, intf, lane, value);
   5595         break;
   5596     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA:
   5597         rv = phy_82764_per_lane_prbs_tx_invert_data_set(pmc, port, intf, lane, value);
   5598         break;
   5599     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE:
   5600         rv = phy_82764_per_lane_prbs_tx_enable_set(pmc, port, intf, lane, value);
   5601         break;
   5602     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL:
   5603         rv = phy_82764_per_lane_prbs_rx_poly_set(pmc, port, intf, lane, value);
   5604         break;
   5605     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA:
   5606         rv = phy_82764_per_lane_prbs_rx_invert_data_set(pmc, port, intf, lane, value);
   5607         break;
   5608     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE:
   5609         rv = phy_82764_per_lane_prbs_rx_enable_set(pmc, port, intf, lane, value);
   5610         break;
   5611     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   5612         rv = phy_82764_per_lane_prbs_tx_poly_set(pmc, port, intf, lane, value);
   5613         rv = phy_82764_per_lane_prbs_rx_poly_set(pmc, port, intf, lane, value);
   5614         break;
   5615     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   5616         rv = phy_82764_per_lane_prbs_tx_invert_data_set(pmc, port, intf, lane, value);
   5617         break;
   5618     case SOC_PHY_CONTROL_PRBS_RX_INVERT_DATA:
   5619         rv = phy_82764_per_lane_prbs_rx_invert_data_set(pmc, port, intf, lane, value);
   5620         break;
   5621     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   5622         /* TX_ENABLE does both tx and rx */
   5623         rv = phy_82764_per_lane_prbs_tx_enable_set(pmc, port, intf, lane, value);
   5624         rv = phy_82764_per_lane_prbs_rx_enable_set(pmc, port, intf, lane, value);
   5625         break; 
   5626     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   5627         rv = phy_82764_per_lane_prbs_tx_enable_set(pmc, port, intf, lane, value);
   5628         rv = phy_82764_per_lane_prbs_rx_enable_set(pmc, port, intf, lane, value);
   5629         break;
   5630     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   5631         rv = phy_82764_per_lane_rx_peak_filter_set(pmc, port, intf, lane, 1 /* enable */, value);
   5632         break;
   5633     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   5634         rv = phy_82764_per_lane_rx_low_freq_filter_set(pmc, port, intf, lane, value);
   5635         break;
   5636     case SOC_PHY_CONTROL_RX_VGA:
   5637         rv = phy_82764_per_lane_rx_vga_set(pmc, port, intf, lane, 1 /* enable */, value);
   5638         break;
   5639     case SOC_PHY_CONTROL_RX_VGA_RELEASE:
   5640         rv = phy_82764_per_lane_rx_vga_set(pmc, port, intf, lane, 0 /* release */, 0x8000);
   5641         break;
   5642     /* TX LANE SQUELCH */
   5643     case SOC_PHY_CONTROL_TX_LANE_SQUELCH:
   5644         rv = phy_82764_per_lane_tx_lane_squelch(pmc, port, intf, lane, value);
   5645         break;
   5646     /* POWER */
   5647     case SOC_PHY_CONTROL_POWER:
   5648        rv = phy_82764_per_lane_power_set(pmc, port, intf, lane, value);
   5649        break;
   5650     /* POLARITY */
   5651     case SOC_PHY_CONTROL_RX_POLARITY:
   5652         rv = phy_82764_per_lane_rx_polarity_set(pmc, port, &pCfg->phy_polarity_config, intf, lane, value);;
   5653         break;
   5654     case SOC_PHY_CONTROL_TX_POLARITY:
   5655         rv = phy_82764_per_lane_tx_polarity_set(pmc, port, &pCfg->phy_polarity_config, intf, lane, value);
   5656         break;
   5657     /* LOOPBACK */
   5658     case SOC_PHY_CONTROL_LOOPBACK_PMD:
   5659         rv = phy_82764_per_lane_loopback_internal_pmd_set(pmc, port, intf, lane, value);
   5660        break;
   5661     case SOC_PHY_CONTROL_LOOPBACK_REMOTE:
   5662     case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS:
   5663         rv = phy_82764_per_lane_loopback_remote_set(pmc, port, intf, lane, value);
   5664         break;
   5665     case SOC_PHY_CONTROL_DUMP:
   5666         rv = phy_82764_per_lane_phy_dump(pmc, port, intf, lane);
   5667     break;
   5668     case SOC_PHY_CONTROL_TX_FIR_PRE:
   5669     case SOC_PHY_CONTROL_TX_FIR_MAIN:
   5670     case SOC_PHY_CONTROL_TX_FIR_POST:
   5671     case SOC_PHY_CONTROL_TX_FIR_POST2:
   5672     case SOC_PHY_CONTROL_TX_FIR_POST3:
   5673         rv = phy_82764_per_lane_tx_set(pmc, port, intf, type, lane, value);
   5674     break;
   5675     case SOC_PHY_CONTROL_CL72:
   5676         rv = phy_82764_per_lane_cl72_enable_set(pmc, port, intf, lane, value);
   5677     break;
   5678     break;
   5679     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE:
   5680         rv = phy_82764_per_lane_short_chn_mode_enable_set(pmc, port, intf, lane, value);
   5681     break;
   5682     default:
   5683         rv = SOC_E_UNAVAIL;
   5684         break; 
   5685     }
   5686 
   5687     return rv;
   5688 }
   5689 /*
   5690  * phy_82764_firmware_mode_set
   5691  */
   5692 STATIC int
   5693 phy_82764_firmware_mode_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 value)
   5694 {
   5695     int idx;
   5696     soc_phymod_ctrl_t *pmc;
   5697     phymod_phy_access_t *pm_phy;
   5698     phymod_phy_access_t pm_phy_copy;
   5699     phymod_firmware_lane_config_t fw_config;
   5700     pmc = &pc->phymod_ctrl;
   5701 
   5702     /* loop through all cores */
   5703     for (idx = 0; idx < pmc->num_phys; idx++) {
   5704         if (pmc->phy[idx] == NULL) {
   5705             return(SOC_E_INTERNAL);
   5706         }
   5707         pm_phy = &pmc->phy[idx]->pm_phy;
   5708         if (pm_phy == NULL) {
   5709             return(SOC_E_INTERNAL);
   5710         }
   5711 
   5712         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5713         pm_phy_copy.port_loc = phymodPortLocLine;
   5714         if(intf == PHY82764_SYS_SIDE) {
   5715             pm_phy_copy.port_loc = phymodPortLocSys;
   5716             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5717         }
   5718 
   5719         sal_memset(&fw_config, 0, sizeof(fw_config));
   5720         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   5721 
   5722         switch (value) {
   5723             case SOC_PHY_FIRMWARE_DEFAULT:
   5724                 fw_config.DfeOn = 0xF;
   5725                 fw_config.LpDfeOn = 0xF;
   5726                 fw_config.ForceBrDfe = 0xF;
   5727                 break;
   5728             case SOC_PHY_FIRMWARE_FORCE_OSDFE:
   5729                 fw_config.DfeOn = 1;
   5730                 fw_config.ForceBrDfe = 0;
   5731                 break;
   5732             case SOC_PHY_FIRMWARE_SFP_DAC:
   5733                 fw_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   5734                 break;
   5735             case SOC_PHY_FIRMWARE_XLAUI:
   5736                 fw_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   5737                 break;
   5738             case SOC_PHY_FIRMWARE_SFP_OPT_SR4:
   5739                 fw_config.MediaType = phymodFirmwareMediaTypeOptics;
   5740                 break;
   5741             case SOC_PHY_FIRMWARE_LP_DFE_ENABLE:
   5742                 fw_config.LpDfeOn = 1;
   5743                 fw_config.DfeOn = 1;
   5744                 break;
   5745             case SOC_PHY_FIRMWARE_DFE_ENABLE:
   5746                 fw_config.DfeOn = 1;
   5747                 break;
   5748             default:
   5749                 return SOC_E_UNAVAIL;
   5750         }
   5751 
   5752         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   5753     }
   5754 
   5755     return(SOC_E_NONE);
   5756 }
   5757 
   5758 /*
   5759  * phy_82764_firmware_dfe_enable_set
   5760  */
   5761 STATIC int
   5762 phy_82764_firmware_dfe_enable_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 enable)
   5763 {
   5764     int idx;
   5765     soc_phymod_ctrl_t *pmc;
   5766     phymod_phy_access_t pm_phy_copy;
   5767     phymod_phy_access_t *pm_phy;
   5768     phymod_firmware_lane_config_t fw_config;
   5769     pmc = &pc->phymod_ctrl;
   5770 
   5771     /* loop through all cores */
   5772     for (idx = 0; idx < pmc->num_phys; idx++) {
   5773         if (pmc->phy[idx] == NULL) {
   5774             return(SOC_E_INTERNAL);
   5775         }
   5776 
   5777         pm_phy = &pmc->phy[idx]->pm_phy;
   5778         if (pm_phy == NULL) {
   5779             return(SOC_E_INTERNAL);
   5780         }
   5781         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5782         pm_phy_copy.port_loc = phymodPortLocLine;
   5783         if(intf == PHY82764_SYS_SIDE) {
   5784             pm_phy_copy.port_loc = phymodPortLocSys;
   5785             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5786         }
   5787 
   5788         sal_memset(&fw_config, 0, sizeof(fw_config));
   5789         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   5790 
   5791         if (enable) {
   5792             fw_config.DfeOn = 1;
   5793         } else {
   5794             fw_config.DfeOn = 0;
   5795         }
   5796 
   5797         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   5798     }
   5799 
   5800     return(SOC_E_NONE);
   5801 }
   5802 
   5803 /*
   5804  * phy_82764_firmware_lp_dfe_enable_set
   5805  */
   5806 STATIC int
   5807 phy_82764_firmware_lp_dfe_enable_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 enable)
   5808 {
   5809     int idx;
   5810     soc_phymod_ctrl_t *pmc;
   5811     phymod_phy_access_t pm_phy_copy;
   5812     phymod_phy_access_t *pm_phy;
   5813     phymod_firmware_lane_config_t fw_config;
   5814     pmc = &pc->phymod_ctrl;
   5815 
   5816     /* loop through all cores */
   5817     for (idx = 0; idx < pmc->num_phys; idx++) {
   5818         if (pmc->phy[idx] == NULL) {
   5819             return(SOC_E_INTERNAL);
   5820         }
   5821 
   5822         pm_phy = &pmc->phy[idx]->pm_phy;
   5823         if (pm_phy == NULL) {
   5824             return(SOC_E_INTERNAL);
   5825         }
   5826 
   5827         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5828         pm_phy_copy.port_loc = phymodPortLocLine;
   5829         if(intf == PHY82764_SYS_SIDE) {
   5830             pm_phy_copy.port_loc = phymodPortLocSys;
   5831             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5832         }
   5833 
   5834         sal_memset(&fw_config, 0, sizeof(fw_config));
   5835         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   5836 
   5837         if (enable) {
   5838             fw_config.DfeOn = 1;
   5839             fw_config.LpDfeOn = 1;
   5840         } else {
   5841             fw_config.LpDfeOn = 0;
   5842         }
   5843 
   5844         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   5845     }
   5846 
   5847     return(SOC_E_NONE);
   5848 }
   5849 
   5850 /*
   5851  * phy_82764_unreliable_los_set
   5852  */
   5853 STATIC int
   5854 phy_82764_unreliable_los_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 enable)
   5855 {
   5856     int idx;
   5857     soc_phymod_ctrl_t *pmc;
   5858     phymod_phy_access_t pm_phy_copy;
   5859     phymod_phy_access_t *pm_phy;
   5860     phymod_firmware_lane_config_t fw_config;
   5861     pmc = &pc->phymod_ctrl;
   5862 
   5863     /* loop through all cores */
   5864     for (idx = 0; idx < pmc->num_phys; idx++) {
   5865         if (pmc->phy[idx] == NULL) {
   5866             return(SOC_E_INTERNAL);
   5867         }
   5868 
   5869         pm_phy = &pmc->phy[idx]->pm_phy;
   5870         if (pm_phy == NULL) {
   5871             return(SOC_E_INTERNAL);
   5872         }
   5873 
   5874         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5875         pm_phy_copy.port_loc = phymodPortLocLine;
   5876         if(intf == PHY82764_SYS_SIDE) {
   5877             pm_phy_copy.port_loc = phymodPortLocSys;
   5878             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5879         }
   5880 
   5881         sal_memset(&fw_config, 0, sizeof(fw_config));
   5882         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   5883 
   5884         if (enable) {
   5885             fw_config.UnreliableLos = 1;
   5886         } else {
   5887             fw_config.UnreliableLos = 0;
   5888         }
   5889 
   5890         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   5891     }
   5892 
   5893     return(SOC_E_NONE);
   5894 }
   5895 
   5896 /*
   5897  * phy_82764_firmware_mode_get
   5898  */
   5899 STATIC int
   5900 phy_82764_firmware_mode_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 *value)
   5901 {
   5902     soc_phymod_ctrl_t *pmc;
   5903     phymod_phy_access_t pm_phy_copy;
   5904     phymod_phy_access_t *pm_phy;
   5905     phymod_firmware_lane_config_t fw_config;
   5906     pmc = &pc->phymod_ctrl;
   5907     *value = 0;
   5908 
   5909     /* just take the value from the first phy */
   5910     if (pmc->phy[0] == NULL) {
   5911         return SOC_E_INTERNAL;
   5912     }
   5913 
   5914     pm_phy = &pmc->phy[0]->pm_phy;
   5915     if (pm_phy == NULL) {
   5916         return SOC_E_INTERNAL;
   5917     }
   5918 
   5919     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5920     pm_phy_copy.port_loc = phymodPortLocLine;
   5921     if(intf == PHY82764_SYS_SIDE) {
   5922         pm_phy_copy.port_loc = phymodPortLocSys;
   5923         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5924     }
   5925 
   5926     sal_memset(&fw_config, 0, sizeof(fw_config));
   5927     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   5928 
   5929     if ((fw_config.LpDfeOn) && (fw_config.DfeOn)) {
   5930         *value = SOC_PHY_FIRMWARE_LP_DFE_ENABLE;
   5931     } else if (fw_config.MediaType == phymodFirmwareMediaTypeCopperCable) {
   5932         *value = SOC_PHY_FIRMWARE_SFP_DAC;
   5933     } else if (fw_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane) {
   5934         *value = SOC_PHY_FIRMWARE_XLAUI;
   5935     } else if (fw_config.MediaType == phymodFirmwareMediaTypeOptics){
   5936         *value = SOC_PHY_FIRMWARE_SFP_OPT_SR4;
   5937     } else if ((fw_config.DfeOn) && (fw_config.ForceBrDfe == 0) && (fw_config.LpDfeOn == 0)) {
   5938         *value = SOC_PHY_FIRMWARE_DFE_ENABLE;
   5939     } else if ((fw_config.DfeOn) && (fw_config.ForceBrDfe == 0)) {
   5940         *value = SOC_PHY_FIRMWARE_FORCE_OSDFE;
   5941     } else {
   5942         *value = SOC_PHY_FIRMWARE_DEFAULT;
   5943     }
   5944 
   5945     return(SOC_E_NONE);
   5946 }
   5947 /*
   5948  * phy_82764_firmware_dfe_enable_get
   5949  */
   5950 STATIC int
   5951 phy_82764_firmware_dfe_enable_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 *value)
   5952 {
   5953     soc_phymod_ctrl_t *pmc;
   5954     phymod_phy_access_t pm_phy_copy;
   5955     phymod_phy_access_t *pm_phy;
   5956     phymod_firmware_lane_config_t fw_config;
   5957     pmc = &pc->phymod_ctrl;
   5958     *value = 0;
   5959 
   5960     /* just take the value from the first phy */
   5961     if (pmc->phy[0] == NULL) {
   5962         return SOC_E_INTERNAL;
   5963     }
   5964 
   5965     pm_phy = &pmc->phy[0]->pm_phy;
   5966     if (pm_phy == NULL) {
   5967         return SOC_E_INTERNAL;
   5968     }
   5969 
   5970     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5971     pm_phy_copy.port_loc = phymodPortLocLine;
   5972     if(intf == PHY82764_SYS_SIDE) {
   5973         pm_phy_copy.port_loc = phymodPortLocSys;
   5974         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   5975     }
   5976 
   5977     sal_memset(&fw_config, 0, sizeof(fw_config));
   5978     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   5979 
   5980     if (fw_config.DfeOn) {
   5981         *value = 1;
   5982     } else {
   5983         *value = 0;
   5984     }
   5985 
   5986     return(SOC_E_NONE);
   5987 }
   5988 /*
   5989  * phy_82764_firmware_lp_dfe_enable_get
   5990  */
   5991 STATIC int
   5992 phy_82764_firmware_lp_dfe_enable_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 *value)
   5993 {
   5994     soc_phymod_ctrl_t *pmc;
   5995     phymod_phy_access_t *pm_phy;
   5996     phymod_firmware_lane_config_t fw_config;
   5997     phymod_phy_access_t pm_phy_copy;
   5998     pmc = &pc->phymod_ctrl;
   5999     *value = 0;
   6000 
   6001     /* just take the value from the first phy */
   6002     if (pmc->phy[0] == NULL) {
   6003         return SOC_E_INTERNAL;
   6004     }
   6005 
   6006     pm_phy = &pmc->phy[0]->pm_phy;
   6007     if (pm_phy == NULL) {
   6008         return SOC_E_INTERNAL;
   6009     }
   6010 
   6011     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6012     pm_phy_copy.port_loc = phymodPortLocLine;
   6013     if(intf == PHY82764_SYS_SIDE) {
   6014         pm_phy_copy.port_loc = phymodPortLocSys;
   6015         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6016     }
   6017 
   6018     sal_memset(&fw_config, 0, sizeof(fw_config));
   6019     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   6020 
   6021     if (fw_config.LpDfeOn && fw_config.DfeOn) {
   6022         *value = 1;
   6023     } else {
   6024         *value = 0;
   6025     }
   6026 
   6027     return(SOC_E_NONE);
   6028 }
   6029 
   6030 /*
   6031  * phy_82764_unreliable_los_get
   6032  */
   6033 STATIC int
   6034 phy_82764_unreliable_los_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, uint32 *value)
   6035 {
   6036     soc_phymod_ctrl_t *pmc;
   6037     phymod_phy_access_t *pm_phy;
   6038     phymod_firmware_lane_config_t fw_config;
   6039     phymod_phy_access_t pm_phy_copy;
   6040     pmc = &pc->phymod_ctrl;
   6041     *value = 0;
   6042 
   6043     /* just take the value from the first phy */
   6044     if (pmc->phy[0] == NULL) {
   6045         return SOC_E_INTERNAL;
   6046     }
   6047 
   6048     pm_phy = &pmc->phy[0]->pm_phy;
   6049     if (pm_phy == NULL) {
   6050         return SOC_E_INTERNAL;
   6051     }
   6052 
   6053     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6054     pm_phy_copy.port_loc = phymodPortLocLine;
   6055     if(intf == PHY82764_SYS_SIDE) {
   6056         pm_phy_copy.port_loc = phymodPortLocSys;
   6057         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6058     }
   6059 
   6060     sal_memset(&fw_config, 0, sizeof(fw_config));
   6061     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   6062     if (fw_config.UnreliableLos) {
   6063         *value = 1;
   6064     } else {
   6065         *value = 0;
   6066     }
   6067 
   6068     return(SOC_E_NONE);
   6069 }
   6070 
   6071 STATIC int phy_82764_diag_eyescan(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int32 lane)
   6072 {
   6073     phymod_phy_access_t     *pm_phy;
   6074     int                     idx = 0, rv = 0;
   6075     phymod_phy_access_t     pm_phy_copy;
   6076     soc_phymod_phy_t        *p_phy;
   6077     uint32_t                lane_map = 0;
   6078 
   6079 
   6080     for (idx = 0; idx < pmc->num_phys; idx++) {
   6081         if (pmc->phy[idx] == NULL) {
   6082             return SOC_E_INTERNAL;
   6083         }
   6084         p_phy = pmc->phy[idx];
   6085         /* Make a copy of the phy access and overwrite the desired lane */
   6086         pm_phy = &p_phy->pm_phy;
   6087         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6088         pm_phy_copy.port_loc = phymodPortLocLine;
   6089         if(intf == PHY_DIAG_INTF_SYS) {
   6090             pm_phy_copy.port_loc = phymodPortLocSys;
   6091             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6092         }
   6093         if (lane == 0xf) {
   6094             /* Get p_phy alone and let lane map be as Phy structure value */
   6095             lane = 1;
   6096             SOC_IF_ERROR_RETURN(
   6097                     _phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6098             lane = 0xf;
   6099         } else {
   6100             SOC_IF_ERROR_RETURN(
   6101                 _phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6102         }
   6103 
   6104         /* Make a copy of the phy access and overwrite the desired lane */
   6105         if (lane != 0xf) {
   6106            pm_phy_copy.access.lane_mask = lane_map;
   6107         }
   6108 
   6109         eye_scan_enabled = 1;
   6110         rv = phymod_phy_eyescan_run(&pm_phy_copy, PHYMOD_EYESCAN_F_DONE, 0, NULL);
   6111         if (rv != SOC_E_NONE) {
   6112             eye_scan_enabled = 0;
   6113             return rv;
   6114         }
   6115     }
   6116     eye_scan_enabled = 0;
   6117 
   6118     return SOC_E_NONE;
   6119 }
   6120 
   6121 STATIC int phy_82764_diag_ber(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int32 lane, void *params)
   6122 {
   6123     phymod_phy_access_t     *pm_phy;
   6124     int                     idx = 0, rv = 0;
   6125     phymod_phy_access_t     pm_phy_copy;
   6126     soc_phymod_phy_t        *p_phy;
   6127     uint32_t                lane_map = 0;
   6128     phymod_phy_eyescan_options_t eyescan_options;
   6129 
   6130     for (idx = 0; idx < pmc->num_phys; idx++) {
   6131         if (pmc->phy[idx] == NULL) {
   6132             return SOC_E_INTERNAL;
   6133         }
   6134         p_phy = pmc->phy[idx];
   6135         /* Make a copy of the phy access and overwrite the desired lane */
   6136         pm_phy = &p_phy->pm_phy;
   6137         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6138         pm_phy_copy.port_loc = phymodPortLocLine;
   6139         if(intf == PHY_DIAG_INTF_SYS) {
   6140             pm_phy_copy.port_loc = phymodPortLocSys;
   6141             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6142         }
   6143         if (lane == 0xf) {
   6144             /* Get p_phy alone and let lane map be as Phy structure value */
   6145             lane = 1;
   6146             SOC_IF_ERROR_RETURN(
   6147                     _phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6148             lane = 0xf;
   6149         } else {
   6150             SOC_IF_ERROR_RETURN(
   6151                 _phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6152         }
   6153 
   6154         /* Make a copy of the phy access and overwrite the desired lane */
   6155         if (lane != 0xf) {
   6156            pm_phy_copy.access.lane_mask = lane_map;
   6157         }
   6158 
   6159         eye_scan_enabled = 1;
   6160         /* following param are used in BER projection */
   6161         sal_memset(&eyescan_options, 0, sizeof(phymod_phy_eyescan_options_t));
   6162         eyescan_options.ber_proj_scan_mode = ((soc_port_phy_eyescan_params_t *)params)->ber_proj_scan_mode;
   6163         eyescan_options.ber_proj_timer_cnt = ((soc_port_phy_eyescan_params_t *)params)->ber_proj_timer_cnt;
   6164         eyescan_options.ber_proj_err_cnt = ((soc_port_phy_eyescan_params_t *)params)->ber_proj_err_cnt;
   6165         rv = phymod_phy_eyescan_run(&pm_phy_copy, PHYMOD_EYESCAN_F_DONE, phymodEyescanModeBERProj, &eyescan_options);
   6166         if (rv != SOC_E_NONE) {
   6167             eye_scan_enabled = 0;
   6168             return rv;
   6169         }
   6170     }
   6171     eye_scan_enabled = 0;
   6172 
   6173     return SOC_E_NONE;
   6174 }
   6175 STATIC int 
   6176 phy_82764_diag_dsc(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf)
   6177 {
   6178     phymod_phy_access_t      *pm_phy;
   6179     int                      idx;
   6180     phymod_phy_access_t      pm_phy_copy;
   6181     soc_phymod_phy_t         *p_phy;
   6182     phymod_phy_diagnostics_t phy_diag;
   6183     uint16_t lane_index = 0;
   6184 
   6185 
   6186     for (idx = 0; idx < pmc->num_phys; idx++) {
   6187         if (pmc->phy[idx] == NULL) {
   6188             return SOC_E_INTERNAL;
   6189         }
   6190         p_phy = pmc->phy[idx];
   6191         /* Make a copy of the phy access and overwrite the desired lane */
   6192         pm_phy = &p_phy->pm_phy;
   6193         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6194         pm_phy_copy.port_loc = phymodPortLocLine;
   6195         if(intf == PHY_DIAG_INTF_SYS) {
   6196             pm_phy_copy.port_loc = phymodPortLocSys;
   6197             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6198         } 
   6199 
   6200         LOG_CLI((BSL_META_U(pmc->unit,
   6201                                     "DSC parameters for port %d\n"), port));
   6202         for (lane_index = 0; lane_index < 10; lane_index ++) {
   6203             if ((pm_phy_copy.access.lane_mask & (1 << lane_index))) {
   6204                  SOC_IF_ERROR_RETURN(phymod_phy_diagnostics_get(&pm_phy_copy, &phy_diag));
   6205 
   6206                  /* display */
   6207                  LOG_CLI((BSL_META_U(pmc->unit,
   6208                             "LaneN SIGDET VGABIASREDUCED POSTCMET OSR PMDMODE "
   6209                             "RXLOCK RXPPM TXPPM CLK90OFFSET CLKP1OFFSET P1LVL1 "
   6210                             "M1LVL1 DFE1_DCD DFE2_DCD SLICERTARGET PE ZE ME "
   6211                             "PO ZO MO HLFT HRGT VUPPR VLOWR SMSTS LNKTM "
   6212                                     "MAIN HIZ BST\n")));
   6213                  LOG_CLI((BSL_META_U(pmc->unit,
   6214                                     "%05d %03d     %06d        %07d  %03d  %05d  %05d %05d %06d  %05d        %08d "
   6215                                     "  %03d   %05d    %04d   %04d      %04d        %02d %02d %02d %02d %02d %02d"
   6216                                     " %03d  %04d %05d %05d %04d  %05d %04d %03d %03d \n"),
   6217                          lane_index, phy_diag.signal_detect, phy_diag.vga_bias_reduced,
   6218                  phy_diag.postc_metric, phy_diag.osr_mode, phy_diag.pmd_mode,
   6219                  phy_diag.rx_lock, phy_diag.rx_ppm, phy_diag.tx_ppm,
   6220                  phy_diag.clk90_offset, phy_diag.clkp1_offset,
   6221                          phy_diag.p1_lvl, phy_diag.m1_lvl, phy_diag.dfe1_dcd,
   6222                  phy_diag.dfe2_dcd, phy_diag.slicer_target, 
   6223                  phy_diag.slicer_offset.offset_pe, phy_diag.slicer_offset.offset_ze,
   6224                  phy_diag.slicer_offset.offset_me, phy_diag.slicer_offset.offset_po,
   6225                  phy_diag.slicer_offset.offset_zo,  phy_diag.slicer_offset.offset_mo,
   6226                  phy_diag.eyescan.heye_left, phy_diag.eyescan.heye_right,
   6227                  phy_diag.eyescan.veye_upper, phy_diag.eyescan.veye_lower,
   6228                  phy_diag.state_machine_status, phy_diag.link_time,
   6229                          phy_diag.pf_main, phy_diag.pf_hiz,
   6230                          phy_diag.pf_bst));
   6231                 LOG_CLI((BSL_META_U(pmc->unit,
   6232                                     "LOW PF2CTRL VGA DCOFFT P1LVLCTRL "
   6233                                     "DFE1 DFE2 DFE3 DFE4 DFE5 DFE6 PRE MAIN POST1 "
   6234                                     "POST2 POST3 TXAMPCTRL BRPDEN \n")));
   6235 
   6236                 LOG_CLI((BSL_META_U(pmc->unit,
   6237                                     "%03d %07d %03d %06d   %04d    %04d %04d %04d %04d %04d %04d %04d"
   6238                                     " %03d %04d  %05d %05d   %04d    %04d\n\n"),
   6239                          phy_diag.pf_low,
   6240                  phy_diag.pf2_ctrl, phy_diag.vga,
   6241                  phy_diag.dc_offset, phy_diag.p1_lvl_ctrl,
   6242                  phy_diag.dfe1, phy_diag.dfe2,
   6243                  phy_diag.dfe3, phy_diag.dfe4,
   6244                  phy_diag.dfe5, phy_diag.dfe6,
   6245                  phy_diag.txfir_pre, phy_diag.txfir_main,
   6246                  phy_diag.txfir_post1, phy_diag.txfir_post2,
   6247                  phy_diag.txfir_post3, phy_diag.tx_amp_ctrl,
   6248                  phy_diag.br_pd_en));
   6249             }
   6250         }
   6251     }
   6252     return SOC_E_NONE;
   6253 }
   6254 /*
   6255  * Function:
   6256  *      phy_82764_diag_ctrl
   6257  * Purpose:
   6258  *      xx
   6259  * Parameters:
   6260  *      unit - BCM unit number.
   6261  *      port - Port number. 
   6262 
   6263  * Returns:     
   6264  *      SOC_E_NONE
   6265  */
   6266 
   6267 STATIC int
   6268 phy_82764_diag_ctrl(
   6269     int unit,        /* unit */
   6270     soc_port_t port, /* port */
   6271     uint32 inst,     /* the specific device block the control action directs to */
   6272     int op_type,     /* operation types: read,write or command sequence */
   6273     int op_cmd,      /* command code */
   6274     void *arg)       /* command argument based on op_type/op_cmd */
   6275 {
   6276     int rv = -1;
   6277     int32 lane;
   6278     int32 intf;
   6279     soc_phymod_ctrl_t   *pmc;
   6280     phy_ctrl_t          *pc;
   6281     /* locate phy control, phymod control, and the configuration data */
   6282     pc = EXT_PHY_SW_STATE(unit, port);
   6283     if (pc == NULL) {
   6284         return SOC_E_INTERNAL;
   6285     }
   6286     pmc = &pc->phymod_ctrl;
   6287 
   6288     lane = PHY_DIAG_INST_LN(inst);
   6289     intf = PHY_DIAG_INST_INTF(inst);
   6290     if (intf == PHY_DIAG_INTF_DFLT) {
   6291         intf = PHY_DIAG_INTF_LINE;
   6292     }
   6293     if (intf == PHY_DIAG_INTF_SYS) {
   6294         pc->flags |= PHYCTRL_SYS_SIDE_CTRL;
   6295     } else {
   6296         pc->flags &= ~PHYCTRL_SYS_SIDE_CTRL;
   6297     }
   6298     switch(op_cmd) {
   6299         case PHY_DIAG_CTRL_DSC:
   6300             rv = phy_82764_diag_dsc(pmc, port, intf);
   6301             break;
   6302         case PHY_DIAG_CTRL_START_FAST_EYESCAN:
   6303             rv =  phy_82764_diag_eyescan(pmc, port, intf, lane);
   6304         break;
   6305         case PHY_DIAG_CTRL_BER:
   6306             rv =  phy_82764_diag_ber(pmc, port, intf, lane, arg);
   6307         break;
   6308         case PHY_DIAG_CTRL_LINKMON_MODE:
   6309         {
   6310             uint32_t value = PTR_TO_INT(arg);
   6311             rv = phy_82764_link_monitor_set(pmc, port, intf, lane, value);
   6312         }
   6313         break;
   6314         case PHY_DIAG_CTRL_LINKMON_STATUS:
   6315         {
   6316             rv = phy_82764_link_monitor_status_get(pmc, port, intf, lane);
   6317         }
   6318         break;
   6319         default:
   6320             if (op_type == PHY_DIAG_CTRL_SET) {
   6321                     rv = phy_82764_control_set(unit,port,op_cmd,PTR_TO_INT(arg));
   6322             } else if (op_type == PHY_DIAG_CTRL_GET) {
   6323                     rv = phy_82764_control_get(unit,port,op_cmd,(uint32 *)arg);
   6324             }
   6325             break ;
   6326     }
   6327 
   6328     /* clear the pc->flags  to make default as PHY_DIAG_INTF_LINE */
   6329     pc->flags &= ~PHYCTRL_SYS_SIDE_CTRL;
   6330 
   6331     /* clear the pc->flags  to make default as PHY_DIAG_INTF_LINE */
   6332     pc->flags &= ~PHYCTRL_SYS_SIDE_CTRL;
   6333 
   6334     return rv;
   6335 }
   6336 
   6337 int32 phy_82764_core_reset(int32 unit, soc_port_t port, void *not_used)
   6338 {
   6339     phy_ctrl_t                *pc;
   6340     soc_phymod_core_t *pmc_core;
   6341     int                  idx;
   6342     phymod_core_access_t *pm_core;
   6343     soc_phymod_ctrl_t *pmc;
   6344     phymod_core_status_t core_status;
   6345     phymod_reset_direction_t reset_direction;
   6346     /* locate phy control */
   6347     pc = EXT_PHY_SW_STATE(unit, port);
   6348     if (pc == NULL) {
   6349         return SOC_E_INTERNAL;
   6350     }
   6351     reset_direction = phymodResetDirectionIn;
   6352     pmc = &pc->phymod_ctrl; 
   6353 
   6354     /* loop through all cores */
   6355     for (idx = 0; idx < pmc->num_phys; idx++) {
   6356         pmc_core = pmc->phy[idx]->core;
   6357         pm_core = &pmc_core->pm_core;
   6358         if (pm_core == NULL) {
   6359             return SOC_E_INTERNAL;
   6360         }
   6361 
   6362         SOC_IF_ERROR_RETURN(phymod_core_reset_set(pm_core, phymodResetModeHard, reset_direction));
   6363         core_status.pmd_active = 0;
   6364         SOC_IF_ERROR_RETURN
   6365             (phymod_core_init(&pmc_core->pm_core, &pmc_core->init_config, &core_status));
   6366     }
   6367 
   6368     return(SOC_E_NONE);
   6369 }
   6370 
   6371 /* 
   6372  * phy_82764_per_lane_tx_set
   6373  */
   6374 STATIC int
   6375 phy_82764_per_lane_tx_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, soc_phy_control_t type, int lane, uint32 value)
   6376 {
   6377     soc_phymod_phy_t    *p_phy;
   6378     uint32              lane_map;
   6379     phymod_phy_access_t pm_phy_copy, *pm_phy;
   6380     phymod_tx_t         phymod_tx;
   6381 
   6382     /* locate the desired phy and lane */
   6383     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6384 
   6385     /* Make a copy of the phy access and overwrite the desired lane */
   6386     pm_phy = &p_phy->pm_phy;
   6387     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6388     pm_phy_copy.access.lane_mask = lane_map;
   6389     pm_phy_copy.port_loc = phymodPortLocLine;
   6390     if(intf == PHY82764_SYS_SIDE) {
   6391         pm_phy_copy.port_loc = phymodPortLocSys;
   6392     } 
   6393     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   6394     switch (type) {
   6395         case SOC_PHY_CONTROL_TX_FIR_PRE:
   6396             phymod_tx.pre = value;
   6397             break;
   6398         case SOC_PHY_CONTROL_TX_FIR_MAIN:
   6399             phymod_tx.main = value;
   6400             break;
   6401         case SOC_PHY_CONTROL_TX_FIR_POST:
   6402             phymod_tx.post = value;
   6403             break;
   6404         case SOC_PHY_CONTROL_TX_FIR_POST2:
   6405             phymod_tx.post2 = value;
   6406             break;
   6407         case SOC_PHY_CONTROL_TX_FIR_POST3:
   6408             phymod_tx.post3 = value;
   6409             break;
   6410         default:
   6411             return SOC_E_UNAVAIL;
   6412     }
   6413 
   6414     SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   6415 
   6416     return(SOC_E_NONE);
   6417 }
   6418 
   6419 /* 
   6420  * phy_82764_per_lane_tx_get
   6421  */
   6422 STATIC int
   6423 phy_82764_per_lane_tx_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, soc_phy_control_t type, int lane, uint32 *value)
   6424 {
   6425     soc_phymod_phy_t    *p_phy;
   6426     uint32              lane_map;
   6427     phymod_phy_access_t pm_phy_copy, *pm_phy;
   6428     phymod_tx_t         phymod_tx;
   6429 
   6430     /* locate the desired phy and lane */
   6431     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6432 
   6433     /* Make a copy of the phy access and overwrite the desired lane */
   6434     pm_phy = &p_phy->pm_phy;
   6435     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6436     pm_phy_copy.access.lane_mask = lane_map;
   6437     pm_phy_copy.port_loc = phymodPortLocLine;
   6438     if(intf == PHY82764_SYS_SIDE) {
   6439         pm_phy_copy.port_loc = phymodPortLocSys;
   6440     } 
   6441 
   6442     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   6443     *value = phymod_tx.amp;
   6444     switch (type) {
   6445         case SOC_PHY_CONTROL_TX_FIR_PRE:
   6446             *value = phymod_tx.pre;
   6447             break;
   6448         case SOC_PHY_CONTROL_TX_FIR_MAIN:
   6449             *value = phymod_tx.main;
   6450             break;
   6451         case SOC_PHY_CONTROL_TX_FIR_POST:
   6452             *value = phymod_tx.post;
   6453             break;
   6454         case SOC_PHY_CONTROL_TX_FIR_POST2:
   6455             *value = phymod_tx.post2;
   6456             break;
   6457         case SOC_PHY_CONTROL_TX_FIR_POST3:
   6458             *value = phymod_tx.post3;
   6459             break;
   6460         default:
   6461             return SOC_E_UNAVAIL;
   6462     }
   6463 
   6464     return(SOC_E_NONE);
   6465 }
   6466 
   6467 /*
   6468 * Function:
   6469 *      _phy_84328_ability_remote_get
   6470 * Purpose:
   6471 *      Get the device's complete abilities.
   6472 * Parameters:
   6473 *      unit - StrataSwitch unit #.
   6474 *      port - StrataSwitch port #.
   6475 *      ability - return device's abilities.
   6476 * Returns:
   6477 *      SOC_E_XXX
   6478 */
   6479 STATIC int
   6480 phy_82764_ability_remote_get(int unit, soc_port_t port, 
   6481                                   soc_port_ability_t *ability)
   6482 {
   6483     int  an = 0, an_done = 0;
   6484     int  line_intf;
   6485     uint32_t an_cap = 0;
   6486     phy_ctrl_t *pc, *int_pc;
   6487     soc_phymod_ctrl_t         *pmc;
   6488     phy82764_config_t         *pCfg;
   6489     soc_phymod_phy_t          *phy;
   6490     phymod_autoneg_ability_t  phymod_autoneg_ability;
   6491 
   6492 
   6493     if (ability == NULL) {
   6494         return SOC_E_PARAM;
   6495     }
   6496     pc = EXT_PHY_SW_STATE(unit, port);
   6497 
   6498 
   6499     /* Only firmware has visibility into remote ability */
   6500     sal_memset(ability, 0, sizeof(soc_port_ability_t));
   6501 
   6502     pmc = &pc->phymod_ctrl;
   6503     pCfg = (phy82764_config_t *) pc->driver_data;
   6504 
   6505     /* only set abilities on the first core */
   6506     phy = pmc->phy[pmc->main_phy];
   6507     if (phy == NULL) {
   6508         return SOC_E_INTERNAL;
   6509     }
   6510     phymod_autoneg_ability_t_init(&phymod_autoneg_ability);
   6511 
   6512 
   6513     line_intf = pCfg->speed_config.line_interface;
   6514 
   6515     if ((line_intf == SOC_PORT_IF_KX) || (line_intf == SOC_PORT_IF_GMII)) {
   6516         int_pc = INT_PHY_SW_STATE(unit, port);
   6517         if (int_pc) {
   6518             SOC_IF_ERROR_RETURN(PHY_ABILITY_REMOTE_GET(int_pc->pd, unit, port, ability));
   6519         }
   6520         return SOC_E_NONE;
   6521     }
   6522 
   6523     ability->speed_half_duplex  = SOC_PA_ABILITY_NONE;
   6524 
   6525     /* Return what the firmware is setting */
   6526     /* If an done, then return the speed for the port */
   6527     SOC_IF_ERROR_RETURN(phy_82764_an_get(unit, port, &an, &an_done));
   6528     if (an && an_done) {
   6529        SOC_IF_ERROR_RETURN
   6530         (phymod_phy_autoneg_remote_ability_get(&phy->pm_phy, &phymod_autoneg_ability));
   6531        an_cap = phymod_autoneg_ability.an_cap;
   6532        ability->speed_full_duplex |= PHYMOD_AN_CAP_100G_CR4_GET(an_cap) ? SOC_PA_SPEED_100GB : 0;
   6533        ability->speed_full_duplex |= PHYMOD_AN_CAP_100G_KR4_GET(an_cap) ? SOC_PA_SPEED_100GB : 0;
   6534        ability->speed_full_duplex |= PHYMOD_AN_CAP_40G_CR4_GET(an_cap) ? SOC_PA_SPEED_40GB : 0;
   6535        ability->speed_full_duplex |= PHYMOD_AN_CAP_40G_KR4_GET(an_cap) ? SOC_PA_SPEED_40GB : 0;
   6536 
   6537         an_cap = phymod_autoneg_ability.capabilities;
   6538         if (an_cap == PHYMOD_AN_CAP_ASYM_PAUSE) {
   6539             ability->pause = SOC_PA_PAUSE_TX;
   6540         } else if (an_cap == (PHYMOD_AN_CAP_SYMM_PAUSE | PHYMOD_AN_CAP_ASYM_PAUSE)) {
   6541             ability->pause = SOC_PA_PAUSE_RX;
   6542         } else if (an_cap == PHYMOD_AN_CAP_SYMM_PAUSE) {
   6543             ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX);
   6544         }
   6545     }
   6546     LOG_INFO(BSL_LS_SOC_PHY,
   6547              (BSL_META_U(unit,
   6548                          "phy_82764_ability_remote_get: u=%d p=%d speed(FD)=0x%x pause=0x%x\n"),
   6549               unit, port, ability->speed_full_duplex, ability->pause));
   6550 
   6551     return SOC_E_NONE;
   6552 }
   6553 
   6554 STATIC int
   6555 phy_82764_per_lane_short_chn_mode_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   6556 {
   6557     phymod_phy_access_t *pm_phy;
   6558     phymod_phy_access_t pm_phy_copy;
   6559     soc_phymod_phy_t    *p_phy;
   6560     uint32              lane_map;
   6561 
   6562     /* locate the desired phy and lane */
   6563     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6564 
   6565     /* Make a copy of the phy access and overwrite the desired lane */
   6566     pm_phy = &p_phy->pm_phy;
   6567     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6568     pm_phy_copy.access.lane_mask = lane_map;
   6569     pm_phy_copy.port_loc = phymodPortLocLine;
   6570     if(intf == PHY82764_SYS_SIDE) {
   6571         pm_phy_copy.port_loc = phymodPortLocSys;
   6572     }
   6573 
   6574     SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_set(&pm_phy_copy, value));
   6575 
   6576     return(SOC_E_NONE);
   6577 }
   6578 
   6579 STATIC int
   6580 phy_82764_per_lane_short_chn_mode_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   6581 {
   6582     phymod_phy_access_t *pm_phy;
   6583     phymod_phy_access_t pm_phy_copy;
   6584     soc_phymod_phy_t    *p_phy;
   6585     uint32              lane_map, status = 0;
   6586 
   6587     /* locate the desired phy and lane */
   6588     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6589 
   6590     /* Make a copy of the phy access and overwrite the desired lane */
   6591     pm_phy = &p_phy->pm_phy;
   6592     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6593     pm_phy_copy.access.lane_mask = lane_map;
   6594     pm_phy_copy.port_loc = phymodPortLocLine;
   6595     if(intf == PHY82764_SYS_SIDE) {
   6596         pm_phy_copy.port_loc = phymodPortLocSys;
   6597     }
   6598 
   6599     SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_get(&pm_phy_copy, value, &status));
   6600 
   6601     return(SOC_E_NONE);
   6602 }
   6603 
   6604 STATIC int
   6605 phy_82764_per_lane_short_chn_mode_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   6606 {
   6607     phymod_phy_access_t *pm_phy;
   6608     phymod_phy_access_t pm_phy_copy;
   6609     soc_phymod_phy_t    *p_phy;
   6610     uint32              lane_map, enable = 0;
   6611 
   6612     /* locate the desired phy and lane */
   6613     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6614 
   6615     /* Make a copy of the phy access and overwrite the desired lane */
   6616     pm_phy = &p_phy->pm_phy;
   6617     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6618     pm_phy_copy.access.lane_mask = lane_map;
   6619     pm_phy_copy.port_loc = phymodPortLocLine;
   6620     if(intf == PHY82764_SYS_SIDE) {
   6621         pm_phy_copy.port_loc = phymodPortLocSys;
   6622     }
   6623 
   6624     SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_get(&pm_phy_copy, &enable, value));
   6625 
   6626     return(SOC_E_NONE);
   6627 }
   6628 
   6629 STATIC int
   6630 phy_82764_per_lane_cl72_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 value)
   6631 {
   6632     phymod_phy_access_t *pm_phy;
   6633     phymod_phy_access_t pm_phy_copy;
   6634     soc_phymod_phy_t    *p_phy;
   6635     uint32              lane_map;
   6636 
   6637     /* locate the desired phy and lane */
   6638     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6639 
   6640     /* Make a copy of the phy access and overwrite the desired lane */
   6641     pm_phy = &p_phy->pm_phy;
   6642     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6643     pm_phy_copy.access.lane_mask = lane_map;
   6644     pm_phy_copy.port_loc = phymodPortLocLine;
   6645     if(intf == PHY82764_SYS_SIDE) {
   6646         pm_phy_copy.port_loc = phymodPortLocSys;
   6647     }
   6648     LOG_CLI((BSL_META_U(0,"Tx training: %d port loc:0x%x\n"), value, pm_phy_copy.port_loc));
   6649 
   6650     SOC_IF_ERROR_RETURN(phymod_phy_cl72_set(&pm_phy_copy, value));
   6651 
   6652     return(SOC_E_NONE);
   6653 }
   6654 
   6655 STATIC int
   6656 phy_82764_per_lane_cl72_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   6657 {
   6658     phymod_phy_access_t  *pm_phy;
   6659     phymod_phy_access_t  pm_phy_copy;
   6660     phymod_cl72_status_t status;
   6661     soc_phymod_phy_t    *p_phy;
   6662     uint32              lane_map;
   6663 
   6664     /* locate the desired phy and lane */
   6665     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6666 
   6667     /* Make a copy of the phy access and overwrite the desired lane */
   6668     pm_phy = &p_phy->pm_phy;
   6669     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6670     pm_phy_copy.access.lane_mask = lane_map;
   6671     pm_phy_copy.port_loc = phymodPortLocLine;
   6672     if(intf == PHY82764_SYS_SIDE) {
   6673         pm_phy_copy.port_loc = phymodPortLocSys;
   6674     }
   6675 
   6676     sal_memset(&status, 0, sizeof(status));
   6677     SOC_IF_ERROR_RETURN(phymod_phy_cl72_status_get(&pm_phy_copy, &status));
   6678     *value = status.locked;
   6679 
   6680     LOG_CLI((BSL_META_U(0,"Tx training Sts: %d Flags:0x%x\n"), *value, pm_phy_copy.access.flags));
   6681 
   6682     return(SOC_E_NONE);
   6683 }
   6684 
   6685 STATIC int
   6686 phy_82764_per_lane_cl72_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int lane, uint32 *value)
   6687 {
   6688     phymod_phy_access_t *pm_phy;
   6689     phymod_phy_access_t pm_phy_copy;
   6690     soc_phymod_phy_t    *p_phy;
   6691     uint32              lane_map;
   6692 
   6693     /* locate the desired phy and lane */
   6694     SOC_IF_ERROR_RETURN(_phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6695 
   6696     /* Make a copy of the phy access and overwrite the desired lane */
   6697     pm_phy = &p_phy->pm_phy;
   6698     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6699     pm_phy_copy.access.lane_mask = lane_map;
   6700     pm_phy_copy.port_loc = phymodPortLocLine;
   6701     if(intf == PHY82764_SYS_SIDE) {
   6702         pm_phy_copy.port_loc = phymodPortLocSys;
   6703     }
   6704 
   6705     SOC_IF_ERROR_RETURN(phymod_phy_cl72_get(&pm_phy_copy, value));
   6706 
   6707     return(SOC_E_NONE);
   6708 }
   6709 
   6710 STATIC int
   6711 phy_82764_link_monitor_set (soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int32 lane, uint32 value)
   6712 {
   6713     phymod_phy_access_t *pm_phy;
   6714     soc_phymod_phy_t    *p_phy;
   6715     uint32              lane_map = 0;
   6716     phymod_phy_access_t pm_phy_copy;
   6717     uint32_t            link_mon_mode = 0;
   6718 
   6719     intf = (intf == PHY_DIAG_INTF_LINE) ? PHY82764_LINE_SIDE : PHY82764_SYS_SIDE;
   6720 
   6721     if (lane == 0xf) {
   6722         /* Get p_phy alone and let lane map be as Phy structure value */
   6723         lane = 1;
   6724         SOC_IF_ERROR_RETURN(
   6725                 _phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6726         lane = 0xf;
   6727     } else {
   6728         SOC_IF_ERROR_RETURN(
   6729                 _phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6730     }
   6731     /* Make a copy of the phy access and overwrite the desired lane */
   6732     pm_phy = &p_phy->pm_phy;
   6733     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6734     if (lane != 0xf) {
   6735         pm_phy_copy.access.lane_mask = lane_map;
   6736     }
   6737 
   6738     pm_phy_copy.port_loc = phymodPortLocLine;
   6739     if(intf == PHY82764_SYS_SIDE) {
   6740         pm_phy_copy.port_loc = phymodPortLocSys;
   6741         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6742     }
   6743 
   6744     if (value == 0) {
   6745         SOC_IF_ERROR_RETURN(
   6746             phymod_phy_link_mon_enable_set(&pm_phy_copy, 0 /*When disable Dont care*/, 0));
   6747     } else {
   6748         link_mon_mode = value - 1;
   6749         SOC_IF_ERROR_RETURN(
   6750             phymod_phy_link_mon_enable_set(&pm_phy_copy, link_mon_mode, 1));
   6751     }
   6752 
   6753     return(SOC_E_NONE);
   6754 }
   6755 
   6756 STATIC int
   6757 phy_82764_link_monitor_status_get (soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, int32 lane)
   6758 {
   6759     phymod_phy_access_t *pm_phy;
   6760     soc_phymod_phy_t    *p_phy;
   6761     uint32              lane_map = 0;
   6762     phymod_phy_access_t pm_phy_copy;
   6763     uint32_t lock_status = 0, lock_lost_lh = 0, error_count = 0;
   6764 
   6765     intf = (intf == PHY_DIAG_INTF_LINE) ? PHY82764_LINE_SIDE : PHY82764_SYS_SIDE;
   6766 
   6767     if (lane == 0xf) {
   6768         /* Get p_phy alone and let lane map be as Phy structure value */
   6769         lane = 1;
   6770         SOC_IF_ERROR_RETURN(
   6771                 _phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6772         lane = 0xf;
   6773     } else {
   6774         SOC_IF_ERROR_RETURN(
   6775                 _phy_82764_find_soc_phy_lane(pmc, port, lane, &p_phy, &lane_map));
   6776     }
   6777     /* Make a copy of the phy access and overwrite the desired lane */
   6778     pm_phy = &p_phy->pm_phy;
   6779     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6780     if (lane != 0xf) {
   6781         pm_phy_copy.access.lane_mask = lane_map;
   6782     }
   6783 
   6784     pm_phy_copy.port_loc = phymodPortLocLine;
   6785 
   6786     if(intf == PHY82764_SYS_SIDE) {
   6787         pm_phy_copy.port_loc = phymodPortLocSys;
   6788         SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6789     }
   6790 
   6791     SOC_IF_ERROR_RETURN(
   6792           phymod_phy_link_mon_status_get(&pm_phy_copy, &lock_status, &lock_lost_lh, &error_count));
   6793 
   6794     if (lane != 0xF) {
   6795         LOG_CLI((BSL_META_U(0,"Lane:%d Lock Status:%d lock lost:%d Error count:%d\n "),
   6796                 lane, lock_status, lock_lost_lh, error_count));
   6797     } else {
   6798         LOG_CLI((BSL_META_U(0,"Lane Map:0x%x Lock Status:%d lock lost:%d Error count:%d\n "),
   6799                 pm_phy_copy.access.lane_mask, lock_status, lock_lost_lh, error_count));
   6800     }
   6801 
   6802     return(SOC_E_NONE);
   6803 
   6804 }
   6805 STATIC int
   6806 phy_82764_intr_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   6807 {
   6808     phymod_phy_access_t     *pm_phy;
   6809     int                     idx;
   6810     phymod_phy_access_t pm_phy_copy;
   6811     for (idx = 0; idx < pmc->num_phys; idx++) {
   6812         pm_phy = &pmc->phy[idx]->pm_phy;
   6813 
   6814         if (pm_phy == NULL) {
   6815             return SOC_E_INTERNAL;
   6816         }
   6817         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6818         pm_phy_copy.port_loc = phymodPortLocLine;
   6819 
   6820         if (intf == PHY82764_SYS_SIDE) {
   6821             pm_phy_copy.port_loc = phymodPortLocSys;
   6822             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6823         }
   6824 
   6825         SOC_IF_ERROR_RETURN(phymod_phy_intr_enable_set(&pm_phy_copy, value));
   6826     }
   6827 
   6828     return(SOC_E_NONE);
   6829 }
   6830 
   6831 STATIC int
   6832 phy_82764_intr_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value)
   6833 {
   6834     phymod_phy_access_t     *pm_phy;
   6835     int                     idx;
   6836     phymod_phy_access_t pm_phy_copy;
   6837 
   6838     *value = 0;
   6839     for (idx = 0; idx < pmc->num_phys; idx++) {
   6840         pm_phy = &pmc->phy[idx]->pm_phy;
   6841 
   6842         if (pm_phy == NULL) {
   6843             return SOC_E_INTERNAL;
   6844         }
   6845         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6846         pm_phy_copy.port_loc = phymodPortLocLine;
   6847 
   6848         if (intf == PHY82764_SYS_SIDE) {
   6849             pm_phy_copy.port_loc = phymodPortLocSys;
   6850             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6851         }
   6852 
   6853         SOC_IF_ERROR_RETURN(phymod_phy_intr_enable_get(&pm_phy_copy, value));
   6854     }
   6855 
   6856     return(SOC_E_NONE);
   6857 }
   6858 
   6859 STATIC int
   6860 phy_82764_intr_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value)
   6861 {
   6862     phymod_phy_access_t     *pm_phy;
   6863     int                     idx;
   6864     phymod_phy_access_t pm_phy_copy;
   6865 
   6866     *value = 0;
   6867     for (idx = 0; idx < pmc->num_phys; idx++) {
   6868         pm_phy = &pmc->phy[idx]->pm_phy;
   6869 
   6870         if (pm_phy == NULL) {
   6871             return SOC_E_INTERNAL;
   6872         }
   6873         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6874         SOC_IF_ERROR_RETURN(phymod_phy_intr_status_get(&pm_phy_copy, value));
   6875         SOC_IF_ERROR_RETURN(phymod_phy_intr_status_clear(&pm_phy_copy, *value));
   6876     }
   6877 
   6878     return(SOC_E_NONE);
   6879 }
   6880 
   6881 STATIC int
   6882 phy_82764_multi_get(int unit, soc_port_t port, uint32 flags,
   6883                     uint32 dev_addr, uint32 offset, int max_size, uint8 *data,
   6884                     int *actual_size)
   6885 {
   6886     phy_ctrl_t *pc;
   6887     soc_phymod_ctrl_t *pmc;
   6888     phymod_phy_access_t *pm_phy;
   6889     phymod_multi_data_t multi_data; 
   6890     pc = EXT_PHY_SW_STATE(unit, port);
   6891     if (pc == NULL) {
   6892         return SOC_E_INTERNAL;
   6893     }
   6894     if (data == NULL) {
   6895         return SOC_E_PARAM;
   6896     }
   6897 
   6898     pmc = &pc->phymod_ctrl;
   6899     pm_phy = &pmc->phy[pmc->main_phy]->pm_phy;
   6900     multi_data.flags=flags;
   6901     multi_data.dev_addr=dev_addr;
   6902     multi_data.offset=offset;
   6903     multi_data.max_size=max_size;
   6904     multi_data.data=data;
   6905     multi_data.actual_size=(uint32_t *) actual_size;     
   6906     SOC_IF_ERROR_RETURN
   6907         (phymod_phy_multi_get(pm_phy,&multi_data));
   6908     if(actual_size){      
   6909         *actual_size=(*(multi_data.actual_size));
   6910     } 
   6911     return SOC_E_NONE;
   6912 }
   6913 
   6914 STATIC int
   6915 phy_82764_cl72_enable_set(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 value)
   6916 {
   6917     phymod_phy_access_t     *pm_phy;
   6918     int                     idx;
   6919     phymod_phy_access_t pm_phy_copy;
   6920 
   6921     for (idx = 0; idx < pmc->num_phys; idx++) {
   6922         pm_phy = &pmc->phy[idx]->pm_phy;
   6923 
   6924         if (pm_phy == NULL) {
   6925             return SOC_E_INTERNAL;
   6926         }
   6927 
   6928         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6929         pm_phy_copy.port_loc = phymodPortLocLine;
   6930 
   6931         if (intf == PHY82764_SYS_SIDE) {
   6932             pm_phy_copy.port_loc = phymodPortLocSys;
   6933             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6934         }
   6935 #ifdef PHY82764_DEBUG
   6936         LOG_CLI((BSL_META_U(0,"Tx training: %d port loc:0x%x\n"), value, pm_phy_copy.port_loc));
   6937 #endif
   6938         SOC_IF_ERROR_RETURN(phymod_phy_cl72_set(&pm_phy_copy, value));
   6939     }
   6940 
   6941     return(SOC_E_NONE);
   6942 }
   6943 
   6944 STATIC int
   6945 phy_82764_cl72_enable_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value)
   6946 {
   6947     phymod_phy_access_t     *pm_phy;
   6948     int                     idx;
   6949     phymod_phy_access_t pm_phy_copy;
   6950 
   6951     for (idx = 0; idx < pmc->num_phys; idx++) {
   6952         pm_phy = &pmc->phy[idx]->pm_phy;
   6953 
   6954         if (pm_phy == NULL) {
   6955             return SOC_E_INTERNAL;
   6956         }
   6957 
   6958         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6959         pm_phy_copy.port_loc = phymodPortLocLine;
   6960 
   6961         if (intf == PHY82764_SYS_SIDE) {
   6962             pm_phy_copy.port_loc = phymodPortLocSys;
   6963             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6964         }
   6965 
   6966         SOC_IF_ERROR_RETURN(phymod_phy_cl72_get(&pm_phy_copy, value));
   6967     }
   6968 
   6969     return(SOC_E_NONE);
   6970 }
   6971 
   6972 STATIC int
   6973 phy_82764_cl72_status_get(soc_phymod_ctrl_t *pmc, soc_port_t port, int32 intf, uint32 *value)
   6974 {
   6975     phymod_phy_access_t     *pm_phy;
   6976     int                     idx;
   6977     phymod_phy_access_t pm_phy_copy;
   6978     phymod_cl72_status_t status;
   6979 
   6980     for (idx = 0; idx < pmc->num_phys; idx++) {
   6981         pm_phy = &pmc->phy[idx]->pm_phy;
   6982 
   6983         if (pm_phy == NULL) {
   6984             return SOC_E_INTERNAL;
   6985         }
   6986 
   6987         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6988         pm_phy_copy.port_loc = phymodPortLocLine;
   6989 
   6990         if (intf == PHY82764_SYS_SIDE) {
   6991             pm_phy_copy.port_loc = phymodPortLocSys;
   6992             SOC_IF_ERROR_RETURN(_phy82764_sys_side_lane_map_get(pmc->unit, port, &pm_phy_copy));
   6993         }
   6994 
   6995         sal_memset(&status, 0, sizeof(status));
   6996         SOC_IF_ERROR_RETURN(phymod_phy_cl72_status_get(&pm_phy_copy, &status));
   6997         *value = status.locked;
   6998     }
   6999 
   7000     LOG_CLI((BSL_META_U(0,"Tx training Sts: %d Flags:0x%x\n"), *value, pm_phy_copy.access.flags));
   7001 
   7002     return(SOC_E_NONE);
   7003 }
   7004 
   7005 
   7006 /*
   7007  * Variable:
   7008  *      phy82764_drv
   7009  * Purpose:
   7010  *      Phy Driver for phy82764 
   7011  */
   7012 phy_driver_t phy82764_drv = {
   7013     /* .drv_name                      = */ "PHY82764 PHYMOD PHY Driver",
   7014     /* .pd_init                       = */ phy_82764_init,
   7015     /* .pd_reset                      = */ phy_82764_core_reset,
   7016     /* .pd_link_get                   = */ phy_82764_link_get,
   7017     /* .pd_enable_set                 = */ phy_82764_enable_set,
   7018     /* .pd_enable_get                 = */ phy_82764_enable_get,
   7019     /* .pd_duplex_set                 = */ phy_null_set,
   7020     /* .pd_duplex_get                 = */ phy82764_duplex_get,
   7021     /* .pd_speed_set                  = */ phy82764_speed_set,
   7022     /* .pd_speed_get                  = */ phy82764_speed_get,
   7023     /* .pd_master_set                 = */ phy_null_set,
   7024     /* .pd_master_get                 = */ phy_null_zero_get,
   7025     /* .pd_an_set                     = */ phy_82764_an_set,
   7026     /* .pd_an_get                     = */ phy_82764_an_get,
   7027     /* .pd_adv_local_set              = */ NULL, /* Deprecated */
   7028     /* .pd_adv_local_get              = */ NULL, /* Deprecated */
   7029     /* .pd_adv_remote_get             = */ NULL, /* Deprecated */ 
   7030     /* .pd_lb_set                     = */ phy_82764_lb_set,
   7031     /* .pd_lb_get                     = */ phy82764_lb_get,
   7032     /* .pd_interface_set              = */ phy82764_interface_set,
   7033     /* .pd_interface_get              = */ phy82764_interface_get,
   7034     /* .pd_ability                    = */ NULL, /* Deprecated */ 
   7035     /* .pd_linkup_evt                 = */ NULL,
   7036     /* .pd_linkdn_evt                 = */ NULL,
   7037     /* .pd_mdix_set                   = */ phy_null_mdix_set,
   7038     /* .pd_mdix_get                   = */ phy_null_mdix_get,
   7039     /* .pd_mdix_status_get            = */ phy_null_mdix_status_get,
   7040     /* .pd_medium_config_set          = */ NULL,
   7041     /* .pd_medium_config_get          = */ NULL,
   7042     /* .pd_medium_get                 = */ phy_null_medium_get,
   7043     /* .pd_cable_diag                 = */ NULL,
   7044     /* .pd_link_change                = */ NULL,
   7045     /* .pd_control_set                = */ phy_82764_control_set,
   7046     /* .pd_control_get                = */ phy_82764_control_get,
   7047     /* .pd_reg_read                   = */ phy82764_reg_read,
   7048     /* .pd_reg_write                  = */ phy82764_reg_write,
   7049     /* .pd_reg_modify                 = */ phy82764_reg_modify,
   7050     /* .pd_notify                     = */ NULL,
   7051     /* .pd_probe                      = */ phy82764_probe,
   7052     /* .pd_ability_advert_set         = */ phy_82764_ability_advert_set, 
   7053     /* .pd_ability_advert_get         = */ phy_82764_ability_advert_get,
   7054     /* .pd_ability_remote_get         = */ phy_82764_ability_remote_get,
   7055     /* .pd_ability_local_get          = */ phy_82764_ability_local_get,
   7056     /* .pd_firmware_set               = */ phy_82764_firmware_set,
   7057     /* .pd_timesync_config_set        = */ NULL,
   7058     /* .pd_timesync_config_get        = */ NULL,
   7059     /* .pd_timesync_control_set       = */ NULL,
   7060     /* .pd_timesync_control_set       = */ NULL,
   7061     /* .pd_diag_ctrl                  = */ phy_82764_diag_ctrl,
   7062     /* .pd_lane_control_set           = */ phy_82764_per_lane_control_set,
   7063     /* .pd_lane_control_get           = */ phy_82764_per_lane_control_get,
   7064     /* pd_lane_reg_read */                 NULL,
   7065     /* pd_lane_reg_write */                NULL,
   7066     /* pd_oam_config_set */                NULL,
   7067     /* pd_oam_config_get */                NULL,
   7068     /* pd_oam_control_set */               NULL,
   7069     /* pd_oam_control_get */               NULL,
   7070     /* pd_timesync_enhanced_capture_get */ NULL,
   7071     /* pd_multi_get */                     phy_82764_multi_get,
   7072     /* pd_precondition_before_probe */     NULL,
   7073 };
   7074 
   7075 #else
   7076 int _phy82764_not_empty;
   7077 #endif /*  INCLUDE_PHY_82764 */
   7078