[Mesh] Meraki routers and watchdog problems

Marc Juul juul at labitat.dk
Wed Dec 4 19:09:26 PST 2013


As some of you may already know, Noisebridge received a donation of
somewhere in the neighborhood of 250 "Meraki Outdoor" routers. I moved most
of them to sudo mesh so they wouldn't disappear from Noisebridge. I expect
we'll have around 150 of them once we've given some out to everyone who has
declared interest.

They're nearly the same specs and chipset as the picostations. The chipset
is an AR2317 instead of an AR2315 and it has an extra ethernet adapter and
only 200 mW of output power.

Here's a datasheet:

  https://meraki.cisco.com/lib/pdf/meraki_datasheet_outdoor.pdf

To use them, we need to solve four problems:

  * Antennas. They use the same connectors as mini-pci cards. I took apart
a broken laptop at sudo room and extracted two antennas, but that's
probably not a viable solution for all of them. We need a source for these
antennas, but I don't know the official name of that type of connector.

* PoE injectors. They take 5 to 22 volts.

* Cases: For indoor use we can use dollar store food storage cases. For
outdoor we can use cases design for outdoor electrical installations
(Mitar's suggestion). If someone's handy with 3D modeling we could also 3D
print cases. PLA is fine for indoor, but for outdoor we need ABS plastic
which requires a heated print bed.

* Software: I've been trying to get OpenWRT running on these, but it has
proven difficult.

The watchdog reboots the routers after 5 minutes and nothing can be done to
stop that from within the built-in RedBoot. Unfortunately it takes longer
than 5 minutes to flash them with OpenWRT. I've written a script that
flashes the routers in four stages, using a serial console and tftp over
ethernet and it works:

  https://github.com/sudomesh/merakiflasher

There are two remaining problems. One is that the sudomesh firmware boots
up and then immediately issues a shutdown command. This should be fairly
simple to solve but I haven't delved into it.

The second issue is the watchdog. The official meraki firmware that comes
with the routers correctly talks to the watchdog. Normal OpenWRT does not.
The kernel driver for the AR2315 watchdog is supposed to create the
/dev/watchdog device and the watchdog can be controlled from userland by
the watchdog daemon (part of busybox utilities) by writing to /dev/watchdog
or issuing ioctls. I've spent some time debugging the issue.

The relevant files are:

  drivers/watchdog/ar2315-wtd.c
  arch/mips/ar231x/ar2315.c
  arch/mips/ar231x/devices.c
  arch/mips/include/asm/mach-ar231x.h

The watchdog is being controlled by writing to memory-mapped registers
defined in mach-ar231x.h and by compiling a kernel with lots of printk
statements inserted into these files I have verified that the register
write functions are being called at the correct times.

I can imagine three things that may be going wrong:

  1. The memory mapped register addresses in mach-ar231x.h are different
for the AR2317 chipset (this seems unlikely based on the info I've been
able to find).

  2. The registers are not being mapped into memory correctly. I don't know
where to find the code that deals with the MMU and mapping registers.

  3. There is some additional initialization required for the AR2317
watchdog that isn't being handled correctly.

  4. The register read/write functions are not implemented correctly. These
seem to be implemented in arch/mips/include/asm/mipsregs.h as assembly, but
the actual ar231x_write_reg function is defined as:

  static inline void
  ar231x_write_reg(u32 reg, u32 val)
  {
      __raw_writel(val, (u32 *) KSEG1ADDR(reg));
  }

and __raw_write is defined in include/asm-generic/io.h as:

static inline void __raw_writel(u32 b, volatile void __iomem *addr)
{
        *(volatile u32 __force *) addr = b;
}

So it's just an assignment. Maybe if the registers are not getting memory
mapped (no idea how to check if they are) we should instead be using
something like:

#define __write_32bit_c0_register(register, sel, value)            \
do {                                    \
    if (sel == 0)                            \
        __asm__ __volatile__(                    \
            "mtc0\t%z0, " #register "\n\t"            \
            : : "Jr" ((unsigned int)(value)));        \
    else                                \
        __asm__ __volatile__(                    \
            ".set\tmips32\n\t"                \
            "mtc0\t%z0, " #register ", " #sel "\n\t"    \
            ".set\tmips0"                    \
            : : "Jr" ((unsigned int)(value)));        \
} while (0)

from mipsregs.h

I'm not sure. I'm speculating at this point.

Adrian: I could really use some help on this. Do you have time to join us
for a hack night soon? or maybe we can just meet on irc?

-- 
marc/juul
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sudoroom.org/lists/private/mesh/attachments/20131204/bfc90ecf/attachment.html>


More information about the mesh mailing list