|
|
|
@ -151,7 +151,7 @@ struct lpc32xx_eth_registers { |
|
|
|
|
#define SUPP_SPEED 0x00000100 |
|
|
|
|
|
|
|
|
|
/* MCFG register bitfields/masks and offsets (see Table 292) */ |
|
|
|
|
#define MCFG_CLOCK_SELECT_MASK 0x0000001C |
|
|
|
|
#define MCFG_RESET_MII_MGMT 0x00008000 |
|
|
|
|
/* divide clock by 28 (see Table 293) */ |
|
|
|
|
#define MCFG_CLOCK_SELECT_DIV28 0x0000001C |
|
|
|
|
|
|
|
|
@ -168,9 +168,10 @@ struct lpc32xx_eth_registers { |
|
|
|
|
#define COMMAND_RXENABLE 0x00000001 |
|
|
|
|
#define COMMAND_TXENABLE 0x00000002 |
|
|
|
|
#define COMMAND_PASSRUNTFRAME 0x00000040 |
|
|
|
|
#define COMMAND_RMII 0x00000200 |
|
|
|
|
#define COMMAND_FULL_DUPLEX 0x00000400 |
|
|
|
|
/* Helper: general reset */ |
|
|
|
|
#define COMMAND_RESETS 0x0000001C |
|
|
|
|
#define COMMAND_RESETS 0x00000038 |
|
|
|
|
|
|
|
|
|
/* STATUS register bitfields/masks and offsets (see Table 283) */ |
|
|
|
|
#define STATUS_RXSTATUS 0x00000001 |
|
|
|
@ -201,6 +202,7 @@ struct lpc32xx_eth_device { |
|
|
|
|
struct eth_device dev; |
|
|
|
|
struct lpc32xx_eth_registers *regs; |
|
|
|
|
struct lpc32xx_eth_buffers *bufs; |
|
|
|
|
bool phy_rmii; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device)) |
|
|
|
@ -359,7 +361,10 @@ int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr, |
|
|
|
|
|
|
|
|
|
static struct lpc32xx_eth_device lpc32xx_eth = { |
|
|
|
|
.regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE, |
|
|
|
|
.bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS |
|
|
|
|
.bufs = (struct lpc32xx_eth_buffers *)LPC32XX_ETH_BUFS, |
|
|
|
|
#if defined(CONFIG_RMII) |
|
|
|
|
.phy_rmii = true, |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#define TX_TIMEOUT 10000 |
|
|
|
@ -459,8 +464,22 @@ static int lpc32xx_eth_init(struct eth_device *dev) |
|
|
|
|
struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; |
|
|
|
|
int index; |
|
|
|
|
|
|
|
|
|
/* Release SOFT reset to let MII talk to PHY */ |
|
|
|
|
clrbits_le32(®s->mac1, MAC1_SOFT_RESET); |
|
|
|
|
/* Initial MAC initialization */ |
|
|
|
|
writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); |
|
|
|
|
writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); |
|
|
|
|
writel(PKTSIZE_ALIGN, ®s->maxf); |
|
|
|
|
|
|
|
|
|
/* Retries: 15 (0xF). Collision window: 57 (0x37). */ |
|
|
|
|
writel(0x370F, ®s->clrt); |
|
|
|
|
|
|
|
|
|
/* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ |
|
|
|
|
writel(0x0012, ®s->ipgr); |
|
|
|
|
|
|
|
|
|
/* pass runt (smaller than 64 bytes) frames */ |
|
|
|
|
if (lpc32xx_eth_device->phy_rmii) |
|
|
|
|
writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); |
|
|
|
|
else |
|
|
|
|
writel(COMMAND_PASSRUNTFRAME, ®s->command); |
|
|
|
|
|
|
|
|
|
/* Configure Full/Half Duplex mode */ |
|
|
|
|
if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { |
|
|
|
@ -477,20 +496,6 @@ static int lpc32xx_eth_init(struct eth_device *dev) |
|
|
|
|
else |
|
|
|
|
writel(0, ®s->supp); |
|
|
|
|
|
|
|
|
|
/* Initial MAC initialization */ |
|
|
|
|
writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); |
|
|
|
|
writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); |
|
|
|
|
writel(PKTSIZE_ALIGN, ®s->maxf); |
|
|
|
|
|
|
|
|
|
/* Retries: 15 (0xF). Collision window: 57 (0x37). */ |
|
|
|
|
writel(0x370F, ®s->clrt); |
|
|
|
|
|
|
|
|
|
/* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ |
|
|
|
|
writel(0x0012, ®s->ipgr); |
|
|
|
|
|
|
|
|
|
/* pass runt (smaller than 64 bytes) frames */ |
|
|
|
|
writel(COMMAND_PASSRUNTFRAME, ®s->command); |
|
|
|
|
|
|
|
|
|
/* Save station address */ |
|
|
|
|
writel((unsigned long) (dev->enetaddr[0] | |
|
|
|
|
(dev->enetaddr[1] << 8)), ®s->sa2); |
|
|
|
@ -562,6 +567,8 @@ static int lpc32xx_eth_halt(struct eth_device *dev) |
|
|
|
|
#if defined(CONFIG_PHYLIB) |
|
|
|
|
int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) |
|
|
|
|
{ |
|
|
|
|
struct lpc32xx_eth_device *lpc32xx_eth_device = |
|
|
|
|
container_of(dev, struct lpc32xx_eth_device, dev); |
|
|
|
|
struct mii_dev *bus; |
|
|
|
|
struct phy_device *phydev; |
|
|
|
|
int ret; |
|
|
|
@ -582,7 +589,11 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) |
|
|
|
|
return -ENOMEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); |
|
|
|
|
if (lpc32xx_eth_device->phy_rmii) |
|
|
|
|
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII); |
|
|
|
|
else |
|
|
|
|
phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); |
|
|
|
|
|
|
|
|
|
if (!phydev) { |
|
|
|
|
printf("phy_connect failed\n"); |
|
|
|
|
return -ENODEV; |
|
|
|
@ -604,7 +615,7 @@ int lpc32xx_eth_initialize(bd_t *bis) |
|
|
|
|
* Set RMII management clock rate. With HCLK at 104 MHz and |
|
|
|
|
* a divider of 28, this will be 3.72 MHz. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
writel(MCFG_RESET_MII_MGMT, ®s->mcfg); |
|
|
|
|
writel(MCFG_CLOCK_SELECT_DIV28, ®s->mcfg); |
|
|
|
|
|
|
|
|
|
/* Reset all MAC logic */ |
|
|
|
@ -630,7 +641,7 @@ int lpc32xx_eth_initialize(bd_t *bis) |
|
|
|
|
eth_register(dev); |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_PHYLIB) |
|
|
|
|
lpc32xx_eth_phylib_init(dev, 0); |
|
|
|
|
lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR); |
|
|
|
|
#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII) |
|
|
|
|
miiphy_register(dev->name, mii_reg_read, mii_reg_write); |
|
|
|
|
#endif |
|
|
|
|