1/* 2 * (C) Copyright 2011 Michal Simek 3 * Copyright 2017, DornerWorks, Ltd. 4 * 5 * Ported to seL4 6 * 7 * Michal SIMEK <monstr@monstr.eu> 8 * 9 * Based on Xilinx gmac driver: 10 * (C) Copyright 2011 Xilinx 11 * 12 * SPDX-License-Identifier: GPL-2.0+ 13 */ 14 15#include "common.h" 16#include "../io.h" 17#include "../unimplemented.h" 18#include "miiphy.h" 19#include "phy.h" 20#include "err.h" 21#include "net.h" 22#include "config.h" 23#include "system.h" 24#include "../zynq_gem.h" 25 26#include <platsupport/clock.h> 27#include <platsupport/io.h> 28 29#include <malloc.h> 30#include <errno.h> 31 32#if !defined(CONFIG_PHYLIB) 33# error XILINX_GEM_ETHERNET requires PHYLIB 34#endif 35 36#ifdef CONFIG_API 37void (*push_packet)(void *, int len) = 0; 38#endif 39 40#define ZYNQ_GEM0_PADDR 0xE000B000 41#define ZYNQ_GEM0_SIZE 0x00001000 42 43#define ZYNQ_DEFAULT_MAC "\x00\x0a\x35\x02\xff\x1e" 44 45ps_io_ops_t *zynq_io_ops; 46 47/* Initialized, rxbd_current, rx_first_buf must be 0 after init */ 48struct zynq_gem_priv { 49 struct emac_bd *tx_bd; 50 struct emac_bd *rx_bd; 51 char *vrxbuffers; 52 char *prxbuffers; 53 u32 rxbuf_offset; 54 u32 bd_phys; 55 u32 rxbd_current; 56 u32 rx_first_buf; 57 int phyaddr; 58 u32 emio; 59 int init; 60 phy_interface_t interface; 61 struct phy_device *phydev; 62 struct mii_dev *bus; 63 ps_io_ops_t *io_ops; 64}; 65 66static inline int mdio_wait(struct eth_device *dev) 67{ 68 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 69 u32 timeout = 20000; 70 71 /* Wait till MDIO interface is ready to accept a new transaction. */ 72 while (--timeout) { 73 if (readl(®s->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK) { 74 break; 75 } 76 WATCHDOG_RESET(); 77 } 78 79 if (!timeout) { 80 printf("%s: Timeout\n", __func__); 81 return 1; 82 } 83 84 return 0; 85} 86 87static u32 phy_setup_op(struct eth_device *dev, u32 phy_addr, u32 regnum, 88 u32 op, u16 *data) 89{ 90 u32 mgtcr; 91 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 92 93 if (mdio_wait(dev)) { 94 return 1; 95 } 96 97 /* Construct mgtcr mask for the operation */ 98 mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op | 99 (phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) | 100 (regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data; 101 102 /* Write mgtcr and wait for completion */ 103 writel(mgtcr, ®s->phymntnc); 104 105 if (mdio_wait(dev)) { 106 return 1; 107 } 108 109 if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK) { 110 *data = readl(®s->phymntnc); 111 } 112 113 return 0; 114} 115 116static u32 phyread(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 *val) 117{ 118 u32 ret; 119 120 ret = phy_setup_op(dev, phy_addr, regnum, 121 ZYNQ_GEM_PHYMNTNC_OP_R_MASK, val); 122 123 if (!ret) 124 debug("%s: phy_addr %d, regnum 0x%x, val 0x%x\n", __func__, 125 phy_addr, regnum, *val); 126 127 return ret; 128} 129 130static u32 phywrite(struct eth_device *dev, u32 phy_addr, u32 regnum, u16 data) 131{ 132 debug("%s: phy_addr %d, regnum 0x%x, data 0x%x\n", __func__, phy_addr, 133 regnum, data); 134 135 return phy_setup_op(dev, phy_addr, regnum, 136 ZYNQ_GEM_PHYMNTNC_OP_W_MASK, &data); 137} 138 139static int phy_detection(struct eth_device *dev) 140{ 141 int i; 142 u16 phyreg; 143 struct zynq_gem_priv *priv = dev->priv; 144 145 if (priv->phyaddr != -1) { 146 phyread(dev, priv->phyaddr, PHY_DETECT_REG, &phyreg); 147 if ((phyreg != 0xFFFF) && 148 ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { 149 /* Found a valid PHY address */ 150 debug("Default phy address %d is valid\n", 151 priv->phyaddr); 152 return 0; 153 } else { 154 debug("PHY address is not setup correctly %d\n", 155 priv->phyaddr); 156 priv->phyaddr = -1; 157 } 158 } 159 160 debug("detecting phy address\n"); 161 if (priv->phyaddr == -1) { 162 /* detect the PHY address */ 163 for (i = 31; i >= 0; i--) { 164 phyread(dev, i, PHY_DETECT_REG, &phyreg); 165 if ((phyreg != 0xFFFF) && 166 ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) { 167 /* Found a valid PHY address */ 168 priv->phyaddr = i; 169 debug("Found valid phy address, %d\n", i); 170 return 0; 171 } 172 } 173 } 174 printf("PHY is not detected\n"); 175 return -1; 176} 177 178int zynq_gem_setup_mac(struct eth_device *dev) 179{ 180 u32 i, macaddrlow, macaddrhigh; 181 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 182 183 /* Set the MAC bits [31:0] in BOT */ 184 macaddrlow = dev->enetaddr[0]; 185 macaddrlow |= dev->enetaddr[1] << 8; 186 macaddrlow |= dev->enetaddr[2] << 16; 187 macaddrlow |= dev->enetaddr[3] << 24; 188 189 /* Set MAC bits [47:32] in TOP */ 190 macaddrhigh = dev->enetaddr[4]; 191 macaddrhigh |= dev->enetaddr[5] << 8; 192 193 for (i = 0; i < 4; i++) { 194 writel(0, ®s->laddr[i][LADDR_LOW]); 195 writel(0, ®s->laddr[i][LADDR_HIGH]); 196 /* Do not use MATCHx register */ 197 writel(0, ®s->match[i]); 198 } 199 200 writel(macaddrlow, ®s->laddr[0][LADDR_LOW]); 201 writel(macaddrhigh, ®s->laddr[0][LADDR_HIGH]); 202 203 return 0; 204} 205 206void zynq_set_gem_ioops(ps_io_ops_t *io_ops) 207{ 208 zynq_io_ops = io_ops; 209} 210 211void zynq_gem_prom_enable(struct eth_device *dev) 212{ 213 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 214 215 /* Read Current Value and Set CopyAll bit */ 216 uint32_t status = readl(®s->nwcfg); 217 writel(status | ZYNQ_GEM_NWCFG_COPY_ALL, ®s->nwcfg); 218} 219 220void zynq_gem_prom_disable(struct eth_device *dev) 221{ 222 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 223 224 /* Read Current Value and Clear CopyAll bit */ 225 uint32_t status = readl(®s->nwcfg); 226 writel(status & ~ZYNQ_GEM_NWCFG_COPY_ALL, ®s->nwcfg); 227} 228 229int zynq_gem_init(struct eth_device *dev) 230{ 231 u32 i; 232 int ret; 233 unsigned long clk_rate = 0; 234 struct phy_device *phydev; 235 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 236 struct zynq_gem_priv *priv = dev->priv; 237 struct clock *gem_clk; 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 printf("zynq_gem_init: Start\n"); 246 247 if (!priv->init) { 248 /* Disable all interrupts */ 249 writel(0xFFFFFFFF, ®s->idr); 250 251 /* Disable the receiver & transmitter */ 252 writel(0, ®s->nwctrl); 253 writel(0xFFFFFFFF, ®s->txsr); 254 writel(0xFFFFFFFF, ®s->rxsr); 255 writel(0, ®s->phymntnc); 256 257 /* Clear the Hash registers for the mac address 258 * pointed by AddressPtr 259 */ 260 writel(0x0, ®s->hashl); 261 /* Write bits [63:32] in TOP */ 262 writel(0x0, ®s->hashh); 263 264 /* Clear all counters */ 265 for (i = 0; i < STAT_SIZE; i++) { 266 readl(®s->stat[i]); 267 } 268 269 /* Setup for DMA Configuration register */ 270 writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); 271 272 /* Setup for Network Control register, MDIO, Rx and Tx enable */ 273 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_MDEN_MASK); 274 275 priv->init++; 276 } 277 278 ret = phy_detection(dev); 279 if (ret) { 280 printf("GEM PHY init failed\n"); 281 return ret; 282 } 283 284 /* interface - look at tsec */ 285 phydev = phy_connect(priv->bus, priv->phyaddr, dev, 286 priv->interface); 287 288 phydev->supported = supported | ADVERTISED_Pause | 289 ADVERTISED_Asym_Pause; 290 phydev->advertising = phydev->supported; 291 priv->phydev = phydev; 292 phy_config(phydev); 293 294 ret = phy_startup(phydev); 295 if (ret) { 296 printf("phy_startup failed!\n"); 297 return ret; 298 } 299 300 if (!phydev->link) { 301 printf("%s: No link.\n", phydev->dev->name); 302 return -1; 303 } 304 305 switch (phydev->speed) { 306 case SPEED_1000: 307 writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED1000, 308 ®s->nwcfg); 309 clk_rate = ZYNQ_GEM_FREQUENCY_1000; 310 break; 311 case SPEED_100: 312 writel(ZYNQ_GEM_NWCFG_INIT | ZYNQ_GEM_NWCFG_SPEED100, 313 ®s->nwcfg); 314 clk_rate = ZYNQ_GEM_FREQUENCY_100; 315 break; 316 case SPEED_10: 317 clk_rate = ZYNQ_GEM_FREQUENCY_10; 318 break; 319 } 320 321 /* Change the rclk and clk only not using EMIO interface */ 322 if (!priv->emio) { 323 /* Set the ethernet clock frequency */ 324 gem_clk = clk_get_clock(&zynq_io_ops->clock_sys, CLK_GEM0); 325 gem_clk->init(gem_clk); 326 clk_set_freq(gem_clk, clk_rate); 327 } 328 329 /* Enable IRQs */ 330 writel((ZYNQ_GEM_IXR_FRAMERX | ZYNQ_GEM_IXR_TXCOMPLETE), ®s->ier); 331 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_TXEN_MASK); 332 333 return 0; 334} 335 336int zynq_gem_start_send(struct eth_device *dev) 337{ 338 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 339 340 /* Wait until GEM isn't sending */ 341 volatile uint32_t status = readl(®s->txsr); 342 while (status & ZYNQ_GEM_TXSR_TXGO) { 343 status = readl(®s->txsr); 344 } 345 346 /* Start transmit */ 347 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); 348 349 return 0; 350} 351 352int zynq_gem_recv_enabled(struct eth_device *dev) 353{ 354 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 355 uint32_t val; 356 /* Check Receive Enabled bit */ 357 val = readl(®s->nwctrl); 358 return (val & ZYNQ_GEM_NWCTRL_RXEN_MASK); 359} 360 361void zynq_gem_recv_enable(struct eth_device *dev) 362{ 363 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 364 365 /* Enable Receive */ 366 setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK); 367} 368 369void zynq_gem_halt(struct eth_device *dev) 370{ 371 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; 372 373 clrsetbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | 374 ZYNQ_GEM_NWCTRL_TXEN_MASK, 0); 375} 376 377static struct eth_device *gem0_dev; 378 379static int zynq_gem_miiphyread(const char *devname, uchar addr, 380 uchar reg, ushort *val) 381{ 382 struct eth_device *dev = gem0_dev; 383 int ret; 384 385 ret = phyread(dev, addr, reg, val); 386 debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, *val); 387 return ret; 388} 389 390static int zynq_gem_miiphy_write(const char *devname, uchar addr, 391 uchar reg, ushort val) 392{ 393 struct eth_device *dev = gem0_dev; 394 395 debug("%s 0x%x, 0x%x, 0x%x\n", __func__, addr, reg, val); 396 return phywrite(dev, addr, reg, val); 397} 398 399struct eth_device *zynq_gem_initialize(phys_addr_t base_addr, 400 int phy_addr, u32 emio) 401{ 402 struct eth_device *dev; 403 struct zynq_gem_priv *priv; 404 405 dev = calloc(1, sizeof(*dev)); 406 if (dev == NULL) { 407 return NULL; 408 } 409 410 dev->priv = calloc(1, sizeof(struct zynq_gem_priv)); 411 if (dev->priv == NULL) { 412 free(dev); 413 return NULL; 414 } 415 priv = dev->priv; 416 417 if (NULL == zynq_io_ops) { 418 return NULL; 419 } 420 421 priv->phyaddr = phy_addr; 422 priv->emio = emio; 423 424#ifndef CONFIG_ZYNQ_GEM_INTERFACE 425 priv->interface = PHY_INTERFACE_MODE_MII; 426#else 427 priv->interface = CONFIG_ZYNQ_GEM_INTERFACE; 428#endif 429 430 sprintf(dev->name, "Gem.%lx", base_addr); 431 432 dev->iobase = base_addr; 433 434 /* fill enetaddr */ 435 struct zynq_gem_regs *regs = (struct zynq_gem_regs *)base_addr; 436 u32 maclow = readl(®s->laddr[0][LADDR_LOW]); 437 u32 machigh = readl(®s->laddr[0][LADDR_HIGH]); 438 439 if (maclow | machigh) { 440 dev->enetaddr[0] = maclow; 441 dev->enetaddr[1] = maclow >> 8; 442 dev->enetaddr[2] = maclow >> 16; 443 dev->enetaddr[3] = maclow >> 24; 444 445 dev->enetaddr[4] = machigh; 446 dev->enetaddr[5] = machigh >> 8; 447 } else { 448 memcpy(dev->enetaddr, ZYNQ_DEFAULT_MAC, 6); 449 } 450 451 452 miiphy_register(dev->name, zynq_gem_miiphyread, zynq_gem_miiphy_write); 453 priv->bus = miiphy_get_dev_by_name(dev->name); 454 455 /* TBD: This is a bad way to handle this */ 456 gem0_dev = dev; 457 458 return dev; 459} 460