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

tscf.c (307952B)


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