1 /* 2 * (C) Copyright 2011 Michal Simek 3 * 4 * Michal SIMEK <monstr@monstr.eu> 5 * 6 * Based on Xilinx gmac driver: 7 * (C) Copyright 2011 Xilinx 8 * 9 * See file CREDITS for list of people who contributed to this 10 * project. 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License as 14 * published by the Free Software Foundation; either version 2 of 15 * the License, or (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 25 * MA 02111-1307 USA 26 */ 27 28 #include <common.h> 29 #include <net.h> 30 #include <config.h> 31 #include <malloc.h> 32 #include <asm/io.h> 33 #include <phy.h> 34 #include <miiphy.h> 35 #include <watchdog.h> 36 #include <asm/arch/sys_proto.h> 37 38 #if !defined(CONFIG_PHYLIB) 39 # error XILINX_GEM_ETHERNET requires PHYLIB 40 #endif 41 42 /* Bit/mask specification */ 43 #define ZYNQ_GEM_PHYMNTNC_OP_MASK 0x40020000 /* operation mask bits */ 44 #define ZYNQ_GEM_PHYMNTNC_OP_R_MASK 0x20000000 /* read operation */ 45 #define ZYNQ_GEM_PHYMNTNC_OP_W_MASK 0x10000000 /* write operation */ 46 #define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK 23 /* Shift bits for PHYAD */ 47 #define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK 18 /* Shift bits for PHREG */ 48 49 #define ZYNQ_GEM_RXBUF_EOF_MASK 0x00008000 /* End of frame. */ 50 #define ZYNQ_GEM_RXBUF_SOF_MASK 0x00004000 /* Start of frame. */ 51 #define ZYNQ_GEM_RXBUF_LEN_MASK 0x00003FFF /* Mask for length field */ 52 53 #define ZYNQ_GEM_RXBUF_WRAP_MASK 0x00000002 /* Wrap bit, last BD */ 54 #define ZYNQ_GEM_RXBUF_NEW_MASK 0x00000001 /* Used bit.. */ 55 #define ZYNQ_GEM_RXBUF_ADD_MASK 0xFFFFFFFC /* Mask for address */ 56 57 /* Wrap bit, last descriptor */ 58 #define ZYNQ_GEM_TXBUF_WRAP_MASK 0x40000000 59 #define ZYNQ_GEM_TXBUF_LAST_MASK 0x00008000 /* Last buffer */ 60 61 #define ZYNQ_GEM_TXSR_HRESPNOK_MASK 0x00000100 /* Transmit hresp not OK */ 62 #define ZYNQ_GEM_TXSR_URUN_MASK 0x00000040 /* Transmit underrun */ 63 /* Transmit buffs exhausted mid frame */ 64 #define ZYNQ_GEM_TXSR_BUFEXH_MASK 0x00000010 65 66 #define ZYNQ_GEM_NWCTRL_TXEN_MASK 0x00000008 /* Enable transmit */ 67 #define ZYNQ_GEM_NWCTRL_RXEN_MASK 0x00000004 /* Enable receive */ 68 #define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010 /* Enable MDIO port */ 69 #define ZYNQ_GEM_NWCTRL_STARTTX_MASK 0x00000200 /* Start tx (tx_go) */ 70 71 #define ZYNQ_GEM_NWCFG_SPEED100 0x000000001 /* 100 Mbps operation */ 72 #define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400 /* 1Gbps operation */ 73 #define ZYNQ_GEM_NWCFG_FDEN 0x000000002 /* Full Duplex mode */ 74 #define ZYNQ_GEM_NWCFG_FSREM 0x000020000 /* FCS removal */ 75 #define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */ 76 #define ZYNQ_GEM_NWCFG_MDCCLKDIV2 0x0000c0000 /* Div pclk by 48, 120MHz */ 77 78 #define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_FDEN | \ 79 ZYNQ_GEM_NWCFG_FSREM | \ 80 ZYNQ_GEM_NWCFG_MDCCLKDIV) 81 82 #define ZYNQ_GEM_NWSR_MDIOIDLE_MASK 0x00000004 /* PHY management idle */ 83 84 #define ZYNQ_GEM_DMACR_BLENGTH 0x00000004 /* INCR4 AHB bursts */ 85 /* Use full configured addressable space (8 Kb) */ 86 #define ZYNQ_GEM_DMACR_RXSIZE 0x00000300 87 /* Use full configured addressable space (4 Kb) */ 88 #define ZYNQ_GEM_DMACR_TXSIZE 0x00000400 89 /* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */ 90 #define ZYNQ_GEM_DMACR_RXBUF 0x00180000 91 92 #define ZYNQ_GEM_DMACR_INIT (ZYNQ_GEM_DMACR_BLENGTH | \ 93 ZYNQ_GEM_DMACR_RXSIZE | \ 94 ZYNQ_GEM_DMACR_TXSIZE | \ 95 ZYNQ_GEM_DMACR_RXBUF) 96 97 /* Device registers */ 98 struct zynq_gem_regs { 99 u32 nwctrl; /* Network Control reg */ 100 u32 nwcfg; /* Network Config reg */ 101 u32 nwsr; /* Network Status reg */ 102 u32 reserved1; 103 u32 dmacr; /* DMA Control reg */ 104 u32 txsr; /* TX Status reg */ 105 u32 rxqbase; /* RX Q Base address reg */ 106 u32 txqbase; /* TX Q Base address reg */ 107 u32 rxsr; /* RX Status reg */ 108 u32 reserved2[2]; 109 u32 idr; /* Interrupt Disable reg */ 110 u32 reserved3; 111 u32 phymntnc; /* Phy Maintaince reg */ 112 u32 reserved4[18]; 113 u32 hashl; /* Hash Low address reg */ 114 u32 hashh; /* Hash High address reg */ 115 #define LADDR_LOW 0 116 #define LADDR_HIGH 1 117 u32 laddr[4][LADDR_HIGH + 1]; /* Specific1 addr low/high reg */ 118 u32 match[4]; /* Type ID1 Match reg */ 119 u32 reserved6[18]; 120 u32 stat[44]; /* Octects transmitted Low reg - stat start */ 121 }; 122 123 /* BD descriptors */ 124 struct emac_bd { 125 u32 addr; /* Next descriptor pointer */ 126 u32 status; 127 }; 128 129 #define RX_BUF 3 130 131 /* Initialized, rxbd_current, rx_first_buf must be 0 after init */ 132 struct zynq_gem_priv { 133 struct emac_bd tx_bd; 134 struct emac_bd rx_bd[RX_BUF]; 135 char rxbuffers[RX_BUF * PKTSIZE_ALIGN]; 136 u32 rxbd_current; 137 u32 rx_first_buf; 138 int phyaddr; 139 int init; 140 struct phy_device *phydev; 141 struct mii_dev *bus; 142 }; 143 144 static inline int mdio_wait(struct eth_device *dev) 145 { 146 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 147 u32 timeout = 200; 148 149 /* Wait till MDIO interface is ready to accept a new transaction. */ 150 while (--timeout) { 151 if (readl(®s->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK) 152 break; 153 WATCHDOG_RESET(); 154 } 155 156 if (!timeout) { 157 printf("%s: Timeout\n", __func__); 158 return 1; 159 } 160 161 return 0; 162 } 163 164 static u32 phy_setup_op(struct eth_device *dev, u32 phy_addr, u32 regnum, 165 u32 op, u16 *data) 166 { 167 u32 mgtcr; 168 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 169 170 if (mdio_wait(dev)) 171 return 1; 172 173 /* Construct mgtcr mask for the operation */ 174 mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op | 175 (phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) | 176 (regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data; 177 178 /* Write mgtcr and wait for completion */ 179 writel(mgtcr, ®s->phymntnc); 180 181 if (mdio_wait(dev)) 182 return 1; 183 184 if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK) 185 *data = readl(®s->phymntnc); 186 187 return 0; 188 } 189 190 static u32 phyread(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 *val) 191 { 192 return phy_setup_op(dev, phy_addr, regnum, 193 ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val); 194 } 195 196 static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data) 197 { 198 return phy_setup_op(dev, phy_addr, regnum, 199 ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data); 200 } 201 202 static int zynq_gem_setup_mac(struct eth_device *dev) 203 { 204 u32 i, macaddrlow, macaddrhigh; 205 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 206 207 /* Set the MAC bits [31:0] in BOT */ 208 macaddrlow = dev->enetaddr[0]; 209 macaddrlow |= dev->enetaddr[1] << 8; 210 macaddrlow |= dev->enetaddr[2] << 16; 211 macaddrlow |= dev->enetaddr[3] << 24; 212 213 /* Set MAC bits [47:32] in TOP */ 214 macaddrhigh = dev->enetaddr[4]; 215 macaddrhigh |= dev->enetaddr[5] << 8; 216 217 for (i = 0; i < 4; i++) { 218 writel(0, ®s->laddr[i][LADDR_LOW]); 219 writel(0, ®s->laddr[i][LADDR_HIGH]); 220 /* Do not use MATCHx register */ 221 writel(0, ®s->match[i]); 222 } 223 224 writel(macaddrlow, ®s->laddr[0][LADDR_LOW]); 225 writel(macaddrhigh, ®s->laddr[0][LADDR_HIGH]); 226 227 return 0; 228 } 229 230 static int zynq_gem_init(struct eth_device *dev, bd_t * bis) 231 { 232 u32 i, rclk, clk = 0; 233 struct phy_device *phydev; 234 const u32 stat_size = (sizeof(struct zynq_gem_regs) - 235 offsetof(struct zynq_gem_regs, stat)) / 4; 236 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 237 struct zynq_gem_priv *priv = dev->priv; 238 const u32 supported = SUPPORTED_10baseT_Half | 239 SUPPORTED_10baseT_Full | 240 SUPPORTED_100baseT_Half | 241 SUPPORTED_100baseT_Full | 242 SUPPORTED_1000baseT_Half | 243 SUPPORTED_1000baseT_Full; 244 245 if (!priv->init) { 246 /* Disable all interrupts */ 247 writel(0xFFFFFFFF, ®s->idr); 248 249 /* Disable the receiver & transmitter */ 250 writel(0, ®s->nwctrl); 251 writel(0, ®s->txsr); 252 writel(0, ®s->rxsr); 253 writel(0, ®s->phymntnc); 254 255 /* Clear the Hash registers for the mac address 256 * pointed by AddressPtr 257 */ 258 writel(0x0, ®s->hashl); 259 /* Write bits [63:32] in TOP */ 260 writel(0x0, ®s->hashh); 261 262 /* Clear all counters */ 263 for (i = 0; i <= stat_size; i++) 264 readl(®s->stat[i]); 265 266 /* Setup RxBD space */ 267 memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd)); 268 /* Create the RxBD ring */ 269 memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers)); 270 271 for (i = 0; i < RX_BUF; i++) { 272 priv->rx_bd[i].status = 0xF0000000; 273 priv->rx_bd[i].addr = 274 (u32)((char *)&(priv->rxbuffers) + 275 (i * PKTSIZE_ALIGN)); 276 } 277 /* WRAP bit to last BD */ 278 priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; 279 /* Write RxBDs to IP */ 280 writel((u32)&(priv->rx_bd), ®s->rxqbase); 281 282 /* Setup for DMA Configuration register */ 283 writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); 284 285 /* Setup for Network Control register, MDIO, Rx and Tx enable */ 286 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); 287 288 priv->init++; 289 } 290 291 /* interface - look at tsec */ 292 phydev = phy_connect(priv->bus, priv->phyaddr, dev, 0); 293 294 phydev->supported = supported | ADVERTISED_Pause | 295 ADVERTISED_Asym_Pause; 296 phydev->advertising = phydev->supported; 297 priv->phydev = phydev; 298 phy_config(phydev); 299 phy_startup(phydev); 300 301 switch (phydev->speed) { 302 case SPEED_1000: 303 writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000, 304 ®s->nwcfg); 305 rclk = (0 << 4) | (1 << 0); 306 clk = (1 << 20) | (8 << 8) | (0 << 4) | (1 << 0); 307 break; 308 case SPEED_100: 309 clrsetbits_le32(®s->nwcfg, ZYNQ_GEM_NWCFG_SPEED1000, 310 ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100); 311 rclk = 1 << 0; 312 clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0); 313 break; 314 case SPEED_10: 315 rclk = 1 << 0; 316 /* FIXME untested */ 317 clk = (5 << 20) | (8 << 8) | (0 << 4) | (1 << 0); 318 break; 319 } 320 /* FIXME maybe better to define gem address in hardware.h */ 321 zynq_slcr_gem_clk_setup(dev->iobase != 0xE000B000, rclk, clk); 322 323 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | 324 ZYNQ_GEM_NWCTRL_TXEN_MASK); 325 326 return 0; 327 } 328 329 static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) 330 { 331 u32 status; 332 struct zynq_gem_priv *priv = dev->priv; 333 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 334 const u32 mask = ZYNQ_GEM_TXSR_HRESPNOK_MASK | \ 335 ZYNQ_GEM_TXSR_URUN_MASK | ZYNQ_GEM_TXSR_BUFEXH_MASK; 336 337 /* setup BD */ 338 writel((u32)&(priv->tx_bd), ®s->txqbase); 339 340 /* Setup Tx BD */ 341 memset((void *)&(priv->tx_bd), 0, sizeof(struct emac_bd)); 342 343 priv->tx_bd.addr = (u32)ptr; 344 priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK; 345 346 /* Start transmit */ 347 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); 348 349 /* Read the stat register to know if the packet has been transmitted */ 350 status = readl(®s->txsr); 351 if (status & mask) 352 printf("Something has gone wrong here!? Status is 0x%x.\n", 353 status); 354 355 /* Clear Tx status register before leaving . */ 356 writel(status, ®s->txsr); 357 return 0; 358 } 359 360 /* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */ 361 static int zynq_gem_recv(struct eth_device *dev) 362 { 363 int frame_len; 364 struct zynq_gem_priv *priv = dev->priv; 365 struct emac_bd *current_bd = &priv->rx_bd[priv->rxbd_current]; 366 struct emac_bd *first_bd; 367 368 if (!(current_bd->addr & ZYNQ_GEM_RXBUF_NEW_MASK)) 369 return 0; 370 371 if (!(current_bd->status & 372 (ZYNQ_GEM_RXBUF_SOF_MASK | ZYNQ_GEM_RXBUF_EOF_MASK))) { 373 printf("GEM: SOF or EOF not set for last buffer received!\n"); 374 return 0; 375 } 376 377 frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK; 378 if (frame_len) { 379 NetReceive((u8 *) (current_bd->addr & 380 ZYNQ_GEM_RXBUF_ADD_MASK), frame_len); 381 382 if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) 383 priv->rx_first_buf = priv->rxbd_current; 384 else { 385 current_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; 386 current_bd->status = 0xF0000000; /* FIXME */ 387 } 388 389 if (current_bd->status & ZYNQ_GEM_RXBUF_EOF_MASK) { 390 first_bd = &priv->rx_bd[priv->rx_first_buf]; 391 first_bd->addr &= ~ZYNQ_GEM_RXBUF_NEW_MASK; 392 first_bd->status = 0xF0000000; 393 } 394 395 if ((++priv->rxbd_current) >= RX_BUF) 396 priv->rxbd_current = 0; 397 } 398 399 return frame_len; 400 } 401 402 static void zynq_gem_halt(struct eth_device *dev) 403 { 404 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 405 406 clrsetbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | 407 ZYNQ_GEM_NWCTRL_TXEN_MASK, 0); 408 } 409 410 static int zynq_gem_miiphyread(const char *devname, uchar addr, 411 uchar reg, ushort *val) 412 { 413 struct eth_device *dev = eth_get_dev(); 414 int ret; 415 416 ret = phyread(dev, addr, reg, val); 417 debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val); 418 return ret; 419 } 420 421 static int zynq_gem_miiphy_write(const char *devname, uchar addr, 422 uchar reg, ushort val) 423 { 424 struct eth_device *dev = eth_get_dev(); 425 426 debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val); 427 return phywrite(dev, addr, reg, val); 428 } 429 430 int zynq_gem_initialize(bd_t *bis, int base_addr) 431 { 432 struct eth_device *dev; 433 struct zynq_gem_priv *priv; 434 435 dev = calloc(1, sizeof(*dev)); 436 if (dev == NULL) 437 return -1; 438 439 dev->priv = calloc(1, sizeof(struct zynq_gem_priv)); 440 if (dev->priv == NULL) { 441 free(dev); 442 return -1; 443 } 444 priv = dev->priv; 445 446 #ifdef CONFIG_PHY_ADDR 447 priv->phyaddr = CONFIG_PHY_ADDR; 448 #else 449 priv->phyaddr = -1; 450 #endif 451 452 sprintf(dev->name, "Gem.%x", base_addr); 453 454 dev->iobase = base_addr; 455 456 dev->init = zynq_gem_init; 457 dev->halt = zynq_gem_halt; 458 dev->send = zynq_gem_send; 459 dev->recv = zynq_gem_recv; 460 dev->write_hwaddr = zynq_gem_setup_mac; 461 462 eth_register(dev); 463 464 miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write); 465 priv->bus = miiphy_get_dev_by_name(dev->name); 466 467 return 1; 468 } 469