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

phy82381.c (328579B)


      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:        phy82381.c
      8  * Purpose:     Support for Furia external PHY
      9  */
     10 
     11 /*
     12  *   This module implements an NTSW SDK Phy driver for the phy82381 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  *   phy82381 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 .phy82381_per_lane_control_set and
     36  *     .phy82381_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  *   furia_config_t
     60  *   Driver specific data.  This structure is used by furia to hold
     61  *   logical port specific working storage.
     62  *
     63  *   soc_phymod_ctrl_t
     64  *   PHYMOD drivers.  Resides in phy_ctrl_t specifies how many cores
     65  *   are in this phy and contains an array of pointers to
     66  *   soc_phymod_phy_t structures, which define a PHYMOD PHY.
     67  *
     68  *   soc_phymod_phy_t
     69  *   This structure contains a pointer to phymod_phy_access_t and a
     70  *   pointer to the associated soc_phymod_core_t.  Instances if this
     71  *   structure are created during device probe/init and are maintained
     72  *   by the SOC.
     73  *
     74  *   soc_phymod_core_t
     75  *   This structure contains per-core information.  Multiple PHYMOD
     76  *   PHYS can point to a single core.
     77  *
     78  *   phymod_phy_access_t
     79  *   This structure contains information about how to read/write PHY
     80  *   registers.  A required parameter for PHYMOD PHY APIs
     81  *
     82  *   phymod_core_access_t
     83  *   This structure contains information about how to read/write PHY
     84  *   registers.  A required parameter for PHYMOD core APIs.
     85  */
     86 
     87 #include <shared/bsl.h>
     88 
     89 #include <sal/types.h>
     90 #include <sal/core/spl.h>
     91 #include <shared/bsl.h>
     92 #include <soc/drv.h>
     93 #include <soc/debug.h>
     94 #include <soc/error.h>
     95 #include <soc/phyreg.h>
     96 #include <soc/port_ability.h>
     97 #include <soc/phy.h>
     98 #include <soc/phy/phyctrl.h>
     99 #include <soc/phy/drv.h>
    100 #include <soc/phy/phymod_ids.h>
    101 
    102 #include "phydefs.h"      /* Must include before other phy related includes */
    103 
    104 #include "phyconfig.h"     /* Must include before other phy related includes */
    105 #include "phyident.h"
    106 #include "phyreg.h"
    107 #include "phynull.h"
    108 #include "xgxs.h"
    109 
    110 
    111 #define PHYMOD_FURIA_SUPPORT
    112 
    113 
    114 #if defined(INCLUDE_PHY_82381)
    115 #include <phymod/phymod.h>
    116 #include <phymod/phymod_debug.h>
    117 #include <phymod/phymod_diagnostics.h>
    118 #include <phymod/chip/furia.h>
    119 
    120 #define NUM_LANES                           4    /* num of lanes per core */
    121 #define MAX_NUM_LANES                       4    /* max num of lanes per port */
    122 #define PHY82381_NO_CFG_VALUE               (-1)
    123 #define PHY82381_DBG_REGACC                 0x2
    124 #define PHY82381_DBG_MEM                    0x3
    125 #define PHY82381_PORT_NO_LANES_4            4
    126 #define PHY82381_PORT_NO_LANES_2            2
    127 #define PHY82381_PORT_NO_LANES_1            1
    128 #define PHY82381_SPD_100G                   100000
    129 #define PHY82381_SPD_106G                   106000
    130 #define PHY82381_SPD_1G                     1000
    131 #define PHY82381_SPD_10G                    10000
    132 #define PHY82381_SPD_11G                    11000
    133 #define PHY82381_SPD_20G                    20000
    134 #define PHY82381_SPD_21G                    21000
    135 #define PHY82381_SPD_25G                    25000
    136 #define PHY82381_SPD_27G                    27000
    137 #define PHY82381_SPD_40G                    40000
    138 #define PHY82381_SPD_42G                    42000
    139 #define PHY82381_SPD_50G                    50000
    140 #define PHY82381_SPD_53G                    53000
    141 #define PHY82381_SPD_6G                     6000
    142 #define INTERFACE_SIDE_SHIFT                31
    143 #define FURIA_ID_82071                      0x82071
    144 #define FURIA_ID_82070                      0x82070
    145 #define FURIA_ID_82073                      0x82073
    146 #define FURIA_ID_82072                      0x82072
    147 #define FURIA_ID_82380                      0x82380
    148 #define FURIA_ID_82381                      0x82381
    149 #define FURIA_ID_82383                      0x82383
    150 #define FURIA_ID_82208                      0x82208
    151 #define FURIA_ID_82209                      0x82209
    152 #define FURIA_ID_82212                      0x82212
    153 #define FURIA_ID_82216                      0x82216
    154 #define FURIA_ID_82314                      0x82314
    155 #define FURIA_ID_82315                      0x82315
    156 #define PHY82381_MAX_LANE                   8
    157 #define PHY82381_CHIP_ID_SIZE               25
    158 typedef struct phy82381_device_aux_mode {
    159     uint32_t repeater;
    160     uint32_t avdd_tx_drv;
    161     uint32_t ull_datapath;
    162     uint32_t an_master_lane;
    163     uint32_t core_id;
    164 } phy82381_device_aux_mode_t;
    165 
    166 typedef struct phy82381_speed_config_s {
    167     uint32  port_refclk_int;
    168     int     speed;
    169     int     port_num_lanes;
    170     uint32  line_interface;
    171     int     pll_divider_req  ;
    172     int     higig_port;
    173 } phy82381_speed_config_t;
    174 
    175 typedef enum PHY82381_INTF_SIDE {
    176     PHY82381_LINE_SIDE,
    177     PHY82381_SYS_SIDE
    178 }PHY82381_INTF_SIDE;
    179 
    180 
    181 #define FURIA_IS_SIMPLEX(devid)\
    182 ((devid) == FURIA_ID_82208 ||\
    183  (devid) == FURIA_ID_82209 ||\
    184  (devid) == FURIA_ID_82212 ||\
    185  (devid) == FURIA_ID_82216   \
    186 )
    187 
    188 #define FURIA_IS_DUPLEX(devid)\
    189 ((devid) == FURIA_ID_82071 ||\
    190  (devid) == FURIA_ID_82070 ||\
    191  (devid) == FURIA_ID_82073 ||\
    192  (devid) == FURIA_ID_82072 ||\
    193  (devid) == FURIA_ID_82380 ||\
    194  (devid) == FURIA_ID_82381 ||\
    195  (devid) == FURIA_ID_82383 ||\
    196  (devid) == FURIA_ID_82314 ||\
    197  (devid) == FURIA_ID_82315   \
    198 )
    199 
    200 /*
    201    Config - per logical port
    202 */
    203 typedef struct {
    204     phymod_polarity_t               phy_polarity_config;
    205     phymod_phy_reset_t              phy_reset_config;
    206     phy82381_speed_config_t         speed_config;
    207     int                             an_master_lane;
    208     int                             ull_datapath;
    209     uint32_t                             devid;
    210     char                            dev_name[PHY82381_CHIP_ID_SIZE];
    211     int                             auto_mod_detect;
    212     phy82381_device_aux_mode_t        *device_aux_modes ;
    213     int                             simplex_tx;
    214     unsigned int                    port_phy_lane_mask;
    215 } phy82381_config_t;
    216 
    217 #define DEVID(_pc)           (((phy82381_config_t *)((_pc) + 1))->devid)
    218 #define DEV_NAME(_pc)        (((phy82381_config_t *)((_pc) + 1))->dev_name)
    219 #define SIMPLEX_TX(_pc)   (((phy82381_config_t *)((_pc) + 1))->simplex_tx)
    220 #define PORT_PHY_LANE_MASK(_pc)   (((phy82381_config_t *)((_pc) + 1))->port_phy_lane_mask)
    221 int is_eye_scan_enabled = 0;
    222 
    223 STATIC int
    224 phy_82381_ability_advert_set(int unit, soc_port_t port,
    225                           soc_port_ability_t *ability);
    226 
    227 STATIC int
    228 phy_82381_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability);
    229 STATIC int
    230 _phy_82381_find_soc_phy_lane(soc_phymod_ctrl_t *pmc, uint32_t lane,
    231                         soc_phymod_phy_t **p_phy, uint32 *lane_map);
    232 
    233 STATIC int
    234 phy_82381_power_set(phy_ctrl_t *pc, int32 intf, uint32 value);
    235 STATIC int
    236 phy_82381_power_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    237 STATIC int
    238 phy_82381_per_lane_tx_get(phy_ctrl_t *pc, int32 intf, soc_phy_control_t type, int lane, uint32 *value);
    239 STATIC int
    240 phy_82381_per_lane_tx_set(phy_ctrl_t *pc, int32 intf, soc_phy_control_t type, int lane, uint32 value);
    241 STATIC int
    242 phy_82381_cl72_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    243 STATIC int
    244 phy_82381_cl72_status_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    245 STATIC int
    246 phy_82381_cl72_enable_set(phy_ctrl_t *pc, int32 intf, uint32 value);
    247 STATIC int
    248 phy_82381_link_monitor_status_get (phy_ctrl_t *pc, int32 intf, int32 lane);
    249 STATIC int
    250 phy_82381_link_monitor_set (phy_ctrl_t *pc, int32 intf, int32 lane, uint32 value);
    251 STATIC int
    252 phy_82381_intr_enable_set(phy_ctrl_t *pc, int32 intf, uint32 value);
    253 STATIC int
    254 phy_82381_intr_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    255 STATIC int
    256 phy_82381_intr_status_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    257 STATIC int
    258 phy_82381_tx_lane_squelch_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    259 STATIC int
    260 phy_82381_per_lane_tx_lane_squelch_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value);
    261 STATIC int
    262 phy_82381_fec_enable_set(phy_ctrl_t *pc, uint32 value);
    263 STATIC int
    264 phy_82381_cross_switch_swap_get(phy_ctrl_t *pc, uint16 intf, uint32 *value);
    265 STATIC int
    266 phy_82381_cross_switch_swap_set(phy_ctrl_t *pc, uint16 intf, uint32 value);
    267 STATIC int
    268 phy_82381_loopback_internal_pmd_set(phy_ctrl_t *pc, int32 intf, uint32 value);
    269 STATIC int
    270 _phy_82381_get_intf_side(uint32_t chip_id, int32 intf, uint32 simplex_tx, uint32 tx_rx, uint32_t *if_side);
    271 STATIC int
    272 phy_82381_per_lane_driver_current_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value);
    273 STATIC int
    274 phy_82381_tx_fir_main_set(phy_ctrl_t *pc, int32 intf, uint32 value);
    275 STATIC int
    276 phy_82381_tx_fir_post_set(phy_ctrl_t *pc, int32 intf, uint32 value);
    277 STATIC int
    278 phy_82381_driver_current_set(phy_ctrl_t *pc, int32 intf, uint32 value);
    279 STATIC int
    280 phy_82381_tx_fir_main_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    281 STATIC int
    282 phy_82381_tx_fir_post_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    283 STATIC int
    284 phy_82381_tx_fir_pre_set(phy_ctrl_t *pc, int32 intf, uint32 value);
    285 STATIC int
    286 phy_82381_tx_fir_pre_get(phy_ctrl_t *pc, int32 intf, uint32 *value);
    287 STATIC int
    288 phy_82381_unreliable_los_set(phy_ctrl_t *pc, int32 intf, uint32 enable);
    289 STATIC int
    290 phy_82381_unreliable_los_get(phy_ctrl_t *pc, int32 intf,  uint32 *value);
    291 STATIC int
    292 phy_82381_per_lane_unreliable_los_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 enable);
    293 STATIC int
    294 phy_82381_per_lane_unreliable_los_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value);
    295 
    296 /*
    297  * Function:
    298  *      _phy82381_reg_read
    299  * Doc:
    300  *      register read operations
    301  * Parameters:
    302  *      unit            - (IN)  unit number
    303  *      core_addr       - (IN)  core address
    304  *      reg_addr        - (IN)  address to read
    305  *      val             - (OUT) read value
    306  */
    307 STATIC int
    308 _phy82381_reg_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
    309 {
    310     uint16 data16;
    311     int rv;
    312     soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc;
    313 
    314     rv = core->read(core->unit, core_addr, reg_addr, &data16);
    315     *val = data16;
    316     PHYMOD_VDBG(PHY82381_DBG_REGACC, NULL,("-22%s: core_addr: 0x%08x reg_addr: 0x%08x, data: 0x%04x\n", __func__, core_addr, reg_addr, *val ));
    317 
    318     return rv;
    319 }
    320 
    321 /*
    322  * Function:
    323  *      _phy82381_reg_write
    324  * Doc:
    325  *      register write operations
    326  * Parameters:
    327  *      unit            - (IN)  unit number
    328  *      core_addr       - (IN)  core address
    329  *      reg_addr        - (IN)  address to write
    330  *      val             - (IN)  write value
    331  */
    332 STATIC int
    333 _phy82381_reg_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
    334 {
    335     soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc;
    336     uint16 data16 = (uint16)val;
    337     uint16 mask = (uint16)(val >> 16);
    338 
    339     if (mask) {
    340         if (core->wrmask) {
    341             return core->wrmask(core->unit, core_addr, reg_addr, data16, mask);
    342         }
    343         (void)core->read(core->unit, core_addr, reg_addr, &data16);
    344         data16 &= ~mask;
    345         data16 |= (val & mask);
    346     }
    347     PHYMOD_VDBG(PHY82381_DBG_REGACC, NULL,("-22%s: core_addr: 0x%08x reg_addr: 0x%08x, data: 0x%04x\n", __func__, core_addr, reg_addr, val ));
    348     return core->write(core->unit, core_addr, reg_addr, data16);
    349 }
    350 
    351 /*
    352  * Function:
    353  *      phy82381_speed_to_interface_config_get
    354  * Purpose:
    355  *      Convert speed to interface_config struct
    356  * Parameters:
    357  *      unit                - BCM unit number.
    358  *      port                - Port number.
    359  *      speed               - speed to convert
    360  *      interface_config    - output interface config struct
    361  * Returns:
    362  *      SOC_E_NONE
    363  */
    364 STATIC int
    365 phy82381_speed_to_interface_config_get(phy82381_speed_config_t* speed_config, phymod_phy_inf_config_t* interface_config)
    366 {
    367     SOC_IF_ERROR_RETURN(phymod_phy_inf_config_t_init(interface_config));
    368 
    369     interface_config->interface_modes = 0;
    370     interface_config->data_rate       = speed_config->speed;
    371     interface_config->pll_divider_req = speed_config->pll_divider_req ;
    372 
    373     switch (speed_config->speed) {
    374         case PHY82381_SPD_1G:
    375             interface_config->interface_type = phymodInterfaceKX;
    376         break;
    377         case PHY82381_SPD_10G:
    378         case PHY82381_SPD_11G:
    379             switch(speed_config->line_interface) {
    380                 case SOC_PORT_IF_KR:
    381                     interface_config->interface_type = phymodInterfaceKR;
    382                 break;
    383                 case SOC_PORT_IF_LR:
    384                     interface_config->interface_type = phymodInterfaceLR;
    385                 break;
    386                 case SOC_PORT_IF_ER:
    387                     interface_config->interface_type = phymodInterfaceER;
    388                 break;
    389                 case SOC_PORT_IF_SR:
    390                     interface_config->interface_type = phymodInterfaceSR;
    391                 break;
    392                 case SOC_PORT_IF_CX:
    393                     interface_config->interface_type = phymodInterfaceCX;
    394                 break;
    395                 case SOC_PORT_IF_CR:
    396                     interface_config->interface_type = phymodInterfaceCR;
    397                 break;
    398                 case SOC_PORT_IF_SFI:
    399                     interface_config->interface_type = phymodInterfaceSFI;
    400                 break;
    401                 case SOC_PORT_IF_XFI:
    402                     interface_config->interface_type = phymodInterfaceXFI;
    403                 break;
    404 
    405                 default:
    406                     return SOC_E_PARAM;
    407 
    408             }
    409         break;
    410         case PHY82381_SPD_20G:
    411         case PHY82381_SPD_21G:
    412             switch(speed_config->line_interface) {
    413                 case SOC_PORT_IF_KR:
    414                     interface_config->interface_type = phymodInterfaceKR;
    415                 break;
    416                 case SOC_PORT_IF_KR2:
    417                     interface_config->interface_type = phymodInterfaceKR2;
    418                 break;
    419                 case SOC_PORT_IF_LR:
    420                     interface_config->interface_type = phymodInterfaceLR;
    421                 break;
    422                 case SOC_PORT_IF_ER:
    423                     interface_config->interface_type = phymodInterfaceER;
    424                 break;
    425 
    426                 default:
    427                     return SOC_E_PARAM;
    428 
    429             }
    430         break ;
    431         case PHY82381_SPD_25G:
    432         case PHY82381_SPD_27G:
    433             switch(speed_config->line_interface) {
    434                 case SOC_PORT_IF_KR:
    435                     interface_config->interface_type = phymodInterfaceKR;
    436                 break;
    437                 case SOC_PORT_IF_LR:
    438                     interface_config->interface_type = phymodInterfaceLR;
    439                 break;
    440                 case SOC_PORT_IF_VSR:
    441                     interface_config->interface_type = phymodInterfaceVSR;
    442                 break;
    443                 case SOC_PORT_IF_ER:
    444                     interface_config->interface_type = phymodInterfaceER;
    445                 break;
    446                 case SOC_PORT_IF_CR:
    447                     interface_config->interface_type = phymodInterfaceCR;
    448                 break;
    449                 case SOC_PORT_IF_SR:
    450                     interface_config->interface_type = phymodInterfaceSR;
    451                 break;
    452 
    453                 default:
    454                     return SOC_E_PARAM;
    455 
    456             }
    457         break;
    458         case PHY82381_SPD_40G:
    459         case PHY82381_SPD_42G:
    460             switch(speed_config->line_interface) {
    461                 case SOC_PORT_IF_KR2:
    462                     interface_config->interface_type = phymodInterfaceKR2;
    463                 break;
    464                 case SOC_PORT_IF_KR4:
    465                     interface_config->interface_type = phymodInterfaceKR4;
    466                 break;
    467                 case SOC_PORT_IF_LR4:
    468                     interface_config->interface_type = phymodInterfaceLR4;
    469                 break;
    470                 case SOC_PORT_IF_ER4:
    471                     interface_config->interface_type = phymodInterfaceER4;
    472                 break;
    473                 case SOC_PORT_IF_SR4:
    474                     interface_config->interface_type = phymodInterfaceSR4;
    475                 break;
    476                 case SOC_PORT_IF_CR4:
    477                     interface_config->interface_type = phymodInterfaceCR4;
    478                 break;
    479                 case SOC_PORT_IF_XLAUI:
    480                     interface_config->interface_type = phymodInterfaceXLAUI;
    481                 break;
    482 
    483                 default:
    484                     return SOC_E_PARAM;
    485 
    486             }
    487         break;
    488         case PHY82381_SPD_50G:
    489         case PHY82381_SPD_53G:
    490             switch(speed_config->line_interface) {
    491                 case SOC_PORT_IF_SR2:
    492                     interface_config->interface_type = phymodInterfaceSR2;
    493                 break;
    494                 case SOC_PORT_IF_KR2:
    495                     interface_config->interface_type = phymodInterfaceKR2;
    496                 break;
    497                 case SOC_PORT_IF_CR2:
    498                     interface_config->interface_type = phymodInterfaceCR2;
    499                 break;
    500                 default:
    501                     return SOC_E_PARAM;
    502 
    503             }
    504         break;
    505         case PHY82381_SPD_100G:
    506         case PHY82381_SPD_106G:
    507             switch(speed_config->line_interface) {
    508                 case SOC_PORT_IF_KR4:
    509                     interface_config->interface_type = phymodInterfaceKR4;
    510                 break;
    511                 case SOC_PORT_IF_LR4:
    512                     interface_config->interface_type = phymodInterfaceLR4;
    513                 break;
    514                 case SOC_PORT_IF_CR4:
    515                     interface_config->interface_type = phymodInterfaceCR4;
    516                 break;
    517                 case SOC_PORT_IF_CAUI_C2C:
    518                     interface_config->interface_type = phymodInterfaceCAUI4_C2C;
    519                  break;
    520                 case SOC_PORT_IF_CAUI:
    521                     interface_config->interface_type = phymodInterfaceCAUI;
    522                 break;
    523                 case SOC_PORT_IF_CAUI4:
    524                     interface_config->interface_type = phymodInterfaceCAUI4;
    525                 break;
    526                 case SOC_PORT_IF_CAUI_C2M:
    527                     interface_config->interface_type = phymodInterfaceCAUI4_C2M;
    528                 break;
    529                 case SOC_PORT_IF_ER4:
    530                     interface_config->interface_type = phymodInterfaceER4;
    531                 break;
    532                 case SOC_PORT_IF_SR4:
    533                     interface_config->interface_type = phymodInterfaceSR4;
    534                 break;
    535 
    536                 default:
    537                     return SOC_E_PARAM;
    538 
    539             }
    540         break;
    541         case PHY82381_SPD_6G:
    542             switch(speed_config->line_interface) {
    543                 case SOC_PORT_IF_SR:
    544                     interface_config->interface_type = phymodInterfaceSR;
    545                 break;
    546                 default:
    547                     return SOC_E_PARAM;
    548 
    549             }
    550         break;
    551 
    552         default:
    553             return SOC_E_PARAM;
    554     }
    555 
    556     switch (speed_config->port_refclk_int) {
    557         case 106:
    558             interface_config->ref_clock = phymodRefClk106Mhz;
    559         break;
    560         case 156:
    561             interface_config->ref_clock = phymodRefClk156Mhz;
    562         break;
    563         case 125:
    564             interface_config->ref_clock = phymodRefClk125Mhz;
    565         break;
    566         case 161:
    567             interface_config->ref_clock = phymodRefClk161Mhz;
    568         break;
    569         case 174:
    570             interface_config->ref_clock = phymodRefClk174Mhz;
    571         break;
    572         default:
    573             return SOC_E_PARAM;
    574     }
    575     if (speed_config->higig_port) {
    576         PHYMOD_INTF_MODES_HIGIG_SET(interface_config);
    577     }
    578     return SOC_E_NONE;
    579 }
    580 
    581 /*
    582  * Function:
    583  *      phy82381_speed_set
    584  * Purpose:
    585  *      Set PHY speed
    586  * Parameters:
    587  *      unit - BCM unit number.
    588  *      port - Port number.
    589  *      speed - link speed in Mbps
    590  * Returns:
    591  *      SOC_E_NONE
    592  */
    593 
    594 STATIC int
    595 phy82381_speed_set(int unit, soc_port_t port, int speed)
    596 {
    597     phy_ctrl_t                *pc;
    598     phy_ctrl_t                *int_pc;
    599     phy82381_config_t             *pCfg;
    600     soc_phymod_ctrl_t         *pmc;
    601     soc_phymod_phy_t          *phy;
    602     int                       idx;
    603     phy82381_speed_config_t       speed_config;
    604     phymod_phy_inf_config_t   interface_config;
    605     int int_speed;
    606 
    607     /* locate phy control */
    608     pc = EXT_PHY_SW_STATE(unit, port);
    609     int_pc = INT_PHY_SW_STATE(unit, port);
    610     if (pc == NULL || int_pc == NULL) {
    611         return SOC_E_INTERNAL;
    612     }
    613 
    614     if (speed == 0) {
    615         return SOC_E_NONE;
    616     }
    617 
    618     pmc = &pc->phymod_ctrl;
    619     pCfg = (phy82381_config_t *) pc->driver_data;
    620 
    621     SOC_IF_ERROR_RETURN(PHY_SPEED_GET(int_pc->pd, unit, port, &int_speed));
    622     if (int_speed != speed || pCfg->speed_config.higig_port == 1/*T_HG2_ENABLE variable is set in speedset macro below. PHY-2942 */)
    623     {
    624        SOC_IF_ERROR_RETURN(PHY_SPEED_SET(int_pc->pd, unit, port, speed));
    625        SOC_IF_ERROR_RETURN(PHY_SPEED_GET(int_pc->pd, unit, port, &int_speed));
    626        if (int_speed != speed) {
    627            return SOC_E_CONFIG;
    628        }
    629     }
    630 
    631     /* take a copy of core and phy configuration values, and set the desired speed */
    632     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
    633     speed_config.speed = speed;
    634 
    635     /* determine the interface configuration */
    636     SOC_IF_ERROR_RETURN
    637         (phy82381_speed_to_interface_config_get(&speed_config, &interface_config));
    638 
    639     /* now loop through all cores */
    640     for (idx = 0; idx < pmc->num_phys; idx++) {
    641         phy = pmc->phy[idx];
    642         if (phy == NULL) {
    643             return SOC_E_INTERNAL;
    644         }
    645         SOC_IF_ERROR_RETURN
    646             (phymod_phy_interface_config_set(&phy->pm_phy,
    647                                              0 /* flags */, &interface_config));
    648     }
    649 
    650     /* record success */
    651     pCfg->speed_config.speed = speed;
    652     /* speed notify from ext phy */
    653     if (speed != interface_config.data_rate) {
    654         speed = interface_config.data_rate;
    655         SOC_IF_ERROR_RETURN(PHY_SPEED_SET(int_pc->pd, unit, port, speed));
    656         SOC_IF_ERROR_RETURN(PHY_SPEED_GET(int_pc->pd, unit, port, &int_speed));
    657         if (int_speed != speed) {
    658             return SOC_E_CONFIG;
    659         }
    660         /* record success on speed notify form ext phy*/
    661         pCfg->speed_config.speed = speed;
    662     }
    663     return (SOC_E_NONE);
    664 }
    665 
    666 /*
    667  * Function:
    668  *      phy82381_speed_get
    669  * Purpose:
    670  *      Get PHY speed
    671  * Parameters:
    672  *      unit - BCM unit number.
    673  *      port - Port number.
    674  *      speed - current link speed in Mbps
    675  * Returns:
    676  *      SOC_E_NONE
    677  */
    678 STATIC int
    679 phy82381_speed_get(int unit, soc_port_t port, int *speed)
    680 {
    681     phy_ctrl_t                *pc;
    682     phy82381_config_t             *pCfg;
    683     soc_phymod_ctrl_t         *pmc;
    684     soc_phymod_phy_t          *phy;
    685     phymod_phy_inf_config_t   interface_config;
    686     phymod_ref_clk_t ref_clock;
    687     phy82381_speed_config_t       speed_config;
    688     int flag = 0;
    689     ref_clock = 0;
    690     /* locate phy control */
    691     pc = EXT_PHY_SW_STATE(unit, port);
    692     if (pc == NULL) {
    693         return SOC_E_INTERNAL;
    694     }
    695     pmc = &pc->phymod_ctrl;
    696 
    697     pCfg = (phy82381_config_t *) pc->driver_data;
    698 
    699     /* take a copy of core and phy configuration values, and set the desired speed */
    700     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
    701     /* initialize the data structure */
    702     interface_config.data_rate = 0;
    703 
    704     /* now loop through all cores */
    705     phy = pmc->phy[pmc->main_phy];
    706     if (phy == NULL) {
    707         return SOC_E_INTERNAL;
    708     }
    709     /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */
    710     SOC_IF_ERROR_RETURN
    711         (phymod_phy_interface_config_get(&phy->pm_phy, flag,
    712                                          ref_clock,
    713                                          &interface_config));
    714 
    715     if(speed_config.speed != interface_config.data_rate) {
    716         *speed = speed_config.speed;
    717     } else {
    718         *speed = interface_config.data_rate;
    719     }
    720     return (SOC_E_NONE);
    721 }
    722 
    723 
    724 STATIC int
    725 phy82381_interface_set(int unit, soc_port_t port, soc_port_if_t pif)
    726 {
    727     phy_ctrl_t      *pc;
    728     phy82381_config_t *pCfg;
    729     phy82381_speed_config_t       speed_config;
    730     phymod_phy_inf_config_t   interface_config;
    731     soc_phymod_ctrl_t         *pmc;
    732     soc_phymod_phy_t          *phy;
    733     int                       idx;
    734 
    735     pc = EXT_PHY_SW_STATE(unit, port);
    736     if (pc == NULL) {
    737         return SOC_E_INTERNAL;
    738     }
    739     pCfg = (phy82381_config_t *) pc->driver_data;
    740     pmc = &pc->phymod_ctrl;
    741 
    742     if (pif >= SOC_PORT_IF_COUNT) {
    743         return SOC_E_PARAM;
    744     }
    745     if (pif == SOC_PORT_IF_MII || pif == SOC_PORT_IF_XGMII || pif == SOC_PORT_IF_GMII) {
    746         return phy_null_interface_set(unit, port, pif);
    747     }
    748 
    749 
    750     /* take a copy of core and phy configuration values, and set the desired speed */
    751     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
    752     speed_config.line_interface = pif;
    753     SOC_IF_ERROR_RETURN
    754         (phy82381_speed_to_interface_config_get(&speed_config, &interface_config));
    755 
    756     /* now loop through all cores */
    757     for (idx = 0; idx < pmc->num_phys; idx++) {
    758         phy = pmc->phy[idx];
    759         if (phy == NULL) {
    760             return SOC_E_INTERNAL;
    761         }
    762      SOC_IF_ERROR_RETURN
    763           (phymod_phy_interface_config_set(&phy->pm_phy,
    764                                            0 /* flags */, &interface_config));
    765     }
    766 
    767     pCfg->speed_config.line_interface = pif;
    768     return SOC_E_NONE;
    769 }
    770 
    771 STATIC int
    772 phy82381_interface_get(int unit, soc_port_t port, soc_port_if_t *pif)
    773 {
    774     phy_ctrl_t                *pc;
    775     phy82381_config_t *pCfg;
    776     soc_phymod_ctrl_t         *pmc;
    777     soc_phymod_phy_t          *phy;
    778     phymod_phy_inf_config_t   interface_config;
    779     phymod_ref_clk_t ref_clock;
    780     phy82381_speed_config_t       speed_config;
    781     int flag = 0;
    782     ref_clock = 0;
    783 
    784     /* locate phy control */
    785     pc = EXT_PHY_SW_STATE(unit, port);
    786     if (pc == NULL) {
    787         return SOC_E_INTERNAL;
    788     }
    789 
    790     pmc = &pc->phymod_ctrl;
    791     pCfg = (phy82381_config_t *) pc->driver_data;
    792     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
    793 
    794 
    795     /* initialize the data structure */
    796     sal_memset(&interface_config, 0x0, sizeof(phymod_phy_inf_config_t));
    797 
    798     /* now loop through all cores */
    799     phy = pmc->phy[pmc->main_phy];
    800     if (phy == NULL) {
    801         return SOC_E_INTERNAL;
    802     }
    803     /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */
    804     SOC_IF_ERROR_RETURN
    805         (phymod_phy_interface_config_get(&phy->pm_phy, ref_clock,
    806                                          flag, &interface_config));
    807     switch (interface_config.interface_type) {
    808         case phymodInterfaceKX:
    809             *pif = SOC_PORT_IF_KX;
    810         break;
    811         case phymodInterfaceKR:
    812             if ((speed_config.speed == 100000) ||
    813                 (speed_config.speed == 106000) ||
    814                 (speed_config.speed == 40000) ||
    815                 (speed_config.speed == 42000)) {
    816                 *pif = SOC_PORT_IF_KR4;
    817             } else if (speed_config.speed == 50000 ||
    818                        speed_config.speed == 53000) {
    819                 *pif = SOC_PORT_IF_KR2;
    820             } else {
    821                 *pif = SOC_PORT_IF_KR;
    822             }
    823         break;
    824         case phymodInterfaceKR2:
    825             *pif = SOC_PORT_IF_KR2;
    826         break;
    827         case phymodInterfaceKR4:
    828             *pif = SOC_PORT_IF_KR4;
    829         break;
    830         case phymodInterfaceCR4:
    831             *pif = SOC_PORT_IF_CR4;
    832         break;
    833         case phymodInterfaceSR:
    834             if ((speed_config.speed == 100000) ||
    835                 (speed_config.speed == 106000) ||
    836                 (speed_config.speed == 40000) ||
    837                 (speed_config.speed == 42000)) {
    838                 *pif = SOC_PORT_IF_SR4;
    839             } else {
    840                 *pif = SOC_PORT_IF_SR;
    841             }
    842         break;
    843         case phymodInterfaceSR2:
    844                 *pif = SOC_PORT_IF_SR2;
    845         break;
    846         case phymodInterfaceLR:
    847             if ((speed_config.speed == 100000) ||
    848                 (speed_config.speed == 106000) ||
    849                 (speed_config.speed == 40000) ||
    850                 (speed_config.speed == 42000)) {
    851                 *pif = SOC_PORT_IF_LR4;
    852             } else {
    853                 *pif = SOC_PORT_IF_LR;
    854             }
    855         break;
    856         case phymodInterfaceER:
    857             if ((speed_config.speed == 100000) ||
    858                 (speed_config.speed == 106000) ||
    859                 (speed_config.speed == 40000) ||
    860                 (speed_config.speed == 42000)) {
    861                 *pif = SOC_PORT_IF_ER4;
    862             } else {
    863                 *pif = SOC_PORT_IF_ER;
    864             }
    865         break;
    866         case phymodInterfaceSR4:
    867             *pif = SOC_PORT_IF_SR4;
    868         break;
    869         case phymodInterfaceLR4:
    870             *pif = SOC_PORT_IF_LR4;
    871         break;
    872         case phymodInterfaceER4:
    873             *pif = SOC_PORT_IF_ER4;
    874         break;
    875 
    876         case phymodInterfaceCX:
    877             if ((speed_config.speed == 100000) ||
    878                 (speed_config.speed == 106000) ||
    879                 (speed_config.speed == 40000) ||
    880                 (speed_config.speed == 42000)) {
    881                 *pif = SOC_PORT_IF_CX4;
    882             } else {
    883                 *pif = SOC_PORT_IF_CX;
    884             }
    885         break;
    886         case phymodInterfaceCR:
    887             if ((speed_config.speed == 100000) ||
    888                 (speed_config.speed == 106000) ||
    889                 (speed_config.speed == 40000) ||
    890                 (speed_config.speed == 42000)) {
    891                 *pif = SOC_PORT_IF_CR4;
    892             } else if (speed_config.speed == 50000 ||
    893                        speed_config.speed == 53000) {
    894                 *pif = SOC_PORT_IF_CR2;
    895             } else {
    896                 *pif = SOC_PORT_IF_CR;
    897             }
    898         break;
    899         case phymodInterfaceCR2:
    900             *pif = SOC_PORT_IF_CR2;
    901         break;
    902         case phymodInterfaceSFI:
    903             *pif = SOC_PORT_IF_SFI;
    904         break;
    905         case phymodInterfaceVSR:
    906             if ((speed_config.speed == 100000) ||
    907                 (speed_config.speed == 106000)) {
    908                 *pif = speed_config.line_interface;
    909             } else {
    910                 *pif = SOC_PORT_IF_VSR;
    911             }
    912         break;
    913         case phymodInterfaceCAUI4_C2C:
    914             *pif = SOC_PORT_IF_CAUI_C2C;
    915         break;
    916         case phymodInterfaceCAUI4_C2M:
    917             *pif = SOC_PORT_IF_CAUI_C2M;
    918         break;
    919         case phymodInterfaceCAUI4:
    920             *pif = SOC_PORT_IF_CAUI4;
    921         break;
    922         case phymodInterfaceCAUI:
    923             *pif = SOC_PORT_IF_CAUI;
    924         break;
    925         case phymodInterfaceXFI:
    926             if ((speed_config.speed == 40000) ||
    927                 (speed_config.speed == 42000)) {
    928                 *pif = SOC_PORT_IF_XLAUI;
    929             } else {
    930                 *pif = SOC_PORT_IF_XFI;
    931             }
    932         break;
    933         case phymodInterfaceXLAUI:
    934             *pif = SOC_PORT_IF_XLAUI;
    935         break;
    936 
    937         default:
    938         break;
    939     }
    940     return (SOC_E_NONE);
    941 
    942 }
    943 
    944 /*
    945  * Function:
    946  *      phy82381_reg_read
    947  * Purpose:
    948  *      Routine to read PHY register
    949  * Parameters:
    950  *      unit         - BCM unit number
    951  *      port         - Port number
    952  *      flags        - Flags which specify the register type
    953  *      phy_reg_addr - Encoded register address
    954  *      phy_data     - (OUT) Value read from PHY register
    955  * Note:
    956  *      This register read function is not thread safe. Higher level
    957  * function that calls this function must obtain a per port lock
    958  * to avoid overriding register page mapping between threads.
    959  */
    960 STATIC int
    961 phy82381_reg_read(int unit, soc_port_t port, uint32 flags,
    962                   uint32 phy_reg_addr, uint32 *phy_reg_data)
    963 {
    964     phy_ctrl_t *pc;
    965     soc_phymod_ctrl_t *pmc;
    966     phymod_phy_access_t *pm_phy;
    967     int idx = 0;
    968     uint8 data8 = 0;
    969 
    970 
    971     pc = EXT_PHY_SW_STATE(unit, port);
    972     if (pc == NULL) {
    973         return SOC_E_INTERNAL;
    974     }
    975 
    976     pmc = &pc->phymod_ctrl;
    977     idx = pmc->main_phy ;
    978     pm_phy = &pmc->phy[idx]->pm_phy;
    979     if (flags & SOC_PHY_I2C_DATA8) {
    980         SOC_IF_ERROR_RETURN
    981             (phymod_phy_i2c_read(pm_phy, 0, SOC_PHY_I2C_DEVAD(phy_reg_addr), SOC_PHY_I2C_REGAD(phy_reg_addr), 1, &data8));
    982         *phy_reg_data = data8;
    983     } else {
    984         SOC_IF_ERROR_RETURN
    985             (phymod_phy_reg_read(pm_phy, phy_reg_addr, phy_reg_data));
    986     }
    987     return SOC_E_NONE;
    988 }
    989 
    990 /*
    991  * Function:
    992  *      phy82381_reg_write
    993  * Purpose:
    994  *      Routine to write PHY register
    995  * Parameters:
    996  *      uint         - BCM unit number
    997  *      pc           - PHY state
    998  *      flags        - Flags which specify the register type
    999  *      phy_reg_addr - Encoded register address
   1000  *      phy_data     - Value write to PHY register
   1001  * Note:
   1002  *      This register read function is not thread safe. Higher level
   1003  * function that calls this function must obtain a per port lock
   1004  * to avoid overriding register page mapping between threads.
   1005  */
   1006 STATIC int
   1007 phy82381_reg_write(int unit, soc_port_t port, uint32 flags,
   1008                    uint32 phy_reg_addr, uint32 phy_reg_data)
   1009 {
   1010     phy_ctrl_t *pc;
   1011     soc_phymod_ctrl_t *pmc;
   1012     phymod_phy_access_t *pm_phy;
   1013     int idx;
   1014     uint8 data8 = 0;
   1015     data8 = phy_reg_data & 0xFF;
   1016 
   1017     pc = EXT_PHY_SW_STATE(unit, port);
   1018     if (pc == NULL) {
   1019         return SOC_E_INTERNAL;
   1020     }
   1021 
   1022     pmc = &pc->phymod_ctrl;
   1023     for (idx = 0; idx < pmc->num_phys; idx++) {
   1024         pm_phy = &pmc->phy[idx]->pm_phy;
   1025         if (flags & SOC_PHY_I2C_DATA8) {
   1026             SOC_IF_ERROR_RETURN
   1027                 (phymod_phy_i2c_write(pm_phy, 0, SOC_PHY_I2C_DEVAD(phy_reg_addr), SOC_PHY_I2C_REGAD(phy_reg_addr), 1, &data8));
   1028         } else {
   1029             SOC_IF_ERROR_RETURN
   1030                 (phymod_phy_reg_write(pm_phy, phy_reg_addr, phy_reg_data));
   1031         }
   1032     }
   1033     return SOC_E_NONE;
   1034 }
   1035 
   1036 /*
   1037  * Function:
   1038  *      phy82381_reg_modify
   1039  * Purpose:
   1040  *      Routine to write PHY register
   1041  * Parameters:
   1042  *      uint         - BCM unit number
   1043  *      pc           - PHY state
   1044  *      flags        - Flags which specify the register type
   1045  *      phy_reg_addr - Encoded register address
   1046  *      phy_mo_data  - New value for the bits specified in phy_mo_mask
   1047  *      phy_mo_mask  - Bit mask to modify
   1048  * Note:
   1049  *      This function is not thread safe. Higher level
   1050  * function that calls this function must obtain a per port lock
   1051  * to avoid overriding register page mapping between threads.
   1052  */
   1053 STATIC int
   1054 phy82381_reg_modify(int unit, soc_port_t port, uint32 flags,
   1055                     uint32 phy_reg_addr, uint32 phy_data,
   1056                     uint32 phy_data_mask)
   1057 {
   1058     phy_ctrl_t *pc;
   1059     soc_phymod_ctrl_t *pmc;
   1060     phymod_phy_access_t *pm_phy;
   1061     uint32 data32, tmp;
   1062     int idx;
   1063 
   1064     pc = EXT_PHY_SW_STATE(unit, port);
   1065     if (pc == NULL) {
   1066         return SOC_E_INTERNAL;
   1067     }
   1068 
   1069     pmc = &pc->phymod_ctrl;
   1070     for (idx = 0; idx < pmc->num_phys; idx++) {
   1071         pm_phy = &pmc->phy[idx]->pm_phy;
   1072         SOC_IF_ERROR_RETURN
   1073             (phymod_phy_reg_read(pm_phy, phy_reg_addr, &data32));
   1074         tmp = data32;
   1075         data32 &= ~(phy_data_mask);
   1076         data32 |= (phy_data & phy_data_mask);
   1077         if (data32 != tmp) {
   1078             SOC_IF_ERROR_RETURN
   1079                 (phymod_phy_reg_write(pm_phy, phy_reg_addr, data32));
   1080         }
   1081     }
   1082     return SOC_E_NONE;
   1083 }
   1084 
   1085 STATIC void
   1086 phy82381_core_init(phy_ctrl_t *pc, soc_phymod_core_t *core,
   1087                    phymod_bus_t *core_bus, uint32 core_addr)
   1088 {
   1089     phymod_core_access_t *pm_core;
   1090     phymod_access_t *pm_acc;
   1091 
   1092     core->unit = pc->unit;
   1093     core->port = pc->port;
   1094     core->read = pc->read;
   1095     /* This is a workaround for override CL45 access callback during warmboot */
   1096     core->write = pc->wb_write ? pc->wb_write : pc->write;
   1097     core->wrmask = pc->wrmask;
   1098 
   1099     pm_core = &core->pm_core;
   1100     phymod_core_access_t_init(pm_core);
   1101     pm_acc = &pm_core->access;
   1102     phymod_access_t_init(pm_acc);
   1103     PHYMOD_ACC_USER_ACC(pm_acc) = core;
   1104     PHYMOD_ACC_BUS(pm_acc) = core_bus;
   1105     PHYMOD_ACC_ADDR(pm_acc) = core_addr;
   1106 
   1107     if (soc_property_port_get(pc->unit, pc->port, "phy82381", 0) == 45) {
   1108         PHYMOD_ACC_F_CLAUSE45_SET(pm_acc);
   1109     }
   1110 
   1111     return;
   1112 }
   1113 
   1114 STATIC int
   1115 _phy82381_device_create_attach(soc_phymod_core_t *core, uint32_t core_id)
   1116 {
   1117     phy82381_device_aux_mode_t *new_device ;
   1118     new_device = sal_alloc(sizeof(phy82381_device_aux_mode_t), "phy82381_device_aux_mode");
   1119     if (new_device == NULL) {
   1120         return SOC_E_MEMORY;
   1121     }
   1122     sal_memset(new_device, 0 ,sizeof(phy82381_device_aux_mode_t));
   1123 
   1124     new_device->core_id = core_id ;
   1125     core->device_aux_modes = (void *)new_device ;
   1126     return SOC_E_NONE;
   1127 }
   1128 
   1129 STATIC int
   1130 _phy82381_device_destroy(phy82381_device_aux_mode_t *device)
   1131 {
   1132     if (device == NULL) {
   1133         return SOC_E_PARAM;
   1134     }
   1135     sal_free(device);
   1136 
   1137     return SOC_E_NONE;
   1138 }
   1139 /*
   1140  * Function:
   1141  *     _phy82381_is_write_disabled
   1142  * Doc:
   1143  *      register write is disable in wormboot
   1144  * Parameters:
   1145  *      unit            - (IN)  unit number
   1146  *      val             - (IN)  is write disable
   1147  */
   1148 STATIC int
   1149 _phy82381_is_write_disabled(void* user_acc,  uint32_t *val)
   1150 {
   1151     #if defined(BCM_WARM_BOOT_SUPPORT)
   1152     soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc;
   1153     int unitV;
   1154     unitV = core->unit;
   1155     *val = SOC_WARM_BOOT(unitV);
   1156     #else
   1157     *val = 0;
   1158     #endif
   1159     return SOC_E_NONE;
   1160 }
   1161 
   1162 STATIC void
   1163 phy82381_cleanup(soc_phymod_ctrl_t *pmc)
   1164 {
   1165     int idx;
   1166     soc_phymod_phy_t *phy;
   1167     soc_phymod_core_t *core;
   1168     phy82381_device_aux_mode_t *device ;
   1169 
   1170     for (idx = 0; idx < pmc->num_phys ; idx++) {
   1171         phy = pmc->phy[idx];
   1172         if (phy == NULL) {
   1173             LOG_WARN(BSL_LS_SOC_PHY,
   1174                      (BSL_META_U(pmc->unit,
   1175                                  "phy object is empty")));
   1176             continue;
   1177         }
   1178 
   1179         core = phy->core;
   1180         if (core != NULL) {
   1181             device = (phy82381_device_aux_mode_t *)core->device_aux_modes ;
   1182         }
   1183         /* Destroy core object if not used anymore */
   1184         if (core && core->ref_cnt) {
   1185             if (--core->ref_cnt == 0) {
   1186                 PHYMOD_VDBG(PHY82381_DBG_MEM, NULL,("clean_up device=%p core_p=%p\n", (void *)device, (void *)core)) ;
   1187                 _phy82381_device_destroy(device) ;
   1188                 soc_phymod_core_destroy(pmc->unit, core);
   1189             }
   1190         }
   1191 
   1192         /* Destroy phy object */
   1193         if (phy) {
   1194             PHYMOD_VDBG(PHY82381_DBG_MEM, NULL,("clean_up phy=%p\n", (void *)phy)) ;
   1195             soc_phymod_phy_destroy(pmc->unit, phy);
   1196         }
   1197     }
   1198     pmc->num_phys = 0;
   1199 }
   1200 
   1201 STATIC int32
   1202 _phy_82381_chip_id_get(phymod_phy_access_t *pm_phy, uint32 *chip_id)
   1203 {
   1204     uint32 chip_id_msb = 0, chip_id_lsb = 0;
   1205 
   1206 
   1207     SOC_IF_ERROR_RETURN(
   1208        phymod_phy_reg_read(pm_phy, 0x8a01, &chip_id_msb));
   1209 
   1210     chip_id_msb = (chip_id_msb & 0xF000) >> 12;
   1211 
   1212     SOC_IF_ERROR_RETURN(
   1213        phymod_phy_reg_read(pm_phy, 0x8a00, &chip_id_lsb));
   1214 
   1215     if (chip_id_msb == 0x8) {
   1216         if (chip_id_lsb == 0x2071) {
   1217             *chip_id = 0x82071;
   1218         } else if(chip_id_lsb == 0x2381) {
   1219             *chip_id = 0x82381;
   1220         } else if(chip_id_lsb == 0x2209) {
   1221             *chip_id = 0x82209;
   1222         } else if(chip_id_lsb == 0x2070) {
   1223             *chip_id = 0x82070;
   1224         } else if(chip_id_lsb == 0x2073) {
   1225             *chip_id = 0x82073;
   1226         } else if(chip_id_lsb == 0x2072) {
   1227             *chip_id = 0x82072;
   1228         } else if(chip_id_lsb == 0x2380) {
   1229             *chip_id = 0x82380;
   1230         } else if(chip_id_lsb == 0x2314) {
   1231             *chip_id = 0x82314;
   1232         } else if(chip_id_lsb == 0x2315) {
   1233             *chip_id = 0x82315;
   1234         } else if(chip_id_lsb == 0x2212) {
   1235             *chip_id = 0x82212;
   1236         }
   1237 
   1238     } else {
   1239         LOG_WARN(BSL_LS_SOC_PHY, (BSL_META_U(0,
   1240                  "Chip ID not found for \n")));
   1241         return SOC_E_NOT_FOUND;
   1242     }
   1243 
   1244     return SOC_E_NONE;
   1245 }
   1246 
   1247 /*
   1248  * Function:
   1249  *      phy82381_probe
   1250  * Purpose:
   1251  *      xx
   1252  * Parameters:
   1253  *      pc->phy_id   (IN)
   1254  *      pc->unit     (IN)
   1255  *      pc->port     (IN)
   1256  *      pc->size     (OUT) - memory required by phy port
   1257  *      pc->dev_name (OUT) - set to port device name
   1258  *
   1259  * Note:
   1260  */
   1261 STATIC int
   1262 phy82381_probe(int unit, phy_ctrl_t *pc)
   1263 {
   1264     int rv, idx;
   1265     uint32 lane_map, num_phys, core_id, phy_id, found;
   1266     phymod_bus_t core_bus;
   1267     phymod_dispatch_type_t phy_type;
   1268     phymod_core_access_t *pm_core;
   1269     phymod_phy_access_t *pm_phy;
   1270     phymod_access_t *pm_acc;
   1271     soc_phymod_ctrl_t *pmc;
   1272     soc_phymod_phy_t *phy;
   1273     soc_phymod_core_t *core;
   1274     soc_phymod_core_t core_probe;
   1275     soc_info_t *si;
   1276     phyident_core_info_t core_info[8];
   1277     int array_max = 8;
   1278     int array_size = 0;
   1279     int port;
   1280     int phy_port;  /* physical port number */
   1281     uint16 chip_id = 0;
   1282     /* Initialize PHY bus */
   1283     SOC_IF_ERROR_RETURN(phymod_bus_t_init(&core_bus));
   1284     core_bus.bus_name = "phy82381";
   1285     core_bus.read = _phy82381_reg_read;
   1286     core_bus.write = _phy82381_reg_write;
   1287     core_bus.is_write_disabled = _phy82381_is_write_disabled;
   1288     /* Configure PHY bus properties */
   1289     if (pc->wrmask) {
   1290         PHYMOD_BUS_CAP_WR_MODIFY_SET(&core_bus);
   1291         PHYMOD_BUS_CAP_LANE_CTRL_SET(&core_bus);
   1292     }
   1293 
   1294     port = pc->port;
   1295     pmc = &pc->phymod_ctrl;
   1296     si = &SOC_INFO(unit);
   1297     if (soc_feature(unit, soc_feature_logical_port_num)) {
   1298         phy_port = si->port_l2p_mapping[port];
   1299     } else {
   1300         phy_port = port;
   1301     }
   1302     /* Install clean up function */
   1303     pmc->unit = pc->unit;
   1304     pmc->cleanup = phy82381_cleanup;
   1305     /*pmc->symbols = &bcmi_tscf_xgxs_symbols;*/ 
   1306     
   1307     pc->lane_num = SOC_PORT_BINDEX(unit, phy_port);
   1308     pc->chip_num = SOC_BLOCK_NUMBER(unit, SOC_PORT_BLOCK(unit, phy_port));
   1309 
   1310     /* request memory for the configuration structure */
   1311     pc->size = sizeof(phy82381_config_t);
   1312     /* Read the lane_mask config variable */
   1313     PORT_PHY_LANE_MASK(pc) = soc_property_port_get(unit, port, spn_PORT_PHY_LANE_MASK, 0);
   1314 
   1315     /* Bit N corresponds to lane N in lane_map */
   1316     lane_map = 0xf;
   1317     num_phys = 1;
   1318     switch (si->port_num_lanes[port]) {
   1319         case 10:
   1320             pc->phy_mode = PHYCTRL_MULTI_CORE_PORT;
   1321             break;
   1322         case 4:
   1323             pc->phy_mode = PHYCTRL_QUAD_LANE_PORT;
   1324             break;
   1325         case 2:
   1326             lane_map = 0x3;
   1327             pc->phy_mode = PHYCTRL_DUAL_LANE_PORT;
   1328             break;
   1329         case 1:
   1330         case 0:
   1331             lane_map = 0x1;
   1332             pc->phy_mode = PHYCTRL_ONE_LANE_PORT;
   1333             break;
   1334         default:
   1335             return SOC_E_CONFIG;
   1336     }
   1337     SOC_IF_ERROR_RETURN(
   1338         READ_PHY_REG(unit, pc,0x18a00 ,&chip_id));
   1339 
   1340     if (!PORT_PHY_LANE_MASK(pc)) {
   1341         if ((chip_id == 0x2208) || (chip_id == 0x2209)) {
   1342             lane_map <<= (pc->lane_num | (4 * (pc->chip_num%2)));
   1343         } else {
   1344             lane_map <<= pc->lane_num;
   1345         }
   1346     } else {
   1347         lane_map = PORT_PHY_LANE_MASK(pc);
   1348     }
   1349     /* we need to get the other core id if more than 1 core per port */
   1350     if (num_phys > 1) {
   1351         /* get the other core address */
   1352         SOC_IF_ERROR_RETURN
   1353         /*
   1354          * COVERITY
   1355          * This is unreachable. It is kept intentionally as a defensive
   1356          * default for future development.
   1357          */
   1358         /* coverity[dead_error_begin] */
   1359             (soc_phy_addr_multi_get(unit, port, array_max, &array_size, &core_info[0]));
   1360     } else {
   1361         core_info[0].mdio_addr = pc->phy_id;
   1362     }
   1363     if (chip_id == 0x2212) {
   1364         phy_type = phymodDispatchTypeFuria_82212;
   1365     } else {
   1366         phy_type = phymodDispatchTypeFuria;
   1367     }
   1368 
   1369     /* Probe cores */
   1370     for (idx = 0; idx < num_phys ; idx++) {
   1371         phy82381_core_init(pc, &core_probe, &core_bus,
   1372                            core_info[idx].mdio_addr);
   1373         /* Check that core is indeed an furia core */
   1374         pm_core = &core_probe.pm_core;
   1375         pm_core->type = phy_type;
   1376         rv = phymod_core_identify(pm_core, 0, &found);
   1377         if (SOC_FAILURE(rv)) {
   1378             LOG_WARN(BSL_LS_SOC_PHY,
   1379                  (BSL_META_U(unit,
   1380                              "port %d: ERROR!!!\n"),
   1381                   pc->port));
   1382 
   1383             return rv;
   1384         }
   1385         if (!found) {
   1386             LOG_WARN(BSL_LS_SOC_PHY,
   1387                  (BSL_META_U(unit,
   1388                              "port %d: NOT FOUND!!\n"),
   1389                   pc->port));
   1390 
   1391             return SOC_E_NOT_FOUND;
   1392         }
   1393     }
   1394 
   1395     rv = SOC_E_NONE;
   1396     for (idx = 0; idx < num_phys ; idx++) {
   1397         /* Set core and phy IDs based on PHY address */
   1398         core_id = pc->phy_id + idx;
   1399         phy_id = (lane_map << 16) | core_id;
   1400         /* Create PHY object */
   1401         rv = soc_phymod_phy_create(unit, phy_id, &pmc->phy[idx]);
   1402         if (SOC_FAILURE(rv)) {
   1403             break;
   1404         }
   1405         pmc->num_phys++;
   1406 
   1407         /* Initialize phy object */
   1408         phy = pmc->phy[idx];
   1409         pm_phy = &phy->pm_phy;
   1410         phymod_phy_access_t_init(pm_phy);
   1411 
   1412         /* Find or create associated core object */
   1413         rv = soc_phymod_core_find_by_id(unit, core_id, &phy->core);
   1414         if (rv == SOC_E_NOT_FOUND) {
   1415             rv = soc_phymod_core_create(unit, core_id, &phy->core);
   1416             rv |= _phy82381_device_create_attach(phy->core, core_id) ;
   1417         }
   1418         if (SOC_FAILURE(rv)) {
   1419             break;
   1420         }
   1421     }
   1422     if (SOC_FAILURE(rv)) {
   1423         phy82381_cleanup(pmc);
   1424         return rv;
   1425     }
   1426 
   1427     for (idx = 0; idx < num_phys ; idx++) {
   1428         phy = pmc->phy[idx];
   1429         core = phy->core;
   1430         pm_core = &core->pm_core;
   1431 
   1432         /* Initialize core object if newly created */
   1433         if (core->ref_cnt == 0) {
   1434             sal_memcpy(&core->pm_bus, &core_bus, sizeof(core->pm_bus));
   1435             phy82381_core_init(pc, core, &core->pm_bus,
   1436                                core_info[idx].mdio_addr);
   1437             /* Set dispatch type */
   1438             pm_core->type = phy_type;
   1439         }
   1440         core->port = pc->port;
   1441         core->ref_cnt++;
   1442 
   1443         /* Initialize phy access based on associated core */
   1444         pm_acc = &phy->pm_phy.access;
   1445         sal_memcpy(pm_acc, &pm_core->access, sizeof(*pm_acc));
   1446         phy->pm_phy.type = phy_type;
   1447         PHYMOD_ACC_LANE_MASK(pm_acc) = lane_map;
   1448     }
   1449 
   1450     return SOC_E_NONE;
   1451 }
   1452 
   1453 
   1454 /*
   1455  * Function:
   1456  *      phy82381_config_init
   1457  * Purpose:
   1458  *      Determine phy configuration data for purposes of PHYMOD initialization.
   1459  *
   1460  *      A side effect of this procedure is to save some per-logical port
   1461  *      information in (phy82381_cfg_t *) &pc->driver_data;
   1462  *
   1463  * Parameters:
   1464  *      unit                  - BCM unit number.
   1465  *      port                  - Port number.
   1466  *      logical_lane_offset   - starting logical lane number
   1467  * Returns:
   1468  *      SOC_E_NONE
   1469  */
   1470 STATIC int
   1471 phy82381_config_init(int unit, soc_port_t port, int logical_lane_offset,
   1472                  phymod_core_init_config_t *core_init_config,
   1473                  phymod_phy_init_config_t  *pm_phy_init_config)
   1474 {
   1475     phy_ctrl_t *pc;
   1476     phy82381_speed_config_t *speed_config;
   1477     phy82381_config_t *pCfg;
   1478     phymod_firmware_load_method_t fw_ld_method;
   1479     int port_num_lanes;
   1480     int core_num;
   1481     int phy_num_lanes;
   1482     uint32_t preemphasis, driver_current,i;
   1483 
   1484 
   1485     pc = EXT_PHY_SW_STATE(unit, port);
   1486     if (pc == NULL) {
   1487         return SOC_E_INTERNAL;
   1488     }
   1489     pCfg = (phy82381_config_t *) pc->driver_data;
   1490 
   1491     port_num_lanes = SOC_INFO(unit).port_num_lanes[port];
   1492 
   1493     /* figure out how many lanes are in this phy */
   1494     core_num = (logical_lane_offset / 4);
   1495     phy_num_lanes = (port_num_lanes - logical_lane_offset);
   1496     if (phy_num_lanes > MAX_NUM_LANES) {
   1497        phy_num_lanes = MAX_NUM_LANES;
   1498     }
   1499 
   1500     SIMPLEX_TX(pc) = soc_property_port_get(unit, port, spn_PORT_PHY_MODE_REVERSE, 0);
   1501     /*CORE configuration*/
   1502     phymod_core_init_config_t_init(core_init_config);
   1503     fw_ld_method = 0x11;
   1504     if (soc_property_port_get(pc->unit, pc->port, "82381_glue", 0)) {
   1505         fw_ld_method = 0x1;
   1506     }
   1507 
   1508     fw_ld_method = soc_property_port_get(unit, port,
   1509                                          spn_PHY_FORCE_FIRMWARE_LOAD, fw_ld_method);
   1510     if (fw_ld_method & 0x1) {
   1511         switch ((fw_ld_method >> 4) & 0xf) {
   1512             case 0:
   1513                 core_init_config->firmware_load_method  = phymodFirmwareLoadMethodNone;
   1514             break;
   1515             case 1:
   1516                 core_init_config->firmware_load_method  = phymodFirmwareLoadMethodInternal;
   1517             break;
   1518             case 2:
   1519                 core_init_config->firmware_load_method  = phymodFirmwareLoadMethodProgEEPROM;
   1520             break;
   1521             default:
   1522                 core_init_config->firmware_load_method  = phymodFirmwareLoadMethodInternal;
   1523             break;
   1524         }
   1525     }
   1526     core_init_config->flags = PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY;
   1527     core_init_config->firmware_load_method &= 0xff; /* clear checksum bits */
   1528     core_init_config->lane_map.num_of_lanes = NUM_LANES;
   1529 
   1530     speed_config = &(pCfg->speed_config);
   1531     speed_config->port_refclk_int  = 156;
   1532     speed_config->port_num_lanes   = phy_num_lanes;
   1533     speed_config->speed = pc->speed_max;
   1534 
   1535     if (port_num_lanes == 1) {
   1536         if (pc->speed_max == PHY82381_SPD_25G ||
   1537             pc->speed_max == PHY82381_SPD_27G) {
   1538             speed_config->line_interface =  SOC_PORT_IF_LR;
   1539         } else if (pc->speed_max == PHY82381_SPD_20G  ||
   1540                    pc->speed_max == PHY82381_SPD_21G) {
   1541             speed_config->line_interface =  SOC_PORT_IF_LR;
   1542         } else if (pc->speed_max == PHY82381_SPD_1G) {
   1543             speed_config->line_interface =  SOC_PORT_IF_KX;
   1544         } else {
   1545             speed_config->line_interface =  SOC_PORT_IF_SR;
   1546         }
   1547     } else if (port_num_lanes == 4) {
   1548         if (pc->speed_max == PHY82381_SPD_40G ||
   1549             pc->speed_max == PHY82381_SPD_42G) {
   1550            speed_config->line_interface =  SOC_PORT_IF_SR4;
   1551         } else {
   1552            speed_config->line_interface =  SOC_PORT_IF_LR4;
   1553         }
   1554     } else if (port_num_lanes == 2) {
   1555         if (pc->speed_max == PHY82381_SPD_50G ||
   1556             pc->speed_max == PHY82381_SPD_53G) {
   1557             speed_config->line_interface =  SOC_PORT_IF_KR2;
   1558         } else if (pc->speed_max == PHY82381_SPD_40G ||
   1559                    pc->speed_max == PHY82381_SPD_42G) {
   1560             speed_config->line_interface =  SOC_PORT_IF_KR2;
   1561         } else {
   1562             speed_config->line_interface =  SOC_PORT_IF_KR2;
   1563         }
   1564     } else {
   1565         LOG_CLI((BSL_META_U(unit,"Invalid number of lanes:%d\n "), port_num_lanes));
   1566         return SOC_E_CONFIG;
   1567     }
   1568 
   1569     /* PHY configuration */
   1570     phymod_phy_init_config_t_init(pm_phy_init_config);
   1571 
   1572     pm_phy_init_config->polarity.rx_polarity
   1573                                  = soc_property_port_get(unit, port,
   1574                                    spn_PHY_RX_POLARITY_FLIP,
   1575                                    0xFFFF);
   1576     pm_phy_init_config->polarity.tx_polarity
   1577                                  = soc_property_port_get(unit, port,
   1578                                    spn_PHY_TX_POLARITY_FLIP,
   1579                                    0xFFFF);
   1580     preemphasis = 0x0;
   1581     preemphasis = soc_property_port_get(unit, port,
   1582             spn_PHY_PREEMPHASIS,
   1583             0x007F7F7F);
   1584 
   1585     driver_current = 0x0;
   1586     driver_current = soc_property_port_get(unit, port,
   1587             spn_PHY_DRIVER_CURRENT,
   1588             0xF);
   1589 
   1590     for (i = 0; i < MAX_NUM_LANES; i++) {
   1591         pm_phy_init_config->tx[i].pre = preemphasis & 0xff;
   1592         pm_phy_init_config->tx[i].main = (preemphasis & 0xff00) >> 8;
   1593         pm_phy_init_config->tx[i].post = (preemphasis & 0xff0000) >> 16;
   1594         pm_phy_init_config->tx[i].amp = driver_current;
   1595     }
   1596 
   1597     /* phy_ctrl_t configuration (LOGICAL PORT BASED)
   1598      * Only do this once, for the first core of the logical port*/
   1599     if (core_num == 0) {
   1600         /* phy_mode, PHYCTRL_MDIO_ADDR_SHARE, PHY_FLAGS_INDEPENDENT_LANE */
   1601         if (port_num_lanes == 4) {
   1602             pc->phy_mode = PHYCTRL_QUAD_LANE_PORT;
   1603             PHY_FLAGS_CLR(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
   1604         } else if (port_num_lanes == 2) {
   1605             pc->phy_mode = PHYCTRL_DUAL_LANE_PORT;
   1606             pc->flags |= PHYCTRL_MDIO_ADDR_SHARE;
   1607             PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
   1608         } else if (port_num_lanes == 1) {
   1609             pc->phy_mode = PHYCTRL_ONE_LANE_PORT;
   1610             pc->flags |= PHYCTRL_MDIO_ADDR_SHARE;
   1611             PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
   1612         }
   1613 
   1614     }
   1615 
   1616     return SOC_E_NONE;
   1617 }
   1618 
   1619 STATIC int
   1620 _phy_82381_init_pass1(int unit, soc_port_t port)
   1621 {
   1622     phy_ctrl_t *pc;
   1623     soc_phymod_ctrl_t *pmc;
   1624     soc_phymod_phy_t *phy = NULL;
   1625     soc_phymod_core_t *core;
   1626     phy82381_config_t *pCfg;
   1627     phy82381_speed_config_t *speed_config;
   1628     phymod_phy_inf_config_t interface_config;
   1629     phymod_core_status_t core_status;
   1630     phymod_core_info_t core_info;
   1631     int idx;
   1632     int logical_lane_offset;
   1633     soc_port_ability_t ability;
   1634     soc_phy_info_t *pi;
   1635     char *dev_name;
   1636     int len = 0;
   1637     uint32 chip_id = 0;
   1638 
   1639     pc = EXT_PHY_SW_STATE(unit, port);
   1640 
   1641     if (pc == NULL) {
   1642         return SOC_E_INTERNAL;
   1643     }
   1644 
   1645     pc->driver_data = (void*)(pc+1);
   1646     pmc = &pc->phymod_ctrl;
   1647     pCfg = (phy82381_config_t *) pc->driver_data;
   1648 
   1649     sal_memset(pCfg, 0, sizeof(*pCfg));
   1650     speed_config = &(pCfg->speed_config);
   1651 
   1652     sal_memset(&ability, 0, sizeof(ability));
   1653 
   1654     dev_name = DEV_NAME(pc);
   1655     phy = pmc->phy[0];
   1656 
   1657     SOC_IF_ERROR_RETURN(
   1658          _phy_82381_chip_id_get(&phy->pm_phy, &chip_id));
   1659     DEVID(pc) = chip_id;
   1660 
   1661     pi = &SOC_PHY_INFO(unit, port);
   1662     if (DEVID(pc) == FURIA_ID_82071) {
   1663         /* coverity[secure_coding] */
   1664         sal_strncpy (dev_name, "BCM82071", sal_strlen("BCM82071"));
   1665     } else if (DEVID(pc) == FURIA_ID_82070) {
   1666         /* coverity[secure_coding] */
   1667         sal_strncpy (dev_name, "BCM82070", sal_strlen("BCM82070"));
   1668     } else if (DEVID(pc) == FURIA_ID_82073) {
   1669         /* coverity[secure_coding] */
   1670         sal_strncpy (dev_name, "BCM82073", sal_strlen("BCM82073"));
   1671     } else if (DEVID(pc) == FURIA_ID_82072) {
   1672         /* coverity[secure_coding] */
   1673         sal_strncpy (dev_name, "BCM82072", sal_strlen("BCM82072"));
   1674     } else if (DEVID(pc) == FURIA_ID_82380) {
   1675         /* coverity[secure_coding] */
   1676         sal_strncpy (dev_name, "BCM82380", sal_strlen("BCM82380"));
   1677     } else if (DEVID(pc) == FURIA_ID_82381) {
   1678         /* coverity[secure_coding] */
   1679         sal_strncpy (dev_name, "BCM82381", sal_strlen("BCM82381"));
   1680     } else if (DEVID(pc) == FURIA_ID_82383) {
   1681         /* coverity[secure_coding] */
   1682         sal_strncpy (dev_name, "BCM82383", sal_strlen("BCM82383"));
   1683     } else if (DEVID(pc) == FURIA_ID_82208) {
   1684         /* coverity[secure_coding] */
   1685         sal_strncpy (dev_name, "BCM82208", sal_strlen("BCM82208"));
   1686     } else if (DEVID(pc) == FURIA_ID_82209) {
   1687         /* coverity[secure_coding] */
   1688         sal_strncpy (dev_name, "BCM82209", sal_strlen("BCM82209"));
   1689     } else if (DEVID(pc) == FURIA_ID_82212) {
   1690         /* coverity[secure_coding] */
   1691         sal_strncpy (dev_name, "BCM82212", sal_strlen("BCM82212"));
   1692     } else if (DEVID(pc) == FURIA_ID_82216) {
   1693         /* coverity[secure_coding] */
   1694         sal_strncpy (dev_name, "BCM82216", sal_strlen("BCM82216"));
   1695     } else if (DEVID(pc) == FURIA_ID_82314) {
   1696         /* coverity[secure_coding] */
   1697         sal_strncpy (dev_name, "BCM82314", sal_strlen("BCM82314"));
   1698     } else if (DEVID(pc) == FURIA_ID_82315) {
   1699         /* coverity[secure_coding] */
   1700         sal_strncpy (dev_name, "BCM82315", sal_strlen("BCM82315"));
   1701     } else {
   1702         /* coverity[secure_coding] */
   1703         sal_strncpy (dev_name, "Furia", sal_strlen("Furia"));
   1704     }
   1705 
   1706     len = sal_strlen(dev_name);
   1707 
   1708     dev_name[len++] = '/';
   1709     dev_name[len++] = pc->lane_num + '0';
   1710     dev_name[len] = 0;
   1711     pc->dev_name = dev_name;  /* string terminator */
   1712     pi->phy_name = dev_name;
   1713 
   1714     /* Loop through all phymod phys that support this SDK phy */
   1715     logical_lane_offset = 0;
   1716     for (idx = 0; idx < pmc->num_phys; idx++) {
   1717         phy = pmc->phy[idx];
   1718         core = phy->core;
   1719 
   1720         pCfg->device_aux_modes = (phy82381_device_aux_mode_t *)(core->device_aux_modes) ;
   1721         pCfg->device_aux_modes->repeater = soc_property_port_get(unit, port, spn_PHY_PCS_REPEATER, 1);
   1722         pCfg->device_aux_modes->avdd_tx_drv = soc_property_port_get(unit, port,
   1723                                    "phy_82381_vdd_tx_drv_voltage", 0);
   1724         pCfg->device_aux_modes->an_master_lane = soc_property_port_get(unit, port,
   1725                                             "phy_82381_an_master_lane", 0);
   1726         pCfg->device_aux_modes->ull_datapath = soc_property_port_get(unit, port,
   1727                                            "phy_82381_datapath", 0);
   1728 
   1729         if (pCfg->device_aux_modes->repeater &&
   1730                 pCfg->device_aux_modes->ull_datapath) {
   1731 
   1732             LOG_CLI((BSL_META_U(unit,"Both ULL datapath and repeater cannot be enabled simultaneously,"
   1733                         "so configuring repeater alone on port:%d\n "), port));
   1734             pCfg->device_aux_modes->repeater = 1;
   1735             pCfg->device_aux_modes->ull_datapath = 0;
   1736         }
   1737         /* determine configuration data structure to default values, based on SOC properties */
   1738         SOC_IF_ERROR_RETURN
   1739             (phy82381_config_init(unit, port,
   1740                               logical_lane_offset,
   1741                               &core->init_config, &phy->init_config));
   1742         speed_config->higig_port = PBMP_MEMBER(PBMP_HG_ALL(unit), port);
   1743         /* set the port to its max or init_speed */
   1744         SOC_IF_ERROR_RETURN
   1745              (phy82381_speed_to_interface_config_get(speed_config, &interface_config));
   1746         sal_memcpy(&core->init_config.interface, &interface_config, sizeof(interface_config));
   1747         core->init_config.interface.device_aux_modes = (void *)pCfg->device_aux_modes;
   1748         core->init_config.op_datapath =  pCfg->device_aux_modes->ull_datapath;
   1749         phy->init_config.an_link_qualifier = soc_property_port_get(unit, port,
   1750                                            "phy_82381_an_link_qualifier", 5);
   1751         core->init_config.tx_fifo_sync_offset = soc_property_port_get(unit, port,
   1752                                            "phy_82381_tx_synctype", 0);
   1753         core->init_config.rx_fifo_sync_offset =  soc_property_port_get(unit, port,
   1754                                            "phy_82381_rx_synctype", 0);
   1755 
   1756         core->init_config.tx_input_voltage = pCfg->device_aux_modes->avdd_tx_drv;
   1757         if (!core->init) {
   1758            core_status.pmd_active = 0;
   1759 #if defined (BCM_WARM_BOOT_SUPPORT)  /*  */
   1760     if ( SOC_WARM_BOOT(pc->unit) || SOC_IS_RELOADING(pc->unit) ) {
   1761         /* In case of warm boot do not update firmware again */
   1762         core->init_config.firmware_load_method=phymodFirmwareLoadMethodNone;
   1763     }
   1764 #endif /* BCM_WARM_BOOT_SUPPORT */
   1765            SOC_IF_ERROR_RETURN
   1766                (phymod_core_init(&core->pm_core, &core->init_config, &core_status));
   1767            core->init = TRUE;
   1768         }
   1769 
   1770         phy->init_config.op_mode = pCfg->device_aux_modes->repeater;
   1771         /*phy->init_config.an_link_qualifier*/
   1772 #if defined (BCM_WARM_BOOT_SUPPORT)  /*  */
   1773     if ( SOC_WARM_BOOT(pc->unit) || SOC_IS_RELOADING(pc->unit) ) {
   1774         /* In case of warm boot do not reinitialize */
   1775     }else
   1776 #endif /* BCM_WARM_BOOT_SUPPORT */
   1777         SOC_IF_ERROR_RETURN
   1778             (phymod_phy_init(&phy->pm_phy, &phy->init_config));
   1779 
   1780         /*read serdes id info */
   1781         SOC_IF_ERROR_RETURN
   1782             (phymod_core_info_get(&core->pm_core, &core_info));
   1783 
   1784         /* for multicore phys, need to ratchet up to the next batch of lanes */
   1785         logical_lane_offset += core->init_config.lane_map.num_of_lanes;
   1786     }
   1787     /* indicate second pass of init is needed */
   1788     if (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS1) {
   1789         PHYCTRL_INIT_STATE_SET(pc,PHYCTRL_INIT_STATE_PASS2);
   1790     }
   1791 
   1792     return SOC_E_NONE;
   1793 }
   1794 void phy82381_phyctrl_to_phymod_interface (uint16_t sys_if, phymod_interface_t *sys_intf)
   1795 {
   1796     switch (sys_if)
   1797     {
   1798         case SOC_PORT_IF_SFI:
   1799             *sys_intf = phymodInterfaceSFI;
   1800         break;
   1801         case SOC_PORT_IF_XFI:
   1802             *sys_intf = phymodInterfaceXFI;
   1803         break;
   1804         case SOC_PORT_IF_KX:
   1805             *sys_intf = phymodInterfaceKX;
   1806         break;
   1807         case SOC_PORT_IF_KR:
   1808             *sys_intf = phymodInterfaceKR;
   1809         break;
   1810         case SOC_PORT_IF_KR4:
   1811             *sys_intf = phymodInterfaceKR4;
   1812         break;
   1813         case SOC_PORT_IF_CR:
   1814             *sys_intf = phymodInterfaceCR;
   1815         break;
   1816         case SOC_PORT_IF_CR4:
   1817             *sys_intf = phymodInterfaceCR4;
   1818         break;
   1819         case SOC_PORT_IF_XLAUI:
   1820             *sys_intf = phymodInterfaceXLAUI;
   1821         break;
   1822         case SOC_PORT_IF_SR:
   1823             *sys_intf = phymodInterfaceSR;
   1824         break;
   1825         case SOC_PORT_IF_CAUI:
   1826             *sys_intf = phymodInterfaceCAUI;
   1827         break;
   1828         case SOC_PORT_IF_LR:
   1829             *sys_intf = phymodInterfaceLR;
   1830         break;
   1831         case SOC_PORT_IF_LR4:
   1832             *sys_intf = phymodInterfaceLR4;
   1833         break;
   1834         case SOC_PORT_IF_ER4:
   1835             *sys_intf = phymodInterfaceER4;
   1836         break;
   1837         case SOC_PORT_IF_SR4:
   1838             *sys_intf = phymodInterfaceSR4;
   1839         break;
   1840         case SOC_PORT_IF_KR2:
   1841             *sys_intf = phymodInterfaceKR2;
   1842         break;
   1843         case SOC_PORT_IF_SR2:
   1844             *sys_intf = phymodInterfaceSR2;
   1845         break;
   1846         case SOC_PORT_IF_CR2:
   1847             *sys_intf = phymodInterfaceCR2;
   1848         break;
   1849         case SOC_PORT_IF_XLAUI2:
   1850             *sys_intf = phymodInterfaceXLAUI2;
   1851         break;
   1852         case SOC_PORT_IF_CAUI_C2C:
   1853             *sys_intf = phymodInterfaceCAUI4_C2C;
   1854         break;
   1855         case SOC_PORT_IF_CAUI4:
   1856             *sys_intf = phymodInterfaceCAUI4;
   1857         break;
   1858 
   1859         default:
   1860             *sys_intf = 0;
   1861     }
   1862 
   1863 }
   1864 #if defined (BCM_WARM_BOOT_SUPPORT)
   1865 void phy82381_phymod_to_phyctrl_interface(uint16_t sys_if, soc_port_if_t *sys_intf)
   1866 {
   1867     switch (sys_if)
   1868     {
   1869         case phymodInterfaceSFI:
   1870             *sys_intf = SOC_PORT_IF_SFI;
   1871         break;
   1872         case  phymodInterfaceXFI:
   1873             *sys_intf = SOC_PORT_IF_XFI;
   1874         break;
   1875         case phymodInterfaceKX:
   1876             *sys_intf = SOC_PORT_IF_KX;
   1877         break;
   1878         case phymodInterfaceKR:
   1879             *sys_intf = SOC_PORT_IF_KR;
   1880         break;
   1881         case phymodInterfaceKR4:
   1882             *sys_intf = SOC_PORT_IF_KR4;
   1883         break;
   1884         case phymodInterfaceCR:
   1885             *sys_intf = SOC_PORT_IF_CR;
   1886         break;
   1887         case phymodInterfaceCR4:
   1888             *sys_intf = SOC_PORT_IF_CR4;
   1889         break;
   1890         case phymodInterfaceXLAUI:
   1891             *sys_intf = SOC_PORT_IF_XLAUI;
   1892         break;
   1893         case phymodInterfaceSR:
   1894             *sys_intf = SOC_PORT_IF_SR;
   1895         break;
   1896         case phymodInterfaceCAUI:
   1897             *sys_intf = SOC_PORT_IF_CAUI;
   1898         break;
   1899         case phymodInterfaceLR:
   1900             *sys_intf = SOC_PORT_IF_LR;
   1901         break;
   1902         case phymodInterfaceLR4:
   1903             *sys_intf = SOC_PORT_IF_LR4;
   1904         break;
   1905         case phymodInterfaceER4:
   1906             *sys_intf = SOC_PORT_IF_ER4;
   1907         break;
   1908         case phymodInterfaceSR4:
   1909             *sys_intf = SOC_PORT_IF_SR4;
   1910         break;
   1911         case phymodInterfaceKR2:
   1912             *sys_intf = SOC_PORT_IF_KR2;
   1913         break;
   1914         case phymodInterfaceCR2:
   1915             *sys_intf = SOC_PORT_IF_CR2;
   1916         break;
   1917         case phymodInterfaceXLAUI2:
   1918             *sys_intf = SOC_PORT_IF_XLAUI2;
   1919         break;
   1920         case phymodInterfaceCAUI4_C2C:
   1921             *sys_intf = SOC_PORT_IF_CAUI_C2C;
   1922         break;
   1923 
   1924         default:
   1925             *sys_intf = 0;
   1926     }
   1927 
   1928 }
   1929 #endif
   1930 STATIC int
   1931 _phy_82381_init_pass2(int unit, soc_port_t port)
   1932 {
   1933     phy_ctrl_t *pc;
   1934     soc_phymod_ctrl_t *pmc;
   1935     soc_phymod_phy_t *phy = NULL;
   1936     phy82381_config_t *pCfg;
   1937     phy82381_speed_config_t *speed_config;
   1938     phymod_phy_inf_config_t interface_config;
   1939     soc_port_ability_t ability;
   1940     uint16_t sys_if = 0;
   1941     phymod_interface_t sys_intf = 0;
   1942 #if defined (BCM_WARM_BOOT_SUPPORT)
   1943     soc_port_if_t pif;
   1944 #endif
   1945     pc = EXT_PHY_SW_STATE(unit, port);
   1946 
   1947     if (pc == NULL) {
   1948         return SOC_E_INTERNAL;
   1949     }
   1950 
   1951     sal_memset(&ability, 0, sizeof(ability));
   1952     pc->driver_data = (void*)(pc+1);
   1953     pmc = &pc->phymod_ctrl;
   1954     pCfg = (phy82381_config_t *) pc->driver_data;
   1955     speed_config = &(pCfg->speed_config);
   1956     phy = pmc->phy[0];
   1957 
   1958     SOC_IF_ERROR_RETURN
   1959          (phy82381_speed_to_interface_config_get(speed_config, &interface_config));
   1960 #if defined (BCM_WARM_BOOT_SUPPORT)
   1961     if ( SOC_WARM_BOOT(pc->unit) || SOC_IS_RELOADING(pc->unit) ) {
   1962        /* In case of warm boot do nothing  */
   1963         SOC_IF_ERROR_RETURN
   1964             (phymod_phy_interface_config_get(&phy->pm_phy,
   1965                                          0 /* flags */,0, &interface_config));
   1966         phy82381_phymod_to_phyctrl_interface(interface_config.interface_type, &pif);
   1967         pCfg->speed_config.line_interface = pif;
   1968         pCfg->speed_config.speed=interface_config.data_rate;
   1969     }else
   1970 #endif /* BCM_WARM_BOOT_SUPPORT */
   1971     SOC_IF_ERROR_RETURN
   1972         (phymod_phy_interface_config_set(&phy->pm_phy,
   1973                              0 /* flags */, &interface_config));
   1974     /* Config Sys interface*/
   1975     sys_if = soc_property_port_get(unit, port, spn_PHY_SYS_INTERFACE, 0);
   1976     if (sys_if) {
   1977         phy82381_phyctrl_to_phymod_interface(sys_if, &sys_intf);
   1978         if (sys_intf == 0) {
   1979             return SOC_E_PARAM;
   1980         }
   1981         phy->pm_phy.access.flags |= (1 << 31);
   1982         interface_config.interface_type = sys_intf;
   1983 
   1984 #if defined (BCM_WARM_BOOT_SUPPORT)
   1985     if ( SOC_WARM_BOOT(pc->unit) || SOC_IS_RELOADING(pc->unit) ) {
   1986        /* In case of warm boot do nothing  */
   1987         SOC_IF_ERROR_RETURN
   1988             (phymod_phy_interface_config_get(&phy->pm_phy,
   1989                                          0 /* flags */,0, &interface_config));
   1990     }else
   1991 #endif /* BCM_WARM_BOOT_SUPPORT */
   1992         SOC_IF_ERROR_RETURN
   1993            (phymod_phy_interface_config_set(&phy->pm_phy,
   1994                              0 /* flags */, &interface_config));
   1995 
   1996         phy->pm_phy.access.flags &= ~(1 << 31);
   1997     }
   1998     /* setup the port's an cap */
   1999     SOC_IF_ERROR_RETURN
   2000         (phy_82381_ability_local_get(unit, port, &ability));
   2001 
   2002     LOG_INFO(BSL_LS_SOC_PHY,
   2003              (BSL_META_U(pc->unit,
   2004                          "phy82381_init_pass2: u=%d p=%d\n"), unit, port));
   2005 
   2006     if (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS2) {
   2007         /* indicate third  pass of init is needed */
   2008         PHYCTRL_INIT_STATE_SET(pc,PHYCTRL_INIT_STATE_PASS3);
   2009     }
   2010 
   2011     return SOC_E_NONE;
   2012 }
   2013 
   2014 STATIC int
   2015 _phy_82381_init_pass3(int unit, soc_port_t port)
   2016 {
   2017     phy_ctrl_t *pc;
   2018     phy82381_config_t *pCfg;
   2019 
   2020     pc = EXT_PHY_SW_STATE(unit, port);
   2021 
   2022     if (pc == NULL) {
   2023         return SOC_E_INTERNAL;
   2024     }
   2025 
   2026     pc->driver_data = (void*)(pc+1);
   2027     pCfg = (phy82381_config_t *) pc->driver_data;
   2028 
   2029     LOG_INFO(BSL_LS_SOC_PHY,
   2030              (BSL_META_U(unit,
   2031                          "PHY82328 init pass3: u=%d p=%d\n"), unit, port));
   2032 
   2033     /* If configured, enable module auto detection */
   2034     pCfg->auto_mod_detect = soc_property_port_get(unit, port, spn_PHY_MOD_AUTO_DETECT, 0);
   2035     if (pCfg->auto_mod_detect) {
   2036 
   2037     }
   2038 
   2039     pCfg->an_master_lane = pCfg->device_aux_modes->an_master_lane ;
   2040     pCfg->ull_datapath =  pCfg->device_aux_modes->ull_datapath;
   2041 
   2042 
   2043     return SOC_E_NONE;
   2044 }
   2045 
   2046 /*
   2047  * Function:
   2048  *      phy82381_init
   2049  *
   2050  *      An SDK "phy" is a logical port, which can consist of from 1-10 lanes,
   2051  *          (A phy with more than 4 lanes requires more than one core).
   2052  *      Per-logical port information is saved in &pc->driver_data.
   2053  *      An SDK phy is implemented as one or more PHYMOD "phy"s.
   2054  *
   2055  *      A PHYMOD "phy" resides completely within a single core, which can be
   2056  *      from 1 to 4 lanes.
   2057  *      Per-phymod phy information is kept in (soc_phymod_ctrl_t) *pc->phymod_ctrl
   2058  *      A phymod phy points to its core.  Up to 4 phymod phys can be on a single core
   2059  *
   2060  * Purpose:
   2061  *      Initialize a phy82381
   2062  * Parameters:
   2063  *      unit - BCM unit number.
   2064  *      port - Port number.
   2065  * Returns:
   2066  *      SOC_E_NONE
   2067  */
   2068 STATIC int
   2069 phy_82381_init(int unit, soc_port_t port)
   2070 {
   2071     phy_ctrl_t *pc;
   2072 
   2073     pc = EXT_PHY_SW_STATE(unit, port);
   2074     if (pc == NULL) {
   2075         return SOC_E_INTERNAL;
   2076     }
   2077     if ((PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS1) ||
   2078         (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_DEFAULT)) {
   2079 
   2080         PHY_FLAGS_SET(unit, port,  PHY_FLAGS_FIBER | PHY_FLAGS_C45 | PHY_FLAGS_REPEATER);
   2081         SOC_IF_ERROR_RETURN(_phy_82381_init_pass1(unit, port));
   2082 
   2083         if (PHYCTRL_INIT_STATE(pc) != PHYCTRL_INIT_STATE_DEFAULT) {
   2084             return SOC_E_NONE;
   2085         }
   2086     }
   2087     if ((PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS2) ||
   2088         (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_DEFAULT)) {
   2089 
   2090         SOC_IF_ERROR_RETURN( _phy_82381_init_pass2(unit, port));
   2091 
   2092         LOG_INFO(BSL_LS_SOC_PHY,
   2093                  (BSL_META_U(unit,
   2094                              "82381 init pass2 completed: u=%d p=%d\n"), unit, port));
   2095         if (PHYCTRL_INIT_STATE(pc) != PHYCTRL_INIT_STATE_DEFAULT) {
   2096             return SOC_E_NONE;
   2097         }
   2098     }
   2099 
   2100     if ((PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_PASS3) ||
   2101         (PHYCTRL_INIT_STATE(pc) == PHYCTRL_INIT_STATE_DEFAULT)) {
   2102 
   2103         SOC_IF_ERROR_RETURN(_phy_82381_init_pass3(unit, port));
   2104 
   2105         LOG_INFO(BSL_LS_SOC_PHY,
   2106                  (BSL_META_U(unit,
   2107                              "PHY82381 init pass3 completed: u=%d p=%d\n"), unit, port));
   2108         PHYCTRL_INIT_STATE_SET(pc, PHYCTRL_INIT_STATE_DEFAULT);
   2109         return SOC_E_NONE;
   2110     }
   2111     return SOC_E_NONE;
   2112 }
   2113 
   2114 /*
   2115  * Function:
   2116  *      phy_82381_ability_local_get
   2117  * Purpose:
   2118  *      xx
   2119  * Parameters:
   2120  *      unit - BCM unit number.
   2121  *      port - Port number.
   2122  *      ability - xx
   2123  * Returns:
   2124  *      SOC_E_NONE
   2125  */
   2126 STATIC int
   2127 phy_82381_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability)
   2128 {
   2129     phy_ctrl_t          *pc;
   2130     uint32_t pa_speed = 0;
   2131 
   2132     pc = EXT_PHY_SW_STATE(unit, port);
   2133 
   2134     if (NULL == ability) {
   2135         return SOC_E_PARAM;
   2136     }
   2137 
   2138     sal_memset(ability, 0, sizeof(*ability));
   2139     if (pc->speed_max == PHY82381_SPD_100G ||
   2140         pc->speed_max == PHY82381_SPD_106G) {
   2141         pa_speed = SOC_PA_SPEED_106GB | SOC_PA_SPEED_100GB | SOC_PA_SPEED_42GB | SOC_PA_SPEED_40GB
   2142             | SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB | SOC_PA_SPEED_27GB | SOC_PA_SPEED_25GB
   2143             | SOC_PA_SPEED_53GB | SOC_PA_SPEED_50GB | SOC_PA_SPEED_11GB | SOC_PA_SPEED_10GB
   2144             | SOC_PA_SPEED_6000MB | SOC_PA_SPEED_1000MB;
   2145     } else if (pc->speed_max == PHY82381_SPD_50G ||
   2146                pc->speed_max == PHY82381_SPD_53G) {
   2147         pa_speed = SOC_PA_SPEED_53GB | SOC_PA_SPEED_50GB | SOC_PA_SPEED_42GB | SOC_PA_SPEED_40GB
   2148             | SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB | SOC_PA_SPEED_27GB | SOC_PA_SPEED_25GB
   2149             | SOC_PA_SPEED_11GB | SOC_PA_SPEED_10GB | SOC_PA_SPEED_6000MB | SOC_PA_SPEED_1000MB;
   2150     } else if (pc->speed_max == PHY82381_SPD_40G ||
   2151                pc->speed_max == PHY82381_SPD_42G) {
   2152         pa_speed = SOC_PA_SPEED_42GB | SOC_PA_SPEED_40GB | SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB
   2153             | SOC_PA_SPEED_27GB | SOC_PA_SPEED_25GB | SOC_PA_SPEED_11GB | SOC_PA_SPEED_10GB | SOC_PA_SPEED_6000MB
   2154             | SOC_PA_SPEED_1000MB;
   2155     } else if (pc->speed_max == PHY82381_SPD_25G ||
   2156                pc->speed_max == PHY82381_SPD_27G) {
   2157         pa_speed = SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB | SOC_PA_SPEED_6000MB | SOC_PA_SPEED_1000MB
   2158             | SOC_PA_SPEED_27GB | SOC_PA_SPEED_25GB | SOC_PA_SPEED_11GB | SOC_PA_SPEED_10GB;
   2159     } else if (pc->speed_max == PHY82381_SPD_20G ||
   2160                pc->speed_max == PHY82381_SPD_21G) {
   2161         pa_speed = SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB | SOC_PA_SPEED_11GB | SOC_PA_SPEED_10GB | SOC_PA_SPEED_6000MB
   2162             | SOC_PA_SPEED_1000MB;
   2163     } else if (pc->speed_max == PHY82381_SPD_10G ||
   2164                pc->speed_max == PHY82381_SPD_11G) {
   2165         pa_speed = SOC_PA_SPEED_11GB | SOC_PA_SPEED_10GB | SOC_PA_SPEED_6000MB | SOC_PA_SPEED_1000MB;
   2166     } else {
   2167         pa_speed = SOC_PA_SPEED_106GB | SOC_PA_SPEED_100GB | SOC_PA_SPEED_53GB | SOC_PA_SPEED_50GB | SOC_PA_SPEED_40GB
   2168             | SOC_PA_SPEED_27GB | SOC_PA_SPEED_25GB | SOC_PA_SPEED_21GB | SOC_PA_SPEED_20GB
   2169             | SOC_PA_SPEED_11GB | SOC_PA_SPEED_10GB | SOC_PA_SPEED_6000MB | SOC_PA_SPEED_1000MB;
   2170     }
   2171 
   2172     ability->loopback  = SOC_PA_LB_PHY;
   2173     ability->medium    = SOC_PA_MEDIUM_COPPER;
   2174     ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   2175     ability->interface = SOC_PA_INTF_XGMII;
   2176     ability->flags     = SOC_PA_AUTONEG;
   2177     ability->speed_full_duplex = pa_speed;
   2178 
   2179 
   2180     LOG_INFO(BSL_LS_SOC_PHY,
   2181              (BSL_META_U(pc->unit,
   2182                          "phy82381_ability_local_get:unit=%d p=%d sp=%08x\n"),
   2183               unit, port, ability->speed_full_duplex));
   2184     return (SOC_E_NONE);
   2185 }
   2186 
   2187 STATIC int
   2188 phy_82381_link_get(int unit, soc_port_t port, int *link)
   2189 {
   2190     phy_ctrl_t                *pc;
   2191     soc_phymod_ctrl_t         *pmc;
   2192     phymod_phy_access_t       *pm_phy;
   2193     phy_ctrl_t *int_pc;
   2194     int32 int_phy_link = 0;
   2195     uint32 chip_id = 0;
   2196     *link = 0;
   2197     int_pc = INT_PHY_SW_STATE(unit, port);
   2198     pc = EXT_PHY_SW_STATE(unit, port);
   2199     if (pc == NULL) {
   2200         return SOC_E_INTERNAL;
   2201     }
   2202     pmc = &pc->phymod_ctrl;
   2203     pm_phy = &pmc->phy[pmc->main_phy]->pm_phy;
   2204     if (is_eye_scan_enabled) {
   2205         /* Return Success if eyescan is in progress*/
   2206         if (int_pc != NULL) {
   2207             SOC_IF_ERROR_RETURN(PHY_LINK_GET(int_pc->pd, unit, port, &int_phy_link));
   2208         }
   2209         *link = int_phy_link;
   2210 #ifdef PHY82381_DEBUG
   2211         if (*link == 0) {
   2212             LOG_CLI((BSL_META_U(unit,"PCS Down: port:%d\n "), port));
   2213         }
   2214 #endif
   2215         return SOC_E_NONE;
   2216     }
   2217     if (int_pc != NULL) {
   2218         SOC_IF_ERROR_RETURN(PHY_LINK_GET(int_pc->pd, unit, port, &int_phy_link));
   2219     }
   2220 
   2221     chip_id = DEVID(pc);
   2222     if (FURIA_IS_SIMPLEX(chip_id) && (!SIMPLEX_TX(pc))) {
   2223        pm_phy->access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2224        pm_phy->access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   2225     }
   2226     /* Get the external phy link status if external phy is duplex or simplex package connected in Rx side */
   2227     if (FURIA_IS_DUPLEX(chip_id) || (FURIA_IS_SIMPLEX(chip_id) && (!SIMPLEX_TX(pc)))) {
   2228         SOC_IF_ERROR_RETURN
   2229             (phymod_phy_link_status_get(pm_phy, (uint32_t *) link));
   2230         /* When PMD lock of 82381 is not Set, Leave the port link as
   2231          * PMD status of 82381. When PMD lock of 82381 is set use
   2232          * PCS status of internal serdes as port link status.
   2233          * When internal serdes is not there use 82381 PMS as link status*/
   2234 #ifdef PHY82381_DEBUG
   2235         if (*link == 1 && int_phy_link == 0) {
   2236             LOG_CLI((BSL_META_U(unit,"PMD UP PCS Down: port:%d\n "), port));
   2237         }
   2238         if (*link == 0 && int_phy_link == 1) {
   2239             LOG_CLI((BSL_META_U(unit,"PMD DOWN PCS UP port:%d\n "), port));
   2240         }
   2241 #endif
   2242         if (*link && int_pc) {
   2243             *link = int_phy_link;
   2244         }
   2245     } else {
   2246         *link = int_phy_link;
   2247     }
   2248     pm_phy->access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2249     return SOC_E_NONE;
   2250 }
   2251 
   2252 STATIC int
   2253 phy_82381_enable_set(int unit, soc_port_t port, int enable)
   2254 {
   2255     phy_ctrl_t                *pc;
   2256     int32 intf;
   2257     /* locate phy control */
   2258     pc = EXT_PHY_SW_STATE(unit, port);
   2259     if (pc == NULL) {
   2260         return SOC_E_INTERNAL;
   2261     }
   2262     if (is_eye_scan_enabled) {
   2263         /* Return Success if eyescan is in progress*/
   2264         return SOC_E_NONE;
   2265     }
   2266     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82381_SYS_SIDE : PHY82381_LINE_SIDE;
   2267 
   2268 
   2269     SOC_IF_ERROR_RETURN
   2270         (phy_82381_power_set(pc, intf, enable));
   2271 
   2272     if (enable) {
   2273         PHY_FLAGS_CLR(unit, port, PHY_FLAGS_DISABLE);
   2274     } else {
   2275         PHY_FLAGS_SET(unit, port, PHY_FLAGS_DISABLE);
   2276     }
   2277 
   2278     return SOC_E_NONE;
   2279 }
   2280 
   2281 STATIC int
   2282 phy_82381_enable_get(int unit, soc_port_t port, int *enable)
   2283 {
   2284     phy_ctrl_t                *pc;
   2285     int32 intf;
   2286     uint32_t ena_dis;
   2287     *enable = 0;
   2288 
   2289     /* locate phy control */
   2290     pc = EXT_PHY_SW_STATE(unit, port);
   2291     if (pc == NULL) {
   2292         return SOC_E_INTERNAL;
   2293     }
   2294     if (is_eye_scan_enabled) {
   2295         /* Return Success if eyescan is in progress*/
   2296         *enable =1;
   2297         return SOC_E_NONE;
   2298     }
   2299     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82381_SYS_SIDE : PHY82381_LINE_SIDE;
   2300     SOC_IF_ERROR_RETURN
   2301         (phy_82381_power_get(pc, intf, &ena_dis));
   2302     *enable = ena_dis;
   2303     return SOC_E_NONE;
   2304 }
   2305 
   2306 STATIC int
   2307 phy_82381_lb_set(int unit, soc_port_t port, int enable)
   2308 {
   2309     phy_ctrl_t* pc;
   2310     pc = EXT_PHY_SW_STATE(unit, port);
   2311     if (pc == NULL) {
   2312         return SOC_E_INTERNAL;
   2313     }
   2314 
   2315     SOC_IF_ERROR_RETURN (
   2316         phy_82381_loopback_internal_pmd_set(pc, PHY82381_LINE_SIDE, enable));
   2317 
   2318     return SOC_E_NONE;
   2319 }
   2320 
   2321 STATIC int
   2322 phy_82381_firmware_set(int unit, int port, int offset, uint8 *array,int datalen)
   2323 {
   2324     return SOC_E_UNAVAIL;
   2325 
   2326 }
   2327 
   2328 /*
   2329  * phy_82381_per_lane_loopback_internal_pmd_get (this is the PMD global loopback)
   2330  */
   2331 STATIC int
   2332 phy_82381_per_lane_loopback_internal_pmd_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   2333 {
   2334     phymod_phy_access_t    *pm_phy;
   2335     uint32_t               enable;
   2336     soc_phymod_phy_t    *p_phy;
   2337     uint32              lane_map;
   2338     phymod_phy_access_t pm_phy_copy;
   2339     soc_phymod_ctrl_t *pmc;
   2340     pmc = &pc->phymod_ctrl;
   2341 
   2342     /* locate the desired phy and lane */
   2343     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2344 
   2345     /* Make a copy of the phy access and overwrite the desired lane */
   2346     pm_phy = &p_phy->pm_phy;
   2347     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2348     pm_phy_copy.access.lane_mask = lane_map;
   2349     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2350     if(intf == PHY82381_SYS_SIDE) {
   2351         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   2352     }
   2353 
   2354 
   2355     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(&pm_phy_copy, phymodLoopbackGlobalPMD, &enable));
   2356     *value = enable;
   2357     return(SOC_E_NONE);
   2358 }
   2359 /*
   2360  * phy_82381_loopback_internal_pmd_get (this is the PMD global loopback)
   2361  */
   2362 STATIC int
   2363 phy_82381_loopback_internal_pmd_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   2364 {
   2365     phymod_phy_access_t    *pm_phy;
   2366     uint32_t               enable;
   2367     phymod_phy_access_t pm_phy_copy;
   2368     soc_phymod_ctrl_t *pmc;
   2369     pmc = &pc->phymod_ctrl;
   2370 
   2371     /* just take the value from the first phy */
   2372     if (pmc->phy[0] == NULL) {
   2373         return SOC_E_INTERNAL;
   2374     }
   2375     pm_phy = &pmc->phy[0]->pm_phy;
   2376 
   2377     if (pm_phy == NULL) {
   2378         return SOC_E_INTERNAL;
   2379     }
   2380 
   2381     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2382     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2383     if(intf == PHY82381_SYS_SIDE) {
   2384         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   2385     }
   2386     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(&pm_phy_copy, phymodLoopbackGlobalPMD, &enable));
   2387     *value = enable;
   2388     return(SOC_E_NONE);
   2389 }
   2390 
   2391 /*
   2392  * phy_82381_per_lane_loopback_remote_get
   2393  */
   2394 STATIC int
   2395 phy_82381_per_lane_loopback_remote_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   2396 {
   2397     phymod_phy_access_t    *pm_phy;
   2398     uint32_t               enable;
   2399     soc_phymod_phy_t    *p_phy;
   2400     uint32              lane_map;
   2401     phymod_phy_access_t pm_phy_copy;
   2402     soc_phymod_ctrl_t *pmc;
   2403     pmc = &pc->phymod_ctrl;
   2404 
   2405     /* locate the desired phy and lane */
   2406     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2407 
   2408     /* Make a copy of the phy access and overwrite the desired lane */
   2409     pm_phy = &p_phy->pm_phy;
   2410     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2411     pm_phy_copy.access.lane_mask = lane_map;
   2412     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2413     if(intf == PHY82381_SYS_SIDE) {
   2414         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   2415     }
   2416 
   2417     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(&pm_phy_copy, phymodLoopbackRemotePMD, &enable));
   2418     *value = enable;
   2419     return(SOC_E_NONE);
   2420 }
   2421 
   2422 /*
   2423  * phy_82381_loopback_remote_get
   2424  */
   2425 STATIC int
   2426 phy_82381_loopback_remote_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   2427 {
   2428     phymod_phy_access_t    *pm_phy;
   2429     uint32_t               enable;
   2430     phymod_phy_access_t pm_phy_copy;
   2431     soc_phymod_ctrl_t *pmc;
   2432     pmc = &pc->phymod_ctrl;
   2433 
   2434     /* just take the value from the first phy */
   2435     if (pmc->phy[0] == NULL) {
   2436         return SOC_E_INTERNAL;
   2437     }
   2438     pm_phy = &pmc->phy[0]->pm_phy;
   2439 
   2440     if (pm_phy == NULL) {
   2441         return SOC_E_INTERNAL;
   2442     }
   2443 
   2444     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2445     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2446     if(intf == PHY82381_SYS_SIDE) {
   2447         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   2448     }
   2449     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(&pm_phy_copy, phymodLoopbackRemotePMD, &enable));
   2450     *value = enable;
   2451     return(SOC_E_NONE);
   2452 }
   2453 
   2454 /*
   2455  * phy_82381_per_lane_prbs_tx_poly_get
   2456  */
   2457 STATIC int
   2458 phy_82381_per_lane_prbs_tx_poly_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   2459 {
   2460     phymod_phy_access_t  *pm_phy;
   2461     phymod_prbs_t        prbs;
   2462     uint32_t flags = 0;
   2463 
   2464 
   2465     soc_phymod_phy_t    *p_phy;
   2466     uint32              lane_map;
   2467     phymod_phy_access_t pm_phy_copy;
   2468     uint32_t if_side = 0;
   2469     uint32_t chip_id = 0;
   2470     uint32 simplex_tx = 0;
   2471     soc_phymod_ctrl_t *pmc;
   2472     pmc = &pc->phymod_ctrl;
   2473 
   2474 
   2475     /* locate the desired phy and lane */
   2476     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2477 
   2478     /* Make a copy of the phy access and overwrite the desired lane */
   2479     pm_phy = &p_phy->pm_phy;
   2480 
   2481     simplex_tx = SIMPLEX_TX(pc);
   2482     chip_id = DEVID(pc);
   2483     SOC_IF_ERROR_RETURN
   2484         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   2485 
   2486     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2487     pm_phy_copy.access.lane_mask = lane_map;
   2488     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2489     pm_phy_copy.access.flags |= if_side;
   2490     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2491     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2492 
   2493     *value = (int) prbs.poly;
   2494 
   2495     /* convert from PHYMOD enum to SDK enum */
   2496     switch(prbs.poly){
   2497     case phymodPrbsPoly7:
   2498         *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1;
   2499         break;
   2500     case phymodPrbsPoly9:
   2501         *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1;
   2502         break;
   2503     case phymodPrbsPoly15:
   2504         *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1;
   2505         break;
   2506     case phymodPrbsPoly23:
   2507         *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1;
   2508         break;
   2509     case phymodPrbsPoly31:
   2510         *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1;
   2511         break;
   2512     case phymodPrbsPoly11:
   2513         *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1;
   2514         break;
   2515     case phymodPrbsPoly58:
   2516         *value = SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1;
   2517         break;
   2518     default:
   2519         return SOC_E_INTERNAL;
   2520     }
   2521     return SOC_E_NONE;
   2522 }
   2523 
   2524 /*
   2525  * phy_82381_prbs_tx_poly_get
   2526  */
   2527 STATIC int
   2528 phy_82381_prbs_tx_poly_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   2529 {
   2530     phymod_phy_access_t  *pm_phy;
   2531     phymod_prbs_t        prbs;
   2532     uint32_t flags = 0;
   2533     phymod_phy_access_t pm_phy_copy;
   2534     uint32_t if_side = 0;
   2535     uint32_t chip_id = 0;
   2536     uint32 simplex_tx = 0;
   2537     soc_phymod_ctrl_t *pmc;
   2538     pmc = &pc->phymod_ctrl;
   2539 
   2540 
   2541     /* just take the value from the first phy */
   2542     if (pmc->phy[0] == NULL) {
   2543         return SOC_E_INTERNAL;
   2544     }
   2545     pm_phy = &pmc->phy[0]->pm_phy;
   2546 
   2547     if (pm_phy == NULL) {
   2548         return SOC_E_INTERNAL;
   2549     }
   2550 
   2551     simplex_tx = SIMPLEX_TX(pc);
   2552     chip_id = DEVID(pc);
   2553     SOC_IF_ERROR_RETURN
   2554         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   2555 
   2556     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2557     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2558     pm_phy_copy.access.flags |= if_side;
   2559     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2560     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2561 
   2562     *value = (int) prbs.poly;
   2563     /* convert from PHYMOD enum to SDK enum */
   2564     switch(prbs.poly){
   2565     case phymodPrbsPoly7:
   2566         *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1;
   2567         break;
   2568     case phymodPrbsPoly9:
   2569         *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1;
   2570         break;
   2571     case phymodPrbsPoly15:
   2572         *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1;
   2573         break;
   2574     case phymodPrbsPoly23:
   2575         *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1;
   2576         break;
   2577     case phymodPrbsPoly31:
   2578         *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1;
   2579         break;
   2580     case phymodPrbsPoly11:
   2581         *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1;
   2582         break;
   2583     case phymodPrbsPoly58:
   2584         *value = SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1;
   2585         break;
   2586     default:
   2587         return SOC_E_INTERNAL;
   2588     }
   2589     return SOC_E_NONE;
   2590 }
   2591 
   2592 
   2593 STATIC int
   2594 phy_82381_short_chn_mode_enable_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   2595 {
   2596     phymod_phy_access_t  *pm_phy;
   2597     int                    idx;
   2598     phymod_phy_access_t pm_phy_copy;
   2599     uint32_t if_side = 0;
   2600     uint32_t chip_id = 0;
   2601     uint32 simplex_tx = 0;
   2602     soc_phymod_ctrl_t *pmc;
   2603     pmc = &pc->phymod_ctrl;
   2604 
   2605 
   2606     for (idx = 0; idx < pmc->num_phys; idx++) {
   2607         if (pmc->phy[idx] == NULL) {
   2608             return SOC_E_INTERNAL;
   2609         }
   2610         pm_phy = &pmc->phy[idx]->pm_phy;
   2611         if (pm_phy == NULL) {
   2612             return SOC_E_INTERNAL;
   2613         }
   2614         simplex_tx = SIMPLEX_TX(pc);
   2615         chip_id = DEVID(pc);
   2616         SOC_IF_ERROR_RETURN
   2617             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   2618 
   2619         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2620         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2621         pm_phy_copy.access.flags |= if_side;
   2622         SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_set(&pm_phy_copy, value));
   2623     }
   2624 
   2625     return(SOC_E_NONE);
   2626 }
   2627 
   2628 STATIC int
   2629 phy_82381_short_chn_mode_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   2630 {
   2631     phymod_phy_access_t  *pm_phy;
   2632     phymod_phy_access_t pm_phy_copy;
   2633     uint32_t if_side = 0;
   2634     uint32_t chip_id = 0;
   2635     uint32 simplex_tx = 0, status = 0;
   2636     soc_phymod_ctrl_t *pmc;
   2637     pmc = &pc->phymod_ctrl;
   2638 
   2639     /* just take the value from the first phy */
   2640     if (pmc->phy[0] == NULL) {
   2641         return SOC_E_INTERNAL;
   2642     }
   2643     pm_phy = &pmc->phy[0]->pm_phy;
   2644 
   2645     if (pm_phy == NULL) {
   2646         return SOC_E_INTERNAL;
   2647     }
   2648 
   2649     simplex_tx = SIMPLEX_TX(pc);
   2650     chip_id = DEVID(pc);
   2651     SOC_IF_ERROR_RETURN
   2652         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   2653 
   2654     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2655     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2656     pm_phy_copy.access.flags |= if_side;
   2657     SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_get(&pm_phy_copy, value, &status));
   2658 
   2659     return(SOC_E_NONE);
   2660 }
   2661 
   2662 STATIC int
   2663 phy_82381_short_chn_mode_status_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   2664 {
   2665     phymod_phy_access_t  *pm_phy;
   2666     phymod_phy_access_t pm_phy_copy;
   2667     uint32_t if_side = 0;
   2668     uint32_t chip_id = 0, enable = 0;
   2669     uint32 simplex_tx = 0;
   2670     soc_phymod_ctrl_t *pmc;
   2671     pmc = &pc->phymod_ctrl;
   2672 
   2673     /* just take the value from the first phy */
   2674     if (pmc->phy[0] == NULL) {
   2675         return SOC_E_INTERNAL;
   2676     }
   2677     pm_phy = &pmc->phy[0]->pm_phy;
   2678 
   2679     if (pm_phy == NULL) {
   2680         return SOC_E_INTERNAL;
   2681     }
   2682 
   2683     simplex_tx = SIMPLEX_TX(pc);
   2684     chip_id = DEVID(pc);
   2685     SOC_IF_ERROR_RETURN
   2686         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   2687 
   2688     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2689     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2690     pm_phy_copy.access.flags |= if_side;
   2691 
   2692     SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_get(&pm_phy_copy, &enable, value));
   2693 
   2694     return(SOC_E_NONE);
   2695 }
   2696 
   2697 STATIC int
   2698 phy_82381_per_lane_short_chn_mode_enable_set(phy_ctrl_t *pc, soc_port_t port, int32 intf, int lane, uint32 value)
   2699 {
   2700     phymod_phy_access_t *pm_phy;
   2701     phymod_phy_access_t pm_phy_copy;
   2702     soc_phymod_phy_t    *p_phy;
   2703     uint32              lane_map;
   2704     soc_phymod_ctrl_t *pmc;
   2705     pmc = &pc->phymod_ctrl;
   2706 
   2707     /* locate the desired phy and lane */
   2708     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2709 
   2710     /* Make a copy of the phy access and overwrite the desired lane */
   2711     pm_phy = &p_phy->pm_phy;
   2712     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2713     pm_phy_copy.access.lane_mask = lane_map;
   2714     if(intf == PHY82381_SYS_SIDE) {
   2715         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   2716     }
   2717 
   2718     SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_set(&pm_phy_copy, value));
   2719 
   2720     return(SOC_E_NONE);
   2721 }
   2722 
   2723 
   2724 STATIC int
   2725 phy_82381_per_lane_short_chn_mode_enable_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2726 {
   2727     phymod_phy_access_t *pm_phy;
   2728     phymod_phy_access_t pm_phy_copy;
   2729     soc_phymod_phy_t    *p_phy;
   2730     uint32              lane_map, status = 0;
   2731     soc_phymod_ctrl_t *pmc;
   2732     pmc = &pc->phymod_ctrl;
   2733 
   2734     /* locate the desired phy and lane */
   2735     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2736 
   2737     /* Make a copy of the phy access and overwrite the desired lane */
   2738     pm_phy = &p_phy->pm_phy;
   2739     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2740     pm_phy_copy.access.lane_mask = lane_map;
   2741     if(intf == PHY82381_SYS_SIDE) {
   2742         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   2743     }
   2744 
   2745     SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_get(&pm_phy_copy, value, &status));
   2746 
   2747     return(SOC_E_NONE);
   2748 }
   2749 
   2750 STATIC int
   2751 phy_82381_per_lane_short_chn_mode_status_get(phy_ctrl_t *pc, soc_port_t port, int32 intf, int lane, uint32 *value)
   2752 {
   2753     phymod_phy_access_t *pm_phy;
   2754     phymod_phy_access_t pm_phy_copy;
   2755     soc_phymod_phy_t    *p_phy;
   2756     uint32              lane_map, enable = 0;
   2757     soc_phymod_ctrl_t *pmc;
   2758     pmc = &pc->phymod_ctrl;
   2759 
   2760     /* locate the desired phy and lane */
   2761     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2762 
   2763     /* Make a copy of the phy access and overwrite the desired lane */
   2764     pm_phy = &p_phy->pm_phy;
   2765     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2766     pm_phy_copy.access.lane_mask = lane_map;
   2767     if(intf == PHY82381_SYS_SIDE) {
   2768         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   2769     }
   2770 
   2771     SOC_IF_ERROR_RETURN(phymod_phy_short_chn_mode_enable_get(&pm_phy_copy, &enable, value));
   2772 
   2773     return(SOC_E_NONE);
   2774 }
   2775 
   2776 /*
   2777  * phy_82381_per_lane_prbs_rx_poly_get
   2778  */
   2779 STATIC int
   2780 phy_82381_per_lane_prbs_rx_poly_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   2781 {
   2782     phymod_phy_access_t  *pm_phy;
   2783     phymod_prbs_t        prbs;
   2784     uint32_t flags = 0;
   2785 
   2786 
   2787     soc_phymod_phy_t    *p_phy;
   2788     uint32              lane_map;
   2789     phymod_phy_access_t pm_phy_copy;
   2790     uint32_t if_side = 0;
   2791     uint32_t chip_id = 0;
   2792     uint32 simplex_tx = 0;
   2793     soc_phymod_ctrl_t *pmc;
   2794     pmc = &pc->phymod_ctrl;
   2795 
   2796 
   2797     /* locate the desired phy and lane */
   2798     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2799 
   2800     /* Make a copy of the phy access and overwrite the desired lane */
   2801     pm_phy = &p_phy->pm_phy;
   2802 
   2803     simplex_tx = SIMPLEX_TX(pc);
   2804     chip_id = DEVID(pc);
   2805     SOC_IF_ERROR_RETURN
   2806         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   2807 
   2808     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2809     pm_phy_copy.access.lane_mask = lane_map;
   2810     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2811     pm_phy_copy.access.flags |= if_side;
   2812     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   2813     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2814 
   2815     *value = (int) prbs.poly;
   2816 
   2817     /* convert from PHYMOD enum to SDK enum */
   2818     switch(prbs.poly){
   2819     case phymodPrbsPoly7:
   2820         *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1;
   2821         break;
   2822     case phymodPrbsPoly9:
   2823         *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1;
   2824         break;
   2825     case phymodPrbsPoly15:
   2826         *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1;
   2827         break;
   2828     case phymodPrbsPoly23:
   2829         *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1;
   2830         break;
   2831     case phymodPrbsPoly31:
   2832         *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1;
   2833         break;
   2834     case phymodPrbsPoly11:
   2835         *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1;
   2836         break;
   2837     case phymodPrbsPoly58:
   2838         *value = SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1;
   2839         break;
   2840     default:
   2841         return SOC_E_INTERNAL;
   2842     }
   2843     return SOC_E_NONE;
   2844 }
   2845 /*
   2846  * phy_82381_prbs_rx_poly_get
   2847  */
   2848 STATIC int
   2849 phy_82381_prbs_rx_poly_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   2850 {
   2851     phymod_phy_access_t  *pm_phy;
   2852     phymod_prbs_t        prbs;
   2853     phymod_phy_access_t pm_phy_copy;
   2854     uint32_t flags = 0;
   2855     uint32_t if_side = 0;
   2856     uint32_t chip_id = 0;
   2857     uint32 simplex_tx = 0;
   2858     soc_phymod_ctrl_t *pmc;
   2859     pmc = &pc->phymod_ctrl;
   2860 
   2861 
   2862     /* just take the value from the first phy */
   2863     if (pmc->phy[0] == NULL) {
   2864         return SOC_E_INTERNAL;
   2865     }
   2866     pm_phy = &pmc->phy[0]->pm_phy;
   2867 
   2868     if (pm_phy == NULL) {
   2869         return SOC_E_INTERNAL;
   2870     }
   2871 
   2872 
   2873     simplex_tx = SIMPLEX_TX(pc);
   2874     chip_id = DEVID(pc);
   2875     SOC_IF_ERROR_RETURN
   2876         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   2877 
   2878     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2879     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2880     pm_phy_copy.access.flags |= if_side;
   2881     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   2882     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2883 
   2884     *value = (int) prbs.poly;
   2885 
   2886     /* convert from PHYMOD enum to SDK enum */
   2887     switch(prbs.poly){
   2888     case phymodPrbsPoly7:
   2889         *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1;
   2890         break;
   2891     case phymodPrbsPoly9:
   2892         *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1;
   2893         break;
   2894     case phymodPrbsPoly15:
   2895         *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1;
   2896         break;
   2897     case phymodPrbsPoly23:
   2898         *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1;
   2899         break;
   2900     case phymodPrbsPoly31:
   2901         *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1;
   2902         break;
   2903     case phymodPrbsPoly11:
   2904         *value = SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1;
   2905         break;
   2906     case phymodPrbsPoly58:
   2907         *value = SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1;
   2908         break;
   2909     default:
   2910         return SOC_E_INTERNAL;
   2911     }
   2912     return SOC_E_NONE;
   2913 }
   2914 
   2915 /*
   2916  * phy_82381_per_lane_prbs_tx_invert_data_get
   2917  */
   2918 STATIC int
   2919 phy_82381_per_lane_prbs_tx_invert_data_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   2920 {
   2921     phymod_phy_access_t  *pm_phy;
   2922     phymod_prbs_t        prbs;
   2923     uint32_t flags = 0;
   2924 
   2925     soc_phymod_phy_t    *p_phy;
   2926     uint32              lane_map;
   2927     phymod_phy_access_t pm_phy_copy;
   2928     uint32_t if_side = 0;
   2929     uint32_t chip_id = 0;
   2930     uint32 simplex_tx = 0;
   2931     soc_phymod_ctrl_t *pmc;
   2932     pmc = &pc->phymod_ctrl;
   2933 
   2934 
   2935     /* locate the desired phy and lane */
   2936     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2937 
   2938     /* Make a copy of the phy access and overwrite the desired lane */
   2939     pm_phy = &p_phy->pm_phy;
   2940 
   2941     simplex_tx = SIMPLEX_TX(pc);
   2942     chip_id = DEVID(pc);
   2943     SOC_IF_ERROR_RETURN
   2944         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   2945 
   2946     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2947     pm_phy_copy.access.lane_mask = lane_map;
   2948     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2949     pm_phy_copy.access.flags |= if_side;
   2950 
   2951     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2952     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2953     *value = prbs.invert;
   2954 
   2955     return(SOC_E_NONE);
   2956 }
   2957 /*
   2958  * phy_82381_prbs_tx_invert_data_get
   2959  */
   2960 STATIC int
   2961 phy_82381_prbs_tx_invert_data_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   2962 {
   2963     phymod_phy_access_t  *pm_phy;
   2964     phymod_prbs_t        prbs;
   2965     uint32_t flags = 0;
   2966     phymod_phy_access_t pm_phy_copy;
   2967     uint32_t if_side = 0;
   2968     uint32_t chip_id = 0;
   2969     uint32 simplex_tx = 0;
   2970     soc_phymod_ctrl_t *pmc;
   2971     pmc = &pc->phymod_ctrl;
   2972 
   2973 
   2974     /* just take the value from the first phy */
   2975     if (pmc->phy[0] == NULL) {
   2976         return SOC_E_INTERNAL;
   2977     }
   2978     pm_phy = &pmc->phy[0]->pm_phy;
   2979 
   2980     if (pm_phy == NULL) {
   2981         return SOC_E_INTERNAL;
   2982     }
   2983 
   2984     simplex_tx = SIMPLEX_TX(pc);
   2985     chip_id = DEVID(pc);
   2986     SOC_IF_ERROR_RETURN
   2987         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   2988 
   2989     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2990     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   2991     pm_phy_copy.access.flags |= if_side;
   2992     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2993     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   2994     *value = prbs.invert;
   2995 
   2996     return(SOC_E_NONE);
   2997 }
   2998 
   2999 /*
   3000  * phy_82381_per_lane_prbs_rx_invert_data_get
   3001  */
   3002 STATIC int
   3003 phy_82381_per_lane_prbs_rx_invert_data_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   3004 {
   3005     phymod_phy_access_t  *pm_phy;
   3006     phymod_prbs_t        prbs;
   3007     uint32_t flags = 0;
   3008     soc_phymod_phy_t    *p_phy;
   3009     uint32              lane_map;
   3010     phymod_phy_access_t pm_phy_copy;
   3011     uint32_t if_side = 0;
   3012     uint32_t chip_id = 0;
   3013     uint32 simplex_tx = 0;
   3014     soc_phymod_ctrl_t *pmc;
   3015     pmc = &pc->phymod_ctrl;
   3016 
   3017 
   3018 
   3019     /* locate the desired phy and lane */
   3020     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3021 
   3022     /* Make a copy of the phy access and overwrite the desired lane */
   3023     pm_phy = &p_phy->pm_phy;
   3024 
   3025     simplex_tx = SIMPLEX_TX(pc);
   3026     chip_id = DEVID(pc);
   3027     SOC_IF_ERROR_RETURN
   3028         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3029 
   3030     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3031     pm_phy_copy.access.lane_mask = lane_map;
   3032     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3033     pm_phy_copy.access.flags |= if_side;
   3034 
   3035     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   3036     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   3037     *value = prbs.invert;
   3038 
   3039     return(SOC_E_NONE);
   3040 }
   3041 /*
   3042  * phy_82381_prbs_rx_invert_data_get
   3043  */
   3044 STATIC int
   3045 phy_82381_prbs_rx_invert_data_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3046 {
   3047     phymod_phy_access_t  *pm_phy;
   3048     phymod_prbs_t        prbs;
   3049     uint32_t flags = 0;
   3050     phymod_phy_access_t pm_phy_copy;
   3051     uint32_t if_side = 0;
   3052     uint32_t chip_id = 0;
   3053     uint32 simplex_tx = 0;
   3054     soc_phymod_ctrl_t *pmc;
   3055     pmc = &pc->phymod_ctrl;
   3056 
   3057     /* just take the value from the first phy */
   3058     if (pmc->phy[0] == NULL) {
   3059         return SOC_E_INTERNAL;
   3060     }
   3061     pm_phy = &pmc->phy[0]->pm_phy;
   3062 
   3063     if (pm_phy == NULL) {
   3064         return SOC_E_INTERNAL;
   3065     }
   3066 
   3067     simplex_tx = SIMPLEX_TX(pc);
   3068     chip_id = DEVID(pc);
   3069     SOC_IF_ERROR_RETURN
   3070         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3071 
   3072     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3073     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3074     pm_phy_copy.access.flags |= if_side;
   3075 
   3076     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   3077     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   3078     *value = prbs.invert;
   3079 
   3080     return(SOC_E_NONE);
   3081 }
   3082 
   3083 /*
   3084  * phy_82381_per_lane_prbs_tx_enable_get
   3085  */
   3086 STATIC int
   3087 phy_82381_per_lane_prbs_tx_enable_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   3088 {
   3089     phymod_phy_access_t  *pm_phy;
   3090     uint32_t flags = 0;
   3091     soc_phymod_phy_t    *p_phy;
   3092     uint32              lane_map;
   3093     phymod_phy_access_t pm_phy_copy;
   3094     uint32_t if_side = 0;
   3095     uint32_t chip_id = 0;
   3096     uint32 simplex_tx = 0;
   3097     soc_phymod_ctrl_t *pmc;
   3098     pmc = &pc->phymod_ctrl;
   3099 
   3100 
   3101     /* locate the desired phy and lane */
   3102     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3103 
   3104     /* Make a copy of the phy access and overwrite the desired lane */
   3105     pm_phy = &p_phy->pm_phy;
   3106 
   3107     simplex_tx = SIMPLEX_TX(pc);
   3108     chip_id = DEVID(pc);
   3109     SOC_IF_ERROR_RETURN
   3110         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   3111     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3112     pm_phy_copy.access.lane_mask = lane_map;
   3113     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3114     pm_phy_copy.access.flags |= if_side;
   3115 
   3116     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   3117     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(&pm_phy_copy, flags, value));
   3118 
   3119     return(SOC_E_NONE);
   3120 }
   3121 
   3122 /*
   3123  * phy_82381_prbs_tx_enable_get
   3124  */
   3125 STATIC int
   3126 phy_82381_prbs_tx_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3127 {
   3128     phymod_phy_access_t  *pm_phy;
   3129     uint32_t flags = 0;
   3130     phymod_phy_access_t pm_phy_copy;
   3131     uint32_t if_side = 0;
   3132     uint32_t chip_id = 0;
   3133     uint32 simplex_tx = 0;
   3134     soc_phymod_ctrl_t *pmc;
   3135     pmc = &pc->phymod_ctrl;
   3136 
   3137 
   3138     /* just take the value from the first phy */
   3139     if (pmc->phy[0] == NULL) {
   3140         return SOC_E_INTERNAL;
   3141     }
   3142     pm_phy = &pmc->phy[0]->pm_phy;
   3143 
   3144     if (pm_phy == NULL) {
   3145         return SOC_E_INTERNAL;
   3146     }
   3147 
   3148     simplex_tx = SIMPLEX_TX(pc);
   3149     chip_id = DEVID(pc);
   3150     SOC_IF_ERROR_RETURN
   3151         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   3152 
   3153     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3154     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3155     pm_phy_copy.access.flags |= if_side;
   3156     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   3157     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(&pm_phy_copy, flags, value));
   3158 
   3159     return(SOC_E_NONE);
   3160 }
   3161 
   3162 /*
   3163  * phy_82381_per_lane_prbs_rx_enable_get
   3164  */
   3165 STATIC int
   3166 phy_82381_per_lane_prbs_rx_enable_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   3167 {
   3168     phymod_phy_access_t  *pm_phy;
   3169     uint32_t flags = 0;
   3170     soc_phymod_phy_t    *p_phy;
   3171     uint32              lane_map;
   3172     phymod_phy_access_t pm_phy_copy;
   3173     uint32_t if_side = 0;
   3174     uint32_t chip_id = 0;
   3175     uint32 simplex_tx = 0;
   3176     soc_phymod_ctrl_t *pmc;
   3177     pmc = &pc->phymod_ctrl;
   3178 
   3179 
   3180     /* locate the desired phy and lane */
   3181     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3182 
   3183     /* Make a copy of the phy access and overwrite the desired lane */
   3184     pm_phy = &p_phy->pm_phy;
   3185 
   3186     simplex_tx = SIMPLEX_TX(pc);
   3187     chip_id = DEVID(pc);
   3188     SOC_IF_ERROR_RETURN
   3189         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3190 
   3191     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3192     pm_phy_copy.access.lane_mask = lane_map;
   3193     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3194     pm_phy_copy.access.flags |= if_side;
   3195 
   3196     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   3197     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(&pm_phy_copy, flags, value));
   3198 
   3199     return(SOC_E_NONE);
   3200 }
   3201 /*
   3202  * phy_82381_prbs_rx_enable_get
   3203  */
   3204 STATIC int
   3205 phy_82381_prbs_rx_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3206 {
   3207     phymod_phy_access_t  *pm_phy;
   3208     uint32_t flags = 0;
   3209     phymod_phy_access_t pm_phy_copy;
   3210     uint32_t if_side = 0;
   3211     uint32_t chip_id = 0;
   3212     uint32 simplex_tx = 0;
   3213     soc_phymod_ctrl_t *pmc;
   3214     pmc = &pc->phymod_ctrl;
   3215 
   3216 
   3217     /* just take the value from the first phy */
   3218     if (pmc->phy[0] == NULL) {
   3219         return SOC_E_INTERNAL;
   3220     }
   3221     pm_phy = &pmc->phy[0]->pm_phy;
   3222 
   3223     if (pm_phy == NULL) {
   3224         return SOC_E_INTERNAL;
   3225     }
   3226 
   3227     simplex_tx = SIMPLEX_TX(pc);
   3228     chip_id = DEVID(pc);
   3229     SOC_IF_ERROR_RETURN
   3230         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3231 
   3232     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3233     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3234     pm_phy_copy.access.flags |= if_side;
   3235 
   3236     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   3237     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(&pm_phy_copy, flags, value));
   3238 
   3239     return(SOC_E_NONE);
   3240 }
   3241 
   3242 /*
   3243  * phy_82381_per_lane_prbs_rx_status_get
   3244  */
   3245 STATIC int
   3246 phy_82381_per_lane_prbs_rx_status_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   3247 {
   3248     phymod_phy_access_t    *pm_phy;
   3249     phymod_prbs_status_t   prbs_tmp;
   3250     int prbs_lock, lock_loss, error_count ;
   3251     soc_phymod_phy_t    *p_phy;
   3252     uint32              lane_map;
   3253     phymod_phy_access_t pm_phy_copy;
   3254     uint32_t if_side = 0;
   3255     uint32_t chip_id = 0;
   3256     uint32 simplex_tx = 0;
   3257     soc_phymod_ctrl_t *pmc;
   3258     pmc = &pc->phymod_ctrl;
   3259 
   3260 
   3261     prbs_lock   = 1 ;
   3262     lock_loss   = 0 ;
   3263     error_count = 0 ;
   3264     /* locate the desired phy and lane */
   3265     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3266 
   3267     /* Make a copy of the phy access and overwrite the desired lane */
   3268     pm_phy = &p_phy->pm_phy;
   3269 
   3270     simplex_tx = SIMPLEX_TX(pc);
   3271     chip_id = DEVID(pc);
   3272     SOC_IF_ERROR_RETURN
   3273         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3274 
   3275     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3276     pm_phy_copy.access.lane_mask = lane_map;
   3277     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3278     pm_phy_copy.access.flags |= if_side;
   3279     /* $$$ Need to add diagnostic API */
   3280     SOC_IF_ERROR_RETURN
   3281         (phymod_phy_prbs_status_get(&pm_phy_copy, 0, &prbs_tmp));
   3282 
   3283     if(prbs_tmp.prbs_lock==0) {
   3284         prbs_lock = 0 ;
   3285     } else {
   3286         if(prbs_tmp.prbs_lock_loss) {
   3287             lock_loss = 1 ;
   3288         } else {
   3289             error_count += prbs_tmp.error_count;
   3290         }
   3291     }
   3292 
   3293     if (prbs_lock == 0) {
   3294         *value = -1;
   3295     } else if ((lock_loss == 1) && (prbs_lock == 1)) {
   3296         *value = -2;
   3297     } else {
   3298         *value = error_count;
   3299     }
   3300     return(SOC_E_NONE);
   3301 }
   3302 /*
   3303  * phy_82381_prbs_rx_status_get
   3304  */
   3305 STATIC int
   3306 phy_82381_prbs_rx_status_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3307 {
   3308     phymod_phy_access_t    *pm_phy;
   3309     phymod_prbs_status_t   prbs_tmp;
   3310     int idx, prbs_lock, lock_loss, error_count ;
   3311     phymod_phy_access_t pm_phy_copy;
   3312     uint32_t if_side = 0;
   3313     uint32_t chip_id = 0;
   3314     uint32 simplex_tx = 0;
   3315     soc_phymod_ctrl_t *pmc;
   3316     pmc = &pc->phymod_ctrl;
   3317 
   3318 
   3319     /* just take the value from the first phy */
   3320     if (pmc->phy[0] == NULL) {
   3321         return SOC_E_INTERNAL;
   3322     }
   3323 
   3324     prbs_lock   = 1 ;
   3325     lock_loss   = 0 ;
   3326     error_count = 0 ;
   3327     for (idx = 0; idx < pmc->num_phys; idx++) {
   3328         pm_phy = &pmc->phy[idx]->pm_phy;
   3329 
   3330         if (pm_phy == NULL) {
   3331             return SOC_E_INTERNAL;
   3332         }
   3333 
   3334         simplex_tx = SIMPLEX_TX(pc);
   3335         chip_id = DEVID(pc);
   3336         SOC_IF_ERROR_RETURN
   3337             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3338 
   3339         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3340         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3341         pm_phy_copy.access.flags |= if_side;
   3342         /* $$$ Need to add diagnostic API */
   3343         SOC_IF_ERROR_RETURN
   3344             (phymod_phy_prbs_status_get(&pm_phy_copy, 0, &prbs_tmp));
   3345         if(prbs_tmp.prbs_lock==0) {
   3346             prbs_lock = 0 ;
   3347         } else {
   3348             if(prbs_tmp.prbs_lock_loss) {
   3349                 lock_loss = 1 ;
   3350             } else {
   3351                 error_count += prbs_tmp.error_count;
   3352             }
   3353         }
   3354     }
   3355 
   3356     if (prbs_lock == 0) {
   3357         *value = -1;
   3358     } else if ((lock_loss == 1) && (prbs_lock == 1)) {
   3359         *value = -2;
   3360     } else {
   3361         *value = error_count;
   3362     }
   3363     return(SOC_E_NONE);
   3364 }
   3365 /*
   3366  * phy_82381_per_lane_rx_peak_filter_get
   3367  */
   3368 STATIC int
   3369 phy_82381_per_lane_rx_peak_filter_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   3370 {
   3371     soc_phymod_phy_t    *p_phy;
   3372     uint32              lane_map;
   3373     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3374     phymod_rx_t         phymod_rx;
   3375     uint32_t if_side = 0;
   3376     uint32_t chip_id = 0;
   3377     uint32 simplex_tx = 0;
   3378     soc_phymod_ctrl_t *pmc;
   3379     pmc = &pc->phymod_ctrl;
   3380 
   3381 
   3382     *value = 0;
   3383 
   3384     /* locate the desired phy and lane */
   3385     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3386 
   3387     /* Make a copy of the phy access and overwrite the desired lane */
   3388     pm_phy = &p_phy->pm_phy;
   3389 
   3390     simplex_tx = SIMPLEX_TX(pc);
   3391     chip_id = DEVID(pc);
   3392     SOC_IF_ERROR_RETURN
   3393         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3394 
   3395     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3396     pm_phy_copy.access.lane_mask = lane_map;
   3397     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3398     pm_phy_copy.access.flags |= if_side;
   3399 
   3400     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3401         *value = phymod_rx.peaking_filter.value;
   3402 
   3403     return(SOC_E_NONE);
   3404 }
   3405 
   3406 /*
   3407  * phy_82381_per_lane_rx_vga_get
   3408  */
   3409 STATIC int
   3410 phy_82381_per_lane_rx_vga_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   3411 {
   3412     soc_phymod_phy_t    *p_phy;
   3413     uint32              lane_map;
   3414     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3415     phymod_rx_t         phymod_rx;
   3416     uint32_t if_side = 0;
   3417     uint32_t chip_id = 0;
   3418     uint32 simplex_tx = 0;
   3419     soc_phymod_ctrl_t *pmc;
   3420     pmc = &pc->phymod_ctrl;
   3421 
   3422 
   3423     *value = 0;
   3424 
   3425     /* locate the desired phy and lane */
   3426     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3427 
   3428     /* Make a copy of the phy access and overwrite the desired lane */
   3429     pm_phy = &p_phy->pm_phy;
   3430 
   3431     simplex_tx = SIMPLEX_TX(pc);
   3432     chip_id = DEVID(pc);
   3433     SOC_IF_ERROR_RETURN
   3434         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3435 
   3436     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3437     pm_phy_copy.access.lane_mask = lane_map;
   3438     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3439     pm_phy_copy.access.flags |= if_side;
   3440 
   3441     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3442         *value = phymod_rx.vga.value;
   3443 
   3444     return(SOC_E_NONE);
   3445 }
   3446 
   3447 /*
   3448  * phy_82381_per_lane_rx_dfe_tap_control_get
   3449  */
   3450 STATIC int
   3451 phy_82381_per_lane_rx_dfe_tap_control_get(phy_ctrl_t *pc, int32 intf, int lane, int tap, uint32 *value)
   3452 {
   3453     soc_phymod_phy_t    *p_phy;
   3454     uint32              lane_map;
   3455     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3456     phymod_rx_t          phymod_rx;
   3457     uint32_t if_side = 0;
   3458     uint32_t chip_id = 0;
   3459     uint32 simplex_tx = 0;
   3460     soc_phymod_ctrl_t *pmc;
   3461     pmc = &pc->phymod_ctrl;
   3462 
   3463 
   3464     *value = 0;
   3465 
   3466     /* locate the desired phy and lane */
   3467     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3468 
   3469     /* Make a copy of the phy access and overwrite the desired lane */
   3470     pm_phy = &p_phy->pm_phy;
   3471 
   3472     simplex_tx = SIMPLEX_TX(pc);
   3473     chip_id = DEVID(pc);
   3474     SOC_IF_ERROR_RETURN
   3475         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3476 
   3477     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3478     pm_phy_copy.access.lane_mask = lane_map;
   3479     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3480     pm_phy_copy.access.flags |= if_side;
   3481 
   3482     if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) {
   3483         /* this can only happen with a coding error */
   3484         return SOC_E_INTERNAL;
   3485     }
   3486 
   3487     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3488     *value = phymod_rx.dfe[tap].value;
   3489 
   3490     return(SOC_E_NONE);
   3491 }
   3492 
   3493 
   3494 /*
   3495  * phy_82381_per_lane_rx_low_freq_filter_get
   3496  */
   3497 STATIC int
   3498 phy_82381_per_lane_rx_low_freq_filter_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   3499 {
   3500     soc_phymod_phy_t    *p_phy;
   3501     uint32              lane_map;
   3502     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3503     phymod_rx_t          phymod_rx;
   3504     uint32_t if_side = 0;
   3505     uint32_t chip_id = 0;
   3506     uint32 simplex_tx = 0;
   3507     soc_phymod_ctrl_t *pmc;
   3508     pmc = &pc->phymod_ctrl;
   3509 
   3510 
   3511     *value = 0;
   3512 
   3513     /* locate the desired phy and lane */
   3514     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3515 
   3516     /* Make a copy of the phy access and overwrite the desired lane */
   3517     pm_phy = &p_phy->pm_phy;
   3518 
   3519     simplex_tx = SIMPLEX_TX(pc);
   3520     chip_id = DEVID(pc);
   3521     SOC_IF_ERROR_RETURN
   3522         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3523 
   3524     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3525     pm_phy_copy.access.lane_mask = lane_map;
   3526     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3527     pm_phy_copy.access.flags |= if_side;
   3528 
   3529     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3530     *value = phymod_rx.low_freq_peaking_filter.value;
   3531    return(SOC_E_NONE);
   3532 }
   3533 
   3534 /*
   3535  * phy_82381_rx_low_freq_filter_get
   3536  */
   3537 STATIC int
   3538 phy_82381_rx_low_freq_filter_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3539 {
   3540     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3541     phymod_rx_t          phymod_rx;
   3542     uint32_t if_side = 0;
   3543     uint32_t chip_id = 0;
   3544     uint32 simplex_tx = 0;
   3545     soc_phymod_ctrl_t *pmc;
   3546     pmc = &pc->phymod_ctrl;
   3547 
   3548 
   3549     *value = 0;
   3550 
   3551 
   3552     /* just take the value from the first phy */
   3553     if (pmc->phy[0] == NULL) {
   3554         return SOC_E_INTERNAL;
   3555     }
   3556     pm_phy = &pmc->phy[0]->pm_phy;
   3557 
   3558     if (pm_phy == NULL) {
   3559         return SOC_E_INTERNAL;
   3560     }
   3561 
   3562     simplex_tx = SIMPLEX_TX(pc);
   3563     chip_id = DEVID(pc);
   3564     SOC_IF_ERROR_RETURN
   3565         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3566 
   3567     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3568     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3569     pm_phy_copy.access.flags |= if_side;
   3570 
   3571     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3572     *value = phymod_rx.low_freq_peaking_filter.value;
   3573     return(SOC_E_NONE);
   3574 }
   3575 /*
   3576  * phy_82381_rx_peak_filter_get
   3577  */
   3578 STATIC int
   3579 phy_82381_rx_peak_filter_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3580 {
   3581     phymod_phy_access_t  *pm_phy;
   3582     phymod_rx_t          phymod_rx;
   3583     phymod_phy_access_t pm_phy_copy;
   3584     uint32_t if_side = 0;
   3585     uint32_t chip_id = 0;
   3586     uint32 simplex_tx = 0;
   3587     soc_phymod_ctrl_t *pmc;
   3588     pmc = &pc->phymod_ctrl;
   3589 
   3590 
   3591     /* just take the value from the first phy */
   3592     if (pmc->phy[0] == NULL) {
   3593         return SOC_E_INTERNAL;
   3594     }
   3595     pm_phy = &pmc->phy[0]->pm_phy;
   3596 
   3597     if (pm_phy == NULL) {
   3598         return SOC_E_INTERNAL;
   3599     }
   3600 
   3601     simplex_tx = SIMPLEX_TX(pc);
   3602     chip_id = DEVID(pc);
   3603     SOC_IF_ERROR_RETURN
   3604         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3605 
   3606     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3607     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3608     pm_phy_copy.access.flags |= if_side;
   3609 
   3610     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3611     *value = phymod_rx.peaking_filter.value;
   3612 
   3613     return(SOC_E_NONE);
   3614 }
   3615 
   3616 /*
   3617  * phy_82381_rx_vga_set
   3618  */
   3619 STATIC int
   3620 phy_82381_rx_vga_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3621 {
   3622     phymod_phy_access_t  *pm_phy;
   3623     phymod_rx_t          phymod_rx;
   3624     phymod_phy_access_t pm_phy_copy;
   3625     uint32_t if_side = 0;
   3626     uint32_t chip_id = 0;
   3627     uint32 simplex_tx = 0;
   3628     soc_phymod_ctrl_t *pmc;
   3629     pmc = &pc->phymod_ctrl;
   3630 
   3631 
   3632 
   3633     /* just take the value from the first phy */
   3634     if (pmc->phy[0] == NULL) {
   3635         return SOC_E_INTERNAL;
   3636     }
   3637     pm_phy = &pmc->phy[0]->pm_phy;
   3638 
   3639     if (pm_phy == NULL) {
   3640         return SOC_E_INTERNAL;
   3641     }
   3642 
   3643     simplex_tx = SIMPLEX_TX(pc);
   3644     chip_id = DEVID(pc);
   3645     SOC_IF_ERROR_RETURN
   3646         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3647 
   3648     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3649     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3650     pm_phy_copy.access.flags |= if_side;
   3651 
   3652     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3653     *value = phymod_rx.vga.value;
   3654 
   3655     return(SOC_E_NONE);
   3656 }
   3657 
   3658 /*
   3659  * phy_82381_rx_tap_get
   3660  */
   3661 STATIC int
   3662 phy_82381_rx_tap_get(phy_ctrl_t *pc, int32 intf, int tap, uint32 *value)
   3663 {
   3664     phymod_phy_access_t  *pm_phy;
   3665     phymod_rx_t          phymod_rx;
   3666     phymod_phy_access_t pm_phy_copy;
   3667     uint32_t if_side = 0;
   3668     uint32_t chip_id = 0;
   3669     uint32 simplex_tx = 0;
   3670     soc_phymod_ctrl_t *pmc;
   3671     pmc = &pc->phymod_ctrl;
   3672 
   3673 
   3674     if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) {
   3675         /* this can only happen with a coding error */
   3676         return SOC_E_INTERNAL;
   3677     }
   3678     /* just take the value from the first phy */
   3679     if (pmc->phy[0] == NULL) {
   3680         return SOC_E_INTERNAL;
   3681     }
   3682     pm_phy = &pmc->phy[0]->pm_phy;
   3683 
   3684     if (pm_phy == NULL) {
   3685         return SOC_E_INTERNAL;
   3686     }
   3687 
   3688 
   3689     simplex_tx = SIMPLEX_TX(pc);
   3690     chip_id = DEVID(pc);
   3691     SOC_IF_ERROR_RETURN
   3692         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3693 
   3694 
   3695     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3696     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3697     pm_phy_copy.access.flags |= if_side;
   3698     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3699     *value = phymod_rx.dfe[tap].value;
   3700 
   3701     return(SOC_E_NONE);
   3702 }
   3703 
   3704 /*
   3705  * phy_82381_pi_control_get
   3706  */
   3707 STATIC int
   3708 phy_82381_pi_control_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3709 {
   3710     phymod_phy_access_t  *pm_phy;
   3711     phymod_tx_override_t tx_override;
   3712     phymod_phy_access_t pm_phy_copy;
   3713     soc_phymod_ctrl_t *pmc;
   3714     uint32_t if_side = 0;
   3715     uint32_t chip_id = 0;
   3716     uint32 simplex_tx = 0;
   3717     pmc = &pc->phymod_ctrl;
   3718 
   3719     /* just take the value from the first phy */
   3720     if (pmc->phy[0] == NULL) {
   3721         return SOC_E_INTERNAL;
   3722     }
   3723     pm_phy = &pmc->phy[0]->pm_phy;
   3724 
   3725     if (pm_phy == NULL) {
   3726         return SOC_E_INTERNAL;
   3727     }
   3728     simplex_tx = SIMPLEX_TX(pc);
   3729     chip_id = DEVID(pc);
   3730     SOC_IF_ERROR_RETURN
   3731         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   3732     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3733     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3734     pm_phy_copy.access.flags |= if_side;
   3735 
   3736     SOC_IF_ERROR_RETURN(phymod_phy_tx_override_get(&pm_phy_copy, &tx_override));
   3737     *value = tx_override.phase_interpolator.value;
   3738 
   3739     return(SOC_E_NONE);
   3740 }
   3741 /*
   3742  * phy_82381_rx_seq_done_get
   3743  */
   3744 STATIC int
   3745 phy_82381_rx_seq_done_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3746 {
   3747     phymod_phy_access_t  *pm_phy;
   3748     phymod_phy_access_t pm_phy_copy;
   3749     uint32_t if_side = 0;
   3750     uint32_t chip_id = 0;
   3751     uint32 simplex_tx = 0;
   3752     soc_phymod_ctrl_t *pmc;
   3753     pmc = &pc->phymod_ctrl;
   3754 
   3755 
   3756     /* just take the value from the first phy */
   3757     if (pmc->phy[0] == NULL) {
   3758         return SOC_E_INTERNAL;
   3759     }
   3760     pm_phy = &pmc->phy[0]->pm_phy;
   3761 
   3762     if (pm_phy == NULL) {
   3763          return SOC_E_INTERNAL;
   3764     }
   3765 
   3766     simplex_tx = SIMPLEX_TX(pc);
   3767     chip_id = DEVID(pc);
   3768     SOC_IF_ERROR_RETURN
   3769         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   3770 
   3771     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3772     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3773     pm_phy_copy.access.flags |= if_side;
   3774 
   3775     SOC_IF_ERROR_RETURN(phymod_phy_rx_pmd_locked_get(&pm_phy_copy, value));
   3776 
   3777     return(SOC_E_NONE);
   3778 }
   3779 /*
   3780  * phy_82381_fec_get
   3781  */
   3782 STATIC int
   3783 phy_82381_fec_enable_get(phy_ctrl_t  *pc, uint32 *value)
   3784 {
   3785     phymod_phy_access_t    *pm_phy;
   3786     uint32_t               enable;
   3787     soc_phymod_ctrl_t *pmc;
   3788     pmc = &pc->phymod_ctrl;
   3789 
   3790     /* just take the value from the first phy */
   3791     if (pmc->phy[0] == NULL) {
   3792         return SOC_E_INTERNAL;
   3793     }
   3794     pm_phy = &pmc->phy[0]->pm_phy;
   3795 
   3796     if (pm_phy == NULL) {
   3797         return SOC_E_INTERNAL;
   3798     }
   3799 
   3800     SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_get(pm_phy,  &enable));
   3801     *value = enable;
   3802 
   3803     return(SOC_E_NONE);
   3804 }
   3805 /*
   3806  * phy_82381_tx_fir_pre_get
   3807  */
   3808 STATIC int
   3809 phy_82381_tx_fir_pre_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3810 {
   3811     phymod_phy_access_t *pm_phy;
   3812     phymod_tx_t         phymod_tx;
   3813     phymod_phy_access_t pm_phy_copy;
   3814     uint32_t if_side = 0;
   3815     uint32_t chip_id = 0;
   3816     uint32 simplex_tx = 0;
   3817     soc_phymod_ctrl_t *pmc;
   3818     pmc = &pc->phymod_ctrl;
   3819 
   3820 
   3821     pm_phy = &pmc->phy[0]->pm_phy;
   3822 
   3823     if (pm_phy == NULL) {
   3824         return SOC_E_INTERNAL;
   3825     }
   3826 
   3827     simplex_tx = SIMPLEX_TX(pc);
   3828     chip_id = DEVID(pc);
   3829     SOC_IF_ERROR_RETURN
   3830         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   3831 
   3832     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3833     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3834     pm_phy_copy.access.flags |= if_side;
   3835 
   3836     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3837     *value = phymod_tx.pre;
   3838 
   3839     return(SOC_E_NONE);
   3840 }
   3841 /*
   3842  * phy_82381_tx_fir_main_get
   3843  */
   3844 STATIC int
   3845 phy_82381_tx_fir_main_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3846 {
   3847     phymod_phy_access_t *pm_phy;
   3848     phymod_tx_t         phymod_tx;
   3849     phymod_phy_access_t pm_phy_copy;
   3850     uint32_t if_side = 0;
   3851     uint32_t chip_id = 0;
   3852     uint32 simplex_tx = 0;
   3853     soc_phymod_ctrl_t *pmc;
   3854     pmc = &pc->phymod_ctrl;
   3855 
   3856 
   3857     pm_phy = &pmc->phy[0]->pm_phy;
   3858 
   3859     if (pm_phy == NULL) {
   3860         return SOC_E_INTERNAL;
   3861     }
   3862 
   3863     simplex_tx = SIMPLEX_TX(pc);
   3864     chip_id = DEVID(pc);
   3865     SOC_IF_ERROR_RETURN
   3866         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   3867 
   3868     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3869     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3870     pm_phy_copy.access.flags |= if_side;
   3871 
   3872     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3873     *value = phymod_tx.main;
   3874 
   3875     return(SOC_E_NONE);
   3876 }
   3877 
   3878 /*
   3879  * phy_82381_tx_fir_post_get
   3880  */
   3881 STATIC int
   3882 phy_82381_tx_fir_post_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3883 {
   3884     phymod_phy_access_t *pm_phy;
   3885     phymod_tx_t         phymod_tx;
   3886     phymod_phy_access_t pm_phy_copy;
   3887     uint32_t if_side = 0;
   3888     uint32_t chip_id = 0;
   3889     uint32 simplex_tx = 0;
   3890     soc_phymod_ctrl_t *pmc;
   3891     pmc = &pc->phymod_ctrl;
   3892 
   3893 
   3894     pm_phy = &pmc->phy[0]->pm_phy;
   3895 
   3896     if (pm_phy == NULL) {
   3897         return SOC_E_INTERNAL;
   3898     }
   3899 
   3900     simplex_tx = SIMPLEX_TX(pc);
   3901     chip_id = DEVID(pc);
   3902     SOC_IF_ERROR_RETURN
   3903         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   3904 
   3905     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3906     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3907     pm_phy_copy.access.flags |= if_side;
   3908 
   3909     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3910     *value = phymod_tx.post;
   3911 
   3912     return(SOC_E_NONE);
   3913 }
   3914 
   3915 /*
   3916  * phy_82381_tx_fir_post2_get
   3917  */
   3918 STATIC int
   3919 phy_82381_tx_fir_post2_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3920 {
   3921     phymod_phy_access_t *pm_phy;
   3922     phymod_tx_t         phymod_tx;
   3923     phymod_phy_access_t pm_phy_copy;
   3924     uint32_t if_side = 0;
   3925     uint32_t chip_id = 0;
   3926     uint32 simplex_tx = 0;
   3927     soc_phymod_ctrl_t *pmc;
   3928     pmc = &pc->phymod_ctrl;
   3929 
   3930 
   3931     pm_phy = &pmc->phy[0]->pm_phy;
   3932 
   3933     if (pm_phy == NULL) {
   3934         return SOC_E_INTERNAL;
   3935     }
   3936 
   3937     simplex_tx = SIMPLEX_TX(pc);
   3938     chip_id = DEVID(pc);
   3939     SOC_IF_ERROR_RETURN
   3940         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   3941 
   3942     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3943     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3944     pm_phy_copy.access.flags |= if_side;
   3945 
   3946     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3947     *value = phymod_tx.post2;
   3948 
   3949     return(SOC_E_NONE);
   3950 }
   3951 
   3952 /*
   3953  * phy_82381_tx_fir_post3_get
   3954  */
   3955 STATIC int
   3956 phy_82381_tx_fir_post3_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3957 {
   3958     phymod_phy_access_t *pm_phy;
   3959     phymod_tx_t         phymod_tx;
   3960     phymod_phy_access_t pm_phy_copy;
   3961     uint32_t if_side = 0;
   3962     uint32_t chip_id = 0;
   3963     uint32 simplex_tx = 0;
   3964     soc_phymod_ctrl_t *pmc;
   3965     pmc = &pc->phymod_ctrl;
   3966 
   3967 
   3968     pm_phy = &pmc->phy[0]->pm_phy;
   3969 
   3970     if (pm_phy == NULL) {
   3971         return SOC_E_INTERNAL;
   3972     }
   3973 
   3974     simplex_tx = SIMPLEX_TX(pc);
   3975     chip_id = DEVID(pc);
   3976     SOC_IF_ERROR_RETURN
   3977         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   3978 
   3979     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3980     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   3981     pm_phy_copy.access.flags |= if_side;
   3982 
   3983     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3984     *value = phymod_tx.post3;
   3985 
   3986     return(SOC_E_NONE);
   3987 }
   3988 /*
   3989  *  * phy_82381_driver_current_get
   3990  */
   3991 STATIC int
   3992 phy_82381_driver_current_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   3993 {
   3994     phymod_phy_access_t *pm_phy;
   3995     phymod_tx_t         phymod_tx;
   3996     phymod_phy_access_t pm_phy_copy;
   3997     uint32_t if_side = 0;
   3998     uint32_t chip_id = 0;
   3999     uint32 simplex_tx = 0;
   4000     soc_phymod_ctrl_t *pmc;
   4001     pmc = &pc->phymod_ctrl;
   4002 
   4003     pm_phy = &pmc->phy[0]->pm_phy;
   4004     if (pm_phy == NULL) {
   4005         return SOC_E_INTERNAL;
   4006     }
   4007 
   4008     simplex_tx = SIMPLEX_TX(pc);
   4009     chip_id = DEVID(pc);
   4010     SOC_IF_ERROR_RETURN
   4011         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   4012     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4013     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4014     pm_phy_copy.access.flags |= if_side;
   4015 
   4016     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4017     *value = phymod_tx.amp;
   4018     return(SOC_E_NONE);
   4019 }
   4020 
   4021 /*
   4022  * phy_82381_per_lane_driver_current_get
   4023  */
   4024 STATIC int
   4025 phy_82381_per_lane_driver_current_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4026 {
   4027     soc_phymod_phy_t    *p_phy;
   4028     uint32              lane_map;
   4029     phymod_phy_access_t pm_phy_copy, *pm_phy;
   4030     phymod_tx_t         phymod_tx;
   4031     uint32_t if_side = 0;
   4032     uint32_t chip_id = 0;
   4033     uint32 simplex_tx = 0;
   4034     soc_phymod_ctrl_t *pmc;
   4035     pmc = &pc->phymod_ctrl;
   4036 
   4037     /* locate the desired phy and lane */
   4038     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4039 
   4040     /* Make a copy of the phy access and overwrite the desired lane */
   4041     pm_phy = &p_phy->pm_phy;
   4042 
   4043     simplex_tx = SIMPLEX_TX(pc);
   4044     chip_id = DEVID(pc);
   4045     SOC_IF_ERROR_RETURN
   4046         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   4047     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4048     pm_phy_copy.access.lane_mask = lane_map;
   4049     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4050     pm_phy_copy.access.flags |= if_side;
   4051 
   4052     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4053     *value = phymod_tx.amp;
   4054 
   4055     return(SOC_E_NONE);
   4056 }
   4057 /*
   4058  * phy_82381_rx_signal_detect_get
   4059  */
   4060 STATIC int
   4061 phy_82381_rx_signal_detect_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4062 {
   4063    /* $$$ Need to add diagnostic API */
   4064    return(SOC_E_UNAVAIL);
   4065 }
   4066 /*
   4067  * phy_82381_rx_ppm_get
   4068  */
   4069 STATIC int
   4070 phy_82381_rx_ppm_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4071 {
   4072     /* $$$ Need to add diagnostic API */
   4073     return(SOC_E_UNAVAIL);
   4074 }
   4075 /*
   4076  * phy_82381_preemphasis_get
   4077  */
   4078 STATIC int
   4079 phy_82381_preemphasis_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4080 {
   4081     phymod_phy_access_t *pm_phy;
   4082     phymod_tx_t         phymod_tx;
   4083     int                 idx;
   4084     phymod_phy_access_t pm_phy_copy;
   4085     uint32_t if_side = 0;
   4086     uint32_t chip_id = 0;
   4087     uint32 simplex_tx = 0;
   4088     soc_phymod_ctrl_t *pmc;
   4089     pmc = &pc->phymod_ctrl;
   4090 
   4091     *value = 0;
   4092 
   4093     /* loop through all cores */
   4094     for (idx = 0; idx < pmc->num_phys; idx++) {
   4095         pm_phy = &pmc->phy[idx]->pm_phy;
   4096 
   4097         if (pm_phy == NULL) {
   4098             return SOC_E_INTERNAL;
   4099         }
   4100         simplex_tx = SIMPLEX_TX(pc);
   4101         chip_id = DEVID(pc);
   4102         SOC_IF_ERROR_RETURN
   4103             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   4104 
   4105         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4106         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4107         pm_phy_copy.access.flags |= if_side;
   4108         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4109         *value |= (phymod_tx.pre & 0xff);
   4110         *value |= ((phymod_tx.main & 0xff) << 8);
   4111         *value |= ((phymod_tx.post & 0xff) << 16);
   4112 
   4113     }
   4114     return(SOC_E_NONE);
   4115 }
   4116 
   4117 /*
   4118  * phy_82381_per_lane_preemphasis_get
   4119  */
   4120 STATIC int
   4121 phy_82381_per_lane_preemphasis_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4122 {
   4123     soc_phymod_phy_t    *p_phy;
   4124     uint32              lane_map;
   4125     phymod_phy_access_t pm_phy_copy, *pm_phy;
   4126     phymod_tx_t         phymod_tx;
   4127     uint32_t if_side = 0;
   4128     uint32_t chip_id = 0;
   4129     uint32 simplex_tx = 0;
   4130     soc_phymod_ctrl_t *pmc;
   4131     pmc = &pc->phymod_ctrl;
   4132 
   4133     *value = 0;
   4134 
   4135     /* locate the desired phy and lane */
   4136     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4137 
   4138     /* Make a copy of the phy access and overwrite the desired lane */
   4139     pm_phy = &p_phy->pm_phy;
   4140 
   4141     simplex_tx = SIMPLEX_TX(pc);
   4142     chip_id = DEVID(pc);
   4143     SOC_IF_ERROR_RETURN
   4144         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   4145     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4146     pm_phy_copy.access.lane_mask = lane_map;
   4147     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4148     pm_phy_copy.access.flags |= if_side;
   4149 
   4150     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   4151     *value |= (phymod_tx.pre & 0xff);
   4152     *value |= ((phymod_tx.main & 0xff) << 8);
   4153     *value |= ((phymod_tx.post & 0xff) << 16);
   4154 
   4155     return(SOC_E_NONE);
   4156 }
   4157 
   4158 /*
   4159  * phy_82381_per_lane_rx_low_freq_filter_set
   4160  */
   4161 STATIC int
   4162 phy_82381_per_lane_rx_low_freq_filter_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   4163 {
   4164     soc_phymod_phy_t    *p_phy;
   4165     uint32              lane_map;
   4166     phymod_phy_access_t pm_phy_copy, *pm_phy;
   4167     phymod_rx_t          phymod_rx;
   4168     uint32_t if_side = 0;
   4169     uint32_t chip_id = 0;
   4170     uint32 simplex_tx = 0;
   4171     soc_phymod_ctrl_t *pmc;
   4172     pmc = &pc->phymod_ctrl;
   4173 
   4174 
   4175     /* locate the desired phy and lane */
   4176     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4177 
   4178     /* Make a copy of the phy access and overwrite the desired lane */
   4179     pm_phy = &p_phy->pm_phy;
   4180 
   4181     simplex_tx = SIMPLEX_TX(pc);
   4182     chip_id = DEVID(pc);
   4183     SOC_IF_ERROR_RETURN
   4184         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4185 
   4186     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4187     pm_phy_copy.access.lane_mask = lane_map;
   4188     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4189     pm_phy_copy.access.flags |= if_side;
   4190 
   4191     sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   4192     phymod_rx.low_freq_peaking_filter.enable = TRUE;
   4193     phymod_rx.low_freq_peaking_filter.value = value;
   4194     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   4195    return(SOC_E_NONE);
   4196 }
   4197 /*
   4198  * phy_82381_per_lane_power_get
   4199  */
   4200 STATIC int
   4201 phy_82381_per_lane_power_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4202 {
   4203     phymod_phy_access_t     *pm_phy;
   4204     phymod_phy_power_t      power;
   4205     soc_phymod_phy_t    *p_phy;
   4206     uint32              lane_map;
   4207     phymod_phy_access_t pm_phy_copy;
   4208     uint32_t if_side = 0;
   4209     uint32_t chip_id = 0;
   4210     uint32 simplex_tx = 0;
   4211     soc_phymod_ctrl_t *pmc;
   4212     pmc = &pc->phymod_ctrl;
   4213 
   4214     /* locate the desired phy and lane */
   4215     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4216 
   4217     /* Make a copy of the phy access and overwrite the desired lane */
   4218     pm_phy = &p_phy->pm_phy;
   4219 
   4220     simplex_tx = SIMPLEX_TX(pc);
   4221     chip_id = DEVID(pc);
   4222     if(FURIA_IS_SIMPLEX(chip_id)){
   4223         if (!simplex_tx) { /* Rx simplex package */
   4224             if (intf == PHY82381_SYS_SIDE) {
   4225                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4226             } else {
   4227                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4228                 if_side |= (1 << INTERFACE_SIDE_SHIFT);
   4229             }
   4230         } else { /* Tx simplex package */
   4231             if (intf == PHY82381_SYS_SIDE) {
   4232                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4233                 if_side |= (1 << INTERFACE_SIDE_SHIFT);
   4234             } else {
   4235                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4236             }
   4237         }
   4238     } else {
   4239         if (intf == PHY82381_SYS_SIDE) {
   4240             if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4241             if_side |= (1 << INTERFACE_SIDE_SHIFT);
   4242         } else {
   4243             if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4244         }
   4245     }
   4246     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4247     pm_phy_copy.access.lane_mask = lane_map;
   4248     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4249     pm_phy_copy.access.flags |= if_side;
   4250 
   4251     phymod_phy_power_t_init(&power);
   4252 
   4253     SOC_IF_ERROR_RETURN(phymod_phy_power_get(&pm_phy_copy, &power));
   4254 
   4255     if(FURIA_IS_SIMPLEX(chip_id)) {
   4256         if(power.tx == phymodPowerOn || power.rx == phymodPowerOn) {
   4257             *value = 1;
   4258         } else {
   4259             *value = 0;
   4260         }
   4261     } else {
   4262         if(power.tx == phymodPowerOn && power.rx == phymodPowerOn) {
   4263             *value = 1;
   4264         } else {
   4265             *value = 0;
   4266         }
   4267     }
   4268     return(SOC_E_NONE);
   4269 }
   4270 /*
   4271  * phy_82381_power_get
   4272  */
   4273 STATIC int
   4274 phy_82381_power_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4275 {
   4276     phymod_phy_access_t     *pm_phy;
   4277     phymod_phy_power_t      power;
   4278     phymod_phy_access_t pm_phy_copy;
   4279     uint32_t if_side = 0;
   4280     uint32_t chip_id = 0;
   4281     uint32 simplex_tx = 0;
   4282     soc_phymod_ctrl_t *pmc;
   4283     pmc = &pc->phymod_ctrl;
   4284 
   4285 
   4286     /* just take the value from the first phy */
   4287     if (pmc->phy[0] == NULL) {
   4288         return SOC_E_INTERNAL;
   4289     }
   4290     pm_phy = &pmc->phy[0]->pm_phy;
   4291 
   4292     if (pm_phy == NULL) {
   4293         return SOC_E_INTERNAL;
   4294     }
   4295 
   4296 
   4297     simplex_tx = SIMPLEX_TX(pc);
   4298     chip_id = DEVID(pc);
   4299     if(FURIA_IS_SIMPLEX(chip_id)){
   4300         if (!simplex_tx) { /* Rx simplex package */
   4301             if (intf == PHY82381_SYS_SIDE) {
   4302                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4303             } else {
   4304                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4305                 if_side |= (1 << INTERFACE_SIDE_SHIFT);
   4306             }
   4307         } else { /* Tx simplex package */
   4308             if (intf == PHY82381_SYS_SIDE) {
   4309                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4310                 if_side |= (1 << INTERFACE_SIDE_SHIFT);
   4311             } else {
   4312                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4313             }
   4314         }
   4315     } else {
   4316         if (intf == PHY82381_SYS_SIDE) {
   4317             if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4318             if_side |= (1 << INTERFACE_SIDE_SHIFT);
   4319         } else {
   4320             if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   4321         }
   4322     }
   4323 
   4324     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4325     phymod_phy_power_t_init(&power);
   4326     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4327     pm_phy_copy.access.flags |= if_side;
   4328 
   4329     SOC_IF_ERROR_RETURN(phymod_phy_power_get(&pm_phy_copy, &power));
   4330 
   4331     if(FURIA_IS_SIMPLEX(chip_id)) {
   4332         if(power.tx == phymodPowerOn || power.rx == phymodPowerOn) {
   4333             *value = 1;
   4334         } else {
   4335             *value = 0;
   4336         }
   4337     } else {
   4338         if(power.tx == phymodPowerOn && power.rx == phymodPowerOn) {
   4339             *value = 1;
   4340         } else {
   4341             *value = 0;
   4342         }
   4343     }
   4344     return(SOC_E_NONE);
   4345 }
   4346 /*
   4347  * phy_82381_per_lane_tx_polarity_get
   4348  */
   4349 STATIC int
   4350 phy_82381_per_lane_tx_polarity_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4351 {
   4352     phymod_phy_access_t  *pm_phy;
   4353     phymod_polarity_t    polarity;
   4354     soc_phymod_phy_t    *p_phy;
   4355     uint32              lane_map;
   4356     phymod_phy_access_t pm_phy_copy;
   4357     uint32_t if_side = 0;
   4358     uint32_t chip_id = 0;
   4359     uint32 simplex_tx = 0;
   4360     soc_phymod_ctrl_t *pmc;
   4361     pmc = &pc->phymod_ctrl;
   4362 
   4363 
   4364     /* locate the desired phy and lane */
   4365     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4366 
   4367     /* Make a copy of the phy access and overwrite the desired lane */
   4368     pm_phy = &p_phy->pm_phy;
   4369 
   4370     simplex_tx = SIMPLEX_TX(pc);
   4371     chip_id = DEVID(pc);
   4372     SOC_IF_ERROR_RETURN
   4373         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   4374 
   4375     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4376     pm_phy_copy.access.lane_mask = lane_map;
   4377     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4378     pm_phy_copy.access.flags |= if_side;
   4379 
   4380     phymod_polarity_t_init(&polarity);
   4381     SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(&pm_phy_copy, &polarity));
   4382 
   4383     *value = polarity.tx_polarity;
   4384 
   4385     return(SOC_E_NONE);
   4386 }
   4387 /*
   4388  * phy_82381_tx_polarity_get
   4389  */
   4390 STATIC int
   4391 phy_82381_tx_polarity_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4392 {
   4393     phymod_phy_access_t  *pm_phy;
   4394     phymod_polarity_t    polarity;
   4395     phymod_phy_access_t pm_phy_copy;
   4396     uint32_t if_side = 0;
   4397     uint32_t chip_id = 0;
   4398     uint32 simplex_tx = 0;
   4399     soc_phymod_ctrl_t *pmc;
   4400     pmc = &pc->phymod_ctrl;
   4401 
   4402 
   4403     /* just take the value from the first phy */
   4404     if (pmc->phy[0] == NULL) {
   4405         return SOC_E_INTERNAL;
   4406     }
   4407     pm_phy = &pmc->phy[0]->pm_phy;
   4408 
   4409     if (pm_phy == NULL) {
   4410         return SOC_E_INTERNAL;
   4411     }
   4412 
   4413     simplex_tx = SIMPLEX_TX(pc);
   4414     chip_id = DEVID(pc);
   4415     SOC_IF_ERROR_RETURN
   4416         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   4417 
   4418     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4419     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4420     pm_phy_copy.access.flags |= if_side;
   4421     phymod_polarity_t_init(&polarity);
   4422     SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(&pm_phy_copy, &polarity));
   4423 
   4424     *value = polarity.tx_polarity;
   4425 
   4426     return(SOC_E_NONE);
   4427 }
   4428 
   4429 /*
   4430  * phy_82381_per_lane_rx_polarity_get
   4431  */
   4432 STATIC int
   4433 phy_82381_per_lane_rx_polarity_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4434 {
   4435     phymod_phy_access_t  *pm_phy;
   4436     phymod_polarity_t    polarity;
   4437     soc_phymod_phy_t    *p_phy;
   4438     uint32              lane_map;
   4439     phymod_phy_access_t pm_phy_copy;
   4440     uint32_t if_side = 0;
   4441     uint32_t chip_id = 0;
   4442     uint32 simplex_tx = 0;
   4443     soc_phymod_ctrl_t *pmc;
   4444     pmc = &pc->phymod_ctrl;
   4445 
   4446 
   4447     /* locate the desired phy and lane */
   4448     SOC_IF_ERROR_RETURN(_phy_82381_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 
   4453     simplex_tx = SIMPLEX_TX(pc);
   4454     chip_id = DEVID(pc);
   4455     SOC_IF_ERROR_RETURN
   4456         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4457 
   4458     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4459     pm_phy_copy.access.lane_mask = lane_map;
   4460     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4461     pm_phy_copy.access.flags |= if_side;
   4462 
   4463     phymod_polarity_t_init(&polarity);
   4464     SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(&pm_phy_copy, &polarity));
   4465 
   4466     *value = polarity.rx_polarity;
   4467 
   4468     return(SOC_E_NONE);
   4469 }
   4470 /*
   4471  * phy_82381_rx_polarity_get
   4472  */
   4473 STATIC int
   4474 phy_82381_rx_polarity_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4475 {
   4476     phymod_phy_access_t  *pm_phy;
   4477     phymod_polarity_t    polarity;
   4478     phymod_phy_access_t pm_phy_copy;
   4479     uint32_t if_side = 0;
   4480     uint32_t chip_id = 0;
   4481     uint32 simplex_tx = 0;
   4482     soc_phymod_ctrl_t *pmc;
   4483     pmc = &pc->phymod_ctrl;
   4484 
   4485 
   4486     /* just take the value from the first phy */
   4487     if (pmc->phy[0] == NULL) {
   4488         return SOC_E_INTERNAL;
   4489     }
   4490     pm_phy = &pmc->phy[0]->pm_phy;
   4491 
   4492     if (pm_phy == NULL) {
   4493         return SOC_E_INTERNAL;
   4494     }
   4495 
   4496     simplex_tx = SIMPLEX_TX(pc);
   4497     chip_id = DEVID(pc);
   4498     SOC_IF_ERROR_RETURN
   4499         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4500 
   4501     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4502     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4503     pm_phy_copy.access.flags |= if_side;
   4504     phymod_polarity_t_init(&polarity);
   4505     SOC_IF_ERROR_RETURN(phymod_phy_polarity_get(&pm_phy_copy, &polarity));
   4506 
   4507     *value = polarity.rx_polarity;
   4508 
   4509     return(SOC_E_NONE);
   4510 }
   4511 
   4512 /*
   4513  * phy_82381_gpio_config_get
   4514  */
   4515 STATIC int
   4516 phy_82381_gpio_config_get(phy_ctrl_t *pc, uint32 *value)
   4517 {
   4518     phymod_phy_access_t  *pm_phy;
   4519     phymod_phy_access_t pm_phy_copy;
   4520     phymod_gpio_mode_t gpio_mode;
   4521     int gpio_pin_no = 0;
   4522     soc_phymod_ctrl_t *pmc;
   4523     pmc = &pc->phymod_ctrl;
   4524     *value = 0;
   4525 
   4526     /* just take the value from the first phy */
   4527     if (pmc->phy[0] == NULL) {
   4528         return SOC_E_INTERNAL;
   4529     }
   4530     pm_phy = &pmc->phy[0]->pm_phy;
   4531 
   4532     if (pm_phy == NULL) {
   4533         return SOC_E_INTERNAL;
   4534     }
   4535     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4536 
   4537     for (gpio_pin_no = 0; gpio_pin_no < 5; gpio_pin_no++) {
   4538         SOC_IF_ERROR_RETURN(phymod_phy_gpio_config_get(&pm_phy_copy, gpio_pin_no, &gpio_mode));
   4539         *value |= (gpio_mode << (4 * gpio_pin_no));
   4540     }
   4541 
   4542     return(SOC_E_NONE);
   4543 }
   4544 /*
   4545  * phy_82381_gpio_value_get
   4546  */
   4547 STATIC int
   4548 phy_82381_gpio_value_get(phy_ctrl_t *pc, uint32 *value)
   4549 {
   4550     phymod_phy_access_t  *pm_phy;
   4551     phymod_phy_access_t pm_phy_copy;
   4552     int gpio_pin_no = 0;
   4553     int pin_value = 0;
   4554     soc_phymod_ctrl_t *pmc;
   4555     pmc = &pc->phymod_ctrl;
   4556     *value = 0;
   4557 
   4558     /* just take the value from the first phy */
   4559     if (pmc->phy[0] == NULL) {
   4560         return SOC_E_INTERNAL;
   4561     }
   4562     pm_phy = &pmc->phy[0]->pm_phy;
   4563 
   4564     if (pm_phy == NULL) {
   4565         return SOC_E_INTERNAL;
   4566     }
   4567 
   4568     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4569 
   4570     for (gpio_pin_no = 0; gpio_pin_no < 5; gpio_pin_no++) {
   4571         SOC_IF_ERROR_RETURN(phymod_phy_gpio_pin_value_get(&pm_phy_copy, gpio_pin_no, &pin_value));
   4572         *value |= (pin_value << (4 * gpio_pin_no));
   4573     }
   4574 
   4575     return(SOC_E_NONE);
   4576 }
   4577 /*
   4578  * phy_82381_firmware_mode_get
   4579  */
   4580 STATIC int
   4581 phy_82381_firmware_mode_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4582 {
   4583     phymod_phy_access_t    *pm_phy;
   4584     phymod_firmware_lane_config_t fw_config;
   4585     soc_phymod_ctrl_t *pmc;
   4586     phymod_phy_access_t pm_phy_copy;
   4587     uint32_t if_side = 0;
   4588     uint32_t chip_id = 0;
   4589     uint32 simplex_tx = 0;
   4590     pmc = &pc->phymod_ctrl;
   4591     *value = 0;
   4592 
   4593     /* just take the value from the first phy */
   4594     if (pmc->phy[0] == NULL) {
   4595         return SOC_E_INTERNAL;
   4596     }
   4597 
   4598     pm_phy = &pmc->phy[0]->pm_phy;
   4599     if (pm_phy == NULL) {
   4600         return SOC_E_INTERNAL;
   4601     }
   4602 
   4603     simplex_tx = SIMPLEX_TX(pc);
   4604     chip_id = DEVID(pc);
   4605     SOC_IF_ERROR_RETURN
   4606         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4607 
   4608     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4609     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4610     pm_phy_copy.access.flags |= if_side;
   4611 
   4612     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4613 
   4614     if ((fw_config.LpDfeOn) && (fw_config.DfeOn)) {
   4615         *value = SOC_PHY_FIRMWARE_LP_DFE_ENABLE;
   4616     } else if ((fw_config.ForceBrDfe) && (fw_config.DfeOn)) {
   4617         *value = SOC_PHY_FIRMWARE_FORCE_BRDFE;
   4618     } else if (fw_config.MediaType == phymodFirmwareMediaTypeCopperCable) {
   4619         *value = SOC_PHY_FIRMWARE_SFP_DAC;
   4620     } else if (fw_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane) {
   4621         *value = SOC_PHY_FIRMWARE_XLAUI;
   4622     } else if (fw_config.MediaType == phymodFirmwareMediaTypeOptics){
   4623         *value = SOC_PHY_FIRMWARE_SFP_OPT_SR4;
   4624     } else if ((fw_config.DfeOn) && (fw_config.ForceBrDfe == 0) && (fw_config.LpDfeOn == 0)) {
   4625         *value = SOC_PHY_FIRMWARE_DFE_ENABLE;
   4626     } else if ((fw_config.DfeOn) && (fw_config.ForceBrDfe == 0)) {
   4627         *value = SOC_PHY_FIRMWARE_FORCE_OSDFE;
   4628     } else {
   4629         *value = SOC_PHY_FIRMWARE_DEFAULT;
   4630     }
   4631 
   4632     return(SOC_E_NONE);
   4633 }
   4634 
   4635 /*
   4636  * phy_82381_firmware_dfe_enable_get
   4637  */
   4638 STATIC int
   4639 phy_82381_firmware_dfe_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4640 {
   4641     phymod_phy_access_t    *pm_phy;
   4642     phymod_firmware_lane_config_t fw_config;
   4643     soc_phymod_ctrl_t *pmc;
   4644     phymod_phy_access_t pm_phy_copy;
   4645     uint32_t if_side = 0;
   4646     uint32_t chip_id = 0;
   4647     uint32 simplex_tx = 0;
   4648     pmc = &pc->phymod_ctrl;
   4649     *value = 0;
   4650 
   4651     /* just take the value from the first phy */
   4652     if (pmc->phy[0] == NULL) {
   4653         return SOC_E_INTERNAL;
   4654     }
   4655 
   4656     pm_phy = &pmc->phy[0]->pm_phy;
   4657     if (pm_phy == NULL) {
   4658         return SOC_E_INTERNAL;
   4659     }
   4660 
   4661     simplex_tx = SIMPLEX_TX(pc);
   4662     chip_id = DEVID(pc);
   4663     SOC_IF_ERROR_RETURN
   4664         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4665 
   4666     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4667     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4668     pm_phy_copy.access.flags |= if_side;
   4669 
   4670     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4671 
   4672     if (fw_config.DfeOn) {
   4673         *value = 1;
   4674     } else {
   4675         *value = 0;
   4676     }
   4677 
   4678     return(SOC_E_NONE);
   4679 }
   4680 
   4681 /*
   4682  * phy_82381_firmware_dfe_enable_get
   4683  */
   4684 STATIC int
   4685 phy_82381_firmware_lp_dfe_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4686 {
   4687     phymod_phy_access_t    *pm_phy;
   4688     phymod_firmware_lane_config_t fw_config;
   4689     soc_phymod_ctrl_t *pmc;
   4690     phymod_phy_access_t pm_phy_copy;
   4691     uint32_t if_side = 0;
   4692     uint32_t chip_id = 0;
   4693     uint32 simplex_tx = 0;
   4694     pmc = &pc->phymod_ctrl;
   4695     *value = 0;
   4696 
   4697     /* just take the value from the first phy */
   4698     if (pmc->phy[0] == NULL) {
   4699         return SOC_E_INTERNAL;
   4700     }
   4701 
   4702     pm_phy = &pmc->phy[0]->pm_phy;
   4703     if (pm_phy == NULL) {
   4704         return SOC_E_INTERNAL;
   4705     }
   4706 
   4707     simplex_tx = SIMPLEX_TX(pc);
   4708     chip_id = DEVID(pc);
   4709     SOC_IF_ERROR_RETURN
   4710         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4711 
   4712     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4713     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4714     pm_phy_copy.access.flags |= if_side;
   4715 
   4716     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4717 
   4718     if (fw_config.LpDfeOn && fw_config.DfeOn) {
   4719         *value = 1;
   4720     } else {
   4721         *value = 0;
   4722     }
   4723 
   4724     return(SOC_E_NONE);
   4725 }
   4726 
   4727 /*
   4728  * phy_82381_firmware_br_dfe_enable_get
   4729  */
   4730 STATIC int
   4731 phy_82381_firmware_br_dfe_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   4732 {
   4733     phymod_phy_access_t    *pm_phy;
   4734     phymod_firmware_lane_config_t fw_config;
   4735     soc_phymod_ctrl_t *pmc;
   4736     phymod_phy_access_t pm_phy_copy;
   4737     uint32_t if_side = 0;
   4738     uint32_t chip_id = 0;
   4739     uint32 simplex_tx = 0;
   4740     pmc = &pc->phymod_ctrl;
   4741     *value = 0;
   4742 
   4743     /* just take the value from the first phy */
   4744     if (pmc->phy[0] == NULL) {
   4745         return SOC_E_INTERNAL;
   4746     }
   4747 
   4748     pm_phy = &pmc->phy[0]->pm_phy;
   4749     if (pm_phy == NULL) {
   4750         return SOC_E_INTERNAL;
   4751     }
   4752 
   4753     simplex_tx = SIMPLEX_TX(pc);
   4754     chip_id = DEVID(pc);
   4755     SOC_IF_ERROR_RETURN
   4756         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4757 
   4758     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4759     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4760     pm_phy_copy.access.flags |= if_side;
   4761     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4762 
   4763     if (fw_config.ForceBrDfe && fw_config.DfeOn) {
   4764         *value = 1;
   4765     } else {
   4766         *value = 0;
   4767     }
   4768 
   4769     return(SOC_E_NONE);
   4770 }
   4771 /*
   4772  * phy_82381_per_lane_firmware_mode_get
   4773  */
   4774 STATIC int
   4775 phy_82381_per_lane_firmware_mode_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4776 {
   4777     phymod_phy_access_t    *pm_phy;
   4778     phymod_firmware_lane_config_t fw_config;
   4779     soc_phymod_phy_t    *p_phy;
   4780     uint32              lane_map;
   4781     phymod_phy_access_t pm_phy_copy;
   4782     uint32_t if_side = 0;
   4783     uint32_t chip_id = 0;
   4784     uint32 simplex_tx = 0;
   4785     soc_phymod_ctrl_t *pmc;
   4786     pmc = &pc->phymod_ctrl;
   4787     *value = 0;
   4788 
   4789     /* locate the desired phy and lane */
   4790     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4791 
   4792     /* Make a copy of the phy access and overwrite the desired lane */
   4793     pm_phy = &p_phy->pm_phy;
   4794 
   4795     simplex_tx = SIMPLEX_TX(pc);
   4796     chip_id = DEVID(pc);
   4797     SOC_IF_ERROR_RETURN
   4798         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4799 
   4800     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4801     pm_phy_copy.access.lane_mask = lane_map;
   4802     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4803     pm_phy_copy.access.flags |= if_side;
   4804 
   4805     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4806 
   4807 
   4808     if ((fw_config.LpDfeOn) && (fw_config.DfeOn)) {
   4809         *value = SOC_PHY_FIRMWARE_LP_DFE_ENABLE;
   4810     } else if ((fw_config.ForceBrDfe) && (fw_config.DfeOn)) {
   4811         *value = SOC_PHY_FIRMWARE_FORCE_BRDFE;
   4812     } else if (fw_config.MediaType == phymodFirmwareMediaTypeCopperCable) {
   4813         *value = SOC_PHY_FIRMWARE_SFP_DAC;
   4814     } else if (fw_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane) {
   4815         *value = SOC_PHY_FIRMWARE_XLAUI;
   4816     } else if (fw_config.MediaType == phymodFirmwareMediaTypeOptics){
   4817         *value = SOC_PHY_FIRMWARE_SFP_OPT_SR4;
   4818     } else if ((fw_config.DfeOn) && (fw_config.ForceBrDfe == 0) && (fw_config.LpDfeOn == 0)) {
   4819         *value = SOC_PHY_FIRMWARE_DFE_ENABLE;
   4820     } else if ((fw_config.DfeOn) && (fw_config.ForceBrDfe == 0)) {
   4821         *value = SOC_PHY_FIRMWARE_FORCE_OSDFE;
   4822     } else {
   4823         *value = SOC_PHY_FIRMWARE_DEFAULT;
   4824     }
   4825 
   4826     return(SOC_E_NONE);
   4827 }
   4828 
   4829 /*
   4830  * phy_82381_per_lane_firmware_dfe_enable_get
   4831  */
   4832 STATIC int
   4833 phy_82381_per_lane_firmware_dfe_enable_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4834 {
   4835     phymod_phy_access_t    *pm_phy;
   4836     phymod_firmware_lane_config_t fw_config;
   4837     soc_phymod_phy_t    *p_phy;
   4838     uint32              lane_map;
   4839     phymod_phy_access_t pm_phy_copy;
   4840     soc_phymod_ctrl_t *pmc;
   4841     uint32_t if_side = 0;
   4842     uint32_t chip_id = 0;
   4843     uint32 simplex_tx = 0;
   4844     pmc = &pc->phymod_ctrl;
   4845     *value = 0;
   4846 
   4847     /* locate the desired phy and lane */
   4848     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4849 
   4850     /* Make a copy of the phy access and overwrite the desired lane */
   4851     pm_phy = &p_phy->pm_phy;
   4852 
   4853     simplex_tx = SIMPLEX_TX(pc);
   4854     chip_id = DEVID(pc);
   4855     SOC_IF_ERROR_RETURN
   4856         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4857 
   4858     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4859     pm_phy_copy.access.lane_mask = lane_map;
   4860     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4861     pm_phy_copy.access.flags |= if_side;
   4862 
   4863     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4864 
   4865     if (fw_config.DfeOn) {
   4866         *value = 1;
   4867     } else {
   4868         *value = 0;
   4869     }
   4870 
   4871     return(SOC_E_NONE);
   4872 }
   4873 
   4874 /*
   4875  * phy_82381_per_lane_firmware_dfe_enable_get
   4876  */
   4877 STATIC int
   4878 phy_82381_per_lane_firmware_lp_dfe_enable_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4879 {
   4880     phymod_phy_access_t    *pm_phy;
   4881     phymod_firmware_lane_config_t fw_config;
   4882     soc_phymod_phy_t    *p_phy;
   4883     uint32              lane_map;
   4884     phymod_phy_access_t pm_phy_copy;
   4885     soc_phymod_ctrl_t *pmc;
   4886     uint32_t if_side = 0;
   4887     uint32_t chip_id = 0;
   4888     uint32 simplex_tx = 0;
   4889     pmc = &pc->phymod_ctrl;
   4890     *value = 0;
   4891 
   4892     /* locate the desired phy and lane */
   4893     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4894 
   4895     /* Make a copy of the phy access and overwrite the desired lane */
   4896     pm_phy = &p_phy->pm_phy;
   4897 
   4898     simplex_tx = SIMPLEX_TX(pc);
   4899     chip_id = DEVID(pc);
   4900     SOC_IF_ERROR_RETURN
   4901         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4902 
   4903     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4904     pm_phy_copy.access.lane_mask = lane_map;
   4905     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4906     pm_phy_copy.access.flags |= if_side;
   4907     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4908 
   4909     if (fw_config.LpDfeOn && fw_config.DfeOn) {
   4910         *value = 1;
   4911     } else {
   4912         *value = 0;
   4913     }
   4914 
   4915     return(SOC_E_NONE);
   4916 }
   4917 
   4918 /*
   4919  * phy_82381_per_lane_firmware_dfe_enable_get
   4920  */
   4921 STATIC int
   4922 phy_82381_per_lane_firmware_br_dfe_enable_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4923 {
   4924     phymod_phy_access_t    *pm_phy;
   4925     phymod_firmware_lane_config_t fw_config;
   4926     soc_phymod_phy_t    *p_phy;
   4927     uint32              lane_map;
   4928     phymod_phy_access_t pm_phy_copy;
   4929     soc_phymod_ctrl_t *pmc;
   4930     uint32_t if_side = 0;
   4931     uint32_t chip_id = 0;
   4932     uint32 simplex_tx = 0;
   4933     pmc = &pc->phymod_ctrl;
   4934     *value = 0;
   4935 
   4936     /* locate the desired phy and lane */
   4937     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4938 
   4939     /* Make a copy of the phy access and overwrite the desired lane */
   4940     pm_phy = &p_phy->pm_phy;
   4941 
   4942     simplex_tx = SIMPLEX_TX(pc);
   4943     chip_id = DEVID(pc);
   4944     SOC_IF_ERROR_RETURN
   4945         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4946 
   4947     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4948     pm_phy_copy.access.lane_mask = lane_map;
   4949     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4950     pm_phy_copy.access.flags |= if_side;
   4951 
   4952     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4953 
   4954     if (fw_config.ForceBrDfe && fw_config.DfeOn) {
   4955         *value = 1;
   4956     } else {
   4957         *value = 0;
   4958     }
   4959 
   4960     return(SOC_E_NONE);
   4961 }
   4962 /*
   4963  * phy_82381_per_lane_unreliable_los_get
   4964  */
   4965 STATIC int
   4966 phy_82381_per_lane_unreliable_los_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   4967 {
   4968     phymod_phy_access_t    *pm_phy;
   4969     phymod_firmware_lane_config_t fw_config;
   4970     soc_phymod_phy_t    *p_phy;
   4971     soc_phymod_ctrl_t *pmc;
   4972     uint32              lane_map;
   4973     phymod_phy_access_t pm_phy_copy;
   4974     uint32_t if_side = 0;
   4975     uint32_t chip_id = 0;
   4976     uint32 simplex_tx = 0;
   4977     pmc = &pc->phymod_ctrl;
   4978     *value = 0;
   4979 
   4980     /* locate the desired phy and lane */
   4981     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   4982 
   4983     /* Make a copy of the phy access and overwrite the desired lane */
   4984     pm_phy = &p_phy->pm_phy;
   4985 
   4986     simplex_tx = SIMPLEX_TX(pc);
   4987     chip_id = DEVID(pc);
   4988     SOC_IF_ERROR_RETURN
   4989         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   4990 
   4991     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   4992     pm_phy_copy.access.lane_mask = lane_map;
   4993     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   4994     pm_phy_copy.access.flags |= if_side;
   4995 
   4996     sal_memset(&fw_config, 0, sizeof(fw_config));
   4997     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   4998     if (fw_config.UnreliableLos) {
   4999         *value = 1;
   5000     } else {
   5001         *value = 0;
   5002     }
   5003 
   5004     return(SOC_E_NONE);
   5005 }
   5006 /*
   5007  * phy_82381_unreliable_los_get
   5008  */
   5009 STATIC int
   5010 phy_82381_unreliable_los_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   5011 {
   5012     phymod_phy_access_t    *pm_phy;
   5013     phymod_firmware_lane_config_t fw_config;
   5014     soc_phymod_ctrl_t *pmc;
   5015     phymod_phy_access_t pm_phy_copy;
   5016     uint32_t if_side = 0;
   5017     uint32_t chip_id = 0;
   5018     uint32 simplex_tx = 0;
   5019     pmc = &pc->phymod_ctrl;
   5020     *value = 0;
   5021 
   5022     /* just take the value from the first phy */
   5023     if (pmc->phy[0] == NULL) {
   5024         return SOC_E_INTERNAL;
   5025     }
   5026 
   5027     pm_phy = &pmc->phy[0]->pm_phy;
   5028     if (pm_phy == NULL) {
   5029         return SOC_E_INTERNAL;
   5030     }
   5031 
   5032     simplex_tx = SIMPLEX_TX(pc);
   5033     chip_id = DEVID(pc);
   5034     SOC_IF_ERROR_RETURN
   5035         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   5036 
   5037     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   5038     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   5039     pm_phy_copy.access.flags |= if_side;
   5040 
   5041     sal_memset(&fw_config, 0, sizeof(fw_config));
   5042     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   5043     if (fw_config.UnreliableLos) {
   5044         *value = 1;
   5045     } else {
   5046         *value = 0;
   5047     }
   5048 
   5049     return(SOC_E_NONE);
   5050 }
   5051 /*
   5052  * Function:
   5053  *      phy82381_control_get
   5054  * Purpose:
   5055  *      Get current control settings of the PHY.
   5056  * Parameters:
   5057  *      unit  - BCM unit number.
   5058  *      port  - Port number.
   5059  *      type  - Control to update
   5060  *      value - (OUT) Current setting for the control
   5061  * Returns:
   5062  *      SOC_E_NONE
   5063  */
   5064 STATIC int
   5065 phy_82381_control_get(int unit, soc_port_t port, soc_phy_control_t type, uint32 *value)
   5066 {
   5067     int                 rv = SOC_E_UNAVAIL;
   5068     phy_ctrl_t          *pc;
   5069     int32 intf;
   5070     uint32 simplex_tx = 0;
   5071     uint32_t chip_id = 0;
   5072     uint32_t value_laneswap = *value;/*to save die select for 82212*/
   5073 
   5074     *value = 0;
   5075     PHY_CONTROL_TYPE_CHECK(type);
   5076 
   5077     /* locate phy control */
   5078     pc = EXT_PHY_SW_STATE(unit, port);
   5079     if (pc == NULL) {
   5080         return SOC_E_INTERNAL;
   5081     }
   5082 
   5083     simplex_tx = SIMPLEX_TX(pc);
   5084     chip_id = DEVID(pc);
   5085 
   5086     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82381_SYS_SIDE : PHY82381_LINE_SIDE;
   5087 
   5088     switch(type) {
   5089     /* PRBS */
   5090     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL:
   5091       rv = phy_82381_prbs_tx_poly_get(pc, intf, value);
   5092       break;
   5093     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA:
   5094       rv = phy_82381_prbs_tx_invert_data_get(pc, intf, value);
   5095       break;
   5096     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE:
   5097       rv = phy_82381_prbs_tx_enable_get(pc, intf, value);
   5098       break;
   5099     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL:
   5100       rv = phy_82381_prbs_rx_poly_get(pc, intf, value);
   5101       break;
   5102     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA:
   5103       rv = phy_82381_prbs_rx_invert_data_get(pc, intf, value);
   5104       break;
   5105     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE:
   5106       rv = phy_82381_prbs_rx_enable_get(pc, intf, value);
   5107       break;
   5108     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   5109         if(FURIA_IS_SIMPLEX(chip_id)){
   5110             if (!simplex_tx) {  /*simplex Rx package */
   5111                 if(intf == PHY82381_SYS_SIDE) {
   5112                     rv = phy_82381_prbs_tx_poly_get(pc, intf, value);
   5113                 } else {
   5114                     rv = phy_82381_prbs_rx_poly_get(pc, intf, value);
   5115                 }
   5116             } else { /* Simplex Tx package */
   5117                 if(intf == PHY82381_SYS_SIDE) {
   5118                     rv = phy_82381_prbs_rx_poly_get(pc, intf, value);
   5119                 } else {
   5120                     rv = phy_82381_prbs_tx_poly_get(pc, intf, value);
   5121                 }
   5122             }
   5123         } else {
   5124             rv = phy_82381_prbs_tx_poly_get(pc, intf, value);
   5125         }
   5126       break;
   5127     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   5128         if(FURIA_IS_SIMPLEX(chip_id)){
   5129             if (!simplex_tx) {  /*simplex Rx package */
   5130                 if(intf == PHY82381_SYS_SIDE) {
   5131                     rv = phy_82381_prbs_tx_invert_data_get(pc, intf, value);
   5132                 }
   5133             } else { /* Simplex Tx package */
   5134                 if(intf == PHY82381_LINE_SIDE) {
   5135                     rv = phy_82381_prbs_tx_invert_data_get(pc, intf, value);
   5136                 }
   5137             }
   5138         } else {
   5139             rv = phy_82381_prbs_tx_invert_data_get(pc, intf, value);
   5140         }
   5141       break;
   5142     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   5143         if(FURIA_IS_SIMPLEX(chip_id)){
   5144             if (!simplex_tx) {  /*simplex Rx package */
   5145                 if(intf == PHY82381_SYS_SIDE) {
   5146                     rv = phy_82381_prbs_tx_enable_get(pc, intf, value);
   5147                 }
   5148             } else { /* Simplex Tx package */
   5149                 if(intf == PHY82381_LINE_SIDE) {
   5150                     rv = phy_82381_prbs_tx_enable_get(pc, intf, value);
   5151                 }
   5152             }
   5153         } else {
   5154             rv = phy_82381_prbs_tx_enable_get(pc, intf, value);
   5155         }
   5156       break;
   5157     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   5158         if(FURIA_IS_SIMPLEX(chip_id)){
   5159             if (!simplex_tx) {  /*simplex Rx package */
   5160                 if(intf == PHY82381_LINE_SIDE) {
   5161                     rv = phy_82381_prbs_rx_enable_get(pc, intf, value);
   5162                 }
   5163             } else { /* Simplex Tx package */
   5164                 if(intf == PHY82381_SYS_SIDE) {
   5165                     rv = phy_82381_prbs_rx_enable_get(pc, intf, value);
   5166                 }
   5167             }
   5168         } else {
   5169             rv = phy_82381_prbs_rx_enable_get(pc, intf, value);
   5170         }
   5171       break;
   5172     case SOC_PHY_CONTROL_PRBS_RX_STATUS:
   5173         if(FURIA_IS_SIMPLEX(chip_id)){
   5174             if (!simplex_tx) {  /*simplex Rx package */
   5175                 if(intf == PHY82381_LINE_SIDE) {
   5176                     rv = phy_82381_prbs_rx_status_get(pc, intf, value);
   5177                 }
   5178             } else { /* Simplex Tx package */
   5179                 if(intf == PHY82381_SYS_SIDE) {
   5180                     rv = phy_82381_prbs_rx_status_get(pc, intf, value);
   5181                 }
   5182             }
   5183         } else {
   5184             rv = phy_82381_prbs_rx_status_get(pc, intf, value);
   5185         }
   5186       break;
   5187     /* LOOPBACK */
   5188     case SOC_PHY_CONTROL_LOOPBACK_REMOTE:
   5189     case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS:
   5190        rv = phy_82381_loopback_remote_get(pc, intf, value);
   5191        break;
   5192     case SOC_PHY_CONTROL_LOOPBACK_PMD:
   5193        rv = phy_82381_loopback_internal_pmd_get(pc, intf, value);
   5194        break;
   5195     /* PREEMPHASIS */
   5196     case SOC_PHY_CONTROL_PREEMPHASIS_LANE0:
   5197         rv = phy_82381_per_lane_preemphasis_get(pc, intf, 0, value);
   5198         break;
   5199     case SOC_PHY_CONTROL_PREEMPHASIS_LANE1:
   5200         rv = phy_82381_per_lane_preemphasis_get(pc, intf, 1, value);
   5201         break;
   5202     case SOC_PHY_CONTROL_PREEMPHASIS_LANE2:
   5203         rv = phy_82381_per_lane_preemphasis_get(pc, intf, 2, value);
   5204         break;
   5205     case SOC_PHY_CONTROL_PREEMPHASIS_LANE3:
   5206         rv = phy_82381_per_lane_preemphasis_get(pc, intf, 3, value);
   5207         break;
   5208     case SOC_PHY_CONTROL_PREEMPHASIS:
   5209         rv = phy_82381_preemphasis_get(pc,intf,value);
   5210         break;
   5211     case SOC_PHY_CONTROL_TX_FIR_PRE:
   5212         /* assume they are all the same as lane 0 */
   5213         rv = phy_82381_tx_fir_pre_get(pc, intf, value);
   5214         break;
   5215     case SOC_PHY_CONTROL_TX_FIR_MAIN:
   5216         /* assume they are all the same as lane 0 */
   5217         rv = phy_82381_tx_fir_main_get(pc, intf, value);
   5218         break;
   5219     case SOC_PHY_CONTROL_TX_FIR_POST:
   5220         /* assume they are all the same as lane 0 */
   5221         rv = phy_82381_tx_fir_post_get(pc, intf, value);
   5222         break;
   5223     case SOC_PHY_CONTROL_TX_FIR_POST2:
   5224         /* assume they are all the same as lane 0 */
   5225         rv = phy_82381_tx_fir_post2_get(pc, intf, value);
   5226         break;
   5227     case SOC_PHY_CONTROL_TX_FIR_POST3:
   5228         /* assume they are all the same as lane 0 */
   5229         rv = phy_82381_tx_fir_post3_get(pc, intf, value);
   5230         break;
   5231 
   5232     /* DRIVER CURRENT */
   5233     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0:
   5234         rv = phy_82381_per_lane_driver_current_get(pc, intf, 0, value);
   5235         break;
   5236     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1:
   5237         rv = phy_82381_per_lane_driver_current_get(pc, intf, 1, value);
   5238         break;
   5239     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2:
   5240         rv = phy_82381_per_lane_driver_current_get(pc, intf, 2, value);
   5241         break;
   5242     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3:
   5243         rv = phy_82381_per_lane_driver_current_get(pc, intf, 3, value);
   5244         break;
   5245     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   5246         rv = phy_82381_driver_current_get(pc, intf, value);
   5247         break;
   5248 
   5249     /* RX PEAK FILTER */
   5250     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   5251         rv = phy_82381_rx_peak_filter_get(pc, intf, value);
   5252         break;
   5253 
   5254     /* RX VGA */
   5255     case SOC_PHY_CONTROL_RX_VGA:
   5256         rv = phy_82381_rx_vga_get(pc, intf, value);
   5257         break;
   5258 
   5259     /* RX TAP */
   5260     case SOC_PHY_CONTROL_RX_TAP1:
   5261         rv = phy_82381_rx_tap_get(pc, intf, 0, value);
   5262         break;
   5263     case SOC_PHY_CONTROL_RX_TAP2:
   5264         rv = phy_82381_rx_tap_get(pc, intf, 1, value);
   5265         break;
   5266     case SOC_PHY_CONTROL_RX_TAP3:
   5267         rv = phy_82381_rx_tap_get(pc, intf, 2, value);
   5268         break;
   5269     case SOC_PHY_CONTROL_RX_TAP4:
   5270         rv = phy_82381_rx_tap_get(pc, intf, 3, value);
   5271         break;
   5272     case SOC_PHY_CONTROL_RX_TAP5:
   5273         rv = phy_82381_rx_tap_get(pc, intf, 4, value);
   5274         break;
   5275 
   5276     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   5277         rv = phy_82381_rx_low_freq_filter_get(pc, intf, value);
   5278         break;
   5279 
   5280     /* PHASE INTERPOLATOR */
   5281     case SOC_PHY_CONTROL_PHASE_INTERP:
   5282         rv = phy_82381_pi_control_get(pc, intf, value);
   5283         break;
   5284 
   5285     /* RX SIGNAL DETECT */
   5286     case SOC_PHY_CONTROL_RX_SIGNAL_DETECT:
   5287       rv = phy_82381_rx_signal_detect_get(pc, intf, value);
   5288       break;
   5289     case SOC_PHY_CONTROL_RX_SEQ_DONE:
   5290       rv = phy_82381_rx_seq_done_get(pc, intf, value);
   5291       break;
   5292     case SOC_PHY_CONTROL_RX_PPM:
   5293       rv = phy_82381_rx_ppm_get(pc, intf, value);
   5294       break;
   5295     /* FEC */
   5296     case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION:
   5297       rv = phy_82381_fec_enable_get(pc, value);
   5298       break;
   5299     case SOC_PHY_CONTROL_RX_POLARITY:
   5300         rv = phy_82381_rx_polarity_get(pc, intf, value);;
   5301         break;
   5302     case SOC_PHY_CONTROL_TX_POLARITY:
   5303         rv = phy_82381_tx_polarity_get(pc, intf, value);
   5304         break;
   5305     /* POWER */
   5306     case SOC_PHY_CONTROL_POWER:
   5307        rv = phy_82381_power_get(pc, intf, value);
   5308        break;
   5309     case SOC_PHY_CONTROL_CL72:
   5310         rv = phy_82381_cl72_enable_get(pc, intf, value);
   5311     break;
   5312     case SOC_PHY_CONTROL_CL72_STATUS:
   5313         rv = phy_82381_cl72_status_get(pc, intf, value);
   5314     break;
   5315     case SOC_PHY_CONTROL_INTR_MASK:
   5316         rv = phy_82381_intr_enable_get(pc, intf, value);
   5317     break;
   5318     case SOC_PHY_CONTROL_INTR_STATUS:
   5319         rv = phy_82381_intr_status_get(pc, intf, value);
   5320     break;
   5321     case SOC_PHY_CONTROL_TX_LANE_SQUELCH:
   5322         rv = phy_82381_tx_lane_squelch_get(pc, intf, value);
   5323     break;
   5324     case SOC_PHY_CONTROL_XSW_LANE_MAP:
   5325         if(FURIA_IS_SIMPLEX(chip_id)){
   5326                *value = value_laneswap;/*restore value*/;
   5327         }
   5328         rv = phy_82381_cross_switch_swap_get(pc, intf, value);
   5329     break;
   5330     case SOC_PHY_CONTROL_GPIO_CONFIG:
   5331         rv = phy_82381_gpio_config_get(pc, value);
   5332     break;
   5333     case SOC_PHY_CONTROL_GPIO_VALUE:
   5334         rv = phy_82381_gpio_value_get(pc, value);
   5335     break;
   5336     /* FIRMWARE MODE */
   5337     case SOC_PHY_CONTROL_FIRMWARE_MODE:
   5338        rv = phy_82381_firmware_mode_get(pc, intf, value);
   5339        break;
   5340     case SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE:
   5341        rv = phy_82381_firmware_dfe_enable_get(pc, intf, value);
   5342        break;
   5343     case SOC_PHY_CONTROL_FIRMWARE_LP_DFE_ENABLE:
   5344        rv = phy_82381_firmware_lp_dfe_enable_get(pc, intf, value);
   5345        break;
   5346     case SOC_PHY_CONTROL_FIRMWARE_BR_DFE_ENABLE:
   5347        rv = phy_82381_firmware_br_dfe_enable_get(pc, intf, value);
   5348        break;
   5349     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE:
   5350         rv = phy_82381_short_chn_mode_enable_get(pc, intf, value);
   5351         break;
   5352     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE_STATUS:
   5353         rv = phy_82381_short_chn_mode_status_get(pc, intf, value);
   5354         break;
   5355     case SOC_PHY_CONTROL_UNRELIABLE_LOS:
   5356         rv = phy_82381_unreliable_los_get(pc, intf, value);
   5357     break;
   5358     default:
   5359        rv = SOC_E_UNAVAIL;
   5360        break;
   5361     }
   5362     return rv;
   5363 }
   5364 
   5365 /*
   5366  * Function:
   5367  *      phy_82381_per_lane_control_get
   5368  * Purpose:
   5369  *      Configure PHY device specific control fucntion.
   5370  * Parameters:
   5371  *      unit  - StrataSwitch unit #.
   5372  *      port  - StrataSwitch port #.
   5373  *      lane  - lane number
   5374  *      type  - Control to update
   5375  *      value - New setting for the control
   5376  * Returns:
   5377  *      SOC_E_NONE
   5378  */
   5379 STATIC int
   5380 phy_82381_per_lane_control_get(int unit, soc_port_t port, int lane,
   5381                      soc_phy_control_t type, uint32 *value)
   5382 {
   5383     int                 rv = SOC_E_UNAVAIL;
   5384     phy_ctrl_t          *pc;
   5385     int32 intf;
   5386     uint32 simplex_tx = 0;
   5387     uint32_t chip_id = 0;
   5388     *value = 0;
   5389 
   5390     /* locate phy control, phymod control, and the configuration data */
   5391     pc = EXT_PHY_SW_STATE(unit, port);
   5392     if (pc == NULL) {
   5393         return SOC_E_INTERNAL;
   5394     }
   5395     simplex_tx = SIMPLEX_TX(pc);
   5396     chip_id = DEVID(pc);
   5397 
   5398     PHY_CONTROL_TYPE_CHECK(type);
   5399 
   5400     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82381_SYS_SIDE : PHY82381_LINE_SIDE;
   5401 
   5402     switch(type) {
   5403 
   5404     case SOC_PHY_CONTROL_PREEMPHASIS:
   5405         rv = phy_82381_per_lane_preemphasis_get(pc, intf, lane, value);
   5406         break;
   5407     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   5408         rv = phy_82381_per_lane_driver_current_get(pc, intf, lane, value);
   5409         break;
   5410     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT:
   5411         rv = SOC_E_UNAVAIL;
   5412         break;
   5413     case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT:
   5414         rv = SOC_E_UNAVAIL;
   5415         break;
   5416     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL:
   5417         rv = phy_82381_per_lane_prbs_tx_poly_get(pc, intf, lane, value);
   5418         break;
   5419     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA:
   5420         rv = phy_82381_per_lane_prbs_tx_invert_data_get(pc, intf, lane, value);
   5421         break;
   5422     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE:
   5423         rv = phy_82381_per_lane_prbs_tx_enable_get(pc, intf, lane, value);
   5424         break;
   5425     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL:
   5426         rv = phy_82381_per_lane_prbs_rx_poly_get(pc, intf, lane, value);
   5427         break;
   5428     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA:
   5429         rv = phy_82381_per_lane_prbs_rx_invert_data_get(pc, intf, lane, value);
   5430         break;
   5431     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE:
   5432         rv = phy_82381_per_lane_prbs_rx_enable_get(pc, intf, lane, value);
   5433         break;
   5434     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   5435         if(FURIA_IS_SIMPLEX(chip_id)){
   5436             if (!simplex_tx) {  /*simplex Rx package */
   5437                 if(intf == PHY82381_SYS_SIDE) {
   5438                     rv = phy_82381_per_lane_prbs_tx_poly_get(pc, intf, lane, value);
   5439                 } else {
   5440                     rv = phy_82381_per_lane_prbs_rx_poly_get(pc, intf, lane, value);
   5441                 }
   5442             } else { /* Simplex Tx package */
   5443                 if(intf == PHY82381_SYS_SIDE) {
   5444                     rv = phy_82381_per_lane_prbs_rx_poly_get(pc, intf, lane, value);
   5445                 } else {
   5446                     rv = phy_82381_per_lane_prbs_tx_poly_get(pc, intf, lane, value);
   5447                 }
   5448             }
   5449         } else {
   5450             rv = phy_82381_per_lane_prbs_tx_poly_get(pc, intf, lane, value);
   5451             rv = phy_82381_per_lane_prbs_rx_poly_get(pc, intf, lane, value);
   5452         }
   5453         break;
   5454     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   5455         if(FURIA_IS_SIMPLEX(chip_id)){
   5456             if (!simplex_tx) {  /*simplex Rx package */
   5457                 if(intf == PHY82381_SYS_SIDE) {
   5458                     rv = phy_82381_per_lane_prbs_tx_invert_data_get(pc, intf, lane, value);
   5459                 } else {
   5460                     rv = SOC_E_NONE;
   5461                 }
   5462             } else { /* Simplex Tx package */
   5463                 if(intf == PHY82381_LINE_SIDE) {
   5464                     rv = phy_82381_per_lane_prbs_tx_invert_data_get(pc, intf, lane, value);
   5465                 } else {
   5466                     rv = SOC_E_NONE;
   5467                 }
   5468             }
   5469         } else {
   5470             rv = phy_82381_per_lane_prbs_tx_invert_data_get(pc, intf, lane, value);
   5471         }
   5472         break;
   5473     case SOC_PHY_CONTROL_PRBS_RX_INVERT_DATA:
   5474         rv = phy_82381_per_lane_prbs_rx_invert_data_get(pc, intf, lane, value);
   5475         break;
   5476     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   5477         /* TX_ENABLE does both tx and rx */
   5478         if(FURIA_IS_SIMPLEX(chip_id)){
   5479             if (!simplex_tx) {  /*simplex Rx package */
   5480                 if(intf == PHY82381_SYS_SIDE) {
   5481                     rv = phy_82381_per_lane_prbs_tx_enable_get(pc, intf, lane, value);
   5482                 } else {
   5483                     rv = phy_82381_per_lane_prbs_rx_enable_get(pc, intf, lane, value);
   5484                 }
   5485             } else { /* Simplex Tx package */
   5486                 if(intf == PHY82381_SYS_SIDE) {
   5487                     rv = phy_82381_per_lane_prbs_rx_enable_get(pc, intf, lane, value);
   5488                 } else {
   5489                     rv = phy_82381_per_lane_prbs_tx_enable_get(pc, intf, lane, value);
   5490                 }
   5491             }
   5492         } else {
   5493             rv = phy_82381_per_lane_prbs_tx_enable_get(pc, intf, lane, value);
   5494             rv = phy_82381_per_lane_prbs_rx_enable_get(pc, intf, lane, value);
   5495         }
   5496         break;
   5497     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   5498         if(FURIA_IS_SIMPLEX(chip_id)){
   5499             if (!simplex_tx) {  /*simplex Rx package */
   5500                 if(intf == PHY82381_SYS_SIDE) {
   5501                     rv = phy_82381_per_lane_prbs_tx_enable_get(pc, intf, lane, value);
   5502                 } else {
   5503                     rv = phy_82381_per_lane_prbs_rx_enable_get(pc, intf, lane, value);
   5504                 }
   5505             } else { /* Simplex Tx package */
   5506                 if(intf == PHY82381_SYS_SIDE) {
   5507                     rv = phy_82381_per_lane_prbs_rx_enable_get(pc, intf, lane, value);
   5508                 } else {
   5509                     rv = phy_82381_per_lane_prbs_tx_enable_get(pc, intf, lane, value);
   5510                 }
   5511             }
   5512         } else {
   5513             rv = phy_82381_per_lane_prbs_tx_enable_get(pc, intf, lane, value);
   5514             rv = phy_82381_per_lane_prbs_rx_enable_get(pc, intf, lane, value);
   5515         }
   5516         break;
   5517     case SOC_PHY_CONTROL_PRBS_RX_STATUS:
   5518         rv = phy_82381_per_lane_prbs_rx_status_get(pc, intf, lane, value);
   5519         break;
   5520     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   5521         rv = phy_82381_per_lane_rx_peak_filter_get(pc, intf, lane, value);
   5522         break;
   5523     case SOC_PHY_CONTROL_RX_VGA:
   5524         rv = phy_82381_per_lane_rx_vga_get(pc, intf, lane, value);
   5525         break;
   5526     case SOC_PHY_CONTROL_RX_TAP1:
   5527         rv = phy_82381_per_lane_rx_dfe_tap_control_get(pc, intf, lane, 0, value);
   5528         break;
   5529     case SOC_PHY_CONTROL_RX_TAP2:
   5530         rv = phy_82381_per_lane_rx_dfe_tap_control_get(pc, intf, lane, 1, value);
   5531         break;
   5532     case SOC_PHY_CONTROL_RX_TAP3:
   5533         rv = phy_82381_per_lane_rx_dfe_tap_control_get(pc, intf, lane, 2, value);
   5534         break;
   5535     case SOC_PHY_CONTROL_RX_TAP4:
   5536         rv = phy_82381_per_lane_rx_dfe_tap_control_get(pc, intf, lane, 3, value);
   5537         break;
   5538     case SOC_PHY_CONTROL_RX_TAP5:
   5539         rv = phy_82381_per_lane_rx_dfe_tap_control_get(pc, intf, lane, 4, value);
   5540         break;
   5541     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   5542         rv = phy_82381_per_lane_rx_low_freq_filter_get(pc, intf, lane, value);
   5543         break;
   5544     case SOC_PHY_CONTROL_RX_PLUS1_SLICER:
   5545         rv = SOC_E_UNAVAIL;
   5546         break;
   5547     case SOC_PHY_CONTROL_RX_MINUS1_SLICER:
   5548         rv = SOC_E_UNAVAIL;
   5549         break;
   5550     case SOC_PHY_CONTROL_RX_D_SLICER:
   5551         rv = SOC_E_UNAVAIL;
   5552         break;
   5553     /* LOOPBACK */
   5554     case SOC_PHY_CONTROL_LOOPBACK_REMOTE:
   5555     case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS:
   5556        rv = phy_82381_per_lane_loopback_remote_get(pc, intf, lane, value);
   5557        break;
   5558     case SOC_PHY_CONTROL_LOOPBACK_PMD:
   5559        rv = phy_82381_per_lane_loopback_internal_pmd_get(pc, intf, lane, value);
   5560        break;
   5561     case SOC_PHY_CONTROL_RX_POLARITY:
   5562         rv = phy_82381_per_lane_rx_polarity_get(pc, intf, lane, value);
   5563         break;
   5564     case SOC_PHY_CONTROL_TX_POLARITY:
   5565         rv = phy_82381_per_lane_tx_polarity_get(pc, intf, lane, value);
   5566         break;
   5567     /* POWER */
   5568     case SOC_PHY_CONTROL_POWER:
   5569        rv = phy_82381_per_lane_power_get(pc, intf, lane, value);
   5570        break;
   5571     case SOC_PHY_CONTROL_TX_FIR_PRE:
   5572     case SOC_PHY_CONTROL_TX_FIR_MAIN:
   5573     case SOC_PHY_CONTROL_TX_FIR_POST:
   5574     case SOC_PHY_CONTROL_TX_FIR_POST2:
   5575     case SOC_PHY_CONTROL_TX_FIR_POST3:
   5576         rv = phy_82381_per_lane_tx_get(pc, intf, type, lane, value);
   5577         break;
   5578     case SOC_PHY_CONTROL_TX_LANE_SQUELCH:
   5579         rv = phy_82381_per_lane_tx_lane_squelch_get(pc, intf, lane, value);
   5580         break;
   5581     /* FIRMWARE MODE */
   5582     case SOC_PHY_CONTROL_FIRMWARE_MODE:
   5583         rv = phy_82381_per_lane_firmware_mode_get(pc, intf, lane, value);
   5584         break;
   5585     case SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE:
   5586         rv = phy_82381_per_lane_firmware_dfe_enable_get(pc, intf, lane, value);
   5587         break;
   5588     case SOC_PHY_CONTROL_FIRMWARE_LP_DFE_ENABLE:
   5589         rv = phy_82381_per_lane_firmware_lp_dfe_enable_get(pc, intf, lane, value);
   5590         break;
   5591     case SOC_PHY_CONTROL_FIRMWARE_BR_DFE_ENABLE:
   5592         rv = phy_82381_per_lane_firmware_br_dfe_enable_get(pc, intf, lane, value);
   5593         break;
   5594     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE:
   5595         rv = phy_82381_per_lane_short_chn_mode_enable_get(pc, port, intf, lane, value);
   5596         break;
   5597     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE_STATUS:
   5598         rv = phy_82381_per_lane_short_chn_mode_status_get(pc, port, intf, lane, value);
   5599         break;
   5600     case SOC_PHY_CONTROL_UNRELIABLE_LOS:
   5601         rv = phy_82381_per_lane_unreliable_los_get(pc, intf, lane, value);
   5602     break;
   5603     default:
   5604         rv = SOC_E_UNAVAIL;
   5605         break;
   5606     }
   5607     return rv;
   5608 }
   5609 
   5610 /*
   5611  * Function:
   5612  *      phy82381_duplex_get
   5613  * Purpose:
   5614  *      Get PHY duplex mode
   5615  * Parameters:
   5616  *      unit - BCM unit number.
   5617  *      port - Port number.
   5618  *      duplex - current duplex mode
   5619  * Returns:
   5620  *      SOC_E_NONE
   5621  */
   5622 STATIC int
   5623 phy82381_duplex_get(int unit, soc_port_t port, int *duplex)
   5624 {
   5625     *duplex = TRUE;
   5626     return SOC_E_NONE;
   5627 }
   5628 
   5629 /*
   5630  * Function:
   5631  *      phy_82381_an_set
   5632  * Purpose:
   5633  *      Enable or disable auto-negotiation on the specified port.
   5634  * Parameters:
   5635  *      unit - BCM unit number.
   5636  *      port - Port number.
   5637  *      an   - Boolean, if true, auto-negotiation is enabled
   5638  *              (and/or restarted). If false, autonegotiation is disabled.
   5639  * Returns:
   5640  *      SOC_E_XXX  _soc_triumph_tx
   5641  */
   5642 STATIC int
   5643 phy_82381_an_set(int unit, soc_port_t port, int enable)
   5644 {
   5645     phy_ctrl_t                *pc;
   5646     soc_phymod_ctrl_t         *pmc;
   5647     soc_phymod_phy_t          *phy;
   5648     phymod_autoneg_control_t  an;
   5649     soc_info_t *si;
   5650     uint32 chip_id = 0;
   5651 
   5652     /* locate phy control */
   5653     pc = EXT_PHY_SW_STATE(unit, port);
   5654     if (pc == NULL) {
   5655         return SOC_E_INTERNAL;
   5656     }
   5657 
   5658 
   5659     phymod_autoneg_control_t_init(&an);
   5660     pmc = &pc->phymod_ctrl;
   5661     chip_id = DEVID(pc);
   5662     if (FURIA_IS_SIMPLEX(chip_id)) {
   5663         return SOC_E_NONE;
   5664     }
   5665     si = &SOC_INFO(unit);
   5666 
   5667     /* only request autoneg on the first core */
   5668     phy = pmc->phy[pmc->main_phy];
   5669     if (phy == NULL) {
   5670         return SOC_E_INTERNAL;
   5671     }
   5672     an.enable = enable;
   5673     an.num_lane_adv = si->port_num_lanes[port];
   5674     an.an_mode = phymod_AN_MODE_CL73;
   5675     SOC_IF_ERROR_RETURN
   5676         (phymod_phy_autoneg_set(&phy->pm_phy, &an));
   5677     return (SOC_E_NONE);
   5678 }
   5679 /*
   5680  * Function:
   5681  *      phy_82381_an_get
   5682  * Purpose:
   5683  *      Get the current auto-negotiation status (enabled/busy)
   5684  * Parameters:
   5685  *      unit - BCM unit number.
   5686  *      port - Port number.
   5687  *      an   - (OUT) if true, auto-negotiation is enabled.
   5688  *      an_done - (OUT) if true, auto-negotiation is complete. This
   5689  *              value is undefined if an == false.
   5690  * Returns:
   5691  *      SOC_E_XXX
   5692  */
   5693 
   5694 STATIC int
   5695 phy_82381_an_get(int unit, soc_port_t port, int *an, int *an_done)
   5696 {
   5697     phy_ctrl_t* pc;
   5698     soc_phymod_ctrl_t *pmc;
   5699     phymod_phy_access_t *pm_phy;
   5700     phymod_autoneg_control_t an_control;
   5701     int an_complete;
   5702     uint32 chip_id = 0;
   5703 
   5704     *an = 0;
   5705     *an_done = 0;
   5706 
   5707     pc = EXT_PHY_SW_STATE(unit, port);
   5708     pmc = &pc->phymod_ctrl;
   5709     pm_phy = &pmc->phy[pmc->main_phy]->pm_phy;
   5710     chip_id = DEVID(pc);
   5711 
   5712     if (FURIA_IS_SIMPLEX(chip_id)) {
   5713         return SOC_E_NONE;
   5714     }
   5715 
   5716     sal_memset(&an_control, 0x0, sizeof(an_control));
   5717 
   5718 
   5719     SOC_IF_ERROR_RETURN
   5720         (phymod_phy_autoneg_get(pm_phy, &an_control, (uint32_t *) &an_complete));
   5721 
   5722     if (an_control.enable) {
   5723         *an = 1;
   5724         *an_done = an_complete;
   5725 #ifdef PHY82381_DEBUG
   5726         LOG_CLI((BSL_META_U(unit,"AN complete:%d\n "),*an_done));
   5727 #endif
   5728     } else {
   5729         *an = 0;
   5730         *an_done = 0;
   5731     }
   5732     return SOC_E_NONE;
   5733 }
   5734 /*
   5735  * Function:
   5736  *      phy_82381_ability_advert_set
   5737  * Purpose:
   5738  *      Set the current advertisement for auto-negotiation.
   5739  * Parameters:
   5740  *      unit - BCM unit number.
   5741  *      port - Port number.
   5742  *      ability - Port mode mask indicating supported options/speeds.
   5743  * Returns:
   5744  *      SOC_E_XXX
   5745  * Notes:
   5746  *      The advertisement is set only for the ACTIVE medium.
   5747  *      No synchronization performed at this level.
   5748  */
   5749 
   5750 STATIC int
   5751 phy_82381_ability_advert_set(int unit, soc_port_t port,
   5752                           soc_port_ability_t *ability)
   5753 {
   5754     int an, an_done;
   5755     phy_ctrl_t                *pc;
   5756     soc_phymod_ctrl_t         *pmc;
   5757     soc_phymod_phy_t          *phy;
   5758     soc_port_if_t             line_interface;
   5759     uint32_t                  an_tech_ability;
   5760     uint32_t                  an_bam37_ability;
   5761     uint32_t                  an_bam73_ability;
   5762     _shr_port_mode_t          speed_full_duplex;
   5763     phymod_autoneg_ability_t  phymod_autoneg_ability;
   5764 
   5765     /* locate phy control */
   5766     pc = EXT_PHY_SW_STATE(unit, port);
   5767     if (pc == NULL) {
   5768         return SOC_E_INTERNAL;
   5769     }
   5770 
   5771     phymod_autoneg_ability_t_init(&phymod_autoneg_ability);
   5772 
   5773     pmc = &pc->phymod_ctrl;
   5774 
   5775     /* only set abilities on the first core */
   5776     phy = pmc->phy[pmc->main_phy];
   5777     if (phy == NULL) {
   5778         return SOC_E_INTERNAL;
   5779     }
   5780 
   5781     an_tech_ability  = 0;
   5782     an_bam37_ability = 0;
   5783     an_bam73_ability = 0;
   5784     speed_full_duplex = ability->speed_full_duplex;
   5785     line_interface = ability->interface;
   5786 
   5787     /* Check if AN is enabled, If so, we need to disable AN before setting
   5788      * ability and re-enable AN after changing ability
   5789      */
   5790     SOC_IF_ERROR_RETURN(phy_82381_an_get(unit, port, &an, &an_done));
   5791     if (an) {
   5792         SOC_IF_ERROR_RETURN(phy_82381_an_set(unit, port, 0));
   5793     }
   5794     /* if ability->interface is NULL, get the configured interface */
   5795     if (!line_interface) {
   5796         SOC_IF_ERROR_RETURN(phy82381_interface_get(unit, port, &line_interface));
   5797     }
   5798 
   5799     if(speed_full_duplex & SOC_PA_SPEED_100GB) {
   5800         if (line_interface == SOC_PORT_IF_KR4) {
   5801             PHYMOD_AN_CAP_100G_KR4_SET(an_tech_ability);
   5802         }
   5803         if (line_interface == SOC_PORT_IF_CR4) {
   5804             PHYMOD_AN_CAP_100G_CR4_SET(an_tech_ability);
   5805         }
   5806     } else if (speed_full_duplex & SOC_PA_SPEED_40GB) {
   5807         if (line_interface == SOC_PORT_IF_KR4) {
   5808             PHYMOD_AN_CAP_40G_KR4_SET(an_tech_ability);
   5809         }
   5810         if (line_interface == SOC_PORT_IF_CR4) {
   5811             PHYMOD_AN_CAP_40G_CR4_SET(an_tech_ability);
   5812         }
   5813     } else if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   5814         if (line_interface == SOC_PORT_IF_KR) {
   5815             PHYMOD_AN_CAP_10G_KR_SET(an_tech_ability);
   5816         }
   5817     } else {
   5818         an_tech_ability = 0;
   5819     }
   5820 
   5821     phymod_autoneg_ability.an_cap = an_tech_ability;
   5822     phymod_autoneg_ability.cl73bam_cap = an_bam73_ability;
   5823     phymod_autoneg_ability.cl37bam_cap = an_bam37_ability;
   5824 #ifdef PHY82381_DEBUG
   5825     LOG_CLI((BSL_META_U(unit,"AN:abilitySet =%x tech ability:%x pause:%d\n"), speed_full_duplex, an_tech_ability,ability->pause));
   5826 #endif
   5827     switch (ability->pause & (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX)) {
   5828         case SOC_PA_PAUSE_TX:
   5829             PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability);
   5830         break;
   5831         case SOC_PA_PAUSE_RX:
   5832             /* an_adv |= MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; */
   5833             PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability);
   5834             PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability);
   5835         break;
   5836         case SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX:
   5837             PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability);
   5838         break;
   5839     }
   5840 
   5841     
   5842 
   5843     phymod_autoneg_ability.sgmii_speed = 2;
   5844     phymod_autoneg_ability.an_cl72 = soc_property_port_get(unit, port, spn_PHY_AN_C72, TRUE);
   5845     SOC_IF_ERROR_RETURN
   5846         (phymod_phy_autoneg_ability_set(&phy->pm_phy, &phymod_autoneg_ability));
   5847     if (an) {
   5848         SOC_IF_ERROR_RETURN(phy_82381_an_set(unit, port, 1));
   5849     }
   5850     return SOC_E_NONE;
   5851 }
   5852 
   5853 /*
   5854  * Function:
   5855  *      phy_82381_ability_advert_get
   5856  * Purpose:
   5857  *      Get the current advertisement for auto-negotiation.
   5858  * Parameters:
   5859  *      unit - BCM unit number.
   5860  *      port - Port number.
   5861  *      ability - (OUT) Port mode mask indicating supported options/speeds.
   5862  * Returns:
   5863  *      SOC_E_XXX
   5864  * Notes:
   5865  *      The advertisement is retrieved for the ACTIVE medium.
   5866  *      No synchronization performed at this level.
   5867  */
   5868 
   5869 STATIC int
   5870 phy_82381_ability_advert_get(int unit, soc_port_t port,
   5871                               soc_port_ability_t *ability)
   5872 {
   5873     phy_ctrl_t                *pc;
   5874     soc_phymod_ctrl_t         *pmc;
   5875     soc_phymod_phy_t          *phy;
   5876     int                       reg73_ability;
   5877     int                       reg_ability;
   5878     _shr_port_mode_t          speed_full_duplex;
   5879     phymod_autoneg_ability_t  phymod_autoneg_ability;
   5880     uint32 chip_id = 0;
   5881 
   5882     /* locate phy control */
   5883     pc = EXT_PHY_SW_STATE(unit, port);
   5884     if (pc == NULL) {
   5885         return SOC_E_INTERNAL;
   5886     }
   5887 
   5888     pmc = &pc->phymod_ctrl;
   5889 
   5890     /* only get abilities from the first core */
   5891     phy = pmc->phy[0];
   5892     if (phy == NULL) {
   5893         return SOC_E_INTERNAL;
   5894     }
   5895 
   5896     chip_id = DEVID(pc);
   5897     if (FURIA_IS_SIMPLEX(chip_id)) {
   5898         return SOC_E_NONE;
   5899     }
   5900     phymod_autoneg_ability_t_init(&phymod_autoneg_ability);
   5901 
   5902     SOC_IF_ERROR_RETURN
   5903         (phymod_phy_autoneg_ability_get(&phy->pm_phy, &phymod_autoneg_ability));
   5904 
   5905 
   5906     speed_full_duplex = 0;
   5907 
   5908     /* retrieve CL73 abilities */
   5909     reg73_ability = phymod_autoneg_ability.an_cap;
   5910     speed_full_duplex |= PHYMOD_AN_CAP_40G_CR4_GET(reg73_ability) ? SOC_PA_SPEED_40GB : 0;
   5911     speed_full_duplex |= PHYMOD_AN_CAP_40G_KR4_GET(reg73_ability) ? SOC_PA_SPEED_40GB : 0;
   5912     speed_full_duplex |= PHYMOD_AN_CAP_10G_KR_GET (reg73_ability)  ? SOC_PA_SPEED_10GB : 0;
   5913     speed_full_duplex |= PHYMOD_AN_CAP_100G_CR4_GET(reg73_ability) ? SOC_PA_SPEED_100GB : 0;
   5914     speed_full_duplex |= PHYMOD_AN_CAP_100G_KR4_GET(reg73_ability) ? SOC_PA_SPEED_100GB : 0;
   5915     speed_full_duplex |= PHYMOD_AN_CAP_100G_CR10_GET(reg73_ability) ? SOC_PA_SPEED_100GB : 0;
   5916 
   5917     if (speed_full_duplex & SOC_PA_SPEED_40GB) {
   5918         if (PHYMOD_AN_CAP_40G_CR4_GET(reg73_ability)) {
   5919             ability->interface = SOC_PORT_IF_CR4;
   5920         } else {
   5921             ability->interface = SOC_PORT_IF_KR4;
   5922         }
   5923     } else if(speed_full_duplex & SOC_PA_SPEED_100GB) {
   5924         if (PHYMOD_AN_CAP_100G_CR4_GET(reg73_ability)) {
   5925             ability->interface = SOC_PORT_IF_CR4;
   5926         } else {
   5927             ability->interface = SOC_PORT_IF_KR4;
   5928         }
   5929     } else if (speed_full_duplex & SOC_PA_SPEED_10GB) {
   5930         ability->interface = SOC_PORT_IF_KR;
   5931     } else {
   5932         ability->interface = 0;
   5933     }
   5934 
   5935 
   5936     /* retrieve "pause" abilities */
   5937     reg_ability = phymod_autoneg_ability.capabilities;
   5938 
   5939     ability->pause = 0;
   5940     if (reg_ability == PHYMOD_AN_CAP_ASYM_PAUSE) {
   5941         ability->pause = SOC_PA_PAUSE_TX;
   5942     } else if (reg_ability == (PHYMOD_AN_CAP_SYMM_PAUSE | PHYMOD_AN_CAP_ASYM_PAUSE)) {
   5943         ability->pause = SOC_PA_PAUSE_RX;
   5944     } else if (reg_ability == PHYMOD_AN_CAP_SYMM_PAUSE) {
   5945         ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX);
   5946     }
   5947 
   5948     ability->speed_full_duplex = speed_full_duplex;
   5949     return SOC_E_NONE;
   5950 }
   5951 
   5952 /*
   5953  * Function:
   5954  *      phy82381_lb_get
   5955  * Purpose:
   5956  *      Get current PHY loopback mode
   5957  * Parameters:
   5958  *      unit - BCM unit number.
   5959  *      port - Port number.
   5960  *      enable - address of location to store binary value for on/off (1/0)
   5961  * Returns:
   5962  *      SOC_E_NONE
   5963  */
   5964 STATIC int
   5965 phy82381_lb_get(int unit, soc_port_t port, int *enable)
   5966 {
   5967     phy_ctrl_t* pc;
   5968     uint32 out_en;
   5969 
   5970     *enable = 0;
   5971 
   5972     pc = EXT_PHY_SW_STATE(unit, port);
   5973     if (pc == NULL) {
   5974         return SOC_E_INTERNAL;
   5975     }
   5976     SOC_IF_ERROR_RETURN(
   5977         phy_82381_loopback_internal_pmd_get(pc, PHY82381_LINE_SIDE, &out_en));
   5978     *enable = (int) out_en;
   5979 
   5980     return SOC_E_NONE;
   5981 }
   5982 
   5983 /*
   5984  * phy_82381_per_lane_loopback_internal_pmd_set
   5985  */
   5986 STATIC int
   5987 phy_82381_per_lane_loopback_internal_pmd_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   5988 {
   5989     phymod_phy_access_t  *pm_phy;
   5990     uint32              lane_map;
   5991     phymod_phy_access_t pm_phy_copy;
   5992     soc_phymod_phy_t    *p_phy;
   5993     soc_phymod_ctrl_t   *pmc;
   5994     pmc = &pc->phymod_ctrl;
   5995 
   5996     /* locate the desired phy and lane */
   5997     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   5998 
   5999     /* Make a copy of the phy access and overwrite the desired lane */
   6000     pm_phy = &p_phy->pm_phy;
   6001     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6002     pm_phy_copy.access.lane_mask = lane_map;
   6003     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6004     if(intf == PHY82381_SYS_SIDE) {
   6005         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   6006     }
   6007 
   6008     SOC_IF_ERROR_RETURN
   6009         (phymod_phy_loopback_set(&pm_phy_copy, phymodLoopbackGlobalPMD, value));
   6010     return(SOC_E_NONE);
   6011 }
   6012 
   6013 /*
   6014  * phy_82381_loopback_internal_pmd_set
   6015  */
   6016 STATIC int
   6017 phy_82381_loopback_internal_pmd_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6018 {
   6019     phymod_phy_access_t  *pm_phy;
   6020     int                    idx;
   6021     phymod_phy_access_t pm_phy_copy;
   6022     soc_phymod_ctrl_t   *pmc;
   6023     pmc = &pc->phymod_ctrl;
   6024 
   6025 
   6026     for (idx = 0; idx < pmc->num_phys; idx++) {
   6027         if (pmc->phy[idx] == NULL) {
   6028             return SOC_E_INTERNAL;
   6029         }
   6030         pm_phy = &pmc->phy[idx]->pm_phy;
   6031         if (pm_phy == NULL) {
   6032             return SOC_E_INTERNAL;
   6033         }
   6034 
   6035         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6036         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6037         if(intf == PHY82381_SYS_SIDE) {
   6038             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   6039         }
   6040 
   6041         SOC_IF_ERROR_RETURN
   6042             (phymod_phy_loopback_set(&pm_phy_copy, phymodLoopbackGlobalPMD, value));
   6043     }
   6044     return(SOC_E_NONE);
   6045 }
   6046 
   6047 /*
   6048  * phy_82381_per_lane_loopback_remote_set
   6049  */
   6050 STATIC int
   6051 phy_82381_per_lane_loopback_remote_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   6052 {
   6053     phymod_phy_access_t  *pm_phy;
   6054     uint32              lane_map;
   6055     phymod_phy_access_t pm_phy_copy;
   6056     soc_phymod_phy_t    *p_phy;
   6057     soc_phymod_ctrl_t   *pmc;
   6058     pmc = &pc->phymod_ctrl;
   6059 
   6060 
   6061     /* locate the desired phy and lane */
   6062     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   6063 
   6064     /* Make a copy of the phy access and overwrite the desired lane */
   6065     pm_phy = &p_phy->pm_phy;
   6066     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6067     pm_phy_copy.access.lane_mask = lane_map;
   6068     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6069     if(intf == PHY82381_SYS_SIDE) {
   6070         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   6071     }
   6072 
   6073     SOC_IF_ERROR_RETURN
   6074         (phymod_phy_loopback_set(&pm_phy_copy, phymodLoopbackRemotePMD, value));
   6075     return(SOC_E_NONE);
   6076 }
   6077 /*
   6078  * phy_82381_loopback_remote_set
   6079  */
   6080 STATIC int
   6081 phy_82381_loopback_remote_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6082 {
   6083     phymod_phy_access_t  *pm_phy;
   6084     int                    idx;
   6085     phymod_phy_access_t pm_phy_copy;
   6086     soc_phymod_ctrl_t   *pmc;
   6087     pmc = &pc->phymod_ctrl;
   6088 
   6089     for (idx = 0; idx < pmc->num_phys; idx++) {
   6090         if (pmc->phy[idx] == NULL) {
   6091             return SOC_E_INTERNAL;
   6092         }
   6093         pm_phy = &pmc->phy[idx]->pm_phy;
   6094         if (pm_phy == NULL) {
   6095             return SOC_E_INTERNAL;
   6096         }
   6097         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6098         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6099         if(intf == PHY82381_SYS_SIDE) {
   6100             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   6101         }
   6102 
   6103         SOC_IF_ERROR_RETURN
   6104             (phymod_phy_loopback_set(&pm_phy_copy, phymodLoopbackRemotePMD, value));
   6105     }
   6106     return(SOC_E_NONE);
   6107 }
   6108 
   6109 /*
   6110  * phy_82381_fec_enable_set
   6111  */
   6112 STATIC int
   6113 phy_82381_fec_enable_set(phy_ctrl_t *pc, uint32 value)
   6114 {
   6115     phymod_phy_access_t    *pm_phy;
   6116     int                     idx;
   6117     soc_phymod_ctrl_t   *pmc;
   6118     pmc = &pc->phymod_ctrl;
   6119 
   6120     /* loop through all cores */
   6121     for (idx = 0; idx < pmc->num_phys; idx++) {
   6122         pm_phy = &pmc->phy[idx]->pm_phy;
   6123 
   6124         if (pm_phy == NULL) {
   6125             return SOC_E_INTERNAL;
   6126         }
   6127         SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_set(pm_phy,  value));
   6128     }
   6129     return(SOC_E_NONE);
   6130 }
   6131 
   6132 STATIC int
   6133 phy_82381_sdk_poly_to_phymod_poly(uint32 sdk_poly, phymod_prbs_poly_t *phymod_poly){
   6134     switch(sdk_poly){
   6135     case SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1:
   6136         *phymod_poly = phymodPrbsPoly7;
   6137         break;
   6138     case SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1:
   6139         *phymod_poly = phymodPrbsPoly15;
   6140         break;
   6141     case SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1:
   6142         *phymod_poly = phymodPrbsPoly23;
   6143         break;
   6144     case SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1:
   6145         *phymod_poly = phymodPrbsPoly31;
   6146         break;
   6147     case SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1:
   6148         *phymod_poly = phymodPrbsPoly9;
   6149         break;
   6150     case SOC_PHY_PRBS_POLYNOMIAL_X11_X9_1:
   6151         *phymod_poly = phymodPrbsPoly11;
   6152         break;
   6153     case SOC_PHY_PRBS_POLYNOMIAL_X58_X31_1:
   6154         *phymod_poly = phymodPrbsPoly58;
   6155         break;
   6156     default:
   6157         return SOC_E_INTERNAL;
   6158     }
   6159     return SOC_E_NONE;
   6160 }
   6161 /*
   6162  * phy_82381_per_lane_prbs_tx_poly_set
   6163  */
   6164 STATIC int
   6165 phy_82381_per_lane_prbs_tx_poly_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   6166 {
   6167     phymod_phy_access_t  *pm_phy;
   6168     phymod_prbs_t        prbs;
   6169     uint32_t flags = 0;
   6170     uint32              lane_map;
   6171     phymod_phy_access_t pm_phy_copy;
   6172     soc_phymod_phy_t    *p_phy;
   6173     soc_phymod_ctrl_t   *pmc;
   6174     uint32_t if_side = 0;
   6175     uint32_t chip_id = 0;
   6176     uint32 simplex_tx = 0;
   6177     pmc = &pc->phymod_ctrl;
   6178 
   6179 
   6180     /* locate the desired phy and lane */
   6181     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   6182 
   6183     /* Make a copy of the phy access and overwrite the desired lane */
   6184     pm_phy = &p_phy->pm_phy;
   6185 
   6186     simplex_tx = SIMPLEX_TX(pc);
   6187     chip_id = DEVID(pc);
   6188     SOC_IF_ERROR_RETURN
   6189         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6190 
   6191     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6192     pm_phy_copy.access.lane_mask = lane_map;
   6193     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6194     pm_phy_copy.access.flags |= if_side;
   6195 
   6196     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   6197     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy,  flags, &prbs));
   6198     SOC_IF_ERROR_RETURN(phy_82381_sdk_poly_to_phymod_poly(value, &prbs.poly));
   6199     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   6200     return(SOC_E_NONE);
   6201 }
   6202 
   6203 STATIC int
   6204 _phy_82381_get_intf_side(uint32_t chip_id, int32 intf, uint32 simplex_tx, uint32 tx_rx, uint32_t *if_side)
   6205 {
   6206     *if_side = 0;
   6207     if (FURIA_IS_SIMPLEX(chip_id)) {  /* Simplex package */
   6208         if (tx_rx) { /* Rx side */
   6209             if (!simplex_tx) { /* Simplex Rx package */
   6210                 if (intf == PHY82381_SYS_SIDE) {
   6211                     LOG_CLI((BSL_META_U(0,"No Rx available at SYS SIDE in Simplex Rx package\n")));
   6212                     return SOC_E_UNAVAIL;
   6213                 } else {
   6214                     *if_side |= (1 << INTERFACE_SIDE_SHIFT);
   6215                 }
   6216             } else { /* Simplex Tx package */
   6217                 if (intf == PHY82381_SYS_SIDE) {
   6218                     *if_side |= (1 << INTERFACE_SIDE_SHIFT);
   6219                 } else {
   6220                     LOG_CLI((BSL_META_U(0,"No Rx available at LINE SIDE in Simplex Tx package\n")));
   6221                     return SOC_E_UNAVAIL;
   6222                 }
   6223             }
   6224         } else { /* Tx side */
   6225             if (!simplex_tx) { /* Simplex Rx package */
   6226                 if (intf == PHY82381_SYS_SIDE) {
   6227                     *if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   6228                 } else {
   6229                     LOG_CLI((BSL_META_U(0,"No Tx available at LINE SIDE in Simplex Rx package\n")));
   6230                     return SOC_E_UNAVAIL;
   6231                 }
   6232             } else {  /* Simplex Tx package */
   6233                 if (intf == PHY82381_SYS_SIDE) {
   6234                     LOG_CLI((BSL_META_U(0, "No Tx available at SYS SIDE in Simplex Tx package\n")));
   6235                     return SOC_E_UNAVAIL;
   6236                 } else {
   6237                     *if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   6238                 }
   6239             }
   6240         }
   6241     } else { /* Duplex package */
   6242         if (intf == PHY82381_SYS_SIDE) {
   6243             *if_side |= (1 << INTERFACE_SIDE_SHIFT);
   6244         } else {
   6245             *if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   6246         }
   6247     }
   6248     return(SOC_E_NONE);
   6249 }
   6250 
   6251 /*
   6252  * phy_82381_prbs_tx_poly_set
   6253  */
   6254 STATIC int
   6255 phy_82381_prbs_tx_poly_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6256 {
   6257     phymod_phy_access_t  *pm_phy;
   6258     phymod_prbs_t        prbs;
   6259     uint32_t flags = 0;
   6260     int                    idx;
   6261     uint32_t if_side = 0;
   6262     uint32_t chip_id = 0;
   6263     phymod_phy_access_t pm_phy_copy;
   6264     uint32 simplex_tx = 0;
   6265     soc_phymod_ctrl_t *pmc;
   6266     pmc = &pc->phymod_ctrl;
   6267 
   6268     for (idx = 0; idx < pmc->num_phys; idx++) {
   6269         if (pmc->phy[idx] == NULL) {
   6270             return SOC_E_INTERNAL;
   6271         }
   6272         pm_phy = &pmc->phy[idx]->pm_phy;
   6273         if (pm_phy == NULL) {
   6274             return SOC_E_INTERNAL;
   6275         }
   6276 
   6277         simplex_tx = SIMPLEX_TX(pc);
   6278         chip_id = DEVID(pc);
   6279         SOC_IF_ERROR_RETURN
   6280             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6281 
   6282         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6283 
   6284 
   6285         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6286         pm_phy_copy.access.flags |= if_side;
   6287         PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   6288         SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy,  flags, &prbs));
   6289         SOC_IF_ERROR_RETURN(phy_82381_sdk_poly_to_phymod_poly(value, &prbs.poly));
   6290         SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   6291     }
   6292     return(SOC_E_NONE);
   6293 }
   6294 /*
   6295  * phy_82381_per_lane_prbs_rx_poly_set
   6296  */
   6297 STATIC int
   6298 phy_82381_per_lane_prbs_rx_poly_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   6299 {
   6300     phymod_phy_access_t  *pm_phy;
   6301     phymod_prbs_t        prbs;
   6302     uint32_t flags = 0;
   6303     uint32              lane_map;
   6304     phymod_phy_access_t pm_phy_copy;
   6305     soc_phymod_phy_t    *p_phy;
   6306     uint32_t if_side = 0;
   6307     uint32_t chip_id = 0;
   6308     uint32 simplex_tx = 0;
   6309     soc_phymod_ctrl_t *pmc;
   6310     pmc = &pc->phymod_ctrl;
   6311 
   6312 
   6313     /* locate the desired phy and lane */
   6314     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   6315 
   6316     /* Make a copy of the phy access and overwrite the desired lane */
   6317     pm_phy = &p_phy->pm_phy;
   6318 
   6319     simplex_tx = SIMPLEX_TX(pc);
   6320     chip_id = DEVID(pc);
   6321     SOC_IF_ERROR_RETURN
   6322         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   6323 
   6324     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6325     pm_phy_copy.access.lane_mask = lane_map;
   6326     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6327     pm_phy_copy.access.flags |= if_side;
   6328 
   6329     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   6330     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   6331     SOC_IF_ERROR_RETURN(phy_82381_sdk_poly_to_phymod_poly(value, &prbs.poly));
   6332     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   6333     return(SOC_E_NONE);
   6334 }
   6335 
   6336 /*
   6337  * phy_82381_prbs_rx_poly_set
   6338  */
   6339 STATIC int
   6340 phy_82381_prbs_rx_poly_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6341 {
   6342     phymod_phy_access_t  *pm_phy;
   6343     phymod_prbs_t        prbs;
   6344     uint32_t flags = 0;
   6345     int                    idx;
   6346     phymod_phy_access_t pm_phy_copy;
   6347     uint32_t if_side = 0;
   6348     uint32_t chip_id = 0;
   6349     uint32 simplex_tx = 0;
   6350     soc_phymod_ctrl_t *pmc;
   6351     pmc = &pc->phymod_ctrl;
   6352 
   6353 
   6354     for (idx = 0; idx < pmc->num_phys; idx++) {
   6355         if (pmc->phy[idx] == NULL) {
   6356             return SOC_E_INTERNAL;
   6357         }
   6358         pm_phy = &pmc->phy[idx]->pm_phy;
   6359         if (pm_phy == NULL) {
   6360             return SOC_E_INTERNAL;
   6361         }
   6362 
   6363         simplex_tx = SIMPLEX_TX(pc);
   6364         chip_id = DEVID(pc);
   6365         SOC_IF_ERROR_RETURN
   6366             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   6367 
   6368         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6369         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6370         pm_phy_copy.access.flags |= if_side;
   6371         PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   6372         SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   6373         SOC_IF_ERROR_RETURN(phy_82381_sdk_poly_to_phymod_poly(value, &prbs.poly));
   6374         SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   6375     }
   6376     return(SOC_E_NONE);
   6377 }
   6378 
   6379 
   6380 /*
   6381  * phy_82381_per_lane_prbs_tx_invert_data_set
   6382  */
   6383 STATIC int
   6384 phy_82381_per_lane_prbs_tx_invert_data_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   6385 {
   6386     phymod_phy_access_t  *pm_phy;
   6387     phymod_prbs_t        prbs;
   6388     uint32_t flags = 0;
   6389 
   6390     uint32              lane_map;
   6391     phymod_phy_access_t pm_phy_copy;
   6392     soc_phymod_phy_t    *p_phy;
   6393     uint32_t if_side = 0;
   6394     uint32_t chip_id = 0;
   6395     uint32 simplex_tx = 0;
   6396     soc_phymod_ctrl_t *pmc;
   6397     pmc = &pc->phymod_ctrl;
   6398 
   6399 
   6400     /* locate the desired phy and lane */
   6401     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   6402 
   6403     /* Make a copy of the phy access and overwrite the desired lane */
   6404     pm_phy = &p_phy->pm_phy;
   6405 
   6406     simplex_tx = SIMPLEX_TX(pc);
   6407     chip_id = DEVID(pc);
   6408     SOC_IF_ERROR_RETURN
   6409         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6410 
   6411     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6412     pm_phy_copy.access.lane_mask = lane_map;
   6413     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6414     pm_phy_copy.access.flags |= if_side;
   6415     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   6416     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   6417     prbs.invert = value;
   6418     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags,  &prbs));
   6419     return(SOC_E_NONE);
   6420 }
   6421 
   6422 /*
   6423  * phy_82381_prbs_tx_invert_data_set
   6424  */
   6425 STATIC int
   6426 phy_82381_prbs_tx_invert_data_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6427 {
   6428     phymod_phy_access_t  *pm_phy;
   6429     phymod_prbs_t        prbs;
   6430     uint32_t flags = 0;
   6431     int                    idx;
   6432     phymod_phy_access_t pm_phy_copy;
   6433     uint32_t if_side = 0;
   6434     uint32_t chip_id = 0;
   6435     uint32 simplex_tx = 0;
   6436     soc_phymod_ctrl_t *pmc;
   6437     pmc = &pc->phymod_ctrl;
   6438 
   6439     for (idx = 0; idx < pmc->num_phys; idx++) {
   6440         if (pmc->phy[idx] == NULL) {
   6441             return SOC_E_INTERNAL;
   6442         }
   6443         pm_phy = &pmc->phy[idx]->pm_phy;
   6444         if (pm_phy == NULL) {
   6445             return SOC_E_INTERNAL;
   6446         }
   6447 
   6448         simplex_tx = SIMPLEX_TX(pc);
   6449         chip_id = DEVID(pc);
   6450         SOC_IF_ERROR_RETURN
   6451             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6452 
   6453         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6454         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6455         pm_phy_copy.access.flags |= if_side;
   6456         PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   6457         SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags, &prbs));
   6458         prbs.invert = value;
   6459         SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags,  &prbs));
   6460     }
   6461     return(SOC_E_NONE);
   6462 }
   6463 
   6464 /*
   6465  * phy_82381_per_lane_prbs_rx_invert_data_set
   6466  */
   6467 STATIC int
   6468 phy_82381_per_lane_prbs_rx_invert_data_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   6469 {
   6470     phymod_phy_access_t  *pm_phy;
   6471     phymod_prbs_t        prbs;
   6472     uint32_t flags = 0;
   6473     uint32              lane_map;
   6474     phymod_phy_access_t pm_phy_copy;
   6475     soc_phymod_phy_t    *p_phy;
   6476     uint32_t if_side = 0;
   6477     uint32_t chip_id = 0;
   6478     uint32 simplex_tx = 0;
   6479     soc_phymod_ctrl_t *pmc;
   6480     pmc = &pc->phymod_ctrl;
   6481 
   6482     /* locate the desired phy and lane */
   6483     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   6484 
   6485     /* Make a copy of the phy access and overwrite the desired lane */
   6486     pm_phy = &p_phy->pm_phy;
   6487     simplex_tx = SIMPLEX_TX(pc);
   6488     chip_id = DEVID(pc);
   6489     SOC_IF_ERROR_RETURN
   6490         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   6491     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6492     pm_phy_copy.access.lane_mask = lane_map;
   6493     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6494     pm_phy_copy.access.flags |= if_side;
   6495 
   6496     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   6497     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags,  &prbs));
   6498     prbs.invert = value;
   6499     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   6500     return(SOC_E_NONE);
   6501 }
   6502 /*
   6503  * phy_82381_prbs_rx_invert_data_set
   6504  */
   6505 STATIC int
   6506 phy_82381_prbs_rx_invert_data_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6507 {
   6508     phymod_phy_access_t  *pm_phy;
   6509     phymod_prbs_t        prbs;
   6510     uint32_t flags = 0;
   6511     int                    idx;
   6512     phymod_phy_access_t pm_phy_copy;
   6513     uint32_t if_side = 0;
   6514     uint32_t chip_id = 0;
   6515     uint32 simplex_tx = 0;
   6516     soc_phymod_ctrl_t *pmc;
   6517     pmc = &pc->phymod_ctrl;
   6518 
   6519 
   6520     for (idx = 0; idx < pmc->num_phys; idx++) {
   6521         if (pmc->phy[idx] == NULL) {
   6522             return SOC_E_INTERNAL;
   6523         }
   6524         pm_phy = &pmc->phy[idx]->pm_phy;
   6525         if (pm_phy == NULL) {
   6526             return SOC_E_INTERNAL;
   6527         }
   6528         simplex_tx = SIMPLEX_TX(pc);
   6529         chip_id = DEVID(pc);
   6530         SOC_IF_ERROR_RETURN
   6531             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   6532 
   6533         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6534         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6535         pm_phy_copy.access.flags |= if_side;
   6536         PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   6537         SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(&pm_phy_copy, flags,  &prbs));
   6538         prbs.invert = value;
   6539         SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(&pm_phy_copy, flags, &prbs));
   6540     }
   6541     return(SOC_E_NONE);
   6542 }
   6543 
   6544 /*
   6545  * phy_82381_per_lane_prbs_tx_enable_set
   6546  */
   6547 STATIC int
   6548 phy_82381_per_lane_prbs_tx_enable_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   6549 {
   6550     phymod_phy_access_t  *pm_phy;
   6551     uint32_t flags = 0;
   6552     uint32              lane_map;
   6553     phymod_phy_access_t pm_phy_copy;
   6554     soc_phymod_phy_t    *p_phy;
   6555     uint32_t if_side = 0;
   6556     uint32_t chip_id = 0;
   6557     uint32 simplex_tx = 0;
   6558     soc_phymod_ctrl_t *pmc;
   6559     pmc = &pc->phymod_ctrl;
   6560 
   6561     /* locate the desired phy and lane */
   6562     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   6563 
   6564     /* Make a copy of the phy access and overwrite the desired lane */
   6565     pm_phy = &p_phy->pm_phy;
   6566 
   6567     simplex_tx = SIMPLEX_TX(pc);
   6568     chip_id = DEVID(pc);
   6569     SOC_IF_ERROR_RETURN
   6570         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6571 
   6572     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6573     pm_phy_copy.access.lane_mask = lane_map;
   6574     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6575     pm_phy_copy.access.flags |= if_side;
   6576 
   6577     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   6578     SOC_IF_ERROR_RETURN(
   6579             phymod_phy_prbs_enable_set(&pm_phy_copy, flags, value));
   6580     return(SOC_E_NONE);
   6581 }
   6582 /*
   6583  * phy_82381_prbs_tx_enable_set
   6584  */
   6585 STATIC int
   6586 phy_82381_prbs_tx_enable_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6587 {
   6588     phymod_phy_access_t  *pm_phy;
   6589     uint32_t flags = 0;
   6590     int                    idx;
   6591     phymod_phy_access_t pm_phy_copy;
   6592     uint32_t if_side = 0;
   6593     uint32_t chip_id = 0;
   6594     uint32 simplex_tx = 0;
   6595     soc_phymod_ctrl_t *pmc;
   6596     pmc = &pc->phymod_ctrl;
   6597 
   6598 
   6599     for (idx = 0; idx < pmc->num_phys; idx++) {
   6600         if (pmc->phy[idx] == NULL) {
   6601             return SOC_E_INTERNAL;
   6602         }
   6603         pm_phy = &pmc->phy[idx]->pm_phy;
   6604         if (pm_phy == NULL) {
   6605             return SOC_E_INTERNAL;
   6606         }
   6607         simplex_tx = SIMPLEX_TX(pc);
   6608         chip_id = DEVID(pc);
   6609         SOC_IF_ERROR_RETURN
   6610             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6611 
   6612         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6613         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6614         pm_phy_copy.access.flags |= if_side;
   6615         PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   6616         SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(&pm_phy_copy, flags, value));
   6617     }
   6618     return(SOC_E_NONE);
   6619 }
   6620 
   6621 /*
   6622  * phy_82381_per_lane_prbs_rx_enable_set
   6623  */
   6624 STATIC int
   6625 phy_82381_per_lane_prbs_rx_enable_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   6626 {
   6627     phymod_phy_access_t  *pm_phy;
   6628     uint32_t flags = 0;
   6629 
   6630     uint32              lane_map;
   6631     phymod_phy_access_t pm_phy_copy;
   6632     soc_phymod_phy_t    *p_phy;
   6633     uint32_t if_side = 0;
   6634     uint32_t chip_id = 0;
   6635     uint32 simplex_tx = 0;
   6636     soc_phymod_ctrl_t *pmc;
   6637     pmc = &pc->phymod_ctrl;
   6638 
   6639 
   6640     /* locate the desired phy and lane */
   6641     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   6642 
   6643     /* Make a copy of the phy access and overwrite the desired lane */
   6644     pm_phy = &p_phy->pm_phy;
   6645 
   6646     simplex_tx = SIMPLEX_TX(pc);
   6647     chip_id = DEVID(pc);
   6648     SOC_IF_ERROR_RETURN
   6649         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   6650 
   6651     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6652     pm_phy_copy.access.lane_mask = lane_map;
   6653     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6654     pm_phy_copy.access.flags |= if_side;
   6655     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   6656     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(&pm_phy_copy, flags,  value));
   6657     return(SOC_E_NONE);
   6658 }
   6659 /*
   6660  * phy_82381_prbs_rx_enable_set
   6661  */
   6662 STATIC int
   6663 phy_82381_prbs_rx_enable_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6664 {
   6665     phymod_phy_access_t  *pm_phy;
   6666     uint32_t flags = 0;
   6667     int                    idx;
   6668     phymod_phy_access_t pm_phy_copy;
   6669     uint32_t if_side = 0;
   6670     uint32_t chip_id = 0;
   6671     uint32 simplex_tx = 0;
   6672     soc_phymod_ctrl_t *pmc;
   6673     pmc = &pc->phymod_ctrl;
   6674 
   6675 
   6676     for (idx = 0; idx < pmc->num_phys; idx++) {
   6677         if (pmc->phy[idx] == NULL) {
   6678             return SOC_E_INTERNAL;
   6679         }
   6680         pm_phy = &pmc->phy[idx]->pm_phy;
   6681         if (pm_phy == NULL) {
   6682             return SOC_E_INTERNAL;
   6683         }
   6684 
   6685         simplex_tx = SIMPLEX_TX(pc);
   6686         chip_id = DEVID(pc);
   6687         SOC_IF_ERROR_RETURN
   6688             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   6689 
   6690         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6691         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6692         pm_phy_copy.access.flags |= if_side;
   6693         PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   6694         SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(&pm_phy_copy, flags,  value));
   6695     }
   6696     return(SOC_E_NONE);
   6697 }
   6698 
   6699 
   6700 /*
   6701  * given a pc (phymod_ctrl_t) and logical lane number,
   6702  *    find the correct soc_phymod_phy_t object and lane
   6703  */
   6704 STATIC int
   6705 _phy_82381_find_soc_phy_lane(soc_phymod_ctrl_t *pmc, uint32_t lane,
   6706                         soc_phymod_phy_t **p_phy, uint32 *lane_map)
   6707 {
   6708     phymod_phy_access_t *pm_phy;
   6709     int idx, lnx, ln_cnt, found;
   6710     uint32 lane_map_copy;
   6711     uint32 chip_id = 0;
   6712     int num_lanes = 0;
   6713     /* Traverse lanes belonging to this port */
   6714     found = 0;
   6715     ln_cnt = 0;
   6716     for (idx = 0; idx < pmc->num_phys; idx++) {
   6717         pm_phy = &pmc->phy[idx]->pm_phy;
   6718         if (pm_phy == NULL) {
   6719             return SOC_E_INTERNAL;
   6720         }
   6721         lane_map_copy = pm_phy->access.lane_mask;
   6722         SOC_IF_ERROR_RETURN(
   6723              _phy_82381_chip_id_get(pm_phy, &chip_id));
   6724         if(FURIA_IS_SIMPLEX(chip_id)){
   6725             if (chip_id == FURIA_ID_82212) {
   6726                 num_lanes = 12;
   6727             } else {
   6728                 num_lanes = 8;
   6729             }
   6730         } else {
   6731            num_lanes = 4;
   6732         }
   6733         for (lnx = 0; lnx < num_lanes; lnx++) {
   6734             if ((1 << lnx) & lane_map_copy) {
   6735                 if ((ln_cnt == lane) || (lane == 0)) {
   6736                     found = 1;
   6737                     break;
   6738                 }
   6739                 ln_cnt++;
   6740             }
   6741         }
   6742         if (found) {
   6743             *p_phy = pmc->phy[idx];
   6744             *lane_map = (1 << lnx);
   6745             break;
   6746         }
   6747     }
   6748 
   6749     if (!found) {
   6750         LOG_CLI((BSL_META_U(pmc->unit,"\nInvalid lane \n")));
   6751         /* No such lane */
   6752         return SOC_E_PARAM;
   6753     }
   6754     return (SOC_E_NONE);
   6755 }
   6756 
   6757 /*
   6758  * phy_82381_per_lane_preemphasis_set
   6759  */
   6760 STATIC int
   6761 phy_82381_per_lane_preemphasis_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   6762 {
   6763     soc_phymod_phy_t    *p_phy;
   6764     uint32              lane_map;
   6765     phymod_phy_access_t pm_phy_copy, *pm_phy;
   6766     phymod_tx_t         phymod_tx;
   6767     uint32_t if_side = 0;
   6768     uint32_t chip_id = 0;
   6769     uint32 simplex_tx = 0;
   6770     soc_phymod_ctrl_t *pmc;
   6771     pmc = &pc->phymod_ctrl;
   6772 
   6773     /* locate the desired phy and lane */
   6774     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   6775 
   6776     /* Make a copy of the phy access and overwrite the desired lane */
   6777     pm_phy = &p_phy->pm_phy;
   6778 
   6779     simplex_tx = SIMPLEX_TX(pc);
   6780     chip_id = DEVID(pc);
   6781     SOC_IF_ERROR_RETURN
   6782         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6783     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6784     pm_phy_copy.access.lane_mask = lane_map;
   6785     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6786     pm_phy_copy.access.flags |= if_side;
   6787 
   6788     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   6789     phymod_tx.pre = (value & 0xff);
   6790     phymod_tx.main = (value & 0xff00) >> 8;
   6791     phymod_tx.post = (value & 0xff0000) >> 16;
   6792     SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   6793 
   6794     return(SOC_E_NONE);
   6795 }
   6796 
   6797 /*
   6798  * phy_82381_preemphasis_set
   6799  */
   6800 STATIC int
   6801 phy_82381_preemphasis_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6802 {
   6803     phymod_phy_access_t *pm_phy;
   6804     phymod_tx_t         phymod_tx;
   6805     int                 idx;
   6806     phymod_phy_access_t pm_phy_copy;
   6807     uint32_t if_side = 0;
   6808     uint32_t chip_id = 0;
   6809     uint32 simplex_tx = 0;
   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         simplex_tx = SIMPLEX_TX(pc);
   6821         chip_id = DEVID(pc);
   6822         SOC_IF_ERROR_RETURN
   6823             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6824 
   6825         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6826         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6827         pm_phy_copy.access.flags |= if_side;
   6828         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   6829         phymod_tx.pre = (value & 0xff);
   6830         phymod_tx.main = (value & 0xff00) >> 8;
   6831         phymod_tx.post = (value & 0xff0000) >> 16;
   6832 
   6833         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   6834 
   6835     }
   6836 
   6837     return(SOC_E_NONE);
   6838 }
   6839 
   6840 /*
   6841  * phy_82381_tx_fir_pre_set
   6842  */
   6843 STATIC int
   6844 phy_82381_tx_fir_pre_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6845 {
   6846     phymod_phy_access_t *pm_phy;
   6847     phymod_tx_t         phymod_tx;
   6848     int                 idx;
   6849     phymod_phy_access_t pm_phy_copy;
   6850     uint32_t if_side = 0;
   6851     uint32_t chip_id = 0;
   6852     uint32 simplex_tx = 0;
   6853     soc_phymod_ctrl_t *pmc;
   6854     pmc = &pc->phymod_ctrl;
   6855 
   6856 
   6857     /* loop through all cores */
   6858     for (idx = 0; idx < pmc->num_phys; idx++) {
   6859         pm_phy = &pmc->phy[idx]->pm_phy;
   6860 
   6861         if (pm_phy == NULL) {
   6862             return SOC_E_INTERNAL;
   6863         }
   6864         simplex_tx = SIMPLEX_TX(pc);
   6865         chip_id = DEVID(pc);
   6866         SOC_IF_ERROR_RETURN
   6867             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6868 
   6869         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6870         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6871         pm_phy_copy.access.flags |= if_side;
   6872 
   6873         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   6874         phymod_tx.pre = value;
   6875         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   6876     }
   6877 
   6878     return(SOC_E_NONE);
   6879 }
   6880 
   6881 /*
   6882  * phy_82381_tx_fir_main_set
   6883  */
   6884 STATIC int
   6885 phy_82381_tx_fir_main_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6886 {
   6887     phymod_phy_access_t *pm_phy;
   6888     phymod_tx_t         phymod_tx;
   6889     int                 idx;
   6890     phymod_phy_access_t pm_phy_copy;
   6891     uint32_t if_side = 0;
   6892     uint32_t chip_id = 0;
   6893     uint32 simplex_tx = 0;
   6894     soc_phymod_ctrl_t *pmc;
   6895     pmc = &pc->phymod_ctrl;
   6896 
   6897     /* loop through all cores */
   6898     for (idx = 0; idx < pmc->num_phys; idx++) {
   6899         pm_phy = &pmc->phy[idx]->pm_phy;
   6900 
   6901         if (pm_phy == NULL) {
   6902             return SOC_E_INTERNAL;
   6903         }
   6904         simplex_tx = SIMPLEX_TX(pc);
   6905         chip_id = DEVID(pc);
   6906         SOC_IF_ERROR_RETURN
   6907             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6908 
   6909         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6910         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6911         pm_phy_copy.access.flags |= if_side;
   6912 
   6913         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   6914         phymod_tx.main = value;
   6915         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   6916     }
   6917 
   6918     return(SOC_E_NONE);
   6919 }
   6920 
   6921 /*
   6922  * phy_82381_tx_fir_post_set
   6923  */
   6924 STATIC int
   6925 phy_82381_tx_fir_post_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6926 {
   6927     phymod_phy_access_t *pm_phy;
   6928     phymod_tx_t         phymod_tx;
   6929     int                 idx;
   6930     phymod_phy_access_t pm_phy_copy;
   6931     uint32_t if_side = 0;
   6932     uint32_t chip_id = 0;
   6933     uint32 simplex_tx = 0;
   6934     soc_phymod_ctrl_t *pmc;
   6935     pmc = &pc->phymod_ctrl;
   6936 
   6937 
   6938     /* loop through all cores */
   6939     for (idx = 0; idx < pmc->num_phys; idx++) {
   6940         pm_phy = &pmc->phy[idx]->pm_phy;
   6941 
   6942         if (pm_phy == NULL) {
   6943             return SOC_E_INTERNAL;
   6944         }
   6945 
   6946         simplex_tx = SIMPLEX_TX(pc);
   6947         chip_id = DEVID(pc);
   6948         SOC_IF_ERROR_RETURN
   6949             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6950 
   6951         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6952         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6953         pm_phy_copy.access.flags |= if_side;
   6954 
   6955         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   6956         phymod_tx.post = value;
   6957         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   6958     }
   6959 
   6960     return(SOC_E_NONE);
   6961 }
   6962 
   6963 /*
   6964  * phy_82381_tx_fir_post2_set
   6965  */
   6966 STATIC int
   6967 phy_82381_tx_fir_post2_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   6968 {
   6969     phymod_phy_access_t *pm_phy;
   6970     phymod_tx_t         phymod_tx;
   6971     int                 idx;
   6972     phymod_phy_access_t pm_phy_copy;
   6973     uint32_t if_side = 0;
   6974     uint32_t chip_id = 0;
   6975     uint32 simplex_tx = 0;
   6976     soc_phymod_ctrl_t *pmc;
   6977     pmc = &pc->phymod_ctrl;
   6978 
   6979 
   6980     /* loop through all cores */
   6981     for (idx = 0; idx < pmc->num_phys; idx++) {
   6982         pm_phy = &pmc->phy[idx]->pm_phy;
   6983 
   6984         if (pm_phy == NULL) {
   6985             return SOC_E_INTERNAL;
   6986         }
   6987         simplex_tx = SIMPLEX_TX(pc);
   6988         chip_id = DEVID(pc);
   6989         SOC_IF_ERROR_RETURN
   6990             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   6991 
   6992         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   6993         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   6994         pm_phy_copy.access.flags |= if_side;
   6995 
   6996         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   6997         phymod_tx.post2 = value;
   6998         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   6999     }
   7000 
   7001     return(SOC_E_NONE);
   7002 }
   7003 
   7004 /*
   7005  * phy_82381_tx_fir_post3_set
   7006  */
   7007 STATIC int
   7008 phy_82381_tx_fir_post3_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   7009 {
   7010     phymod_phy_access_t *pm_phy;
   7011     phymod_tx_t         phymod_tx;
   7012     int                 idx;
   7013     phymod_phy_access_t pm_phy_copy;
   7014     uint32_t if_side = 0;
   7015     uint32_t chip_id = 0;
   7016     uint32 simplex_tx = 0;
   7017     soc_phymod_ctrl_t *pmc;
   7018     pmc = &pc->phymod_ctrl;
   7019 
   7020 
   7021     /* loop through all cores */
   7022     for (idx = 0; idx < pmc->num_phys; idx++) {
   7023         pm_phy = &pmc->phy[idx]->pm_phy;
   7024 
   7025         if (pm_phy == NULL) {
   7026             return SOC_E_INTERNAL;
   7027         }
   7028 
   7029         simplex_tx = SIMPLEX_TX(pc);
   7030         chip_id = DEVID(pc);
   7031         SOC_IF_ERROR_RETURN
   7032             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7033 
   7034         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7035         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7036         pm_phy_copy.access.flags |= if_side;
   7037 
   7038         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   7039         phymod_tx.post3 = value;
   7040         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   7041     }
   7042 
   7043     return(SOC_E_NONE);
   7044 }
   7045 
   7046 
   7047 /*
   7048  * phy_82381_per_lane_driver_current_set
   7049  */
   7050 STATIC int
   7051 phy_82381_per_lane_driver_current_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   7052 {
   7053     soc_phymod_phy_t    *p_phy;
   7054     uint32              lane_map;
   7055     phymod_phy_access_t pm_phy_copy, *pm_phy;
   7056     phymod_tx_t         phymod_tx;
   7057     uint32_t if_side = 0;
   7058     uint32_t chip_id = 0;
   7059     uint32 simplex_tx = 0;
   7060     soc_phymod_ctrl_t *pmc;
   7061     pmc = &pc->phymod_ctrl;
   7062 
   7063     /* locate the desired phy and lane */
   7064     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7065 
   7066     /* Make a copy of the phy access and overwrite the desired lane */
   7067     pm_phy = &p_phy->pm_phy;
   7068 
   7069     simplex_tx = SIMPLEX_TX(pc);
   7070     chip_id = DEVID(pc);
   7071     SOC_IF_ERROR_RETURN
   7072         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7073     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7074     pm_phy_copy.access.lane_mask = lane_map;
   7075     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7076     pm_phy_copy.access.flags |= if_side;
   7077 
   7078     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   7079     phymod_tx.amp = value;
   7080     SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   7081 
   7082     return(SOC_E_NONE);
   7083 }
   7084 
   7085 /*
   7086  * phy_82381_driver_current_set
   7087  */
   7088 STATIC int
   7089 phy_82381_driver_current_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   7090 {
   7091     phymod_phy_access_t *pm_phy;
   7092     phymod_tx_t         phymod_tx;
   7093     int                 idx;
   7094     phymod_phy_access_t pm_phy_copy;
   7095     uint32_t if_side = 0;
   7096     uint32_t chip_id = 0;
   7097     uint32 simplex_tx = 0;
   7098     soc_phymod_ctrl_t *pmc;
   7099     pmc = &pc->phymod_ctrl;
   7100 
   7101     /* loop through all cores */
   7102     for (idx = 0; idx < pmc->num_phys; idx++) {
   7103         pm_phy = &pmc->phy[idx]->pm_phy;
   7104 
   7105         if (pm_phy == NULL) {
   7106             return SOC_E_INTERNAL;
   7107         }
   7108         simplex_tx = SIMPLEX_TX(pc);
   7109         chip_id = DEVID(pc);
   7110         SOC_IF_ERROR_RETURN
   7111             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7112         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7113         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7114         pm_phy_copy.access.flags |= if_side;
   7115 
   7116         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   7117         phymod_tx.amp = value;
   7118         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   7119     }
   7120 
   7121     return(SOC_E_NONE);
   7122 }
   7123 
   7124 /*
   7125  * phy_82381_per_lane_rx_dfe_tap_control_set
   7126  */
   7127 STATIC int
   7128 phy_82381_per_lane_rx_dfe_tap_control_set(phy_ctrl_t *pc, int32 intf, int lane, int tap, int enable, uint32 value)
   7129 {
   7130     soc_phymod_phy_t    *p_phy;
   7131     uint32              lane_map;
   7132     phymod_phy_access_t pm_phy_copy, *pm_phy;
   7133     phymod_rx_t          phymod_rx;
   7134     uint32_t if_side = 0;
   7135     uint32_t chip_id = 0;
   7136     uint32 simplex_tx = 0;
   7137     soc_phymod_ctrl_t *pmc;
   7138     pmc = &pc->phymod_ctrl;
   7139 
   7140 
   7141     /* locate the desired phy and lane */
   7142     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7143 
   7144     /* Make a copy of the phy access and overwrite the desired lane */
   7145     pm_phy = &p_phy->pm_phy;
   7146     simplex_tx = SIMPLEX_TX(pc);
   7147     chip_id = DEVID(pc);
   7148     SOC_IF_ERROR_RETURN
   7149         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7150 
   7151     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7152     pm_phy_copy.access.lane_mask = lane_map;
   7153     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7154     pm_phy_copy.access.flags |= if_side;
   7155 
   7156     if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) {
   7157         /* this can only happen with a coding error */
   7158         return SOC_E_INTERNAL;
   7159     }
   7160     sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   7161     phymod_rx.dfe[tap].enable = enable;
   7162     phymod_rx.dfe[tap].value = value;
   7163     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   7164     if (!enable) {
   7165         SOC_IF_ERROR_RETURN(phymod_phy_rx_adaptation_resume(&pm_phy_copy));
   7166     }
   7167 
   7168     return(SOC_E_NONE);
   7169 }
   7170 /*
   7171  * phy_82381_per_lane_tx_lane_squelch
   7172  */
   7173 STATIC int
   7174 phy_82381_per_lane_tx_lane_squelch(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   7175 {
   7176     phymod_phy_access_t *pm_phy;
   7177     phymod_phy_tx_lane_control_t  tx_control;
   7178     int                 idx;
   7179     phymod_phy_access_t pm_phy_copy;
   7180     soc_phymod_phy_t    *p_phy;
   7181     uint32              lane_map;
   7182     uint32_t if_side = 0;
   7183     uint32_t chip_id = 0;
   7184     uint32 simplex_tx = 0;
   7185     soc_phymod_ctrl_t *pmc;
   7186     pmc = &pc->phymod_ctrl;
   7187 
   7188 
   7189     /* locate the desired phy and lane */
   7190     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7191 
   7192     /* loop through all cores */
   7193     for (idx = 0; idx < pmc->num_phys; idx++) {
   7194         pm_phy = &pmc->phy[idx]->pm_phy;
   7195 
   7196         if (pm_phy == NULL) {
   7197             return SOC_E_INTERNAL;
   7198         }
   7199 
   7200         simplex_tx = SIMPLEX_TX(pc);
   7201         chip_id = DEVID(pc);
   7202         SOC_IF_ERROR_RETURN
   7203             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7204 
   7205         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7206         pm_phy_copy.access.lane_mask = lane_map;
   7207         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7208         pm_phy_copy.access.flags |= if_side;
   7209 
   7210         if (value == 1) {
   7211             tx_control = phymodTxSquelchOn;
   7212         } else {
   7213             tx_control = phymodTxSquelchOff;
   7214         }
   7215         SOC_IF_ERROR_RETURN
   7216             (phymod_phy_tx_lane_control_set(&pm_phy_copy, tx_control));
   7217 
   7218     }
   7219     return(SOC_E_NONE);
   7220 }
   7221 
   7222 STATIC int
   7223 phy_82381_per_lane_tx_lane_squelch_get(phy_ctrl_t *pc, int32 intf, int lane, uint32 *value)
   7224 {
   7225     phymod_phy_access_t *pm_phy;
   7226     phymod_phy_tx_lane_control_t  tx_control;
   7227     int                 idx;
   7228     phymod_phy_access_t pm_phy_copy;
   7229     soc_phymod_phy_t    *p_phy;
   7230     uint32              lane_map;
   7231     uint32_t if_side = 0;
   7232     uint32_t chip_id = 0;
   7233     uint32 simplex_tx = 0;
   7234     soc_phymod_ctrl_t *pmc;
   7235     pmc = &pc->phymod_ctrl;
   7236 
   7237 
   7238     /* locate the desired phy and lane */
   7239     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7240 
   7241     /* loop through all cores */
   7242     for (idx = 0; idx < pmc->num_phys; idx++) {
   7243         pm_phy = &pmc->phy[idx]->pm_phy;
   7244 
   7245         if (pm_phy == NULL) {
   7246             return SOC_E_INTERNAL;
   7247         }
   7248         simplex_tx = SIMPLEX_TX(pc);
   7249         chip_id = DEVID(pc);
   7250         SOC_IF_ERROR_RETURN
   7251             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7252 
   7253         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7254         pm_phy_copy.access.lane_mask = lane_map;
   7255         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7256         pm_phy_copy.access.flags |= if_side;
   7257 
   7258         tx_control = phymodTxSquelchOn;
   7259         SOC_IF_ERROR_RETURN
   7260             (phymod_phy_tx_lane_control_get(&pm_phy_copy, &tx_control));
   7261         *value = tx_control;
   7262     }
   7263     return(SOC_E_NONE);
   7264 }
   7265 
   7266 /*
   7267  * phy_82381_tx_lane_squelch
   7268  */
   7269 STATIC int
   7270 phy_82381_tx_lane_squelch(phy_ctrl_t *pc, int32 intf, uint32 value)
   7271 {
   7272     phymod_phy_access_t *pm_phy;
   7273     phymod_phy_tx_lane_control_t  tx_control;
   7274     int                 idx;
   7275     phymod_phy_access_t pm_phy_copy;
   7276     uint32_t if_side = 0;
   7277     uint32_t chip_id = 0;
   7278     uint32 simplex_tx = 0;
   7279     soc_phymod_ctrl_t *pmc;
   7280     pmc = &pc->phymod_ctrl;
   7281 
   7282     /* loop through all cores */
   7283     for (idx = 0; idx < pmc->num_phys; idx++) {
   7284         pm_phy = &pmc->phy[idx]->pm_phy;
   7285 
   7286         if (pm_phy == NULL) {
   7287             return SOC_E_INTERNAL;
   7288         }
   7289 
   7290         simplex_tx = SIMPLEX_TX(pc);
   7291         chip_id = DEVID(pc);
   7292         SOC_IF_ERROR_RETURN
   7293             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7294         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7295         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7296         pm_phy_copy.access.flags |= if_side;
   7297 
   7298         if (value == 1) {
   7299             tx_control = phymodTxSquelchOn;
   7300         } else {
   7301             tx_control = phymodTxSquelchOff;
   7302         }
   7303         SOC_IF_ERROR_RETURN
   7304             (phymod_phy_tx_lane_control_set(&pm_phy_copy, tx_control));
   7305 
   7306     }
   7307     return(SOC_E_NONE);
   7308 }
   7309 
   7310 /*
   7311  * phy_82381_tx_lane_squelch_get
   7312  */
   7313 STATIC int
   7314 phy_82381_tx_lane_squelch_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   7315 {
   7316     phymod_phy_access_t *pm_phy;
   7317     phymod_phy_tx_lane_control_t  tx_control;
   7318     int                 idx;
   7319     phymod_phy_access_t pm_phy_copy;
   7320     uint32_t if_side = 0;
   7321     uint32_t chip_id = 0;
   7322     uint32 simplex_tx = 0;
   7323     soc_phymod_ctrl_t *pmc;
   7324     pmc = &pc->phymod_ctrl;
   7325 
   7326     /* loop through all cores */
   7327     for (idx = 0; idx < pmc->num_phys; idx++) {
   7328         pm_phy = &pmc->phy[idx]->pm_phy;
   7329 
   7330         if (pm_phy == NULL) {
   7331             return SOC_E_INTERNAL;
   7332         }
   7333         simplex_tx = SIMPLEX_TX(pc);
   7334         chip_id = DEVID(pc);
   7335         SOC_IF_ERROR_RETURN
   7336             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7337         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7338         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7339         pm_phy_copy.access.flags |= if_side;
   7340         tx_control = phymodTxSquelchOn;
   7341         SOC_IF_ERROR_RETURN
   7342             (phymod_phy_tx_lane_control_get(&pm_phy_copy, &tx_control));
   7343         *value = tx_control;
   7344     }
   7345     return(SOC_E_NONE);
   7346 }
   7347 
   7348 /*
   7349  * phy_82381_per_lane_rx_peak_filter_set
   7350  */
   7351 STATIC int
   7352 phy_82381_per_lane_rx_peak_filter_set(phy_ctrl_t *pc, int32 intf, int lane, int enable, uint32 value)
   7353 {
   7354     soc_phymod_phy_t    *p_phy;
   7355     uint32              lane_map;
   7356     phymod_phy_access_t pm_phy_copy, *pm_phy;
   7357     phymod_rx_t         phymod_rx;
   7358     uint32_t if_side = 0;
   7359     uint32_t chip_id = 0;
   7360     uint32 simplex_tx = 0;
   7361     soc_phymod_ctrl_t *pmc;
   7362     pmc = &pc->phymod_ctrl;
   7363 
   7364     /* locate the desired phy and lane */
   7365     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7366 
   7367     /* Make a copy of the phy access and overwrite the desired lane */
   7368     pm_phy = &p_phy->pm_phy;
   7369 
   7370     simplex_tx = SIMPLEX_TX(pc);
   7371     chip_id = DEVID(pc);
   7372     SOC_IF_ERROR_RETURN
   7373         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7374 
   7375     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7376     pm_phy_copy.access.lane_mask = lane_map;
   7377     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7378     pm_phy_copy.access.flags |= if_side;
   7379     sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   7380     phymod_rx.peaking_filter.enable = TRUE;
   7381     phymod_rx.peaking_filter.value = value;
   7382     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   7383 
   7384     return(SOC_E_NONE);
   7385 }
   7386 
   7387 /*
   7388  * phy_82381_rx_peak_filter_set
   7389  */
   7390 STATIC int
   7391 phy_82381_rx_peak_filter_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   7392 {
   7393     phymod_phy_access_t *pm_phy;
   7394     phymod_rx_t         phymod_rx;
   7395     int                 idx;
   7396     phymod_phy_access_t pm_phy_copy;
   7397     uint32_t if_side = 0;
   7398     uint32_t chip_id = 0;
   7399     uint32 simplex_tx = 0;
   7400     soc_phymod_ctrl_t *pmc;
   7401     pmc = &pc->phymod_ctrl;
   7402 
   7403 
   7404     /* loop through all cores */
   7405     for (idx = 0; idx < pmc->num_phys; idx++) {
   7406         pm_phy = &pmc->phy[idx]->pm_phy;
   7407 
   7408         if (pm_phy == NULL) {
   7409             return SOC_E_INTERNAL;
   7410         }
   7411 
   7412         simplex_tx = SIMPLEX_TX(pc);
   7413         chip_id = DEVID(pc);
   7414         SOC_IF_ERROR_RETURN
   7415             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7416 
   7417         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7418         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7419         pm_phy_copy.access.flags |= if_side;
   7420 
   7421         sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   7422         phymod_rx.peaking_filter.enable = TRUE;
   7423         phymod_rx.peaking_filter.value = value;
   7424         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   7425     }
   7426 
   7427     return(SOC_E_NONE);
   7428 }
   7429 
   7430 /*
   7431  * phy_82381_per_lane_rx_vga_set
   7432  */
   7433 STATIC int
   7434 phy_82381_per_lane_rx_vga_set(phy_ctrl_t *pc, int32 intf, int lane, int enable, uint32 value)
   7435 {
   7436     soc_phymod_phy_t    *p_phy;
   7437     uint32              lane_map;
   7438     phymod_phy_access_t pm_phy_copy, *pm_phy;
   7439     phymod_rx_t         phymod_rx;
   7440     uint32_t if_side = 0;
   7441     uint32_t chip_id = 0;
   7442     uint32 simplex_tx = 0;
   7443     soc_phymod_ctrl_t *pmc;
   7444     pmc = &pc->phymod_ctrl;
   7445 
   7446 
   7447     /* locate the desired phy and lane */
   7448     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7449 
   7450     /* Make a copy of the phy access and overwrite the desired lane */
   7451     pm_phy = &p_phy->pm_phy;
   7452 
   7453     simplex_tx = SIMPLEX_TX(pc);
   7454     chip_id = DEVID(pc);
   7455     SOC_IF_ERROR_RETURN
   7456         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7457 
   7458     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7459     pm_phy_copy.access.lane_mask = lane_map;
   7460     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7461     pm_phy_copy.access.flags |= if_side;
   7462 
   7463     sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   7464     phymod_rx.vga.enable = TRUE;
   7465     phymod_rx.vga.value = value;
   7466     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   7467     if (!enable) {
   7468         SOC_IF_ERROR_RETURN(phymod_phy_rx_adaptation_resume(&pm_phy_copy));
   7469     }
   7470 
   7471     return(SOC_E_NONE);
   7472 }
   7473 
   7474 /*
   7475  * phy_82381_rx_vga_set
   7476  */
   7477 STATIC int
   7478 phy_82381_rx_vga_set(phy_ctrl_t *pc, int32 intf, int enable, uint32 value)
   7479 {
   7480     phymod_phy_access_t *pm_phy;
   7481     phymod_rx_t         phymod_rx;
   7482     int                 idx;
   7483     phymod_phy_access_t pm_phy_copy;
   7484     uint32_t if_side = 0;
   7485     uint32_t chip_id = 0;
   7486     uint32 simplex_tx = 0;
   7487     soc_phymod_ctrl_t *pmc;
   7488     pmc = &pc->phymod_ctrl;
   7489 
   7490     /* loop through all cores */
   7491     for (idx = 0; idx < pmc->num_phys; idx++) {
   7492         pm_phy = &pmc->phy[idx]->pm_phy;
   7493 
   7494         if (pm_phy == NULL) {
   7495             return SOC_E_INTERNAL;
   7496         }
   7497 
   7498         simplex_tx = SIMPLEX_TX(pc);
   7499         chip_id = DEVID(pc);
   7500         SOC_IF_ERROR_RETURN
   7501             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7502 
   7503         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7504         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7505         pm_phy_copy.access.flags |= if_side;
   7506 
   7507         sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   7508         phymod_rx.vga.enable = TRUE;
   7509         phymod_rx.vga.value = value;
   7510         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   7511         if (!enable) {
   7512             SOC_IF_ERROR_RETURN(phymod_phy_rx_adaptation_resume(&pm_phy_copy));
   7513         }
   7514 
   7515     }
   7516 
   7517     return(SOC_E_NONE);
   7518 }
   7519 
   7520 STATIC int
   7521 phy_82381_rx_tap_release(phy_ctrl_t *pc, int32 intf, int tap)
   7522 {
   7523     phymod_phy_access_t *pm_phy;
   7524     phymod_rx_t         phymod_rx;
   7525     int                 idx;
   7526     phymod_phy_access_t pm_phy_copy;
   7527     uint32_t if_side = 0;
   7528     uint32_t chip_id = 0;
   7529     uint32 simplex_tx = 0;
   7530     soc_phymod_ctrl_t *pmc;
   7531     pmc = &pc->phymod_ctrl;
   7532 
   7533 
   7534     /* bounds check "tap" */
   7535     if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) {
   7536         return SOC_E_INTERNAL;
   7537     }
   7538 
   7539     /* loop through all cores */
   7540     for (idx = 0; idx < pmc->num_phys; idx++) {
   7541         pm_phy = &pmc->phy[idx]->pm_phy;
   7542 
   7543         if (pm_phy == NULL) {
   7544             return SOC_E_INTERNAL;
   7545         }
   7546         simplex_tx = SIMPLEX_TX(pc);
   7547         chip_id = DEVID(pc);
   7548         SOC_IF_ERROR_RETURN
   7549             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7550 
   7551         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7552         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7553         pm_phy_copy.access.flags |= if_side;
   7554         SOC_IF_ERROR_RETURN(phymod_phy_rx_adaptation_resume(&pm_phy_copy));
   7555     }
   7556     return(SOC_E_NONE);
   7557 }
   7558 
   7559 /*
   7560  * phy_82381_rx_tap_set
   7561  */
   7562 STATIC int
   7563 phy_82381_rx_tap_set(phy_ctrl_t *pc, int32 intf, int tap, uint32 value)
   7564 {
   7565     phymod_phy_access_t *pm_phy;
   7566     phymod_rx_t         phymod_rx;
   7567     int                 idx;
   7568     phymod_phy_access_t pm_phy_copy;
   7569     uint32_t if_side = 0;
   7570     uint32_t chip_id = 0;
   7571     uint32 simplex_tx = 0;
   7572     soc_phymod_ctrl_t *pmc;
   7573     pmc = &pc->phymod_ctrl;
   7574 
   7575 
   7576     /* bounds check "tap" */
   7577     if (tap < 0 || tap >= COUNTOF(phymod_rx.dfe)) {
   7578         return SOC_E_INTERNAL;
   7579     }
   7580 
   7581     /* loop through all cores */
   7582     for (idx = 0; idx < pmc->num_phys; idx++) {
   7583         pm_phy = &pmc->phy[idx]->pm_phy;
   7584 
   7585         if (pm_phy == NULL) {
   7586             return SOC_E_INTERNAL;
   7587         }
   7588         simplex_tx = SIMPLEX_TX(pc);
   7589         chip_id = DEVID(pc);
   7590         SOC_IF_ERROR_RETURN
   7591             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7592 
   7593         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7594         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7595         pm_phy_copy.access.flags |= if_side;
   7596 
   7597         sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   7598         phymod_rx.dfe[tap].enable = TRUE;
   7599         phymod_rx.dfe[tap].value = value;
   7600         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   7601     }
   7602 
   7603     return(SOC_E_NONE);
   7604 }
   7605 
   7606 /*
   7607  * phy_82381_pi_control_set
   7608  */
   7609 STATIC int
   7610 phy_82381_pi_control_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   7611 {
   7612     phymod_phy_access_t  *pm_phy;
   7613     phymod_tx_override_t tx_override;
   7614     int                  idx;
   7615     phymod_phy_access_t pm_phy_copy;
   7616     uint32_t if_side = 0;
   7617     uint32_t chip_id = 0;
   7618     uint32 simplex_tx = 0;
   7619     soc_phymod_ctrl_t *pmc;
   7620     pmc = &pc->phymod_ctrl;
   7621 
   7622     /* loop through all cores */
   7623     for (idx = 0; idx < pmc->num_phys; idx++) {
   7624         pm_phy = &pmc->phy[idx]->pm_phy;
   7625 
   7626         if (pm_phy == NULL) {
   7627             return SOC_E_INTERNAL;
   7628         }
   7629         simplex_tx = SIMPLEX_TX(pc);
   7630         chip_id = DEVID(pc);
   7631         SOC_IF_ERROR_RETURN
   7632             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7633         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7634         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7635         pm_phy_copy.access.flags |= if_side;
   7636 
   7637         phymod_tx_override_t_init(&tx_override);
   7638         tx_override.phase_interpolator.enable = (value == 0) ? 0 : 1;
   7639         tx_override.phase_interpolator.value = value;
   7640         SOC_IF_ERROR_RETURN(phymod_phy_tx_override_set(&pm_phy_copy, &tx_override));
   7641     }
   7642 
   7643     return(SOC_E_NONE);
   7644 }
   7645 
   7646 STATIC int
   7647 phy_82381_per_lane_tx_polarity_set(phy_ctrl_t *pc, phymod_polarity_t *cfg_polarity, int32 intf, int lane, uint32 value)
   7648 {
   7649     phymod_phy_access_t  *pm_phy;
   7650     phymod_polarity_t    polarity;
   7651     uint32              lane_map;
   7652     phymod_phy_access_t pm_phy_copy;
   7653     soc_phymod_phy_t    *p_phy;
   7654     uint32_t if_side = 0;
   7655     uint32_t chip_id = 0;
   7656     uint32 simplex_tx = 0;
   7657     soc_phymod_ctrl_t *pmc;
   7658     pmc = &pc->phymod_ctrl;
   7659 
   7660 
   7661     /* locate the desired phy and lane */
   7662     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7663 
   7664     /* Make a copy of the phy access and overwrite the desired lane */
   7665     pm_phy = &p_phy->pm_phy;
   7666 
   7667     simplex_tx = SIMPLEX_TX(pc);
   7668     chip_id = DEVID(pc);
   7669     SOC_IF_ERROR_RETURN
   7670         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7671 
   7672     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7673     pm_phy_copy.access.lane_mask = lane_map;
   7674     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7675     pm_phy_copy.access.flags |= if_side;
   7676 
   7677     sal_memcpy(&polarity, cfg_polarity, sizeof(polarity));
   7678     polarity.tx_polarity = value;
   7679     SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(&pm_phy_copy, &polarity));
   7680 
   7681     /* after successfully setting the parity, update the configured value */
   7682     cfg_polarity->tx_polarity = value;
   7683 
   7684     return(SOC_E_NONE);
   7685 }
   7686 /*
   7687  * phy_82381_tx_polarity_set
   7688  */
   7689 STATIC int
   7690 phy_82381_tx_polarity_set(phy_ctrl_t *pc, phymod_polarity_t *cfg_polarity, int32 intf, uint32 value)
   7691 {
   7692     phymod_phy_access_t  *pm_phy;
   7693     phymod_polarity_t    polarity;
   7694     int                  idx;
   7695     phymod_phy_access_t pm_phy_copy;
   7696     uint32_t if_side = 0;
   7697     uint32_t chip_id = 0;
   7698     uint32 simplex_tx = 0;
   7699     soc_phymod_ctrl_t *pmc;
   7700     pmc = &pc->phymod_ctrl;
   7701 
   7702 
   7703     /* loop through all cores */
   7704     for (idx = 0; idx < pmc->num_phys; idx++) {
   7705         pm_phy = &pmc->phy[idx]->pm_phy;
   7706 
   7707         if (pm_phy == NULL) {
   7708             return SOC_E_INTERNAL;
   7709         }
   7710 
   7711         simplex_tx = SIMPLEX_TX(pc);
   7712         chip_id = DEVID(pc);
   7713         SOC_IF_ERROR_RETURN
   7714             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7715 
   7716         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7717         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7718         pm_phy_copy.access.flags |= if_side;
   7719 
   7720         sal_memcpy(&polarity, cfg_polarity, sizeof(polarity));
   7721         polarity.tx_polarity = value;
   7722         SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(&pm_phy_copy, &polarity));
   7723 
   7724         /* after successfully setting the parity, update the configured value */
   7725         cfg_polarity->tx_polarity = value;
   7726     }
   7727 
   7728     return(SOC_E_NONE);
   7729 }
   7730 /*
   7731  * phy_82381_per_lane_rx_polarity_set
   7732  */
   7733 STATIC int
   7734 phy_82381_per_lane_rx_polarity_set(phy_ctrl_t *pc, phymod_polarity_t *cfg_polarity, int32 intf, int lane, uint32 value)
   7735 {
   7736     phymod_phy_access_t  *pm_phy;
   7737     phymod_polarity_t    polarity;
   7738     uint32              lane_map;
   7739     phymod_phy_access_t pm_phy_copy;
   7740     soc_phymod_phy_t    *p_phy;
   7741     uint32_t if_side = 0;
   7742     uint32_t chip_id = 0;
   7743     uint32 simplex_tx = 0;
   7744     soc_phymod_ctrl_t *pmc;
   7745     pmc = &pc->phymod_ctrl;
   7746 
   7747 
   7748     /* locate the desired phy and lane */
   7749     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7750 
   7751     /* Make a copy of the phy access and overwrite the desired lane */
   7752     pm_phy = &p_phy->pm_phy;
   7753 
   7754     simplex_tx = SIMPLEX_TX(pc);
   7755     chip_id = DEVID(pc);
   7756     SOC_IF_ERROR_RETURN
   7757         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7758 
   7759     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7760     pm_phy_copy.access.lane_mask = lane_map;
   7761     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7762     pm_phy_copy.access.flags |= if_side;
   7763 
   7764     sal_memcpy(&polarity, cfg_polarity, sizeof(polarity));
   7765     polarity.rx_polarity = value;
   7766     SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(&pm_phy_copy, &polarity));
   7767 
   7768     /* after successfully setting the parity, update the configured value */
   7769     cfg_polarity->rx_polarity = value;
   7770     return(SOC_E_NONE);
   7771 }
   7772 
   7773 /*
   7774  * phy_82381_rx_polarity_set
   7775  */
   7776 
   7777 STATIC int
   7778 phy_82381_rx_polarity_set(phy_ctrl_t *pc, phymod_polarity_t *cfg_polarity, int32 intf, uint32 value)
   7779 {
   7780     phymod_phy_access_t  *pm_phy;
   7781     phymod_polarity_t    polarity;
   7782     int                  idx;
   7783     phymod_phy_access_t pm_phy_copy;
   7784     uint32_t if_side = 0;
   7785     uint32_t chip_id = 0;
   7786     uint32 simplex_tx = 0;
   7787     soc_phymod_ctrl_t *pmc;
   7788     pmc = &pc->phymod_ctrl;
   7789 
   7790 
   7791     /* loop through all cores */
   7792     for (idx = 0; idx < pmc->num_phys; idx++) {
   7793         pm_phy = &pmc->phy[idx]->pm_phy;
   7794 
   7795         if (pm_phy == NULL) {
   7796             return SOC_E_INTERNAL;
   7797         }
   7798 
   7799         simplex_tx = SIMPLEX_TX(pc);
   7800         chip_id = DEVID(pc);
   7801         SOC_IF_ERROR_RETURN
   7802             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7803 
   7804         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7805         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7806         pm_phy_copy.access.flags |= if_side;
   7807         sal_memcpy(&polarity, cfg_polarity, sizeof(polarity));
   7808         polarity.rx_polarity = value;
   7809         SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(&pm_phy_copy, &polarity));
   7810 
   7811         /* after successfully setting the parity, update the configured value */
   7812         cfg_polarity->rx_polarity = value;
   7813     }
   7814 
   7815     return(SOC_E_NONE);
   7816 }
   7817 
   7818 /*
   7819  * phy_82381_rx_reset_set
   7820  */
   7821 STATIC int
   7822 phy_82381_rx_reset(phy_ctrl_t *pc, phymod_phy_reset_t *cfg_reset, int32 intf, uint32 value)
   7823 {
   7824     phymod_phy_access_t *pm_phy;
   7825     phymod_phy_reset_t  reset;
   7826     int                 idx;
   7827     phymod_phy_access_t pm_phy_copy;
   7828     uint32_t if_side = 0;
   7829     uint32_t chip_id = 0;
   7830     uint32 simplex_tx = 0;
   7831     soc_phymod_ctrl_t *pmc;
   7832     pmc = &pc->phymod_ctrl;
   7833 
   7834 
   7835     /* loop through all cores */
   7836     for (idx = 0; idx < pmc->num_phys; idx++) {
   7837         pm_phy = &pmc->phy[idx]->pm_phy;
   7838 
   7839         if (pm_phy == NULL) {
   7840             return SOC_E_INTERNAL;
   7841         }
   7842 
   7843         simplex_tx = SIMPLEX_TX(pc);
   7844         chip_id = DEVID(pc);
   7845         SOC_IF_ERROR_RETURN
   7846             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   7847 
   7848         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7849         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7850         pm_phy_copy.access.flags |= if_side;
   7851 
   7852         sal_memcpy(&reset, cfg_reset, sizeof(reset));
   7853         reset.rx = (phymod_reset_direction_t) value;
   7854         SOC_IF_ERROR_RETURN(phymod_phy_reset_set(&pm_phy_copy, &reset));
   7855 
   7856         /* after successfully setting the parity, update the configured value */
   7857         cfg_reset->rx = (phymod_reset_direction_t) value;
   7858     }
   7859 
   7860     return(SOC_E_NONE);
   7861 }
   7862 
   7863 /*
   7864  * phy_82381_tx_reset
   7865  */
   7866 STATIC int
   7867 phy_82381_tx_reset(phy_ctrl_t *pc, phymod_phy_reset_t *cfg_reset, int32 intf, uint32 value)
   7868 {
   7869     phymod_phy_access_t *pm_phy;
   7870     phymod_phy_reset_t  reset;
   7871     int                 idx;
   7872     phymod_phy_access_t pm_phy_copy;
   7873     uint32_t if_side = 0;
   7874     uint32_t chip_id = 0;
   7875     uint32 simplex_tx = 0;
   7876     soc_phymod_ctrl_t *pmc;
   7877     pmc = &pc->phymod_ctrl;
   7878 
   7879 
   7880     /* loop through all cores */
   7881     for (idx = 0; idx < pmc->num_phys; idx++) {
   7882         pm_phy = &pmc->phy[idx]->pm_phy;
   7883 
   7884         if (pm_phy == NULL) {
   7885             return SOC_E_INTERNAL;
   7886         }
   7887 
   7888         simplex_tx = SIMPLEX_TX(pc);
   7889         chip_id = DEVID(pc);
   7890         SOC_IF_ERROR_RETURN
   7891             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   7892 
   7893         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7894         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7895         pm_phy_copy.access.flags |= if_side;
   7896 
   7897         sal_memcpy(&reset, cfg_reset, sizeof(reset));
   7898         reset.tx = (phymod_reset_direction_t) value;
   7899         SOC_IF_ERROR_RETURN(phymod_phy_reset_set(&pm_phy_copy, &reset));
   7900 
   7901         /* after successfully setting the parity, update the configured value */
   7902         cfg_reset->tx = (phymod_reset_direction_t) value;
   7903     }
   7904 
   7905     return(SOC_E_NONE);
   7906 }
   7907 
   7908 
   7909 /*
   7910  * phy_82381_per_lane_power_set
   7911  */
   7912 STATIC int
   7913 phy_82381_per_lane_power_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   7914 {
   7915     phymod_phy_access_t     *pm_phy;
   7916     phymod_phy_power_t      power;
   7917     uint32              lane_map;
   7918     phymod_phy_access_t pm_phy_copy;
   7919     soc_phymod_phy_t    *p_phy;
   7920     uint32_t if_side = 0;
   7921     uint32_t chip_id = 0;
   7922     uint32 simplex_tx = 0;
   7923     soc_phymod_ctrl_t *pmc;
   7924     pmc = &pc->phymod_ctrl;
   7925 
   7926     /* locate the desired phy and lane */
   7927     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   7928 
   7929     /* Make a copy of the phy access and overwrite the desired lane */
   7930     pm_phy = &p_phy->pm_phy;
   7931 
   7932     simplex_tx = SIMPLEX_TX(pc);
   7933     chip_id = DEVID(pc);
   7934 
   7935     phymod_phy_power_t_init(&power);
   7936     if(FURIA_IS_SIMPLEX(chip_id)){
   7937         if (!simplex_tx) { /* Rx simplex package */
   7938             if (intf == PHY82381_SYS_SIDE) {
   7939                if (value) {
   7940                    power.tx = phymodPowerOn;
   7941                    power.rx = phymodPowerOn;
   7942                } else {
   7943                    power.tx = phymodPowerOff;
   7944                    power.rx = phymodPowerOn;
   7945                }
   7946                if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   7947             } else {
   7948                 if (value) {
   7949                    power.rx = phymodPowerOn;
   7950                    power.tx = phymodPowerOn;
   7951                 } else {
   7952                    power.rx = phymodPowerOff;
   7953                    power.tx = phymodPowerOn;
   7954                 }
   7955                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   7956                 if_side |= (1 << INTERFACE_SIDE_SHIFT);
   7957             }
   7958         } else { /* Tx simplex package */
   7959             if (intf == PHY82381_SYS_SIDE) {
   7960                if (value) {
   7961                    power.rx = phymodPowerOn;
   7962                    power.tx = phymodPowerOn;
   7963                } else {
   7964                    power.rx = phymodPowerOff;
   7965                    power.tx = phymodPowerOn;
   7966                }
   7967                if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   7968                if_side |= (1 << INTERFACE_SIDE_SHIFT);
   7969             } else {
   7970                 if (value) {
   7971                    power.tx = phymodPowerOn;
   7972                    power.rx = phymodPowerOn;
   7973                 } else {
   7974                    power.tx = phymodPowerOff;
   7975                    power.rx = phymodPowerOn;
   7976                 }
   7977                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   7978             }
   7979         }
   7980     } else {
   7981         if (value) {
   7982             power.tx = phymodPowerOn;
   7983             power.rx = phymodPowerOn;
   7984         } else {
   7985             power.tx = phymodPowerOff;
   7986             power.rx = phymodPowerOff;
   7987         }
   7988         if (intf == PHY82381_SYS_SIDE) {
   7989            if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   7990            if_side |= (1 << INTERFACE_SIDE_SHIFT);
   7991         } else {
   7992            if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   7993         }
   7994     }
   7995 
   7996     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   7997     pm_phy_copy.access.lane_mask = lane_map;
   7998     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   7999     pm_phy_copy.access.flags |= if_side;
   8000 
   8001     SOC_IF_ERROR_RETURN(phymod_phy_power_set(&pm_phy_copy, &power));
   8002 
   8003     return(SOC_E_NONE);
   8004 }
   8005 /*
   8006  * phy_82381_power_set
   8007  */
   8008 STATIC int
   8009 phy_82381_power_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   8010 {
   8011     phymod_phy_access_t     *pm_phy;
   8012     phymod_phy_power_t      power;
   8013     int                     idx;
   8014     phymod_phy_access_t pm_phy_copy;
   8015     uint32_t if_side = 0;
   8016     uint32_t chip_id = 0;
   8017     uint32 simplex_tx = 0;
   8018     soc_phymod_ctrl_t *pmc;
   8019     pmc = &pc->phymod_ctrl;
   8020 
   8021     /* loop through all cores */
   8022     for (idx = 0; idx < pmc->num_phys; idx++) {
   8023         pm_phy = &pmc->phy[idx]->pm_phy;
   8024 
   8025         if (pm_phy == NULL) {
   8026             return SOC_E_INTERNAL;
   8027         }
   8028 
   8029         simplex_tx = SIMPLEX_TX(pc);
   8030         chip_id = DEVID(pc);
   8031 
   8032         phymod_phy_power_t_init(&power);
   8033         if(FURIA_IS_SIMPLEX(chip_id)){
   8034             if (!simplex_tx) { /* Rx simplex package */
   8035                 if (intf == PHY82381_SYS_SIDE) {
   8036                     if (value) {
   8037                         power.tx = phymodPowerOn;
   8038                     } else {
   8039                         power.tx = phymodPowerOff;
   8040                     }
   8041                     power.rx = phymodPowerNoChange;
   8042                     if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   8043                 } else {
   8044                     if (value) {
   8045                         power.rx = phymodPowerOn;
   8046                     } else {
   8047                         power.rx = phymodPowerOff;
   8048                     }
   8049                     power.tx = phymodPowerNoChange;
   8050                     if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   8051                     if_side |= (1 << INTERFACE_SIDE_SHIFT);
   8052                 }
   8053             } else { /* Tx simplex package */
   8054                 if (intf == PHY82381_SYS_SIDE) {
   8055                     if (value) {
   8056                         power.rx = phymodPowerOn;
   8057                     } else {
   8058                         power.rx = phymodPowerOff;
   8059                     }
   8060                     power.tx = phymodPowerNoChange;
   8061                     if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   8062                     if_side |= (1 << INTERFACE_SIDE_SHIFT);
   8063                 } else {
   8064                     if (value) {
   8065                         power.tx = phymodPowerOn;
   8066                     } else {
   8067                         power.tx = phymodPowerOff;
   8068                     }
   8069                     power.rx = phymodPowerNoChange;
   8070                     if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   8071                 }
   8072             }
   8073         } else {
   8074             if (value) {
   8075                 power.tx = phymodPowerOn;
   8076                 power.rx = phymodPowerOn;
   8077             } else {
   8078                 power.tx = phymodPowerOff;
   8079                 power.rx = phymodPowerOff;
   8080             }
   8081             if (intf == PHY82381_SYS_SIDE) {
   8082                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   8083                 if_side |= (1 << INTERFACE_SIDE_SHIFT);
   8084             } else {
   8085                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   8086             }
   8087         }
   8088 
   8089         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8090         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8091         pm_phy_copy.access.flags |= if_side;
   8092         /*sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));*/
   8093 
   8094         SOC_IF_ERROR_RETURN(phymod_phy_power_set(&pm_phy_copy, &power));
   8095     }
   8096 
   8097     return(SOC_E_NONE);
   8098 }
   8099 
   8100 
   8101 /*
   8102  * phy_82381_rx_low_freq_filter_set
   8103  */
   8104 STATIC int
   8105 phy_82381_rx_low_freq_filter_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   8106 {
   8107     phymod_phy_access_t  *pm_phy;
   8108     phymod_rx_t          phymod_rx;
   8109     int                  idx;
   8110     phymod_phy_access_t pm_phy_copy;
   8111     uint32_t if_side = 0;
   8112     uint32_t chip_id = 0;
   8113     uint32 simplex_tx = 0;
   8114     soc_phymod_ctrl_t *pmc;
   8115     pmc = &pc->phymod_ctrl;
   8116 
   8117 
   8118     /* loop through all cores */
   8119     for (idx = 0; idx < pmc->num_phys; idx++) {
   8120         pm_phy = &pmc->phy[idx]->pm_phy;
   8121 
   8122         if (pm_phy == NULL) {
   8123             return SOC_E_INTERNAL;
   8124         }
   8125 
   8126         simplex_tx = SIMPLEX_TX(pc);
   8127         chip_id = DEVID(pc);
   8128         SOC_IF_ERROR_RETURN
   8129             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8130 
   8131         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8132         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8133         pm_phy_copy.access.flags |= if_side;
   8134 
   8135         sal_memset(&phymod_rx, 0, sizeof(phymod_rx));
   8136         phymod_rx.low_freq_peaking_filter.enable = TRUE;
   8137         phymod_rx.low_freq_peaking_filter.value = value;
   8138         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   8139     }
   8140 
   8141     return(SOC_E_NONE);
   8142 }
   8143 
   8144 STATIC int
   8145 phy_82381_rx_seq_restart(phy_ctrl_t *pc, int32 intf, uint32 value)
   8146 {
   8147     phymod_sequencer_operation_t seq_operation;
   8148     int                  idx;
   8149     soc_phymod_core_t *pmc_core;
   8150     phymod_core_access_t *pm_core;
   8151     phymod_core_access_t pm_core_copy;
   8152     phymod_phy_access_t     *pm_phy;
   8153     uint32_t flags = 0;
   8154     uint32_t if_side = 0;
   8155     uint32_t chip_id = 0;
   8156     uint32 simplex_tx = 0;
   8157     soc_phymod_ctrl_t *pmc;
   8158     pmc = &pc->phymod_ctrl;
   8159 
   8160 
   8161     /* loop through all cores */
   8162     for (idx = 0; idx < pmc->num_phys; idx++) {
   8163         pmc_core = pmc->phy[idx]->core;
   8164         pm_core = &pmc_core->pm_core;
   8165         if (pm_core == NULL) {
   8166             return SOC_E_INTERNAL;
   8167         }
   8168         pm_phy = &pmc->phy[idx]->pm_phy;
   8169 
   8170         if (pm_phy == NULL) {
   8171             return SOC_E_INTERNAL;
   8172         }
   8173 
   8174 
   8175         simplex_tx = SIMPLEX_TX(pc);
   8176         chip_id = DEVID(pc);
   8177         SOC_IF_ERROR_RETURN
   8178             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8179 
   8180         sal_memcpy(&pm_core_copy, pm_core, sizeof(pm_core_copy));
   8181         pm_core_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8182         pm_core_copy.access.flags |= if_side;
   8183         seq_operation = phymodSeqOpRestart;
   8184         SOC_IF_ERROR_RETURN(phymod_core_pll_sequencer_restart(pm_core, flags, seq_operation));
   8185     }
   8186     return(SOC_E_NONE);
   8187 }
   8188 
   8189 STATIC int
   8190 phy_82381_phy_dump(phy_ctrl_t *pc, int32 intf)
   8191 {
   8192     phymod_phy_access_t     *pm_phy;
   8193     int                     idx;
   8194     phymod_phy_access_t pm_phy_copy;
   8195     soc_phymod_ctrl_t *pmc;
   8196     pmc = &pc->phymod_ctrl;
   8197 
   8198     /* loop through all cores */
   8199     for (idx = 0; idx < pmc->num_phys; idx++) {
   8200         pm_phy = &pmc->phy[idx]->pm_phy;
   8201 
   8202         if (pm_phy == NULL) {
   8203             return SOC_E_INTERNAL;
   8204         }
   8205 
   8206         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8207         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8208         if(intf == PHY82381_SYS_SIDE) {
   8209             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   8210         }
   8211         SOC_IF_ERROR_RETURN(phymod_phy_status_dump(&pm_phy_copy));
   8212 
   8213     }
   8214 
   8215     return(SOC_E_NONE);
   8216 }
   8217 STATIC int
   8218 phy_82381_per_lane_phy_dump(phy_ctrl_t *pc, int32 intf, int lane)
   8219 {
   8220     phymod_phy_access_t     *pm_phy;
   8221     uint32              lane_map;
   8222     phymod_phy_access_t pm_phy_copy;
   8223     soc_phymod_phy_t    *p_phy;
   8224     soc_phymod_ctrl_t *pmc;
   8225     pmc = &pc->phymod_ctrl;
   8226 
   8227     /* locate the desired phy and lane */
   8228     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   8229 
   8230     /* Make a copy of the phy access and overwrite the desired lane */
   8231     pm_phy = &p_phy->pm_phy;
   8232     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8233     pm_phy_copy.access.lane_mask = lane_map;
   8234     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8235     if(intf == PHY82381_SYS_SIDE) {
   8236         pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   8237     }
   8238 
   8239     SOC_IF_ERROR_RETURN(phymod_phy_status_dump(&pm_phy_copy));
   8240     return(SOC_E_NONE);
   8241 }
   8242 
   8243 /*
   8244  * phy_82381_gpio_config_set
   8245  */
   8246 STATIC int
   8247 phy_82381_gpio_config_set(phy_ctrl_t *pc, uint32 value)
   8248 {
   8249     phymod_phy_access_t  *pm_phy;
   8250     int                  idx;
   8251     phymod_phy_access_t pm_phy_copy;
   8252     int gpio_mode = 0;
   8253     int gpio_pin_no = 0;
   8254     soc_phymod_ctrl_t *pmc;
   8255     pmc = &pc->phymod_ctrl;
   8256 
   8257     /* loop through all cores */
   8258     for (idx = 0; idx < pmc->num_phys; idx++) {
   8259         pm_phy = &pmc->phy[idx]->pm_phy;
   8260 
   8261         if (pm_phy == NULL) {
   8262             return SOC_E_INTERNAL;
   8263         }
   8264 
   8265         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8266 
   8267         for (gpio_pin_no = 0; gpio_pin_no < 5; gpio_pin_no++) {
   8268             gpio_mode = (value >> (4 * gpio_pin_no)) & 0xF;
   8269             SOC_IF_ERROR_RETURN(phymod_phy_gpio_config_set(&pm_phy_copy, gpio_pin_no, (phymod_gpio_mode_t)gpio_mode));
   8270         }
   8271     }
   8272 
   8273     return(SOC_E_NONE);
   8274 }
   8275 /*
   8276  * phy_82381_gpio_value_set
   8277  */
   8278 STATIC int
   8279 phy_82381_gpio_value_set(phy_ctrl_t *pc, uint32 value)
   8280 {
   8281     phymod_phy_access_t  *pm_phy;
   8282     int                  idx;
   8283     phymod_phy_access_t pm_phy_copy;
   8284     int pin_value = 0;
   8285     int gpio_pin_no = 0;
   8286     soc_phymod_ctrl_t *pmc;
   8287     pmc = &pc->phymod_ctrl;
   8288 
   8289     /* loop through all cores */
   8290     for (idx = 0; idx < pmc->num_phys; idx++) {
   8291         pm_phy = &pmc->phy[idx]->pm_phy;
   8292 
   8293         if (pm_phy == NULL) {
   8294             return SOC_E_INTERNAL;
   8295         }
   8296 
   8297         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8298 
   8299         for (gpio_pin_no = 0; gpio_pin_no < 5; gpio_pin_no++) {
   8300             pin_value = (value >> (4 * gpio_pin_no)) & 0xF;
   8301             SOC_IF_ERROR_RETURN(phymod_phy_gpio_pin_value_set(&pm_phy_copy, gpio_pin_no, pin_value));
   8302         }
   8303     }
   8304 
   8305     return(SOC_E_NONE);
   8306 }
   8307 /*
   8308  * phy_82381_firmware_mode_set
   8309  */
   8310 STATIC int
   8311 phy_82381_firmware_mode_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   8312 {
   8313     phymod_phy_access_t    *pm_phy;
   8314     phymod_firmware_lane_config_t fw_config;
   8315     int                    idx;
   8316     soc_phymod_ctrl_t *pmc;
   8317     int                 rv;
   8318     uint32_t if_side = 0;
   8319     uint32_t chip_id = 0;
   8320     phymod_phy_access_t pm_phy_copy;
   8321     uint32 simplex_tx = 0;
   8322     pmc = &pc->phymod_ctrl;
   8323     rv = SOC_E_UNAVAIL;
   8324 
   8325     /* loop through all cores */
   8326     for (idx = 0; idx < pmc->num_phys; idx++) {
   8327         if (pmc->phy[idx] == NULL) {
   8328             return(SOC_E_INTERNAL);
   8329         }
   8330 
   8331         pm_phy = &pmc->phy[idx]->pm_phy;
   8332         if (pm_phy == NULL) {
   8333             return(SOC_E_INTERNAL);
   8334         }
   8335 
   8336         simplex_tx = SIMPLEX_TX(pc);
   8337         chip_id = DEVID(pc);
   8338         SOC_IF_ERROR_RETURN
   8339             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8340 
   8341         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8342 
   8343         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8344         pm_phy_copy.access.flags |= if_side;
   8345 
   8346         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8347 
   8348         switch (value) {
   8349             case SOC_PHY_FIRMWARE_DEFAULT:
   8350                 fw_config.DfeOn = 0xF;
   8351                 fw_config.LpDfeOn = 0xF;
   8352                 fw_config.ForceBrDfe = 0xF;
   8353                 break;
   8354             case SOC_PHY_FIRMWARE_FORCE_OSDFE:
   8355                 fw_config.DfeOn = 1;
   8356                 fw_config.ForceBrDfe = 0;
   8357                 break;
   8358             case SOC_PHY_FIRMWARE_SFP_DAC:
   8359                 fw_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   8360                 break;
   8361             case SOC_PHY_FIRMWARE_XLAUI:
   8362                 fw_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   8363                 break;
   8364             case SOC_PHY_FIRMWARE_SFP_OPT_SR4:
   8365                 fw_config.MediaType = phymodFirmwareMediaTypeOptics;
   8366                 break;
   8367             case SOC_PHY_FIRMWARE_LP_DFE_ENABLE:
   8368                 fw_config.LpDfeOn = 1;
   8369                 fw_config.DfeOn = 1;
   8370                 break;
   8371             case SOC_PHY_FIRMWARE_FORCE_BRDFE:
   8372                 fw_config.ForceBrDfe = 1;
   8373                 fw_config.DfeOn = 1;
   8374                 break;
   8375             case SOC_PHY_FIRMWARE_DFE_ENABLE:
   8376                 fw_config.DfeOn = 1;
   8377                 break;
   8378             default:
   8379                 rv = SOC_E_UNAVAIL;
   8380                 return rv;
   8381         }
   8382 
   8383         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8384     }
   8385 
   8386     return(SOC_E_NONE);
   8387 }
   8388 
   8389 /*
   8390  * phy_82381_firmware_br_dfe_enable_set
   8391  */
   8392 STATIC int
   8393 phy_82381_firmware_br_dfe_enable_set(phy_ctrl_t *pc, int32 intf, uint32 enable)
   8394 {
   8395     phymod_phy_access_t    *pm_phy;
   8396     phymod_firmware_lane_config_t fw_config;
   8397     int                    idx;
   8398     soc_phymod_ctrl_t *pmc;
   8399     phymod_phy_access_t pm_phy_copy;
   8400     uint32_t if_side = 0;
   8401     uint32_t chip_id = 0;
   8402     uint32 simplex_tx = 0;
   8403     pmc = &pc->phymod_ctrl;
   8404 
   8405     /* loop through all cores */
   8406     for (idx = 0; idx < pmc->num_phys; idx++) {
   8407         if (pmc->phy[idx] == NULL) {
   8408             return(SOC_E_INTERNAL);
   8409         }
   8410 
   8411         pm_phy = &pmc->phy[idx]->pm_phy;
   8412         if (pm_phy == NULL) {
   8413             return(SOC_E_INTERNAL);
   8414         }
   8415 
   8416         simplex_tx = SIMPLEX_TX(pc);
   8417         chip_id = DEVID(pc);
   8418         SOC_IF_ERROR_RETURN
   8419             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8420 
   8421         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8422 
   8423         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8424         pm_phy_copy.access.flags |= if_side;
   8425         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8426 
   8427         if (enable) {
   8428             fw_config.DfeOn = 1;
   8429             fw_config.ForceBrDfe = 1;
   8430         } else {
   8431             fw_config.ForceBrDfe = 0;
   8432         }
   8433 
   8434         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8435     }
   8436 
   8437     return(SOC_E_NONE);
   8438 }
   8439 
   8440 /*
   8441  * phy_82381_firmware_lp_dfe_enable_set
   8442  */
   8443 STATIC int
   8444 phy_82381_firmware_lp_dfe_enable_set(phy_ctrl_t *pc, int32 intf, uint32 enable)
   8445 {
   8446     phymod_phy_access_t    *pm_phy;
   8447     phymod_firmware_lane_config_t fw_config;
   8448     int                    idx;
   8449     soc_phymod_ctrl_t *pmc;
   8450     phymod_phy_access_t pm_phy_copy;
   8451     uint32_t if_side = 0;
   8452     uint32_t chip_id = 0;
   8453     uint32 simplex_tx = 0;
   8454     pmc = &pc->phymod_ctrl;
   8455 
   8456     /* loop through all cores */
   8457     for (idx = 0; idx < pmc->num_phys; idx++) {
   8458         if (pmc->phy[idx] == NULL) {
   8459             return(SOC_E_INTERNAL);
   8460         }
   8461 
   8462         pm_phy = &pmc->phy[idx]->pm_phy;
   8463         if (pm_phy == NULL) {
   8464             return(SOC_E_INTERNAL);
   8465         }
   8466         simplex_tx = SIMPLEX_TX(pc);
   8467         chip_id = DEVID(pc);
   8468         SOC_IF_ERROR_RETURN
   8469             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8470 
   8471         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8472 
   8473         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8474         pm_phy_copy.access.flags |= if_side;
   8475 
   8476         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8477 
   8478         if (enable) {
   8479             fw_config.DfeOn = 1;
   8480             fw_config.LpDfeOn = 1;
   8481         } else {
   8482             fw_config.LpDfeOn = 0;
   8483         }
   8484 
   8485         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8486     }
   8487 
   8488     return(SOC_E_NONE);
   8489 }
   8490 
   8491 /*
   8492  * phy_82381_firmware_dfe_enable_set
   8493  */
   8494 STATIC int
   8495 phy_82381_firmware_dfe_enable_set(phy_ctrl_t *pc, int32 intf, uint32 enable)
   8496 {
   8497     phymod_phy_access_t    *pm_phy;
   8498     phymod_firmware_lane_config_t fw_config;
   8499     int                    idx;
   8500     soc_phymod_ctrl_t *pmc;
   8501     phymod_phy_access_t pm_phy_copy;
   8502     uint32_t if_side = 0;
   8503     uint32_t chip_id = 0;
   8504     uint32 simplex_tx = 0;
   8505     pmc = &pc->phymod_ctrl;
   8506 
   8507     /* loop through all cores */
   8508     for (idx = 0; idx < pmc->num_phys; idx++) {
   8509         if (pmc->phy[idx] == NULL) {
   8510             return(SOC_E_INTERNAL);
   8511         }
   8512 
   8513         pm_phy = &pmc->phy[idx]->pm_phy;
   8514         if (pm_phy == NULL) {
   8515             return(SOC_E_INTERNAL);
   8516         }
   8517 
   8518         simplex_tx = SIMPLEX_TX(pc);
   8519         chip_id = DEVID(pc);
   8520         SOC_IF_ERROR_RETURN
   8521             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8522 
   8523         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8524 
   8525         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8526         pm_phy_copy.access.flags |= if_side;
   8527         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8528 
   8529         if (enable) {
   8530             fw_config.DfeOn = 1;
   8531         } else {
   8532             fw_config.DfeOn = 0;
   8533         }
   8534 
   8535         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8536     }
   8537 
   8538     return(SOC_E_NONE);
   8539 }
   8540 /*
   8541  * phy_82381_per_lane_firmware_mode_set
   8542  */
   8543 STATIC int
   8544 phy_82381_per_lane_firmware_mode_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 value)
   8545 {
   8546     phymod_firmware_lane_config_t fw_config;
   8547     soc_phymod_phy_t    *p_phy;
   8548     uint32              lane_map;
   8549     phymod_phy_access_t pm_phy_copy, *pm_phy;
   8550     int                 rv;
   8551     soc_phymod_ctrl_t *pmc;
   8552     uint32_t if_side = 0;
   8553     uint32_t chip_id = 0;
   8554     uint32 simplex_tx = 0;
   8555     pmc = &pc->phymod_ctrl;
   8556     rv = SOC_E_UNAVAIL;
   8557 
   8558     /* locate the desired phy and lane */
   8559     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   8560 
   8561     /* Make a copy of the phy access and overwrite the desired lane */
   8562     pm_phy = &p_phy->pm_phy;
   8563 
   8564     simplex_tx = SIMPLEX_TX(pc);
   8565     chip_id = DEVID(pc);
   8566     SOC_IF_ERROR_RETURN
   8567         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8568     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8569     pm_phy_copy.access.lane_mask = lane_map;
   8570     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8571     pm_phy_copy.access.flags |= if_side;
   8572 
   8573     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8574 
   8575 
   8576     switch (value) {
   8577         case SOC_PHY_FIRMWARE_DEFAULT:
   8578             fw_config.DfeOn = 0xF;
   8579             fw_config.LpDfeOn = 0xF;
   8580             fw_config.ForceBrDfe = 0xF;
   8581             break;
   8582         case SOC_PHY_FIRMWARE_FORCE_OSDFE:
   8583             fw_config.DfeOn = 1;
   8584             fw_config.ForceBrDfe = 0;
   8585             break;
   8586         case SOC_PHY_FIRMWARE_SFP_DAC:
   8587             fw_config.MediaType = phymodFirmwareMediaTypeCopperCable;
   8588             break;
   8589         case SOC_PHY_FIRMWARE_XLAUI:
   8590             fw_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane;
   8591             break;
   8592         case SOC_PHY_FIRMWARE_SFP_OPT_SR4:
   8593             fw_config.MediaType = phymodFirmwareMediaTypeOptics;
   8594             break;
   8595         case SOC_PHY_FIRMWARE_LP_DFE_ENABLE:
   8596             fw_config.LpDfeOn = 1;
   8597             fw_config.DfeOn = 1;
   8598             break;
   8599         case SOC_PHY_FIRMWARE_FORCE_BRDFE:
   8600             fw_config.ForceBrDfe = 1;
   8601             fw_config.DfeOn = 1;
   8602             break;
   8603         case SOC_PHY_FIRMWARE_DFE_ENABLE:
   8604             fw_config.DfeOn = 1;
   8605             break;
   8606         default:
   8607             rv = SOC_E_UNAVAIL;
   8608             return rv;
   8609     }
   8610     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8611 
   8612     return(SOC_E_NONE);
   8613 }
   8614 
   8615 /*
   8616  * phy_82381_per_lane_firmware_br_dfe_enable_set
   8617  */
   8618 STATIC int
   8619 phy_82381_per_lane_firmware_br_dfe_enable_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 enable)
   8620 {
   8621     phymod_firmware_lane_config_t fw_config;
   8622     uint32              lane_map;
   8623     phymod_phy_access_t pm_phy_copy, *pm_phy;
   8624     soc_phymod_phy_t    *p_phy;
   8625     soc_phymod_ctrl_t *pmc;
   8626     uint32_t if_side = 0;
   8627     uint32_t chip_id = 0;
   8628     uint32 simplex_tx = 0;
   8629     pmc = &pc->phymod_ctrl;
   8630 
   8631     /* locate the desired phy and lane */
   8632     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   8633 
   8634     /* Make a copy of the phy access and overwrite the desired lane */
   8635     pm_phy = &p_phy->pm_phy;
   8636 
   8637     simplex_tx = SIMPLEX_TX(pc);
   8638     chip_id = DEVID(pc);
   8639     SOC_IF_ERROR_RETURN
   8640         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8641     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8642     pm_phy_copy.access.lane_mask = lane_map;
   8643     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8644     pm_phy_copy.access.flags |= if_side;
   8645 
   8646     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8647 
   8648     if (enable) {
   8649         fw_config.DfeOn = 1;
   8650         fw_config.ForceBrDfe = 1;
   8651     } else {
   8652         fw_config.ForceBrDfe = 0;
   8653     }
   8654 
   8655     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8656 
   8657     return(SOC_E_NONE);
   8658 }
   8659 
   8660 /*
   8661  * phy_82381_per_lane_firmware_lp_dfe_enable_set
   8662  */
   8663 STATIC int
   8664 phy_82381_per_lane_firmware_lp_dfe_enable_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 enable)
   8665 {
   8666     phymod_firmware_lane_config_t fw_config;
   8667     uint32              lane_map;
   8668     phymod_phy_access_t pm_phy_copy, *pm_phy;
   8669     soc_phymod_phy_t    *p_phy;
   8670     uint32_t if_side = 0;
   8671     uint32_t chip_id = 0;
   8672     uint32 simplex_tx = 0;
   8673     soc_phymod_ctrl_t *pmc;
   8674     pmc = &pc->phymod_ctrl;
   8675 
   8676     /* locate the desired phy and lane */
   8677     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   8678 
   8679     /* Make a copy of the phy access and overwrite the desired lane */
   8680     pm_phy = &p_phy->pm_phy;
   8681 
   8682     simplex_tx = SIMPLEX_TX(pc);
   8683     chip_id = DEVID(pc);
   8684     SOC_IF_ERROR_RETURN
   8685         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8686     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8687     pm_phy_copy.access.lane_mask = lane_map;
   8688     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8689     pm_phy_copy.access.flags |= if_side;
   8690 
   8691     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8692 
   8693     if (enable) {
   8694         fw_config.DfeOn = 1;
   8695         fw_config.LpDfeOn = 1;
   8696     } else {
   8697         fw_config.LpDfeOn = 0;
   8698     }
   8699 
   8700     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8701 
   8702     return(SOC_E_NONE);
   8703 }
   8704 
   8705 /*
   8706  * phy_82381_per_lane_firmware_dfe_enable_set
   8707  */
   8708 STATIC int
   8709 phy_82381_per_lane_firmware_dfe_enable_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 enable)
   8710 {
   8711     phymod_firmware_lane_config_t fw_config;
   8712     uint32              lane_map;
   8713     phymod_phy_access_t pm_phy_copy, *pm_phy;
   8714     soc_phymod_phy_t    *p_phy;
   8715     soc_phymod_ctrl_t *pmc;
   8716     uint32_t if_side = 0;
   8717     uint32_t chip_id = 0;
   8718     uint32 simplex_tx = 0;
   8719     pmc = &pc->phymod_ctrl;
   8720 
   8721     /* locate the desired phy and lane */
   8722     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   8723 
   8724     /* Make a copy of the phy access and overwrite the desired lane */
   8725     pm_phy = &p_phy->pm_phy;
   8726 
   8727     simplex_tx = SIMPLEX_TX(pc);
   8728     chip_id = DEVID(pc);
   8729     SOC_IF_ERROR_RETURN
   8730         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8731     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8732     pm_phy_copy.access.lane_mask = lane_map;
   8733     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8734     pm_phy_copy.access.flags |= if_side;
   8735 
   8736     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8737 
   8738     if (enable) {
   8739         fw_config.DfeOn = 1;
   8740     } else {
   8741         fw_config.DfeOn = 0;
   8742     }
   8743 
   8744     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8745 
   8746     return SOC_E_NONE;
   8747 }
   8748 /*
   8749  * phy_82381_unreliable_los_set
   8750  */
   8751 STATIC int
   8752 phy_82381_unreliable_los_set(phy_ctrl_t *pc, int32 intf, uint32 enable)
   8753 {
   8754     phymod_phy_access_t    *pm_phy;
   8755     phymod_firmware_lane_config_t fw_config;
   8756     int                    idx;
   8757     soc_phymod_ctrl_t *pmc;
   8758     phymod_phy_access_t pm_phy_copy;
   8759     uint32_t if_side = 0;
   8760     uint32_t chip_id = 0;
   8761     uint32 simplex_tx = 0;
   8762     pmc = &pc->phymod_ctrl;
   8763 
   8764     /* loop through all cores */
   8765     for (idx = 0; idx < pmc->num_phys; idx++) {
   8766         if (pmc->phy[idx] == NULL) {
   8767             return(SOC_E_INTERNAL);
   8768         }
   8769 
   8770         pm_phy = &pmc->phy[idx]->pm_phy;
   8771         if (pm_phy == NULL) {
   8772             return(SOC_E_INTERNAL);
   8773         }
   8774 
   8775         simplex_tx = SIMPLEX_TX(pc);
   8776         chip_id = DEVID(pc);
   8777         SOC_IF_ERROR_RETURN
   8778             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8779 
   8780         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8781         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8782         pm_phy_copy.access.flags |= if_side;
   8783 
   8784         sal_memset(&fw_config, 0, sizeof(fw_config));
   8785         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8786 
   8787         if (enable) {
   8788             fw_config.UnreliableLos = 1;
   8789         } else {
   8790             fw_config.UnreliableLos = 0;
   8791         }
   8792 
   8793         SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8794     }
   8795 
   8796     return(SOC_E_NONE);
   8797 }
   8798 /*
   8799  * phy_82381_per_lane_unreliable_los_set
   8800  */
   8801 STATIC int
   8802 phy_82381_per_lane_unreliable_los_set(phy_ctrl_t *pc, int32 intf, int lane, uint32 enable)
   8803 {
   8804     phymod_phy_access_t    *pm_phy;
   8805     soc_phymod_phy_t    *p_phy;
   8806     phymod_firmware_lane_config_t fw_config;
   8807     soc_phymod_ctrl_t *pmc;
   8808     phymod_phy_access_t pm_phy_copy;
   8809     uint32_t if_side = 0;
   8810     uint32_t chip_id = 0;
   8811     uint32 simplex_tx = 0;
   8812     uint32              lane_map;
   8813     pmc = &pc->phymod_ctrl;
   8814 
   8815     /* locate the desired phy and lane */
   8816     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   8817 
   8818     /* Make a copy of the phy access and overwrite the desired lane */
   8819     pm_phy = &p_phy->pm_phy;
   8820 
   8821     simplex_tx = SIMPLEX_TX(pc);
   8822     chip_id = DEVID(pc);
   8823     SOC_IF_ERROR_RETURN
   8824         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   8825     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   8826     pm_phy_copy.access.lane_mask = lane_map;
   8827     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   8828     pm_phy_copy.access.flags |= if_side;
   8829 
   8830     sal_memset(&fw_config, 0, sizeof(fw_config));
   8831     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_get(&pm_phy_copy, &fw_config));
   8832 
   8833     if (enable) {
   8834         fw_config.UnreliableLos = 1;
   8835     } else {
   8836         fw_config.UnreliableLos = 0;
   8837     }
   8838 
   8839     SOC_IF_ERROR_RETURN(phymod_phy_firmware_lane_config_set(&pm_phy_copy, fw_config));
   8840 
   8841     return(SOC_E_NONE);
   8842 }
   8843 /*
   8844  * Function:
   8845  *      phy_82381_control_set
   8846  * Purpose:
   8847  *      Configure PHY device specific control fucntion.
   8848  * Parameters:
   8849  *      unit  - BCM unit number.
   8850  *      port  - Port number.
   8851  *      type  - Control to update
   8852  *      value - New setting for the control
   8853  * Returns:
   8854  *      SOC_E_NONE
   8855  */
   8856 STATIC int
   8857 phy_82381_control_set(int unit, soc_port_t port, soc_phy_control_t type, uint32 value)
   8858 {
   8859     int                 rv;
   8860     phy_ctrl_t          *pc;
   8861     phy82381_config_t       *pCfg;
   8862     int32 intf;
   8863     uint32 simplex_tx = 0;
   8864     uint32_t chip_id = 0;
   8865     rv = SOC_E_UNAVAIL;
   8866 
   8867     PHY_CONTROL_TYPE_CHECK(type);
   8868 
   8869     /* locate phy control, phymod control, and the configuration data */
   8870     pc = EXT_PHY_SW_STATE(unit, port);
   8871     if (pc == NULL) {
   8872         return SOC_E_INTERNAL;
   8873     }
   8874     pCfg = (phy82381_config_t *) pc->driver_data;
   8875     simplex_tx = SIMPLEX_TX(pc);
   8876     chip_id = DEVID(pc);
   8877 
   8878 
   8879 
   8880     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82381_SYS_SIDE : PHY82381_LINE_SIDE;
   8881     switch(type) {
   8882     /* decoupled PRBS */
   8883     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL:
   8884         rv = phy_82381_prbs_tx_poly_set(pc, intf, value);
   8885         break;
   8886     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA:
   8887         rv = phy_82381_prbs_tx_invert_data_set(pc, intf, value);
   8888         break;
   8889     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE:
   8890         rv = phy_82381_prbs_tx_enable_set(pc, intf, value);
   8891         break;
   8892     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL:
   8893         rv = phy_82381_prbs_rx_poly_set(pc, intf, value);
   8894         break;
   8895     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA:
   8896         rv = phy_82381_prbs_rx_invert_data_set(pc, intf, value);
   8897         break;
   8898     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE:
   8899         rv = phy_82381_prbs_rx_enable_set(pc, intf, value);
   8900         break;
   8901     /* for legacy prbs usage mainly set both tx/rx the same */
   8902     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   8903         if(FURIA_IS_SIMPLEX(chip_id)){
   8904             if (!simplex_tx) {  /*simplex Rx package */
   8905                 if(intf == PHY82381_SYS_SIDE) {
   8906                     rv = phy_82381_prbs_tx_poly_set(pc, intf, value);
   8907                 } else {
   8908                     rv = phy_82381_prbs_rx_poly_set(pc, intf, value);
   8909                 }
   8910             } else { /* Simplex Tx package */
   8911                 if(intf == PHY82381_SYS_SIDE) {
   8912                     rv = phy_82381_prbs_rx_poly_set(pc, intf, value);
   8913                 } else {
   8914                     rv = phy_82381_prbs_tx_poly_set(pc, intf, value);
   8915                 }
   8916             }
   8917         } else {
   8918             rv = phy_82381_prbs_tx_poly_set(pc, intf, value);
   8919             rv = phy_82381_prbs_rx_poly_set(pc, intf, value);
   8920         }
   8921         break;
   8922     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   8923         if(FURIA_IS_SIMPLEX(chip_id)){
   8924             if (!simplex_tx) {  /*simplex Rx package */
   8925                 if(intf == PHY82381_SYS_SIDE) {
   8926                     rv = phy_82381_prbs_tx_invert_data_set(pc, intf, value);
   8927                 } else {
   8928                     rv = SOC_E_NONE;
   8929                 }
   8930             } else { /* Simplex Tx package */
   8931                 if(intf == PHY82381_LINE_SIDE) {
   8932                     rv = phy_82381_prbs_tx_invert_data_set(pc, intf, value);
   8933                 } else {
   8934                     rv = SOC_E_NONE;
   8935                 }
   8936             }
   8937         } else {
   8938             rv = phy_82381_prbs_tx_invert_data_set(pc, intf, value);
   8939         }
   8940         break;
   8941     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   8942         if(FURIA_IS_SIMPLEX(chip_id)){
   8943             if (!simplex_tx) {  /*simplex Rx package */
   8944                 if(intf == PHY82381_SYS_SIDE) {
   8945                     rv = phy_82381_prbs_tx_enable_set(pc, intf, value);
   8946                 } else {
   8947                     rv = phy_82381_prbs_rx_enable_set(pc, intf, value);
   8948                 }
   8949             } else { /* Simplex Tx package */
   8950                 if(intf == PHY82381_SYS_SIDE) {
   8951                     rv = phy_82381_prbs_rx_enable_set(pc, intf, value);
   8952                 } else {
   8953                     rv = phy_82381_prbs_tx_enable_set(pc, intf, value);
   8954                 }
   8955             }
   8956         } else {
   8957             rv = phy_82381_prbs_tx_enable_set(pc, intf, value);
   8958             rv = phy_82381_prbs_rx_enable_set(pc, intf, value);
   8959         }
   8960         break;
   8961     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   8962         if(FURIA_IS_SIMPLEX(chip_id)){
   8963             if (!simplex_tx) {  /*simplex Rx package */
   8964                 if(intf == PHY82381_SYS_SIDE) {
   8965                     rv = phy_82381_prbs_tx_enable_set(pc, intf, value);
   8966                 } else {
   8967                     rv = phy_82381_prbs_rx_enable_set(pc, intf, value);
   8968                 }
   8969             } else { /* Simplex Tx package */
   8970                 if(intf == PHY82381_SYS_SIDE) {
   8971                     rv = phy_82381_prbs_rx_enable_set(pc, intf, value);
   8972                 } else {
   8973                     rv = phy_82381_prbs_tx_enable_set(pc, intf, value);
   8974                 }
   8975             }
   8976         } else {
   8977             rv = phy_82381_prbs_tx_enable_set(pc, intf, value);
   8978             rv = phy_82381_prbs_rx_enable_set(pc, intf, value);
   8979         }
   8980         break;
   8981     /* LOOPBACK */
   8982     case SOC_PHY_CONTROL_LOOPBACK_PMD:
   8983         rv = phy_82381_loopback_internal_pmd_set(pc, intf, value);
   8984        break;
   8985     case SOC_PHY_CONTROL_LOOPBACK_REMOTE:
   8986     case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS:
   8987         rv = phy_82381_loopback_remote_set(pc, intf, value);
   8988         break;
   8989     case SOC_PHY_CONTROL_TX_FIR_PRE:
   8990         rv = phy_82381_tx_fir_pre_set(pc, intf, value);
   8991         break;
   8992     case SOC_PHY_CONTROL_TX_FIR_MAIN:
   8993         rv = phy_82381_tx_fir_main_set(pc, intf, value);
   8994         break;
   8995     case SOC_PHY_CONTROL_TX_FIR_POST:
   8996         rv = phy_82381_tx_fir_post_set(pc, intf, value);
   8997         break;
   8998     case SOC_PHY_CONTROL_TX_FIR_POST2:
   8999         rv = phy_82381_tx_fir_post2_set(pc, intf, value);
   9000         break;
   9001     case SOC_PHY_CONTROL_TX_FIR_POST3:
   9002         rv = phy_82381_tx_fir_post3_set(pc, intf, value);
   9003         break;
   9004     /* PREEMPHASIS */
   9005     case SOC_PHY_CONTROL_PREEMPHASIS_LANE0:
   9006         rv = phy_82381_per_lane_preemphasis_set(pc, intf, 0, value);
   9007         break;
   9008     case SOC_PHY_CONTROL_PREEMPHASIS_LANE1:
   9009         rv = phy_82381_per_lane_preemphasis_set(pc, intf, 1, value);
   9010         break;
   9011     case SOC_PHY_CONTROL_PREEMPHASIS_LANE2:
   9012         rv = phy_82381_per_lane_preemphasis_set(pc, intf, 2, value);
   9013         break;
   9014     case SOC_PHY_CONTROL_PREEMPHASIS_LANE3:
   9015         rv = phy_82381_per_lane_preemphasis_set(pc, intf, 3, value);
   9016         break;
   9017     case SOC_PHY_CONTROL_PREEMPHASIS:
   9018         rv = phy_82381_preemphasis_set(pc, intf, value);
   9019         break;
   9020 
   9021     /* DRIVER CURRENT */
   9022     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0:
   9023         rv = phy_82381_per_lane_driver_current_set(pc, intf, 0, value);
   9024         break;
   9025     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1:
   9026         rv = phy_82381_per_lane_driver_current_set(pc, intf, 1, value);
   9027         break;
   9028     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2:
   9029         rv = phy_82381_per_lane_driver_current_set(pc, intf, 2, value);
   9030         break;
   9031     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3:
   9032         rv = phy_82381_per_lane_driver_current_set(pc, intf, 3, value);
   9033         break;
   9034     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   9035         rv = phy_82381_driver_current_set(pc, intf, value);
   9036         break;
   9037     /* TX LANE SQUELCH */
   9038     case SOC_PHY_CONTROL_TX_LANE_SQUELCH:
   9039         rv = phy_82381_tx_lane_squelch(pc, intf, value);
   9040         break;
   9041     /* RX PEAK FILTER */
   9042     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   9043         rv = phy_82381_rx_peak_filter_set(pc, intf, value);
   9044         break;
   9045 
   9046     /* RX VGA */
   9047     case SOC_PHY_CONTROL_RX_VGA:
   9048         rv = phy_82381_rx_vga_set(pc, intf, 1, value);
   9049         break;
   9050     /* RX VGA RELEASE */
   9051     case SOC_PHY_CONTROL_RX_VGA_RELEASE:
   9052         rv = phy_82381_rx_vga_set(pc, intf, 0, value);
   9053         break;
   9054     /* RX TAP */
   9055     case SOC_PHY_CONTROL_RX_TAP1:
   9056         rv = phy_82381_rx_tap_set(pc, intf, 0, value);
   9057         break;
   9058     case SOC_PHY_CONTROL_RX_TAP2:
   9059         rv = phy_82381_rx_tap_set(pc, intf, 1, value);
   9060         break;
   9061     case SOC_PHY_CONTROL_RX_TAP3:
   9062         rv = phy_82381_rx_tap_set(pc, intf, 2, value);
   9063         break;
   9064     case SOC_PHY_CONTROL_RX_TAP4:
   9065         rv = phy_82381_rx_tap_set(pc, intf, 3, value);
   9066         break;
   9067     case SOC_PHY_CONTROL_RX_TAP5:
   9068         rv = phy_82381_rx_tap_set(pc, intf, 4, value);
   9069         break;
   9070     case SOC_PHY_CONTROL_RX_TAP1_RELEASE:       /* $$$ tbd $$$ */
   9071        rv = phy_82381_rx_tap_release(pc, intf, 0);
   9072        break;
   9073     case SOC_PHY_CONTROL_RX_TAP2_RELEASE:       /* $$$ tbd $$$ */
   9074        rv = phy_82381_rx_tap_release(pc, intf, 1);
   9075        break;
   9076     case SOC_PHY_CONTROL_RX_TAP3_RELEASE:       /* $$$ tbd $$$ */
   9077        rv = phy_82381_rx_tap_release(pc, intf, 2);
   9078        break;
   9079     case SOC_PHY_CONTROL_RX_TAP4_RELEASE:       /* $$$ tbd $$$ */
   9080        rv = phy_82381_rx_tap_release(pc, intf, 3);
   9081        break;
   9082     case SOC_PHY_CONTROL_RX_TAP5_RELEASE:       /* $$$ tbd $$$ */
   9083        rv = phy_82381_rx_tap_release(pc, intf, 4);
   9084        break;
   9085     /* PHASE INTERPOLATOR */
   9086     case SOC_PHY_CONTROL_PHASE_INTERP:
   9087         rv = phy_82381_pi_control_set(pc, intf, value);
   9088         break;
   9089     /* POLARITY */
   9090     case SOC_PHY_CONTROL_RX_POLARITY:
   9091         rv = phy_82381_rx_polarity_set(pc, &pCfg->phy_polarity_config, intf, value);;
   9092         break;
   9093     case SOC_PHY_CONTROL_TX_POLARITY:
   9094         rv = phy_82381_tx_polarity_set(pc, &pCfg->phy_polarity_config, intf, value);
   9095         break;
   9096     /* RESET */
   9097     case SOC_PHY_CONTROL_RX_RESET:
   9098         rv = phy_82381_rx_reset(pc, &pCfg->phy_reset_config, intf, value);
   9099         break;
   9100     case SOC_PHY_CONTROL_TX_RESET:
   9101         rv = phy_82381_tx_reset(pc, &pCfg->phy_reset_config, intf, value);
   9102         break;
   9103     /* POWER */
   9104     case SOC_PHY_CONTROL_POWER:
   9105        {
   9106            phy_ctrl_t                *int_pc;
   9107            int_pc = INT_PHY_SW_STATE(unit, port);
   9108            SOC_IF_ERROR_RETURN(PHY_ENABLE_SET(int_pc->pd, unit, port, value));
   9109            rv = phy_82381_power_set(pc, intf, value);
   9110        }
   9111        break;
   9112     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   9113         rv = phy_82381_rx_low_freq_filter_set(pc, intf, value);
   9114     break;
   9115     case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION:
   9116        rv = phy_82381_fec_enable_set(pc, value);
   9117        break;
   9118     case SOC_PHY_CONTROL_RX_SEQ_TOGGLE:
   9119         rv = phy_82381_rx_seq_restart(pc, intf, value);
   9120     break;
   9121     case SOC_PHY_CONTROL_DUMP:
   9122         rv = phy_82381_phy_dump(pc, intf);
   9123     break;
   9124     case SOC_PHY_CONTROL_CL72:
   9125         rv = phy_82381_cl72_enable_set(pc, intf, value);
   9126     break;
   9127     case SOC_PHY_CONTROL_INTR_MASK:
   9128         rv = phy_82381_intr_enable_set(pc, intf, value);
   9129     break;
   9130     case SOC_PHY_CONTROL_XSW_LANE_MAP:
   9131         rv = phy_82381_cross_switch_swap_set(pc, intf, value);
   9132     break;
   9133     case SOC_PHY_CONTROL_GPIO_CONFIG:
   9134         rv = phy_82381_gpio_config_set(pc, value);
   9135     break;
   9136     case SOC_PHY_CONTROL_GPIO_VALUE:
   9137         rv = phy_82381_gpio_value_set(pc, value);
   9138     break;
   9139     /* FIRMWARE MODE */
   9140     case SOC_PHY_CONTROL_FIRMWARE_MODE:
   9141         rv = phy_82381_firmware_mode_set(pc, intf, value);
   9142         break;
   9143     case SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE:
   9144         rv = phy_82381_firmware_dfe_enable_set(pc, intf, value);
   9145         break;
   9146     case SOC_PHY_CONTROL_FIRMWARE_LP_DFE_ENABLE:
   9147         rv = phy_82381_firmware_lp_dfe_enable_set(pc, intf, value);
   9148         break;
   9149     case SOC_PHY_CONTROL_FIRMWARE_BR_DFE_ENABLE:
   9150         rv = phy_82381_firmware_br_dfe_enable_set(pc, intf, value);
   9151         break;
   9152     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE:
   9153         rv = phy_82381_short_chn_mode_enable_set(pc, intf, value);
   9154         break;
   9155     case SOC_PHY_CONTROL_UNRELIABLE_LOS:
   9156         rv = phy_82381_unreliable_los_set(pc, intf, value);
   9157     break;
   9158     default:
   9159         rv = SOC_E_UNAVAIL;
   9160         break;
   9161     }
   9162     return rv;
   9163 }
   9164 /*
   9165  * Function:
   9166  *      phy_82381_per_lane_control_set
   9167  * Purpose:
   9168  *      Configure PHY device specific control fucntion.
   9169  * Parameters:
   9170  *      unit  - StrataSwitch unit #.
   9171  *      port  - StrataSwitch port #.
   9172  *      lane  - lane number
   9173  *      type  - Control to update
   9174  *      value - New setting for the control
   9175  * Returns:
   9176  *      SOC_E_NONE
   9177  */
   9178 STATIC int
   9179 phy_82381_per_lane_control_set(int unit, soc_port_t port, int lane, soc_phy_control_t type, uint32 value)
   9180 {
   9181     int                 rv = SOC_E_UNAVAIL;
   9182     phy_ctrl_t          *pc;
   9183     phy82381_config_t       *pCfg;
   9184     int32 intf;
   9185     uint32 simplex_tx = 0;
   9186     uint32_t chip_id = 0;
   9187 
   9188     /* locate phy control, phymod control, and the configuration data */
   9189     pc = EXT_PHY_SW_STATE(unit, port);
   9190     if (pc == NULL) {
   9191         return SOC_E_INTERNAL;
   9192     }
   9193     pCfg = (phy82381_config_t *) pc->driver_data;
   9194     simplex_tx = SIMPLEX_TX(pc);
   9195     chip_id = DEVID(pc);
   9196 
   9197     PHY_CONTROL_TYPE_CHECK(type);
   9198 
   9199     intf = (pc->flags & PHYCTRL_SYS_SIDE_CTRL) ? PHY82381_SYS_SIDE : PHY82381_LINE_SIDE;
   9200 
   9201     switch(type) {
   9202     case SOC_PHY_CONTROL_PREEMPHASIS:
   9203         rv = phy_82381_per_lane_preemphasis_set(pc, intf, lane, value);
   9204         break;
   9205     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   9206         rv = phy_82381_per_lane_driver_current_set(pc, intf, lane, value);
   9207         break;
   9208     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT:
   9209         rv = SOC_E_UNAVAIL;
   9210         break;
   9211     case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT:
   9212         rv = SOC_E_UNAVAIL;
   9213         break;
   9214     case SOC_PHY_CONTROL_RX_TAP1:
   9215         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 0 /* tap */, 1 /* enable */, value);
   9216         break;
   9217     case SOC_PHY_CONTROL_RX_TAP1_RELEASE:
   9218         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 0 /* tap */, 0 /* release */, 0x8000);
   9219         break;
   9220     case SOC_PHY_CONTROL_RX_TAP2:
   9221         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 1 /* tap */, 1 /* enable */, value);
   9222         break;
   9223     case SOC_PHY_CONTROL_RX_TAP2_RELEASE:
   9224         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 1 /* tap */, 0 /* release */, 0x8000);
   9225         break;
   9226     case SOC_PHY_CONTROL_RX_TAP3:
   9227         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 2 /* tap */, 1 /* enable */, value);
   9228         break;
   9229     case SOC_PHY_CONTROL_RX_TAP3_RELEASE:
   9230         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 2 /* tap */, 0 /* release */, 0x8000);
   9231         break;
   9232     case SOC_PHY_CONTROL_RX_TAP4:
   9233         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 3 /* tap */, 1 /* enable */, value);
   9234         break;
   9235     case SOC_PHY_CONTROL_RX_TAP4_RELEASE:
   9236         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 3 /* tap */, 0 /* release */, 0x8000);
   9237         break;
   9238     case SOC_PHY_CONTROL_RX_TAP5:
   9239         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 4 /* tap */, 1 /* enable */, value);
   9240         break;
   9241     case SOC_PHY_CONTROL_RX_TAP5_RELEASE:
   9242         rv = phy_82381_per_lane_rx_dfe_tap_control_set (pc, intf, lane, 4 /* tap */, 0 /* release */, 0x8000);
   9243         break;
   9244     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL:
   9245         rv = phy_82381_per_lane_prbs_tx_poly_set(pc, intf, lane, value);
   9246         break;
   9247     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA:
   9248         rv = phy_82381_per_lane_prbs_tx_invert_data_set(pc, intf, lane, value);
   9249         break;
   9250     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE:
   9251         rv = phy_82381_per_lane_prbs_tx_enable_set(pc, intf, lane, value);
   9252         break;
   9253     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL:
   9254         rv = phy_82381_per_lane_prbs_rx_poly_set(pc, intf, lane, value);
   9255         break;
   9256     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA:
   9257         rv = phy_82381_per_lane_prbs_rx_invert_data_set(pc, intf, lane, value);
   9258         break;
   9259     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE:
   9260         rv = phy_82381_per_lane_prbs_rx_enable_set(pc, intf, lane, value);
   9261         break;
   9262     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   9263         if(FURIA_IS_SIMPLEX(chip_id)){
   9264             if (!simplex_tx) {  /*simplex Rx package */
   9265                 if(intf == PHY82381_SYS_SIDE) {
   9266                     rv = phy_82381_per_lane_prbs_tx_poly_set(pc, intf, lane, value);
   9267                 } else {
   9268                     rv = phy_82381_per_lane_prbs_rx_poly_set(pc, intf, lane, value);
   9269                 }
   9270             } else { /* Simplex Tx package */
   9271                 if(intf == PHY82381_SYS_SIDE) {
   9272                     rv = phy_82381_per_lane_prbs_rx_poly_set(pc, intf, lane, value);
   9273                 } else {
   9274                     rv = phy_82381_per_lane_prbs_tx_poly_set(pc, intf, lane, value);
   9275                 }
   9276             }
   9277         } else {
   9278             rv = phy_82381_per_lane_prbs_tx_poly_set(pc, intf, lane, value);
   9279             rv = phy_82381_per_lane_prbs_rx_poly_set(pc, intf, lane, value);
   9280         }
   9281         break;
   9282     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   9283         if(FURIA_IS_SIMPLEX(chip_id)){
   9284             if (!simplex_tx) {  /*simplex Rx package */
   9285                 if(intf == PHY82381_SYS_SIDE) {
   9286                     rv = phy_82381_per_lane_prbs_tx_invert_data_set(pc, intf, lane, value);
   9287                 } else {
   9288                     rv = SOC_E_NONE;
   9289                 }
   9290             } else { /* Simplex Tx package */
   9291                 if(intf == PHY82381_LINE_SIDE) {
   9292                     rv = phy_82381_per_lane_prbs_tx_invert_data_set(pc, intf, lane, value);
   9293                 } else {
   9294                     rv = SOC_E_NONE;
   9295                 }
   9296             }
   9297         } else {
   9298             rv = phy_82381_per_lane_prbs_tx_invert_data_set(pc, intf, lane, value);
   9299         }
   9300         break;
   9301     case SOC_PHY_CONTROL_PRBS_RX_INVERT_DATA:
   9302         rv = phy_82381_per_lane_prbs_rx_invert_data_set(pc, intf, lane, value);
   9303         break;
   9304     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   9305         /* TX_ENABLE does both tx and rx */
   9306         if(FURIA_IS_SIMPLEX(chip_id)){
   9307             if (!simplex_tx) {  /*simplex Rx package */
   9308                 if(intf == PHY82381_SYS_SIDE) {
   9309                     rv = phy_82381_per_lane_prbs_tx_enable_set(pc, intf, lane, value);
   9310                 } else {
   9311                     rv = phy_82381_per_lane_prbs_rx_enable_set(pc, intf, lane, value);
   9312                 }
   9313             } else { /* Simplex Tx package */
   9314                 if(intf == PHY82381_SYS_SIDE) {
   9315                     rv = phy_82381_per_lane_prbs_rx_enable_set(pc, intf, lane, value);
   9316                 } else {
   9317                     rv = phy_82381_per_lane_prbs_tx_enable_set(pc, intf, lane, value);
   9318                 }
   9319             }
   9320         } else {
   9321             rv = phy_82381_per_lane_prbs_tx_enable_set(pc, intf, lane, value);
   9322             rv = phy_82381_per_lane_prbs_rx_enable_set(pc, intf, lane, value);
   9323         }
   9324         break;
   9325     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   9326         if(FURIA_IS_SIMPLEX(chip_id)){
   9327             if (!simplex_tx) {  /*simplex Rx package */
   9328                 if(intf == PHY82381_SYS_SIDE) {
   9329                     rv = phy_82381_per_lane_prbs_tx_enable_set(pc, intf, lane, value);
   9330                 } else {
   9331                     rv = phy_82381_per_lane_prbs_rx_enable_set(pc, intf, lane, value);
   9332                 }
   9333             } else { /* Simplex Tx package */
   9334                 if(intf == PHY82381_SYS_SIDE) {
   9335                     rv = phy_82381_per_lane_prbs_rx_enable_set(pc, intf, lane, value);
   9336                 } else {
   9337                     rv = phy_82381_per_lane_prbs_tx_enable_set(pc, intf, lane, value);
   9338                 }
   9339             }
   9340         } else {
   9341             rv = phy_82381_per_lane_prbs_tx_enable_set(pc, intf, lane, value);
   9342             rv = phy_82381_per_lane_prbs_rx_enable_set(pc, intf, lane, value);
   9343         }
   9344         break;
   9345     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   9346         rv = phy_82381_per_lane_rx_peak_filter_set(pc, intf, lane, 1 /* enable */, value);
   9347         break;
   9348     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   9349         rv = phy_82381_per_lane_rx_low_freq_filter_set(pc, intf, lane, value);
   9350         break;
   9351     case SOC_PHY_CONTROL_RX_VGA:
   9352         rv = phy_82381_per_lane_rx_vga_set(pc, intf, lane, 1 /* enable */, value);
   9353         break;
   9354     case SOC_PHY_CONTROL_RX_VGA_RELEASE:
   9355         rv = phy_82381_per_lane_rx_vga_set(pc, intf, lane, 0 /* release */, 0x8000);
   9356         break;
   9357     case SOC_PHY_CONTROL_RX_PLUS1_SLICER:
   9358         rv = SOC_E_UNAVAIL;
   9359         break;
   9360     case SOC_PHY_CONTROL_RX_MINUS1_SLICER:
   9361         rv = SOC_E_UNAVAIL;
   9362         break;
   9363     case SOC_PHY_CONTROL_RX_D_SLICER:
   9364         rv = SOC_E_UNAVAIL;
   9365         break;
   9366     /* TX LANE SQUELCH */
   9367     case SOC_PHY_CONTROL_TX_LANE_SQUELCH:
   9368         rv = phy_82381_per_lane_tx_lane_squelch(pc, intf, lane, value);
   9369         break;
   9370     /* POWER */
   9371     case SOC_PHY_CONTROL_POWER:
   9372        rv = phy_82381_per_lane_power_set(pc, intf, lane, value);
   9373        break;
   9374     /* POLARITY */
   9375     case SOC_PHY_CONTROL_RX_POLARITY:
   9376         rv = phy_82381_per_lane_rx_polarity_set(pc, &pCfg->phy_polarity_config, intf, lane, value);;
   9377         break;
   9378     case SOC_PHY_CONTROL_TX_POLARITY:
   9379         rv = phy_82381_per_lane_tx_polarity_set(pc, &pCfg->phy_polarity_config,
   9380  intf, lane, value);
   9381         break;
   9382     /* LOOPBACK */
   9383     case SOC_PHY_CONTROL_LOOPBACK_PMD:
   9384         rv = phy_82381_per_lane_loopback_internal_pmd_set(pc, intf, lane, value);
   9385        break;
   9386     case SOC_PHY_CONTROL_LOOPBACK_REMOTE:
   9387     case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS:
   9388         rv = phy_82381_per_lane_loopback_remote_set(pc, intf, lane, value);
   9389         break;
   9390     case SOC_PHY_CONTROL_DUMP:
   9391         rv = phy_82381_per_lane_phy_dump(pc, intf, lane);
   9392     break;
   9393     case SOC_PHY_CONTROL_TX_FIR_PRE:
   9394     case SOC_PHY_CONTROL_TX_FIR_MAIN:
   9395     case SOC_PHY_CONTROL_TX_FIR_POST:
   9396     case SOC_PHY_CONTROL_TX_FIR_POST2:
   9397     case SOC_PHY_CONTROL_TX_FIR_POST3:
   9398         rv = phy_82381_per_lane_tx_set(pc, intf, type, lane, value);
   9399         break;
   9400     /* FIRMWARE MODE */
   9401     case SOC_PHY_CONTROL_FIRMWARE_MODE:
   9402         rv = phy_82381_per_lane_firmware_mode_set(pc, intf, lane, value);
   9403         break;
   9404     case SOC_PHY_CONTROL_FIRMWARE_DFE_ENABLE:
   9405         rv = phy_82381_per_lane_firmware_dfe_enable_set(pc, intf, lane, value);
   9406         break;
   9407     case SOC_PHY_CONTROL_FIRMWARE_LP_DFE_ENABLE:
   9408         rv = phy_82381_per_lane_firmware_lp_dfe_enable_set(pc, intf, lane, value);
   9409         break;
   9410     case SOC_PHY_CONTROL_FIRMWARE_BR_DFE_ENABLE:
   9411         rv = phy_82381_per_lane_firmware_br_dfe_enable_set(pc, intf, lane, value);
   9412         break;
   9413     case SOC_PHY_CONTROL_SHORT_CHANNEL_MODE:
   9414         rv = phy_82381_per_lane_short_chn_mode_enable_set(pc, port, intf, lane, value);
   9415     break;
   9416     case SOC_PHY_CONTROL_UNRELIABLE_LOS:
   9417         rv = phy_82381_per_lane_unreliable_los_set(pc, intf, lane, value);
   9418     break;
   9419     default:
   9420         rv = SOC_E_UNAVAIL;
   9421         break;
   9422     }
   9423 
   9424     return rv;
   9425 }
   9426 
   9427 STATIC int phy_82381_diag_eyescan(soc_port_t port, phy_ctrl_t *pc, int32 intf, int32 lane)
   9428 {
   9429     phymod_phy_access_t     *pm_phy;
   9430     int                     idx = 0, rv = 0;
   9431     phymod_phy_access_t     pm_phy_copy;
   9432     soc_phymod_phy_t        *p_phy;
   9433     uint32_t lane_map = 0;
   9434     uint32_t if_side = 0;
   9435     uint32_t chip_id = 0;
   9436     uint32 simplex_tx = 0;
   9437     soc_phymod_ctrl_t *pmc;
   9438     pmc = &pc->phymod_ctrl;
   9439 
   9440     intf = (intf == PHY_DIAG_INTF_SYS) ? PHY82381_SYS_SIDE : PHY82381_LINE_SIDE;
   9441     for (idx = 0; idx < pmc->num_phys; idx++) {
   9442         if (pmc->phy[idx] == NULL) {
   9443             return SOC_E_INTERNAL;
   9444         }
   9445         p_phy = pmc->phy[idx];
   9446 
   9447         /* Make a copy of the phy access and overwrite the desired lane */
   9448         pm_phy = &p_phy->pm_phy;
   9449 
   9450         simplex_tx = SIMPLEX_TX(pc);
   9451         chip_id = DEVID(pc);
   9452 
   9453         SOC_IF_ERROR_RETURN
   9454             (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
   9455         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   9456 
   9457         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   9458         pm_phy_copy.access.flags |= if_side;
   9459         if (lane == 0xf) {
   9460             /* Get p_phy alone and let lane map be as Phy structure value */
   9461             lane = 1;
   9462             SOC_IF_ERROR_RETURN(
   9463                     _phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   9464             lane = 0xf;
   9465         } else {
   9466             SOC_IF_ERROR_RETURN(
   9467                 _phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   9468         }
   9469         /* Make a copy of the phy access and overwrite the desired lane */
   9470         if (lane != 0xf) {
   9471            pm_phy_copy.access.lane_mask = lane_map;
   9472         }
   9473 
   9474         is_eye_scan_enabled = 1;
   9475         rv = phymod_phy_eyescan_run(&pm_phy_copy, PHYMOD_EYESCAN_F_DONE, 0, NULL);
   9476         if (rv != SOC_E_NONE) {
   9477             is_eye_scan_enabled = 0;
   9478             return rv;
   9479         }
   9480     }
   9481     is_eye_scan_enabled = 0;
   9482     return SOC_E_NONE;
   9483 }
   9484 STATIC int
   9485 phy_82381_diag_dsc(phy_ctrl_t *pc, int32 intf)
   9486 {
   9487     phymod_phy_access_t  *pm_phy;
   9488     int                    idx;
   9489     phymod_phy_access_t pm_phy_copy;
   9490     soc_phymod_phy_t    *p_phy;
   9491     phymod_phy_diagnostics_t phy_diag;
   9492     uint16_t lane_index = 0;
   9493     uint32_t if_side = 0;
   9494     uint32_t chip_id = 0;
   9495     uint32 simplex_tx = 0;
   9496     uint32 num_lanes = 0;
   9497     soc_phymod_ctrl_t *pmc;
   9498     pmc = &pc->phymod_ctrl;
   9499 
   9500 
   9501     for (idx = 0; idx < pmc->num_phys; idx++) {
   9502         if (pmc->phy[idx] == NULL) {
   9503             return SOC_E_INTERNAL;
   9504         }
   9505         p_phy = pmc->phy[idx];
   9506         /* Make a copy of the phy access and overwrite the desired lane */
   9507         pm_phy = &p_phy->pm_phy;
   9508 
   9509         simplex_tx = SIMPLEX_TX(pc);
   9510         chip_id = DEVID(pc);
   9511 
   9512         if(FURIA_IS_SIMPLEX(chip_id)){
   9513             if (!simplex_tx) { /* Rx simplex package */
   9514                 if (intf == PHY_DIAG_INTF_SYS) {
   9515                     if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   9516                 } else {
   9517                     if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   9518                     if_side |= (1 << INTERFACE_SIDE_SHIFT);
   9519                 }
   9520             } else { /* Tx simplex package */
   9521                 if (intf == PHY_DIAG_INTF_SYS) {
   9522                     if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   9523                     if_side |= (1 << INTERFACE_SIDE_SHIFT);
   9524                 } else {
   9525                     if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   9526                 }
   9527             }
   9528         } else {
   9529             if (intf == PHY_DIAG_INTF_SYS) {
   9530                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   9531                 if_side |= (1 << INTERFACE_SIDE_SHIFT);
   9532             } else {
   9533                 if_side &= ~(1 << INTERFACE_SIDE_SHIFT);
   9534             }
   9535         }
   9536         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   9537         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   9538         pm_phy_copy.access.flags |= if_side;
   9539         LOG_CLI((BSL_META_U(pmc->unit,
   9540                                     "DSC parameters for port %d\n"), pc->port));
   9541         if(FURIA_IS_SIMPLEX(chip_id)){
   9542             if (chip_id == FURIA_ID_82212) {
   9543                 num_lanes = 12;
   9544             } else {
   9545                 num_lanes = 8;
   9546             }
   9547         } else {
   9548             num_lanes = 4;
   9549         }
   9550         for (lane_index = 0; lane_index < num_lanes; lane_index ++) {
   9551             if ((pm_phy->access.lane_mask & (1 << lane_index))) {
   9552                 pm_phy_copy.access.lane_mask = (1 << lane_index);
   9553                 SOC_IF_ERROR_RETURN(phymod_phy_diagnostics_get(&pm_phy_copy, &phy_diag));
   9554 
   9555                 /* display */
   9556                 LOG_CLI((BSL_META_U(pc->unit,
   9557                                     "LaneN SIGDET VGABIASREDUCED POSTCMET OSR PMDMODE "
   9558                                     "RXLOCK RXPPM TXPPM CLK90OFFSET CLKP1OFFSET P1LVL1 "
   9559                                     "M1LVL1 DFE1_DCD DFE2_DCD SLICERTARGET PE ZE ME "
   9560                                     "PO ZO MO HLFT HRGT VUPPR VLOWR SMSTS LNKTM "
   9561                                     "MAIN HIZ BST\n")));
   9562                 LOG_CLI((BSL_META_U(pc->unit,
   9563                                     "%05d %03d     %06d        %07d  %03d  %05d  %05d %05d %06d  %05d        %08d "
   9564                                     "  %03d   %05d    %04d   %04d      %04d        %02d %02d %02d %02d %02d %02d"
   9565                                     " %03d  %04d %05d %05d %04d  %05d %04d %03d %03d \n"),
   9566                          (lane_index), phy_diag.signal_detect, phy_diag.vga_bias_reduced,
   9567                          phy_diag.postc_metric, phy_diag.osr_mode, phy_diag.pmd_mode,
   9568                          phy_diag.rx_lock, phy_diag.rx_ppm, phy_diag.tx_ppm,
   9569                          phy_diag.clk90_offset, phy_diag.clkp1_offset,
   9570                          phy_diag.p1_lvl, phy_diag.m1_lvl, phy_diag.dfe1_dcd,
   9571                          phy_diag.dfe2_dcd, phy_diag.slicer_target,
   9572                          phy_diag.slicer_offset.offset_pe, phy_diag.slicer_offset.offset_ze,
   9573                          phy_diag.slicer_offset.offset_me, phy_diag.slicer_offset.offset_po,
   9574                          phy_diag.slicer_offset.offset_zo,  phy_diag.slicer_offset.offset_mo,
   9575                          phy_diag.eyescan.heye_left, phy_diag.eyescan.heye_right,
   9576                          phy_diag.eyescan.veye_upper, phy_diag.eyescan.veye_lower,
   9577                          phy_diag.state_machine_status, phy_diag.link_time,
   9578                          phy_diag.pf_main, phy_diag.pf_hiz,
   9579                          phy_diag.pf_bst));
   9580                 LOG_CLI((BSL_META_U(pc->unit,
   9581                                     "LOW PF2CTRL VGA DCOFFT P1LVLCTRL "
   9582                                     "DFE1 DFE2 DFE3 DFE4 DFE5 DFE6 PRE MAIN POST1 "
   9583                                     "POST2 POST3 TXAMPCTRL BRPDEN \n")));
   9584 
   9585                 LOG_CLI((BSL_META_U(pc->unit,
   9586                                     "%03d %07d %03d %06d   %04d    %04d %04d %04d %04d %04d %04d %04d"
   9587                                     " %03d %04d  %05d %05d   %04d    %04d\n\n"),
   9588                          phy_diag.pf_low,
   9589                          phy_diag.pf2_ctrl, phy_diag.vga,
   9590                          phy_diag.dc_offset, phy_diag.p1_lvl_ctrl,
   9591                          phy_diag.dfe1, phy_diag.dfe2,
   9592                          phy_diag.dfe3, phy_diag.dfe4,
   9593                          phy_diag.dfe5, phy_diag.dfe6,
   9594                          phy_diag.txfir_pre, phy_diag.txfir_main,
   9595                          phy_diag.txfir_post1, phy_diag.txfir_post2,
   9596                          phy_diag.txfir_post3, phy_diag.tx_amp_ctrl,
   9597                          phy_diag.br_pd_en));
   9598             }
   9599         }
   9600     }
   9601     return SOC_E_NONE;
   9602 }
   9603 /*
   9604  * Function:
   9605  *      phy_82381_diag_ctrl
   9606  * Purpose:
   9607  *      xx
   9608  * Parameters:
   9609  *      unit - BCM unit number.
   9610  *      port - Port number.
   9611 
   9612  * Returns:
   9613  *      SOC_E_NONE
   9614  */
   9615 
   9616 STATIC int
   9617 phy_82381_diag_ctrl(
   9618     int unit,        /* unit */
   9619     soc_port_t port, /* port */
   9620     uint32 inst,     /* the specific device block the control action directs to */
   9621     int op_type,     /* operation types: read,write or command sequence */
   9622     int op_cmd,      /* command code */
   9623     void *arg)       /* command argument based on op_type/op_cmd */
   9624 {
   9625     int rv = -1;
   9626     int32 lane;
   9627     int32 intf;
   9628     phy_ctrl_t          *pc;
   9629     /* locate phy control, phymod control, and the configuration data */
   9630     pc = EXT_PHY_SW_STATE(unit, port);
   9631     if (pc == NULL) {
   9632         return SOC_E_INTERNAL;
   9633     }
   9634 
   9635 
   9636     lane = PHY_DIAG_INST_LN(inst);
   9637     intf = PHY_DIAG_INST_INTF(inst);
   9638     if (intf == PHY_DIAG_INTF_DFLT) {
   9639         intf = PHY_DIAG_INTF_LINE;
   9640     }
   9641     if (intf == PHY_DIAG_INTF_SYS) {
   9642         pc->flags |= PHYCTRL_SYS_SIDE_CTRL;
   9643     } else {
   9644         pc->flags &= ~PHYCTRL_SYS_SIDE_CTRL;
   9645     }
   9646     switch(op_cmd) {
   9647         case PHY_DIAG_CTRL_DSC:
   9648             rv = phy_82381_diag_dsc(pc, intf);
   9649             break;
   9650         case PHY_DIAG_CTRL_START_FAST_EYESCAN:
   9651             rv =  phy_82381_diag_eyescan(port, pc, intf, lane);
   9652         break;
   9653         case PHY_DIAG_CTRL_LINKMON_MODE:
   9654         {
   9655             uint32_t value = PTR_TO_INT(arg);
   9656             rv = phy_82381_link_monitor_set(pc, intf, lane, value);
   9657         }
   9658         break;
   9659         case PHY_DIAG_CTRL_LINKMON_STATUS:
   9660         {
   9661             rv = phy_82381_link_monitor_status_get(pc, intf, lane);
   9662         }
   9663         break;
   9664         default:
   9665             if (op_type == PHY_DIAG_CTRL_SET) {
   9666                     rv = phy_82381_control_set(unit,port,op_cmd,PTR_TO_INT(arg));
   9667             } else if (op_type == PHY_DIAG_CTRL_GET) {
   9668                     rv = phy_82381_control_get(unit,port,op_cmd,(uint32 *)arg);
   9669             }
   9670             break ;
   9671     }
   9672 
   9673     /* clear the pc->flags  to make default as PHY_DIAG_INTF_LINE */
   9674     pc->flags &= ~PHYCTRL_SYS_SIDE_CTRL;
   9675 
   9676     return rv;
   9677 }
   9678 
   9679 int32 phy_82381_core_reset(int32 unit, soc_port_t port, void *not_used)
   9680 {
   9681     phy_ctrl_t                *pc;
   9682     soc_phymod_core_t *pmc_core;
   9683     int                  idx;
   9684     phymod_core_access_t *pm_core;
   9685     soc_phymod_ctrl_t *pmc;
   9686     phymod_reset_direction_t reset_direction;
   9687     /* locate phy control */
   9688     pc = EXT_PHY_SW_STATE(unit, port);
   9689     if (pc == NULL) {
   9690         return SOC_E_INTERNAL;
   9691     }
   9692     reset_direction = phymodResetDirectionIn;
   9693     pmc = &pc->phymod_ctrl;
   9694 
   9695     /* loop through all cores */
   9696     for (idx = 0; idx < pmc->num_phys; idx++) {
   9697         pmc_core = pmc->phy[idx]->core;
   9698         pm_core = &pmc_core->pm_core;
   9699         if (pm_core == NULL) {
   9700             return SOC_E_INTERNAL;
   9701         }
   9702 
   9703         SOC_IF_ERROR_RETURN(phymod_core_reset_set(pm_core, phymodResetModeSoft, reset_direction));
   9704     }
   9705     return(SOC_E_NONE);
   9706 }
   9707 
   9708 /*
   9709  * phy_82381_per_lane_tx_set
   9710  */
   9711 STATIC int
   9712 phy_82381_per_lane_tx_set(phy_ctrl_t *pc, int32 intf, soc_phy_control_t type, int lane, uint32 value)
   9713 {
   9714     soc_phymod_phy_t    *p_phy;
   9715     uint32              lane_map;
   9716     phymod_phy_access_t pm_phy_copy, *pm_phy;
   9717     phymod_tx_t         phymod_tx;
   9718     uint32_t if_side = 0;
   9719     uint32_t chip_id = 0;
   9720     uint32 simplex_tx = 0;
   9721     soc_phymod_ctrl_t *pmc;
   9722     pmc = &pc->phymod_ctrl;
   9723 
   9724     /* locate the desired phy and lane */
   9725     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   9726 
   9727     /* Make a copy of the phy access and overwrite the desired lane */
   9728     pm_phy = &p_phy->pm_phy;
   9729 
   9730     simplex_tx = SIMPLEX_TX(pc);
   9731     chip_id = DEVID(pc);
   9732     SOC_IF_ERROR_RETURN
   9733         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   9734     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   9735     pm_phy_copy.access.lane_mask = lane_map;
   9736     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   9737     pm_phy_copy.access.flags |= if_side;
   9738     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   9739     switch (type) {
   9740         case SOC_PHY_CONTROL_TX_FIR_PRE:
   9741             phymod_tx.pre = value;
   9742             break;
   9743         case SOC_PHY_CONTROL_TX_FIR_MAIN:
   9744             phymod_tx.main = value;
   9745             break;
   9746         case SOC_PHY_CONTROL_TX_FIR_POST:
   9747             phymod_tx.post = value;
   9748             break;
   9749         case SOC_PHY_CONTROL_TX_FIR_POST2:
   9750             phymod_tx.post2 = value;
   9751             break;
   9752         case SOC_PHY_CONTROL_TX_FIR_POST3:
   9753             phymod_tx.post3 = value;
   9754             break;
   9755         default:
   9756             return SOC_E_UNAVAIL;
   9757     }
   9758 
   9759     SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   9760 
   9761     return(SOC_E_NONE);
   9762 }
   9763 
   9764 /*
   9765  * phy_82381_per_lane_tx_get
   9766  */
   9767 STATIC int
   9768 phy_82381_per_lane_tx_get(phy_ctrl_t *pc, int32 intf, soc_phy_control_t type, int lane, uint32 *value)
   9769 {
   9770     soc_phymod_phy_t    *p_phy;
   9771     uint32              lane_map;
   9772     phymod_phy_access_t pm_phy_copy, *pm_phy;
   9773     phymod_tx_t         phymod_tx;
   9774     uint32_t if_side = 0;
   9775     uint32_t chip_id = 0;
   9776     uint32 simplex_tx = 0;
   9777     soc_phymod_ctrl_t *pmc;
   9778     pmc = &pc->phymod_ctrl;
   9779 
   9780     /* locate the desired phy and lane */
   9781     SOC_IF_ERROR_RETURN(_phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   9782 
   9783     /* Make a copy of the phy access and overwrite the desired lane */
   9784     pm_phy = &p_phy->pm_phy;
   9785 
   9786     simplex_tx = SIMPLEX_TX(pc);
   9787     chip_id = DEVID(pc);
   9788     SOC_IF_ERROR_RETURN
   9789         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 0, &if_side));
   9790     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   9791     pm_phy_copy.access.lane_mask = lane_map;
   9792     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   9793     pm_phy_copy.access.flags |= if_side;
   9794 
   9795     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   9796     *value = phymod_tx.amp;
   9797     switch (type) {
   9798         case SOC_PHY_CONTROL_TX_FIR_PRE:
   9799             *value = phymod_tx.pre;
   9800             break;
   9801         case SOC_PHY_CONTROL_TX_FIR_MAIN:
   9802             *value = phymod_tx.main;
   9803             break;
   9804         case SOC_PHY_CONTROL_TX_FIR_POST:
   9805             *value = phymod_tx.post;
   9806             break;
   9807         case SOC_PHY_CONTROL_TX_FIR_POST2:
   9808             *value = phymod_tx.post2;
   9809             break;
   9810         case SOC_PHY_CONTROL_TX_FIR_POST3:
   9811             *value = phymod_tx.post3;
   9812             break;
   9813         default:
   9814             return SOC_E_UNAVAIL;
   9815     }
   9816 
   9817     return(SOC_E_NONE);
   9818 }
   9819 
   9820 /*
   9821 * Function:
   9822 *      _phy_84328_ability_remote_get
   9823 * Purpose:
   9824 *      Get the device's complete abilities.
   9825 * Parameters:
   9826 *      unit - StrataSwitch unit #.
   9827 *      port - StrataSwitch port #.
   9828 *      ability - return device's abilities.
   9829 * Returns:
   9830 *      SOC_E_XXX
   9831 */
   9832 STATIC int
   9833 phy_82381_ability_remote_get(int unit, soc_port_t port,
   9834                                   soc_port_ability_t *ability)
   9835 {
   9836     int an, an_done;
   9837     phy_ctrl_t *pc, *int_pc;
   9838     int  line_intf;
   9839     phymod_autoneg_ability_t  phymod_autoneg_ability;
   9840     uint32_t an_cap = 0;
   9841     soc_phymod_ctrl_t         *pmc;
   9842     phy82381_config_t         *pCfg;
   9843     soc_phymod_phy_t          *phy;
   9844     uint32 chip_id = 0;
   9845 
   9846 
   9847     if (ability == NULL) {
   9848         return SOC_E_PARAM;
   9849     }
   9850     pc = EXT_PHY_SW_STATE(unit, port);
   9851 
   9852 
   9853     /* Only firmware has visibility into remote ability */
   9854     sal_memset(ability, 0, sizeof(soc_port_ability_t));
   9855 
   9856     pmc = &pc->phymod_ctrl;
   9857     chip_id = DEVID(pc);
   9858     if (FURIA_IS_SIMPLEX(chip_id)) {
   9859         return SOC_E_NONE;
   9860     }
   9861     pCfg = (phy82381_config_t *) pc->driver_data;
   9862 
   9863     /* only set abilities on the first core */
   9864     phy = pmc->phy[pmc->main_phy];
   9865     if (phy == NULL) {
   9866         return SOC_E_INTERNAL;
   9867     }
   9868     phymod_autoneg_ability_t_init(&phymod_autoneg_ability);
   9869 
   9870 
   9871     line_intf = pCfg->speed_config.line_interface;
   9872 
   9873     if ((line_intf == SOC_PORT_IF_KX) || (line_intf == SOC_PORT_IF_GMII)) {
   9874         int_pc = INT_PHY_SW_STATE(unit, port);
   9875         if (int_pc) {
   9876             SOC_IF_ERROR_RETURN(PHY_ABILITY_REMOTE_GET(int_pc->pd, unit, port, ability));
   9877         }
   9878         return SOC_E_NONE;
   9879     }
   9880 
   9881     ability->speed_half_duplex  = SOC_PA_ABILITY_NONE;
   9882 
   9883     /* Return what the firmware is setting */
   9884     /* If an done, then return the speed for the port */
   9885     SOC_IF_ERROR_RETURN(phy_82381_an_get(unit, port, &an, &an_done));
   9886     if (an && an_done) {
   9887        SOC_IF_ERROR_RETURN
   9888         (phymod_phy_autoneg_remote_ability_get(&phy->pm_phy, &phymod_autoneg_ability));
   9889        an_cap = phymod_autoneg_ability.an_cap;
   9890        ability->speed_full_duplex |= PHYMOD_AN_CAP_40G_CR4_GET(an_cap) ? SOC_PA_SPEED_40GB : 0;
   9891        ability->speed_full_duplex |= PHYMOD_AN_CAP_40G_KR4_GET(an_cap) ? SOC_PA_SPEED_40GB : 0;
   9892        ability->speed_full_duplex |= PHYMOD_AN_CAP_10G_KR_GET(an_cap)  ? SOC_PA_SPEED_10GB : 0;
   9893        ability->speed_full_duplex |= PHYMOD_AN_CAP_100G_CR4_GET(an_cap) ? SOC_PA_SPEED_100GB : 0;
   9894        ability->speed_full_duplex |= PHYMOD_AN_CAP_100G_KR4_GET(an_cap) ? SOC_PA_SPEED_100GB : 0;
   9895        ability->speed_full_duplex |= PHYMOD_AN_CAP_100G_CR10_GET(an_cap) ? SOC_PA_SPEED_100GB : 0;
   9896 
   9897         an_cap = phymod_autoneg_ability.capabilities;
   9898         if (an_cap == PHYMOD_AN_CAP_ASYM_PAUSE) {
   9899             ability->pause = SOC_PA_PAUSE_TX;
   9900         } else if (an_cap == (PHYMOD_AN_CAP_SYMM_PAUSE | PHYMOD_AN_CAP_ASYM_PAUSE)) {
   9901             ability->pause = SOC_PA_PAUSE_RX;
   9902         } else if (an_cap == PHYMOD_AN_CAP_SYMM_PAUSE) {
   9903             ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX);
   9904         }
   9905     }
   9906     LOG_INFO(BSL_LS_SOC_PHY,
   9907              (BSL_META_U(unit,
   9908                          "phy_84328_ability_remote_get: u=%d p=%d speed(FD)=0x%x pause=0x%x\n"),
   9909               unit, port, ability->speed_full_duplex, ability->pause));
   9910 
   9911     return SOC_E_NONE;
   9912 }
   9913 
   9914 STATIC int
   9915 phy_82381_cl72_enable_set(phy_ctrl_t *pc, int32 intf, uint32 value)
   9916 {
   9917     phymod_phy_access_t     *pm_phy;
   9918     int                     idx;
   9919     phymod_phy_access_t pm_phy_copy;
   9920     soc_phymod_ctrl_t *pmc;
   9921     pmc = &pc->phymod_ctrl;
   9922 
   9923     for (idx = 0; idx < pmc->num_phys; idx++) {
   9924         pm_phy = &pmc->phy[idx]->pm_phy;
   9925 
   9926         if (pm_phy == NULL) {
   9927             return SOC_E_INTERNAL;
   9928         }
   9929 
   9930         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   9931         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   9932 
   9933         if (intf == PHY82381_SYS_SIDE) {
   9934             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   9935         }
   9936 #ifdef PHY82381_DEBUG
   9937         LOG_CLI((BSL_META_U(0,"Tx training: %d Flags:0x%x\n"), value, pm_phy_copy.access.flags));
   9938 #endif
   9939         SOC_IF_ERROR_RETURN(phymod_phy_cl72_set(&pm_phy_copy, value));
   9940     }
   9941 
   9942     return(SOC_E_NONE);
   9943 }
   9944 
   9945 
   9946 STATIC int
   9947 phy_82381_cl72_status_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   9948 {
   9949     phymod_phy_access_t     *pm_phy;
   9950     int                     idx;
   9951     phymod_phy_access_t pm_phy_copy;
   9952     phymod_cl72_status_t status;
   9953     soc_phymod_ctrl_t *pmc;
   9954     pmc = &pc->phymod_ctrl;
   9955 
   9956     for (idx = 0; idx < pmc->num_phys; idx++) {
   9957         pm_phy = &pmc->phy[idx]->pm_phy;
   9958 
   9959         if (pm_phy == NULL) {
   9960             return SOC_E_INTERNAL;
   9961         }
   9962 
   9963         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   9964         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   9965 
   9966         if (intf == PHY82381_SYS_SIDE) {
   9967             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
   9968         }
   9969 
   9970         sal_memset(&status, 0, sizeof(status));
   9971         SOC_IF_ERROR_RETURN(phymod_phy_cl72_status_get(&pm_phy_copy, &status));
   9972         *value = status.locked;
   9973     }
   9974 #ifdef PHY82381_DEBUG
   9975     LOG_CLI((BSL_META_U(0,"Tx training Sts: %d Flags:0x%x\n"), *value, pm_phy_copy.access.flags));
   9976 #endif
   9977 
   9978     return(SOC_E_NONE);
   9979 }
   9980 
   9981 STATIC int
   9982 phy_82381_cl72_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
   9983 {
   9984     phymod_phy_access_t     *pm_phy;
   9985     int                     idx;
   9986     phymod_phy_access_t pm_phy_copy;
   9987     soc_phymod_ctrl_t *pmc;
   9988     pmc = &pc->phymod_ctrl;
   9989 
   9990     for (idx = 0; idx < pmc->num_phys; idx++) {
   9991         pm_phy = &pmc->phy[idx]->pm_phy;
   9992 
   9993         if (pm_phy == NULL) {
   9994             return SOC_E_INTERNAL;
   9995         }
   9996 
   9997         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   9998         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
   9999 
  10000         if (intf == PHY82381_SYS_SIDE) {
  10001             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
  10002         }
  10003 
  10004         SOC_IF_ERROR_RETURN(phymod_phy_cl72_get(&pm_phy_copy, value));
  10005     }
  10006     return(SOC_E_NONE);
  10007 }
  10008 
  10009 STATIC int
  10010 phy_82381_link_monitor_set (phy_ctrl_t *pc, int32 intf, int32 lane, uint32 value)
  10011 {
  10012     phymod_phy_access_t    *pm_phy;
  10013     soc_phymod_phy_t    *p_phy;
  10014     uint32              lane_map = 0;
  10015     phymod_phy_access_t pm_phy_copy;
  10016     uint32_t link_mon_mode = 0;
  10017     uint32_t if_side = 0;
  10018     uint32_t chip_id = 0;
  10019     uint32 simplex_tx = 0;
  10020     soc_phymod_ctrl_t *pmc;
  10021     pmc = &pc->phymod_ctrl;
  10022 
  10023     intf = (intf == PHY_DIAG_INTF_LINE) ? PHY82381_LINE_SIDE : PHY82381_SYS_SIDE;
  10024     if (lane == 0xf) {
  10025         /* Get p_phy alone and let lane map be as Phy structure value */
  10026         lane = 1;
  10027         SOC_IF_ERROR_RETURN(
  10028                 _phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
  10029         lane = 0xf;
  10030     } else {
  10031         SOC_IF_ERROR_RETURN(
  10032                 _phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
  10033     }
  10034 
  10035     /* Make a copy of the phy access and overwrite the desired lane */
  10036     pm_phy = &p_phy->pm_phy;
  10037 
  10038     simplex_tx = SIMPLEX_TX(pc);
  10039     chip_id = DEVID(pc);
  10040     SOC_IF_ERROR_RETURN
  10041         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
  10042     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
  10043     if (lane != 0xf) {
  10044         pm_phy_copy.access.lane_mask = lane_map;
  10045     }
  10046 
  10047     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
  10048     pm_phy_copy.access.flags |= if_side;
  10049 
  10050     if (value == 0) {
  10051         SOC_IF_ERROR_RETURN(
  10052             phymod_phy_link_mon_enable_set(&pm_phy_copy, 0 /*When disable Dont care*/, 0));
  10053     } else {
  10054         link_mon_mode = value - 1;
  10055         SOC_IF_ERROR_RETURN(
  10056             phymod_phy_link_mon_enable_set(&pm_phy_copy, link_mon_mode, 1));
  10057     }
  10058 
  10059     return(SOC_E_NONE);
  10060 }
  10061 
  10062 STATIC int
  10063 phy_82381_link_monitor_status_get (phy_ctrl_t *pc, int32 intf, int32 lane)
  10064 {
  10065     phymod_phy_access_t    *pm_phy;
  10066     soc_phymod_phy_t    *p_phy;
  10067     uint32              lane_map = 0;
  10068     phymod_phy_access_t pm_phy_copy;
  10069     uint32_t lock_status = 0, lock_lost_lh = 0, error_count = 0;
  10070     uint32_t if_side = 0;
  10071     uint32_t chip_id = 0;
  10072     uint32 simplex_tx = 0;
  10073     soc_phymod_ctrl_t *pmc;
  10074     pmc = &pc->phymod_ctrl;
  10075 
  10076     intf = (intf == PHY_DIAG_INTF_LINE) ? PHY82381_LINE_SIDE : PHY82381_SYS_SIDE;
  10077     if (lane == 0xf) {
  10078         /* Get p_phy alone and let lane map be as Phy structure value */
  10079         lane = 1;
  10080         SOC_IF_ERROR_RETURN(
  10081                 _phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
  10082         lane = 0xf;
  10083     } else {
  10084         SOC_IF_ERROR_RETURN(
  10085                 _phy_82381_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
  10086     }
  10087 
  10088     /* Make a copy of the phy access and overwrite the desired lane */
  10089     pm_phy = &p_phy->pm_phy;
  10090 
  10091     simplex_tx = SIMPLEX_TX(pc);
  10092     chip_id = DEVID(pc);
  10093     SOC_IF_ERROR_RETURN
  10094         (_phy_82381_get_intf_side(chip_id, intf, simplex_tx, 1, &if_side));
  10095     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
  10096     if (lane != 0xf) {
  10097         pm_phy_copy.access.lane_mask = lane_map;
  10098     }
  10099 
  10100     pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
  10101     pm_phy_copy.access.flags |= if_side;
  10102 
  10103     SOC_IF_ERROR_RETURN(
  10104           phymod_phy_link_mon_status_get(&pm_phy_copy, &lock_status, &lock_lost_lh, &error_count));
  10105 
  10106     if (lane != 0xF) {
  10107         LOG_CLI((BSL_META_U(0,"Lane:%d Lock Status:%d lock lost:%d Error count:%d\n "),
  10108                 lane, lock_status, lock_lost_lh, error_count));
  10109     } else {
  10110         LOG_CLI((BSL_META_U(0,"Lane Map:0x%x Lock Status:%d lock lost:%d Error count:%d\n "),
  10111                 pm_phy_copy.access.lane_mask, lock_status, lock_lost_lh, error_count));
  10112     }
  10113 
  10114     return(SOC_E_NONE);
  10115 
  10116 }
  10117 
  10118 STATIC int
  10119 phy_82381_cross_switch_swap_set(phy_ctrl_t *pc, uint16 intf, uint32 value)
  10120 {
  10121     phymod_phy_access_t     *pm_phy;
  10122     int                     idx;
  10123     phymod_phy_access_t pm_phy_copy;
  10124     int lane_index = 0;
  10125     uint32_t tx_array[8]={0,};
  10126     soc_phymod_ctrl_t *pmc;
  10127     pmc = &pc->phymod_ctrl;
  10128 
  10129     for (idx = 0; idx < pmc->num_phys; idx++) {
  10130         pm_phy = &pmc->phy[idx]->pm_phy;
  10131 
  10132         if (pm_phy == NULL) {
  10133             return SOC_E_INTERNAL;
  10134         }
  10135         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
  10136         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
  10137         if(intf == PHY82381_SYS_SIDE) {
  10138             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
  10139         }
  10140 
  10141         for (lane_index = 0; lane_index < PHY82381_MAX_LANE; lane_index++) {
  10142             tx_array[lane_index] = (value >> (lane_index * 4)) & 0xF;
  10143         }
  10144         SOC_IF_ERROR_RETURN(
  10145             phymod_phy_lane_cross_switch_map_set(&pm_phy_copy, tx_array));
  10146     }
  10147 
  10148     return(SOC_E_NONE);
  10149 }
  10150 
  10151 STATIC int
  10152 phy_82381_cross_switch_swap_get(phy_ctrl_t *pc, uint16 intf, uint32 *value)
  10153 {
  10154     phymod_phy_access_t     *pm_phy;
  10155     int                     idx;
  10156     phymod_phy_access_t pm_phy_copy;
  10157     uint32_t tx_array[8] = {0,};
  10158     int lane_index = 0;
  10159     soc_phymod_ctrl_t *pmc;
  10160     uint32_t chip_id = 0;
  10161 
  10162     pmc = &pc->phymod_ctrl;
  10163     chip_id = DEVID(pc);
  10164     if(FURIA_IS_SIMPLEX(chip_id)){
  10165            tx_array[6] = (*value >> (6 * 4)) & 0x1;/*set die selection for 82212 on 7th member*/
  10166     }
  10167 
  10168     *value = 0;
  10169     for (idx = 0; idx < pmc->num_phys; idx++) {
  10170         pm_phy = &pmc->phy[idx]->pm_phy;
  10171 
  10172         if (pm_phy == NULL) {
  10173             return SOC_E_INTERNAL;
  10174         }
  10175         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
  10176         pm_phy_copy.access.flags &= ~(1 << INTERFACE_SIDE_SHIFT);
  10177         if(intf == PHY82381_SYS_SIDE) {
  10178             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
  10179         }
  10180 
  10181         SOC_IF_ERROR_RETURN (
  10182             phymod_phy_lane_cross_switch_map_get(&pm_phy_copy, tx_array));
  10183 
  10184         for (lane_index = 0; lane_index < PHY82381_MAX_LANE; lane_index++) {
  10185             *value |= (tx_array[lane_index] << (lane_index * 4));
  10186         }
  10187     }
  10188 
  10189     return(SOC_E_NONE);
  10190 }
  10191 
  10192 STATIC int
  10193 phy_82381_intr_enable_set(phy_ctrl_t *pc, int32 intf, uint32 value)
  10194 {
  10195     phymod_phy_access_t     *pm_phy;
  10196     int                     idx;
  10197     phymod_phy_access_t pm_phy_copy;
  10198     soc_phymod_ctrl_t *pmc;
  10199     pmc = &pc->phymod_ctrl;
  10200     for (idx = 0; idx < pmc->num_phys; idx++) {
  10201         pm_phy = &pmc->phy[idx]->pm_phy;
  10202 
  10203         if (pm_phy == NULL) {
  10204             return SOC_E_INTERNAL;
  10205         }
  10206         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
  10207         if(intf == PHY82381_SYS_SIDE) {
  10208             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
  10209         }
  10210 
  10211     SOC_IF_ERROR_RETURN(
  10212         phymod_phy_intr_enable_set(&pm_phy_copy, value));
  10213     }
  10214 
  10215     return(SOC_E_NONE);
  10216 }
  10217 
  10218 STATIC int
  10219 phy_82381_intr_enable_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
  10220 {
  10221     phymod_phy_access_t     *pm_phy;
  10222     int                     idx;
  10223     phymod_phy_access_t pm_phy_copy;
  10224     soc_phymod_ctrl_t *pmc;
  10225     pmc = &pc->phymod_ctrl;
  10226 
  10227     *value = 0;
  10228     for (idx = 0; idx < pmc->num_phys; idx++) {
  10229         pm_phy = &pmc->phy[idx]->pm_phy;
  10230 
  10231         if (pm_phy == NULL) {
  10232             return SOC_E_INTERNAL;
  10233         }
  10234         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
  10235         if(intf == PHY82381_SYS_SIDE) {
  10236             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
  10237         }
  10238 
  10239         SOC_IF_ERROR_RETURN(
  10240             phymod_phy_intr_enable_get(&pm_phy_copy, value));
  10241     }
  10242 
  10243     return(SOC_E_NONE);
  10244 }
  10245 
  10246 STATIC int
  10247 phy_82381_intr_status_get(phy_ctrl_t *pc, int32 intf, uint32 *value)
  10248 {
  10249     phymod_phy_access_t     *pm_phy;
  10250     int                     idx;
  10251     phymod_phy_access_t pm_phy_copy;
  10252     soc_phymod_ctrl_t *pmc;
  10253     pmc = &pc->phymod_ctrl;
  10254 
  10255     *value = 0;
  10256     for (idx = 0; idx < pmc->num_phys; idx++) {
  10257         pm_phy = &pmc->phy[idx]->pm_phy;
  10258 
  10259         if (pm_phy == NULL) {
  10260             return SOC_E_INTERNAL;
  10261         }
  10262         sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
  10263         if(intf == PHY82381_SYS_SIDE) {
  10264             pm_phy_copy.access.flags |= (1 << INTERFACE_SIDE_SHIFT);
  10265         }
  10266 
  10267         SOC_IF_ERROR_RETURN(
  10268             phymod_phy_intr_status_get(&pm_phy_copy, value));
  10269         SOC_IF_ERROR_RETURN(
  10270             phymod_phy_intr_status_clear(&pm_phy_copy, *value));
  10271     }
  10272 
  10273     return(SOC_E_NONE);
  10274 }
  10275 
  10276 /*
  10277  * Variable:
  10278  *      phy82381_drv
  10279  * Purpose:
  10280  *      Phy Driver for phy82381
  10281  */
  10282 phy_driver_t phy82381_drv = {
  10283     /* .drv_name                      = */ "PHY82381 PHYMOD PHY Driver",
  10284     /* .pd_init                       = */ phy_82381_init,
  10285     /* .pd_reset                      = */ phy_82381_core_reset,
  10286     /* .pd_link_get                   = */ phy_82381_link_get,
  10287     /* .pd_enable_set                 = */ phy_82381_enable_set,
  10288     /* .pd_enable_get                 = */ phy_82381_enable_get,
  10289     /* .pd_duplex_set                 = */ phy_null_set,
  10290     /* .pd_duplex_get                 = */ phy82381_duplex_get,
  10291     /* .pd_speed_set                  = */ phy82381_speed_set,
  10292     /* .pd_speed_get                  = */ phy82381_speed_get,
  10293     /* .pd_master_set                 = */ phy_null_set,
  10294     /* .pd_master_get                 = */ phy_null_zero_get,
  10295     /* .pd_an_set                     = */ phy_82381_an_set,
  10296     /* .pd_an_get                     = */ phy_82381_an_get,
  10297     /* .pd_adv_local_set              = */ NULL, /* Deprecated */
  10298     /* .pd_adv_local_get              = */ NULL, /* Deprecated */
  10299     /* .pd_adv_remote_get             = */ NULL, /* Deprecated */
  10300     /* .pd_lb_set                     = */ phy_82381_lb_set,
  10301     /* .pd_lb_get                     = */ phy82381_lb_get,
  10302     /* .pd_interface_set              = */ phy82381_interface_set,
  10303     /* .pd_interface_get              = */ phy82381_interface_get,
  10304     /* .pd_ability                    = */ NULL, /* Deprecated */
  10305     /* .pd_linkup_evt                 = */ NULL,
  10306     /* .pd_linkdn_evt                 = */ NULL,
  10307     /* .pd_mdix_set                   = */ phy_null_mdix_set,
  10308     /* .pd_mdix_get                   = */ phy_null_mdix_get,
  10309     /* .pd_mdix_status_get            = */ phy_null_mdix_status_get,
  10310     /* .pd_medium_config_set          = */ NULL,
  10311     /* .pd_medium_config_get          = */ NULL,
  10312     /* .pd_medium_get                 = */ phy_null_medium_get,
  10313     /* .pd_cable_diag                 = */ NULL,
  10314     /* .pd_link_change                = */ NULL,
  10315     /* .pd_control_set                = */ phy_82381_control_set,
  10316     /* .pd_control_get                = */ phy_82381_control_get,
  10317     /* .pd_reg_read                   = */ phy82381_reg_read,
  10318     /* .pd_reg_write                  = */ phy82381_reg_write,
  10319     /* .pd_reg_modify                 = */ phy82381_reg_modify,
  10320     /* .pd_notify                     = */ NULL,
  10321     /* .pd_probe                      = */ phy82381_probe,
  10322     /* .pd_ability_advert_set         = */ phy_82381_ability_advert_set,
  10323     /* .pd_ability_advert_get         = */ phy_82381_ability_advert_get,
  10324     /* .pd_ability_remote_get         = */ phy_82381_ability_remote_get,
  10325     /* .pd_ability_local_get          = */ phy_82381_ability_local_get,
  10326     /* .pd_firmware_set               = */ phy_82381_firmware_set,
  10327     /* .pd_timesync_config_set        = */ NULL,
  10328     /* .pd_timesync_config_get        = */ NULL,
  10329     /* .pd_timesync_control_set       = */ NULL,
  10330     /* .pd_timesync_control_set       = */ NULL,
  10331     /* .pd_diag_ctrl                  = */ phy_82381_diag_ctrl,
  10332     /* .pd_lane_control_set           = */ phy_82381_per_lane_control_set,
  10333     /* .pd_lane_control_get           = */ phy_82381_per_lane_control_get
  10334 };
  10335 
  10336 #else
  10337 int _phy82381_not_empty;
  10338 #endif /*  INCLUDE_PHY_82381 */
  10339