1ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 2ac2916a2SAlbert ARIBAUD \(3ADEV\) * LPC32xx Ethernet MAC interface driver 3ac2916a2SAlbert ARIBAUD \(3ADEV\) * 4ac2916a2SAlbert ARIBAUD \(3ADEV\) * (C) Copyright 2014 DENX Software Engineering GmbH 5ac2916a2SAlbert ARIBAUD \(3ADEV\) * Written-by: Albert ARIBAUD - 3ADEV <albert.aribaud@3adev.fr> 6ac2916a2SAlbert ARIBAUD \(3ADEV\) * 7ac2916a2SAlbert ARIBAUD \(3ADEV\) * SPDX-License-Identifier: GPL-2.0+ 8ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 9ac2916a2SAlbert ARIBAUD \(3ADEV\) 10ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <common.h> 11ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <net.h> 12ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <malloc.h> 13ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <miiphy.h> 14ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <asm/io.h> 15ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <asm/errno.h> 16ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <asm/types.h> 17ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <asm/system.h> 18ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <asm/byteorder.h> 19ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <asm/arch/cpu.h> 20ac2916a2SAlbert ARIBAUD \(3ADEV\) #include <asm/arch/config.h> 21ac2916a2SAlbert ARIBAUD \(3ADEV\) 22ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 23ac2916a2SAlbert ARIBAUD \(3ADEV\) * Notes: 24ac2916a2SAlbert ARIBAUD \(3ADEV\) * 25ac2916a2SAlbert ARIBAUD \(3ADEV\) * 1. Unless specified otherwise, all references to tables or paragraphs 26ac2916a2SAlbert ARIBAUD \(3ADEV\) * are to UM10326, "LPC32x0 and LPC32x0/01 User manual". 27ac2916a2SAlbert ARIBAUD \(3ADEV\) * 28ac2916a2SAlbert ARIBAUD \(3ADEV\) * 2. Only bitfield masks/values which are actually used by the driver 29ac2916a2SAlbert ARIBAUD \(3ADEV\) * are defined. 30ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 31ac2916a2SAlbert ARIBAUD \(3ADEV\) 32ac2916a2SAlbert ARIBAUD \(3ADEV\) /* a single RX descriptor. The controller has an array of these */ 33ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_rxdesc { 34ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 packet; /* Receive packet pointer */ 35ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 control; /* Descriptor command status */ 36ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 37ac2916a2SAlbert ARIBAUD \(3ADEV\) 38ac2916a2SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_ETH_RX_DESC_SIZE (sizeof(struct lpc32xx_eth_rxdesc)) 39ac2916a2SAlbert ARIBAUD \(3ADEV\) 40ac2916a2SAlbert ARIBAUD \(3ADEV\) /* RX control bitfields/masks (see Table 330) */ 41ac2916a2SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_ETH_RX_CTRL_SIZE_MASK 0x000007FF 42ac2916a2SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_ETH_RX_CTRL_UNUSED 0x7FFFF800 43ac2916a2SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_ETH_RX_CTRL_INTERRUPT 0x80000000 44ac2916a2SAlbert ARIBAUD \(3ADEV\) 45ac2916a2SAlbert ARIBAUD \(3ADEV\) /* a single RX status. The controller has an array of these */ 46ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_rxstat { 47ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 statusinfo; /* Transmit Descriptor status */ 48ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 statushashcrc; /* Transmit Descriptor CRCs */ 49ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 50ac2916a2SAlbert ARIBAUD \(3ADEV\) 51ac2916a2SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_ETH_RX_STAT_SIZE (sizeof(struct lpc32xx_eth_rxstat)) 52ac2916a2SAlbert ARIBAUD \(3ADEV\) 53ac2916a2SAlbert ARIBAUD \(3ADEV\) /* RX statusinfo bitfields/masks (see Table 333) */ 54ac2916a2SAlbert ARIBAUD \(3ADEV\) #define RX_STAT_RXSIZE 0x000007FF 55ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Helper: OR of all errors except RANGE */ 56ac2916a2SAlbert ARIBAUD \(3ADEV\) #define RX_STAT_ERRORS 0x1B800000 57ac2916a2SAlbert ARIBAUD \(3ADEV\) 58ac2916a2SAlbert ARIBAUD \(3ADEV\) /* a single TX descriptor. The controller has an array of these */ 59ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_txdesc { 60ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 packet; /* Transmit packet pointer */ 61ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 control; /* Descriptor control */ 62ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 63ac2916a2SAlbert ARIBAUD \(3ADEV\) 64ac2916a2SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_ETH_TX_DESC_SIZE (sizeof(struct lpc32xx_eth_txdesc)) 65ac2916a2SAlbert ARIBAUD \(3ADEV\) 66ac2916a2SAlbert ARIBAUD \(3ADEV\) /* TX control bitfields/masks (see Table 335) */ 67ac2916a2SAlbert ARIBAUD \(3ADEV\) #define TX_CTRL_TXSIZE 0x000007FF 68ac2916a2SAlbert ARIBAUD \(3ADEV\) #define TX_CTRL_LAST 0x40000000 69ac2916a2SAlbert ARIBAUD \(3ADEV\) 70ac2916a2SAlbert ARIBAUD \(3ADEV\) /* a single TX status. The controller has an array of these */ 71ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_txstat { 72ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 statusinfo; /* Transmit Descriptor status */ 73ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 74ac2916a2SAlbert ARIBAUD \(3ADEV\) 75ac2916a2SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_ETH_TX_STAT_SIZE (sizeof(struct lpc32xx_eth_txstat)) 76ac2916a2SAlbert ARIBAUD \(3ADEV\) 77ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Ethernet MAC interface registers (see Table 283) */ 78ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers { 79ac2916a2SAlbert ARIBAUD \(3ADEV\) /* MAC registers - 0x3106_0000 to 0x3106_01FC */ 80ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mac1; /* MAC configuration register 1 */ 81ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mac2; /* MAC configuration register 2 */ 82ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 ipgt; /* Back-to-back Inter-Packet Gap reg. */ 83ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 ipgr; /* Non-back-to-back IPG register */ 84ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 clrt; /* Collision Window / Retry register */ 85ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 maxf; /* Maximum Frame register */ 86ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 supp; /* Phy Support register */ 87ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 test; 88ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mcfg; /* MII management configuration reg. */ 89ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mcmd; /* MII management command register */ 90ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 madr; /* MII management address register */ 91ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mwtd; /* MII management wite data register */ 92ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mrdd; /* MII management read data register */ 93ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mind; /* MII management indicators register */ 94ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved1[2]; 95ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 sa0; /* Station address register 0 */ 96ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 sa1; /* Station address register 1 */ 97ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 sa2; /* Station address register 2 */ 98ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved2[45]; 99ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Control registers */ 100ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 command; 101ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 status; 102ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rxdescriptor; 103ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rxstatus; 104ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rxdescriptornumber; /* actually, number MINUS ONE */ 105ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rxproduceindex; /* head of rx desc fifo */ 106ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rxconsumeindex; /* tail of rx desc fifo */ 107ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 txdescriptor; 108ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 txstatus; 109ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 txdescriptornumber; /* actually, number MINUS ONE */ 110ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 txproduceindex; /* head of rx desc fifo */ 111ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 txconsumeindex; /* tail of rx desc fifo */ 112ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved3[10]; 113ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 tsv0; /* Transmit status vector register 0 */ 114ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 tsv1; /* Transmit status vector register 1 */ 115ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rsv; /* Receive status vector register */ 116ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved4[3]; 117ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 flowcontrolcounter; 118ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 flowcontrolstatus; 119ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved5[34]; 120ac2916a2SAlbert ARIBAUD \(3ADEV\) /* RX filter registers - 0x3106_0200 to 0x3106_0FDC */ 121ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rxfilterctrl; 122ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rxfilterwolstatus; 123ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 rxfilterwolclear; 124ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved6; 125ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 hashfilterl; 126ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 hashfilterh; 127ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved7[882]; 128ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Module control registers - 0x3106_0FE0 to 0x3106_0FF8 */ 129ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 intstatus; /* Interrupt status register */ 130ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 intenable; 131ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 intclear; 132ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 intset; 133ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved8; 134ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 powerdown; 135ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 reserved9; 136ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 137ac2916a2SAlbert ARIBAUD \(3ADEV\) 138ac2916a2SAlbert ARIBAUD \(3ADEV\) /* MAC1 register bitfields/masks and offsets (see Table 283) */ 139ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MAC1_RECV_ENABLE 0x00000001 140ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MAC1_PASS_ALL_RX_FRAMES 0x00000002 141ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MAC1_SOFT_RESET 0x00008000 142ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Helper: general reset */ 143ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MAC1_RESETS 0x0000CF00 144ac2916a2SAlbert ARIBAUD \(3ADEV\) 145ac2916a2SAlbert ARIBAUD \(3ADEV\) /* MAC2 register bitfields/masks and offsets (see Table 284) */ 146ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MAC2_FULL_DUPLEX 0x00000001 147ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MAC2_CRC_ENABLE 0x00000010 148ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MAC2_PAD_CRC_ENABLE 0x00000020 149ac2916a2SAlbert ARIBAUD \(3ADEV\) 150ac2916a2SAlbert ARIBAUD \(3ADEV\) /* SUPP register bitfields/masks and offsets (see Table 290) */ 151ac2916a2SAlbert ARIBAUD \(3ADEV\) #define SUPP_SPEED 0x00000100 152ac2916a2SAlbert ARIBAUD \(3ADEV\) 153ac2916a2SAlbert ARIBAUD \(3ADEV\) /* MCFG register bitfields/masks and offsets (see Table 292) */ 15423f5db0eSVladimir Zapolskiy #define MCFG_RESET_MII_MGMT 0x00008000 155ac2916a2SAlbert ARIBAUD \(3ADEV\) /* divide clock by 28 (see Table 293) */ 156ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MCFG_CLOCK_SELECT_DIV28 0x0000001C 157ac2916a2SAlbert ARIBAUD \(3ADEV\) 158ac2916a2SAlbert ARIBAUD \(3ADEV\) /* MADR register bitfields/masks and offsets (see Table 295) */ 159ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MADR_REG_MASK 0x0000001F 160ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MADR_PHY_MASK 0x00001F00 161ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MADR_REG_OFFSET 0 162ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MADR_PHY_OFFSET 8 163ac2916a2SAlbert ARIBAUD \(3ADEV\) 164ac2916a2SAlbert ARIBAUD \(3ADEV\) /* MIND register bitfields/masks (see Table 298) */ 165ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MIND_BUSY 0x00000001 166ac2916a2SAlbert ARIBAUD \(3ADEV\) 167ac2916a2SAlbert ARIBAUD \(3ADEV\) /* COMMAND register bitfields/masks and offsets (see Table 283) */ 168ac2916a2SAlbert ARIBAUD \(3ADEV\) #define COMMAND_RXENABLE 0x00000001 169ac2916a2SAlbert ARIBAUD \(3ADEV\) #define COMMAND_TXENABLE 0x00000002 170ac2916a2SAlbert ARIBAUD \(3ADEV\) #define COMMAND_PASSRUNTFRAME 0x00000040 1711a791892SVladimir Zapolskiy #define COMMAND_RMII 0x00000200 172ac2916a2SAlbert ARIBAUD \(3ADEV\) #define COMMAND_FULL_DUPLEX 0x00000400 173ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Helper: general reset */ 1746e039b4cSVladimir Zapolskiy #define COMMAND_RESETS 0x00000038 175ac2916a2SAlbert ARIBAUD \(3ADEV\) 176ac2916a2SAlbert ARIBAUD \(3ADEV\) /* STATUS register bitfields/masks and offsets (see Table 283) */ 177ac2916a2SAlbert ARIBAUD \(3ADEV\) #define STATUS_RXSTATUS 0x00000001 178ac2916a2SAlbert ARIBAUD \(3ADEV\) #define STATUS_TXSTATUS 0x00000002 179ac2916a2SAlbert ARIBAUD \(3ADEV\) 180ac2916a2SAlbert ARIBAUD \(3ADEV\) /* RXFILTERCTRL register bitfields/masks (see Table 319) */ 181ac2916a2SAlbert ARIBAUD \(3ADEV\) #define RXFILTERCTRL_ACCEPTBROADCAST 0x00000002 182ac2916a2SAlbert ARIBAUD \(3ADEV\) #define RXFILTERCTRL_ACCEPTPERFECT 0x00000020 183ac2916a2SAlbert ARIBAUD \(3ADEV\) 184ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Buffers and descriptors */ 185ac2916a2SAlbert ARIBAUD \(3ADEV\) 186ac2916a2SAlbert ARIBAUD \(3ADEV\) #define ATTRS(n) __aligned(n) 187ac2916a2SAlbert ARIBAUD \(3ADEV\) 188ac2916a2SAlbert ARIBAUD \(3ADEV\) #define TX_BUF_COUNT 4 189ac2916a2SAlbert ARIBAUD \(3ADEV\) #define RX_BUF_COUNT 4 190ac2916a2SAlbert ARIBAUD \(3ADEV\) 191ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_buffers { 192ac2916a2SAlbert ARIBAUD \(3ADEV\) ATTRS(4) struct lpc32xx_eth_txdesc tx_desc[TX_BUF_COUNT]; 193ac2916a2SAlbert ARIBAUD \(3ADEV\) ATTRS(4) struct lpc32xx_eth_txstat tx_stat[TX_BUF_COUNT]; 194ac2916a2SAlbert ARIBAUD \(3ADEV\) ATTRS(PKTALIGN) u8 tx_buf[TX_BUF_COUNT*PKTSIZE_ALIGN]; 195ac2916a2SAlbert ARIBAUD \(3ADEV\) ATTRS(4) struct lpc32xx_eth_rxdesc rx_desc[RX_BUF_COUNT]; 196ac2916a2SAlbert ARIBAUD \(3ADEV\) ATTRS(8) struct lpc32xx_eth_rxstat rx_stat[RX_BUF_COUNT]; 197ac2916a2SAlbert ARIBAUD \(3ADEV\) ATTRS(PKTALIGN) u8 rx_buf[RX_BUF_COUNT*PKTSIZE_ALIGN]; 198ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 199ac2916a2SAlbert ARIBAUD \(3ADEV\) 200ac2916a2SAlbert ARIBAUD \(3ADEV\) /* port device data struct */ 201ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device { 202ac2916a2SAlbert ARIBAUD \(3ADEV\) struct eth_device dev; 203ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs; 204ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_buffers *bufs; 2051a791892SVladimir Zapolskiy bool phy_rmii; 206ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 207ac2916a2SAlbert ARIBAUD \(3ADEV\) 208ac2916a2SAlbert ARIBAUD \(3ADEV\) #define LPC32XX_ETH_DEVICE_SIZE (sizeof(struct lpc32xx_eth_device)) 209ac2916a2SAlbert ARIBAUD \(3ADEV\) 210ac2916a2SAlbert ARIBAUD \(3ADEV\) /* generic macros */ 211ac2916a2SAlbert ARIBAUD \(3ADEV\) #define to_lpc32xx_eth(_d) container_of(_d, struct lpc32xx_eth_device, dev) 212ac2916a2SAlbert ARIBAUD \(3ADEV\) 213ac2916a2SAlbert ARIBAUD \(3ADEV\) /* timeout for MII polling */ 214ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MII_TIMEOUT 10000000 215ac2916a2SAlbert ARIBAUD \(3ADEV\) 216ac2916a2SAlbert ARIBAUD \(3ADEV\) /* limits for PHY and register addresses */ 217ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MII_MAX_REG (MADR_REG_MASK >> MADR_REG_OFFSET) 218ac2916a2SAlbert ARIBAUD \(3ADEV\) 219ac2916a2SAlbert ARIBAUD \(3ADEV\) #define MII_MAX_PHY (MADR_PHY_MASK >> MADR_PHY_OFFSET) 220ac2916a2SAlbert ARIBAUD \(3ADEV\) 221ac2916a2SAlbert ARIBAUD \(3ADEV\) DECLARE_GLOBAL_DATA_PTR; 222ac2916a2SAlbert ARIBAUD \(3ADEV\) 223ac2916a2SAlbert ARIBAUD \(3ADEV\) #if defined(CONFIG_PHYLIB) || defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 224ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 225ac2916a2SAlbert ARIBAUD \(3ADEV\) * mii_reg_read - miiphy_read callback function. 226ac2916a2SAlbert ARIBAUD \(3ADEV\) * 227ac2916a2SAlbert ARIBAUD \(3ADEV\) * Returns 16bit phy register value, or 0xffff on error 228ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 229ac2916a2SAlbert ARIBAUD \(3ADEV\) static int mii_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data) 230ac2916a2SAlbert ARIBAUD \(3ADEV\) { 231ac2916a2SAlbert ARIBAUD \(3ADEV\) struct eth_device *dev = eth_get_dev_by_name(devname); 232ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); 233ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; 234ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mind_reg; 235ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 timeout; 236ac2916a2SAlbert ARIBAUD \(3ADEV\) 237ac2916a2SAlbert ARIBAUD \(3ADEV\) /* check parameters */ 238ac2916a2SAlbert ARIBAUD \(3ADEV\) if (phy_adr > MII_MAX_PHY) { 239ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: Invalid PHY address %d\n", 240ac2916a2SAlbert ARIBAUD \(3ADEV\) __func__, __LINE__, phy_adr); 241ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 242ac2916a2SAlbert ARIBAUD \(3ADEV\) } 243ac2916a2SAlbert ARIBAUD \(3ADEV\) if (reg_ofs > MII_MAX_REG) { 244ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: Invalid register offset %d\n", 245ac2916a2SAlbert ARIBAUD \(3ADEV\) __func__, __LINE__, reg_ofs); 246ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 247ac2916a2SAlbert ARIBAUD \(3ADEV\) } 248ac2916a2SAlbert ARIBAUD \(3ADEV\) 249ac2916a2SAlbert ARIBAUD \(3ADEV\) /* write the phy and reg addressse into the MII address reg */ 250ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), 251ac2916a2SAlbert ARIBAUD \(3ADEV\) ®s->madr); 252ac2916a2SAlbert ARIBAUD \(3ADEV\) 253ac2916a2SAlbert ARIBAUD \(3ADEV\) /* write 1 to the MII command register to cause a read */ 254ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(1, ®s->mcmd); 255ac2916a2SAlbert ARIBAUD \(3ADEV\) 256ac2916a2SAlbert ARIBAUD \(3ADEV\) /* wait till the MII is not busy */ 257ac2916a2SAlbert ARIBAUD \(3ADEV\) timeout = MII_TIMEOUT; 258ac2916a2SAlbert ARIBAUD \(3ADEV\) do { 259ac2916a2SAlbert ARIBAUD \(3ADEV\) /* read MII indicators register */ 260ac2916a2SAlbert ARIBAUD \(3ADEV\) mind_reg = readl(®s->mind); 261ac2916a2SAlbert ARIBAUD \(3ADEV\) if (--timeout == 0) 262ac2916a2SAlbert ARIBAUD \(3ADEV\) break; 263ac2916a2SAlbert ARIBAUD \(3ADEV\) } while (mind_reg & MIND_BUSY); 264ac2916a2SAlbert ARIBAUD \(3ADEV\) 265ac2916a2SAlbert ARIBAUD \(3ADEV\) /* write 0 to the MII command register to finish the read */ 266ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0, ®s->mcmd); 267ac2916a2SAlbert ARIBAUD \(3ADEV\) 268ac2916a2SAlbert ARIBAUD \(3ADEV\) if (timeout == 0) { 269ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: MII busy timeout\n", __func__, __LINE__); 270ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 271ac2916a2SAlbert ARIBAUD \(3ADEV\) } 272ac2916a2SAlbert ARIBAUD \(3ADEV\) 273ac2916a2SAlbert ARIBAUD \(3ADEV\) *data = (u16) readl(®s->mrdd); 274ac2916a2SAlbert ARIBAUD \(3ADEV\) 275ac2916a2SAlbert ARIBAUD \(3ADEV\) debug("%s:(adr %d, off %d) => %04x\n", __func__, phy_adr, 276ac2916a2SAlbert ARIBAUD \(3ADEV\) reg_ofs, *data); 277ac2916a2SAlbert ARIBAUD \(3ADEV\) 278ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 279ac2916a2SAlbert ARIBAUD \(3ADEV\) } 280ac2916a2SAlbert ARIBAUD \(3ADEV\) 281ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 282ac2916a2SAlbert ARIBAUD \(3ADEV\) * mii_reg_write - imiiphy_write callback function. 283ac2916a2SAlbert ARIBAUD \(3ADEV\) * 284ac2916a2SAlbert ARIBAUD \(3ADEV\) * Returns 0 if write succeed, -EINVAL on bad parameters 285ac2916a2SAlbert ARIBAUD \(3ADEV\) * -ETIME on timeout 286ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 287ac2916a2SAlbert ARIBAUD \(3ADEV\) static int mii_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) 288ac2916a2SAlbert ARIBAUD \(3ADEV\) { 289ac2916a2SAlbert ARIBAUD \(3ADEV\) struct eth_device *dev = eth_get_dev_by_name(devname); 290ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); 291ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; 292ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mind_reg; 293ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 timeout; 294ac2916a2SAlbert ARIBAUD \(3ADEV\) 295ac2916a2SAlbert ARIBAUD \(3ADEV\) /* check parameters */ 296ac2916a2SAlbert ARIBAUD \(3ADEV\) if (phy_adr > MII_MAX_PHY) { 297ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: Invalid PHY address %d\n", 298ac2916a2SAlbert ARIBAUD \(3ADEV\) __func__, __LINE__, phy_adr); 299ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 300ac2916a2SAlbert ARIBAUD \(3ADEV\) } 301ac2916a2SAlbert ARIBAUD \(3ADEV\) if (reg_ofs > MII_MAX_REG) { 302ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: Invalid register offset %d\n", 303ac2916a2SAlbert ARIBAUD \(3ADEV\) __func__, __LINE__, reg_ofs); 304ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 305ac2916a2SAlbert ARIBAUD \(3ADEV\) } 306ac2916a2SAlbert ARIBAUD \(3ADEV\) 30779206c04SVladimir Zapolskiy /* write the phy and reg addressse into the MII address reg */ 30879206c04SVladimir Zapolskiy writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), 30979206c04SVladimir Zapolskiy ®s->madr); 31079206c04SVladimir Zapolskiy 31179206c04SVladimir Zapolskiy /* write data to the MII write register */ 31279206c04SVladimir Zapolskiy writel(data, ®s->mwtd); 31379206c04SVladimir Zapolskiy 314ac2916a2SAlbert ARIBAUD \(3ADEV\) /* wait till the MII is not busy */ 315ac2916a2SAlbert ARIBAUD \(3ADEV\) timeout = MII_TIMEOUT; 316ac2916a2SAlbert ARIBAUD \(3ADEV\) do { 317ac2916a2SAlbert ARIBAUD \(3ADEV\) /* read MII indicators register */ 318ac2916a2SAlbert ARIBAUD \(3ADEV\) mind_reg = readl(®s->mind); 319ac2916a2SAlbert ARIBAUD \(3ADEV\) if (--timeout == 0) 320ac2916a2SAlbert ARIBAUD \(3ADEV\) break; 321ac2916a2SAlbert ARIBAUD \(3ADEV\) } while (mind_reg & MIND_BUSY); 322ac2916a2SAlbert ARIBAUD \(3ADEV\) 323ac2916a2SAlbert ARIBAUD \(3ADEV\) if (timeout == 0) { 324ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: MII busy timeout\n", __func__, 325ac2916a2SAlbert ARIBAUD \(3ADEV\) __LINE__); 326ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 327ac2916a2SAlbert ARIBAUD \(3ADEV\) } 328ac2916a2SAlbert ARIBAUD \(3ADEV\) 329ac2916a2SAlbert ARIBAUD \(3ADEV\) /*debug("%s:(adr %d, off %d) <= %04x\n", __func__, phy_adr, 330ac2916a2SAlbert ARIBAUD \(3ADEV\) reg_ofs, data);*/ 331ac2916a2SAlbert ARIBAUD \(3ADEV\) 332ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 333ac2916a2SAlbert ARIBAUD \(3ADEV\) } 334ac2916a2SAlbert ARIBAUD \(3ADEV\) #endif 335ac2916a2SAlbert ARIBAUD \(3ADEV\) 336ac2916a2SAlbert ARIBAUD \(3ADEV\) #if defined(CONFIG_PHYLIB) 337ac2916a2SAlbert ARIBAUD \(3ADEV\) int lpc32xx_eth_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr, 338ac2916a2SAlbert ARIBAUD \(3ADEV\) int reg_addr) 339ac2916a2SAlbert ARIBAUD \(3ADEV\) { 340ac2916a2SAlbert ARIBAUD \(3ADEV\) u16 data; 341ac2916a2SAlbert ARIBAUD \(3ADEV\) int ret; 342ac2916a2SAlbert ARIBAUD \(3ADEV\) ret = mii_reg_read(bus->name, phy_addr, reg_addr, &data); 343ac2916a2SAlbert ARIBAUD \(3ADEV\) if (ret) 344ac2916a2SAlbert ARIBAUD \(3ADEV\) return ret; 345ac2916a2SAlbert ARIBAUD \(3ADEV\) return data; 346ac2916a2SAlbert ARIBAUD \(3ADEV\) } 347ac2916a2SAlbert ARIBAUD \(3ADEV\) 348ac2916a2SAlbert ARIBAUD \(3ADEV\) int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr, 349ac2916a2SAlbert ARIBAUD \(3ADEV\) int reg_addr, u16 data) 350ac2916a2SAlbert ARIBAUD \(3ADEV\) { 351ac2916a2SAlbert ARIBAUD \(3ADEV\) return mii_reg_write(bus->name, phy_addr, reg_addr, data); 352ac2916a2SAlbert ARIBAUD \(3ADEV\) } 353ac2916a2SAlbert ARIBAUD \(3ADEV\) #endif 354ac2916a2SAlbert ARIBAUD \(3ADEV\) 355ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 35668a77668SSylvain Lemieux * Provide default Ethernet buffers base address if target did not. 357ac2916a2SAlbert ARIBAUD \(3ADEV\) * Locate buffers in SRAM at 0x00001000 to avoid cache issues and 358ac2916a2SAlbert ARIBAUD \(3ADEV\) * maximize throughput. 359ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 36068a77668SSylvain Lemieux #if !defined(CONFIG_LPC32XX_ETH_BUFS_BASE) 36168a77668SSylvain Lemieux #define CONFIG_LPC32XX_ETH_BUFS_BASE 0x00001000 36268a77668SSylvain Lemieux #endif 363ac2916a2SAlbert ARIBAUD \(3ADEV\) 364ac2916a2SAlbert ARIBAUD \(3ADEV\) static struct lpc32xx_eth_device lpc32xx_eth = { 365ac2916a2SAlbert ARIBAUD \(3ADEV\) .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE, 36668a77668SSylvain Lemieux .bufs = (struct lpc32xx_eth_buffers *)CONFIG_LPC32XX_ETH_BUFS_BASE, 3671a791892SVladimir Zapolskiy #if defined(CONFIG_RMII) 3681a791892SVladimir Zapolskiy .phy_rmii = true, 3691a791892SVladimir Zapolskiy #endif 370ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 371ac2916a2SAlbert ARIBAUD \(3ADEV\) 372ac2916a2SAlbert ARIBAUD \(3ADEV\) #define TX_TIMEOUT 10000 373ac2916a2SAlbert ARIBAUD \(3ADEV\) 374ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_send(struct eth_device *dev, void *dataptr, int datasize) 375ac2916a2SAlbert ARIBAUD \(3ADEV\) { 376ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 377ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 378ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 379ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; 380ac2916a2SAlbert ARIBAUD \(3ADEV\) int timeout, tx_index; 381ac2916a2SAlbert ARIBAUD \(3ADEV\) 382ac2916a2SAlbert ARIBAUD \(3ADEV\) /* time out if transmit descriptor array remains full too long */ 383ac2916a2SAlbert ARIBAUD \(3ADEV\) timeout = TX_TIMEOUT; 384ac2916a2SAlbert ARIBAUD \(3ADEV\) while ((readl(®s->status) & STATUS_TXSTATUS) && 385ac2916a2SAlbert ARIBAUD \(3ADEV\) (readl(®s->txconsumeindex) 386ac2916a2SAlbert ARIBAUD \(3ADEV\) == readl(®s->txproduceindex))) { 387ac2916a2SAlbert ARIBAUD \(3ADEV\) if (timeout-- == 0) 388ac2916a2SAlbert ARIBAUD \(3ADEV\) return -1; 389ac2916a2SAlbert ARIBAUD \(3ADEV\) } 390ac2916a2SAlbert ARIBAUD \(3ADEV\) 391ac2916a2SAlbert ARIBAUD \(3ADEV\) /* determine next transmit packet index to use */ 392ac2916a2SAlbert ARIBAUD \(3ADEV\) tx_index = readl(®s->txproduceindex); 393ac2916a2SAlbert ARIBAUD \(3ADEV\) 394ac2916a2SAlbert ARIBAUD \(3ADEV\) /* set up transmit packet */ 395ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)dataptr, &bufs->tx_desc[tx_index].packet); 396ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(TX_CTRL_LAST | ((datasize - 1) & TX_CTRL_TXSIZE), 397ac2916a2SAlbert ARIBAUD \(3ADEV\) &bufs->tx_desc[tx_index].control); 398ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0, &bufs->tx_stat[tx_index].statusinfo); 399ac2916a2SAlbert ARIBAUD \(3ADEV\) 400ac2916a2SAlbert ARIBAUD \(3ADEV\) /* pass transmit packet to DMA engine */ 401ac2916a2SAlbert ARIBAUD \(3ADEV\) tx_index = (tx_index + 1) % TX_BUF_COUNT; 402ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(tx_index, ®s->txproduceindex); 403ac2916a2SAlbert ARIBAUD \(3ADEV\) 404ac2916a2SAlbert ARIBAUD \(3ADEV\) /* transmission succeeded */ 405ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 406ac2916a2SAlbert ARIBAUD \(3ADEV\) } 407ac2916a2SAlbert ARIBAUD \(3ADEV\) 408ac2916a2SAlbert ARIBAUD \(3ADEV\) #define RX_TIMEOUT 1000000 409ac2916a2SAlbert ARIBAUD \(3ADEV\) 410ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_recv(struct eth_device *dev) 411ac2916a2SAlbert ARIBAUD \(3ADEV\) { 412ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 413ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 414ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 415ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; 416ac2916a2SAlbert ARIBAUD \(3ADEV\) int timeout, rx_index; 417ac2916a2SAlbert ARIBAUD \(3ADEV\) 418ac2916a2SAlbert ARIBAUD \(3ADEV\) /* time out if receive descriptor array remains empty too long */ 419ac2916a2SAlbert ARIBAUD \(3ADEV\) timeout = RX_TIMEOUT; 420ac2916a2SAlbert ARIBAUD \(3ADEV\) while (readl(®s->rxproduceindex) == readl(®s->rxconsumeindex)) { 421ac2916a2SAlbert ARIBAUD \(3ADEV\) if (timeout-- == 0) 422ac2916a2SAlbert ARIBAUD \(3ADEV\) return -1; 423ac2916a2SAlbert ARIBAUD \(3ADEV\) } 424ac2916a2SAlbert ARIBAUD \(3ADEV\) 425ac2916a2SAlbert ARIBAUD \(3ADEV\) /* determine next receive packet index to use */ 426ac2916a2SAlbert ARIBAUD \(3ADEV\) rx_index = readl(®s->rxconsumeindex); 427ac2916a2SAlbert ARIBAUD \(3ADEV\) 428ac2916a2SAlbert ARIBAUD \(3ADEV\) /* if data was valid, pass it on */ 4291fd92db8SJoe Hershberger if (!(bufs->rx_stat[rx_index].statusinfo & RX_STAT_ERRORS)) { 4301fd92db8SJoe Hershberger net_process_received_packet( 4311fd92db8SJoe Hershberger &(bufs->rx_buf[rx_index * PKTSIZE_ALIGN]), 432ac2916a2SAlbert ARIBAUD \(3ADEV\) (bufs->rx_stat[rx_index].statusinfo 433ac2916a2SAlbert ARIBAUD \(3ADEV\) & RX_STAT_RXSIZE) + 1); 4341fd92db8SJoe Hershberger } 435ac2916a2SAlbert ARIBAUD \(3ADEV\) 436ac2916a2SAlbert ARIBAUD \(3ADEV\) /* pass receive slot back to DMA engine */ 437ac2916a2SAlbert ARIBAUD \(3ADEV\) rx_index = (rx_index + 1) % RX_BUF_COUNT; 438ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(rx_index, ®s->rxconsumeindex); 439ac2916a2SAlbert ARIBAUD \(3ADEV\) 440ac2916a2SAlbert ARIBAUD \(3ADEV\) /* reception successful */ 441ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 442ac2916a2SAlbert ARIBAUD \(3ADEV\) } 443ac2916a2SAlbert ARIBAUD \(3ADEV\) 444ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_write_hwaddr(struct eth_device *dev) 445ac2916a2SAlbert ARIBAUD \(3ADEV\) { 446ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 447ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 448ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 449ac2916a2SAlbert ARIBAUD \(3ADEV\) 450ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Save station address */ 451ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[0] | 452ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[1] << 8)), ®s->sa2); 453ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[2] | 454ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[3] << 8)), ®s->sa1); 455ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[4] | 456ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[5] << 8)), ®s->sa0); 457ac2916a2SAlbert ARIBAUD \(3ADEV\) 458ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 459ac2916a2SAlbert ARIBAUD \(3ADEV\) } 460ac2916a2SAlbert ARIBAUD \(3ADEV\) 461ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_init(struct eth_device *dev) 462ac2916a2SAlbert ARIBAUD \(3ADEV\) { 463ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 464ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 465ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 466ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; 467ac2916a2SAlbert ARIBAUD \(3ADEV\) int index; 468ac2916a2SAlbert ARIBAUD \(3ADEV\) 46923f5db0eSVladimir Zapolskiy /* Initial MAC initialization */ 47023f5db0eSVladimir Zapolskiy writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); 47123f5db0eSVladimir Zapolskiy writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); 47223f5db0eSVladimir Zapolskiy writel(PKTSIZE_ALIGN, ®s->maxf); 47323f5db0eSVladimir Zapolskiy 47423f5db0eSVladimir Zapolskiy /* Retries: 15 (0xF). Collision window: 57 (0x37). */ 47523f5db0eSVladimir Zapolskiy writel(0x370F, ®s->clrt); 47623f5db0eSVladimir Zapolskiy 47723f5db0eSVladimir Zapolskiy /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ 47823f5db0eSVladimir Zapolskiy writel(0x0012, ®s->ipgr); 47923f5db0eSVladimir Zapolskiy 48023f5db0eSVladimir Zapolskiy /* pass runt (smaller than 64 bytes) frames */ 4811a791892SVladimir Zapolskiy if (lpc32xx_eth_device->phy_rmii) 4821a791892SVladimir Zapolskiy writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); 4831a791892SVladimir Zapolskiy else 48423f5db0eSVladimir Zapolskiy writel(COMMAND_PASSRUNTFRAME, ®s->command); 485ac2916a2SAlbert ARIBAUD \(3ADEV\) 486ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Configure Full/Half Duplex mode */ 487ac2916a2SAlbert ARIBAUD \(3ADEV\) if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { 488ac2916a2SAlbert ARIBAUD \(3ADEV\) setbits_le32(®s->mac2, MAC2_FULL_DUPLEX); 489ac2916a2SAlbert ARIBAUD \(3ADEV\) setbits_le32(®s->command, COMMAND_FULL_DUPLEX); 490ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0x15, ®s->ipgt); 491ac2916a2SAlbert ARIBAUD \(3ADEV\) } else { 492ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0x12, ®s->ipgt); 493ac2916a2SAlbert ARIBAUD \(3ADEV\) } 494ac2916a2SAlbert ARIBAUD \(3ADEV\) 495ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Configure 100MBit/10MBit mode */ 496ac2916a2SAlbert ARIBAUD \(3ADEV\) if (miiphy_speed(dev->name, CONFIG_PHY_ADDR) == _100BASET) 497ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(SUPP_SPEED, ®s->supp); 498ac2916a2SAlbert ARIBAUD \(3ADEV\) else 499ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0, ®s->supp); 500ac2916a2SAlbert ARIBAUD \(3ADEV\) 501ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Save station address */ 502ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[0] | 503ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[1] << 8)), ®s->sa2); 504ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[2] | 505ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[3] << 8)), ®s->sa1); 506ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[4] | 507ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[5] << 8)), ®s->sa0); 508ac2916a2SAlbert ARIBAUD \(3ADEV\) 509ac2916a2SAlbert ARIBAUD \(3ADEV\) /* set up transmit buffers */ 510ac2916a2SAlbert ARIBAUD \(3ADEV\) for (index = 0; index < TX_BUF_COUNT; index++) { 511ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->tx_desc[index].control = 0; 512ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->tx_stat[index].statusinfo = 0; 513ac2916a2SAlbert ARIBAUD \(3ADEV\) } 514ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)(&bufs->tx_desc), (u32 *)®s->txdescriptor); 515ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)(&bufs->tx_stat), ®s->txstatus); 516ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(TX_BUF_COUNT-1, ®s->txdescriptornumber); 517ac2916a2SAlbert ARIBAUD \(3ADEV\) 518ac2916a2SAlbert ARIBAUD \(3ADEV\) /* set up receive buffers */ 519ac2916a2SAlbert ARIBAUD \(3ADEV\) for (index = 0; index < RX_BUF_COUNT; index++) { 520ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->rx_desc[index].packet = 521ac2916a2SAlbert ARIBAUD \(3ADEV\) (u32) (bufs->rx_buf+index*PKTSIZE_ALIGN); 522ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->rx_desc[index].control = PKTSIZE_ALIGN - 1; 523ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->rx_stat[index].statusinfo = 0; 524ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->rx_stat[index].statushashcrc = 0; 525ac2916a2SAlbert ARIBAUD \(3ADEV\) } 526ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)(&bufs->rx_desc), ®s->rxdescriptor); 527ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)(&bufs->rx_stat), ®s->rxstatus); 528ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(RX_BUF_COUNT-1, ®s->rxdescriptornumber); 529ac2916a2SAlbert ARIBAUD \(3ADEV\) 530ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Enable broadcast and matching address packets */ 531ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(RXFILTERCTRL_ACCEPTBROADCAST | 532ac2916a2SAlbert ARIBAUD \(3ADEV\) RXFILTERCTRL_ACCEPTPERFECT, ®s->rxfilterctrl); 533ac2916a2SAlbert ARIBAUD \(3ADEV\) 534ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Clear and disable interrupts */ 535ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0xFFFF, ®s->intclear); 536ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0, ®s->intenable); 537ac2916a2SAlbert ARIBAUD \(3ADEV\) 538ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Enable receive and transmit mode of MAC ethernet core */ 539ac2916a2SAlbert ARIBAUD \(3ADEV\) setbits_le32(®s->command, COMMAND_RXENABLE | COMMAND_TXENABLE); 540ac2916a2SAlbert ARIBAUD \(3ADEV\) setbits_le32(®s->mac1, MAC1_RECV_ENABLE); 541ac2916a2SAlbert ARIBAUD \(3ADEV\) 542ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 543ac2916a2SAlbert ARIBAUD \(3ADEV\) * Perform a 'dummy' first send to work around Ethernet.1 544ac2916a2SAlbert ARIBAUD \(3ADEV\) * erratum (see ES_LPC3250 rev. 9 dated 1 June 2011). 545ac2916a2SAlbert ARIBAUD \(3ADEV\) * Use zeroed "index" variable as the dummy. 546ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 547ac2916a2SAlbert ARIBAUD \(3ADEV\) 548ac2916a2SAlbert ARIBAUD \(3ADEV\) index = 0; 549ac2916a2SAlbert ARIBAUD \(3ADEV\) lpc32xx_eth_send(dev, &index, 4); 550ac2916a2SAlbert ARIBAUD \(3ADEV\) 551ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 552ac2916a2SAlbert ARIBAUD \(3ADEV\) } 553ac2916a2SAlbert ARIBAUD \(3ADEV\) 554ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_halt(struct eth_device *dev) 555ac2916a2SAlbert ARIBAUD \(3ADEV\) { 556ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 557ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 558ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 559ac2916a2SAlbert ARIBAUD \(3ADEV\) 560ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Reset all MAC logic */ 561ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(MAC1_RESETS, ®s->mac1); 562ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(COMMAND_RESETS, ®s->command); 563ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Let reset condition settle */ 564ac2916a2SAlbert ARIBAUD \(3ADEV\) udelay(2000); 565ac2916a2SAlbert ARIBAUD \(3ADEV\) 566ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 567ac2916a2SAlbert ARIBAUD \(3ADEV\) } 568ac2916a2SAlbert ARIBAUD \(3ADEV\) 569ac2916a2SAlbert ARIBAUD \(3ADEV\) #if defined(CONFIG_PHYLIB) 570ac2916a2SAlbert ARIBAUD \(3ADEV\) int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) 571ac2916a2SAlbert ARIBAUD \(3ADEV\) { 5721a791892SVladimir Zapolskiy struct lpc32xx_eth_device *lpc32xx_eth_device = 5731a791892SVladimir Zapolskiy container_of(dev, struct lpc32xx_eth_device, dev); 574ac2916a2SAlbert ARIBAUD \(3ADEV\) struct mii_dev *bus; 575ac2916a2SAlbert ARIBAUD \(3ADEV\) struct phy_device *phydev; 576ac2916a2SAlbert ARIBAUD \(3ADEV\) int ret; 577ac2916a2SAlbert ARIBAUD \(3ADEV\) 578ac2916a2SAlbert ARIBAUD \(3ADEV\) bus = mdio_alloc(); 579ac2916a2SAlbert ARIBAUD \(3ADEV\) if (!bus) { 580ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("mdio_alloc failed\n"); 581ac2916a2SAlbert ARIBAUD \(3ADEV\) return -ENOMEM; 582ac2916a2SAlbert ARIBAUD \(3ADEV\) } 583ac2916a2SAlbert ARIBAUD \(3ADEV\) bus->read = lpc32xx_eth_phy_read; 584ac2916a2SAlbert ARIBAUD \(3ADEV\) bus->write = lpc32xx_eth_phy_write; 585*192bc694SBen Whitten strcpy(bus->name, dev->name); 586ac2916a2SAlbert ARIBAUD \(3ADEV\) 587ac2916a2SAlbert ARIBAUD \(3ADEV\) ret = mdio_register(bus); 588ac2916a2SAlbert ARIBAUD \(3ADEV\) if (ret) { 589ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("mdio_register failed\n"); 590ac2916a2SAlbert ARIBAUD \(3ADEV\) free(bus); 591ac2916a2SAlbert ARIBAUD \(3ADEV\) return -ENOMEM; 592ac2916a2SAlbert ARIBAUD \(3ADEV\) } 593ac2916a2SAlbert ARIBAUD \(3ADEV\) 5941a791892SVladimir Zapolskiy if (lpc32xx_eth_device->phy_rmii) 5951a791892SVladimir Zapolskiy phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII); 5961a791892SVladimir Zapolskiy else 597ac2916a2SAlbert ARIBAUD \(3ADEV\) phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); 5981a791892SVladimir Zapolskiy 599ac2916a2SAlbert ARIBAUD \(3ADEV\) if (!phydev) { 600ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("phy_connect failed\n"); 601ac2916a2SAlbert ARIBAUD \(3ADEV\) return -ENODEV; 602ac2916a2SAlbert ARIBAUD \(3ADEV\) } 603ac2916a2SAlbert ARIBAUD \(3ADEV\) 604ac2916a2SAlbert ARIBAUD \(3ADEV\) phy_config(phydev); 605ac2916a2SAlbert ARIBAUD \(3ADEV\) phy_startup(phydev); 606ac2916a2SAlbert ARIBAUD \(3ADEV\) 607ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 608ac2916a2SAlbert ARIBAUD \(3ADEV\) } 609ac2916a2SAlbert ARIBAUD \(3ADEV\) #endif 610ac2916a2SAlbert ARIBAUD \(3ADEV\) 611ac2916a2SAlbert ARIBAUD \(3ADEV\) int lpc32xx_eth_initialize(bd_t *bis) 612ac2916a2SAlbert ARIBAUD \(3ADEV\) { 613ac2916a2SAlbert ARIBAUD \(3ADEV\) struct eth_device *dev = &lpc32xx_eth.dev; 614ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth.regs; 615ac2916a2SAlbert ARIBAUD \(3ADEV\) 616ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 617ac2916a2SAlbert ARIBAUD \(3ADEV\) * Set RMII management clock rate. With HCLK at 104 MHz and 618ac2916a2SAlbert ARIBAUD \(3ADEV\) * a divider of 28, this will be 3.72 MHz. 619ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 62023f5db0eSVladimir Zapolskiy writel(MCFG_RESET_MII_MGMT, ®s->mcfg); 621ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(MCFG_CLOCK_SELECT_DIV28, ®s->mcfg); 622ac2916a2SAlbert ARIBAUD \(3ADEV\) 623ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Reset all MAC logic */ 624ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(MAC1_RESETS, ®s->mac1); 625ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(COMMAND_RESETS, ®s->command); 626ac2916a2SAlbert ARIBAUD \(3ADEV\) 627ac2916a2SAlbert ARIBAUD \(3ADEV\) /* wait 10 ms for the whole I/F to reset */ 628ac2916a2SAlbert ARIBAUD \(3ADEV\) udelay(10000); 629ac2916a2SAlbert ARIBAUD \(3ADEV\) 630ac2916a2SAlbert ARIBAUD \(3ADEV\) /* must be less than sizeof(dev->name) */ 631ac2916a2SAlbert ARIBAUD \(3ADEV\) strcpy(dev->name, "eth0"); 632ac2916a2SAlbert ARIBAUD \(3ADEV\) 633ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->init = (void *)lpc32xx_eth_init; 634ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->halt = (void *)lpc32xx_eth_halt; 635ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->send = (void *)lpc32xx_eth_send; 636ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->recv = (void *)lpc32xx_eth_recv; 637ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->write_hwaddr = (void *)lpc32xx_eth_write_hwaddr; 638ac2916a2SAlbert ARIBAUD \(3ADEV\) 639ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Release SOFT reset to let MII talk to PHY */ 640ac2916a2SAlbert ARIBAUD \(3ADEV\) clrbits_le32(®s->mac1, MAC1_SOFT_RESET); 641ac2916a2SAlbert ARIBAUD \(3ADEV\) 642ac2916a2SAlbert ARIBAUD \(3ADEV\) /* register driver before talking to phy */ 643ac2916a2SAlbert ARIBAUD \(3ADEV\) eth_register(dev); 644ac2916a2SAlbert ARIBAUD \(3ADEV\) 645ac2916a2SAlbert ARIBAUD \(3ADEV\) #if defined(CONFIG_PHYLIB) 646fe0596caSVladimir Zapolskiy lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR); 647ac2916a2SAlbert ARIBAUD \(3ADEV\) #elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 648ac2916a2SAlbert ARIBAUD \(3ADEV\) miiphy_register(dev->name, mii_reg_read, mii_reg_write); 649ac2916a2SAlbert ARIBAUD \(3ADEV\) #endif 650ac2916a2SAlbert ARIBAUD \(3ADEV\) 651ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 652ac2916a2SAlbert ARIBAUD \(3ADEV\) } 653