From 48838c74bbed64b47bd7253b72c30677f931af36 Mon Sep 17 00:00:00 2001 From: nbd Date: Thu, 17 Jul 2014 16:36:46 +0000 Subject: [PATCH] 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 git-svn-id: svn://svn.openwrt.org/openwrt/trunk@41698 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/atheros/patches-3.10/100-board.patch | 57 ++++++++++++++-------- .../atheros/patches-3.10/110-ar2313_ethernet.patch | 48 +++++++++++------- .../patches-3.10/220-enet_micrel_workaround.patch | 8 +-- 3 files changed, 72 insertions(+), 41 deletions(-) diff --git a/target/linux/atheros/patches-3.10/100-board.patch b/target/linux/atheros/patches-3.10/100-board.patch index b9a88a1b1d..4fdf435e87 100644 --- a/target/linux/atheros/patches-3.10/100-board.patch +++ b/target/linux/atheros/patches-3.10/100-board.patch @@ -388,7 +388,7 @@ +} --- /dev/null +++ b/arch/mips/include/asm/mach-ar231x/ar231x_platform.h -@@ -0,0 +1,84 @@ +@@ -0,0 +1,83 @@ +#ifndef __AR531X_PLATFORM_H +#define __AR531X_PLATFORM_H + @@ -467,7 +467,6 @@ + void (*reset_clear)(u32); + u32 reset_mac; + u32 reset_phy; -+ u32 phy_base; + struct ar231x_board_config *config; + char *macaddr; +}; @@ -714,7 +713,7 @@ +#endif /* __ASM_MIPS_MACH_ATHEROS_WAR_H */ --- /dev/null +++ b/arch/mips/include/asm/mach-ar231x/ar2315_regs.h -@@ -0,0 +1,614 @@ +@@ -0,0 +1,617 @@ +/* + * Register definitions for AR2315+ + * @@ -771,6 +770,9 @@ +#define AR2315_SPI_MMR 0x11300000 /* SPI FLASH MMR */ +#define AR2315_PCIEXT 0x80000000 /* pci external */ + ++/* MII registers offset inside Ethernet MMR region */ ++#define AR2315_ENET0_MII (AR2315_ENET0 + 0x14) ++ +/* + * Reset Register + */ @@ -1331,7 +1333,7 @@ +#endif /* __AR2315_REG_H */ --- /dev/null +++ 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 + * 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_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\ + * should be considered available. @@ -1805,7 +1811,6 @@ + .reset_clear = ar5312_device_reset_clear, + .reset_mac = AR531X_RESET_ENET0, + .reset_phy = AR531X_RESET_EPHY0, -+ .phy_base = AR531X_ENET0, + .config = &ar231x_board, +}; + @@ -1814,7 +1819,6 @@ + .reset_clear = ar5312_device_reset_clear, + .reset_mac = AR531X_RESET_ENET1, + .reset_phy = AR531X_RESET_EPHY1, -+ .phy_base = AR531X_ENET1, + .config = &ar231x_board, +}; + @@ -1936,11 +1940,13 @@ + switch (ar231x_devtype) { + case DEV_TYPE_AR5312: + 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_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); + + if (!ar231x_board.radio) @@ -1957,11 +1963,11 @@ + */ + case DEV_TYPE_AR2312: + 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.macaddr = config->enet0_mac; -+ ar231x_add_ethernet(0, AR531X_ENET1, -+ AR5312_IRQ_ENET1_INTRS, &ar5312_eth1_data); ++ ar231x_add_ethernet(1, AR531X_ENET1, "eth0_mii", ++ AR531X_ENET0_MII, AR5312_IRQ_ENET1_INTRS, ++ &ar5312_eth1_data); + + if (!ar231x_board.radio) + return 0; @@ -2126,7 +2132,7 @@ + --- /dev/null +++ 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 + * License. See the file "COPYING" in the main directory of this archive @@ -2409,7 +2415,6 @@ + .reset_clear = ar2315_device_reset_clear, + .reset_mac = AR2315_RESET_ENET0, + .reset_phy = AR2315_RESET_EPHY0, -+ .phy_base = AR2315_ENET0, + .config = &ar231x_board, +}; + @@ -2523,8 +2528,8 @@ + ar2315_init_gpio_leds(); + platform_device_register(&ar2315_wdt); + platform_device_register(&ar2315_spiflash); -+ ar231x_add_ethernet(0, AR2315_ENET0, AR2315_IRQ_ENET0_INTRS, -+ &ar2315_eth_data); ++ ar231x_add_ethernet(0, AR2315_ENET0, "eth0_mii", AR2315_ENET0_MII, ++ AR2315_IRQ_ENET0_INTRS, &ar2315_eth_data); + ar231x_add_wmac(0, AR2315_WLAN0, AR2315_IRQ_WLAN0_INTRS); + + return 0; @@ -2813,7 +2818,7 @@ +#endif --- /dev/null +++ b/arch/mips/ar231x/devices.h -@@ -0,0 +1,37 @@ +@@ -0,0 +1,38 @@ +#ifndef __AR231X_DEVICES_H +#define __AR231X_DEVICES_H + @@ -2838,7 +2843,8 @@ +extern int ar231x_find_config(u8 *flash_limit); +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_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) +{ @@ -2853,7 +2859,7 @@ +#endif --- /dev/null +++ b/arch/mips/ar231x/devices.c -@@ -0,0 +1,168 @@ +@@ -0,0 +1,181 @@ +#include +#include +#include @@ -2875,6 +2881,10 @@ + .flags = IORESOURCE_MEM, + }, + { ++ .name = "eth0_mii", ++ .flags = IORESOURCE_MEM, ++ }, ++ { + .name = "eth0_irq", + .flags = IORESOURCE_IRQ, + } @@ -2886,6 +2896,10 @@ + .flags = IORESOURCE_MEM, + }, + { ++ .name = "eth1_mii", ++ .flags = IORESOURCE_MEM, ++ }, ++ { + .name = "eth1_irq", + .flags = IORESOURCE_IRQ, + } @@ -2966,7 +2980,8 @@ + + +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; + @@ -2975,6 +2990,10 @@ + res->start = base; + res->end = base + 0x2000 - 1; + res++; ++ res->name = mii_name; ++ res->start = mii_base; ++ res->end = mii_base + 8 - 1; ++ res++; + res->start = irq; + res->end = irq; + return platform_device_register(&ar231x_eth[nr]); diff --git a/target/linux/atheros/patches-3.10/110-ar2313_ethernet.patch b/target/linux/atheros/patches-3.10/110-ar2313_ethernet.patch index 0e158d4d01..a9dcab24c9 100644 --- a/target/linux/atheros/patches-3.10/110-ar2313_ethernet.patch +++ b/target/linux/atheros/patches-3.10/110-ar2313_ethernet.patch @@ -33,7 +33,7 @@ +obj-$(CONFIG_NET_AR231X) += ar231x.o --- /dev/null +++ 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. + * @@ -216,7 +216,7 @@ +#endif +}; + -+int ar231x_probe(struct platform_device *pdev) ++static int ar231x_probe(struct platform_device *pdev) +{ + struct net_device *dev; + struct ar231x_private *sp; @@ -266,17 +266,19 @@ + /** + * When there's only one MAC, PHY regs are typically on ENET0, + * 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) -+ sp->phy_regs = sp->eth_regs; -+ else { -+ sp->phy_regs = ioremap_nocache(sp->cfg->phy_base, -+ sizeof(*sp->phy_regs)); -+ if (!sp->phy_regs) { -+ printk("Can't remap phy registers\n"); -+ return -ENXIO; -+ } ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "eth0_mii"); ++ if (!res) { ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, ++ "eth1_mii"); ++ if (!res) ++ return -ENODEV; ++ } ++ 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, @@ -482,6 +484,8 @@ + iounmap((void *)sp->eth_regs); + if (sp->dma_regs) + iounmap((void *)sp->dma_regs); ++ if (sp->phy_regs) ++ iounmap((void *)sp->phy_regs); + + if (sp->rx_skb) { + for (j = 0; j < AR2313_DESCR_ENTRIES; j++) { @@ -1195,7 +1199,7 @@ +{ + struct net_device *const dev = bus->priv; + 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); + while (ethernet->mii_addr & MII_ADDR_BUSY) @@ -1208,7 +1212,7 @@ +{ + struct net_device *const dev = bus->priv; + 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) + ; @@ -1282,7 +1286,7 @@ + --- /dev/null +++ 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. + * @@ -1444,13 +1448,16 @@ + +/** + * 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 { + volatile unsigned int mac_control; /* 0x00 */ + volatile unsigned int mac_addr[2]; /* 0x04 - 0x08 */ + volatile unsigned int mcast_table[2]; /* 0x0c - 0x10 */ -+ volatile unsigned int mii_addr; /* 0x14 */ -+ volatile unsigned int mii_data; /* 0x18 */ ++ volatile unsigned int __mii_addr; /* 0x14 */ ++ volatile unsigned int __mii_data; /* 0x18 */ + volatile unsigned int flow_control; /* 0x1c */ + volatile unsigned int vlan_tag; /* 0x20 */ + volatile unsigned int pad[7]; /* 0x24 - 0x3c */ @@ -1458,6 +1465,11 @@ + +} ETHERNET_STRUCT; + ++typedef struct { ++ volatile unsigned int mii_addr; ++ volatile unsigned int mii_data; ++} MII; ++ +/******************************************************************** + * Interrupt controller + ********************************************************************/ @@ -1505,7 +1517,7 @@ + int version; + u32 mb[2]; + -+ volatile ETHERNET_STRUCT *phy_regs; ++ volatile MII *phy_regs; + volatile ETHERNET_STRUCT *eth_regs; + volatile DMA *dma_regs; + struct ar231x_eth *cfg; diff --git a/target/linux/atheros/patches-3.10/220-enet_micrel_workaround.patch b/target/linux/atheros/patches-3.10/220-enet_micrel_workaround.patch index 361b4e3466..dade7ee6ab 100644 --- a/target/linux/atheros/patches-3.10/220-enet_micrel_workaround.patch +++ b/target/linux/atheros/patches-3.10/220-enet_micrel_workaround.patch @@ -38,10 +38,10 @@ + return 0; +} + - int ar231x_probe(struct platform_device *pdev) + static int ar231x_probe(struct platform_device *pdev) { 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); @@ -65,7 +65,7 @@ if (ar231x_mdiobus_probe(dev) != 0) { printk(KERN_ERR "%s: mdiobus_probe failed\n", dev->name); 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); ar231x_init_cleanup(dev); unregister_netdev(dev); @@ -78,7 +78,7 @@ kfree(dev); 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); int ret; -- 2.11.0