raspberrypi / linux

Kernel source tree for Raspberry Pi-provided kernel builds. Issues unrelated to the linux kernel should be posted on the community forum at https://forums.raspberrypi.com/
Other
11.02k stars 4.95k forks source link

Please enable CONFIG_ENC28J60=m #795

Closed RadekHvizdos closed 9 years ago

RadekHvizdos commented 9 years ago

With 3.18 we have moved to device tree based configuration, so we no longer need to put SPI connection specific information into a board file. Could we now enable ENC28J60 as a module so that both armv6 and amrv7 distribution kernels support this ethernet controller?

http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=18397

Thanks!

popcornmix commented 9 years ago

Looks okay.

pelwell commented 9 years ago

Ask me nicely and I'll create you an overlay to get it loaded.

RadekHvizdos commented 9 years ago

Pretty please :)

You would make my day.

popcornmix commented 9 years ago

The module is enabled in latest rpi-update kernel.

DougieLawson commented 9 years ago

Thanks a million. That makes adding the eth0 on my A+ so much easier.

pelwell commented 9 years ago

I haven't forgotten the overlay - I will get back to it eventually.

gajdipajti commented 9 years ago

Wow, this is really good news.

pelwell commented 9 years ago

The overlay and slightly tweaked module are now in the rpi-3.18.y branch. Build with 'dtbs' as a make target, and copy arch/arm/boot/dtbs/enc28j60-overlay.dtb to /boot/overlays, add 'dtoverlay=enc28j60' and reboot.

popcornmix commented 9 years ago

@pelwell's overlay is in latest rpi-update firmware.

RadekHvizdos commented 9 years ago

Thanks a lot guys!

pelwell commented 9 years ago

Are you happy to close this?

pelwell commented 9 years ago

Closing for lack of response.

RadekHvizdos commented 9 years ago

Hi pelwell, I am sorry, but I have not been available to test the implementation until now. I have tried it tonight with mixed results. The device tree overlay loads the kernel module, but the network interface does not work. It is as if the cable is not plugged in. I suspect the issue is with missing IRQ definitions in the overlay; any chance to investigate this?

Thank you and the team for your help so far.

eth1      Link encap:Ethernet  HWaddr 8e:41:c9:c3:dc:0f
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

ethtool eth1
Settings for eth1:
        Supported ports: [ TP ]
        Supported link modes:   10baseT/Half 10baseT/Full
        Supported pause frame use: No
        Supports auto-negotiation: No
        Advertised link modes:  Not reported
        Advertised pause frame use: No
        Advertised auto-negotiation: No
        Speed: 10Mb/s
        Duplex: Half
        Port: Twisted Pair
        PHYAD: 0
        Transceiver: internal
        Auto-negotiation: off
        MDI-X: Unknown
        Current message level: 0x00000036 (54)
                               probe link ifdown ifup
gajdipajti commented 9 years ago

Same here, dmesg:

bcm2708_spi 20204000.spi: master is unqueued, this is deprecated
enc28j60 spi0.0: enc28j60 Ethernet driver 1.01 loaded
net eth0: enc28j60 driver registered
bcm2708_spi 20204000.spi: SPI Controller at 0x20204000 (irq 80)
net eth0: link down
net eth0: normal mode
net eth0: multicast mode

$ ip addr

eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000
  link/ether 1e:3e:ab:b3:26:c8 brd ff:ff:ff:ff:ff:ff
pelwell commented 9 years ago

I don't have a setup to test this. @DougieLawson, can you comment?

DougieLawson commented 9 years ago

Hi Phil,

I'm not sure my hardware is working, I've run it up on an Arduino and it doesn't appear to work there. So I have a new one being shipped from China (don't you love eBay).

When I get that I'll test it with the Arduino then on my A+.

RadekHvizdos commented 9 years ago

Could we re-open this bug until we have a working implementation?

Thanks.

DougieLawson commented 9 years ago

My replacement hardware arrived today. I've tested this with Linux aplus 3.18.9+ #768 and it is not working.

I'll build a new 3.18.9 kernel tomorrow (with the patched version of bcm2708.c) and give that a try.

DougieLawson commented 9 years ago

I've got the hardware. I can't get it to work at all.

pelwell commented 9 years ago

Can you elaborate? That doesn't give us much to work with.

DougieLawson commented 9 years ago

