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\) */ 2295a49f174SJoe Hershberger static int mii_reg_read(struct mii_dev *bus, int phy_adr, int devad, 2305a49f174SJoe Hershberger int reg_ofs) 231ac2916a2SAlbert ARIBAUD \(3ADEV\) { 2325a49f174SJoe Hershberger u16 data = 0; 2335a49f174SJoe Hershberger struct eth_device *dev = eth_get_dev_by_name(bus->name); 234ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); 235ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; 236ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mind_reg; 237ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 timeout; 238ac2916a2SAlbert ARIBAUD \(3ADEV\) 239ac2916a2SAlbert ARIBAUD \(3ADEV\) /* check parameters */ 240ac2916a2SAlbert ARIBAUD \(3ADEV\) if (phy_adr > MII_MAX_PHY) { 241ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: Invalid PHY address %d\n", 242ac2916a2SAlbert ARIBAUD \(3ADEV\) __func__, __LINE__, phy_adr); 243ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 244ac2916a2SAlbert ARIBAUD \(3ADEV\) } 245ac2916a2SAlbert ARIBAUD \(3ADEV\) if (reg_ofs > MII_MAX_REG) { 246ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: Invalid register offset %d\n", 247ac2916a2SAlbert ARIBAUD \(3ADEV\) __func__, __LINE__, reg_ofs); 248ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 249ac2916a2SAlbert ARIBAUD \(3ADEV\) } 250ac2916a2SAlbert ARIBAUD \(3ADEV\) 251ac2916a2SAlbert ARIBAUD \(3ADEV\) /* write the phy and reg addressse into the MII address reg */ 252ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), 253ac2916a2SAlbert ARIBAUD \(3ADEV\) ®s->madr); 254ac2916a2SAlbert ARIBAUD \(3ADEV\) 255ac2916a2SAlbert ARIBAUD \(3ADEV\) /* write 1 to the MII command register to cause a read */ 256ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(1, ®s->mcmd); 257ac2916a2SAlbert ARIBAUD \(3ADEV\) 258ac2916a2SAlbert ARIBAUD \(3ADEV\) /* wait till the MII is not busy */ 259ac2916a2SAlbert ARIBAUD \(3ADEV\) timeout = MII_TIMEOUT; 260ac2916a2SAlbert ARIBAUD \(3ADEV\) do { 261ac2916a2SAlbert ARIBAUD \(3ADEV\) /* read MII indicators register */ 262ac2916a2SAlbert ARIBAUD \(3ADEV\) mind_reg = readl(®s->mind); 263ac2916a2SAlbert ARIBAUD \(3ADEV\) if (--timeout == 0) 264ac2916a2SAlbert ARIBAUD \(3ADEV\) break; 265ac2916a2SAlbert ARIBAUD \(3ADEV\) } while (mind_reg & MIND_BUSY); 266ac2916a2SAlbert ARIBAUD \(3ADEV\) 267ac2916a2SAlbert ARIBAUD \(3ADEV\) /* write 0 to the MII command register to finish the read */ 268ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0, ®s->mcmd); 269ac2916a2SAlbert ARIBAUD \(3ADEV\) 270ac2916a2SAlbert ARIBAUD \(3ADEV\) if (timeout == 0) { 271ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: MII busy timeout\n", __func__, __LINE__); 272ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 273ac2916a2SAlbert ARIBAUD \(3ADEV\) } 274ac2916a2SAlbert ARIBAUD \(3ADEV\) 2755a49f174SJoe Hershberger data = (u16) readl(®s->mrdd); 276ac2916a2SAlbert ARIBAUD \(3ADEV\) 277ac2916a2SAlbert ARIBAUD \(3ADEV\) debug("%s:(adr %d, off %d) => %04x\n", __func__, phy_adr, 2785a49f174SJoe Hershberger reg_ofs, data); 279ac2916a2SAlbert ARIBAUD \(3ADEV\) 2805a49f174SJoe Hershberger return data; 281ac2916a2SAlbert ARIBAUD \(3ADEV\) } 282ac2916a2SAlbert ARIBAUD \(3ADEV\) 283ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 284ac2916a2SAlbert ARIBAUD \(3ADEV\) * mii_reg_write - imiiphy_write callback function. 285ac2916a2SAlbert ARIBAUD \(3ADEV\) * 286ac2916a2SAlbert ARIBAUD \(3ADEV\) * Returns 0 if write succeed, -EINVAL on bad parameters 287ac2916a2SAlbert ARIBAUD \(3ADEV\) * -ETIME on timeout 288ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 2895a49f174SJoe Hershberger static int mii_reg_write(struct mii_dev *bus, int phy_adr, int devad, 2905a49f174SJoe Hershberger int reg_ofs, u16 data) 291ac2916a2SAlbert ARIBAUD \(3ADEV\) { 2925a49f174SJoe Hershberger struct eth_device *dev = eth_get_dev_by_name(bus->name); 293ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); 294ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; 295ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 mind_reg; 296ac2916a2SAlbert ARIBAUD \(3ADEV\) u32 timeout; 297ac2916a2SAlbert ARIBAUD \(3ADEV\) 298ac2916a2SAlbert ARIBAUD \(3ADEV\) /* check parameters */ 299ac2916a2SAlbert ARIBAUD \(3ADEV\) if (phy_adr > MII_MAX_PHY) { 300ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: Invalid PHY address %d\n", 301ac2916a2SAlbert ARIBAUD \(3ADEV\) __func__, __LINE__, phy_adr); 302ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 303ac2916a2SAlbert ARIBAUD \(3ADEV\) } 304ac2916a2SAlbert ARIBAUD \(3ADEV\) if (reg_ofs > MII_MAX_REG) { 305ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: Invalid register offset %d\n", 306ac2916a2SAlbert ARIBAUD \(3ADEV\) __func__, __LINE__, reg_ofs); 307ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 308ac2916a2SAlbert ARIBAUD \(3ADEV\) } 309ac2916a2SAlbert ARIBAUD \(3ADEV\) 31079206c04SVladimir Zapolskiy /* write the phy and reg addressse into the MII address reg */ 31179206c04SVladimir Zapolskiy writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET), 31279206c04SVladimir Zapolskiy ®s->madr); 31379206c04SVladimir Zapolskiy 31479206c04SVladimir Zapolskiy /* write data to the MII write register */ 31579206c04SVladimir Zapolskiy writel(data, ®s->mwtd); 31679206c04SVladimir Zapolskiy 317ac2916a2SAlbert ARIBAUD \(3ADEV\) /* wait till the MII is not busy */ 318ac2916a2SAlbert ARIBAUD \(3ADEV\) timeout = MII_TIMEOUT; 319ac2916a2SAlbert ARIBAUD \(3ADEV\) do { 320ac2916a2SAlbert ARIBAUD \(3ADEV\) /* read MII indicators register */ 321ac2916a2SAlbert ARIBAUD \(3ADEV\) mind_reg = readl(®s->mind); 322ac2916a2SAlbert ARIBAUD \(3ADEV\) if (--timeout == 0) 323ac2916a2SAlbert ARIBAUD \(3ADEV\) break; 324ac2916a2SAlbert ARIBAUD \(3ADEV\) } while (mind_reg & MIND_BUSY); 325ac2916a2SAlbert ARIBAUD \(3ADEV\) 326ac2916a2SAlbert ARIBAUD \(3ADEV\) if (timeout == 0) { 327ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("%s:%u: MII busy timeout\n", __func__, 328ac2916a2SAlbert ARIBAUD \(3ADEV\) __LINE__); 329ac2916a2SAlbert ARIBAUD \(3ADEV\) return -EFAULT; 330ac2916a2SAlbert ARIBAUD \(3ADEV\) } 331ac2916a2SAlbert ARIBAUD \(3ADEV\) 332ac2916a2SAlbert ARIBAUD \(3ADEV\) /*debug("%s:(adr %d, off %d) <= %04x\n", __func__, phy_adr, 333ac2916a2SAlbert ARIBAUD \(3ADEV\) reg_ofs, data);*/ 334ac2916a2SAlbert ARIBAUD \(3ADEV\) 335ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 336ac2916a2SAlbert ARIBAUD \(3ADEV\) } 337ac2916a2SAlbert ARIBAUD \(3ADEV\) #endif 338ac2916a2SAlbert ARIBAUD \(3ADEV\) 339ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 34068a77668SSylvain Lemieux * Provide default Ethernet buffers base address if target did not. 341ac2916a2SAlbert ARIBAUD \(3ADEV\) * Locate buffers in SRAM at 0x00001000 to avoid cache issues and 342ac2916a2SAlbert ARIBAUD \(3ADEV\) * maximize throughput. 343ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 34468a77668SSylvain Lemieux #if !defined(CONFIG_LPC32XX_ETH_BUFS_BASE) 34568a77668SSylvain Lemieux #define CONFIG_LPC32XX_ETH_BUFS_BASE 0x00001000 34668a77668SSylvain Lemieux #endif 347ac2916a2SAlbert ARIBAUD \(3ADEV\) 348ac2916a2SAlbert ARIBAUD \(3ADEV\) static struct lpc32xx_eth_device lpc32xx_eth = { 349ac2916a2SAlbert ARIBAUD \(3ADEV\) .regs = (struct lpc32xx_eth_registers *)LPC32XX_ETH_BASE, 35068a77668SSylvain Lemieux .bufs = (struct lpc32xx_eth_buffers *)CONFIG_LPC32XX_ETH_BUFS_BASE, 3511a791892SVladimir Zapolskiy #if defined(CONFIG_RMII) 3521a791892SVladimir Zapolskiy .phy_rmii = true, 3531a791892SVladimir Zapolskiy #endif 354ac2916a2SAlbert ARIBAUD \(3ADEV\) }; 355ac2916a2SAlbert ARIBAUD \(3ADEV\) 356ac2916a2SAlbert ARIBAUD \(3ADEV\) #define TX_TIMEOUT 10000 357ac2916a2SAlbert ARIBAUD \(3ADEV\) 358ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_send(struct eth_device *dev, void *dataptr, int datasize) 359ac2916a2SAlbert ARIBAUD \(3ADEV\) { 360ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 361ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 362ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 363ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; 364ac2916a2SAlbert ARIBAUD \(3ADEV\) int timeout, tx_index; 365ac2916a2SAlbert ARIBAUD \(3ADEV\) 366ac2916a2SAlbert ARIBAUD \(3ADEV\) /* time out if transmit descriptor array remains full too long */ 367ac2916a2SAlbert ARIBAUD \(3ADEV\) timeout = TX_TIMEOUT; 368ac2916a2SAlbert ARIBAUD \(3ADEV\) while ((readl(®s->status) & STATUS_TXSTATUS) && 369ac2916a2SAlbert ARIBAUD \(3ADEV\) (readl(®s->txconsumeindex) 370ac2916a2SAlbert ARIBAUD \(3ADEV\) == readl(®s->txproduceindex))) { 371ac2916a2SAlbert ARIBAUD \(3ADEV\) if (timeout-- == 0) 372ac2916a2SAlbert ARIBAUD \(3ADEV\) return -1; 373ac2916a2SAlbert ARIBAUD \(3ADEV\) } 374ac2916a2SAlbert ARIBAUD \(3ADEV\) 375ac2916a2SAlbert ARIBAUD \(3ADEV\) /* determine next transmit packet index to use */ 376ac2916a2SAlbert ARIBAUD \(3ADEV\) tx_index = readl(®s->txproduceindex); 377ac2916a2SAlbert ARIBAUD \(3ADEV\) 378ac2916a2SAlbert ARIBAUD \(3ADEV\) /* set up transmit packet */ 379ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)dataptr, &bufs->tx_desc[tx_index].packet); 380ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(TX_CTRL_LAST | ((datasize - 1) & TX_CTRL_TXSIZE), 381ac2916a2SAlbert ARIBAUD \(3ADEV\) &bufs->tx_desc[tx_index].control); 382ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0, &bufs->tx_stat[tx_index].statusinfo); 383ac2916a2SAlbert ARIBAUD \(3ADEV\) 384ac2916a2SAlbert ARIBAUD \(3ADEV\) /* pass transmit packet to DMA engine */ 385ac2916a2SAlbert ARIBAUD \(3ADEV\) tx_index = (tx_index + 1) % TX_BUF_COUNT; 386ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(tx_index, ®s->txproduceindex); 387ac2916a2SAlbert ARIBAUD \(3ADEV\) 388ac2916a2SAlbert ARIBAUD \(3ADEV\) /* transmission succeeded */ 389ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 390ac2916a2SAlbert ARIBAUD \(3ADEV\) } 391ac2916a2SAlbert ARIBAUD \(3ADEV\) 392ac2916a2SAlbert ARIBAUD \(3ADEV\) #define RX_TIMEOUT 1000000 393ac2916a2SAlbert ARIBAUD \(3ADEV\) 394ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_recv(struct eth_device *dev) 395ac2916a2SAlbert ARIBAUD \(3ADEV\) { 396ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 397ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 398ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 399ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; 400ac2916a2SAlbert ARIBAUD \(3ADEV\) int timeout, rx_index; 401ac2916a2SAlbert ARIBAUD \(3ADEV\) 402ac2916a2SAlbert ARIBAUD \(3ADEV\) /* time out if receive descriptor array remains empty too long */ 403ac2916a2SAlbert ARIBAUD \(3ADEV\) timeout = RX_TIMEOUT; 404ac2916a2SAlbert ARIBAUD \(3ADEV\) while (readl(®s->rxproduceindex) == readl(®s->rxconsumeindex)) { 405ac2916a2SAlbert ARIBAUD \(3ADEV\) if (timeout-- == 0) 406ac2916a2SAlbert ARIBAUD \(3ADEV\) return -1; 407ac2916a2SAlbert ARIBAUD \(3ADEV\) } 408ac2916a2SAlbert ARIBAUD \(3ADEV\) 409ac2916a2SAlbert ARIBAUD \(3ADEV\) /* determine next receive packet index to use */ 410ac2916a2SAlbert ARIBAUD \(3ADEV\) rx_index = readl(®s->rxconsumeindex); 411ac2916a2SAlbert ARIBAUD \(3ADEV\) 412ac2916a2SAlbert ARIBAUD \(3ADEV\) /* if data was valid, pass it on */ 4131fd92db8SJoe Hershberger if (!(bufs->rx_stat[rx_index].statusinfo & RX_STAT_ERRORS)) { 4141fd92db8SJoe Hershberger net_process_received_packet( 4151fd92db8SJoe Hershberger &(bufs->rx_buf[rx_index * PKTSIZE_ALIGN]), 416ac2916a2SAlbert ARIBAUD \(3ADEV\) (bufs->rx_stat[rx_index].statusinfo 417ac2916a2SAlbert ARIBAUD \(3ADEV\) & RX_STAT_RXSIZE) + 1); 4181fd92db8SJoe Hershberger } 419ac2916a2SAlbert ARIBAUD \(3ADEV\) 420ac2916a2SAlbert ARIBAUD \(3ADEV\) /* pass receive slot back to DMA engine */ 421ac2916a2SAlbert ARIBAUD \(3ADEV\) rx_index = (rx_index + 1) % RX_BUF_COUNT; 422ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(rx_index, ®s->rxconsumeindex); 423ac2916a2SAlbert ARIBAUD \(3ADEV\) 424ac2916a2SAlbert ARIBAUD \(3ADEV\) /* reception successful */ 425ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 426ac2916a2SAlbert ARIBAUD \(3ADEV\) } 427ac2916a2SAlbert ARIBAUD \(3ADEV\) 428ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_write_hwaddr(struct eth_device *dev) 429ac2916a2SAlbert ARIBAUD \(3ADEV\) { 430ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 431ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 432ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 433ac2916a2SAlbert ARIBAUD \(3ADEV\) 434ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Save station address */ 435ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[0] | 436ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[1] << 8)), ®s->sa2); 437ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[2] | 438ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[3] << 8)), ®s->sa1); 439ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[4] | 440ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[5] << 8)), ®s->sa0); 441ac2916a2SAlbert ARIBAUD \(3ADEV\) 442ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 443ac2916a2SAlbert ARIBAUD \(3ADEV\) } 444ac2916a2SAlbert ARIBAUD \(3ADEV\) 445ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_init(struct eth_device *dev) 446ac2916a2SAlbert ARIBAUD \(3ADEV\) { 447ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 448ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 449ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 450ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_buffers *bufs = lpc32xx_eth_device->bufs; 451ac2916a2SAlbert ARIBAUD \(3ADEV\) int index; 452ac2916a2SAlbert ARIBAUD \(3ADEV\) 45323f5db0eSVladimir Zapolskiy /* Initial MAC initialization */ 45423f5db0eSVladimir Zapolskiy writel(MAC1_PASS_ALL_RX_FRAMES, ®s->mac1); 45523f5db0eSVladimir Zapolskiy writel(MAC2_PAD_CRC_ENABLE | MAC2_CRC_ENABLE, ®s->mac2); 45623f5db0eSVladimir Zapolskiy writel(PKTSIZE_ALIGN, ®s->maxf); 45723f5db0eSVladimir Zapolskiy 45823f5db0eSVladimir Zapolskiy /* Retries: 15 (0xF). Collision window: 57 (0x37). */ 45923f5db0eSVladimir Zapolskiy writel(0x370F, ®s->clrt); 46023f5db0eSVladimir Zapolskiy 46123f5db0eSVladimir Zapolskiy /* Set IP gap pt 2 to default 0x12 but pt 1 to non-default 0 */ 46223f5db0eSVladimir Zapolskiy writel(0x0012, ®s->ipgr); 46323f5db0eSVladimir Zapolskiy 46423f5db0eSVladimir Zapolskiy /* pass runt (smaller than 64 bytes) frames */ 4651a791892SVladimir Zapolskiy if (lpc32xx_eth_device->phy_rmii) 4661a791892SVladimir Zapolskiy writel(COMMAND_PASSRUNTFRAME | COMMAND_RMII, ®s->command); 4671a791892SVladimir Zapolskiy else 46823f5db0eSVladimir Zapolskiy writel(COMMAND_PASSRUNTFRAME, ®s->command); 469ac2916a2SAlbert ARIBAUD \(3ADEV\) 470ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Configure Full/Half Duplex mode */ 471ac2916a2SAlbert ARIBAUD \(3ADEV\) if (miiphy_duplex(dev->name, CONFIG_PHY_ADDR) == FULL) { 472ac2916a2SAlbert ARIBAUD \(3ADEV\) setbits_le32(®s->mac2, MAC2_FULL_DUPLEX); 473ac2916a2SAlbert ARIBAUD \(3ADEV\) setbits_le32(®s->command, COMMAND_FULL_DUPLEX); 474ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0x15, ®s->ipgt); 475ac2916a2SAlbert ARIBAUD \(3ADEV\) } else { 476ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0x12, ®s->ipgt); 477ac2916a2SAlbert ARIBAUD \(3ADEV\) } 478ac2916a2SAlbert ARIBAUD \(3ADEV\) 479ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Configure 100MBit/10MBit mode */ 480ac2916a2SAlbert ARIBAUD \(3ADEV\) if (miiphy_speed(dev->name, CONFIG_PHY_ADDR) == _100BASET) 481ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(SUPP_SPEED, ®s->supp); 482ac2916a2SAlbert ARIBAUD \(3ADEV\) else 483ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0, ®s->supp); 484ac2916a2SAlbert ARIBAUD \(3ADEV\) 485ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Save station address */ 486ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[0] | 487ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[1] << 8)), ®s->sa2); 488ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[2] | 489ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[3] << 8)), ®s->sa1); 490ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((unsigned long) (dev->enetaddr[4] | 491ac2916a2SAlbert ARIBAUD \(3ADEV\) (dev->enetaddr[5] << 8)), ®s->sa0); 492ac2916a2SAlbert ARIBAUD \(3ADEV\) 493ac2916a2SAlbert ARIBAUD \(3ADEV\) /* set up transmit buffers */ 494ac2916a2SAlbert ARIBAUD \(3ADEV\) for (index = 0; index < TX_BUF_COUNT; index++) { 495ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->tx_desc[index].control = 0; 496ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->tx_stat[index].statusinfo = 0; 497ac2916a2SAlbert ARIBAUD \(3ADEV\) } 498ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)(&bufs->tx_desc), (u32 *)®s->txdescriptor); 499ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)(&bufs->tx_stat), ®s->txstatus); 500ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(TX_BUF_COUNT-1, ®s->txdescriptornumber); 501ac2916a2SAlbert ARIBAUD \(3ADEV\) 502ac2916a2SAlbert ARIBAUD \(3ADEV\) /* set up receive buffers */ 503ac2916a2SAlbert ARIBAUD \(3ADEV\) for (index = 0; index < RX_BUF_COUNT; index++) { 504ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->rx_desc[index].packet = 505ac2916a2SAlbert ARIBAUD \(3ADEV\) (u32) (bufs->rx_buf+index*PKTSIZE_ALIGN); 506ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->rx_desc[index].control = PKTSIZE_ALIGN - 1; 507ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->rx_stat[index].statusinfo = 0; 508ac2916a2SAlbert ARIBAUD \(3ADEV\) bufs->rx_stat[index].statushashcrc = 0; 509ac2916a2SAlbert ARIBAUD \(3ADEV\) } 510ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)(&bufs->rx_desc), ®s->rxdescriptor); 511ac2916a2SAlbert ARIBAUD \(3ADEV\) writel((u32)(&bufs->rx_stat), ®s->rxstatus); 512ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(RX_BUF_COUNT-1, ®s->rxdescriptornumber); 513ac2916a2SAlbert ARIBAUD \(3ADEV\) 514ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Enable broadcast and matching address packets */ 515ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(RXFILTERCTRL_ACCEPTBROADCAST | 516ac2916a2SAlbert ARIBAUD \(3ADEV\) RXFILTERCTRL_ACCEPTPERFECT, ®s->rxfilterctrl); 517ac2916a2SAlbert ARIBAUD \(3ADEV\) 518ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Clear and disable interrupts */ 519ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0xFFFF, ®s->intclear); 520ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(0, ®s->intenable); 521ac2916a2SAlbert ARIBAUD \(3ADEV\) 522ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Enable receive and transmit mode of MAC ethernet core */ 523ac2916a2SAlbert ARIBAUD \(3ADEV\) setbits_le32(®s->command, COMMAND_RXENABLE | COMMAND_TXENABLE); 524ac2916a2SAlbert ARIBAUD \(3ADEV\) setbits_le32(®s->mac1, MAC1_RECV_ENABLE); 525ac2916a2SAlbert ARIBAUD \(3ADEV\) 526ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 527ac2916a2SAlbert ARIBAUD \(3ADEV\) * Perform a 'dummy' first send to work around Ethernet.1 528ac2916a2SAlbert ARIBAUD \(3ADEV\) * erratum (see ES_LPC3250 rev. 9 dated 1 June 2011). 529ac2916a2SAlbert ARIBAUD \(3ADEV\) * Use zeroed "index" variable as the dummy. 530ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 531ac2916a2SAlbert ARIBAUD \(3ADEV\) 532ac2916a2SAlbert ARIBAUD \(3ADEV\) index = 0; 533ac2916a2SAlbert ARIBAUD \(3ADEV\) lpc32xx_eth_send(dev, &index, 4); 534ac2916a2SAlbert ARIBAUD \(3ADEV\) 535ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 536ac2916a2SAlbert ARIBAUD \(3ADEV\) } 537ac2916a2SAlbert ARIBAUD \(3ADEV\) 538ac2916a2SAlbert ARIBAUD \(3ADEV\) static int lpc32xx_eth_halt(struct eth_device *dev) 539ac2916a2SAlbert ARIBAUD \(3ADEV\) { 540ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_device *lpc32xx_eth_device = 541ac2916a2SAlbert ARIBAUD \(3ADEV\) container_of(dev, struct lpc32xx_eth_device, dev); 542ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth_device->regs; 543ac2916a2SAlbert ARIBAUD \(3ADEV\) 544ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Reset all MAC logic */ 545ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(MAC1_RESETS, ®s->mac1); 546ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(COMMAND_RESETS, ®s->command); 547ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Let reset condition settle */ 548ac2916a2SAlbert ARIBAUD \(3ADEV\) udelay(2000); 549ac2916a2SAlbert ARIBAUD \(3ADEV\) 550ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 551ac2916a2SAlbert ARIBAUD \(3ADEV\) } 552ac2916a2SAlbert ARIBAUD \(3ADEV\) 553ac2916a2SAlbert ARIBAUD \(3ADEV\) #if defined(CONFIG_PHYLIB) 554ac2916a2SAlbert ARIBAUD \(3ADEV\) int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid) 555ac2916a2SAlbert ARIBAUD \(3ADEV\) { 5561a791892SVladimir Zapolskiy struct lpc32xx_eth_device *lpc32xx_eth_device = 5571a791892SVladimir Zapolskiy container_of(dev, struct lpc32xx_eth_device, dev); 558ac2916a2SAlbert ARIBAUD \(3ADEV\) struct mii_dev *bus; 559ac2916a2SAlbert ARIBAUD \(3ADEV\) struct phy_device *phydev; 560ac2916a2SAlbert ARIBAUD \(3ADEV\) int ret; 561ac2916a2SAlbert ARIBAUD \(3ADEV\) 562ac2916a2SAlbert ARIBAUD \(3ADEV\) bus = mdio_alloc(); 563ac2916a2SAlbert ARIBAUD \(3ADEV\) if (!bus) { 564ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("mdio_alloc failed\n"); 565ac2916a2SAlbert ARIBAUD \(3ADEV\) return -ENOMEM; 566ac2916a2SAlbert ARIBAUD \(3ADEV\) } 567*875e0bc6SJoe Hershberger bus->read = mii_reg_read; 568*875e0bc6SJoe Hershberger bus->write = mii_reg_write; 569192bc694SBen Whitten strcpy(bus->name, dev->name); 570ac2916a2SAlbert ARIBAUD \(3ADEV\) 571ac2916a2SAlbert ARIBAUD \(3ADEV\) ret = mdio_register(bus); 572ac2916a2SAlbert ARIBAUD \(3ADEV\) if (ret) { 573ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("mdio_register failed\n"); 574ac2916a2SAlbert ARIBAUD \(3ADEV\) free(bus); 575ac2916a2SAlbert ARIBAUD \(3ADEV\) return -ENOMEM; 576ac2916a2SAlbert ARIBAUD \(3ADEV\) } 577ac2916a2SAlbert ARIBAUD \(3ADEV\) 5781a791892SVladimir Zapolskiy if (lpc32xx_eth_device->phy_rmii) 5791a791892SVladimir Zapolskiy phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RMII); 5801a791892SVladimir Zapolskiy else 581ac2916a2SAlbert ARIBAUD \(3ADEV\) phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_MII); 5821a791892SVladimir Zapolskiy 583ac2916a2SAlbert ARIBAUD \(3ADEV\) if (!phydev) { 584ac2916a2SAlbert ARIBAUD \(3ADEV\) printf("phy_connect failed\n"); 585ac2916a2SAlbert ARIBAUD \(3ADEV\) return -ENODEV; 586ac2916a2SAlbert ARIBAUD \(3ADEV\) } 587ac2916a2SAlbert ARIBAUD \(3ADEV\) 588ac2916a2SAlbert ARIBAUD \(3ADEV\) phy_config(phydev); 589ac2916a2SAlbert ARIBAUD \(3ADEV\) phy_startup(phydev); 590ac2916a2SAlbert ARIBAUD \(3ADEV\) 591ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 592ac2916a2SAlbert ARIBAUD \(3ADEV\) } 593ac2916a2SAlbert ARIBAUD \(3ADEV\) #endif 594ac2916a2SAlbert ARIBAUD \(3ADEV\) 595ac2916a2SAlbert ARIBAUD \(3ADEV\) int lpc32xx_eth_initialize(bd_t *bis) 596ac2916a2SAlbert ARIBAUD \(3ADEV\) { 597ac2916a2SAlbert ARIBAUD \(3ADEV\) struct eth_device *dev = &lpc32xx_eth.dev; 598ac2916a2SAlbert ARIBAUD \(3ADEV\) struct lpc32xx_eth_registers *regs = lpc32xx_eth.regs; 599ac2916a2SAlbert ARIBAUD \(3ADEV\) 600ac2916a2SAlbert ARIBAUD \(3ADEV\) /* 601ac2916a2SAlbert ARIBAUD \(3ADEV\) * Set RMII management clock rate. With HCLK at 104 MHz and 602ac2916a2SAlbert ARIBAUD \(3ADEV\) * a divider of 28, this will be 3.72 MHz. 603ac2916a2SAlbert ARIBAUD \(3ADEV\) */ 60423f5db0eSVladimir Zapolskiy writel(MCFG_RESET_MII_MGMT, ®s->mcfg); 605ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(MCFG_CLOCK_SELECT_DIV28, ®s->mcfg); 606ac2916a2SAlbert ARIBAUD \(3ADEV\) 607ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Reset all MAC logic */ 608ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(MAC1_RESETS, ®s->mac1); 609ac2916a2SAlbert ARIBAUD \(3ADEV\) writel(COMMAND_RESETS, ®s->command); 610ac2916a2SAlbert ARIBAUD \(3ADEV\) 611ac2916a2SAlbert ARIBAUD \(3ADEV\) /* wait 10 ms for the whole I/F to reset */ 612ac2916a2SAlbert ARIBAUD \(3ADEV\) udelay(10000); 613ac2916a2SAlbert ARIBAUD \(3ADEV\) 614ac2916a2SAlbert ARIBAUD \(3ADEV\) /* must be less than sizeof(dev->name) */ 615ac2916a2SAlbert ARIBAUD \(3ADEV\) strcpy(dev->name, "eth0"); 616ac2916a2SAlbert ARIBAUD \(3ADEV\) 617ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->init = (void *)lpc32xx_eth_init; 618ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->halt = (void *)lpc32xx_eth_halt; 619ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->send = (void *)lpc32xx_eth_send; 620ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->recv = (void *)lpc32xx_eth_recv; 621ac2916a2SAlbert ARIBAUD \(3ADEV\) dev->write_hwaddr = (void *)lpc32xx_eth_write_hwaddr; 622ac2916a2SAlbert ARIBAUD \(3ADEV\) 623ac2916a2SAlbert ARIBAUD \(3ADEV\) /* Release SOFT reset to let MII talk to PHY */ 624ac2916a2SAlbert ARIBAUD \(3ADEV\) clrbits_le32(®s->mac1, MAC1_SOFT_RESET); 625ac2916a2SAlbert ARIBAUD \(3ADEV\) 626ac2916a2SAlbert ARIBAUD \(3ADEV\) /* register driver before talking to phy */ 627ac2916a2SAlbert ARIBAUD \(3ADEV\) eth_register(dev); 628ac2916a2SAlbert ARIBAUD \(3ADEV\) 629ac2916a2SAlbert ARIBAUD \(3ADEV\) #if defined(CONFIG_PHYLIB) 630fe0596caSVladimir Zapolskiy lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR); 631ac2916a2SAlbert ARIBAUD \(3ADEV\) #elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII) 6325a49f174SJoe Hershberger int retval; 6335a49f174SJoe Hershberger struct mii_dev *mdiodev = mdio_alloc(); 6345a49f174SJoe Hershberger if (!mdiodev) 6355a49f174SJoe Hershberger return -ENOMEM; 6365a49f174SJoe Hershberger strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); 6375a49f174SJoe Hershberger mdiodev->read = mii_reg_read; 6385a49f174SJoe Hershberger mdiodev->write = mii_reg_write; 6395a49f174SJoe Hershberger 6405a49f174SJoe Hershberger retval = mdio_register(mdiodev); 6415a49f174SJoe Hershberger if (retval < 0) 6425a49f174SJoe Hershberger return retval; 643ac2916a2SAlbert ARIBAUD \(3ADEV\) #endif 644ac2916a2SAlbert ARIBAUD \(3ADEV\) 645ac2916a2SAlbert ARIBAUD \(3ADEV\) return 0; 646ac2916a2SAlbert ARIBAUD \(3ADEV\) } 647