From 15b5d38385d8261339eed833b85a339505f4105c Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 24 Dec 2017 13:56:24 +0100 Subject: linux: bump kernel 4.4.x 4.9.x 4.14.x --- target/config/Config.in.kernelversion | 12 +- target/linux/patches/4.13.13/h8300.patch | 12 - target/linux/patches/4.13.13/or1k-more-ram.patch | 12 - target/linux/patches/4.14.8/h8300.patch | 12 + target/linux/patches/4.14.8/or1k-more-ram.patch | 12 + .../patches/4.4.107/coldfire-sighandler.patch | 100 + target/linux/patches/4.4.107/crisv32.patch | 33 + .../patches/4.4.107/crisv32_ethernet_driver.patch | 4048 +++ target/linux/patches/4.4.107/h8300.patch | 44 + .../patches/4.4.107/initramfs-nosizelimit.patch | 57 + target/linux/patches/4.4.107/ld-or1k.patch | 12 + target/linux/patches/4.4.107/macsonic.patch | 11 + target/linux/patches/4.4.107/mips-xz.patch | 12 + target/linux/patches/4.4.107/patch-realtime | 32228 +++++++++++++++++++ target/linux/patches/4.4.107/startup.patch | 34 + .../linux/patches/4.4.107/use-libgcc-for-sh.patch | 29 + target/linux/patches/4.4.107/versatile-nommu.patch | 16 + .../linux/patches/4.4.96/coldfire-sighandler.patch | 100 - target/linux/patches/4.4.96/crisv32.patch | 33 - .../patches/4.4.96/crisv32_ethernet_driver.patch | 4048 --- target/linux/patches/4.4.96/h8300.patch | 44 - .../patches/4.4.96/initramfs-nosizelimit.patch | 57 - target/linux/patches/4.4.96/ld-or1k.patch | 12 - target/linux/patches/4.4.96/macsonic.patch | 11 - target/linux/patches/4.4.96/mips-xz.patch | 12 - target/linux/patches/4.4.96/patch-realtime | 32228 ------------------- target/linux/patches/4.4.96/startup.patch | 34 - .../linux/patches/4.4.96/use-libgcc-for-sh.patch | 29 - target/linux/patches/4.4.96/versatile-nommu.patch | 16 - .../patches/4.9.60/crisv32_ethernet_driver.patch | 4048 --- target/linux/patches/4.9.60/h8300.patch | 44 - .../patches/4.9.60/initramfs-nosizelimit.patch | 57 - target/linux/patches/4.9.60/ld-or1k.patch | 12 - target/linux/patches/4.9.60/macsonic.patch | 11 - .../patches/4.9.60/microblaze-sigaltstack.patch | 12 - target/linux/patches/4.9.60/or1k-more-ram.patch | 12 - target/linux/patches/4.9.60/patch-realtime | 26986 ---------------- target/linux/patches/4.9.60/sh2.patch | 11 - target/linux/patches/4.9.60/startup.patch | 34 - target/linux/patches/4.9.60/vdso2.patch | 27 - .../patches/4.9.71/crisv32_ethernet_driver.patch | 4048 +++ target/linux/patches/4.9.71/h8300.patch | 44 + .../patches/4.9.71/initramfs-nosizelimit.patch | 57 + target/linux/patches/4.9.71/ld-or1k.patch | 12 + target/linux/patches/4.9.71/macsonic.patch | 11 + .../patches/4.9.71/microblaze-sigaltstack.patch | 12 + target/linux/patches/4.9.71/or1k-more-ram.patch | 12 + target/linux/patches/4.9.71/patch-realtime | 26986 ++++++++++++++++ target/linux/patches/4.9.71/sh2.patch | 11 + target/linux/patches/4.9.71/startup.patch | 34 + target/linux/patches/4.9.71/vdso2.patch | 27 + 51 files changed, 67908 insertions(+), 67908 deletions(-) delete mode 100644 target/linux/patches/4.13.13/h8300.patch delete mode 100644 target/linux/patches/4.13.13/or1k-more-ram.patch create mode 100644 target/linux/patches/4.14.8/h8300.patch create mode 100644 target/linux/patches/4.14.8/or1k-more-ram.patch create mode 100644 target/linux/patches/4.4.107/coldfire-sighandler.patch create mode 100644 target/linux/patches/4.4.107/crisv32.patch create mode 100644 target/linux/patches/4.4.107/crisv32_ethernet_driver.patch create mode 100644 target/linux/patches/4.4.107/h8300.patch create mode 100644 target/linux/patches/4.4.107/initramfs-nosizelimit.patch create mode 100644 target/linux/patches/4.4.107/ld-or1k.patch create mode 100644 target/linux/patches/4.4.107/macsonic.patch create mode 100644 target/linux/patches/4.4.107/mips-xz.patch create mode 100644 target/linux/patches/4.4.107/patch-realtime create mode 100644 target/linux/patches/4.4.107/startup.patch create mode 100644 target/linux/patches/4.4.107/use-libgcc-for-sh.patch create mode 100644 target/linux/patches/4.4.107/versatile-nommu.patch delete mode 100644 target/linux/patches/4.4.96/coldfire-sighandler.patch delete mode 100644 target/linux/patches/4.4.96/crisv32.patch delete mode 100644 target/linux/patches/4.4.96/crisv32_ethernet_driver.patch delete mode 100644 target/linux/patches/4.4.96/h8300.patch delete mode 100644 target/linux/patches/4.4.96/initramfs-nosizelimit.patch delete mode 100644 target/linux/patches/4.4.96/ld-or1k.patch delete mode 100644 target/linux/patches/4.4.96/macsonic.patch delete mode 100644 target/linux/patches/4.4.96/mips-xz.patch delete mode 100644 target/linux/patches/4.4.96/patch-realtime delete mode 100644 target/linux/patches/4.4.96/startup.patch delete mode 100644 target/linux/patches/4.4.96/use-libgcc-for-sh.patch delete mode 100644 target/linux/patches/4.4.96/versatile-nommu.patch delete mode 100644 target/linux/patches/4.9.60/crisv32_ethernet_driver.patch delete mode 100644 target/linux/patches/4.9.60/h8300.patch delete mode 100644 target/linux/patches/4.9.60/initramfs-nosizelimit.patch delete mode 100644 target/linux/patches/4.9.60/ld-or1k.patch delete mode 100644 target/linux/patches/4.9.60/macsonic.patch delete mode 100644 target/linux/patches/4.9.60/microblaze-sigaltstack.patch delete mode 100644 target/linux/patches/4.9.60/or1k-more-ram.patch delete mode 100644 target/linux/patches/4.9.60/patch-realtime delete mode 100644 target/linux/patches/4.9.60/sh2.patch delete mode 100644 target/linux/patches/4.9.60/startup.patch delete mode 100644 target/linux/patches/4.9.60/vdso2.patch create mode 100644 target/linux/patches/4.9.71/crisv32_ethernet_driver.patch create mode 100644 target/linux/patches/4.9.71/h8300.patch create mode 100644 target/linux/patches/4.9.71/initramfs-nosizelimit.patch create mode 100644 target/linux/patches/4.9.71/ld-or1k.patch create mode 100644 target/linux/patches/4.9.71/macsonic.patch create mode 100644 target/linux/patches/4.9.71/microblaze-sigaltstack.patch create mode 100644 target/linux/patches/4.9.71/or1k-more-ram.patch create mode 100644 target/linux/patches/4.9.71/patch-realtime create mode 100644 target/linux/patches/4.9.71/sh2.patch create mode 100644 target/linux/patches/4.9.71/startup.patch create mode 100644 target/linux/patches/4.9.71/vdso2.patch (limited to 'target') diff --git a/target/config/Config.in.kernelversion b/target/config/Config.in.kernelversion index b3c57ac21..099153153 100644 --- a/target/config/Config.in.kernelversion +++ b/target/config/Config.in.kernelversion @@ -19,8 +19,8 @@ default ADK_TARGET_KERNEL_VERSION_4_4 if ADK_TARGET_ARCH_H8300 default ADK_TARGET_KERNEL_VERSION_4_4 if ADK_TARGET_ARCH_METAG default ADK_TARGET_KERNEL_VERSION_4_4 if ADK_TARGET_SYSTEM_QEMU_ARM_VERSATILEPB_NOMMU default ADK_TARGET_KERNEL_VERSION_4_4 if ADK_TARGET_SYSTEM_QEMU_ARM_REALVIEW_EB_MPCORE -default ADK_TARGET_KERNEL_VERSION_4_13 if ADK_TARGET_SYSTEM_ORANGE_PI0 -default ADK_TARGET_KERNEL_VERSION_4_13 if ADK_TARGET_ARCH_OR1K +default ADK_TARGET_KERNEL_VERSION_4_14 if ADK_TARGET_SYSTEM_ORANGE_PI0 +default ADK_TARGET_KERNEL_VERSION_4_14 if ADK_TARGET_ARCH_OR1K default ADK_TARGET_KERNEL_VERSION_4_9 config ADK_TARGET_KERNEL_VERSION_GIT @@ -33,8 +33,8 @@ config ADK_TARGET_KERNEL_VERSION_GIT select ADK_TARGET_KERNEL_IMAGE if ADK_TARGET_SYSTEM_SOLIDRUN_IMX6 select ADK_TARGET_KERNEL_IMAGE if ADK_TARGET_SYSTEM_BEAGLEBONE_BLACK -config ADK_TARGET_KERNEL_VERSION_4_13 - bool "4.13.13" +config ADK_TARGET_KERNEL_VERSION_4_14 + bool "4.14.8" depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_CRIS depends on !ADK_TARGET_ARCH_CSKY @@ -46,7 +46,7 @@ config ADK_TARGET_KERNEL_VERSION_4_13 depends on !ADK_TARGET_SYSTEM_QEMU_ARM_REALVIEW_EB_MPCORE config ADK_TARGET_KERNEL_VERSION_4_9 - bool "4.9.60" + bool "4.9.71" depends on !ADK_TARGET_ARCH_CRIS depends on !ADK_TARGET_ARCH_CSKY depends on !ADK_TARGET_ARCH_METAG @@ -59,7 +59,7 @@ config ADK_TARGET_KERNEL_VERSION_4_9 depends on !ADK_TARGET_SYSTEM_ORANGE_PI0 config ADK_TARGET_KERNEL_VERSION_4_4 - bool "4.4.96" + bool "4.4.107" depends on !ADK_TARGET_ARCH_CSKY depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 diff --git a/target/linux/patches/4.13.13/h8300.patch b/target/linux/patches/4.13.13/h8300.patch deleted file mode 100644 index 836a414e5..000000000 --- a/target/linux/patches/4.13.13/h8300.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur linux-4.13.2.orig/arch/h8300/Kconfig.cpu linux-4.13.2/arch/h8300/Kconfig.cpu ---- linux-4.13.2.orig/arch/h8300/Kconfig.cpu 2017-09-13 23:21:49.000000000 +0200 -+++ linux-4.13.2/arch/h8300/Kconfig.cpu 2017-09-16 18:32:15.263759679 +0200 -@@ -96,4 +96,8 @@ - hex "Load offset" - default 0 - -+config RAMBASE -+ hex "RAM base address" -+ default 0x400000 -+ - endmenu diff --git a/target/linux/patches/4.13.13/or1k-more-ram.patch b/target/linux/patches/4.13.13/or1k-more-ram.patch deleted file mode 100644 index de848c838..000000000 --- a/target/linux/patches/4.13.13/or1k-more-ram.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur linux-4.8.11.orig/arch/openrisc/boot/dts/or1ksim.dts linux-4.8.11/arch/openrisc/boot/dts/or1ksim.dts ---- linux-4.8.11.orig/arch/openrisc/boot/dts/or1ksim.dts 2016-11-26 09:57:13.000000000 +0100 -+++ linux-4.8.11/arch/openrisc/boot/dts/or1ksim.dts 2016-12-04 14:39:46.092952799 +0100 -@@ -11,7 +11,7 @@ - - memory@0 { - device_type = "memory"; -- reg = <0x00000000 0x02000000>; -+ reg = <0x00000000 0x04000000>; - }; - - cpus { diff --git a/target/linux/patches/4.14.8/h8300.patch b/target/linux/patches/4.14.8/h8300.patch new file mode 100644 index 000000000..836a414e5 --- /dev/null +++ b/target/linux/patches/4.14.8/h8300.patch @@ -0,0 +1,12 @@ +diff -Nur linux-4.13.2.orig/arch/h8300/Kconfig.cpu linux-4.13.2/arch/h8300/Kconfig.cpu +--- linux-4.13.2.orig/arch/h8300/Kconfig.cpu 2017-09-13 23:21:49.000000000 +0200 ++++ linux-4.13.2/arch/h8300/Kconfig.cpu 2017-09-16 18:32:15.263759679 +0200 +@@ -96,4 +96,8 @@ + hex "Load offset" + default 0 + ++config RAMBASE ++ hex "RAM base address" ++ default 0x400000 ++ + endmenu diff --git a/target/linux/patches/4.14.8/or1k-more-ram.patch b/target/linux/patches/4.14.8/or1k-more-ram.patch new file mode 100644 index 000000000..de848c838 --- /dev/null +++ b/target/linux/patches/4.14.8/or1k-more-ram.patch @@ -0,0 +1,12 @@ +diff -Nur linux-4.8.11.orig/arch/openrisc/boot/dts/or1ksim.dts linux-4.8.11/arch/openrisc/boot/dts/or1ksim.dts +--- linux-4.8.11.orig/arch/openrisc/boot/dts/or1ksim.dts 2016-11-26 09:57:13.000000000 +0100 ++++ linux-4.8.11/arch/openrisc/boot/dts/or1ksim.dts 2016-12-04 14:39:46.092952799 +0100 +@@ -11,7 +11,7 @@ + + memory@0 { + device_type = "memory"; +- reg = <0x00000000 0x02000000>; ++ reg = <0x00000000 0x04000000>; + }; + + cpus { diff --git a/target/linux/patches/4.4.107/coldfire-sighandler.patch b/target/linux/patches/4.4.107/coldfire-sighandler.patch new file mode 100644 index 000000000..c52a4e228 --- /dev/null +++ b/target/linux/patches/4.4.107/coldfire-sighandler.patch @@ -0,0 +1,100 @@ +From a95517992a37488c0bc8b629c47c570e580e407d Mon Sep 17 00:00:00 2001 +From: Greg Ungerer +Date: Mon, 15 Feb 2016 16:36:29 +1000 +Subject: m68k: Use conventional function parameters for do_sigreturn + +Create conventional stack parameters for the calls to do_sigreturn and +do_rt_sigreturn. The current C code for do_sigreturn and do_rt_sigreturn +dig into the stack to create local pointers to the saved switch stack +and the pt_regs structs. + +The motivation for this change is a problem with non-MMU targets that +have broken signal return paths on newer versions of gcc. It appears as +though gcc has determined that the pointers into the saved stack structs, +and the saved structs themselves, are function parameters and updates to +them will be lost on function return, so they are optimized away. This +results in large parts of restore_sigcontext() and mangle_kernel_stack() +functions being removed. Of course this results in non-functional code +causing kernel oops. This problem has been observed with gcc version +5.2 and 5.3, and probably exists in earlier versions as well. + +Using conventional stack parameter pointers passed to these functions has +the advantage of the code here not needing to know the exact details of +how the underlying entry handler layed these structs out on the stack. +So the rather ugly pointer setup casting and arg referencing can be +removed. + +The resulting code after this change is a few bytes larger (due to the +overhead of creating the stack args and their tear down). Not being hot +paths I don't think this is too much of a problem here. + +An alternative solution is to put a barrier() in the do_sigreturn() code, +but this doesn't feel quite as clean as this solution. + +This change has been compile tested on all defconfigs, and run tested on +Atari (through aranym), ColdFire with MMU (M5407EVB) and ColdFire with +no-MMU (QEMU and M5208EVB). + +Signed-off-by: Greg Ungerer +Acked-by: Andreas Schwab +Signed-off-by: Geert Uytterhoeven +--- + arch/m68k/kernel/entry.S | 6 ++++++ + arch/m68k/kernel/signal.c | 8 ++------ + 2 files changed, 8 insertions(+), 6 deletions(-) + +diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S +index b54ac7a..97cd3ea 100644 +--- a/arch/m68k/kernel/entry.S ++++ b/arch/m68k/kernel/entry.S +@@ -71,13 +71,19 @@ ENTRY(__sys_vfork) + + ENTRY(sys_sigreturn) + SAVE_SWITCH_STACK ++ movel %sp,%sp@- | switch_stack pointer ++ pea %sp@(SWITCH_STACK_SIZE+4) | pt_regs pointer + jbsr do_sigreturn ++ addql #8,%sp + RESTORE_SWITCH_STACK + rts + + ENTRY(sys_rt_sigreturn) + SAVE_SWITCH_STACK ++ movel %sp,%sp@- | switch_stack pointer ++ pea %sp@(SWITCH_STACK_SIZE+4) | pt_regs pointer + jbsr do_rt_sigreturn ++ addql #8,%sp + RESTORE_SWITCH_STACK + rts + +diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c +index af1c4f3..2dcee3a 100644 +--- a/arch/m68k/kernel/signal.c ++++ b/arch/m68k/kernel/signal.c +@@ -737,10 +737,8 @@ badframe: + return 1; + } + +-asmlinkage int do_sigreturn(unsigned long __unused) ++asmlinkage int do_sigreturn(struct pt_regs *regs, struct switch_stack *sw) + { +- struct switch_stack *sw = (struct switch_stack *) &__unused; +- struct pt_regs *regs = (struct pt_regs *) (sw + 1); + unsigned long usp = rdusp(); + struct sigframe __user *frame = (struct sigframe __user *)(usp - 4); + sigset_t set; +@@ -764,10 +762,8 @@ badframe: + return 0; + } + +-asmlinkage int do_rt_sigreturn(unsigned long __unused) ++asmlinkage int do_rt_sigreturn(struct pt_regs *regs, struct switch_stack *sw) + { +- struct switch_stack *sw = (struct switch_stack *) &__unused; +- struct pt_regs *regs = (struct pt_regs *) (sw + 1); + unsigned long usp = rdusp(); + struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4); + sigset_t set; +-- +cgit v0.12 + diff --git a/target/linux/patches/4.4.107/crisv32.patch b/target/linux/patches/4.4.107/crisv32.patch new file mode 100644 index 000000000..cb9b0d028 --- /dev/null +++ b/target/linux/patches/4.4.107/crisv32.patch @@ -0,0 +1,33 @@ +diff -Nur linux-4.4.13.orig/arch/cris/arch-v32/mm/intmem.c linux-4.4.13/arch/cris/arch-v32/mm/intmem.c +--- linux-4.4.13.orig/arch/cris/arch-v32/mm/intmem.c 2016-06-08 03:14:51.000000000 +0200 ++++ linux-4.4.13/arch/cris/arch-v32/mm/intmem.c 2016-06-21 20:40:18.919361891 +0200 +@@ -113,14 +113,14 @@ + + allocation->status = STATUS_FREE; + /* Join with prev and/or next if also free */ +- if ((prev != &intmem_allocations) && ++ if ((&prev->entry != &intmem_allocations) && + (prev->status == STATUS_FREE)) { + prev->size += allocation->size; + list_del(&allocation->entry); + kfree(allocation); + allocation = prev; + } +- if ((next != &intmem_allocations) && ++ if ((&next->entry != &intmem_allocations) && + (next->status == STATUS_FREE)) { + allocation->size += next->size; + list_del(&next->entry); +@@ -145,5 +145,11 @@ + (unsigned long)intmem_virtual + MEM_INTMEM_START + + RESERVED_SIZE); + } +-device_initcall(crisv32_intmem_init); + ++static int __init crisv32_intmem_setup(void) ++{ ++ crisv32_intmem_init(); ++ ++ return 0; ++} ++device_initcall(crisv32_intmem_setup); diff --git a/target/linux/patches/4.4.107/crisv32_ethernet_driver.patch b/target/linux/patches/4.4.107/crisv32_ethernet_driver.patch new file mode 100644 index 000000000..0cef202fc --- /dev/null +++ b/target/linux/patches/4.4.107/crisv32_ethernet_driver.patch @@ -0,0 +1,4048 @@ +diff -Nur linux-4.7.3.orig/arch/cris/arch-v32/drivers/Kconfig linux-4.7.3/arch/cris/arch-v32/drivers/Kconfig +--- linux-4.7.3.orig/arch/cris/arch-v32/drivers/Kconfig 2016-09-07 08:35:12.000000000 +0200 ++++ linux-4.7.3/arch/cris/arch-v32/drivers/Kconfig 2016-09-13 01:47:09.507717605 +0200 +@@ -8,9 +8,18 @@ + This option enables the ETRAX FS built-in 10/100Mbit Ethernet + controller. + ++config ETRAX_HAVE_PHY ++ bool "PHY present" ++ default y ++ help ++ Search and use the first PHY available on the MDIO bus. Fail ++ if none is found. Say Y here if you are not in a switched ++ environment (single port device). ++ + config ETRAX_NO_PHY + bool "PHY not present" + depends on ETRAX_ETHERNET ++ default n + help + This option disables all MDIO communication with an ethernet + transceiver connected to the MII interface. This option shall +@@ -18,6 +27,70 @@ + switch. This option should normally be disabled. If enabled, + speed and duplex will be locked to 100 Mbit and full duplex. + ++config ETRAX_PHY_FALLBACK ++ bool "Fixed PHY fallback" ++ depends on ETRAX_ETHERNET ++ default n ++ help ++ If no PHY is found on the MDIO bus, fall back on a fixed ++ 100/Full fixed PHY. Say Y here if you need dynamic PHY ++ presence detection (switch connection where some but not ++ all ports have integrated PHYs), otherwise say N. ++ ++config ETRAX_ETHERNET_IFACE0 ++ depends on ETRAX_ETHERNET ++ bool "Enable network interface 0" ++ ++config ETRAX_ETHERNET_IFACE1 ++ depends on (ETRAX_ETHERNET && ETRAXFS) ++ bool "Enable network interface 1 (uses DMA6 and DMA7)" ++ ++choice ++ prompt "Eth0 led group" ++ depends on ETRAX_ETHERNET_IFACE0 ++ default ETRAX_ETH0_USE_LEDGRP0 ++ ++config ETRAX_ETH0_USE_LEDGRP0 ++ bool "Use LED grp 0" ++ depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO ++ help ++ Use LED grp 0 for eth0 ++ ++config ETRAX_ETH0_USE_LEDGRP1 ++ bool "Use LED grp 1" ++ depends on ETRAX_NBR_LED_GRP_TWO ++ help ++ Use LED grp 1 for eth0 ++ ++config ETRAX_ETH0_USE_LEDGRPNULL ++ bool "Use no LEDs for eth0" ++ help ++ Use no LEDs for eth0 ++endchoice ++ ++choice ++ prompt "Eth1 led group" ++ depends on ETRAX_ETHERNET_IFACE1 ++ default ETRAX_ETH1_USE_LEDGRP1 ++ ++config ETRAX_ETH1_USE_LEDGRP0 ++ bool "Use LED grp 0" ++ depends on ETRAX_NBR_LED_GRP_ONE || ETRAX_NBR_LED_GRP_TWO ++ help ++ Use LED grp 0 for eth1 ++ ++config ETRAX_ETH1_USE_LEDGRP1 ++ bool "Use LED grp 1" ++ depends on ETRAX_NBR_LED_GRP_TWO ++ help ++ Use LED grp 1 for eth1 ++ ++config ETRAX_ETH1_USE_LEDGRPNULL ++ bool "Use no LEDs for eth1" ++ help ++ Use no LEDs for eth1 ++endchoice ++ + config ETRAXFS_SERIAL + bool "Serial-port support" + depends on ETRAX_ARCH_V32 +diff -Nur linux-4.7.3.orig/arch/cris/include/arch-v32/arch/hwregs/eth_defs.h linux-4.7.3/arch/cris/include/arch-v32/arch/hwregs/eth_defs.h +--- linux-4.7.3.orig/arch/cris/include/arch-v32/arch/hwregs/eth_defs.h 2016-09-07 08:35:12.000000000 +0200 ++++ linux-4.7.3/arch/cris/include/arch-v32/arch/hwregs/eth_defs.h 2016-09-13 01:47:09.527718381 +0200 +@@ -2,69 +2,64 @@ + #define __eth_defs_h + + /* +- * This file is autogenerated from +- * file: eth.r +- * id: eth_regs.r,v 1.16 2005/05/20 15:41:22 perz Exp +- * last modfied: Mon Jan 9 06:06:41 2006 +- * +- * by /n/asic/design/tools/rdesc/rdes2c eth.r +- * id: $Id: eth_defs.h,v 1.7 2006/01/26 13:45:30 karljope Exp $ +- * Any changes here will be lost. +- * +- * -*- buffer-read-only: t -*- ++ * Note: Previously this was autogenerated code from the hardware ++ * implementation. However, to enable the same file to be used ++ * for both ARTPEC-3 and ETRAX FS this file is now hand-edited. ++ * Be careful. + */ ++ + /* Main access macros */ + #ifndef REG_RD + #define REG_RD( scope, inst, reg ) \ +- REG_READ( reg_##scope##_##reg, \ +- (inst) + REG_RD_ADDR_##scope##_##reg ) ++ REG_READ( reg_##scope##_##reg, \ ++ (inst) + REG_RD_ADDR_##scope##_##reg ) + #endif + + #ifndef REG_WR + #define REG_WR( scope, inst, reg, val ) \ +- REG_WRITE( reg_##scope##_##reg, \ +- (inst) + REG_WR_ADDR_##scope##_##reg, (val) ) ++ REG_WRITE( reg_##scope##_##reg, \ ++ (inst) + REG_WR_ADDR_##scope##_##reg, (val) ) + #endif + + #ifndef REG_RD_VECT + #define REG_RD_VECT( scope, inst, reg, index ) \ +- REG_READ( reg_##scope##_##reg, \ +- (inst) + REG_RD_ADDR_##scope##_##reg + \ +- (index) * STRIDE_##scope##_##reg ) ++ REG_READ( reg_##scope##_##reg, \ ++ (inst) + REG_RD_ADDR_##scope##_##reg + \ ++ (index) * STRIDE_##scope##_##reg ) + #endif + + #ifndef REG_WR_VECT + #define REG_WR_VECT( scope, inst, reg, index, val ) \ +- REG_WRITE( reg_##scope##_##reg, \ +- (inst) + REG_WR_ADDR_##scope##_##reg + \ +- (index) * STRIDE_##scope##_##reg, (val) ) ++ REG_WRITE( reg_##scope##_##reg, \ ++ (inst) + REG_WR_ADDR_##scope##_##reg + \ ++ (index) * STRIDE_##scope##_##reg, (val) ) + #endif + + #ifndef REG_RD_INT + #define REG_RD_INT( scope, inst, reg ) \ +- REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg ) ++ REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg ) + #endif + + #ifndef REG_WR_INT + #define REG_WR_INT( scope, inst, reg, val ) \ +- REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) ) ++ REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg, (val) ) + #endif + + #ifndef REG_RD_INT_VECT + #define REG_RD_INT_VECT( scope, inst, reg, index ) \ +- REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \ +- (index) * STRIDE_##scope##_##reg ) ++ REG_READ( int, (inst) + REG_RD_ADDR_##scope##_##reg + \ ++ (index) * STRIDE_##scope##_##reg ) + #endif + + #ifndef REG_WR_INT_VECT + #define REG_WR_INT_VECT( scope, inst, reg, index, val ) \ +- REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \ +- (index) * STRIDE_##scope##_##reg, (val) ) ++ REG_WRITE( int, (inst) + REG_WR_ADDR_##scope##_##reg + \ ++ (index) * STRIDE_##scope##_##reg, (val) ) + #endif + + #ifndef REG_TYPE_CONV + #define REG_TYPE_CONV( type, orgtype, val ) \ +- ( { union { orgtype o; type n; } r; r.o = val; r.n; } ) ++ ( { union { orgtype o; type n; } r; r.o = val; r.n; } ) + #endif + + #ifndef reg_page_size +@@ -73,306 +68,332 @@ + + #ifndef REG_ADDR + #define REG_ADDR( scope, inst, reg ) \ +- ( (inst) + REG_RD_ADDR_##scope##_##reg ) ++ ( (inst) + REG_RD_ADDR_##scope##_##reg ) + #endif + + #ifndef REG_ADDR_VECT + #define REG_ADDR_VECT( scope, inst, reg, index ) \ +- ( (inst) + REG_RD_ADDR_##scope##_##reg + \ +- (index) * STRIDE_##scope##_##reg ) ++ ( (inst) + REG_RD_ADDR_##scope##_##reg + \ ++ (index) * STRIDE_##scope##_##reg ) + #endif + + /* C-code for register scope eth */ + + /* Register rw_ma0_lo, scope eth, type rw */ + typedef struct { +- unsigned int addr : 32; ++ unsigned int addr : 32; + } reg_eth_rw_ma0_lo; + #define REG_RD_ADDR_eth_rw_ma0_lo 0 + #define REG_WR_ADDR_eth_rw_ma0_lo 0 + + /* Register rw_ma0_hi, scope eth, type rw */ + typedef struct { +- unsigned int addr : 16; +- unsigned int dummy1 : 16; ++ unsigned int addr : 16; ++ unsigned int dummy1 : 16; + } reg_eth_rw_ma0_hi; + #define REG_RD_ADDR_eth_rw_ma0_hi 4 + #define REG_WR_ADDR_eth_rw_ma0_hi 4 + + /* Register rw_ma1_lo, scope eth, type rw */ + typedef struct { +- unsigned int addr : 32; ++ unsigned int addr : 32; + } reg_eth_rw_ma1_lo; + #define REG_RD_ADDR_eth_rw_ma1_lo 8 + #define REG_WR_ADDR_eth_rw_ma1_lo 8 + + /* Register rw_ma1_hi, scope eth, type rw */ + typedef struct { +- unsigned int addr : 16; +- unsigned int dummy1 : 16; ++ unsigned int addr : 16; ++ unsigned int dummy1 : 16; + } reg_eth_rw_ma1_hi; + #define REG_RD_ADDR_eth_rw_ma1_hi 12 + #define REG_WR_ADDR_eth_rw_ma1_hi 12 + + /* Register rw_ga_lo, scope eth, type rw */ + typedef struct { +- unsigned int tbl : 32; ++ unsigned int table : 32; + } reg_eth_rw_ga_lo; + #define REG_RD_ADDR_eth_rw_ga_lo 16 + #define REG_WR_ADDR_eth_rw_ga_lo 16 + + /* Register rw_ga_hi, scope eth, type rw */ + typedef struct { +- unsigned int tbl : 32; ++ unsigned int table : 32; + } reg_eth_rw_ga_hi; + #define REG_RD_ADDR_eth_rw_ga_hi 20 + #define REG_WR_ADDR_eth_rw_ga_hi 20 + + /* Register rw_gen_ctrl, scope eth, type rw */ + typedef struct { +- unsigned int en : 1; +- unsigned int phy : 2; +- unsigned int protocol : 1; +- unsigned int loopback : 1; +- unsigned int flow_ctrl : 1; +- unsigned int gtxclk_out : 1; +- unsigned int phyrst_n : 1; +- unsigned int dummy1 : 24; ++ unsigned int en : 1; ++ unsigned int phy : 2; ++ unsigned int protocol : 1; ++ unsigned int loopback : 1; ++ unsigned int flow_ctrl : 1; ++ unsigned int gtxclk_out : 1; ++ unsigned int phyrst_n : 1; ++ unsigned int dummy1 : 24; + } reg_eth_rw_gen_ctrl; + #define REG_RD_ADDR_eth_rw_gen_ctrl 24 + #define REG_WR_ADDR_eth_rw_gen_ctrl 24 + + /* Register rw_rec_ctrl, scope eth, type rw */ + typedef struct { +- unsigned int ma0 : 1; +- unsigned int ma1 : 1; +- unsigned int individual : 1; +- unsigned int broadcast : 1; +- unsigned int undersize : 1; +- unsigned int oversize : 1; +- unsigned int bad_crc : 1; +- unsigned int duplex : 1; +- unsigned int max_size : 16; +- unsigned int dummy1 : 8; ++ unsigned int ma0 : 1; ++ unsigned int ma1 : 1; ++ unsigned int individual : 1; ++ unsigned int broadcast : 1; ++ unsigned int undersize : 1; ++ unsigned int oversize : 1; ++ unsigned int bad_crc : 1; ++ unsigned int duplex : 1; ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++ unsigned int max_size : 16; ++ unsigned int dummy1 : 8; ++#else ++ unsigned int max_size : 1; ++ unsigned int dummy1 : 23; ++#endif + } reg_eth_rw_rec_ctrl; + #define REG_RD_ADDR_eth_rw_rec_ctrl 28 + #define REG_WR_ADDR_eth_rw_rec_ctrl 28 + + /* Register rw_tr_ctrl, scope eth, type rw */ + typedef struct { +- unsigned int crc : 1; +- unsigned int pad : 1; +- unsigned int retry : 1; +- unsigned int ignore_col : 1; +- unsigned int cancel : 1; +- unsigned int hsh_delay : 1; +- unsigned int ignore_crs : 1; +- unsigned int carrier_ext : 1; +- unsigned int dummy1 : 24; ++ unsigned int crc : 1; ++ unsigned int pad : 1; ++ unsigned int retry : 1; ++ unsigned int ignore_col : 1; ++ unsigned int cancel : 1; ++ unsigned int hsh_delay : 1; ++ unsigned int ignore_crs : 1; ++ unsigned int carrier_ext : 1; ++ unsigned int dummy1 : 24; + } reg_eth_rw_tr_ctrl; + #define REG_RD_ADDR_eth_rw_tr_ctrl 32 + #define REG_WR_ADDR_eth_rw_tr_ctrl 32 + + /* Register rw_clr_err, scope eth, type rw */ + typedef struct { +- unsigned int clr : 1; +- unsigned int dummy1 : 31; ++ unsigned int clr : 1; ++ unsigned int dummy1 : 31; + } reg_eth_rw_clr_err; + #define REG_RD_ADDR_eth_rw_clr_err 36 + #define REG_WR_ADDR_eth_rw_clr_err 36 + + /* Register rw_mgm_ctrl, scope eth, type rw */ + typedef struct { +- unsigned int mdio : 1; +- unsigned int mdoe : 1; +- unsigned int mdc : 1; +- unsigned int dummy1 : 29; ++ unsigned int mdio : 1; ++ unsigned int mdoe : 1; ++ unsigned int mdc : 1; ++ unsigned int phyclk : 1; ++ unsigned int txdata : 4; ++ unsigned int txen : 1; ++ unsigned int dummy1 : 23; + } reg_eth_rw_mgm_ctrl; + #define REG_RD_ADDR_eth_rw_mgm_ctrl 40 + #define REG_WR_ADDR_eth_rw_mgm_ctrl 40 + + /* Register r_stat, scope eth, type r */ + typedef struct { +- unsigned int mdio : 1; +- unsigned int exc_col : 1; +- unsigned int urun : 1; +- unsigned int clk_125 : 1; +- unsigned int dummy1 : 28; ++ unsigned int mdio : 1; ++ unsigned int exc_col : 1; ++ unsigned int urun : 1; ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++ unsigned int clk_125 : 1; ++#else ++ unsigned int phyclk : 1; ++#endif ++ unsigned int txdata : 4; ++ unsigned int txen : 1; ++ unsigned int col : 1; ++ unsigned int crs : 1; ++ unsigned int txclk : 1; ++ unsigned int rxdata : 4; ++ unsigned int rxer : 1; ++ unsigned int rxdv : 1; ++ unsigned int rxclk : 1; ++ unsigned int dummy1 : 13; + } reg_eth_r_stat; + #define REG_RD_ADDR_eth_r_stat 44 + + /* Register rs_rec_cnt, scope eth, type rs */ + typedef struct { +- unsigned int crc_err : 8; +- unsigned int align_err : 8; +- unsigned int oversize : 8; +- unsigned int congestion : 8; ++ unsigned int crc_err : 8; ++ unsigned int align_err : 8; ++ unsigned int oversize : 8; ++ unsigned int congestion : 8; + } reg_eth_rs_rec_cnt; + #define REG_RD_ADDR_eth_rs_rec_cnt 48 + + /* Register r_rec_cnt, scope eth, type r */ + typedef struct { +- unsigned int crc_err : 8; +- unsigned int align_err : 8; +- unsigned int oversize : 8; +- unsigned int congestion : 8; ++ unsigned int crc_err : 8; ++ unsigned int align_err : 8; ++ unsigned int oversize : 8; ++ unsigned int congestion : 8; + } reg_eth_r_rec_cnt; + #define REG_RD_ADDR_eth_r_rec_cnt 52 + + /* Register rs_tr_cnt, scope eth, type rs */ + typedef struct { +- unsigned int single_col : 8; +- unsigned int mult_col : 8; +- unsigned int late_col : 8; +- unsigned int deferred : 8; ++ unsigned int single_col : 8; ++ unsigned int mult_col : 8; ++ unsigned int late_col : 8; ++ unsigned int deferred : 8; + } reg_eth_rs_tr_cnt; + #define REG_RD_ADDR_eth_rs_tr_cnt 56 + + /* Register r_tr_cnt, scope eth, type r */ + typedef struct { +- unsigned int single_col : 8; +- unsigned int mult_col : 8; +- unsigned int late_col : 8; +- unsigned int deferred : 8; ++ unsigned int single_col : 8; ++ unsigned int mult_col : 8; ++ unsigned int late_col : 8; ++ unsigned int deferred : 8; + } reg_eth_r_tr_cnt; + #define REG_RD_ADDR_eth_r_tr_cnt 60 + + /* Register rs_phy_cnt, scope eth, type rs */ + typedef struct { +- unsigned int carrier_loss : 8; +- unsigned int sqe_err : 8; +- unsigned int dummy1 : 16; ++ unsigned int carrier_loss : 8; ++ unsigned int sqe_err : 8; ++ unsigned int dummy1 : 16; + } reg_eth_rs_phy_cnt; + #define REG_RD_ADDR_eth_rs_phy_cnt 64 + + /* Register r_phy_cnt, scope eth, type r */ + typedef struct { +- unsigned int carrier_loss : 8; +- unsigned int sqe_err : 8; +- unsigned int dummy1 : 16; ++ unsigned int carrier_loss : 8; ++ unsigned int sqe_err : 8; ++ unsigned int dummy1 : 16; + } reg_eth_r_phy_cnt; + #define REG_RD_ADDR_eth_r_phy_cnt 68 + + /* Register rw_test_ctrl, scope eth, type rw */ + typedef struct { +- unsigned int snmp_inc : 1; +- unsigned int snmp : 1; +- unsigned int backoff : 1; +- unsigned int dummy1 : 29; ++ unsigned int snmp_inc : 1; ++ unsigned int snmp : 1; ++ unsigned int backoff : 1; ++ unsigned int dummy1 : 29; + } reg_eth_rw_test_ctrl; + #define REG_RD_ADDR_eth_rw_test_ctrl 72 + #define REG_WR_ADDR_eth_rw_test_ctrl 72 + + /* Register rw_intr_mask, scope eth, type rw */ + typedef struct { +- unsigned int crc : 1; +- unsigned int align : 1; +- unsigned int oversize : 1; +- unsigned int congestion : 1; +- unsigned int single_col : 1; +- unsigned int mult_col : 1; +- unsigned int late_col : 1; +- unsigned int deferred : 1; +- unsigned int carrier_loss : 1; +- unsigned int sqe_test_err : 1; +- unsigned int orun : 1; +- unsigned int urun : 1; +- unsigned int exc_col : 1; +- unsigned int mdio : 1; +- unsigned int dummy1 : 18; ++ unsigned int crc : 1; ++ unsigned int align : 1; ++ unsigned int oversize : 1; ++ unsigned int congestion : 1; ++ unsigned int single_col : 1; ++ unsigned int mult_col : 1; ++ unsigned int late_col : 1; ++ unsigned int deferred : 1; ++ unsigned int carrier_loss : 1; ++ unsigned int sqe_test_err : 1; ++ unsigned int orun : 1; ++ unsigned int urun : 1; ++ unsigned int exc_col : 1; ++ unsigned int mdio : 1; ++ unsigned int dummy1 : 18; + } reg_eth_rw_intr_mask; + #define REG_RD_ADDR_eth_rw_intr_mask 76 + #define REG_WR_ADDR_eth_rw_intr_mask 76 + + /* Register rw_ack_intr, scope eth, type rw */ + typedef struct { +- unsigned int crc : 1; +- unsigned int align : 1; +- unsigned int oversize : 1; +- unsigned int congestion : 1; +- unsigned int single_col : 1; +- unsigned int mult_col : 1; +- unsigned int late_col : 1; +- unsigned int deferred : 1; +- unsigned int carrier_loss : 1; +- unsigned int sqe_test_err : 1; +- unsigned int orun : 1; +- unsigned int urun : 1; +- unsigned int exc_col : 1; +- unsigned int mdio : 1; +- unsigned int dummy1 : 18; ++ unsigned int crc : 1; ++ unsigned int align : 1; ++ unsigned int oversize : 1; ++ unsigned int congestion : 1; ++ unsigned int single_col : 1; ++ unsigned int mult_col : 1; ++ unsigned int late_col : 1; ++ unsigned int deferred : 1; ++ unsigned int carrier_loss : 1; ++ unsigned int sqe_test_err : 1; ++ unsigned int orun : 1; ++ unsigned int urun : 1; ++ unsigned int exc_col : 1; ++ unsigned int mdio : 1; ++ unsigned int dummy1 : 18; + } reg_eth_rw_ack_intr; + #define REG_RD_ADDR_eth_rw_ack_intr 80 + #define REG_WR_ADDR_eth_rw_ack_intr 80 + + /* Register r_intr, scope eth, type r */ + typedef struct { +- unsigned int crc : 1; +- unsigned int align : 1; +- unsigned int oversize : 1; +- unsigned int congestion : 1; +- unsigned int single_col : 1; +- unsigned int mult_col : 1; +- unsigned int late_col : 1; +- unsigned int deferred : 1; +- unsigned int carrier_loss : 1; +- unsigned int sqe_test_err : 1; +- unsigned int orun : 1; +- unsigned int urun : 1; +- unsigned int exc_col : 1; +- unsigned int mdio : 1; +- unsigned int dummy1 : 18; ++ unsigned int crc : 1; ++ unsigned int align : 1; ++ unsigned int oversize : 1; ++ unsigned int congestion : 1; ++ unsigned int single_col : 1; ++ unsigned int mult_col : 1; ++ unsigned int late_col : 1; ++ unsigned int deferred : 1; ++ unsigned int carrier_loss : 1; ++ unsigned int sqe_test_err : 1; ++ unsigned int orun : 1; ++ unsigned int urun : 1; ++ unsigned int exc_col : 1; ++ unsigned int mdio : 1; ++ unsigned int dummy1 : 18; + } reg_eth_r_intr; + #define REG_RD_ADDR_eth_r_intr 84 + + /* Register r_masked_intr, scope eth, type r */ + typedef struct { +- unsigned int crc : 1; +- unsigned int align : 1; +- unsigned int oversize : 1; +- unsigned int congestion : 1; +- unsigned int single_col : 1; +- unsigned int mult_col : 1; +- unsigned int late_col : 1; +- unsigned int deferred : 1; +- unsigned int carrier_loss : 1; +- unsigned int sqe_test_err : 1; +- unsigned int orun : 1; +- unsigned int urun : 1; +- unsigned int exc_col : 1; +- unsigned int mdio : 1; +- unsigned int dummy1 : 18; ++ unsigned int crc : 1; ++ unsigned int align : 1; ++ unsigned int oversize : 1; ++ unsigned int congestion : 1; ++ unsigned int single_col : 1; ++ unsigned int mult_col : 1; ++ unsigned int late_col : 1; ++ unsigned int deferred : 1; ++ unsigned int carrier_loss : 1; ++ unsigned int sqe_test_err : 1; ++ unsigned int orun : 1; ++ unsigned int urun : 1; ++ unsigned int exc_col : 1; ++ unsigned int mdio : 1; ++ unsigned int dummy1 : 18; + } reg_eth_r_masked_intr; + #define REG_RD_ADDR_eth_r_masked_intr 88 + +- + /* Constants */ + enum { +- regk_eth_discard = 0x00000000, +- regk_eth_ether = 0x00000000, +- regk_eth_full = 0x00000001, +- regk_eth_gmii = 0x00000003, +- regk_eth_gtxclk = 0x00000001, +- regk_eth_half = 0x00000000, +- regk_eth_hsh = 0x00000001, +- regk_eth_mii = 0x00000001, +- regk_eth_mii_arec = 0x00000002, +- regk_eth_mii_clk = 0x00000000, +- regk_eth_no = 0x00000000, +- regk_eth_phyrst = 0x00000000, +- regk_eth_rec = 0x00000001, +- regk_eth_rw_ga_hi_default = 0x00000000, +- regk_eth_rw_ga_lo_default = 0x00000000, +- regk_eth_rw_gen_ctrl_default = 0x00000000, +- regk_eth_rw_intr_mask_default = 0x00000000, +- regk_eth_rw_ma0_hi_default = 0x00000000, +- regk_eth_rw_ma0_lo_default = 0x00000000, +- regk_eth_rw_ma1_hi_default = 0x00000000, +- regk_eth_rw_ma1_lo_default = 0x00000000, +- regk_eth_rw_mgm_ctrl_default = 0x00000000, +- regk_eth_rw_test_ctrl_default = 0x00000000, +- regk_eth_size1518 = 0x000005ee, +- regk_eth_size1522 = 0x000005f2, +- regk_eth_yes = 0x00000001 ++ regk_eth_discard = 0x00000000, ++ regk_eth_ether = 0x00000000, ++ regk_eth_full = 0x00000001, ++ regk_eth_gmii = 0x00000003, ++ regk_eth_gtxclk = 0x00000001, ++ regk_eth_half = 0x00000000, ++ regk_eth_hsh = 0x00000001, ++ regk_eth_mii = 0x00000001, ++ regk_eth_mii_arec = 0x00000002, ++ regk_eth_mii_clk = 0x00000000, ++ regk_eth_no = 0x00000000, ++ regk_eth_phyrst = 0x00000000, ++ regk_eth_rec = 0x00000001, ++ regk_eth_rw_ga_hi_default = 0x00000000, ++ regk_eth_rw_ga_lo_default = 0x00000000, ++ regk_eth_rw_gen_ctrl_default = 0x00000000, ++ regk_eth_rw_intr_mask_default = 0x00000000, ++ regk_eth_rw_ma0_hi_default = 0x00000000, ++ regk_eth_rw_ma0_lo_default = 0x00000000, ++ regk_eth_rw_ma1_hi_default = 0x00000000, ++ regk_eth_rw_ma1_lo_default = 0x00000000, ++ regk_eth_rw_mgm_ctrl_default = 0x00000000, ++ regk_eth_rw_test_ctrl_default = 0x00000000, ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++ regk_eth_size1518 = 0x000005ee, ++ regk_eth_size1522 = 0x000005f2, ++#else ++ regk_eth_size1518 = 0x00000000, ++ regk_eth_size1522 = 0x00000001, ++#endif ++ regk_eth_yes = 0x00000001 + }; ++ + #endif /* __eth_defs_h */ +diff -Nur linux-4.7.3.orig/drivers/net/cris/eth_v32.c linux-4.7.3/drivers/net/cris/eth_v32.c +--- linux-4.7.3.orig/drivers/net/cris/eth_v32.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-4.7.3/drivers/net/cris/eth_v32.c 2016-09-13 01:48:05.953910422 +0200 +@@ -0,0 +1,3060 @@ ++/* ++ * Driver for the ETRAX FS/Artpec-3 network controller. ++ * ++ * Copyright (c) 2003-2008 Axis Communications AB. ++ * ++ * TODO: ++ * * Decrease the amount of code running with interrupts disabled. ++ * * Rework the error handling so that we do not need to touch the tx ++ * ring from the error interrupts. When done, we should be able to ++ * do tx completition from the NAPI loop without disabling interrupts. ++ * * Remove the gigabit code. It's probably never going to be used. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include /* CRIS_LED_* I/O functions */ ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_ETRAXFS ++#include ++#else ++#include ++#endif ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "eth_v32.h" ++ ++#ifndef CONFIG_ETRAXFS ++#define ETH0_INTR_VECT ETH_INTR_VECT ++#define ETH1_INTR_VECT ETH_INTR_VECT ++#define regi_eth0 regi_eth ++#define regi_eth1 regi_ ++#endif ++ ++#define DEBUG(x) ++#define GET_BIT(bit,val) (((val) >> (bit)) & 0x01) ++ ++#if defined(CONFIG_ETRAX_HAVE_PHY) || defined(CONFIG_ETRAX_PHY_FALLBACK) ++#define RESET_PHY 1 ++#else ++#define RESET_PHY 0 ++#endif ++ ++enum { ++ HAVE_PHY, ++ NO_PHY, ++ FALLBACK_PHY, ++}; ++#if defined(CONFIG_ETRAX_PHY_FALLBACK) ++#define PHY_MODE (FALLBACK_PHY) ++#elif defined(CONFIG_ETRAX_NO_PHY) ++#define PHY_MODE (NO_PHY) ++#elif defined(CONFIG_ETRAX_HAVE_PHY) ++#define PHY_MODE (HAVE_PHY) ++#else ++#error Unknown PHY behaviour ++#endif ++ ++static struct { ++ const char str[ETH_GSTRING_LEN]; ++} const ethtool_stats_keys[] = { ++ { "tx_dma_restarts" }, ++ { "tx_mac_resets" }, ++ { "rx_dma_restarts" }, ++ { "rx_dma_timeouts" }, ++ { " dropped_rx" } ++}; ++ ++static void crisv32_eth_check_speed(unsigned long idev); ++static void crisv32_eth_check_duplex(unsigned long idev); ++static void update_rx_stats(struct crisv32_ethernet_local *np); ++static void update_tx_stats(struct crisv32_ethernet_local *np); ++static int crisv32_eth_poll(struct napi_struct *napi, int budget); ++static void crisv32_eth_setup_controller(struct net_device *dev); ++static int crisv32_eth_request_irqdma(struct net_device *dev); ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++static void ++crisv32_eth_restart_rx_dma(struct net_device* dev, ++ struct crisv32_ethernet_local *np); ++#endif ++#if 0 ++static void crisv32_ethernet_bug(struct net_device *dev); ++#endif ++ ++/* ++ * The name of the card. Is used for messages and in the requests for ++ * io regions, irqs and dma channels. ++ */ ++#ifdef CONFIG_ETRAXFS ++static const char cardname[] = "ETRAX FS built-in ethernet controller"; ++#else ++static const char cardname[] = "ARTPEC-3 built-in ethernet controller"; ++#endif ++ ++/* Some chipset needs special care. */ ++#ifndef CONFIG_ETRAX_NO_PHY ++struct transceiver_ops transceivers[] = { ++ {0x1018, broadcom_check_speed, broadcom_check_duplex}, ++ {0x50EF, broadcom_check_speed, broadcom_check_duplex}, ++ /* TDK 2120 and TDK 2120C */ ++ {0xC039, tdk_check_speed, tdk_check_duplex}, ++ {0x039C, tdk_check_speed, tdk_check_duplex}, ++ /* Intel LXT972A*/ ++ {0x04de, intel_check_speed, intel_check_duplex}, ++ /* National Semiconductor DP83865 */ ++ {0x0017, national_check_speed, national_check_duplex}, ++ /* Vitesse VCS8641 */ ++ {0x01c1, vitesse_check_speed, vitesse_check_duplex}, ++ /* Davicom DM9161 */ ++ {0x606E, davicom_check_speed, davicom_check_duplex}, ++ /* Generic, must be last. */ ++ {0x0000, generic_check_speed, generic_check_duplex} ++}; ++#endif ++ ++static struct net_device *crisv32_dev[2]; ++static struct crisv32_eth_leds *crisv32_leds[3]; ++ ++/* Default MAC address for interface 0. ++ * The real one will be set later. */ ++static struct sockaddr default_mac_iface0 = ++ {0, {0x00, 0x40, 0x8C, 0xCD, 0x00, 0x00}}; ++ ++#ifdef CONFIG_CPU_FREQ ++static int ++crisv32_ethernet_freq_notifier(struct notifier_block *nb, unsigned long val, ++ void *data); ++ ++static struct notifier_block crisv32_ethernet_freq_notifier_block = { ++ .notifier_call = crisv32_ethernet_freq_notifier ++}; ++#endif ++ ++static void receive_timeout(unsigned long arg); ++static void receive_timeout_work(struct work_struct* work); ++static void transmit_timeout(unsigned long arg); ++ ++/* ++ * mask in and out tx/rx interrupts. ++ */ ++static inline void crisv32_disable_tx_ints(struct crisv32_ethernet_local *np) ++{ ++ reg_dma_rw_intr_mask intr_mask_tx = { .data = regk_dma_no }; ++ REG_WR(dma, np->dma_out_inst, rw_intr_mask, intr_mask_tx); ++} ++ ++static inline void crisv32_enable_tx_ints(struct crisv32_ethernet_local *np) ++{ ++ reg_dma_rw_intr_mask intr_mask_tx = { .data = regk_dma_yes }; ++ REG_WR(dma, np->dma_out_inst, rw_intr_mask, intr_mask_tx); ++} ++ ++static inline void crisv32_disable_rx_ints(struct crisv32_ethernet_local *np) ++{ ++ reg_dma_rw_intr_mask intr_mask_rx = { .in_eop = regk_dma_no }; ++ REG_WR(dma, np->dma_in_inst, rw_intr_mask, intr_mask_rx); ++} ++ ++static inline void crisv32_enable_rx_ints(struct crisv32_ethernet_local *np) ++{ ++ reg_dma_rw_intr_mask intr_mask_rx = { .in_eop = regk_dma_yes }; ++ REG_WR(dma, np->dma_in_inst, rw_intr_mask, intr_mask_rx); ++} ++ ++static inline void crisv32_disable_eth_ints(struct crisv32_ethernet_local *np) ++{ ++ int intr_mask_nw = 0x0; ++ REG_WR_INT(eth, np->eth_inst, rw_intr_mask, intr_mask_nw); ++} ++ ++static inline void crisv32_enable_eth_ints(struct crisv32_ethernet_local *np) ++{ ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++ /* For Artpec-3 we use overrun to workaround voodoo TR 87 */ ++ int intr_mask_nw = 0x1c00; ++#else ++ int intr_mask_nw = 0x1800; ++#endif ++ REG_WR_INT(eth, np->eth_inst, rw_intr_mask, intr_mask_nw); ++} ++ ++static inline int crisv32_eth_gigabit(struct crisv32_ethernet_local *np) ++{ ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++ return np->gigabit_mode; ++#else ++ return 0; ++#endif ++} ++ ++static inline void crisv32_eth_set_gigabit(struct crisv32_ethernet_local *np, ++ int g) ++{ ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++ np->gigabit_mode = g; ++#endif ++} ++ ++/* start/stop receiver */ ++static inline void crisv32_start_receiver(struct crisv32_ethernet_local *np) ++{ ++ reg_eth_rw_rec_ctrl rec_ctrl; ++ ++ rec_ctrl = REG_RD(eth, np->eth_inst, rw_rec_ctrl); ++ rec_ctrl.ma0 = regk_eth_yes; ++ rec_ctrl.broadcast = regk_eth_rec; ++ REG_WR(eth, np->eth_inst, rw_rec_ctrl, rec_ctrl); ++} ++ ++static inline void crisv32_stop_receiver(struct crisv32_ethernet_local *np) ++{ ++ reg_eth_rw_rec_ctrl rec_ctrl; ++ ++ rec_ctrl = REG_RD(eth, np->eth_inst, rw_rec_ctrl); ++ rec_ctrl.ma0 = regk_eth_no; ++ rec_ctrl.broadcast = regk_eth_discard; ++ REG_WR(eth, np->eth_inst, rw_rec_ctrl, rec_ctrl); ++} ++ ++static inline void crisv32_eth_reset(struct crisv32_ethernet_local *np) ++{ ++ reg_eth_rw_gen_ctrl gen_ctrl = { 0 }; ++ ++ gen_ctrl = REG_RD(eth, np->eth_inst, rw_gen_ctrl); ++ gen_ctrl.en = regk_eth_no; ++ REG_WR(eth, np->eth_inst, rw_gen_ctrl, gen_ctrl); ++ gen_ctrl.en = regk_eth_yes; ++ REG_WR(eth, np->eth_inst, rw_gen_ctrl, gen_ctrl); ++} ++ ++static void crisv32_eth_tx_cancel_frame(struct crisv32_ethernet_local *np) ++{ ++ reg_eth_rw_tr_ctrl tr_ctrl; ++ ++ /* Cancel any pending transmits. This should bring us to the ++ excessive collisions state but it doesn't always do it. */ ++ tr_ctrl = REG_RD(eth, np->eth_inst, rw_tr_ctrl); ++ tr_ctrl.cancel = 1; ++ REG_WR(eth, np->eth_inst, rw_tr_ctrl, tr_ctrl); ++ tr_ctrl.cancel = 0; ++ REG_WR(eth, np->eth_inst, rw_tr_ctrl, tr_ctrl); ++} ++ ++/* ++ * Hack to disconnect/reconnect the dma from the ethernet block while we reset ++ * things. TODO: verify that we don't need to disconnect out channels and ++ * remove that code. ++ * ++ * ARTPEC-3 has only a single ethernet block so np->eth_inst is always eth0. ++ * The strmux values are named slightly different, redefine to avoid #ifdefs ++ * in the code blocks. For artpec3 only regk_strmux_eth0 and channel 0/1 ++ * should be used. ++ */ ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++#define regk_strmux_eth0 regk_strmux_eth ++#define regk_strmux_eth1 regk_strmux_eth ++#endif ++static inline void ++crisv32_disconnect_eth_tx_dma(struct crisv32_ethernet_local *np) ++{ ++ reg_strmux_rw_cfg strmux_cfg; ++ ++ strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); ++ if (np->eth_inst == regi_eth0) ++ strmux_cfg.dma0 = regk_strmux_off; ++ else ++ strmux_cfg.dma6 = regk_strmux_off; ++ REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); ++} ++ ++static inline void crisv32_connect_eth_tx_dma(struct crisv32_ethernet_local *np) ++{ ++ reg_strmux_rw_cfg strmux_cfg; ++ ++ strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); ++ if (np->eth_inst == regi_eth0) ++ strmux_cfg.dma0 = regk_strmux_eth0; ++ else ++ strmux_cfg.dma6 = regk_strmux_eth1; ++ REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); ++} ++ ++static inline void ++crisv32_disconnect_eth_rx_dma(struct crisv32_ethernet_local *np) ++{ ++ reg_strmux_rw_cfg strmux_cfg; ++ ++ strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); ++ if (np->eth_inst == regi_eth0) ++ strmux_cfg.dma1 = regk_strmux_off; ++ else ++ strmux_cfg.dma7 = regk_strmux_off; ++ REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); ++} ++ ++static inline void crisv32_connect_eth_rx_dma(struct crisv32_ethernet_local *np) ++{ ++ reg_strmux_rw_cfg strmux_cfg; ++ ++ strmux_cfg = REG_RD(strmux, regi_strmux, rw_cfg); ++ if (np->eth_inst == regi_eth0) ++ strmux_cfg.dma1 = regk_strmux_eth0; ++ else ++ strmux_cfg.dma7 = regk_strmux_eth1; ++ REG_WR(strmux, regi_strmux, rw_cfg, strmux_cfg); ++} ++ ++static int dma_wait_busy(int inst, int timeout) ++{ ++ reg_dma_rw_stream_cmd dma_sc; ++ ++ do { ++ dma_sc = REG_RD(dma, inst, rw_stream_cmd); ++ } while (timeout-- > 0 && dma_sc.busy); ++ return dma_sc.busy; ++} ++ ++static int __init crisv32_eth_request_irqdma(struct net_device *dev) ++{ ++ struct crisv32_ethernet_local *np = netdev_priv(dev); ++ ++ /* Allocate IRQs and DMAs. */ ++ if (np->eth_inst == regi_eth0) { ++ if (request_irq(DMA0_INTR_VECT, crisv32tx_eth_interrupt, ++ 0, "Ethernet TX", dev)) { ++ return -EAGAIN; ++ } ++ ++ if (request_irq(DMA1_INTR_VECT, crisv32rx_eth_interrupt, ++ 0, "Ethernet RX", dev)) ++ goto err0_1; ++ ++ if (crisv32_request_dma(0, cardname, DMA_VERBOSE_ON_ERROR, ++ 12500000, dma_eth0)) ++ goto err0_2; ++ ++ if (crisv32_request_dma(1, cardname, DMA_VERBOSE_ON_ERROR, ++ 12500000, dma_eth0)) ++ goto err0_3; ++ ++ if (request_irq(ETH0_INTR_VECT, crisv32nw_eth_interrupt, 0, ++ cardname, dev)) { ++ crisv32_free_dma(1); ++err0_3: ++ crisv32_free_dma(0); ++err0_2: ++ free_irq(DMA1_INTR_VECT, dev); ++err0_1: ++ free_irq(DMA0_INTR_VECT, dev); ++ return -EAGAIN; ++ } ++ } else { ++ if (request_irq(DMA6_INTR_VECT, crisv32tx_eth_interrupt, ++ 0, cardname, dev)) ++ return -EAGAIN; ++ ++ if (request_irq(DMA7_INTR_VECT, crisv32rx_eth_interrupt, ++ 0, cardname, dev)) ++ goto err1_1; ++ ++ if (crisv32_request_dma(6, cardname, DMA_VERBOSE_ON_ERROR, ++ 0, dma_eth1)) ++ goto err1_2; ++ ++ if (crisv32_request_dma(7, cardname, DMA_VERBOSE_ON_ERROR, ++ 0, dma_eth1)) ++ goto err1_3; ++ ++ if (request_irq(ETH1_INTR_VECT, crisv32nw_eth_interrupt, 0, ++ cardname, dev)) { ++ crisv32_free_dma(7); ++err1_3: ++ crisv32_free_dma(6); ++err1_2: ++ free_irq(DMA7_INTR_VECT, dev); ++err1_1: ++ free_irq(DMA6_INTR_VECT, dev); ++ return -EAGAIN; ++ } ++ } ++ return 0; ++} ++ ++static int __init crisv32_eth_init_phy(struct net_device *dev) ++{ ++ struct crisv32_ethernet_local *np = netdev_priv(dev); ++ struct timer_list timer_init = TIMER_INITIALIZER(NULL, 0, 0); ++ ++ if (RESET_PHY) { ++#ifdef CONFIG_ETRAXFS ++ reg_config_rw_pad_ctrl pad_ctrl; ++ pad_ctrl = REG_RD(config, regi_config, rw_pad_ctrl); ++ pad_ctrl.phyrst_n = 0; ++ REG_WR(config, regi_config, rw_pad_ctrl, pad_ctrl); ++ ++ udelay(500); /* RESET_LEN */ ++ ++ pad_ctrl.phyrst_n = 1; ++ REG_WR(config, regi_config, rw_pad_ctrl, pad_ctrl); ++#else ++ reg_eth_rw_gen_ctrl gen_ctrl = REG_RD(eth, np->eth_inst, rw_gen_ctrl); ++ gen_ctrl.phyrst_n = 0; ++ REG_WR(eth, np->eth_inst, rw_gen_ctrl, gen_ctrl); ++ ++ udelay(500); /* RESET_LEN */ ++ ++ gen_ctrl.phyrst_n = 1; ++ REG_WR(eth, np->eth_inst, rw_gen_ctrl, gen_ctrl); ++#endif ++ ++ udelay(200); /* RESET_WAIT */ ++ } ++ ++ switch (PHY_MODE) { ++ case FALLBACK_PHY: ++ /* Fall back on using fixed iff there is no PHY on */ ++ /* the MDIO bus */ ++ np->fixed_phy = crisv32_eth_probe_transceiver(dev) != 0; ++ if (np->fixed_phy) ++ printk(KERN_WARNING ++ "eth: No transciever found, falling back " ++ "to fixed phy mode\n"); ++ break; ++ ++ case NO_PHY: ++ /* Don't even bother looking for a PHY, always rely */ ++ /* on fixed PHY */ ++ np->fixed_phy = 1; ++ break; ++ ++ default: /* HAVE_PHY */ ++ /* Look for a PHY and abort if there is none, */ ++ /* otherwise just carry on */ ++ if (crisv32_eth_probe_transceiver(dev)) { ++ printk(KERN_WARNING ++ "eth: No transceiver found, " ++ "removing interface\n"); ++ return -ENODEV; ++ } ++ np->fixed_phy = 0; ++ } ++ ++ if (np->fixed_phy) { ++ reg_eth_rw_rec_ctrl rec_ctrl; ++ ++ /* speed */ ++ np->current_speed = 100; ++ np->current_speed_selection = 100; /* Auto. */ ++ ++ /* duplex */ ++ np->full_duplex = 1; ++ np->current_duplex = full; ++ ++ rec_ctrl = REG_RD(eth, np->eth_inst, rw_rec_ctrl); ++ rec_ctrl.duplex = regk_eth_full; ++ REG_WR(eth, np->eth_inst, rw_rec_ctrl, rec_ctrl); ++ } else { ++ np->mii_if.supports_gmii = mii_check_gmii_support(&np->mii_if); ++ ++ /* speed */ ++ np->current_speed = 10; ++ np->current_speed_selection = 0; /* Auto. */ ++ np->speed_timer = timer_init; ++ np->speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL; ++ np->speed_timer.data = (unsigned long) dev; ++ np->speed_timer.function = crisv32_eth_check_speed; ++ ++ /* duplex */ ++ np->full_duplex = 0; ++ np->current_duplex = autoneg; ++ np->duplex_timer = timer_init; ++ np->duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL; ++ np->duplex_timer.data = (unsigned long) dev; ++ np->duplex_timer.function = crisv32_eth_check_duplex; ++ } ++ ++ return 0; ++} ++ ++static void __init crisv32_eth_setup_controller(struct net_device *dev) ++{ ++ struct crisv32_ethernet_local *np = netdev_priv(dev); ++ reg_eth_rw_gen_ctrl gen_ctrl; ++ ++ reg_eth_rw_tr_ctrl tr_ctrl = { ++ /* SW retransmits to avoid transmitter bugs. */ ++ .retry = regk_eth_no, ++ .pad = regk_eth_yes, ++ .crc = regk_eth_yes ++ }; ++ ++ reg_eth_rw_rec_ctrl rec_ctrl = { ++ .ma0 = regk_eth_no, /* enable at open() */ ++ .broadcast = regk_eth_no, ++ .max_size = regk_eth_size1522 ++ }; ++ ++ reg_eth_rw_ga_lo ga_lo = { 0 }; ++ reg_eth_rw_ga_hi ga_hi = { 0 }; ++ ++ /* ++ * Initialize group address registers to make sure that no ++ * unwanted addresses are matched. ++ */ ++ REG_WR(eth, np->eth_inst, rw_ga_lo, ga_lo); ++ REG_WR(eth, np->eth_inst, rw_ga_hi, ga_hi); ++ ++ /* Configure receiver and transmitter */ ++ REG_WR(eth, np->eth_inst, rw_rec_ctrl, rec_ctrl); ++ REG_WR(eth, np->eth_inst, rw_tr_ctrl, tr_ctrl); ++ ++ /* ++ * Read from rw_gen_ctrl so that we don't override any previous ++ * configuration. ++ */ ++ gen_ctrl = REG_RD(eth, np->eth_inst, rw_gen_ctrl); ++ gen_ctrl.phy = regk_eth_mii_clk; ++#ifdef CONFIG_ETRAXFS ++ /* On ETRAX FS, this bit has reversed meaning */ ++ gen_ctrl.flow_ctrl = regk_eth_no; ++#else ++ gen_ctrl.flow_ctrl = regk_eth_yes; ++#endif ++ ++ /* Enable ethernet controller with mii clk. */ ++ REG_WR(eth, np->eth_inst, rw_gen_ctrl, gen_ctrl); ++ gen_ctrl.en = regk_eth_yes; ++ REG_WR(eth, np->eth_inst, rw_gen_ctrl, gen_ctrl); ++} ++ ++static void crisv32_eth_reset_rx_ring(struct net_device *dev) ++{ ++ struct crisv32_ethernet_local *np = netdev_priv(dev); ++ int i; ++ ++ /* cleanup the rx-ring */ ++ for (i = 0; i < NBR_RX_DESC; i++) { ++ struct sk_buff *skb; ++ skb = np->dma_rx_descr_list[i].skb; ++ if (!skb ++ || (np->dma_rx_descr_list[i].descr.buf != ++ (void *)virt_to_phys(skb->data))) { ++ if (skb) ++ dev_kfree_skb(skb); ++ skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE); ++ np->dma_rx_descr_list[i].skb = skb; ++ np->dma_rx_descr_list[i].descr.buf = ++ (char*)virt_to_phys(skb->data); ++ } ++ if (np->dma_rx_descr_list[i].descr.in_eop) ++ np->rx_restarts_dropped++; ++ np->dma_rx_descr_list[i].descr.after = ++ (char*)virt_to_phys(skb->data ++ + MAX_MEDIA_DATA_SIZE); ++ np->dma_rx_descr_list[i].descr.eol = 0; ++ np->dma_rx_descr_list[i].descr.in_eop = 0; ++ /* Workaround cache bug */ ++ flush_dma_descr(&np->dma_rx_descr_list[i].descr, 1); ++ } ++ ++ /* reset rx-ring */ ++ np->active_rx_desc = &np->dma_rx_descr_list[0]; ++ np->prev_rx_desc = &np->dma_rx_descr_list[NBR_RX_DESC - 1]; ++ np->last_rx_desc = np->prev_rx_desc; ++ np->dma_rx_descr_list[NBR_RX_DESC - 1].descr.eol = 1; ++ flush_dma_descr(&np->dma_rx_descr_list[NBR_RX_DESC - 1].descr, 0); ++ /* ready to accept new packets. */ ++ np->new_rx_package = 1; ++ ++ /* Fill context descriptors. */ ++ np->ctxt_in.next = 0; ++ np->ctxt_in.saved_data = ++ (void *)virt_to_phys(&np->active_rx_desc->descr); ++ np->ctxt_in.saved_data_buf = np->active_rx_desc->descr.buf; ++} ++ ++static inline int crisv32_eth_tx_ring_full(struct crisv32_ethernet_local *np) ++{ ++ crisv32_eth_descr *active = np->active_tx_desc; ++ ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++ active = phys_to_virt((unsigned long)active->descr.next); ++#endif ++ if (active == np->catch_tx_desc) ++ return 1; ++ return 0; ++} ++ ++static void crisv32_eth_reset_tx_ring(struct net_device *dev) ++{ ++ struct crisv32_ethernet_local *np = netdev_priv(dev); ++ ++ /* free un-handled tx packets */ ++ while (np->txpackets || np->catch_tx_desc != np->active_tx_desc) { ++ np->txpackets--; ++ if (np->catch_tx_desc->skb) ++ dev_kfree_skb(np->catch_tx_desc->skb); ++ ++ np->catch_tx_desc->skb = 0; ++ np->catch_tx_desc = ++ phys_to_virt((int)np->catch_tx_desc->descr.next); ++ } ++ ++ WARN_ON(np->txpackets != 0); ++ np->txpackets = 0; ++ ++ /* reset tx-ring */ ++ np->dma_tx_descr_list[0].descr.buf = ++ np->dma_tx_descr_list[0].descr.after = 0; ++ np->dma_tx_descr_list[0].descr.eol = 1; ++ ++ np->active_tx_desc = &np->dma_tx_descr_list[0]; ++ np->prev_tx_desc = &np->dma_tx_descr_list[NBR_TX_DESC - 1]; ++ np->catch_tx_desc = &np->dma_tx_descr_list[0]; ++ ++ np->ctxt_out.next = 0; ++ np->ctxt_out.saved_data = ++ (void *)virt_to_phys(&np->dma_tx_descr_list[0].descr); ++ ++} ++ ++static void crisv32_eth_reset_rings(struct net_device *dev) ++{ ++ crisv32_eth_reset_tx_ring(dev); ++ crisv32_eth_reset_rx_ring(dev); ++} ++ ++/* ++ * Really advance the receive ring. RX interrupts must be off. ++ */ ++static void __crisv32_eth_rx_ring_advance(struct crisv32_ethernet_local *np) ++{ ++ if (np->newbuf) ++ np->active_rx_desc->descr.buf = (void *) np->newbuf; ++ np->active_rx_desc->descr.after = ++ np->active_rx_desc->descr.buf + MAX_MEDIA_DATA_SIZE; ++ np->active_rx_desc->descr.eol = 1; ++ np->active_rx_desc->descr.in_eop = 0; ++ np->active_rx_desc = phys_to_virt((int)np->active_rx_desc->descr.next); ++ barrier(); ++ np->prev_rx_desc->descr.eol = 0; ++ ++ /* Workaround cache bug. */ ++ flush_dma_descr(&np->prev_rx_desc->descr, 0); ++ np->prev_rx_desc = phys_to_virt((int)np->prev_rx_desc->descr.next); ++ flush_dma_descr(&np->prev_rx_desc->descr, 1); ++} ++ ++/* ++ * Advance the receive ring. RX interrupts must be off. ++ */ ++static inline void ++crisv32_eth_rx_ring_advance(struct crisv32_ethernet_local *np) ++{ ++ /* ++ * When the input DMA reaches eol precaution must be taken, otherwise ++ * the DMA could stop. The problem occurs if the eol flag is re-placed ++ * on the descriptor that the DMA stands on before the DMA proceed to ++ * the next descriptor. This case could, for example, happen if there ++ * is a traffic burst and then the network goes silent. To prevent this ++ * we make sure that we do not set the eol flag on the descriptor that ++ * the DMA stands on. ++ */ ++ unsigned long dma_pos; ++ ++ /* Get the current input dma position. */ ++ dma_pos = REG_RD_INT(dma, np->dma_in_inst, rw_saved_data); ++ ++ if (virt_to_phys(&np->active_rx_desc->descr) != dma_pos) { ++ crisv32_eth_descr *cur, *nxt; ++ ++ /* Now really advance the ring one step. */ ++ __crisv32_eth_rx_ring_advance(np); ++ ++ cur = np->active_rx_desc; ++ nxt = (void *)phys_to_virt((unsigned long)cur->descr.next); ++ flush_dma_descr(&cur->descr, 0); ++ flush_dma_descr(&nxt->descr, 0); ++ if (!cur->descr.in_eop && nxt->descr.in_eop) { ++ /* TODO: Investigate this more. The DMA seems to have ++ skipped a descriptor, possibly due to incoherence ++ between the CPU L1 cache and the DMA updates to the ++ descriptor. */ ++ np->newbuf = (unsigned long) np->active_rx_desc->descr.buf; ++ __crisv32_eth_rx_ring_advance(np); ++ } ++ /* flush after peek. */ ++ flush_dma_descr(&cur->descr, 0); ++ flush_dma_descr(&nxt->descr, 0); ++ } else { ++ /* delay the advancing of the ring. */ ++ np->new_rx_package = 0; ++ } ++} ++ ++static void __init crisv32_eth_init_rings(struct net_device *dev) ++{ ++ struct crisv32_ethernet_local *np = netdev_priv(dev); ++ int i; ++ ++ /* Initialise receive descriptors for interface. */ ++ for (i = 0; i < NBR_RX_DESC; i++) { ++ struct sk_buff *skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE); ++ ++ np->dma_rx_descr_list[i].skb = skb; ++ np->dma_rx_descr_list[i].descr.buf = ++ (char*)virt_to_phys(skb->data); ++ np->dma_rx_descr_list[i].descr.after = ++ (char*)virt_to_phys(skb->data + MAX_MEDIA_DATA_SIZE); ++ ++ np->dma_rx_descr_list[i].descr.eol = 0; ++ np->dma_rx_descr_list[i].descr.in_eop = 0; ++ np->dma_rx_descr_list[i].descr.next = ++ (void *) virt_to_phys(&np->dma_rx_descr_list[i + 1].descr); ++ } ++ /* bend the list into a ring */ ++ np->dma_rx_descr_list[NBR_RX_DESC - 1].descr.next = ++ (void *) virt_to_phys(&np->dma_rx_descr_list[0].descr); ++ ++ /* Initialize transmit descriptors. */ ++ for (i = 0; i < NBR_TX_DESC; i++) { ++ np->dma_tx_descr_list[i].descr.wait = 1; ++ np->dma_tx_descr_list[i].descr.eol = 0; ++ np->dma_tx_descr_list[i].descr.out_eop = 0; ++ np->dma_tx_descr_list[i].descr.next = ++ (void*)virt_to_phys(&np->dma_tx_descr_list[i+1].descr); ++ } ++ /* bend the list into a ring */ ++ np->dma_tx_descr_list[NBR_TX_DESC - 1].descr.next = ++ (void *) virt_to_phys(&np->dma_tx_descr_list[0].descr); ++ ++ crisv32_eth_reset_rings(dev); ++} ++ ++static void __init crisv32_init_leds(int ledgrp, struct net_device *dev) ++{ ++ struct timer_list timer_init = TIMER_INITIALIZER(NULL, 0, 0); ++ struct crisv32_ethernet_local *np = netdev_priv(dev); ++ ++ /* Use already allocated led grp if initialized */ ++ if (crisv32_leds[ledgrp] != NULL) { ++ np->leds = crisv32_leds[ledgrp]; ++ return; ++ } ++ ++ crisv32_leds[ledgrp] = ++ kmalloc(sizeof(struct crisv32_eth_leds), GFP_KERNEL); ++ ++ crisv32_leds[ledgrp]->ledgrp = ledgrp; ++ crisv32_leds[ledgrp]->led_active = 0; ++ crisv32_leds[ledgrp]->ifisup[0] = 0; ++ crisv32_leds[ledgrp]->ifisup[1] = 0; ++ /* NOTE: Should this value be set to zero as the jiffies timer ++ can wrap? */ ++ crisv32_leds[ledgrp]->led_next_time = jiffies; ++ ++ crisv32_leds[ledgrp]->clear_led_timer = timer_init; ++ crisv32_leds[ledgrp]->clear_led_timer.function = ++ crisv32_clear_network_leds; ++ crisv32_leds[ledgrp]->clear_led_timer.data = (unsigned long) dev; ++ ++ spin_lock_init(&crisv32_leds[ledgrp]->led_lock); ++ ++ np->leds = crisv32_leds[ledgrp]; ++} ++ ++static int __init crisv32_ethernet_init(void) ++{ ++ struct crisv32_ethernet_local *np; ++ int ret = 0; ++ ++#ifdef CONFIG_ETRAXFS ++ printk("ETRAX FS 10/100MBit ethernet v0.01 (c)" ++ " 2003 Axis Communications AB\n"); ++#else ++ printk("ARTPEC-3 10/100 MBit ethernet (c)" ++ " 2003-2009 Axis Communications AB\n"); ++#endif ++ ++#ifdef CONFIG_CRIS_MACH_ARTPEC3 ++ { ++ reg_clkgen_rw_clk_ctrl clk_ctrl = REG_RD(clkgen, regi_clkgen, ++ rw_clk_ctrl); ++ clk_ctrl.eth = clk_ctrl.dma0_1_eth = regk_clkgen_yes; ++ REG_WR(clkgen, regi_clkgen, rw