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

xmac.c (107083B)


      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  * XMAC driver
      8  */
      9 
     10 #include <shared/bsl.h>
     11 
     12 #include <sal/core/libc.h>
     13 #include <shared/alloc.h>
     14 #include <sal/core/spl.h>
     15 #include <sal/core/boot.h>
     16 
     17 #include <soc/drv.h>
     18 #include <soc/error.h>
     19 #include <soc/cmic.h>
     20 #include <soc/portmode.h>
     21 #include <soc/ll.h>
     22 #include <soc/counter.h>
     23 #include <soc/macutil.h>
     24 #include <soc/phyctrl.h>
     25 #ifdef BCM_KATANA2_SUPPORT
     26 #include <soc/katana2.h>
     27 #endif
     28 
     29 #ifdef BCM_XMAC_SUPPORT
     30 
     31 #define XMAC_RUNT_THRESHOLD_GE    0x40   /* Runt threshold value for GE ports */
     32 #define XMAC_RUNT_THRESHOLD_XE    0x40   /* Runt threshold value for XE ports */
     33 #define XMAC_RUNT_THRESHOLD_HG1   0x48   /* Runt threshold value for HG1 ports */
     34 #define XMAC_RUNT_THRESHOLD_HG2   0x4c   /* Runt threshold value for HG2 ports */
     35 #define IPG_BYTE(a)               ((a / 8) & 0x1f)
     36 
     37 /*
     38  * XMAC Register field definitions.
     39  */
     40 
     41 /* Transmit CRC Modes (Receive has bit field definitions in register) */
     42 #define XMAC_CRC_APPEND          0x00   /* Append CRC (Default) */
     43 #define XMAC_CRC_KEEP            0x01   /* CRC Assumed correct */
     44 #define XMAC_CRC_REGEN           0x02   /* Replace CRC with a new one */
     45 #define XMAC_CRC_RSVP            0x03   /* Reserved (does Replace) */
     46 
     47 #define JUMBO_MAXSZ              0x3fe8 /* Max legal value (per regsfile) */
     48 
     49 mac_driver_t soc_mac_x;
     50 
     51 #ifdef BROADCOM_DEBUG
     52 static char *mac_x_encap_mode[] = SOC_ENCAP_MODE_NAMES_INITIALIZER;
     53 static char *mac_x_port_if_names[] = SOC_PORT_IF_NAMES_INITIALIZER;
     54 #endif /* BROADCOM_DEBUG */
     55 
     56 #define SOC_XMAC_SPEED_10     0x0
     57 #define SOC_XMAC_SPEED_100    0x1
     58 #define SOC_XMAC_SPEED_1000   0x2
     59 #define SOC_XMAC_SPEED_2500   0x3
     60 #define SOC_XMAC_SPEED_10000  0x4
     61 
     62 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
     63 typedef struct {
     64     uint64 mac_ctrl;
     65     uint64 rx_ctrl;
     66     uint64 tx_ctrl;
     67     uint64 pfc_ctrl;
     68     uint64 rx_max_size;
     69     uint64 mac_mode;
     70     uint64 pause_ctrl;
     71     uint64 rx_mac_sa;
     72     uint64 tx_mac_sa;
     73     uint64 pfc_da;
     74     uint64 llfc_ctrl;
     75     uint64 eee_ctrl;
     76     uint64 eee_timers;
     77     uint64 rx_lss_ctrl;
     78     uint64 rx_vlan_tag;
     79 } _mac_x_cfg_t;
     80 #endif
     81 
     82 /* Forward declarations */
     83 STATIC int mac_x_loopback_set(int unit, soc_port_t port, int lb);
     84 STATIC int mac_x_loopback_get(int unit, soc_port_t port, int *lb);
     85 STATIC int mac_x_frame_max_set(int unit, soc_port_t port, int size);
     86 STATIC int mac_x_frame_max_get(int unit, soc_port_t port, int *size);
     87 STATIC int mac_x_pause_set(int unit, soc_port_t port, int pause_tx, int pause_rx);
     88 STATIC int mac_x_pause_get(int unit, soc_port_t port, int *pause_tx, int *pause_rx);
     89 
     90 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
     91 /* xmac tx/rx clock rates for various speeds from xmac spec*/
     92 struct {
     93     int speed;
     94     uint32 xmac_clk;
     95 }_mac_x_clock_rate[] = {
     96     { 40000, 312 },
     97     { 20000, 156 },
     98     { 10000, 78  },
     99     { 2500,  312 },
    100     { 1000,  125 },
    101     { 100,   25  },
    102 };
    103 STATIC int
    104 mac_x_speed_get(int unit, soc_port_t port, int *speed);
    105 
    106 void
    107 _mac_x_speed_to_clock_rate(int unit, soc_port_t port, int speed, uint32 *clk_rate)
    108 {
    109     int idx;
    110 
    111     *clk_rate = 0;
    112     if (speed == _mac_x_clock_rate[0].speed) {
    113         /* Max Speed */
    114         *clk_rate = _mac_x_clock_rate[0].xmac_clk;
    115     } else {
    116         for (idx = 1; idx < sizeof(_mac_x_clock_rate) /
    117              sizeof(_mac_x_clock_rate[0]); idx++) {
    118             if ((speed >=_mac_x_clock_rate[idx].speed) &&
    119                (speed < _mac_x_clock_rate[idx-1].speed)) {
    120                 *clk_rate = _mac_x_clock_rate[idx].xmac_clk;
    121                 break;
    122             }
    123         } 
    124         if (*clk_rate == 0) {
    125             /* Min speed */
    126             *clk_rate = _mac_x_clock_rate[idx-1].xmac_clk;
    127         }
    128     }
    129 }
    130 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) */
    131 
    132 #ifndef BCM_TRIUMPH3_SUPPORT
    133 STATIC
    134 #endif
    135 int
    136 _mac_x_drain_cells(int unit, soc_port_t port, int notify_phy)
    137 {
    138     int         rv;
    139     int         pause_tx, pause_rx, pfc_rx, llfc_rx;
    140 #ifdef BCM_KATANA_SUPPORT
    141     uint32      rval = 0;
    142 #endif
    143 
    144     rv  = SOC_E_NONE;
    145 
    146     if (SOC_IS_RELOADING(unit)) {
    147         return rv;
    148     }
    149 
    150 #ifdef BCM_TRIUMPH3_SUPPORT
    151     /* Skipping in for Disabled Ports */
    152     if (SOC_IS_TRIUMPH3(unit)) {
    153         if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) {
    154             return SOC_E_NONE;
    155         }
    156     }
    157 #endif
    158 
    159 #ifdef BCM_KATANA_SUPPORT
    160     if (SOC_IS_KATANAX(unit)) {
    161         READ_XP_TXFIFO_PKT_DROP_CTLr(unit, port, &rval);
    162         soc_reg_field_set(unit, XP_TXFIFO_PKT_DROP_CTLr, &rval,
    163                                DROP_ENf, 1);
    164         WRITE_XP_TXFIFO_PKT_DROP_CTLr(unit, port, rval);
    165     }
    166 #endif /* BCM_KATANA2_SUPPORT */
    167     /* Drain cells in mmu/port before cells entering TX FIFO */
    168     SOC_IF_ERROR_RETURN(soc_mmu_flush_enable(unit, port, TRUE));
    169 
    170     /* Disable pause/pfc/llfc function */
    171     SOC_IF_ERROR_RETURN
    172         (soc_mac_x.md_pause_get(unit, port, &pause_tx, &pause_rx));
    173     SOC_IF_ERROR_RETURN
    174         (soc_mac_x.md_pause_set(unit, port, pause_tx, 0));
    175 
    176     SOC_IF_ERROR_RETURN
    177         (soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE,
    178                                   &pfc_rx));
    179     SOC_IF_ERROR_RETURN
    180         (soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE,
    181                                   0));
    182 
    183     SOC_IF_ERROR_RETURN
    184         (soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,
    185                                   &llfc_rx));
    186     SOC_IF_ERROR_RETURN
    187         (soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,
    188                                   0));
    189 
    190     /* Drain data in TX FIFO without egressing */
    191     SOC_IF_ERROR_RETURN
    192         (soc_reg_field32_modify(unit, XMAC_TX_CTRLr, port, DISCARDf, 1));
    193 
    194     if (notify_phy == 1) {
    195     /* Notify PHY driver */
    196         SOC_IF_ERROR_RETURN
    197             (soc_phyctrl_notify(unit, port, phyEventStop, PHY_STOP_DRAIN));
    198     } 
    199     /* Wait until mmu cell count is 0 */
    200     rv = soc_egress_drain_cells(unit, port, 250000);
    201     if (SOC_E_NONE == rv) {
    202         /* Wait until TX fifo cell count is 0 */
    203         rv = soc_txfifo_drain_cells(unit, port, 250000);
    204     }
    205 
    206     /* Notify PHY driver */
    207     if (notify_phy == 1) {
    208         SOC_IF_ERROR_RETURN
    209             (soc_phyctrl_notify(unit, port, phyEventResume, PHY_STOP_DRAIN));
    210     }
    211     /* Stop TX FIFO drainging */
    212     SOC_IF_ERROR_RETURN
    213         (soc_reg_field32_modify(unit, XMAC_TX_CTRLr, port, DISCARDf, 0));
    214 
    215     /* Restore original pause/pfc/llfc configuration */
    216     SOC_IF_ERROR_RETURN
    217         (soc_mac_x.md_pause_set(unit, port, pause_tx, pause_rx));
    218     SOC_IF_ERROR_RETURN
    219         (soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE,
    220                                   pfc_rx));
    221     SOC_IF_ERROR_RETURN
    222         (soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,
    223                                   llfc_rx));
    224     
    225 #ifdef BCM_KATANA_SUPPORT
    226      if (SOC_IS_KATANAX(unit)) {
    227          READ_XP_TXFIFO_PKT_DROP_CTLr(unit, port, &rval);
    228          soc_reg_field_set(unit, XP_TXFIFO_PKT_DROP_CTLr, &rval,
    229                                DROP_ENf, 0);
    230          WRITE_XP_TXFIFO_PKT_DROP_CTLr(unit, port, rval);
    231      } else
    232 #endif
    233      {
    234          /* Stop draining cells in mmu/port */
    235          SOC_IF_ERROR_RETURN(soc_mmu_flush_enable(unit, port, FALSE));
    236      }
    237 
    238     return rv;
    239 }
    240 
    241 #if defined(BCM_SHADOW_SUPPORT)
    242 /* Shadow specific initializations */
    243 
    244 STATIC int
    245 __shadow_petrab_mac_x_init(int unit, soc_port_t port)
    246 {
    247     uint64 reg64;
    248 
    249     /* add Rx+Tx CRC insert/terminate */
    250     SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &reg64));
    251     soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &reg64, CRC_MODEf, XMAC_CRC_APPEND);
    252     SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, reg64));
    253 
    254     /* xmac Rx ctrl */
    255     SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &reg64));
    256     soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &reg64, STRIP_CRCf, 1);
    257     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, reg64));
    258 
    259     /* XMAC Pause Ctrl */
    260     SOC_IF_ERROR_RETURN (READ_XMAC_PAUSE_CTRLr(unit, port, &reg64));
    261     soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &reg64, 
    262                           RX_PAUSE_ENf, 0);
    263     soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &reg64, 
    264                           TX_PAUSE_ENf, 0);
    265     soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &reg64, 
    266                           PAUSE_REFRESH_ENf, 0);
    267     SOC_IF_ERROR_RETURN (WRITE_XMAC_PAUSE_CTRLr(unit, port, reg64));
    268 
    269     /* xmac pfc ctrl */ 
    270     SOC_IF_ERROR_RETURN (READ_XMAC_PFC_CTRLr(unit, port, &reg64));
    271     soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &reg64, 
    272                           PFC_REFRESH_ENf, 1);
    273     soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &reg64, 
    274                           PFC_STATS_ENf, 1);
    275     soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &reg64, 
    276                           RX_PFC_ENf, 1);
    277     soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &reg64, 
    278                           TX_PFC_ENf, 1);
    279     SOC_IF_ERROR_RETURN (WRITE_XMAC_PFC_CTRLr(unit, port, reg64));
    280 
    281     /* Set Max pkt Size */
    282     SOC_IF_ERROR_RETURN
    283         (soc_reg_field32_modify(unit, XMAC_RX_MAX_SIZEr, port,
    284                                 RX_MAX_SIZEf, 16256)); 
    285 
    286     return SOC_E_NONE;
    287 }
    288 
    289 STATIC int
    290 __shadow_mac_x_init(int unit, soc_port_t port)
    291 {
    292     uint64 tx_ctrl, rval, data;
    293 
    294     LOG_VERBOSE(BSL_LS_SOC_10G,
    295                 (BSL_META_U(unit,
    296                             "__shadow_mac_x_init: unit %d port %s\n"),
    297                  unit, SOC_PORT_NAME(unit, port)));
    298 
    299     {
    300         if (IS_XE_PORT(unit, port)) {
    301             SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAX_SIZEr(unit, port, &data));
    302             soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &data, RX_MAX_SIZEf, 9600);
    303             SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr(unit, port, data));
    304 
    305             /*  Initialize additional device mode xmac configurations */
    306             if (soc_property_get(unit, spn_BCM88732_DEVICE_MODE, 0)) {
    307                 SOC_IF_ERROR_RETURN(__shadow_petrab_mac_x_init(unit, port));
    308             }
    309         }
    310     }
    311 
    312     SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &tx_ctrl));
    313     soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, PAD_ENf, 1);
    314     SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, tx_ctrl));
    315 
    316     /* Setup header mode, check for property for bcm5632 mode */
    317     COMPILER_64_ZERO(rval);
    318     SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit, port, rval));
    319 
    320     return SOC_E_NONE;
    321 }
    322 #endif /* BCM_SHADOW_SUPPORT */
    323 
    324 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT_SUPPORT)
    325 STATIC int _mac_x_register_store(int unit, soc_port_t port, _mac_x_cfg_t *port_cfg)
    326 {
    327     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &port_cfg->mac_ctrl));
    328     SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &port_cfg->rx_ctrl));
    329     SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &port_cfg->tx_ctrl));
    330     SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &port_cfg->pfc_ctrl));
    331     SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAX_SIZEr(unit, port, &port_cfg->rx_max_size));
    332     SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &port_cfg->mac_mode));
    333     SOC_IF_ERROR_RETURN(READ_XMAC_PAUSE_CTRLr(unit, port, &port_cfg->pause_ctrl));
    334     SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAC_SAr(unit, port, &port_cfg->rx_mac_sa));
    335     SOC_IF_ERROR_RETURN(READ_XMAC_TX_MAC_SAr(unit, port, &port_cfg->tx_mac_sa));
    336     SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &port_cfg->pfc_da));
    337     SOC_IF_ERROR_RETURN(READ_XMAC_LLFC_CTRLr(unit, port, &port_cfg->llfc_ctrl));
    338     SOC_IF_ERROR_RETURN(READ_XMAC_EEE_CTRLr(unit, port, &port_cfg->eee_ctrl));
    339     SOC_IF_ERROR_RETURN(READ_XMAC_EEE_TIMERSr(unit, port, &port_cfg->eee_timers));
    340     SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_CTRLr(unit, port, &port_cfg->rx_lss_ctrl));
    341     SOC_IF_ERROR_RETURN(READ_XMAC_RX_VLAN_TAGr(unit, port, &port_cfg->rx_vlan_tag));
    342     return SOC_E_NONE;
    343 }
    344 
    345 STATIC int _mac_x_register_restore(int unit, soc_port_t port, _mac_x_cfg_t *port_cfg)
    346 {
    347     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, port_cfg->mac_ctrl));
    348     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, port_cfg->rx_ctrl));
    349     SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, port_cfg->tx_ctrl));
    350     SOC_IF_ERROR_RETURN(WRITE_XMAC_PFC_CTRLr(unit, port, port_cfg->pfc_ctrl));
    351     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr(unit, port, port_cfg->rx_max_size));
    352     SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit, port, port_cfg->mac_mode));
    353     SOC_IF_ERROR_RETURN(WRITE_XMAC_PAUSE_CTRLr(unit, port, port_cfg->pause_ctrl));
    354     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAC_SAr(unit, port, port_cfg->rx_mac_sa));
    355     SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_MAC_SAr(unit, port, port_cfg->tx_mac_sa));
    356     SOC_IF_ERROR_RETURN(WRITE_XMAC_PFC_DAr(unit, port, port_cfg->pfc_da));
    357     SOC_IF_ERROR_RETURN(WRITE_XMAC_LLFC_CTRLr(unit, port, port_cfg->llfc_ctrl));
    358     SOC_IF_ERROR_RETURN(WRITE_XMAC_EEE_CTRLr(unit, port, port_cfg->eee_ctrl));
    359     SOC_IF_ERROR_RETURN(WRITE_XMAC_EEE_TIMERSr(unit, port, port_cfg->eee_timers));
    360     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_LSS_CTRLr(unit, port, port_cfg->rx_lss_ctrl));
    361     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_VLAN_TAGr(unit, port, port_cfg->rx_vlan_tag));
    362     return SOC_E_NONE;
    363 }
    364 
    365 /*
    366  * Function:
    367  *      _bcm_port_mac_reinit
    368  * Purpose:
    369  *      Resets the MAC and restores the configured values.
    370  */
    371 
    372 int
    373 _mac_x_reinit(int unit, soc_port_t port)
    374 {
    375     _mac_x_cfg_t *pcfg;
    376     static const soc_field_t mac_field[] = {
    377         XMAC0_RESETf,
    378         XMAC1_RESETf,
    379         XMAC2_RESETf
    380     };
    381 
    382     int blk_num = 0, phy_port, phy_port_base = 0;
    383     soc_port_t l_port =0;
    384     soc_info_t *si;
    385     int core_index = -1, i;
    386     uint32 rval;
    387 #if defined(BCM_KATANA2_SUPPORT)
    388     uint8 mxqblock = 0, mxqblock_port = 0;
    389 #endif
    390     si = &SOC_INFO(unit);
    391 
    392     phy_port = (soc_feature(unit, soc_feature_logical_port_num))
    393                ? si->port_l2p_mapping[port] : port;
    394     if (phy_port == -1) {
    395         return SOC_E_INTERNAL;
    396     }
    397 
    398     core_index = SOC_PORT_BINDEX(unit, phy_port) / 4;
    399     pcfg = (_mac_x_cfg_t *) sal_alloc(
    400                     sizeof(_mac_x_cfg_t) * 4,"MAC config");
    401     if (pcfg == NULL) {
    402         return SOC_E_MEMORY;
    403     }
    404     /* Store MAC settings */
    405 #if defined(BCM_KATANA2_SUPPORT)
    406     if (SOC_IS_KATANA2(unit)) {
    407         SOC_IF_ERROR_CLEAN_RETURN(soc_katana2_get_port_mxqblock(
    408                                   unit, port, &mxqblock), sal_free(pcfg));
    409         for (i = 0; i < KT2_MAX_MXQPORTS_PER_BLOCK; i++) {
    410              mxqblock_port = (*kt2_mxqblock_ports[unit])[mxqblock][i];
    411              if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) {
    412                  SOC_IF_ERROR_CLEAN_RETURN
    413                      (_mac_x_register_store(unit, mxqblock_port, &pcfg[i]),
    414                       sal_free(pcfg));
    415              }
    416         }
    417     } else
    418 #endif
    419 #if defined(BCM_TRIDENT_SUPPORT)
    420     if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
    421         phy_port_base = ((phy_port - 1)/4)*4 + 1;
    422         for (i = 0; i < 4; i++) {
    423             l_port = si->port_p2l_mapping[phy_port_base+i];
    424             if(l_port == -1) {
    425                 continue;
    426             }
    427             if(0 == si->port_num_lanes[l_port]) {
    428                 continue;
    429             }
    430             SOC_IF_ERROR_CLEAN_RETURN
    431                 (_mac_x_register_store(unit, l_port, &pcfg[i]), sal_free(pcfg));
    432         }
    433     } else
    434 #endif
    435     {
    436         blk_num = SOC_PORT_BLOCK(unit, phy_port);
    437         phy_port_base = si->blk_fpp[blk_num] + core_index*4;
    438         for (i = 0; i < 4; i++) {
    439             l_port = si->port_p2l_mapping[phy_port_base+i];
    440             if(l_port == -1) {
    441                 continue;
    442             }
    443             if(0 == si->port_num_lanes[l_port]) {
    444                 continue;
    445             }
    446             SOC_IF_ERROR_CLEAN_RETURN
    447                 (_mac_x_register_store(unit, l_port, &pcfg[i]), sal_free(pcfg));
    448         }
    449     }
    450     /* Hard reset */
    451 #if defined(BCM_KATANA2_SUPPORT)
    452     if (SOC_IS_KATANA2(unit)) {
    453         SOC_IF_ERROR_CLEAN_RETURN(READ_XPORT_XMAC_CONTROLr(unit, port, &rval), sal_free(pcfg));
    454         soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1);
    455         SOC_IF_ERROR_CLEAN_RETURN(WRITE_XPORT_XMAC_CONTROLr(unit, port, rval), sal_free(pcfg));
    456         sal_udelay(10);
    457         soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0);
    458         SOC_IF_ERROR_CLEAN_RETURN(WRITE_XPORT_XMAC_CONTROLr(unit, port, rval), sal_free(pcfg));
    459     } else
    460 #endif
    461 #if defined(BCM_TRIDENT_SUPPORT)
    462     if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
    463         SOC_IF_ERROR_CLEAN_RETURN(READ_XLPORT_XMAC_CONTROLr(unit, port, &rval), sal_free(pcfg));
    464         soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1);
    465         SOC_IF_ERROR_CLEAN_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval), sal_free(pcfg));
    466         sal_udelay(10);
    467         soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0);
    468         SOC_IF_ERROR_CLEAN_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval), sal_free(pcfg));
    469     } else
    470 #endif
    471     {
    472         SOC_IF_ERROR_CLEAN_RETURN(READ_PORT_MAC_CONTROLr(unit, port, &rval),sal_free(pcfg));
    473         soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
    474                           mac_field[core_index], 1);
    475         SOC_IF_ERROR_CLEAN_RETURN(WRITE_PORT_MAC_CONTROLr(unit, port, rval),sal_free(pcfg));
    476         sal_udelay(10);
    477         soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval,
    478                           mac_field[core_index], 0);
    479         SOC_IF_ERROR_CLEAN_RETURN(WRITE_PORT_MAC_CONTROLr(unit, port, rval),sal_free(pcfg));
    480     }
    481     sal_udelay(10);
    482 #if defined(BCM_KATANA2_SUPPORT)
    483     if (SOC_IS_KATANA2(unit)) {
    484         /* Restore MAC settings. */
    485         SOC_IF_ERROR_CLEAN_RETURN(soc_katana2_get_port_mxqblock(
    486                                   unit, port, &mxqblock), sal_free(pcfg));
    487         for (i = 0; i < KT2_MAX_MXQPORTS_PER_BLOCK; i++) {
    488              mxqblock_port = (*kt2_mxqblock_ports[unit])[mxqblock][i];
    489              if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) {
    490                  SOC_IF_ERROR_CLEAN_RETURN
    491                      (_mac_x_register_restore(unit, mxqblock_port, &pcfg[i]),
    492                       sal_free(pcfg));
    493              }
    494         }
    495     } else
    496 #endif
    497 #if defined(BCM_TRIDENT_SUPPORT)
    498     if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) {
    499         for (i = 0; i < 4; i++) {
    500             l_port = si->port_p2l_mapping[phy_port_base+i];
    501             if(l_port == -1) {
    502                 continue;
    503             }
    504             if(0 == si->port_num_lanes[l_port]) {
    505                 continue;
    506             }
    507             /* Restore MAC settings. */
    508             SOC_IF_ERROR_CLEAN_RETURN
    509                 (_mac_x_register_restore(unit, l_port, &pcfg[i]), sal_free(pcfg));
    510         }
    511     } else
    512 #endif
    513     {
    514         for (i = 0; i < 4; i++) {
    515             l_port = si->port_p2l_mapping[phy_port_base+i];
    516             if(l_port == -1) {
    517                 continue;
    518             }
    519             if(0 == si->port_num_lanes[l_port]) {
    520                 continue;
    521             }
    522             /* Restore MAC settings. */
    523             SOC_IF_ERROR_CLEAN_RETURN
    524                 (_mac_x_register_restore(unit, l_port, &pcfg[i]), sal_free(pcfg));
    525         }
    526     }
    527     sal_free(pcfg);
    528     return SOC_E_NONE;
    529 }
    530 #endif
    531 
    532 
    533 /*
    534  * Function:
    535  *      mac_x_init
    536  * Purpose:
    537  *      Initialize Xmac into a known good state.
    538  * Parameters:
    539  *      unit - XGS unit #.
    540  *      port - Port number on unit.
    541  * Returns:
    542  *      SOC_E_XXX
    543  * Notes:
    544  */
    545 STATIC int
    546 mac_x_init(int unit, soc_port_t port)
    547 {
    548     soc_info_t *si;
    549     uint64 mac_ctrl, rx_ctrl, tx_ctrl, rval;
    550     uint32 ipg;
    551     int mode;
    552     
    553 #if defined(BCM_KATANA2_SUPPORT)
    554     int                 sgn_det = 0;
    555     uint32              sgn_crs;
    556 #endif
    557     
    558     LOG_VERBOSE(BSL_LS_SOC_10G,
    559                 (BSL_META_U(unit,
    560                             "mac_x_init: unit %d port %s\n"),
    561                  unit, SOC_PORT_NAME(unit, port)));
    562 
    563     si = &SOC_INFO(unit);
    564 
    565     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &mac_ctrl));
    566     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, SOFT_RESETf, 1);
    567     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, mac_ctrl));
    568 
    569     /* Disable Tx/Rx, assume that MAC is stable (or out of reset) */
    570     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &mac_ctrl));
    571 
    572     if (IS_HG_PORT(unit, port)) {
    573         soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, SOFT_RESETf, 0);
    574     }
    575 
    576     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, RX_ENf, 0);
    577     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, TX_ENf, 0);
    578     if ((si->port_speed_max[port] == 40000) || 
    579         (si->port_speed_max[port]) == 42000) {
    580         int xlgmii_align = 0;
    581 
    582         if (IS_XE_PORT(unit, port)) { 
    583             xlgmii_align = 1; 
    584         } else { /* HG port with external PHY may also use IEEE 40G mld-4 */ 
    585             if (PHY_EXTERNAL_MODE(unit, port)
    586                 && (!PHY_PASSTHRU_MODE(unit, port))
    587                 && (!soc_property_port_get(unit, port, 
    588                                            spn_PORT_PHY_MODE_REVERSE, 0))) {
    589                 xlgmii_align = 1; 
    590             } 
    591         } 
    592         soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, XLGMII_ALIGN_ENBf,
    593                               xlgmii_align);
    594     }
    595     if (soc_reg_field_valid(unit, XMAC_CTRLr, XGMII_IPG_CHECK_DISABLEf)) {
    596         soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl,
    597                               XGMII_IPG_CHECK_DISABLEf,
    598                               IS_HG_PORT(unit, port) ? 1 : 0);
    599     }
    600 
    601     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, mac_ctrl));
    602 
    603     SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rx_ctrl));
    604     soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, STRIP_CRCf, 0);
    605 
    606 #ifdef  BCM_TRIUMPH3_SUPPORT 
    607     if (SOC_IS_TRIUMPH3(unit) && IS_HG_PORT(unit, port)) {
    608         soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, RUNT_THRESHOLDf,
    609                               XMAC_RUNT_THRESHOLD_HG1);
    610     }
    611 #endif /* BCM_TRIUMPH3_SUPPORT */
    612 
    613     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rx_ctrl));
    614 
    615 
    616     /* XMAC_TX_CTRL settings */
    617     SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &tx_ctrl));
    618     if(IS_XE_PORT(unit,port) || IS_GE_PORT(unit, port)) {
    619        ipg = SOC_PERSIST(unit)->ipg[port].fd_xe;
    620     } else {
    621         ipg = soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0) ?
    622               SOC_PERSIST(unit)->ipg[port].fd_hg2 :
    623               SOC_PERSIST(unit)->ipg[port].fd_hg;
    624     }
    625     soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, AVERAGE_IPGf,
    626                           IPG_BYTE(ipg));
    627     soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, CRC_MODEf, 3);
    628 #if defined(BCM_HELIX4_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
    629      if (SOC_IS_TRIUMPH3(unit)) {
    630          if ((si->port_speed_max[port] > 1000 &&
    631              si->port_speed_max[port] <= 3000) ||
    632              IS_XL_PORT(unit, port)) {
    633              soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, 
    634                                     TX_64BYTE_BUFFER_ENf, 1);
    635          }
    636      }
    637 #endif /* defined(BCM_HELIX4_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) */
    638 #ifdef BCM_KATANA2_SUPPORT
    639     if (SOC_IS_KATANA2(unit)) {
    640         if (si->port_speed_max[port] <= 2500) {
    641             soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, 
    642                                     TX_64BYTE_BUFFER_ENf, 1);
    643         }
    644         if (SOC_PBMP_MEMBER(si->linkphy_pbm, port)) {
    645             soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &tx_ctrl, CRC_MODEf, 0);
    646         }
    647     }
    648 #endif
    649     SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, tx_ctrl));
    650 
    651     if (IS_ST_PORT(unit, port)) {
    652         soc_mac_x.md_pause_set(unit, port, FALSE, FALSE);
    653     } else {
    654         soc_mac_x.md_pause_set(unit, port, TRUE, TRUE);
    655     }
    656 
    657     SOC_IF_ERROR_RETURN
    658         (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, PFC_REFRESH_ENf,
    659                                 1));
    660 
    661     if (soc_property_port_get(unit, port, spn_PHY_WAN_MODE, FALSE)) {
    662         /* Max speed for WAN mode is 9.294Gbps.
    663          * This setting gives 10Gbps * (13/14) or 9.286 Gbps */
    664         SOC_IF_ERROR_RETURN
    665             (soc_mac_x.md_control_set(unit, port,
    666                                       SOC_MAC_CONTROL_FRAME_SPACING_STRETCH,
    667                                       13));
    668     }
    669 
    670     /* Set jumbo max size (8000 byte payload) */
    671     COMPILER_64_ZERO(rval);
    672 #ifdef BCM_XGS_SUPPORT
    673     if (SOC_IS_XGS(unit)) {
    674         soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &rval, RX_MAX_SIZEf,
    675                               SOC_INFO(unit).max_mtu); 
    676     } else
    677 #endif
    678     {
    679         soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &rval, RX_MAX_SIZEf,
    680                               JUMBO_MAXSZ); 
    681     }
    682     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr(unit, port, rval));
    683 
    684     /* Setup header mode, check for property for higig2 mode */
    685     COMPILER_64_ZERO(rval);
    686     if (!IS_XE_PORT(unit, port) && !IS_GE_PORT(unit, port)) {
    687         mode = soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0) ?
    688             2 : 1;
    689         soc_reg64_field32_set(unit, XMAC_MODEr, &rval, HDR_MODEf, mode);
    690     }
    691     if (soc_reg_field_valid(unit, XMAC_MODEr, SPEED_MODEf)) {
    692         switch (si->port_speed_max[port]) {
    693         case 10:
    694             mode = SOC_XMAC_SPEED_10;
    695             break;
    696         case 100:
    697             mode = SOC_XMAC_SPEED_100;
    698             break;
    699         case 1000:
    700             mode = SOC_XMAC_SPEED_1000;
    701             break;
    702         case 2500:
    703         case 3000:
    704             mode = SOC_XMAC_SPEED_2500;
    705             break;
    706         default:
    707             mode = SOC_XMAC_SPEED_10000;
    708             break;
    709         }
    710         soc_reg64_field32_set(unit, XMAC_MODEr, &rval, SPEED_MODEf, mode);
    711     }
    712     SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit, port, rval));
    713 
    714     /* XMAC_RX_CTRL settings */
    715     SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rx_ctrl));
    716 
    717 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \
    718     defined(BCM_KATANA_SUPPORT)
    719 
    720     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) ) {
    721         if (IS_GE_PORT(unit, port)) {
    722             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    723                                   STRICT_PREAMBLEf, 0);
    724             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    725                                   PROCESS_VARIABLE_PREAMBLEf, 1);
    726 	    soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval,
    727                                   RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_GE);
    728             
    729         } else if (IS_XE_PORT(unit, port)) {
    730             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    731                                   STRICT_PREAMBLEf, 1);
    732             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    733                                   PROCESS_VARIABLE_PREAMBLEf, 0);
    734             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval,
    735                                   RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_XE);
    736 
    737         } else if (IS_HG_PORT(unit, port)) {
    738             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    739                                   STRICT_PREAMBLEf, 0);
    740             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    741                                   PROCESS_VARIABLE_PREAMBLEf, 0);
    742             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 
    743                     RX_PASS_CTRLf, 1);
    744             if (soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0)) {
    745                 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 
    746                                       RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_HG2);
    747             } else {
    748                 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 
    749                                       RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_HG1);
    750             }
    751 
    752         }
    753     } else if (SOC_IS_KATANA(unit)) {
    754           if (IS_GE_PORT(unit, port) || IS_XE_PORT(unit, port)) {
    755               soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    756                                     STRICT_PREAMBLEf, 0);
    757               soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    758                                   PROCESS_VARIABLE_PREAMBLEf, 1);
    759               soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    760                                     RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_XE);
    761           } else if (IS_HG_PORT(unit, port)) {
    762               soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    763                                     STRICT_PREAMBLEf, 0);
    764               soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl,
    765                                     PROCESS_VARIABLE_PREAMBLEf, 0);
    766               soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 
    767                        RX_PASS_CTRLf, 1);
    768               if (soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0)) {
    769                   soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 
    770                                     RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_HG2);
    771               } else {
    772                 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, 
    773                                       RUNT_THRESHOLDf, XMAC_RUNT_THRESHOLD_HG1);
    774               }
    775           }
    776    }
    777 
    778    if (SOC_IS_KATANA2(unit) && SOC_PBMP_MEMBER(si->linkphy_pbm, port)) {
    779       soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, STRIP_CRCf, 1);
    780    }
    781 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_KATANA2_SUPPORT || 
    782           BCM_KATANA_SUPPORT */
    783 #if defined(BCM_TRIDENT_SUPPORT)
    784     if ((SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) && IS_HG_PORT(unit, port)) {
    785         soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rx_ctrl, RUNT_THRESHOLDf,
    786                       soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE, 0)?
    787                              XMAC_RUNT_THRESHOLD_HG2 : XMAC_RUNT_THRESHOLD_HG1);
    788     }
    789 #endif /* BCM_TRIDENT_SUPPORT*/
    790    SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rx_ctrl));
    791 
    792 
    793 #if defined(BCM_SHADOW_SUPPORT)
    794     /* Shadow Specific Initialization */
    795     if (SOC_IS_SHADOW(unit)) {
    796         SOC_IF_ERROR_RETURN(__shadow_mac_x_init(unit, port));
    797     }
    798 #endif /* BCM_SHADOW_SUPPORT */
    799 
    800     /* Disable loopback and bring XMAC out of reset */
    801     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, CORE_REMOTE_LPBKf, 0);
    802     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, LINE_REMOTE_LPBKf, 0);
    803     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, CORE_LOCAL_LPBKf, 0);
    804     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, LINE_LOCAL_LPBKf, 0);
    805     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, RX_ENf, 1);
    806     soc_reg64_field32_set(unit, XMAC_CTRLr, &mac_ctrl, TX_ENf, 1);
    807 
    808     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, mac_ctrl));
    809 
    810 #if defined(BCM_KATANA2_SUPPORT)
    811     if (SOC_IS_KATANA2(unit)) {
    812         sgn_det = soc_property_port_get(unit, port,  spn_SERDES_RX_LOS, 0);
    813         SOC_IF_ERROR_RETURN(READ_X_GPORT_SGNDET_EARLYCRSr(unit, port, &sgn_crs));
    814         soc_reg_field_set(unit, X_GPORT_SGNDET_EARLYCRSr, &sgn_crs, SGN_DETf, sgn_det);
    815         SOC_IF_ERROR_RETURN(WRITE_X_GPORT_SGNDET_EARLYCRSr(unit, port, sgn_crs));
    816     }
    817 #endif
    818 
    819     return SOC_E_NONE;
    820 }
    821 
    822 /*
    823  * Function:
    824  *      mac_x_enable_set
    825  * Purpose:
    826  *      Drain the egress queues with out bringing down the port
    827  * Parameters:
    828  *      unit - XGS unit #.
    829  *      port - Port number on unit.
    830  * Returns:
    831  *      SOC_E_XXX
    832  */
    833 STATIC int
    834 mac_x_egress_queue_drain(int unit, soc_port_t port)
    835 {
    836     uint64 ctrl;
    837     pbmp_t mask;
    838     int rx_enable = 0;
    839 
    840     LOG_VERBOSE(BSL_LS_SOC_10G,
    841                 (BSL_META_U(unit,
    842                             "mac_x_egress_queue_drain_set: unit %d port %s\n"),
    843                  unit, SOC_PORT_NAME(unit, port)));
    844 
    845     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl));
    846 
    847     rx_enable = soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, RX_ENf);
    848     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 0);
    849     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
    850     sal_udelay(10);
    851 
    852     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 1);
    853     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
    854 
    855     soc_link_mask2_get(unit, &mask);
    856     SOC_PBMP_PORT_REMOVE(mask, port);
    857     SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask));
    858     SOC_IF_ERROR_RETURN(_mac_x_drain_cells(unit, port, 0));
    859 
    860     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl));
    861 
    862         /* Remove SOFT_RESET before RX_EN */
    863     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 0);
    864     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
    865 
    866     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, TX_ENf, 1);
    867     soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, rx_enable ? 1 : 0);
    868     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
    869     sal_udelay(10);
    870 
    871     soc_link_mask2_get(unit, &mask);
    872     SOC_PBMP_PORT_ADD(mask, port);
    873     SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask));
    874 
    875     return SOC_E_NONE;
    876 }
    877 /*
    878  * Function:
    879  *      mac_x_enable_set
    880  * Purpose:
    881  *      Enable or disable MAC
    882  * Parameters:
    883  *      unit - XGS unit #.
    884  *      port - Port number on unit.
    885  *      enable - TRUE to enable, FALSE to disable
    886  * Returns:
    887  *      SOC_E_XXX
    888  */
    889 STATIC int
    890 mac_x_enable_set(int unit, soc_port_t port, int enable)
    891 {
    892     uint64 ctrl;
    893     pbmp_t mask;
    894 
    895     LOG_VERBOSE(BSL_LS_SOC_10G,
    896                 (BSL_META_U(unit,
    897                             "mac_x_enable_set: unit %d port %s enable=%s\n"),
    898                  unit, SOC_PORT_NAME(unit, port),
    899                  enable ? "True" : "False"));
    900 
    901     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl));
    902 
    903     if (enable) {
    904         /* Remove SOFT_RESET before RX_EN */
    905 #ifdef BCM_KATANA_SUPPORT
    906         if (SOC_IS_KATANAX(unit)) {
    907             SOC_IF_ERROR_RETURN(soc_mmu_flush_enable(unit, port, FALSE));
    908         }
    909 #endif
    910         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 0);
    911         SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
    912 
    913         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, TX_ENf, 1);
    914         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 1);
    915         SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
    916         sal_udelay(10);
    917 
    918         soc_link_mask2_get(unit, &mask);
    919         SOC_PBMP_PORT_ADD(mask, port);
    920         SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask));
    921         SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventResume,
    922                                                PHY_STOP_MAC_DIS));
    923     } else {
    924         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 0);
    925         SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
    926         sal_udelay(10);
    927 
    928         soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 1);
    929         SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl));
    930 
    931         soc_link_mask2_get(unit, &mask);
    932         SOC_PBMP_PORT_REMOVE(mask, port);
    933         SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask));
    934         SOC_IF_ERROR_RETURN(_mac_x_drain_cells(unit, port, 1));
    935         SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventStop,
    936                                                PHY_STOP_MAC_DIS));
    937     }
    938 
    939     return SOC_E_NONE;
    940 }
    941 
    942 /*
    943  * Function:
    944  *      mac_x_enable_get
    945  * Purpose:
    946  *      Get MAC enable state
    947  * Parameters:
    948  *      unit - XGS unit #.
    949  *      port - Port number on unit.
    950  *      enable - (OUT) TRUE if enabled, FALSE if disabled
    951  * Returns:
    952  *      SOC_E_XXX
    953  */
    954 STATIC int
    955 mac_x_enable_get(int unit, soc_port_t port, int *enable)
    956 {
    957     uint64 ctrl;
    958 
    959     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl));
    960 
    961     *enable = soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, RX_ENf);
    962 
    963     LOG_VERBOSE(BSL_LS_SOC_10G,
    964                 (BSL_META_U(unit,
    965                             "mac_x_enable_get: unit %d port %s enable=%s\n"),
    966                  unit, SOC_PORT_NAME(unit, port),
    967                  *enable ? "True" : "False"));
    968 
    969     return SOC_E_NONE;
    970 }
    971 
    972 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)
    973 /*
    974  * Function:
    975  *      _mac_x_timestamp_delay_set
    976  * Purpose:
    977  *      Set Timestamp delay for one-step to account for lane and pipeline delay.
    978  * Parameters:
    979  *      unit - XGS unit #.
    980  *      port - Port number on unit.
    981  *      speed - Speed
    982  *      phy_mode - single/dual/quad phy mode
    983  * Returns:
    984  *      SOC_E_XXX
    985  */
    986 STATIC int
    987 _mac_x_timestamp_delay_set(int unit, soc_port_t port, int speed, int phy_mode)
    988 {
    989     uint64 ctrl;
    990     uint32 clk_rate, tx_clk_ns;
    991     int osts_delay, delay;
    992     uint32 field;
    993 
    994     LOG_VERBOSE(BSL_LS_SOC_10G,
    995                 (BSL_META_U(unit,
    996                             "mac_x_timestamp_delay_set: unit %d port %s\n"),
    997                  unit, SOC_PORT_NAME(unit, port)));
    998 
    999     if (SOC_REG_IS_VALID(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr)) {
   1000         SOC_IF_ERROR_RETURN(READ_XMAC_OSTS_TIMESTAMP_ADJUSTr(unit, port, &ctrl));
   1001 
   1002         _mac_x_speed_to_clock_rate(unit, port, speed, &clk_rate);
   1003         /* Tx clock rate for single/dual/quad phy mode */
   1004         if ((speed >= 10000) && (speed <= 40000)) {
   1005             /* tx clock rate in ns */
   1006             tx_clk_ns = (((1000/clk_rate))/ (1 << phy_mode));
   1007         } else {
   1008             tx_clk_ns = 0;
   1009         }
   1010 
   1011         
   1012         
   1013         /*
   1014          * MAC pipeline delay for XGMII/XLGMII mode is : ( as in XMAC specification)
   1015          *          = (5.5 * TX line clock period) + (Timestamp clock period)
   1016          */
   1017         /* signed value of pipeline delay in ns */
   1018         osts_delay = soc_property_port_get(unit, port, spn_TIMESTAMP_ADJUST(speed),
   1019                                            SOC_TIMESYNC_PLL_CLOCK_NS(unit) -
   1020                                            ((11 * tx_clk_ns ) / 2));
   1021 
   1022         if (SOC_E_NONE != soc_reg_signed_field_mask(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr,
   1023                                                     TS_ADJUSTf, osts_delay, &field)) {
   1024             LOG_WARN(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   1025                 "%s property out of bounds (is %d)\n"),
   1026                 spn_TIMESTAMP_ADJUST(speed), osts_delay));
   1027             field = 0;
   1028         }
   1029 
   1030         soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl,
   1031                               TS_ADJUSTf, field);
   1032         /*
   1033          * Lane delay for xmac lanes
   1034          *   Lane_0(0-3)  : 1 * TX line clock period
   1035          *   Lane_1(4-7)  : 2 * TX line clock period
   1036          *   Lane_2(8-11) : 3 * TX line clock period
   1037          *   Lane_3(12-15): 4 * TX line clock period
   1038          */
   1039         /* unsigned value of lane delay in ns */
   1040         delay = 1 * tx_clk_ns;
   1041         soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl,
   1042                               TS_ADJUST_DEMUX_DELAY_0f, delay );
   1043         delay = 2 * tx_clk_ns;
   1044         soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl,
   1045                               TS_ADJUST_DEMUX_DELAY_1f, delay );
   1046         delay = 3 * tx_clk_ns;
   1047         soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl,
   1048                               TS_ADJUST_DEMUX_DELAY_2f, delay );
   1049         delay = 4 * tx_clk_ns;
   1050         soc_reg64_field32_set(unit, XMAC_OSTS_TIMESTAMP_ADJUSTr, &ctrl,
   1051                               TS_ADJUST_DEMUX_DELAY_3f, delay );
   1052 
   1053         SOC_IF_ERROR_RETURN(WRITE_XMAC_OSTS_TIMESTAMP_ADJUSTr(unit, port, ctrl));
   1054     }
   1055 
   1056     return SOC_E_NONE;
   1057 }
   1058 #endif /* defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) */
   1059 
   1060 /*
   1061  * Function:
   1062  *      mac_x_duplex_set
   1063  * Purpose:
   1064  *      Set XMAC in the specified duplex mode.
   1065  * Parameters:
   1066  *      unit - XGS unit #.
   1067  *      port - XGS port # on unit.
   1068  *      duplex - Boolean: true --> full duplex, false --> half duplex.
   1069  * Returns:
   1070  *      SOC_E_XXX
   1071  * Notes:
   1072  */
   1073 STATIC int
   1074 mac_x_duplex_set(int unit, soc_port_t port, int duplex)
   1075 {
   1076     LOG_VERBOSE(BSL_LS_SOC_10G,
   1077                 (BSL_META_U(unit,
   1078                             "mac_x_duplex_set: unit %d port %s duplex=%s\n"),
   1079                  unit, SOC_PORT_NAME(unit, port),
   1080                  duplex ? "Full" : "Half"));
   1081     return SOC_E_NONE;
   1082 }
   1083 
   1084 /*
   1085  * Function:
   1086  *      mac_x_duplex_get
   1087  * Purpose:
   1088  *      Get XMAC duplex mode.
   1089  * Parameters:
   1090  *      unit - XGS unit #.
   1091  *      duplex - (OUT) Boolean: true --> full duplex, false --> half duplex.
   1092  * Returns:
   1093  *      SOC_E_XXX
   1094  */
   1095 STATIC int
   1096 mac_x_duplex_get(int unit, soc_port_t port, int *duplex)
   1097 {
   1098     *duplex = TRUE; /* Always full duplex */
   1099 
   1100     LOG_VERBOSE(BSL_LS_SOC_10G,
   1101                 (BSL_META_U(unit,
   1102                             "mac_x_duplex_get: unit %d port %s duplex=%s\n"),
   1103                  unit, SOC_PORT_NAME(unit, port),
   1104                  *duplex ? "Full" : "Half"));
   1105     return SOC_E_NONE;
   1106 }
   1107 
   1108 /*
   1109  * Function:
   1110  *      mac_x_pause_set
   1111  * Purpose:
   1112  *      Configure XMAC to transmit/receive pause frames.
   1113  * Parameters:
   1114  *      unit - XGS unit #.
   1115  *      port - XGS port # on unit.
   1116  *      pause_tx - Boolean: transmit pause or -1 (don't change)
   1117  *      pause_rx - Boolean: receive pause or -1 (don't change)
   1118  * Returns:
   1119  *      SOC_E_XXX
   1120  */
   1121 STATIC int
   1122 mac_x_pause_set(int unit, soc_port_t port, int pause_tx, int pause_rx)
   1123 {
   1124     soc_field_t fields[2] = { TX_PAUSE_ENf, RX_PAUSE_ENf };
   1125     uint32 values[2];
   1126 
   1127     LOG_VERBOSE(BSL_LS_SOC_10G,
   1128                 (BSL_META_U(unit,
   1129                             "mac_x_pause_set: unit %d port %s TX=%s RX=%s\n"),
   1130                  unit, SOC_PORT_NAME(unit, port),
   1131                  pause_tx != FALSE ? "on" : "off",
   1132                  pause_rx != FALSE ? "on" : "off"));
   1133 
   1134     if (SOC_IS_TD_TT(unit)) {
   1135         fields[1] = RX_PASS_PAUSEf;
   1136     }
   1137     values[0] = pause_tx != FALSE ? 1 : 0;
   1138     values[1] = pause_rx != FALSE ? 1 : 0;
   1139     return soc_reg_fields32_modify(unit, XMAC_PAUSE_CTRLr, port, 2,
   1140                                    fields, values);
   1141 }
   1142 
   1143 /*
   1144  * Function:
   1145  *      mac_x_pause_get
   1146  * Purpose:
   1147  *      Return the pause ability of XMAC
   1148  * Parameters:
   1149  *      unit - XGS unit #.
   1150  *      port - XGS port # on unit.
   1151  *      pause_tx - Boolean: transmit pause
   1152  *      pause_rx - Boolean: receive pause
   1153  *      pause_mac - MAC address used for pause transmission.
   1154  * Returns:
   1155  *      SOC_E_XXX
   1156  */
   1157 STATIC int
   1158 mac_x_pause_get(int unit, soc_port_t port, int *pause_tx, int *pause_rx)
   1159 {
   1160     soc_field_t field = RX_PAUSE_ENf;
   1161     uint64 rval;
   1162 
   1163     if (SOC_IS_TD_TT(unit)) {
   1164         field = RX_PASS_PAUSEf;
   1165     }
   1166 
   1167     SOC_IF_ERROR_RETURN(READ_XMAC_PAUSE_CTRLr(unit, port, &rval));
   1168     *pause_tx =
   1169         soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval, TX_PAUSE_ENf);
   1170     *pause_rx = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval, field);
   1171 
   1172     LOG_VERBOSE(BSL_LS_SOC_10G,
   1173                 (BSL_META_U(unit,
   1174                             "mac_x_pause_get: unit %d port %s TX=%s RX=%s\n"),
   1175                  unit, SOC_PORT_NAME(unit, port),
   1176                  *pause_tx ? "on" : "off",
   1177                  *pause_rx ? "on" : "off"));
   1178     return SOC_E_NONE;
   1179 }
   1180 
   1181 /*
   1182  * Function:
   1183  *      mac_x_speed_set
   1184  * Purpose:
   1185  *      Set XMAC in the specified speed.
   1186  * Parameters:
   1187  *      unit - XGS unit #.
   1188  *      port - XGS port # on unit.
   1189  *      speed - 10000, 15000, 20000, 30000, 40000.
   1190  * Returns:
   1191  *      SOC_E_XXX
   1192  */
   1193 STATIC int
   1194 mac_x_speed_set(int unit, soc_port_t port, int speed)
   1195 {
   1196     soc_port_if_t intf;
   1197 #ifdef BCM_UNIPORT_SUPPORT
   1198     static const soc_field_t core_mode_field[] = {
   1199         XPORT0_CORE_PORT_MODEf, 
   1200         XPORT1_CORE_PORT_MODEf,
   1201         XPORT2_CORE_PORT_MODEf
   1202     };
   1203     static const soc_field_t phy_mode_field[] = {
   1204         XPORT0_PHY_PORT_MODEf,
   1205         XPORT1_PHY_PORT_MODEf,
   1206         XPORT2_PHY_PORT_MODEf
   1207     };
   1208     static const soc_field_t xpc_gmii_enable_field[] = {
   1209         XPC0_GMII_MII_ENABLEf,
   1210         XPC1_GMII_MII_ENABLEf,
   1211         XPC2_GMII_MII_ENABLEf
   1212     };
   1213 #endif /* BCM_UNIPORT_SUPPORT */
   1214     uint64 rval64;
   1215     int xlgmii_align;
   1216 #if defined(BCM_TRIDENT_SUPPORT)
   1217     int ipg_check_disable;
   1218 #endif
   1219 
   1220     LOG_VERBOSE(BSL_LS_SOC_10G,
   1221                 (BSL_META_U(unit,
   1222                             "mac_x_speed_set: unit %d port %s speed=%dMb\n"),
   1223                  unit, SOC_PORT_NAME(unit, port),
   1224                  speed));
   1225 
   1226 #ifdef BCM_KATANA_SUPPORT
   1227     /* We should be looking for Ver B0 in  XMAC_VERSION_ID reg. But this reg
   1228      is not implemented in Katana A0. So, check for SPEED_MODE field instead */
   1229     if (SOC_IS_KATANAX(unit) && 
   1230         soc_reg_field_valid(unit, XMAC_MODEr, SPEED_MODEf)) {
   1231         int speed_select, enable;
   1232         uint32 phy_mode = 0;
   1233         uint32 rval, rval_orig;
   1234         uint32 strict_preamble = 1;
   1235         int  same_mxqblock_max_port_speed = 0;
   1236 #ifdef BCM_KATANA2_SUPPORT
   1237         uint32 core_mode = 0;
   1238         uint32 wc_10g_21g_sel = 0;
   1239         uint8  mxqblock = 0;
   1240         bcmMxqConnection_t connection_mode;
   1241         int  other_port_speed = 0;
   1242         int loop;
   1243 #endif
   1244 
   1245         switch (speed) {
   1246         case 10:
   1247             strict_preamble = 0;
   1248             speed_select = SOC_XMAC_SPEED_10;
   1249             break;
   1250         /* support non-standard speed in Broadreach mode */
   1251         case 20:
   1252         case 25:
   1253         case 33:
   1254         case 50:
   1255             /* fall through to case 100 */
   1256         case 100:
   1257             strict_preamble = 0;
   1258             speed_select = SOC_XMAC_SPEED_100;
   1259             break;
   1260         case 1000:
   1261             strict_preamble = 0;
   1262             speed_select = SOC_XMAC_SPEED_1000;
   1263             break;
   1264         case 2500:
   1265             strict_preamble = 0;
   1266             speed_select = SOC_XMAC_SPEED_2500;
   1267             break;
   1268         case 10000:
   1269         case 12000:
   1270         case 13000:
   1271         case 15000:
   1272         case 16000:
   1273             speed_select = SOC_XMAC_SPEED_10000;
   1274             break;
   1275         case 0:
   1276             return (SOC_E_NONE);              /* Support NULL PHY */            
   1277         default:
   1278 #ifdef BCM_KATANA2_SUPPORT
   1279             if (SOC_IS_KATANA2(unit) && ((speed == 21000) || (speed == 20000))){
   1280                   speed_select = SOC_XMAC_SPEED_10000;
   1281                   break;
   1282             }
   1283 #endif
   1284             return (SOC_E_CONFIG);
   1285         }
   1286         SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rval64));
   1287         if (IS_HG_PORT(unit, port)) {
   1288             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64,
   1289                                           STRICT_PREAMBLEf, 0);
   1290             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64,
   1291                                 PROCESS_VARIABLE_PREAMBLEf, 0);
   1292         } else {
   1293             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64,
   1294                             STRICT_PREAMBLEf, strict_preamble ? 1 : 0);
   1295             soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64,
   1296                         PROCESS_VARIABLE_PREAMBLEf, strict_preamble ? 0 : 1);
   1297         }
   1298 
   1299         SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rval64));
   1300         SOC_IF_ERROR_RETURN(mac_x_enable_get(unit, port, &enable));
   1301         
   1302         if (enable) {
   1303             /* Turn off TX/RX enable */
   1304             SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 0));
   1305         }
   1306         
   1307         /* Update the speed */
   1308         SOC_IF_ERROR_RETURN
   1309             (soc_reg_field32_modify(unit, XMAC_MODEr, port,
   1310                                     SPEED_MODEf, speed_select));
   1311 
   1312         if (IS_MXQ_PORT(unit,port)) {
   1313             phy_mode = (speed >= 10000) ? 0 : 2;
   1314             SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval));
   1315             rval_orig = rval;
   1316 #ifdef BCM_KATANA2_SUPPORT
   1317             if (SOC_IS_KATANA2(unit)) {
   1318                 SOC_IF_ERROR_RETURN(soc_katana2_get_phy_port_mode(unit,
   1319                                     port, speed,
   1320                                     &phy_mode));
   1321                 SOC_IF_ERROR_RETURN(soc_katana2_get_core_port_mode(unit,
   1322                                     port, &core_mode));
   1323                 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval,
   1324                                   CORE_PORT_MODEf, core_mode);
   1325                 SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock(
   1326                                     unit,port,&mxqblock));
   1327                 if ((mxqblock == 8) || (mxqblock == 9)) {
   1328                      same_mxqblock_max_port_speed = 0;
   1329                      if (core_mode == (bcmMxqCorePortMode_t )
   1330                                        bcmMxqCorePortModeDual) {
   1331                          for (loop = 0; loop < 4; loop ++) {
   1332                               if ((*kt2_mxqblock_ports[unit])[mxqblock][loop] 
   1333                                   != port) {
   1334                                   if (mac_x_speed_get(unit, 
   1335                                       (*kt2_mxqblock_ports[unit])[mxqblock]
   1336                                       [loop], &other_port_speed)==SOC_E_NONE) {
   1337                                       if (other_port_speed > 
   1338                                           same_mxqblock_max_port_speed) {
   1339                                           same_mxqblock_max_port_speed = 
   1340                                                         other_port_speed;
   1341                                       }
   1342                                   }
   1343                               }
   1344                          }
   1345                      } else {
   1346                          same_mxqblock_max_port_speed = 0;
   1347                      }
   1348                      if ((speed == 10000) || (speed == 21000) || 
   1349                          (same_mxqblock_max_port_speed == 10000) || 
   1350                          (same_mxqblock_max_port_speed == 21000)) {
   1351                           wc_10g_21g_sel = 1;
   1352                      }
   1353                 }
   1354                 if ((mxqblock == 6) || (mxqblock == 7)) {
   1355                      if (speed == 10000) {
   1356                          SOC_IF_ERROR_RETURN(
   1357                          soc_katana2_get_phy_connection_mode(unit,port,
   1358                               mxqblock,&connection_mode)); 
   1359                          /* XFI Mode */ 
   1360                          if (connection_mode == bcmMqxConnectionWarpCore) {
   1361                              wc_10g_21g_sel = 1;
   1362                          }
   1363                      }
   1364                 }
   1365                 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval,
   1366                                   WC_10G_21G_SELf, wc_10g_21g_sel);
   1367             }
   1368 #endif
   1369             soc_reg_field_set(unit, XPORT_MODE_REGr, &rval,
   1370                                 PHY_PORT_MODEf, phy_mode);
   1371             soc_reg_field_set(unit, XPORT_MODE_REGr, &rval,
   1372                                 PORT_GMII_MII_ENABLEf, 
   1373                                 ((speed >= 10000) || 
   1374                                  (same_mxqblock_max_port_speed >= 10000))
   1375                                 ? 0 : 1);
   1376             if (rval != rval_orig) {
   1377                 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval));
   1378 #ifdef BCM_TRIUMPH3_SUPPORT
   1379                 /* On TR3/KT2 hard reset XMAC following mode change */
   1380                 if (soc_feature(unit, soc_feature_xmac_reset_on_mode_change)) {
   1381                     SOC_IF_ERROR_RETURN(_mac_x_reinit(unit, port));
   1382                 }
   1383 #endif
   1384             }
   1385         }
   1386 
   1387         if (enable) {
   1388             /* Re-enable transmitter and receiver */
   1389             SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 1));
   1390         }
   1391 
   1392         /* Set Timestamp Mac Delays */
   1393         if (!IS_GE_PORT(unit, port)) {
   1394             SOC_IF_ERROR_RETURN(_mac_x_timestamp_delay_set(
   1395                                     unit, port, speed, phy_mode));
   1396         }
   1397     }
   1398 #endif /* BCM_KATANA_SUPPORT */
   1399 
   1400 #ifdef BCM_UNIPORT_SUPPORT
   1401     if (SOC_IS_TRIUMPH3(unit)) {
   1402         
   1403         soc_info_t *si;
   1404         int phy_port;
   1405         int bindex = -1;
   1406         uint32 rval;
   1407         uint32 core_mode, core_mode_org = -1, phy_mode, phy_mode_org = -1;
   1408         uint32 xpc_enable = 0, xpc_enable_org = -1;
   1409         uint32 strict_preamble = 1;
   1410         uint64 rval64;
   1411 
   1412         si = &SOC_INFO(unit);
   1413         phy_port = si->port_l2p_mapping[port];
   1414         if (phy_port == -1) {
   1415             return SOC_E_INTERNAL;
   1416         }
   1417         bindex = SOC_PORT_BINDEX(unit, phy_port) / 4;
   1418         SOC_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval));
   1419 
   1420         xpc_enable_org = soc_reg_field_get(unit, PORT_MODE_REGr, rval, 
   1421                                            xpc_gmii_enable_field[bindex]);
   1422 
   1423         if ((speed < 10000) && (IS_XT_PORT(unit, port) ||
   1424             (port == si->management_port))) {
   1425             if (!SOC_IS_HELIX4(unit)) {
   1426                 xpc_enable = 1;
   1427             }
   1428         }
   1429 
   1430         if (xpc_enable != xpc_enable_org) {
   1431             soc_reg_field_set(unit, PORT_MODE_REGr, &rval, 
   1432                               xpc_gmii_enable_field[bindex],
   1433                               xpc_enable);
   1434             SOC_IF_ERROR_RETURN(WRITE_PORT_MODE_REGr(unit, port, rval));
   1435         }
   1436         core_mode_org = soc_reg_field_get(unit, PORT_MODE_REGr, rval, 
   1437                                          core_mode_field[bindex]);
   1438         phy_mode_org = soc_reg_field_get(unit, PORT_MODE_REGr, rval, 
   1439                                          phy_mode_field[bindex]);
   1440 
   1441         if (IS_XT_PORT(unit, port) && (speed >= 10000)) {
   1442             core_mode = 0; /* XAUI */
   1443             phy_mode = 1;
   1444         } else if (!IS_XT_PORT(unit, port)) {
   1445             core_mode = 0;
   1446             phy_mode = 0;
   1447             if ((speed >= 10000) && (speed <= 11000)) {
   1448                 phy_mode = 2; /* XAUI */
   1449                 if (si->port_num_lanes[port] == 1) { /* XFI */
   1450                     core_mode = 2;
   1451                 } else if (si->port_num_lanes[port] == 2) { /* RXAUI */
   1452                     core_mode = 1;
   1453                 }
   1454             } else if ((speed > 11000) && (si->port_num_lanes[port] == 2)) { /* HG-Duo */
   1455                 core_mode = 1;
   1456                 phy_mode = 1;
   1457             } else if (speed <= 2500) {
   1458                 core_mode = 2;
   1459                 phy_mode = 2;
   1460             } else if (speed <= 20000) {
   1461                 phy_mode = 1; /* HG 12/13/16/20 */
   1462             }
   1463         } else { /* GE */
   1464             core_mode = 2;
   1465             phy_mode = 2;
   1466         }
   1467         if ((core_mode_org != core_mode) || (phy_mode_org != phy_mode)) {
   1468             LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1469                         (BSL_META_U(unit,
   1470                                     "cmo: %d -> cm: %d, pmo: %d -> pm: %d\n"), 
   1471                          core_mode_org, core_mode, phy_mode_org, phy_mode));
   1472 
   1473             soc_reg_field_set(unit, PORT_MODE_REGr, &rval, 
   1474                               core_mode_field[bindex], core_mode);
   1475             soc_reg_field_set(unit, PORT_MODE_REGr, &rval, 
   1476                               phy_mode_field[bindex], phy_mode);
   1477             LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1478                         (BSL_META_U(unit,
   1479                                     "Port: %d set port mode: %d, phy mode: %d\n"), 
   1480                          port, core_mode, phy_mode));
   1481             SOC_IF_ERROR_RETURN(WRITE_PORT_MODE_REGr(unit, port, rval));
   1482 
   1483 #ifdef BCM_TRIUMPH3_SUPPORT
   1484             if (SOC_IS_TRIUMPH3(unit)) {
   1485                 SOC_IF_ERROR_RETURN(_mac_x_reinit(unit, port));
   1486             }
   1487 #endif
   1488         }
   1489         if (soc_reg_field_valid(unit, XMAC_MODEr, SPEED_MODEf)) {
   1490             int speed_select, enable;
   1491             switch (speed) {
   1492             case 10:
   1493                 strict_preamble = 0;
   1494                 speed_select = SOC_XMAC_SPEED_10;
   1495                 break;
   1496             /* support non-standard speed in Broadreach mode */
   1497             case 20:
   1498             case 25:
   1499             case 33:
   1500             case 50:
   1501                 /* fall through to case 100 */
   1502             case 100:
   1503                 strict_preamble = 0;
   1504                 speed_select = SOC_XMAC_SPEED_100;
   1505                 break;
   1506             case 1000:
   1507                 speed_select = SOC_XMAC_SPEED_1000;
   1508                 strict_preamble = 0; 
   1509                 break;
   1510             case 2500:
   1511             case 3000:
   1512                 strict_preamble = 0;
   1513                 speed_select = SOC_XMAC_SPEED_2500;
   1514                 break;
   1515             case 10000:
   1516             case 11000:
   1517             case 12000:
   1518             case 13000:
   1519             case 15000:
   1520             case 16000:
   1521             case 20000:
   1522             case 21000:
   1523             case 23000:
   1524             case 25000:
   1525             case 30000:
   1526             case 32000:
   1527             case 40000:
   1528             case 42000:
   1529                 speed_select = SOC_XMAC_SPEED_10000;
   1530                 break;
   1531             case 0:
   1532                 return (SOC_E_NONE);              /* Support NULL PHY */            
   1533             default:
   1534                 return (SOC_E_CONFIG);
   1535             }
   1536             /* Update preamble processing */
   1537             SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rval64));
   1538             if (IS_HG_PORT(unit, port)) {
   1539                 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64,
   1540                                       STRICT_PREAMBLEf, 0);
   1541                 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64,
   1542                                       PROCESS_VARIABLE_PREAMBLEf, 0);
   1543             } else {
   1544                 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64,
   1545                                       STRICT_PREAMBLEf, strict_preamble ?
   1546                                       1 : 0);
   1547                 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64,
   1548                                       PROCESS_VARIABLE_PREAMBLEf, 
   1549                                       strict_preamble ? 0 : 1);
   1550             }
   1551             SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rval64));
   1552 
   1553             SOC_IF_ERROR_RETURN(mac_x_enable_get(unit, port, &enable));
   1554             
   1555             if (enable) {
   1556                 /* Turn off TX/RX enable */
   1557                 SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 0));
   1558             }
   1559             
   1560             /* Update the speed */
   1561             SOC_IF_ERROR_RETURN
   1562                 (soc_reg_field32_modify(unit, XMAC_MODEr, port,
   1563                                         SPEED_MODEf, speed_select));
   1564 
   1565 
   1566 
   1567             if (enable) {
   1568                 /* Re-enable transmitter and receiver */
   1569                 SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 1));
   1570             }
   1571 
   1572         }
   1573 
   1574         /* Set Timestamp Mac Delays */
   1575         if (!IS_GE_PORT(unit, port)) {
   1576             SOC_IF_ERROR_RETURN(_mac_x_timestamp_delay_set(
   1577                                     unit, port, speed, phy_mode));
   1578         }
   1579     }
   1580 #endif /* BCM_UNIPORT_SUPPORT */
   1581     /* Enable XLGMII_ALIGN_ENB when using Multi-Lane Distribution (MLD) */
   1582     xlgmii_align = 0;
   1583 
   1584 #if defined(BCM_TRIDENT_SUPPORT)
   1585     ipg_check_disable = 0;
   1586 #endif
   1587 
   1588     SOC_IF_ERROR_RETURN(soc_phyctrl_interface_get(unit,port,&intf));
   1589     if (IS_XE_PORT(unit, port)) {
   1590         /* xe port, 40G mld-4 and 20G mld-2 */
   1591         if ((speed == 40000) || (speed == 42000) || 
   1592             ((speed == 20000) && (intf==SOC_PORT_IF_KR))) {
   1593             xlgmii_align = 1;
   1594         }
   1595     } else { /* HG port with external PHY may also use IEEE 40G mld-4 */
   1596         if (((speed == 40000) || (speed == 42000))
   1597             && PHY_EXTERNAL_MODE(unit, port)
   1598             && (!PHY_PASSTHRU_MODE(unit, port))
   1599             && (!soc_property_port_get(unit, port, 
   1600                                        spn_PORT_PHY_MODE_REVERSE, 0))) {
   1601             xlgmii_align = 1;
   1602         }
   1603 #if defined(BCM_TRIDENT_SUPPORT)
   1604         if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT(unit)) {
   1605             if (intf == SOC_PORT_IF_KR4) {
   1606                 xlgmii_align = 1;
   1607             }
   1608             else {
   1609                 ipg_check_disable = 1;
   1610             }
   1611         }
   1612 #endif
   1613     }
   1614     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval64));
   1615     soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, XLGMII_ALIGN_ENBf,
   1616                           xlgmii_align);
   1617 #if defined(BCM_TRIDENT_SUPPORT)
   1618     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT(unit)) {
   1619         if (soc_reg_field_valid(unit, XMAC_CTRLr, XGMII_IPG_CHECK_DISABLEf)) {
   1620             soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64,XGMII_IPG_CHECK_DISABLEf, ipg_check_disable);
   1621         }
   1622     }
   1623 #endif
   1624     SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, rval64));
   1625 
   1626     return SOC_E_NONE;
   1627 }
   1628 
   1629 /*
   1630  * Function:
   1631  *      mac_x_speed_get
   1632  * Purpose:
   1633  *      Get XMAC speed
   1634  * Parameters:
   1635  *      unit - XGS unit #.
   1636  *      port - XGS port # on unit.
   1637  *      speed - (OUT) speed in Mb
   1638  * Returns:
   1639  *      SOC_E_XXX
   1640  */
   1641 STATIC int
   1642 mac_x_speed_get(int unit, soc_port_t port, int *speed)
   1643 {
   1644     uint64 rval;
   1645 #ifdef BCM_KATANA_SUPPORT
   1646     uint32 index=0;
   1647     uint32 rval32=0;
   1648     soc_field_t speed_fields[]={XGXS0_SPEED16000f,XGXS0_SPEED15000f,
   1649                                 XGXS0_SPEED13000f,XGXS0_SPEED12500f,
   1650                                 XGXS0_SPEED12000f,XGXS0_SPEED10000_CX4f,
   1651                                 XGXS0_SPEED10000f,XGXS0_SPEED1000f};
   1652     int         speed_values[]={16000,15000,
   1653                                13000,12500,
   1654                                12000,10000,
   1655                                10000,1000};
   1656 #endif /* BCM_KATANA_SUPPORT */
   1657 
   1658     *speed = 10000;
   1659 
   1660     /* We should be looking for Ver B0 in  XMAC_VERSION_ID reg. But this reg
   1661      is not implemented in Katana A0. So, check for SPEED_MODE field instead */
   1662     if (soc_reg_field_valid(unit, XMAC_MODEr, SPEED_MODEf)) {
   1663 
   1664         SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &rval));
   1665         switch (soc_reg64_field32_get(unit, XMAC_MODEr, rval, SPEED_MODEf)) {
   1666         case SOC_XMAC_SPEED_10:
   1667             *speed = 10;
   1668             break;
   1669         case SOC_XMAC_SPEED_100:
   1670             *speed = 100;
   1671             break;
   1672         case SOC_XMAC_SPEED_1000:
   1673             *speed = 1000;
   1674             break;
   1675         case SOC_XMAC_SPEED_2500:
   1676             *speed = 2500;
   1677             break;
   1678         case SOC_XMAC_SPEED_10000:
   1679         default:
   1680 #ifdef BCM_KATANA_SUPPORT
   1681             if (SOC_IS_KATANA(unit)) {
   1682                 if (IS_HG_PORT(unit, port)) {
   1683                     SOC_IF_ERROR_RETURN
   1684                     (READ_XPORT_XGXS_NEWSTATUS1_REGr(unit, port, &rval32));
   1685                     for(index=0;
   1686                         index <sizeof(speed_values)/sizeof(speed_values[0]);
   1687                         index++) {
   1688                         if (soc_reg_field_get(
   1689                             unit, XPORT_XGXS_NEWSTATUS1_REGr,
   1690                             rval32, speed_fields[index])) {
   1691                             *speed = speed_values[index];
   1692                             break;
   1693                         }
   1694                     }
   1695                     if (index != sizeof(speed_values)/sizeof(speed_values[0])) {
   1696                         break;
   1697                     }
   1698                 }
   1699             }
   1700             /* No other option left*/
   1701 #endif /* BCM_KATANA_SUPPORT */
   1702             *speed = 10000;
   1703             break;
   1704         }
   1705     }
   1706 
   1707     LOG_VERBOSE(BSL_LS_SOC_10G,
   1708                 (BSL_META_U(unit,
   1709                             "mac_x_speed_get: unit %d port %s speed=%dMb\n"),
   1710                  unit, SOC_PORT_NAME(unit, port),
   1711                  *speed));
   1712     return SOC_E_NONE;
   1713 }
   1714 
   1715 /*
   1716  * Function:
   1717  *      mac_x_loopback_set
   1718  * Purpose:
   1719  *      Set a XMAC into/out-of loopback mode
   1720  * Parameters:
   1721  *      unit - XGS unit #.
   1722  *      port - XGS unit # on unit.
   1723  *      loopback - Boolean: true -> loopback mode, false -> normal operation
   1724  * Note:
   1725  *      On Xmac, when setting loopback, we enable the TX/RX function also.
   1726  *      Note that to test the PHY, we use the remote loopback facility.
   1727  * Returns:
   1728  *      SOC_E_XXX
   1729  */
   1730 STATIC int
   1731 mac_x_loopback_set(int unit, soc_port_t port, int lb)
   1732 {
   1733     LOG_VERBOSE(BSL_LS_SOC_10G,
   1734                 (BSL_META_U(unit,
   1735                             "mac_x_loopback_set: unit %d port %s loopback=%s\n"),
   1736                  unit, SOC_PORT_NAME(unit, port),
   1737                  lb ? "local" : "no"));
   1738 
   1739     /* need to enable clock compensation for applicable serdes device */
   1740     (void)soc_phyctrl_notify(unit, port, phyEventMacLoopback, lb? 1: 0);
   1741 
   1742     if (lb) {
   1743         SOC_IF_ERROR_RETURN(soc_mac_x_sync_fifo_reset(unit, port));
   1744     }
   1745 
   1746     return soc_reg_field32_modify(unit, XMAC_CTRLr, port,
   1747                                   soc_property_port_get(unit, port,
   1748                                                         "mac_line_lb", 1) ?
   1749                                   LINE_LOCAL_LPBKf : CORE_LOCAL_LPBKf,
   1750                                   lb ? 1 : 0);
   1751 }
   1752 
   1753 /*
   1754  * Function:
   1755  *      mac_x_loopback_get
   1756  * Purpose:
   1757  *      Get current XMAC loopback mode setting.
   1758  * Parameters:
   1759  *      unit - XGS unit #.
   1760  *      port - XGS port # on unit.
   1761  *      loopback - (OUT) Boolean: true = loopback, false = normal
   1762  * Returns:
   1763  *      SOC_E_XXX
   1764  */
   1765 STATIC int
   1766 mac_x_loopback_get(int unit, soc_port_t port, int *lb)
   1767 {
   1768     uint64 ctrl;
   1769     int local, remote;
   1770 
   1771     SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl));
   1772 
   1773     remote = soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, CORE_REMOTE_LPBKf) |
   1774         soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, LINE_REMOTE_LPBKf);
   1775     local = soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, CORE_LOCAL_LPBKf) |
   1776         soc_reg64_field32_get(unit, XMAC_CTRLr, ctrl, LINE_LOCAL_LPBKf);
   1777     *lb = local | remote;
   1778 
   1779     LOG_VERBOSE(BSL_LS_SOC_10G,
   1780                 (BSL_META_U(unit,
   1781                             "mac_x_loopback_get: unit %d port %s loopback=%s\n"),
   1782                  unit, SOC_PORT_NAME(unit, port),
   1783                  *lb ? (remote ? "remote" : "local") : "no"));
   1784     return SOC_E_NONE;
   1785 }
   1786 
   1787 /*
   1788  * Function:
   1789  *      mac_x_pause_addr_set
   1790  * Purpose:
   1791  *      Configure PAUSE frame source address.
   1792  * Parameters:
   1793  *      unit - XGS unit #.
   1794  *      port - XGS port # on unit.
   1795  *      pause_mac - (OUT) MAC address used for pause transmission.
   1796  * Returns:
   1797  *      SOC_E_XXX
   1798  */
   1799 STATIC int
   1800 mac_x_pause_addr_set(int unit, soc_port_t port, sal_mac_addr_t m)
   1801 {
   1802     uint64 r, tmp;
   1803     int i;
   1804 
   1805     LOG_VERBOSE(BSL_LS_SOC_10G,
   1806                 (BSL_META_U(unit,
   1807                             "mac_x_pause_addr_set: unit %d port %s MAC=<"
   1808                              "%02x:%02x:%02x:%02x:%02x:%02x>\n"),
   1809                  unit, SOC_PORT_NAME(unit, port),
   1810                  m[0], m[1], m[2], m[3], m[4], m[5]));
   1811 
   1812     COMPILER_64_ZERO(r);
   1813     for (i = 0; i< 6; i++) {
   1814         COMPILER_64_SET(tmp, 0, m[i]);
   1815         COMPILER_64_SHL(r, 8);
   1816         COMPILER_64_OR(r, tmp);
   1817     }
   1818 
   1819     SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_MAC_SAr(unit, port, r));
   1820     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAC_SAr(unit, port, r));
   1821 
   1822     return SOC_E_NONE;
   1823 }
   1824 
   1825 /*
   1826  * Function:
   1827  *      mac_x_pause_addr_get
   1828  * Purpose:
   1829  *      Retrieve PAUSE frame source address.
   1830  * Parameters:
   1831  *      unit - XGS unit #.
   1832  *      port - XGS port # on unit.
   1833  *      pause_mac - (OUT) MAC address used for pause transmission.
   1834  * Returns:
   1835  *      SOC_E_XXX
   1836  * NOTE: We always write the same thing to TX & RX SA
   1837  *       so, we just return the contects on RX_MAC_SA.
   1838  */
   1839 STATIC int
   1840 mac_x_pause_addr_get(int unit, soc_port_t port, sal_mac_addr_t m)
   1841 {
   1842     uint64 reg;
   1843     uint32 msw;
   1844     uint32 lsw;
   1845 
   1846     SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAC_SAr(unit, port, &reg));
   1847     COMPILER_64_TO_32_HI(msw, reg);
   1848     COMPILER_64_TO_32_LO(lsw, reg);
   1849 
   1850     m[0] = (uint8) ( ( msw & 0x0000ff00 ) >> 8 );
   1851     m[1] = (uint8) ( msw & 0x000000ff );
   1852 
   1853     m[2] = (uint8)  ( ( lsw & 0xff000000) >> 24 );
   1854     m[3] = (uint8)  ( ( lsw & 0x00ff0000) >> 16 );
   1855     m[4] = (uint8)  ( ( lsw & 0x0000ff00) >> 8 );
   1856     m[5] = (uint8)  ( lsw & 0x000000ff );
   1857 
   1858     LOG_VERBOSE(BSL_LS_SOC_10G,
   1859                 (BSL_META_U(unit,
   1860                             "mac_x_pause_addr_get: unit %d port %s MAC=<"
   1861                              "%02x:%02x:%02x:%02x:%02x:%02x>\n"),
   1862                  unit, SOC_PORT_NAME(unit, port),
   1863                  m[0], m[1], m[2], m[3], m[4], m[5]));
   1864     return SOC_E_NONE;
   1865 }
   1866 
   1867 /*
   1868  * Function:
   1869  *      mac_x_interface_set
   1870  * Purpose:
   1871  *      Set a XMAC interface type
   1872  * Parameters:
   1873  *      unit - XGS unit #.
   1874  *      port - XGS port # on unit.
   1875  *      pif - one of SOC_PORT_IF_*
   1876  * Returns:
   1877  *      SOC_E_NONE
   1878  *      SOC_E_UNAVAIL - requested mode not supported.
   1879  * Notes:
   1880  */
   1881 STATIC int
   1882 mac_x_interface_set(int unit, soc_port_t port, soc_port_if_t pif)
   1883 {
   1884 #ifdef BROADCOM_DEBUG
   1885     LOG_VERBOSE(BSL_LS_SOC_10G,
   1886                 (BSL_META_U(unit,
   1887                             "mac_x_interface_set: unit %d port %s interface=%s\n"),
   1888                  unit, SOC_PORT_NAME(unit, port),
   1889                  mac_x_port_if_names[pif]));
   1890 #endif
   1891     return SOC_E_NONE;
   1892 }
   1893 
   1894 /*
   1895  * Function:
   1896  *      mac_x_interface_get
   1897  * Purpose:
   1898  *      Retrieve XMAC interface type
   1899  * Parameters:
   1900  *      unit - XGS unit #.
   1901  *      port - XGS port # on unit.
   1902  *      pif - (OUT) one of SOC_PORT_IF_*
   1903  * Returns:
   1904  *      SOC_E_NONE
   1905  */
   1906 STATIC int
   1907 mac_x_interface_get(int unit, soc_port_t port, soc_port_if_t *pif)
   1908 {
   1909     COMPILER_REFERENCE(unit);
   1910     COMPILER_REFERENCE(port);
   1911 
   1912     *pif = SOC_PORT_IF_MII;
   1913 
   1914 #ifdef BROADCOM_DEBUG
   1915     LOG_VERBOSE(BSL_LS_SOC_10G,
   1916                 (BSL_META_U(unit,
   1917                             "mac_x_interface_get: unit %d port %s interface=%s\n"),
   1918                  unit, SOC_PORT_NAME(unit, port),
   1919                  mac_x_port_if_names[*pif]));
   1920 #endif
   1921     return SOC_E_NONE;
   1922 }
   1923 
   1924 /*
   1925  * Function:
   1926  *      mac_x_frame_max_set
   1927  * Description:
   1928  *      Set the maximum receive frame size for the port
   1929  * Parameters:
   1930  *      unit - Device number
   1931  *      port - Port number
   1932  *      size - Maximum frame size in bytes
   1933  * Return Value:
   1934  *      BCM_E_XXX
   1935  */
   1936 STATIC int
   1937 mac_x_frame_max_set(int unit, soc_port_t port, int size)
   1938 {
   1939     uint64 rval;
   1940 
   1941     LOG_VERBOSE(BSL_LS_SOC_10G,
   1942                 (BSL_META_U(unit,
   1943                             "mac_x_frame_max_set: unit %d port %s size=%d\n"),
   1944                  unit, SOC_PORT_NAME(unit, port),
   1945                  size));
   1946 
   1947     if (IS_GE_PORT(unit, port) || IS_XE_PORT(unit, port)) {
   1948         /* For VLAN tagged packets */
   1949         size += 4;
   1950     }
   1951     COMPILER_64_ZERO(rval);
   1952     soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &rval, RX_MAX_SIZEf, size);
   1953     SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr(unit, port, rval));
   1954     return SOC_E_NONE;
   1955 }
   1956 
   1957 /*
   1958  * Function:
   1959  *      mac_x_frame_max_get
   1960  * Description:
   1961  *      Set the maximum receive frame size for the port
   1962  * Parameters:
   1963  *      unit - Device number
   1964  *      port - Port number
   1965  *      size - Maximum frame size in bytes
   1966  * Return Value:
   1967  *      BCM_E_XXX
   1968  */
   1969 STATIC int
   1970 mac_x_frame_max_get(int unit, soc_port_t port, int *size)
   1971 {
   1972     uint64 rval;
   1973 
   1974     SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAX_SIZEr(unit, port, &rval));
   1975     *size = soc_reg64_field32_get(unit, XMAC_RX_MAX_SIZEr, rval, RX_MAX_SIZEf);
   1976     if (IS_GE_PORT(unit, port) || IS_XE_PORT(unit, port)) {
   1977         /* For VLAN tagged packets */
   1978         *size -= 4;
   1979     }
   1980 
   1981     LOG_VERBOSE(BSL_LS_SOC_10G,
   1982                 (BSL_META_U(unit,
   1983                             "mac_x_frame_max_get: unit %d port %s size=%d\n"),
   1984                  unit, SOC_PORT_NAME(unit, port),
   1985                  *size));
   1986     return SOC_E_NONE;
   1987 }
   1988 
   1989 /*
   1990  * Function:
   1991  *      mac_x_ifg_set
   1992  * Description:
   1993  *      Sets the new ifg (Inter-frame gap) value
   1994  * Parameters:
   1995  *      unit   - Device number
   1996  *      port   - Port number
   1997  *      speed  - the speed for which the IFG is being set
   1998  *      duplex - the duplex for which the IFG is being set
   1999  *      ifg - number of bits to use for average inter-frame gap
   2000  * Return Value:
   2001  *      BCM_E_XXX
   2002  * Notes:
   2003  *      The function makes sure the IFG value makes sense and updates the
   2004  *      IPG register in case the speed/duplex match the current settings
   2005  */
   2006 STATIC int
   2007 mac_x_ifg_set(int unit, soc_port_t port, int speed,
   2008                 soc_port_duplex_t duplex, int ifg)
   2009 {
   2010     int         real_ifg, encap;
   2011     soc_ipg_t  *si = &SOC_PERSIST(unit)->ipg[port];
   2012     uint64      rval, orval;
   2013     soc_port_ability_t ability;
   2014     uint32      pa_flag;
   2015 
   2016     LOG_VERBOSE(BSL_LS_SOC_10G,
   2017                 (BSL_META_U(unit,
   2018                             "mac_x_ifg_set: unit %d port %s speed=%dMb duplex=%s "
   2019                              "ifg=%d\n"),
   2020                  unit, SOC_PORT_NAME(unit, port),
   2021                  speed, duplex ? "True" : "False", ifg));
   2022 
   2023     pa_flag = SOC_PA_SPEED(speed); 
   2024     soc_mac_x.md_ability_local_get(unit, port, &ability);
   2025     if (!(pa_flag & ability.speed_full_duplex)) {
   2026         return SOC_E_PARAM;
   2027     }
   2028 
   2029     /* Silently adjust the specified ifp bits to valid value */
   2030     /* valid value: 8 to 31 bytes (i.e. multiple of 8 bits) */
   2031     real_ifg = ifg < 64 ? 64 : (ifg > 248 ? 248 : (ifg + 7) & (0x1f << 3));
   2032 
   2033     if (IS_XE_PORT(unit, port) || IS_GE_PORT(unit,port)) {
   2034         si->fd_xe = real_ifg;
   2035     } else {
   2036         SOC_IF_ERROR_RETURN
   2037             (soc_mac_x.md_encap_get(unit, port, &encap));
   2038         if(encap == SOC_ENCAP_HIGIG2) {
   2039             si->fd_hg2 = real_ifg;
   2040         } else {
   2041             si->fd_hg = real_ifg;
   2042         }
   2043     }
   2044 
   2045 
   2046     SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &rval));
   2047     orval = rval;
   2048     soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, AVERAGE_IPGf,
   2049                           IPG_BYTE(real_ifg));
   2050     if (COMPILER_64_NE(rval, orval)) {
   2051         SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, rval));
   2052     }
   2053 
   2054     return SOC_E_NONE;
   2055 }
   2056 
   2057 /*
   2058  * Function:
   2059  *      mac_x_ifg_get
   2060  * Description:
   2061  *      Sets the new ifg (Inter-frame gap) value
   2062  * Parameters:
   2063  *      unit   - Device number
   2064  *      port   - Port number
   2065  *      speed  - the speed for which the IFG is being set
   2066  *      duplex - the duplex for which the IFG is being set
   2067  *      size - Maximum frame size in bytes
   2068  * Return Value:
   2069  *      BCM_E_XXX
   2070  * Notes:
   2071  *      The function makes sure the IFG value makes sense and updates the
   2072  *      IPG register in case the speed/duplex match the current settings
   2073  */
   2074 STATIC int
   2075 mac_x_ifg_get(int unit, soc_port_t port, int speed,
   2076                 soc_port_duplex_t duplex, int *ifg)
   2077 {
   2078     soc_ipg_t  *si = &SOC_PERSIST(unit)->ipg[port];
   2079     soc_port_ability_t ability;
   2080     uint32      pa_flag;
   2081     int encap;
   2082 
   2083     if (!duplex) {
   2084         return SOC_E_PARAM;
   2085     }
   2086 
   2087     pa_flag = SOC_PA_SPEED(speed); 
   2088     soc_mac_x.md_ability_local_get(unit, port, &ability);
   2089     if (!(pa_flag & ability.speed_full_duplex)) {
   2090         return SOC_E_PARAM;
   2091     }
   2092 
   2093     if (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port)) {
   2094         *ifg = si->fd_xe;
   2095     } else {
   2096         SOC_IF_ERROR_RETURN
   2097             (soc_mac_x.md_encap_get(unit, port, &encap));
   2098         if(encap == SOC_ENCAP_HIGIG2) {
   2099             *ifg = si->fd_hg2;
   2100         } else {
   2101             *ifg = si->fd_hg;
   2102         }
   2103     }
   2104 
   2105     LOG_VERBOSE(BSL_LS_SOC_10G,
   2106                 (BSL_META_U(unit,
   2107                             "mac_x_ifg_get: unit %d port %s speed=%dMb duplex=%s "
   2108                              "ifg=%d\n"),
   2109                  unit, SOC_PORT_NAME(unit, port),
   2110                  speed, duplex ? "True" : "False", *ifg));
   2111     return SOC_E_NONE;
   2112 }
   2113 
   2114 /*
   2115  * Function:
   2116  *      mac_x_loopback_remote_set
   2117  * Purpose:
   2118  *      Set the XMAC into remote-loopback state.
   2119  * Parameters:
   2120  *      unit - XGS unit #.
   2121  *      port - XGS port # on unit.
   2122  *      mode - (INT) loopback enable state
   2123  * Returns:
   2124  *      SOC_E_XXX
   2125  */
   2126 int
   2127 mac_x_loopback_remote_set(int unit, soc_port_t port, int lb)
   2128 {
   2129     LOG_VERBOSE(BSL_LS_SOC_10G,
   2130                 (BSL_META_U(unit,
   2131                             "mac_x_loopback_remote_set: unit %d port %s loopback=%s\n"),
   2132                  unit, SOC_PORT_NAME(unit, port),
   2133                  lb ? "remote" : "no"));
   2134 
   2135     return soc_reg_field32_modify(unit, XMAC_CTRLr, port, CORE_REMOTE_LPBKf,
   2136                                   lb ? 1 : 0);
   2137 }
   2138 
   2139 /*
   2140  * Function:
   2141  *      _mac_x_port_mode_update
   2142  * Purpose:
   2143  *      Set the XMAC port encapsulation mode.
   2144  * Parameters:
   2145  *      unit - XGS unit #.
   2146  *      port - XGS port # on unit.
   2147  *      to_hg_port - (TRUE/FALSE)
   2148  * Returns:
   2149  *      SOC_E_XXX
   2150  */
   2151 STATIC int
   2152 _mac_x_port_mode_update(int unit, soc_port_t port, int to_hg_port)
   2153 {
   2154     uint32              rval;
   2155     uint64              val64;
   2156     soc_pbmp_t          ctr_pbmp;
   2157     int                 rv = SOC_E_NONE;
   2158 
   2159     /* Pause linkscan */
   2160     soc_linkscan_pause(unit);
   2161 
   2162     /* Pause counter collection */
   2163     COUNTER_LOCK(unit);
   2164 
   2165     soc_xport_type_update(unit, port, to_hg_port);
   2166 
   2167 #if defined(BCM_TRIDENT_SUPPORT) || defined (BCM_TRIUMPH3_SUPPORT) || \
   2168     defined(BCM_SHADOW_SUPPORT) || defined(BCM_KATANA2_SUPPORT)
   2169     if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) ||
   2170                        SOC_IS_SHADOW(unit) || SOC_IS_KATANA2(unit)) {
   2171        /* no need to hard reset the Warpcore serdes device. Soft init
   2172         * should be good enough.  Hard reset brings
   2173         * down all other ports using the same Warpcore in quad-port mode. 
   2174         */
   2175     } else 
   2176 #endif /* BCM_TRIDENT_SUPPORT || BCM_TRIUMPH3_SUPPORT || BCM_SHADOW_SUPPORT */
   2177     {
   2178         rv = soc_xgxs_reset(unit, port);
   2179     }
   2180 
   2181     if (SOC_SUCCESS(rv)) {
   2182         rv = soc_phyctrl_init(unit, port);
   2183     }
   2184 
   2185     if (SOC_SUCCESS(rv)) {
   2186         rv = mac_x_init(unit, port);
   2187     }
   2188 
   2189     if (SOC_SUCCESS(rv)) {
   2190         rv = mac_x_enable_set(unit, port, 0);
   2191     }
   2192 
   2193     if (SOC_SUCCESS(rv)) {
   2194         SOC_PBMP_CLEAR(ctr_pbmp);
   2195         SOC_PBMP_PORT_SET(ctr_pbmp, port);
   2196         COMPILER_64_SET(val64, 0, 0);
   2197         rv = soc_counter_set_by_port(unit, ctr_pbmp, val64);
   2198     }
   2199 
   2200     COUNTER_UNLOCK(unit);
   2201     soc_linkscan_continue(unit);
   2202 
   2203     if (SOC_REG_IS_VALID(unit, XLPORT_CONFIGr)) {
   2204         SOC_IF_ERROR_RETURN(READ_XLPORT_CONFIGr(unit, port, &rval));
   2205         soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, HIGIG_MODEf,
   2206                           to_hg_port ? 1 : 0);
   2207         soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, XPAUSE_RX_ENf,
   2208                           to_hg_port ? 1 : 0);
   2209         soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, XPAUSE_TX_ENf,
   2210                           to_hg_port ? 1 : 0);
   2211         soc_reg_field_set(unit, XLPORT_CONFIGr, &rval, XPAUSE_ENf,
   2212                           to_hg_port ? 1 : 0);
   2213         SOC_IF_ERROR_RETURN(WRITE_XLPORT_CONFIGr(unit, port, rval));
   2214     }
   2215     if (SOC_REG_IS_VALID(unit, XPORT_CONFIGr)) {
   2216         SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &rval));
   2217         if (to_hg_port) {
   2218             soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1);
   2219         } else {
   2220             soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 0);
   2221         }
   2222         SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval));
   2223     }
   2224     return rv;
   2225 }
   2226 
   2227 /*
   2228  * Function:
   2229  *      mac_x_encap_set
   2230  * Purpose:
   2231  *      Set the XMAC port encapsulation mode.
   2232  * Parameters:
   2233  *      unit - XGS unit #.
   2234  *      port - XGS port # on unit.
   2235  *      mode - (IN) encap bits (defined above)
   2236  * Returns:
   2237  *      SOC_E_XXX
   2238  */
   2239 STATIC int
   2240 mac_x_encap_set(int unit, soc_port_t port, int mode)
   2241 {
   2242     int enable, encap, rv;
   2243     int runt, ipg;
   2244 
   2245 #ifdef BROADCOM_DEBUG
   2246     LOG_VERBOSE(BSL_LS_SOC_10G,
   2247                 (BSL_META_U(unit,
   2248                             "mac_x_encap_set: unit %d port %s encapsulation=%s\n"),
   2249                  unit, SOC_PORT_NAME(unit, port),
   2250                  mac_x_encap_mode[mode]));
   2251 #endif
   2252 
   2253     switch (mode) {
   2254     case SOC_ENCAP_IEEE:
   2255     case SOC_ENCAP_HIGIG2_LITE:
   2256         encap = 0;
   2257         break;
   2258     case SOC_ENCAP_HIGIG:
   2259         encap = 1;
   2260         break;
   2261     case SOC_ENCAP_HIGIG2:
   2262         encap = 2;
   2263         break;
   2264     default:
   2265         return SOC_E_PARAM;
   2266     }
   2267 
   2268     if (!soc_feature(unit, soc_feature_xport_convertible)) {
   2269         if ((IS_E_PORT(unit, port) && mode != SOC_ENCAP_IEEE) ||
   2270             (IS_ST_PORT(unit, port) && mode == SOC_ENCAP_IEEE)) {
   2271             return SOC_E_PARAM;
   2272         }
   2273     }
   2274 
   2275     SOC_IF_ERROR_RETURN(mac_x_enable_get(unit, port, &enable));
   2276 
   2277     if (enable) {
   2278         /* Turn off TX/RX enable */
   2279         SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 0));
   2280     }
   2281 
   2282     if (IS_E_PORT(unit, port) && mode != SOC_ENCAP_IEEE) {
   2283         /* XE -> HG */
   2284         SOC_IF_ERROR_RETURN(_mac_x_port_mode_update(unit, port, TRUE));
   2285     } else if (IS_ST_PORT(unit, port) && mode == SOC_ENCAP_IEEE) {
   2286         /* HG -> XE */
   2287         SOC_IF_ERROR_RETURN(_mac_x_port_mode_update(unit, port, FALSE));
   2288     }
   2289 
   2290     /* Update the encapsulation mode */
   2291     rv = soc_reg_field32_modify(unit, XMAC_MODEr, port, HDR_MODEf, encap);
   2292 #if defined(BCM_KATANA2_SUPPORT)
   2293     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
   2294         if (mode == SOC_ENCAP_HIGIG2_LITE) {
   2295             rv = soc_reg_field32_modify(unit, XMAC_MODEr, port, SPEED_MODEf, 3);
   2296         }
   2297     }
   2298 #endif
   2299 
   2300     /* Update the RUNT */
   2301     if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit) ||
   2302                                    SOC_IS_KATANAX(unit)) {
   2303         runt = ((mode == SOC_ENCAP_HIGIG2) || (mode == SOC_ENCAP_HIGIG2_LITE)) ?
   2304                                                     XMAC_RUNT_THRESHOLD_HG2 : 
   2305                 ((mode == SOC_ENCAP_HIGIG) ? 
   2306                              XMAC_RUNT_THRESHOLD_HG1 : XMAC_RUNT_THRESHOLD_XE);
   2307         SOC_IF_ERROR_RETURN
   2308             (soc_reg_field32_modify(unit, XMAC_RX_CTRLr, port, RUNT_THRESHOLDf,runt));
   2309     }
   2310 
   2311     ipg = (mode == SOC_ENCAP_HIGIG2) ? SOC_PERSIST(unit)->ipg[port].fd_hg2 :
   2312         ((mode == SOC_ENCAP_HIGIG) ? SOC_PERSIST(unit)->ipg[port].fd_hg :
   2313          SOC_PERSIST(unit)->ipg[port].fd_xe);
   2314     SOC_IF_ERROR_RETURN
   2315         (soc_reg_field32_modify(unit, XMAC_TX_CTRLr, port, AVERAGE_IPGf,
   2316                                 IPG_BYTE(ipg)));
   2317 
   2318     if (enable) {
   2319         /* Re-enable transmitter and receiver */
   2320         SOC_IF_ERROR_RETURN(mac_x_enable_set(unit, port, 1));
   2321     }
   2322 
   2323     return rv;
   2324 }
   2325 
   2326 /*
   2327  * Function:
   2328  *      mac_x_encap_get
   2329  * Purpose:
   2330  *      Get the XMAC port encapsulation mode.
   2331  * Parameters:
   2332  *      unit - XGS unit #.
   2333  *      port - XGS port # on unit.
   2334  *      mode - (INT) encap bits (defined above)
   2335  * Returns:
   2336  *      SOC_E_XXX
   2337  */
   2338 STATIC int
   2339 mac_x_encap_get(int unit, soc_port_t port, int *mode)
   2340 {
   2341     uint64 rval;
   2342 
   2343     if (!mode) {
   2344         return SOC_E_PARAM;
   2345     }
   2346 
   2347     SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &rval));
   2348     switch (soc_reg64_field32_get(unit, XMAC_MODEr, rval, HDR_MODEf)) {
   2349     case 0:
   2350         *mode = SOC_ENCAP_IEEE;
   2351         break;
   2352     case 1:
   2353         *mode = SOC_ENCAP_HIGIG;
   2354         break;
   2355     case 2:
   2356         *mode = SOC_ENCAP_HIGIG2;
   2357         break;
   2358     default:
   2359         *mode = SOC_ENCAP_COUNT;
   2360     }
   2361 
   2362 #ifdef BROADCOM_DEBUG
   2363     LOG_VERBOSE(BSL_LS_SOC_10G,
   2364                 (BSL_META_U(unit,
   2365                             "mac_x_encap_get: unit %d port %s encapsulation=%s\n"),
   2366                  unit, SOC_PORT_NAME(unit, port),
   2367                  mac_x_encap_mode[*mode]));
   2368 #endif
   2369     return SOC_E_NONE;
   2370 }
   2371 
   2372 /*
   2373  * Function:
   2374  *      mac_x_expected_rx_latency_get
   2375  * Purpose:
   2376  *      Get the XMAC port expected Rx latency
   2377  * Parameters:
   2378  *      unit - XGS unit #.
   2379  *      port - XGS port # on unit.
   2380  *      latency - (OUT) Latency in NS
   2381  * Returns:
   2382  *      SOC_E_XXX
   2383  */
   2384 STATIC int
   2385 mac_x_expected_rx_latency_get(int unit, soc_port_t port, int *latency)
   2386 {
   2387     int speed = 0;
   2388     SOC_IF_ERROR_RETURN(mac_x_speed_get(unit, port, &speed));
   2389 
   2390     
   2391     switch (speed) {
   2392     case 1000:  /* GigE */
   2393         *latency = 0;
   2394         break;
   2395 
   2396     case 10000:  /* 10G */
   2397         *latency = 0;
   2398         break;
   2399 
   2400     default:
   2401         *latency = 0;
   2402         break;
   2403     }
   2404 
   2405     return SOC_E_NONE;
   2406 }
   2407 
   2408 
   2409 /*
   2410  * Function:
   2411  *      mac_x_control_set
   2412  * Purpose:
   2413  *      To configure MAC control properties.
   2414  * Parameters:
   2415  *      unit - XGS unit #.
   2416  *      port - XGS port # on unit.
   2417  *      type - MAC control property to set.
   2418  *      int  - New setting for MAC control.
   2419  * Returns:
   2420  *      SOC_E_XXX
   2421  */
   2422 STATIC int
   2423 mac_x_control_set(int unit, soc_port_t port, soc_mac_control_t type,
   2424                   int value)
   2425 {
   2426     uint64 rval, copy;
   2427     uint32 fval;
   2428 
   2429     LOG_VERBOSE(BSL_LS_SOC_10G,
   2430                 (BSL_META_U(unit,
   2431                             "mac_x_control_set: unit %d port %s type=%d value=%d\n"),
   2432                  unit, SOC_PORT_NAME(unit, port),
   2433                  type, value));
   2434 
   2435     switch (type) {
   2436     case SOC_MAC_CONTROL_RX_SET:
   2437         SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval));
   2438         copy = rval;
   2439         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval, RX_ENf, value ? 1 : 0);
   2440         if (COMPILER_64_NE(rval, copy)) {
   2441             SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, rval));
   2442         }    
   2443         break;
   2444     case SOC_MAC_CONTROL_FAILOVER_RX_SET:
   2445         
   2446         break;
   2447     case SOC_MAC_CONTROL_TX_SET:
   2448         SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval));
   2449         copy = rval;
   2450         soc_reg64_field32_set(unit, XMAC_CTRLr, &rval, TX_ENf, value ? 1 : 0);
   2451         if (COMPILER_64_NE(rval, copy)) {
   2452             SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, rval));
   2453         }    
   2454         break;
   2455     case SOC_MAC_CONTROL_FRAME_SPACING_STRETCH:
   2456         if (value < 0 || value > 255) {
   2457             return SOC_E_PARAM;
   2458         } else {
   2459             SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &rval));
   2460             if (value >= 8) {
   2461                 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, THROT_DENOMf,
   2462                                       value);
   2463                 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, THROT_NUMf,
   2464                                       1);
   2465             } else {
   2466                 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, THROT_DENOMf,
   2467                                       0);
   2468                 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval, THROT_NUMf,
   2469                                       0);
   2470             }
   2471             SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr(unit, port, rval));
   2472         }
   2473         return SOC_E_NONE;
   2474 
   2475     case SOC_MAC_PASS_CONTROL_FRAME:
   2476         SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rval));
   2477         soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval, RX_PASS_CTRLf,
   2478                               value ? 1 : 0);
   2479         SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr(unit, port, rval));
   2480         break;
   2481 
   2482     case SOC_MAC_CONTROL_PFC_TYPE:
   2483         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_PFC_TYPEr, port,
   2484                                                    PFC_ETH_TYPEf, value));
   2485         break;
   2486 
   2487     case SOC_MAC_CONTROL_PFC_OPCODE:
   2488         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_PFC_OPCODEr,
   2489                                                    port, PFC_OPCODEf, value));
   2490         break;
   2491 
   2492     case SOC_MAC_CONTROL_PFC_CLASSES:
   2493         if (value != 8) {
   2494             return SOC_E_PARAM;
   2495         }
   2496         break;
   2497 
   2498     case SOC_MAC_CONTROL_PFC_MAC_DA_OUI:
   2499         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &rval));
   2500         fval = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, PFC_MACDA_LOf);
   2501         fval &= 0x00ffffff;
   2502         fval |= (value & 0xff) << 24;
   2503         soc_reg64_field32_set(unit, XMAC_PFC_DAr, &rval, PFC_MACDA_LOf, fval);
   2504 
   2505         soc_reg64_field32_set(unit, XMAC_PFC_DAr, &rval, PFC_MACDA_HIf,
   2506                               value >> 8);
   2507         SOC_IF_ERROR_RETURN(WRITE_XMAC_PFC_DAr(unit, port, rval));
   2508         break;
   2509 
   2510     case SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI:
   2511         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &rval));
   2512         fval = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, PFC_MACDA_LOf);
   2513         fval &= 0xff000000;
   2514         fval |= value;
   2515         soc_reg64_field32_set(unit, XMAC_PFC_DAr, &rval, PFC_MACDA_LOf, fval);
   2516         SOC_IF_ERROR_RETURN(WRITE_XMAC_PFC_DAr(unit, port, rval));
   2517         break;
   2518 
   2519     case SOC_MAC_CONTROL_PFC_RX_PASS:
   2520         SOC_IF_ERROR_RETURN
   2521             (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, RX_PASS_PFCf,
   2522                                     value ? 1 : 0));
   2523         break;
   2524 
   2525     case SOC_MAC_CONTROL_PFC_RX_ENABLE:
   2526         SOC_IF_ERROR_RETURN
   2527             (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, RX_PFC_ENf,
   2528                                     value ? 1 : 0));
   2529         break;
   2530 
   2531     case SOC_MAC_CONTROL_PFC_TX_ENABLE:
   2532         SOC_IF_ERROR_RETURN
   2533             (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, TX_PFC_ENf,
   2534                                     value ? 1 : 0));
   2535         break;
   2536 
   2537     case SOC_MAC_CONTROL_PFC_FORCE_XON:
   2538         SOC_IF_ERROR_RETURN
   2539             (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, FORCE_PFC_XONf,
   2540                                     value ? 1 : 0));
   2541         break;
   2542 
   2543     case SOC_MAC_CONTROL_PFC_STATS_ENABLE:
   2544         SOC_IF_ERROR_RETURN
   2545             (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, PFC_STATS_ENf,
   2546                                     value ? 1 : 0));
   2547         break;
   2548 
   2549     case SOC_MAC_CONTROL_PFC_REFRESH_TIME:
   2550         SOC_IF_ERROR_RETURN
   2551             (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, 
   2552                                     PFC_REFRESH_TIMERf, value));
   2553         break;
   2554 
   2555     case SOC_MAC_CONTROL_PFC_XOFF_TIME:
   2556         SOC_IF_ERROR_RETURN
   2557             (soc_reg_field32_modify(unit, XMAC_PFC_CTRLr, port, 
   2558                                     PFC_XOFF_TIMERf, value));
   2559         break;
   2560 
   2561     case SOC_MAC_CONTROL_LLFC_RX_ENABLE:
   2562         SOC_IF_ERROR_RETURN
   2563             (soc_reg_field32_modify(unit, XMAC_LLFC_CTRLr, port, RX_LLFC_ENf,
   2564                                     value ? 1 : 0));
   2565         break;
   2566 
   2567     case SOC_MAC_CONTROL_LLFC_TX_ENABLE:
   2568         SOC_IF_ERROR_RETURN
   2569             (soc_reg_field32_modify(unit, XMAC_LLFC_CTRLr, port, TX_LLFC_ENf,
   2570                                     value ? 1 : 0));
   2571         break;
   2572 
   2573     case SOC_MAC_CONTROL_EEE_ENABLE:
   2574         if (!soc_feature(unit, soc_feature_eee)) {
   2575             return SOC_E_UNAVAIL;
   2576         }
   2577         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_EEE_CTRLr, 
   2578                                                    port, EEE_ENf, value));
   2579         break;
   2580 
   2581     case SOC_MAC_CONTROL_EEE_TX_IDLE_TIME:
   2582         if (!soc_feature(unit, soc_feature_eee)) {
   2583             return SOC_E_UNAVAIL;
   2584         }
   2585         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_EEE_TIMERSr, 
   2586                                     port, EEE_DELAY_ENTRY_TIMERf, value));
   2587         break;
   2588 
   2589     case SOC_MAC_CONTROL_EEE_TX_WAKE_TIME:
   2590         if (!soc_feature(unit, soc_feature_eee)) {
   2591             return SOC_E_UNAVAIL;
   2592         }
   2593         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XMAC_EEE_TIMERSr, 
   2594                                     port, EEE_WAKE_TIMERf, value));
   2595         break;
   2596 
   2597     case SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE:
   2598         SOC_IF_ERROR_RETURN
   2599             (soc_reg_field32_modify(unit, XMAC_RX_LSS_CTRLr, port,
   2600                                     LOCAL_FAULT_DISABLEf, value ? 0 : 1));
   2601         break;
   2602 
   2603     case SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE:
   2604         SOC_IF_ERROR_RETURN
   2605             (soc_reg_field32_modify(unit, XMAC_RX_LSS_CTRLr, port,
   2606                                     REMOTE_FAULT_DISABLEf, value ? 0 : 1));
   2607         break;
   2608     case SOC_MAC_CONTROL_EGRESS_DRAIN:
   2609         SOC_IF_ERROR_RETURN(mac_x_egress_queue_drain(unit, port));
   2610         break;
   2611 
   2612     case SOC_MAC_CONTROL_RX_VLAN_TAG_OUTER_TPID:
   2613         SOC_IF_ERROR_RETURN
   2614             (soc_reg_field32_modify(unit, XMAC_RX_VLAN_TAGr, port, 
   2615                                     OUTER_VLAN_TAGf, value));
   2616         SOC_IF_ERROR_RETURN
   2617             (soc_reg_field32_modify(unit, XMAC_RX_VLAN_TAGr, port, 
   2618                                     OUTER_VLAN_TAG_ENABLEf, value ? 1 : 0));
   2619         break;
   2620     case SOC_MAC_CONTROL_RX_VLAN_TAG_INNER_TPID:
   2621         SOC_IF_ERROR_RETURN
   2622             (soc_reg_field32_modify(unit, XMAC_RX_VLAN_TAGr, port, 
   2623                                     INNER_VLAN_TAGf, value));
   2624         SOC_IF_ERROR_RETURN
   2625             (soc_reg_field32_modify(unit, XMAC_RX_VLAN_TAGr, port, 
   2626                                     INNER_VLAN_TAG_ENABLEf, value ? 1 : 0));
   2627         break;
   2628 
   2629     default:
   2630         return SOC_E_UNAVAIL;
   2631     }
   2632 
   2633     return SOC_E_NONE;
   2634 }
   2635 
   2636 /*
   2637  * Function:
   2638  *      mac_x_control_get
   2639  * Purpose:
   2640  *      To get current MAC control setting.
   2641  * Parameters:
   2642  *      unit - XGS unit #.
   2643  *      port - XGS port # on unit.
   2644  *      type - MAC control property to set.
   2645  *      int  - New setting for MAC control.
   2646  * Returns:
   2647  *      SOC_E_XXX
   2648  */
   2649 STATIC int
   2650 mac_x_control_get(int unit, soc_port_t port, soc_mac_control_t type,
   2651                   int *value)
   2652 {
   2653     int rv;
   2654     uint64 rval;
   2655     uint32 fval0, fval1;
   2656 
   2657     if (value == NULL) {
   2658         return SOC_E_PARAM;
   2659     }
   2660 
   2661     rv = SOC_E_NONE;
   2662     switch (type) {
   2663     case SOC_MAC_CONTROL_RX_SET:
   2664         SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval));
   2665         *value = soc_reg64_field32_get(unit, XMAC_CTRLr, rval, RX_ENf);
   2666         break;
   2667     case SOC_MAC_CONTROL_TX_SET:
   2668         SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval));
   2669         *value = soc_reg64_field32_get(unit, XMAC_CTRLr, rval, TX_ENf);
   2670         break;
   2671     case SOC_MAC_CONTROL_SW_RESET:
   2672         SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &rval));
   2673         *value = soc_reg64_field32_get(unit, XMAC_CTRLr, rval, SOFT_RESETf);
   2674         break;
   2675     case SOC_MAC_CONTROL_FRAME_SPACING_STRETCH:
   2676         SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr(unit, port, &rval));
   2677         *value = soc_reg64_field32_get(unit, XMAC_TX_CTRLr, rval,
   2678                                        THROT_DENOMf);
   2679         rv = SOC_E_NONE;
   2680         break;
   2681 
   2682     case SOC_MAC_CONTROL_TIMESTAMP_TRANSMIT:
   2683         {
   2684             uint32  timestamp = 0;
   2685             if (soc_feature(unit, soc_feature_timestamp_counter) &&
   2686                 soc_property_get(unit, spn_SW_TIMESTAMP_FIFO_ENABLE, 1)) {
   2687                 if (soc_counter_timestamp_get(unit, port, &timestamp) !=
   2688                     SOC_E_NOT_FOUND) {
   2689                     *value = (int)timestamp;
   2690                     break;
   2691                 }
   2692             }
   2693 
   2694             SOC_IF_ERROR_RETURN
   2695                 (READ_XMAC_TX_TIMESTAMP_FIFO_STATUSr(unit, port, &rval));
   2696             if (soc_reg64_field32_get(unit, XMAC_TX_TIMESTAMP_FIFO_STATUSr, rval,
   2697                                       ENTRY_COUNTf) == 0) {
   2698                 return SOC_E_EMPTY;
   2699             }
   2700             SOC_IF_ERROR_RETURN
   2701                 (READ_XMAC_TX_TIMESTAMP_FIFO_DATAr(unit, port, &rval));
   2702             *value = soc_reg64_field32_get(unit, XMAC_TX_TIMESTAMP_FIFO_DATAr,
   2703                                        rval, TIME_STAMPf);
   2704         }
   2705         break;
   2706 
   2707     case SOC_MAC_PASS_CONTROL_FRAME:
   2708         SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr(unit, port, &rval));
   2709         *value = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval,
   2710                                        RX_PASS_CTRLf);
   2711         break;
   2712 
   2713     case SOC_MAC_CONTROL_PFC_TYPE:
   2714         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_TYPEr(unit, port, &rval));
   2715         *value = soc_reg64_field32_get(unit, XMAC_PFC_TYPEr, rval,
   2716                                        PFC_ETH_TYPEf);
   2717         break;
   2718 
   2719     case SOC_MAC_CONTROL_PFC_OPCODE:
   2720         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_OPCODEr(unit, port, &rval));
   2721         *value = soc_reg64_field32_get(unit, XMAC_PFC_OPCODEr, rval,
   2722                                        PFC_OPCODEf);
   2723         break;
   2724 
   2725     case SOC_MAC_CONTROL_PFC_CLASSES:
   2726         *value = 8;
   2727         break;
   2728 
   2729     case SOC_MAC_CONTROL_PFC_MAC_DA_OUI:
   2730         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &rval));
   2731         fval0 = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, PFC_MACDA_LOf);
   2732         fval1 = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval, PFC_MACDA_HIf);
   2733         *value = (fval0 >> 24) | (fval1 << 8);
   2734         break;
   2735 
   2736     case SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI:
   2737         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_DAr(unit, port, &rval));
   2738         *value = soc_reg64_field32_get(unit, XMAC_PFC_DAr, rval,
   2739                                        PFC_MACDA_LOf) & 0x00ffffff;
   2740         break;
   2741 
   2742     case SOC_MAC_CONTROL_PFC_RX_PASS:
   2743         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval));
   2744         *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval,
   2745                                        RX_PASS_PFCf);
   2746         break;
   2747 
   2748     case SOC_MAC_CONTROL_PFC_RX_ENABLE:
   2749         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval));
   2750         *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval,
   2751                                        RX_PFC_ENf);
   2752         break;
   2753 
   2754     case SOC_MAC_CONTROL_PFC_TX_ENABLE:
   2755         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval));
   2756         *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval,
   2757                                        TX_PFC_ENf);
   2758         break;
   2759 
   2760     case SOC_MAC_CONTROL_PFC_FORCE_XON:
   2761         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval));
   2762         *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval,
   2763                                        FORCE_PFC_XONf);
   2764         break;
   2765 
   2766     case SOC_MAC_CONTROL_PFC_STATS_ENABLE:
   2767         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval));
   2768         *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval,
   2769                                        PFC_STATS_ENf);
   2770         break;
   2771 
   2772     case SOC_MAC_CONTROL_PFC_REFRESH_TIME:
   2773         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval));
   2774         *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval,
   2775                                        PFC_REFRESH_TIMERf);
   2776         break;
   2777 
   2778     case SOC_MAC_CONTROL_PFC_XOFF_TIME:
   2779         SOC_IF_ERROR_RETURN(READ_XMAC_PFC_CTRLr(unit, port, &rval));
   2780         *value = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval,
   2781                                        PFC_XOFF_TIMERf);
   2782         break;
   2783 
   2784     case SOC_MAC_CONTROL_LLFC_RX_ENABLE:
   2785         SOC_IF_ERROR_RETURN(READ_XMAC_LLFC_CTRLr(unit, port, &rval));
   2786         *value = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval,
   2787                                        RX_LLFC_ENf);
   2788         break;
   2789 
   2790     case SOC_MAC_CONTROL_LLFC_TX_ENABLE:
   2791         SOC_IF_ERROR_RETURN(READ_XMAC_LLFC_CTRLr(unit, port, &rval));
   2792         *value = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval,
   2793                                        TX_LLFC_ENf);
   2794         break;
   2795 
   2796     case SOC_MAC_CONTROL_EEE_ENABLE:
   2797         if (!soc_feature(unit, soc_feature_eee)) {
   2798             return SOC_E_UNAVAIL;
   2799         }
   2800         if (!soc_reg_field_valid(unit, XMAC_EEE_CTRLr, EEE_ENf)) {
   2801             return SOC_E_UNAVAIL;
   2802         }
   2803         SOC_IF_ERROR_RETURN(READ_XMAC_EEE_CTRLr(unit, port, &rval));
   2804         *value = soc_reg64_field32_get(unit, XMAC_EEE_CTRLr, rval, EEE_ENf);
   2805         break;
   2806 
   2807     case SOC_MAC_CONTROL_EEE_TX_IDLE_TIME:
   2808         if (!soc_feature(unit, soc_feature_eee)) {
   2809             return SOC_E_UNAVAIL;
   2810         }
   2811         if (!soc_reg_field_valid(unit, XMAC_EEE_TIMERSr, EEE_DELAY_ENTRY_TIMERf)) {
   2812             return SOC_E_UNAVAIL;
   2813         }
   2814         SOC_IF_ERROR_RETURN(READ_XMAC_EEE_TIMERSr(unit, port, &rval));
   2815         *value = soc_reg64_field32_get(unit, XMAC_EEE_TIMERSr, rval,
   2816                 EEE_DELAY_ENTRY_TIMERf);
   2817         break;
   2818 
   2819     case SOC_MAC_CONTROL_EEE_TX_WAKE_TIME:
   2820         if (!soc_feature(unit, soc_feature_eee)) {
   2821             return SOC_E_UNAVAIL;
   2822         }
   2823         if (!soc_reg_field_valid(unit, XMAC_EEE_TIMERSr, EEE_WAKE_TIMERf)) {
   2824             return SOC_E_UNAVAIL;
   2825         }
   2826         SOC_IF_ERROR_RETURN(READ_XMAC_EEE_TIMERSr(unit, port, &rval));
   2827         *value = soc_reg64_field32_get(unit, XMAC_EEE_TIMERSr, rval,
   2828                 EEE_WAKE_TIMERf);
   2829         break;
   2830 
   2831     case SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE:
   2832         SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_CTRLr(unit, port, &rval));
   2833         *value = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval,
   2834                                        LOCAL_FAULT_DISABLEf) ? 0 : 1;
   2835         break;
   2836 
   2837     case SOC_MAC_CONTROL_FAULT_LOCAL_STATUS:
   2838         SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_STATUSr(unit, port, &rval));
   2839         *value = soc_reg64_field32_get(unit, XMAC_RX_LSS_STATUSr, rval,
   2840                                        LOCAL_FAULT_STATUSf);
   2841         break;
   2842 
   2843     case SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE:
   2844         SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_CTRLr(unit, port, &rval));
   2845         *value = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval,
   2846                                        REMOTE_FAULT_DISABLEf) ? 0 : 1;
   2847         break;
   2848 
   2849     case SOC_MAC_CONTROL_FAULT_REMOTE_STATUS:
   2850         SOC_IF_ERROR_RETURN(READ_XMAC_RX_LSS_STATUSr(unit, port, &rval));
   2851         *value = soc_reg64_field32_get(unit, XMAC_RX_LSS_STATUSr, rval,
   2852                                        REMOTE_FAULT_STATUSf);
   2853         break;
   2854     case SOC_MAC_CONTROL_RX_VLAN_TAG_OUTER_TPID:
   2855         SOC_IF_ERROR_RETURN(READ_XMAC_RX_VLAN_TAGr(unit, port, &rval));
   2856         *value = soc_reg64_field32_get(unit, XMAC_RX_VLAN_TAGr, 
   2857                                        rval, OUTER_VLAN_TAGf);
   2858         break;
   2859     case SOC_MAC_CONTROL_RX_VLAN_TAG_INNER_TPID:
   2860         SOC_IF_ERROR_RETURN(READ_XMAC_RX_VLAN_TAGr(unit, port, &rval));
   2861         *value = soc_reg64_field32_get(unit, XMAC_RX_VLAN_TAGr, 
   2862                                        rval, INNER_VLAN_TAGf);
   2863         break;
   2864     case SOC_MAC_CONTROL_EXPECTED_RX_LATENCY:
   2865         SOC_IF_ERROR_RETURN(mac_x_expected_rx_latency_get(unit, port, value));
   2866         break;
   2867     default:
   2868         return SOC_E_UNAVAIL;
   2869     }
   2870 
   2871     LOG_VERBOSE(BSL_LS_SOC_10G,
   2872                 (BSL_META_U(unit,
   2873                             "mac_x_control_get: unit %d port %s type=%d value=%d "
   2874                              "rv=%d\n"),
   2875                  unit, SOC_PORT_NAME(unit, port),
   2876                  type, *value, rv));
   2877     return rv;
   2878 }
   2879 
   2880 /*
   2881  * Function:
   2882  *      mac_x_ability_local_get
   2883  * Purpose:
   2884  *      Return the abilities of XMAC
   2885  * Parameters:
   2886  *      unit - XGS unit #.
   2887  *      port - XGS port # on unit.
   2888  *      mode - (OUT) Supported operating modes as a mask of abilities.
   2889  * Returns:
   2890  *      SOC_E_XXX
   2891  */
   2892 STATIC int
   2893 mac_x_ability_local_get(int unit, soc_port_t port,
   2894                           soc_port_ability_t *ability)
   2895 {
   2896 #ifdef BCM_KATANA2_SUPPORT
   2897     uint8  mxqblock = 0;
   2898     if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) {
   2899         SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock(
   2900                             unit,port,&mxqblock));
   2901     }
   2902 #endif
   2903     if (NULL == ability) {
   2904         return SOC_E_PARAM;
   2905     }
   2906 
   2907     ability->speed_half_duplex  = SOC_PA_ABILITY_NONE;
   2908     ability->pause     = SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM;
   2909     ability->interface = SOC_PA_INTF_MII | SOC_PA_INTF_XGMII;
   2910     ability->medium    = SOC_PA_ABILITY_NONE;
   2911     ability->loopback  = SOC_PA_LB_MAC;
   2912     ability->flags     = SOC_PA_ABILITY_NONE;
   2913     ability->encap = SOC_PA_ENCAP_IEEE | SOC_PA_ENCAP_HIGIG |
   2914                          SOC_PA_ENCAP_HIGIG2;
   2915 #ifdef BCM_KATANA2_SUPPORT
   2916     if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && ((mxqblock == 6) || (mxqblock == 7))) {
   2917         ability->encap |= SOC_PA_ENCAP_HIGIG2_LITE; 
   2918     } 
   2919 #endif
   2920 
   2921     if (IS_HL_PORT(unit , port)) {
   2922         if (SOC_INFO(unit).port_speed_max[port]) {
   2923             ability->speed_full_duplex |= SOC_PA_SPEED_2500MB;
   2924         }
   2925     } 
   2926     if (IS_HG_PORT(unit , port)) {
   2927         switch (SOC_INFO(unit).port_speed_max[port]) {
   2928         case 42000:
   2929             ability->speed_full_duplex |= SOC_PA_SPEED_42GB;
   2930             /* fall through */
   2931         case 40000:
   2932             ability->speed_full_duplex |= SOC_PA_SPEED_40GB;
   2933             if(soc_feature(unit, soc_feature_higig_misc_speed_support)) {
   2934                 ability->speed_full_duplex |= SOC_PA_SPEED_42GB;                 
   2935             }
   2936             /* fall through */
   2937         case 30000:
   2938             ability->speed_full_duplex |= SOC_PA_SPEED_30GB;
   2939             /* fall through */
   2940         case 25000:
   2941             ability->speed_full_duplex |= SOC_PA_SPEED_25GB;
   2942             /* fall through */
   2943         case 23000:
   2944             ability->speed_full_duplex |= SOC_PA_SPEED_23GB;
   2945             /* fall through */
   2946         case 21000:
   2947             ability->speed_full_duplex |= SOC_PA_SPEED_21GB;
   2948             /* fall through */
   2949         case 20000:
   2950             ability->speed_full_duplex |= SOC_PA_SPEED_20GB;
   2951             if(soc_feature(unit, soc_feature_higig_misc_speed_support)) {
   2952                 ability->speed_full_duplex |= SOC_PA_SPEED_21GB;                 
   2953             }
   2954             /* fall through */
   2955         case 16000:
   2956             ability->speed_full_duplex |= SOC_PA_SPEED_16GB;
   2957             /* fall through */
   2958         case 15000:
   2959             ability->speed_full_duplex |= SOC_PA_SPEED_15GB;
   2960             /* fall through */
   2961         case 13000:
   2962             ability->speed_full_duplex |= SOC_PA_SPEED_13GB;
   2963             /* fall through */
   2964         case 12000:
   2965             ability->speed_full_duplex |= SOC_PA_SPEED_12GB;
   2966             /* fall through */
   2967         case 11000:
   2968             ability->speed_full_duplex |= SOC_PA_SPEED_11GB;
   2969             /* fall through */
   2970         case 10000:
   2971             ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   2972             if (soc_feature(unit, soc_feature_higig_misc_speed_support)) {
   2973                 ability->speed_full_duplex |= SOC_PA_SPEED_11GB;
   2974             }
   2975             break;
   2976         default:
   2977             break;
   2978         }
   2979     } else {
   2980         if (SOC_INFO(unit).port_speed_max[port] >= 40000) {
   2981             ability->speed_full_duplex |= SOC_PA_SPEED_40GB |
   2982                 SOC_PA_SPEED_42GB;
   2983         }
   2984         
   2985          if (SOC_INFO(unit).port_speed_max[port] >= 20000) {
   2986             ability->speed_full_duplex |= SOC_PA_SPEED_20GB;
   2987         }
   2988         if (SOC_INFO(unit).port_speed_max[port] >= 10000) {
   2989             ability->speed_full_duplex |= SOC_PA_SPEED_10GB;
   2990         }
   2991         if (soc_feature(unit, soc_feature_unified_port) || IS_MXQ_PORT(unit, port)) {
   2992             if (SOC_INFO(unit).port_speed_max[port] >= 2500) {
   2993                 ability->speed_full_duplex |= SOC_PA_SPEED_2500MB;
   2994             }
   2995             if (SOC_INFO(unit).port_speed_max[port] >= 1000) {
   2996                 ability->speed_full_duplex |= SOC_PA_SPEED_1000MB;
   2997             }
   2998             if (SOC_INFO(unit).port_speed_max[port] >= 100) {
   2999                 ability->speed_full_duplex |= SOC_PA_SPEED_100MB;
   3000             }
   3001             if (SOC_INFO(unit).port_speed_max[port] >= 10) {
   3002                 ability->speed_full_duplex |= SOC_PA_SPEED_10MB;
   3003             }
   3004         }
   3005     }
   3006 
   3007     LOG_VERBOSE(BSL_LS_SOC_10G,
   3008                 (BSL_META_U(unit,
   3009                             "mac_x_ability_local_get: unit %d port %s "
   3010                              "speed_half=0x%x speed_full=0x%x encap=0x%x pause=0x%x "
   3011                              "interface=0x%x medium=0x%x loopback=0x%x flags=0x%x\n"),
   3012                  unit, SOC_PORT_NAME(unit, port),
   3013                  ability->speed_half_duplex, ability->speed_full_duplex,
   3014                  ability->encap, ability->pause, ability->interface,
   3015                  ability->medium, ability->loopback, ability->flags));
   3016     return SOC_E_NONE;
   3017 }
   3018 
   3019 /* Exported XMAC driver structure */
   3020 mac_driver_t soc_mac_x = {
   3021     "XMAC Driver",                /* drv_name */
   3022     mac_x_init,                   /* md_init  */
   3023     mac_x_enable_set,             /* md_enable_set */
   3024     mac_x_enable_get,             /* md_enable_get */
   3025     mac_x_duplex_set,             /* md_duplex_set */
   3026     mac_x_duplex_get,             /* md_duplex_get */
   3027     mac_x_speed_set,              /* md_speed_set */
   3028     mac_x_speed_get,              /* md_speed_get */
   3029     mac_x_pause_set,              /* md_pause_set */
   3030     mac_x_pause_get,              /* md_pause_get */
   3031     mac_x_pause_addr_set,         /* md_pause_addr_set */
   3032     mac_x_pause_addr_get,         /* md_pause_addr_get */
   3033     mac_x_loopback_set,           /* md_lb_set */
   3034     mac_x_loopback_get,           /* md_lb_get */
   3035     mac_x_interface_set,          /* md_interface_set */
   3036     mac_x_interface_get,          /* md_interface_get */
   3037     NULL,                         /* md_ability_get - Deprecated */
   3038     mac_x_frame_max_set,          /* md_frame_max_set */
   3039     mac_x_frame_max_get,          /* md_frame_max_get */
   3040     mac_x_ifg_set,                /* md_ifg_set */
   3041     mac_x_ifg_get,                /* md_ifg_get */
   3042     mac_x_encap_set,              /* md_encap_set */
   3043     mac_x_encap_get,              /* md_encap_get */
   3044     mac_x_control_set,            /* md_control_set */
   3045     mac_x_control_get,            /* md_control_get */
   3046     mac_x_ability_local_get,      /* md_ability_local_get */
   3047     NULL                          /* md_timesync_tx_info_get */
   3048  };
   3049 
   3050 #endif /* BCM_XMAC_SUPPORT */