diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Kconfig | 1 | ||||
-rw-r--r-- | drivers/net/xilinx_emaclite.c | 378 |
2 files changed, 336 insertions, 43 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5f646523c5ae..b711d5416100 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -1963,6 +1963,7 @@ config ATL2 | |||
1963 | config XILINX_EMACLITE | 1963 | config XILINX_EMACLITE |
1964 | tristate "Xilinx 10/100 Ethernet Lite support" | 1964 | tristate "Xilinx 10/100 Ethernet Lite support" |
1965 | depends on PPC32 || MICROBLAZE | 1965 | depends on PPC32 || MICROBLAZE |
1966 | select PHYLIB | ||
1966 | help | 1967 | help |
1967 | This driver supports the 10/100 Ethernet Lite from Xilinx. | 1968 | This driver supports the 10/100 Ethernet Lite from Xilinx. |
1968 | 1969 | ||
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index f7fe1aa03b42..1a74594224b1 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c | |||
@@ -22,11 +22,17 @@ | |||
22 | 22 | ||
23 | #include <linux/of_device.h> | 23 | #include <linux/of_device.h> |
24 | #include <linux/of_platform.h> | 24 | #include <linux/of_platform.h> |
25 | #include <linux/of_mdio.h> | ||
26 | #include <linux/phy.h> | ||
25 | 27 | ||
26 | #define DRIVER_NAME "xilinx_emaclite" | 28 | #define DRIVER_NAME "xilinx_emaclite" |
27 | 29 | ||
28 | /* Register offsets for the EmacLite Core */ | 30 | /* Register offsets for the EmacLite Core */ |
29 | #define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */ | 31 | #define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */ |
32 | #define XEL_MDIOADDR_OFFSET 0x07E4 /* MDIO Address Register */ | ||
33 | #define XEL_MDIOWR_OFFSET 0x07E8 /* MDIO Write Data Register */ | ||
34 | #define XEL_MDIORD_OFFSET 0x07EC /* MDIO Read Data Register */ | ||
35 | #define XEL_MDIOCTRL_OFFSET 0x07F0 /* MDIO Control Register */ | ||
30 | #define XEL_GIER_OFFSET 0x07F8 /* GIE Register */ | 36 | #define XEL_GIER_OFFSET 0x07F8 /* GIE Register */ |
31 | #define XEL_TSR_OFFSET 0x07FC /* Tx status */ | 37 | #define XEL_TSR_OFFSET 0x07FC /* Tx status */ |
32 | #define XEL_TPLR_OFFSET 0x07F4 /* Tx packet length */ | 38 | #define XEL_TPLR_OFFSET 0x07F4 /* Tx packet length */ |
@@ -37,6 +43,22 @@ | |||
37 | 43 | ||
38 | #define XEL_BUFFER_OFFSET 0x0800 /* Next Tx/Rx buffer's offset */ | 44 | #define XEL_BUFFER_OFFSET 0x0800 /* Next Tx/Rx buffer's offset */ |
39 | 45 | ||
46 | /* MDIO Address Register Bit Masks */ | ||
47 | #define XEL_MDIOADDR_REGADR_MASK 0x0000001F /* Register Address */ | ||
48 | #define XEL_MDIOADDR_PHYADR_MASK 0x000003E0 /* PHY Address */ | ||
49 | #define XEL_MDIOADDR_PHYADR_SHIFT 5 | ||
50 | #define XEL_MDIOADDR_OP_MASK 0x00000400 /* RD/WR Operation */ | ||
51 | |||
52 | /* MDIO Write Data Register Bit Masks */ | ||
53 | #define XEL_MDIOWR_WRDATA_MASK 0x0000FFFF /* Data to be Written */ | ||
54 | |||
55 | /* MDIO Read Data Register Bit Masks */ | ||
56 | #define XEL_MDIORD_RDDATA_MASK 0x0000FFFF /* Data to be Read */ | ||
57 | |||
58 | /* MDIO Control Register Bit Masks */ | ||
59 | #define XEL_MDIOCTRL_MDIOSTS_MASK 0x00000001 /* MDIO Status Mask */ | ||
60 | #define XEL_MDIOCTRL_MDIOEN_MASK 0x00000008 /* MDIO Enable */ | ||
61 | |||
40 | /* Global Interrupt Enable Register (GIER) Bit Masks */ | 62 | /* Global Interrupt Enable Register (GIER) Bit Masks */ |
41 | #define XEL_GIER_GIE_MASK 0x80000000 /* Global Enable */ | 63 | #define XEL_GIER_GIE_MASK 0x80000000 /* Global Enable */ |
42 | 64 | ||
@@ -87,6 +109,12 @@ | |||
87 | * @reset_lock: lock used for synchronization | 109 | * @reset_lock: lock used for synchronization |
88 | * @deferred_skb: holds an skb (for transmission at a later time) when the | 110 | * @deferred_skb: holds an skb (for transmission at a later time) when the |
89 | * Tx buffer is not free | 111 | * Tx buffer is not free |
112 | * @phy_dev: pointer to the PHY device | ||
113 | * @phy_node: pointer to the PHY device node | ||
114 | * @mii_bus: pointer to the MII bus | ||
115 | * @mdio_irqs: IRQs table for MDIO bus | ||
116 | * @last_link: last link status | ||
117 | * @has_mdio: indicates whether MDIO is included in the HW | ||
90 | */ | 118 | */ |
91 | struct net_local { | 119 | struct net_local { |
92 | 120 | ||
@@ -100,6 +128,15 @@ struct net_local { | |||
100 | 128 | ||
101 | spinlock_t reset_lock; | 129 | spinlock_t reset_lock; |
102 | struct sk_buff *deferred_skb; | 130 | struct sk_buff *deferred_skb; |
131 | |||
132 | struct phy_device *phy_dev; | ||
133 | struct device_node *phy_node; | ||
134 | |||
135 | struct mii_bus *mii_bus; | ||
136 | int mdio_irqs[PHY_MAX_ADDR]; | ||
137 | |||
138 | int last_link; | ||
139 | bool has_mdio; | ||
103 | }; | 140 | }; |
104 | 141 | ||
105 | 142 | ||
@@ -431,7 +468,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) | |||
431 | } | 468 | } |
432 | 469 | ||
433 | /** | 470 | /** |
434 | * xemaclite_set_mac_address - Set the MAC address for this device | 471 | * xemaclite_update_address - Update the MAC address in the device |
435 | * @drvdata: Pointer to the Emaclite device private data | 472 | * @drvdata: Pointer to the Emaclite device private data |
436 | * @address_ptr:Pointer to the MAC address (MAC address is a 48-bit value) | 473 | * @address_ptr:Pointer to the MAC address (MAC address is a 48-bit value) |
437 | * | 474 | * |
@@ -441,8 +478,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata, u8 *data) | |||
441 | * The MAC address can be programmed using any of the two transmit | 478 | * The MAC address can be programmed using any of the two transmit |
442 | * buffers (if configured). | 479 | * buffers (if configured). |
443 | */ | 480 | */ |
444 | static void xemaclite_set_mac_address(struct net_local *drvdata, | 481 | static void xemaclite_update_address(struct net_local *drvdata, |
445 | u8 *address_ptr) | 482 | u8 *address_ptr) |
446 | { | 483 | { |
447 | void __iomem *addr; | 484 | void __iomem *addr; |
448 | u32 reg_data; | 485 | u32 reg_data; |
@@ -465,6 +502,30 @@ static void xemaclite_set_mac_address(struct net_local *drvdata, | |||
465 | } | 502 | } |
466 | 503 | ||
467 | /** | 504 | /** |
505 | * xemaclite_set_mac_address - Set the MAC address for this device | ||
506 | * @dev: Pointer to the network device instance | ||
507 | * @addr: Void pointer to the sockaddr structure | ||
508 | * | ||
509 | * This function copies the HW address from the sockaddr strucutre to the | ||
510 | * net_device structure and updates the address in HW. | ||
511 | * | ||
512 | * Return: Error if the net device is busy or 0 if the addr is set | ||
513 | * successfully | ||
514 | */ | ||
515 | static int xemaclite_set_mac_address(struct net_device *dev, void *address) | ||
516 | { | ||
517 | struct net_local *lp = (struct net_local *) netdev_priv(dev); | ||
518 | struct sockaddr *addr = address; | ||
519 | |||
520 | if (netif_running(dev)) | ||
521 | return -EBUSY; | ||
522 | |||
523 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | ||
524 | xemaclite_update_address(lp, dev->dev_addr); | ||
525 | return 0; | ||
526 | } | ||
527 | |||
528 | /** | ||
468 | * xemaclite_tx_timeout - Callback for Tx Timeout | 529 | * xemaclite_tx_timeout - Callback for Tx Timeout |
469 | * @dev: Pointer to the network device | 530 | * @dev: Pointer to the network device |
470 | * | 531 | * |
@@ -641,12 +702,219 @@ static irqreturn_t xemaclite_interrupt(int irq, void *dev_id) | |||
641 | return IRQ_HANDLED; | 702 | return IRQ_HANDLED; |
642 | } | 703 | } |
643 | 704 | ||
705 | /**********************/ | ||
706 | /* MDIO Bus functions */ | ||
707 | /**********************/ | ||
708 | |||
709 | /** | ||
710 | * xemaclite_mdio_wait - Wait for the MDIO to be ready to use | ||
711 | * @lp: Pointer to the Emaclite device private data | ||
712 | * | ||
713 | * This function waits till the device is ready to accept a new MDIO | ||
714 | * request. | ||
715 | * | ||
716 | * Return: 0 for success or ETIMEDOUT for a timeout | ||
717 | */ | ||
718 | |||
719 | static int xemaclite_mdio_wait(struct net_local *lp) | ||
720 | { | ||
721 | long end = jiffies + 2; | ||
722 | |||
723 | /* wait for the MDIO interface to not be busy or timeout | ||
724 | after some time. | ||
725 | */ | ||
726 | while (in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET) & | ||
727 | XEL_MDIOCTRL_MDIOSTS_MASK) { | ||
728 | if (end - jiffies <= 0) { | ||
729 | WARN_ON(1); | ||
730 | return -ETIMEDOUT; | ||
731 | } | ||
732 | msleep(1); | ||
733 | } | ||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | /** | ||
738 | * xemaclite_mdio_read - Read from a given MII management register | ||
739 | * @bus: the mii_bus struct | ||
740 | * @phy_id: the phy address | ||
741 | * @reg: register number to read from | ||
742 | * | ||
743 | * This function waits till the device is ready to accept a new MDIO | ||
744 | * request and then writes the phy address to the MDIO Address register | ||
745 | * and reads data from MDIO Read Data register, when its available. | ||
746 | * | ||
747 | * Return: Value read from the MII management register | ||
748 | */ | ||
749 | static int xemaclite_mdio_read(struct mii_bus *bus, int phy_id, int reg) | ||
750 | { | ||
751 | struct net_local *lp = bus->priv; | ||
752 | u32 ctrl_reg; | ||
753 | u32 rc; | ||
754 | |||
755 | if (xemaclite_mdio_wait(lp)) | ||
756 | return -ETIMEDOUT; | ||
757 | |||
758 | /* Write the PHY address, register number and set the OP bit in the | ||
759 | * MDIO Address register. Set the Status bit in the MDIO Control | ||
760 | * register to start a MDIO read transaction. | ||
761 | */ | ||
762 | ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET); | ||
763 | out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET, | ||
764 | XEL_MDIOADDR_OP_MASK | | ||
765 | ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg)); | ||
766 | out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | ||
767 | ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); | ||
768 | |||
769 | if (xemaclite_mdio_wait(lp)) | ||
770 | return -ETIMEDOUT; | ||
771 | |||
772 | rc = in_be32(lp->base_addr + XEL_MDIORD_OFFSET); | ||
773 | |||
774 | dev_dbg(&lp->ndev->dev, | ||
775 | "xemaclite_mdio_read(phy_id=%i, reg=%x) == %x\n", | ||
776 | phy_id, reg, rc); | ||
777 | |||
778 | return rc; | ||
779 | } | ||
780 | |||
781 | /** | ||
782 | * xemaclite_mdio_write - Write to a given MII management register | ||
783 | * @bus: the mii_bus struct | ||
784 | * @phy_id: the phy address | ||
785 | * @reg: register number to write to | ||
786 | * @val: value to write to the register number specified by reg | ||
787 | * | ||
788 | * This fucntion waits till the device is ready to accept a new MDIO | ||
789 | * request and then writes the val to the MDIO Write Data register. | ||
790 | */ | ||
791 | static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg, | ||
792 | u16 val) | ||
793 | { | ||
794 | struct net_local *lp = bus->priv; | ||
795 | u32 ctrl_reg; | ||
796 | |||
797 | dev_dbg(&lp->ndev->dev, | ||
798 | "xemaclite_mdio_write(phy_id=%i, reg=%x, val=%x)\n", | ||
799 | phy_id, reg, val); | ||
800 | |||
801 | if (xemaclite_mdio_wait(lp)) | ||
802 | return -ETIMEDOUT; | ||
803 | |||
804 | /* Write the PHY address, register number and clear the OP bit in the | ||
805 | * MDIO Address register and then write the value into the MDIO Write | ||
806 | * Data register. Finally, set the Status bit in the MDIO Control | ||
807 | * register to start a MDIO write transaction. | ||
808 | */ | ||
809 | ctrl_reg = in_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET); | ||
810 | out_be32(lp->base_addr + XEL_MDIOADDR_OFFSET, | ||
811 | ~XEL_MDIOADDR_OP_MASK & | ||
812 | ((phy_id << XEL_MDIOADDR_PHYADR_SHIFT) | reg)); | ||
813 | out_be32(lp->base_addr + XEL_MDIOWR_OFFSET, val); | ||
814 | out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | ||
815 | ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK); | ||
816 | |||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * xemaclite_mdio_reset - Reset the mdio bus. | ||
822 | * @bus: Pointer to the MII bus | ||
823 | * | ||
824 | * This function is required(?) as per Documentation/networking/phy.txt. | ||
825 | * There is no reset in this device; this function always returns 0. | ||
826 | */ | ||
827 | static int xemaclite_mdio_reset(struct mii_bus *bus) | ||
828 | { | ||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | /** | ||
833 | * xemaclite_mdio_setup - Register mii_bus for the Emaclite device | ||
834 | * @lp: Pointer to the Emaclite device private data | ||
835 | * @ofdev: Pointer to OF device structure | ||
836 | * | ||
837 | * This function enables MDIO bus in the Emaclite device and registers a | ||
838 | * mii_bus. | ||
839 | * | ||
840 | * Return: 0 upon success or a negative error upon failure | ||
841 | */ | ||
842 | static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) | ||
843 | { | ||
844 | struct mii_bus *bus; | ||
845 | int rc; | ||
846 | struct resource res; | ||
847 | struct device_node *np = of_get_parent(lp->phy_node); | ||
848 | |||
849 | /* Don't register the MDIO bus if the phy_node or its parent node | ||
850 | * can't be found. | ||
851 | */ | ||
852 | if (!np) | ||
853 | return -ENODEV; | ||
854 | |||
855 | /* Enable the MDIO bus by asserting the enable bit in MDIO Control | ||
856 | * register. | ||
857 | */ | ||
858 | out_be32(lp->base_addr + XEL_MDIOCTRL_OFFSET, | ||
859 | XEL_MDIOCTRL_MDIOEN_MASK); | ||
860 | |||
861 | bus = mdiobus_alloc(); | ||
862 | if (!bus) | ||
863 | return -ENOMEM; | ||
864 | |||
865 | of_address_to_resource(np, 0, &res); | ||
866 | snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", | ||
867 | (unsigned long long)res.start); | ||
868 | bus->priv = lp; | ||
869 | bus->name = "Xilinx Emaclite MDIO"; | ||
870 | bus->read = xemaclite_mdio_read; | ||
871 | bus->write = xemaclite_mdio_write; | ||
872 | bus->reset = xemaclite_mdio_reset; | ||
873 | bus->parent = dev; | ||
874 | bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ | ||
875 | |||
876 | lp->mii_bus = bus; | ||
877 | |||
878 | rc = of_mdiobus_register(bus, np); | ||
879 | if (rc) | ||
880 | goto err_register; | ||
881 | |||
882 | return 0; | ||
883 | |||
884 | err_register: | ||
885 | mdiobus_free(bus); | ||
886 | return rc; | ||
887 | } | ||
888 | |||
889 | /** | ||
890 | * xemaclite_adjust_link - Link state callback for the Emaclite device | ||
891 | * @ndev: pointer to net_device struct | ||
892 | * | ||
893 | * There's nothing in the Emaclite device to be configured when the link | ||
894 | * state changes. We just print the status. | ||
895 | */ | ||
896 | void xemaclite_adjust_link(struct net_device *ndev) | ||
897 | { | ||
898 | struct net_local *lp = netdev_priv(ndev); | ||
899 | struct phy_device *phy = lp->phy_dev; | ||
900 | int link_state; | ||
901 | |||
902 | /* hash together the state values to decide if something has changed */ | ||
903 | link_state = phy->speed | (phy->duplex << 1) | phy->link; | ||
904 | |||
905 | if (lp->last_link != link_state) { | ||
906 | lp->last_link = link_state; | ||
907 | phy_print_status(phy); | ||
908 | } | ||
909 | } | ||
910 | |||
644 | /** | 911 | /** |
645 | * xemaclite_open - Open the network device | 912 | * xemaclite_open - Open the network device |
646 | * @dev: Pointer to the network device | 913 | * @dev: Pointer to the network device |
647 | * | 914 | * |
648 | * This function sets the MAC address, requests an IRQ and enables interrupts | 915 | * This function sets the MAC address, requests an IRQ and enables interrupts |
649 | * for the Emaclite device and starts the Tx queue. | 916 | * for the Emaclite device and starts the Tx queue. |
917 | * It also connects to the phy device, if MDIO is included in Emaclite device. | ||
650 | */ | 918 | */ |
651 | static int xemaclite_open(struct net_device *dev) | 919 | static int xemaclite_open(struct net_device *dev) |
652 | { | 920 | { |
@@ -656,14 +924,47 @@ static int xemaclite_open(struct net_device *dev) | |||
656 | /* Just to be safe, stop the device first */ | 924 | /* Just to be safe, stop the device first */ |
657 | xemaclite_disable_interrupts(lp); | 925 | xemaclite_disable_interrupts(lp); |
658 | 926 | ||
927 | if (lp->phy_node) { | ||
928 | u32 bmcr; | ||
929 | |||
930 | lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, | ||
931 | xemaclite_adjust_link, 0, | ||
932 | PHY_INTERFACE_MODE_MII); | ||
933 | if (!lp->phy_dev) { | ||
934 | dev_err(&lp->ndev->dev, "of_phy_connect() failed\n"); | ||
935 | return -ENODEV; | ||
936 | } | ||
937 | |||
938 | /* EmacLite doesn't support giga-bit speeds */ | ||
939 | lp->phy_dev->supported &= (PHY_BASIC_FEATURES); | ||
940 | lp->phy_dev->advertising = lp->phy_dev->supported; | ||
941 | |||
942 | /* Don't advertise 1000BASE-T Full/Half duplex speeds */ | ||
943 | phy_write(lp->phy_dev, MII_CTRL1000, 0); | ||
944 | |||
945 | /* Advertise only 10 and 100mbps full/half duplex speeds */ | ||
946 | phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL); | ||
947 | |||
948 | /* Restart auto negotiation */ | ||
949 | bmcr = phy_read(lp->phy_dev, MII_BMCR); | ||
950 | bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); | ||
951 | phy_write(lp->phy_dev, MII_BMCR, bmcr); | ||
952 | |||
953 | phy_start(lp->phy_dev); | ||
954 | } | ||
955 | |||
659 | /* Set the MAC address each time opened */ | 956 | /* Set the MAC address each time opened */ |
660 | xemaclite_set_mac_address(lp, dev->dev_addr); | 957 | xemaclite_update_address(lp, dev->dev_addr); |
661 | 958 | ||
662 | /* Grab the IRQ */ | 959 | /* Grab the IRQ */ |
663 | retval = request_irq(dev->irq, xemaclite_interrupt, 0, dev->name, dev); | 960 | retval = request_irq(dev->irq, xemaclite_interrupt, 0, dev->name, dev); |
664 | if (retval) { | 961 | if (retval) { |
665 | dev_err(&lp->ndev->dev, "Could not allocate interrupt %d\n", | 962 | dev_err(&lp->ndev->dev, "Could not allocate interrupt %d\n", |
666 | dev->irq); | 963 | dev->irq); |
964 | if (lp->phy_dev) | ||
965 | phy_disconnect(lp->phy_dev); | ||
966 | lp->phy_dev = NULL; | ||
967 | |||
667 | return retval; | 968 | return retval; |
668 | } | 969 | } |
669 | 970 | ||
@@ -682,6 +983,7 @@ static int xemaclite_open(struct net_device *dev) | |||
682 | * | 983 | * |
683 | * This function stops the Tx queue, disables interrupts and frees the IRQ for | 984 | * This function stops the Tx queue, disables interrupts and frees the IRQ for |
684 | * the Emaclite device. | 985 | * the Emaclite device. |
986 | * It also disconnects the phy device associated with the Emaclite device. | ||
685 | */ | 987 | */ |
686 | static int xemaclite_close(struct net_device *dev) | 988 | static int xemaclite_close(struct net_device *dev) |
687 | { | 989 | { |
@@ -691,6 +993,10 @@ static int xemaclite_close(struct net_device *dev) | |||
691 | xemaclite_disable_interrupts(lp); | 993 | xemaclite_disable_interrupts(lp); |
692 | free_irq(dev->irq, dev); | 994 | free_irq(dev->irq, dev); |
693 | 995 | ||
996 | if (lp->phy_dev) | ||
997 | phy_disconnect(lp->phy_dev); | ||
998 | lp->phy_dev = NULL; | ||
999 | |||
694 | return 0; | 1000 | return 0; |
695 | } | 1001 | } |
696 | 1002 | ||
@@ -754,42 +1060,6 @@ static int xemaclite_send(struct sk_buff *orig_skb, struct net_device *dev) | |||
754 | } | 1060 | } |
755 | 1061 | ||
756 | /** | 1062 | /** |
757 | * xemaclite_ioctl - Perform IO Control operations on the network device | ||
758 | * @dev: Pointer to the network device | ||
759 | * @rq: Pointer to the interface request structure | ||
760 | * @cmd: IOCTL command | ||
761 | * | ||
762 | * The only IOCTL operation supported by this function is setting the MAC | ||
763 | * address. An error is reported if any other operations are requested. | ||
764 | * | ||
765 | * Return: 0 to indicate success, or a negative error for failure. | ||
766 | */ | ||
767 | static int xemaclite_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
768 | { | ||
769 | struct net_local *lp = (struct net_local *) netdev_priv(dev); | ||
770 | struct hw_addr_data *hw_addr = (struct hw_addr_data *) &rq->ifr_hwaddr; | ||
771 | |||
772 | switch (cmd) { | ||
773 | case SIOCETHTOOL: | ||
774 | return -EIO; | ||
775 | |||
776 | case SIOCSIFHWADDR: | ||
777 | dev_err(&lp->ndev->dev, "SIOCSIFHWADDR\n"); | ||
778 | |||
779 | /* Copy MAC address in from user space */ | ||
780 | copy_from_user((void __force *) dev->dev_addr, | ||
781 | (void __user __force *) hw_addr, | ||
782 | IFHWADDRLEN); | ||
783 | xemaclite_set_mac_address(lp, dev->dev_addr); | ||
784 | break; | ||
785 | default: | ||
786 | return -EOPNOTSUPP; | ||
787 | } | ||
788 | |||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | /** | ||
793 | * xemaclite_remove_ndev - Free the network device | 1063 | * xemaclite_remove_ndev - Free the network device |
794 | * @ndev: Pointer to the network device to be freed | 1064 | * @ndev: Pointer to the network device to be freed |
795 | * | 1065 | * |
@@ -840,6 +1110,8 @@ static struct net_device_ops xemaclite_netdev_ops; | |||
840 | * This function probes for the Emaclite device in the device tree. | 1110 | * This function probes for the Emaclite device in the device tree. |
841 | * It initializes the driver data structure and the hardware, sets the MAC | 1111 | * It initializes the driver data structure and the hardware, sets the MAC |
842 | * address and registers the network device. | 1112 | * address and registers the network device. |
1113 | * It also registers a mii_bus for the Emaclite device, if MDIO is included | ||
1114 | * in the device. | ||
843 | * | 1115 | * |
844 | * Return: 0, if the driver is bound to the Emaclite device, or | 1116 | * Return: 0, if the driver is bound to the Emaclite device, or |
845 | * a negative error if there is failure. | 1117 | * a negative error if there is failure. |
@@ -880,6 +1152,7 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, | |||
880 | } | 1152 | } |
881 | 1153 | ||
882 | dev_set_drvdata(dev, ndev); | 1154 | dev_set_drvdata(dev, ndev); |
1155 | SET_NETDEV_DEV(ndev, &ofdev->dev); | ||
883 | 1156 | ||
884 | ndev->irq = r_irq.start; | 1157 | ndev->irq = r_irq.start; |
885 | ndev->mem_start = r_mem.start; | 1158 | ndev->mem_start = r_mem.start; |
@@ -923,7 +1196,12 @@ static int __devinit xemaclite_of_probe(struct of_device *ofdev, | |||
923 | out_be32(lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0); | 1196 | out_be32(lp->base_addr + XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0); |
924 | 1197 | ||
925 | /* Set the MAC address in the EmacLite device */ | 1198 | /* Set the MAC address in the EmacLite device */ |
926 | xemaclite_set_mac_address(lp, ndev->dev_addr); | 1199 | xemaclite_update_address(lp, ndev->dev_addr); |
1200 | |||
1201 | lp->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); | ||
1202 | rc = xemaclite_mdio_setup(lp, &ofdev->dev); | ||
1203 | if (rc) | ||
1204 | dev_warn(&ofdev->dev, "error registering MDIO bus\n"); | ||
927 | 1205 | ||
928 | dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr); | 1206 | dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr); |
929 | 1207 | ||
@@ -968,12 +1246,25 @@ static int __devexit xemaclite_of_remove(struct of_device *of_dev) | |||
968 | struct device *dev = &of_dev->dev; | 1246 | struct device *dev = &of_dev->dev; |
969 | struct net_device *ndev = dev_get_drvdata(dev); | 1247 | struct net_device *ndev = dev_get_drvdata(dev); |
970 | 1248 | ||
1249 | struct net_local *lp = (struct net_local *) netdev_priv(ndev); | ||
1250 | |||
1251 | /* Un-register the mii_bus, if configured */ | ||
1252 | if (lp->has_mdio) { | ||
1253 | mdiobus_unregister(lp->mii_bus); | ||
1254 | kfree(lp->mii_bus->irq); | ||
1255 | mdiobus_free(lp->mii_bus); | ||
1256 | lp->mii_bus = NULL; | ||
1257 | } | ||
1258 | |||
971 | unregister_netdev(ndev); | 1259 | unregister_netdev(ndev); |
972 | 1260 | ||
1261 | if (lp->phy_node) | ||
1262 | of_node_put(lp->phy_node); | ||
1263 | lp->phy_node = NULL; | ||
1264 | |||
973 | release_mem_region(ndev->mem_start, ndev->mem_end-ndev->mem_start + 1); | 1265 | release_mem_region(ndev->mem_start, ndev->mem_end-ndev->mem_start + 1); |
974 | 1266 | ||
975 | xemaclite_remove_ndev(ndev); | 1267 | xemaclite_remove_ndev(ndev); |
976 | |||
977 | dev_set_drvdata(dev, NULL); | 1268 | dev_set_drvdata(dev, NULL); |
978 | 1269 | ||
979 | return 0; | 1270 | return 0; |
@@ -983,7 +1274,7 @@ static struct net_device_ops xemaclite_netdev_ops = { | |||
983 | .ndo_open = xemaclite_open, | 1274 | .ndo_open = xemaclite_open, |
984 | .ndo_stop = xemaclite_close, | 1275 | .ndo_stop = xemaclite_close, |
985 | .ndo_start_xmit = xemaclite_send, | 1276 | .ndo_start_xmit = xemaclite_send, |
986 | .ndo_do_ioctl = xemaclite_ioctl, | 1277 | .ndo_set_mac_address = xemaclite_set_mac_address, |
987 | .ndo_tx_timeout = xemaclite_tx_timeout, | 1278 | .ndo_tx_timeout = xemaclite_tx_timeout, |
988 | .ndo_get_stats = xemaclite_get_stats, | 1279 | .ndo_get_stats = xemaclite_get_stats, |
989 | }; | 1280 | }; |
@@ -995,6 +1286,7 @@ static struct of_device_id xemaclite_of_match[] __devinitdata = { | |||
995 | { .compatible = "xlnx,xps-ethernetlite-1.00.a", }, | 1286 | { .compatible = "xlnx,xps-ethernetlite-1.00.a", }, |
996 | { .compatible = "xlnx,xps-ethernetlite-2.00.a", }, | 1287 | { .compatible = "xlnx,xps-ethernetlite-2.00.a", }, |
997 | { .compatible = "xlnx,xps-ethernetlite-2.01.a", }, | 1288 | { .compatible = "xlnx,xps-ethernetlite-2.01.a", }, |
1289 | { .compatible = "xlnx,xps-ethernetlite-3.00.a", }, | ||
998 | { /* end of list */ }, | 1290 | { /* end of list */ }, |
999 | }; | 1291 | }; |
1000 | MODULE_DEVICE_TABLE(of, xemaclite_of_match); | 1292 | MODULE_DEVICE_TABLE(of, xemaclite_of_match); |