atheros[ar231x-eth]: pass PHY I/O memory via device resources

Pass PHY I/O memory region via platform resources and remap them
unconditionally.

Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>

SVN-Revision: 41698
This commit is contained in:
Felix Fietkau 2014-07-17 16:36:46 +00:00
parent 9041410017
commit 572b532e6a
3 changed files with 72 additions and 41 deletions

View File

@ -388,7 +388,7 @@
+} +}
--- /dev/null --- /dev/null
+++ b/arch/mips/include/asm/mach-ar231x/ar231x_platform.h +++ b/arch/mips/include/asm/mach-ar231x/ar231x_platform.h
@@ -0,0 +1,84 @@ @@ -0,0 +1,83 @@
+#ifndef __AR531X_PLATFORM_H +#ifndef __AR531X_PLATFORM_H
+#define __AR531X_PLATFORM_H +#define __AR531X_PLATFORM_H
+ +
@ -467,7 +467,6 @@
+ void (*reset_clear)(u32); + void (*reset_clear)(u32);
+ u32 reset_mac; + u32 reset_mac;
+ u32 reset_phy; + u32 reset_phy;
+ u32 phy_base;
+ struct ar231x_board_config *config; + struct ar231x_board_config *config;
+ char *macaddr; + char *macaddr;
+}; +};
@ -714,7 +713,7 @@
+#endif /* __ASM_MIPS_MACH_ATHEROS_WAR_H */ +#endif /* __ASM_MIPS_MACH_ATHEROS_WAR_H */
--- /dev/null --- /dev/null
+++ b/arch/mips/include/asm/mach-ar231x/ar2315_regs.h +++ b/arch/mips/include/asm/mach-ar231x/ar2315_regs.h
@@ -0,0 +1,614 @@ @@ -0,0 +1,617 @@
+/* +/*
+ * Register definitions for AR2315+ + * Register definitions for AR2315+
+ * + *
@ -771,6 +770,9 @@
+#define AR2315_SPI_MMR 0x11300000 /* SPI FLASH MMR */ +#define AR2315_SPI_MMR 0x11300000 /* SPI FLASH MMR */
+#define AR2315_PCIEXT 0x80000000 /* pci external */ +#define AR2315_PCIEXT 0x80000000 /* pci external */
+ +
+/* MII registers offset inside Ethernet MMR region */
+#define AR2315_ENET0_MII (AR2315_ENET0 + 0x14)
+
+/* +/*
+ * Reset Register + * Reset Register
+ */ + */
@ -1331,7 +1333,7 @@
+#endif /* __AR2315_REG_H */ +#endif /* __AR2315_REG_H */
--- /dev/null --- /dev/null
+++ b/arch/mips/include/asm/mach-ar231x/ar5312_regs.h +++ b/arch/mips/include/asm/mach-ar231x/ar5312_regs.h
@@ -0,0 +1,249 @@ @@ -0,0 +1,253 @@
+/* +/*
+ * This file is subject to the terms and conditions of the GNU General Public + * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive + * License. See the file "COPYING" in the main directory of this archive
@ -1401,6 +1403,10 @@
+#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ +#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */
+#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ +#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */
+ +
+/* MII registers offset inside Ethernet MMR region */
+#define AR531X_ENET0_MII (AR531X_ENET0 + 0x14)
+#define AR531X_ENET1_MII (AR531X_ENET1 + 0x14)
+
+/* +/*
+ * AR531X_NUM_WMAC defines the number of Wireless MACs that\ + * AR531X_NUM_WMAC defines the number of Wireless MACs that\
+ * should be considered available. + * should be considered available.
@ -1805,7 +1811,6 @@
+ .reset_clear = ar5312_device_reset_clear, + .reset_clear = ar5312_device_reset_clear,
+ .reset_mac = AR531X_RESET_ENET0, + .reset_mac = AR531X_RESET_ENET0,
+ .reset_phy = AR531X_RESET_EPHY0, + .reset_phy = AR531X_RESET_EPHY0,
+ .phy_base = AR531X_ENET0,
+ .config = &ar231x_board, + .config = &ar231x_board,
+}; +};
+ +
@ -1814,7 +1819,6 @@
+ .reset_clear = ar5312_device_reset_clear, + .reset_clear = ar5312_device_reset_clear,
+ .reset_mac = AR531X_RESET_ENET1, + .reset_mac = AR531X_RESET_ENET1,
+ .reset_phy = AR531X_RESET_EPHY1, + .reset_phy = AR531X_RESET_EPHY1,
+ .phy_base = AR531X_ENET1,
+ .config = &ar231x_board, + .config = &ar231x_board,
+}; +};
+ +
@ -1936,11 +1940,13 @@
+ switch (ar231x_devtype) { + switch (ar231x_devtype) {
+ case DEV_TYPE_AR5312: + case DEV_TYPE_AR5312:
+ ar5312_eth0_data.macaddr = config->enet0_mac; + ar5312_eth0_data.macaddr = config->enet0_mac;
+ ar231x_add_ethernet(0, AR531X_ENET0, AR5312_IRQ_ENET0_INTRS, + ar231x_add_ethernet(0, AR531X_ENET0, "eth0_mii",
+ AR531X_ENET0_MII, AR5312_IRQ_ENET0_INTRS,
+ &ar5312_eth0_data); + &ar5312_eth0_data);
+ +
+ ar5312_eth1_data.macaddr = config->enet1_mac; + ar5312_eth1_data.macaddr = config->enet1_mac;
+ ar231x_add_ethernet(1, AR531X_ENET1, AR5312_IRQ_ENET1_INTRS, + ar231x_add_ethernet(1, AR531X_ENET1, "eth1_mii",
+ AR531X_ENET1_MII, AR5312_IRQ_ENET1_INTRS,
+ &ar5312_eth1_data); + &ar5312_eth1_data);
+ +
+ if (!ar231x_board.radio) + if (!ar231x_board.radio)
@ -1957,11 +1963,11 @@
+ */ + */
+ case DEV_TYPE_AR2312: + case DEV_TYPE_AR2312:
+ case DEV_TYPE_AR2313: + case DEV_TYPE_AR2313:
+ ar5312_eth1_data.phy_base = ar5312_eth0_data.phy_base;
+ ar5312_eth1_data.reset_phy = ar5312_eth0_data.reset_phy; + ar5312_eth1_data.reset_phy = ar5312_eth0_data.reset_phy;
+ ar5312_eth1_data.macaddr = config->enet0_mac; + ar5312_eth1_data.macaddr = config->enet0_mac;
+ ar231x_add_ethernet(0, AR531X_ENET1, + ar231x_add_ethernet(1, AR531X_ENET1, "eth0_mii",
+ AR5312_IRQ_ENET1_INTRS, &ar5312_eth1_data); + AR531X_ENET0_MII, AR5312_IRQ_ENET1_INTRS,
+ &ar5312_eth1_data);
+ +
+ if (!ar231x_board.radio) + if (!ar231x_board.radio)
+ return 0; + return 0;
@ -2126,7 +2132,7 @@
+ +
--- /dev/null --- /dev/null
+++ b/arch/mips/ar231x/ar2315.c +++ b/arch/mips/ar231x/ar2315.c
@@ -0,0 +1,557 @@ @@ -0,0 +1,556 @@
+/* +/*
+ * This file is subject to the terms and conditions of the GNU General Public + * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive + * License. See the file "COPYING" in the main directory of this archive
@ -2409,7 +2415,6 @@
+ .reset_clear = ar2315_device_reset_clear, + .reset_clear = ar2315_device_reset_clear,
+ .reset_mac = AR2315_RESET_ENET0, + .reset_mac = AR2315_RESET_ENET0,
+ .reset_phy = AR2315_RESET_EPHY0, + .reset_phy = AR2315_RESET_EPHY0,
+ .phy_base = AR2315_ENET0,
+ .config = &ar231x_board, + .config = &ar231x_board,
+}; +};
+ +
@ -2523,8 +2528,8 @@
+ ar2315_init_gpio_leds(); + ar2315_init_gpio_leds();
+ platform_device_register(&ar2315_wdt); + platform_device_register(&ar2315_wdt);
+ platform_device_register(&ar2315_spiflash); + platform_device_register(&ar2315_spiflash);
+ ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS, + ar231x_add_ethernet(0, AR2315_ENET0, "eth0_mii", AR2315_ENET0_MII,
+ &ar2315_eth_data); + AR2315_IRQ_ENET0_INTRS, &ar2315_eth_data);
+ ar231x_add_wmac(0, AR2315_WLAN0, AR2315_IRQ_WLAN0_INTRS); + ar231x_add_wmac(0, AR2315_WLAN0, AR2315_IRQ_WLAN0_INTRS);
+ +
+ return 0; + return 0;
@ -2813,7 +2818,7 @@
+#endif +#endif
--- /dev/null --- /dev/null
+++ b/arch/mips/ar231x/devices.h +++ b/arch/mips/ar231x/devices.h
@@ -0,0 +1,37 @@ @@ -0,0 +1,38 @@
+#ifndef __AR231X_DEVICES_H +#ifndef __AR231X_DEVICES_H
+#define __AR231X_DEVICES_H +#define __AR231X_DEVICES_H
+ +
@ -2838,7 +2843,8 @@
+extern int ar231x_find_config(u8 *flash_limit); +extern int ar231x_find_config(u8 *flash_limit);
+extern void ar231x_serial_setup(u32 mapbase, int irq, unsigned int uartclk); +extern void ar231x_serial_setup(u32 mapbase, int irq, unsigned int uartclk);
+extern int ar231x_add_wmac(int nr, u32 base, int irq); +extern int ar231x_add_wmac(int nr, u32 base, int irq);
+extern int ar231x_add_ethernet(int nr, u32 base, int irq, void *pdata); +extern int ar231x_add_ethernet(int nr, u32 base, const char *mii_name,
+ u32 mii_base, int irq, void *pdata);
+ +
+static inline bool is_2315(void) +static inline bool is_2315(void)
+{ +{
@ -2853,7 +2859,7 @@
+#endif +#endif
--- /dev/null --- /dev/null
+++ b/arch/mips/ar231x/devices.c +++ b/arch/mips/ar231x/devices.c
@@ -0,0 +1,168 @@ @@ -0,0 +1,181 @@
+#include <linux/kernel.h> +#include <linux/kernel.h>
+#include <linux/init.h> +#include <linux/init.h>
+#include <linux/serial.h> +#include <linux/serial.h>
@ -2875,6 +2881,10 @@
+ .flags = IORESOURCE_MEM, + .flags = IORESOURCE_MEM,
+ }, + },
+ { + {
+ .name = "eth0_mii",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "eth0_irq", + .name = "eth0_irq",
+ .flags = IORESOURCE_IRQ, + .flags = IORESOURCE_IRQ,
+ } + }
@ -2886,6 +2896,10 @@
+ .flags = IORESOURCE_MEM, + .flags = IORESOURCE_MEM,
+ }, + },
+ { + {
+ .name = "eth1_mii",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "eth1_irq", + .name = "eth1_irq",
+ .flags = IORESOURCE_IRQ, + .flags = IORESOURCE_IRQ,
+ } + }
@ -2966,7 +2980,8 @@
+ +
+ +
+int __init +int __init
+ar231x_add_ethernet(int nr, u32 base, int irq, void *pdata) +ar231x_add_ethernet(int nr, u32 base, const char *mii_name, u32 mii_base,
+ int irq, void *pdata)
+{ +{
+ struct resource *res; + struct resource *res;
+ +
@ -2975,6 +2990,10 @@
+ res->start = base; + res->start = base;
+ res->end = base + 0x2000 - 1; + res->end = base + 0x2000 - 1;
+ res++; + res++;
+ res->name = mii_name;
+ res->start = mii_base;
+ res->end = mii_base + 8 - 1;
+ res++;
+ res->start = irq; + res->start = irq;
+ res->end = irq; + res->end = irq;
+ return platform_device_register(&ar231x_eth[nr]); + return platform_device_register(&ar231x_eth[nr]);

View File

@ -33,7 +33,7 @@
+obj-$(CONFIG_NET_AR231X) += ar231x.o +obj-$(CONFIG_NET_AR231X) += ar231x.o
--- /dev/null --- /dev/null
+++ b/drivers/net/ethernet/atheros/ar231x/ar231x.c +++ b/drivers/net/ethernet/atheros/ar231x/ar231x.c
@@ -0,0 +1,1246 @@ @@ -0,0 +1,1250 @@
+/* +/*
+ * ar231x.c: Linux driver for the Atheros AR231x Ethernet device. + * ar231x.c: Linux driver for the Atheros AR231x Ethernet device.
+ * + *
@ -216,7 +216,7 @@
+#endif +#endif
+}; +};
+ +
+int ar231x_probe(struct platform_device *pdev) +static int ar231x_probe(struct platform_device *pdev)
+{ +{
+ struct net_device *dev; + struct net_device *dev;
+ struct ar231x_private *sp; + struct ar231x_private *sp;
@ -266,17 +266,19 @@
+ /** + /**
+ * When there's only one MAC, PHY regs are typically on ENET0, + * When there's only one MAC, PHY regs are typically on ENET0,
+ * even though the MAC might be on ENET1. + * even though the MAC might be on ENET1.
+ * Needto remap PHY regs separately in this case + * So remap PHY regs separately.
+ */ + */
+ if (ar_eth_base == sp->cfg->phy_base) + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eth0_mii");
+ sp->phy_regs = sp->eth_regs; + if (!res) {
+ else { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ sp->phy_regs = ioremap_nocache(sp->cfg->phy_base, + "eth1_mii");
+ sizeof(*sp->phy_regs)); + if (!res)
+ if (!sp->phy_regs) { + return -ENODEV;
+ printk("Can't remap phy registers\n"); + }
+ return -ENXIO; + sp->phy_regs = ioremap_nocache(res->start, resource_size(res));
+ } + if (!sp->phy_regs) {
+ printk("Can't remap phy registers\n");
+ return -ENXIO;
+ } + }
+ +
+ sp->dma_regs = ioremap_nocache(ar_eth_base + 0x1000, + sp->dma_regs = ioremap_nocache(ar_eth_base + 0x1000,
@ -482,6 +484,8 @@
+ iounmap((void *)sp->eth_regs); + iounmap((void *)sp->eth_regs);
+ if (sp->dma_regs) + if (sp->dma_regs)
+ iounmap((void *)sp->dma_regs); + iounmap((void *)sp->dma_regs);
+ if (sp->phy_regs)
+ iounmap((void *)sp->phy_regs);
+ +
+ if (sp->rx_skb) { + if (sp->rx_skb) {
+ for (j = 0; j < AR2313_DESCR_ENTRIES; j++) { + for (j = 0; j < AR2313_DESCR_ENTRIES; j++) {
@ -1195,7 +1199,7 @@
+{ +{
+ struct net_device *const dev = bus->priv; + struct net_device *const dev = bus->priv;
+ struct ar231x_private *sp = netdev_priv(dev); + struct ar231x_private *sp = netdev_priv(dev);
+ volatile ETHERNET_STRUCT *ethernet = sp->phy_regs; + volatile MII *ethernet = sp->phy_regs;
+ +
+ ethernet->mii_addr = MII_ADDR(phy_addr, regnum); + ethernet->mii_addr = MII_ADDR(phy_addr, regnum);
+ while (ethernet->mii_addr & MII_ADDR_BUSY) + while (ethernet->mii_addr & MII_ADDR_BUSY)
@ -1208,7 +1212,7 @@
+{ +{
+ struct net_device *const dev = bus->priv; + struct net_device *const dev = bus->priv;
+ struct ar231x_private *sp = netdev_priv(dev); + struct ar231x_private *sp = netdev_priv(dev);
+ volatile ETHERNET_STRUCT *ethernet = sp->phy_regs; + volatile MII *ethernet = sp->phy_regs;
+ +
+ while (ethernet->mii_addr & MII_ADDR_BUSY) + while (ethernet->mii_addr & MII_ADDR_BUSY)
+ ; + ;
@ -1282,7 +1286,7 @@
+ +
--- /dev/null --- /dev/null
+++ b/drivers/net/ethernet/atheros/ar231x/ar231x.h +++ b/drivers/net/ethernet/atheros/ar231x/ar231x.h
@@ -0,0 +1,287 @@ @@ -0,0 +1,295 @@
+/* +/*
+ * ar231x.h: Linux driver for the Atheros AR231x Ethernet device. + * ar231x.h: Linux driver for the Atheros AR231x Ethernet device.
+ * + *
@ -1444,13 +1448,16 @@
+ +
+/** +/**
+ * New Combo structure for Both Eth0 AND eth1 + * New Combo structure for Both Eth0 AND eth1
+ *
+ * Don't directly access MII related regs since phy chip could be actually
+ * connected to another ethernet block.
+ */ + */
+typedef struct { +typedef struct {
+ volatile unsigned int mac_control; /* 0x00 */ + volatile unsigned int mac_control; /* 0x00 */
+ volatile unsigned int mac_addr[2]; /* 0x04 - 0x08 */ + volatile unsigned int mac_addr[2]; /* 0x04 - 0x08 */
+ volatile unsigned int mcast_table[2]; /* 0x0c - 0x10 */ + volatile unsigned int mcast_table[2]; /* 0x0c - 0x10 */
+ volatile unsigned int mii_addr; /* 0x14 */ + volatile unsigned int __mii_addr; /* 0x14 */
+ volatile unsigned int mii_data; /* 0x18 */ + volatile unsigned int __mii_data; /* 0x18 */
+ volatile unsigned int flow_control; /* 0x1c */ + volatile unsigned int flow_control; /* 0x1c */
+ volatile unsigned int vlan_tag; /* 0x20 */ + volatile unsigned int vlan_tag; /* 0x20 */
+ volatile unsigned int pad[7]; /* 0x24 - 0x3c */ + volatile unsigned int pad[7]; /* 0x24 - 0x3c */
@ -1458,6 +1465,11 @@
+ +
+} ETHERNET_STRUCT; +} ETHERNET_STRUCT;
+ +
+typedef struct {
+ volatile unsigned int mii_addr;
+ volatile unsigned int mii_data;
+} MII;
+
+/******************************************************************** +/********************************************************************
+ * Interrupt controller + * Interrupt controller
+ ********************************************************************/ + ********************************************************************/
@ -1505,7 +1517,7 @@
+ int version; + int version;
+ u32 mb[2]; + u32 mb[2];
+ +
+ volatile ETHERNET_STRUCT *phy_regs; + volatile MII *phy_regs;
+ volatile ETHERNET_STRUCT *eth_regs; + volatile ETHERNET_STRUCT *eth_regs;
+ volatile DMA *dma_regs; + volatile DMA *dma_regs;
+ struct ar231x_eth *cfg; + struct ar231x_eth *cfg;

View File

@ -38,10 +38,10 @@
+ return 0; + return 0;
+} +}
+ +
int ar231x_probe(struct platform_device *pdev) static int ar231x_probe(struct platform_device *pdev)
{ {
struct net_device *dev; struct net_device *dev;
@@ -284,6 +311,23 @@ int ar231x_probe(struct platform_device @@ -286,6 +313,23 @@ static int ar231x_probe(struct platform_
mdiobus_register(sp->mii_bus); mdiobus_register(sp->mii_bus);
@ -65,7 +65,7 @@
if (ar231x_mdiobus_probe(dev) != 0) { if (ar231x_mdiobus_probe(dev) != 0) {
printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name); printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name);
rx_tasklet_cleanup(dev); rx_tasklet_cleanup(dev);
@@ -340,8 +384,10 @@ static int ar231x_remove(struct platform @@ -342,8 +386,10 @@ static int ar231x_remove(struct platform
rx_tasklet_cleanup(dev); rx_tasklet_cleanup(dev);
ar231x_init_cleanup(dev); ar231x_init_cleanup(dev);
unregister_netdev(dev); unregister_netdev(dev);
@ -78,7 +78,7 @@
kfree(dev); kfree(dev);
return 0; return 0;
} }
@@ -1100,6 +1146,9 @@ static int ar231x_ioctl(struct net_devic @@ -1104,6 +1150,9 @@ static int ar231x_ioctl(struct net_devic
struct ar231x_private *sp = netdev_priv(dev); struct ar231x_private *sp = netdev_priv(dev);
int ret; int ret;