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

gxumac.c (38285B)


      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  * XGS Media Access Controller Driver for port with multiple MACs such as:
      8  *     Port with BigMAC and UniMAC or
      9  *     Port with XMAC and UniMAC
     10  *
     11  * The general idea is to have this "pseudo" driver act like a wrapper to
     12  * 10G MAC (BigMAC or XMAC) driver and GE MAC (UniMAC) driver. Depends on the
     13  * nature of individual driver funciton, some functions will call corresponding
     14  * function in both MAC drivers, some just call the the function in the active
     15  * MAC driver.
     16  *
     17  * Use _mac_combo_mode_get to determine which driver is currently active.
     18  * Should not make decision upon the link speed from XGXS, it is only accurate
     19  * when link is up, however some driver function may be called regardless of
     20  * the link status.
     21  */
     22 
     23 #include <shared/bsl.h>
     24 
     25 #include <soc/drv.h>
     26 #include <soc/debug.h>
     27 #ifdef BCM_TRIUMPH_SUPPORT
     28 #include <soc/triumph.h>
     29 #endif /* BCM_TRIUMPH_SUPPORT */
     30 #ifdef BCM_TRIUMPH2_SUPPORT
     31 #include <soc/triumph2.h>
     32 #endif /* BCM_TRIUMPH2_SUPPORT */
     33 #ifdef BCM_HURRICANE_SUPPORT
     34 #include <soc/hurricane.h>
     35 #endif /* BCM_HURRICANE_SUPPORT */
     36 
     37 #if defined(BCM_BIGMAC_SUPPORT) || defined(BCM_XMAC_SUPPORT) || defined(BCM_CMAC_SUPPORT) ||\
     38     defined(BCM_UNIMAC_SUPPORT)
     39 
     40 STATIC mac_driver_t *
     41 _mac_combo_ge_mac(int unit)
     42 {
     43 #ifdef BCM_UNIPORT_SUPPORT
     44     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
     45         return &soc_mac_x;
     46     } else 
     47 #endif
     48     {
     49         return &soc_mac_uni;
     50     }
     51 }
     52 
     53 STATIC mac_driver_t *
     54 _mac_combo_10g_mac(int unit)
     55 {
     56     mac_driver_t *mac = NULL;
     57 
     58 #ifdef BCM_XMAC_SUPPORT
     59     if (soc_feature(unit, soc_feature_xmac)) {
     60         return &soc_mac_x;
     61     }
     62 #endif /* BCM_XMAC_SUPPORT */
     63 #ifdef BCM_BIGMAC_SUPPORT
     64     mac = &soc_mac_big;
     65 #endif /* BCM_BIGMAC_SUPPORT */
     66 
     67     return mac;
     68 }
     69 
     70 #ifdef BCM_CMAC_SUPPORT
     71 STATIC mac_driver_t *
     72 _mac_combo_100g_mac(int unit)
     73 {
     74     mac_driver_t *mac = NULL;
     75     if (soc_feature(unit, soc_feature_cmac)) {
     76         return &soc_mac_c;
     77     }
     78     return mac;
     79 }
     80 #endif /* BCM_CMAC_SUPPORT */
     81 
     82 /*
     83  * Function:
     84  *     _xgmac_select_mode
     85  * Purpose:
     86  *     Select current MAC
     87  * Parameters:
     88  *     unit - XGS unit #.
     89  *     port - Port number on unit.
     90  *     mode - new MAC mode (SOC_MAC_MODE_XXX).
     91  * Returns:
     92  *     SOC_E_NONE
     93  */
     94 STATIC int
     95 _mac_combo_select_mac(int unit, soc_port_t port, soc_mac_mode_t mode)
     96 {
     97     if (LOG_CHECK(BSL_LS_SOC_10G | BSL_VERBOSE) ||
     98         LOG_CHECK(BSL_LS_SOC_GE | BSL_VERBOSE)) {
     99         LOG_CLI((BSL_META_U(unit,
    100                             "_mac_combo_select_mac: unit %d port %s mode %s\n"),
    101                  unit, SOC_PORT_NAME(unit, port),
    102                  mode == SOC_MAC_MODE_10000 ? "10G" : "GE"));
    103     }
    104 
    105 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT)
    106     if (!SOC_IS_TRIUMPH3(unit) && IS_XL_PORT(unit, port)) {
    107         soc_info_t *si;
    108         int phy_port, bindex;
    109         soc_field_t field[] = { PORT0_MAC_MODEf, PORT1_MAC_MODEf,
    110                                 PORT2_MAC_MODEf, PORT3_MAC_MODEf };
    111 
    112         si = &SOC_INFO(unit);
    113         if (soc_feature(unit, soc_feature_logical_port_num)) {
    114             phy_port = si->port_l2p_mapping[port];
    115         } else {
    116             phy_port = port;
    117         }
    118         if (phy_port == -1) {
    119             return SOC_E_INTERNAL;
    120         }
    121         bindex = SOC_PORT_BINDEX(unit, phy_port);
    122         SOC_IF_ERROR_RETURN
    123             (soc_reg_field32_modify(unit, XLPORT_MODE_REGr, port,
    124                                     field[bindex],
    125                                     mode == SOC_MAC_MODE_10000 ? 0 : 1));
    126         return SOC_E_NONE;
    127     }
    128 #endif /* BCM_TRIDENT_SUPPORT */
    129 
    130 #ifdef BCM_TRIUMPH3_SUPPORT
    131     if (SOC_IS_TRIUMPH3(unit) && IS_CL_PORT(unit, port)) {
    132         soc_info_t *si;
    133         int phy_port, bindex;
    134         si = &SOC_INFO(unit);
    135         phy_port = si->port_l2p_mapping[port];
    136         bindex = SOC_PORT_BINDEX(unit, phy_port);
    137         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    138                     (BSL_META_U(unit,
    139                                 "cl port: %d, phy_port: %d, bindex %d\n"), 
    140                      port, phy_port, bindex));
    141         SOC_IF_ERROR_RETURN
    142             (soc_reg_field32_modify(unit, PORT_MODE_REGr, port,
    143                                     MAC_MODEf,
    144                                     mode == SOC_MAC_MODE_100000 ? 1 : 0));
    145         return SOC_E_NONE;
    146     }
    147 #endif
    148 
    149 #ifdef BCM_KATANA_SUPPORT
    150     if (IS_MXQ_PORT(unit, port)) {
    151         int phy_port;
    152         /* MXQPORT2 = 27,32,33,34 and MXQPORT3 = 28,29,30,31 */
    153         if ((port >= 29) && (port <= 31)) {
    154             phy_port = 28;
    155         } else if ((port >= 32) && (port <= 34)) {
    156             phy_port = 27;
    157         } else {
    158             phy_port = port;
    159         }
    160         SOC_IF_ERROR_RETURN
    161             (soc_reg_field32_modify(unit, XPORT_MODE_REGr, phy_port,
    162                                 CORE_PORT_MODEf,
    163                                 mode == SOC_MAC_MODE_10000 ? 0 : 2));
    164         SOC_IF_ERROR_RETURN
    165             (soc_reg_field32_modify(unit, XPORT_MODE_REGr, phy_port,
    166                                 PHY_PORT_MODEf,
    167                                 mode == SOC_MAC_MODE_10000 ? 0 : 2));
    168         return SOC_E_NONE;
    169     }
    170 #endif /* BCM_KATANA_SUPPORT */
    171 
    172 #ifdef BCM_TRIUMPH_SUPPORT
    173     if (IS_XG_PORT(unit, port)) {
    174         return soc_triumph_xgport_mode_change(unit, port, mode);
    175     }
    176 #endif /* BCM_TRIUMPH_SUPPORT */
    177 
    178     SOC_IF_ERROR_RETURN
    179         (soc_reg_field32_modify(unit, XPORT_CONFIGr, port, XPORT_ENf,
    180                                 mode == SOC_MAC_MODE_10000 ? 1 : 0));
    181 
    182 #ifdef BCM_TRIUMPH2_SUPPORT
    183     if (IS_XQ_PORT(unit, port)) {
    184 #ifdef BCM_ENDURO_SUPPORT
    185         if (SOC_IS_ENDURO(unit)) {
    186             SOC_IF_ERROR_RETURN
    187                 (soc_reg_field32_modify(unit, XQPORT_MODE_REGr, port,
    188                                     XQPORT_MODE_BITSf,
    189                                     mode == SOC_MAC_MODE_10000 ? 2 : 1));
    190             return SOC_E_NONE;
    191         } else 
    192 #endif
    193 #ifdef BCM_HURRICANE1_SUPPORT
    194         if (SOC_IS_HURRICANE(unit)) {
    195             return soc_hu_xqport_mode_change(unit, port, mode);
    196         } else 
    197 #endif
    198         {
    199             return soc_tr2_xqport_mode_change(unit, port, mode);
    200         }
    201     } else 
    202 #endif /* BCM_TRIUMPH2_SUPPORT */
    203     {
    204         SOC_IF_ERROR_RETURN
    205             (soc_reg_field32_modify(unit, XPORT_MODE_REGr, port,
    206                                     XPORT_MODE_BITSf,
    207                                     mode == SOC_MAC_MODE_10000 ? 1 : 2));
    208     }
    209 
    210     return SOC_E_NONE;
    211 }
    212 
    213 STATIC int
    214 _mac_combo_mode_get(int unit, soc_port_t port, soc_mac_mode_t *mode)
    215 {
    216     uint32 rval;
    217     int bits;
    218 
    219 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT)
    220     if (!SOC_IS_TRIUMPH3(unit) && IS_XL_PORT(unit, port)) {
    221         soc_info_t *si;
    222         int phy_port, bindex;
    223         soc_field_t field[] = { PORT0_MAC_MODEf, PORT1_MAC_MODEf,
    224                                 PORT2_MAC_MODEf, PORT3_MAC_MODEf };
    225 
    226         si = &SOC_INFO(unit);
    227         if (soc_feature(unit, soc_feature_logical_port_num)) {
    228             phy_port = si->port_l2p_mapping[port];
    229         } else {
    230             phy_port = port;
    231         }
    232         if (phy_port == -1) {
    233             return SOC_E_INTERNAL;
    234         }
    235         bindex = SOC_PORT_BINDEX(unit, phy_port);
    236         SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port, &rval));
    237         bits = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, field[bindex]);
    238         *mode = bits == 0 ? SOC_MAC_MODE_10000 : SOC_MAC_MODE_1000_T;
    239         return SOC_E_NONE;
    240     }
    241 #endif /* BCM_TRIDENT_SUPPORT */
    242 #ifdef BCM_TRIUMPH3_SUPPORT
    243     if (SOC_IS_TRIUMPH3(unit) && IS_XL_PORT(unit, port)) {
    244         *mode = SOC_MAC_MODE_10000;
    245         return SOC_E_NONE;
    246     } else if (SOC_IS_TRIUMPH3(unit) && IS_XT_PORT(unit, port)) {
    247         *mode = SOC_MAC_MODE_10000;
    248         return SOC_E_NONE;
    249     } else if (SOC_IS_TRIUMPH3(unit) && IS_CL_PORT(unit, port)) {
    250         soc_info_t *si;
    251         int phy_port, bindex;
    252 
    253         si = &SOC_INFO(unit);
    254         phy_port = si->port_l2p_mapping[port];
    255         bindex = SOC_PORT_BINDEX(unit, phy_port);
    256         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    257                     (BSL_META_U(unit,
    258                                 "cl port: %d, phy_port: %d, bindex %d\n"), 
    259                      port, phy_port, bindex));
    260         SOC_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval));
    261         bits = soc_reg_field_get(unit, PORT_MODE_REGr, rval, MAC_MODEf);
    262         *mode = bits == 0 ? SOC_MAC_MODE_10000 : SOC_MAC_MODE_100000;
    263         return SOC_E_NONE;
    264     }
    265 #endif
    266 
    267 #ifdef BCM_KATANA_SUPPORT
    268     if (IS_MXQ_PORT(unit, port)) {
    269         /* MXQPORT2 = 27,32,33,34 and MXQPORT3 = 28,29,30,31 */
    270         if ((port >= 29) && (port <= 31)) {
    271             SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, 28, &rval));
    272         } else if ((port >= 32) && (port <= 34)) {
    273             SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, 27, &rval));
    274         } else {
    275             SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval));
    276         }
    277         bits = soc_reg_field_get(unit, XPORT_MODE_REGr, rval,
    278                                  CORE_PORT_MODEf);
    279         if (bits == 0) { /* 10G+ Mode */
    280             *mode = SOC_MAC_MODE_10000;
    281         } else if (bits == 2) { /* 1G/2.5G Mode */
    282             *mode = SOC_MAC_MODE_1000_T;
    283         } else { /* disabled or other modes */
    284             return SOC_E_FAIL;
    285         }
    286         return SOC_E_NONE;
    287     }
    288 #endif /* BCM_KATANA_SUPPORT */
    289 
    290     if (IS_XG_PORT(unit, port)) {
    291         SOC_IF_ERROR_RETURN(READ_XGPORT_MODE_REGr(unit, port, &rval));
    292         bits = soc_reg_field_get(unit, XGPORT_MODE_REGr, rval,
    293                                  XGPORT_MODE_BITSf);
    294         if (bits == 2) { /* xport-mode */
    295             *mode = SOC_MAC_MODE_10000;
    296         } else if (bits == 1) { /* gport-mode */
    297             *mode = SOC_MAC_MODE_1000_T;
    298         } else { /* disabled or other modes */
    299             return SOC_E_FAIL;
    300         }
    301     } else if (IS_XQ_PORT(unit, port)) {
    302         SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval));
    303         bits = soc_reg_field_get(unit, XQPORT_MODE_REGr, rval,
    304                                  XQPORT_MODE_BITSf);
    305         if (bits == 2) { /* xport-mode */
    306             *mode = SOC_MAC_MODE_10000;
    307         } else if (bits == 1) { /* gport-mode */
    308             *mode = SOC_MAC_MODE_1000_T;
    309         } else { /* disabled or other modes */
    310             return SOC_E_FAIL;
    311         }
    312     } else {
    313         SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval));
    314         bits = soc_reg_field_get(unit, XPORT_MODE_REGr, rval,
    315                                  XPORT_MODE_BITSf);
    316         if (bits == 1) { /* xport-mode */
    317             *mode = SOC_MAC_MODE_10000;
    318         } else if (bits == 2) { /* gport-mode */
    319             *mode = SOC_MAC_MODE_1000_T;
    320         } else { /* disabled */
    321             return SOC_E_FAIL;
    322         }
    323     }
    324 
    325     return SOC_E_NONE;
    326 }
    327 
    328 /*
    329  * Function:
    330  *      mac_combo_init
    331  * Purpose:
    332  *      Initialize 10G MAC and GE MAC into a known good state.
    333  * Parameters:
    334  *      unit - XGS unit #.
    335  *      port - Port number on unit.
    336  * Returns:
    337  *      SOC_E_XXX
    338  * Notes:
    339  */
    340 STATIC int
    341 mac_combo_init(int unit, soc_port_t port)
    342 {
    343     soc_mac_mode_t mode;
    344 
    345     /*
    346      * Initialize GE MAC
    347      */
    348     if (!SOC_IS_TRIUMPH3(unit) && !SOC_IS_KATANAX(unit)) {
    349         SOC_IF_ERROR_RETURN(_mac_combo_ge_mac(unit)->md_init(unit, port));
    350     } 
    351 
    352     /*
    353      * Initialize 10G MAC
    354      */
    355     SOC_IF_ERROR_RETURN(_mac_combo_10g_mac(unit)->md_init(unit, port));
    356 
    357 #ifdef BCM_CMAC_SUPPORT
    358     /*
    359      * Initialize 100G MAC if applicable
    360      */
    361     if (IS_CE_PORT(unit, port)) {
    362         SOC_IF_ERROR_RETURN(_mac_combo_100g_mac(unit)->md_init(unit, port));
    363     }
    364 #endif
    365 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT)
    366     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) {
    367         return SOC_E_NONE;
    368     }
    369 #endif
    370     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    371     if (mode == SOC_MAC_MODE_100000) {
    372         SOC_IF_ERROR_RETURN(
    373             _mac_combo_select_mac(unit, port, SOC_MAC_MODE_100000));
    374     } else if (mode == SOC_MAC_MODE_10000) {
    375         SOC_IF_ERROR_RETURN(
    376             _mac_combo_select_mac(unit, port, SOC_MAC_MODE_10000));
    377     } else {
    378         SOC_IF_ERROR_RETURN(
    379             _mac_combo_select_mac(unit, port, SOC_MAC_MODE_1000_T));
    380     }
    381     return SOC_E_NONE;
    382 }
    383 
    384 /*
    385  * Function:
    386  *      mac_combo_enable_set
    387  * Purpose:
    388  *      Enable or disable MAC
    389  * Parameters:
    390  *      unit - XGS unit #.
    391  *      port - Port number on unit.
    392  *      enable - TRUE to enable, FALSE to disable
    393  * Returns:
    394  *      SOC_E_XXX
    395  */
    396 STATIC int
    397 mac_combo_enable_set(int unit, soc_port_t port, int enable)
    398 {
    399     soc_mac_mode_t mode;
    400 
    401     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    402 #ifdef BCM_CMAC_SUPPORT
    403     if (mode == SOC_MAC_MODE_100000) {
    404         return _mac_combo_100g_mac(unit)->md_enable_set(unit, port, enable);
    405     } else 
    406 #endif
    407     if (mode == SOC_MAC_MODE_10000) {
    408         return _mac_combo_10g_mac(unit)->md_enable_set(unit, port, enable);
    409     } else {
    410         return _mac_combo_ge_mac(unit)->md_enable_set(unit, port, enable);
    411     }
    412 }
    413 
    414 /*
    415  * Function:
    416  *      mac_combo_enable_get
    417  * Purpose:
    418  *      Get MAC enable state
    419  * Parameters:
    420  *      unit - XGS unit #.
    421  *      port - Port number on unit.
    422  *      enable - (OUT) TRUE if enabled, FALSE if disabled
    423  * Returns:
    424  *      SOC_E_XXX
    425  */
    426 STATIC int
    427 mac_combo_enable_get(int unit, soc_port_t port, int *enable)
    428 {
    429     int enable_ge = 0, enable_10g = 0;
    430 #if defined(BCM_CMAC_SUPPORT) && defined(BCM_UNIPORT_SUPPORT)
    431     int enable_100g = 0;
    432 #endif
    433 
    434     /* Instead of checking the current mode we read from all MACs */
    435 
    436 #ifdef BCM_UNIPORT_SUPPORT
    437     if (SOC_IS_TRIUMPH3(unit)) {
    438         SOC_IF_ERROR_RETURN
    439         (_mac_combo_10g_mac(unit)->md_enable_get(unit, port, &enable_10g));
    440 #ifdef BCM_CMAC_SUPPORT
    441         if (IS_CL_PORT(unit, port)) {
    442             SOC_IF_ERROR_RETURN
    443             (_mac_combo_100g_mac(unit)->md_enable_get(unit, port, 
    444                                                       &enable_100g));
    445         }
    446         *enable = enable_10g | enable_100g;
    447 #else
    448         *enable = enable_10g;
    449 #endif
    450         return SOC_E_NONE;
    451     }
    452 #endif
    453     /* GE MAC */
    454     SOC_IF_ERROR_RETURN
    455         (_mac_combo_ge_mac(unit)->md_enable_get(unit, port, &enable_ge));
    456     /* 10G MAC */
    457     SOC_IF_ERROR_RETURN
    458         (_mac_combo_10g_mac(unit)->md_enable_get(unit, port, &enable_10g));
    459 
    460     *enable = enable_ge | enable_10g;
    461 
    462     return SOC_E_NONE;
    463 }
    464 
    465 /*
    466  * Function:
    467  *      mac_combo_duplex_set
    468  * Purpose:
    469  *      Set  mac_combo in the specified duplex mode.
    470  * Parameters:
    471  *      unit - XGS unit #.
    472  *      port - XGS port # on unit.
    473  *      duplex - Boolean: true --> full duplex, false --> half duplex.
    474  * Returns:
    475  *      SOC_E_XXX
    476  * Notes:
    477  */
    478 STATIC int
    479 mac_combo_duplex_set(int unit, soc_port_t port, int duplex)
    480 {
    481     if (IS_GE_PORT(unit, port)) {
    482         return _mac_combo_ge_mac(unit)->md_duplex_set(unit, port, duplex);
    483     }
    484 
    485     return SOC_E_NONE;
    486 }
    487 
    488 /*
    489  * Function:
    490  *      mac_combo_duplex_get
    491  * Purpose:
    492  *      Get mac_combo duplex mode.
    493  * Parameters:
    494  *      unit - XGS unit #.
    495  *      duplex - (OUT) Boolean: true --> full duplex, false --> half duplex.
    496  * Returns:
    497  *      SOC_E_XXX
    498  */
    499 STATIC int
    500 mac_combo_duplex_get(int unit, soc_port_t port, int *duplex)
    501 {
    502     soc_mac_mode_t mode;
    503 
    504     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    505     if ((mode == SOC_MAC_MODE_10000) || (mode == SOC_MAC_MODE_100000)) {
    506         *duplex = TRUE;
    507         return SOC_E_NONE;
    508     } else {
    509         return _mac_combo_ge_mac(unit)->md_duplex_get(unit, port, duplex);
    510     }
    511 }
    512 
    513 /*
    514  * Function:
    515  *      mac_combo_speed_set
    516  * Purpose:
    517  *      Set mac_combo speed.
    518  * Parameters:
    519  *      unit - XGS unit #.
    520  *      port - XGS port # on unit.
    521  *      speed - 1000, 2500, ... 16000.
    522  * Returns:
    523  *      SOC_E_NONE
    524  */
    525 STATIC int
    526 mac_combo_speed_set(int unit, soc_port_t port, int speed)
    527 {
    528     int enable;
    529     soc_mac_mode_t mode, new_mode;
    530     int rv = SOC_E_NONE;
    531 
    532     if (IS_HG_PORT(unit, port)) {
    533         if (speed && speed < 10000) {
    534             return SOC_E_PARAM;
    535         }
    536         if (SOC_INFO(unit).port_speed_max[port] > 0 &&
    537             speed > SOC_INFO(unit).port_speed_max[port]) {
    538                 /* make exception for 11G & 21G & 42G speeds*/
    539                 if (!((soc_feature(unit, soc_feature_higig_misc_speed_support))
    540                     && (((SOC_INFO(unit).port_speed_max[port] >= 40000) && speed == 42000)
    541                     || ((SOC_INFO(unit).port_speed_max[port] == 20000) && speed == 21000)
    542                     || ((SOC_INFO(unit).port_speed_max[port] == 10000) && speed == 11000)))) {
    543                     return SOC_E_PARAM;
    544                 }
    545         }
    546     } else {
    547         if (speed && speed < 0) {
    548             return SOC_E_PARAM;
    549         }
    550     }
    551     if (speed == 0) {
    552         return SOC_E_NONE; /* Transient state */
    553     }
    554 
    555     SOC_IF_ERROR_RETURN(mac_combo_enable_get(unit, port, &enable));
    556     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    557     new_mode = speed < 10000 ? SOC_MAC_MODE_1000_T : 
    558                                speed < 100000 ? SOC_MAC_MODE_10000 : SOC_MAC_MODE_100000;
    559 
    560     if (mode != new_mode) {
    561       rv = _mac_combo_select_mac(unit, port, new_mode);
    562     }
    563 
    564     /* Disable MACs before doing anything else */
    565     if (SOC_SUCCESS(rv)) {
    566         rv = mac_combo_enable_set(unit, port, 0);
    567     }
    568 
    569     if (SOC_SUCCESS(rv)) {
    570         if (speed <= 2500) {
    571             rv = _mac_combo_ge_mac(unit)->md_speed_set(unit, port, speed);
    572         } else if (speed <= 42000) {
    573             rv = _mac_combo_10g_mac(unit)->md_speed_set(unit, port, speed);
    574         } 
    575 #ifdef BCM_CMAC_SUPPORT
    576           else {
    577             rv = _mac_combo_100g_mac(unit)->md_speed_set(unit, port, speed);
    578         }
    579 #endif
    580     }
    581 
    582     if (SOC_SUCCESS(rv)) {
    583         if (mode != new_mode) {
    584             rv = _mac_combo_select_mac(unit, port, new_mode);
    585         }
    586     }
    587 
    588     /* Re-enable MAC */
    589     if (SOC_SUCCESS(rv)) {
    590         rv = mac_combo_enable_set(unit, port, enable);
    591     }
    592 
    593     return rv;
    594 }
    595 
    596 /*
    597  * Function:
    598  *      mac_combo_speed_get
    599  * Purpose:
    600  *      Get mac_combo speed
    601  * Parameters:
    602  *      unit - XGS unit #.
    603  *      port - XGS port # on unit.
    604  *      speed - (OUT) speed in Mbps
    605  * Returns:
    606  *      SOC_E_XXX
    607  */
    608 STATIC int
    609 mac_combo_speed_get(int unit, soc_port_t port, int *speed)
    610 {
    611     soc_mac_mode_t mode;
    612 
    613     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    614 #ifdef BCM_CMAC_SUPPORT
    615     if (mode == SOC_MAC_MODE_100000) {
    616         return _mac_combo_100g_mac(unit)->md_speed_get(unit, port, speed);
    617     } else 
    618 #endif
    619     if (mode == SOC_MAC_MODE_10000) {
    620         return _mac_combo_10g_mac(unit)->md_speed_get(unit, port, speed);
    621     } else {
    622         return _mac_combo_ge_mac(unit)->md_speed_get(unit, port, speed);
    623     }
    624 }
    625 
    626 /*
    627  * Function:
    628  *      mac_combo_pause_set
    629  * Purpose:
    630  *      Configure mac_combo to transmit/receive pause frames.
    631  * Parameters:
    632  *      unit - XGS unit #.
    633  *      port - XGS port # on unit.
    634  *      pause_tx - Boolean: transmit pause or -1 (don't change)
    635  *      pause_rx - Boolean: receive pause or -1 (don't change)
    636  * Returns:
    637  *      SOC_E_XXX
    638  */
    639 STATIC int
    640 mac_combo_pause_set(int unit, soc_port_t port, int pause_tx, int pause_rx)
    641 {
    642     if (!IS_HG_PORT(unit, port)) { /* Avoid stacking pause conflict */
    643         /* GE MAC */
    644         SOC_IF_ERROR_RETURN
    645             (_mac_combo_ge_mac(unit)->md_pause_set(unit, port, pause_tx,
    646                                                    pause_rx));
    647     }
    648 
    649     /* 10G MAC */
    650     SOC_IF_ERROR_RETURN
    651         (_mac_combo_10g_mac(unit)->md_pause_set(unit, port, pause_tx,
    652                                                 pause_rx));
    653 
    654 #ifdef BCM_CMAC_SUPPORT
    655     if (IS_CL_PORT(unit, port)) {
    656         /* 100G MAC */
    657         SOC_IF_ERROR_RETURN
    658         (_mac_combo_100g_mac(unit)->md_pause_set(unit, port, pause_tx,
    659                                                  pause_rx));
    660     }
    661 #endif
    662     return SOC_E_NONE;
    663 }
    664 
    665 /*
    666  * Function:
    667  *      mac_combo_pause_get
    668  * Purpose:
    669  *      Return the pause ability.
    670  * Parameters:
    671  *      unit - XGS unit #.
    672  *      port - XGS port # on unit.
    673  *      pause_tx - Boolean: transmit pause
    674  *      pause_rx - Boolean: receive pause
    675  *      pause_mac - MAC address used for pause transmission.
    676  * Returns:
    677  *      SOC_E_XXX
    678  */
    679 STATIC int
    680 mac_combo_pause_get(int unit, soc_port_t port, int *pause_tx, int *pause_rx)
    681 {
    682     soc_mac_mode_t mode;
    683 
    684     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    685 #ifdef BCM_CMAC_SUPPORT
    686     if (mode == SOC_MAC_MODE_100000) {
    687         return _mac_combo_100g_mac(unit)->md_pause_get(unit, port, pause_tx,
    688                                                        pause_rx);
    689     } else 
    690 #endif
    691     if (mode == SOC_MAC_MODE_10000) {
    692         return _mac_combo_10g_mac(unit)->md_pause_get(unit, port, pause_tx,
    693                                                       pause_rx);
    694     } else {
    695         return _mac_combo_ge_mac(unit)->md_pause_get(unit, port, pause_tx,
    696                                                      pause_rx);
    697     }
    698 }
    699 
    700 /*
    701  * Function:
    702  *      mac_combo_pause_addr_set
    703  * Purpose:
    704  *      Configure PAUSE frame source address.
    705  * Parameters:
    706  *      unit - XGS unit #.
    707  *      port - XGS port # on unit.
    708  *      pause_mac - (OUT) MAC address used for pause transmission.
    709  * Returns:
    710  *      SOC_E_XXX
    711  */
    712 STATIC int
    713 mac_combo_pause_addr_set(int unit, soc_port_t port, sal_mac_addr_t mac)
    714 {
    715     /* GE MAC */
    716     if (!SOC_IS_TRIUMPH3(unit)) {
    717         SOC_IF_ERROR_RETURN
    718         (_mac_combo_ge_mac(unit)->md_pause_addr_set(unit, port, mac));
    719     }
    720     /* 10G MAC */
    721     SOC_IF_ERROR_RETURN
    722         (_mac_combo_10g_mac(unit)->md_pause_addr_set(unit, port, mac));
    723 
    724 #ifdef BCM_CMAC_SUPPORT
    725     if (IS_CL_PORT(unit, port)) {
    726         /* 100G MAC */
    727         SOC_IF_ERROR_RETURN
    728         (_mac_combo_100g_mac(unit)->md_pause_addr_set(unit, port, mac));
    729     }
    730 #endif
    731     return SOC_E_NONE;
    732 }
    733 
    734 /*
    735  * Function:
    736  *      mac_combo_pause_addr_get
    737  * Purpose:
    738  *      Retrieve PAUSE frame source address.
    739  * Parameters:
    740  *      unit - XGS unit #.
    741  *      port - XGS port # on unit.
    742  *      pause_mac - (OUT) MAC address used for pause transmission.
    743  * Returns:
    744  *      SOC_E_XXX
    745  */
    746 STATIC int
    747 mac_combo_pause_addr_get(int unit, soc_port_t port, sal_mac_addr_t mac)
    748 {
    749     soc_mac_mode_t mode;
    750 
    751     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    752 #ifdef BCM_CMAC_SUPPORT
    753     if (mode == SOC_MAC_MODE_100000) {
    754         return _mac_combo_100g_mac(unit)->md_pause_addr_get(unit, port, mac);
    755     } else
    756 #endif
    757     if (mode == SOC_MAC_MODE_10000) {
    758         return _mac_combo_10g_mac(unit)->md_pause_addr_get(unit, port, mac);
    759     } else {
    760         return _mac_combo_ge_mac(unit)->md_pause_addr_get(unit, port, mac);
    761     }
    762 }
    763 
    764 /*
    765  * Function:
    766  *      mac_combo_loopback_set
    767  * Purpose:
    768  *      Set MAC loopback mode.
    769  * Parameters:
    770  *      unit - XGS unit #.
    771  *      port - XGS unit # on unit.
    772  *      loopback - Boolean: true -> loopback mode, false -> normal operation
    773  * Returns:
    774  *      SOC_E_XXX
    775  */
    776 STATIC int
    777 mac_combo_loopback_set(int unit, soc_port_t port, int lb)
    778 {
    779     if (!SOC_IS_TRIUMPH3(unit)) {
    780         /* GE MAC */
    781         SOC_IF_ERROR_RETURN(_mac_combo_ge_mac(unit)->md_lb_set(unit, port, lb));
    782     }
    783 
    784     /* 10G MAC */
    785     SOC_IF_ERROR_RETURN(_mac_combo_10g_mac(unit)->md_lb_set(unit, port, lb));
    786 
    787 #ifdef BCM_CMAC_SUPPORT
    788     if (IS_CL_PORT(unit, port)) {
    789         /* 100G MAC */
    790         SOC_IF_ERROR_RETURN(_mac_combo_100g_mac(unit)->md_lb_set(unit, port, lb));
    791     }
    792 #endif
    793 
    794 #if 0 
    795     /* Power lanes up/down? */
    796     soc_unicore16g_lane_power_set(unit, port, lb ? 0 : 0xf);
    797 #endif
    798 
    799     return SOC_E_NONE;
    800 }
    801 
    802 /*
    803  * Function:
    804  *      mac_combo_loopback_get
    805  * Purpose:
    806  *      Get current loopback mode setting.
    807  * Parameters:
    808  *      unit - XGS unit #.
    809  *      port - XGS port # on unit.
    810  *      loopback - (OUT) Boolean: true = loopback, false = normal
    811  * Returns:
    812  *      SOC_E_XXX
    813  */
    814 STATIC int
    815 mac_combo_loopback_get(int unit, soc_port_t port, int *lb)
    816 {
    817     soc_mac_mode_t mode;
    818 
    819     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    820 #ifdef BCM_CMAC_SUPPORT
    821     if (mode == SOC_MAC_MODE_100000) {
    822         return _mac_combo_100g_mac(unit)->md_lb_get(unit, port, lb);
    823     } else 
    824 #endif
    825     if (mode == SOC_MAC_MODE_10000) {
    826         return _mac_combo_10g_mac(unit)->md_lb_get(unit, port, lb);
    827     } else {
    828         return _mac_combo_ge_mac(unit)->md_lb_get(unit, port, lb);
    829     }
    830 }
    831 
    832 /*
    833  * Function:
    834  *      mac_combo_interface_set
    835  * Purpose:
    836  *      Set MAC interface type
    837  * Parameters:
    838  *      unit - XGS unit #.
    839  *      port - XGS port # on unit.
    840  *      pif - one of SOC_PORT_IF_*
    841  * Returns:
    842  *      SOC_E_NONE
    843  * Notes:
    844  */
    845 STATIC int
    846 mac_combo_interface_set(int unit, soc_port_t port, soc_port_if_t pif)
    847 {
    848     return SOC_E_NONE;
    849 }
    850 
    851 /*
    852  * Function:
    853  *      mac_combo_interface_get
    854  * Purpose:
    855  *      Retrieve MAC interface type
    856  * Parameters:
    857  *      unit - XGS unit #.
    858  *      port - XGS port # on unit.
    859  *      pif - (OUT) one of SOC_PORT_IF_*
    860  * Returns:
    861  *      SOC_E_NONE
    862  */
    863 STATIC int
    864 mac_combo_interface_get(int unit, soc_port_t port, soc_port_if_t *pif)
    865 {
    866     *pif = SOC_PORT_IF_MII;
    867     return SOC_E_NONE;
    868 }
    869 
    870 /*
    871  * Function:
    872  *      mac_combo_frame_max_set
    873  * Description:
    874  *      Set the maximum allowed receive frame size.
    875  * Parameters:
    876  *      unit - Device number
    877  *      port - Port number
    878  *      size - Maximum frame size in bytes
    879  * Return Value:
    880  *      BCM_E_XXX
    881  */
    882 STATIC int
    883 mac_combo_frame_max_set(int unit, soc_port_t port, int size)
    884 {
    885     /* GE MAC */
    886     if (!SOC_IS_TRIUMPH3(unit)) {
    887         SOC_IF_ERROR_RETURN
    888         (_mac_combo_ge_mac(unit)->md_frame_max_set(unit, port, size));
    889     }
    890 
    891     /* 10G MAC */
    892     SOC_IF_ERROR_RETURN
    893         (_mac_combo_10g_mac(unit)->md_frame_max_set(unit, port, size));
    894 
    895 #ifdef BCM_CMAC_SUPPORT
    896     if (IS_CL_PORT(unit, port)) {
    897         /* 100G MAC */
    898         SOC_IF_ERROR_RETURN
    899         (_mac_combo_100g_mac(unit)->md_frame_max_set(unit, port, size));
    900     }
    901 #endif
    902 
    903     return SOC_E_NONE;
    904 }
    905 
    906 /*
    907  * Function:
    908  *      mac_combo_frame_max_get
    909  * Description:
    910  *      Get the maximum allowed receive frame size.
    911  * Parameters:
    912  *      unit - Device number
    913  *      port - Port number
    914  *      size - Maximum frame size in bytes
    915  * Return Value:
    916  *      BCM_E_XXX
    917  */
    918 STATIC int
    919 mac_combo_frame_max_get(int unit, soc_port_t port, int *size)
    920 {
    921     soc_mac_mode_t mode;
    922 
    923     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
    924 #ifdef BCM_CMAC_SUPPORT
    925     if (mode == SOC_MAC_MODE_100000) {
    926         return _mac_combo_100g_mac(unit)->md_frame_max_get(unit, port, size);
    927     } else 
    928 #endif
    929     if (mode == SOC_MAC_MODE_10000) {
    930         return _mac_combo_10g_mac(unit)->md_frame_max_get(unit, port, size);
    931     } else {
    932         return _mac_combo_ge_mac(unit)->md_frame_max_get(unit, port, size);
    933     }
    934 }
    935 
    936 /*
    937  * Function:
    938  *      mac_combo_ifg_set
    939  * Description:
    940  *      Set ifg (Inter-frame gap) value
    941  * Parameters:
    942  *      unit   - Device number
    943  *      port   - Port number
    944  *      speed  - the speed for which the IFG is being set
    945  *      duplex - the duplex for which the IFG is being set
    946  *      ifg    - the IFG value
    947  * Return Value:
    948  *      BCM_E_XXX
    949  */
    950 STATIC int
    951 mac_combo_ifg_set(int unit, soc_port_t port, int speed,
    952                   soc_port_duplex_t duplex, int ifg)
    953 {
    954     if (speed < 10000) {
    955         /* GE MAC */
    956         return _mac_combo_ge_mac(unit)->md_ifg_set(unit, port, speed, duplex,
    957                                                    ifg);
    958     } else if (speed < 100000) {
    959         /* 10G MAC */
    960         return _mac_combo_10g_mac(unit)->md_ifg_set(unit, port, speed, duplex,
    961                                                     ifg);
    962     } 
    963 #ifdef BCM_CMAC_SUPPORT
    964       else {
    965         /* 100G MAC */
    966         return _mac_combo_100g_mac(unit)->md_ifg_set(unit, port, speed, duplex,
    967                                                      ifg);
    968     }
    969 #endif
    970     return SOC_E_PARAM;
    971 }
    972 
    973 /*
    974  * Function:
    975  *      mac_combo_ifg_get
    976  * Description:
    977  *      Get ifg (Inter-frame gap) value
    978  * Parameters:
    979  *      unit   - Device number
    980  *      port   - Port number
    981  *      speed  - the speed for which the IFG is being set
    982  *      duplex - the duplex for which the IFG is being set
    983  *      ifg    - the IFG value
    984  * Return Value:
    985  *      BCM_E_XXX
    986  */
    987 STATIC int
    988 mac_combo_ifg_get(int unit, soc_port_t port, int speed,
    989                   soc_port_duplex_t duplex, int *ifg)
    990 {
    991     if (speed < 10000) {
    992         /* GE MAC */
    993         return _mac_combo_ge_mac(unit)->md_ifg_get(unit, port, speed, duplex,
    994                                                    ifg);
    995     } else if (speed < 100000) {
    996         /* 10G MAC */
    997         return _mac_combo_10g_mac(unit)->md_ifg_get(unit, port, speed, duplex,
    998                                                     ifg);
    999     }
   1000 #ifdef BCM_CMAC_SUPPORT
   1001       else {
   1002         /* 100G MAC */
   1003         return _mac_combo_100g_mac(unit)->md_ifg_get(unit, port, speed, duplex,
   1004                                                      ifg);
   1005     }
   1006 #endif
   1007     return SOC_E_PARAM;
   1008 }
   1009 
   1010 /*
   1011  * Function:
   1012  *      mac_combo_encap_set
   1013  * Purpose:
   1014  *      Set MAC encapsulation type.
   1015  * Parameters:
   1016  *      unit - XGS unit #.
   1017  *      port - XGS port # on unit.
   1018  *      type - (IN) encap type.
   1019  * Returns:
   1020  *      SOC_E_XXX
   1021  */
   1022 STATIC int
   1023 mac_combo_encap_set(int unit, soc_port_t port, int type)
   1024 {
   1025     int rv = SOC_E_NONE;
   1026     rv = _mac_combo_10g_mac(unit)->md_encap_set(unit, port, type);
   1027     if (rv != SOC_E_NONE) {
   1028         return rv;
   1029     }
   1030 #ifdef BCM_CMAC_SUPPORT
   1031     if (IS_CL_PORT(unit, port)) {
   1032         return _mac_combo_100g_mac(unit)->md_encap_set(unit, port, type);
   1033     }
   1034 #endif
   1035     return rv;   
   1036 }
   1037 
   1038 /*
   1039  * Function:
   1040  *      mac_combo_encap_get
   1041  * Purpose:
   1042  *      Get MAC encapsulation type.
   1043  * Parameters:
   1044  *      unit - XGS unit #.
   1045  *      port - XGS port # on unit.
   1046  *      type - encap type.
   1047  * Returns:
   1048  *      SOC_E_XXX
   1049  */
   1050 STATIC int
   1051 mac_combo_encap_get(int unit, soc_port_t port, int *type)
   1052 {
   1053     soc_mac_mode_t mode;
   1054 
   1055     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
   1056 #ifdef BCM_CMAC_SUPPORT
   1057     if (mode == SOC_MAC_MODE_100000) {
   1058         return _mac_combo_100g_mac(unit)->md_encap_get(unit, port, type);
   1059     } else 
   1060 #endif
   1061     if (mode == SOC_MAC_MODE_10000) {
   1062         return _mac_combo_10g_mac(unit)->md_encap_get(unit, port, type);
   1063     } else {
   1064         return _mac_combo_ge_mac(unit)->md_encap_get(unit, port, type);
   1065     }
   1066 }
   1067 
   1068 /*
   1069  * Function:
   1070  *      mac_combo_control_set
   1071  * Purpose:
   1072  *      To configure MAC control properties.
   1073  * Parameters:
   1074  *      unit - XGS unit #.
   1075  *      port - XGS port # on unit.
   1076  *      type - MAC control property to set.
   1077  *      int  - New setting for MAC control.
   1078  * Returns:
   1079  *      SOC_E_XXX
   1080  */
   1081 STATIC int
   1082 mac_combo_control_set(int unit, soc_port_t port, soc_mac_control_t type,
   1083                       int value)
   1084 {
   1085     int rv = SOC_E_NONE;
   1086     soc_mac_mode_t mode;
   1087 
   1088     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
   1089 
   1090     switch (type) {
   1091     case SOC_MAC_CONTROL_RX_SET:
   1092     case SOC_MAC_CONTROL_TX_SET:
   1093     case SOC_MAC_CONTROL_SW_RESET:
   1094     case SOC_MAC_CONTROL_DISABLE_PHY:
   1095     case SOC_MAC_CONTROL_EGRESS_DRAIN:
   1096 #ifdef BCM_CMAC_SUPPORT
   1097         if (mode == SOC_MAC_MODE_100000) {
   1098             rv = _mac_combo_100g_mac(unit)->md_control_set(unit, port, type,
   1099                                                              value);
   1100         } else
   1101 #endif 
   1102         if (mode == SOC_MAC_MODE_10000) {
   1103             rv = _mac_combo_10g_mac(unit)->md_control_set(unit, port, type,
   1104                                                             value);
   1105         } else {
   1106             rv = _mac_combo_ge_mac(unit)->md_control_set(unit, port, type,
   1107                                                            value);
   1108         }
   1109         break;
   1110     default:
   1111         if (!SOC_IS_TRIUMPH3(unit)) {
   1112             rv = _mac_combo_ge_mac(unit)->md_control_set(unit, port, type, 
   1113                                                            value);
   1114         }
   1115         if (SOC_SUCCESS(rv) || rv == SOC_E_UNAVAIL) {
   1116             rv = _mac_combo_10g_mac(unit)->md_control_set(unit, port, type, 
   1117                                                             value);
   1118         }
   1119 #ifdef BCM_CMAC_SUPPORT
   1120         if (IS_CL_PORT(unit, port) &&
   1121             (SOC_SUCCESS(rv) || rv == SOC_E_UNAVAIL)) {
   1122             rv = _mac_combo_100g_mac(unit)->md_control_set(unit, port, type, 
   1123                                                               value);
   1124         }
   1125 #endif 
   1126     }
   1127 
   1128     return rv;
   1129 }
   1130 
   1131 /*
   1132  * Function:
   1133  *      mac_combo_control_get
   1134  * Purpose:
   1135  *      To get current MAC control setting.
   1136  * Parameters:
   1137  *      unit - XGS unit #.
   1138  *      port - XGS port # on unit.
   1139  *      type - MAC control property to set.
   1140  *      int  - New setting for MAC control.
   1141  * Returns:
   1142  *      SOC_E_XXX
   1143  */
   1144 STATIC int
   1145 mac_combo_control_get(int unit, soc_port_t port, soc_mac_control_t type,
   1146                       int *value)
   1147 {
   1148     soc_mac_mode_t mode;
   1149 
   1150     SOC_IF_ERROR_RETURN(_mac_combo_mode_get(unit, port, &mode));
   1151 #ifdef BCM_CMAC_SUPPORT
   1152     if (mode == SOC_MAC_MODE_100000) {
   1153         return _mac_combo_100g_mac(unit)->md_control_get(unit, port, type,
   1154                                                         value);
   1155     } else
   1156 #endif
   1157     if (mode == SOC_MAC_MODE_10000) {
   1158         return _mac_combo_10g_mac(unit)->md_control_get(unit, port, type,
   1159                                                         value);
   1160     } else {
   1161         return _mac_combo_ge_mac(unit)->md_control_get(unit, port, type,
   1162                                                        value);
   1163     }
   1164 }
   1165 
   1166 /*
   1167  * Function:
   1168  *      mac_combo_ability_local_get
   1169  * Purpose:
   1170  *      Get MAC abilities.
   1171  * Parameters:
   1172  *      unit - XGS unit #.
   1173  *      port - XGS port # on unit.
   1174  *      mode - (OUT) Supported operating modes as a mask of abilities.
   1175  * Returns:
   1176  *      SOC_E_XXX
   1177  */
   1178 STATIC  int
   1179 mac_combo_ability_local_get(int unit, soc_port_t port,
   1180                             soc_port_ability_t *ability)
   1181 {
   1182     soc_port_ability_t mac_ability_ge, mac_ability_10g; 
   1183 #if defined(BCM_UNIPORT_SUPPORT) || defined(BCM_CMAC_SUPPORT)
   1184     soc_port_ability_t mac_ability_100g = { 0 };
   1185 #endif
   1186 
   1187     if (NULL == ability) {
   1188         return SOC_E_PARAM;
   1189     }
   1190 
   1191     sal_memset(&mac_ability_ge, 0, sizeof(mac_ability_ge));
   1192     sal_memset(&mac_ability_10g, 0, sizeof(mac_ability_10g));
   1193 
   1194     if ((!IS_HG_PORT(unit, port)) && (!SOC_IS_TRIUMPH3(unit))) {
   1195         /* GE MAC */
   1196         SOC_IF_ERROR_RETURN
   1197             (_mac_combo_ge_mac(unit)->md_ability_local_get(unit, port,
   1198                                                            &mac_ability_ge));
   1199     }
   1200 
   1201     /*  10G MAC */
   1202     SOC_IF_ERROR_RETURN
   1203         (_mac_combo_10g_mac(unit)->md_ability_local_get(unit, port,
   1204                                                         &mac_ability_10g));
   1205 
   1206 #ifdef BCM_CMAC_SUPPORT
   1207     if (IS_CL_PORT(unit, port)) {
   1208         /*  10G MAC */
   1209         SOC_IF_ERROR_RETURN
   1210         (_mac_combo_100g_mac(unit)->md_ability_local_get(unit, port,
   1211                                                          &mac_ability_100g));
   1212     }
   1213 #endif
   1214 #if defined(BCM_UNIPORT_SUPPORT) || defined(BCM_CMAC_SUPPORT)
   1215     if (SOC_IS_TRIUMPH3(unit)) {
   1216         ability->speed_half_duplex =
   1217             mac_ability_10g.speed_half_duplex | mac_ability_100g.speed_half_duplex;
   1218         ability->speed_full_duplex =
   1219             mac_ability_10g.speed_full_duplex | mac_ability_100g.speed_full_duplex;
   1220         ability->pause = mac_ability_10g.pause | mac_ability_100g.pause;
   1221         ability->interface = mac_ability_10g.interface | mac_ability_100g.interface;
   1222         ability->medium = mac_ability_10g.medium | mac_ability_100g.medium;
   1223         ability->loopback = mac_ability_10g.loopback | mac_ability_100g.loopback;
   1224         ability->flags = mac_ability_10g.flags | mac_ability_100g.flags;
   1225 
   1226         return SOC_E_NONE;
   1227     }    
   1228 #endif
   1229     ability->speed_half_duplex =
   1230         mac_ability_ge.speed_half_duplex | mac_ability_10g.speed_half_duplex;
   1231     ability->speed_full_duplex =
   1232         mac_ability_ge.speed_full_duplex | mac_ability_10g.speed_full_duplex;
   1233     ability->pause = mac_ability_ge.pause | mac_ability_10g.pause;
   1234     ability->interface = mac_ability_ge.interface | mac_ability_10g.interface;
   1235     ability->medium = mac_ability_ge.medium | mac_ability_10g.medium;
   1236     ability->loopback = mac_ability_ge.loopback | mac_ability_10g.loopback;
   1237     ability->flags = mac_ability_ge.flags | mac_ability_10g.flags;
   1238     ability->encap = mac_ability_ge.encap | mac_ability_10g.encap;
   1239 
   1240     return SOC_E_NONE;
   1241 }
   1242 
   1243 /* Exported combo MAC driver structure */
   1244 mac_driver_t soc_mac_combo = {
   1245     "Combo MAC Driver",            /* drv_name */
   1246     mac_combo_init,                /* md_init  */
   1247     mac_combo_enable_set,          /* md_enable_set */
   1248     mac_combo_enable_get,          /* md_enable_get */
   1249     mac_combo_duplex_set,          /* md_duplex_set */
   1250     mac_combo_duplex_get,          /* md_duplex_get */
   1251     mac_combo_speed_set,           /* md_speed_set */
   1252     mac_combo_speed_get,           /* md_speed_get */
   1253     mac_combo_pause_set,           /* md_pause_set */
   1254     mac_combo_pause_get,           /* md_pause_get */
   1255     mac_combo_pause_addr_set,      /* md_pause_addr_set */
   1256     mac_combo_pause_addr_get,      /* md_pause_addr_get */
   1257     mac_combo_loopback_set,        /* md_lb_set */
   1258     mac_combo_loopback_get,        /* md_lb_get */
   1259     mac_combo_interface_set,       /* md_interface_set */
   1260     mac_combo_interface_get,       /* md_interface_get */
   1261     NULL,                          /* md_ability_get - Deprecated */
   1262     mac_combo_frame_max_set,       /* md_frame_max_set */
   1263     mac_combo_frame_max_get,       /* md_frame_max_get */
   1264     mac_combo_ifg_set,             /* md_ifg_set */
   1265     mac_combo_ifg_get,             /* md_ifg_get */
   1266     mac_combo_encap_set,           /* md_encap_set */
   1267     mac_combo_encap_get,           /* md_encap_get */
   1268     mac_combo_control_set,         /* md_control_set */
   1269     mac_combo_control_get,         /* md_control_get */
   1270     mac_combo_ability_local_get,   /* md_ability_local_get */
   1271     NULL                           /* md_timesync_tx_info_get */
   1272 };
   1273 
   1274 #endif /* BCM_BIGMAC_SUPPORT || BCM_XMAC_SUPPORT || BCM_UNIMAC_SUPPORT || BCM_CMAC_SUPPORT */