diff options
Diffstat (limited to 'drivers/net/xilinx_emaclite.c')
| -rw-r--r-- | drivers/net/xilinx_emaclite.c | 384 |
1 files changed, 336 insertions, 48 deletions
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 8c777ba4e2b3..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,13 +1196,14 @@ 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); |
| 927 | 1200 | ||
| 928 | dev_info(dev, | 1201 | lp->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0); |
| 929 | "MAC address is now %2x:%2x:%2x:%2x:%2x:%2x\n", | 1202 | rc = xemaclite_mdio_setup(lp, &ofdev->dev); |
| 930 | ndev->dev_addr[0], ndev->dev_addr[1], | 1203 | if (rc) |
| 931 | ndev->dev_addr[2], ndev->dev_addr[3], | 1204 | dev_warn(&ofdev->dev, "error registering MDIO bus\n"); |
| 932 | ndev->dev_addr[4], ndev->dev_addr[5]); | 1205 | |
| 1206 | dev_info(dev, "MAC address is now %pM\n", ndev->dev_addr); | ||
| 933 | 1207 | ||
| 934 | ndev->netdev_ops = &xemaclite_netdev_ops; | 1208 | ndev->netdev_ops = &xemaclite_netdev_ops; |
| 935 | ndev->flags &= ~IFF_MULTICAST; | 1209 | ndev->flags &= ~IFF_MULTICAST; |
| @@ -972,12 +1246,25 @@ static int __devexit xemaclite_of_remove(struct of_device *of_dev) | |||
| 972 | struct device *dev = &of_dev->dev; | 1246 | struct device *dev = &of_dev->dev; |
| 973 | struct net_device *ndev = dev_get_drvdata(dev); | 1247 | struct net_device *ndev = dev_get_drvdata(dev); |
| 974 | 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 | |||
| 975 | unregister_netdev(ndev); | 1259 | unregister_netdev(ndev); |
| 976 | 1260 | ||
| 1261 | if (lp->phy_node) | ||
| 1262 | of_node_put(lp->phy_node); | ||
| 1263 | lp->phy_node = NULL; | ||
| 1264 | |||
| 977 | 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); |
| 978 | 1266 | ||
| 979 | xemaclite_remove_ndev(ndev); | 1267 | xemaclite_remove_ndev(ndev); |
| 980 | |||
| 981 | dev_set_drvdata(dev, NULL); | 1268 | dev_set_drvdata(dev, NULL); |
| 982 | 1269 | ||
| 983 | return 0; | 1270 | return 0; |
| @@ -987,7 +1274,7 @@ static struct net_device_ops xemaclite_netdev_ops = { | |||
| 987 | .ndo_open = xemaclite_open, | 1274 | .ndo_open = xemaclite_open, |
| 988 | .ndo_stop = xemaclite_close, | 1275 | .ndo_stop = xemaclite_close, |
| 989 | .ndo_start_xmit = xemaclite_send, | 1276 | .ndo_start_xmit = xemaclite_send, |
| 990 | .ndo_do_ioctl = xemaclite_ioctl, | 1277 | .ndo_set_mac_address = xemaclite_set_mac_address, |
| 991 | .ndo_tx_timeout = xemaclite_tx_timeout, | 1278 | .ndo_tx_timeout = xemaclite_tx_timeout, |
| 992 | .ndo_get_stats = xemaclite_get_stats, | 1279 | .ndo_get_stats = xemaclite_get_stats, |
| 993 | }; | 1280 | }; |
| @@ -999,6 +1286,7 @@ static struct of_device_id xemaclite_of_match[] __devinitdata = { | |||
| 999 | { .compatible = "xlnx,xps-ethernetlite-1.00.a", }, | 1286 | { .compatible = "xlnx,xps-ethernetlite-1.00.a", }, |
| 1000 | { .compatible = "xlnx,xps-ethernetlite-2.00.a", }, | 1287 | { .compatible = "xlnx,xps-ethernetlite-2.00.a", }, |
| 1001 | { .compatible = "xlnx,xps-ethernetlite-2.01.a", }, | 1288 | { .compatible = "xlnx,xps-ethernetlite-2.01.a", }, |
| 1289 | { .compatible = "xlnx,xps-ethernetlite-3.00.a", }, | ||
| 1002 | { /* end of list */ }, | 1290 | { /* end of list */ }, |
| 1003 | }; | 1291 | }; |
| 1004 | MODULE_DEVICE_TABLE(of, xemaclite_of_match); | 1292 | MODULE_DEVICE_TABLE(of, xemaclite_of_match); |
