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

phy522xcdiag.c (7726B)


      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:        phy522x.c
      8  * Purpose:	Broadcom 522x phy driver
      9  *    	Supports 5218, 5220/5221, 5226, 5228, 5238, 5248
     10  *      and phy5324(8 ports 10/100 PHY, bcm5324 built-in)
     11  */
     12 #ifdef INCLUDE_PHY_522X
     13 #include <sal/types.h>
     14 #include <sal/core/thread.h>
     15 #include <shared/bsl.h>
     16 #include <soc/phy.h>
     17 #include <soc/drv.h>
     18 #include <soc/debug.h>
     19 #include <soc/error.h>
     20 #include <soc/phyreg.h>
     21 
     22 #include <soc/phy.h>
     23 #include <soc/phy/phyctrl.h>
     24 #include <soc/phy/drv.h>
     25 
     26 #include "phyident.h"
     27 #include "phyreg.h"
     28 #include "phyfege.h"
     29 #include "phy522x.h"
     30 
     31 static int l1[] = {0,0,0,0,0,0,0,4,8,12,15,19,22,26,29,32,35,38,41,44,46,49,
     32 51,54,56,59,61,63,66,68,70,72,74,76,78,80,81,83,85,87,89,90,92,94,95,97,99,
     33 100,102,104,105,107,109,110,112,114,115,117,119,121,122,124,126,128};static
     34 int l2[] = {0,0,0,0,0,0,0,0,0,0,0,5,5,10,10,15,20,25,25,30,30,35,40,45,45,50,
     35 55,60,60,65,65,70,75,80,80,85,90,90,95,100,105,105,110,115,120,125,125,130,
     36 130,135,140,145,145,150,150,150,150,150,150,150,150,150,150,150};int l3(int l4
     37 ,soc_port_t l5,soc_port_cable_diag_t*l6){phy_ctrl_t*l7;uint16 l8;uint16 l9;
     38 int l10;int l11 = SOC_E_NONE;int l12;l7 = EXT_PHY_SW_STATE(l4,l5);
     39 SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x1f,0x008b));for(l12 = 0;l12<2;l12++
     40 ){sal_usleep(1000);SOC_IF_ERROR_RETURN(READ_PHY_REG(l4,l7,0x14,&l8));}if(l8&
     41 0x0040){l6->npairs = 2;l6->fuzz_len = 10;l6->state = l6->pair_state[0] = l6->
     42 pair_state[1] = SOC_PORT_CABLE_STATE_OK;SOC_IF_ERROR_RETURN(READ_PHY_REG(l4,
     43 l7,0x18,&l8));l8 = (l8>>9)&0x7f;l10 = l8-0x40;l6->pair_len[0] = l6->pair_len[
     44 1] = l2[l10];SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x1f,0x000b));return
     45 SOC_E_NONE;}SOC_IF_ERROR_RETURN(READ_PHY_REG(l4,l7,0x00,&l9));l11 = 
     46 WRITE_PHY_REG(l4,l7,0x00,0x2000);if(l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,
     47 l7,0x14,0x8000);if(l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,l7,0x13,0x0002);if
     48 (l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,l7,0x13,0x0000);if(l11<0){goto l13;}
     49 l11 = WRITE_PHY_REG(l4,l7,0x13,0x4868);if(l11<0){goto l13;}l11 = 
     50 WRITE_PHY_REG(l4,l7,0x13,0x1f00);if(l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,
     51 l7,0x13,0x044e);if(l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,l7,0x13,0x0446);if
     52 (l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,l7,0x13,0x0000);if(l11<0){goto l13;}
     53 l11 = WRITE_PHY_REG(l4,l7,0x13,0x004e);if(l11<0){goto l13;}l11 = 
     54 WRITE_PHY_REG(l4,l7,0x13,0x0c45);if(l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,
     55 l7,0x13,0x1040);if(l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,l7,0x14,0x8000);if
     56 (l11<0){goto l13;}l11 = WRITE_PHY_REG(l4,l7,0x13,0x0006);if(l11<0){goto l13;}
     57 do{sal_usleep(1000);l11 = WRITE_PHY_REG(l4,l7,0x14,0x8000);if(l11<0){goto l13
     58 ;}l11 = READ_PHY_REG(l4,l7,0x13,&l8);if(l11<0){goto l13;}}while(l8&0x0004);l6
     59 ->npairs = 2;l6->fuzz_len = 0;switch((l8>>10)&0x3){case 0:l6->pair_state[0] = 
     60 SOC_PORT_CABLE_STATE_OK;break;case 1:l6->pair_state[0] = 
     61 SOC_PORT_CABLE_STATE_OPEN;break;case 2:l6->pair_state[0] = 
     62 SOC_PORT_CABLE_STATE_SHORT;break;default:l6->pair_state[0] = 
     63 SOC_PORT_CABLE_STATE_UNKNOWN;break;}switch((l8>>12)&0x3){case 0:l6->
     64 pair_state[1] = SOC_PORT_CABLE_STATE_OK;break;case 1:l6->pair_state[1] = 
     65 SOC_PORT_CABLE_STATE_OPEN;break;case 2:l6->pair_state[1] = 
     66 SOC_PORT_CABLE_STATE_SHORT;break;default:l6->pair_state[1] = 
     67 SOC_PORT_CABLE_STATE_UNKNOWN;break;}l6->state = l6->pair_state[0];if(l6->
     68 pair_state[1]>l6->state){l6->state = l6->pair_state[1];}l11 = READ_PHY_REG(l4
     69 ,l7,0x13,&l8);if(l11<0){goto l13;}l6->pair_len[0] = ((l8&0xff)*80)/100;l6->
     70 pair_len[1] = (((l8>>8)&0xff)*80)/100;l11 = WRITE_PHY_REG(l4,l7,0x1f,0x000b);
     71 l13:SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x00,l9));return l11;}int
     72 phy_522x_cable_diag(int l4,soc_port_t l5,soc_port_cable_diag_t*l6){phy_ctrl_t
     73 *l7;uint16 l8;int l10;int l12;uint8 l14;int l15;l7 = EXT_PHY_SW_STATE(l4,l5);
     74 if(!(PHY_IS_BCM5248(l7)||PHY_IS_BCM5348(l7)||PHY_IS_BCM5324(l7)||
     75 PHY_IS_BCM5324A1(l7)||PHY_IS_BCM53242(l7)||PHY_IS_BCM53262(l7)||
     76 PHY_IS_BCM53280(l7))){return SOC_E_UNAVAIL;}if(PHY_IS_BCM53280_A0(l7)){return
     77 SOC_E_UNAVAIL;}if(l6 == NULL){return SOC_E_PARAM;}SOC_IF_ERROR_RETURN(
     78 READ_PHY_REG(l4,l7,MII_ASSR_REG,&l8));l14 = (l8&MII_ASSR_LS)?TRUE:FALSE;if(
     79 PHY_IS_BCM5348(l7)||PHY_IS_BCM5324(l7)||PHY_IS_BCM5324A1(l7)||PHY_IS_BCM53242
     80 (l7)||PHY_IS_BCM53262(l7)||PHY_IS_BCM53280(l7)){SOC_IF_ERROR_RETURN(
     81 phy_fe_ge_speed_get(l4,l5,&l15));if((l15!= 100)&&(l14)){LOG_WARN(BSL_LS_SOC_PHY, 
     82 (BSL_META("Cable diagnostic is only supported for 100Mb mode\n")));
     83 return SOC_E_UNAVAIL;}
     84 }if(PHY_IS_BCM53280(l7)){return(l3(l4,l5,l6));}SOC_IF_ERROR_RETURN(
     85 WRITE_PHY_REG(l4,l7,0x1f,0x008b));sal_usleep(1000);if(!PHY_IS_BCM5248(l7)){if
     86 (l14){l6->npairs = 2;l6->fuzz_len = 5;l6->state = l6->pair_state[0] = l6->
     87 pair_state[1] = SOC_PORT_CABLE_STATE_OK;SOC_IF_ERROR_RETURN(READ_PHY_REG(l4,
     88 l7,0x18,&l8));l6->pair_len[0] = l6->pair_len[1] = ((((uint32)((l8&0x7E00)>>9)
     89 )*1000L-9163L)*172L/100L/1000L);SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x1f,
     90 0x000b));return SOC_E_NONE;}}else{SOC_IF_ERROR_RETURN(READ_PHY_REG(l4,l7,0x14
     91 ,&l8));if(l8&0x0040){l6->npairs = 2;l6->fuzz_len = 10;l6->state = l6->
     92 pair_state[0] = l6->pair_state[1] = SOC_PORT_CABLE_STATE_OK;for(l10 = 0,l12 = 
     93 0;l12<10;l12++){SOC_IF_ERROR_RETURN(READ_PHY_REG(l4,l7,0x18,&l8));l8 = (l8>>9
     94 )&0x3f;l10+= l8;}l10 = l10/10;l6->pair_len[0] = l6->pair_len[1] = l1[l10];
     95 SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x1f,0x000b));return SOC_E_NONE;}}
     96 SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x14,0x0000));SOC_IF_ERROR_RETURN(
     97 WRITE_PHY_REG(l4,l7,0x13,0x0000));SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,
     98 0x13,0x0000));SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x13,0x4824));if(
     99 PHY_IS_BCM53242(l7)||PHY_IS_BCM53262(l7)){SOC_IF_ERROR_RETURN(WRITE_PHY_REG(
    100 l4,l7,0x13,0x3000));}else{SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x13,0x4000
    101 ));}SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x13,0x0500));SOC_IF_ERROR_RETURN
    102 (WRITE_PHY_REG(l4,l7,0x13,0xc404));SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,
    103 0x13,0x0100));if(PHY_IS_BCM53242(l7)||PHY_IS_BCM53262(l7)){
    104 SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x13,0x004f));}else{
    105 SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7,0x13,0x004c));}SOC_IF_ERROR_RETURN(
    106 WRITE_PHY_REG(l4,l7,0x13,0x8006));do{sal_usleep(1000);SOC_IF_ERROR_RETURN(
    107 WRITE_PHY_REG(l4,l7,0x14,0x0000));SOC_IF_ERROR_RETURN(READ_PHY_REG(l4,l7,0x13
    108 ,&l8));}while(l8&0x0004);if((l8&0x03c0)!= 0x0300){SOC_IF_ERROR_RETURN(
    109 WRITE_PHY_REG(l4,l7,0x1f,0x000b));return SOC_E_FAIL;}l6->npairs = 2;l6->
    110 fuzz_len = 0;switch((l8>>10)&0x3){case 0:l6->pair_state[0] = 
    111 SOC_PORT_CABLE_STATE_OK;break;case 1:l6->pair_state[0] = 
    112 SOC_PORT_CABLE_STATE_OPEN;break;case 2:l6->pair_state[0] = 
    113 SOC_PORT_CABLE_STATE_SHORT;break;default:l6->pair_state[0] = 
    114 SOC_PORT_CABLE_STATE_UNKNOWN;break;}switch((l8>>12)&0x3){case 0:l6->
    115 pair_state[1] = SOC_PORT_CABLE_STATE_OK;break;case 1:l6->pair_state[1] = 
    116 SOC_PORT_CABLE_STATE_OPEN;break;case 2:l6->pair_state[1] = 
    117 SOC_PORT_CABLE_STATE_SHORT;break;default:l6->pair_state[1] = 
    118 SOC_PORT_CABLE_STATE_UNKNOWN;break;}switch((l8>>12)&0x3){case 0:l6->
    119 pair_state[1] = SOC_PORT_CABLE_STATE_OK;break;case 1:l6->pair_state[1] = 
    120 SOC_PORT_CABLE_STATE_OPEN;break;case 2:l6->pair_state[1] = 
    121 SOC_PORT_CABLE_STATE_SHORT;break;default:l6->pair_state[1] = 
    122 SOC_PORT_CABLE_STATE_UNKNOWN;break;}l6->state = l6->pair_state[0];if(l6->
    123 pair_state[1]>l6->state){l6->state = l6->pair_state[1];}SOC_IF_ERROR_RETURN(
    124 READ_PHY_REG(l4,l7,0x13,&l8));l6->pair_len[0] = ((l8&0xff)*80)/100;l6->
    125 pair_len[1] = (((l8>>8)&0xff)*80)/100;SOC_IF_ERROR_RETURN(WRITE_PHY_REG(l4,l7
    126 ,0x1f,0x000b));return SOC_E_NONE;}
    127 
    128 #else
    129 int _phy522xcdiag_not_empty;
    130 #endif /* INCLUDE_PHY_522X */