The interface appears to be active, I can assign a hw MAC address, DHCP (I'm running dhcpcd not isc-dhcp-client) fails to get a IP assigned by my router so gives it a 169.254.xxx.yyy address.

There's green and a winking orange light, the switch has a green light (the cable is known to be good as I've tested it with my 2B).

I can ping the local side of the interface, I can't send traffic out through my router. I can't ping in from the network.

That's running a kernel with the old hack for bcm2708.c and with the DT disabled. Same effect with DT and your overlay. Same effect with DT and my hacked full system DTB.

With this new hardware I've not tried it on my Arduino, but it's fresh from the Chinese ebayer that I bought it from.

pelwell commented 9 years ago

Thanks - that's much clearer. Unfortunately I don't think there's much I can do here, unless somebody can narrow down where the problem is.

gajdipajti commented 9 years ago

@DougieLawson what does dmesg or ip addr show, is the cable plugged in?

pelwell commented 9 years ago

I think we can assume the latter - Mr Lawson has proved himself to be at least that capable. ;-)

DougieLawson commented 9 years ago

Of course the cable isn't plugged in and the raspberry pi is halted. I'll just beat myself round the ears with my Louisville Slugger for being so damned stupid. :-) :-1:

dmesg shows the interface is working "mostly" normally.

pelwell commented 9 years ago

So that's that solved then...

gajdipajti commented 9 years ago

Sorry, I wasn't clear enough. Mine shows that the cable is unplugged, as I posted it 19 days ago. But the cable is physically plugged in and the other end is in a router. Only it is not detected. (I changed the router and the cable also)

DougieLawson commented 9 years ago

@gajdipajti Sorry, we should be more sensitive to the fact that your first language isn't English.

You're reporting the same symptoms that I'm seeing.

@pelwell do you want me to stick my hardware in an envelope and mail it to you?

pelwell commented 9 years ago

It's OK - I've splashed a fiver on a UK-sourced one. I should get it on Friday. N.B. This is going to have to be a background task for me.

notro commented 9 years ago

@msperl you have this working with Device Tree. Can you share how you did it?

msperl commented 9 years ago

Using the upstream kernel it works like this:

        eth1_pins: eth1_pins {
                brcm,pins = <23>;
                brcm,function = <0>; /* input */
        };
...
        eth1: enc28j60@3 {
                reg = <3>;
                status = "okay";
                compatible = "microchip,enc28j60";
                pinctrl-names = "default";
                pinctrl-0 = <&eth1_pins>;
                spi-max-frequency = <10000000>;
                interrupt-parent = <&gpio>;
                interrupts = <23 0x2>;
        };

The device seems quite sensitive with spi-max-frequency, so I had to limit myself to 10MHz.

But note that I essentially run 5 devices on the bus: 2xmcp2515, 1xenc28j60, 1xfb_st7735r and 1xmmc_spi (which I have not got to work stably). So that also impacts capacitance on the bus and distorts waveforms - if you connect only one then it might work with Fsck=20MHz as per Datasheet... Worsted case it will stop after a few frames...

pelwell commented 9 years ago

Dougie - your setup didn't include the dedicated interrupt line, and that's what I've replicated. Perhaps that is the cause of the problem.

DougieLawson commented 9 years ago

I'll hack a version of your overlay and try that.

Mine is set to run at 12MHz.

DougieLawson commented 9 years ago

Sorry I can't get a DTB to work or get an overlay DTB to compile. I don't understand enough about that funky overlay syntax to be able to add @msperl's stuff.

pelwell commented 9 years ago
// Overlay for the Microchip ENC28J60 Ethernet Controller
/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2708";

    fragment@0 {
        target = <&spi0>;
        __overlay__ {
            /* needed to avoid dtc warning */
            #address-cells = <1>;
            #size-cells = <0>;

            status = "okay";

            spidev@0{
                status = "disabled";
            };

            eth1: enc28j60@0{
                compatible = "microchip,enc28j60";
                reg = <0>; /* CE0 */
                pinctrl-names = "default";
                pinctrl-0 = <&eth1_pins>;
                interrupt-parent = <&gpio>;
                interrupts = <23 0x2>; /* falling edge */
                spi-max-frequency = <12000000>;
                status = "okay";
            };
        };
    };

    fragment@1 {
        target = <&gpio>;
        __overlay__ {
            eth1_pins: eth1_pins {
                brcm,pins = <23>;
                brcm,function = <0>; /* IN */
            };
        };
    };

    __overrides__ {
        int_pin = <&eth1_pins>, "brcm,pins:0",
                  <&eth1>, "interrupts:0";
    };
};
pelwell commented 9 years ago

