These changes add MDIO and phy lib support to the driver as the
IP core now supports the MDIO bus.
The MDIO bus and phy are added as a child to the emaclite in the device
tree as illustrated below.
mdio {
#address-cells = 1;
#size-cells = 0;
compatible = xlnx,emaclite-mdio;
phy0: p...@7 {
reg = 7;
} ;
}
Signed-off-by: Sadanand Mutyala sadanand.muty...@xilinx.com
Signed-off-by: John Linn john.l...@xilinx.com
---
V2 - updated it for Grant's comments, except I couldn't find any tabs
converted to white space issue, let's see if V2 has it also
---
drivers/net/Kconfig |1 +
drivers/net/xilinx_emaclite.c | 393 -
2 files changed, 351 insertions(+), 43 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dd9a09c..9509a36 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1939,6 +1939,7 @@ config ATL2
config XILINX_EMACLITE
tristate Xilinx 10/100 Ethernet Lite support
depends on PPC32 || MICROBLAZE
+ select PHYLIB
help
This driver supports the 10/100 Ethernet Lite from Xilinx.
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 8c777ba..02f18dd 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -22,11 +22,17 @@
#include linux/of_device.h
#include linux/of_platform.h
+#include linux/of_mdio.h
+#include linux/phy.h
#define DRIVER_NAME xilinx_emaclite
/* Register offsets for the EmacLite Core */
#define XEL_TXBUFF_OFFSET 0x0 /* Transmit Buffer */
+#define XEL_MDIOADDR_OFFSET0x07E4 /* MDIO Address Register */
+#define XEL_MDIOWR_OFFSET 0x07E8 /* MDIO Write Data Register */
+#define XEL_MDIORD_OFFSET 0x07EC /* MDIO Read Data Register */
+#define XEL_MDIOCTRL_OFFSET0x07F0 /* MDIO Control Register */
#define XEL_GIER_OFFSET0x07F8 /* GIE Register */
#define XEL_TSR_OFFSET 0x07FC /* Tx status */
#define XEL_TPLR_OFFSET0x07F4 /* Tx packet length */
@@ -37,6 +43,22 @@
#define XEL_BUFFER_OFFSET 0x0800 /* Next Tx/Rx buffer's offset */
+/* MDIO Address Register Bit Masks */
+#define XEL_MDIOADDR_REGADR_MASK 0x001F /* Register Address */
+#define XEL_MDIOADDR_PHYADR_MASK 0x03E0 /* PHY Address */
+#define XEL_MDIOADDR_PHYADR_SHIFT 5
+#define XEL_MDIOADDR_OP_MASK 0x0400/* RD/WR Operation */
+
+/* MDIO Write Data Register Bit Masks */
+#define XEL_MDIOWR_WRDATA_MASK 0x/* Data to be Written */
+
+/* MDIO Read Data Register Bit Masks */
+#define XEL_MDIORD_RDDATA_MASK 0x/* Data to be Read */
+
+/* MDIO Control Register Bit Masks */
+#define XEL_MDIOCTRL_MDIOSTS_MASK 0x0001 /* MDIO Status Mask */
+#define XEL_MDIOCTRL_MDIOEN_MASK 0x0008 /* MDIO Enable */
+
/* Global Interrupt Enable Register (GIER) Bit Masks */
#define XEL_GIER_GIE_MASK 0x8000 /* Global Enable */
@@ -87,6 +109,13 @@
* @reset_lock:lock used for synchronization
* @deferred_skb: holds an skb (for transmission at a later time) when the
* Tx buffer is not free
+ * @phy_dev: pointer to the PHY device
+ * @phy_node: pointer to the PHY device node
+ * @mii_bus: pointer to the MII bus
+ * @mdio_irqs: IRQs table for MDIO bus
+ * @last_link: last link status
+ * @has_mdio: indicates whether MDIO is included in the HW
+ * @mdio_mutex:protects MDIO accesses
*/
struct net_local {
@@ -100,6 +129,16 @@ struct net_local {
spinlock_t reset_lock;
struct sk_buff *deferred_skb;
+
+ struct phy_device *phy_dev;
+ struct device_node *phy_node;
+
+ struct mii_bus *mii_bus;
+ int mdio_irqs[PHY_MAX_ADDR];
+
+ int last_link;
+ bool has_mdio;
+ struct mutex mdio_mutex;
};
@@ -431,7 +470,7 @@ static u16 xemaclite_recv_data(struct net_local *drvdata,
u8 *data)
}
/**
- * xemaclite_set_mac_address - Set the MAC address for this device
+ * xemaclite_update_address - Update the MAC address in the device
* @drvdata: Pointer to the Emaclite device private data
* @address_ptr:Pointer to the MAC address (MAC address is a 48-bit value)
*
@@ -441,8 +480,8 @@ static u16 xemaclite_recv_data(struct net_local *drvdata,
u8 *data)
* The MAC address can be programmed using any of the two transmit
* buffers (if configured).
*/
-static void xemaclite_set_mac_address(struct net_local *drvdata,
- u8 *address_ptr)
+static void xemaclite_update_address(struct net_local *drvdata,
+u8 *address_ptr)
{
void __iomem *addr;
u32 reg_data;
@@ -465,6 +504,30 @@ static void xemaclite_set_mac_address(struct net_local
*drvdata,
}
/**
+ *