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

phyreg.c (37969B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        phy5482.c
      8  * Purpose:     PHY driver for BCM5482 and BCM5482S
      9  */
     10 
     11 #include <sal/types.h>
     12 #include <shared/bsl.h>
     13 #include <soc/drv.h>
     14 #include <soc/debug.h>
     15 #include <soc/error.h>
     16 #include <soc/phyreg.h>
     17 
     18 #include <soc/ll.h>
     19 #include <soc/phy/phyctrl.h>
     20 
     21 #include "phydefs.h"      /* Must include before other phy related includes */
     22 
     23 #include "phyreg.h"
     24 
     25 #define _SOC_PHY_REG_DIRECT \
     26         ((SOC_PHY_REG_1000X << 1) | (SOC_PHY_REG_1000X >> 1))
     27 
     28 
     29 #define PHY_MODEL_CHECK(_pc, _oui, _model) \
     30                                 (((_pc)->phy_oui == (_oui)) && \
     31                                  ((_pc)->phy_model == (_model)))
     32 
     33 
     34 /* SHAD_EXPD for 54640E (macros) */
     35 #define PHY_IS_BCM54640E(_pc)   (PHY_MODEL_CHECK((_pc), \
     36                                  0x001be9, \
     37                                  0x27) \
     38                                  && (((_pc)->phy_rev & 0x8) == 0))
     39 
     40 uint16 phy54640e_save = 0;
     41 #define BCM54640E_SHAD_EXPD_PRE(_unit, _pc, _reg_bank)\
     42     if (PHY_IS_BCM54640E((_pc))            &&                       \
     43         ((_pc)->flags & PHYCTRL_IS_PORT0)  &&                       \
     44         (_reg_bank) != 0x0d01              &&                       \
     45         ((_reg_bank) & 0xff00) == 0x0d00 ) {                        \
     46             SOC_IF_ERROR_RETURN                                     \
     47                 (WRITE_PHY_REG((_unit), (_pc), 0x17, 0x0d01));      \
     48             SOC_IF_ERROR_RETURN                                     \
     49                 (READ_PHY_REG((_unit), (_pc), 0x15, &phy54640e_save));  \
     50     } else {                                                        \
     51             phy54640e_save = 0;                                     \
     52     }
     53 
     54 #define BCM54640E_SHAD_EXPD_POST(_unit, _pc, _rv)\
     55     if ((SOC_SUCCESS(_rv)) && phy54640e_save != 0) {                 \
     56         _rv = WRITE_PHY_REG((_unit), (_pc), 0x17, 0x0d01);           \
     57         if ((SOC_SUCCESS(_rv)) ) {                                   \
     58             _rv = WRITE_PHY_REG((_unit), (_pc), 0x15, phy54640e_save);   \
     59         }                                                            \
     60         phy54640e_save = 0;                                          \
     61     }
     62 
     63 
     64 int 
     65 phy_reg_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr,
     66                uint16 reg_data, uint16 reg_mask)
     67 {
     68     uint16  tmp, otmp;
     69 
     70     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
     71         return SOC_E_NONE;
     72     }
     73 
     74     reg_data = reg_data & reg_mask;
     75 
     76     SOC_IF_ERROR_RETURN
     77         (READ_PHY_REG(unit, pc, reg_addr, &tmp));
     78     otmp = tmp;
     79     tmp &= ~(reg_mask);
     80     tmp |= reg_data;
     81 
     82     if (otmp != tmp) {
     83         SOC_IF_ERROR_RETURN
     84             (WRITE_PHY_REG(unit, pc, reg_addr, tmp));
     85     }
     86     return SOC_E_NONE;
     87 }
     88 int 
     89 phy_reg_fe_read(int unit, phy_ctrl_t *pc, uint16 reg_bank,
     90                 uint8 reg_addr, uint16 *data)
     91 {
     92     uint16 test_reg;
     93   
     94     if (reg_bank) {
     95         SOC_IF_ERROR_RETURN
     96             (READ_PHY_REG(unit, pc, 0x1f, &test_reg));
     97         SOC_IF_ERROR_RETURN
     98             (WRITE_PHY_REG(unit, pc, 0x1f, test_reg | 0x0080));
     99     
    100         SOC_IF_ERROR_RETURN
    101             (READ_PHY_REG(unit, pc, reg_addr, data));
    102         SOC_IF_ERROR_RETURN
    103             (WRITE_PHY_REG(unit, pc, 0x1f, test_reg));
    104     } else {
    105         SOC_IF_ERROR_RETURN
    106             (READ_PHY_REG(unit, pc, reg_addr, data));
    107     }
    108     return SOC_E_NONE;
    109 }
    110 
    111 int 
    112 phy_reg_fe_write(int unit, phy_ctrl_t *pc, uint16 reg_bank, 
    113                  uint8 reg_addr, uint16 data)
    114 {
    115     uint16 test_reg;
    116  
    117     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    118         return SOC_E_NONE;
    119     }
    120  
    121     if (reg_bank) {
    122         SOC_IF_ERROR_RETURN
    123             (READ_PHY_REG(unit, pc, 0x1f, &test_reg));
    124         SOC_IF_ERROR_RETURN
    125             (WRITE_PHY_REG(unit, pc, 0x1f, test_reg | 0x0080));
    126     
    127         SOC_IF_ERROR_RETURN
    128             (WRITE_PHY_REG(unit, pc, reg_addr, data));
    129         SOC_IF_ERROR_RETURN
    130             (WRITE_PHY_REG(unit, pc, 0x1f, test_reg));
    131     } else {
    132         SOC_IF_ERROR_RETURN
    133             (WRITE_PHY_REG(unit, pc, reg_addr, data));
    134     }
    135     return SOC_E_NONE;
    136 }
    137 
    138 int 
    139 phy_reg_fe_modify(int unit, phy_ctrl_t *pc, uint16 reg_bank, 
    140                   uint8 reg_addr, uint16 data, uint16 mask)
    141 {
    142     uint16 test_reg;
    143 
    144     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    145         return SOC_E_NONE;
    146     }
    147   
    148     if (reg_bank) {
    149         SOC_IF_ERROR_RETURN
    150             (READ_PHY_REG(unit, pc, 0x1f, &test_reg));
    151         SOC_IF_ERROR_RETURN
    152             (WRITE_PHY_REG(unit, pc, 0x1f, test_reg | 0x0080));
    153     
    154         SOC_IF_ERROR_RETURN
    155             (MODIFY_PHY_REG(unit, pc, reg_addr, data, mask));
    156         SOC_IF_ERROR_RETURN
    157             (WRITE_PHY_REG(unit, pc, 0x1f, test_reg));
    158     } else {
    159         SOC_IF_ERROR_RETURN
    160             (MODIFY_PHY_REG(unit, pc, reg_addr, data, mask));
    161     }
    162  
    163     return SOC_E_NONE;
    164 }
    165 
    166 int
    167 phy_reg_ge_read(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    168                 uint8 reg_addr, uint16 *data)
    169 {
    170     int     rv;
    171 
    172     rv       = SOC_E_NONE;
    173 
    174     if (flags & SOC_PHY_REG_1000X) {
    175         if (reg_addr <= 0x000f) {
    176             uint16 blk_sel;
    177 
    178             /* Map 1000X page */
    179             SOC_IF_ERROR_RETURN
    180                 (WRITE_PHY_REG(unit, pc, 0x1c, 0x7c00));
    181             SOC_IF_ERROR_RETURN
    182                 (READ_PHY_REG(unit, pc, 0x1c, &blk_sel));
    183             SOC_IF_ERROR_RETURN
    184                 (WRITE_PHY_REG(unit, pc, 0x1c, blk_sel | 0x8001));
    185 
    186             /* Read 1000X IEEE register */
    187             SOC_IF_ERROR_RETURN
    188                 (READ_PHY_REG(unit, pc, reg_addr, data));
    189 
    190            /* Restore IEEE mapping */
    191             SOC_IF_ERROR_RETURN
    192                 (WRITE_PHY_REG(unit, pc, 0x1c, 
    193                                 (blk_sel & 0xfffe) | 0x8000));
    194         } else {
    195             rv = SOC_E_PARAM;
    196         }
    197     } else {
    198         switch(reg_addr) {
    199         /* Map shadow registers */
    200         case 0x15:
    201             SOC_IF_ERROR_RETURN
    202                 (WRITE_PHY_REG(unit, pc, 0x17, reg_bank));
    203             break;
    204         case 0x18:
    205             if (reg_bank <= 0x0007) {
    206                 SOC_IF_ERROR_RETURN
    207                     (WRITE_PHY_REG(unit, pc, reg_addr, 
    208                                     (reg_bank << 12) | 0x7));
    209             } else {
    210                 rv = SOC_E_PARAM;
    211             }
    212             break;
    213         case 0x1C:
    214             if (reg_bank <= 0x001F) {
    215                 SOC_IF_ERROR_RETURN
    216                     (WRITE_PHY_REG(unit, pc, reg_addr, 
    217                                    (reg_bank << 10)));
    218             } else {
    219                 rv = SOC_E_PARAM;
    220             }
    221             break;
    222         case 0x1D:
    223             if (reg_bank <= 0x0001) {
    224                 SOC_IF_ERROR_RETURN
    225                     (WRITE_PHY_REG(unit, pc, reg_addr, reg_bank << 15));
    226             } else {
    227                 rv = SOC_E_PARAM;
    228             }
    229             break;
    230         default:
    231             if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) {
    232                 /* Must not read from reserved registers */ 
    233                 if (reg_addr > 0x001e) {
    234                    rv = SOC_E_PARAM;
    235                 }
    236             }
    237             break;
    238         }
    239         if (SOC_SUCCESS(rv)) {
    240             rv = READ_PHY_REG(unit, pc, reg_addr, data);
    241         }
    242     } 
    243     if (SOC_FAILURE(rv)) {
    244         LOG_ERROR(BSL_LS_SOC_PHY,
    245                   (BSL_META_U(unit,
    246                               "phy_reg_ge_read failed:"
    247                               " u=%d phy_id=0x%2x reg_bank=0x%04x reg_addr=0x%02x "
    248                               " rv=%d\n"), unit, pc->phy_id, reg_bank, reg_addr, rv)); 
    249     }
    250     return rv;
    251 }
    252 
    253 
    254 STATIC int
    255 check_if_necessary_then_fix(int unit, 
    256 			    phy_ctrl_t *pc, 
    257 			    uint32 flags,
    258 			    uint8 reg_addr, 
    259 			    uint16 reg_bank, 
    260 			    uint16 data, 
    261 			    int chk)
    262 {
    263     uint16 chk_data = 0;
    264     int rv = 0;
    265 
    266 
    267     if (reg_bank == 0xd01) return 0;
    268 
    269     rv = phy_reg_ge_read(unit, pc, flags,reg_bank, reg_addr, &chk_data);
    270 
    271     if (chk_data != data ) {
    272         /*
    273         bsl_printf("%s: data= 0x%08x,  chk_data %x, reg_addr=%x, bank=%x, counter %d\n",
    274         __FUNCTION__, data, chk_data, reg_addr, reg_bank, chk);
    275         */
    276 
    277         if(!chk) return 1;
    278 
    279         flags |= SOC_PHY_REG_NO_RETRY_ACCESS;
    280         rv = phy_reg_ge_write(unit, pc, flags, reg_bank, reg_addr, data);
    281 
    282         if (!rv ) {
    283             return check_if_necessary_then_fix(
    284                        unit, pc, flags, reg_addr, reg_bank, data, --chk);
    285         } else {
    286             return rv;
    287         }
    288 
    289     } else {
    290         return rv;
    291     }
    292 
    293     return 0;
    294 }
    295 
    296 int
    297 phy_reg_ge_write(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    298                 uint8 reg_addr, uint16 data)
    299 {
    300     int     rv;
    301 
    302     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    303         return SOC_E_NONE;
    304     }
    305 
    306     rv       = SOC_E_NONE;
    307 
    308     if (flags & SOC_PHY_REG_1000X) {
    309         if (reg_addr <= 0x000f) {
    310             uint16 blk_sel;
    311 
    312             /* Map 1000X page */
    313             SOC_IF_ERROR_RETURN
    314                 (WRITE_PHY_REG(unit, pc, 0x1c, 0x7c00));
    315             SOC_IF_ERROR_RETURN
    316                 (READ_PHY_REG(unit, pc, 0x1c, &blk_sel));
    317             SOC_IF_ERROR_RETURN
    318                 (WRITE_PHY_REG(unit, pc, 0x1c, blk_sel | 0x8001));
    319 
    320             /* Write 1000X IEEE register */
    321             SOC_IF_ERROR_RETURN
    322                 (WRITE_PHY_REG(unit, pc, reg_addr, data));
    323 
    324            /* Restore IEEE mapping */
    325             SOC_IF_ERROR_RETURN
    326                 (WRITE_PHY_REG(unit, pc, 0x1c, 
    327                                 (blk_sel & 0xfffe) | 0x8000));
    328         } else if (flags & _SOC_PHY_REG_DIRECT) {
    329             SOC_IF_ERROR_RETURN
    330                 (WRITE_PHY_REG(unit, pc, reg_addr, data));
    331         }  else {
    332             rv = SOC_E_PARAM;
    333         }
    334     } else {
    335         switch(reg_addr) {
    336         /* Map shadow registers */
    337         case 0x15:
    338             /* SHAD_EXPD for 54640E */
    339             BCM54640E_SHAD_EXPD_PRE(unit, pc, reg_bank);
    340 
    341             SOC_IF_ERROR_RETURN
    342                     (WRITE_PHY_REG(unit, pc, 0x17, reg_bank));
    343             break;
    344         case 0x18:
    345             if (reg_bank <= 0x0007) {
    346                 if (reg_bank == 0x0007) {
    347                     data |= 0x8000;
    348                 }
    349                 data = (data & ~(0x0007)) | reg_bank;
    350             } else {
    351                 rv = SOC_E_PARAM;
    352             }
    353             break;
    354         case 0x1C:
    355             if (reg_bank <= 0x001F) {
    356                 data = 0x8000 | (reg_bank << 10) | (data & 0x03FF);
    357             } else {
    358                 rv = SOC_E_PARAM;
    359             }
    360             break;
    361         case 0x1D:
    362             if (reg_bank == 0x0000) {
    363                 data = data & 0x07FFF;
    364             } else {
    365                 rv = SOC_E_PARAM;
    366             }
    367             break;
    368         default:
    369             if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) {
    370                 /* Must not write to reserved registers */ 
    371                 if (reg_addr > 0x001e) {
    372                     rv = SOC_E_PARAM;
    373                 }
    374             }
    375             break;
    376         }
    377         if (SOC_SUCCESS(rv)) {
    378             rv = WRITE_PHY_REG(unit, pc, reg_addr, data);
    379 
    380             /* SHAD_EXPD for 54640E */
    381             BCM54640E_SHAD_EXPD_POST(unit, pc, rv);
    382 
    383             if  (!(flags & SOC_PHY_REG_NO_RETRY_ACCESS )) {
    384                 if (SOC_SUCCESS(rv)  && PHY_IS_BCM54640E(pc)  && (reg_addr==0x15 && ((reg_bank&0x0f00) == 0x0d00))) {
    385                     rv = check_if_necessary_then_fix(
    386                             unit, pc, flags, reg_addr, reg_bank, data,
    387                             SOC_PHY_SHAD_RETRY_CNT);
    388                 }
    389             }
    390         }
    391     } 
    392 
    393     if (SOC_FAILURE(rv)) {
    394         LOG_ERROR(BSL_LS_SOC_PHY,
    395                   (BSL_META_U(unit,
    396                               "phy_reg_ge_write failed:"
    397                               " u=%d phy_id=0x%2x reg_bank=0x%04x reg_addr=0x%02x "
    398                               " rv=%d\n"), unit, pc->phy_id, reg_bank, reg_addr, rv)); 
    399     }
    400 
    401     return rv;
    402 }
    403 
    404 int
    405 phy_reg_ge_modify(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    406                 uint8 reg_addr, uint16 data, uint16 mask)
    407 {
    408     int     rv;
    409 
    410     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    411         return SOC_E_NONE;
    412     }
    413 
    414     rv       = SOC_E_NONE;
    415 
    416     if (flags & SOC_PHY_REG_1000X) {
    417         if (reg_addr <= 0x000f) {
    418             uint16 blk_sel;
    419 
    420             /* Map 1000X page */
    421             SOC_IF_ERROR_RETURN
    422                 (WRITE_PHY_REG(unit, pc, 0x1c, 0x7c00));
    423             SOC_IF_ERROR_RETURN
    424                 (READ_PHY_REG(unit, pc, 0x1c, &blk_sel));
    425             SOC_IF_ERROR_RETURN
    426                 (WRITE_PHY_REG(unit, pc, 0x1c, blk_sel | 0x8001));
    427 
    428             /* Modify 1000X IEEE register */
    429             SOC_IF_ERROR_RETURN
    430                 (MODIFY_PHY_REG(unit, pc, reg_addr, data, mask));
    431 
    432            /* Restore IEEE mapping */
    433             SOC_IF_ERROR_RETURN
    434                 (WRITE_PHY_REG(unit, pc, 0x1c, 
    435                                 (blk_sel & 0xfffe) | 0x8000));
    436         } else {
    437             rv = SOC_E_PARAM;
    438         }
    439     } else {
    440         switch(reg_addr) {
    441         /* Map shadow registers */
    442         case 0x15:
    443             /* SHAD_EXPD for 54640E */
    444             BCM54640E_SHAD_EXPD_PRE(unit, pc, reg_bank);
    445 
    446             SOC_IF_ERROR_RETURN
    447                 (WRITE_PHY_REG(unit, pc, 0x17, reg_bank));
    448             break;
    449         case 0x18:
    450             if (reg_bank <= 0x0007) {
    451                 SOC_IF_ERROR_RETURN
    452                     (WRITE_PHY_REG(unit, pc, reg_addr,
    453                                     (reg_bank << 12) | 0x7));
    454 
    455                 if (reg_bank == 0x0007) {
    456                     data |= 0x8000;
    457                     mask |= 0x8000;
    458                 }
    459                 mask &= ~(0x0007);
    460             } else {
    461                 rv = SOC_E_PARAM;
    462             }
    463             break;
    464         case 0x1C:
    465             if (reg_bank <= 0x001F) {
    466                 SOC_IF_ERROR_RETURN
    467                     (WRITE_PHY_REG(unit, pc, reg_addr, (reg_bank << 10)));
    468                 data |= 0x8000;
    469                 mask |= 0x8000;
    470                 mask &= ~(0x1F << 10);
    471             } else {
    472                 rv = SOC_E_PARAM;
    473             }
    474             break;
    475         case 0x1D:
    476             if (reg_bank == 0x0000) {
    477                 mask &= 0x07FFF;
    478             } else {
    479                 rv = SOC_E_PARAM;
    480             }
    481             break;
    482         default:
    483             if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) {
    484                 /* Must not write to reserved registers */ 
    485                 if (reg_addr > 0x001e) {
    486                     rv = SOC_E_PARAM;
    487                 }
    488             }
    489             break;
    490         }
    491         if (SOC_SUCCESS(rv)) {
    492             rv = MODIFY_PHY_REG(unit, pc, reg_addr, data, mask);
    493 
    494             /* SHAD_EXPD for 54640E */
    495             BCM54640E_SHAD_EXPD_POST(unit, pc, rv);
    496 
    497             if  (!(flags & SOC_PHY_REG_NO_RETRY_ACCESS )) {
    498 
    499                 if (SOC_SUCCESS(rv)  && PHY_IS_BCM54640E(pc)  && (reg_addr==0x15 && ((reg_bank&0x0F00) == 0x0d00))) {
    500 
    501                     uint16 tmp;
    502 
    503                     rv = READ_PHY_REG(unit, pc, reg_addr, &tmp);
    504 
    505                     if (SOC_SUCCESS(rv)) {
    506 
    507                         tmp &= ~(mask);
    508                         tmp |= (data & mask);
    509 
    510                         rv = check_if_necessary_then_fix(
    511                                 unit, pc, flags, reg_addr, reg_bank, tmp,
    512                                 SOC_PHY_SHAD_RETRY_CNT);
    513                     }
    514 
    515                 }
    516             }
    517 
    518         }
    519     } 
    520 
    521     if (SOC_FAILURE(rv)) {
    522         LOG_ERROR(BSL_LS_SOC_PHY,
    523                   (BSL_META_U(unit,
    524                               "phy_reg_ge_modify failed:"
    525                               " u=%d phy_id=0x%2x reg_bank=0x%04x reg_addr=0x%02x "
    526                               " rv=%d\n"), unit, pc->phy_id, reg_bank, reg_addr, rv)); 
    527     }
    528     return rv;
    529 }
    530 
    531 int
    532 phy_reg_xge_read(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    533                 uint8 dev_addr, uint16 reg_addr, uint16 *data)
    534 {
    535     int     rv;
    536     uint32  value;
    537     uint16  tmp, tmp2;
    538     rv       = SOC_E_NONE;
    539 
    540     {
    541         switch(reg_addr) {
    542         /* Map shadow registers */
    543         case 0xfff5:
    544             SOC_IF_ERROR_RETURN
    545                 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, 0xfff7), reg_bank));
    546             break;
    547         case 0xfff8:
    548             if (reg_bank <= 0x0007) {
    549                 SOC_IF_ERROR_RETURN
    550                     (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), 
    551                                     (reg_bank << 12) | 0x7));
    552             } else {
    553                 rv = SOC_E_PARAM;
    554             }
    555             break;
    556         case 0xfffc:
    557             if (reg_bank <= 0x001F) {
    558                 SOC_IF_ERROR_RETURN
    559                     (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), 
    560                                    (reg_bank << 10)));
    561             } else {
    562                 rv = SOC_E_PARAM;
    563             }
    564             break;
    565         case 0xfffd:
    566             if (reg_bank <= 0x0001) {
    567                 SOC_IF_ERROR_RETURN
    568                     (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), reg_bank << 15));
    569             } else {
    570                 rv = SOC_E_PARAM;
    571             }
    572             break;
    573         default:
    574             if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) {
    575                 /* Must not read from reserved registers */ 
    576                 if (reg_addr > 0xfffe) {
    577                    rv = SOC_E_PARAM;
    578                 }
    579             }
    580             break;
    581         }
    582         if (SOC_SUCCESS(rv)) {
    583             if(!(flags & SOC_PHY_REG_DUMMY_ACCESS)) {
    584                 rv = READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), data);
    585             }
    586             else {  
    587                 /* Do two dummy reads. Read #3 and #4 gives values */
    588                 READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), &tmp); /* Dummy read #1 */
    589                 READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), &tmp); /* Dummy read #2 */
    590                 READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), &tmp); /* Lower count */
    591                 READ_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), &tmp2); /* Upper count */
    592                 value = tmp2;
    593                 value <<= 16; /*upper count*/
    594                 value |= tmp;
    595                 * ((uint32 *) data) = value;
    596             }
    597         }
    598     } 
    599     if (SOC_FAILURE(rv)) {
    600         LOG_ERROR(BSL_LS_SOC_PHY,
    601                   (BSL_META_U(unit,
    602                               "phy_reg_ge_read failed:"
    603                               " u=%d phy_id=0x%2x dev_addr=0x%02x reg_bank=0x%04x reg_addr=0x%02x "
    604                               " rv=%d\n"), unit, pc->phy_id, dev_addr, reg_bank, reg_addr, rv)); 
    605     }
    606     return rv;
    607 }
    608 
    609 int
    610 phy_reg_xge_write(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    611                 uint8 dev_addr, uint16 reg_addr, uint16 data)
    612 {
    613     int     rv;
    614 
    615     rv       = SOC_E_NONE;
    616 
    617     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)) {
    618         return rv;
    619     }
    620 
    621     {
    622         switch(reg_addr) {
    623         /* Map shadow registers */
    624         case 0xfff5:
    625             SOC_IF_ERROR_RETURN
    626                     (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, 0xfff7), reg_bank));
    627             break;
    628         case 0xfff8:
    629             if (reg_bank <= 0x0007) {
    630                 if (reg_bank == 0x0007) {
    631                     data |= 0x8000;
    632                 }
    633                 data = (data & ~(0x0007)) | reg_bank;
    634             } else {
    635                 rv = SOC_E_PARAM;
    636             }
    637             break;
    638         case 0xfffc:
    639             if (reg_bank <= 0x001F) {
    640                 data = 0x8000 | (reg_bank << 10) | (data & 0x03FF);
    641             } else {
    642                 rv = SOC_E_PARAM;
    643             }
    644             break;
    645         case 0xfffd:
    646             if (reg_bank == 0x0000) {
    647                 data = data & 0x07FFF;
    648             } else {
    649                 rv = SOC_E_PARAM;
    650             }
    651             break;
    652         default:
    653             if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) {
    654                 /* Must not write to reserved registers */ 
    655                 if (reg_addr > 0xfffe) {
    656                     rv = SOC_E_PARAM;
    657                 }
    658             }
    659             break;
    660         }
    661         if (SOC_SUCCESS(rv)) {
    662             rv = WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), data);
    663         }
    664     } 
    665 
    666     if (SOC_FAILURE(rv)) {
    667         LOG_ERROR(BSL_LS_SOC_PHY,
    668                   (BSL_META_U(unit,
    669                               "phy_reg_ge_write failed:"
    670                               " u=%d phy_id=0x%2x dev_addr=0x%02x reg_bank=0x%04x reg_addr=0x%02x "
    671                               " rv=%d\n"), unit, pc->phy_id, dev_addr, reg_bank, reg_addr, rv)); 
    672     }
    673 
    674     return rv;
    675 }
    676 
    677 int
    678 phy_reg_xge_modify(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    679                 uint8 dev_addr, uint16 reg_addr, uint16 data, uint16 mask)
    680 {
    681     int     rv;
    682 
    683     rv       = SOC_E_NONE;
    684 
    685     {
    686         switch(reg_addr) {
    687         /* Map shadow registers */
    688         case 0xfff5:
    689             SOC_IF_ERROR_RETURN
    690                 (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, 0xfff7), reg_bank));
    691             break;
    692         case 0xfff8:
    693             if (reg_bank <= 0x0007) {
    694                 SOC_IF_ERROR_RETURN
    695                     (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr),
    696                                     (reg_bank << 12) | 0x7));
    697 
    698                 if (reg_bank == 0x0007) {
    699                     data |= 0x8000;
    700                     mask |= 0x8000;
    701                 }
    702                 mask &= ~(0x0007);
    703             } else {
    704                 rv = SOC_E_PARAM;
    705             }
    706             break;
    707         case 0xfffc:
    708             if (reg_bank <= 0x001F) {
    709                 SOC_IF_ERROR_RETURN
    710                     (WRITE_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), (reg_bank << 10)));
    711                 data |= 0x8000;
    712                 mask |= 0x8000;
    713                 mask &= ~(0x1F << 10);
    714             } else {
    715                 rv = SOC_E_PARAM;
    716             }
    717             break;
    718         case 0xfffd:
    719             if (reg_bank == 0x0000) {
    720                 mask &= 0x07FFF;
    721             } else {
    722                 rv = SOC_E_PARAM;
    723             }
    724             break;
    725         default:
    726             if (!(flags & SOC_PHY_REG_RESERVE_ACCESS)) {
    727                 /* Must not write to reserved registers */ 
    728                 if (reg_addr > 0xfffe) {
    729                     rv = SOC_E_PARAM;
    730                 }
    731             }
    732             break;
    733         }
    734         if (SOC_SUCCESS(rv)) {
    735             rv = MODIFY_PHY_REG(unit, pc, SOC_PHY_CLAUSE45_ADDR(dev_addr, reg_addr), data, mask);
    736         }
    737     } 
    738 
    739     if (SOC_FAILURE(rv)) {
    740         LOG_ERROR(BSL_LS_SOC_PHY,
    741                   (BSL_META_U(unit,
    742                               "phy_reg_ge_modify failed:"
    743                               " u=%d phy_id=0x%2x dev_addr=0x%02x reg_bank=0x%04x reg_addr=0x%02x "
    744                               " rv=%d\n"), unit, pc->phy_id, dev_addr, reg_bank, reg_addr, rv)); 
    745     }
    746     return rv;
    747 }
    748 
    749 int 
    750 phy_reg_serdes_read(int unit, phy_ctrl_t *pc,  uint16 reg_bank, 
    751                     uint8 reg_addr, uint16 *phy_rd_data) 
    752 { 
    753     int    rv; 
    754  
    755     rv     = SOC_E_NONE; 
    756  
    757 #ifdef INCLUDE_PHY_XGXS6
    758     if (soc_feature(unit, soc_feature_xgxs_v6)) { 
    759         if ((reg_bank != 0) || (reg_addr >= 0x0010)) { 
    760             reg_bank = 0x300 + (reg_bank << 4); 
    761         } 
    762     } 
    763 #endif /* INCLUDE_PHY_XGXS6 */
    764 
    765     rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank); 
    766  
    767     if (SOC_SUCCESS(rv)) { 
    768         rv = READ_PHY_REG(unit, pc, reg_addr, phy_rd_data);  
    769     } 
    770  
    771     return rv; 
    772 }
    773 
    774 int
    775 phy_reg_serdes_write(int unit, phy_ctrl_t *pc, uint16 reg_bank, 
    776                      uint8 reg_addr, uint16 phy_wr_data)
    777 {
    778     int    rv;
    779 
    780     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    781         return SOC_E_NONE;
    782     }
    783 
    784     rv     = SOC_E_NONE;
    785 
    786 #ifdef INCLUDE_PHY_XGXS6
    787     if (soc_feature(unit, soc_feature_xgxs_v6)) {
    788         if ((reg_bank != 0) || (reg_addr >= 0x0010)) {
    789             reg_bank = 0x300 + (reg_bank << 4);
    790         }
    791     }
    792 #endif /* INCLUDE_PHY_XGXS6 */
    793 
    794     rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank);
    795 
    796     if (SOC_SUCCESS(rv)) {
    797         rv = WRITE_PHY_REG(unit, pc, reg_addr, phy_wr_data);
    798     }
    799 
    800     return rv;
    801 }
    802 
    803 int
    804 phy_reg_serdes_modify(int unit, phy_ctrl_t *pc,
    805                       uint16 reg_bank, uint8 reg_addr,
    806                       uint16 phy_mo_data, uint16 phy_mo_mask)
    807 {
    808     int    rv;
    809 
    810     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    811         return SOC_E_NONE;
    812     }
    813 
    814     rv     = SOC_E_NONE;
    815 
    816 #ifdef INCLUDE_PHY_XGXS6
    817     if (soc_feature(unit, soc_feature_xgxs_v6)) {
    818         if ((reg_bank != 0) || (reg_addr >= 0x0010)) {
    819             reg_bank = 0x300 + (reg_bank << 4);
    820         }
    821     }
    822 #endif /* INCLUDE_PHY_XGXS6 */
    823 
    824     rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank);
    825 
    826     if (SOC_SUCCESS(rv)) {
    827         rv = MODIFY_PHY_REG(unit, pc, reg_addr, phy_mo_data, phy_mo_mask);
    828     }
    829 
    830     return rv;
    831 }
    832 
    833 #if defined(INCLUDE_PHY_XGXS)
    834 int 
    835 phy_reg_xgxs_read(int unit, phy_ctrl_t *pc, uint16 reg_bank,
    836                            uint8 reg_addr, uint16 *data)
    837 {
    838     int    rv;
    839 
    840     rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank);
    841 
    842     if (SOC_SUCCESS(rv)) {
    843         rv = READ_PHY_REG(unit, pc, reg_addr, data);
    844     }
    845 
    846     return rv;
    847 }
    848 
    849 int 
    850 phy_reg_xgxs_write(int unit, phy_ctrl_t *pc, uint16 reg_bank,
    851                             uint8 reg_addr, uint16 data)
    852 {
    853     int    rv;
    854 
    855     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    856         return SOC_E_NONE;
    857     }
    858 
    859     rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank);
    860 
    861     if (SOC_SUCCESS(rv)) {
    862         rv = WRITE_PHY_REG(unit, pc, reg_addr, data);
    863     }
    864 
    865     return rv;
    866 }
    867 
    868 int 
    869 phy_reg_xgxs_modify(int unit, phy_ctrl_t *pc, uint16 reg_bank,
    870                              uint8 reg_addr, uint16 data, uint16 mask)
    871 {
    872     int    rv;
    873 
    874     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    875         return SOC_E_NONE;
    876     }
    877 
    878     rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank);
    879 
    880     if (SOC_SUCCESS(rv)) {
    881         rv = MODIFY_PHY_REG(unit, pc, reg_addr, data, mask);
    882     }
    883 
    884     return rv;
    885 }
    886 #endif /* INCLUDE_PHY_XGXS */
    887 
    888 #if defined(INCLUDE_PHY_XGXS6)
    889 int 
    890 phy_reg_xgxs6_read(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    891                            uint8 reg_addr, uint16 *data)
    892 {
    893     int    rv;
    894 
    895     rv     = SOC_E_NONE;
    896 
    897     if (reg_addr < 0x10) {
    898         /* Select between SerDes and XAUI mapping */
    899         SOC_IF_ERROR_RETURN
    900             (WRITE_PHY_REG(unit, pc, 0x1f, 0x0000));
    901         SOC_IF_ERROR_RETURN
    902             (MODIFY_PHY_REG(unit, pc, 0x1e, 
    903                              (flags & SOC_PHY_REG_1000X) ? 0x0000 : 0x0001,
    904                              0x0001)); 
    905     }
    906 
    907     if (SOC_SUCCESS(rv)) {
    908         rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank);
    909     }
    910 
    911     if (SOC_SUCCESS(rv)) {
    912         rv = READ_PHY_REG(unit, pc, reg_addr, data);
    913     }
    914 
    915     return rv;
    916 }
    917 
    918 int 
    919 phy_reg_xgxs6_write(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    920                             uint8 reg_addr, uint16 data)
    921 {
    922     int    rv;
    923 
    924     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    925         return SOC_E_NONE;
    926     }
    927 
    928     rv     = SOC_E_NONE;
    929 
    930     if (reg_addr < 0x10) {
    931         /* Select between SerDes and XAUI mapping */
    932         SOC_IF_ERROR_RETURN
    933             (WRITE_PHY_REG(unit, pc, 0x1f, 0x0000));
    934         SOC_IF_ERROR_RETURN
    935             (MODIFY_PHY_REG(unit, pc, 0x1e, 
    936                              (flags & SOC_PHY_REG_1000X) ? 0x0000 : 0x0001,
    937                              0x0001)); 
    938     }
    939 
    940     if (SOC_SUCCESS(rv)) {
    941         rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank);
    942     }
    943 
    944     if (SOC_SUCCESS(rv)) {
    945         rv = WRITE_PHY_REG(unit, pc, reg_addr, data);
    946     }
    947 
    948     return rv;
    949 }
    950 
    951 int 
    952 phy_reg_xgxs6_modify(int unit, phy_ctrl_t *pc, uint32 flags, uint16 reg_bank,
    953                              uint8 reg_addr, uint16 data, uint16 mask)
    954 {
    955     int    rv;
    956 
    957     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
    958         return SOC_E_NONE;
    959     }
    960 
    961     rv     = SOC_E_NONE;
    962 
    963     if (reg_addr < 0x10) {
    964         /* Select between SerDes and XAUI mapping */
    965         SOC_IF_ERROR_RETURN
    966             (WRITE_PHY_REG(unit, pc, 0x1f, 0x0000));
    967         SOC_IF_ERROR_RETURN
    968             (MODIFY_PHY_REG(unit, pc, 0x1e, 
    969                              (flags & SOC_PHY_REG_1000X) ? 0x0000 : 0x0001,
    970                              0x0001)); 
    971     }
    972 
    973     if (SOC_SUCCESS(rv)) {
    974         rv = WRITE_PHY_REG(unit, pc, 0x1f, reg_bank);
    975     }
    976 
    977     if (SOC_SUCCESS(rv)) {
    978         rv = MODIFY_PHY_REG(unit, pc, reg_addr, data, mask);
    979     }
    980 
    981     return rv;
    982 }
    983 #endif /* INCLUDE_PHY_XGXS6 */
    984 
    985 STATIC int 
    986 _phy_reg_aer_cl45_read(int unit, phy_ctrl_t *pc, uint32 reg_addr,
    987                  uint16 *data)
    988 {
    989     uint16 phy_reg_addr;
    990     int    cl45_devid;
    991 
    992     phy_reg_addr = PHY_AER_REG_ADDR_CL45_REGAD(reg_addr);
    993     cl45_devid   = PHY_AER_REG_ADDR_CL45_DEVID(reg_addr);
    994 
    995     if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) {
    996         /* write the lane number to the AER if lane specific */
    997         SOC_IF_ERROR_RETURN
    998             (WRITE_PHY_REG(unit, pc, 
    999                 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG),
   1000                 PHY_AER_REG_ADDR_LANE_NUM(reg_addr)));
   1001     }
   1002     SOC_IF_ERROR_RETURN
   1003         (READ_PHY_REG(unit, pc, 
   1004             SOC_PHY_CLAUSE45_ADDR(cl45_devid,phy_reg_addr), data));
   1005 
   1006     if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) {
   1007         /* restore back the lane number to 0 */
   1008         SOC_IF_ERROR_RETURN
   1009             (WRITE_PHY_REG(unit, pc, 
   1010                 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG),
   1011                 0));
   1012     }
   1013     return SOC_E_NONE;
   1014 }
   1015 
   1016 STATIC int 
   1017 _phy_reg_aer_cl45_write(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1018                   uint16 data)
   1019 {
   1020     uint16 phy_reg_addr;
   1021     int    cl45_devid;
   1022 
   1023     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
   1024         return SOC_E_NONE;
   1025     }
   1026 
   1027     phy_reg_addr = PHY_AER_REG_ADDR_CL45_REGAD(reg_addr);
   1028     cl45_devid = PHY_AER_REG_ADDR_CL45_DEVID(reg_addr);
   1029 
   1030     if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) {
   1031         /* write the lane number to the AER if lane specific */
   1032         SOC_IF_ERROR_RETURN
   1033             (WRITE_PHY_REG(unit, pc, 
   1034                 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG),
   1035                 PHY_AER_REG_ADDR_LANE_NUM(reg_addr)));
   1036     }
   1037     SOC_IF_ERROR_RETURN
   1038         (WRITE_PHY_REG(unit, pc, 
   1039             SOC_PHY_CLAUSE45_ADDR(cl45_devid,phy_reg_addr), data));
   1040 
   1041     if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) {
   1042         /* write the lane number 0 to the AER */
   1043         SOC_IF_ERROR_RETURN
   1044             (WRITE_PHY_REG(unit, pc, 
   1045                 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG),
   1046                 0));
   1047     }
   1048     return SOC_E_NONE;
   1049 }
   1050 
   1051 STATIC int 
   1052 _phy_reg_aer_cl45_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1053                   uint16 data,uint16 mask)
   1054 {
   1055     uint16 phy_reg_addr;
   1056     int    cl45_devid;
   1057 
   1058     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
   1059         return SOC_E_NONE;
   1060     }
   1061 
   1062     phy_reg_addr = PHY_AER_REG_ADDR_CL45_REGAD(reg_addr);
   1063     cl45_devid = PHY_AER_REG_ADDR_CL45_DEVID(reg_addr);
   1064 
   1065     if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) {
   1066         /* write the lane number to the AER if lane specific */
   1067         SOC_IF_ERROR_RETURN
   1068             (WRITE_PHY_REG(unit, pc, 
   1069                 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG),
   1070                 PHY_AER_REG_ADDR_LANE_NUM(reg_addr)));
   1071     }
   1072     SOC_IF_ERROR_RETURN
   1073         (MODIFY_PHY_REG(unit, pc, 
   1074             SOC_PHY_CLAUSE45_ADDR(cl45_devid,phy_reg_addr), data,mask));
   1075 
   1076     if (PHY_AER_REG_ADDR_LANE_NUM(reg_addr)) {
   1077         /* write the lane number 0 to the AER */
   1078         SOC_IF_ERROR_RETURN
   1079             (WRITE_PHY_REG(unit, pc, 
   1080                 SOC_PHY_CLAUSE45_ADDR(cl45_devid,PHY_AER_REG),
   1081                 0));
   1082     }
   1083     return SOC_E_NONE;
   1084 }
   1085 
   1086 STATIC int 
   1087 _phy_reg_aer_cl22_read(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1088                  uint16 *data)
   1089 {
   1090     uint16 phy_reg_aer;
   1091     uint16 phy_reg_blk;
   1092     uint16 phy_reg_addr;
   1093     int    rv;
   1094 
   1095     rv     = SOC_E_UNAVAIL;
   1096 
   1097     phy_reg_aer  = PHY_AER_REG_ADDR_AER(reg_addr);
   1098     phy_reg_blk  = PHY_AER_REG_ADDR_BLK(reg_addr);
   1099     phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg_addr);
   1100     if (phy_reg_aer == 0) {
   1101         rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk);
   1102 
   1103         if (SOC_SUCCESS(rv)) {
   1104             rv = READ_PHY_REG(unit, pc, phy_reg_addr, data);
   1105         }
   1106     } else {
   1107         /* Set desired AER */
   1108         rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0);
   1109         if (SOC_SUCCESS(rv)) {
   1110             rv = WRITE_PHY_REG(unit, pc, 0x1e, phy_reg_aer);
   1111         }
   1112 
   1113         /* Map requested block */
   1114         if (SOC_SUCCESS(rv)) {
   1115             rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk);
   1116         }
   1117 
   1118         /* Read from the requested register */
   1119         if (SOC_SUCCESS(rv)) {
   1120             rv = READ_PHY_REG(unit, pc, phy_reg_addr, data);
   1121         }
   1122 
   1123         /* Set AER back to 0 */
   1124         if (SOC_SUCCESS(rv)) {
   1125             rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0);
   1126         }
   1127         if (SOC_SUCCESS(rv)) {
   1128             rv = WRITE_PHY_REG(unit, pc, 0x1e, 0);
   1129         }
   1130         if (SOC_SUCCESS(rv)) {
   1131             rv = WRITE_PHY_REG(unit, pc, 0x1f, 0x0);
   1132         }
   1133     }
   1134     return rv;
   1135 }
   1136 
   1137 STATIC int 
   1138 _phy_reg_aer_cl22_write(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1139                   uint16 data)
   1140 {
   1141     uint16 phy_reg_aer;
   1142     uint16 phy_reg_blk;
   1143     uint16 phy_reg_addr;
   1144     int    rv;
   1145 
   1146     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
   1147         return SOC_E_NONE;
   1148     }
   1149 
   1150     rv     = SOC_E_UNAVAIL;
   1151 
   1152     phy_reg_aer  = PHY_AER_REG_ADDR_AER(reg_addr);
   1153     phy_reg_blk  = PHY_AER_REG_ADDR_BLK(reg_addr);
   1154     phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg_addr);
   1155     if (phy_reg_aer == 0) {
   1156         rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk);
   1157 
   1158         if (SOC_SUCCESS(rv)) {
   1159             rv = WRITE_PHY_REG(unit, pc, phy_reg_addr, data);
   1160         }
   1161     } else {
   1162         /* Set desired AER */
   1163         rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0);
   1164         if (SOC_SUCCESS(rv)) {
   1165             rv = WRITE_PHY_REG(unit, pc, 0x1e, phy_reg_aer);
   1166         }
   1167 
   1168         /* Map requested block */
   1169         if (SOC_SUCCESS(rv)) {
   1170             rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk);
   1171         }
   1172 
   1173         /* Write to requested register */
   1174         if (SOC_SUCCESS(rv)) {
   1175             rv = WRITE_PHY_REG(unit, pc, phy_reg_addr, data);
   1176         }
   1177 
   1178         /* Set AER back to 0 */
   1179         if (SOC_SUCCESS(rv)) {
   1180             rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0);
   1181         }
   1182         if (SOC_SUCCESS(rv)) {
   1183             rv = WRITE_PHY_REG(unit, pc, 0x1e, 0);
   1184         }
   1185     }
   1186     return rv;
   1187 }
   1188 
   1189 STATIC int 
   1190 _phy_reg_aer_cl22_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1191                    uint16 data, uint16 mask)
   1192 {
   1193     uint16 phy_reg_aer;
   1194     uint16 phy_reg_blk;
   1195     uint16 phy_reg_addr;
   1196     int    rv;
   1197 
   1198     if (SOC_WARM_BOOT(unit) || SOC_IS_RELOADING(unit)){
   1199         return SOC_E_NONE;
   1200     }
   1201 
   1202     rv     = SOC_E_UNAVAIL;
   1203 
   1204     phy_reg_aer  = PHY_AER_REG_ADDR_AER(reg_addr);
   1205     phy_reg_blk  = PHY_AER_REG_ADDR_BLK(reg_addr);
   1206     phy_reg_addr = PHY_AER_REG_ADDR_REGAD(reg_addr);
   1207     if (phy_reg_aer == 0) {
   1208         /* Only support AER = 0 for now */
   1209         rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk);
   1210 
   1211         if (SOC_SUCCESS(rv)) {
   1212             rv = MODIFY_PHY_REG(unit, pc, phy_reg_addr, data, mask);
   1213         }
   1214     } else {
   1215         rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0);
   1216         if (SOC_SUCCESS(rv)) {
   1217             rv = WRITE_PHY_REG(unit, pc, 0x1e, phy_reg_aer);
   1218         }
   1219 
   1220         /* Map requested block */
   1221         if (SOC_SUCCESS(rv)) {
   1222             rv = WRITE_PHY_REG(unit, pc, 0x1f, phy_reg_blk);
   1223         }
   1224 
   1225         /* Modify requested register */
   1226         if (SOC_SUCCESS(rv)) {
   1227             rv = MODIFY_PHY_REG(unit, pc, phy_reg_addr, data, mask);
   1228         }
   1229 
   1230         /* Set AER back to 0 */
   1231         if (SOC_SUCCESS(rv)) {
   1232             rv = WRITE_PHY_REG(unit, pc, 0x1f, 0xffd0);
   1233         }
   1234         if (SOC_SUCCESS(rv)) {
   1235             rv = WRITE_PHY_REG(unit, pc, 0x1e, 0);
   1236         }
   1237 
   1238     }
   1239     return rv;
   1240 
   1241 }
   1242 
   1243 int
   1244 phy_reg_aer_read(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1245                  uint16 *data)
   1246 {
   1247     int rv;
   1248     if (pc->flags & PHYCTRL_MDIO_CL45) {
   1249         rv = _phy_reg_aer_cl45_read(unit,pc,reg_addr,data);
   1250     } else {
   1251         rv = _phy_reg_aer_cl22_read(unit,pc,reg_addr,data);
   1252     }
   1253     return rv;
   1254 }
   1255 
   1256 int
   1257 phy_reg_aer_write(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1258                  uint16 data)
   1259 {
   1260     int rv;
   1261     if (pc->flags & PHYCTRL_MDIO_CL45) {
   1262         rv = _phy_reg_aer_cl45_write(unit,pc,reg_addr,data);
   1263     } else {
   1264         rv = _phy_reg_aer_cl22_write(unit,pc,reg_addr,data);
   1265     }
   1266     return rv;
   1267 }
   1268      
   1269 int
   1270 phy_reg_aer_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1271                  uint16 data,uint16 mask)
   1272 {
   1273     int rv;
   1274     if (pc->flags & PHYCTRL_MDIO_CL45) {
   1275         rv = _phy_reg_aer_cl45_modify(unit,pc,reg_addr,data,mask);
   1276     } else {
   1277         rv = _phy_reg_aer_cl22_modify(unit,pc,reg_addr,data,mask);
   1278     }
   1279     return rv;
   1280 }
   1281      
   1282 #if defined(INCLUDE_XGXS_QSGMII65)
   1283 int 
   1284 phy_reg_qsgmii_aer_read(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1285                  uint16 *data)
   1286 {
   1287     int    rv = SOC_E_UNAVAIL;
   1288 
   1289     reg_addr = reg_addr | (pc->lane_num << 16);
   1290 
   1291     rv = phy_reg_aer_read(unit, pc, reg_addr, data);
   1292     return rv;
   1293 }
   1294 
   1295 int 
   1296 phy_reg_qsgmii_aer_write(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1297                   uint16 data)
   1298 {
   1299     int    rv = SOC_E_UNAVAIL;
   1300 
   1301     reg_addr = reg_addr | (pc->lane_num << 16);
   1302 
   1303     rv = phy_reg_aer_write(unit, pc, reg_addr, data);
   1304     return rv;
   1305 }
   1306 
   1307 int 
   1308 phy_reg_qsgmii_aer_modify(int unit, phy_ctrl_t *pc, uint32 reg_addr,
   1309                    uint16 data, uint16 mask)
   1310 {
   1311     int    rv = SOC_E_UNAVAIL;
   1312 
   1313     reg_addr = reg_addr | (pc->lane_num << 16);
   1314     
   1315     rv = phy_reg_aer_modify(unit, pc, reg_addr, data, mask);
   1316     return rv;
   1317 }
   1318 #endif /* INCLUDE_XGXS_QSGMII65 */