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

phy84749.c (54433B)


      1 /*
      2  * 
      3  *
      4  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      5  * 
      6  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      7  */
      8 
      9 /*
     10  * File:        phy84749.c
     11  * Purpose:     SDK PHY driver for BCM84749 (MACSec)
     12  *
     13  * Supported BCM546X Family of PHY devices:
     14  *
     15  *      Device  Ports   Media                           MAC Interface
     16  *      84749    4       2 10G SFP+, 2 1G SFP            XFI
     17  *
     18  * Workarounds:
     19  *
     20  * References:
     21  *     
     22  * Notes:
     23  */ 
     24 
     25 
     26 #include <sal/types.h>
     27 #include <sal/core/spl.h>
     28 #include <shared/bsl.h>
     29 #include <soc/drv.h>
     30 #include <soc/debug.h>
     31 #include <soc/error.h>
     32 #include <soc/phyreg.h>
     33 
     34 #include <soc/phy.h>
     35 #include <soc/phy/phyctrl.h>
     36 #include <soc/phy/drv.h>
     37 
     38 #include "phydefs.h"      /* Must include before other phy related includes */
     39 
     40 
     41 
     42 #if defined(INCLUDE_MACSEC)
     43 #if defined(INCLUDE_PHY_84749)
     44 #include "phyconfig.h"    /* Must be the first phy include after phydefs.h */
     45 #include "phyident.h"
     46 #include "phyreg.h"
     47 #include "phynull.h"
     48 #include "phyfege.h"
     49 #include "phyxehg.h"
     50 #include "phy84749.h"
     51 
     52 #include <soc/macsecphy.h>
     53 #include <bmacsec.h>
     54 #include <bmacsec_io.h>
     55 
     56 
     57 #define ADVERT_ALL_COPPER \
     58         (SOC_PA_PAUSE | SOC_PA_SPEED_10MB | \
     59          SOC_PA_SPEED_100MB | SOC_PA_SPEED_1000MB)
     60 
     61 #define ADVERT_ALL_FIBER \
     62         (SOC_PA_PAUSE | SOC_PA_SPEED_1000MB) 
     63 
     64 #define ADVERT_ALL_10GFIBER \
     65         (SOC_PA_PAUSE | SOC_PA_SPEED_10GB) 
     66 
     67 
     68 static bmacsec_error_t error_tbl[] = {
     69                                 SOC_E_NONE,
     70                                 SOC_E_INTERNAL,
     71                                 SOC_E_MEMORY,
     72                                 SOC_E_PARAM,
     73                                 SOC_E_EMPTY,
     74                                 SOC_E_FULL,
     75                                 SOC_E_NOT_FOUND,
     76                                 SOC_E_EXISTS,
     77                                 SOC_E_TIMEOUT,
     78                                 SOC_E_FAIL,
     79                                 SOC_E_DISABLED,
     80                                 SOC_E_BADID,
     81                                 SOC_E_RESOURCE,
     82                                 SOC_E_CONFIG,
     83                                 SOC_E_UNAVAIL,
     84                                 SOC_E_INIT,
     85                                 SOC_E_PORT,
     86                             };
     87 /*
     88  * Convert BMACSEC return codes to SOC return code.
     89  */
     90 #define SOC_ERROR(e)    error_tbl[(-e)]
     91 
     92 #define PHY84749_REG_READ(_unit, _phy_ctrl, _addr, _val) \
     93             READ_PHY_REG((_unit), (_phy_ctrl), (_addr), (_val))
     94 
     95 #define READ_PHY84749_PMA_PMD_REG(_unit, _phy_ctrl, _reg,_val) \
     96             PHY84749_REG_READ((_unit), (_phy_ctrl), \
     97               SOC_PHY_CLAUSE45_ADDR(1, (_reg)), (_val))
     98 
     99 
    100 STATIC int phy_84749_init(int unit, soc_port_t port);
    101 STATIC int phy_84749_link_get(int unit, soc_port_t port, int *link);
    102 STATIC int phy_84749_enable_set(int unit, soc_port_t port, int enable);
    103 STATIC int phy_84749_duplex_set(int unit, soc_port_t port, int duplex);
    104 STATIC int phy_84749_duplex_get(int unit, soc_port_t port, int *duplex);
    105 STATIC int phy_84749_speed_set(int unit, soc_port_t port, int speed);
    106 STATIC int phy_84749_speed_get(int unit, soc_port_t port, int *speed);
    107 #if 0
    108 STATIC int phy_84749_master_set(int unit, soc_port_t port, int master);
    109 STATIC int phy_84749_master_get(int unit, soc_port_t port, int *master);
    110 #endif
    111 STATIC int phy_84749_an_set(int unit, soc_port_t port, int autoneg);
    112 STATIC int phy_84749_an_get(int unit, soc_port_t port,
    113                                 int *autoneg, int *autoneg_done);
    114 STATIC int phy_84749_lb_set(int unit, soc_port_t port, int enable);
    115 STATIC int phy_84749_lb_get(int unit, soc_port_t port, int *enable);
    116 STATIC int phy_84749_medium_config_set(int unit, soc_port_t port, 
    117                                       soc_port_medium_t  medium,
    118                                       soc_phy_config_t  *cfg);
    119 STATIC int phy_84749_medium_config_get(int unit, soc_port_t port, 
    120                                       soc_port_medium_t medium,
    121                                       soc_phy_config_t *cfg);
    122 STATIC int phy_84749_ability_advert_set(int unit, soc_port_t port, 
    123                                        soc_port_ability_t *ability);
    124 STATIC int phy_84749_ability_advert_get(int unit, soc_port_t port,
    125                                        soc_port_ability_t *ability);
    126 STATIC int phy_84749_ability_remote_get(int unit, soc_port_t port,
    127                                        soc_port_ability_t *ability);
    128 STATIC int phy_84749_ability_local_get(int unit, soc_port_t port, 
    129                                 soc_port_ability_t *ability);
    130 STATIC int phy_84749_firmware_set(int unit, int port, int offset, 
    131                                  uint8 *data, int len);
    132 STATIC int phy_84749_control_set(int unit, soc_port_t port,
    133                      soc_phy_control_t type, uint32 value);
    134 STATIC int phy_84749_control_get(int unit, soc_port_t port,
    135                      soc_phy_control_t type, uint32 *value);
    136 STATIC int phy_84749_linkup(int unit, soc_port_t port);
    137 
    138 /*
    139  * Function:
    140  *      _phy_84749_medium_config_update
    141  * Purpose:
    142  *      Update the PHY with config parameters
    143  * Parameters:
    144  *      unit - StrataSwitch unit #.
    145  *      port - StrataSwitch port #.
    146  *      cfg - Config structure.
    147  * Returns:
    148  *      SOC_E_XXX
    149  */
    150 
    151 STATIC int
    152 _phy_84749_medium_config_update(int unit, soc_port_t port,
    153                                 soc_phy_config_t *cfg)
    154 {
    155 
    156     SOC_IF_ERROR_RETURN
    157         (phy_84749_speed_set(unit, port, cfg->force_speed));
    158     SOC_IF_ERROR_RETURN
    159         (phy_84749_duplex_set(unit, port, cfg->force_duplex));
    160     SOC_IF_ERROR_RETURN
    161         (phy_84749_ability_advert_set(unit, port, &cfg->advert_ability));
    162     SOC_IF_ERROR_RETURN
    163         (phy_84749_an_set(unit, port, cfg->autoneg_enable));
    164 
    165     return SOC_E_NONE;
    166 }
    167 
    168 /* Function:
    169  *    phy_84749_init
    170  * Purpose:    
    171  *    Initialize 84749 phys
    172  * Parameters:
    173  *    unit - StrataSwitch unit #.
    174  *    port - StrataSwitch port #. 
    175  * Returns:    
    176  *    SOC_E_NONE
    177  */
    178 
    179 STATIC int
    180 phy_84749_init(int unit, soc_port_t port)
    181 {
    182     phy_ctrl_t     *pc;
    183     bmacsec_dev_addr_t phy_dev_addr;
    184     bmacsec_dev_addr_t macsec_dev_addr;
    185     int line_mode;
    186     int fiber_preferred;
    187     int rv = SOC_E_NONE;
    188     int macsec_enable = 0, mmi_mdio_addr;
    189     int phy_ext_rom_boot;
    190     uint32 phy_sys_xaui_tx_lane_map;
    191     uint32 phy_sys_xaui_rx_lane_map;
    192     char *str;
    193     uint16 temp;
    194 
    195     pc     = EXT_PHY_SW_STATE(unit, port);
    196 
    197     macsec_dev_addr = 0;
    198 
    199     /* By default MACSEC is disable */
    200     /* Check if enable property is set */
    201     macsec_enable = soc_property_port_get(unit, port, spn_MACSEC_ENABLE, 0);
    202     pc->macsec_enable = macsec_enable;
    203 
    204     pc->macsec_dev_port = soc_property_port_get(unit, port, 
    205                                        spn_MACSEC_PORT_INDEX, -1);
    206     phy_dev_addr    = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1); 
    207 
    208     /* Base PHY ID is used to access MACSEC core */
    209     mmi_mdio_addr = soc_property_port_get(unit, port, 
    210                                         spn_MACSEC_DEV_ADDR, -1);
    211     if (mmi_mdio_addr < 0) {
    212         LOG_WARN(BSL_LS_SOC_PHY,
    213                  (BSL_META_U(unit,
    214                              "phy_84749_init: "
    215                              "MACSEC_DEV_ADDR property "
    216                              "not configured for u=%d p=%d\n"), unit, port));
    217         return SOC_E_CONFIG;
    218     }
    219 
    220     macsec_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, mmi_mdio_addr, 1);
    221     pc->macsec_dev_addr = macsec_dev_addr;
    222 
    223     rv = bmacsec_phy84749_phy_mac_addr_set(phy_dev_addr, 
    224                                           macsec_dev_addr, 
    225                                           pc->macsec_dev_port,
    226                                           bmacsec_io_mmi1_cl45);
    227 
    228 
    229     if(rv != BMACSEC_E_NONE) {
    230         LOG_WARN(BSL_LS_SOC_PHY,
    231                  (BSL_META_U(unit,
    232                              "phy_84749_init: bmacsec_phy_mac_addr_set "
    233                              "returned error for u=%d p=%d\n"), unit, port));
    234         return SOC_E_FAIL;
    235     }
    236 
    237     phy_ext_rom_boot = soc_property_port_get(unit, port,
    238                                             spn_PHY_EXT_ROM_BOOT, 1);
    239 
    240     LOG_INFO(BSL_LS_SOC_PHY,
    241              (BSL_META_U(unit,
    242                          "phy_84749_init: u=%d p=%d\n"),unit, port));
    243 
    244     /* Preferred mode:
    245      * phy_fiber_pref = 1 ; Port is in SFI mode in 10G Default
    246      *                      when speed is changed to 1G, its 1000X
    247      * phy_fiber_pref = 0; Port is in SGMII mode, allows only 1G/100M/10M
    248      */
    249     fiber_preferred =
    250         soc_property_port_get(unit, port, spn_PHY_FIBER_PREF, 1);
    251 
    252     /* Initially configure for the preferred medium. */
    253     PHY_FLAGS_CLR(unit, port, PHY_FLAGS_COPPER);
    254     PHY_FLAGS_CLR(unit, port, PHY_FLAGS_FIBER);
    255     PHY_FLAGS_CLR(unit, port, PHY_FLAGS_PASSTHRU);
    256     PHY_FLAGS_CLR(unit, port, PHY_FLAGS_100FX);
    257 
    258     if (fiber_preferred) {
    259         line_mode = BMACSEC_PHY84749_INTF_SFI;
    260         pc->copper.enable = FALSE;
    261         pc->fiber.enable = TRUE;
    262         pc->interface = SOC_PORT_IF_XFI;
    263         PHY_FLAGS_SET(unit, port, PHY_FLAGS_FIBER);
    264     } else {
    265         pc->interface = SOC_PORT_IF_SGMII;
    266         line_mode = BMACSEC_PHY84749_INTF_SGMII;
    267         pc->copper.enable = TRUE;
    268         pc->fiber.enable = FALSE;
    269         PHY_FLAGS_SET(unit, port, PHY_FLAGS_COPPER);
    270     }
    271     PHY_FLAGS_SET(unit, port, PHY_FLAGS_C45);
    272 
    273     pc->copper.preferred = !fiber_preferred;
    274     pc->copper.autoneg_enable = TRUE;
    275     pc->copper.autoneg_advert = ADVERT_ALL_COPPER;
    276     pc->copper.force_speed = 1000;
    277     pc->copper.force_duplex = TRUE;
    278     pc->copper.master = SOC_PORT_MS_AUTO;
    279     pc->copper.mdix = SOC_PORT_MDIX_AUTO;
    280 
    281     pc->fiber.preferred = TRUE;
    282     pc->fiber.autoneg_enable = FALSE;
    283     pc->fiber.autoneg_advert = ADVERT_ALL_FIBER;
    284     pc->fiber.force_speed = 10000;
    285     pc->fiber.force_duplex = TRUE;
    286     pc->fiber.master = SOC_PORT_MS_NONE;
    287     pc->fiber.mdix = SOC_PORT_MDIX_NORMAL;
    288 
    289     /* XAUI RX Lane Swap (Lane A, B, C, D changes to Lane D, C, B, A) */
    290     str = soc_property_port_get_str(unit, port, spn_PHY_XAUI_RX_LANE_SWAP); 
    291     if (str != NULL) {
    292         temp = soc_property_port_get(unit, port,
    293                                     spn_PHY_XAUI_RX_LANE_SWAP, 0);
    294     } else {
    295         temp = 0;
    296     }
    297     phy_sys_xaui_rx_lane_map = (temp) ? 0x3210 : 0;
    298 
    299 
    300     /* XAUI TX Lane Swap (Lane A, B, C, D changes to Lane D, C, B, A) */
    301     str = soc_property_port_get_str(unit, port, spn_PHY_XAUI_TX_LANE_SWAP); 
    302     if (str != NULL) {
    303         temp = soc_property_port_get(unit, port,
    304                                     spn_PHY_XAUI_TX_LANE_SWAP, 0);
    305     } else {
    306         temp = 0;
    307     }
    308     phy_sys_xaui_tx_lane_map = (temp) ? 0x3210 : 0;
    309 
    310 
    311 
    312     /* Init PHYS and MACs to defaults */
    313     rv = bmacsec_phy84749_init(phy_dev_addr, 1, 
    314                                line_mode, 
    315                                macsec_enable, 
    316                                phy_sys_xaui_tx_lane_map,
    317                                phy_sys_xaui_rx_lane_map,
    318                                phy_ext_rom_boot);
    319 
    320     if (rv != BMACSEC_E_NONE) {
    321         return SOC_E_FAIL;
    322     }
    323 
    324 #if 0
    325     /* Use lane mapping */
    326     SOC_IF_ERROR_RETURN(
    327         bsdk_phy84728_lane_map(pc));
    328 #endif
    329 
    330 
    331     /* Get Requested LED selectors (defaults are hardware defaults) */
    332     pc->ledmode[0] = soc_property_port_get(unit, port, spn_PHY_LED1_MODE, 0);
    333     pc->ledmode[1] = soc_property_port_get(unit, port, spn_PHY_LED2_MODE, 1);
    334     pc->ledmode[2] = soc_property_port_get(unit, port, spn_PHY_LED3_MODE, 3);
    335     pc->ledmode[3] = soc_property_port_get(unit, port, spn_PHY_LED4_MODE, 6);
    336     pc->ledctrl = soc_property_port_get(unit, port, spn_PHY_LED_CTRL, 0x8);
    337     pc->ledselect = soc_property_port_get(unit, port, spn_PHY_LED_SELECT, 0);
    338 
    339     /*
    340      * Some reasonable defaults
    341      */
    342     pc->macsec_switch_fixed = 0;
    343     pc->macsec_switch_fixed_speed = 10000;
    344     pc->macsec_switch_fixed_duplex = 1;
    345     pc->macsec_switch_fixed_pause = 1;
    346     pc->macsec_pause_rx_fwd = 0;
    347     pc->macsec_pause_tx_fwd = 0;
    348     pc->macsec_line_ipg = 0xc;
    349     pc->macsec_switch_ipg = 0xc;
    350 
    351 
    352     if (line_mode != BMACSEC_PHY84749_INTF_SGMII) {
    353         SOC_IF_ERROR_RETURN
    354             (_phy_84749_medium_config_update(unit, port,
    355                                     PHY_COPPER_MODE(unit, port) ?
    356                                     &pc->copper :
    357                                     &pc->fiber));
    358     }
    359 
    360     if (IS_HG_PORT(unit, port)) {
    361         rv = bmacsec_phy84749_higig_mode(phy_dev_addr, 1);
    362         if (rv != BMACSEC_E_NONE) {
    363             return SOC_E_FAIL;
    364         }
    365     }
    366 
    367     if (macsec_enable) {
    368         rv = soc_macsecphy_init(unit, port, pc, 
    369                     BMACSEC_CORE_BCM84749, bmacsec_io_mmi1_cl45);
    370         if (!SOC_SUCCESS(rv)) {
    371         LOG_ERROR(BSL_LS_SOC_PHY,
    372                   (BSL_META_U(unit,
    373                               "soc_macsecphy_init: MACSEC init for"
    374                               " u=%d p=%d FAILED "), unit, port));
    375         } else {
    376         LOG_INFO(BSL_LS_SOC_PHY,
    377                  (BSL_META_U(unit,
    378                              "soc_macsecphy_init: MACSEC init for"
    379                              " u=%d p=%d SUCCESS "), unit, port));
    380         }
    381     }
    382 
    383 
    384     return SOC_E_NONE;
    385 }
    386 
    387 
    388 /*
    389  * Function:
    390  *    phy_84749_link_get
    391  * Purpose:
    392  *    Get layer2 connection status.
    393  * Parameters:
    394  *    unit - StrataSwitch unit #.
    395  *    port - StrataSwitch port #. 
    396  *      link - address of memory to store link up/down state.
    397  * Returns:    
    398  *    SOC_E_NONE
    399  */
    400 
    401 STATIC int
    402 phy_84749_link_get(int unit, soc_port_t port, int *link)
    403 {
    404     phy_ctrl_t    *pc;
    405     int rv = SOC_E_NONE;
    406     bmacsec_dev_addr_t phy_dev_addr;
    407     bmacsec_phy84749_intf_t bmacsec_mode;
    408     int bmacsec_link;
    409 
    410     pc    = EXT_PHY_SW_STATE(unit, port);
    411     *link = FALSE;      /* Default return */
    412 
    413     if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_DISABLE)) {
    414         return SOC_E_NONE;
    415     }
    416 
    417     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1); 
    418 
    419     rv = bmacsec_phy84749_line_intf_get(phy_dev_addr, 0, &bmacsec_mode);
    420     if (!BMACSEC_E_SUCCESS(rv)) {
    421         return SOC_E_FAIL;
    422     }
    423 
    424     if (bmacsec_mode == BMACSEC_PHY84749_INTF_SGMII) {
    425         PHY_FLAGS_SET(unit, port, PHY_FLAGS_COPPER);
    426         PHY_FLAGS_CLR(unit, port, PHY_FLAGS_FIBER);
    427     } else {
    428         PHY_FLAGS_SET(unit, port, PHY_FLAGS_FIBER);
    429         PHY_FLAGS_CLR(unit, port, PHY_FLAGS_COPPER);
    430     }
    431 
    432     rv = bmacsec_phy84749_link_get(phy_dev_addr, &bmacsec_link);
    433     if (!BMACSEC_E_SUCCESS(rv)) {
    434         return SOC_E_FAIL;
    435     }
    436     if (bmacsec_link) {
    437         *link = TRUE;
    438     } else {
    439         *link = FALSE;
    440     }
    441 
    442     LOG_VERBOSE(BSL_LS_SOC_PHY,
    443                 (BSL_META_U(unit,
    444                             "phy_84749_link_get: u=%d p=%d link=%d\n"),
    445                  unit, port,
    446                  *link));
    447 
    448     return SOC_E_NONE;
    449 }
    450 
    451 /*
    452  * Function:
    453  *      phy_84749_enable_set
    454  * Purpose:
    455  *      Enable or disable the physical interface.
    456  * Parameters:
    457  *      unit - StrataSwitch unit #.
    458  *      port - StrataSwitch port #.
    459  *      enable - Boolean, true = enable PHY, false = disable.
    460  * Returns:
    461  *      SOC_E_XXX
    462  */
    463 
    464 STATIC int
    465 phy_84749_enable_set(int unit, soc_port_t port, int enable)
    466 {
    467     phy_ctrl_t    *pc;
    468     int rv = SOC_E_NONE;
    469     bmacsec_dev_addr_t phy_dev_addr;
    470 
    471     pc     = EXT_PHY_SW_STATE(unit, port);
    472 
    473     if (enable) {
    474         PHY_FLAGS_CLR(unit, port, PHY_FLAGS_DISABLE);
    475     } else {
    476         PHY_FLAGS_SET(unit, port, PHY_FLAGS_DISABLE);
    477     }
    478 
    479     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    480 
    481     rv = bmacsec_phy84749_enable_set(phy_dev_addr, enable);
    482 
    483     if(rv != BMACSEC_E_NONE) {
    484         return SOC_E_FAIL;
    485     }
    486 
    487     LOG_INFO(BSL_LS_SOC_PHY,
    488              (BSL_META_U(unit,
    489                          "phy_84749_enable_set: "
    490                          "Power %s fiber medium\n"), (enable) ? "up" : "down"));
    491 
    492     return SOC_E_NONE;
    493 }
    494 
    495 /*
    496  * Function:
    497  *      phy_84749_duplex_set
    498  * Purpose:
    499  *      Set the current duplex mode
    500  * Parameters:
    501  *      unit - StrataSwitch unit #.
    502  *      port - StrataSwitch port #.
    503  *      duplex - Boolean, true indicates full duplex, false indicates half.
    504  * Returns:
    505  *      SOC_E_NONE
    506  *      SOC_E_UNAVAIL - Half duplex requested, and not supported.
    507  * Notes:
    508  */
    509 STATIC int
    510 phy_84749_duplex_set(int unit, soc_port_t port, int duplex)
    511 {
    512     int                          rv;
    513     phy_ctrl_t                   *pc;
    514     bmacsec_dev_addr_t           phy_dev_addr;
    515     bmacsec_phy84749_duplex_t    bmacsec_duplex;
    516 
    517     pc = EXT_PHY_SW_STATE(unit, port);
    518 
    519     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    520 
    521     if (duplex) {
    522         bmacsec_duplex = BMACSEC_PHY84749_FULL_DUPLEX;
    523     } else {
    524         bmacsec_duplex = BMACSEC_PHY84749_HALF_DUPLEX;
    525     }
    526     rv = bmacsec_phy84749_duplex_set(phy_dev_addr, bmacsec_duplex);
    527 
    528     if(BMACSEC_E_SUCCESS(rv)) {
    529         pc->copper.force_duplex = duplex;
    530     }
    531 
    532     LOG_INFO(BSL_LS_SOC_PHY,
    533              (BSL_META_U(unit,
    534                          "phy_84749_duplex_set: u=%d p=%d d=%d rv=%d\n"),
    535               unit, port, duplex, rv));
    536     return (SOC_ERROR(rv));
    537 }
    538 
    539 /*
    540  * Function:
    541  *      phy_84749_duplex_get
    542  * Purpose:
    543  *      Get the current operating duplex mode. If autoneg is enabled,
    544  *      then operating mode is returned, otherwise forced mode is returned.
    545  * Parameters:
    546  *      unit - StrataSwitch unit #.
    547  *      port - StrataSwitch port #.
    548  *      duplex - (OUT) Boolean, true indicates full duplex, false
    549  *              indicates half.
    550  * Returns:
    551  *      SOC_E_NONE
    552  * Notes:
    553  *      The duplex is retrieved for the ACTIVE medium.
    554  *      No synchronization performed at this level. Autonegotiation is
    555  *      not manipulated.
    556  */
    557 
    558 STATIC int
    559 phy_84749_duplex_get(int unit, soc_port_t port, int *duplex)
    560 {
    561 
    562     int rv = SOC_E_NONE;
    563     phy_ctrl_t                   *pc;
    564     bmacsec_dev_addr_t phy_dev_addr;
    565     bmacsec_phy84749_duplex_t bmacsec_duplex;
    566 
    567     pc = EXT_PHY_SW_STATE(unit, port);
    568 
    569     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    570 
    571     rv = bmacsec_phy84749_duplex_get(phy_dev_addr, &bmacsec_duplex);
    572     if (rv != BMACSEC_E_NONE) {
    573         return SOC_E_FAIL;
    574     }
    575     if (bmacsec_duplex == BMACSEC_PHY84749_FULL_DUPLEX) {
    576         *duplex = TRUE;
    577     } else {
    578         *duplex = FALSE;
    579     }
    580 
    581     LOG_INFO(BSL_LS_SOC_PHY,
    582              (BSL_META_U(unit,
    583                          "phy_84749_duplex_get: u=%d p=%d d=%d rv=%d\n"),
    584               unit, port, *duplex, rv));
    585     return SOC_E_NONE;
    586 }
    587 
    588 
    589 /*
    590  * Function:
    591  *      phy_84749_speed_set
    592  * Purpose:
    593  *      Set PHY speed
    594  * Parameters:
    595  *      unit - StrataSwitch unit #.
    596  *      port - StrataSwitch port #.
    597  *      speed - link speed in Mbps
    598  * Returns:
    599  *      SOC_E_NONE
    600  */
    601 STATIC int
    602 phy_84749_speed_set(int unit, soc_port_t port, int speed)
    603 {
    604     phy_ctrl_t *pc;
    605     phy_ctrl_t  *int_pc;
    606     int            rv; 
    607     bmacsec_dev_addr_t phy_dev_addr;
    608 
    609     pc = EXT_PHY_SW_STATE(unit, port);
    610     int_pc = INT_PHY_SW_STATE(unit, port);
    611     rv = SOC_E_NONE;
    612 
    613     if (speed > 10000) {
    614         return SOC_E_UNAVAIL;
    615     }
    616 
    617     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    618 
    619     if(PHY_FIBER_MODE(unit, port)) {
    620         if (speed < 1000) {
    621             return SOC_E_UNAVAIL;
    622         }
    623     }
    624 
    625     rv = bmacsec_phy84749_speed_set(phy_dev_addr, speed);
    626     if(BMACSEC_E_SUCCESS(rv)) {
    627         if (NULL != int_pc) {
    628             PHY_AUTO_NEGOTIATE_SET (int_pc->pd, unit, port, 0);
    629             PHY_SPEED_SET(int_pc->pd, unit, port, speed);
    630         }
    631         if(PHY_COPPER_MODE(unit, port)) {
    632             pc->copper.force_speed = speed;
    633         } else {
    634             if(PHY_FIBER_MODE(unit, port)) {
    635                 pc->fiber.force_speed = speed;
    636             }
    637         }
    638     }
    639     LOG_INFO(BSL_LS_SOC_PHY,
    640              (BSL_META_U(unit,
    641                          "phy_84749_speed_set: u=%d p=%d s=%d fiber=%d rv=%d\n"),
    642               unit, port, speed, PHY_FIBER_MODE(unit, port), rv));
    643 
    644     return SOC_ERROR(rv);
    645 }
    646 
    647 /*
    648  * Function:
    649  *      phy_84749_speed_get
    650  * Purpose:
    651  *      Get the current operating speed for a 84749 device.
    652  * Parameters:
    653  *      unit - StrataSwitch unit #.
    654  *      port - StrataSwitch port #.
    655  *      speed - (OUT) Speed of the phy
    656  * Returns:
    657  *      SOC_E_NONE
    658  * Notes:
    659  *      The speed is retrieved for the ACTIVE medium.
    660  */
    661 
    662 STATIC int
    663 phy_84749_speed_get(int unit, soc_port_t port, int *speed)
    664 {
    665     int rv = SOC_E_NONE;
    666     bmacsec_dev_addr_t phy_dev_addr;
    667     phy_ctrl_t    *pc;
    668 
    669     pc = EXT_PHY_SW_STATE(unit, port);
    670 
    671     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    672 
    673     rv = bmacsec_phy84749_speed_get(phy_dev_addr, speed);
    674 
    675     if(!BMACSEC_E_SUCCESS(rv)) {
    676         LOG_WARN(BSL_LS_SOC_PHY,
    677                  (BSL_META_U(unit,
    678                              "phy_84749_speed_get: u=%d p=%d invalid speed\n"),
    679                   unit, port));
    680     } else {
    681         LOG_INFO(BSL_LS_SOC_PHY,
    682                  (BSL_META_U(unit,
    683                              "phy_84749_speed_get: u=%d p=%d speed=%d"),
    684                   unit, port, *speed));
    685     }
    686 
    687     return SOC_ERROR(rv);
    688 }
    689 
    690 /*
    691  * Function:
    692  *      phy_84749_an_set
    693  * Purpose:
    694  *      Enable or disable auto-negotiation on the specified port.
    695  * Parameters:
    696  *      unit - StrataSwitch unit #.
    697  *      port - StrataSwitch port #.
    698  *      autoneg - Boolean, if true, auto-negotiation is enabled
    699  *              (and/or restarted). If false, autonegotiation is disabled.
    700  * Returns:
    701  *      SOC_E_XXX
    702  * Notes:
    703  *      The autoneg mode is set only for the ACTIVE medium.
    704  */
    705 
    706 STATIC int
    707 phy_84749_an_set(int unit, soc_port_t port, int autoneg)
    708 {
    709     int                 rv;
    710     phy_ctrl_t   *pc;
    711     int autoneg_advert = 0;
    712     bmacsec_dev_addr_t phy_dev_addr;
    713 
    714     pc = EXT_PHY_SW_STATE(unit, port);
    715     rv = SOC_E_NONE;
    716 
    717     if(PHY_COPPER_MODE(unit, port)) {
    718         autoneg_advert = 0;
    719     } else {
    720         if(PHY_FIBER_MODE(unit, port)) {
    721             autoneg_advert = pc->fiber.autoneg_advert;
    722         }
    723     }
    724     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    725 
    726     rv = bmacsec_phy84749_an_set(phy_dev_addr, autoneg, autoneg_advert);
    727     if(BMACSEC_E_SUCCESS(rv)) {
    728         if(PHY_COPPER_MODE(unit, port)) {
    729             pc->copper.autoneg_enable = autoneg ? TRUE : FALSE;
    730         } else {
    731             if(PHY_FIBER_MODE(unit, port)) {
    732                 pc->fiber.autoneg_enable = autoneg ? TRUE : FALSE;
    733             }
    734         }
    735     }
    736 
    737     LOG_INFO(BSL_LS_SOC_PHY,
    738              (BSL_META_U(unit,
    739                          "phy_84749_an_set: u=%d p=%d autoneg=%d rv=%d\n"),
    740               unit, port, autoneg, rv));
    741     return SOC_ERROR(rv);
    742 }
    743 
    744 /*
    745  * Function:
    746  *      phy_84749_an_get
    747  * Purpose:
    748  *      Get the current auto-negotiation status (enabled/busy).
    749  * Parameters:
    750  *      unit - StrataSwitch unit #.
    751  *      port - StrataSwitch port #.
    752  *      autoneg - (OUT) if true, auto-negotiation is enabled.
    753  *      autoneg_done - (OUT) if true, auto-negotiation is complete. This
    754  *              value is undefined if autoneg == FALSE.
    755  * Returns:
    756  *      SOC_E_XXX
    757  * Notes:
    758  *      The autoneg mode is retrieved for the ACTIVE medium.
    759  */
    760 
    761 STATIC int
    762 phy_84749_an_get(int unit, soc_port_t port,
    763                      int *autoneg, int *autoneg_done)
    764 {
    765     int           rv;
    766     phy_ctrl_t   *pc;
    767     bmacsec_dev_addr_t phy_dev_addr;
    768 
    769     pc = EXT_PHY_SW_STATE(unit, port);
    770 
    771     rv            = SOC_E_NONE;
    772     *autoneg      = FALSE;
    773     *autoneg_done = FALSE;
    774 
    775     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    776 
    777     rv = bmacsec_phy84749_an_get(phy_dev_addr, autoneg, autoneg_done);
    778 
    779     return SOC_ERROR(rv);
    780 }
    781 
    782 /*
    783  * Function:
    784  *      phy_84749_lb_set
    785  * Purpose:
    786  *      Set the local PHY loopback mode.
    787  * Parameters:
    788  *      unit - StrataSwitch unit #.
    789  *      port - StrataSwitch port #.
    790  *      loopback - Boolean: true = enable loopback, false = disable.
    791  * Returns:
    792  *      SOC_E_XXX
    793  * Notes:
    794  *      The loopback mode is set only for the ACTIVE medium.
    795  *      No synchronization performed at this level.
    796  */
    797 
    798 STATIC int
    799 phy_84749_lb_set(int unit, soc_port_t port, int enable)
    800 {
    801     int           rv;
    802 #if 0
    803     int           link = 0;
    804     soc_timeout_t  to;
    805 #endif
    806     phy_ctrl_t    *pc;
    807     bmacsec_dev_addr_t phy_dev_addr;
    808 
    809     pc = EXT_PHY_SW_STATE(unit, port);
    810     rv = SOC_E_NONE;
    811 
    812     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    813 
    814     rv = bmacsec_phy84749_loopback_set(phy_dev_addr, enable);
    815 
    816     if (rv == BMACSEC_E_NONE) {
    817         /* wait for link up when loopback is enabled */
    818         
    819         if (enable) {
    820             sal_usleep(2000000);
    821         }
    822     }
    823 
    824     LOG_INFO(BSL_LS_SOC_PHY,
    825              (BSL_META_U(unit,
    826                          "phy_84749_lb_set: u=%d p=%d en=%d rv=%d\n"), 
    827               unit, port, enable, rv));
    828 
    829     return SOC_ERROR(rv); 
    830 }
    831 
    832 /*
    833  * Function:
    834  *      phy_84749_lb_get
    835  * Purpose:
    836  *      Get the local PHY loopback mode.
    837  * Parameters:
    838  *      unit - StrataSwitch unit #.
    839  *      port - StrataSwitch port #.
    840  *      loopback - (OUT) Boolean: true = enable loopback, false = disable.
    841  * Returns:
    842  *      SOC_E_XXX
    843  * Notes:
    844  *      The loopback mode is retrieved for the ACTIVE medium.
    845  */
    846 
    847 STATIC int
    848 phy_84749_lb_get(int unit, soc_port_t port, int *enable)
    849 {
    850     int                  rv;
    851     phy_ctrl_t    *pc;
    852     bmacsec_dev_addr_t phy_dev_addr;
    853 
    854     pc = EXT_PHY_SW_STATE(unit, port);
    855     rv = SOC_E_NONE;
    856 
    857     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
    858 
    859     rv = bmacsec_phy84749_loopback_get(phy_dev_addr, enable);
    860 
    861     return SOC_ERROR(rv); 
    862 }
    863 
    864 /*
    865  * Function:
    866  *      phy_84749_medium_config_set
    867  * Purpose:
    868  *      Set the operating parameters that are automatically selected
    869  *      when medium switches type.
    870  * Parameters:
    871  *      unit - StrataSwitch unit #
    872  *      port - Port number
    873  *      medium - SOC_PORT_MEDIUM_COPPER/FIBER
    874  *      cfg - Operating parameters
    875  * Returns:
    876  *      SOC_E_XXX
    877  */
    878 
    879 STATIC int
    880 phy_84749_medium_config_set(int unit, soc_port_t port, 
    881                            soc_port_medium_t  medium,
    882                            soc_phy_config_t  *cfg)
    883 {
    884     phy_ctrl_t    *pc;
    885 #if 0
    886     soc_phy_config_t *active_medium;  /* Currently active medium */
    887 #endif
    888     soc_phy_config_t *change_medium;  /* Requested medium */
    889     soc_phy_config_t *other_medium;   /* The other medium */
    890 
    891     soc_port_mode_t   advert_mask;
    892 
    893     if (NULL == cfg) {
    894         return SOC_E_PARAM;
    895     }
    896 
    897     pc            = EXT_PHY_SW_STATE(unit, port);
    898 
    899    switch (medium) {
    900     case SOC_PORT_MEDIUM_COPPER:
    901         if (!pc->automedium && !PHY_COPPER_MODE(unit, port)) {
    902             return SOC_E_UNAVAIL;
    903         }
    904         change_medium  = &pc->copper;
    905         other_medium   = &pc->fiber;
    906         advert_mask    = ADVERT_ALL_COPPER;
    907         break;
    908     case SOC_PORT_MEDIUM_FIBER:
    909         if (!pc->automedium && !PHY_FIBER_MODE(unit, port)) {
    910             return SOC_E_UNAVAIL;
    911         }
    912         change_medium  = &pc->fiber;
    913         other_medium   = &pc->copper;
    914         advert_mask    = ADVERT_ALL_FIBER;
    915         break;
    916     default:
    917         return SOC_E_PARAM;
    918     }
    919 
    920     /*
    921      * Changes take effect immediately if the target medium is active or
    922      * the preferred medium changes.
    923      */
    924     if (change_medium->enable != cfg->enable) {
    925     }
    926     if (change_medium->preferred != cfg->preferred) {
    927         /* Make sure that only one medium is preferred */
    928         other_medium->preferred = !cfg->preferred;
    929     }
    930 
    931     sal_memcpy(change_medium, cfg, sizeof(*change_medium));
    932     change_medium->autoneg_advert &= advert_mask;
    933 
    934 #if 0
    935     if (medium_update) {
    936         /* The new configuration may cause medium change. Check
    937          * and update medium.
    938          */
    939         SOC_IF_ERROR_RETURN
    940             (_phy_84749_medium_change(unit, port, TRUE, medium));
    941     } else {
    942         active_medium = (PHY_COPPER_MODE(unit, port)) ?  
    943                             &pc->copper : &pc->fiber;
    944         if (active_medium == change_medium) {
    945             /* If the medium to update is active, update the configuration */
    946             SOC_IF_ERROR_RETURN
    947                 (_phy_84749_medium_config_update(unit, port, change_medium));
    948         }
    949     }
    950 #endif
    951     return SOC_E_NONE;
    952 }
    953 
    954 /*
    955  * Function:
    956  *      phy_84749_medium_config_get
    957  * Purpose:
    958  *      Get the operating parameters that are automatically selected
    959  *      when medium switches type.
    960  * Parameters:
    961  *      unit - StrataSwitch unit #
    962  *      port - Port number
    963  *      medium - SOC_PORT_MEDIUM_COPPER/FIBER
    964  *      cfg - (OUT) Operating parameters
    965  * Returns:
    966  *      SOC_E_XXX
    967  */
    968 
    969 STATIC int
    970 phy_84749_medium_config_get(int unit, soc_port_t port, 
    971                            soc_port_medium_t medium,
    972                            soc_phy_config_t *cfg)
    973 {
    974     int            rv;
    975     phy_ctrl_t    *pc;
    976 
    977     pc = EXT_PHY_SW_STATE(unit, port);
    978     rv = SOC_E_NONE;
    979 
    980     switch (medium) {
    981     case SOC_PORT_MEDIUM_COPPER:
    982         if (pc->automedium || PHY_COPPER_MODE(unit, port)) {
    983             sal_memcpy(cfg, &pc->copper, sizeof (*cfg));
    984         } else {
    985             rv = SOC_E_UNAVAIL;
    986         }
    987         break;
    988     case SOC_PORT_MEDIUM_FIBER:
    989         if (pc->automedium || PHY_FIBER_MODE(unit, port)) {
    990             sal_memcpy(cfg, &pc->fiber, sizeof (*cfg));
    991         } else {
    992             rv = SOC_E_UNAVAIL;
    993         }
    994         break;
    995     default:
    996         rv = SOC_E_PARAM;
    997         break;
    998     }
    999 
   1000     return rv;
   1001 }
   1002 
   1003 /*
   1004  * Function:
   1005  *      phy_84749_ability_advert_set
   1006  * Purpose:
   1007  *      Set the current advertisement for auto-negotiation.
   1008  * Parameters:
   1009  *      unit - StrataSwitch unit #.
   1010  *      port - StrataSwitch port #.
   1011  *      mode - Port mode mask indicating supported options/speeds.
   1012  * Returns:
   1013  *      SOC_E_XXX
   1014  * Notes:
   1015  *      The advertisement is set only for the ACTIVE medium.
   1016  *      No synchronization performed at this level.
   1017  */
   1018 STATIC int
   1019 phy_84749_ability_advert_set(int unit, soc_port_t port,soc_port_ability_t *ability)
   1020 {
   1021     int        rv;
   1022     phy_ctrl_t *pc;
   1023     bmacsec_phy84749_port_ability_t local_ability;
   1024     bmacsec_dev_addr_t phy_dev_addr;
   1025 
   1026     pc = EXT_PHY_SW_STATE(unit, port);
   1027 
   1028     if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_DISABLE)) {
   1029         return SOC_E_NONE;
   1030     }
   1031 
   1032     if (NULL == ability) {
   1033         return (SOC_E_PARAM);
   1034     }
   1035 
   1036     if (PHY_COPPER_MODE(unit, port)) {
   1037         pc->copper.advert_ability = *ability;
   1038     } else {
   1039         pc->fiber.advert_ability = *ability;
   1040     }
   1041 
   1042     local_ability = 0;
   1043 
   1044     if(ability->speed_full_duplex & SOC_PA_SPEED_1000MB) {
   1045         local_ability |= BMACSEC_PHY84749_PA_1000MB_FD;
   1046     }
   1047     if(ability->speed_full_duplex & SOC_PA_SPEED_10GB) {
   1048         local_ability |= BMACSEC_PHY84749_PA_10000MB_FD;
   1049     }
   1050 
   1051     if(ability->pause & SOC_PA_PAUSE_TX) {
   1052         local_ability |= BMACSEC_PHY84749_PA_PAUSE_TX;
   1053     }
   1054     if(ability->pause & SOC_PA_PAUSE_RX) {
   1055         local_ability |= BMACSEC_PHY84749_PA_PAUSE_RX;
   1056     }
   1057     if(ability->pause & SOC_PA_PAUSE_ASYMM) {
   1058         local_ability |= BMACSEC_PHY84749_PA_PAUSE_ASYMM;
   1059     }
   1060 
   1061     if(ability->loopback & SOC_PA_LB_NONE) {
   1062         local_ability |= BMACSEC_PHY84749_PA_LB_NONE;
   1063     }
   1064     if(ability->loopback & SOC_PA_LB_PHY) {
   1065         local_ability |= BMACSEC_PHY84749_PA_LB_PHY;
   1066     }
   1067     if(ability->flags & SOC_PA_AUTONEG) {
   1068         local_ability |= BMACSEC_PHY84749_PA_AN;
   1069     }
   1070 
   1071     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1072 
   1073     rv = bmacsec_phy84749_ability_advert_set(phy_dev_addr, local_ability);
   1074 
   1075 
   1076     return SOC_ERROR(rv);
   1077 }
   1078 
   1079 /*
   1080  * Function:
   1081  *      phy_84749_ability_advert_get
   1082  * Purpose:
   1083  *      Get the current advertisement for auto-negotiation.
   1084  * Parameters:
   1085  *      unit - StrataSwitch unit #.
   1086  *      port - StrataSwitch port #.
   1087  *      mode - (OUT) Port mode mask indicating supported options/speeds.
   1088  * Returns:
   1089  *      SOC_E_XXX
   1090  * Notes:
   1091  *      The advertisement is retrieved for the ACTIVE medium.
   1092  *      No synchronization performed at this level.
   1093  */
   1094 STATIC int
   1095 phy_84749_ability_advert_get(int unit, soc_port_t port,soc_port_ability_t *ability)
   1096 {
   1097     phy_ctrl_t      *pc;
   1098     int        rv;
   1099     bmacsec_phy84749_port_ability_t local_ability;
   1100     bmacsec_dev_addr_t phy_dev_addr;
   1101 
   1102     if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_DISABLE)) {
   1103         return SOC_E_NONE;
   1104     }
   1105 
   1106     if (NULL == ability) {
   1107         return (SOC_E_PARAM);
   1108     }
   1109 
   1110     pc = EXT_PHY_SW_STATE(unit, port);
   1111 
   1112     local_ability = 0;
   1113 
   1114     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1115 
   1116     rv = bmacsec_phy84749_ability_advert_get(phy_dev_addr, &local_ability);
   1117     if (rv != BMACSEC_E_NONE) {
   1118         return SOC_E_FAIL;
   1119     }
   1120 
   1121     if(local_ability & BMACSEC_PHY84749_PA_1000MB_FD) {
   1122         ability->speed_full_duplex |= SOC_PA_SPEED_1000MB;
   1123     }
   1124     if(local_ability & BMACSEC_PHY84749_PA_10000MB_FD) {
   1125         ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   1126     }
   1127 
   1128     if(local_ability & BMACSEC_PHY84749_PA_PAUSE_TX) {
   1129         ability->pause |= SOC_PA_PAUSE_TX;
   1130     }
   1131     if(local_ability & BMACSEC_PHY84749_PA_PAUSE_RX) {
   1132         ability->pause |= SOC_PA_PAUSE_RX;
   1133     }
   1134     if(local_ability & BMACSEC_PHY84749_PA_PAUSE_ASYMM) {
   1135         ability->pause |= SOC_PA_PAUSE_ASYMM;
   1136     }
   1137 
   1138     if(local_ability & BMACSEC_PHY84749_PA_LB_NONE) {
   1139         ability->loopback |= SOC_PA_LB_NONE;
   1140     }
   1141     if(local_ability & BMACSEC_PHY84749_PA_LB_PHY) {
   1142         ability->loopback |= SOC_PA_LB_PHY;
   1143     }
   1144     if(local_ability & BMACSEC_PHY84749_PA_AN) {
   1145         ability->flags = SOC_PA_AUTONEG;
   1146     }
   1147 
   1148     return SOC_E_NONE;
   1149 }
   1150 
   1151 /*
   1152  * Function:
   1153  *      phy_84749_ability_remote_get
   1154  * Purpose:
   1155  *      Get the current remote advertisement for auto-negotiation.
   1156  * Parameters:
   1157  *      unit - StrataSwitch unit #.
   1158  *      port - StrataSwitch port #.
   1159  *      mode - (OUT) Port mode mask indicating supported options/speeds.
   1160  * Returns:
   1161  *      SOC_E_XXX
   1162  * Notes:
   1163  *      The advertisement is retrieved for the ACTIVE medium.
   1164  *      No synchronization performed at this level.
   1165  */
   1166 STATIC int
   1167 phy_84749_ability_remote_get(int unit, soc_port_t port,soc_port_ability_t *ability)
   1168 {
   1169     phy_ctrl_t      *pc;
   1170     int        rv;
   1171     bmacsec_phy84749_port_ability_t remote_ability;
   1172     bmacsec_dev_addr_t phy_dev_addr;
   1173 
   1174     if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_DISABLE)) {
   1175         return SOC_E_NONE;
   1176     }
   1177 
   1178     if (NULL == ability) {
   1179         return (SOC_E_PARAM);
   1180     }
   1181 
   1182     pc = EXT_PHY_SW_STATE(unit, port);
   1183 
   1184     remote_ability = 0;
   1185 
   1186     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1187 
   1188     rv = bmacsec_phy84749_remote_ability_advert_get(phy_dev_addr,
   1189                                                    &remote_ability);
   1190     if (rv != BMACSEC_E_NONE) {
   1191         return SOC_E_FAIL;
   1192     }
   1193 
   1194     if(remote_ability & BMACSEC_PHY84749_PA_1000MB_FD) {
   1195         ability->speed_full_duplex |= SOC_PA_SPEED_1000MB;
   1196     }
   1197     if(remote_ability & BMACSEC_PHY84749_PA_10000MB_FD) {
   1198         ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   1199     }
   1200 
   1201     if(remote_ability & BMACSEC_PHY84749_PA_PAUSE_TX) {
   1202         ability->pause |= SOC_PA_PAUSE_TX;
   1203     }
   1204     if(remote_ability & BMACSEC_PHY84749_PA_PAUSE_RX) {
   1205         ability->pause |= SOC_PA_PAUSE_RX;
   1206     }
   1207     if(remote_ability & BMACSEC_PHY84749_PA_PAUSE_ASYMM) {
   1208         ability->pause |= SOC_PA_PAUSE_ASYMM;
   1209     }
   1210 
   1211     if(remote_ability & BMACSEC_PHY84749_PA_LB_NONE) {
   1212         ability->loopback |= SOC_PA_LB_NONE;
   1213     }
   1214     if(remote_ability & BMACSEC_PHY84749_PA_LB_PHY) {
   1215         ability->loopback |= SOC_PA_LB_PHY;
   1216     }
   1217     if(remote_ability & BMACSEC_PHY84749_PA_AN) {
   1218         ability->flags = SOC_PA_AUTONEG;
   1219     }
   1220 
   1221     return SOC_E_NONE;
   1222 }
   1223 
   1224 
   1225 
   1226 /*
   1227  * Function:
   1228  *      phy_84749_ability_local_get
   1229  * Purpose:
   1230  *      Get local abilities 
   1231  * Parameters:
   1232  *      unit - StrataSwitch unit #.
   1233  *      port - StrataSwitch port #.
   1234  *      mode - (OUT) Port mode mask indicating supported options/speeds.
   1235  * Returns:
   1236  *      SOC_E_NONE
   1237  * Notes:
   1238  *      The ability is retrieved only for the ACTIVE medium.
   1239  */
   1240 
   1241 STATIC int
   1242 phy_84749_ability_local_get(int unit, soc_port_t port, soc_port_ability_t *ability)
   1243 {
   1244     int         rv = SOC_E_NONE;
   1245     phy_ctrl_t *pc;
   1246     bmacsec_phy84749_port_ability_t local_ability = 0;
   1247     bmacsec_dev_addr_t phy_dev_addr;
   1248 
   1249     if (NULL == ability) {
   1250         return SOC_E_PARAM;
   1251     }
   1252 
   1253     pc = EXT_PHY_SW_STATE(unit, port);
   1254 
   1255     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1256 
   1257     rv = bmacsec_phy84749_ability_local_get(phy_dev_addr, &local_ability);
   1258     if (rv != BMACSEC_E_NONE) {
   1259         return SOC_E_FAIL;
   1260     }
   1261 
   1262     if(local_ability & BMACSEC_PHY84749_PA_1000MB_FD) {
   1263         ability->speed_full_duplex |= SOC_PA_SPEED_1000MB;
   1264     }
   1265     if(local_ability & BMACSEC_PHY84749_PA_10000MB_FD) {
   1266         ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   1267     }
   1268 
   1269     if(local_ability & BMACSEC_PHY84749_PA_PAUSE_TX) {
   1270         ability->pause |= SOC_PA_PAUSE_TX;
   1271     }
   1272     if(local_ability & BMACSEC_PHY84749_PA_PAUSE_RX) {
   1273         ability->pause |= SOC_PA_PAUSE_RX;
   1274     }
   1275     if(local_ability & BMACSEC_PHY84749_PA_PAUSE_ASYMM) {
   1276         ability->pause |= SOC_PA_PAUSE_ASYMM;
   1277     }
   1278 
   1279 
   1280     if(local_ability & BMACSEC_PHY84749_PA_LB_NONE) {
   1281         ability->loopback |= SOC_PA_LB_NONE;
   1282     }
   1283     if(local_ability & BMACSEC_PHY84749_PA_LB_PHY) {
   1284         ability->loopback |= SOC_PA_LB_PHY;
   1285     }
   1286     if(local_ability & BMACSEC_PHY84749_PA_AN) {
   1287         ability->flags = SOC_PA_AUTONEG;
   1288     }
   1289 
   1290     return SOC_E_NONE;
   1291 }
   1292 
   1293 /*
   1294  * Function:
   1295  *      phy_84749_firmware_set
   1296  * Purpose:
   1297  *      program the given firmware into the SPI-ROM
   1298  * Parameters:
   1299  *      unit - StrataSwitch unit #.
   1300  *      port - StrataSwitch port #.
   1301  *      offset - offset to the data stream
   1302  *      array  - the given data
   1303  *      datalen- the data length
   1304  * Returns:
   1305  *      SOC_E_NONE
   1306  */
   1307 
   1308 STATIC int
   1309 phy_84749_firmware_set(int unit, int port, int offset, uint8 *data,int len)
   1310 {
   1311     int            rv;
   1312     phy_ctrl_t *pc;
   1313     bmacsec_dev_addr_t phy_dev_addr;
   1314 
   1315     pc = EXT_PHY_SW_STATE(unit, port);
   1316 
   1317     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1318 
   1319     rv = bmacsec_phy84749_spi_firmware_update(phy_dev_addr, data, len);
   1320     if (rv != BMACSEC_E_NONE) {
   1321             LOG_WARN(BSL_LS_SOC_PHY,
   1322                      (BSL_META_U(unit,
   1323                                  "PHY84749 firmware upgrade possibly failed:"
   1324                                  "u=%d p=%d\n"), unit, port));
   1325         return (SOC_E_FAIL);
   1326     }
   1327     LOG_INFO(BSL_LS_SOC_PHY,
   1328              (BSL_META_U(unit,
   1329                          "PHY84749 firmware upgrade successful:"
   1330                          "u=%d p=%d\n"), unit, port));
   1331 
   1332     return SOC_E_NONE;
   1333 }
   1334 
   1335 /*
   1336  * Function:
   1337  *      phy_84749_medium_status
   1338  * Purpose:
   1339  *      Indicate the current active medium
   1340  * Parameters:
   1341  *      unit - StrataSwitch unit #.
   1342  *      port - StrataSwitch port #.
   1343  *      medium - (OUT) One of:
   1344  *              SOC_PORT_MEDIUM_COPPER
   1345  *              SOC_PORT_MEDIUM_XAUI
   1346  * Returns:
   1347  *      SOC_E_NONE
   1348  */
   1349 
   1350 STATIC int
   1351 phy_84749_medium_status(int unit, soc_port_t port, soc_port_medium_t *medium)
   1352 {
   1353     COMPILER_REFERENCE(unit);
   1354     COMPILER_REFERENCE(port);
   1355 
   1356     *medium = SOC_PORT_MEDIUM_FIBER;
   1357 
   1358     return SOC_E_NONE;
   1359 }
   1360 
   1361 
   1362 /*
   1363  * Function:
   1364  *      phy_84749_control_set
   1365  * Purpose:
   1366  *      Configure PHY device specific control fucntion.
   1367  * Parameters:
   1368  *      unit  - StrataSwitch unit #.
   1369  *      port  - StrataSwitch port #.
   1370  *      type  - Control to update
   1371  *      value - New setting for the control
   1372  * Returns:    
   1373  *      SOC_E_NONE
   1374  */
   1375 STATIC int
   1376 phy_84749_control_set(int unit, soc_port_t port,
   1377                      soc_phy_control_t type, uint32 value)
   1378 {
   1379     int rv = BMACSEC_E_NONE; 
   1380 
   1381 #ifdef INCLUDE_MACSEC
   1382 #ifdef PHY84749_SWITCH_FIXED_MODE
   1383     bmacsec_dev_addr_t phy_dev_addr;
   1384     bmacsec_phy84749_intf_t line_mode;
   1385     int pause_fwd =0, line_speed=0, line_duplex=0, line_pause=1;
   1386     phy_ctrl_t    *pc;
   1387 
   1388     rv = BMACSEC_E_NONE;    
   1389     pc = EXT_PHY_SW_STATE(unit, port);
   1390 
   1391 /* Disable switch fixed speed modes and supporting functions
   1392    Code not deleted to save the work already done if feature is enabled later
   1393 */
   1394     if (pc->macsec_enable != 1) {
   1395         return SOC_E_UNAVAIL;
   1396     }
   1397 
   1398     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1); 
   1399     rv = bmacsec_phy84749_line_intf_get(phy_dev_addr,
   1400                                        pc->macsec_dev_port, &line_mode);
   1401     if (rv != BMACSEC_E_NONE) {
   1402         return SOC_ERROR(rv);
   1403     }
   1404     switch(type) {
   1405         case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED:
   1406             pc->macsec_switch_fixed = value;
   1407             if(value) {
   1408                 rv = bmacsec_phy84749_switch_side_set_params(phy_dev_addr, 
   1409                                 BMACSEC_BCM84749_SWITCH_FIXED, 
   1410                                 pc->macsec_switch_fixed_speed,
   1411                                 pc->macsec_switch_fixed_duplex,
   1412                                 pc->macsec_switch_fixed_pause);
   1413             } else { /* Switch side follows line side */
   1414                 SOC_IF_ERROR_RETURN
   1415                     (phy_84749_speed_get(unit, port, &line_speed));
   1416                 SOC_IF_ERROR_RETURN
   1417                     (phy_84749_duplex_get(unit, port, &line_duplex));
   1418 #if 0 
   1419                 SOC_IF_ERROR_RETURN
   1420                     (phy_84749_pause_get(unit, port, &line_pause));
   1421 #endif
   1422                 rv = bmacsec_phy84749_switch_side_set_params(phy_dev_addr, 
   1423                                 BMACSEC_BCM84749_SWITCH_FOLLOWS_LINE, 
   1424                                 line_speed, line_duplex, line_pause);
   1425             }
   1426             break;
   1427         case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED_SPEED:
   1428             /* Switch fixed speed is allowed only to be 1000Mbps */
   1429             if (pc->macsec_dev_port > 2) {
   1430                 if (value != 1000) {
   1431                     return SOC_E_CONFIG;
   1432                 }
   1433             } else {
   1434                 if (line_mode == BMACSEC_PHY84749_INTF_1000X) {
   1435                     if (value != 1000) {
   1436                         return SOC_E_CONFIG;
   1437                     }
   1438                 } else {
   1439                     if (value != 10000) {
   1440                         return SOC_E_CONFIG;
   1441                     }
   1442                 }
   1443             } 
   1444 
   1445             if(pc->macsec_switch_fixed_speed != value) {
   1446                 pc->macsec_switch_fixed_speed = value;
   1447             }
   1448             break;
   1449         case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED_DUPLEX:
   1450             /* Switch fixed Duplex is allowed only to be Full Duplex mode */
   1451             if (value != 1) {
   1452                 return SOC_E_CONFIG;
   1453             }
   1454             if(pc->macsec_switch_fixed_duplex != value) {
   1455                 pc->macsec_switch_fixed_duplex = value;
   1456             }
   1457             break;
   1458         case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED_PAUSE:
   1459             if(pc->macsec_switch_fixed_pause != value) {
   1460                 pc->macsec_switch_fixed_pause = value;
   1461             }
   1462             break;
   1463         case SOC_PHY_CONTROL_MACSEC_PAUSE_RX_FORWARD:
   1464             pc->macsec_pause_rx_fwd = value;
   1465             pause_fwd = (value == 1) ? 1 : 0;
   1466 
   1467             rv = bmacsec_phy84749_line_side_pause_forward(phy_dev_addr,
   1468                                                          pause_fwd);
   1469             if (rv == BMACSEC_E_NONE) {
   1470                 rv = bmacsec_phy84749_switch_side_pause_forward(
   1471                                                      phy_dev_addr, pause_fwd);
   1472             }
   1473             break;
   1474         case SOC_PHY_CONTROL_MACSEC_PAUSE_TX_FORWARD:
   1475             pc->macsec_pause_tx_fwd = value;
   1476             pause_fwd = (value == 1) ? 1 : 0;
   1477 
   1478             rv = bmacsec_phy84749_line_side_pause_forward(phy_dev_addr,
   1479                                                           pause_fwd);
   1480             if (rv == BMACSEC_E_NONE) {
   1481                 rv = bmacsec_phy84749_switch_side_pause_forward(phy_dev_addr,
   1482                                                                 pause_fwd);
   1483             }
   1484             break;
   1485         case SOC_PHY_CONTROL_MACSEC_LINE_IPG:
   1486             pc->macsec_line_ipg = value;
   1487             rv = bmacsec_phy84749_line_side_ipg_set(phy_dev_addr, value);
   1488             break;
   1489         case SOC_PHY_CONTROL_MACSEC_SWITCH_IPG:
   1490             pc->macsec_switch_ipg = value;
   1491             rv = bmacsec_phy84749_switch_side_ipg_set(phy_dev_addr, value);
   1492             break;
   1493         default:
   1494             rv = SOC_E_UNAVAIL;
   1495             break;
   1496     }
   1497 #endif /* PHY84749_SWITCH_FIXED_MODE */
   1498 #else
   1499     bmacsec_dev_addr_t phy_dev_addr;
   1500     bmacsec_phy84749_intf_t line_mode;
   1501     int pause_fwd =0, line_speed=0, line_duplex=0, line_pause=1;
   1502 
   1503     pause_fwd = 0;
   1504     line_speed = 0;
   1505     line_duplex = 0;
   1506     line_pause = 1;
   1507     phy_dev_addr = 0;
   1508     line_mode = 0;
   1509 
   1510     rv = SOC_E_UNAVAIL;
   1511 #endif
   1512 
   1513     return SOC_ERROR(rv);
   1514 }
   1515 
   1516 /*
   1517  * Function:
   1518  *      phy_84749_control_get
   1519  * Purpose:
   1520  *      Get current control settign of the PHY.
   1521  * Parameters:
   1522  *      unit  - StrataSwitch unit #.
   1523  *      port  - StrataSwitch port #.
   1524  *      type  - Control to update
   1525  *      value - (OUT)Current setting for the control
   1526  * Returns:
   1527  *      SOC_E_NONE
   1528  */
   1529 STATIC int 
   1530 phy_84749_control_get(int unit, soc_port_t port,
   1531                      soc_phy_control_t type, uint32 *value)
   1532 {
   1533     int rv = SOC_E_NONE;
   1534 #ifdef INCLUDE_MACSEC
   1535 #ifdef PHY84749_SWITCH_FIXED_MODE
   1536     phy_ctrl_t    *pc;
   1537 
   1538     pc = EXT_PHY_SW_STATE(unit, port);
   1539 
   1540 /* Disable switch fixed speed modes and supporting functions
   1541    Code not deleted to save the work already done if feature is enabled later
   1542 */
   1543 
   1544     if (pc->macsec_enable != 1) {
   1545         return SOC_E_UNAVAIL;
   1546     }
   1547 
   1548     if (NULL == value) {
   1549         return SOC_E_PARAM;
   1550     }
   1551 
   1552     if ((type < 0) || (type >= SOC_PHY_CONTROL_COUNT)) {
   1553         return SOC_E_PARAM;
   1554     }
   1555 
   1556     switch(type) {
   1557         case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED:
   1558             *value = pc->macsec_switch_fixed;
   1559             break;
   1560         case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED_SPEED:
   1561             *value = pc->macsec_switch_fixed_speed;
   1562             break;
   1563         case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED_DUPLEX:
   1564             *value = pc->macsec_switch_fixed_duplex;
   1565             break;
   1566         case SOC_PHY_CONTROL_MACSEC_SWITCH_FIXED_PAUSE:
   1567             *value = pc->macsec_switch_fixed_pause;
   1568             break;
   1569         case SOC_PHY_CONTROL_MACSEC_PAUSE_RX_FORWARD:
   1570             *value = pc->macsec_pause_rx_fwd;
   1571             break;
   1572         case SOC_PHY_CONTROL_MACSEC_PAUSE_TX_FORWARD:
   1573             *value = pc->macsec_pause_tx_fwd;
   1574             break;
   1575         case SOC_PHY_CONTROL_MACSEC_LINE_IPG:
   1576             *value = pc->macsec_line_ipg;
   1577             break;
   1578         case SOC_PHY_CONTROL_MACSEC_SWITCH_IPG:
   1579             *value = pc->macsec_switch_ipg;
   1580             break;
   1581         default:
   1582             rv = SOC_E_UNAVAIL;
   1583             break; 
   1584     }
   1585 #endif /* PHY84749_SWITCH_FIXED_MODE */
   1586 #else
   1587     rv = SOC_E_UNAVAIL;
   1588 #endif /* INCLUDE_MACSEC */
   1589     return rv;
   1590 }
   1591 
   1592 /*
   1593  * Function:
   1594  *      phy_84749_linkup
   1595  * Purpose:
   1596  *      Link up handler
   1597  * Parameters:
   1598  *      unit  - StrataSwitch unit #.
   1599  *      port  - StrataSwitch port #.
   1600  * Returns:
   1601  *      SOC_E_NONE
   1602  */
   1603 STATIC int 
   1604 phy_84749_linkup(int unit, soc_port_t port)
   1605 {
   1606     int rv = SOC_E_NONE;
   1607     phy_ctrl_t    *pc;
   1608     bmacsec_dev_addr_t phy_dev_addr;
   1609     bmacsec_phy84749_intf_t line_mode;
   1610 
   1611     pc = EXT_PHY_SW_STATE(unit, port);
   1612 
   1613     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1614 
   1615     rv = bmacsec_phy84749_line_intf_get(phy_dev_addr, 0, &line_mode);
   1616     if (!BMACSEC_E_SUCCESS(rv)) {
   1617         return SOC_E_FAIL;
   1618     }
   1619 
   1620     rv = bmacsec_84749_phy_linkup(phy_dev_addr, pc->macsec_enable);
   1621 
   1622     if (line_mode == BMACSEC_PHY84749_INTF_SGMII) {
   1623         SOC_IF_ERROR_RETURN(
   1624           soc_phyctrl_notify(unit, port, phyEventInterface, SOC_PORT_IF_SGMII));
   1625     }
   1626 
   1627     return SOC_ERROR(rv);
   1628 }
   1629 
   1630 /*
   1631  * Function:
   1632  *      phy_84749_interface_get
   1633  * Purpose:
   1634  *      Get interface on a given port.
   1635  * Parameters:
   1636  *      unit  - StrataSwitch unit #.
   1637  *      port  - StrataSwitch port #.
   1638  *      pif   - Interface.
   1639  * Returns:
   1640  *      SOC_E_NONE
   1641  */
   1642 STATIC int
   1643 phy_84749_interface_get(int unit, soc_port_t port, soc_port_if_t *pif)
   1644 {
   1645     *pif = PHY_COPPER_MODE(unit, port) ? SOC_PORT_IF_SGMII : SOC_PORT_IF_XFI;
   1646     return SOC_E_NONE;
   1647 }
   1648 
   1649 /*
   1650  * Function:
   1651  *      phy_84749_probe
   1652  * Purpose:
   1653  *      Complement the generic phy probe routine to identify this phy when its
   1654  *      phy id0 and id1 is same as some other phy's.
   1655  * Parameters:
   1656  *      unit - StrataSwitch unit #.
   1657  *      pc   - phy ctrl descriptor.
   1658  * Returns:
   1659  *      SOC_E_NONE,SOC_E_NOT_FOUND and SOC_E_<error>
   1660  */
   1661 STATIC int
   1662 phy_84749_probe(int unit, phy_ctrl_t *pc)
   1663 {
   1664     uint16  data1, data2;
   1665 
   1666     if (READ_PHY84749_PMA_PMD_REG(unit, pc, 0xc802, &data1) < 0) {
   1667         return SOC_E_NOT_FOUND;
   1668     }
   1669 
   1670     if (READ_PHY84749_PMA_PMD_REG(unit, pc, 0xc803, &data2) < 0) {
   1671         return SOC_E_NOT_FOUND;
   1672     }
   1673 
   1674     if ((data2 & 0xf) == 0x8) {
   1675 
   1676         switch (data1) {
   1677 
   1678             case 0x4728:
   1679             case 0x4748:
   1680                 if (0x8700 != soc_property_port_get(unit, 
   1681                                                     pc->port,
   1682                                                     spn_PORT_PHY_ID1, 0)){
   1683                     return SOC_E_NOT_FOUND;
   1684                 }
   1685             /* fall through */
   1686             case 0x4729:
   1687             case 0x4749:
   1688 
   1689                 /* pc->size = sizeof(phy84749_map_t); */
   1690                 return SOC_E_NONE;
   1691         }
   1692     }
   1693 
   1694     return SOC_E_NOT_FOUND;
   1695 }
   1696 
   1697 /*
   1698  * Function:
   1699  *      phy_84749_timesync_config_set
   1700  * Description:
   1701  *      
   1702  * Parameters:
   1703  *
   1704  * Return Value:
   1705  *      SOC_E_XXX
   1706  */
   1707 
   1708 int
   1709 phy_84749_timesync_config_set(int unit, soc_port_t port, soc_port_phy_timesync_config_t *timesync_config)
   1710 {
   1711     int                          rv;
   1712     phy_ctrl_t                   *pc;
   1713     bmacsec_dev_addr_t phy_dev_addr;
   1714 
   1715     pc = EXT_PHY_SW_STATE(unit, port);
   1716     rv = SOC_E_NONE;
   1717     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1718  
   1719     rv = bmacsec_phy84749_timesync_config_set(phy_dev_addr, (bmacsec_port_phy_timesync_config_t *)timesync_config);
   1720     return (SOC_ERROR(rv));
   1721 
   1722 }
   1723 
   1724 /*
   1725  * Function:
   1726  *     phy_84749_timesync_config_get 
   1727  * Description:
   1728  *     
   1729  * Parameters:
   1730  *
   1731  * Return Value:
   1732  *      SOC_E_XXX
   1733  */
   1734 
   1735 int
   1736 phy_84749_timesync_config_get(int unit, soc_port_t port, soc_port_phy_timesync_config_t *timesync_config)
   1737 {
   1738     int                          rv;
   1739     phy_ctrl_t                   *pc;
   1740     bmacsec_dev_addr_t phy_dev_addr;
   1741 
   1742     pc = EXT_PHY_SW_STATE(unit, port);
   1743     rv = SOC_E_NONE;
   1744     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1745  
   1746     rv = bmacsec_phy84749_timesync_config_get(phy_dev_addr, (bmacsec_port_phy_timesync_config_t *)timesync_config);
   1747     return (SOC_ERROR(rv));
   1748 
   1749 }
   1750 
   1751 /*
   1752  * Function:
   1753  *      phy_84749_timesync_control_set
   1754  * Description:
   1755  *      
   1756  * Parameters:
   1757  *
   1758  * Return Value:
   1759  *      SOC_E_XXX
   1760  */
   1761 
   1762 int
   1763 phy_84749_timesync_control_set(int unit, soc_port_t port, soc_port_control_phy_timesync_t control_type, uint64 value)
   1764 {
   1765     int                          rv;
   1766     phy_ctrl_t                   *pc;
   1767     bmacsec_dev_addr_t phy_dev_addr;
   1768     buint64_t btemp64;
   1769 
   1770     COMPILER_64_SET(btemp64, COMPILER_64_HI(value), COMPILER_64_LO(value)); 
   1771 
   1772     pc = EXT_PHY_SW_STATE(unit, port);
   1773     rv = SOC_E_NONE;
   1774     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1775  
   1776     rv = bmacsec_phy84749_timesync_control_set(phy_dev_addr, control_type, btemp64);
   1777     return (SOC_ERROR(rv));
   1778 
   1779 }
   1780 
   1781 /*
   1782  * Function:
   1783  *      phy_84749_timesync_control_get
   1784  * Description:
   1785  *      
   1786  * Parameters:
   1787  *
   1788  * Return Value:
   1789  *      SOC_E_XXX
   1790  */
   1791 int
   1792 phy_84749_timesync_control_get(int unit, soc_port_t port, soc_port_control_phy_timesync_t control_type, uint64 *value)
   1793 {
   1794     int                          rv;
   1795     phy_ctrl_t                   *pc;
   1796     bmacsec_dev_addr_t phy_dev_addr;
   1797     buint64_t btemp64;
   1798 
   1799     COMPILER_64_ZERO(btemp64);
   1800     pc = EXT_PHY_SW_STATE(unit, port);
   1801     rv = SOC_E_NONE;
   1802     phy_dev_addr = SOC_MACSECPHY_MDIO_ADDR(unit, pc->phy_id, 1);
   1803  
   1804     rv = bmacsec_phy84749_timesync_control_get(phy_dev_addr, control_type, &btemp64);
   1805   
   1806     COMPILER_64_SET(*value, COMPILER_64_HI(btemp64), COMPILER_64_LO(btemp64));
   1807 
   1808     return (SOC_ERROR(rv));
   1809 
   1810 }
   1811 
   1812 
   1813 /*
   1814  * Variable:
   1815  *    phy_84749_drv
   1816  * Purpose:
   1817  *    Phy Driver for BCM84749 MACSEC PHY
   1818  */
   1819 
   1820 phy_driver_t phy_84749drv_xe = {
   1821     "84749 1G/10-Gigabit PHY Driver",
   1822     phy_84749_init,        /* Init */
   1823     phy_null_reset,       /* Reset */
   1824     phy_84749_link_get,    /* Link get   */
   1825     phy_84749_enable_set,  /* Enable set */
   1826     phy_null_enable_get,  /* Enable get */
   1827     phy_84749_duplex_set,  /* Duplex set */
   1828     phy_84749_duplex_get,  /* Duplex get */
   1829     phy_84749_speed_set,   /* Speed set  */
   1830     phy_84749_speed_get,   /* Speed get  */
   1831     phy_null_set,          /* Master set */
   1832     phy_null_zero_get,     /* Master get */
   1833     phy_84749_an_set,      /* ANA set */
   1834     phy_84749_an_get,      /* ANA get */
   1835     NULL,                 /* Local Advert set, deprecated */
   1836     NULL,                 /* Local Advert get, deprecated */
   1837     NULL,                 /* Remote Advert get, deprecated */
   1838     phy_84749_lb_set,      /* PHY loopback set */
   1839     phy_84749_lb_get,      /* PHY loopback set */
   1840     phy_null_interface_set, /* IO Interface set */
   1841     phy_84749_interface_get, /* IO Interface get */
   1842     NULL,                   /* pd_ability, deprecated */
   1843     phy_84749_linkup,
   1844     NULL,
   1845     phy_null_mdix_set,        /* phy_84749_mdix_set */
   1846     phy_null_mdix_get,        /* phy_84749_mdix_get */
   1847     phy_null_mdix_status_get, /* phy_84749_mdix_status_get */
   1848     phy_84749_medium_config_set, /* medium config setting set */
   1849     phy_84749_medium_config_get, /* medium config setting get */
   1850     phy_84749_medium_status,        /* active medium */
   1851     NULL,                    /* phy_cable_diag  */
   1852     NULL,                    /* phy_link_change */
   1853     phy_84749_control_set,    /* phy_control_set */
   1854     phy_84749_control_get,    /* phy_control_get */
   1855     NULL,                    /* phy_reg_read */
   1856     NULL,                    /* phy_reg_write */
   1857     NULL,                    /* phy_reg_modify */
   1858     NULL,                    /* phy_notify */
   1859     phy_84749_probe,         /* pd_probe  */
   1860     phy_84749_ability_advert_set,  /* pd_ability_advert_set */
   1861     phy_84749_ability_advert_get,  /* pd_ability_advert_get */
   1862     phy_84749_ability_remote_get,  /* pd_ability_remote_get */
   1863     phy_84749_ability_local_get,   /* pd_ability_local_get  */
   1864     phy_84749_firmware_set,
   1865     phy_84749_timesync_config_set,
   1866     phy_84749_timesync_config_get,
   1867     phy_84749_timesync_control_set,
   1868     phy_84749_timesync_control_get
   1869 };
   1870 
   1871 #else /* INCLUDE_PHY_84749 */
   1872 int _phy_84749_not_empty;
   1873 #endif /* INCLUDE_PHY_84749 */
   1874 #endif /* INCLUDE_MACSEC */