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

qsgmiie.c (164833B)


      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:        qsgmiie.c
      8  * Purpose:     Support Broadcom TSC/Eagle internal SerDes
      9  */
     10 
     11 /*
     12  *   This module implements an NTSW SDK Phy driver for the TSC/Eagle 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_qsgmiie_per_lane_control_set and
     36  *     .phy_qsgmiie_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  *   qsgmiie_config_t
     60  *   Driver specific data.  This structure is used by qsgmiie 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 #if defined(INCLUDE_SERDES_QSGMIIE)
    113 
    114 #include <phymod/phymod.h>
    115 #include <phymod/phymod_diagnostics.h>
    116 #include <phymod/chip/bcmi_qsgmiie_serdes_sym.h>
    117 #include <phymod/chip/qsgmiie.h>
    118 
    119 #define NUM_LANES             4    /* num of lanes per core */
    120 #define MAX_NUM_LANES         4    /* max num of lanes per port */
    121 #define QSGMIIE_NO_CFG_VALUE     (-1)
    122 
    123 /*
    124  * The DBG_OK macro will bypass the function body and return success
    125  * if the PHY simulator is enabled for a particular port. This allows
    126  * system initialization to complete even if the driver has not been
    127  * fully tested/debugged. As development progresses, we should be able
    128  * to remove all instances of this macro.
    129  */
    130 #define DBG_OK() do { \
    131     if (soc_property_port_get(unit, port, "qsgmiie_sim", 0)) { \
    132         return SOC_E_NONE; \
    133     } \
    134 } while (0)
    135 
    136 
    137 #define PHYMOD_IF_CR4    (1 << SOC_PORT_IF_CR4)
    138 
    139 
    140 typedef struct qsgmiie_speed_config_s {
    141     uint32  port_refclk_int;
    142     int     speed;
    143     int     port_num_lanes;
    144     int     port_is_higig;
    145     int     rxaui_mode;
    146     int     scrambler_en;
    147     int     line_interface;
    148     int     pcs_bypass;
    149     int     fiber_pref;
    150     int     phy_supports_dual_rate;
    151 } qsgmiie_speed_config_t;
    152 
    153 #define NUM_PATTERN_DATA_INTS    8
    154 typedef struct qsgmiie_pattern_s {
    155     uint32 pattern_data[NUM_PATTERN_DATA_INTS];
    156     uint32 pattern_length;
    157 } qsgmiie_pattern_t;
    158 
    159 #define QSGMIIE_LANE_NAME_LEN   30
    160 
    161 typedef struct {
    162     uint16 serdes_id0;
    163     char   name[QSGMIIE_LANE_NAME_LEN];
    164 } qsgmiie_dev_info_t;
    165 
    166 /* index to TX drive configuration table for each VCO setting.
    167  */
    168 typedef enum txdrv_inxs {
    169     TXDRV_XFI_INX = 0,     /* 10G XFI */
    170     TXDRV_SFI_INX,     /* 10G SR fiber mode */
    171     TXDRV_SFIDAC_INX,  /* 10G SFI DAC mode */
    172     TXDRV_AN_INX,      /* a common entry for autoneg mode */
    173     TXDRV_DFT_INX,     /* temp for any missing speed modes */
    174     TXDRV_LAST_INX      /* always last */
    175 } TXDRV_INXS_t;
    176 
    177 #define TXDRV_ENTRY_NUM     (TXDRV_LAST_INX)
    178 
    179 
    180 
    181 /*
    182    Config - per logical port
    183 */
    184 typedef struct {
    185     phymod_polarity_t               phy_polarity_config;
    186     phymod_phy_reset_t              phy_reset_config;
    187     qsgmiie_pattern_t                  pattern;
    188     qsgmiie_speed_config_t             speed_config;
    189 
    190     int fiber_pref;                 /* spn_SERDES_FIBER_PREF */
    191     int cl73an;                     /* spn_PHY_AN_C73 */
    192     int cx4_10g;                    /* spn_10G_IS_CX4 */
    193     int pdetect1000x;
    194     int cl37an;                     /* spn_PHY_AN_C37 */
    195     int an_cl72;                    /* spn_PHY_AN_C72 */
    196     int forced_init_cl72;           /* spn_FORCED_INIT_CL72 */
    197     int hg_mode;                    /* higig port */
    198     int an_fec;                     /*enable FEC for AN mode */
    199     int sgmii_mstr;                 /* sgmii master mode */
    200     qsgmiie_dev_info_t info;          /*serdes id info */
    201     phymod_tx_t tx_drive[TXDRV_ENTRY_NUM];
    202 
    203 } qsgmiie_config_t;
    204 
    205 #define QSGMIIE_IF_NULL   (1 << SOC_PORT_IF_NULL)
    206 #define QSGMIIE_IF_SR     (1 << SOC_PORT_IF_SR)
    207 #define QSGMIIE_IF_KR     (1 << SOC_PORT_IF_KR)
    208 #define QSGMIIE_IF_KR4    (1 << SOC_PORT_IF_KR4)
    209 #define QSGMIIE_IF_CR     (1 << SOC_PORT_IF_CR)
    210 #define QSGMIIE_IF_CR4    (1 << SOC_PORT_IF_CR4)
    211 #define QSGMIIE_IF_XFI    (1 << SOC_PORT_IF_XFI)
    212 #define QSGMIIE_IF_SFI    (1 << SOC_PORT_IF_SFI)
    213 #define QSGMIIE_IF_XLAUI  (1 << SOC_PORT_IF_XLAUI)
    214 #define QSGMIIE_IF_XGMII  (1 << SOC_PORT_IF_XGMII)
    215 #define QSGMIIE_IF_ILKN   (1 << SOC_PORT_IF_ILKN)
    216 
    217 
    218 
    219 #define TEMOD_CL73_CL37              0x5
    220 #define TEMOD_CL73_HPAM              0x4
    221 #define TEMOD_CL73_HPAM_VS_SW        0x8
    222 #define TEMOD_CL73_WO_BAM            0x2
    223 #define TEMOD_CL73_W_BAM             0x1
    224 #define TEMOD_CL73_DISABLE           0x0
    225 
    226 #define TEMOD_CL37_HR2SPM_W_10G 5
    227 #define TEMOD_CL37_HR2SPM       4
    228 #define TEMOD_CL37_W_10G     3
    229 #define TEMOD_CL37_WO_BAM    2
    230 #define TEMOD_CL37_W_BAM     1
    231 #define TEMOD_CL37_DISABLE   0
    232 
    233 /*
    234  * Function:
    235  *      _qsgmiie_reg_read
    236  * Doc:
    237  *      register read operations
    238  * Parameters:
    239  *      unit            - (IN)  unit number
    240  *      core_addr       - (IN)  core address
    241  *      reg_addr        - (IN)  address to read
    242  *      val             - (OUT) read value
    243  */
    244 STATIC int 
    245 _qsgmiie_reg_read(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val)
    246 {
    247     uint16 data16;
    248     int rv;
    249     soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc;
    250 
    251     rv = core->read(core->unit, core_addr, reg_addr, &data16);
    252     *val = data16;
    253 
    254     return rv;
    255 }
    256 
    257 /*
    258  * Function:
    259  *      _qsgmiie_reg_write
    260  * Doc:
    261  *      register write operations
    262  * Parameters:
    263  *      unit            - (IN)  unit number
    264  *      core_addr       - (IN)  core address
    265  *      reg_addr        - (IN)  address to write
    266  *      val             - (IN)  write value
    267  */
    268 STATIC int 
    269 _qsgmiie_reg_write(void* user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val)
    270 {
    271     soc_phymod_core_t *core = (soc_phymod_core_t *)user_acc;
    272     uint16 data16 = (uint16)val;
    273     uint16 mask = (uint16)(val >> 16);
    274 
    275     if (mask) {
    276         if (core->wrmask) {
    277             return core->wrmask(core->unit, core_addr, reg_addr, data16, mask);
    278         }
    279         (void)core->read(core->unit, core_addr, reg_addr, &data16);
    280         data16 &= ~mask;
    281         data16 |= (val & mask);
    282     }
    283     return core->write(core->unit, core_addr, reg_addr, data16);
    284 }
    285 
    286 
    287 #define IS_DUAL_LANE_PORT(_pc) ((_pc)->phy_mode == PHYCTRL_DUAL_LANE_PORT) 
    288 #define IND_LANE_MODE(_pc) (((_pc)->phy_mode == PHYCTRL_DUAL_LANE_PORT) || ((_pc)->phy_mode == PHYCTRL_ONE_LANE_PORT))  
    289 #define MAIN0_SERDESID_REV_LETTER_SHIFT  (14)
    290 #define MAIN0_SERDESID_REV_NUMBER_SHIFT  (11)
    291 
    292 /*
    293  * Function:
    294  *      qsgmiie_show_serdes_info
    295  * Purpose:
    296  *      Show SerDes information.
    297  * Parameters:
    298  *      pc             - (IN)  phyctrl  oject
    299  *      pInfo          - (IN)  device info object
    300  *      rev_id         - (IN)  serdes revid
    301  * Returns:     
    302  *      SOC_E_NONE
    303  */
    304 STATIC int
    305 qsgmiie_show_serdes_info(phy_ctrl_t *pc, qsgmiie_dev_info_t *pInfo, phymod_core_info_t *core_info)
    306 {
    307     uint32_t serdes_id0, len;
    308 
    309     pInfo->serdes_id0 = core_info->serdes_id ;
    310 
    311     /* This is TSC/Eagle device */
    312     serdes_id0 = pInfo->serdes_id0;
    313     sal_strncpy(pInfo->name,"QSGMIIE-", strlen("QSGMIIE-"));
    314     len = sal_strlen(pInfo->name);
    315     /* add rev letter */
    316     pInfo->name[len++] = 'A' + ((serdes_id0 >>
    317                           MAIN0_SERDESID_REV_LETTER_SHIFT) & 0x3);
    318     /* add rev number */
    319     pInfo->name[len++] = '0' + ((serdes_id0 >>
    320                           MAIN0_SERDESID_REV_NUMBER_SHIFT) & 0x7);
    321     pInfo->name[len++] = '/';
    322     pInfo->name[len++] = (pc->chip_num / 10) % 10 + '0';
    323     pInfo->name[len++] = pc->chip_num % 10 + '0';
    324     pInfo->name[len++] = '/';
    325 
    326     /* phy_mode: 0 single port mode, port uses all four lanes of Warpcore
    327      *           1 dual port mode, port uses 2 lanes
    328      *           2 quad port mode, port uses 1 lane
    329      */
    330     if (IS_DUAL_LANE_PORT(pc)) { /* dual-xgxs mode */
    331         if (pc->lane_num < 2) { /* the first dual-xgxs port */
    332             pInfo->name[len++] = '0';
    333             pInfo->name[len++] = '-';
    334             pInfo->name[len++] = '1';
    335         } else {
    336             pInfo->name[len++] = '2';
    337             pInfo->name[len++] = '-';
    338             pInfo->name[len++] = '3';
    339         }
    340     } else if (pc->phy_mode == PHYCTRL_QSGMII_CORE_PORT) {
    341         pInfo->name[len++] = pc->lane_num + '0';
    342     } else {
    343         pInfo->name[len++] = '4';
    344     }
    345     pInfo->name[len] = 0;  /* string terminator */
    346 
    347     if (len > QSGMIIE_LANE_NAME_LEN) {
    348         LOG_ERROR(BSL_LS_SOC_COMMON,
    349                   (BSL_META("QSGMIIE info string length %d exceeds max length 0x%x: u=%d p=%d\n"),
    350                    len,QSGMIIE_LANE_NAME_LEN, pc->unit, pc->port));
    351         return SOC_E_MEMORY;
    352     }
    353     return SOC_E_NONE;
    354 }
    355 
    356 STATIC int 
    357 qsgmiie_ref_clk_convert(int port_refclk_int, phymod_ref_clk_t *ref_clk)
    358 {
    359     switch (port_refclk_int)
    360     {
    361         case 156:
    362             *ref_clk = phymodRefClk156Mhz;
    363             break;
    364         case 125:
    365             *ref_clk = phymodRefClk125Mhz;
    366             break;
    367         default:
    368             *ref_clk = phymodRefClk156Mhz;
    369             break;
    370     }
    371 
    372     return SOC_E_NONE;
    373 }
    374 /*
    375  * Function:
    376  *      qsgmiie_speed_to_interface_config_get
    377  * Purpose:     
    378  *      Convert speed to interface_config struct
    379  * Parameters:
    380  *      unit                - BCM unit number.
    381  *      port                - Port number.
    382  *      speed               - speed to convert
    383  *      interface_config    - output interface config struct
    384  * Returns:     
    385  *      SOC_E_NONE
    386  */
    387 STATIC int 
    388 qsgmiie_speed_to_interface_config_get(qsgmiie_speed_config_t* speed_config, phymod_phy_inf_config_t* interface_config)
    389 {
    390     /*
    391     int port_is_higig;
    392     int port_num_lanes;
    393     int scr_enabled;
    394     int fiber_pref;
    395     */
    396 
    397     /*
    398     port_is_higig = speed_config->port_is_higig;
    399     port_num_lanes = speed_config->port_num_lanes;
    400     scr_enabled = speed_config->scrambler_en;
    401     fiber_pref = speed_config->fiber_pref;
    402     */
    403 
    404     SOC_IF_ERROR_RETURN(phymod_phy_inf_config_t_init(interface_config));
    405 
    406     interface_config->data_rate = speed_config->speed;
    407 
    408     switch (speed_config->speed) {
    409         case 10:
    410             interface_config->interface_type = phymodInterfaceSGMII;
    411             break;
    412         case 100:
    413         case 1000:
    414             if (speed_config->fiber_pref) {
    415                 interface_config->interface_type = phymodInterface1000X;
    416             } else {
    417                 interface_config->interface_type = phymodInterfaceSGMII;
    418             }
    419             break;
    420         case 2500:
    421             interface_config->interface_type = phymodInterface1000X;
    422             break;
    423     default:
    424             if (speed_config->fiber_pref) {
    425                 interface_config->interface_type = phymodInterface1000X;
    426             } else {
    427                 interface_config->interface_type = phymodInterfaceSGMII;
    428             }
    429             break;
    430     }
    431 
    432     SOC_IF_ERROR_RETURN(
    433         qsgmiie_ref_clk_convert(speed_config->port_refclk_int, &(interface_config->ref_clock)));
    434     
    435     return SOC_E_NONE;
    436 }
    437 
    438 /*
    439  * Function:
    440  *      qsgmiie_config_init
    441  * Purpose:     
    442  *      Determine phy configuration data for purposes of PHYMOD initialization.
    443  * 
    444  *      A side effect of this procedure is to save some per-logical port
    445  *      information in (qsgmiie_cfg_t *) &pc->driver_data;
    446  *
    447  * Parameters:
    448  *      unit                  - BCM unit number.
    449  *      port                  - Port number.
    450  *      logical_lane_offset   - starting logical lane number
    451  * Returns:     
    452  *      SOC_E_NONE
    453  */
    454 STATIC int
    455 qsgmiie_config_init(int unit, soc_port_t port, int logical_lane_offset,
    456                  phymod_core_init_config_t *core_init_config, 
    457                  phymod_phy_init_config_t  *pm_phy_init_config)
    458 {
    459     phy_ctrl_t                   *pc;
    460     qsgmiie_speed_config_t          *speed_config;
    461     qsgmiie_config_t                *pCfg;
    462     phymod_tx_t                  *p_tx;
    463     int                          port_refclk_int;
    464     int                          port_num_lanes;
    465     int                          core_num;
    466     int                          phy_num_lanes;
    467     int                          port_is_higig;
    468     int                          phy_passthru;
    469     int                          phy_supports_dual_rate;
    470     int                          lane_map_rx, lane_map_tx;
    471     int                          i;
    472     int                          fiber_pref = 1;
    473 
    474     pc = INT_PHY_SW_STATE(unit, port);
    475     if (pc == NULL) {
    476         return SOC_E_INTERNAL;
    477     }
    478     pCfg = (qsgmiie_config_t *) pc->driver_data;
    479 
    480     /* extract data from SOC_INFO */
    481     port_refclk_int = SOC_INFO(unit).port_refclk_int[port];
    482 #if 0
    483     
    484     port_refclk_int = soc_property_port_get(unit,port, spn_XGXS_PHY_VCO_FREQ, pCfg->refclk);
    485 #endif
    486     port_refclk_int = soc_property_port_get(unit, port,spn_XGXS_LCPLL_XTAL_REFCLK, port_refclk_int);
    487     port_num_lanes = SOC_INFO(unit).port_num_lanes[port];
    488     port_is_higig = PBMP_MEMBER(PBMP_HG_ALL(unit), port);
    489     phy_supports_dual_rate = PHY_IS_SUPPORT_DUAL_RATE(unit, port);
    490 
    491     /* figure out how many lanes are in this phy */
    492     core_num = (logical_lane_offset / 4);
    493     phy_num_lanes = (port_num_lanes - logical_lane_offset);
    494     if (phy_num_lanes > MAX_NUM_LANES) {
    495        phy_num_lanes = MAX_NUM_LANES;
    496     }
    497     
    498     /* 
    499         CORE configuration
    500     */
    501     phymod_core_init_config_t_init(core_init_config);
    502 
    503     core_init_config->lane_map.num_of_lanes = NUM_LANES;
    504     core_init_config->flags = PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY;
    505     lane_map_rx = soc_property_port_suffix_num_get(unit, port, core_num,
    506                                         spn_XGXS_RX_LANE_MAP, "core", 0x3210);
    507     for (i=0; i<NUM_LANES; i++) {
    508         core_init_config->lane_map.lane_map_rx[i] = (lane_map_rx >> (i * 4 /*4 bit per lane*/)) & 0xf;
    509     }
    510  
    511     lane_map_tx = soc_property_port_suffix_num_get(unit, port, core_num,
    512                                         spn_XGXS_TX_LANE_MAP, "core", 0x3210);
    513     for (i=0; i<NUM_LANES; i++) {
    514         core_init_config->lane_map.lane_map_tx[i] = (lane_map_tx >> (i * 4 /*4 bit per lane*/)) & 0xf;
    515     }
    516 
    517     speed_config = &(pCfg->speed_config);
    518     speed_config->port_refclk_int  = port_refclk_int;
    519     speed_config->speed  = soc_property_port_get(unit, port, spn_PORT_INIT_SPEED, 0);
    520     speed_config->port_num_lanes   = phy_num_lanes;
    521     speed_config->port_is_higig    = port_is_higig;
    522     speed_config->rxaui_mode       = soc_property_port_get(unit, port, spn_SERDES_RXAUI_MODE, 1);
    523     speed_config->scrambler_en     = soc_property_port_get(unit, port, spn_SERDES_SCRAMBLER_ENABLE, 0);
    524     speed_config->line_interface   = soc_property_port_get(unit, port, spn_SERDES_IF_TYPE, 0);
    525     speed_config->fiber_pref = soc_property_port_get(unit, port, spn_SERDES_FIBER_PREF, fiber_pref);
    526     speed_config->pcs_bypass       = 0;
    527     speed_config->phy_supports_dual_rate = phy_supports_dual_rate;
    528 
    529     SOC_IF_ERROR_RETURN
    530         (qsgmiie_speed_to_interface_config_get(speed_config, &(core_init_config->interface)));
    531 
    532     /* 
    533         PHY configuration
    534     */
    535 
    536     /*set the default tx parameters */
    537     for (i = 0; i < TXDRV_ENTRY_NUM; i++) {
    538         p_tx = &pCfg->tx_drive[i];
    539         SOC_IF_ERROR_RETURN(phymod_tx_t_init(p_tx));
    540     }
    541     p_tx = &pCfg->tx_drive[TXDRV_DFT_INX];
    542     p_tx->amp = 0xc;
    543     p_tx->pre = 0x00;
    544     p_tx->main = 0x70;
    545     p_tx->post = 0x0;
    546     p_tx->post2 = 0x00;
    547     p_tx->post3 = 0x00;
    548 
    549     p_tx = &pCfg->tx_drive[TXDRV_XFI_INX];
    550     p_tx->amp = 0xc;
    551     p_tx->pre = 0x00;
    552     p_tx->main = 0x30;
    553     p_tx->post = 0x0;
    554     p_tx->post2 = 0x00;
    555     p_tx->post3 = 0x00;
    556 
    557     p_tx = &pCfg->tx_drive[TXDRV_SFIDAC_INX];
    558     p_tx->amp = 0xc;
    559     p_tx->pre = 0x00;
    560     p_tx->main = 0x18;
    561     p_tx->post = 0x18;
    562     p_tx->post2 = 0x00;
    563     p_tx->post3 = 0x00;
    564 
    565     p_tx = &pCfg->tx_drive[TXDRV_AN_INX];
    566     p_tx->amp = 0xc;
    567     p_tx->pre = 0x00;
    568     p_tx->main = 0x70;
    569     p_tx->post = 0x00;
    570     p_tx->post2 = 0x00;
    571     p_tx->post3 = 0x00;
    572 
    573     phymod_phy_init_config_t_init(pm_phy_init_config);
    574     /*initialize the tx taps and driver current*/
    575     for (i = 0; i < 4; i++) { 
    576         pm_phy_init_config->tx[i].pre = 0x00;
    577         pm_phy_init_config->tx[i].main = 0x70;
    578         pm_phy_init_config->tx[i].post = 0x0;
    579         pm_phy_init_config->tx[i].post2 = 0x0;
    580         pm_phy_init_config->tx[i].post3 = 0x0;
    581         pm_phy_init_config->tx[i].amp = 0xc;
    582     }
    583     pm_phy_init_config->polarity.rx_polarity 
    584                                  = soc_property_port_get(unit, port,
    585                                    spn_PHY_XAUI_TX_POLARITY_FLIP, FALSE);
    586     pm_phy_init_config->polarity.tx_polarity 
    587                                  = soc_property_port_get(unit, port,
    588                                    spn_PHY_XAUI_RX_POLARITY_FLIP, FALSE);
    589 
    590     for (i = 0; i < MAX_NUM_LANES; i++) {
    591         uint32_t preemphasis;
    592         preemphasis = soc_property_port_suffix_num_get(unit, port,
    593                                     i + core_num * 4, spn_SERDES_PREEMPHASIS,
    594                                     "lane", QSGMIIE_NO_CFG_VALUE);
    595         if (preemphasis != QSGMIIE_NO_CFG_VALUE) {
    596             pm_phy_init_config->tx[i].pre = preemphasis & 0xff;
    597             pm_phy_init_config->tx[i].main = (preemphasis & 0xff00) >> 8;
    598             pm_phy_init_config->tx[i].post = (preemphasis & 0xff0000) >> 16;
    599         }     
    600     }
    601 
    602     for (i = 0; i < MAX_NUM_LANES; i++) {
    603         pm_phy_init_config->tx[i].amp = soc_property_port_suffix_num_get(unit, port,
    604                                     i + core_num * 4, spn_SERDES_DRIVER_CURRENT,
    605                                     "lane", pm_phy_init_config->tx[i].amp);
    606     }
    607 
    608     
    609 
    610     
    611     pm_phy_init_config->cl72_en = soc_property_port_get(unit, port, spn_PHY_AN_C72, TRUE);
    612     pm_phy_init_config->an_en = TRUE;
    613 
    614     /* check the higig port mode, then set the default cl73 mode */
    615     if (port_is_higig) {
    616         pCfg->cl73an = FALSE;
    617     } else {
    618         pCfg->cl73an = PHYMOD_AN_CAP_CL73;
    619     }
    620 
    621     /* by default disable cl37 */
    622     pCfg->cl37an = FALSE;
    623     pCfg->an_cl72 = TRUE;
    624     pCfg->forced_init_cl72 = FALSE; 
    625 
    626     pCfg->cl73an  = soc_property_port_get(unit, port,
    627                                           spn_PHY_AN_C73, pCfg->cl73an); /* no L: C73, not CL73 */
    628 
    629     pCfg->cl37an = soc_property_port_get(unit, port,
    630                                         spn_PHY_AN_C37, pCfg->cl37an); /* no L: C37, not CL37 */
    631 
    632     pCfg->an_cl72 = soc_property_port_get(unit, port,
    633                                         spn_PHY_AN_C72, pCfg->an_cl72);
    634     pCfg->forced_init_cl72 = soc_property_port_get(unit, port,
    635                                         spn_PORT_INIT_CL72, pCfg->forced_init_cl72);
    636 
    637     
    638     /* 
    639         phy_ctrl_t configuration (LOGICAL PORT BASED)
    640         Only do this once, for the first core of the logical port
    641     */
    642     if (core_num == 0) {
    643         
    644         /* pc->lane_num, pc->chip_num */
    645 #if 0
    646         soc_port_info = &(SOC_DRIVER(unit)->port_info[phy_port]);
    647 /* mark it for the assertion of lane_num and chip_num is assigned */
    648         pc->lane_num = soc_port_info->bindex;
    649         pc->chip_num = SOC_BLOCK_NUMBER(unit, soc_port_info->blk);
    650 #endif
    651 
    652         /* phy_mode, PHYCTRL_MDIO_ADDR_SHARE, PHY_FLAGS_INDEPENDENT_LANE */
    653         if (port_num_lanes == 4) {
    654             pc->phy_mode = PHYCTRL_QUAD_LANE_PORT;
    655             PHY_FLAGS_CLR(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
    656         } else if (port_num_lanes == 2) {
    657             pc->phy_mode = PHYCTRL_DUAL_LANE_PORT;
    658             pc->flags |= PHYCTRL_MDIO_ADDR_SHARE;
    659             PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
    660         } else if (port_num_lanes == 1) {
    661             pc->phy_mode = PHYCTRL_ONE_LANE_PORT;
    662             pc->flags |= PHYCTRL_MDIO_ADDR_SHARE;
    663             PHY_FLAGS_SET(unit, port, PHY_FLAGS_INDEPENDENT_LANE);
    664         }
    665 
    666         /* PHY_FLAGS_PASSTHRU */
    667         phy_passthru = 0;
    668         if (PHY_EXTERNAL_MODE(unit, port)) {
    669             PHY_FLAGS_CLR(unit, port, PHY_FLAGS_PASSTHRU);
    670             phy_passthru = soc_property_port_get(unit, port,
    671                                                  spn_PHY_PCS_REPEATER, 0);
    672             if (phy_passthru) {
    673                 PHY_FLAGS_SET(unit, port, PHY_FLAGS_PASSTHRU);
    674             }
    675         }
    676 
    677         /* PHY_FLAGS_FIBER */
    678         PHY_FLAGS_CLR(unit, port, PHY_FLAGS_FIBER);
    679         if (!PHY_EXTERNAL_MODE(unit, port)) {
    680 
    681             fiber_pref = FALSE;
    682             if (PHY_FIBER_MODE(unit, port) ||
    683                 (phy_passthru) ||
    684                 (!PHY_INDEPENDENT_LANE_MODE(unit, port)) ||
    685                 (pc->speed_max >= 10000)) {
    686                 fiber_pref = TRUE;
    687             }
    688 
    689             fiber_pref = soc_property_port_get(unit, port,
    690                                                spn_SERDES_FIBER_PREF, fiber_pref);
    691             if (fiber_pref) {
    692                 PHY_FLAGS_SET(unit, port, PHY_FLAGS_FIBER);
    693             }
    694         }
    695 
    696         
    697         PHY_FLAGS_SET(unit,port,PHY_FLAGS_SERVICE_INT_PHY_LINK_GET);
    698 
    699         
    700         /* not used  */
    701         /* pCfg->cl73an = soc_property_port_get(unit, port, spn_PHY_AN_C73, TSCMOD_CL73_WO_BAM);
    702 
    703         if (!PHY_EXTERNAL_MODE(unit, port)) {
    704             if (pCfg->cl73an) {
    705                 PHY_FLAGS_SET(unit, port, PHY_FLAGS_C73);
    706             }
    707         }
    708         */
    709 
    710         
    711         if ((PHY_FIBER_MODE(unit, port) && !PHY_EXTERNAL_MODE(unit, port)) ||
    712             phy_passthru) {
    713             pCfg->pdetect1000x = TRUE;
    714         } else {
    715             pCfg->pdetect1000x = FALSE;
    716         }
    717 
    718 #if 0
    719         
    720         pCfg->forced_init_cl72 = soc_property_port_get(unit, port, spn_PORT_INIT_CL72, FALSE);
    721         /* for forced speed mode */
    722         if((pCfg->forced_init_cl72>0)&&(pCfg->forced_init_cl72<16)) 
    723            FORCE_CL72_MODE(pc)    = 1 ;
    724         else                         
    725            FORCE_CL72_MODE(pc)    = 0 ;
    726 
    727         FORCE_CL72_ENABLED(pc) = 0;
    728         FORCE_CL72_STATE(pc)   = TSCMOD_FORCE_CL72_IDLE;
    729         FORCE_CL72_RESTART_CNT(pc) = 0;
    730 #endif
    731 #if 0
    732         
    733         pCfg->sw_rx_los.enable = soc_property_port_get(unit, port,
    734                                 spn_SERDES_RX_LOS, pCfg->sw_rx_los.enable);
    735 #endif
    736 
    737 #if 0
    738 #endif
    739         pCfg->cx4_10g            = soc_property_port_get(unit, port, spn_10G_IS_CX4, TRUE);
    740     }
    741 
    742     return SOC_E_NONE;
    743 }
    744 
    745 /*
    746  * Function:
    747  *      phy_qsgmiie_init
    748  *  
    749  *      An SDK "phy" is a logical port, which can consist of from 1-10 lanes,
    750  *          (A phy with more than 4 lanes requires more than one core).
    751  *      Per-logical port information is saved in (qsgmiie_cfg_t *) &pc->driver_data.
    752  *      An SDK phy is implemented as one or more PHYMOD "phy"s.
    753  *  
    754  *      A PHYMOD "phy" resides completely within a single core, which can be
    755  *      from 1 to 4 lanes.
    756  *      Per-phymod phy information is kept in (soc_phymod_ctrl_t) *pc->phymod_ctrl
    757  *      A phymod phy points to its core.  Up to 4 phymod phys can be on a single core
    758  *  
    759  * Purpose:     
    760  *      Initialize a qsgmiie phy
    761  * Parameters:
    762  *      unit - BCM unit number.
    763  *      port - Port number. 
    764  * Returns:     
    765  *      SOC_E_NONE
    766  */
    767 STATIC int
    768 phy_qsgmiie_init(int unit, soc_port_t port)
    769 {
    770     phy_ctrl_t                *pc; 
    771     soc_phymod_ctrl_t         *pmc;
    772     soc_phymod_phy_t          *phy = NULL;
    773     soc_phymod_core_t         *core;
    774     qsgmiie_config_t             *pCfg;
    775     qsgmiie_speed_config_t       *speed_config;
    776     qsgmiie_dev_info_t           *pInfo;
    777     soc_phy_info_t            *pi;
    778     phymod_phy_inf_config_t   interface_config;
    779     phymod_core_status_t      core_status;
    780     phymod_core_info_t        core_info;
    781     int idx;
    782     int logical_lane_offset;
    783 
    784     DBG_OK();
    785 
    786     pc = INT_PHY_SW_STATE(unit, port);
    787     if (pc == NULL) {
    788         return SOC_E_INTERNAL;
    789     }
    790     pc->driver_data = (void*)(pc+1);
    791     pmc = &pc->phymod_ctrl;
    792     pCfg = (qsgmiie_config_t *) pc->driver_data;
    793     pInfo = &pCfg->info; 
    794     
    795     sal_memset(pCfg, 0, sizeof(*pCfg));
    796     speed_config = &(pCfg->speed_config);
    797 
    798     /* Loop through all phymod phys that support this SDK phy */
    799     logical_lane_offset = 0;
    800     for (idx = 0; idx < pmc->num_phys; idx++) {
    801         phy = pmc->phy[idx];
    802         core = phy->core;
    803 
    804         
    805 
    806         /* determine configuration data structure to default values, based on SOC properties */
    807         SOC_IF_ERROR_RETURN
    808             (qsgmiie_config_init(unit, port,
    809                               logical_lane_offset,
    810                               &core->init_config, &phy->init_config));
    811 
    812         
    813         if (!core->init) {
    814            core_status.pmd_active = 0;
    815            if (!SOC_WARM_BOOT(unit)) {
    816             SOC_IF_ERROR_RETURN
    817                (phymod_core_init(&core->pm_core, &core->init_config, &core_status));
    818            }
    819            core->init = TRUE;
    820         }
    821 
    822         if (!SOC_WARM_BOOT(unit)) {
    823             SOC_IF_ERROR_RETURN
    824                 (phymod_phy_init(&phy->pm_phy, &phy->init_config));
    825         }
    826 
    827         /*read serdes id info */
    828         SOC_IF_ERROR_RETURN
    829             (phymod_core_info_get(&core->pm_core, &core_info)); 
    830 
    831 
    832         /* for multicore phys, need to ratchet up to the next batch of lanes */
    833         logical_lane_offset += core->init_config.lane_map.num_of_lanes;
    834     }
    835 
    836     /*fill up the pInfo table for displaying the serdes driver info */
    837     SOC_IF_ERROR_RETURN
    838         (qsgmiie_show_serdes_info(pc, pInfo, &core_info));
    839 
    840     /* retrieve chip level information for serdes driver info */
    841     pi = &SOC_PHY_INFO(unit, port);
    842 
    843     if (!PHY_EXTERNAL_MODE(unit, port)) {
    844         pi->phy_name = pInfo->name;
    845     }
    846 
    847     if (SOC_WARM_BOOT(unit)) {
    848         return SOC_E_NONE;
    849     }
    850     /* set the port to its max or init_speed */
    851     SOC_IF_ERROR_RETURN
    852         (qsgmiie_speed_to_interface_config_get(speed_config, &interface_config));
    853     SOC_IF_ERROR_RETURN
    854         (phymod_phy_interface_config_set(&phy->pm_phy,
    855                                          0 /* flags */, &interface_config));
    856 
    857     return SOC_E_NONE;
    858 }
    859 
    860 /*
    861  * Function:
    862  *      phy_qsgmiie_link_get
    863  * Purpose:
    864  *      Get layer2 connection status.
    865  * Parameters:
    866  *      unit - BCM unit number.
    867  *      port - Port number. 
    868  *      link - address of memory to store link up/down state.
    869  * Returns:     
    870  *      SOC_E_NONE
    871  */
    872 STATIC int
    873 phy_qsgmiie_link_get(int unit, soc_port_t port, int *link)
    874 {
    875     phy_ctrl_t                *pc;
    876     soc_phymod_ctrl_t         *pmc;
    877     phymod_phy_access_t       *pm_phy;
    878 
    879     *link = 0;
    880     /* locate phy control */
    881     pc = INT_PHY_SW_STATE(unit, port);
    882     if (pc == NULL) {
    883         return SOC_E_INTERNAL;
    884     }
    885 
    886     pmc = &pc->phymod_ctrl;
    887     pm_phy = &pmc->phy[0]->pm_phy;
    888 
    889     SOC_IF_ERROR_RETURN
    890         (phymod_phy_link_status_get(pm_phy, (uint32_t *) link));
    891     return (SOC_E_NONE);
    892 }
    893 
    894 /*
    895  * Function:
    896  *      phy_qsgmiie_enable_set
    897  * Purpose:
    898  *      Enable/Disable phy 
    899  * Parameters:
    900  *      unit - BCM unit number.
    901  *      port - Port number. 
    902  *      enable - on/off state to set
    903  * Returns:     
    904  *      SOC_E_NONE
    905  */
    906 STATIC int
    907 phy_qsgmiie_enable_set(int unit, soc_port_t port, int enable)
    908 {
    909     phy_ctrl_t                *pc;
    910     soc_phymod_ctrl_t         *pmc;
    911     phymod_phy_access_t       *pm_phy;
    912     phymod_phy_power_t        phy_power;
    913     int idx;
    914 
    915     DBG_OK();
    916 
    917     /* locate phy control */
    918     pc = INT_PHY_SW_STATE(unit, port);
    919     if (pc == NULL) {
    920         return SOC_E_INTERNAL;
    921     }
    922 
    923     if (enable) {
    924         phy_power.tx = phymodPowerOn;
    925         phy_power.rx = phymodPowerOn;
    926     } else {
    927         phy_power.tx = phymodPowerOff;
    928         phy_power.rx = phymodPowerOff;
    929     }
    930 
    931     pmc = &pc->phymod_ctrl;
    932     for (idx = 0; idx < pmc->num_phys; idx++) {
    933         pm_phy = &pmc->phy[idx]->pm_phy;
    934         SOC_IF_ERROR_RETURN
    935             (phymod_phy_power_set(pm_phy, &phy_power));
    936     }
    937     return (SOC_E_NONE);
    938 }
    939 
    940 /*
    941  * Function:
    942  *      phy_qsgmiie_enable_get
    943  * Purpose:
    944  *      Enable/Disable phy 
    945  * Parameters:
    946  *      unit - BCM unit number.
    947  *      port - Port number. 
    948  *      enable - on/off state to set
    949  * Returns:     
    950  *      SOC_E_NONE
    951  */
    952 STATIC int
    953 phy_qsgmiie_enable_get(int unit, soc_port_t port, int *enable)
    954 {
    955     phy_ctrl_t                *pc;
    956     soc_phymod_ctrl_t         *pmc;
    957     phymod_phy_access_t       *pm_phy;
    958     phymod_phy_power_t        phy_power;
    959 
    960     DBG_OK();
    961 
    962     /* locate phy control */
    963     pc = INT_PHY_SW_STATE(unit, port);
    964     if (pc == NULL) {
    965         return SOC_E_INTERNAL;
    966     }
    967 
    968     pmc = &pc->phymod_ctrl;
    969     pm_phy = &pmc->phy[0]->pm_phy;
    970     SOC_IF_ERROR_RETURN
    971         (phymod_phy_power_get(pm_phy, &phy_power));
    972     if ((phy_power.tx == phymodPowerOff) && (phy_power.rx == phymodPowerOff)) {
    973         *enable = 0;
    974     } else if ((phy_power.tx == phymodPowerOn) && (phy_power.rx == phymodPowerOn)) {
    975         *enable = 1;
    976     } else if ((phy_power.tx == phymodPowerOffOn) && (phy_power.rx == phymodPowerOffOn)){
    977         *enable = 1;
    978     } else {
    979         *enable = 0;
    980     }
    981 
    982     return (SOC_E_NONE);
    983 }
    984 
    985 
    986 /*
    987  * Function:
    988  *      phy_qsgmiie_duplex_get
    989  * Purpose:
    990  *      Get PHY duplex mode
    991  * Parameters:
    992  *      unit - BCM unit number.
    993  *      port - Port number. 
    994  *      duplex - current duplex mode
    995  * Returns:     
    996  *      SOC_E_NONE
    997  */
    998 STATIC int
    999 phy_qsgmiie_duplex_get(int unit, soc_port_t port, int *duplex)
   1000 {
   1001     *duplex = TRUE;
   1002     return SOC_E_NONE;
   1003 }
   1004 
   1005 /*
   1006  * Function:
   1007  *      phy_qsgmiie_speed_set
   1008  * Purpose:
   1009  *      Set PHY speed
   1010  * Parameters:
   1011  *      unit - BCM unit number.
   1012  *      port - Port number. 
   1013  *      speed - link speed in Mbps
   1014  * Returns:     
   1015  *      SOC_E_NONE
   1016  */
   1017 
   1018 STATIC int
   1019 phy_qsgmiie_speed_set(int unit, soc_port_t port, int speed)
   1020 {
   1021     phy_ctrl_t                *pc;
   1022     qsgmiie_config_t             *pCfg;
   1023     soc_phymod_ctrl_t         *pmc;
   1024     soc_phymod_phy_t          *phy;
   1025     int                       idx;
   1026     qsgmiie_speed_config_t       speed_config;
   1027     phymod_phy_inf_config_t   interface_config;
   1028 
   1029     /* locate phy control */
   1030     pc = INT_PHY_SW_STATE(unit, port);
   1031     if (pc == NULL) {
   1032         return SOC_E_INTERNAL;
   1033     }
   1034 
   1035     if (speed == 0) {
   1036         return SOC_E_NONE;
   1037     }
   1038 
   1039     DBG_OK();
   1040 
   1041     pmc = &pc->phymod_ctrl;
   1042     pCfg = (qsgmiie_config_t *) pc->driver_data;
   1043 
   1044     /* take a copy of core and phy configuration values, and set the desired speed */
   1045     sal_memcpy(&speed_config, &pCfg->speed_config, sizeof(speed_config));
   1046     speed_config.speed = speed;
   1047 
   1048     /* determine the interface configuration */
   1049     SOC_IF_ERROR_RETURN
   1050         (qsgmiie_speed_to_interface_config_get(&speed_config, &interface_config));
   1051 
   1052     /* now loop through all cores */
   1053     for (idx = 0; idx < pmc->num_phys; idx++) {
   1054         phy = pmc->phy[idx];
   1055         if (phy == NULL) {
   1056             return SOC_E_INTERNAL;
   1057         }
   1058 
   1059         /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */
   1060         SOC_IF_ERROR_RETURN
   1061             (phymod_phy_interface_config_set(&phy->pm_phy,
   1062                                              0 /* flags */, &interface_config));
   1063     }
   1064 
   1065     /* record success */
   1066     pCfg->speed_config.speed = speed;
   1067 
   1068     return (SOC_E_NONE);
   1069 }
   1070 
   1071 /*
   1072  * Function:
   1073  *      phy_qsgmiie_speed_get
   1074  * Purpose:
   1075  *      Get PHY speed
   1076  * Parameters:
   1077  *      unit - BCM unit number.
   1078  *      port - Port number. 
   1079  *      speed - current link speed in Mbps
   1080  * Returns:     
   1081  *      SOC_E_NONE
   1082  */
   1083 STATIC int
   1084 phy_qsgmiie_speed_get(int unit, soc_port_t port, int *speed)
   1085 {
   1086     phy_ctrl_t                *pc;
   1087     soc_phymod_ctrl_t         *pmc;
   1088     soc_phymod_phy_t          *phy;
   1089     phymod_phy_inf_config_t   interface_config;
   1090     int flag = 0;
   1091     phymod_ref_clk_t ref_clk;
   1092     qsgmiie_config_t *pCfg;
   1093 
   1094     /* locate phy control */
   1095     pc = INT_PHY_SW_STATE(unit, port);
   1096     if (pc == NULL) {
   1097         return SOC_E_INTERNAL;
   1098     }
   1099 
   1100     DBG_OK();
   1101 
   1102     pmc = &pc->phymod_ctrl;
   1103 
   1104     /* initialize the data structure */
   1105     interface_config.data_rate = 0;
   1106 
   1107     /* now loop through all cores */
   1108     phy = pmc->phy[0];
   1109     if (phy == NULL) {
   1110         return SOC_E_INTERNAL;
   1111     }
   1112 
   1113     pCfg = (qsgmiie_config_t *) pc->driver_data;
   1114     SOC_IF_ERROR_RETURN(
   1115         qsgmiie_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clk));
   1116 
   1117     /* note that the flags have an option to indicate whether it's ok to reprogram the PLL */
   1118     SOC_IF_ERROR_RETURN
   1119         (phymod_phy_interface_config_get(&phy->pm_phy,
   1120                                          flag, ref_clk, &interface_config));
   1121     *speed = interface_config.data_rate;
   1122     return (SOC_E_NONE);
   1123 }
   1124 
   1125 /*
   1126  * Function:    
   1127  *      phy_qsgmiie_an_set
   1128  * Purpose:     
   1129  *      Enable or disable auto-negotiation on the specified port.
   1130  * Parameters:
   1131  *      unit - BCM unit number.
   1132  *      port - Port number. 
   1133  *      an   - Boolean, if true, auto-negotiation is enabled 
   1134  *              (and/or restarted). If false, autonegotiation is disabled.
   1135  * Returns:     
   1136  *      SOC_E_XXX  _soc_triumph_tx
   1137  */
   1138 STATIC int
   1139 phy_qsgmiie_an_set(int unit, soc_port_t port, int enable)
   1140 {
   1141     phy_ctrl_t                *pc;
   1142     qsgmiie_config_t             *pCfg;
   1143     soc_phymod_ctrl_t         *pmc;
   1144     soc_phymod_phy_t          *phy;
   1145     phymod_autoneg_control_t  an;
   1146     soc_info_t *si;
   1147 
   1148     /* locate phy control */
   1149     pc = INT_PHY_SW_STATE(unit, port);
   1150     if (pc == NULL) {
   1151         return SOC_E_INTERNAL;
   1152     }
   1153 
   1154     DBG_OK();
   1155 
   1156     phymod_autoneg_control_t_init(&an);
   1157     pmc = &pc->phymod_ctrl;
   1158     pCfg = (qsgmiie_config_t *) pc->driver_data;
   1159     si = &SOC_INFO(unit);
   1160 
   1161     /* only request autoneg on the first core */
   1162     phy = pmc->phy[0];
   1163     if (phy == NULL) {
   1164         return SOC_E_INTERNAL;
   1165     }
   1166     an.enable = enable;
   1167     an.num_lane_adv = si->port_num_lanes[port];
   1168     an.an_mode = phymod_AN_MODE_NONE;
   1169     if(pCfg->cl73an) {
   1170         switch (pCfg->cl73an) {
   1171             case TEMOD_CL73_W_BAM:  
   1172                 an.an_mode = phymod_AN_MODE_CL73BAM;  
   1173                 break ;
   1174             case TEMOD_CL73_WO_BAM:
   1175                 an.an_mode = phymod_AN_MODE_CL73;  
   1176                 break ;
   1177             case TEMOD_CL73_HPAM_VS_SW:    
   1178                 an.an_mode = phymod_AN_MODE_HPAM;  
   1179                 break ;  /* against TD+ */
   1180             case TEMOD_CL73_HPAM:
   1181                 an.an_mode = phymod_AN_MODE_HPAM;  
   1182                 break ;  /* against TR3 */
   1183             case TEMOD_CL73_CL37:    
   1184                 an.an_mode = phymod_AN_MODE_CL73;  
   1185                 break ;
   1186             default:
   1187                 break;
   1188         }
   1189     } else if (pCfg->cl37an) {
   1190         switch (pCfg->cl37an) {
   1191             case TEMOD_CL37_WO_BAM:
   1192                 an.an_mode = phymod_AN_MODE_CL37;
   1193                 break;
   1194             case TEMOD_CL37_W_BAM:
   1195                 an.an_mode = phymod_AN_MODE_CL37BAM;
   1196                 break;
   1197             default:
   1198                 break;
   1199         } 
   1200     } else {
   1201          if(pCfg->hg_mode) {
   1202             an.an_mode = phymod_AN_MODE_CL37BAM;  /* default mode */
   1203          } else {        
   1204             if(pCfg->fiber_pref) {
   1205                 an.an_mode = phymod_AN_MODE_CL37;
   1206             } else {
   1207                 an.an_mode = phymod_AN_MODE_SGMII;
   1208             }
   1209          }
   1210     }
   1211     SOC_IF_ERROR_RETURN
   1212         (phymod_phy_autoneg_set(&phy->pm_phy, &an));
   1213 
   1214     return (SOC_E_NONE);
   1215 }
   1216 
   1217 /*
   1218  * Function:    
   1219  *      phy_qsgmiie_an_get
   1220  * Purpose:     
   1221  *      Get the current auto-negotiation status (enabled/busy)
   1222  * Parameters:
   1223  *      unit - BCM unit number.
   1224  *      port - Port number. 
   1225  *      an   - (OUT) if true, auto-negotiation is enabled.
   1226  *      an_done - (OUT) if true, auto-negotiation is complete. This
   1227  *              value is undefined if an == false.
   1228  * Returns:     
   1229  *      SOC_E_XXX
   1230  */
   1231 
   1232 STATIC int
   1233 phy_qsgmiie_an_get(int unit, soc_port_t port, int *an, int *an_done)
   1234 {
   1235     return (SOC_E_NONE);
   1236 }
   1237 
   1238 /*
   1239  * Function:
   1240  *      phy_qsgmiie_ability_advert_set
   1241  * Purpose:
   1242  *      Set the current advertisement for auto-negotiation.
   1243  * Parameters:
   1244  *      unit - BCM unit number.
   1245  *      port - Port number.
   1246  *      ability - Port mode mask indicating supported options/speeds.
   1247  * Returns:
   1248  *      SOC_E_XXX
   1249  * Notes:
   1250  *      The advertisement is set only for the ACTIVE medium.
   1251  *      No synchronization performed at this level.
   1252  */
   1253 
   1254 STATIC int
   1255 phy_qsgmiie_ability_advert_set(int unit, soc_port_t port,
   1256                           soc_port_ability_t *ability)
   1257 {
   1258     phy_ctrl_t                *pc;
   1259     soc_phymod_ctrl_t         *pmc;
   1260     soc_phymod_phy_t          *phy;
   1261     phymod_autoneg_ability_t  phymod_autoneg_ability; 
   1262 
   1263     /* locate phy control */
   1264     pc = INT_PHY_SW_STATE(unit, port);
   1265     if (pc == NULL) {
   1266         return SOC_E_INTERNAL;
   1267     }
   1268 
   1269     phymod_autoneg_ability_t_init(&phymod_autoneg_ability);
   1270 
   1271     pmc = &pc->phymod_ctrl;
   1272 
   1273     /* only set abilities on the first core */
   1274     phy = pmc->phy[0];
   1275     if (phy == NULL) {
   1276         return SOC_E_INTERNAL;
   1277     }
   1278 
   1279     
   1280 
   1281     switch (ability->pause & (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX)) {
   1282     case SOC_PA_PAUSE_TX:
   1283         PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability);
   1284         break;
   1285     case SOC_PA_PAUSE_RX:
   1286         /*an_adv |= MII_ANA_C37_PAUSE | MII_ANA_C37_ASYM_PAUSE; */
   1287         PHYMOD_AN_CAP_ASYM_PAUSE_SET(&phymod_autoneg_ability);
   1288         PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability);
   1289         break;
   1290     case SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX:
   1291         PHYMOD_AN_CAP_SYMM_PAUSE_SET(&phymod_autoneg_ability);
   1292         break;
   1293     }
   1294 
   1295     /* also set the sgmii speed */
   1296     if(ability->speed_full_duplex & SOC_PA_SPEED_1000MB) {
   1297         PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability);
   1298         phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_1000M;
   1299     } else if(ability->speed_full_duplex & SOC_PA_SPEED_100MB) {
   1300         PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability);
   1301         phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_100M;
   1302     } else if(ability->speed_full_duplex & SOC_PA_SPEED_10MB) {
   1303         PHYMOD_AN_CAP_SGMII_SET(&phymod_autoneg_ability);
   1304         phymod_autoneg_ability.sgmii_speed = phymod_CL37_SGMII_10M;
   1305     }
   1306 
   1307     SOC_IF_ERROR_RETURN
   1308         (phymod_phy_autoneg_ability_set(&phy->pm_phy, &phymod_autoneg_ability));
   1309 
   1310     return SOC_E_NONE;
   1311 }
   1312 
   1313 /*
   1314  * Function:
   1315  *      phy_qsgmiie_ability_advert_get
   1316  * Purpose:
   1317  *      Get the current advertisement for auto-negotiation.
   1318  * Parameters:
   1319  *      unit - BCM unit number.
   1320  *      port - Port number.
   1321  *      ability - (OUT) Port mode mask indicating supported options/speeds.
   1322  * Returns:
   1323  *      SOC_E_XXX
   1324  * Notes:
   1325  *      The advertisement is retrieved for the ACTIVE medium.
   1326  *      No synchronization performed at this level.
   1327  */
   1328 
   1329 STATIC int
   1330 phy_qsgmiie_ability_advert_get(int unit, soc_port_t port,
   1331                               soc_port_ability_t *ability)
   1332 {
   1333     phy_ctrl_t                *pc;
   1334     soc_phymod_ctrl_t         *pmc;
   1335     soc_phymod_phy_t          *phy;
   1336     int                       reg37_ability;
   1337     int                       reg73_ability;
   1338     int                       reg_ability;
   1339     _shr_port_mode_t          speed_full_duplex;
   1340 
   1341     /* locate phy control */
   1342     pc = INT_PHY_SW_STATE(unit, port);
   1343     if (pc == NULL) {
   1344         return SOC_E_INTERNAL;
   1345     }
   1346 
   1347     DBG_OK();
   1348 
   1349     pmc = &pc->phymod_ctrl;
   1350 
   1351     /* only get abilities from the first core */
   1352     phy = pmc->phy[0];
   1353     if (phy == NULL) {
   1354         return SOC_E_INTERNAL;
   1355     }
   1356 
   1357     speed_full_duplex = 0;
   1358 
   1359     
   1360     reg73_ability = 0;
   1361     speed_full_duplex|= PHYMOD_AN_CAP_40G_CR4_GET(reg73_ability) ?SOC_PA_SPEED_40GB:0;
   1362     speed_full_duplex|= PHYMOD_AN_CAP_40G_KR4_GET(reg73_ability) ?SOC_PA_SPEED_40GB:0;
   1363     speed_full_duplex|= PHYMOD_AN_CAP_10G_KR_GET(reg73_ability)  ?SOC_PA_SPEED_10GB:0;
   1364     speed_full_duplex|= PHYMOD_AN_CAP_10G_KX4_GET(reg73_ability) ?SOC_PA_SPEED_10GB:0;
   1365     speed_full_duplex|= PHYMOD_AN_CAP_1G_KX_GET(reg73_ability)   ?SOC_PA_SPEED_1000MB:0;
   1366 
   1367     
   1368     reg37_ability = 0;
   1369     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_40G_GET(reg37_ability) ? SOC_PA_SPEED_40GB:0;
   1370     /* speed_full_duplex|= (reg37_ability &(1<<PHYMOD_BAM37ABL_32P7G))?      SOC_PA_SPEED_33GB:0; */
   1371     /* speed_full_duplex|= (reg37_ability &(1<<PHYMOD_BAM37ABL_31P5G))?      SOC_PA_SPEED_32GB:0; */
   1372     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_25P455G_GET(reg37_ability) ?    SOC_PA_SPEED_25GB:0;
   1373     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_21G_X4_GET(reg37_ability)?     SOC_PA_SPEED_21GB:0;
   1374     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X2_CX4_GET(reg37_ability)? SOC_PA_SPEED_20GB:0;
   1375     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X2_GET(reg37_ability)?     SOC_PA_SPEED_20GB:0;
   1376     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X4_GET(reg37_ability)?     SOC_PA_SPEED_20GB:0;
   1377     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_20G_X4_CX4_GET(reg37_ability)? SOC_PA_SPEED_20GB:0;
   1378     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_16G_X4_GET(reg37_ability)?     SOC_PA_SPEED_16GB:0;
   1379     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_15P75G_R2_GET(reg37_ability)?  SOC_PA_SPEED_16GB:0;
   1380     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_15G_X4_GET(reg37_ability)?     SOC_PA_SPEED_15GB:0;
   1381     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_13G_X4_GET(reg37_ability)?     SOC_PA_SPEED_13GB:0;
   1382     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12P7_DXGXS_GET(reg37_ability)? SOC_PA_SPEED_13GB:0;
   1383     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12P5_X4_GET(reg37_ability)?    SOC_PA_SPEED_12P5GB:0;
   1384     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_12G_X4_GET(reg37_ability)?     SOC_PA_SPEED_12GB:0;
   1385     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_GET(reg37_ability)?SOC_PA_SPEED_11GB:0;
   1386     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_X2_CX4_GET(reg37_ability)? SOC_PA_SPEED_10GB:0;
   1387     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_DXGXS_GET(reg37_ability)?  SOC_PA_SPEED_10GB:0;
   1388     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_CX4_GET(reg37_ability)?    SOC_PA_SPEED_10GB:0;
   1389     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_10G_HIGIG_GET(reg37_ability)?  SOC_PA_SPEED_10GB:0; /* 4-lane */
   1390     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_6G_X4_GET(reg37_ability)?      SOC_PA_SPEED_6000MB:0;
   1391     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_5G_X4_GET(reg37_ability)?      SOC_PA_SPEED_5000MB:0;
   1392     speed_full_duplex|= PHYMOD_BAM_CL37_CAP_2P5G_GET(reg37_ability)?       SOC_PA_SPEED_2500MB:0;
   1393     speed_full_duplex|= SOC_PA_SPEED_1000MB ;
   1394 
   1395     
   1396     reg_ability = 0 & (PHYMOD_AN_CAP_SYMM_PAUSE|PHYMOD_AN_CAP_ASYM_PAUSE);
   1397 
   1398     ability->pause = 0;
   1399     if (reg_ability == PHYMOD_AN_CAP_ASYM_PAUSE) {
   1400         ability->pause = SOC_PA_PAUSE_TX;
   1401     } else if (reg_ability == (PHYMOD_AN_CAP_SYMM_PAUSE|PHYMOD_AN_CAP_ASYM_PAUSE)) {
   1402         ability->pause = SOC_PA_PAUSE_RX;
   1403     } else if (reg_ability == PHYMOD_AN_CAP_SYMM_PAUSE) {
   1404         ability->pause = (SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX);
   1405     }
   1406 
   1407     ability->speed_full_duplex = speed_full_duplex;
   1408 
   1409     return SOC_E_NONE;
   1410 }
   1411 
   1412 /*
   1413  * Function:
   1414  *      phy_qsgmiie_ability_remote_get
   1415  * Purpose:
   1416  *      Get the current advertisement for auto-negotiation.
   1417  * Parameters:
   1418  *      unit - BCM unit number.
   1419  *      port - Port number.
   1420  *      ability - (OUT) Port mode mask indicating supported options/speeds.
   1421  * Returns:
   1422  *      SOC_E_XXX
   1423  * Notes:
   1424  *      The advertisement is retrieved for the ACTIVE medium.
   1425  *      No synchronization performed at this level.
   1426  */
   1427 
   1428 STATIC int
   1429 phy_qsgmiie_ability_remote_get(int unit, soc_port_t port,
   1430                                soc_port_ability_t *ability)
   1431 {
   1432    /*
   1433    phy_ctrl_t        *pc;
   1434    TSCMOD_DEV_DESC_t *pDesc;
   1435    tscmod_st         *tsc;
   1436    int cl37_reg, cl73_reg, sgmii_speed ;  uint32 reg73_ability, reg37_ability, reg_ability; soc_port_mode_t  ability_mode;
   1437    int rv ; 
   1438    */
   1439 #if 0
   1440 
   1441    pc    = INT_PHY_SW_STATE(unit, port);
   1442    pDesc = (TSCMOD_DEV_DESC_t *)(pc + 1);
   1443    tsc   =  (tscmod_st *)( pDesc + 1);
   1444 
   1445    tscmod_sema_lock(unit, port, __func__) ;
   1446 
   1447    TSCMOD_MEM_SET(ability, 0, sizeof(*ability));
   1448 
   1449    cl73_reg = 0 ; cl37_reg = 0 ;  sgmii_speed =0 ;  ability_mode = 0 ;  reg73_ability = 0 ; reg37_ability = 0  ;
   1450    if((tsc->an_type==TSCMOD_CL73)||(tsc->an_type==TSCMOD_CL73_BAM)) {
   1451       cl73_reg = 1 ;
   1452    } else if(tsc->an_type==TSCMOD_CL37_BAM) {
   1453       cl37_reg = 1 ;
   1454    } else {
   1455       cl37_reg = 1 ; cl73_reg = 1 ;
   1456    }
   1457 
   1458    if(cl73_reg) {
   1459       tsc->per_lane_control=TSCMOD_AN_GET_LP_CL73_ABIL ;
   1460       tscmod_tier1_selector("AUTONEG_GET", tsc, &rv);
   1461       reg73_ability = tsc->accData ;
   1462       ability_mode|= (reg73_ability &(1<<TSCMOD_ABILITY_40G_CR4)) ?SOC_PA_SPEED_40GB:0;
   1463       ability_mode|= (reg73_ability &(1<<TSCMOD_ABILITY_40G_KR4)) ?SOC_PA_SPEED_40GB:0;
   1464       ability_mode|= (reg73_ability &(1<<TSCMOD_ABILITY_20G_CR2)) ?SOC_PA_SPEED_20GB:0;
   1465       ability_mode|= (reg73_ability &(1<<TSCMOD_ABILITY_20G_KR2)) ?SOC_PA_SPEED_20GB:0;
   1466       ability_mode|= (reg73_ability &(1<<TSCMOD_ABILITY_10G_KR))  ?SOC_PA_SPEED_10GB:0;
   1467       ability_mode|= (reg73_ability &(1<<TSCMOD_ABILITY_10G_KX4)) ?SOC_PA_SPEED_10GB:0;
   1468       ability_mode|= (reg73_ability &(1<<TSCMOD_ABILITY_1G_KX))   ?SOC_PA_SPEED_1000MB:0;
   1469    }
   1470    if(cl37_reg) {
   1471       tsc->per_lane_control=TSCMOD_AN_GET_LP_CL37_ABIL ;
   1472       tscmod_tier1_selector("AUTONEG_GET", tsc, &rv);
   1473       reg37_ability = tsc->accData ;
   1474       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_40G))?        SOC_PA_SPEED_40GB:0;
   1475       /* ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_32P7G))?      SOC_PA_SPEED_33GB:0; */
   1476       /* ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_31P5G))?      SOC_PA_SPEED_32GB:0; */
   1477       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_25P455G))?    SOC_PA_SPEED_25GB:0;
   1478       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_21G_X4))?     SOC_PA_SPEED_21GB:0;
   1479       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_20G_X2_CX4))? SOC_PA_SPEED_20GB:0;
   1480       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_20G_X2))?     SOC_PA_SPEED_20GB:0;
   1481       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_20G_X4))?     SOC_PA_SPEED_20GB:0;
   1482       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_20G_X4_CX4))? SOC_PA_SPEED_20GB:0;
   1483       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_16G_X4))?     SOC_PA_SPEED_16GB:0;
   1484       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_15P75G_R2))?  SOC_PA_SPEED_16GB:0;
   1485       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_15G_X4))?     SOC_PA_SPEED_15GB:0;
   1486       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_13G_X4))?     SOC_PA_SPEED_13GB:0;
   1487       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_12P7_DXGXS))? SOC_PA_SPEED_13GB:0;
   1488       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_12P5_X4))?    SOC_PA_SPEED_12P5GB:0;
   1489       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_12G_X4))?     SOC_PA_SPEED_12GB:0;
   1490       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_10P5G_DXGXS))?SOC_PA_SPEED_11GB:0;
   1491       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_10G_X2_CX4))? SOC_PA_SPEED_10GB:0;
   1492       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_10G_DXGXS))?  SOC_PA_SPEED_10GB:0;
   1493       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_10G_CX4))?    SOC_PA_SPEED_10GB:0;
   1494       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_10G_HIGIG))?  SOC_PA_SPEED_10GB:0; /* 4-lane */
   1495       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_6G_X4))?      SOC_PA_SPEED_6000MB:0;
   1496       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_5G_X4))?      SOC_PA_SPEED_5000MB:0;
   1497       ability_mode|= (reg37_ability &(1<<TSCMOD_BAM37ABL_2P5G))?       SOC_PA_SPEED_2500MB:0;
   1498    }
   1499 
   1500    ability->speed_full_duplex = ability_mode ;
   1501 
   1502    tsc->per_lane_control=TSCMOD_AN_GET_LP_MISC_ABIL ;
   1503    tscmod_tier1_selector("AUTONEG_GET", tsc, &rv);
   1504    reg_ability = tsc->accData ;
   1505    switch(reg_ability & (TSCMOD_SYMM_PAUSE|TSCMOD_ASYM_PAUSE)) {
   1506    case TSCMOD_SYMM_PAUSE:
   1507       ability->pause = SOC_PA_PAUSE_TX | SOC_PA_PAUSE_RX;
   1508       break ;
   1509    case TSCMOD_ASYM_PAUSE:
   1510       ability->pause = SOC_PA_PAUSE_TX;
   1511       break ;
   1512    case TSCMOD_SYMM_PAUSE|TSCMOD_ASYM_PAUSE:
   1513       ability->pause = SOC_PA_PAUSE_RX;
   1514       break ;
   1515    }
   1516 
   1517    if(tsc->an_type==TSCMOD_CL37_SGMII) {
   1518       tsc->per_lane_control=TSCMOD_AN_GET_LP_SGMII_ABIL ;
   1519       tscmod_tier1_selector("AUTONEG_GET", tsc, &rv);
   1520       reg_ability = tsc->accData ;
   1521 
   1522       sgmii_speed = reg_ability & 0x3 ;
   1523    }
   1524 
   1525    if(tsc->verbosity&TSCMOD_DBG_AN) {
   1526       printf("%-22s u=%0d p=%0d full_duplex REMOTE ability %s(=%0x) pause=%x sgmii_speed=%0d\n",
   1527              __func__, unit, port, tscmod_ability_msg0(ability->speed_full_duplex),
   1528              ability->speed_full_duplex, ability->pause, sgmii_speed);
   1529    }
   1530 
   1531    tscmod_sema_unlock(unit, port) ;
   1532 #endif
   1533 
   1534    return SOC_E_NONE;
   1535 }
   1536 
   1537 /*
   1538  * Function:
   1539  *      phy_qsgmiie_lb_set
   1540  * Purpose:
   1541  *      Enable/disable PHY loopback mode
   1542  * Parameters:
   1543  *      unit - BCM unit number.
   1544  *      port - Port number. 
   1545  *      enable - binary value for on/off (1/0)
   1546  * Returns:     
   1547  *      SOC_E_NONE
   1548  */
   1549 STATIC int
   1550 phy_qsgmiie_lb_set(int unit, soc_port_t port, int enable)
   1551 {
   1552     phy_ctrl_t* pc; 
   1553     soc_phymod_ctrl_t *pmc;
   1554     phymod_phy_access_t *pm_phy;
   1555     int idx;
   1556 
   1557     pc = INT_PHY_SW_STATE(unit, port);
   1558     pmc = &pc->phymod_ctrl;
   1559 
   1560     for (idx = 0; idx < pmc->num_phys; idx++) {
   1561         pm_phy = &pmc->phy[idx]->pm_phy;
   1562         SOC_IF_ERROR_RETURN
   1563             (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobalPMD, enable)); 
   1564     }
   1565 
   1566     return (SOC_E_NONE);
   1567 }
   1568 
   1569 /*
   1570  * Function:
   1571  *      phy_qsgmiie_lb_get
   1572  * Purpose:
   1573  *      Get current PHY loopback mode
   1574  * Parameters:
   1575  *      unit - BCM unit number.
   1576  *      port - Port number. 
   1577  *      enable - address of location to store binary value for on/off (1/0)
   1578  * Returns:     
   1579  *      SOC_E_NONE
   1580  */
   1581 STATIC int
   1582 phy_qsgmiie_lb_get(int unit, soc_port_t port, int *enable)
   1583 {
   1584     phy_ctrl_t* pc; 
   1585     soc_phymod_ctrl_t *pmc;
   1586     phymod_phy_access_t *pm_phy;
   1587     uint32 lb_enable;
   1588 
   1589     pc = INT_PHY_SW_STATE(unit, port);
   1590     pmc = &pc->phymod_ctrl;
   1591 
   1592     *enable = 0;
   1593 
   1594     DBG_OK();
   1595 
   1596     pm_phy = &pmc->phy[0]->pm_phy;
   1597     SOC_IF_ERROR_RETURN
   1598         (phymod_phy_loopback_get(pm_phy, phymodLoopbackGlobalPMD, &lb_enable));
   1599 
   1600     return (SOC_E_NONE);
   1601 }
   1602 
   1603 /*
   1604  * Function:
   1605  *      phy_qsgmiie_ability_local_get
   1606  * Purpose:
   1607  *      xx
   1608  * Parameters:
   1609  *      unit - BCM unit number.
   1610  *      port - Port number. 
   1611  *      ability - xx
   1612  * Returns:     
   1613  *      SOC_E_NONE
   1614  */
   1615 STATIC int
   1616 phy_qsgmiie_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability)
   1617 {
   1618     phy_ctrl_t          *pc; 
   1619     qsgmiie_config_t    *pCfg;
   1620 
   1621     pc = INT_PHY_SW_STATE(unit, port);
   1622     pCfg = (qsgmiie_config_t *) pc->driver_data;
   1623 
   1624     if (NULL == ability) {
   1625         return SOC_E_PARAM;
   1626     }
   1627 
   1628     sal_memset(ability, 0, sizeof(*ability));
   1629 
   1630     ability->loopback  = SOC_PA_LB_PHY;
   1631     ability->medium    = SOC_PA_MEDIUM_FIBER;
   1632     ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   1633     ability->flags     = 0;
   1634 
   1635     ability->speed_full_duplex  = SOC_PA_SPEED_1000MB;
   1636     if (pCfg->fiber_pref)   {
   1637         ability->speed_full_duplex  |= SOC_PA_SPEED_2500MB |
   1638                                        SOC_PA_SPEED_10GB;
   1639             ability->speed_full_duplex  |= SOC_PA_SPEED_100MB;
   1640             ability->speed_half_duplex  = SOC_PA_SPEED_100MB;
   1641     } else {
   1642         ability->speed_half_duplex  = SOC_PA_SPEED_10MB |
   1643                                       SOC_PA_SPEED_100MB;
   1644         ability->speed_full_duplex  |= SOC_PA_SPEED_10MB |
   1645                                        SOC_PA_SPEED_100MB;
   1646     } 
   1647 
   1648     ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   1649     ability->interface = SOC_PA_INTF_GMII | SOC_PA_INTF_SGMII;
   1650     ability->medium    = SOC_PA_MEDIUM_FIBER;
   1651     ability->loopback  = SOC_PA_LB_PHY;
   1652 
   1653     LOG_INFO(BSL_LS_SOC_PHY,
   1654              (BSL_META_U(pc->unit,
   1655                          "phy_qsgmiie_ability_local_get:unit=%d p=%d sp=%08x\n"),
   1656               unit, port, ability->speed_full_duplex));
   1657     return (SOC_E_NONE);
   1658 }
   1659 
   1660 /*
   1661  * Function:
   1662  *      qsgmiie_uc_status_dump
   1663  * Purpose:
   1664  *      display all the serdes related parameters
   1665  * Parameters:
   1666  *      unit - BCM unit number.
   1667  *      port - Port number. 
   1668 
   1669  * Returns:     
   1670  *      SOC_E_NONE
   1671  */
   1672 STATIC int
   1673 qsgmiie_uc_status_dump(int unit, soc_port_t port)
   1674 {
   1675     phy_ctrl_t* pc; 
   1676     soc_phymod_ctrl_t *pmc;
   1677     phymod_phy_access_t *pm_phy;
   1678     int idx;
   1679 
   1680     pc = INT_PHY_SW_STATE(unit, port);
   1681     pmc = &pc->phymod_ctrl;
   1682 
   1683     for (idx = 0; idx < pmc->num_phys; idx++) {
   1684         pm_phy = &pmc->phy[idx]->pm_phy;
   1685         SOC_IF_ERROR_RETURN
   1686             (phymod_phy_status_dump(pm_phy)); 
   1687     }
   1688     return (SOC_E_NONE);
   1689 }
   1690 
   1691 /* 
   1692  * given a pc (phymod_ctrl_t) and logical lane number, 
   1693  *    find the correct soc_phymod_phy_t object and lane
   1694  */
   1695 STATIC int
   1696 _qsgmiie_find_soc_phy_lane(soc_phymod_ctrl_t *pmc, uint32_t lane, 
   1697                            soc_phymod_phy_t **p_phy, uint32 *lane_map)
   1698 {
   1699     phymod_phy_access_t *pm_phy;
   1700     int idx, lnx, ln_cnt, found;
   1701     uint32 lane_map_copy;
   1702 
   1703     /* Traverse lanes belonging to this port */
   1704     found = 0;
   1705     ln_cnt = 0;
   1706     for (idx = 0; idx < pmc->num_phys; idx++) {
   1707         pm_phy = &pmc->phy[idx]->pm_phy;
   1708         if (pm_phy == NULL) {
   1709             return SOC_E_INTERNAL;
   1710         }
   1711         lane_map_copy = pm_phy->access.lane_mask;
   1712         for (lnx = 0; lnx < 4; lnx++) {
   1713             if ((1 << lnx) & lane_map_copy) {
   1714                 if (ln_cnt == lane) {
   1715                     found = 1;
   1716                     break;
   1717                 }
   1718                 ln_cnt++;
   1719             }
   1720         }
   1721         if (found) {
   1722             *p_phy = pmc->phy[idx];
   1723             *lane_map = (1 << lnx);
   1724             break;
   1725         }
   1726     } 
   1727 
   1728     if (!found) {
   1729         /* No such lane */
   1730         return SOC_E_PARAM;
   1731     }
   1732     return (SOC_E_NONE);
   1733 }
   1734 
   1735 /* 
   1736  * qsgmiie_per_lane_preemphasis_set
   1737  */
   1738 STATIC int
   1739 qsgmiie_per_lane_preemphasis_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value)
   1740 {
   1741     soc_phymod_phy_t    *p_phy;
   1742     uint32              lane_map;
   1743     phymod_phy_access_t pm_phy_copy, *pm_phy;
   1744     phymod_tx_t         phymod_tx;
   1745 
   1746     /* locate the desired phy and lane */
   1747     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   1748 
   1749     /* Make a copy of the phy access and overwrite the desired lane */
   1750     pm_phy = &p_phy->pm_phy;
   1751     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   1752     pm_phy_copy.access.lane_mask = lane_map;
   1753 
   1754     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   1755     phymod_tx.pre = value;
   1756     SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   1757 
   1758     return(SOC_E_NONE);
   1759 }
   1760 
   1761 /* 
   1762  * qsgmiie_preemphasis_set
   1763  */
   1764 STATIC int
   1765 qsgmiie_preemphasis_set(soc_phymod_ctrl_t *pmc, uint32 value)
   1766 {
   1767     phymod_phy_access_t *pm_phy;
   1768     phymod_tx_t         phymod_tx;
   1769     int                 idx;
   1770 
   1771     /* loop through all cores */
   1772     for (idx = 0; idx < pmc->num_phys; idx++) {
   1773         pm_phy = &pmc->phy[idx]->pm_phy;
   1774 
   1775         if (pm_phy == NULL) {
   1776             return SOC_E_INTERNAL;
   1777         }
   1778 
   1779         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   1780         phymod_tx.pre = value;
   1781         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx));
   1782 
   1783         
   1784     }
   1785 
   1786     return(SOC_E_NONE);
   1787 }
   1788 
   1789 /* 
   1790  * qsgmiie_tx_fir_pre_set
   1791  */
   1792 STATIC int
   1793 qsgmiie_tx_fir_pre_set(soc_phymod_ctrl_t *pmc, uint32 value)
   1794 {
   1795     phymod_phy_access_t *pm_phy;
   1796     phymod_tx_t         phymod_tx;
   1797     int                 idx;
   1798 
   1799     /* loop through all cores */
   1800     for (idx = 0; idx < pmc->num_phys; idx++) {
   1801         pm_phy = &pmc->phy[idx]->pm_phy;
   1802 
   1803         if (pm_phy == NULL) {
   1804             return SOC_E_INTERNAL;
   1805         }
   1806 
   1807         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   1808         phymod_tx.pre = value;
   1809         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx));
   1810     }
   1811 
   1812     return(SOC_E_NONE);
   1813 }
   1814 
   1815 /* 
   1816  * qsgmiie_tx_fir_main_set
   1817  */
   1818 STATIC int
   1819 qsgmiie_tx_fir_main_set(soc_phymod_ctrl_t *pmc, uint32 value)
   1820 {
   1821     phymod_phy_access_t *pm_phy;
   1822     phymod_tx_t         phymod_tx;
   1823     int                 idx;
   1824 
   1825     /* loop through all cores */
   1826     for (idx = 0; idx < pmc->num_phys; idx++) {
   1827         pm_phy = &pmc->phy[idx]->pm_phy;
   1828 
   1829         if (pm_phy == NULL) {
   1830             return SOC_E_INTERNAL;
   1831         }
   1832 
   1833         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   1834         phymod_tx.main = value;
   1835         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx));
   1836     }
   1837 
   1838     return(SOC_E_NONE);
   1839 }
   1840 
   1841 /* 
   1842  * qsgmiie_tx_fir_post_set
   1843  */
   1844 STATIC int
   1845 qsgmiie_tx_fir_post_set(soc_phymod_ctrl_t *pmc, uint32 value)
   1846 {
   1847     phymod_phy_access_t *pm_phy;
   1848     phymod_tx_t         phymod_tx;
   1849     int                 idx;
   1850 
   1851     /* loop through all cores */
   1852     for (idx = 0; idx < pmc->num_phys; idx++) {
   1853         pm_phy = &pmc->phy[idx]->pm_phy;
   1854 
   1855         if (pm_phy == NULL) {
   1856             return SOC_E_INTERNAL;
   1857         }
   1858 
   1859         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   1860         phymod_tx.post = value;
   1861         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx));
   1862     }
   1863 
   1864     return(SOC_E_NONE);
   1865 }
   1866 
   1867 /* 
   1868  * qsgmiie_tx_fir_post2_set
   1869  */
   1870 STATIC int
   1871 qsgmiie_tx_fir_post2_set(soc_phymod_ctrl_t *pmc, uint32 value)
   1872 {
   1873     phymod_phy_access_t *pm_phy;
   1874     phymod_tx_t         phymod_tx;
   1875     int                 idx;
   1876 
   1877     /* loop through all cores */
   1878     for (idx = 0; idx < pmc->num_phys; idx++) {
   1879         pm_phy = &pmc->phy[idx]->pm_phy;
   1880 
   1881         if (pm_phy == NULL) {
   1882             return SOC_E_INTERNAL;
   1883         }
   1884 
   1885         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   1886         phymod_tx.post2 = value;
   1887         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx));
   1888     }
   1889 
   1890     return(SOC_E_NONE);
   1891 }
   1892 
   1893 /* 
   1894  * qsgmiie_tx_fir_post3_set
   1895  */
   1896 STATIC int
   1897 qsgmiie_tx_fir_post3_set(soc_phymod_ctrl_t *pmc, uint32 value)
   1898 {
   1899     phymod_phy_access_t *pm_phy;
   1900     phymod_tx_t         phymod_tx;
   1901     int                 idx;
   1902 
   1903     /* loop through all cores */
   1904     for (idx = 0; idx < pmc->num_phys; idx++) {
   1905         pm_phy = &pmc->phy[idx]->pm_phy;
   1906 
   1907         if (pm_phy == NULL) {
   1908             return SOC_E_INTERNAL;
   1909         }
   1910 
   1911         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   1912         phymod_tx.post3 = value;
   1913         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx));
   1914     }
   1915 
   1916     return(SOC_E_NONE);
   1917 }
   1918 
   1919 
   1920 /* 
   1921  * qsgmiie_per_lane_driver_current_set
   1922  */
   1923 STATIC int
   1924 qsgmiie_per_lane_driver_current_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value)
   1925 {
   1926     soc_phymod_phy_t    *p_phy;
   1927     uint32              lane_map;
   1928     phymod_phy_access_t pm_phy_copy, *pm_phy;
   1929     phymod_tx_t         phymod_tx;
   1930     
   1931     /* locate the desired phy and lane */
   1932     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   1933 
   1934     /* Make a copy of the phy access and overwrite the desired lane */
   1935     pm_phy = &p_phy->pm_phy;
   1936     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   1937     pm_phy_copy.access.lane_mask = lane_map;
   1938 
   1939     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   1940     phymod_tx.amp = value;
   1941     SOC_IF_ERROR_RETURN(phymod_phy_tx_set(&pm_phy_copy, &phymod_tx));
   1942 
   1943     
   1944 
   1945     return(SOC_E_NONE);
   1946 }
   1947 
   1948 /* 
   1949  * qsgmiie_driver_current_set
   1950  */
   1951 STATIC int
   1952 qsgmiie_driver_current_set(soc_phymod_ctrl_t *pmc, uint32 value)
   1953 {
   1954     phymod_phy_access_t *pm_phy;
   1955     phymod_tx_t         phymod_tx;
   1956     int                 idx;
   1957 
   1958     /* loop through all cores */
   1959     for (idx = 0; idx < pmc->num_phys; idx++) {
   1960         pm_phy = &pmc->phy[idx]->pm_phy;
   1961 
   1962         if (pm_phy == NULL) {
   1963             return SOC_E_INTERNAL;
   1964         }
   1965 
   1966         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   1967         phymod_tx.amp = value;
   1968         SOC_IF_ERROR_RETURN(phymod_phy_tx_set(pm_phy, &phymod_tx));
   1969     }
   1970 
   1971     
   1972 
   1973     return(SOC_E_NONE);
   1974 }
   1975 
   1976 /* 
   1977  * qsgmiie_per_lane_rx_dfe_tap_control_set
   1978  */
   1979 STATIC int
   1980 qsgmiie_per_lane_rx_dfe_tap_control_set(soc_phymod_ctrl_t *pmc, int lane, int tap, int enable, uint32 value)
   1981 {
   1982     soc_phymod_phy_t    *p_phy;
   1983     uint32              lane_map;
   1984     phymod_phy_access_t pm_phy_copy, *pm_phy;
   1985     phymod_rx_t          phymod_rx;
   1986 
   1987     /* locate the desired phy and lane */
   1988     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   1989 
   1990     /* Make a copy of the phy access and overwrite the desired lane */
   1991     pm_phy = &p_phy->pm_phy;
   1992     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   1993     pm_phy_copy.access.lane_mask = lane_map;
   1994 
   1995     if ((tap<0)||(tap>(COUNTOF(phymod_rx.dfe) - 1))) {
   1996         /* this can only happen with a coding error */
   1997         return SOC_E_INTERNAL;
   1998     }
   1999 
   2000     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   2001     phymod_rx.dfe[tap].enable = enable;
   2002     phymod_rx.dfe[tap].value = value;
   2003     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(&pm_phy_copy, &phymod_rx));
   2004 
   2005     return(SOC_E_NONE);
   2006 }
   2007 
   2008 
   2009 /* 
   2010  * qsgmiie_tx_lane_squelch
   2011  */
   2012 STATIC int
   2013 qsgmiie_tx_lane_squelch(soc_phymod_ctrl_t *pmc, uint32 value)
   2014 {
   2015     phymod_phy_access_t *pm_phy;
   2016     phymod_phy_power_t  phy_power;
   2017     int                 idx;
   2018 
   2019     /* loop through all cores */
   2020     for (idx = 0; idx < pmc->num_phys; idx++) {
   2021         pm_phy = &pmc->phy[idx]->pm_phy;
   2022 
   2023         if (pm_phy == NULL) {
   2024             return SOC_E_INTERNAL;
   2025         }
   2026 
   2027         if (value == 1) {
   2028             phy_power.tx = phymodPowerOff;
   2029             phy_power.rx = phymodPowerNoChange;
   2030         } else {
   2031             phy_power.tx = phymodPowerOn;
   2032             phy_power.rx = phymodPowerNoChange;
   2033         }
   2034         SOC_IF_ERROR_RETURN
   2035             (phymod_phy_power_set(pm_phy, &phy_power));
   2036     }
   2037     return(SOC_E_NONE);
   2038 }
   2039 
   2040 /* 
   2041  * qsgmiie_per_lane_rx_peak_filter_set
   2042  */
   2043 STATIC int
   2044 qsgmiie_per_lane_rx_peak_filter_set(soc_phymod_ctrl_t *pmc, int lane, int enable, uint32 value)
   2045 {
   2046     soc_phymod_phy_t    *p_phy;
   2047     uint32              lane_map;
   2048     phymod_phy_access_t pm_phy_copy, *pm_phy;
   2049     phymod_rx_t         phymod_rx;
   2050 
   2051     /* locate the desired phy and lane */
   2052     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2053 
   2054     /* Make a copy of the phy access and overwrite the desired lane */
   2055     pm_phy = &p_phy->pm_phy;
   2056     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2057     pm_phy_copy.access.lane_mask = lane_map;
   2058 
   2059     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   2060     phymod_rx.peaking_filter.enable = TRUE;
   2061     phymod_rx.peaking_filter.value = value;
   2062     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx));
   2063 
   2064     return(SOC_E_NONE);
   2065 }
   2066 
   2067 /* 
   2068  * qsgmiie_rx_peak_filter_set
   2069  */
   2070 STATIC int 
   2071 qsgmiie_rx_peak_filter_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2072 {
   2073     phymod_phy_access_t *pm_phy;
   2074     phymod_rx_t         phymod_rx;
   2075     int                 idx;
   2076 
   2077     /* loop through all cores */
   2078     for (idx = 0; idx < pmc->num_phys; idx++) {
   2079         pm_phy = &pmc->phy[idx]->pm_phy;
   2080 
   2081         if (pm_phy == NULL) {
   2082             return SOC_E_INTERNAL;
   2083         }
   2084 
   2085         SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx));
   2086         phymod_rx.peaking_filter.enable = TRUE;
   2087         phymod_rx.peaking_filter.value = value;
   2088         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx));
   2089     }
   2090 
   2091     return(SOC_E_NONE);
   2092 }
   2093 
   2094 /* 
   2095  * qsgmiie_per_lane_rx_vga_set
   2096  */
   2097 STATIC int
   2098 qsgmiie_per_lane_rx_vga_set(soc_phymod_ctrl_t *pmc, int lane, int enable, uint32 value)
   2099 {
   2100     soc_phymod_phy_t    *p_phy;
   2101     uint32              lane_map;
   2102     phymod_phy_access_t pm_phy_copy, *pm_phy;
   2103     phymod_rx_t         phymod_rx;
   2104 
   2105     /* locate the desired phy and lane */
   2106     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   2107 
   2108     /* Make a copy of the phy access and overwrite the desired lane */
   2109     pm_phy = &p_phy->pm_phy;
   2110     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   2111     pm_phy_copy.access.lane_mask = lane_map;
   2112 
   2113     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   2114     phymod_rx.vga.enable = TRUE;
   2115     phymod_rx.vga.value = value;
   2116     SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx));
   2117 
   2118     return(SOC_E_NONE);
   2119 }
   2120 
   2121 /* 
   2122  * qsgmiie_rx_vga_set
   2123  */
   2124 STATIC int 
   2125 qsgmiie_rx_vga_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2126 {
   2127     phymod_phy_access_t *pm_phy;
   2128     phymod_rx_t         phymod_rx;
   2129     int                 idx;
   2130 
   2131     /* loop through all cores */
   2132     for (idx = 0; idx < pmc->num_phys; idx++) {
   2133         pm_phy = &pmc->phy[idx]->pm_phy;
   2134 
   2135         if (pm_phy == NULL) {
   2136             return SOC_E_INTERNAL;
   2137         }
   2138 
   2139         SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx));
   2140         phymod_rx.vga.enable = TRUE;
   2141         phymod_rx.vga.value = value;
   2142         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx));
   2143     }
   2144 
   2145     return(SOC_E_NONE);
   2146 }
   2147 
   2148 STATIC int
   2149 qsgmiie_rx_tap_release(soc_phymod_ctrl_t *pmc, int tap)
   2150 {
   2151     phymod_phy_access_t *pm_phy;
   2152     phymod_rx_t         phymod_rx;
   2153     int                 idx;
   2154 
   2155     /* bounds check "tap" */
   2156     if ((tap < 0) || (tap >= COUNTOF(phymod_rx.dfe))) {
   2157         return SOC_E_INTERNAL;
   2158     }
   2159 
   2160     /* loop through all cores */
   2161     for (idx = 0; idx < pmc->num_phys; idx++) {
   2162         pm_phy = &pmc->phy[idx]->pm_phy;
   2163 
   2164         if (pm_phy == NULL) {
   2165             return SOC_E_INTERNAL;
   2166         }
   2167         SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx));
   2168         phymod_rx.dfe[tap].enable = FALSE;
   2169         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx));
   2170     }
   2171     return(SOC_E_NONE);
   2172 }
   2173 
   2174 /* 
   2175  * qsgmiie_rx_tap_set
   2176  */
   2177 STATIC int 
   2178 qsgmiie_rx_tap_set(soc_phymod_ctrl_t *pmc, int tap, uint32 value)
   2179 {
   2180     phymod_phy_access_t *pm_phy;
   2181     phymod_rx_t         phymod_rx;
   2182     int                 idx;
   2183 
   2184     /* bounds check "tap" */
   2185     if ((tap < 0) || (tap > COUNTOF(phymod_rx.dfe) - 1)) {
   2186         return SOC_E_INTERNAL;
   2187     }
   2188 
   2189     /* loop through all cores */
   2190     for (idx = 0; idx < pmc->num_phys; idx++) {
   2191         pm_phy = &pmc->phy[idx]->pm_phy;
   2192 
   2193         if (pm_phy == NULL) {
   2194             return SOC_E_INTERNAL;
   2195         }
   2196         SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx));
   2197         phymod_rx.dfe[tap].enable = TRUE;
   2198         phymod_rx.dfe[tap].value = value;
   2199         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx));
   2200     }
   2201 
   2202     return(SOC_E_NONE);
   2203 }
   2204 
   2205 /* 
   2206  * qsgmiie_pi_control_set
   2207  */
   2208 STATIC int 
   2209 qsgmiie_pi_control_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2210 {
   2211     phymod_phy_access_t  *pm_phy;
   2212     phymod_tx_override_t tx_override;
   2213     int                  idx;
   2214 
   2215     /* loop through all cores */
   2216     for (idx = 0; idx < pmc->num_phys; idx++) {
   2217         pm_phy = &pmc->phy[idx]->pm_phy;
   2218 
   2219         if (pm_phy == NULL) {
   2220             return SOC_E_INTERNAL;
   2221         }
   2222 
   2223         phymod_tx_override_t_init(&tx_override);
   2224         tx_override.phase_interpolator.enable = (value == 0) ? 0 : 1;
   2225         tx_override.phase_interpolator.value = value;
   2226         SOC_IF_ERROR_RETURN(phymod_phy_tx_override_set(pm_phy, &tx_override));
   2227     }
   2228 
   2229     return(SOC_E_NONE);
   2230 }
   2231 
   2232 /* 
   2233  * qsgmiie_tx_polarity_set
   2234  */
   2235 STATIC int 
   2236 qsgmiie_tx_polarity_set(soc_phymod_ctrl_t *pmc, phymod_polarity_t *cfg_polarity, uint32 value)
   2237 {
   2238     phymod_phy_access_t  *pm_phy;
   2239     phymod_polarity_t    polarity;
   2240     int                  idx;
   2241 
   2242     /* loop through all cores */
   2243     for (idx = 0; idx < pmc->num_phys; idx++) {
   2244         pm_phy = &pmc->phy[idx]->pm_phy;
   2245 
   2246         if (pm_phy == NULL) {
   2247             return SOC_E_INTERNAL;
   2248         }
   2249 
   2250         sal_memcpy(&polarity, cfg_polarity, sizeof(polarity));
   2251         polarity.tx_polarity = value;
   2252         SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(pm_phy, &polarity));
   2253 
   2254         /* after successfully setting the parity, update the configured value */
   2255         cfg_polarity->tx_polarity = value;
   2256     }
   2257 
   2258     return(SOC_E_NONE);
   2259 }
   2260 
   2261 /* 
   2262  * qsgmiie_rx_polarity_set
   2263  */
   2264 
   2265 STATIC int 
   2266 qsgmiie_rx_polarity_set(soc_phymod_ctrl_t *pmc, phymod_polarity_t *cfg_polarity, uint32 value)
   2267 {
   2268     phymod_phy_access_t  *pm_phy;
   2269     phymod_polarity_t    polarity;
   2270     int                  idx;
   2271 
   2272     /* loop through all cores */
   2273     for (idx = 0; idx < pmc->num_phys; idx++) {
   2274         pm_phy = &pmc->phy[idx]->pm_phy;
   2275 
   2276         if (pm_phy == NULL) {
   2277             return SOC_E_INTERNAL;
   2278         }
   2279 
   2280         sal_memcpy(&polarity, cfg_polarity, sizeof(polarity));
   2281         polarity.rx_polarity = value;
   2282         SOC_IF_ERROR_RETURN(phymod_phy_polarity_set(pm_phy, &polarity));
   2283 
   2284         /* after successfully setting the parity, update the configured value */
   2285         cfg_polarity->rx_polarity = value;
   2286     }
   2287 
   2288     return(SOC_E_NONE);
   2289 }
   2290 
   2291 /* 
   2292  * qsgmiie_rx_reset
   2293  */
   2294 STATIC int
   2295 qsgmiie_rx_reset(soc_phymod_ctrl_t *pmc, phymod_phy_reset_t *cfg_reset, uint32 value)
   2296 {
   2297     phymod_phy_access_t *pm_phy;
   2298     phymod_phy_reset_t  reset;
   2299     int                 idx;
   2300 
   2301     /* loop through all cores */
   2302     for (idx = 0; idx < pmc->num_phys; idx++) {
   2303         pm_phy = &pmc->phy[idx]->pm_phy;
   2304 
   2305         if (pm_phy == NULL) {
   2306             return SOC_E_INTERNAL;
   2307         }
   2308 
   2309         sal_memcpy(&reset, cfg_reset, sizeof(reset));
   2310         reset.rx = (phymod_reset_direction_t) value;
   2311         SOC_IF_ERROR_RETURN(phymod_phy_reset_set(pm_phy, &reset));
   2312 
   2313         /* after successfully setting the parity, update the configured value */
   2314         cfg_reset->rx = (phymod_reset_direction_t) value;
   2315     }
   2316 
   2317     return(SOC_E_NONE);
   2318 }
   2319 
   2320 /* 
   2321  * qsgmiie_tx_reset
   2322  */
   2323 STATIC int
   2324 qsgmiie_tx_reset(soc_phymod_ctrl_t *pmc, phymod_phy_reset_t *cfg_reset, uint32 value)
   2325 {
   2326     phymod_phy_access_t *pm_phy;
   2327     phymod_phy_reset_t  reset;
   2328     int                 idx;
   2329 
   2330     /* loop through all cores */
   2331     for (idx = 0; idx < pmc->num_phys; idx++) {
   2332         pm_phy = &pmc->phy[idx]->pm_phy;
   2333 
   2334         if (pm_phy == NULL) {
   2335             return SOC_E_INTERNAL;
   2336         }
   2337 
   2338         sal_memcpy(&reset, cfg_reset, sizeof(reset));
   2339         reset.tx = (phymod_reset_direction_t) value;
   2340         SOC_IF_ERROR_RETURN(phymod_phy_reset_set(pm_phy, &reset));
   2341 
   2342         /* after successfully setting the parity, update the configured value */
   2343         cfg_reset->tx = (phymod_reset_direction_t) value;
   2344     }
   2345 
   2346     return(SOC_E_NONE);
   2347 }
   2348 
   2349 /* 
   2350  * qsgmiie_cl72_enable_set
   2351  */
   2352 STATIC int
   2353 qsgmiie_cl72_enable_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2354 {
   2355     phymod_phy_access_t *pm_phy;
   2356     int                 idx;
   2357 
   2358     /* loop through all cores */
   2359     for (idx = 0; idx < pmc->num_phys; idx++) {
   2360         pm_phy = &pmc->phy[idx]->pm_phy;
   2361 
   2362         if (pm_phy == NULL) {
   2363             return SOC_E_INTERNAL;
   2364         }
   2365 
   2366         SOC_IF_ERROR_RETURN(phymod_phy_cl72_set(pm_phy, value));
   2367     }
   2368 
   2369     return(SOC_E_NONE);
   2370 }
   2371 
   2372 STATIC int
   2373 qsgmiie_lane_map_set(soc_phymod_ctrl_t *pmc, uint32 value){
   2374     int idx;
   2375     phymod_lane_map_t lane_map;
   2376 
   2377     lane_map.num_of_lanes = NUM_LANES;
   2378     if(pmc->phy[0] == NULL){
   2379         return(SOC_E_INTERNAL);
   2380     }
   2381     for (idx=0; idx < NUM_LANES; idx++) {
   2382         lane_map.lane_map_rx[idx] = (value >> (idx * 4 /*4 bit per lane*/)) & 0xf;
   2383     }
   2384     for (idx=0; idx < NUM_LANES; idx++) {
   2385         lane_map.lane_map_tx[idx] = (value >> (16 + idx * 4 /*4 bit per lane*/)) & 0xf;
   2386     }
   2387     SOC_IF_ERROR_RETURN(phymod_core_lane_map_set(&pmc->phy[0]->core->pm_core, &lane_map));
   2388     return(SOC_E_NONE);
   2389 }
   2390 
   2391 
   2392 STATIC int
   2393 qsgmiie_lane_map_get(soc_phymod_ctrl_t *pmc, uint32 *value){
   2394     int idx;
   2395     phymod_lane_map_t lane_map;
   2396 
   2397     *value = 0;
   2398     if(pmc->phy[0] == NULL){
   2399         return(SOC_E_INTERNAL);
   2400     }
   2401     SOC_IF_ERROR_RETURN(phymod_core_lane_map_get(&pmc->phy[0]->core->pm_core, &lane_map));
   2402     if(lane_map.num_of_lanes != NUM_LANES){
   2403         return SOC_E_INTERNAL;
   2404     }
   2405     for (idx=0; idx < NUM_LANES; idx++) {
   2406         value += (lane_map.lane_map_rx[idx] << (idx * 4));
   2407     }
   2408     for (idx=0; idx < NUM_LANES; idx++) {
   2409         value += (lane_map.lane_map_rx[idx]<< (idx * 4 + 16));
   2410     }
   2411     
   2412     return(SOC_E_NONE);
   2413 }
   2414 
   2415 
   2416 STATIC int
   2417 qsgmiie_pattern_len_set(soc_phymod_ctrl_t *pmc, uint32_t value)
   2418 {
   2419     phymod_phy_access_t    *pm_phy;
   2420     phymod_pattern_t       phymod_pattern;
   2421     int                    idx;
   2422 
   2423     /* loop through all cores */
   2424     for (idx = 0; idx < pmc->num_phys; idx++) {
   2425         pm_phy = &pmc->phy[idx]->pm_phy;
   2426 
   2427         if (pm_phy == NULL) {
   2428             return SOC_E_INTERNAL;
   2429         }
   2430 
   2431         phymod_pattern_t_init(&phymod_pattern);
   2432         SOC_IF_ERROR_RETURN
   2433             (phymod_phy_pattern_config_get(pm_phy, &phymod_pattern));
   2434         phymod_pattern.pattern_len = value;
   2435         SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_set(pm_phy, &phymod_pattern));
   2436     }
   2437     return(SOC_E_NONE);
   2438 }
   2439 
   2440 STATIC int
   2441 qsgmiie_pattern_enable_set(soc_phymod_ctrl_t *pmc, uint32_t value)
   2442 {
   2443     phymod_phy_access_t    *pm_phy;
   2444     phymod_pattern_t       phymod_pattern;
   2445     int                    idx;
   2446 
   2447     /* loop through all cores */
   2448     for (idx = 0; idx < pmc->num_phys; idx++) {
   2449         pm_phy = &pmc->phy[idx]->pm_phy;
   2450 
   2451         if (pm_phy == NULL) {
   2452             return SOC_E_INTERNAL;
   2453         }
   2454 
   2455         phymod_pattern_t_init(&phymod_pattern);
   2456         SOC_IF_ERROR_RETURN
   2457             (phymod_phy_pattern_config_get(pm_phy, &phymod_pattern));
   2458         SOC_IF_ERROR_RETURN(phymod_phy_pattern_enable_set(pm_phy,  value, &phymod_pattern));
   2459     }
   2460     return(SOC_E_NONE);
   2461 }
   2462 
   2463 /* 
   2464  * qsgmiie_pattern_data_set 
   2465  *    Sets 32 bits of the 256 bit data pattern.
   2466  */
   2467 STATIC int
   2468 qsgmiie_pattern_data_set(int idx, qsgmiie_pattern_t *pattern, uint32 value)
   2469 {
   2470     if ((idx<0) || (idx >= COUNTOF(pattern->pattern_data))) {
   2471         return SOC_E_INTERNAL;
   2472     }
   2473 
   2474     /* update pattern data */
   2475     pattern->pattern_data[idx] = value;
   2476 
   2477     return(SOC_E_NONE);
   2478 }
   2479 
   2480 /* 
   2481  * qsgmiie_per_lane_prbs_poly_set
   2482  */
   2483 STATIC int
   2484 qsgmiie_per_lane_prbs_poly_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value)
   2485 {
   2486    return(SOC_E_UNAVAIL);
   2487 }
   2488 
   2489 
   2490 STATIC
   2491 int
   2492 qsgmiie_sdk_poly_to_phymod_poly(uint32 sdk_poly, phymod_prbs_poly_t *phymod_poly){
   2493     switch(sdk_poly){
   2494     case SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1:
   2495         *phymod_poly = phymodPrbsPoly7;
   2496         break;
   2497     case SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1:
   2498         *phymod_poly = phymodPrbsPoly15;
   2499         break;
   2500     case SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1:
   2501         *phymod_poly = phymodPrbsPoly23;
   2502         break;
   2503     case SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1:
   2504         *phymod_poly = phymodPrbsPoly31;
   2505         break;
   2506     case SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1:
   2507         *phymod_poly = phymodPrbsPoly9;
   2508         break;
   2509     case 6:
   2510         *phymod_poly = phymodPrbsPoly58;
   2511         break;
   2512     default:
   2513         return SOC_E_INTERNAL;
   2514     }
   2515     return SOC_E_NONE;
   2516 }
   2517 
   2518 /* 
   2519  * qsgmiie_prbs_tx_poly_set
   2520  */
   2521 STATIC int
   2522 qsgmiie_prbs_tx_poly_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2523 {
   2524     phymod_phy_access_t  *pm_phy;
   2525     phymod_prbs_t        prbs;
   2526     uint32_t flags = 0;
   2527 
   2528 
   2529     /* just take the value from the first phy */
   2530     if (pmc->phy[0] == NULL) {
   2531         return SOC_E_INTERNAL;
   2532     }
   2533     pm_phy = &pmc->phy[0]->pm_phy;
   2534 
   2535     if (pm_phy == NULL) {
   2536         return SOC_E_INTERNAL;
   2537     }
   2538     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2539     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs));
   2540     SOC_IF_ERROR_RETURN(qsgmiie_sdk_poly_to_phymod_poly(value, &prbs.poly));
   2541     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs));
   2542     return(SOC_E_NONE);
   2543 }
   2544 
   2545 /* 
   2546  * qsgmiie_prbs_rx_poly_set
   2547  */
   2548 STATIC int
   2549 qsgmiie_prbs_rx_poly_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2550 {
   2551     phymod_phy_access_t  *pm_phy;
   2552     phymod_prbs_t        prbs;
   2553     uint32_t flags = 0;
   2554 
   2555     /* just take the value from the first phy */
   2556     if (pmc->phy[0] == NULL) {
   2557         return SOC_E_INTERNAL;
   2558     }
   2559     pm_phy = &pmc->phy[0]->pm_phy;
   2560 
   2561     if (pm_phy == NULL) {
   2562         return SOC_E_INTERNAL;
   2563     }
   2564 
   2565     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   2566     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags,  &prbs));
   2567     SOC_IF_ERROR_RETURN(qsgmiie_sdk_poly_to_phymod_poly(value, &prbs.poly));
   2568     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs));
   2569     return(SOC_E_NONE);
   2570 }
   2571 
   2572 
   2573 /* 
   2574  * qsgmiie_per_lane_prbs_tx_invert_data_set
   2575  */
   2576 STATIC int
   2577 qsgmiie_per_lane_prbs_tx_invert_data_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value)
   2578 {
   2579    return(SOC_E_UNAVAIL);
   2580 }
   2581 
   2582 /* 
   2583  * qsgmiie_prbs_tx_invert_data_set
   2584  */
   2585 STATIC int
   2586 qsgmiie_prbs_tx_invert_data_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2587 {
   2588     phymod_phy_access_t  *pm_phy;
   2589     phymod_prbs_t        prbs;
   2590     uint32_t flags = 0;
   2591 
   2592     /* just take the value from the first phy */
   2593     if (pmc->phy[0] == NULL) {
   2594         return SOC_E_INTERNAL;
   2595     }
   2596     pm_phy = &pmc->phy[0]->pm_phy;
   2597 
   2598     if (pm_phy == NULL) {
   2599         return SOC_E_INTERNAL;
   2600     }
   2601 
   2602     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2603     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs));
   2604     prbs.invert = value;
   2605     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags, &prbs));
   2606     return(SOC_E_NONE);
   2607 }
   2608 
   2609 /* 
   2610  * qsgmiie_prbs_rx_invert_data_set
   2611  */
   2612 STATIC int
   2613 qsgmiie_prbs_rx_invert_data_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2614 {
   2615     phymod_phy_access_t  *pm_phy;
   2616     phymod_prbs_t        prbs;
   2617     uint32_t flags = 0;
   2618     /* just take the value from the first phy */
   2619     if (pmc->phy[0] == NULL) {
   2620         return SOC_E_INTERNAL;
   2621     }
   2622     pm_phy = &pmc->phy[0]->pm_phy;
   2623 
   2624     if (pm_phy == NULL) {
   2625         return SOC_E_INTERNAL;
   2626     }
   2627 
   2628     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   2629    SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs));
   2630     prbs.invert = value;
   2631     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_set(pm_phy, flags,  &prbs));
   2632     return(SOC_E_NONE);
   2633 }
   2634 
   2635 /* 
   2636  * qsgmiie_per_lane_prbs_tx_enable_set
   2637  */
   2638 STATIC int
   2639 qsgmiie_per_lane_prbs_tx_enable_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value)
   2640 {
   2641    return(SOC_E_UNAVAIL);
   2642 }
   2643 /* 
   2644  * qsgmiie_prbs_tx_enable_set
   2645  */
   2646 STATIC int
   2647 qsgmiie_prbs_tx_enable_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2648 {
   2649     phymod_phy_access_t  *pm_phy;
   2650     uint32_t flags = 0;
   2651 
   2652     /* just take the value from the first phy */
   2653     if (pmc->phy[0] == NULL) {
   2654         return SOC_E_INTERNAL;
   2655     }
   2656     pm_phy = &pmc->phy[0]->pm_phy;
   2657 
   2658     if (pm_phy == NULL) {
   2659         return SOC_E_INTERNAL;
   2660     }
   2661     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   2662     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(pm_phy, flags, value));
   2663     return(SOC_E_NONE);
   2664 }
   2665 
   2666 /* 
   2667  * qsgmiie_prbs_rx_enable_set
   2668  */
   2669 STATIC int
   2670 qsgmiie_prbs_rx_enable_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2671 {
   2672     phymod_phy_access_t  *pm_phy;
   2673     uint32_t flags = 0;
   2674 
   2675     /* just take the value from the first phy */
   2676     if (pmc->phy[0] == NULL) {
   2677         return SOC_E_INTERNAL;
   2678     }
   2679     pm_phy = &pmc->phy[0]->pm_phy;
   2680 
   2681     if (pm_phy == NULL) {
   2682         return SOC_E_INTERNAL;
   2683     }
   2684     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   2685     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_set(pm_phy, flags, value));
   2686     return(SOC_E_NONE);
   2687 }
   2688 
   2689 /* 
   2690  * qsgmiie_loopback_internal_set
   2691  */
   2692 STATIC int 
   2693 qsgmiie_loopback_internal_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2694 {
   2695     phymod_phy_access_t  *pm_phy;
   2696 
   2697     /* just take the value from the first phy */
   2698     if (pmc->phy[0] == NULL) {
   2699         return SOC_E_INTERNAL;
   2700     }
   2701     pm_phy = &pmc->phy[0]->pm_phy;
   2702 
   2703     if (pm_phy == NULL) {
   2704         return SOC_E_INTERNAL;
   2705     }
   2706 
   2707     SOC_IF_ERROR_RETURN
   2708         (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobal, value));
   2709 
   2710     return(SOC_E_NONE);
   2711 }
   2712 
   2713 /* 
   2714  * qsgmiie_loopback_internal_pmd_set
   2715  */
   2716 STATIC int 
   2717 qsgmiie_loopback_internal_pmd_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2718 {
   2719     phymod_phy_access_t  *pm_phy;
   2720 
   2721     /* just take the value from the first phy */
   2722     if (pmc->phy[0] == NULL) {
   2723         return SOC_E_INTERNAL;
   2724     }
   2725     pm_phy = &pmc->phy[0]->pm_phy;
   2726 
   2727     if (pm_phy == NULL) {
   2728         return SOC_E_INTERNAL;
   2729     }
   2730 
   2731     SOC_IF_ERROR_RETURN
   2732         (phymod_phy_loopback_set(pm_phy, phymodLoopbackGlobalPMD, value));
   2733 
   2734     return(SOC_E_NONE);
   2735 }
   2736 
   2737 /* 
   2738  * qsgmiie_loopback_remote_set
   2739  */
   2740 STATIC int 
   2741 qsgmiie_loopback_remote_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2742 {
   2743     phymod_phy_access_t  *pm_phy;
   2744 
   2745     /* just take the value from the first phy */
   2746     if (pmc->phy[0] == NULL) {
   2747         return SOC_E_INTERNAL;
   2748     }
   2749     pm_phy = &pmc->phy[0]->pm_phy;
   2750 
   2751     if (pm_phy == NULL) {
   2752         return SOC_E_INTERNAL;
   2753     }
   2754 
   2755     SOC_IF_ERROR_RETURN
   2756         (phymod_phy_loopback_set(pm_phy, phymodLoopbackRemotePMD, value));
   2757 
   2758     return(SOC_E_NONE);
   2759 }
   2760 
   2761 /* 
   2762  * qsgmiie_loopback_remote_pcs_set
   2763  */
   2764 STATIC int 
   2765 qsgmiie_loopback_remote_pcs_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2766 {
   2767     phymod_phy_access_t  *pm_phy;
   2768 
   2769     /* just take the value from the first phy */
   2770     if (pmc->phy[0] == NULL) {
   2771         return SOC_E_INTERNAL;
   2772     }
   2773     pm_phy = &pmc->phy[0]->pm_phy;
   2774 
   2775     if (pm_phy == NULL) {
   2776         return SOC_E_INTERNAL;
   2777     }
   2778 
   2779     SOC_IF_ERROR_RETURN
   2780         (phymod_phy_loopback_set(pm_phy, phymodLoopbackRemotePCS, value));
   2781 
   2782     return(SOC_E_NONE);
   2783 }
   2784 
   2785 /* 
   2786  * qsgmiie_fec_enable_set
   2787  */
   2788 STATIC int 
   2789 qsgmiie_fec_enable_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2790 {
   2791     phymod_phy_access_t     *pm_phy;
   2792     int                     idx;
   2793 
   2794     /* loop through all cores */
   2795     for (idx = 0; idx < pmc->num_phys; idx++) {
   2796         pm_phy = &pmc->phy[idx]->pm_phy;
   2797 
   2798         if (pm_phy == NULL) {
   2799             return SOC_E_INTERNAL;
   2800         }
   2801         SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_set(pm_phy, value));
   2802     }
   2803     return(SOC_E_NONE);
   2804 }
   2805 
   2806 /* 
   2807  * qsgmiie_scrambler_set
   2808  */
   2809 STATIC int
   2810 qsgmiie_scrambler_set(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 value)
   2811 {
   2812     phymod_phy_access_t     *pm_phy;
   2813     phymod_phy_inf_config_t config;
   2814     int                     idx;
   2815     phy_ctrl_t              *pc;
   2816     qsgmiie_config_t        *pCfg;
   2817     phymod_ref_clk_t        ref_clk;
   2818 
   2819     pc = INT_PHY_SW_STATE(pmc->unit, port);
   2820     if (pc == NULL) {
   2821         return SOC_E_INTERNAL;
   2822     }
   2823 
   2824     pCfg = (qsgmiie_config_t *) pc->driver_data;
   2825     SOC_IF_ERROR_RETURN(
   2826         qsgmiie_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clk));
   2827 
   2828     /* loop through all cores */
   2829     for (idx = 0; idx < pmc->num_phys; idx++) {
   2830         pm_phy = &pmc->phy[idx]->pm_phy;
   2831 
   2832         if (pm_phy == NULL) {
   2833             return SOC_E_INTERNAL;
   2834         }
   2835 
   2836         SOC_IF_ERROR_RETURN(phymod_phy_interface_config_get(pm_phy, 0 /* flags */, ref_clk, &config));
   2837         PHYMOD_INTF_MODES_SCR_SET(&config);
   2838         SOC_IF_ERROR_RETURN(phymod_phy_interface_config_set(pm_phy, PHYMOD_INTF_F_DONT_OVERIDE_TX_PARAMS, &config));
   2839     }
   2840 
   2841 #if 0
   2842    /* tscmod had the following side effect; assume this is not needed */
   2843    DEV_CFG_PTR(pc)->scrambler_en = value? TRUE: FALSE;
   2844 #endif
   2845 
   2846     return(SOC_E_NONE);
   2847 }
   2848 
   2849 /* 
   2850  * qsgmiie_8b10b_set
   2851  */
   2852 STATIC int
   2853 qsgmiie_8b10b_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2854 {
   2855 #if 0
   2856 In discussion: whether encoding API should be separate
   2857 Setting interface and speed:
   2858 typedef struct phymod_phy_inf_config_s {
   2859     phymod_interface_t interface_type;          
   2860     uint32                      data_rate;          /*Use PHYMOD_DEFAULT_RATE of interface default*/
   2861     uint32                      interface_modes;    
   2862 } phymod_phy_inf_config_t;
   2863 
   2864 #define PHYMOD_DEFAULT_RATE 0xFFFFFFFF
   2865 
   2866 int phymod_phy_interface_config_set(int unit, uint32 phy_id, uint32 flags, const phymod_phy_inf_config_t* config);
   2867 int phymod_phy_interface_config_get(int unit, uint32 phy_id, uint32 flags, phymod_phy_inf_config_t* config);
   2868 #endif
   2869 
   2870    return(SOC_E_UNAVAIL);
   2871 }
   2872 
   2873 /* 
   2874  * qsgmiie_64b65b_set
   2875  */
   2876 STATIC int
   2877 qsgmiie_64b65b_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2878 {
   2879 #if 0
   2880 In discussion: whether encoding API should be separate
   2881 Setting interface and speed:
   2882 typedef struct phymod_phy_inf_config_s {
   2883     phymod_interface_t interface_type;          
   2884     uint32                      data_rate;          /*Use PHYMOD_DEFAULT_RATE of interface default*/
   2885     uint32                      interface_modes;    
   2886 } phymod_phy_inf_config_t;
   2887 
   2888 #define PHYMOD_DEFAULT_RATE 0xFFFFFFFF
   2889 
   2890 int phymod_phy_interface_config_set(int unit, uint32 phy_id, uint32 flags, const phymod_phy_inf_config_t* config);
   2891 int phymod_phy_interface_config_get(int unit, uint32 phy_id, uint32 flags, phymod_phy_inf_config_t* config);
   2892 #endif
   2893 
   2894    return(SOC_E_UNAVAIL);
   2895 }
   2896 
   2897 /* 
   2898  * qsgmiie_power_set
   2899  */
   2900 STATIC int
   2901 qsgmiie_power_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2902 {
   2903     phymod_phy_access_t     *pm_phy;
   2904     phymod_phy_power_t      power;
   2905     int                     idx;
   2906 
   2907     /* loop through all cores */
   2908     for (idx = 0; idx < pmc->num_phys; idx++) {
   2909         pm_phy = &pmc->phy[idx]->pm_phy;
   2910 
   2911         if (pm_phy == NULL) {
   2912             return SOC_E_INTERNAL;
   2913         }
   2914 
   2915         phymod_phy_power_t_init(&power);
   2916         if (value) {
   2917             power.tx = phymodPowerOn;
   2918             power.rx = phymodPowerOn;
   2919         } 
   2920         else {
   2921             power.tx = phymodPowerOff;
   2922             power.rx = phymodPowerOff;
   2923         }
   2924 
   2925         SOC_IF_ERROR_RETURN(phymod_phy_power_set(pm_phy, &power));
   2926     }
   2927 
   2928     return(SOC_E_NONE);
   2929 }
   2930 
   2931 /* 
   2932  * qsgmiie_per_lane_rx_low_freq_filter_set
   2933  */
   2934 STATIC int
   2935 qsgmiie_per_lane_rx_low_freq_filter_set(soc_phymod_ctrl_t *pmc, int lane, uint32 value)
   2936 {
   2937    return(SOC_E_UNAVAIL);
   2938 }
   2939 
   2940 /* 
   2941  * qsgmiie_rx_low_freq_filter_set
   2942  */
   2943 STATIC int
   2944 qsgmiie_rx_low_freq_filter_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2945 {
   2946     phymod_phy_access_t  *pm_phy;
   2947     phymod_rx_t          phymod_rx;
   2948     int                  idx;
   2949 
   2950     /* loop through all cores */
   2951     for (idx = 0; idx < pmc->num_phys; idx++) {
   2952         pm_phy = &pmc->phy[idx]->pm_phy;
   2953 
   2954         if (pm_phy == NULL) {
   2955             return SOC_E_INTERNAL;
   2956         }
   2957 
   2958         SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx));
   2959 
   2960         phymod_rx.low_freq_peaking_filter.enable = TRUE;
   2961         phymod_rx.low_freq_peaking_filter.value = value;
   2962         SOC_IF_ERROR_RETURN(phymod_phy_rx_set(pm_phy, &phymod_rx));
   2963     }
   2964 
   2965     return(SOC_E_NONE);
   2966 }
   2967 
   2968 /* 
   2969  * qsgmiie_tx_ppm_adjust_set
   2970  */
   2971 STATIC int
   2972 qsgmiie_tx_ppm_adjust_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2973 {
   2974     phymod_phy_access_t  *pm_phy;
   2975     phymod_tx_override_t tx_override;
   2976     int                  idx;
   2977 
   2978     /* loop through all cores */
   2979     for (idx = 0; idx < pmc->num_phys; idx++) {
   2980         pm_phy = &pmc->phy[idx]->pm_phy;
   2981 
   2982         if (pm_phy == NULL) {
   2983             return SOC_E_INTERNAL;
   2984         }
   2985 
   2986         tx_override.phase_interpolator.enable = 1;
   2987         tx_override.phase_interpolator.value = value;
   2988         SOC_IF_ERROR_RETURN(phymod_phy_tx_override_set(pm_phy, &tx_override));
   2989     }
   2990     return(SOC_E_NONE);
   2991 }
   2992 
   2993 /* 
   2994  * qsgmiie_vco_freq_set
   2995  */
   2996 STATIC int
   2997 qsgmiie_vco_freq_set(soc_phymod_ctrl_t *pmc, uint32 value)
   2998 {
   2999 #if 0
   3000 The following 3 controls are used to override pre-defined speed in the phy.
   3001 What we discussed in SJ is that in case of rate which is not officially supported the driver will try to 
   3002 understand this parameters by itself.
   3003 Questions:
   3004 1. Do we want to support direct configuration of PLL\OS?
   3005 2. If yes - same API or new API
   3006 
   3007 phymod_phy_interface_config_set (?)
   3008 #endif
   3009 
   3010    return(SOC_E_UNAVAIL);
   3011 }
   3012 
   3013 /* 
   3014  * qsgmiie_pll_divider_set
   3015  */
   3016 STATIC int
   3017 qsgmiie_pll_divider_set(soc_phymod_ctrl_t *pmc, uint32 value)
   3018 {
   3019 #if 0
   3020 phymod_phy_interface_config_set (?)
   3021 #endif
   3022 
   3023    return(SOC_E_UNAVAIL);
   3024 }
   3025 
   3026 /* 
   3027  * qsgmiie_oversample_mode_set
   3028  */
   3029 STATIC int
   3030 qsgmiie_oversample_mode_set(soc_phymod_ctrl_t *pmc, uint32 value)
   3031 {
   3032 #if 0
   3033 phymod_phy_interface_config_set (?)
   3034 #endif
   3035 
   3036    return(SOC_E_UNAVAIL);
   3037 }
   3038 
   3039 /* 
   3040  * qsgmiie_ref_clk_set
   3041  */
   3042 STATIC int
   3043 qsgmiie_ref_clk_set(soc_phymod_ctrl_t *pmc, uint32 value)
   3044 {
   3045 #if 0
   3046 The control stores the ref clock in SW DB. 
   3047 As discussed the phymod will be stateless. 
   3048 So itll be added to interface_config_set as input parameter.
   3049 
   3050 phymod_phy_interface_config_set
   3051 #endif
   3052 
   3053    return(SOC_E_UNAVAIL);
   3054 }
   3055 
   3056 /* 
   3057  * qsgmiie_rx_seq_toggle_set 
   3058  */
   3059 STATIC int
   3060 qsgmiie_rx_seq_toggle_set(soc_phymod_ctrl_t *pmc)
   3061 {
   3062     phymod_phy_access_t    *pm_phy;
   3063     int                    idx;
   3064 
   3065     /* loop through all cores */
   3066     for (idx = 0; idx < pmc->num_phys; idx++) {
   3067         if (pmc->phy[idx] == NULL) {
   3068             return(SOC_E_INTERNAL);
   3069         }
   3070 
   3071         pm_phy = &pmc->phy[idx]->pm_phy;
   3072         if (pm_phy == NULL) {
   3073             return(SOC_E_INTERNAL);
   3074         }
   3075         SOC_IF_ERROR_RETURN(phymod_phy_rx_restart(pm_phy));
   3076     }
   3077 
   3078     return(SOC_E_NONE);
   3079 }
   3080 
   3081 /* 
   3082  * qsgmiie_driver_supply_set
   3083  */
   3084 STATIC int
   3085 qsgmiie_driver_supply_set(soc_phymod_ctrl_t *pmc, uint32 value)
   3086 {
   3087 #if 0
   3088 Can be added as init parameter.
   3089 Do you think set\get API are required?
   3090 #endif
   3091 
   3092    return(SOC_E_UNAVAIL);
   3093 }
   3094 
   3095 /*
   3096  * Function:
   3097  *      phy_qsgmiie_control_set
   3098  * Purpose:
   3099  *      Configure PHY device specific control fucntion. 
   3100  * Parameters:
   3101  *      unit  - BCM unit number.
   3102  *      port  - Port number. 
   3103  *      type  - Control to update 
   3104  *      value - New setting for the control 
   3105  * Returns:     
   3106  *      SOC_E_NONE
   3107  */
   3108 STATIC int
   3109 phy_qsgmiie_control_set(int unit, soc_port_t port, soc_phy_control_t type, uint32 value)
   3110 {
   3111     int                 rv;
   3112     phy_ctrl_t          *pc;
   3113     soc_phymod_ctrl_t   *pmc;
   3114     qsgmiie_config_t       *pCfg;
   3115 
   3116     rv = SOC_E_UNAVAIL;
   3117 
   3118     if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) {
   3119         return (SOC_E_PARAM);
   3120     }
   3121 
   3122     /* locate phy control, phymod control, and the configuration data */
   3123     pc = INT_PHY_SW_STATE(unit, port);
   3124     if (pc == NULL) {
   3125         return SOC_E_INTERNAL;
   3126     }
   3127     pmc = &pc->phymod_ctrl;
   3128     pCfg = (qsgmiie_config_t *) pc->driver_data;
   3129 
   3130     switch(type) {
   3131 
   3132     case SOC_PHY_CONTROL_TX_FIR_PRE:
   3133         rv = qsgmiie_tx_fir_pre_set(pmc, value);
   3134         break;
   3135     case SOC_PHY_CONTROL_TX_FIR_MAIN:
   3136         rv = qsgmiie_tx_fir_main_set(pmc, value);
   3137         break;
   3138     case SOC_PHY_CONTROL_TX_FIR_POST:
   3139         rv = qsgmiie_tx_fir_post_set(pmc, value);
   3140         break;
   3141     case SOC_PHY_CONTROL_TX_FIR_POST2:
   3142         rv = qsgmiie_tx_fir_post2_set(pmc, value);
   3143         break;
   3144     case SOC_PHY_CONTROL_TX_FIR_POST3:
   3145         rv = qsgmiie_tx_fir_post3_set(pmc, value);
   3146         break;
   3147     /* PREEMPHASIS */
   3148     case SOC_PHY_CONTROL_PREEMPHASIS_LANE0:
   3149         rv = qsgmiie_per_lane_preemphasis_set(pmc, 0, value);
   3150         break;
   3151     case SOC_PHY_CONTROL_PREEMPHASIS_LANE1:
   3152         rv = qsgmiie_per_lane_preemphasis_set(pmc, 1, value);
   3153         break;
   3154     case SOC_PHY_CONTROL_PREEMPHASIS_LANE2:
   3155         rv = qsgmiie_per_lane_preemphasis_set(pmc, 2, value);
   3156         break;
   3157     case SOC_PHY_CONTROL_PREEMPHASIS_LANE3:
   3158         rv = qsgmiie_per_lane_preemphasis_set(pmc, 3, value);
   3159         break;
   3160     case SOC_PHY_CONTROL_PREEMPHASIS:
   3161         rv = qsgmiie_preemphasis_set(pmc, value);
   3162         break;
   3163 
   3164     /* DRIVER CURRENT */
   3165     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0:
   3166         rv = qsgmiie_per_lane_driver_current_set(pmc, 0, value);
   3167         break;
   3168     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1:
   3169         rv = qsgmiie_per_lane_driver_current_set(pmc, 1, value);
   3170         break;
   3171     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2:
   3172         rv = qsgmiie_per_lane_driver_current_set(pmc, 2, value);
   3173         break;
   3174     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3:
   3175         rv = qsgmiie_per_lane_driver_current_set(pmc, 3, value);
   3176         break;
   3177     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   3178         rv = qsgmiie_driver_current_set(pmc, value);
   3179         break;
   3180 
   3181     /* PRE_DRIVER CURRENT  not supported anymore */
   3182     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE0:
   3183         rv = SOC_E_UNAVAIL;
   3184         break;
   3185     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE1:
   3186         rv = SOC_E_UNAVAIL;
   3187         break;
   3188     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE2:
   3189         rv = SOC_E_UNAVAIL;
   3190         break;
   3191     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE3:
   3192         rv = SOC_E_UNAVAIL;
   3193         break;
   3194     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT:
   3195         rv = SOC_E_UNAVAIL;
   3196         break;
   3197 
   3198     /* POST2_DRIVER CURRENT not supported anymore */
   3199     case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT:
   3200         rv = SOC_E_UNAVAIL;
   3201         break;
   3202     case SOC_PHY_CONTROL_DUMP:
   3203         /* "N/A: will be part of common phymod application" */
   3204         /*     was rv = tscmod_uc_status_dump(unit, port); */
   3205         break;
   3206 
   3207     /* TX LANE SQUELCH */
   3208     case SOC_PHY_CONTROL_TX_LANE_SQUELCH:
   3209         rv = qsgmiie_tx_lane_squelch(pmc, value);
   3210         break;
   3211 
   3212     /* RX PEAK FILTER */
   3213     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   3214         rv = qsgmiie_rx_peak_filter_set(pmc, value);
   3215         break;
   3216 
   3217     /* RX VGA */
   3218     case SOC_PHY_CONTROL_RX_VGA:
   3219         rv = qsgmiie_rx_vga_set(pmc, value);
   3220         break;
   3221     case SOC_PHY_CONTROL_RX_VGA_RELEASE:
   3222        /* $$$ tbd $$$ */
   3223        break;
   3224 
   3225     /* RX TAP */
   3226     case SOC_PHY_CONTROL_RX_TAP1:
   3227         rv = qsgmiie_rx_tap_set(pmc, 0, value);
   3228         break;
   3229     case SOC_PHY_CONTROL_RX_TAP2:
   3230         rv = qsgmiie_rx_tap_set(pmc, 1, value);
   3231         break;
   3232     case SOC_PHY_CONTROL_RX_TAP3:
   3233         rv = qsgmiie_rx_tap_set(pmc, 2, value);
   3234         break;
   3235     case SOC_PHY_CONTROL_RX_TAP4:
   3236         rv = qsgmiie_rx_tap_set(pmc, 3, value);
   3237         break;
   3238     case SOC_PHY_CONTROL_RX_TAP5:
   3239         rv = qsgmiie_rx_tap_set(pmc, 4, value);
   3240         break;
   3241     case SOC_PHY_CONTROL_RX_TAP1_RELEASE:       /* $$$ tbd $$$ */
   3242        rv = qsgmiie_rx_tap_release(pmc, 0);
   3243        break;
   3244     case SOC_PHY_CONTROL_RX_TAP2_RELEASE:       /* $$$ tbd $$$ */
   3245        rv = qsgmiie_rx_tap_release(pmc, 1);
   3246        break;
   3247     case SOC_PHY_CONTROL_RX_TAP3_RELEASE:       /* $$$ tbd $$$ */
   3248        rv = qsgmiie_rx_tap_release(pmc, 2);
   3249        break;
   3250     case SOC_PHY_CONTROL_RX_TAP4_RELEASE:       /* $$$ tbd $$$ */
   3251        rv = qsgmiie_rx_tap_release(pmc, 3);
   3252        break;
   3253     case SOC_PHY_CONTROL_RX_TAP5_RELEASE:       /* $$$ tbd $$$ */
   3254        rv = qsgmiie_rx_tap_release(pmc, 4);
   3255        break;
   3256     /* RX SLICER */
   3257     case SOC_PHY_CONTROL_RX_PLUS1_SLICER:
   3258         rv = SOC_E_UNAVAIL;
   3259         break;
   3260     case SOC_PHY_CONTROL_RX_MINUS1_SLICER:
   3261         rv = SOC_E_UNAVAIL;
   3262         break;
   3263     case SOC_PHY_CONTROL_RX_D_SLICER:
   3264         rv = SOC_E_UNAVAIL;
   3265         break;
   3266 
   3267     /* PHASE INTERPOLATOR */
   3268     case SOC_PHY_CONTROL_PHASE_INTERP:
   3269         rv = qsgmiie_pi_control_set(pmc, value);
   3270         break;
   3271 
   3272     /* POLARITY */
   3273     case SOC_PHY_CONTROL_RX_POLARITY:
   3274         rv = qsgmiie_rx_polarity_set(pmc, &pCfg->phy_polarity_config, value);;
   3275         break;
   3276     case SOC_PHY_CONTROL_TX_POLARITY:
   3277         rv = qsgmiie_tx_polarity_set(pmc, &pCfg->phy_polarity_config, value);
   3278         break;
   3279 
   3280     /* RESET */
   3281     case SOC_PHY_CONTROL_RX_RESET:
   3282         rv = qsgmiie_rx_reset(pmc, &pCfg->phy_reset_config, value);
   3283         break;
   3284     case SOC_PHY_CONTROL_TX_RESET:
   3285         rv = qsgmiie_tx_reset(pmc, &pCfg->phy_reset_config, value);
   3286         break;
   3287 
   3288     /* CL72 ENABLE */
   3289     case SOC_PHY_CONTROL_CL72:
   3290         rv = qsgmiie_cl72_enable_set(pmc, value);
   3291         break;
   3292 
   3293     /* LANE SWAP */
   3294     case SOC_PHY_CONTROL_LANE_SWAP:
   3295         rv = qsgmiie_lane_map_set(pmc, value);
   3296         break;
   3297 
   3298     /* TX PATTERN */
   3299     case SOC_PHY_CONTROL_TX_PATTERN_20BIT:
   3300         rv = SOC_E_UNAVAIL;
   3301         break;
   3302     case SOC_PHY_CONTROL_TX_PATTERN_256BIT:
   3303         rv = SOC_E_UNAVAIL;
   3304         break;
   3305     case SOC_PHY_CONTROL_TX_PATTERN_LENGTH:
   3306         rv = qsgmiie_pattern_len_set(pmc, value);
   3307         break;
   3308     case SOC_PHY_CONTROL_TX_PATTERN_GEN_ENABLE:
   3309         rv = qsgmiie_pattern_enable_set(pmc, value);
   3310         break;
   3311     case SOC_PHY_CONTROL_TX_PATTERN_DATA0:
   3312         rv = qsgmiie_pattern_data_set(0, &pCfg->pattern, value);
   3313         break;
   3314     case SOC_PHY_CONTROL_TX_PATTERN_DATA1:
   3315         rv = qsgmiie_pattern_data_set(1, &pCfg->pattern, value);
   3316         break;
   3317     case SOC_PHY_CONTROL_TX_PATTERN_DATA2:
   3318         rv = qsgmiie_pattern_data_set(2, &pCfg->pattern, value);
   3319         break;
   3320     case SOC_PHY_CONTROL_TX_PATTERN_DATA3:
   3321         rv = qsgmiie_pattern_data_set(3, &pCfg->pattern, value);
   3322         break;
   3323     case SOC_PHY_CONTROL_TX_PATTERN_DATA4:
   3324         rv = qsgmiie_pattern_data_set(4, &pCfg->pattern, value);
   3325         break;
   3326     case SOC_PHY_CONTROL_TX_PATTERN_DATA5:
   3327         rv = qsgmiie_pattern_data_set(5, &pCfg->pattern, value);
   3328         break;
   3329     case SOC_PHY_CONTROL_TX_PATTERN_DATA6:
   3330         rv = qsgmiie_pattern_data_set(6, &pCfg->pattern, value);
   3331         break;
   3332     case SOC_PHY_CONTROL_TX_PATTERN_DATA7:
   3333         rv = qsgmiie_pattern_data_set(7, &pCfg->pattern, value);
   3334         break;
   3335 
   3336     /* decoupled PRBS */
   3337     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL:
   3338         rv = qsgmiie_prbs_tx_poly_set(pmc, value);
   3339         break;
   3340     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA:
   3341         rv = qsgmiie_prbs_tx_invert_data_set(pmc, value);
   3342         break;
   3343     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE:
   3344         rv = qsgmiie_prbs_tx_enable_set(pmc, value);
   3345         break; 
   3346     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL:
   3347         rv = qsgmiie_prbs_rx_poly_set(pmc, value);
   3348         break;
   3349     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA:
   3350         rv = qsgmiie_prbs_rx_invert_data_set(pmc, value);
   3351         break;
   3352     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE:
   3353         rv = qsgmiie_prbs_rx_enable_set(pmc, value);
   3354         break;
   3355     /*for legacy prbs usage mainly set both tx/rx the same */
   3356     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   3357         rv = qsgmiie_prbs_tx_poly_set(pmc, value);
   3358         rv = qsgmiie_prbs_rx_poly_set(pmc, value);
   3359         break;
   3360     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   3361         rv = qsgmiie_prbs_tx_invert_data_set(pmc, value);
   3362         break;
   3363     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   3364         rv = qsgmiie_prbs_tx_enable_set(pmc, value);
   3365         rv = qsgmiie_prbs_rx_enable_set(pmc, value);
   3366         break;
   3367     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   3368         rv = qsgmiie_prbs_tx_enable_set(pmc, value);
   3369         rv = qsgmiie_prbs_rx_enable_set(pmc, value);
   3370         break;
   3371 
   3372     /* LOOPBACK */
   3373     case SOC_PHY_CONTROL_LOOPBACK_INTERNAL:
   3374         rv = qsgmiie_loopback_internal_set(pmc, value);
   3375        break;
   3376     case SOC_PHY_CONTROL_LOOPBACK_PMD:
   3377         rv = qsgmiie_loopback_internal_pmd_set(pmc, value);
   3378        break;
   3379     case SOC_PHY_CONTROL_LOOPBACK_REMOTE:
   3380         rv = qsgmiie_loopback_remote_set(pmc, value);
   3381         break;
   3382     case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS:
   3383         rv = qsgmiie_loopback_remote_pcs_set(pmc, value);
   3384         break;
   3385 
   3386     /* FEC */
   3387     case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION:
   3388         rv = qsgmiie_fec_enable_set(pmc, value);
   3389         break;
   3390 
   3391     /* CUSTOM */
   3392     case SOC_PHY_CONTROL_CUSTOM1:
   3393        /* Obsolete ??
   3394        DEV_CFG_PTR(pc)->custom1 = value? TRUE: FALSE ;
   3395        rv = SOC_E_NONE; */
   3396        rv = SOC_E_UNAVAIL;
   3397        break;
   3398 
   3399     /* SCRAMBLER */
   3400     case SOC_PHY_CONTROL_SCRAMBLER:
   3401         rv = qsgmiie_scrambler_set(pmc, port, value);
   3402         break;
   3403 
   3404     /* 8B10B */
   3405     case SOC_PHY_CONTROL_8B10B:
   3406         rv = qsgmiie_8b10b_set(pmc, value);
   3407         break;
   3408 
   3409     /* 64B65B */
   3410     case SOC_PHY_CONTROL_64B66B:
   3411         rv = qsgmiie_64b65b_set(pmc, value);
   3412         break;
   3413 
   3414     /* POWER */
   3415     case SOC_PHY_CONTROL_POWER:
   3416        rv = qsgmiie_power_set(pmc, value);
   3417        break;
   3418 
   3419     /* RX_LOW_FREQ_PEAK_FILTER */
   3420     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   3421        rv = qsgmiie_rx_low_freq_filter_set(pmc, value);
   3422        break;
   3423 
   3424     /* TX_PPM_ADJUST */
   3425     case SOC_PHY_CONTROL_TX_PPM_ADJUST:
   3426        rv = qsgmiie_tx_ppm_adjust_set(pmc, value);
   3427        break;
   3428 
   3429     /* VCO_FREQ */
   3430     case SOC_PHY_CONTROL_VCO_FREQ:
   3431        rv = qsgmiie_vco_freq_set(pmc, value);
   3432        break;
   3433 
   3434     /* PLL_DIVIDER */
   3435     case SOC_PHY_CONTROL_PLL_DIVIDER:
   3436        rv = qsgmiie_pll_divider_set(pmc, value);
   3437        break;
   3438 
   3439     /* OVERSAMPLE_MODE */
   3440     case SOC_PHY_CONTROL_OVERSAMPLE_MODE:
   3441        rv = qsgmiie_oversample_mode_set(pmc, value);
   3442        break;
   3443 
   3444     /* REF_CLK */
   3445     case SOC_PHY_CONTROL_REF_CLK:
   3446        rv = qsgmiie_ref_clk_set(pmc, value);
   3447        break;
   3448 
   3449     /* RX_SEQ_TOGGLE */
   3450     case SOC_PHY_CONTROL_RX_SEQ_TOGGLE:
   3451        rv = qsgmiie_rx_seq_toggle_set(pmc);
   3452        break;
   3453 
   3454     /* DRIVER_SUPPLY */
   3455     case SOC_PHY_CONTROL_DRIVER_SUPPLY:
   3456        rv = qsgmiie_driver_supply_set(pmc, value);
   3457        break;
   3458 
   3459     /* EEE */
   3460 #ifdef TSC_EEE_SUPPORT
   3461     case SOC_PHY_CONTROL_EEE:
   3462     case SOC_PHY_CONTROL_EEE_AUTO:
   3463         rv = SOC_E_NONE;   /* not supported */
   3464         break;
   3465 #endif
   3466 #if 0
   3467        /* Added to support WA for HW bug; probably not required. */
   3468     case SOC_PHY_CONTROL_SOFTWARE_RX_LOS:
   3469         DEV_CFG_PTR(pc)->sw_rx_los.enable = (value == 0? 0: 1);
   3470         DEV_CFG_PTR(pc)->sw_rx_los.sys_link = 0; 
   3471         DEV_CFG_PTR(pc)->sw_rx_los.state = RXLOS_RESET;
   3472         DEV_CFG_PTR(pc)->sw_rx_los.link_status = 0;
   3473         /* THE FLAG IS SET IN INIT. FOR TSCMOD DRIVER
   3474            TO WORK IT'S LINK_GET MUST BE CALLED */
   3475         /* Manage the _SERVICE_INT_PHY_LINK_GET flag so that 
   3476            if external phy is present link_get for 
   3477            internal phy is still called to process 
   3478            software rx los feature 
   3479         if(value) {
   3480             PHY_FLAGS_SET(unit, port, PHY_FLAGS_SERVICE_INT_PHY_LINK_GET);
   3481         } else {
   3482             PHY_FLAGS_CLR(unit, port, PHY_FLAGS_SERVICE_INT_PHY_LINK_GET);
   3483         }
   3484         */
   3485         rv = SOC_E_NONE;
   3486         break;  
   3487     case SOC_PHY_CONTROL_FEC_OFF:
   3488         rv = qsgmiie_fec_enable_set(pmc, 0);
   3489         break;
   3490     case SOC_PHY_CONTROL_FEC_ON:
   3491         rv = qsgmiie_fec_enable_set(pmc, 1);
   3492         break;
   3493 
   3494     /* UNAVAIL */
   3495     case SOC_PHY_CONTROL_LINKDOWN_TRANSMIT:
   3496     case SOC_PHY_CONTROL_PARALLEL_DETECTION:
   3497     case SOC_PHY_CONTROL_BERT_PATTERN:
   3498     case SOC_PHY_CONTROL_BERT_RUN:
   3499     case SOC_PHY_CONTROL_BERT_PACKET_SIZE:
   3500     case SOC_PHY_CONTROL_BERT_IPG:
   3501     case SOC_PHY_CONTROL_RX_PEAK_FILTER_TEMP_COMP:
   3502     case SOC_PHY_CONTROL_CL73_FSM_AUTO_RECOVER:
   3503 #endif
   3504     default:
   3505         rv = SOC_E_UNAVAIL;
   3506         break; 
   3507     }
   3508     return rv;
   3509 }
   3510 
   3511 
   3512 /* 
   3513  * qsgmiie_tx_fir_pre_get
   3514  */
   3515 STATIC int
   3516 qsgmiie_tx_fir_pre_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3517 {
   3518     phymod_phy_access_t *pm_phy;
   3519     phymod_tx_t         phymod_tx;
   3520     int                 idx;
   3521 
   3522     /* loop through all cores */
   3523     for (idx = 0; idx < pmc->num_phys; idx++) {
   3524         pm_phy = &pmc->phy[idx]->pm_phy;
   3525 
   3526         if (pm_phy == NULL) {
   3527             return SOC_E_INTERNAL;
   3528         }
   3529 
   3530         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   3531         *value = phymod_tx.pre;
   3532     }
   3533 
   3534     return(SOC_E_NONE);
   3535 }
   3536 
   3537 /* 
   3538  * qsgmiie_tx_fir_main_get
   3539  */
   3540 STATIC int
   3541 qsgmiie_tx_fir_main_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3542 {
   3543     phymod_phy_access_t *pm_phy;
   3544     phymod_tx_t         phymod_tx;
   3545     int                 idx;
   3546 
   3547     /* loop through all cores */
   3548     for (idx = 0; idx < pmc->num_phys; idx++) {
   3549         pm_phy = &pmc->phy[idx]->pm_phy;
   3550 
   3551         if (pm_phy == NULL) {
   3552             return SOC_E_INTERNAL;
   3553         }
   3554 
   3555         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   3556         *value = phymod_tx.main;
   3557     }
   3558 
   3559     return(SOC_E_NONE);
   3560 }
   3561 
   3562 /* 
   3563  * qsgmiie_tx_fir_post_get
   3564  */
   3565 STATIC int
   3566 qsgmiie_tx_fir_post_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3567 {
   3568     phymod_phy_access_t *pm_phy;
   3569     phymod_tx_t         phymod_tx;
   3570     int                 idx;
   3571 
   3572     /* loop through all cores */
   3573     for (idx = 0; idx < pmc->num_phys; idx++) {
   3574         pm_phy = &pmc->phy[idx]->pm_phy;
   3575 
   3576         if (pm_phy == NULL) {
   3577             return SOC_E_INTERNAL;
   3578         }
   3579 
   3580         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   3581         *value = phymod_tx.post;
   3582     }
   3583 
   3584     return(SOC_E_NONE);
   3585 }
   3586 
   3587 /* 
   3588  * qsgmiie_tx_fir_post2_get
   3589  */
   3590 STATIC int
   3591 qsgmiie_tx_fir_post2_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3592 {
   3593     phymod_phy_access_t *pm_phy;
   3594     phymod_tx_t         phymod_tx;
   3595     int                 idx;
   3596 
   3597     /* loop through all cores */
   3598     for (idx = 0; idx < pmc->num_phys; idx++) {
   3599         pm_phy = &pmc->phy[idx]->pm_phy;
   3600 
   3601         if (pm_phy == NULL) {
   3602             return SOC_E_INTERNAL;
   3603         }
   3604 
   3605         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   3606         *value = phymod_tx.post2;
   3607     }
   3608 
   3609     return(SOC_E_NONE);
   3610 }
   3611 
   3612 /* 
   3613  * qsgmiie_tx_fir_post3_get
   3614  */
   3615 STATIC int
   3616 qsgmiie_tx_fir_post3_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3617 {
   3618     phymod_phy_access_t *pm_phy;
   3619     phymod_tx_t         phymod_tx;
   3620     int                 idx;
   3621     
   3622     /* loop through all cores */
   3623     for (idx = 0; idx < pmc->num_phys; idx++) {
   3624         pm_phy = &pmc->phy[idx]->pm_phy;
   3625 
   3626         if (pm_phy == NULL) {
   3627             return SOC_E_INTERNAL;
   3628         }
   3629 
   3630         SOC_IF_ERROR_RETURN(phymod_phy_tx_get(pm_phy, &phymod_tx));
   3631         *value = phymod_tx.post3;
   3632     }
   3633 
   3634     return(SOC_E_NONE);
   3635 }
   3636 
   3637 /* 
   3638  * qsgmiie_per_lane_preemphasis_get
   3639  */
   3640 STATIC int
   3641 qsgmiie_per_lane_preemphasis_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3642 {
   3643     soc_phymod_phy_t    *p_phy;
   3644     uint32              lane_map;
   3645     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3646     phymod_tx_t         phymod_tx;
   3647 
   3648     /* locate the desired phy and lane */
   3649     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3650 
   3651     /* Make a copy of the phy access and overwrite the desired lane */
   3652     pm_phy = &p_phy->pm_phy;
   3653     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3654     pm_phy_copy.access.lane_mask = lane_map;
   3655 
   3656     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3657     *value = phymod_tx.pre;
   3658 
   3659     return(SOC_E_NONE);
   3660 }
   3661 
   3662 /* 
   3663  * qsgmiie_per_lane_driver_current_get
   3664  */
   3665 STATIC int
   3666 qsgmiie_per_lane_driver_current_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3667 {
   3668     soc_phymod_phy_t    *p_phy;
   3669     uint32              lane_map;
   3670     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3671     phymod_tx_t         phymod_tx;
   3672 
   3673     /* locate the desired phy and lane */
   3674     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3675 
   3676     /* Make a copy of the phy access and overwrite the desired lane */
   3677     pm_phy = &p_phy->pm_phy;
   3678     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3679     pm_phy_copy.access.lane_mask = lane_map;
   3680 
   3681     SOC_IF_ERROR_RETURN(phymod_phy_tx_get(&pm_phy_copy, &phymod_tx));
   3682     *value = phymod_tx.amp;
   3683 
   3684     return(SOC_E_NONE);
   3685 }
   3686 
   3687 /* 
   3688  * qsgmiie_per_lane_prbs_poly_get
   3689  */
   3690 STATIC int
   3691 qsgmiie_per_lane_prbs_poly_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3692 {
   3693    return(SOC_E_UNAVAIL);
   3694 }
   3695 
   3696 /* 
   3697  * qsgmiie_per_lane_prbs_tx_invert_data_get
   3698  */
   3699 STATIC int
   3700 qsgmiie_per_lane_prbs_tx_invert_data_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3701 {
   3702    return(SOC_E_UNAVAIL);
   3703 }
   3704 
   3705 /* 
   3706  * qsgmiie_per_lane_prbs_tx_enable_get
   3707  */
   3708 STATIC int
   3709 qsgmiie_per_lane_prbs_tx_enable_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3710 {
   3711    return(SOC_E_UNAVAIL);
   3712 }
   3713 
   3714 /* 
   3715  * qsgmiie_per_lane_prbs_rx_enable_get
   3716  */
   3717 STATIC int
   3718 qsgmiie_per_lane_prbs_rx_enable_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3719 {
   3720    return(SOC_E_UNAVAIL);
   3721 }
   3722 
   3723 /* 
   3724  * qsgmiie_per_lane_prbs_rx_status_get
   3725  */
   3726 STATIC int
   3727 qsgmiie_per_lane_prbs_rx_status_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3728 {
   3729    /* $$$ Need to add diagnostic API */
   3730    return(SOC_E_UNAVAIL);
   3731 }
   3732 
   3733 /* 
   3734  * qsgmiie_per_lane_rx_peak_filter_get
   3735  */
   3736 STATIC int
   3737 qsgmiie_per_lane_rx_peak_filter_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3738 {
   3739     soc_phymod_phy_t    *p_phy;
   3740     uint32              lane_map;
   3741     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3742     phymod_rx_t         phymod_rx;
   3743 
   3744     *value = 0;
   3745 
   3746     /* locate the desired phy and lane */
   3747     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3748 
   3749     /* Make a copy of the phy access and overwrite the desired lane */
   3750     pm_phy = &p_phy->pm_phy;
   3751     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3752     pm_phy_copy.access.lane_mask = lane_map;
   3753 
   3754     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3755     if (phymod_rx.peaking_filter.enable)
   3756         *value = phymod_rx.peaking_filter.value;
   3757 
   3758     return(SOC_E_NONE);
   3759 }
   3760 
   3761 /* 
   3762  * qsgmiie_per_lane_rx_vga_get
   3763  */
   3764 STATIC int
   3765 qsgmiie_per_lane_rx_vga_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3766 {
   3767     soc_phymod_phy_t    *p_phy;
   3768     uint32              lane_map;
   3769     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3770     phymod_rx_t         phymod_rx;
   3771 
   3772     *value = 0;
   3773 
   3774     /* locate the desired phy and lane */
   3775     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3776 
   3777     /* Make a copy of the phy access and overwrite the desired lane */
   3778     pm_phy = &p_phy->pm_phy;
   3779     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3780     pm_phy_copy.access.lane_mask = lane_map;
   3781 
   3782     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3783     if (phymod_rx.vga.enable)
   3784         *value = phymod_rx.vga.value;
   3785 
   3786     return(SOC_E_NONE);
   3787 }
   3788 
   3789 /* 
   3790  * qsgmiie_per_lane_rx_dfe_tap_control_get
   3791  */
   3792 STATIC int
   3793 qsgmiie_per_lane_rx_dfe_tap_control_get(soc_phymod_ctrl_t *pmc, int lane, int tap, uint32 *value)
   3794 {
   3795     soc_phymod_phy_t    *p_phy;
   3796     uint32              lane_map;
   3797     phymod_phy_access_t pm_phy_copy, *pm_phy;
   3798     phymod_rx_t          phymod_rx;
   3799 
   3800     *value = 0;
   3801 
   3802     /* locate the desired phy and lane */
   3803     SOC_IF_ERROR_RETURN(_qsgmiie_find_soc_phy_lane(pmc, lane, &p_phy, &lane_map));
   3804 
   3805     /* Make a copy of the phy access and overwrite the desired lane */
   3806     pm_phy = &p_phy->pm_phy;
   3807     sal_memcpy(&pm_phy_copy, pm_phy, sizeof(pm_phy_copy));
   3808     pm_phy_copy.access.lane_mask = lane_map;
   3809 
   3810     if ((tap<0)||(tap>(COUNTOF(phymod_rx.dfe) -1 ))) {
   3811         /* this can only happen with a coding error */
   3812         return SOC_E_INTERNAL;
   3813     }
   3814 
   3815     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(&pm_phy_copy, &phymod_rx));
   3816     if (phymod_rx.dfe[tap].enable)
   3817        *value = phymod_rx.dfe[tap].value;
   3818 
   3819     return(SOC_E_NONE);
   3820 }
   3821 
   3822 
   3823 /* 
   3824  * qsgmiie_per_lane_rx_low_freq_filter_get
   3825  */
   3826 STATIC int
   3827 qsgmiie_per_lane_rx_low_freq_filter_get(soc_phymod_ctrl_t *pmc, int lane, uint32 *value)
   3828 {
   3829    return(SOC_E_UNAVAIL);
   3830 }
   3831 
   3832 /* 
   3833  * qsgmiie_rx_peak_filter_get
   3834  */
   3835 STATIC int 
   3836 qsgmiie_rx_peak_filter_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3837 {
   3838     phymod_phy_access_t  *pm_phy;
   3839     phymod_rx_t          phymod_rx;
   3840 
   3841     /* just take the value from the first phy */
   3842     if (pmc->phy[0] == NULL) {
   3843         return SOC_E_INTERNAL;
   3844     }
   3845     pm_phy = &pmc->phy[0]->pm_phy;
   3846 
   3847     if (pm_phy == NULL) {
   3848         return SOC_E_INTERNAL;
   3849     }
   3850 
   3851     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx));
   3852     *value = phymod_rx.peaking_filter.value;
   3853 
   3854     return(SOC_E_NONE);
   3855 }
   3856 
   3857 /* 
   3858  * qsgmiie_rx_vga_set
   3859  */
   3860 STATIC int 
   3861 qsgmiie_rx_vga_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3862 {
   3863     phymod_phy_access_t  *pm_phy;
   3864     phymod_rx_t          phymod_rx;
   3865 
   3866     /* just take the value from the first phy */
   3867     if (pmc->phy[0] == NULL) {
   3868         return SOC_E_INTERNAL;
   3869     }
   3870     pm_phy = &pmc->phy[0]->pm_phy;
   3871 
   3872     if (pm_phy == NULL) {
   3873         return SOC_E_INTERNAL;
   3874     }
   3875 
   3876     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx));
   3877     *value = phymod_rx.vga.value;
   3878 
   3879     return(SOC_E_NONE);
   3880 }
   3881 
   3882 /* 
   3883  * qsgmiie_rx_tap_get
   3884  */
   3885 STATIC int 
   3886 qsgmiie_rx_tap_get(soc_phymod_ctrl_t *pmc, int tap, uint32 *value)
   3887 {
   3888     phymod_phy_access_t  *pm_phy;
   3889     phymod_rx_t          phymod_rx;
   3890 
   3891     if ((tap < 0)||(tap > (COUNTOF(phymod_rx.dfe) - 1))) {
   3892         /* this can only happen with a coding error */
   3893         return SOC_E_INTERNAL;
   3894     }
   3895     /* just take the value from the first phy */
   3896     if (pmc->phy[0] == NULL) {
   3897         return SOC_E_INTERNAL;
   3898     }
   3899     pm_phy = &pmc->phy[0]->pm_phy;
   3900 
   3901     if (pm_phy == NULL) {
   3902         return SOC_E_INTERNAL;
   3903     }
   3904 
   3905     SOC_IF_ERROR_RETURN(phymod_phy_rx_get(pm_phy, &phymod_rx));
   3906     *value = phymod_rx.dfe[tap].value;
   3907 
   3908     return(SOC_E_NONE);
   3909 }
   3910 
   3911 /* 
   3912  * qsgmiie_pi_control_get
   3913  */
   3914 STATIC int 
   3915 qsgmiie_pi_control_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3916 {
   3917     phymod_phy_access_t  *pm_phy;
   3918     phymod_tx_override_t tx_override;
   3919 
   3920     /* just take the value from the first phy */
   3921     if (pmc->phy[0] == NULL) {
   3922         return SOC_E_INTERNAL;
   3923     }
   3924     pm_phy = &pmc->phy[0]->pm_phy;
   3925 
   3926     if (pm_phy == NULL) {
   3927         return SOC_E_INTERNAL;
   3928     }
   3929 
   3930     SOC_IF_ERROR_RETURN(phymod_phy_tx_override_get(pm_phy, &tx_override));
   3931     *value = tx_override.phase_interpolator.value;
   3932 
   3933     return(SOC_E_NONE);
   3934 }
   3935 
   3936 /* 
   3937  * qsgmiie_rx_signal_detect_get
   3938  */
   3939 STATIC int
   3940 qsgmiie_rx_signal_detect_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3941 {
   3942    /* $$$ Need to add diagnostic API */
   3943    return(SOC_E_UNAVAIL);
   3944 }
   3945 
   3946 /* 
   3947  * qsgmiie_rx_seq_done_get
   3948  */
   3949 STATIC int
   3950 qsgmiie_rx_seq_done_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3951 {
   3952     phymod_phy_access_t  *pm_phy;
   3953 
   3954     /* just take the value from the first phy */
   3955     if (pmc->phy[0] == NULL) {
   3956         return SOC_E_INTERNAL;
   3957     }
   3958     pm_phy = &pmc->phy[0]->pm_phy;
   3959 
   3960     if (pm_phy == NULL) {
   3961          return SOC_E_INTERNAL;
   3962     }
   3963 
   3964     SOC_IF_ERROR_RETURN(phymod_phy_rx_pmd_locked_get(pm_phy, value));
   3965 
   3966     return(SOC_E_NONE);
   3967 }
   3968 
   3969 /* 
   3970  * qsgmiie_rx_ppm_get
   3971  */
   3972 STATIC int
   3973 qsgmiie_rx_ppm_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3974 {
   3975     /* $$$ Need to add diagnostic API */
   3976     return(SOC_E_UNAVAIL);
   3977 }
   3978 
   3979 /* 
   3980  * qsgmiie_cl72_enable_get
   3981  */
   3982 STATIC int
   3983 qsgmiie_cl72_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   3984 {
   3985     phymod_phy_access_t  *pm_phy;
   3986     phymod_cl72_status_t status;
   3987 
   3988     /* just take the value from the first phy */
   3989     if (pmc->phy[0] == NULL) {
   3990         return SOC_E_INTERNAL;
   3991     }
   3992     pm_phy = &pmc->phy[0]->pm_phy;
   3993 
   3994     if (pm_phy == NULL) {
   3995          return SOC_E_INTERNAL;
   3996     }
   3997 
   3998     SOC_IF_ERROR_RETURN(phymod_phy_cl72_status_get(pm_phy, &status));
   3999     *value = status.enabled;
   4000 
   4001     return(SOC_E_NONE);
   4002 }
   4003 
   4004 /* 
   4005  * qsgmiie_cl72_status_get
   4006  */
   4007 STATIC int
   4008 qsgmiie_cl72_status_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4009 {
   4010     phymod_phy_access_t  *pm_phy;
   4011     phymod_cl72_status_t status;
   4012 
   4013     /* just take the value from the first phy */
   4014     if (pmc->phy[0] == NULL) {
   4015         return SOC_E_INTERNAL;
   4016     }
   4017     pm_phy = &pmc->phy[0]->pm_phy;
   4018 
   4019     if (pm_phy == NULL) {
   4020         return SOC_E_INTERNAL;
   4021     }
   4022 
   4023     SOC_IF_ERROR_RETURN(phymod_phy_cl72_status_get(pm_phy, &status));
   4024     *value = status.locked;
   4025 
   4026     return(SOC_E_NONE);
   4027 }
   4028 
   4029 /* 
   4030  * qsgmiie_prbs_tx_poly_get
   4031  */
   4032 STATIC int
   4033 qsgmiie_prbs_tx_poly_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4034 {
   4035     phymod_phy_access_t  *pm_phy;
   4036     phymod_prbs_t        prbs;
   4037     uint32_t flags = 0;
   4038 
   4039     /* just take the value from the first phy */
   4040     if (pmc->phy[0] == NULL) {
   4041         return SOC_E_INTERNAL;
   4042     }
   4043     pm_phy = &pmc->phy[0]->pm_phy;
   4044 
   4045     if (pm_phy == NULL) {
   4046         return SOC_E_INTERNAL;
   4047     }
   4048 
   4049     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   4050     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs));
   4051 
   4052     *value = (int) prbs.poly;
   4053 
   4054     /* convert from PHYMOD enum to SDK enum */
   4055     switch(prbs.poly){
   4056     case phymodPrbsPoly7:
   4057         *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1;
   4058         break;
   4059     case phymodPrbsPoly9:
   4060         *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1;
   4061         break;
   4062     case phymodPrbsPoly15:
   4063         *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1;
   4064         break;
   4065     case phymodPrbsPoly23:
   4066         *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1;
   4067         break;
   4068     case phymodPrbsPoly31:
   4069         *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1;
   4070         break;
   4071     case phymodPrbsPoly58:
   4072         *value = 6; 
   4073         break;
   4074     default:
   4075         return SOC_E_INTERNAL;
   4076     }
   4077     return SOC_E_NONE;
   4078 }
   4079 /* 
   4080  * qsgmiie_prbs_rx_poly_get
   4081  */
   4082 STATIC int
   4083 qsgmiie_prbs_rx_poly_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4084 {
   4085     phymod_phy_access_t  *pm_phy;
   4086     phymod_prbs_t        prbs;
   4087     uint32_t flags = 0;
   4088 
   4089     /* just take the value from the first phy */
   4090     if (pmc->phy[0] == NULL) {
   4091         return SOC_E_INTERNAL;
   4092     }
   4093     pm_phy = &pmc->phy[0]->pm_phy;
   4094 
   4095     if (pm_phy == NULL) {
   4096         return SOC_E_INTERNAL;
   4097     }
   4098 
   4099     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   4100     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs));
   4101 
   4102     *value = (int) prbs.poly;
   4103 
   4104     /* convert from PHYMOD enum to SDK enum */
   4105     switch(prbs.poly){
   4106     case phymodPrbsPoly7:
   4107         *value = SOC_PHY_PRBS_POLYNOMIAL_X7_X6_1;
   4108         break;
   4109     case phymodPrbsPoly9:
   4110         *value = SOC_PHY_PRBS_POLYNOMIAL_X9_X5_1;
   4111         break;
   4112     case phymodPrbsPoly15:
   4113         *value = SOC_PHY_PRBS_POLYNOMIAL_X15_X14_1;
   4114         break;
   4115     case phymodPrbsPoly23:
   4116         *value = SOC_PHY_PRBS_POLYNOMIAL_X23_X18_1;
   4117         break;
   4118     case phymodPrbsPoly31:
   4119         *value = SOC_PHY_PRBS_POLYNOMIAL_X31_X28_1;
   4120         break;
   4121     case phymodPrbsPoly58:
   4122         *value = 6; 
   4123         break;
   4124     default:
   4125         return SOC_E_INTERNAL;
   4126     }
   4127     return SOC_E_NONE;
   4128 }
   4129 
   4130 /* 
   4131  * qsgmiie_prbs_tx_invert_data_get
   4132  */
   4133 STATIC int
   4134 qsgmiie_prbs_tx_invert_data_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4135 {
   4136     phymod_phy_access_t  *pm_phy;
   4137     phymod_prbs_t        prbs;
   4138     uint32_t flags = 0;
   4139 
   4140     /* just take the value from the first phy */
   4141     if (pmc->phy[0] == NULL) {
   4142         return SOC_E_INTERNAL;
   4143     }
   4144     pm_phy = &pmc->phy[0]->pm_phy;
   4145 
   4146     if (pm_phy == NULL) {
   4147         return SOC_E_INTERNAL;
   4148     }
   4149 
   4150     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   4151     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs));
   4152     *value = prbs.invert;
   4153 
   4154     return(SOC_E_NONE);
   4155 }
   4156 
   4157 /* 
   4158  * qsgmiie_prbs_rx_invert_data_get
   4159  */
   4160 STATIC int
   4161 qsgmiie_prbs_rx_invert_data_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4162 {
   4163     phymod_phy_access_t  *pm_phy;
   4164     phymod_prbs_t        prbs;
   4165     uint32_t flags = 0;
   4166 
   4167     /* just take the value from the first phy */
   4168     if (pmc->phy[0] == NULL) {
   4169         return SOC_E_INTERNAL;
   4170     }
   4171     pm_phy = &pmc->phy[0]->pm_phy;
   4172 
   4173     if (pm_phy == NULL) {
   4174         return SOC_E_INTERNAL;
   4175     }
   4176 
   4177     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   4178     SOC_IF_ERROR_RETURN(phymod_phy_prbs_config_get(pm_phy, flags, &prbs));
   4179     *value = prbs.invert;
   4180 
   4181     return(SOC_E_NONE);
   4182 }
   4183 
   4184 
   4185 /* 
   4186  * qsgmiie_prbs_tx_enable_get
   4187  */
   4188 STATIC int
   4189 qsgmiie_prbs_tx_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4190 {
   4191     phymod_phy_access_t  *pm_phy;
   4192     uint32_t flags = 0;
   4193 
   4194     /* just take the value from the first phy */
   4195     if (pmc->phy[0] == NULL) {
   4196         return SOC_E_INTERNAL;
   4197     }
   4198     pm_phy = &pmc->phy[0]->pm_phy;
   4199 
   4200     if (pm_phy == NULL) {
   4201         return SOC_E_INTERNAL;
   4202     }
   4203     PHYMOD_PRBS_DIRECTION_TX_SET(flags);
   4204     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(pm_phy, flags, value));
   4205 
   4206     return(SOC_E_NONE);
   4207 }
   4208 
   4209 /* 
   4210  * qsgmiie_prbs_rx_enable_get
   4211  */
   4212 STATIC int
   4213 qsgmiie_prbs_rx_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4214 {
   4215     phymod_phy_access_t  *pm_phy;
   4216     uint32_t flags = 0;
   4217     /* just take the value from the first phy */
   4218     if (pmc->phy[0] == NULL) {
   4219         return SOC_E_INTERNAL;
   4220     }
   4221     pm_phy = &pmc->phy[0]->pm_phy;
   4222 
   4223     if (pm_phy == NULL) {
   4224         return SOC_E_INTERNAL;
   4225     }
   4226 
   4227     PHYMOD_PRBS_DIRECTION_RX_SET(flags);
   4228     SOC_IF_ERROR_RETURN(phymod_phy_prbs_enable_get(pm_phy, flags, value));
   4229 
   4230     return(SOC_E_NONE);
   4231 }
   4232 
   4233 /* 
   4234  * qsgmiie_prbs_rx_status_get
   4235  */
   4236 STATIC int
   4237 qsgmiie_prbs_rx_status_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4238 {
   4239     phymod_phy_access_t    *pm_phy;
   4240     phymod_prbs_status_t   prbs_tmp;
   4241 
   4242     /* just take the value from the first phy */
   4243     if (pmc->phy[0] == NULL) {
   4244         return SOC_E_INTERNAL;
   4245     }
   4246     pm_phy = &pmc->phy[0]->pm_phy;
   4247 
   4248     if (pm_phy == NULL) {
   4249         return SOC_E_INTERNAL;
   4250     }
   4251     /* $$$ Need to add diagnostic API */
   4252     SOC_IF_ERROR_RETURN
   4253         (phymod_phy_prbs_status_get(pm_phy, 0, &prbs_tmp));
   4254     if (prbs_tmp.prbs_lock == 0) {
   4255         *value = -1;
   4256     } else if ((prbs_tmp.prbs_lock_loss == 1) && (prbs_tmp.prbs_lock == 1)) {
   4257         *value = -2;
   4258     } else {
   4259         *value = prbs_tmp.error_count;
   4260     }     
   4261 
   4262     return(SOC_E_NONE);
   4263 }
   4264 
   4265 /* 
   4266  * qsgmiie_loopback_internal_pmd_get (this is the PMD global loopback)
   4267  */
   4268 STATIC int 
   4269 qsgmiie_loopback_internal_pmd_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4270 {
   4271     phymod_phy_access_t    *pm_phy;
   4272     uint32_t               enable;
   4273 
   4274     /* just take the value from the first phy */
   4275     if (pmc->phy[0] == NULL) {
   4276         return SOC_E_INTERNAL;
   4277     }
   4278     pm_phy = &pmc->phy[0]->pm_phy;
   4279 
   4280     if (pm_phy == NULL) {
   4281         return SOC_E_INTERNAL;
   4282     }
   4283 
   4284     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackGlobalPMD, &enable));
   4285     *value = enable;
   4286     return(SOC_E_NONE);
   4287 }
   4288 
   4289 
   4290 /* 
   4291  * qsgmiie_loopback_remote_get
   4292  */
   4293 STATIC int 
   4294 qsgmiie_loopback_remote_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4295 {
   4296     phymod_phy_access_t    *pm_phy;
   4297     uint32_t               enable;
   4298 
   4299     /* just take the value from the first phy */
   4300     if (pmc->phy[0] == NULL) {
   4301         return SOC_E_INTERNAL;
   4302     }
   4303     pm_phy = &pmc->phy[0]->pm_phy;
   4304 
   4305     if (pm_phy == NULL) {
   4306         return SOC_E_INTERNAL;
   4307     }
   4308 
   4309     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackRemotePMD, &enable));
   4310     *value = enable;
   4311     return(SOC_E_NONE);
   4312 }
   4313 
   4314 /* 
   4315  * qsgmiie_loopback_remote_pcs_get
   4316  */
   4317 STATIC int 
   4318 qsgmiie_loopback_remote_pcs_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4319 {
   4320     phymod_phy_access_t    *pm_phy;
   4321     uint32_t               enable;
   4322 
   4323     /* just take the value from the first phy */
   4324     if (pmc->phy[0] == NULL) {
   4325         return SOC_E_INTERNAL;
   4326     }
   4327     pm_phy = &pmc->phy[0]->pm_phy;
   4328 
   4329     if (pm_phy == NULL) {
   4330         return SOC_E_INTERNAL;
   4331     }
   4332 
   4333     SOC_IF_ERROR_RETURN(phymod_phy_loopback_get(pm_phy, phymodLoopbackRemotePCS, &enable));
   4334     *value = enable;
   4335     return(SOC_E_NONE);
   4336 }
   4337 
   4338 /* 
   4339  * qsgmiie_fec_get
   4340  */
   4341 STATIC int 
   4342 qsgmiie_fec_enable_get(soc_phymod_ctrl_t *pmc, uint32 *value)
   4343 {
   4344     phymod_phy_access_t    *pm_phy;
   4345     uint32_t               enable;
   4346 
   4347     /* just take the value from the first phy */
   4348     if (pmc->phy[0] == NULL) {
   4349         return SOC_E_INTERNAL;
   4350     }
   4351     pm_phy = &pmc->phy[0]->pm_phy;
   4352 
   4353     if (pm_phy == NULL) {
   4354         return SOC_E_INTERNAL;
   4355     }
   4356 
   4357     SOC_IF_ERROR_RETURN(phymod_phy_fec_enable_get(pm_phy,  &enable));
   4358     *value = enable;
   4359 
   4360     return(SOC_E_NONE);
   4361 }
   4362 /* 
   4363  * qsgmiie_pattern_256bit_get 
   4364  *  
   4365  * CHECK SEMANTICS: assumption is that this procedure will retrieve the pattern 
   4366  * from Tier1 and return whether the tx pattern is enabled.  Note that this 
   4367  * is different from the 20 bit pattern retrieval semantics 
   4368  */
   4369 /* 
   4370  * qsgmiie_pattern_256bit_get 
   4371  *  
   4372  * CHECK SEMANTICS: assumption is that this procedure will retrieve the pattern 
   4373  * from Tier1 and return whether the tx pattern is enabled.  Note that this 
   4374  * is different from the 20 bit pattern retrieval semantics 
   4375  */
   4376 STATIC int
   4377 qsgmiie_pattern_get(soc_phymod_ctrl_t *pmc, qsgmiie_pattern_t* cfg_pattern)
   4378 {
   4379     phymod_phy_access_t    *pm_phy;
   4380     phymod_pattern_t       phymod_pattern;
   4381     uint32_t               *temp_data;
   4382 
   4383     /* just take the value from the first phy */
   4384     if (pmc->phy[0] == NULL) {
   4385         return SOC_E_INTERNAL;
   4386     }
   4387     pm_phy = &pmc->phy[0]->pm_phy;
   4388 
   4389     if (pm_phy == NULL) {
   4390         return SOC_E_INTERNAL;
   4391     }
   4392 
   4393     SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_get(pm_phy, &phymod_pattern));
   4394     temp_data = phymod_pattern.pattern;
   4395     cfg_pattern->pattern_data[0] = *temp_data;
   4396     cfg_pattern->pattern_length =  phymod_pattern.pattern_len;
   4397     /* sal_memcpy(cfg_pattern , phymod_pattern.pattern, sizeof(*cfg_pattern)); */
   4398     return(SOC_E_NONE);
   4399 }
   4400 
   4401 STATIC int
   4402 qsgmiie_pattern_len_get(soc_phymod_ctrl_t *pmc, uint32_t *value)
   4403 {
   4404     phymod_phy_access_t    *pm_phy;
   4405     phymod_pattern_t       phymod_pattern;
   4406 
   4407     /* just take the value from the first phy */
   4408     if (pmc->phy[0] == NULL) {
   4409         return SOC_E_INTERNAL;
   4410     }
   4411     pm_phy = &pmc->phy[0]->pm_phy;
   4412 
   4413     if (pm_phy == NULL) {
   4414         return SOC_E_INTERNAL;
   4415     }
   4416 
   4417     SOC_IF_ERROR_RETURN(phymod_phy_pattern_config_get(pm_phy, &phymod_pattern));
   4418     *value = phymod_pattern.pattern_len;
   4419     return(SOC_E_NONE);
   4420 }
   4421 
   4422 /* 
   4423  * qsgmiie_scrambler_get
   4424  */
   4425 STATIC int
   4426 qsgmiie_scrambler_get(soc_phymod_ctrl_t *pmc, soc_port_t port, uint32 *value)
   4427 {
   4428     phymod_phy_access_t     *pm_phy;
   4429     phymod_phy_inf_config_t config;
   4430     phy_ctrl_t              *pc;
   4431     qsgmiie_config_t        *pCfg;
   4432     phymod_ref_clk_t        ref_clk;
   4433 
   4434 
   4435     /* just take the value from the first phy */
   4436     if (pmc->phy[0] == NULL) {
   4437         return SOC_E_INTERNAL;
   4438     }
   4439     pm_phy = &pmc->phy[0]->pm_phy;
   4440 
   4441     if (pm_phy == NULL) {
   4442         return SOC_E_INTERNAL;
   4443     }
   4444 
   4445     pc = INT_PHY_SW_STATE(pmc->unit, port);
   4446     if (pc == NULL) {
   4447         return SOC_E_INTERNAL;
   4448     }
   4449 
   4450     pCfg = (qsgmiie_config_t *) pc->driver_data;
   4451     SOC_IF_ERROR_RETURN(
   4452         qsgmiie_ref_clk_convert(pCfg->speed_config.port_refclk_int, &ref_clk));
   4453 
   4454 
   4455     SOC_IF_ERROR_RETURN(phymod_phy_interface_config_get(pm_phy, 0 /* flags */, ref_clk, &config));
   4456     *value = PHYMOD_INTF_MODES_SCR_GET(&config);
   4457 
   4458     return(SOC_E_NONE);
   4459 }
   4460 
   4461 /*
   4462  * Function:
   4463  *      phy_qsgmiie_control_get
   4464  * Purpose:
   4465  *      Get current control settings of the PHY. 
   4466  * Parameters:
   4467  *      unit  - BCM unit number.
   4468  *      port  - Port number. 
   4469  *      type  - Control to update 
   4470  *      value - (OUT) Current setting for the control 
   4471  * Returns:     
   4472  *      SOC_E_NONE
   4473  */
   4474 STATIC int
   4475 phy_qsgmiie_control_get(int unit, soc_port_t port, soc_phy_control_t type, uint32 *value)
   4476 {
   4477     int                 rv;
   4478     phy_ctrl_t          *pc;
   4479     soc_phymod_ctrl_t   *pmc;
   4480     qsgmiie_config_t       *pCfg;
   4481 
   4482     if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) {
   4483         return (SOC_E_PARAM);
   4484     }
   4485 
   4486     /* locate phy control */
   4487     pc = INT_PHY_SW_STATE(unit, port);
   4488     if (pc == NULL) {
   4489         return SOC_E_INTERNAL;
   4490     }
   4491 
   4492     pmc = &pc->phymod_ctrl;
   4493     pCfg = (qsgmiie_config_t *) pc->driver_data;
   4494 
   4495     switch(type) {
   4496 
   4497     /* PREEMPHASIS */
   4498     case SOC_PHY_CONTROL_PREEMPHASIS_LANE0:
   4499         rv = qsgmiie_per_lane_preemphasis_get(pmc, 0, value);
   4500         break;
   4501     case SOC_PHY_CONTROL_PREEMPHASIS_LANE1:
   4502         rv = qsgmiie_per_lane_preemphasis_get(pmc, 1, value);
   4503         break;
   4504     case SOC_PHY_CONTROL_PREEMPHASIS_LANE2:
   4505         rv = qsgmiie_per_lane_preemphasis_get(pmc, 2, value);
   4506         break;
   4507     case SOC_PHY_CONTROL_PREEMPHASIS_LANE3:
   4508         rv = qsgmiie_per_lane_preemphasis_get(pmc, 3, value);
   4509         break;
   4510     case SOC_PHY_CONTROL_TX_FIR_PRE:
   4511         /* assume they are all the same as lane 0 */
   4512         rv = qsgmiie_tx_fir_pre_get(pmc, value);
   4513         break;
   4514     case SOC_PHY_CONTROL_TX_FIR_MAIN:
   4515         /* assume they are all the same as lane 0 */
   4516         rv = qsgmiie_tx_fir_main_get(pmc, value);
   4517         break;
   4518     case SOC_PHY_CONTROL_TX_FIR_POST:
   4519         /* assume they are all the same as lane 0 */
   4520         rv = qsgmiie_tx_fir_post_get(pmc, value);
   4521         break;
   4522     case SOC_PHY_CONTROL_TX_FIR_POST2:
   4523         /* assume they are all the same as lane 0 */
   4524         rv = qsgmiie_tx_fir_post2_get(pmc, value);
   4525         break;
   4526     case SOC_PHY_CONTROL_TX_FIR_POST3:
   4527         /* assume they are all the same as lane 0 */
   4528         rv = qsgmiie_tx_fir_post3_get(pmc, value);
   4529         break;
   4530 
   4531     /* DRIVER CURRENT */
   4532     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE0:
   4533         rv = qsgmiie_per_lane_driver_current_get(pmc, 0, value);
   4534         break;
   4535     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE1:
   4536         rv = qsgmiie_per_lane_driver_current_get(pmc, 1, value);
   4537         break;
   4538     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE2:
   4539         rv = qsgmiie_per_lane_driver_current_get(pmc, 2, value);
   4540         break;
   4541     case SOC_PHY_CONTROL_DRIVER_CURRENT_LANE3:
   4542         rv = qsgmiie_per_lane_driver_current_get(pmc, 3, value);
   4543         break;
   4544     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   4545         rv = qsgmiie_per_lane_driver_current_get(pmc, 0, value);
   4546         break;
   4547 
   4548     /* PRE-DRIVER CURRENT */
   4549     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE0:
   4550         rv = SOC_E_UNAVAIL;
   4551         break;
   4552     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE1:
   4553         rv = SOC_E_UNAVAIL;
   4554         break;
   4555     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE2:
   4556         rv = SOC_E_UNAVAIL;
   4557         break;
   4558     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT_LANE3:
   4559         rv = SOC_E_UNAVAIL;
   4560         break;
   4561     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT:
   4562         rv = SOC_E_UNAVAIL;
   4563         break;
   4564 
   4565     /* POST2_DRIVER CURRENT */
   4566     case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT:
   4567         rv = SOC_E_UNAVAIL;
   4568         break;
   4569 
   4570     /* RX PEAK FILTER */
   4571     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   4572         rv = qsgmiie_rx_peak_filter_get(pmc, value);
   4573         break;
   4574 
   4575     /* RX VGA */
   4576     case SOC_PHY_CONTROL_RX_VGA:
   4577         rv = qsgmiie_rx_vga_get(pmc, value);
   4578         break;
   4579 
   4580     /* RX TAP */
   4581     case SOC_PHY_CONTROL_RX_TAP1:
   4582         rv = qsgmiie_rx_tap_get(pmc, 0, value);
   4583         break;
   4584     case SOC_PHY_CONTROL_RX_TAP2:
   4585         rv = qsgmiie_rx_tap_get(pmc, 1, value);
   4586         break;
   4587     case SOC_PHY_CONTROL_RX_TAP3:
   4588         rv = qsgmiie_rx_tap_get(pmc, 2, value);
   4589         break;
   4590     case SOC_PHY_CONTROL_RX_TAP4:
   4591         rv = qsgmiie_rx_tap_get(pmc, 3, value);
   4592         break;
   4593     case SOC_PHY_CONTROL_RX_TAP5:
   4594         rv = qsgmiie_rx_tap_get(pmc, 4, value);
   4595         break;
   4596 
   4597     /* RX SLICER */
   4598     case SOC_PHY_CONTROL_RX_PLUS1_SLICER:
   4599         rv = SOC_E_UNAVAIL;
   4600         break;
   4601     case SOC_PHY_CONTROL_RX_MINUS1_SLICER:
   4602         rv = SOC_E_UNAVAIL;
   4603         break;
   4604     case SOC_PHY_CONTROL_RX_D_SLICER:
   4605         rv = SOC_E_UNAVAIL;
   4606         break;
   4607 
   4608     /* PHASE INTERPOLATOR */
   4609     case SOC_PHY_CONTROL_PHASE_INTERP:
   4610         rv = qsgmiie_pi_control_get(pmc, value);
   4611         break;
   4612 
   4613     /* RX SIGNAL DETECT */
   4614     case SOC_PHY_CONTROL_RX_SIGNAL_DETECT:
   4615       rv = qsgmiie_rx_signal_detect_get(pmc, value);
   4616       break;
   4617     case SOC_PHY_CONTROL_RX_SEQ_DONE:
   4618       rv = qsgmiie_rx_seq_done_get(pmc, value);
   4619       break;
   4620     case SOC_PHY_CONTROL_RX_PPM:
   4621       rv = qsgmiie_rx_ppm_get(pmc, value);
   4622       break;
   4623 
   4624     /* CL72 */
   4625     case SOC_PHY_CONTROL_CL72:
   4626       rv = qsgmiie_cl72_enable_get(pmc, value);
   4627       break;
   4628     case SOC_PHY_CONTROL_CL72_STATUS:
   4629       rv = qsgmiie_cl72_status_get(pmc, value);
   4630       break;
   4631 
   4632     /* PRBS */
   4633     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_POLYNOMIAL:
   4634       rv = qsgmiie_prbs_tx_poly_get(pmc, value);
   4635       break;
   4636     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_INVERT_DATA:
   4637       rv = qsgmiie_prbs_tx_invert_data_get(pmc, value);
   4638       break;
   4639     case SOC_PHY_CONTROL_PRBS_DECOUPLED_TX_ENABLE:
   4640       rv = qsgmiie_prbs_tx_enable_get(pmc, value);
   4641       break;
   4642     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_POLYNOMIAL:
   4643       rv = qsgmiie_prbs_rx_poly_get(pmc, value);
   4644       break;
   4645     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_INVERT_DATA:
   4646       rv = qsgmiie_prbs_rx_invert_data_get(pmc, value);
   4647       break;
   4648     case SOC_PHY_CONTROL_PRBS_DECOUPLED_RX_ENABLE:
   4649       rv = qsgmiie_prbs_rx_enable_get(pmc, value);
   4650       break;
   4651     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   4652       rv = qsgmiie_prbs_tx_poly_get(pmc, value);
   4653       break;
   4654     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   4655       rv = qsgmiie_prbs_tx_invert_data_get(pmc, value);
   4656       break;
   4657     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   4658       rv = qsgmiie_prbs_tx_enable_get(pmc, value);
   4659       break;
   4660     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   4661       rv = qsgmiie_prbs_rx_enable_get(pmc, value);
   4662       break;
   4663     case SOC_PHY_CONTROL_PRBS_RX_STATUS:
   4664       rv = qsgmiie_prbs_rx_status_get(pmc, value);
   4665       break;
   4666 
   4667     /* LOOPBACK */
   4668     case SOC_PHY_CONTROL_LOOPBACK_REMOTE:
   4669        rv = qsgmiie_loopback_remote_get(pmc, value);
   4670        break;
   4671     case SOC_PHY_CONTROL_LOOPBACK_REMOTE_PCS_BYPASS:
   4672        rv = qsgmiie_loopback_remote_pcs_get(pmc, value);
   4673        break;
   4674     case SOC_PHY_CONTROL_LOOPBACK_PMD:
   4675        rv = qsgmiie_loopback_internal_pmd_get(pmc, value);
   4676        break;
   4677 
   4678     /* FEC */
   4679     case SOC_PHY_CONTROL_FORWARD_ERROR_CORRECTION:
   4680       rv = qsgmiie_fec_enable_get(pmc, value);
   4681       break;
   4682 
   4683     /* TX PATTERN */
   4684     case SOC_PHY_CONTROL_TX_PATTERN_256BIT:
   4685        rv = qsgmiie_pattern_get(pmc, &pCfg->pattern);
   4686       break;
   4687     case SOC_PHY_CONTROL_TX_PATTERN_LENGTH:
   4688        rv = qsgmiie_pattern_len_get(pmc, value);
   4689       break;
   4690     case SOC_PHY_CONTROL_TX_PATTERN_20BIT:
   4691        rv = qsgmiie_pattern_get(pmc, &pCfg->pattern);
   4692       break;
   4693 
   4694     /* SCRAMBLER */
   4695     case SOC_PHY_CONTROL_SCRAMBLER:
   4696        rv = qsgmiie_scrambler_get(pmc, port, value);
   4697        break;
   4698     case SOC_PHY_CONTROL_LANE_SWAP:
   4699         rv = qsgmiie_lane_map_get(pmc, value);
   4700         break;
   4701     /* UNAVAIL */
   4702 
   4703 #if 0
   4704     /* BERT */
   4705     case SOC_PHY_CONTROL_BERT_TX_PACKETS:       /* fall through */
   4706     case SOC_PHY_CONTROL_BERT_RX_PACKETS:       /* fall through */
   4707     case SOC_PHY_CONTROL_BERT_RX_ERROR_BITS:    /* fall through */
   4708     case SOC_PHY_CONTROL_BERT_RX_ERROR_BYTES:   /* fall through */
   4709     case SOC_PHY_CONTROL_BERT_RX_ERROR_PACKETS: /* fall through */
   4710     case SOC_PHY_CONTROL_BERT_PATTERN:          /* fall through */
   4711     case SOC_PHY_CONTROL_BERT_PACKET_SIZE:      /* fall through */
   4712     case SOC_PHY_CONTROL_BERT_IPG:              /* fall through */
   4713         rv = SOC_E_NONE;
   4714         break;
   4715 
   4716     /* CUSTOM */
   4717     case SOC_PHY_CONTROL_CUSTOM1:
   4718       /* Obsolete ??
   4719       *value = DEV_CFG_PTR(pc)->custom1;
   4720       rv = SOC_E_NONE; */
   4721       break;
   4722 
   4723     /* SOFTWARE RX LOS */
   4724     case SOC_PHY_CONTROL_SOFTWARE_RX_LOS:
   4725        /* Was 
   4726        *value = DEV_CFG_PTR(pc)->sw_rx_los.enable ; */
   4727        rv = SOC_E_NONE ;
   4728        break ;
   4729 
   4730     /* UNAVAIL */
   4731     case SOC_PHY_CONTROL_LINKDOWN_TRANSMIT:
   4732     case SOC_PHY_CONTROL_PARALLEL_DETECTION:
   4733        rv = SOC_E_UNAVAIL;
   4734        break;
   4735 #endif
   4736     default:
   4737         rv = SOC_E_UNAVAIL;
   4738         break; 
   4739     }
   4740     return rv;
   4741 }     
   4742 
   4743 /*
   4744  * Function:
   4745  *      phy_qsgmiie_per_lane_control_set
   4746  * Purpose:
   4747  *      Configure PHY device specific control fucntion. 
   4748  * Parameters:
   4749  *      unit  - StrataSwitch unit #.
   4750  *      port  - StrataSwitch port #. 
   4751  *      lane  - lane number
   4752  *      type  - Control to update 
   4753  *      value - New setting for the control 
   4754  * Returns:     
   4755  *      SOC_E_NONE
   4756  */
   4757 STATIC int
   4758 phy_qsgmiie_per_lane_control_set(int unit, soc_port_t port, int lane, soc_phy_control_t type, uint32 value)
   4759 {
   4760     int                 rv;
   4761     phy_ctrl_t          *pc;
   4762     soc_phymod_ctrl_t   *pmc;
   4763 
   4764     /* locate phy control, phymod control, and the configuration data */
   4765     pc = INT_PHY_SW_STATE(unit, port);
   4766     if (pc == NULL) {
   4767         return SOC_E_INTERNAL;
   4768     }
   4769     pmc = &pc->phymod_ctrl;
   4770 
   4771     if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) {
   4772         return SOC_E_PARAM;
   4773     }
   4774 
   4775     switch(type) {
   4776     case SOC_PHY_CONTROL_PREEMPHASIS:
   4777         rv = qsgmiie_per_lane_preemphasis_set(pmc, lane, value);
   4778         break; 
   4779     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   4780         rv = qsgmiie_per_lane_driver_current_set(pmc, lane, value);
   4781         break;
   4782     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT:
   4783         rv = SOC_E_UNAVAIL;
   4784         break;
   4785     case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT:
   4786         rv = SOC_E_UNAVAIL;
   4787         break;
   4788     case SOC_PHY_CONTROL_RX_TAP1:
   4789         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 0 /* tap */, 1 /* enable */, value);
   4790         break;
   4791     case SOC_PHY_CONTROL_RX_TAP1_RELEASE:
   4792         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 0 /* tap */, 0 /* release */, 0x8000);
   4793         break;
   4794     case SOC_PHY_CONTROL_RX_TAP2:
   4795         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 1 /* tap */, 1 /* enable */, value);
   4796         break;
   4797     case SOC_PHY_CONTROL_RX_TAP2_RELEASE:
   4798         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 1 /* tap */, 0 /* release */, 0x8000);
   4799         break;
   4800     case SOC_PHY_CONTROL_RX_TAP3:
   4801         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 2 /* tap */, 1 /* enable */, value);
   4802         break;
   4803     case SOC_PHY_CONTROL_RX_TAP3_RELEASE:
   4804         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 2 /* tap */, 0 /* release */, 0x8000);
   4805         break;
   4806     case SOC_PHY_CONTROL_RX_TAP4:
   4807         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 3 /* tap */, 1 /* enable */, value);
   4808         break;
   4809     case SOC_PHY_CONTROL_RX_TAP4_RELEASE:
   4810         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 3 /* tap */, 0 /* release */, 0x8000);
   4811         break;
   4812     case SOC_PHY_CONTROL_RX_TAP5:
   4813         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 4 /* tap */, 1 /* enable */, value);
   4814         break;
   4815     case SOC_PHY_CONTROL_RX_TAP5_RELEASE:
   4816         rv = qsgmiie_per_lane_rx_dfe_tap_control_set (pmc, lane, 4 /* tap */, 0 /* release */, 0x8000);
   4817         break;
   4818 
   4819     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   4820         rv = qsgmiie_per_lane_prbs_poly_set(pmc, lane, value);
   4821         break;
   4822     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   4823         rv = qsgmiie_per_lane_prbs_tx_invert_data_set(pmc, lane, value);
   4824         break;
   4825     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   4826         /* TX_ENABLE does both tx and rx */
   4827         rv = qsgmiie_per_lane_prbs_tx_enable_set(pmc, lane, value);
   4828         break; 
   4829     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   4830         rv = SOC_E_NONE;
   4831         break;
   4832     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   4833         rv = qsgmiie_per_lane_rx_peak_filter_set(pmc, lane, 1 /* enable */, value);
   4834         break;
   4835     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   4836         rv = qsgmiie_per_lane_rx_low_freq_filter_set(pmc, lane, value);
   4837         break;
   4838     case SOC_PHY_CONTROL_RX_VGA:
   4839         rv = qsgmiie_per_lane_rx_vga_set(pmc, lane, 1 /* enable */, value);
   4840         break;
   4841     case SOC_PHY_CONTROL_RX_VGA_RELEASE:
   4842         rv = qsgmiie_per_lane_rx_vga_set(pmc, lane, 0 /* release */, 0x8000);
   4843         break;
   4844     case SOC_PHY_CONTROL_RX_PLUS1_SLICER:
   4845         rv = SOC_E_UNAVAIL;
   4846         break; 
   4847     case SOC_PHY_CONTROL_RX_MINUS1_SLICER:
   4848         rv = SOC_E_UNAVAIL;
   4849         break; 
   4850     case SOC_PHY_CONTROL_RX_D_SLICER:
   4851         rv = SOC_E_UNAVAIL;
   4852         break;
   4853     default:
   4854         rv = SOC_E_UNAVAIL;
   4855         break; 
   4856     }
   4857 
   4858     return rv;
   4859 }
   4860 
   4861 /*
   4862  * Function:
   4863  *      phy_qsgmiie_per_lane_control_get
   4864  * Purpose:
   4865  *      Configure PHY device specific control fucntion. 
   4866  * Parameters:
   4867  *      unit  - StrataSwitch unit #.
   4868  *      port  - StrataSwitch port #. 
   4869  *      lane  - lane number
   4870  *      type  - Control to update 
   4871  *      value - New setting for the control 
   4872  * Returns:     
   4873  *      SOC_E_NONE
   4874  */
   4875 STATIC int
   4876 phy_qsgmiie_per_lane_control_get(int unit, soc_port_t port, int lane,
   4877                      soc_phy_control_t type, uint32 *value)
   4878 {
   4879     int                 rv;
   4880     phy_ctrl_t          *pc;
   4881     soc_phymod_ctrl_t   *pmc;
   4882 
   4883     /* locate phy control, phymod control, and the configuration data */
   4884     pc = INT_PHY_SW_STATE(unit, port);
   4885     if (pc == NULL) {
   4886         return SOC_E_INTERNAL;
   4887     }
   4888     pmc = &pc->phymod_ctrl;
   4889 
   4890     if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) {
   4891         return SOC_E_PARAM;
   4892     }
   4893 
   4894     switch(type) {
   4895 
   4896     case SOC_PHY_CONTROL_PREEMPHASIS:
   4897         rv = qsgmiie_per_lane_preemphasis_get(pmc, lane, value);
   4898         break; 
   4899     case SOC_PHY_CONTROL_DRIVER_CURRENT:
   4900         rv = qsgmiie_per_lane_driver_current_get(pmc, lane, value);
   4901         break;
   4902     case SOC_PHY_CONTROL_PRE_DRIVER_CURRENT:
   4903         rv = SOC_E_UNAVAIL;
   4904         break;
   4905     case SOC_PHY_CONTROL_DRIVER_POST2_CURRENT:
   4906         rv = SOC_E_UNAVAIL;
   4907         break;
   4908     case SOC_PHY_CONTROL_PRBS_POLYNOMIAL:
   4909         rv = qsgmiie_per_lane_prbs_poly_get(pmc, lane, value);
   4910         break;
   4911     case SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA:
   4912         rv = qsgmiie_per_lane_prbs_tx_invert_data_get(pmc, lane, value);
   4913         break;
   4914     case SOC_PHY_CONTROL_PRBS_TX_ENABLE:
   4915         rv = qsgmiie_per_lane_prbs_tx_enable_get(pmc, lane, value);
   4916         break;
   4917     case SOC_PHY_CONTROL_PRBS_RX_ENABLE:
   4918         rv = qsgmiie_per_lane_prbs_rx_enable_get(pmc, lane, value);
   4919         break;
   4920     case SOC_PHY_CONTROL_PRBS_RX_STATUS:
   4921         rv = qsgmiie_per_lane_prbs_rx_status_get(pmc, lane, value);
   4922         break;
   4923     case SOC_PHY_CONTROL_RX_PEAK_FILTER:
   4924         rv = qsgmiie_per_lane_rx_peak_filter_get(pmc, lane, value);
   4925         break;
   4926     case SOC_PHY_CONTROL_RX_VGA:
   4927         rv = qsgmiie_per_lane_rx_vga_get(pmc, lane, value);
   4928         break;
   4929     case SOC_PHY_CONTROL_RX_TAP1:
   4930         rv = qsgmiie_per_lane_rx_dfe_tap_control_get(pmc, lane, 0, value);
   4931         break;
   4932     case SOC_PHY_CONTROL_RX_TAP2:
   4933         rv = qsgmiie_per_lane_rx_dfe_tap_control_get(pmc, lane, 1, value);
   4934         break;
   4935     case SOC_PHY_CONTROL_RX_TAP3:
   4936         rv = qsgmiie_per_lane_rx_dfe_tap_control_get(pmc, lane, 2, value);
   4937         break;
   4938     case SOC_PHY_CONTROL_RX_TAP4:
   4939         rv = qsgmiie_per_lane_rx_dfe_tap_control_get(pmc, lane, 3, value);
   4940         break;
   4941     case SOC_PHY_CONTROL_RX_TAP5:
   4942         rv = qsgmiie_per_lane_rx_dfe_tap_control_get(pmc, lane, 4, value);
   4943         break;
   4944     case SOC_PHY_CONTROL_RX_LOW_FREQ_PEAK_FILTER:
   4945         rv = qsgmiie_per_lane_rx_low_freq_filter_get(pmc, lane, value);
   4946         break;
   4947     case SOC_PHY_CONTROL_RX_PLUS1_SLICER:
   4948         rv = SOC_E_UNAVAIL;
   4949         break; 
   4950     case SOC_PHY_CONTROL_RX_MINUS1_SLICER:
   4951         rv = SOC_E_UNAVAIL;
   4952         break; 
   4953     case SOC_PHY_CONTROL_RX_D_SLICER:
   4954         rv = SOC_E_UNAVAIL;
   4955         break; 
   4956     default:
   4957         rv = SOC_E_UNAVAIL;
   4958         break; 
   4959     }
   4960     return rv;
   4961 }
   4962 
   4963 /*
   4964  * Function:
   4965  *      phy_qsgmiie_reg_read
   4966  * Purpose:
   4967  *      Routine to read PHY register
   4968  * Parameters:
   4969  *      unit         - BCM unit number
   4970  *      port         - Port number
   4971  *      flags        - Flags which specify the register type
   4972  *      phy_reg_addr - Encoded register address
   4973  *      phy_data     - (OUT) Value read from PHY register
   4974  * Note:
   4975  *      This register read function is not thread safe. Higher level
   4976  * function that calls this function must obtain a per port lock
   4977  * to avoid overriding register page mapping between threads.
   4978  */
   4979 STATIC int
   4980 phy_qsgmiie_reg_read(int unit, soc_port_t port, uint32 flags,
   4981                   uint32 phy_reg_addr, uint32 *phy_reg_data)
   4982 {
   4983     phy_ctrl_t *pc;
   4984     soc_phymod_ctrl_t *pmc;
   4985     phymod_phy_access_t *pm_phy;
   4986 
   4987     pc = INT_PHY_SW_STATE(unit, port);
   4988     if (pc == NULL) {
   4989         return SOC_E_INTERNAL;
   4990     }
   4991 
   4992     pmc = &pc->phymod_ctrl;
   4993     pm_phy = &pmc->phy[0]->pm_phy;
   4994     SOC_IF_ERROR_RETURN
   4995         (phymod_phy_reg_read(pm_phy, phy_reg_addr, phy_reg_data));
   4996 
   4997     return SOC_E_NONE;
   4998 }
   4999 
   5000 /*
   5001  * Function:
   5002  *      phy_qsgmiie_reg_write
   5003  * Purpose:
   5004  *      Routine to write PHY register
   5005  * Parameters:
   5006  *      uint         - BCM unit number
   5007  *      pc           - PHY state
   5008  *      flags        - Flags which specify the register type
   5009  *      phy_reg_addr - Encoded register address
   5010  *      phy_data     - Value write to PHY register
   5011  * Note:
   5012  *      This register read function is not thread safe. Higher level
   5013  * function that calls this function must obtain a per port lock
   5014  * to avoid overriding register page mapping between threads.
   5015  */
   5016 STATIC int
   5017 phy_qsgmiie_reg_write(int unit, soc_port_t port, uint32 flags,
   5018                    uint32 phy_reg_addr, uint32 phy_reg_data)
   5019 {
   5020     phy_ctrl_t *pc;
   5021     soc_phymod_ctrl_t *pmc;
   5022     phymod_phy_access_t *pm_phy;
   5023     int idx;
   5024 
   5025     pc = INT_PHY_SW_STATE(unit, port);
   5026     if (pc == NULL) {
   5027         return SOC_E_INTERNAL;
   5028     }
   5029 
   5030     pmc = &pc->phymod_ctrl;
   5031     for (idx = 0; idx < pmc->num_phys; idx++) {
   5032         pm_phy = &pmc->phy[idx]->pm_phy;
   5033         SOC_IF_ERROR_RETURN
   5034             (phymod_phy_reg_write(pm_phy, phy_reg_addr, phy_reg_data));
   5035     }
   5036     return SOC_E_NONE;
   5037 }
   5038 
   5039 /*
   5040  * Function:
   5041  *      phy_qsgmiie_reg_modify
   5042  * Purpose:
   5043  *      Routine to write PHY register
   5044  * Parameters:
   5045  *      uint         - BCM unit number
   5046  *      pc           - PHY state
   5047  *      flags        - Flags which specify the register type
   5048  *      phy_reg_addr - Encoded register address
   5049  *      phy_mo_data  - New value for the bits specified in phy_mo_mask
   5050  *      phy_mo_mask  - Bit mask to modify
   5051  * Note:
   5052  *      This function is not thread safe. Higher level
   5053  * function that calls this function must obtain a per port lock
   5054  * to avoid overriding register page mapping between threads.
   5055  */
   5056 STATIC int
   5057 phy_qsgmiie_reg_modify(int unit, soc_port_t port, uint32 flags,
   5058                     uint32 phy_reg_addr, uint32 phy_data,
   5059                     uint32 phy_data_mask)
   5060 {
   5061     phy_ctrl_t *pc;
   5062     soc_phymod_ctrl_t *pmc;
   5063     phymod_phy_access_t *pm_phy;
   5064     uint32 data32, tmp;
   5065     int idx;
   5066 
   5067     pc = INT_PHY_SW_STATE(unit, port);
   5068     if (pc == NULL) {
   5069         return SOC_E_INTERNAL;
   5070     }
   5071 
   5072     pmc = &pc->phymod_ctrl;
   5073     for (idx = 0; idx < pmc->num_phys; idx++) {
   5074         pm_phy = &pmc->phy[idx]->pm_phy;
   5075         SOC_IF_ERROR_RETURN
   5076             (phymod_phy_reg_read(pm_phy, phy_reg_addr, &data32));
   5077         tmp = data32;
   5078         data32 &= ~(phy_data_mask);
   5079         data32 |= (phy_data & phy_data_mask);
   5080         if (data32 != tmp) {
   5081             SOC_IF_ERROR_RETURN
   5082                 (phymod_phy_reg_write(pm_phy, phy_reg_addr, data32));
   5083         }
   5084     }
   5085     return SOC_E_NONE;
   5086 }
   5087 
   5088 STATIC void
   5089 phy_qsgmiie_cleanup(soc_phymod_ctrl_t *pmc)
   5090 {
   5091     int idx;
   5092     soc_phymod_phy_t *phy;
   5093     soc_phymod_core_t *core;
   5094 
   5095     for (idx = 0; idx < pmc->num_phys ; idx++) {
   5096         phy = pmc->phy[idx];
   5097         if (phy == NULL) {
   5098             LOG_WARN(BSL_LS_SOC_PHY,
   5099                      (BSL_META_U(pmc->unit,
   5100                                  "phy object is empty")));
   5101             continue;
   5102         }
   5103 
   5104         core = phy->core;
   5105 
   5106         /* Destroy core object if not used anymore */
   5107         if (core && core->ref_cnt) {
   5108             if (--core->ref_cnt == 0) {
   5109                 soc_phymod_core_destroy(pmc->unit, core);
   5110             }
   5111         }
   5112 
   5113         /* Destroy phy object */
   5114         if (phy) {
   5115             soc_phymod_phy_destroy(pmc->unit, phy);
   5116         }
   5117     }
   5118     pmc->num_phys = 0;
   5119 }
   5120 
   5121 STATIC void
   5122 phy_qsgmiie_core_init(phy_ctrl_t *pc, soc_phymod_core_t *core,
   5123                    phymod_bus_t *core_bus, uint32 core_addr)
   5124 {
   5125     phymod_core_access_t *pm_core;
   5126     phymod_access_t *pm_acc;
   5127 
   5128     core->unit = pc->unit;
   5129     core->read = pc->read;
   5130     core->write = pc->write;
   5131     core->wrmask = pc->wrmask;
   5132     core->port = pc->port;
   5133 
   5134     pm_core = &core->pm_core;
   5135     phymod_core_access_t_init(pm_core);
   5136     pm_acc = &pm_core->access;
   5137     phymod_access_t_init(pm_acc);
   5138     PHYMOD_ACC_USER_ACC(pm_acc) = core;
   5139     PHYMOD_ACC_BUS(pm_acc) = core_bus;
   5140     PHYMOD_ACC_ADDR(pm_acc) = core_addr;
   5141 
   5142     if (soc_property_port_get(pc->unit, pc->port, "qsgmiie_sim", 0) == 45) {
   5143         PHYMOD_ACC_F_CLAUSE45_SET(pm_acc);
   5144     }
   5145 
   5146     return;
   5147 }
   5148 
   5149 /*
   5150  * Function:
   5151  *      phy_qsgmiie_probe
   5152  * Purpose:
   5153  *      xx
   5154  * Parameters:
   5155  *      pc->phy_id   (IN)
   5156  *      pc->unit     (IN)
   5157  *      pc->port     (IN)
   5158  *      pc->size     (OUT) - memory required by phy port
   5159  *      pc->dev_name (OUT) - set to port device name
   5160  *  
   5161  * Note:
   5162  */
   5163 STATIC int
   5164 phy_qsgmiie_probe(int unit, phy_ctrl_t *pc)
   5165 {
   5166     int rv, idx;
   5167     uint32 lane_map, num_phys, core_id, phy_id, found;
   5168     phymod_bus_t core_bus;
   5169     phymod_dispatch_type_t phy_type;
   5170     phymod_core_access_t *pm_core;
   5171     phymod_phy_access_t *pm_phy;
   5172     phymod_access_t *pm_acc;
   5173     soc_phymod_ctrl_t *pmc;
   5174     soc_phymod_phy_t *phy;
   5175     soc_phymod_core_t *core;
   5176     soc_phymod_core_t core_probe;
   5177     soc_info_t *si;
   5178     phyident_core_info_t core_info[8];  
   5179 #if 0  /* for QSGMII */
   5180     int array_max = 8;
   5181     int array_size = 0;
   5182 #endif
   5183     int port;
   5184     int phy_port;  /* physical port number */
   5185 
   5186     rv = 0;
   5187 
   5188     /* Initialize PHY bus */
   5189     SOC_IF_ERROR_RETURN(phymod_bus_t_init(&core_bus));
   5190     core_bus.bus_name = "qsgmiie_sim"; 
   5191     core_bus.read = _qsgmiie_reg_read; 
   5192     core_bus.write = _qsgmiie_reg_write;
   5193 
   5194     /* Configure PHY bus properties */
   5195     if (pc->wrmask) {
   5196         PHYMOD_BUS_CAP_WR_MODIFY_SET(&core_bus);
   5197         PHYMOD_BUS_CAP_LANE_CTRL_SET(&core_bus);
   5198     }
   5199 
   5200     port = pc->port;
   5201     pmc = &pc->phymod_ctrl;
   5202     si = &SOC_INFO(unit);
   5203     if (soc_feature(unit, soc_feature_logical_port_num)) {
   5204         phy_port = si->port_l2p_mapping[port];
   5205     } else {
   5206         phy_port = port;
   5207     }
   5208 
   5209     /* Install clean up function */
   5210     pmc->unit = pc->unit;
   5211     pmc->cleanup = phy_qsgmiie_cleanup;
   5212     pmc->symbols = &bcmi_qsgmiie_serdes_symbols;
   5213 
   5214     
   5215     if (SOC_IS_GREYHOUND(unit)) {
   5216         int i, blk;
   5217         blk = -1;
   5218         for (i=0; i< SOC_DRIVER(unit)->port_num_blktype; i++){
   5219             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   5220             if (PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), port)){
   5221                 break;
   5222             }
   5223         }
   5224         if (blk == -1) {
   5225             pc->chip_num = -1;
   5226             return SOC_E_NOT_FOUND;
   5227         } else {
   5228             pc->chip_num = SOC_BLOCK_NUMBER(unit, blk);
   5229         }
   5230         /* current lane number for QSGMII-Eagle is 0-15 */
   5231         pc->lane_num = (SOC_PORT_BINDEX(unit, phy_port) + 
   5232                 ((pc->chip_num > 0) ? 8 : 0)) % 16;
   5233     } else {
   5234         /* TBD for other chips */
   5235     }
   5236 
   5237     /* request memory for the configuration structure */
   5238     pc->size = sizeof(qsgmiie_config_t);
   5239 
   5240 #if 1  /* for QSGMMII only6 */
   5241     num_phys = 1;
   5242     pc->phy_mode = PHYCTRL_QSGMII_CORE_PORT;
   5243     lane_map = 1 << pc->lane_num;
   5244     core_info[0].mdio_addr = pc->phy_id;
   5245 #else
   5246     /* Bit N corresponds to lane N in lane_map */
   5247     lane_map = 0xf;
   5248     num_phys = 1;
   5249     switch (si->port_num_lanes[port]) {
   5250     case 10:
   5251         num_phys = 3;
   5252         break;
   5253     case 4:
   5254         break;
   5255     case 2:
   5256         lane_map = 0x3;
   5257         break;
   5258     case 1:
   5259     case 0:
   5260         lane_map = 0x1;
   5261         pc->phy_mode = PHYCTRL_QSGMII_CORE_PORT;
   5262         break;
   5263     default:
   5264         return SOC_E_CONFIG;
   5265     }
   5266     lane_map <<= pc->lane_num;
   5267 
   5268     /* we need to get the other core id if more than 1 core per port */
   5269     if (num_phys > 1) {
   5270         /* get the other core address */
   5271         SOC_IF_ERROR_RETURN
   5272             (soc_phy_addr_multi_get(unit, port, array_max, &array_size, &core_info[0]));
   5273     } else {
   5274         core_info[0].mdio_addr = pc->phy_id;
   5275     }
   5276 #endif
   5277 
   5278     phy_type = phymodDispatchTypeQsgmiie;
   5279 
   5280     /* Probe cores */
   5281     for (idx = 0; idx < num_phys ; idx++) {
   5282         phy_qsgmiie_core_init(pc, &core_probe, &core_bus,
   5283                            core_info[idx].mdio_addr);
   5284         /* Check that core is indeed an TSC/Eagle core */
   5285         pm_core = &core_probe.pm_core;
   5286         pm_core->type = phy_type;
   5287         rv = phymod_core_identify(pm_core, 0, &found);
   5288         if (SOC_FAILURE(rv)) {
   5289             return rv;
   5290         }
   5291         if (!found) {
   5292             return SOC_E_NOT_FOUND;
   5293         }
   5294     }
   5295 
   5296     for (idx = 0; idx < num_phys ; idx++) {
   5297         /* Set core and phy IDs based on PHY address */
   5298         core_id = pc->phy_id + idx;
   5299         phy_id = (lane_map << 16) | core_id;
   5300 
   5301         /* Create PHY object */
   5302         rv = soc_phymod_phy_create(unit, phy_id, &pmc->phy[idx]);
   5303         if (SOC_FAILURE(rv)) {
   5304             break;
   5305         }
   5306         pmc->num_phys++;
   5307 
   5308         /* Initialize phy object */
   5309         phy = pmc->phy[idx];
   5310         pm_phy = &phy->pm_phy;
   5311         phymod_phy_access_t_init(pm_phy);
   5312 
   5313         /* Find or create associated core object */
   5314         rv = soc_phymod_core_find_by_id(unit, core_id, &phy->core);
   5315         if (rv == SOC_E_NOT_FOUND) {
   5316             rv = soc_phymod_core_create(unit, core_id, &phy->core);
   5317         }
   5318         if (SOC_FAILURE(rv)) {
   5319             break;
   5320         }
   5321     }
   5322     if (SOC_FAILURE(rv)) {
   5323         phy_qsgmiie_cleanup(pmc);
   5324         return rv;
   5325     }
   5326 
   5327     for (idx = 0; idx < pmc->num_phys ; idx++) {
   5328         phy = pmc->phy[idx];
   5329         core = phy->core;
   5330         pm_core = &core->pm_core;
   5331 
   5332         /* Initialize core object if newly created */
   5333         if (core->ref_cnt == 0) {
   5334             sal_memcpy(&core->pm_bus, &core_bus, sizeof(core->pm_bus));
   5335             phy_qsgmiie_core_init(pc, core, &core->pm_bus,
   5336                                core_info[idx].mdio_addr);
   5337             /* Set dispatch type */
   5338             pm_core->type = phy_type;
   5339         }
   5340         core->ref_cnt++;
   5341 
   5342         /* Initialize phy access based on associated core */
   5343         pm_acc = &phy->pm_phy.access;
   5344         sal_memcpy(pm_acc, &pm_core->access, sizeof(*pm_acc));
   5345         phy->pm_phy.type = phy_type;
   5346         PHYMOD_ACC_LANE_MASK(pm_acc) = lane_map;
   5347     }
   5348 
   5349     return SOC_E_NONE;
   5350 }
   5351 
   5352 
   5353 /***********************************************************************
   5354  *
   5355  * PASS-THROUGH NOTIFY ROUTINES
   5356  */
   5357 
   5358 /*
   5359  * Function:
   5360  *      _qsgmiie_notify_duplex
   5361  * Purpose:
   5362  *      Program duplex if (and only if) serdesqsgmiie is an intermediate PHY.
   5363  * Parameters:
   5364  *      unit - BCM unit number.
   5365  *      port - Port number.
   5366  *      duplex - Boolean, TRUE indicates full duplex, FALSE
   5367  *              indicates half.
   5368  * Returns:
   5369  *      SOC_E_XXX
   5370  * Notes:
   5371  *      If PHY_FLAGS_FIBER is set, it indicates the PHY is being used to
   5372  *      talk directly to an external fiber module.
   5373  *
   5374  *      If PHY_FLAGS_FIBER is clear, the PHY is being used in
   5375  *      pass-through mode to talk to an external SGMII PHY.
   5376  *
   5377  *      When used in pass-through mode, autoneg must be turned off and
   5378  *      the speed/duplex forced to match that of the external PHY.
   5379  */
   5380 
   5381 STATIC int
   5382 _qsgmiie_notify_duplex(int unit, soc_port_t port, uint32 duplex)
   5383 {
   5384     return SOC_E_NONE;
   5385 }
   5386 
   5387 /*
   5388  * Function:
   5389  *      _qsgmiie_stop
   5390  * Purpose:
   5391  *      Put serdesqsgmiie SERDES in or out of reset depending on conditions
   5392  */
   5393 
   5394 STATIC int
   5395 _qsgmiie_stop(int unit, soc_port_t port)
   5396 {
   5397     phy_ctrl_t* pc; 
   5398     soc_phymod_ctrl_t *pmc;
   5399     phymod_phy_access_t *pm_phy;
   5400     phymod_phy_power_t phy_power;
   5401     int  stop, copper;
   5402 
   5403     pc = INT_PHY_SW_STATE(unit, port);
   5404     pmc = &pc->phymod_ctrl;
   5405     pm_phy = &pmc->phy[0]->pm_phy;
   5406 
   5407     copper = (pc->stop &
   5408               PHY_STOP_COPPER) != 0;
   5409 
   5410     stop = ((pc->stop &
   5411              (PHY_STOP_PHY_DIS |
   5412               PHY_STOP_DRAIN)) != 0 ||
   5413             (copper &&
   5414              (pc->stop &
   5415               (PHY_STOP_MAC_DIS |
   5416                PHY_STOP_DUPLEX_CHG |
   5417                PHY_STOP_SPEED_CHG)) != 0));
   5418 
   5419     LOG_INFO(BSL_LS_SOC_PHY,
   5420              (BSL_META_U(pc->unit,
   5421                          "qsgmiie_stop: u=%d p=%d copper=%d stop=%d flg=0x%x\n"),
   5422               unit, port, copper, stop,
   5423               pc->stop));
   5424     if (stop) {
   5425         phy_power.tx = phymodPowerOff;
   5426         phy_power.rx = phymodPowerOff;
   5427     } else {
   5428         phy_power.tx = phymodPowerOn;
   5429         phy_power.rx = phymodPowerOn;
   5430     }
   5431     SOC_IF_ERROR_RETURN
   5432         (phymod_phy_power_set(pm_phy, &phy_power));
   5433     return SOC_E_NONE;
   5434 }
   5435 
   5436 /*
   5437  * Function:
   5438  *      _qsgmiie_notify_stop
   5439  * Purpose:
   5440  *      Add a reason to put serdesqsgmiie PHY in reset.
   5441  * Parameters:
   5442  *      unit - BCM unit number.
   5443  *      port - Port number.
   5444  *      flags - Reason to stop
   5445  * Returns:     
   5446  *      SOC_E_XXX
   5447  */
   5448 
   5449 STATIC int
   5450 _qsgmiie_notify_stop(int unit, soc_port_t port, uint32 flags)
   5451 {
   5452     INT_PHY_SW_STATE(unit, port)->stop |= flags;
   5453     return _qsgmiie_stop(unit, port);
   5454 }
   5455 
   5456 /*  
   5457  * Function:
   5458  *      _qsgmiie_notify_resume
   5459  * Purpose:
   5460  *      Remove a reason to put serdesqsgmiie PHY in reset.
   5461  * Parameters:
   5462  *      unit - BCM unit number.
   5463  *      port - Port number.
   5464  *      flags - Reason to stop
   5465  * Returns:     
   5466  *      SOC_E_XXX
   5467  */
   5468 
   5469 STATIC int
   5470 _qsgmiie_notify_resume(int unit, soc_port_t port, uint32 flags)
   5471 {   
   5472     INT_PHY_SW_STATE(unit, port)->stop &= ~flags;
   5473     return _qsgmiie_stop(unit, port);
   5474 }
   5475 
   5476 /*
   5477  * Function:
   5478  *      _qsgmiie_notify_speed
   5479  * Purpose:
   5480  *      Program duplex if (and only if) serdesqsgmiie is an intermediate PHY.
   5481  * Parameters:
   5482  *      unit - BCM unit number.
   5483  *      port - Port number.
   5484  *      speed - Speed to program.
   5485  * Returns:
   5486  *      SOC_E_XXX
   5487  * Notes:
   5488  *      If PHY_FLAGS_FIBER is set, it indicates the PHY is being used to
   5489  *      talk directly to an external fiber module.
   5490  *
   5491  *      If PHY_FLAGS_FIBER is clear, the PHY is being used in
   5492  *      pass-through mode to talk to an external SGMII PHY.
   5493  *
   5494  *      When used in pass-through mode, autoneg must be turned off and
   5495  *      the speed/duplex forced to match that of the external PHY.
   5496  */
   5497 
   5498 STATIC int
   5499 _qsgmiie_notify_speed(int unit, soc_port_t port, uint32 speed)
   5500 {
   5501     phy_ctrl_t* pc; 
   5502     qsgmiie_config_t *pCfg;
   5503     int  fiber;
   5504 
   5505     pc = INT_PHY_SW_STATE(unit, port);
   5506     pCfg = (qsgmiie_config_t *) pc->driver_data;
   5507     fiber = pCfg->fiber_pref;
   5508 
   5509     LOG_INFO(BSL_LS_SOC_PHY,
   5510              (BSL_META_U(pc->unit,
   5511                          "_qsgmiie_notify_speed: "
   5512                          "u=%d p=%d speed=%d fiber=%d\n"),
   5513               unit, port, speed, fiber));
   5514 
   5515     if (SAL_BOOT_SIMULATION) {
   5516         return SOC_E_NONE;
   5517     }
   5518 
   5519     /* Put SERDES PHY in reset */
   5520     SOC_IF_ERROR_RETURN
   5521         (_qsgmiie_notify_stop(unit, port, PHY_STOP_SPEED_CHG));
   5522 
   5523     /* Update speed */
   5524     SOC_IF_ERROR_RETURN
   5525         (phy_qsgmiie_speed_set(unit, port, speed));
   5526 
   5527     /* Take SERDES PHY out of reset */
   5528     SOC_IF_ERROR_RETURN
   5529         (_qsgmiie_notify_resume(unit, port, PHY_STOP_SPEED_CHG));
   5530 
   5531     return SOC_E_NONE;
   5532 }
   5533 
   5534 /*
   5535  * Function:
   5536  *      qsgmiie_media_setup
   5537  * Purpose:     
   5538  *      Configure 
   5539  * Parameters:
   5540  *      unit - BCM unit number.
   5541  *      port - Port number.
   5542  *      fiber_mode - Configure for fiber mode
   5543  *      fiber_pref - Fiber preferrred (if fiber mode)
   5544  * Returns:     
   5545  *      SOC_E_XXX
   5546  */
   5547 STATIC int
   5548 _qsgmiie_notify_interface(int unit, soc_port_t port, uint32 intf)
   5549 {
   5550     return SOC_E_NONE;
   5551 }
   5552 
   5553 /*
   5554  * Function:
   5555  *      _qsgmiie_notify_mac_loopback
   5556  * Purpose:
   5557  *      Turn on rx clock compensation in mac loopback mode for
   5558  *      applicable XGXS devices
   5559  * Parameters:
   5560  *      unit - BCM unit number.
   5561  *      port - Port number.
   5562  *      enable - TRUE: In MAC loopback mode, FALSE: Not in MAC loopback mode 
   5563  * Returns:
   5564  *      SOC_E_XXX
   5565  */
   5566 STATIC int
   5567 _qsgmiie_notify_mac_loopback(int unit, soc_port_t port, uint32 enable)
   5568 {
   5569     return SOC_E_NONE;
   5570 }
   5571 
   5572 STATIC int
   5573 phy_qsgmiie_notify(int unit, soc_port_t port,
   5574                        soc_phy_event_t event, uint32 value)
   5575 {
   5576     int             rv;
   5577     rv = SOC_E_NONE ;
   5578 
   5579     if (event >= phyEventCount) {
   5580         return SOC_E_PARAM;
   5581     }
   5582 
   5583     switch(event) {
   5584     case phyEventInterface:
   5585         rv = (_qsgmiie_notify_interface(unit, port, value));
   5586         break;
   5587     case phyEventDuplex:
   5588         rv = (_qsgmiie_notify_duplex(unit, port, value));
   5589         break;
   5590     case phyEventSpeed:
   5591         rv = (_qsgmiie_notify_speed(unit, port, value));
   5592         break;
   5593     case phyEventStop:
   5594         rv = (_qsgmiie_notify_stop(unit, port, value));
   5595         break;
   5596     case phyEventResume:
   5597         rv = (_qsgmiie_notify_resume(unit, port, value));
   5598         break;
   5599     case phyEventAutoneg:
   5600 #if 0
   5601         rv = (_qsgmiie_an_set(unit, port, value));
   5602 #endif
   5603         break;
   5604     case phyEventMacLoopback:
   5605         rv = (_qsgmiie_notify_mac_loopback(unit, port, value));
   5606         break;
   5607     case phyEventLpiBypass:
   5608         rv = phy_qsgmiie_control_set(unit, port, SOC_PHY_CONTROL_EEE, value);
   5609         break;
   5610     default:
   5611         rv = SOC_E_UNAVAIL;
   5612         break;
   5613     }
   5614 
   5615     return rv;
   5616 }
   5617 
   5618 /*
   5619  * Function:
   5620  *      phy_qsgmiie_diag_ctrl
   5621  * Purpose:
   5622  *      xx
   5623  * Parameters:
   5624  *      unit - BCM unit number.
   5625  *      port - Port number. 
   5626 
   5627  * Returns:     
   5628  *      SOC_E_NONE
   5629  */
   5630 
   5631 STATIC int
   5632 phy_qsgmiie_diag_ctrl(
   5633     int unit,        /* unit */
   5634     soc_port_t port, /* port */
   5635     uint32 inst,     /* the specific device block the control action directs to */
   5636     int op_type,     /* operation types: read,write or command sequence */
   5637     int op_cmd,      /* command code */
   5638     void *arg)       /* command argument based on op_type/op_cmd */
   5639 {
   5640     switch(op_cmd) {
   5641         case PHY_DIAG_CTRL_DSC:
   5642             LOG_INFO(BSL_LS_SOC_PHY,
   5643                      (BSL_META_U(unit,
   5644                                  "phy_tscmod_diag_ctrl: "
   5645                                  "u=%d p=%d PHY_DIAG_CTRL_DSC 0x%x\n"),
   5646                       unit, port, PHY_DIAG_CTRL_DSC));
   5647             SOC_IF_ERROR_RETURN(qsgmiie_uc_status_dump(unit, port));
   5648             break;
   5649         default:
   5650             if (op_type == PHY_DIAG_CTRL_SET) {
   5651                 SOC_IF_ERROR_RETURN(phy_qsgmiie_control_set(unit,port,op_cmd,PTR_TO_INT(arg)));
   5652             } else if (op_type == PHY_DIAG_CTRL_GET) {
   5653                 SOC_IF_ERROR_RETURN(phy_qsgmiie_control_get(unit,port,op_cmd,(uint32 *)arg));
   5654             }
   5655             break ;
   5656         }
   5657     return (SOC_E_NONE);
   5658 }
   5659 
   5660 
   5661 #ifdef BROADCOM_DEBUG
   5662 void
   5663 qsgmiie_state_dump(int unit, soc_port_t port)
   5664 {
   5665     /* Show PHY configuration summary */
   5666     /* Lane status */
   5667     /* Show Counters */
   5668     /* Dump Registers */
   5669 }
   5670 #endif /* BROADCOM_DEBUG */
   5671 
   5672 /*
   5673  * Variable:
   5674  *      qsgmiie_drv
   5675  * Purpose:
   5676  *      Phy Driver for TSC/Eagle 
   5677  */
   5678 phy_driver_t phy_qsgmiie_drv = {
   5679     /* .drv_name                      = */ "TSC/Eagle PHYMOD PHY Driver",
   5680     /* .pd_init                       = */ phy_qsgmiie_init,
   5681     /* .pd_reset                      = */ phy_null_reset,
   5682     /* .pd_link_get                   = */ phy_qsgmiie_link_get,
   5683     /* .pd_enable_set                 = */ phy_qsgmiie_enable_set,
   5684     /* .pd_enable_get                 = */ phy_qsgmiie_enable_get,
   5685     /* .pd_duplex_set                 = */ phy_null_set,
   5686     /* .pd_duplex_get                 = */ phy_qsgmiie_duplex_get,
   5687     /* .pd_speed_set                  = */ phy_qsgmiie_speed_set,
   5688     /* .pd_speed_get                  = */ phy_qsgmiie_speed_get,
   5689     /* .pd_master_set                 = */ phy_null_set,
   5690     /* .pd_master_get                 = */ phy_null_zero_get,
   5691     /* .pd_an_set                     = */ phy_qsgmiie_an_set,
   5692     /* .pd_an_get                     = */ phy_qsgmiie_an_get,
   5693     /* .pd_adv_local_set              = */ NULL, /* Deprecated */
   5694     /* .pd_adv_local_get              = */ NULL, /* Deprecated */
   5695     /* .pd_adv_remote_get             = */ NULL, /* Deprecated */ 
   5696     /* .pd_lb_set                     = */ phy_qsgmiie_lb_set,
   5697     /* .pd_lb_get                     = */ phy_qsgmiie_lb_get,
   5698     /* .pd_interface_set              = */ phy_null_interface_set,
   5699     /* .pd_interface_get              = */ phy_null_interface_get,
   5700     /* .pd_ability                    = */ NULL, /* Deprecated */ 
   5701     /* .pd_linkup_evt                 = */ NULL,
   5702     /* .pd_linkdn_evt                 = */ NULL,
   5703     /* .pd_mdix_set                   = */ phy_null_mdix_set,
   5704     /* .pd_mdix_get                   = */ phy_null_mdix_get,
   5705     /* .pd_mdix_status_get            = */ phy_null_mdix_status_get,
   5706     /* .pd_medium_config_set          = */ NULL,
   5707     /* .pd_medium_config_get          = */ NULL,
   5708     /* .pd_medium_get                 = */ phy_null_medium_get,
   5709     /* .pd_cable_diag                 = */ NULL,
   5710     /* .pd_link_change                = */ NULL,
   5711     /* .pd_control_set                = */ phy_qsgmiie_control_set,
   5712     /* .pd_control_get                = */ phy_qsgmiie_control_get,
   5713     /* .pd_reg_read                   = */ phy_qsgmiie_reg_read,
   5714     /* .pd_reg_write                  = */ phy_qsgmiie_reg_write,
   5715     /* .pd_reg_modify                 = */ phy_qsgmiie_reg_modify,
   5716     /* .pd_notify                     = */ phy_qsgmiie_notify,
   5717     /* .pd_probe                      = */ phy_qsgmiie_probe,
   5718     /* .pd_ability_advert_set         = */ phy_qsgmiie_ability_advert_set, 
   5719     /* .pd_ability_advert_get         = */ phy_qsgmiie_ability_advert_get,
   5720     /* .pd_ability_remote_get         = */ phy_qsgmiie_ability_remote_get,
   5721     /* .pd_ability_local_get          = */ phy_qsgmiie_ability_local_get,
   5722     /* .pd_firmware_set               = */ NULL,
   5723     /* .pd_timesync_config_set        = */ NULL,
   5724     /* .pd_timesync_config_get        = */ NULL,
   5725     /* .pd_timesync_control_set       = */ NULL,
   5726     /* .pd_timesync_control_set       = */ NULL,
   5727     /* .pd_diag_ctrl                  = */ phy_qsgmiie_diag_ctrl,
   5728     /* .pd_lane_control_set           = */ phy_qsgmiie_per_lane_control_set,    
   5729     /* .pd_lane_control_get           = */ phy_qsgmiie_per_lane_control_get
   5730 };
   5731 
   5732 #else
   5733 int _qsgmiie_not_empty;
   5734 #endif /*  INCLUDE_SERDES_QSGMIIE */
   5735