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(&regs->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, &regs->phymntnc);
104
105    if (mdio_wait(dev)) {
106        return 1;
107    }
108
109    if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK) {
110        *data = readl(&regs->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, &regs->laddr[i][LADDR_LOW]);
195        writel(0, &regs->laddr[i][LADDR_HIGH]);
196        /* Do not use MATCHx register */
197        writel(0, &regs->match[i]);
198    }
199
200    writel(macaddrlow, &regs->laddr[0][LADDR_LOW]);
201    writel(macaddrhigh, &regs->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(&regs->nwcfg);
217    writel(status | ZYNQ_GEM_NWCFG_COPY_ALL, &regs->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(&regs->nwcfg);
226    writel(status & ~ZYNQ_GEM_NWCFG_COPY_ALL, &regs->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, &regs->idr);
250
251        /* Disable the receiver & transmitter */
252        writel(0, &regs->nwctrl);
253        writel(0xFFFFFFFF, &regs->txsr);
254        writel(0xFFFFFFFF, &regs->rxsr);
255        writel(0, &regs->phymntnc);
256
257        /* Clear the Hash registers for the mac address
258         * pointed by AddressPtr
259         */
260        writel(0x0, &regs->hashl);
261        /* Write bits [63:32] in TOP */
262        writel(0x0, &regs->hashh);
263
264        /* Clear all counters */
265        for (i = 0; i < STAT_SIZE; i++) {
266            readl(&regs->stat[i]);
267        }
268
269        /* Setup for DMA Configuration register */
270        writel(ZYNQ_GEM_DMACR_INIT, &regs->dmacr);
271
272        /* Setup for Network Control register, MDIO, Rx and Tx enable */
273        setbits_le32(&regs->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               &regs->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               &regs->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), &regs->ier);
331    setbits_le32(&regs->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(&regs->txsr);
342    while (status & ZYNQ_GEM_TXSR_TXGO) {
343        status = readl(&regs->txsr);
344    }
345
346    /* Start transmit */
347    setbits_le32(&regs->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(&regs->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(&regs->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(&regs->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(&regs->laddr[0][LADDR_LOW]);
437    u32 machigh = readl(&regs->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