📄 mac_init.c
字号:
/*
*-------------------------------------------------------------------------------
*
* I N T E L P R O P R I E T A R Y
*
* COPYRIGHT (c) 2002 BY INTEL CORPORATION. ALL RIGHTS
* RESERVED. NO PART OF THIS PROGRAM OR PUBLICATION MAY
* BE REPRODUCED, TRANSMITTED, TRANSCRIBED, STORED IN A
* RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER
* LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,
* MAGNETIC, OPTICAL, CHEMICAL, MANUAL, OR OTHERWISE, WITHOUT
* THE PRIOR WRITTEN PERMISSION OF :
*
* INTEL CORPORATION
*
* 2200 MISSION COLLEGE BLVD
*
* SANTA CLARA, CALIFORNIA 95052-8119
*
* ------------------------------------------------------------------------------
*/
/**
* User defined include files required.
*/
#include "diag.h"
#include "mac_init.h"
#include "error_map.h"
#include "register_map.h"
#include "reg_api.h"
#include "common.h"
#include "diagstruct.h"
/**
* Pre-processor symbols and macros used in this file.
*/
#define PLL_LOCK_TIMER 50 /* Check PLL lock register 50 times
with a delay of 1ms */
#define PHY_REG_ADDRESS 0x1F
#define PHY_DEVICE_ADDRESS 0x03
#define PHY_DEVICE_SHIFT 0x08
#define PHY_READ 0x120000
#define PHY_WRITE 0x110000
#define DEFAULT_SET 0x01
#define NUM_PHY_REGS 0x1F
/**
* Variable declarations global to this file only. Externs are followed by
* static variables.
*/
static configData aMacResetConfigTbl[ ] =
{
{MAC_SOFT_RESET, 0x0000000F, 1},
{TXFIFO_PORT_RESET, 0x0000000F, 1},
{RXFIFO_PORT_RESET, 0x0000000F, 1},
{SPI3_TX_GLOBAL_CONFIG, 0x00E00000, 1}
//{MDIO_RESET, 0x00000001, 1}
};
#define MacResetConfigTblSz (sizeof(aMacResetConfigTbl) /sizeof(aMacResetConfigTbl[0]))
static configData aMacDisableResetConfigTbl[] =
{
{MAC_SOFT_RESET, 0x00000000, 1},
{TXFIFO_PORT_RESET, 0x00000000, 1},
{RXFIFO_PORT_RESET, 0x00000000, 1},
{MDIO_RESET, 0x00000000, 1},
{SERDES_CLKMODE_REG, 0x0000000F, 1},
{PORT_ENABLE, 0x0000000F, 1}
};
#define MacDisableResetConfigTblSz (sizeof(aMacDisableResetConfigTbl) /sizeof(aMacDisableResetConfigTbl[0]))
/**
* Extern function prototypes.
*/
extern UINT32 reg_read( volatile UINT32 offset);
extern void reg_write( volatile UINT32 offset, UINT32 val);
extern void hal_delay_us(unsigned int usecs);
extern void eprintf(char *f, ...);
extern void gets(char *str, int len);
extern void Disable_CPSR_Int(void);
extern void Enable_CPSR_Int(void);
extern short check_autoneg_status(void);
extern UINT32 cu_init(UINT32 set_int_lpbk);
extern int getCmdLine(char* cmdLine);
/** local functions **/
void gbe_mac_phy_write(UINT32 arg_PhyAddress,UINT32 arg_RegAddress,UINT32 arg_WriteValue);
UINT32 gbe_mac_phy_read(UINT32 arg_PhyAddress, UINT32 arg_RegAddress);
void fiber_init(void);
void mixed_mode_init(UINT32 set_int_lpbk);
void mixed_mode_init1(UINT32 set_int_lpbk);
unsigned int htoi(char *s);
int ctoi(char c);
void check_error_display_txstats(void);
void gets(char *str, int len);
/* Globals */
extern UINT32 loop,speed;
extern char channel,test_opt,dplx, loopback_mode;
extern UINT32 media_seat;
extern UINT32 silicon_rev;
UINT32 orig_sp_val[8];
UINT32 cport=0;
UINT32 mdio_enabled = 0;
UINT32 sf_mdio_enabled = 0;
extern UINT32 rxstat[4][30],txstat[4][30];
extern UINT32 ports;
/**
* Function definitions.
*/
UINT32 init_mac_dev (UINT32 set_int_lpbk)
{
UINT32 pll_lock_status =0;
UINT32 pll1_tuning_status,pll2_tuning_status,pll3_tuning_status =0;
UINT32 total_delay=0, status=0, ctr=0;
/* configure slow port in mode 3 */
spConfig();
pll_lock_status=reg_read(SERDES_PLL_LOCK_STATUS);
pll1_tuning_status= reg_read(PLL1_TUNE_REG);
pll2_tuning_status= reg_read(PLL2_TUNE_REG);
pll3_tuning_status= reg_read(PLL3_TUNE_REG);
eprintf("Waiting for PLL Lock to set...\n");
do
{
hal_delay_us(1000); /* delay of 1 ms */
pll_lock_status=reg_read(SERDES_PLL_LOCK_STATUS);
pll1_tuning_status= reg_read(PLL1_TUNE_REG);
pll2_tuning_status= reg_read(PLL2_TUNE_REG);
pll3_tuning_status= reg_read(PLL3_TUNE_REG);
if ( (pll1_tuning_status != 0x534) || (pll2_tuning_status != 0x534) || (pll3_tuning_status != 0x5be) )
{
eprintf("pll1_tuning_status=0x%08X\n", pll1_tuning_status);
eprintf("pll2_tuning_status=0x%08X\n", pll2_tuning_status);
eprintf("pll3_tuning_status=0x%08X\n", pll3_tuning_status);
eprintf("Pll Tuning register lock failed !\n");
return ABORT;
}
// MSG("PLL lock 0x%x\n",pll_lock_status,0,0);
// MSG("PLL lock 0x%x\n",pll1_tuning_status,0,0);
// MSG("PLL lock 0x%x\n",pll2_tuning_status,0,0);
// MSG("PLL lock 0x%x\n",pll3_tuning_status,0,0);
total_delay ++;
if (total_delay > PLL_LOCK_TIMER)
{
eprintf("PLL Lock Timer : Timed out\n");
eprintf("pll1_tuning_status=0x%08X\n", pll1_tuning_status);
eprintf("pll2_tuning_status=0x%08X\n", pll2_tuning_status);
eprintf("pll3_tuning_status=0x%08X\n", pll3_tuning_status);
eprintf("pll_lock_status=0x%08X\n", pll_lock_status);
return PLL_LOCK_ERR;
}
}
while(pll_lock_status != 0x3);
switch (channel)
{
case 'f' :
case 'F' :
eprintf("\nConfiguring Fiber Channels ..\n");
fiber_init(); /** configure the device in fiber mode **/
break;
case 'c' :
case 'C' :
eprintf("\nConfiguring Copper Channels ..\n");
status=cu_init(set_int_lpbk);
break;
case 'm' :
case 'M' :
if (cport == 0)
{
eprintf("\nConfiguring channel 0,1 in Copper and 2, 3 in Fiber ..\n");
}
else if (cport == 2)
{
eprintf("\nConfiguring channel 0,1 in Fibre and 2, 3 in Copper ..\n");
}
mixed_mode_init(set_int_lpbk);
break;
case 'n' :
case 'N' :
eprintf("\nConfiguring chaneel 2,3 in Copper and 0, 1 in Fiber ..\n");
mixed_mode_init1(set_int_lpbk);
break;
default : //eprintf("\nIllegal Channel option.. configuring fiber as default. \n");
fiber_init(); /** configure the device in fiber mode **/
break;
}
if (status == ABORT)
return ABORT;
/* apply delay of 1 second for clock stabilization */
hal_delay_us(1000000);
/* configure station addresses */
reg_write((STATION_ADDR_LOW), 0xA0A0A0A0);
reg_write((STATION_ADDR_HIGH),0x00A0);
reg_write((STATION_ADDR_LOW + 0x80), 0xB0B0B0B0);
reg_write((STATION_ADDR_HIGH + 0x80),0x00B0);
reg_write((STATION_ADDR_LOW + 0x100), 0xC0C0C0C0);
reg_write((STATION_ADDR_HIGH + 0x100),0x00C0);
reg_write((STATION_ADDR_LOW + 0x180), 0xD0D0D0D0);
reg_write((STATION_ADDR_HIGH + 0x180),0x00D0);
/* 48-bit globally assigned multicast pause frame destination address */
reg_write((MUL_PORT_ADDR_LOW), 0xA0A0A0A0);
reg_write((MUL_PORT_ADDR_HIGH), 0xA1A0);
reg_write((MUL_PORT_ADDR_LOW + 0x80), 0xB0B0B0B0);
reg_write((MUL_PORT_ADDR_HIGH + 0x80), 0xA1B0);
reg_write((MUL_PORT_ADDR_LOW + 0x100), 0xC0C0C0C0);
reg_write((MUL_PORT_ADDR_HIGH + 0x100), 0xA1C0);
reg_write((MUL_PORT_ADDR_LOW + 0x180), 0xD0D0D0D0);
reg_write((MUL_PORT_ADDR_HIGH + 0x180), 0xA1D0);
for(ctr=0;ctr<4;ctr++)
{
/* Tx FIFO high watermark */
reg_write((PORT0_TX_HIGH_WATERMARK + ctr), 0x3E0);
/* Tx FIFO low watermark */
reg_write((PORT0_TX_LOW_WATERMARK + ctr), 0xD0);
/* Tx FIFO MAC threshold */
reg_write((PORT0_TX_MAC_THRESHOLD + ctr), 0x1BE);
/* Rx FIFO high watermark */
reg_write((PORT0_RX_HIGH_WATERMARK + ctr), 0x0E6);
/* Rx FIFO low watermark */
reg_write((PORT0_RX_LOW_WATERMARK + ctr), 0x072);
}
spRestore();
return DONE;
}
void mac_disable_reset(void)
{
short i=0;
for (i=0;i<MacDisableResetConfigTblSz; i++)
{
reg_write((aMacDisableResetConfigTbl[i].reg_addr), aMacDisableResetConfigTbl[i].config_val);
}
}
void mac_reset_config(void)
{
short i=0;
for (i=0;i<MacResetConfigTblSz; i++)
{
reg_write(aMacResetConfigTbl[i].reg_addr, aMacResetConfigTbl[i].config_val);
}
}
void config_phy_for_line_lpbk(void)
{
short port_ctr = 0;
for (port_ctr=0;port_ctr<4; port_ctr++)
{
//gbe_mac_phy_write(port_ctr, 0x1B, 0x105); /* Set LED Control in PHY */
gbe_mac_phy_write(port_ctr, 0x19, 0xB400); /* Enable all interrupts */
gbe_mac_phy_write(port_ctr, 0x17, 0x1300); // Enable RGMII mode
if (speed == 1000)
gbe_mac_phy_write(port_ctr, 0x9, 0x300); /* set gigabit operation */
gbe_mac_phy_write(port_ctr, 0, 0x1240); // set auto-neg
}
}
UINT32 config_phy(void)
{
int s_PortCount =0;
UINT32 status=0;
for(s_PortCount=0; s_PortCount<4;s_PortCount++)
{
//gbe_mac_phy_write(s_PortCount, 0x1B, 0x105); /* Set LED Control in PHY */
gbe_mac_phy_write(s_PortCount, 0x19, 0xB400); /* Enable all interrupts */
gbe_mac_phy_write(s_PortCount, 0x17, 0x1300); // Enable RGMII mode
switch (speed)
{
case 1000 : //eprintf("configuring 1000 \n");
switch(dplx)
{
case 'h':
gbe_mac_phy_write(s_PortCount, 0x4, 0x0);
gbe_mac_phy_write(s_PortCount, 0x9, 0x100); /* set gigabit operation */
gbe_mac_phy_write(s_PortCount, 0, 0x1240);
gbe_mac_phy_write(s_PortCount, 22, 0x2018);
gbe_mac_phy_write(s_PortCount, 24, 0x3248);
//gbe_mac_phy_write(s_PortCount, 0, 0x1040);
break;
case 'f':
gbe_mac_phy_write(s_PortCount, 0x4, 0x0);
gbe_mac_phy_write(s_PortCount, 0x9, 0x300); /* set gigabit operation */
gbe_mac_phy_write(s_PortCount, 0, 0x1240);
gbe_mac_phy_write(s_PortCount, 22, 0x18);
gbe_mac_phy_write(s_PortCount, 24, 0x3248);
break;
}
//gig_config();
break;
case 100:
//eprintf("configuring 100 \n");
switch(dplx)
{
case 'h' : //gbe_mac_phy_write(s_PortCount, 0, 0x1240);
gbe_mac_phy_write(s_PortCount, 0x4, 0x80);
gbe_mac_phy_write(s_PortCount, 0x9, 0x400);
gbe_mac_phy_write(s_PortCount, 0, 0x1240);
//gbe_mac_phy_write(s_PortCount, 0, 0x2000);
break;
case 'f' : //gbe_mac_phy_write(s_PortCount, 0, 0x1240);
gbe_mac_phy_write(s_PortCount, 0x4, 0x180);
gbe_mac_phy_write(s_PortCount, 0x9, 0x400);
gbe_mac_phy_write(s_PortCount, 0, 0x1240);
//gbe_mac_phy_write(s_PortCount, 0, 0x2100);
break;
}
break;
case 10:
//eprintf("configuring 10 \n");
switch(dplx)
{
case 'h' : //gbe_mac_phy_write(s_PortCount, 0, 0x1240);
gbe_mac_phy_write(s_PortCount, 0x4, 0x60);
gbe_mac_phy_write(s_PortCount, 0x9, 0x400);
gbe_mac_phy_write(s_PortCount, 0, 0x1240);
//gbe_mac_phy_write(s_PortCount, 0, 0x0);
break;
case 'f' : //gbe_mac_phy_write(s_PortCount, 0, 0x1240);
gbe_mac_phy_write(s_PortCount, 0x4, 0x40);
gbe_mac_phy_write(s_PortCount, 0x9, 0x400);
gbe_mac_phy_write(s_PortCount, 0, 0x1240);
//gbe_mac_phy_write(s_PortCount, 0, 0x0100);
break;
}
break;
default : eprintf("Bad speed option ... configuring 100 Mbps speed.\n");
//eprintf("configuring 100 \n");
switch(dplx)
{
case 'h' : gbe_mac_phy_write(s_PortCount, 0, 0x2000);
break;
case 'f' : gbe_mac_phy_write(s_PortCount, 0, 0x2100);
break;
}
break;
}
}
if (channel == 'm')
{
check_autoneg_status_mixed_mode();
}
else
{
status = check_autoneg_status();
}
if (status == ERROR)
{
eprintf("Auto-negotiation FAILED \n");
return ABORT;
}
return DONE;
}
void gbe_mac_phy_write( UINT32 arg_PhyAddress,
UINT32 arg_RegAddress,
UINT32 arg_WriteValue
)
{
UINT32 s_ReadValue;
UINT32 s_WriteValue = 0;
UINT32 s_RegAddress, s_PhyAddress;
UINT32 mdio_done = 0;
UINT32 ctr=0;
if(((!media_seat) && (!mdio_enabled)) || ((media_seat) && (!sf_mdio_enabled)))
{
reg_write(MDIO_CTL,0x6); // enable mdi and autoscan
s_ReadValue = reg_read((unsigned int)MDIO_CTL);
s_ReadValue = s_ReadValue >> 3;
s_ReadValue &= DEFAULT_SET;
mdio_done = s_ReadValue;
while(mdio_done != 0)
{
ctr++;
hal_delay_us(10000);
if (ctr > 5)
{
eprintf("ERROR: COULD NOT PERFORM MDIO READ\n");
return;
}
s_ReadValue = reg_read((unsigned int)MDIO_CTL);
s_ReadValue = s_ReadValue >> 3;
s_ReadValue &= DEFAULT_SET;
mdio_done = s_ReadValue;
}
ctr = 0;
if(media_seat)
{
sf_mdio_enabled = 1;
}
else
{
mdio_enabled = 1;
}
}
s_RegAddress = arg_RegAddress & PHY_REG_ADDRESS;
s_PhyAddress = arg_PhyAddress & PHY_DEVICE_ADDRESS;
s_PhyAddress = s_PhyAddress << PHY_DEVICE_SHIFT;
s_WriteValue = s_PhyAddress | s_RegAddress;
s_WriteValue = s_WriteValue | PHY_WRITE;
reg_write(MDIO_SINGLE_RW_DATA,arg_WriteValue); // write value to be programmed in phy
reg_write(MDIO_SNGL_CMD, s_WriteValue); // write command to mdio
s_ReadValue = reg_read((unsigned int)MDIO_SNGL_CMD);
s_ReadValue = s_ReadValue >> 20;
s_ReadValue &= DEFAULT_SET;
mdio_done = s_ReadValue;
while (mdio_done != 0)
{
ctr++;
hal_delay_us(10000);
if (ctr > 5)
{
eprintf("ERROR: COULD NOT PERFORM MDIO WRITE\n");
break;
}
s_ReadValue = reg_read((unsigned int)MDIO_SNGL_CMD);
s_ReadValue = s_ReadValue >> 20;
s_ReadValue &= DEFAULT_SET;
mdio_done = s_ReadValue;
}
}
void gbe_mac_phy_read_all()
{
short i=0;
short phy = 0;
char inp[2],p;
register PDiagCommon acL = (PDiagCommon) ACADDRESS;
if(acL->argv[3][0] == 's')
{
media_seat = 0xBABECAFE;
}
eprintf("Enter phy no (0-3) :\n");
gets(inp,2);
p = inp[0];
switch (p)
{
case '0' : phy = 0;
break;
case '1': phy = 1;
break;
case '2' : phy = 2;
break;
case '3' : phy = 3;
break;
default : phy = 0;
break;
}
eprintf("Reading PHY %d Registers \n",phy);
eprintf("------------------------\n");
eprintf("\n Reg Number \t\t Value\n");
for (i=0;i<=NUM_PHY_REGS;i++)
{
eprintf("0x%x \t\t 0x%x\n", i, gbe_mac_phy_read(phy, i));
}
media_seat = 0;
}
UINT32 gbe_mac_phy_read( UINT32 arg_PhyAddress,
UINT32 arg_RegAddress)
{
UINT32 s_ReadValue;
UINT32 s_WriteValue = 0;
UINT32 s_RegAddress, s_PhyAddress;
UINT32 mdio_done = 0;
UINT32 ctr=0;
short phy = arg_PhyAddress;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -