mvgbe.c (e9bf75c9d3b2494c985fd4a21db8036b493fbd11) mvgbe.c (fb7310769882c2fb9716352a78744327e72c2430)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2009
4 * Marvell Semiconductor <www.marvell.com>
5 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
6 *
7 * (C) Copyright 2003
8 * Ingo Assmus <ingo.assmus@keymile.com>
9 *
10 * based on - Driver for MV64360X ethernet ports
11 * Copyright (C) 2002 rabeeh@galileo.co.il
12 */
13
14#include <common.h>
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2009
4 * Marvell Semiconductor <www.marvell.com>
5 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
6 *
7 * (C) Copyright 2003
8 * Ingo Assmus <ingo.assmus@keymile.com>
9 *
10 * based on - Driver for MV64360X ethernet ports
11 * Copyright (C) 2002 rabeeh@galileo.co.il
12 */
13
14#include <common.h>
15#include <dm.h>
15#include <net.h>
16#include <malloc.h>
17#include <miiphy.h>
18#include <wait_bit.h>
19#include <asm/io.h>
20#include <linux/errno.h>
21#include <asm/types.h>
22#include <asm/system.h>

--- 99 unchanged lines hidden (view full) ---

122/*
123 * smi_reg_read - miiphy_read callback function.
124 *
125 * Returns 16bit phy register value, or -EFAULT on error
126 */
127static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
128 int reg_ofs)
129{
16#include <net.h>
17#include <malloc.h>
18#include <miiphy.h>
19#include <wait_bit.h>
20#include <asm/io.h>
21#include <linux/errno.h>
22#include <asm/types.h>
23#include <asm/system.h>

--- 99 unchanged lines hidden (view full) ---

123/*
124 * smi_reg_read - miiphy_read callback function.
125 *
126 * Returns 16bit phy register value, or -EFAULT on error
127 */
128static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
129 int reg_ofs)
130{
131#ifdef CONFIG_DM_ETH
132 struct mvgbe_device *dmvgbe = bus->priv;
133#else
130 struct eth_device *dev = eth_get_dev_by_name(bus->name);
131 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
134 struct eth_device *dev = eth_get_dev_by_name(bus->name);
135 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
136#endif
132
133 return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
134}
135
136static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
137 int devad, int reg_ofs, u16 data)
138{
139 struct mvgbe_registers *regs = dmvgbe->regs;

--- 35 unchanged lines hidden (view full) ---

175/*
176 * smi_reg_write - miiphy_write callback function.
177 *
178 * Returns 0 if write succeed, -EFAULT on error
179 */
180static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
181 int reg_ofs, u16 data)
182{
137
138 return __mvgbe_mdio_read(dmvgbe, phy_adr, devad, reg_ofs);
139}
140
141static int __mvgbe_mdio_write(struct mvgbe_device *dmvgbe, int phy_adr,
142 int devad, int reg_ofs, u16 data)
143{
144 struct mvgbe_registers *regs = dmvgbe->regs;

--- 35 unchanged lines hidden (view full) ---

180/*
181 * smi_reg_write - miiphy_write callback function.
182 *
183 * Returns 0 if write succeed, -EFAULT on error
184 */
185static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
186 int reg_ofs, u16 data)
187{
188#ifdef CONFIG_DM_ETH
189 struct mvgbe_device *dmvgbe = bus->priv;
190#else
183 struct eth_device *dev = eth_get_dev_by_name(bus->name);
184 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
191 struct eth_device *dev = eth_get_dev_by_name(bus->name);
192 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
193#endif
185
186 return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
187}
188#endif
189
190/* Stop and checks all queues */
191static void stop_queue(u32 * qreg)
192{

--- 217 unchanged lines hidden (view full) ---

410 p_rx_desc->nxtdesc_p = (struct mvgbe_rxdesc *)
411 ((u32) p_rx_desc + MV_RXQ_DESC_ALIGNED_SIZE);
412 p_rx_desc = p_rx_desc->nxtdesc_p;
413 }
414 }
415 dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
416}
417
194
195 return __mvgbe_mdio_write(dmvgbe, phy_adr, devad, reg_ofs, data);
196}
197#endif
198
199/* Stop and checks all queues */
200static void stop_queue(u32 * qreg)
201{

--- 217 unchanged lines hidden (view full) ---

419 p_rx_desc->nxtdesc_p = (struct mvgbe_rxdesc *)
420 ((u32) p_rx_desc + MV_RXQ_DESC_ALIGNED_SIZE);
421 p_rx_desc = p_rx_desc->nxtdesc_p;
422 }
423 }
424 dmvgbe->p_rxdesc_curr = dmvgbe->p_rxdesc;
425}
426
418static int __mvgbe_init(struct mvgbe_device *dmvgbe)
427static int __mvgbe_init(struct mvgbe_device *dmvgbe, u8 *enetaddr,
428 const char *name)
419{
420 struct mvgbe_registers *regs = dmvgbe->regs;
421#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
422 !defined(CONFIG_PHYLIB) && \
429{
430 struct mvgbe_registers *regs = dmvgbe->regs;
431#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
432 !defined(CONFIG_PHYLIB) && \
433 !defined(CONFIG_DM_ETH) && \
423 defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
424 int i;
425#endif
426 /* setup RX rings */
427 mvgbe_init_rx_desc_ring(dmvgbe);
428
429 /* Clear the ethernet port interrupts */
430 MVGBE_REG_WR(regs->ic, 0);
431 MVGBE_REG_WR(regs->ice, 0);
432 /* Unmask RX buffer and TX end interrupt */
433 MVGBE_REG_WR(regs->pim, INT_CAUSE_UNMASK_ALL);
434 /* Unmask phy and link status changes interrupts */
435 MVGBE_REG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT);
436
437 set_dram_access(regs);
438 port_init_mac_tables(regs);
434 defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
435 int i;
436#endif
437 /* setup RX rings */
438 mvgbe_init_rx_desc_ring(dmvgbe);
439
440 /* Clear the ethernet port interrupts */
441 MVGBE_REG_WR(regs->ic, 0);
442 MVGBE_REG_WR(regs->ice, 0);
443 /* Unmask RX buffer and TX end interrupt */
444 MVGBE_REG_WR(regs->pim, INT_CAUSE_UNMASK_ALL);
445 /* Unmask phy and link status changes interrupts */
446 MVGBE_REG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT);
447
448 set_dram_access(regs);
449 port_init_mac_tables(regs);
439 port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
450 port_uc_addr_set(dmvgbe, enetaddr);
440
441 /* Assign port configuration and command. */
442 MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
443 MVGBE_REG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE);
444 MVGBE_REG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE);
445
446 /* Assign port SDMA configuration */
447 MVGBE_REG_WR(regs->sdc, PORT_SDMA_CFG_VALUE);

