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

phy82864.c (271615B)


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