1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
TP-Link_Archer-XR500v/EN7526G_3.18Kernel_SDK/bootrom/bootram/net/tcswitch.c
2024-07-22 01:58:46 -03:00

2036 lines
59 KiB
C
Executable File

#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/random.h>
#include <asm/bitops.h>
#include <asm/bootinfo.h>
#include <asm/irq.h>
#include <asm/mipsregs.h>
#include <asm/system.h>
#include <linux/circ_buf.h>
#include <asm/tc3162.h>
#include <asm/io.h>
#include "skbuff.h"
#include "eth.h"
#if defined(TCSUPPORT_CPU_EN7512) ||defined(TCSUPPORT_CPU_EN7521)
#include "7512_eth.h"
#else
#include "tc3162l2mac.h"
#endif
#define TCPHY_4PORT 1
#ifdef RT63365
#define TC2105MJ_SUPPORT 1
#else
#define TC2104MC_SUPPORT 1
#endif
#define TCPHY_SUPPORT 1
#define DO_PER_PORT 1
#define DO_4_PORT 0
#define DO_5_PORT 2
#define SWIC_TC2206 7
#define tcPhyVer_2031 0 // 9400, LEH
#define tcPhyVer_2101mb 1 // 9401, LEM
#define tcPhyVer_2104mc 2 // 9402, tc2206
#define tcPhyVer_2104sd 3 // 9403, tc2104sd
#define tcPhyVer_2101me 4 // 9404, 62UE
#define tcPhyVer_2102me 5 // 9405, tc3182
#define tcPhyVer_2104me 6 // 9406, tc2206F
#define tcPhyVer_2101mf 7 // 9407, FPGA(MF)
#define tcPhyVer_2105mj 11 // 940b, RT63365
#define TCPHY_PORTNUM 4
#define mtPhyVer_7530 13 //MT7530
#define tcPhyVer_mt7510FE 15 //MT7510,FE(Fast Ethernet)
#define mtPhyVer_7510Ge 16 //MT7510Ge
#define tcPhyVer_7512Fe 18 // 9412, EN7512Fe, need to check R15(0xf)[13]=0: no Giga capability
#define tcPhyVer_7512Ge 19 // 9451, EN7512Ge
#define TCPHYDISP1 if(tcPhy_disp_level>=1) printf
#define TCPHYDISP4 if(tcPhy_disp_level>=4) printf
#define TCPHYDISP5 if(tcPhy_disp_level>=5) printf
#define bool uint8
#define ENABLE 1
#define DISABLE 0
#define tc2104mc_G0R22_Tx10AmpSave_ON 0x0e64
#define tc2104mc_G0R22_Tx10AmpSave_OFF 0x066F
#define printf prom_printf
#define tcMiiStationRead(x, y) miiStationRead(x, y)
#define tcMiiStationWrite(x, y, z) miiStationWrite(x, y, z)
// for tcXXXX_link_state
#define ST_LINK_DOWN 0
static uint32 eco_rev = 0x00;
extern macAdapter_t *mac_p;
static phyDeviceList_t phyDeviceList[] = {
{ 0x0013, "LXT972" },
{ 0x0022, "AC101L" },
{ 0x0243, "IP101" },
{ 0x8201, "RTL8201" },
{ 0x03a2, "TC2031" }
};
static uint8 ephy_addr_base = 0; // replace "mac_p->enetPhyAddr"
#define MODEL_V0 (1<<0) /*TC2206A1*/
#define MODEL_V1 (1<<1) /*TC2206B2*/
#define MODEL_V2 (1<<2) /*TC2206F*/
typedef struct swic_reg{
uint16 model_id;
uint16 phyaddr;
uint16 regaddr;
uint16 value;
}swic_reg_t;
swic_reg_t tc2206_swic_reg[]=
{
{MODEL_V0|MODEL_V1, 22, 0, 0x6f9},/*P4MECR,Enable RGMII Mode*/
{MODEL_V0|MODEL_V1, 22, 1, 0x7f8},/*P5MECR*/
{MODEL_V0|MODEL_V1, 21, 5, 0x68c},/*HIGMPSCR*/
{MODEL_V0|MODEL_V1, 20, 13, 0x20},/*ATCR*/
{MODEL_V0|MODEL_V1, 21, 17, 0x10d},/*SCR1*/
{MODEL_V0|MODEL_V1, 21, 18, 0x7fc},/*P0MCR*/
{MODEL_V0|MODEL_V1, 21, 19, 0x7fc},/*P1MCR*/
{MODEL_V0|MODEL_V1, 21, 20, 0x7fc},/*P2MCR*/
{MODEL_V0|MODEL_V1, 21, 21, 0x7fc},/*P3MCR*/
{MODEL_V0|MODEL_V1, 21, 22, 0x0ffc},/*P4MCR*/
{MODEL_V0|MODEL_V1|MODEL_V2, 21, 23, 0x5ffc},/*P5MCR,Let CPU Port (Port 5) fixed on Link UP & 100 Full-Duplex Speed*/
{MODEL_V0|MODEL_V1, 20, 2, 0xf20f},/*P0CR*/
{MODEL_V0|MODEL_V1, 20, 3, 0xf20f},/*P1CR*/
{MODEL_V0|MODEL_V1, 20, 4, 0xf20f},/*P2CR*/
{MODEL_V0|MODEL_V1, 20, 5, 0xf20f},/*P3CR*/
{MODEL_V0|MODEL_V1, 20, 6, 0xf20f},/*P4CR*/
{MODEL_V0|MODEL_V1, 20, 7, 0xf20f},/*P5CR*/
{MODEL_V0|MODEL_V1, 21, 31, 0x40},/*MCMBTCR*/
{MODEL_V0|MODEL_V1|MODEL_V2, 24, 22, 0x4000},/*Enable the secondary L2 mac table to workaround thatSA=0.0.0.0 will be used entry 2049 entry*/
{MODEL_V0|MODEL_V1, 30, 8, 0x7777},/*RXCDC, must to be set up*/
{MODEL_V0|MODEL_V1, 30, 13, 0x0},/*WDTCR,Disable the watchdog timer*/
{MODEL_V0|MODEL_V1|MODEL_V2, 21, 4, 0xd},/*MLDPCR, MLD(IPv6 packet) forward to port_dft_mcas*/
{MODEL_V0|MODEL_V1|MODEL_V2, 21, 16, 0x10},/*SCR0,Disable illegal DA/SA check operation*/
{0, 0, 0x0}
};
/*Those registers is used to check the switch register is reset to default value.
It is used to protect ESD test.*/
swic_reg_t esd_chk_reg[]=
{
{MODEL_V0|MODEL_V1, 21, 22, 0x0},/*P4MCR*/
{MODEL_V0|MODEL_V1|MODEL_V2, 21, 23, 0x0},/*P5MCR,Let CPU Port (Port 5) fixed on Link UP & 100 Full-Duplex Speed*/
{MODEL_V0|MODEL_V1, 30, 8, 0x0},/*RXCDC, must to be set up*/
{MODEL_V0|MODEL_V1, 30, 13, 0x0},/*WDTCR,Disable the watchdog timer*/
{0,0, 0, 0x0}
};
static uint8 tcPhyFlag = 0;
static uint8 tcPhyVer = 99; // default: unknown PhyVer
static uint8 tcPhyPortNum = 1; // set value in tcPhyVerLookUp
static uint8 swicVendor = 0;
static uint8 esd_sw_patch=1;//default is enable ESD software patch
static uint8 sw_patch_flag = 1;
uint8 tcPhy_disp_level = 0; // default level 0
static uint8 current_idx = 0; // default 0, Do NOT change
static uint8 sw_FixPdWakeup_flag = 1;/*Default is enable*/
static uint8 tcphy_link_state[TCPHY_PORTNUM];
static uint8 cfg_Tx10AmpSave_flag = 1; // default ENABLE
static uint8 sw_ErrOverMonitor_flag = 1; // default enable
static uint8 tc2104mc_FixNonAnPairSwap_flag = 1;// default: enable
// variables for mii registers
typedef struct {
uint8 main_reset; // 15
uint8 force_speed; // 13
uint8 autoneg_enable; // 12
uint8 powerdown; // 11
uint8 force_duplex; // 8
} tcphy_mr0_reg_t;
typedef struct {
uint16 value; // 15:0
//uint8 autoneg_complete; // 5
bool link_status; // 2
bool link_status_prev;
} tcphy_mr1_reg_t;
typedef struct {
uint8 selector_field; //4:0
uint8 able100F; // 8
uint8 able100H; // 7
uint8 able10F; // 6
uint8 able10H; // 5
} tcphy_mr4_reg_t; // use for mr4 & mr5
typedef struct {
//uint8 parallel_detect_fault; // 4
uint8 lp_np_able; // 3
//uint8 np_able; // 2
//uint8 lch_page_rx; // 1
uint8 lp_autoneg_able; // 0
} tcphy_mr6_reg_t; // use for mr6
typedef struct {
uint8 slicer_err_thd; // 15:11
uint16 err_over_cnt; // 10:0
uint16 err_over_cnt_prev; // 10:0
} tcphy_l0r25_reg_t;
typedef struct {
uint8 lch_sig_detect;
uint8 lch_rx_linkpulse;
uint8 lch_linkup_100;
uint8 lch_linkup_10;
uint8 lch_linkup_mdi;
uint8 lch_linkup_mdix;
uint8 lch_descr_lock;
uint8 mdix_status;
uint8 tx_amp_save;
uint8 final_duplex;
uint8 final_speed;
uint8 final_link;
} tcphy_l0r28_reg_t;
tcphy_mr0_reg_t mr0;
tcphy_mr4_reg_t mr4;
tcphy_mr4_reg_t mr5;
tcphy_mr6_reg_t mr6;
tcphy_l0r28_reg_t mr28; // L0R28
// for multiple phy support
tcphy_mr1_reg_t Nmr1[TCPHY_PORTNUM];
tcphy_l0r25_reg_t Nmr25[TCPHY_PORTNUM];
// type for register settings
typedef struct cfg_data_s{
uint32 reg_num;
uint32 val;
}cfg_data_t;
typedef struct cfg_cL45data_s
{
uint32 dev_num;
uint32 reg_num;
uint32 val;
}cfg_cl45data_t;
typedef struct cfg_trdata_s
{
char reg_typ[10];
uint32 reg_num;
uint32 val;
}cfg_trdata_t;
#ifdef TC2206_SUPPORT
#define TC2104MC_PHY_INIT_GDATA_LEN 10
#define TC2104MC_PHY_INIT_LDATA_LEN 5
#define TC2104MC_PHY_INIT_SET_NUM 1
typedef struct tc2104mc_cfg_data_s{
char name[10];
cfg_data_t gdata[TC2104MC_PHY_INIT_GDATA_LEN];
cfg_data_t ldata[TC2104MC_PHY_INIT_LDATA_LEN];
}tc2104mc_cfg_data_t;
// G0R22b11: tx10_eee_mode
// L0R30b11: bypass_pd_wakeup
// L0R30b3: pd_analog_wakeup
//const uint16 tc2104mc_L0R30_PDWAKEUP_ON = 0x8808;
const uint16 tc2104mc_L0R30_PDWAKEUP_OFF = 0x8800;
const uint16 tc2104mc_L0R30_PDWAKEUP_AUTO = 0x8000;
#define tc2104mc_FixTrcyStep_L1R18_default 0x240a // trgap=16T, trstep=4 --> 1/4
#define tc2104mc_G3R16_default 0x0018
#define tc2104mc_L0R25_default 0xa000
tc2104mc_cfg_data_t tc2104mc_cfg[TC2104MC_PHY_INIT_SET_NUM]={
{{"C11.5"},
{ {31,0x3000},{16,tc2104mc_G3R16_default},{19,0x4f00},{21,0x0706},{22,0x00f4},
{31,0x1000},{20,0x8914},{24,0x0030},{25,0x0018}
//{31,0x0000},{22,0x0664},
},
{ {31,0x9000},{16,0x0000},{18,tc2104mc_FixTrcyStep_L1R18_default},
{31,0x8000},{25,tc2104mc_L0R25_default}
}
},
};
void tc2104meCfgLoad(uint8 idx, uint8 doPerPort_flag, uint8 port_num);
#endif
// note: The value of L0R25 and G3R16 are also used in tc2104mcInitialRegFlag()
uint32
tcPhyReadReg(uint8 port_num, uint8 reg_num)
{
uint32 val, val_r31;
uint32 phyAddr = mac_p->enetPhyAddr + port_num;
// page to L0
val_r31 = tcMiiStationRead(phyAddr, 31);
tcMiiStationWrite(phyAddr, 31, 0x8000);
// read reg
val = tcMiiStationRead(phyAddr, reg_num);
// restore page if necessary
if (val_r31 != 0x8000) {
tcMiiStationWrite(phyAddr, 31, val_r31);
}
// update variables
switch(reg_num){
case 0:
mr0.main_reset = (val>>15)&0x00000001;
mr0.force_speed = (val>>13)&0x00000001;
mr0.autoneg_enable = (val>>12)&0x00000001;
mr0.powerdown = (val>>11)&0x00000001;
mr0.force_duplex = (val>>8)&0x00000001;
break;
case 1:
//mr1.autoneg_complete = (val>>5)&0x00000001;
//mr1_link_status_reg = val;
//mr1.value = val;
//mr1.link_status_prev = mr1.link_status;
//mr1.link_status = (val>>2)&0x00000001;
Nmr1[port_num].value = val;
Nmr1[port_num].link_status_prev = Nmr1[port_num].link_status;
Nmr1[port_num].link_status = (val>>2)&0x00000001;
break;
case 4:
mr4.able100F = (val>>8)&0x0001;
mr4.able100H = (val>>7)&0x0001;
mr4.able10F = (val>>6)&0x0001;
mr4.able10H = (val>>5)&0x0001;
mr4.selector_field = (val)&0x001f;
break;
case 5:
mr5.able100F = (val>>8)&0x0001;
mr5.able100H = (val>>7)&0x0001;
mr5.able10F = (val>>6)&0x0001;
mr5.able10H = (val>>5)&0x0001;
mr5.selector_field = (val)&0x001f;
break;
case 6:
mr6.lp_np_able = (val>>3)&0x0001;
mr6.lp_autoneg_able = (val)&0x0001;
break;
case 25:
//mr25.slicer_err_thd = (val >> 11) & 0x0000001f;
//mr25.err_over_cnt_prev = mr25.err_over_cnt;
//mr25.err_over_cnt = (val & 0x0000007ff);
Nmr25[port_num].err_over_cnt_prev = Nmr25[port_num].err_over_cnt;
Nmr25[port_num].err_over_cnt = (val & 0x0000007ff);
break;
case 28:
mr28.lch_sig_detect = (val>>15)&0x0001;
mr28.lch_rx_linkpulse= (val>>14)&0x0001;
mr28.lch_linkup_100 = (val>>13)&0x0001;
mr28.lch_linkup_10 = (val>>12)&0x0001;
mr28.lch_linkup_mdi = (val>>11)&0x0001; // after LEM
mr28.lch_linkup_mdix = (val>>10)&0x0001; // after LEM
mr28.lch_descr_lock = (val>>9)&0x0001; // after LEM
mr28.mdix_status = (val>>5)&0x0001; /* {0:mdi,1:mdix} */
mr28.tx_amp_save = (val>>3)&0x0003; /* 0:100%, 1:90%, 2:80%, 3:70% */
mr28.final_duplex = (val>>2)&0x0001; /* {0:half-duplex, 1:full-duplex} */
mr28.final_speed = (val>>1)&0x0001; /* {0:10, 1:100} */
mr28.final_link = (val)&0x0001; /* {0:linkdown, 1:linkup} */
break;
default:
break;
}
return (val);
}
// read Global Reg
uint32
tcPhyReadGReg(uint8 port_num,uint8 page_num,uint8 reg_num){
uint32 val, val_r31;
uint32 phyAddr = mac_p->enetPhyAddr + port_num;
uint32 pageAddr = (page_num<<12);
// page to L0
val_r31 = tcMiiStationRead(phyAddr, 31);
tcMiiStationWrite(phyAddr, 31, pageAddr);
val = tcMiiStationRead(phyAddr, reg_num);
// restore page if necessary
if (val_r31 != pageAddr) {
tcMiiStationWrite(phyAddr, 31, val_r31);
}
return val;
}
void
tcPhyWriteGReg(uint8 port_num,uint8 page_num,uint8 reg_num,uint32 reg_data){
uint32 val_r31;
uint32 phyAddr = mac_p->enetPhyAddr + port_num;
uint32 pageAddr = (page_num<<12);
// page to L0
val_r31 = tcMiiStationRead(phyAddr, 31);
tcMiiStationWrite(phyAddr, 31, pageAddr);
tcMiiStationWrite(phyAddr, reg_num, reg_data);
// restore page if necessary
if (val_r31 != pageAddr) {
tcMiiStationWrite(phyAddr, 31, val_r31);
}
}
// write Local Reg
void
tcPhyWriteLReg(uint8 port_num,uint8 page_num,uint8 reg_num,uint32 reg_data){
uint32 val_r31;
uint32 phyAddr = mac_p->enetPhyAddr + port_num;
uint32 pageAddr = (page_num<<12)+0x8000;
// page to L0
val_r31 = tcMiiStationRead(phyAddr, 31);
tcMiiStationWrite(phyAddr, 31, pageAddr);
tcMiiStationWrite(phyAddr, reg_num, reg_data);
// restore page if necessary
if (val_r31 != pageAddr) {
tcMiiStationWrite(phyAddr, 31, val_r31);
}
}
#ifdef TC2206_SUPPORT
#define TC2104ME_PHY_INIT_GDATA_LEN 12
#define TC2104ME_PHY_INIT_LDATA_LEN 5
#define TC2104ME_PHY_INIT_PERPDATA_LEN 2
#define TC2104ME_PHY_INIT_SET_NUM 1
typedef struct tc2104me_cfg_data_s{
char name[10];
cfg_data_t gdata[TC2104ME_PHY_INIT_GDATA_LEN];
cfg_data_t ldata[TC2104ME_PHY_INIT_LDATA_LEN];
cfg_data_t perpdata[TC2104ME_PHY_INIT_PERPDATA_LEN]; //per port register setting
}tc2104me_cfg_data_t;
// G0R22b11: tx10_eee_mode
const uint16 tc2104me_G0R22_Tx10AmpSave_ON = 0x0264;
const uint16 tc2104me_G0R22_Tx10AmpSave_OFF = 0x006F;
#define tc2104me_G3R23_default 0x48f0
#define tc2104me_L0R25_default 0xa000
tc2104me_cfg_data_t tc2104me_cfg[TC2104ME_PHY_INIT_SET_NUM]={
//{{"F1.0"},
//{ {31,0x3000},{16,0x001a},{23,0xabf0},{24,0x8801},
// {31,0x1000}
//},
{{"F11.0"},
{ {31,0x3000},{16,0x001a},{17,0x7138},{19,0x0100},{21,0x7386},{23,tc2104me_G3R23_default},{24,0x2201},
{31,0x1000},{25,0x0018},{27,0x0126},
{31,0x0000},{23,0x0006}
},
{ {31,0x9000},{22,0x0140},
{31,0x8000},{04,0x05e1},{25,tc2104me_L0R25_default}
},
{ {31,0x8000},{30,0x8100}
}
},
};
static void
tc2104meLRCfgLoad(uint8 idx, uint8 port_num)
{
int i;
current_idx = idx;
for( i=0; i<TC2104ME_PHY_INIT_LDATA_LEN; i++ ){
tcMiiStationWrite(port_num, tc2104me_cfg[current_idx].ldata[i].reg_num, tc2104me_cfg[current_idx].ldata[i].val );
}
}
static void
tc2104mePerPortCfgLoad(uint8 idx, uint8 port_num)
{
int i;
current_idx = idx;
for( i=0; i<TC2104ME_PHY_INIT_PERPDATA_LEN; i++ ){
tcMiiStationWrite(port_num, tc2104me_cfg[current_idx].perpdata[i].reg_num, tc2104me_cfg[current_idx].perpdata[i].val );
}
}
static void
tc2104meCfgTx10AmpSave(void)
{
uint16 phyAddr = mac_p->enetPhyAddr;
if (cfg_Tx10AmpSave_flag==1){ // enable
tcPhyWriteGReg(phyAddr,0,22,tc2104me_G0R22_Tx10AmpSave_ON);
TCPHYDISP4("tcphy: Tx10AmpSave enable!\r\n");
}
else { // disable
tcPhyWriteGReg(phyAddr,0,22,tc2104me_G0R22_Tx10AmpSave_OFF);
TCPHYDISP4("tcphy: Tx10AmpSave disable!\r\n");
}
}
// 1. loading default register setting in tcPhyInit()
// 2. changing register setting
void
tc2104meCfgLoad(uint8 idx, uint8 doPerPort_flag, uint8 port_num)
{
int pn, i;
uint16 phyAddr;
current_idx = idx;
#ifdef UNH_TEST
cfg_Tx10AmpSave_flag=0;
#endif
// global registers
phyAddr = 0; //mac_p->enetPhyAddr;
for( i=0; i<TC2104ME_PHY_INIT_GDATA_LEN; i++ ){
tcMiiStationWrite(phyAddr, tc2104me_cfg[current_idx].gdata[i].reg_num, tc2104me_cfg[current_idx].gdata[i].val );
}
//
tc2104meCfgTx10AmpSave();
// local registers
if (doPerPort_flag == DO_PER_PORT) {
tc2104meLRCfgLoad(current_idx, port_num);
}
else {
for( pn=0; pn<TCPHY_PORTNUM; pn++){
phyAddr = pn; //mac_p->enetPhyAddr + pn;
tc2104meLRCfgLoad(current_idx, phyAddr);
if ((eco_rev == 0x00) || (eco_rev == 0x01)) { // bypass powerdown rx filter if eco_rev=0
tc2104mePerPortCfgLoad(current_idx,phyAddr);
}
}
}
TCPHYDISP4("tcphy: CfgLoad %s\r\n", tc2104me_cfg[current_idx].name);
#ifdef UNH_TEST
phyAddr = 0;
//tcPhyWriteGReg(phyAddr,0,22,0x0664); // disable tx10_eee_mode
//tcPhyWriteGReg(phyAddr,0,26,0x0012); // disable cr_signal_status_opt
tcPhyWriteGReg(phyAddr,1,22,0x0012); // enable RX_ER extension to Pass PCS pause test
if (doPerPort_flag == DO_PER_PORT) {
tcPhyWriteLReg(port_num,0,30,0x0800); // disable AAPS to avoid varaince lc_max
tcPhyWriteLReg(port_num,0,26,0x1201); // disable Link_Det_Ext function
}
else{
for( pn=0; pn<TCPHY_PORTNUM; pn++){
phyAddr = pn; //mac_p->enetPhyAddr + pn;
tcPhyWriteLReg(phyAddr,0,30,0x0800); // disable AAPS to avoid varaince lc_max
tcPhyWriteLReg(phyAddr,0,26,0x1201); // disable Link_Det_Ext function
}
}
TCPHYDISP4("tcphy: CfgLoad UNH-IOL setting\r\n");
#endif
}
#endif
/************************************************************************
*
* Variables and Functions for tc2105mjSwPatch()
*
*************************************************************************
*/
#ifdef TC2105MJ_SUPPORT
#define TC2105MJ_PHY_INIT_GDATA_LEN 15
#define TC2105MJ_PHY_INIT_LDATA_LEN 1
#define TC2105MJ_PHY_INIT_PERPDATA_LEN 1
#define TC2105MJ_PHY_INIT_SET_NUM 1
#define TC2105MJ_PORTNUM 5
typedef struct tc2105mj_cfg_data_s{
char name[10];
cfg_data_t gdata[TC2105MJ_PHY_INIT_GDATA_LEN];
cfg_data_t ldata[TC2105MJ_PHY_INIT_LDATA_LEN];
cfg_data_t perpdata[TC2105MJ_PHY_INIT_PERPDATA_LEN]; //per port register setting
}tc2105mj_cfg_data_t;
const uint32 tc2105mj_page_sel_addr=31;
// G0R22b11: tx10_eee_mode
const uint16 tc2105mj_G0R22_Tx10AmpSave_ON = 0x0264;
const uint16 tc2105mj_G0R22_Tx10AmpSave_OFF = 0x006F;
const uint16 tc2105mj_L2R16[TC2105MJ_PORTNUM] = {0x0e0e, 0x0c0c, 0x0f0f, 0x1010, 0x0909};
const uint16 tc2105mj_L2R17_A1[TC2105MJ_PORTNUM] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
const uint16 tc2105mj_L2R17_A2[TC2105MJ_PORTNUM] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000};
const uint32 tc2105mj_G4R21_A1 = 0x7160;
const uint32 tc2105mj_G4R21_A2 = 0x7160;
const uint32 tc2105mj_G4R25_A1 = 0x0102;
const uint32 tc2105mj_G4R25_A2 = 0x0212;
const uint32 tc2105mj_G4R29_A1 = 0x8641;
const uint32 tc2105mj_G4R29_A2 = 0x4640;
tc2105mj_cfg_data_t tc2105mj_cfg[TC2105MJ_PHY_INIT_SET_NUM]={
{ {"J8.0"},
{ {31,0x4000}, {16,0xD4CC}, {17,0x7444}, {19,0x0112}, {22,0x10cf}, {26,0x0777},
{31,0x2000}, {21,0x0655}, {22,0x0fd3}, {23,0x003d}, {24,0x096e}, {25,0x0fed}, {26,0x0fc4},
{31,0x1000}, {17,0xe7f8}
},
{ {31,0x9000}
},
{ {31,0x8000}
}
},
};
static int32 tc2105mj_erroversum=0;
void tc2105mjCfgLoad(uint8 idx, uint8 doPerPort_flag, uint8 port_num);
static void tc2105mjLRCfgLoad(uint8 idx, uint8 port_num);
static void tc2105mjCfgTx10AmpSave(void);
void tc2105mjGRCfgCheck(void);
void tc2105mjLRCfgCheck(uint8 port_num);
void tc2105mjCfgCheck(void);
int32 tc2105mjReadProbe(uint8 port_num, uint8 mode);
void tc2105mjSwPatch(void);
// 1. loading default register setting in tcPhyInit()
// 2. changing register setting
void
tc2105mjCfgLoad(uint8 idx, uint8 doPerPort_flag, uint8 port_num)
{
int pn,i;
uint16 phyAddr;
current_idx = idx;
uint32 rev = 0x00;
// global registers
phyAddr = mac_p->enetPhyAddr;
for( i=0; i<TC2105MJ_PHY_INIT_GDATA_LEN; i++ ){
tcMiiStationWrite(phyAddr, tc2105mj_cfg[current_idx].gdata[i].reg_num, tc2105mj_cfg[current_idx].gdata[i].val );
}
//
tc2105mjCfgTx10AmpSave();
// local registers
if (doPerPort_flag == DO_PER_PORT) {
tc2105mjLRCfgLoad(current_idx, port_num);
}
else {
for( pn=0; pn<TC2105MJ_PORTNUM; pn++){
phyAddr = pn; //mac_p->enetPhyAddr + pn;
tc2105mjLRCfgLoad(current_idx, phyAddr);
}
}
rev = tcMiiStationRead(0, 31);
rev &= (0x0f);
// load revision-related settings
if (rev == 0x00) { //rev=A1
tcPhyWriteGReg(phyAddr,4,21,tc2105mj_G4R21_A1);
tcPhyWriteGReg(phyAddr,4,25,tc2105mj_G4R25_A1);
tcPhyWriteGReg(phyAddr,4,29,tc2105mj_G4R29_A1);
}
else { //rev=A2
tcPhyWriteGReg(phyAddr,4,21,tc2105mj_G4R21_A2);
tcPhyWriteGReg(phyAddr,4,25,tc2105mj_G4R25_A2);
tcPhyWriteGReg(phyAddr,4,29,tc2105mj_G4R29_A2);
}
TCPHYDISP4("tcphy: CfgLoad %s\r\n", tc2105mj_cfg[current_idx].name);
}
static void
tc2105mjLRCfgLoad(uint8 idx, uint8 port_num)
{
int i;
uint32 rev = 0x00;
current_idx = idx;
for( i=0; i<TC2105MJ_PHY_INIT_LDATA_LEN; i++ ){
tcMiiStationWrite(port_num, tc2105mj_cfg[current_idx].ldata[i].reg_num, tc2105mj_cfg[current_idx].ldata[i].val );
}
tcPhyWriteLReg(port_num,2,16,tc2105mj_L2R16[port_num]);
rev = tcMiiStationRead(port_num, 31);
rev &= (0x0f);
if (rev == 0x00) { //rev=A1
tcPhyWriteLReg(port_num,2,17,tc2105mj_L2R17_A1[port_num]);
}
else { //rev=A2
tcPhyWriteLReg(port_num,2,17,tc2105mj_L2R17_A2[port_num]);
}
}
static void
tc2105mjCfgTx10AmpSave(void)
{
uint16 phyAddr = mac_p->enetPhyAddr;
if (cfg_Tx10AmpSave_flag==1){ // enable
tcPhyWriteGReg(phyAddr,0,22,tc2105mj_G0R22_Tx10AmpSave_ON);
TCPHYDISP4("tcphy: Tx10AmpSave enable!\r\n");
}
else { // disable
tcPhyWriteGReg(phyAddr,0,22,tc2105mj_G0R22_Tx10AmpSave_OFF);
TCPHYDISP4("tcphy: Tx10AmpSave disable!\r\n");
}
}
#endif
bool
tc2104mcInitialRegFlag(void)
{
bool initial_value_flag=1; // default: correct initial value
uint8 pn;
uint16 rval;
// check G3R16
rval = tcPhyReadGReg(0,3,16);
if (rval != 0x0018){
initial_value_flag=0; // wrong initial value
}
// check L0R25
for(pn=0;pn<TCPHY_PORTNUM;pn++){
rval = tcPhyReadReg(pn,25);
if ((rval&0xf000)!=0xc000){
initial_value_flag=0; // wrong initial value
}
}
return (initial_value_flag);
}
bool getTcPhyInitialRegFlag(void){
if (!sw_patch_flag)
return 0;
switch (tcPhyVer) {
#ifdef TC2104MC_SUPPORT
case tcPhyVer_2104mc: // 2206
return (tc2104mcInitialRegFlag());
break;
#endif
}
return 0;
}
#ifdef TC2206_SUPPORT
static void
tc2104mcCfgTx10AmpSave(void)
{
uint16 phyAddr = mac_p->enetPhyAddr;
if (cfg_Tx10AmpSave_flag==ENABLE){
tcPhyWriteGReg(phyAddr,0,22,tc2104mc_G0R22_Tx10AmpSave_ON);
TCPHYDISP4("tcphy: Tx10AmpSave ENABLE!\r\n");
}
else { // DISABLE
tcPhyWriteGReg(phyAddr,0,22,tc2104mc_G0R22_Tx10AmpSave_OFF);
TCPHYDISP4("tcphy: Tx10AmpSave DISABLE!\r\n");
}
}
const uint32 tc2104mc_G3R17_B1 = 0x4683;
const uint32 tc2104mc_G3R20_A1 = 0x0f30;
const uint32 tc2104mc_G3R20_B1 = 0x0e30;
static void
tc2104mcLRCfgLoad(uint8 idx, uint8 port_num)
{
int i;
current_idx = idx;
for( i=0; i<TC2104MC_PHY_INIT_LDATA_LEN; i++ ){
tcMiiStationWrite(port_num, tc2104mc_cfg[current_idx].ldata[i].reg_num, tc2104mc_cfg[current_idx].ldata[i].val );
}
if (sw_FixPdWakeup_flag) {
tcPhyWriteLReg(port_num,0,30,tc2104mc_L0R30_PDWAKEUP_OFF);
TCPHYDISP5("tcphy[%d]: PdWakeup OFF mode!\r\n",port_num);
}
}
// 1. loading default register setting in tcPhyInit()
// 2. changing register setting
void
tc2104mcCfgLoad(uint8 idx, uint8 doPerPort_flag, uint8 port_num)
{
int pn, i;
uint16 phyAddr;
//uint32 eco_rev;
current_idx = idx;
#ifdef UNH_TEST
sw_ErrOverMonitor_flag=0;
sw_FixPdWakeup_flag=0;
cfg_Tx10AmpSave_flag=0;
tc2104mc_FixNonAnPairSwap_flag=0;
#endif
// global registers
phyAddr = 0; //mac_p->enetPhyAddr;
//eco_rev = tcMiiStationRead(phyAddr, 31);
//eco_rev &= (0x0f);
if (eco_rev != 0x00) { // turn off PdWakeup patched if eco_rev>0
sw_FixPdWakeup_flag=0;
}
for( i=0; i<TC2104MC_PHY_INIT_GDATA_LEN; i++ ){
tcMiiStationWrite(phyAddr, tc2104mc_cfg[current_idx].gdata[i].reg_num, tc2104mc_cfg[current_idx].gdata[i].val );
}
//
tc2104mcCfgTx10AmpSave();
// local registers
if (doPerPort_flag == DO_PER_PORT) {
tc2104mcLRCfgLoad(current_idx, port_num);
}
else {
for( pn=0; pn<TCPHY_PORTNUM; pn++){
phyAddr = pn; //mac_p->enetPhyAddr + pn;
tc2104mcLRCfgLoad(current_idx, phyAddr);
}
}
// load revision-related settings
if (eco_rev == 0x00) { //rev=A1
tcPhyWriteGReg(phyAddr,3,20,tc2104mc_G3R20_A1);
}
else { //rev=B1
tcPhyWriteGReg(phyAddr,3,17,tc2104mc_G3R17_B1);
tcPhyWriteGReg(phyAddr,3,20,tc2104mc_G3R20_B1);
}
TCPHYDISP4("tcphy: CfgLoad %s\r\n", tc2104mc_cfg[current_idx].name);
#ifdef UNH_TEST
phyAddr = 0;
//tcPhyWriteGReg(phyAddr,0,22,0x0664); // disable tx10_eee_mode
//tcPhyWriteGReg(phyAddr,0,26,0x0012); // disable cr_signal_status_opt
tcPhyWriteGReg(phyAddr,1,22,0x0012); // enable RX_ER extension to Pass PCS pause test
if (doPerPort_flag == DO_PER_PORT) {
tcPhyWriteLReg(port_num,0,30,0x0800); // disable AAPS to avoid varaince lc_max
tcPhyWriteLReg(port_num,0,26,0x1201); // disable Link_Det_Ext function
}
else{
for( pn=0; pn<TCPHY_PORTNUM; pn++){
phyAddr = pn; //mac_p->enetPhyAddr + pn;
tcPhyWriteLReg(phyAddr,0,30,0x0800); // disable AAPS to avoid varaince lc_max
tcPhyWriteLReg(phyAddr,0,26,0x1201); // disable Link_Det_Ext function
}
}
TCPHYDISP4("tcphy: CfgLoad UNH-IOL setting\r\n");
#endif
}
#endif
#ifdef TC2102ME_SUPPORT
static uint8 sw_FixUp2DownFast_flag = 1;
#define TC2102ME_PHY_INIT_GDATA_LEN 9
#define TC2102ME_PHY_INIT_LDATA_LEN 7
#define TC2102ME_PHY_INIT_SET_NUM 1
typedef struct tc2102me_cfg_data_s{
char name[10];
cfg_data_t gdata[TC2102ME_PHY_INIT_GDATA_LEN];
cfg_data_t ldata[TC2102ME_PHY_INIT_LDATA_LEN];
}tc2102me_cfg_data_t;
#define tc2102me_G3R17_default 0x7238
#define tc2102me_L0R25_default 0xa000
const uint16 tc2102me_G0R22_Tx10AmpSave_ON = 0x0264;
const uint16 tc2102me_G0R22_Tx10AmpSave_OFF = 0x006F;
tc2102me_cfg_data_t tc2102me_cfg[TC2102ME_PHY_INIT_SET_NUM]={
{{"G3.2"},
{ {31,0x3000},{17,tc2102me_G3R17_default},{21,0x7107},
{31,0x1000},{20,0x0914},{25,0x0018},{27,0x0125},
{31,0x0000},{23,0x0006}
},
{ {31,0x9000},{16,0x0001},{22,0x0140},{23,0x0400},{24,0x4447},
{31,0x8000},{25,tc2102me_L0R25_default}
}
},
};
static void
tc2102meLRCfgLoad(uint8 idx, uint8 port_num)
{
int i;
current_idx = idx;
for( i=0; i<TC2102ME_PHY_INIT_LDATA_LEN; i++ ){
tcMiiStationWrite(port_num, tc2102me_cfg[current_idx].ldata[i].reg_num, tc2102me_cfg[current_idx].ldata[i].val );
}
}
static void
tc2102meCfgTx10AmpSave(void)
{
uint16 phyAddr = mac_p->enetPhyAddr;
if (cfg_Tx10AmpSave_flag==1){ // enable
tcPhyWriteGReg(phyAddr,0,22,tc2102me_G0R22_Tx10AmpSave_ON);
TCPHYDISP4("tcphy: Tx10AmpSave enable!\r\n");
}
else { // disable
tcPhyWriteGReg(phyAddr,0,22,tc2102me_G0R22_Tx10AmpSave_OFF);
TCPHYDISP4("tcphy: Tx10AmpSave disable!\r\n");
}
}
// 1. loading default register setting in tcPhyInit()
// 2. changing register setting
void
tc2102meCfgLoad(uint8 idx)
{
int i;
uint16 phyAddr=mac_p->enetPhyAddr;
current_idx = idx;
// global registers
//phyAddr = idx; //mac_p->enetPhyAddr;
for( i=0; i<TC2102ME_PHY_INIT_GDATA_LEN; i++ ){
tcMiiStationWrite(phyAddr, tc2102me_cfg[current_idx].gdata[i].reg_num, tc2102me_cfg[current_idx].gdata[i].val );
}
//
tc2102meCfgTx10AmpSave();
// local registers
tc2102meLRCfgLoad(current_idx, phyAddr);
TCPHYDISP4("tcphy: CfgLoad %s\r\n", tc2102me_cfg[current_idx].name);
#ifdef UNH_TEST
//tcPhyWriteGReg(phyAddr,0,22,0x0664); // disable tx10_eee_mode
//tcPhyWriteGReg(phyAddr,0,26,0x0012); // disable cr_signal_status_opt
sw_FixUp2DownFast_flag= 0;
cfg_Tx10AmpSave_flag=0; // disable tx10_eee_mode
tc2102meCfgTx10AmpSave();
tcPhyWriteGReg(phyAddr,1,22,0x0012); // enable RX_ER extension to Pass PCS pause test
tcPhyWriteLReg(phyAddr,0,30,0x0800); // disable AAPS to avoid varaince lc_max
tcPhyWriteLReg(phyAddr,0,26,0x1200); // disable Link_Det_Ext function
TCPHYDISP4("tcphy: CfgLoad UNH-IOL setting\r\n");
#endif
}
#endif
#ifdef TC2031_SUPPORT
static uint8 config_ldps = 0; // off, on
#define TC2031_PHY_INIT_DATA_LEN 18
#define TC2031_PHY_INIT_SET_NUM 3
typedef struct tc2031_cfg_data_s{
char name[10];
cfg_data_t data[TC2031_PHY_INIT_DATA_LEN];
}tc2031_cfg_data_t;
tc2031_cfg_data_t tc2031_cfg[TC2031_PHY_INIT_SET_NUM]={
{{"R38.23"},{{31,0x0000}, { 0,0x3c1f}, { 1,0x524a}, { 2,0x625a}, { 3,0xa166},
{ 4,0x0114}, {11,0x9007}, {17,0x0e10}, {18,0x42ca}, {20,0x7988},
{23,0x140c}, {25,0x6000}, {26,0x0001}, {28,0x4310},
{31,0x8000}, {21,0x0068}, {29,0xf300}, {19,0x00e0}}}, // default setting
{{"R38b"}, { {31,0x0000}, { 0,0x3c1f}, { 1,0x524a}, { 2,0x625a}, { 3,0xa166},
{ 4,0x0914}, {11,0x9007}, {17,0x0e10}, {18,0x42ca}, {20,0x7988},
{23,0x140c}, {25,0x6000}, {26,0x0001}, {28,0x4310},
{31,0x8000}, {21,0x0068}, {29,0xf300}, {19,0x00e0}}}, // link-down & 100Mbps only
{{"R38c"}, { {31,0x0000}, { 0,0x3c1f}, { 1,0x524a}, { 2,0x625a}, { 3,0xa166},
{ 4,0x0114}, {11,0xa007}, {17,0x0e10}, {18,0x42ca}, {20,0x7988},
{23,0x140c}, {25,0x6000}, {26,0x0001}, {28,0x0310},
{31,0x8000}, {21,0x0068}, {29,0xf300}, {19,0x00e0}}}, // 10Mbps only
};
// 1. loading default register setting in tcPhyInit()
// 2. changing register setting
static void
tc2031CfgLoad(uint8 idx)
{
int i;
current_idx=idx;
for( i=0; i<TC2031_PHY_INIT_DATA_LEN; i++ ){
miiStationWrite(mac_p, tc2031_cfg[current_idx].data[i].reg_num, tc2031_cfg[current_idx].data[i].val );
}
//TCPHYDISP2("tcphy CfgLoad %s\r\n", tc2031_cfg[current_idx].name);
}
void
tc2031LdpsSet(uint8 mode) // link-down power-saving
{
miiStationWrite( mac_p, 31, 0x0000);
if(mode==1){ // on
miiStationWrite( mac_p, 22, 0x066f);
}
else{ // off
miiStationWrite( mac_p, 22, 0x0064);
}
miiStationWrite( mac_p, 31, 0x8000);
}
#endif
#ifdef TC2101ME_SUPPORT
static uint8 tc2101me_FixNonAnPairSwap_flag = 1;// default: enable
#define TC2101ME_PHY_INIT_DATA_LEN 13
#define TC2101ME_PHY_INIT_SET_NUM 1
typedef struct tc2101me_cfg_data_s{
char name[10];
cfg_data_t data[TC2101ME_PHY_INIT_DATA_LEN];
}tc2101me_cfg_data_t;
tc2101me_cfg_data_t tc2101me_cfg[TC2101ME_PHY_INIT_SET_NUM]={
{{"E5.2"},
{{31,0x3000}, {17,0x7238}, {21,0x7247},
{31,0x1000}, {20,0x0914}, {25,0x0018}, {27,0x0125},
{31,0x0000}, {23,0x0006},
{31,0x9000}, {22,0x0140}, {23,0x0400}, {24,0x4447}}},
};
const uint16 tc2101me_G0R22_Tx10AmpSave_ON = 0x0264;
const uint16 tc2101me_G0R22_Tx10AmpSave_OFF = 0x0064;
static void
tc2101meCfgTx10AmpSave(void)
{
if (cfg_Tx10AmpSave_flag==1){ // enable
tcPhyWriteGReg(0,0,22,tc2101me_G0R22_Tx10AmpSave_ON);
TCPHYDISP4("tcphy: Tx10AmpSave enable!\r\n");
}
else { // disable
tcPhyWriteGReg(0,0,22,tc2101me_G0R22_Tx10AmpSave_OFF);
TCPHYDISP4("tcphy: Tx10AmpSave disable!\r\n");
}
}
// 1. loading default register setting in tcPhyInit()
// 2. changing register setting
static void
tc2101meCfgLoad(uint8 idx)
{
int i;
current_idx = idx;
for( i=0; i<TC2101ME_PHY_INIT_DATA_LEN; i++ ){
miiStationWrite( mac_p, tc2101me_cfg[current_idx].data[i].reg_num, tc2101me_cfg[current_idx].data[i].val );
}
//TCPHYDISP3("tcphy: CfgLoad %s\r\n", tc2101me_cfg[current_idx].name);
//TCPHYDISP3("tcphy: Cfg Ver: %s\r\n", tc2101me_cfg[current_idx].name);
#if defined UNH_TEST
sw_ErrOverMonitor_flag=0;
cfg_Tx10AmpSave_flag=0; // disable tx10_eee_mode
tc2101me_FixNonAnPairSwap_flag=0;
sw_FixUp2DownFast_flag=0;
tc2101meCfgTx10AmpSave();
tcPhyWriteGReg(0,1,22,0x0012); // enable RX_ER extension to Pass PCS pause test
tcPhyWriteLReg(0,0,30,0x0000); // disable AAPS to avoid varaince lc_max
tcPhyWriteLReg(0,0,26,0x1201); // disable Link_Det_Ext function
TCPHYDISP4("tcphy: CfgLoad UNH-IOL setting\r\n");
#endif
}
#endif
#ifdef TC2101MB_SUPPORT
//*** TC2101MB register settting ***//
#define TC2101MB_PHY_INIT_DATA_LEN 29
#define TC2101MB_PHY_INIT_SET_NUM 1
typedef struct tc2101mb_cfg_data_s{
char name[10];
cfg_data_t data[TC2101MB_PHY_INIT_DATA_LEN];
}tc2101mb_cfg_data_t;
#define tc2101mb_FixFalseSquelch_G0R16_default 0x040F
#define tc2101mb_FixTrcyStep_L1R18_default 0x240a // trgap=16T, trstep=4 --> 1/4
tc2101mb_cfg_data_t tc2101mb_cfg[TC2101MB_PHY_INIT_SET_NUM]={
{{"B19.0"},
{{31,0x3000}, {17,0x06B1}, {19,0x0100}, {20,0x0730}, {21,0x0705},
{31,0x2000}, {29,0x1e1c},
{31,0x1000}, {19,0x6968}, {20,0x0914}, {24,0x0030}, {27,0x7015},
{31,0x0000}, {16,tc2101mb_FixFalseSquelch_G0R16_default},
{17,0x0c0c}, {18,0x400a}, {20,0x0a08},
{22,0x066f}, {23,0x0004}, {26,0x0002},
{31,0x9000}, {16,0x0002}, {18,tc2101mb_FixTrcyStep_L1R18_default},
{21,0x0010},{22,0x0000},
{31,0x8000}, {21,0x00c4}, {25,0xa000}, {26,0x1601}}},
};
// 1. loading default register setting in tcPhyInit()
// 2. changing register setting
static void
tc2101mbCfgLoad(uint8 idx)
{
int i;
current_idx = idx;
for( i=0; i<TC2101MB_PHY_INIT_DATA_LEN; i++ ){
miiStationWrite( mac_p, tc2101mb_cfg[current_idx].data[i].reg_num, tc2101mb_cfg[current_idx].data[i].val );
}
#ifdef TCPHY_PHY2PHY
tc2101mbCfgPhy2Phy();
#endif
}
#endif
/************************************************************************
*
* Variables and Functions for 7530 GE PHY (ID=0x9412)
*
**************************************************************************/
#define MTPHY_PORTNUM 5
#define MT7530_PORTNUM 5
#define MT7530_PHY_INIT_LDATA_LEN 1
#define MT7530_PHY_INIT_PERPDATA_LEN 0
#define MT7530_PHY_INIT_SET_NUM 1
#define MT7530_PHY_INIT_CL45_GDATA_LEN 1 // allen_20150206
#define MT7530_PHY_INIT_CL45_LDATA_LEN 1 // allen_20150206
#define MT7530_PHY_INIT_CL45_PERPDATA_LEN 0
#define MT7530_PHY_INIT_CL45_SET_NUM 1
#define MT7530_PHY_INIT_TR_LDATA_LEN 0
#define MT7530_PHY_INIT_TR_PERPDATA_LEN 0
#define MT7530_PHY_INIT_TR_SET_NUM 1
typedef struct mt7530_cfg_data_s
{
char name[10];
cfg_data_t ldata[MT7530_PHY_INIT_LDATA_LEN];
cfg_data_t perpdata[MT7530_PHY_INIT_PERPDATA_LEN]; //per port register setting
}mt7530_cfg_data_t;
typedef struct mt7530_cfg_cl45data_s
{
cfg_cl45data_t gdata[MT7530_PHY_INIT_CL45_GDATA_LEN];
cfg_cl45data_t ldata[MT7530_PHY_INIT_CL45_LDATA_LEN];
cfg_cl45data_t perpdata[MT7530_PHY_INIT_CL45_PERPDATA_LEN]; //per port register setting
}mt7530_cfg_cl45data_t;
typedef struct mt7530_cfg_trdata_s
{
cfg_trdata_t ldata[MT7530_PHY_INIT_TR_LDATA_LEN];
cfg_trdata_t perpdata[MT7530_PHY_INIT_PERPDATA_LEN]; //per port register setting
}mt7530_cfg_trdata_t;
const uint32 mt7530_page_sel_addr = 31;
mt7530_cfg_data_t mt7530_cfg[MT7530_PHY_INIT_SET_NUM] =
{
{
{"E4.0"},
//local data
{ //{0x00,0x4000}
//for reference {0x1f,0x2A30},{0x0d,0x1002}, //TEST 0D//force txfil value at test page
#if 0 //E2 setting
{0x1f,0x0003},{0x15,0x206a},{0x1a,0x0604},{0x1f,0x0000}
#endif
{0x09, 0x1e00} // master mode
},
//per-port data
{
}
},
};
mt7530_cfg_cl45data_t mt7530_cfg_cl45[MT7530_PHY_INIT_CL45_SET_NUM]=
{
{ //globle data
{
//for reference {0x1f,0x0032,0x0C24},// disable lpi_1000_pwr_seq_en
#if 0 //E2 setting
{0x1f, 0x0103, 0x0020}, // invert clock of DFF for phase-mux data input //CML_20130223
{0x1f, 0x0104, 0x0608}, // disable PLL //CML_20130321
{0x1f, 0x0104, 0x2608}, // enable PLL //CML_20130321
{0x1f, 0x0416, 0x0047}, // mcc_acc_ref_th setting //CML_20130327
{0x1f, 0x027c, 0x0c0c}, // for 10BASE-T amplitude //CML_20130327
{0x1f, 0x027b, 0x1177} //disable 10BASE-TE
#endif
{0x1f,0x0417,0x7775} // allen_20150206
},
//local data
{
//for reference {0x1e,0x003D,0x0800},//modify Pair A DC for 100M
//{0x1e,0x00a6,0x0000} // disable TX power control //CML_20130321 //CML_20130327
{0x1e,0x00a6,0x0350}
#if 0 // keep E1 setting //CML_20130401
{0x1e,0x0001,0x0158}, // for 100BASE-T TX //CML_20130327
{0x1e,0x0003,0x0043}, // for 100BASE-T TX //CML_20130327
{0x1e,0x0004,0x0207}, // for 100BASE-T TX //CML_20130327
{0x1e,0x0007,0x0357}, // for 100BASE-T TX //CML_20130327
{0x1e,0x0008,0x02f0}, // for 100BASE-T TX //CML_20130327
{0x1e,0x000a,0x0006} // for 100BASE-T TX //CML_20130327
#endif //CML_20130401
#if 0 //E2 setting
{0x1e,0x0012,0x7210}, // for 100BASE-T TX //CML_20130401
{0x1e,0x00a6,0x0300}, //disable power saving
{0x1e,0x0120,0x8d0d},
{0x1e,0x0122,0xffa0},
#endif
},
//per-port data
{
}
},
};
mt7530_cfg_trdata_t mt7530_cfg_tr[MT7530_PHY_INIT_TR_SET_NUM]=
{
{ //local data
{
//for reference {"PMA",0x20,0x0700},
#if 0 //E2 setting
{"DSPF",0x0010,0x005000},
{"DSPF",0x000e,0x800008}
#endif
},
//per-port data
{ //{"PMA",0x20,0x0700}
}
},
};
void tcMiiExtStationWrite_CL22(uint32 port_num,uint32 dev_num,uint32 reg_num,uint32 reg_data)
{
const uint16 MMD_Control_register=0xD;
const uint16 MMD_addr_data_register=0xE;
const uint16 page_reg=31;
tcMiiStationWrite(port_num, page_reg, 0x00); //switch to main page
tcMiiStationWrite(port_num, MMD_Control_register, (0<<14)+dev_num);
tcMiiStationWrite(port_num, MMD_addr_data_register, reg_num);
tcMiiStationWrite(port_num, MMD_Control_register, (1<<14)+dev_num);
tcMiiStationWrite(port_num, MMD_addr_data_register, reg_data);
//printf("* doPhyMMDWrite_CL22=> phyaddr=%d, dev_addr=%d, data_addr=0x%04lX , value=0x%04lX\r\n", port_num, dev_num, reg_num, reg_data);
}
void mtEMiiRegWrite(uint32 port_num, uint32 dev_num, uint32 reg_num, uint32 reg_data)
{
tcMiiExtStationWrite_CL22( port_num, dev_num, reg_num, reg_data);
}
void mt7530GePhyCfgLoad(uint8 idx, uint8 doPerPort_flag, uint8 port_num)
{
int pn, i;
uint16 phyAddr;
current_idx = idx;
// global registers
phyAddr = port_num; //ephy_addr_base;
for(pn=0; pn<MTPHY_PORTNUM; pn++)
{
phyAddr = pn; //ephy_addr_base + pn;
for( i=0; i<MT7530_PHY_INIT_CL45_GDATA_LEN; i++ )
{
mtEMiiRegWrite(phyAddr, mt7530_cfg_cl45[current_idx].gdata[i].dev_num, mt7530_cfg_cl45[current_idx].gdata[i].reg_num, mt7530_cfg_cl45[current_idx].gdata[i].val);
}
for( i=0; i<MT7530_PHY_INIT_CL45_LDATA_LEN; i++ )
{
mtEMiiRegWrite(phyAddr, mt7530_cfg_cl45[current_idx].ldata[i].dev_num, mt7530_cfg_cl45[current_idx].ldata[i].reg_num, mt7530_cfg_cl45[current_idx].ldata[i].val);
}
for( i=0; i<MT7530_PHY_INIT_LDATA_LEN; i++ )
{
tcMiiStationWrite(phyAddr, mt7530_cfg[current_idx].ldata[i].reg_num, mt7530_cfg[current_idx].ldata[i].val);
}
for( i=0; i<MT7530_PHY_INIT_TR_LDATA_LEN; i++ )
{
mtPhyMiiWrite_TrDbg( phyAddr, mt7530_cfg_tr[current_idx].ldata[i].reg_typ, mt7530_cfg_tr[current_idx].ldata[i].reg_num, mt7530_cfg_tr[current_idx].ldata[i].val,0);
}
//mtEMiiRegWrite(phyAddr, 0x1e, 0x12, mt7530_dev1Ehreg12h_A2[phyAddr]); // for 100BASE-T TX //CML_20130327 //CML_20130401
}
//printf("mtphy: CfgLoad %s\r\n", mt7530_cfg[current_idx].name);
}
/************************************************************************
*
* Variables and Functions for 7512 FE PHY (ID=0x9412, R15(0xf)[13]=0)
*
**************************************************************************/
#define MT7512FE_PHY_INIT_GDATA_LEN 5
#define MT7512FE_PHY_INIT_LDATA_LEN 9
#define MT7512FE_PHY_INIT_PERPDATA_LEN 1
#define MT7512FE_PHY_INIT_SET_NUM 1
#define MT7512FE_PORTNUM 4
typedef struct mt7512FE_cfg_data_s
{
char name[10];
cfg_data_t gdata[MT7512FE_PHY_INIT_GDATA_LEN];
cfg_data_t ldata[MT7512FE_PHY_INIT_LDATA_LEN];
cfg_data_t perpdata[MT7512FE_PHY_INIT_PERPDATA_LEN]; //per port register setting
}mt7512FE_cfg_data_t;
const uint32 mt7512FE_page_sel_addr = 31;
const uint16 mt7512FE_G0R22_Tx10AmpSave_ON = 0x0264;
const uint16 mt7512FE_G0R22_Tx10AmpSave_OFF = 0x006F;
const uint16 mt7512FE_L2R16[MT7512FE_PORTNUM] = {0x0606, 0x0606, 0x0606, 0x0606, 0x0606}; // allen_20130926 : FE R offset
const uint16 mt7512FE_L2R17_A1[MT7512FE_PORTNUM] = {0x0003, 0x0003, 0x0003, 0x0003, 0x0003}; // 0002 // allen_20130926 : FE Tx gain
const uint16 mt7512FE_L3R17_A1[MT7512FE_PORTNUM] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; // default_fe_l3r17
mt7512FE_cfg_data_t mt7512FE_cfg[MT7512FE_PHY_INIT_SET_NUM] =
{
{
{"Fe_1.0"},
{ /* global */
/*
{31,0x2000}, // g2
{22,0x0092},
{23,0x007d},
{24,0x09b0},
{25,0x0f6e},
{26,0x0fc4},
*/
{31,0x4000}, // g4 // allen_20130926 : [5:4] reduce cr_a_tx_cmd_cld for 10Base 3th harmonic
//{16,0x00cc}
{26,0x8044}, // g4r26: tx bias (0x8444)
{31,0x5000},
{21,0x00ea}, // g5r21: z2p_ovs
{27,0x02f0} // g5r27: z2n_ovs
},
{ // local
{31,0x8000}, // l0
{30,0x0000}, // l0r30: tx pwd
{31,0x9000}, // l1
{22,0xf000}, // l1r22: for intel82579 EEE IOT
{31,0xa000}, // l2
{22,0x4444}, // l2r22: ps_dri (0x3444)
{28,0x7c44}, // l2r28: ps_op (0x6c44)
{31,0xb000}, // l3
{17,0x0000} //disable EEE
},
{
{31,0x8000}
}
},
};
static void mt7512FECfgTx10AmpSave(void)
{
uint16 phyAddr = ephy_addr_base;
if(cfg_Tx10AmpSave_flag==1)
{ // enable
tcPhyWriteGReg(phyAddr,0,22,mt7512FE_G0R22_Tx10AmpSave_ON);
//printf("tcphy: Tx10AmpSave enable!\r\n");
}
else
{ // disable
tcPhyWriteGReg(phyAddr,0,22,mt7512FE_G0R22_Tx10AmpSave_OFF);
//printf("tcphy: Tx10AmpSave disable!\r\n");
}
}
static void mt7512FELRCfgLoad(uint8 idx, uint8 port_num)
{
int i;
current_idx = idx;
if(ephy_addr_base == 0) // allen_20140911
ephy_addr_base += 8;
for(i=0; i<MT7512FE_PHY_INIT_LDATA_LEN; i++ )
{
tcMiiStationWrite((port_num+ephy_addr_base), mt7512FE_cfg[current_idx].ldata[i].reg_num, mt7512FE_cfg[current_idx].ldata[i].val );
}
/*tcPhyWriteLReg(port_num,2,16,mt7512FE_L2R16[port_num]); // allen_20130926 : FE R offset*/
// load revision-related settings
/*tcPhyWriteLReg(port_num,2,17,mt7512FE_L2R17_A1[port_num]);*/
/*tcPhyWriteLReg(port_num,3,17,mt7512FE_L3R17_A1[port_num]);*/
}
// 1. loading default register setting in EPhyInit()
// 2. changing register setting
void mt7512FECfgLoad(uint8 idx, uint8 doPerPort_flag, uint8 phyaddr)
{
int pn,i;
uint16 port_num;
current_idx = idx;
if(ephy_addr_base == 0)
ephy_addr_base += 8;
//printf("phyaddr = %d \r\n", phyaddr);
for(i=0; i<MT7512FE_PHY_INIT_GDATA_LEN; i++ )
{
tcMiiStationWrite(phyaddr, mt7512FE_cfg[current_idx].gdata[i].reg_num, mt7512FE_cfg[current_idx].gdata[i].val );
}
mt7512FECfgTx10AmpSave();
// local registers
if(doPerPort_flag == DO_PER_PORT)
{
port_num = phyaddr - ephy_addr_base;
mt7512FELRCfgLoad(current_idx, port_num);
}
else
{
for(pn=0; pn<MT7512FE_PORTNUM; pn++)
{
mt7512FELRCfgLoad(current_idx, pn);
}
}
// load revision-related settings
//printf("tcphy: CfgLoad %s\r\n", mt7512FE_cfg[current_idx].name);
}
/************************************************************************
*
* Variables and Functions for 7512 GE PHY (ID=0x9451)
*
**************************************************************************/
#define MT7512Ge_PORTNUM 1
#define MT7512Ge_PHY_INIT_LDATA_LEN 1
#define MT7512Ge_PHY_INIT_PERPDATA_LEN 0
#define MT7512Ge_INIT_SET_NUM 1
#define MT7512Ge_PHY_INIT_SET_NUM 1
#define MT7512Ge_PHY_INIT_CL45_GDATA_LEN 9
#define MT7512Ge_PHY_INIT_CL45_LDATA_LEN 9
#define MT7512Ge_PHY_INIT_CL45_PERPDATA_LEN 0
#define MT7512Ge_PHY_INIT_CL45_SET_NUM 1
#define MT7512Ge_PHY_INIT_TR_LDATA_LEN 0
#define MT7512Ge_PHY_INIT_TR_PERPDATA_LEN 0
#define MT7512Ge_PHY_INIT_TR_SET_NUM 1
typedef struct mt7512Ge_cfg_data_s
{
char name[10];
cfg_data_t ldata[MT7512Ge_PHY_INIT_LDATA_LEN];
cfg_data_t perpdata[MT7512Ge_PHY_INIT_PERPDATA_LEN]; //per port register setting
}mt7512Ge_cfg_data_t;
typedef struct mt7512Ge_cfg_cl45data_s
{
cfg_cl45data_t gdata[MT7512Ge_PHY_INIT_CL45_GDATA_LEN];
cfg_cl45data_t ldata[MT7512Ge_PHY_INIT_CL45_LDATA_LEN];
cfg_cl45data_t perpdata[MT7512Ge_PHY_INIT_CL45_PERPDATA_LEN]; //per port register setting
}mt7512Ge_cfg_cl45data_t;
typedef struct mt7512Ge_cfg_trdata_s
{
cfg_trdata_t ldata[MT7512Ge_PHY_INIT_TR_LDATA_LEN];
cfg_trdata_t perpdata[MT7512Ge_PHY_INIT_PERPDATA_LEN]; //per port register setting
}mt7512Ge_cfg_trdata_t;
const uint32 mt7512Ge_page_sel_addr = 31;
mt7512Ge_cfg_data_t mt7512Ge_cfg[MT7512Ge_PHY_INIT_SET_NUM]=
{
{
{"Ge_1.0"},
//local data
{ //{0x00,0x4000}
//for reference {0x1f,0x2A30},{0x0d,0x1002}, //TEST 0D//force txfil value at test page
//{0x1f,0x0003}, // allen_20140530, lpi (21=0x15, 26=0x1a)
//{0x15,0x206a},
//{0x1a,0x0604}
{0x09, 0x1e00}
},
//per-port data
{ //{0x00,0x4000}
}
},
};
mt7512Ge_cfg_cl45data_t mt7512Ge_cfg_cl45[MT7512Ge_PHY_INIT_CL45_SET_NUM]=
{
{ //globle data
{
//for reference {0x1f,0x0032,0x0C24},// disable lpi_1000_pwr_seq_en
//{0x1f, 0x0103, 0x0020}, // invert clock of DFF for phase-mux data input //CML_20130223
//{0x1f, 0x0104, 0x0608}, // disable PLL //CML_20130321
//{0x1f, 0x0104, 0x2608}, // enable PLL //CML_20130321
//{0x1f, 0x0416, 0x0047}, // mcc_acc_ref_th setting //CML_20130327
/*{0x1f, 0x027c, 0x0c0c}, // for 10BASE-T amplitude //CML_20130327*/
/*{0x1f, 0x0021, 0x800a}, // allen_20131120*/
/*{0x1f, 0x0024, 0xc007}, // allen_20131120*/
/*{0x1f, 0x0025, 0x003f}, // allen_20131120*/
{0x1f, 0x0272, 0x3cff}, // ps_op
{0x1f, 0x0269, 0x4344}, // ps_dri
{0x1f, 0x0044, 0x0030}, // pair delay (digital)
{0x1f, 0x027c, 0x0808}, // 10 base Tx
{0x1f, 0x027b, 0x1177}, // disable 10 base-Te
{0x1f, 0x0417, 0x7775},
{0x1f, 0x0024, 0xc007}, // gphy led
{0x1f, 0x0025, 0x003f}, // gphy led
{0x1f, 0x0021, 0x800a} // gphy led
//{0x1f, 0x027b, 0x1177} // allen_20140530 (10baseT Tx gain for IOT, if tx no EEE, rx only)
},
//local data
{
//for reference {0x1e,0x003D,0x0800},//modify Pair A DC for 100M
//{0x1e,0x00a6,0x0000} // disable TX power control //CML_20130321 //CML_20130327
//{0x7,0x003c,0x0000}, //disable EEE mode // allen_20130926 : GePhy: IOT, wait 7511 E4 ECO
#if 0 // keep E1 setting //CML_20130401
{0x1e,0x0001,0x0158}, // for 100BASE-T TX //CML_20130327
{0x1e,0x0003,0x0043}, // for 100BASE-T TX //CML_20130327
{0x1e,0x0004,0x0207}, // for 100BASE-T TX //CML_20130327
{0x1e,0x0007,0x0357}, // for 100BASE-T TX //CML_20130327
{0x1e,0x0008,0x02f0}, // for 100BASE-T TX //CML_20130327
{0x1e,0x000a,0x0006} // for 100BASE-T TX //CML_20130327
#endif //CML_20130401
/*{0x1e,0x0012,0x7230}, // 0x7210 // allen_20130926 : tx gain*/
/*{0x1e,0x0045,0x0303}, // 0x0202 // allen_20130926 : R offset*/
/*{0x1e,0x0046,0x0303}, // 0x0303 // for 100BASE-T TX //CML_20130401 // allen_20130926 : R offset */
{0x1e,0x0002,0x01b4}, // z2p_ovs
{0x1e,0x0005,0x0080}, // p2z_ovs
{0x1e,0x0008,0x03b7}, // z2n_ovs
{0x1e,0x000b,0x0002}, // n2z_ovs
{0x1e,0x0014,0x0440}, // pair delay (afe)
{0x1e,0x0012,0x2c10}, // 10 base Tx
{0x1e,0x0017,0x0410}, // 10 base Tx
{0x1e,0x00a6,0x0350},
{0x07,0x003c,0x0000}
//{0x1e,0x0120,0x8d0d}, // for 7510 E4
//{0x1e,0x0122,0xffa0}, // for 7510 E4
//{0x1e,0x00a6,0x03e0} // for 7510 E4
},
//per-port data
{
}
},
};
mt7512Ge_cfg_trdata_t mt7512Ge_cfg_tr[MT7512Ge_PHY_INIT_TR_SET_NUM]=
{
{ //local data
{
//for reference {"PMA",0x20,0x0700},
//{"DSPF",0x0010,0x005000},
//{"DSPF",0x0011,0x040004},
//{"DSPF",0x000e,0x800008}
},
//per-port data
{ //{"PMA",0x20,0x0700}
}
},
};
void mt7512GePhyCfgLoad(uint8 idx)
{
int pn, i;
uint16 phyAddr, phyAddr_base = 12;
current_idx = idx;
eco_rev = VPint(0xbfb00064);
// global registers
for( pn=0; pn<tcPhyPortNum; pn++)
{
phyAddr = phyAddr_base + pn;
//printf("\n 7512Ge, phyaddr= (%d,%d) \n", phyAddr_base, phyAddr);
for( i=0; i<MT7512Ge_PHY_INIT_CL45_GDATA_LEN; i++ )
{
mtEMiiRegWrite(phyAddr, mt7512Ge_cfg_cl45[current_idx].gdata[i].dev_num, mt7512Ge_cfg_cl45[current_idx].gdata[i].reg_num, mt7512Ge_cfg_cl45[current_idx].gdata[i].val);
}
for( i=0; i<MT7512Ge_PHY_INIT_CL45_LDATA_LEN; i++ )
{
mtEMiiRegWrite(phyAddr, mt7512Ge_cfg_cl45[current_idx].ldata[i].dev_num, mt7512Ge_cfg_cl45[current_idx].ldata[i].reg_num, mt7512Ge_cfg_cl45[current_idx].ldata[i].val);
}
for( i=0; i<MT7512Ge_PHY_INIT_LDATA_LEN; i++ )
{
tcMiiStationWrite(phyAddr, mt7512Ge_cfg[current_idx].ldata[i].reg_num, mt7512Ge_cfg[current_idx].ldata[i].val);
}
for( i=0; i<MT7512Ge_PHY_INIT_TR_LDATA_LEN; i++ )
{
mtPhyMiiWrite_TrDbg( phyAddr, mt7512Ge_cfg_tr[current_idx].ldata[i].reg_typ, mt7512Ge_cfg_tr[current_idx].ldata[i].reg_num, mt7512Ge_cfg_tr[current_idx].ldata[i].val,0);
}
}
#if 0
if(eco_rev >= 0x00050003) // allen_20140530 // allen_20150206
{
for(pn=0; pn < tcPhyPortNum; pn++)
{
phyAddr = phyAddr_base + pn;
TCPHYDISP3("debug... ,phyaddr=%d ,eco=0x%x \r\n", phyAddr, eco_rev);
tcMiiStationWrite(phyAddr, 0x1F, 0x0003); // lpi
tcMiiStationWrite(phyAddr, 0x15, 0x206a); // 21 = 0x15
tcMiiStationWrite(phyAddr, 0x1a, 0x0604); // 26 = 0x1a
mtEMiiRegWrite(phyAddr, 0x1e, 0x0120, 0x8d0d);
mtEMiiRegWrite(phyAddr, 0x1e, 0x0122, 0xffa0);
mtEMiiRegWrite(phyAddr, 0x1e, 0x00a6, 0x0350);
mtEMiiRegWrite(phyAddr, 0x1f, 0x0417, 0x7775); // allen_20150206
//mtEMiiRegWrite(phyAddr, 0x1e, 0x00a6, 0x0350); // allen_20150206
mtEMiiRegWrite(phyAddr, 0x7, 0x003c, 0x0000); // allen_20141121 // allen_20141225
mtPhyMiiWrite_TrDbg(phyAddr, "DSPF", 0x0010, 0x005000, 0);
mtPhyMiiWrite_TrDbg(phyAddr, "DSPF", 0x0011, 0x040004, 0);
mtPhyMiiWrite_TrDbg(phyAddr, "DSPF", 0x000e, 0x800008, 0);
}
}
#endif
//printf("mtphy: CfgLoad %s\r\n", mt7512Ge_cfg[current_idx].name);
}
// tcPhy initial: reset, load default register setting, restat AN
int tcPhyInit(macAdapter_t * mac_p){
int i=0;
uint16 start_addr= mac_p->enetPhyAddr;
//miiStationWrite( mac_p, PHY_CONTROL_REG, PHY_RESET );
for( i=start_addr; i<start_addr+tcPhyPortNum; i++ ){
tcMiiStationWrite(i, PHY_CONTROL_REG, PHY_RESET );
}
switch (tcPhyVer) {
#ifdef TC2031_SUPPORT
case tcPhyVer_2031: // LEH
tc2031CfgLoad(0);
tc2031LdpsSet(config_ldps);
break;
#endif
#ifdef TC2101MB_SUPPORT
case tcPhyVer_2101mb: // LEM
tc2101mbCfgLoad(0);
break;
#endif
#ifdef TC2206_SUPPORT
case tcPhyVer_2104mc: // 2206
tc2104mcCfgLoad(0, DO_4_PORT, 0);
break;
#endif
#ifdef TC2104SD_SUPPORT
case tcPhyVer_2104sd: // 2104sd
tc2104sdCfgLoad(0);
break;
#endif
#ifdef TC2101ME_SUPPORT
case tcPhyVer_2101me: // 62U
tc2101meCfgLoad(0);
break;
#endif
#ifdef TC2102ME_SUPPORT
case tcPhyVer_2102me: // 3182
tc2102meCfgLoad(0);
break;
#endif
#ifdef TC2206_SUPPORT
case tcPhyVer_2104me: // 2206F
tc2104meCfgLoad(0, DO_4_PORT, 0);
break;
#endif
#ifdef TC2105MJ_SUPPORT
case tcPhyVer_2105mj: // RT63365
tc2105mjCfgLoad(0, DO_4_PORT, 0);
break;
#endif
case mtPhyVer_7530: // MT7530
mt7530GePhyCfgLoad(0, DO_5_PORT, 0);
break;
case tcPhyVer_7512Fe:
mt7512FECfgLoad(0, DO_4_PORT, 8);
break;
case tcPhyVer_7512Ge:
mt7512FECfgLoad(0, DO_4_PORT, 8);
mt7512GePhyCfgLoad(0);
break;
default:
printf("Not found TC Phy\r\n");
break;
}
// always boot-up with AN-ENABLE
//miiStationWrite( mac_p, PHY_CONTROL_REG, MIIDR_AUTO_NEGOTIATE );
for( i=start_addr; i<start_addr+tcPhyPortNum; i++ ){
tcMiiStationWrite(i, PHY_CONTROL_REG, MIIDR_AUTO_NEGOTIATE );
}
// tcphy_link_state init.
for(i=0;i<TCPHY_PORTNUM;i++){
tcphy_link_state[i]=ST_LINK_DOWN;
}
return 0;
}
int tcPhyPortNumGet(void){
if(tcPhyVer != 99)
return tcPhyPortNum;
else
return 0;
}
// set tcPhyFlag & tcPhyVer
int tcPhyVerLookUp(macAdapter_t *mac_p){
uint32 rval;
uint16 r15_val;
tcPhyFlag = 1;
rval = miiStationRead(mac_p->enetPhyAddr, 3); // phy revision id
rval &= 0xffff;
r15_val = miiStationRead(mac_p->enetPhyAddr, 0xF);
if (rval==0x9400){
tcPhyVer=tcPhyVer_2031;
tcPhyPortNum=1;
TCPHYDISP1("TC2031, ");
// #if ( defined(TC2031_DEBUG) && !defined(ZYXEL_LEH) )
// printf("TC2031_%s, ", tc2031_cfg[current_idx].name);
// #endif
} else if (rval==0x9401){
tcPhyVer=tcPhyVer_2101mb;
tcPhyPortNum=1;
//printf("TC2101MB, ");
} else if (rval==0x9402){
tcPhyVer=tcPhyVer_2104mc;
tcPhyPortNum=4;
//printf("TC2104MC, ");
} else if (rval==0x9403){
tcPhyVer=tcPhyVer_2104sd;
tcPhyPortNum=4;
//printf("TC2104SD, ");
} else if (rval==0x9404){
tcPhyVer=tcPhyVer_2101me;
tcPhyPortNum=1;
//printf("TC2101ME, ");
} else if (rval==0x9405){
tcPhyVer=tcPhyVer_2102me;
tcPhyPortNum=2;
} else if (rval==0x9406){
tcPhyVer=tcPhyVer_2104me;
tcPhyPortNum=4;
} else if (rval==0x9407){
tcPhyVer=tcPhyVer_2101mf;
tcPhyPortNum=1;
} else if (rval==0x940b){
tcPhyVer=tcPhyVer_2105mj;
tcPhyPortNum=5;
#if defined(TCSUPPORT_CPU_MT7520) || defined(TCSUPPORT_CPU_EN7512) || defined(TCSUPPORT_CPU_EN7521)
} else if (rval==0x940F){
tcPhyVer=tcPhyVer_mt7510FE;
tcPhyPortNum=4;
printf("tcPhyVer_mt7510FE \n ");
//} else if (rval==0x0440){
} else if (rval==0x9412){ //CML_20130219, E2 PHY ID
if(r15_val & 0x2000)
{
tcPhyVer=mtPhyVer_7530;
tcPhyPortNum=1;
#if defined(TCSUPPORT_CPU_EN7512) || defined(TCSUPPORT_CPU_EN7521)
}else{
tcPhyVer=tcPhyVer_7512Fe;
tcPhyPortNum=4;
#endif
}
} else if (rval==0x9421){
tcPhyVer=mtPhyVer_7510Ge;
tcPhyPortNum=1;
#endif
#if defined(TCSUPPORT_CPU_EN7512) || defined(TCSUPPORT_CPU_EN7521)
}else if (rval==0x9451){
tcPhyVer=tcPhyVer_7512Ge;
tcPhyPortNum=1;
#endif
#ifdef TCPHY_DEBUG
} else {
printf("unknown PHYID: %lx, ", rval);
#endif
}
return 0;
}
uint32
macPhyLookUp(
macAdapter_t *mac_p,
uint32 companyId
)
{
uint32 i;
uint32 phyTypeSupport;
phyTypeSupport = sizeof(phyDeviceList) / sizeof(phyDeviceList_t);
for ( i = 0; i < phyTypeSupport; i++ ) {
if ( companyId == phyDeviceList[i].companyId ) {
mac_p->enetPhyId = i;
if( companyId == 0x03a2 ){
tcPhyVerLookUp(mac_p);
}
return 1;
}
}
return 0;
}
int32
macSearchPhyAddr(
macAdapter_t *mac_p
)
{
uint32 miiReg = 0;
#ifdef TC3262
int cnt=10000;
do{
if(miiStationRead(0 , 2)!=0xffff){
break;
}
cnt--;
}while(cnt>0);
#endif
#if !(defined(TCSUPPORT_CPU_MT7520) || defined(TCSUPPORT_CPU_EN7512)|| defined(TCSUPPORT_CPU_EN7521))
mac_p->enetPhyAddr = 0;
for ( mac_p->enetPhyAddr = 0; mac_p->enetPhyAddr < 32; mac_p->enetPhyAddr++ )
#endif
{
miiReg = miiStationRead(mac_p->enetPhyAddr , PHY_ID_REG1);
if (miiReg == 0)
miiReg = miiStationRead(mac_p->enetPhyAddr, PHY_ID_REG2);
if ( macPhyLookUp(mac_p, miiReg) ) {
return 0;
}
}
#if !(defined(TCSUPPORT_CPU_MT7520) || defined(TCSUPPORT_CPU_EN7512)|| defined(TCSUPPORT_CPU_EN7521))
mac_p->enetPhyAddr = 0x00000000;
#endif
return -1;
}
/*_____________________________________________________________________________
** function name: filedSwicDefVal
** descriptions:
** We need to refilled the TC2206 switch ic register default value, it be
** overwrited by hardware trap.
**
** parameters:
** none
**
** global:
** None
**
** return:
** None
**
** call:
** None
**
** revision:
** 1. Here 2009/7/30
** 2. Here 2010/1/30
**____________________________________________________________________________
*/
void
filedSwicDefVal(void){
int i=0;
uint16 ver=0;
uint16 val=0;
/*Get the TC2206 switch IC model id*/
ver=(uint16)(1<<(tcMiiStationRead(31, 30)));
/*Let IP175C PING compatible, so let those register to reset default value*/
for(i=0; tc2206_swic_reg[i].phyaddr!=0; i++){
if(ver & tc2206_swic_reg[i].model_id){
tcMiiStationWrite(tc2206_swic_reg[i].phyaddr, tc2206_swic_reg[i].regaddr, tc2206_swic_reg[i].value);
}
}
/*The L2P2/L3P3/L4P4 CPU is not supported Turbo MII mode, we need to disabled it*/
if(isTC3162L2P2 | isTC3162L3P3 | isTC3162L4P4){
val = tcMiiStationRead(22, 1) & 0xfffd;
tcMiiStationWrite(22, 1, val);
}
}/*end filedSwicDefVal*/
/*_____________________________________________________________________________
** function name: macSetUpPhy
** descriptions:
** Detect the switch vender id and setup related mii register,such as
** cpu port's link up status.
**
** parameters:
** mac_p:
**
** global:
** None
**
** return:
** 0
**
** call:
** miiStationRead
** miiStationWrite
**
** revision:
** 2009/05/08
**____________________________________________________________________________
*/
int
macSetUpPhy
(
macAdapter_t *mac_p
)
{
/* detect if RTL8305 or RTL8306 Switch*/
if ((miiStationRead(4, 2) == 0x1c) && (miiStationRead(4, 3) == 0xc852)) {
if ((miiStationRead(6, 2) == 0x1c) && (miiStationRead(6, 3) == 0xc852) ){
/*swicVendor = SWIC_RTL8306SD;Let CPU Port Link up*/
miiStationWrite(5, 22,miiStationRead(5,22)|0x8000);
miiStationWrite(6, 22,miiStationRead(6,22)|0x8000);
}
}
tcPhyInit(mac_p);
/*Switch Model Number Register (SMNR), Addr.: 16'h02FE*/
if (tcMiiStationRead(31, 31) == 0x2206){
/*TC2206 switch IC and to filled the switch default value*/
swicVendor=SWIC_TC2206;
filedSwicDefVal();
}
return 0;
}/*end macSetUpPhy*/
/*_____________________________________________________________________________
** function name: getTC2206InitRegFlag
** descriptions:
** System will accroding the esd_chk_reg to check the switch status is handing or not
**
** parameters:
** none
**
** global:
** esd_chk_reg
**
** return:
** 0: Switch IC is happend handing problem.
** 1: Work fine.
**
** call:
** tcMiiStationRead
**
** revision:
** 1. Here 2009/8/6
**____________________________________________________________________________
*/
int
getTC2206InitRegFlag(void){
int i=0;
int j=0;
uint16 ver = 0;
ver = (uint16)(1<<(tcMiiStationRead(31,30)));
for(i=0; esd_chk_reg[i].phyaddr!=0; i++){
for(j=0; tc2206_swic_reg[j].phyaddr!=0; j++){
/*Check the switch ic register is reset to default*/
if((esd_chk_reg[i].model_id & ver)
&&(tc2206_swic_reg[j].model_id)
&&(esd_chk_reg[i].phyaddr == tc2206_swic_reg[j].phyaddr)
&&(esd_chk_reg[i].regaddr == tc2206_swic_reg[j].regaddr)){
if(tcMiiStationRead(esd_chk_reg[i].phyaddr, esd_chk_reg[i].regaddr)!=tc2206_swic_reg[j].value){
return 0;
}
}
}
}
return 1;
}/*end getTC2206InitRegFlag*/
/*_____________________________________________________________________________
** function name: esdSwPatch
** descriptions:
** During the ESD test that is due to switch/phy handing on at TC2206 switch ic, so we need to use
** hardware reset to wake up the hardware.So system need to reload the switch/phy register settings.
**
** parameters:
** none
**
** global:
** None
**
** return:
** None
**
** call:
** None
**
** revision:
** 1. Here 2009/7/30
**____________________________________________________________________________
*/
void
esdSwPatch(void){
uint8 ether_gpio=*(uint8 *)(FLASH_ETHER_GPIO);
/*The esd software patch is only work at TC2206A1 version*/
if((swicVendor==SWIC_TC2206) && esd_sw_patch && (miiStationRead(31,30)==0x0)){
if((!getTC2206InitRegFlag()) ||(!getTcPhyInitialRegFlag())){
printf("\r\nESD detected!!\r\n");
/* ----- Hardware reset Ehernet phy chip, this address is defined by h/w engineer ----- */
VPint(CR_GPIO_CTRL) |= (1<<(ether_gpio<<1));/*Example: gpio 9=(1<<(9*2))*/
VPint(CR_GPIO_ODRAIN) |= (1<<ether_gpio);
VPint(CR_GPIO_DATA) &= ~(1<<ether_gpio);
pause(100);
VPint(CR_GPIO_DATA) |= (1<<ether_gpio);
pause(100);
/*Reload the switch default value for hardware trap*/
filedSwicDefVal();
/*Reload the tce phy default value for afe settings and power issue*/
tcPhyInit(mac_p);
}
}
}/*end filedSwicDefVal*/