--- 20 unchanged lines hidden (view full) ---

468 MVGBE_REG_WR(regs->rxcdp[RXUQ], (u32) dmvgbe->p_rxdesc_curr);
469 /* ensure previous write is done before enabling Rx DMA */
470 isb();
471 /* Enable port Rx. */
472 MVGBE_REG_WR(regs->rqc, (1 << RXUQ));
473
474#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
475 !defined(CONFIG_PHYLIB) && \
451
452 /* Assign port configuration and command. */
453 MVGBE_REG_WR(regs->pxc, PRT_CFG_VAL);
454 MVGBE_REG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE);
455 MVGBE_REG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE);
456
457 /* Assign port SDMA configuration */
458 MVGBE_REG_WR(regs->sdc, PORT_SDMA_CFG_VALUE);

--- 20 unchanged lines hidden (view full) ---

479 MVGBE_REG_WR(regs->rxcdp[RXUQ], (u32) dmvgbe->p_rxdesc_curr);
480 /* ensure previous write is done before enabling Rx DMA */
481 isb();
482 /* Enable port Rx. */
483 MVGBE_REG_WR(regs->rqc, (1 << RXUQ));
484
485#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \
486 !defined(CONFIG_PHYLIB) && \
487 !defined(CONFIG_DM_ETH) && \
476 defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
477 /* Wait up to 5s for the link status */
478 for (i = 0; i < 5; i++) {
479 u16 phyadr;
480
488 defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
489 /* Wait up to 5s for the link status */
490 for (i = 0; i < 5; i++) {
491 u16 phyadr;
492
481 miiphy_read(dmvgbe->dev.name, MV_PHY_ADR_REQUEST,
493 miiphy_read(name, MV_PHY_ADR_REQUEST,
482 MV_PHY_ADR_REQUEST, &phyadr);
483 /* Return if we get link up */
494 MV_PHY_ADR_REQUEST, &phyadr);
495 /* Return if we get link up */
484 if (miiphy_link(dmvgbe->dev.name, phyadr))
496 if (miiphy_link(name, phyadr))
485 return 0;
486 udelay(1000000);
487 }
488
497 return 0;
498 udelay(1000000);
499 }
500
489 printf("No link on %s\n", dmvgbe->dev.name);
501 printf("No link on %s\n", name);
490 return -1;
491#endif
492 return 0;
493}
494
502 return -1;
503#endif
504 return 0;
505}
506
507#ifndef CONFIG_DM_ETH
495static int mvgbe_init(struct eth_device *dev)
496{
497 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
498
508static int mvgbe_init(struct eth_device *dev)
509{
510 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
511
499 return __mvgbe_init(dmvgbe);
512 return __mvgbe_init(dmvgbe, dmvgbe->dev.enetaddr, dmvgbe->dev.name);
500}
513}
514#endif
501
502static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
503{
504 struct mvgbe_registers *regs = dmvgbe->regs;
505
506 /* Disable all gigE address decoder */
507 MVGBE_REG_WR(regs->bare, 0x3f);
508

--- 10 unchanged lines hidden (view full) ---

519#endif
520 /* Disable & mask ethernet port interrupts */
521 MVGBE_REG_WR(regs->ic, 0);
522 MVGBE_REG_WR(regs->ice, 0);
523 MVGBE_REG_WR(regs->pim, 0);
524 MVGBE_REG_WR(regs->peim, 0);
525}
526
515
516static void __mvgbe_halt(struct mvgbe_device *dmvgbe)
517{
518 struct mvgbe_registers *regs = dmvgbe->regs;
519
520 /* Disable all gigE address decoder */
521 MVGBE_REG_WR(regs->bare, 0x3f);
522

--- 10 unchanged lines hidden (view full) ---

533#endif
534 /* Disable & mask ethernet port interrupts */
535 MVGBE_REG_WR(regs->ic, 0);
536 MVGBE_REG_WR(regs->ice, 0);
537 MVGBE_REG_WR(regs->pim, 0);
538 MVGBE_REG_WR(regs->peim, 0);
539}
540
541#ifndef CONFIG_DM_ETH
527static int mvgbe_halt(struct eth_device *dev)
528{
529 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
530
531 __mvgbe_halt(dmvgbe);
532
533 return 0;
534}
542static int mvgbe_halt(struct eth_device *dev)
543{
544 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
545
546 __mvgbe_halt(dmvgbe);
547
548 return 0;
549}
550#endif
535
551
552#ifdef CONFIG_DM_ETH
553static int mvgbe_write_hwaddr(struct udevice *dev)
554{
555 struct eth_pdata *pdata = dev_get_platdata(dev);
556
557 port_uc_addr_set(dev_get_priv(dev), pdata->enetaddr);
558
559 return 0;
560}
561#else
536static int mvgbe_write_hwaddr(struct eth_device *dev)
537{
538 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
539
540 /* Programs net device MAC address after initialization */
541 port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
542 return 0;
543}
562static int mvgbe_write_hwaddr(struct eth_device *dev)
563{
564 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
565
566 /* Programs net device MAC address after initialization */
567 port_uc_addr_set(dmvgbe, dmvgbe->dev.enetaddr);
568 return 0;
569}
570#endif
544
545static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
546 int datasize)
547{
548 struct mvgbe_registers *regs = dmvgbe->regs;
549 struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc;
550 void *p = (void *)dataptr;
551 u32 cmd_sts;

--- 40 unchanged lines hidden (view full) ---

592 printf("Err..(%s) in xmit packet\n", __func__);
593 return -1;
594 }
595 cmd_sts = readl(&p_txdesc->cmd_sts);
596 };
597 return 0;
598}
599
571
572static int __mvgbe_send(struct mvgbe_device *dmvgbe, void *dataptr,
573 int datasize)
574{
575 struct mvgbe_registers *regs = dmvgbe->regs;
576 struct mvgbe_txdesc *p_txdesc = dmvgbe->p_txdesc;
577 void *p = (void *)dataptr;
578 u32 cmd_sts;

--- 40 unchanged lines hidden (view full) ---

619 printf("Err..(%s) in xmit packet\n", __func__);
620 return -1;
621 }
622 cmd_sts = readl(&p_txdesc->cmd_sts);
623 };
624 return 0;
625}
626
627#ifndef CONFIG_DM_ETH
600static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
601{
602 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
603
604 return __mvgbe_send(dmvgbe, dataptr, datasize);
605}
628static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
629{
630 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
631
632 return __mvgbe_send(dmvgbe, dataptr, datasize);
633}
634#endif
606
607static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
608{
609 struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr;
610 u32 cmd_sts;
611 u32 timeout = 0;
612 u32 rxdesc_curr_addr;
613 unsigned char *data;

--- 58 unchanged lines hidden (view full) ---

672 p_rxdesc_curr->byte_cnt = 0;
673
674 rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr;
675 writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr);
676
677 return rx_bytes;
678}
679
635
636static int __mvgbe_recv(struct mvgbe_device *dmvgbe, uchar **packetp)
637{
638 struct mvgbe_rxdesc *p_rxdesc_curr = dmvgbe->p_rxdesc_curr;
639 u32 cmd_sts;
640 u32 timeout = 0;
641 u32 rxdesc_curr_addr;
642 unsigned char *data;

--- 58 unchanged lines hidden (view full) ---

701 p_rxdesc_curr->byte_cnt = 0;
702
703 rxdesc_curr_addr = (u32)&dmvgbe->p_rxdesc_curr;
704 writel((unsigned)p_rxdesc_curr->nxtdesc_p, rxdesc_curr_addr);
705
706 return rx_bytes;
707}
708
709#ifndef CONFIG_DM_ETH
680static int mvgbe_recv(struct eth_device *dev)
681{
682 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
683 uchar *packet;
684 int ret;
685
686 ret = __mvgbe_recv(dmvgbe, &packet);
687 if (ret < 0)
688 return ret;
689
690 net_process_received_packet(packet, ret);
691
692 return 0;
693}
710static int mvgbe_recv(struct eth_device *dev)
711{
712 struct mvgbe_device *dmvgbe = to_mvgbe(dev);
713 uchar *packet;
714 int ret;
715
716 ret = __mvgbe_recv(dmvgbe, &packet);
717 if (ret < 0)
718 return ret;
719
720 net_process_received_packet(packet, ret);
721
722 return 0;
723}
724#endif
694
725
695#if defined(CONFIG_PHYLIB)
726#if defined(CONFIG_PHYLIB) || defined(CONFIG_DM_ETH)
727#if defined(CONFIG_DM_ETH)
728static struct phy_device *__mvgbe_phy_init(struct udevice *dev,
729 struct mii_dev *bus,
730 phy_interface_t phy_interface,
731 int phyid)
732#else
733static struct phy_device *__mvgbe_phy_init(struct eth_device *dev,
734 struct mii_dev *bus,
735 phy_interface_t phy_interface,
736 int phyid)
737#endif
738{
739 struct phy_device *phydev;
740
741 /* Set phy address of the port */
742 miiphy_write(dev->name, MV_PHY_ADR_REQUEST, MV_PHY_ADR_REQUEST,
743 phyid);
744
745 phydev = phy_connect(bus, phyid, dev, phy_interface);
746 if (!phydev) {
747 printf("phy_connect failed\n");
748 return NULL;
749 }
750
751 phy_config(phydev);
752 phy_startup(phydev);
753
754 return phydev;
755}
756#endif /* CONFIG_PHYLIB || CONFIG_DM_ETH */
757
758#if defined(CONFIG_PHYLIB) && !defined(CONFIG_DM_ETH)
696int mvgbe_phylib_init(struct eth_device *dev, int phyid)
697{
698 struct mii_dev *bus;
699 struct phy_device *phydev;
700 int ret;
701
702 bus = mdio_alloc();
703 if (!bus) {

--- 6 unchanged lines hidden (view full) ---

710
711 ret = mdio_register(bus);
712 if (ret) {
713 printf("mdio_register failed\n");
714 free(bus);
715 return -ENOMEM;
716 }
717
759int mvgbe_phylib_init(struct eth_device *dev, int phyid)
760{
761 struct mii_dev *bus;
762 struct phy_device *phydev;
763 int ret;
764
765 bus = mdio_alloc();
766 if (!bus) {

--- 6 unchanged lines hidden (view full) ---

773
774 ret = mdio_register(bus);
775 if (ret) {
776 printf("mdio_register failed\n");
777 free(bus);
778 return -ENOMEM;
779 }
780
718 /* Set phy address of the port */
719 smi_reg_write(bus, MV_PHY_ADR_REQUEST, 0, MV_PHY_ADR_REQUEST, phyid);
720
721 phydev = phy_connect(bus, phyid, dev, PHY_INTERFACE_MODE_RGMII);
722 if (!phydev) {
723 printf("phy_connect failed\n");
781 phydev = __mvgbe_phy_init(dev, bus, PHY_INTERFACE_MODE_RGMII, phyid);
782 if (!phydev)
724 return -ENODEV;
783 return -ENODEV;
725 }
726
784
727 phy_config(phydev);
728 phy_startup(phydev);
729
730 return 0;
731}
732#endif
733
785 return 0;
786}
787#endif
788
789static int mvgbe_alloc_buffers(struct mvgbe_device *dmvgbe)
790{
791 dmvgbe->p_rxdesc = memalign(PKTALIGN,
792 MV_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
793 if (!dmvgbe->p_rxdesc)
794 goto error1;
795
796 dmvgbe->p_rxbuf = memalign(PKTALIGN,
797 RINGSZ * PKTSIZE_ALIGN + 1);
798 if (!dmvgbe->p_rxbuf)
799 goto error2;
800
801 dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
802 if (!dmvgbe->p_aligned_txbuf)
803 goto error3;
804
805 dmvgbe->p_txdesc = memalign(PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
806 if (!dmvgbe->p_txdesc)
807 goto error4;
808
809 return 0;
810
811error4:
812 free(dmvgbe->p_aligned_txbuf);
813error3:
814 free(dmvgbe->p_rxbuf);
815error2:
816 free(dmvgbe->p_rxdesc);
817error1:
818 return -ENOMEM;
819}
820
821#ifndef CONFIG_DM_ETH
734int mvgbe_initialize(bd_t *bis)
735{
736 struct mvgbe_device *dmvgbe;
737 struct eth_device *dev;
738 int devnum;
822int mvgbe_initialize(bd_t *bis)
823{
824 struct mvgbe_device *dmvgbe;
825 struct eth_device *dev;
826 int devnum;
827 int ret;
739 u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
740
741 for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
742 /*skip if port is configured not to use */
743 if (used_ports[devnum] == 0)
744 continue;
745
746 dmvgbe = malloc(sizeof(struct mvgbe_device));
828 u8 used_ports[MAX_MVGBE_DEVS] = CONFIG_MVGBE_PORTS;
829
830 for (devnum = 0; devnum < MAX_MVGBE_DEVS; devnum++) {
831 /*skip if port is configured not to use */
832 if (used_ports[devnum] == 0)
833 continue;
834
835 dmvgbe = malloc(sizeof(struct mvgbe_device));
747
748 if (!dmvgbe)
836 if (!dmvgbe)
749 goto error1;
837 return -ENOMEM;
750
751 memset(dmvgbe, 0, sizeof(struct mvgbe_device));
838
839 memset(dmvgbe, 0, sizeof(struct mvgbe_device));
752
753 dmvgbe->p_rxdesc =
754 (struct mvgbe_rxdesc *)memalign(PKTALIGN,
755 MV_RXQ_DESC_ALIGNED_SIZE*RINGSZ + 1);
756
757 if (!dmvgbe->p_rxdesc)
758 goto error2;
759
760 dmvgbe->p_rxbuf = (u8 *) memalign(PKTALIGN,
761 RINGSZ*PKTSIZE_ALIGN + 1);
762
763 if (!dmvgbe->p_rxbuf)
764 goto error3;
765
766 dmvgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
767
768 if (!dmvgbe->p_aligned_txbuf)
769 goto error4;
770
771 dmvgbe->p_txdesc = (struct mvgbe_txdesc *) memalign(
772 PKTALIGN, sizeof(struct mvgbe_txdesc) + 1);
773
774 if (!dmvgbe->p_txdesc) {
775 free(dmvgbe->p_aligned_txbuf);
776error4:
777 free(dmvgbe->p_rxbuf);
778error3:
779 free(dmvgbe->p_rxdesc);
780error2:
781 free(dmvgbe);
782error1:
840 ret = mvgbe_alloc_buffers(dmvgbe);
841 if (ret) {
783 printf("Err.. %s Failed to allocate memory\n",
784 __func__);
842 printf("Err.. %s Failed to allocate memory\n",
843 __func__);
785 return -1;
844 free(dmvgbe);
845 return ret;
786 }
787
788 dev = &dmvgbe->dev;
789
790 /* must be less than sizeof(dev->name) */
791 sprintf(dev->name, "egiga%d", devnum);
792
793 switch (devnum) {

--- 35 unchanged lines hidden (view full) ---

829 return retval;
830 /* Set phy address of the port */
831 miiphy_write(dev->name, MV_PHY_ADR_REQUEST,
832 MV_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);
833#endif
834 }
835 return 0;
836}
846 }
847
848 dev = &dmvgbe->dev;
849
850 /* must be less than sizeof(dev->name) */
851 sprintf(dev->name, "egiga%d", devnum);
852
853 switch (devnum) {

--- 35 unchanged lines hidden (view full) ---

889 return retval;
890 /* Set phy address of the port */
891 miiphy_write(dev->name, MV_PHY_ADR_REQUEST,
892 MV_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);
893#endif
894 }
895 return 0;
896}
897#endif
898
899#ifdef CONFIG_DM_ETH
900static int mvgbe_port_is_fixed_link(struct mvgbe_device *dmvgbe)
901{
902 return dmvgbe->phyaddr > PHY_MAX_ADDR;
903}
904
905static int mvgbe_start(struct udevice *dev)
906{
907 struct eth_pdata *pdata = dev_get_platdata(dev);
908 struct mvgbe_device *dmvgbe = dev_get_priv(dev);
909 int ret;
910
911 ret = __mvgbe_init(dmvgbe, pdata->enetaddr, dev->name);
912 if (ret)
913 return ret;
914
915 if (!mvgbe_port_is_fixed_link(dmvgbe)) {
916 dmvgbe->phydev = __mvgbe_phy_init(dev, dmvgbe->bus,
917 dmvgbe->phy_interface,
918 dmvgbe->phyaddr);
919 if (!dmvgbe->phydev)
920 return -ENODEV;
921 }
922
923 return 0;
924}
925
926static int mvgbe_send(struct udevice *dev, void *packet, int length)
927{
928 struct mvgbe_device *dmvgbe = dev_get_priv(dev);
929
930 return __mvgbe_send(dmvgbe, packet, length);
931}
932
933static int mvgbe_recv(struct udevice *dev, int flags, uchar **packetp)
934{
935 struct mvgbe_device *dmvgbe = dev_get_priv(dev);
936
937 return __mvgbe_recv(dmvgbe, packetp);
938}
939
940static void mvgbe_stop(struct udevice *dev)
941{
942 struct mvgbe_device *dmvgbe = dev_get_priv(dev);
943
944 __mvgbe_halt(dmvgbe);
945}
946
947static int mvgbe_probe(struct udevice *dev)
948{
949 struct eth_pdata *pdata = dev_get_platdata(dev);
950 struct mvgbe_device *dmvgbe = dev_get_priv(dev);
951 struct mii_dev *bus;
952 int ret;
953
954 ret = mvgbe_alloc_buffers(dmvgbe);
955 if (ret)
956 return ret;
957
958 dmvgbe->regs = (void __iomem *)pdata->iobase;
959
960 bus = mdio_alloc();
961 if (!bus) {
962 printf("Failed to allocate MDIO bus\n");
963 return -ENOMEM;
964 }
965
966 bus->read = smi_reg_read;
967 bus->write = smi_reg_write;
968 snprintf(bus->name, sizeof(bus->name), dev->name);
969 bus->priv = dmvgbe;
970 dmvgbe->bus = bus;
971
972 ret = mdio_register(bus);
973 if (ret < 0)
974 return ret;
975
976 return 0;
977}
978
979static const struct eth_ops mvgbe_ops = {
980 .start = mvgbe_start,
981 .send = mvgbe_send,
982 .recv = mvgbe_recv,
983 .stop = mvgbe_stop,
984 .write_hwaddr = mvgbe_write_hwaddr,
985};
986
987static int mvgbe_ofdata_to_platdata(struct udevice *dev)
988{
989 struct eth_pdata *pdata = dev_get_platdata(dev);
990 struct mvgbe_device *dmvgbe = dev_get_priv(dev);
991 void *blob = (void *)gd->fdt_blob;
992 int node = dev_of_offset(dev);
993 const char *phy_mode;
994 int fl_node;
995 int pnode;
996 unsigned long addr;
997
998 pdata->iobase = devfdt_get_addr(dev);
999 pdata->phy_interface = -1;
1000
1001 pnode = fdt_node_offset_by_compatible(blob, node,
1002 "marvell,kirkwood-eth-port");
1003
1004 /* Get phy-mode / phy_interface from DT */
1005 phy_mode = fdt_getprop(gd->fdt_blob, pnode, "phy-mode", NULL);
1006 if (phy_mode)
1007 pdata->phy_interface = phy_get_interface_by_name(phy_mode);
1008 if (pdata->phy_interface == -1) {
1009 debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
1010 return -EINVAL;
1011 }
1012
1013 dmvgbe->phy_interface = pdata->phy_interface;
1014
1015 /* fetch 'fixed-link' property */
1016 fl_node = fdt_subnode_offset(blob, pnode, "fixed-link");
1017 if (fl_node != -FDT_ERR_NOTFOUND) {
1018 /* set phy_addr to invalid value for fixed link */
1019 dmvgbe->phyaddr = PHY_MAX_ADDR + 1;
1020 dmvgbe->duplex = fdtdec_get_bool(blob, fl_node, "full-duplex");
1021 dmvgbe->speed = fdtdec_get_int(blob, fl_node, "speed", 0);
1022 } else {
1023 /* Now read phyaddr from DT */
1024 addr = fdtdec_lookup_phandle(blob, pnode, "phy-handle");
1025 if (addr > 0)
1026 dmvgbe->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
1027 }
1028
1029 return 0;
1030}
1031
1032static const struct udevice_id mvgbe_ids[] = {
1033 { .compatible = "marvell,kirkwood-eth" },
1034 { }
1035};
1036
1037U_BOOT_DRIVER(mvgbe) = {
1038 .name = "mvgbe",
1039 .id = UCLASS_ETH,
1040 .of_match = mvgbe_ids,
1041 .ofdata_to_platdata = mvgbe_ofdata_to_platdata,
1042 .probe = mvgbe_probe,
1043 .ops = &mvgbe_ops,
1044 .priv_auto_alloc_size = sizeof(struct mvgbe_device),
1045 .platdata_auto_alloc_size = sizeof(struct eth_pdata),
1046};
1047#endif /* CONFIG_DM_ETH */