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