net: fm: bug fix when CONFIG_PHYLIB not defined
[platform/kernel/u-boot.git] / drivers / net / fm / eth.c
1 /*
2  * Copyright 2009-2012 Freescale Semiconductor, Inc.
3  *      Dave Liu <daveliu@freescale.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7 #include <common.h>
8 #include <asm/io.h>
9 #include <malloc.h>
10 #include <net.h>
11 #include <hwconfig.h>
12 #include <fm_eth.h>
13 #include <fsl_mdio.h>
14 #include <miiphy.h>
15 #include <phy.h>
16 #include <asm/fsl_dtsec.h>
17 #include <asm/fsl_tgec.h>
18 #include <fsl_memac.h>
19
20 #include "fm.h"
21
22 static struct eth_device *devlist[NUM_FM_PORTS];
23 static int num_controllers;
24
25 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII)
26
27 #define TBIANA_SETTINGS (TBIANA_ASYMMETRIC_PAUSE | TBIANA_SYMMETRIC_PAUSE | \
28                          TBIANA_FULL_DUPLEX)
29
30 #define TBIANA_SGMII_ACK 0x4001
31
32 #define TBICR_SETTINGS (TBICR_ANEG_ENABLE | TBICR_RESTART_ANEG | \
33                         TBICR_FULL_DUPLEX | TBICR_SPEED1_SET)
34
35 /* Configure the TBI for SGMII operation */
36 static void dtsec_configure_serdes(struct fm_eth *priv)
37 {
38 #ifdef CONFIG_SYS_FMAN_V3
39         u32 value;
40         struct mii_dev bus;
41         bus.priv = priv->mac->phyregs;
42         bool sgmii_2500 = (priv->enet_if ==
43                         PHY_INTERFACE_MODE_SGMII_2500) ? true : false;
44
45         /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */
46         value = PHY_SGMII_IF_MODE_SGMII;
47         if (!sgmii_2500)
48                 value |= PHY_SGMII_IF_MODE_AN;
49
50         memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value);
51
52         /* Dev ability according to SGMII specification */
53         value = PHY_SGMII_DEV_ABILITY_SGMII;
54         memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x4, value);
55
56         /* Adjust link timer for SGMII  -
57         1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 */
58         memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x3);
59         memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xd40);
60
61         /* Restart AN */
62         value = PHY_SGMII_CR_DEF_VAL;
63         if (!sgmii_2500)
64                 value |= PHY_SGMII_CR_RESET_AN;
65         memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0, value);
66 #else
67         struct dtsec *regs = priv->mac->base;
68         struct tsec_mii_mng *phyregs = priv->mac->phyregs;
69
70         /*
71          * Access TBI PHY registers at given TSEC register offset as
72          * opposed to the register offset used for external PHY accesses
73          */
74         tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0, TBI_TBICON,
75                         TBICON_CLK_SELECT);
76         tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0, TBI_ANA,
77                         TBIANA_SGMII_ACK);
78         tsec_local_mdio_write(phyregs, in_be32(&regs->tbipa), 0,
79                         TBI_CR, TBICR_SETTINGS);
80 #endif
81 }
82
83 static void dtsec_init_phy(struct eth_device *dev)
84 {
85         struct fm_eth *fm_eth = dev->priv;
86 #ifndef CONFIG_SYS_FMAN_V3
87         struct dtsec *regs = (struct dtsec *)CONFIG_SYS_FSL_FM1_DTSEC1_ADDR;
88
89         /* Assign a Physical address to the TBI */
90         out_be32(&regs->tbipa, CONFIG_SYS_TBIPA_VALUE);
91 #endif
92
93         if (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII ||
94             fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII_2500)
95                 dtsec_configure_serdes(fm_eth);
96 }
97
98 #ifdef CONFIG_PHYLIB
99 static int tgec_is_fibre(struct eth_device *dev)
100 {
101         struct fm_eth *fm = dev->priv;
102         char phyopt[20];
103
104         sprintf(phyopt, "fsl_fm%d_xaui_phy", fm->fm_index + 1);
105
106         return hwconfig_arg_cmp(phyopt, "xfi");
107 }
108 #endif
109 #endif
110
111 static u16 muram_readw(u16 *addr)
112 {
113         ulong base = (ulong)addr & ~0x3UL;
114         u32 val32 = in_be32((void *)base);
115         int byte_pos;
116         u16 ret;
117
118         byte_pos = (ulong)addr & 0x3UL;
119         if (byte_pos)
120                 ret = (u16)(val32 & 0x0000ffff);
121         else
122                 ret = (u16)((val32 & 0xffff0000) >> 16);
123
124         return ret;
125 }
126
127 static void muram_writew(u16 *addr, u16 val)
128 {
129         ulong base = (ulong)addr & ~0x3UL;
130         u32 org32 = in_be32((void *)base);
131         u32 val32;
132         int byte_pos;
133
134         byte_pos = (ulong)addr & 0x3UL;
135         if (byte_pos)
136                 val32 = (org32 & 0xffff0000) | val;
137         else
138                 val32 = (org32 & 0x0000ffff) | ((u32)val << 16);
139
140         out_be32((void *)base, val32);
141 }
142
143 static void bmi_rx_port_disable(struct fm_bmi_rx_port *rx_port)
144 {
145         int timeout = 1000000;
146
147         clrbits_be32(&rx_port->fmbm_rcfg, FMBM_RCFG_EN);
148
149         /* wait until the rx port is not busy */
150         while ((in_be32(&rx_port->fmbm_rst) & FMBM_RST_BSY) && timeout--)
151                 ;
152 }
153
154 static void bmi_rx_port_init(struct fm_bmi_rx_port *rx_port)
155 {
156         /* set BMI to independent mode, Rx port disable */
157         out_be32(&rx_port->fmbm_rcfg, FMBM_RCFG_IM);
158         /* clear FOF in IM case */
159         out_be32(&rx_port->fmbm_rim, 0);
160         /* Rx frame next engine -RISC */
161         out_be32(&rx_port->fmbm_rfne, NIA_ENG_RISC | NIA_RISC_AC_IM_RX);
162         /* Rx command attribute - no order, MR[3] = 1 */
163         clrbits_be32(&rx_port->fmbm_rfca, FMBM_RFCA_ORDER | FMBM_RFCA_MR_MASK);
164         setbits_be32(&rx_port->fmbm_rfca, FMBM_RFCA_MR(4));
165         /* enable Rx statistic counters */
166         out_be32(&rx_port->fmbm_rstc, FMBM_RSTC_EN);
167         /* disable Rx performance counters */
168         out_be32(&rx_port->fmbm_rpc, 0);
169 }
170
171 static void bmi_tx_port_disable(struct fm_bmi_tx_port *tx_port)
172 {
173         int timeout = 1000000;
174
175         clrbits_be32(&tx_port->fmbm_tcfg, FMBM_TCFG_EN);
176
177         /* wait until the tx port is not busy */
178         while ((in_be32(&tx_port->fmbm_tst) & FMBM_TST_BSY) && timeout--)
179                 ;
180 }
181
182 static void bmi_tx_port_init(struct fm_bmi_tx_port *tx_port)
183 {
184         /* set BMI to independent mode, Tx port disable */
185         out_be32(&tx_port->fmbm_tcfg, FMBM_TCFG_IM);
186         /* Tx frame next engine -RISC */
187         out_be32(&tx_port->fmbm_tfne, NIA_ENG_RISC | NIA_RISC_AC_IM_TX);
188         out_be32(&tx_port->fmbm_tfene, NIA_ENG_RISC | NIA_RISC_AC_IM_TX);
189         /* Tx command attribute - no order, MR[3] = 1 */
190         clrbits_be32(&tx_port->fmbm_tfca, FMBM_TFCA_ORDER | FMBM_TFCA_MR_MASK);
191         setbits_be32(&tx_port->fmbm_tfca, FMBM_TFCA_MR(4));
192         /* enable Tx statistic counters */
193         out_be32(&tx_port->fmbm_tstc, FMBM_TSTC_EN);
194         /* disable Tx performance counters */
195         out_be32(&tx_port->fmbm_tpc, 0);
196 }
197
198 static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
199 {
200         struct fm_port_global_pram *pram;
201         u32 pram_page_offset;
202         void *rx_bd_ring_base;
203         void *rx_buf_pool;
204         u32 bd_ring_base_lo, bd_ring_base_hi;
205         u32 buf_lo, buf_hi;
206         struct fm_port_bd *rxbd;
207         struct fm_port_qd *rxqd;
208         struct fm_bmi_rx_port *bmi_rx_port = fm_eth->rx_port;
209         int i;
210
211         /* alloc global parameter ram at MURAM */
212         pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index,
213                 FM_PRAM_SIZE, FM_PRAM_ALIGN);
214         if (!pram) {
215                 printf("%s: No muram for Rx global parameter\n", __func__);
216                 return -ENOMEM;
217         }
218
219         fm_eth->rx_pram = pram;
220
221         /* parameter page offset to MURAM */
222         pram_page_offset = (void *)pram - fm_muram_base(fm_eth->fm_index);
223
224         /* enable global mode- snooping data buffers and BDs */
225         out_be32(&pram->mode, PRAM_MODE_GLOBAL);
226
227         /* init the Rx queue descriptor pionter */
228         out_be32(&pram->rxqd_ptr, pram_page_offset + 0x20);
229
230         /* set the max receive buffer length, power of 2 */
231         muram_writew(&pram->mrblr, MAX_RXBUF_LOG2);
232
233         /* alloc Rx buffer descriptors from main memory */
234         rx_bd_ring_base = malloc(sizeof(struct fm_port_bd)
235                         * RX_BD_RING_SIZE);
236         if (!rx_bd_ring_base)
237                 return -ENOMEM;
238
239         memset(rx_bd_ring_base, 0, sizeof(struct fm_port_bd)
240                         * RX_BD_RING_SIZE);
241
242         /* alloc Rx buffer from main memory */
243         rx_buf_pool = malloc(MAX_RXBUF_LEN * RX_BD_RING_SIZE);
244         if (!rx_buf_pool)
245                 return -ENOMEM;
246
247         memset(rx_buf_pool, 0, MAX_RXBUF_LEN * RX_BD_RING_SIZE);
248         debug("%s: rx_buf_pool = %p\n", __func__, rx_buf_pool);
249
250         /* save them to fm_eth */
251         fm_eth->rx_bd_ring = rx_bd_ring_base;
252         fm_eth->cur_rxbd = rx_bd_ring_base;
253         fm_eth->rx_buf = rx_buf_pool;
254
255         /* init Rx BDs ring */
256         rxbd = (struct fm_port_bd *)rx_bd_ring_base;
257         for (i = 0; i < RX_BD_RING_SIZE; i++) {
258                 muram_writew(&rxbd->status, RxBD_EMPTY);
259                 muram_writew(&rxbd->len, 0);
260                 buf_hi = upper_32_bits(virt_to_phys(rx_buf_pool +
261                                         i * MAX_RXBUF_LEN));
262                 buf_lo = lower_32_bits(virt_to_phys(rx_buf_pool +
263                                         i * MAX_RXBUF_LEN));
264                 muram_writew(&rxbd->buf_ptr_hi, (u16)buf_hi);
265                 out_be32(&rxbd->buf_ptr_lo, buf_lo);
266                 rxbd++;
267         }
268
269         /* set the Rx queue descriptor */
270         rxqd = &pram->rxqd;
271         muram_writew(&rxqd->gen, 0);
272         bd_ring_base_hi = upper_32_bits(virt_to_phys(rx_bd_ring_base));
273         bd_ring_base_lo = lower_32_bits(virt_to_phys(rx_bd_ring_base));
274         muram_writew(&rxqd->bd_ring_base_hi, (u16)bd_ring_base_hi);
275         out_be32(&rxqd->bd_ring_base_lo, bd_ring_base_lo);
276         muram_writew(&rxqd->bd_ring_size, sizeof(struct fm_port_bd)
277                         * RX_BD_RING_SIZE);
278         muram_writew(&rxqd->offset_in, 0);
279         muram_writew(&rxqd->offset_out, 0);
280
281         /* set IM parameter ram pointer to Rx Frame Queue ID */
282         out_be32(&bmi_rx_port->fmbm_rfqid, pram_page_offset);
283
284         return 0;
285 }
286
287 static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
288 {
289         struct fm_port_global_pram *pram;
290         u32 pram_page_offset;
291         void *tx_bd_ring_base;
292         u32 bd_ring_base_lo, bd_ring_base_hi;
293         struct fm_port_bd *txbd;
294         struct fm_port_qd *txqd;
295         struct fm_bmi_tx_port *bmi_tx_port = fm_eth->tx_port;
296         int i;
297
298         /* alloc global parameter ram at MURAM */
299         pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index,
300                 FM_PRAM_SIZE, FM_PRAM_ALIGN);
301         if (!pram) {
302                 printf("%s: No muram for Tx global parameter\n", __func__);
303                 return -ENOMEM;
304         }
305         fm_eth->tx_pram = pram;
306
307         /* parameter page offset to MURAM */
308         pram_page_offset = (void *)pram - fm_muram_base(fm_eth->fm_index);
309
310         /* enable global mode- snooping data buffers and BDs */
311         out_be32(&pram->mode, PRAM_MODE_GLOBAL);
312
313         /* init the Tx queue descriptor pionter */
314         out_be32(&pram->txqd_ptr, pram_page_offset + 0x40);
315
316         /* alloc Tx buffer descriptors from main memory */
317         tx_bd_ring_base = malloc(sizeof(struct fm_port_bd)
318                         * TX_BD_RING_SIZE);
319         if (!tx_bd_ring_base)
320                 return -ENOMEM;
321
322         memset(tx_bd_ring_base, 0, sizeof(struct fm_port_bd)
323                         * TX_BD_RING_SIZE);
324         /* save it to fm_eth */
325         fm_eth->tx_bd_ring = tx_bd_ring_base;
326         fm_eth->cur_txbd = tx_bd_ring_base;
327
328         /* init Tx BDs ring */
329         txbd = (struct fm_port_bd *)tx_bd_ring_base;
330         for (i = 0; i < TX_BD_RING_SIZE; i++) {
331                 muram_writew(&txbd->status, TxBD_LAST);
332                 muram_writew(&txbd->len, 0);
333                 muram_writew(&txbd->buf_ptr_hi, 0);
334                 out_be32(&txbd->buf_ptr_lo, 0);
335                 txbd++;
336         }
337
338         /* set the Tx queue decriptor */
339         txqd = &pram->txqd;
340         bd_ring_base_hi = upper_32_bits(virt_to_phys(tx_bd_ring_base));
341         bd_ring_base_lo = lower_32_bits(virt_to_phys(tx_bd_ring_base));
342         muram_writew(&txqd->bd_ring_base_hi, (u16)bd_ring_base_hi);
343         out_be32(&txqd->bd_ring_base_lo, bd_ring_base_lo);
344         muram_writew(&txqd->bd_ring_size, sizeof(struct fm_port_bd)
345                         * TX_BD_RING_SIZE);
346         muram_writew(&txqd->offset_in, 0);
347         muram_writew(&txqd->offset_out, 0);
348
349         /* set IM parameter ram pointer to Tx Confirmation Frame Queue ID */
350         out_be32(&bmi_tx_port->fmbm_tcfqid, pram_page_offset);
351
352         return 0;
353 }
354
355 static int fm_eth_init(struct fm_eth *fm_eth)
356 {
357         int ret;
358
359         ret = fm_eth_rx_port_parameter_init(fm_eth);
360         if (ret)
361                 return ret;
362
363         ret = fm_eth_tx_port_parameter_init(fm_eth);
364         if (ret)
365                 return ret;
366
367         return 0;
368 }
369
370 static int fm_eth_startup(struct fm_eth *fm_eth)
371 {
372         struct fsl_enet_mac *mac;
373         int ret;
374
375         mac = fm_eth->mac;
376
377         /* Rx/TxBDs, Rx/TxQDs, Rx buff and parameter ram init */
378         ret = fm_eth_init(fm_eth);
379         if (ret)
380                 return ret;
381         /* setup the MAC controller */
382         mac->init_mac(mac);
383
384         /* For some reason we need to set SPEED_100 */
385         if (((fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) ||
386              (fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII)) &&
387               mac->set_if_mode)
388                 mac->set_if_mode(mac, fm_eth->enet_if, SPEED_100);
389
390         /* init bmi rx port, IM mode and disable */
391         bmi_rx_port_init(fm_eth->rx_port);
392         /* init bmi tx port, IM mode and disable */
393         bmi_tx_port_init(fm_eth->tx_port);
394
395         return 0;
396 }
397
398 static void fmc_tx_port_graceful_stop_enable(struct fm_eth *fm_eth)
399 {
400         struct fm_port_global_pram *pram;
401
402         pram = fm_eth->tx_pram;
403         /* graceful stop transmission of frames */
404         setbits_be32(&pram->mode, PRAM_MODE_GRACEFUL_STOP);
405         sync();
406 }
407
408 static void fmc_tx_port_graceful_stop_disable(struct fm_eth *fm_eth)
409 {
410         struct fm_port_global_pram *pram;
411
412         pram = fm_eth->tx_pram;
413         /* re-enable transmission of frames */
414         clrbits_be32(&pram->mode, PRAM_MODE_GRACEFUL_STOP);
415         sync();
416 }
417
418 static int fm_eth_open(struct eth_device *dev, bd_t *bd)
419 {
420         struct fm_eth *fm_eth;
421         struct fsl_enet_mac *mac;
422 #ifdef CONFIG_PHYLIB
423         int ret;
424 #endif
425
426         fm_eth = (struct fm_eth *)dev->priv;
427         mac = fm_eth->mac;
428
429         /* setup the MAC address */
430         if (dev->enetaddr[0] & 0x01) {
431                 printf("%s: MacAddress is multcast address\n",  __func__);
432                 return 1;
433         }
434         mac->set_mac_addr(mac, dev->enetaddr);
435
436         /* enable bmi Rx port */
437         setbits_be32(&fm_eth->rx_port->fmbm_rcfg, FMBM_RCFG_EN);
438         /* enable MAC rx/tx port */
439         mac->enable_mac(mac);
440         /* enable bmi Tx port */
441         setbits_be32(&fm_eth->tx_port->fmbm_tcfg, FMBM_TCFG_EN);
442         /* re-enable transmission of frame */
443         fmc_tx_port_graceful_stop_disable(fm_eth);
444
445 #ifdef CONFIG_PHYLIB
446         if (fm_eth->phydev) {
447                 ret = phy_startup(fm_eth->phydev);
448                 if (ret) {
449                         printf("%s: Could not initialize\n",
450                                fm_eth->phydev->dev->name);
451                         return ret;
452                 }
453         } else {
454                 return 0;
455         }
456 #else
457         fm_eth->phydev->speed = SPEED_1000;
458         fm_eth->phydev->link = 1;
459         fm_eth->phydev->duplex = DUPLEX_FULL;
460 #endif
461
462         /* set the MAC-PHY mode */
463         mac->set_if_mode(mac, fm_eth->enet_if, fm_eth->phydev->speed);
464
465         if (!fm_eth->phydev->link)
466                 printf("%s: No link.\n", fm_eth->phydev->dev->name);
467
468         return fm_eth->phydev->link ? 0 : -1;
469 }
470
471 static void fm_eth_halt(struct eth_device *dev)
472 {
473         struct fm_eth *fm_eth;
474         struct fsl_enet_mac *mac;
475
476         fm_eth = (struct fm_eth *)dev->priv;
477         mac = fm_eth->mac;
478
479         /* graceful stop the transmission of frames */
480         fmc_tx_port_graceful_stop_enable(fm_eth);
481         /* disable bmi Tx port */
482         bmi_tx_port_disable(fm_eth->tx_port);
483         /* disable MAC rx/tx port */
484         mac->disable_mac(mac);
485         /* disable bmi Rx port */
486         bmi_rx_port_disable(fm_eth->rx_port);
487
488 #ifdef CONFIG_PHYLIB
489         if (fm_eth->phydev)
490                 phy_shutdown(fm_eth->phydev);
491 #endif
492 }
493
494 static int fm_eth_send(struct eth_device *dev, void *buf, int len)
495 {
496         struct fm_eth *fm_eth;
497         struct fm_port_global_pram *pram;
498         struct fm_port_bd *txbd, *txbd_base;
499         u16 offset_in;
500         int i;
501
502         fm_eth = (struct fm_eth *)dev->priv;
503         pram = fm_eth->tx_pram;
504         txbd = fm_eth->cur_txbd;
505
506         /* find one empty TxBD */
507         for (i = 0; muram_readw(&txbd->status) & TxBD_READY; i++) {
508                 udelay(100);
509                 if (i > 0x1000) {
510                         printf("%s: Tx buffer not ready, txbd->status = 0x%x\n",
511                                dev->name, muram_readw(&txbd->status));
512                         return 0;
513                 }
514         }
515         /* setup TxBD */
516         muram_writew(&txbd->buf_ptr_hi, (u16)upper_32_bits(virt_to_phys(buf)));
517         out_be32(&txbd->buf_ptr_lo, lower_32_bits(virt_to_phys(buf)));
518         muram_writew(&txbd->len, len);
519         sync();
520         muram_writew(&txbd->status, TxBD_READY | TxBD_LAST);
521         sync();
522
523         /* update TxQD, let RISC to send the packet */
524         offset_in = muram_readw(&pram->txqd.offset_in);
525         offset_in += sizeof(struct fm_port_bd);
526         if (offset_in >= muram_readw(&pram->txqd.bd_ring_size))
527                 offset_in = 0;
528         muram_writew(&pram->txqd.offset_in, offset_in);
529         sync();
530
531         /* wait for buffer to be transmitted */
532         for (i = 0; muram_readw(&txbd->status) & TxBD_READY; i++) {
533                 udelay(100);
534                 if (i > 0x10000) {
535                         printf("%s: Tx error, txbd->status = 0x%x\n",
536                                dev->name, muram_readw(&txbd->status));
537                         return 0;
538                 }
539         }
540
541         /* advance the TxBD */
542         txbd++;
543         txbd_base = (struct fm_port_bd *)fm_eth->tx_bd_ring;
544         if (txbd >= (txbd_base + TX_BD_RING_SIZE))
545                 txbd = txbd_base;
546         /* update current txbd */
547         fm_eth->cur_txbd = (void *)txbd;
548
549         return 1;
550 }
551
552 static int fm_eth_recv(struct eth_device *dev)
553 {
554         struct fm_eth *fm_eth;
555         struct fm_port_global_pram *pram;
556         struct fm_port_bd *rxbd, *rxbd_base;
557         u16 status, len;
558         u32 buf_lo, buf_hi;
559         u8 *data;
560         u16 offset_out;
561         int ret = 1;
562
563         fm_eth = (struct fm_eth *)dev->priv;
564         pram = fm_eth->rx_pram;
565         rxbd = fm_eth->cur_rxbd;
566         status = muram_readw(&rxbd->status);
567
568         while (!(status & RxBD_EMPTY)) {
569                 if (!(status & RxBD_ERROR)) {
570                         buf_hi = muram_readw(&rxbd->buf_ptr_hi);
571                         buf_lo = in_be32(&rxbd->buf_ptr_lo);
572                         data = (u8 *)((ulong)(buf_hi << 16) << 16 | buf_lo);
573                         len = muram_readw(&rxbd->len);
574                         net_process_received_packet(data, len);
575                 } else {
576                         printf("%s: Rx error\n", dev->name);
577                         ret = 0;
578                 }
579
580                 /* clear the RxBDs */
581                 muram_writew(&rxbd->status, RxBD_EMPTY);
582                 muram_writew(&rxbd->len, 0);
583                 sync();
584
585                 /* advance RxBD */
586                 rxbd++;
587                 rxbd_base = (struct fm_port_bd *)fm_eth->rx_bd_ring;
588                 if (rxbd >= (rxbd_base + RX_BD_RING_SIZE))
589                         rxbd = rxbd_base;
590                 /* read next status */
591                 status = muram_readw(&rxbd->status);
592
593                 /* update RxQD */
594                 offset_out = muram_readw(&pram->rxqd.offset_out);
595                 offset_out += sizeof(struct fm_port_bd);
596                 if (offset_out >= muram_readw(&pram->rxqd.bd_ring_size))
597                         offset_out = 0;
598                 muram_writew(&pram->rxqd.offset_out, offset_out);
599                 sync();
600         }
601         fm_eth->cur_rxbd = (void *)rxbd;
602
603         return ret;
604 }
605
606 static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg)
607 {
608         struct fsl_enet_mac *mac;
609         int num;
610         void *base, *phyregs = NULL;
611
612         num = fm_eth->num;
613
614 #ifdef CONFIG_SYS_FMAN_V3
615 #ifndef CONFIG_FSL_FM_10GEC_REGULAR_NOTATION
616         if (fm_eth->type == FM_ETH_10G_E) {
617                 /* 10GEC1/10GEC2 use mEMAC9/mEMAC10 on T2080/T4240.
618                  * 10GEC3/10GEC4 use mEMAC1/mEMAC2 on T2080.
619                  * 10GEC1 uses mEMAC1 on T1024.
620                  * so it needs to change the num.
621                  */
622                 if (fm_eth->num >= 2)
623                         num -= 2;
624                 else
625                         num += 8;
626         }
627 #endif
628         base = &reg->memac[num].fm_memac;
629         phyregs = &reg->memac[num].fm_memac_mdio;
630 #else
631         /* Get the mac registers base address */
632         if (fm_eth->type == FM_ETH_1G_E) {
633                 base = &reg->mac_1g[num].fm_dtesc;
634                 phyregs = &reg->mac_1g[num].fm_mdio.miimcfg;
635         } else {
636                 base = &reg->mac_10g[num].fm_10gec;
637                 phyregs = &reg->mac_10g[num].fm_10gec_mdio;
638         }
639 #endif
640
641         /* alloc mac controller */
642         mac = malloc(sizeof(struct fsl_enet_mac));
643         if (!mac)
644                 return -ENOMEM;
645         memset(mac, 0, sizeof(struct fsl_enet_mac));
646
647         /* save the mac to fm_eth struct */
648         fm_eth->mac = mac;
649
650 #ifdef CONFIG_SYS_FMAN_V3
651         init_memac(mac, base, phyregs, MAX_RXBUF_LEN);
652 #else
653         if (fm_eth->type == FM_ETH_1G_E)
654                 init_dtsec(mac, base, phyregs, MAX_RXBUF_LEN);
655         else
656                 init_tgec(mac, base, phyregs, MAX_RXBUF_LEN);
657 #endif
658
659         return 0;
660 }
661
662 static int init_phy(struct eth_device *dev)
663 {
664         struct fm_eth *fm_eth = dev->priv;
665 #ifdef CONFIG_PHYLIB
666         struct phy_device *phydev = NULL;
667         u32 supported;
668 #endif
669
670         if (fm_eth->type == FM_ETH_1G_E)
671                 dtsec_init_phy(dev);
672
673 #ifdef CONFIG_PHYLIB
674         if (fm_eth->bus) {
675                 phydev = phy_connect(fm_eth->bus, fm_eth->phyaddr, dev,
676                                         fm_eth->enet_if);
677                 if (!phydev) {
678                         printf("Failed to connect\n");
679                         return -1;
680                 }
681         } else {
682                 return 0;
683         }
684
685         if (fm_eth->type == FM_ETH_1G_E) {
686                 supported = (SUPPORTED_10baseT_Half |
687                                 SUPPORTED_10baseT_Full |
688                                 SUPPORTED_100baseT_Half |
689                                 SUPPORTED_100baseT_Full |
690                                 SUPPORTED_1000baseT_Full);
691         } else {
692                 supported = SUPPORTED_10000baseT_Full;
693
694                 if (tgec_is_fibre(dev))
695                         phydev->port = PORT_FIBRE;
696         }
697
698         phydev->supported &= supported;
699         phydev->advertising = phydev->supported;
700
701         fm_eth->phydev = phydev;
702
703         phy_config(phydev);
704 #endif
705
706         return 0;
707 }
708
709 int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info)
710 {
711         struct eth_device *dev;
712         struct fm_eth *fm_eth;
713         int i, num = info->num;
714         int ret;
715
716         /* alloc eth device */
717         dev = (struct eth_device *)malloc(sizeof(struct eth_device));
718         if (!dev)
719                 return -ENOMEM;
720         memset(dev, 0, sizeof(struct eth_device));
721
722         /* alloc the FMan ethernet private struct */
723         fm_eth = (struct fm_eth *)malloc(sizeof(struct fm_eth));
724         if (!fm_eth)
725                 return -ENOMEM;
726         memset(fm_eth, 0, sizeof(struct fm_eth));
727
728         /* save off some things we need from the info struct */
729         fm_eth->fm_index = info->index - 1; /* keep as 0 based for muram */
730         fm_eth->num = num;
731         fm_eth->type = info->type;
732
733         fm_eth->rx_port = (void *)&reg->port[info->rx_port_id - 1].fm_bmi;
734         fm_eth->tx_port = (void *)&reg->port[info->tx_port_id - 1].fm_bmi;
735
736         /* set the ethernet max receive length */
737         fm_eth->max_rx_len = MAX_RXBUF_LEN;
738
739         /* init global mac structure */
740         ret = fm_eth_init_mac(fm_eth, reg);
741         if (ret)
742                 return ret;
743
744         /* keep same as the manual, we call FMAN1, FMAN2, DTSEC1, DTSEC2, etc */
745         if (fm_eth->type == FM_ETH_1G_E)
746                 sprintf(dev->name, "FM%d@DTSEC%d", info->index, num + 1);
747         else
748                 sprintf(dev->name, "FM%d@TGEC%d", info->index, num + 1);
749
750         devlist[num_controllers++] = dev;
751         dev->iobase = 0;
752         dev->priv = (void *)fm_eth;
753         dev->init = fm_eth_open;
754         dev->halt = fm_eth_halt;
755         dev->send = fm_eth_send;
756         dev->recv = fm_eth_recv;
757         fm_eth->dev = dev;
758         fm_eth->bus = info->bus;
759         fm_eth->phyaddr = info->phy_addr;
760         fm_eth->enet_if = info->enet_if;
761
762         /* startup the FM im */
763         ret = fm_eth_startup(fm_eth);
764         if (ret)
765                 return ret;
766
767         init_phy(dev);
768
769         /* clear the ethernet address */
770         for (i = 0; i < 6; i++)
771                 dev->enetaddr[i] = 0;
772         eth_register(dev);
773
774         return 0;
775 }