And here's the compiled dtb (base64'd):

0A3+7QAABPsAAAA4AAAEMAAAACgAAAARAAAAEAAAAAAAAADLAAAD+AAAAAAAAAAAAAAAAAAAAAAA
AAABAAAAAAAAAAMAAAANAAAAAGJyY20sYmNtMjcwOAAAAAAAAAABZnJhZ21lbnRAMAAAAAAAAwAA
AAQAAAAL3q2+7wAAAAFfX292ZXJsYXlfXwAAAAADAAAABAAAABIAAAABAAAAAwAAAAQAAAAhAAAA
AAAAAAMAAAAFAAAALW9rYXkAAAAAAAAAAXNwaWRldkAwAAAAAAAAAAMAAAAJAAAALWRpc2FibGVk
AAAAAAAAAAIAAAABZW5jMjhqNjBAMAAAAAAAAwAAABMAAAAAbWljcm9jaGlwLGVuYzI4ajYwAAAA
AAADAAAABAAAADQAAAAAAAAAAwAAAAgAAAA4ZGVmYXVsdAAAAAADAAAABAAAAEYAAAABAAAAAwAA
AAQAAABQ3q2+7wAAAAMAAAAIAAAAYQAAABcAAAACAAAAAwAAAAQAAABsALcbAAAAAAMAAAAFAAAA
LW9rYXkAAAAAAAAAAwAAAAQAAAB+AAAAAgAAAAMAAAAEAAAAhAAAAAIAAAACAAAAAgAAAAIAAAAB
ZnJhZ21lbnRAMQAAAAAAAwAAAAQAAAAL3q2+7wAAAAFfX292ZXJsYXlfXwAAAAABZXRoMV9waW5z
AAAAAAAAAwAAAAQAAACMAAAAFwAAAAMAAAAEAAAAlgAAAAAAAAADAAAABAAAAH4AAAABAAAAAwAA
AAQAAACEAAAAAQAAAAIAAAACAAAAAgAAAAFfX292ZXJyaWRlc19fAAAAAAAAAwAAACEAAACkAAAA
AWJyY20scGluczowAAAAAAJpbnRlcnJ1cHRzOjAAAAAAAAAAAgAAAAFfX3N5bWJvbHNfXwAAAAAD
AAAAIwAAAKwvZnJhZ21lbnRAMC9fX292ZXJsYXlfXy9lbmMyOGo2MEAwAAAAAAADAAAAIgAAALEv
ZnJhZ21lbnRAMS9fX292ZXJsYXlfXy9ldGgxX3BpbnMAAAAAAAACAAAAAV9fZml4dXBzX18AAAAA
AAMAAAAVAAAAuy9mcmFnbWVudEAwOnRhcmdldDowAAAAAAAAAAMAAABLAAAAwC9mcmFnbWVudEAw
L19fb3ZlcmxheV9fL2VuYzI4ajYwQDA6aW50ZXJydXB0LXBhcmVudDowAC9mcmFnbWVudEAxOnRh
cmdldDowAAAAAAACAAAAAV9fbG9jYWxfZml4dXBzX18AAAAAAAAAAwAAAGIAAADFL2ZyYWdtZW50
QDAvX19vdmVybGF5X18vZW5jMjhqNjBAMDpwaW5jdHJsLTA6MAAvX19vdmVycmlkZXNfXzppbnRf
cGluOjAAL19fb3ZlcnJpZGVzX186aW50X3BpbjoxNgAAAAAAAAIAAAACAAAACWNvbXBhdGlibGUA
dGFyZ2V0ACNhZGRyZXNzLWNlbGxzACNzaXplLWNlbGxzAHN0YXR1cwByZWcAcGluY3RybC1uYW1l
cwBwaW5jdHJsLTAAaW50ZXJydXB0LXBhcmVudABpbnRlcnJ1cHRzAHNwaS1tYXgtZnJlcXVlbmN5
AGxpbnV4LHBoYW5kbGUAYnJjbSxwaW5zAGJyY20sZnVuY3Rpb24AaW50X3BpbgBldGgxAGV0aDFf
cGlucwBzcGkwAGdwaW8AZml4dXAA
pelwell commented 9 years ago

Assuming you've overwritten /boot/overlays/enc28j60-overlay.dtb, you load with:

dtoverlay=enc28j60,int_pin=25

And 8-p to the b64 haters.

DougieLawson commented 9 years ago

Thanks Phil,

It's working.

pelwell commented 9 years ago

Great. I'll get that checked in tomorrow, and it will be in the next firmware update.

DougieLawson commented 9 years ago

New problem:

[ 380.090883] ------------[ cut here ]------------ [ 380.090956] WARNING: CPU: 0 PID: 0 at net/sched/sch_generic.c:303 dev_watchdog+0x300/0x324() [ 380.090973] NETDEV WATCHDOG: eth0 (enc28j60): transmit queue 0 timed out [ 380.090983] Modules linked in: ctr ccm arc4 rt2800usb rt2800lib rt2x00usb rt2x00lib mac80211 cfg80211 crc_ccitt rfkill rpcsec_gss_krb5 nfsd ipv6 i2c_dev snd_bcm2835 snd_pcm snd_seq snd_seq_device snd_timer snd evdev enc28j60 i2c_bcm2708 spi_bcm2708 uio_pdrv_genirq uio [ 380.091116] CPU: 0 PID: 0 Comm: swapper Not tainted 3.18.9+ #772 [ 380.091181] [<c0014edc>] (unwind_backtrace) from [<c0012650>] (show_stack+0x20/0x24) [ 380.091223] [<c0012650>] (show_stack) from [<c054b070>] (dump_stack+0x20/0x28) [ 380.091262] [<c054b070>] (dump_stack) from [<c0022a9c>] (warn_slowpath_common+0x7c/0x9c) [ 380.091291] [<c0022a9c>] (warn_slowpath_common) from [<c0022afc>] (warn_slowpath_fmt+0x40/0x48) [ 380.091320] [<c0022afc>] (warn_slowpath_fmt) from [<c04933d0>] (dev_watchdog+0x300/0x324) [ 380.091360] [<c04933d0>] (dev_watchdog) from [<c006b840>] (call_timer_fn+0x40/0x184) [ 380.091390] [<c006b840>] (call_timer_fn) from [<c006c154>] (run_timer_softirq+0x2d0/0x39c) [ 380.091421] [<c006c154>] (run_timer_softirq) from [<c0026190>] (__do_softirq+0x118/0x36c) [ 380.091448] [<c0026190>] (__do_softirq) from [<c0026748>] (irq_exit+0xbc/0x110) [ 380.091482] [<c0026748>] (irq_exit) from [<c005d350>] (__handle_domain_irq+0x84/0xd0) [ 380.091510] [<c005d350>] (__handle_domain_irq) from [<c000853c>] (asm_do_IRQ+0x2c/0x30) [ 380.091545] [<c000853c>] (asm_do_IRQ) from [<c0550278>] (__irq_svc+0x38/0xd0) [ 380.091560] Exception stack(0xc07eff20 to 0xc07eff68) [ 380.091586] ff20: 00000000 00000000 00000000 c07f6f48 00000002 c07ee000 00000000 c07f608c [ 380.091610] ff40: c0840608 c083fba6 c083fba6 c07eff74 c07eff68 c07eff68 c000f324 c000f328 [ 380.091624] ff60: 60000013 ffffffff [ 380.091658] [<c0550278>] (__irq_svc) from [<c000f328>] (arch_cpu_idle+0x30/0x40) [ 380.091698] [<c000f328>] (arch_cpu_idle) from [<c0050004>] (cpu_startup_entry+0x1a4/0x210) [ 380.091731] [<c0050004>] (cpu_startup_entry) from [<c05468e0>] (rest_init+0x80/0x98) [ 380.091774] [<c05468e0>] (rest_init) from [<c0799ca8>] (start_kernel+0x364/0x3cc) [ 380.091792] ---[ end trace c16baba9f10fcaf1 ]--- [ 380.123724] net eth0: hw_reset() failed [ 380.123766] net eth0: could not restart -22

It died less than five minutes after I booted it.

pelwell commented 9 years ago

My module has arrived and it seems to be working. It is the version of the module with mounting holes, and I've installed it using ~15cm jumper wires.

