Line 1... |
Line 1... |
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Interrupt-driven Ethernet MAC test code for use on board ////
|
//// OpenCores 10/100 Ethernet MAC test and diagnosis program ////
|
//// ////
|
//// ////
|
//// Description ////
|
//// Description ////
|
//// Controllable ping program - also responds to ARP requests ////
|
//// Controllable ping program - also responds to ARP requests ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - jb, jb@orsoc.se, with parts taken from Linux kernel ////
|
//// - Julius Baxter, julius@opencores.org ////
|
//// open_eth driver. ////
|
//// Parts from old Linux open_eth driver. ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2009,2011 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
Line 144... |
Line 144... |
oeth_bd *tx_bd_base; /* Address of Tx BDs. */
|
oeth_bd *tx_bd_base; /* Address of Tx BDs. */
|
|
|
// struct net_device_stats stats;
|
// struct net_device_stats stats;
|
};
|
};
|
|
|
|
int ethphy_found = -1;
|
|
|
#define PRINT_BIT_NAME(bit,name) printf("%02d:"name" %d\n",bit,!!(reg&(1<<bit)))
|
#define PRINT_BIT_NAME(bit,name) printf("%02d:"name" %d\n",bit,!!(reg&(1<<bit)))
|
void oeth_print_moder(unsigned long reg)
|
void oeth_print_moder(unsigned long reg)
|
{
|
{
|
PRINT_BIT_NAME(16,"RECSMALL");
|
PRINT_BIT_NAME(16,"RECSMALL");
|
PRINT_BIT_NAME(15,"PAD");
|
PRINT_BIT_NAME(15,"PAD");
|
Line 313... |
Line 315... |
else if (last_char == 7)
|
else if (last_char == 7)
|
{
|
{
|
printf("|");
|
printf("|");
|
last_char=-1;
|
last_char=-1;
|
}
|
}
|
|
printf("\r");
|
last_char++;
|
last_char++;
|
|
|
for(i=0;i<150000;i++);
|
for(i=0;i<150000;i++);
|
|
|
}
|
}
|
|
|
#define PHYNUM 7
|
static inline void ethphy_smi_read(void)
|
|
{
|
|
|
|
volatile oeth_regs *regs;
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
|
/* Wait for command to be registered*/
|
|
while(!(regs->miistatus & OETH_MIISTATUS_BUSY));
|
|
|
|
regs->miicommand = 0;
|
|
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
}
|
|
|
|
|
|
void
|
|
eth_mii_write(char phynum, short regnum, short data)
|
|
{
|
|
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
|
|
regs->miiaddress = (regnum << 8) | phynum;
|
|
regs->miitx_data = data;
|
|
regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
|
|
regs->miicommand = 0;
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
}
|
|
|
|
short
|
|
eth_mii_read(char phynum, short regnum)
|
|
{
|
|
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
|
|
regs->miiaddress = (regnum << 8) | phynum;
|
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
|
regs->miicommand = 0;
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
|
|
return regs->miirx_data;
|
|
}
|
|
|
|
|
/* Scan the MIIM bus for PHYs */
|
/* Scan the MIIM bus for PHYs */
|
void scan_ethphys(void)
|
void scan_ethphys(void)
|
{
|
{
|
unsigned int phynum,regnum, i;
|
unsigned int phynum,regnum, i;
|
Line 332... |
Line 372... |
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
regs->miitx_data = 0;
|
regs->miitx_data = 0;
|
|
|
|
printf("Locating Ethernet PHYs on MDIO bus\n");
|
|
|
for(phynum=0;phynum<32;phynum++)
|
for(phynum=0;phynum<32;phynum++)
|
{
|
{
|
for (regnum=0;regnum<8;regnum++)
|
for (regnum=0;regnum<8;regnum++)
|
{
|
{
|
printf("scan_ethphys: phy %d r%d ",phynum, regnum);
|
|
|
|
/* Now actually perform the read on the MIIM bus*/
|
/* Now actually perform the read on the MIIM bus*/
|
regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
|
regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
ethphy_smi_read();
|
|
|
while(!(regs->miistatus & OETH_MIISTATUS_BUSY)); /* Wait for command to be registered*/
|
//printf("%x\n",regs->miirx_data);
|
|
|
regs->miicommand = 0;
|
// Remember first phy found
|
|
if (regnum==0 && regs->miirx_data!=0xffff)
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
{
|
|
// Save found phy address in global variable ethphy_found
|
|
// for use elsewhere.
|
|
ethphy_found = phynum;
|
|
printf("PHY detected at address %d\n",phynum);
|
|
return;
|
|
}
|
|
|
printf("%x\n",regs->miirx_data);
|
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
|
|
Line 370... |
Line 417... |
{
|
{
|
printf("scan_ethphy%d: r%x ",phynum, regnum);
|
printf("scan_ethphy%d: r%x ",phynum, regnum);
|
|
|
/* Now actually perform the read on the MIIM bus*/
|
/* Now actually perform the read on the MIIM bus*/
|
regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
|
regs->miiaddress = (regnum << 8) | phynum; /* Basic Control Register */
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
|
|
|
while(!(regs->miistatus & OETH_MIISTATUS_BUSY)); /* Wait for command to be registered*/
|
ethphy_smi_read();
|
|
|
regs->miicommand = 0;
|
printf("%x\n",regs->miirx_data);
|
|
}
|
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
}
|
|
|
|
|
|
void ethphy_toggle_loopback(void)
|
|
{
|
|
volatile oeth_regs *regs;
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
|
// First read the loopback bit from the basic control reg
|
|
if (eth_mii_read(ethphy_found%0xff, 0) & (1<<14))
|
|
{
|
|
printf("Disabling PHY loopback\n");
|
|
eth_mii_write(ethphy_found, 0,
|
|
eth_mii_read(ethphy_found,0) & ~(1<<14));
|
|
}
|
|
else
|
|
{
|
|
printf("Enabling PHY loopback\n");
|
|
eth_mii_write(ethphy_found, 0,
|
|
eth_mii_read(ethphy_found,0) | (1<<14));
|
|
}
|
|
|
printf("%x\n",regs->miirx_data);
|
|
}
|
}
|
|
|
|
void marvell_phy_toggle_delay(void)
|
|
{
|
|
volatile oeth_regs *regs;
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
|
// First read the loopback bit from the basic control reg
|
|
if (eth_mii_read(ethphy_found%0xff, 20) & (1<<1))
|
|
{
|
|
printf("Disabling PHY GTX_CLK delay\n");
|
|
eth_mii_write(ethphy_found, 20,
|
|
eth_mii_read(ethphy_found,20) & ~(1<<1));
|
|
}
|
|
else
|
|
{
|
|
printf("Enabling PHY GTX_CLK delay\n");
|
|
eth_mii_write(ethphy_found, 20,
|
|
eth_mii_read(ethphy_found,20) | (1<<1));
|
|
}
|
|
|
|
}
|
|
|
|
void ethphy_toggle_gigadvertise()
|
|
{
|
|
volatile oeth_regs *regs;
|
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
// Are we advertising gige?
|
|
if (eth_mii_read(ethphy_found%0xff, 9) & (1<<8))
|
|
{
|
|
printf("Disabling 1000base-t advertisement\n");
|
|
eth_mii_write(ethphy_found, 9,
|
|
eth_mii_read(ethphy_found,9) & ~((1<<8)|(1<<9)));
|
|
}
|
|
else
|
|
{
|
|
printf("Enabling 1000base-t advertisement\n");
|
|
eth_mii_write(ethphy_found, 9,
|
|
eth_mii_read(ethphy_found,9) | ((1<<8)|(1<<9)));
|
}
|
}
|
|
|
|
|
|
|
|
}
|
|
|
void ethmac_scanstatus(void)
|
void ethmac_scanstatus(void)
|
{
|
{
|
volatile oeth_regs *regs;
|
volatile oeth_regs *regs;
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
regs = (oeth_regs *)(OETH_REG_BASE);
|
|
|
Line 404... |
Line 509... |
//spin_cursor();
|
//spin_cursor();
|
//printf("\r");
|
//printf("\r");
|
//or32_exit(0);
|
//or32_exit(0);
|
}
|
}
|
|
|
void
|
|
eth_mii_write(char phynum, short regnum, short data)
|
|
{
|
|
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
|
|
regs->miiaddress = (regnum << 8) | phynum;
|
|
regs->miitx_data = data;
|
|
regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
|
|
regs->miicommand = 0;
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
}
|
|
|
|
short
|
|
eth_mii_read(char phynum, short regnum)
|
|
{
|
|
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
|
|
regs->miiaddress = (regnum << 8) | phynum;
|
|
regs->miicommand = OETH_MIICOMMAND_RSTAT;
|
|
regs->miicommand = 0;
|
|
while(regs->miistatus & OETH_MIISTATUS_BUSY);
|
|
|
|
return regs->miirx_data;
|
|
}
|
|
|
|
|
|
void
|
void
|
ethphy_reset(int phynum)
|
ethphy_reset(int phynum)
|
{
|
{
|
eth_mii_write(phynum, MII_BMCR,
|
eth_mii_write(phynum, MII_BMCR,
|
Line 458... |
Line 540... |
void
|
void
|
ethphy_set_100mbit(int phynum)
|
ethphy_set_100mbit(int phynum)
|
{
|
{
|
// Hardset PHY to just use 10Mbit mode
|
// Hardset PHY to just use 10Mbit mode
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
cr &= !BMCR_ANENABLE; // Clear auto negotiate bit
|
cr &= ~(1<<6);
|
cr |= BMCR_SPEED100; // Clear fast eth. bit
|
cr |= (1<<13);
|
eth_mii_write(phynum, MII_BMCR, cr);
|
eth_mii_write(phynum, MII_BMCR, cr);
|
}
|
}
|
|
|
void
|
void
|
ethphy_set_autoneg(int phynum)
|
ethphy_toggle_autoneg(int phynum)
|
{
|
{
|
// Hardset PHY to just use 10Mbit mode
|
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
|
cr |= BMCR_ANENABLE; // Clear auto negotiate bit
|
|
eth_mii_write(phynum, MII_BMCR, cr);
|
|
}
|
|
|
|
|
|
|
|
void m88e111_config_init(int phyaddr)
|
|
{
|
|
short ctl;
|
|
short adv;
|
|
#if 1
|
|
// Soft reset
|
|
eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
|
|
while(eth_mii_read(phyaddr, MII_BMCR) & BMCR_RESET);
|
|
|
|
ctl = eth_mii_read(phyaddr, MII_BMCR);
|
|
ctl &= ~(BMCR_SPD2);
|
|
eth_mii_write(phyaddr, MII_BMCR, ctl);
|
|
|
|
eth_mii_read(phyaddr, MII_ADVERTISE);
|
|
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_1000XFULL
|
|
|ADVERTISE_1000XHALF | ADVERTISE_1000XPAUSE |
|
|
ADVERTISE_1000XPSE_ASYM);
|
|
adv |= ADVERTISE_10HALF;
|
|
adv |= ADVERTISE_10FULL;
|
|
adv |= ADVERTISE_100HALF;
|
|
adv |= ADVERTISE_100FULL;
|
|
eth_mii_write(phyaddr, MII_ADVERTISE, adv);
|
|
// Disable gigabit???
|
|
adv = eth_mii_read(phyaddr, MII_M1011_PHY_SPEC_CONTROL);
|
|
adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
|
|
MII_1000BASETCONTROL_HALFDUPLEXCAP);
|
|
eth_mii_write(phyaddr, MII_M1011_PHY_SPEC_CONTROL, adv);
|
|
// Even more disable gigabit?!
|
|
adv = eth_mii_read(phyaddr, MII_CTRL1000);
|
|
adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
|
|
eth_mii_write(phyaddr, MII_CTRL1000, adv);
|
|
|
|
// Restart autoneg
|
|
printf("Resetting phy...\n");
|
|
eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
|
|
ctl = eth_mii_read(phyaddr, MII_BMCR);
|
|
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
|
|
eth_mii_write(phyaddr, MII_BMCR, ctl);
|
|
#endif
|
|
|
|
#if 0
|
|
// Adapted from kernel: drivers/net/phy/marvell.c
|
|
// Soft reset
|
|
eth_mii_write(phyaddr, MII_BMCR, BMCR_RESET);
|
|
|
|
eth_mii_write(phyaddr, 0x1d, 0x1f);
|
|
eth_mii_write(phyaddr, 0x1e, 0x200c);
|
|
eth_mii_write(phyaddr, 0x1d, 0x5);
|
|
eth_mii_write(phyaddr, 0x1e, 0);
|
|
eth_mii_write(phyaddr, 0x1e, 0x100);
|
|
#define MII_M1011_PHY_SCR 0x10
|
|
#define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060
|
|
eth_mii_write(phyaddr, MII_M1011_PHY_SCR,
|
|
MII_M1011_PHY_SCR_AUTO_CROSS);
|
|
#define MII_M1111_PHY_LED_CONTROL 0x18
|
|
#define MII_M1111_PHY_LED_DIRECT 0x4100
|
|
eth_mii_write(phyaddr, MII_M1111_PHY_LED_CONTROL,
|
|
MII_M1111_PHY_LED_DIRECT);
|
|
|
|
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
|
|
ADVERTISE_PAUSE_ASYM);
|
|
adv |= ADVERTISE_10HALF;
|
|
adv |= ADVERTISE_10FULL;
|
|
adv |= ADVERTISE_100HALF;
|
|
adv |= ADVERTISE_100FULL;
|
|
adv |= ADVERTISE_PAUSE_CAP;
|
|
adv |= ADVERTISE_PAUSE_ASYM;
|
|
eth_mii_write(phyaddr, MII_ADVERTISE, adv);
|
|
|
|
|
|
ctl = eth_mii_read(phyaddr, MII_BMCR);
|
short cr = eth_mii_read(phynum, MII_BMCR);
|
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
|
if (cr & BMCR_ANENABLE)
|
eth_mii_write(phyaddr, MII_BMCR, ctl);
|
printf("Disabling PHY autonegotiation\n");
|
|
else
|
#endif
|
printf("Enabling PHY autonegotiation\n");
|
|
|
#if 0
|
|
ctl = eth_mii_read(phyaddr, MII_BMCR);
|
|
ctl &= ~(BMCR_ANENABLE); // Disable autoneg...
|
|
// Try forcing config
|
|
ctl = BMCR_SPEED100 | BMCR_FULLDPLX;
|
|
eth_mii_write(phyaddr, MII_BMCR, ctl);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
cr ^= BMCR_ANENABLE; // Toggle auto negotiate bit
|
|
eth_mii_write(phynum, MII_BMCR, cr);
|
}
|
}
|
|
|
|
|
void ethphy_print_status(int phyaddr)
|
void ethphy_print_status(int phyaddr)
|
{
|
{
|
short regnum, ctl;
|
short regnum, value;
|
int bitnum;
|
int bitnum;
|
int bitset;
|
int bitset;
|
|
short reg2;
|
printf("phyaddr %d\n",phyaddr);
|
printf("phyaddr %d\n",phyaddr);
|
for (regnum = 0;regnum<16; regnum++)
|
for (regnum = 0;regnum<16; regnum++)
|
{
|
{
|
ctl = eth_mii_read(phyaddr, regnum);
|
value = eth_mii_read(phyaddr, regnum);
|
printf("\treg 0x%x: ", regnum);
|
printf("\treg 0x%x: ", regnum);
|
switch(regnum)
|
switch(regnum)
|
{
|
{
|
case 0:
|
case 0:
|
printf("basic control\n");
|
printf("basic control\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 0:
|
case 0:
|
printf("\t\tbit%d:\t%d \t(disable transmitter)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(disable transmitter)\n",bitnum,bitset);
|
break;
|
break;
|
Line 626... |
Line 622... |
break;
|
break;
|
case 1:
|
case 1:
|
printf("basic status\n");
|
printf("basic status\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 0:
|
case 0:
|
printf("\t\tbit%d:\t%d \t(extend capability)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(extend capability)\n",bitnum,bitset);
|
break;
|
break;
|
Line 671... |
Line 667... |
break;
|
break;
|
|
|
}
|
}
|
}
|
}
|
break;
|
break;
|
|
case 2:
|
|
// We'll do presentation of phy ID in reg 3
|
|
reg2 = value;
|
|
printf("\n");
|
|
break;
|
|
case 3:
|
|
printf("\t\tPHY Identifier (regs 2,3)\n");
|
|
printf("\t\tOrganizationally Unique Identifier (OUI): 0x%06x\n",
|
|
((reg2<<6) | ((value>>10)&0x3f)));
|
|
printf("\t\tManufacturer's Model: 0x%02x\n",(value>>4)&0x3f);
|
|
printf("\t\tRevision number: 0x%01x\n",value&0xf);
|
|
break;
|
case 4:
|
case 4:
|
printf("autoneg advertise reg\n");
|
printf("autoneg advertise reg\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 5:
|
case 5:
|
printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
|
break;
|
break;
|
Line 712... |
Line 720... |
break;
|
break;
|
case 5:
|
case 5:
|
printf("autoneg link partner ability\n");
|
printf("autoneg link partner ability\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 5:
|
case 5:
|
printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(10mbps cap.)\n",bitnum,bitset);
|
break;
|
break;
|
Line 756... |
Line 764... |
break;
|
break;
|
case 9:
|
case 9:
|
printf("1000mbit advertise\n");
|
printf("1000mbit advertise\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 8:
|
case 8:
|
printf("\t\tbit%d:\t%d \t(1000base-t half dup)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(1000base-t half dup)\n",bitnum,bitset);
|
break;
|
break;
|
Line 774... |
Line 782... |
break;
|
break;
|
case 0xf:
|
case 0xf:
|
printf("extended status\n");
|
printf("extended status\n");
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 12:
|
case 12:
|
printf("\t\tbit%d:\t%d \t(1000mb half dup.)\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t(1000mb half dup.)\n",bitnum,bitset);
|
break;
|
break;
|
Line 791... |
Line 799... |
}
|
}
|
break;
|
break;
|
/* case 1:
|
/* case 1:
|
for(bitnum = 0; bitnum<16;bitnum++)
|
for(bitnum = 0; bitnum<16;bitnum++)
|
{
|
{
|
bitset = !!(ctl & (1<<bitnum));
|
bitset = !!(value & (1<<bitnum));
|
switch(bitnum)
|
switch(bitnum)
|
{
|
{
|
case 0:
|
case 0:
|
printf("\t\tbit%d:\t%d \t()\n",bitnum,bitset);
|
printf("\t\tbit%d:\t%d \t()\n",bitnum,bitset);
|
break;
|
break;
|
Line 815... |
Line 823... |
|
|
}
|
}
|
|
|
void ethphy_init(void)
|
void ethphy_init(void)
|
{
|
{
|
|
short ctl;
|
/* Init the Alaska 88E1111 Phy */
|
scan_ethphys();
|
char alaska88e1111_ml501_phynum = 0x7;
|
|
m88e111_config_init(alaska88e1111_ml501_phynum);
|
|
|
|
return;
|
|
|
|
/* Init, reset */
|
|
short ctl = eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR);
|
|
ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
|
|
ctl |= BMCR_SPEED100; // 100MBit
|
|
ctl |= BMCR_FULLDPLX; // Full duplex
|
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_BMCR, ctl);
|
|
|
|
// Setup Autoneg
|
|
short adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_ADVERTISE);
|
|
adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_1000XFULL
|
|
|ADVERTISE_1000XHALF | ADVERTISE_1000XPAUSE |
|
|
ADVERTISE_1000XPSE_ASYM);
|
|
adv |= ADVERTISE_10HALF;
|
|
adv |= ADVERTISE_10FULL;
|
|
adv |= ADVERTISE_100HALF;
|
|
adv |= ADVERTISE_100FULL;
|
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_ADVERTISE, adv);
|
|
// Disable gigabit???
|
|
adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL);
|
|
adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
|
|
MII_1000BASETCONTROL_HALFDUPLEXCAP);
|
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL, adv);
|
|
// Even more disable gigabit?!
|
|
adv = eth_mii_read(alaska88e1111_ml501_phynum, MII_CTRL1000);
|
|
adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
|
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_CTRL1000, adv);
|
|
|
|
// Restart autoneg
|
// Restart autoneg
|
printf("Resetting phy...\n");
|
printf("Resetting phy...\n");
|
ctl = eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR);
|
ctl = eth_mii_read(ethphy_found, MII_BMCR);
|
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
|
ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
|
eth_mii_write(alaska88e1111_ml501_phynum, MII_BMCR, ctl);
|
eth_mii_write(ethphy_found, MII_BMCR, ctl);
|
|
|
printf("\nOeth: PHY control reg: 0x%.4x\n",
|
printf("\nOeth: PHY control reg: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_BMCR));
|
eth_mii_read(ethphy_found, MII_BMCR));
|
printf("Oeth: PHY control reg: 0x%.4x\n",
|
printf("Oeth: PHY control reg: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_BMSR));
|
eth_mii_read(ethphy_found, MII_BMSR));
|
printf("Oeth: PHY id0: 0x%.4x\n",
|
printf("Oeth: PHY id0: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_PHYSID1));
|
eth_mii_read(ethphy_found, MII_PHYSID1));
|
printf("Oeth: PHY id1: 0x%.4x\n",
|
printf("Oeth: PHY id1: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_PHYSID2));
|
eth_mii_read(ethphy_found, MII_PHYSID2));
|
printf("Oeth: PHY adv: 0x%.4x\n",
|
printf("Oeth: PHY adv: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_ADVERTISE));
|
eth_mii_read(ethphy_found, MII_ADVERTISE));
|
printf("Oeth: PHY lpa: 0x%.4x\n",
|
printf("Oeth: PHY lpa: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_LPA));
|
eth_mii_read(ethphy_found, MII_LPA));
|
printf("Oeth: PHY physpec: 0x%.4x\n",
|
printf("Oeth: PHY physpec: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_M1011_PHY_SPEC_CONTROL));
|
eth_mii_read(ethphy_found, MII_M1011_PHY_SPEC_CONTROL));
|
printf("Oeth: PHY expansion: 0x%.4x\n",
|
printf("Oeth: PHY expansion: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_EXPANSION ));
|
eth_mii_read(ethphy_found, MII_EXPANSION ));
|
printf("Oeth: PHY ctrl1000: 0x%.4x\n",
|
printf("Oeth: PHY ctrl1000: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_CTRL1000));
|
eth_mii_read(ethphy_found, MII_CTRL1000));
|
printf("Oeth: PHY stat1000: 0x%.4x\n",
|
printf("Oeth: PHY stat1000: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_STAT1000));
|
eth_mii_read(ethphy_found, MII_STAT1000));
|
printf("Oeth: PHY estatus: 0x%.4x\n",
|
printf("Oeth: PHY estatus: 0x%.4x\n",
|
eth_mii_read(alaska88e1111_ml501_phynum, MII_ESTATUS));
|
eth_mii_read(ethphy_found, MII_ESTATUS));
|
|
|
|
|
}
|
}
|
|
|
|
|
Line 2000... |
Line 1977... |
if (bad) {
|
if (bad) {
|
printf("RXE: 0x%x\n",rx_bdp[i].len_status &
|
printf("RXE: 0x%x\n",rx_bdp[i].len_status &
|
OETH_RX_BD_STATS);
|
OETH_RX_BD_STATS);
|
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
|
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
|
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
|
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
|
|
|
|
if (print_packet_contents)
|
|
{
|
|
oeth_print_packet(i, rx_bdp[i].addr,
|
|
rx_bdp[i].len_status
|
|
>> 16);
|
|
printf("\t end of packet\n\n");
|
|
}
|
|
|
bad = 0;
|
bad = 0;
|
continue;
|
continue;
|
}
|
}
|
else {
|
else {
|
|
|
Line 2068... |
Line 2054... |
if (tx_bd[i].len_status & OETH_TX_BD_STATS)
|
if (tx_bd[i].len_status & OETH_TX_BD_STATS)
|
printf("TXER: 0x%x\n",
|
printf("TXER: 0x%x\n",
|
(tx_bd[i].len_status &OETH_TX_BD_STATS));
|
(tx_bd[i].len_status &OETH_TX_BD_STATS));
|
|
|
if (print_packet_contents)
|
if (print_packet_contents)
|
printf("T%d",i);
|
printf("T%d\n",i);
|
}
|
}
|
}
|
}
|
return;
|
return;
|
}
|
}
|
|
|
Line 2142... |
Line 2128... |
else
|
else
|
printf("Packet dumping disabled\n");
|
printf("Packet dumping disabled\n");
|
}
|
}
|
else if (c == 'p')
|
else if (c == 'p')
|
oeth_printregs();
|
oeth_printregs();
|
else if (c == '0')
|
else if (c == 'a')
|
scan_ethphy(0);
|
ethphy_print_status(ethphy_found);
|
else if (c == '1')
|
else if (c >= '0' && c <= '9')
|
scan_ethphy(1);
|
scan_ethphy(c - 0x30);
|
else if (c == '7')
|
|
{
|
|
//scan_ethphy(7);
|
|
//ethphy_print_status(7);
|
|
printf("ext_sr 0x%x\n",eth_mii_read(0x7, 0x1b));
|
|
}
|
|
else if (c == 'r')
|
else if (c == 'r')
|
{
|
{
|
ethphy_reset(7);
|
ethphy_reset(ethphy_found);
|
printf("PHY reset\n");
|
printf("PHY reset\n");
|
}
|
}
|
else if (c == 'R')
|
else if (c == 'R')
|
{
|
{
|
//oeth_reset_tx_bd_pointer();
|
//oeth_reset_tx_bd_pointer();
|
ethmac_setup();
|
ethmac_setup();
|
printf("MAC reset\n");
|
printf("MAC reset\n");
|
}
|
}
|
else if (c == 'n')
|
else if (c == 'n')
|
ethphy_reneg(7);
|
ethphy_reneg(ethphy_found);
|
else if (c == 'N')
|
else if (c == 'N')
|
ethphy_set_autoneg(7);
|
ethphy_toggle_autoneg(ethphy_found);
|
else if (c == 'm')
|
else if (c == 'm')
|
ethmac_togglehugen();
|
ethmac_togglehugen();
|
else if (c == 't')
|
else if (c == 't')
|
ethphy_set_10mbit(0);
|
ethphy_set_10mbit(ethphy_found);
|
else if (c == 'w')
|
else if (c == 'H')
|
{
|
ethphy_set_100mbit(ethphy_found);
|
// Play with HWCFG mode of Alaska 88e1111 Phy
|
|
c = uart_getc(DEFAULT_UART);
|
|
short newvalue;
|
|
// c is an ascii char, let's convert it to actual hex
|
|
// value
|
|
if (c >= 'A' && c <= 'F')
|
|
newvalue = c - (65 - 10);
|
|
else if (c >= 'a' && c <= 'f')
|
|
newvalue = c - (99 - 10);
|
|
else if (c >= '0' && c <= '9')
|
|
newvalue = c - 48;
|
|
|
|
// Take this value and or it into the bottom bit
|
|
// (supposedly ext_sr)
|
|
#define MII_M1111_PHY_EXT_SR 0x1b
|
|
short ext_sr;
|
|
ext_sr = eth_mii_read(0x7, MII_M1111_PHY_EXT_SR);
|
|
#define MII_M1111_HWCFG_MODE_MASK 0xf
|
|
ext_sr &= ~MII_M1111_HWCFG_MODE_MASK;
|
|
ext_sr |= (short) newvalue;
|
|
eth_mii_write(0x7, MII_M1111_PHY_EXT_SR, ext_sr);
|
|
printf("ext_sr updated to - 0x%x\n",
|
|
eth_mii_read(0x7, MII_M1111_PHY_EXT_SR));
|
|
}
|
|
else if ( c == 'b' )
|
else if ( c == 'b' )
|
{
|
{
|
printf("\n\t---\n");
|
printf("\n\t---\n");
|
oeth_dump_bds();
|
oeth_dump_bds();
|
printf("\t---\n");
|
printf("\t---\n");
|
Line 2215... |
Line 2171... |
else if (c == 'd' )
|
else if (c == 'd' )
|
{
|
{
|
oeth_print_wbdebug();
|
oeth_print_wbdebug();
|
print_ethmac_debug_reg = !print_ethmac_debug_reg;
|
print_ethmac_debug_reg = !print_ethmac_debug_reg;
|
}
|
}
|
|
else if (c == 'D')
|
|
{
|
|
marvell_phy_toggle_delay();
|
|
}
|
else if (c == 'v' )
|
else if (c == 'v' )
|
{
|
{
|
if (packet_inspect_debug)
|
if (packet_inspect_debug)
|
printf("Disabling ");
|
printf("Disabling ");
|
else
|
else
|
Line 2228... |
Line 2188... |
|
|
packet_inspect_debug = !packet_inspect_debug;
|
packet_inspect_debug = !packet_inspect_debug;
|
}
|
}
|
else if ( c == 'o' )
|
else if ( c == 'o' )
|
oeth_toggle_promiscuous();
|
oeth_toggle_promiscuous();
|
|
else if (c == 'L')
|
|
ethphy_toggle_loopback();
|
|
else if (c == 'g')
|
|
ethphy_toggle_gigadvertise();
|
|
|
}
|
}
|
|
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|