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

phy82780.c (222568B)


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