It has just downloaded NOOBS - 770MB at 260KB/s (not quick), with no errors or dmesg output. I have a slightly tweaked overlay - the default pin is now 25, which seems common, and the overlay explicitly clears the pull down on the interrupt pin, which although it should be harmless is not optimal - but the testing before and after the change looks identical.

I will push the new overlay, to be picked up in the next release, but I wouldn't expect you to see any difference.

msperl commented 9 years ago

I guess that it could be some interference on the bus - try to run with a slower spi_speed via a dt-parameter just to see if that solves the issue (at the cost of more packet loss) Also you may give it a try to see if the spi-bcm2835 driver shows the same behaviour.

I am actually running 4 devices on my SPI bus (with an updated spi-bcm2835) and I have not seen any issue like yours...

pelwell commented 9 years ago

There is a "speed" parameter in the updated overlay that sets spi-max-frequency - the default is 12000000.

Mine has been running for hours now, transferring (a few) gigabytes without a hitch.

gajdipajti commented 9 years ago

Thank you everyone, my device now works, and I can finally start finnishing my bird cam project!

RadekHvizdos commented 9 years ago

Hi all,

Thank you for your assistance. The new overlay is working fine. I am getting reasonable throughput (386kB/s average, with peeks over 400kB/s) without any issues so far.

I have only tested the blob posted by pelwell, as the stock firmware has not been updated yet, and my Debian system can't compile the source (has old DT compiler). Hopefully the firmware will get updated soon so that we can close this topic.

Thanks again.

RadekHvizdos commented 9 years ago

Hi all,

I was able to compile the latest DT overlay source and confirm it is working. I have also looked at SPI clock with an oscilloscope. The default in DT is currently configured with spi-max-frequency = <12000000> as the default. But this is translated to 7.8MHz SPI clock as visible on my scope. According to http://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md, the SPI driver can only accept power of two integer divisors which results in the following possible SPI clock frequencies:

cdiv speed
2 125.0 MHz
4 62.5 MHz
8 31.2 MHz
16 15.6 MHz
32 7.8 MHz
64 3.9 MHz
128 1953 kHz
256 976 kHz
512 488 kHz
1024 244 kHz
2048 122 kHz
4096 61 kHz
8192 30.5 kHz
16384 15.2 kHz
32768 7629 Hz

This is working for most people, but the errata sheet for ENC28j60 describes a silicon bug for some revisions of this IC:

When the SPI clock from the host microcontroller is run at frequencies of less than 8 MHz, reading or writing to the MAC registers may be unreliable.

Work around Two work arounds are presented; others may be available.

  1. Run the SPI at frequencies of at least 8 MHz.
  2. Generate an SPI clock of 25/2 (12.5 MHz), 25/3 (8.333 MHz), 25/4 (6.25 MHz),25/5 (5 MHz), etc., and synchronize with the 25 MHz clock entering OSC1 on the ENC28J60. This could potentially be accomplished by feeding the same 25 MHz clock into the ENC28J60 and host controller. Alternatively, the host controller could potentially be clocked off of the CLKOUT output of the ENC28J60.

Current default does not meet this requirement.

I propose to increase the default to 20000000 (chip maximum), which sets the SPI clock to 15.6 MHz (confirmed on the scope), well above the silicon bug. This has a side benefit of increasing the throughput from 386kB/s to 540kB/s on my Model A+. Perhaps some time in the future the divisor restriction will be lifted to allow us to use full 20MHz SPI clock.

I believe this would be a reasonable default; one can always lower the frequency by changing the overlay parameter.

Thanks

msperl commented 9 years ago

well - there is a patch in the pipeline for the spi-bcm2835 driver that should also handle this case. it would mean that the clock-divider can be a multiple of 2 not a power of 2. When it gets accepted into the kernel - probably with 4.1 - then we can backport it also into the foundation kernel.

But note that for me 20MHz did not work on my breadboard setup with multiple SPI devices - I am using 10MHz and there it works fine!

pelwell commented 9 years ago

If you can point me at the patch, which must be for spi-bcm2835.c, then we may apply it to spi-bcm2708.c, i.e. the driver used by the stock RPi kernels.

notro commented 9 years ago

[PATCH] SPI: BCM2835: clock divider can be a multiple of 2: https://www.marc.info/?l=linux-spi&m=142675575809112&w=3

msperl commented 9 years ago

The bcm2835 is now also loadable as a module with the right overlay - this was done to keep the development upstream...