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