LANCOM NWAPP - neuschaefer/linux GitHub Wiki
aka. L-320agn Wireless, L-321agn Wireless, L-322agn dual Wireless_
This is the original design; for the redesigned version see NWAPP2.
Pictures

LANCOM NWAPP.E0, top side

LANCOM NWAPP.E0, bottom side
- LANCOM console port (RS-232 over mini-DIN 8-pin)
- 10/100/1000 Mbit/s Ethernet port
- 10/100 Mbit/s Ethernet port
- 12 V DC
- 2 mPCIe slots for WLAN
Top side:
- U1: Freescale MPC8314E SoC - powerpc 32-bit, PowerQUICC II, e300 core
- U800, U801: Nanya NT5DS16M16DS-ST: 256Mb DDR SDRAM (64 MiB in total)
- U1001: Marvell 88E1116-NNC1: Gigabit Ethernet PHY
- U1101: Marvell 88E3018-NNC1: "Fast" Ethernet PHY (100 Mbit/s)
- U401: TI SN74LVCH16373A: 16-Bit Transparent D-Type Latch With 3-State Outputs
- U1500, U1501: TI CDx4HC164: High-Speed CMOS Logic 8-Bit Serial-In, Parallel-Out Shift Register
- U1602: Onsemi MC74HC595A: 8-Bit Serial-Input/Serial or Parallel-Output Shift Register with Latched 3-State Outputs
- U1612: SIPEX SP3238ECA: Intelligent +3.0V to +5.5V RS-232 Transceiver
Bottom side:
- U900: Intel StrataFlash JS28F128: 256 Mbit CFI NOR flash
- U1900, U1901: Intel EN5322: Step-down DC-DC switching converter with integrated inductor
- JP1500 (
D) is the debug jumper. Setting it causes the bootloader to skip the memory test and start the main menu instead of any installed firmware. - CN1500 is for flash access
- CN1501 ?
- CN1 is for JTAG, it follows the JTAG/COP pinout:

V<adr>/I/R/G/B/S/U/D/e/f/t/H/?>
Flashlayout:16MB_Strataflash
FE000000 32KiB Loader1
FE008000 8KiB Romdscr1
FE00A000 24KiB Unused
FE010000 8KiB Romdscr2
FE012000 24KiB Unused
FE018000 160KiB Loader2
FE040000 512KiB LCFS
FE0C0000 512KiB Config
FE140000 512KiB Accounting
FE1C0000 14592KiB Firmware
V<adr>/I/R/G/B/S/U/D/e/f/t/H/?>
Monitor help page
-----------------
V<adr> : Dump memory addresses <adr>
G : Start active firmware
I : Version Info
U0,U1 : Upload file to Flash-ROM by XMODEM-/CRC
D0,D1 : Download file by XMODEM-128/1K
R : Reboot (Warmstart)
Bx : Modify outband bitrate
E ...* : Erase menu * = action required
F ... : Firmware menu
T ... : Test menu
Memory (both RAM and flash) can be dumping with two simple scripts:
decode.py
#!/usr/bin/python3
import re, argparse
LINE = re.compile("(........): (.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..) | ................")
MiB = 1024 ** 2
def main(i, o):
buf = bytearray()
start = None
for line in i:
if 'L2Ldr: exception #' in line: break
if m := LINE.match(line):
addr = int(m.group(1), 16)
if not start:
start = addr
print(f"Start: {start:#x}")
offset = addr - start
data = bytes.fromhex(m.group(2))
if len(buf) < offset:
buf += b'\0' * (offset - len(buf))
if len(buf) != offset:
print("vorwärts immer, rückwärts nimmer!")
break
buf += data
l = len(buf)
print(f"Got {l} ({l:#x}) bytes, {l / MiB:.4} MiB")
o.write(buf)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="decode LANCOM bootloader output")
parser.add_argument('log', help='log file to read')
parser.add_argument('bin', help='binary file to write')
args = parser.parse_args()
i = open(args.log, 'r')
o = open(args.bin, 'wb')
main(i, o)trigger.sh
#!/bin/sh
printf "V$1\r"
while sleep 0.1; do printf '\r'; donewhich are then invoked like this:
./trigger.sh 0 | microcom -s 115200 /dev/ttyUSB0 | tee ram.log
./trigger.sh FE000000 | microcom -s 115200 /dev/ttyUSB0 | tee flash.log
./decode.py ram.log ram.bin
./decode.py flash.log flash.binThe test menu can be entered by pressing t in the main menu.
It offers a shell-like interface, rather than the single-letter commands in the
main menu.
V<adr>/I/R/G/B/S/U/D/e/f/t/H/?>
If you can read this, you have voided your warranty.
Mon>help
help>
unknown command! type ? for help
Mon>?
?>
fs_list list filesystem contents
fs_del <id> delete file <id>
list_flash detect/list flash roms
q Quit
; queue commands
run <num> start firmware #num (0 or 1)
dbg <dbg_lvl> Set debug level 0..n (default==1)
rep <val>; cmd <args> [;cmd <args>] ... repeat commands n-times
cb <addr32>, <data8> read and compare byte value from address
cw <addr32>, <data16> read and compare word value from address
cl <addr32>, <data32> read and compare long value from address
rb <addr32> read byte value from address
rw <addr32> read word value from address
rl <addr32> read long value from address
wb <addr32>,<data8> [,count] write byte value to address
ww <addr32>,<data16> [,count] write word value to address
wl <addr32>,<data32> [,count] write long value to address
test_timers test timer system
test_wdog test watchdog
v24_status show V24 status lines
v24_dcd 1|0 set V24 DCD signal
v24_dsr 1|0 set V24 DSR signal
upload upload UPX-File to flash(X-Modem)
download start,end X-Modem download
led num,val test LED
? Help
coldboot cold-boot system (if implemented)
d [base[,len]] dump memory block
mmu print mmu regs
clocks print clocks
map print mappings
cr hostbrg,bus,dev,fct,reg [,data32] read and optionally compare PCI config reg
cw hostbrg,bus,dev,fct,reg,val write PCI config reg
lspci list PCI devices
Mon>
The file system uses numerical tags instead of names:
Mon>fs_list
fs_list>
FE040004: ID 5, len 00000039
FE040040: ID 4, len 00000072
FE0400B5: ID 1, len 0000E29F
FE04E357: ID 12, len 0000068B
FE04E9E5: ID 41, len 0000068B
FE04F073: ID 43, len 0000029C
FE04F312: ID 47, len 000000F1
FE04F406: ID 3, len 00000074
FE04F47D: ID A9, len 00001216
FE050696: ID D, len 00000004
FE068FEE: ID 6, len 0000B850
FE07595B: ID C7, len 000007A9
FE076107: <END>
GPIODAT = 0xe0000c08
| # | I/O | mask | device | description |
|---|---|---|---|---|
| 0 | I | 0x8000_0000 |
JP1500 | debug status (active low) |
| 1 | I | 0x4000_0000 |
SW1500 | reset button (active low) |
| 2 | O | 0x2000_0000 |
U1602? | bitbanged latch |
| 5 | O | 0x0400_0000 |
U1602? | bitbanged clock |
| 18 | O | 0x0000_2000 |
something related to SPI | |
| 20 | O | 0x0000_0800 |
U1602? | bitbanged data |
| 21 | O | 0x0000_0400 |
RS-232 DCD active | |
| 22 | O | 0x0000_0200 |
RS-232 DSR active |
The MPC8314E has 32 GPIOs. Their usage on the NWAPP2 board is as follows, (#) indicates active low signals:
An 8-bit shift register is bitbanged through GPIO 2/5/20. Bits are transmitted MSB-first, in the following steps:
- clock, latch, data = 0
- for every bit:
- data = bit
- clock = 1
- clock = 0
- latch = 1
- latch = 0
| number | mask | default | description |
|---|---|---|---|
| 0 | 0x01 |
1 | |
| 1 | 0x02 |
1 | |
| 2 | 0x04 |
0 | |
| 3 | 0x08 |
1 | |
| 4 | 0x10 |
1 | |
| 5 | 0x20 |
0 | |
| 6 | 0x40 |
0 | board reset |
| 7 | 0x80 |
0 |
The LEDs are connected to the shift registers U1500/U1501, which are driven
through the SoC's SPI controller. LANCOM's bootloader configures the SPI
controller to use 16-bit words, so that a single word-write to the SPI transmit
register at 0xe0007030 sets the LED pattern. The shift registers do not have
a latch pin, so any changes come into effect immediately.
Active-low signals are indicated by a hash sign (#).
| LED | purpose | color | bit | comments |
|---|---|---|---|---|
| 1500 | Power | red | 0 # | |
| (top) | green | 1 # | ||
| 1501 | Power | red | 2 | |
| (front) | green | 3 | ||
| 1502 | WLAN 1 | red | 4 | |
| (front) | green | 5 | ||
| 1503 | WLAN | red | 6 # | |
| (top) | green | 7 # | ||
| 1504 | WLAN 2 | red | 8 # | |
| (front) | green | 9 # | ||
| 1505 | red | 10 | unpopulated | |
| green | 11 | |||
| 1506 | ETH 1 | red | -- | not CPU-controlled |
| green | -- | |||
| 1507 | ETH 2 | red | -- | |
| green | -- |
There are two mini-PCIe slots, typically used for WLAN cards (Model DNXA-116). PCI/PCIe configuration on the MPC8314E is rather complex, but the preconfigured access windows are as follows:
| type | slot 1 | slot 2 | size |
|---|---|---|---|
| config | 0x88000000 |
0x8c000000 |
4 MiB |
| I/O | 0x8a000000 |
0x8e000000 |
4 MiB |
| memory | 0x8a400000 |
0x8e400000 |
32 MiB |
Note that 32 MiB of memory address space are not enough for typical GPUs. Previous attempts at configuring a larger access window have failed.
There are two Ethernet ports, externally labelled as ETH 1 and ETH 2.
| port | MAC | PHY | Conn. | LED | speed (Mbit/s) |
|---|---|---|---|---|---|
| ETH 2 | eTSEC 1 @ 0xe0024000
|
U1101, 88E3018 | CN1100 | LED1507 | 10/100 |
| ETH 1 | eTSEC 2 @ 0xe0025000
|
U1001, 88E1116 | CN1000 | LED1506 | 10/100/1000 |
MDIO scans show the following:
md0.scan()
Port 0:
0: 1140 7949 0141 0e11 01e1 0000 0004 2001
8: 0000 0300 0000 0000 0000 0000 0000 3000
16: 6060 8040 0000 0040 0000 0000 0000 0000
24: 0000 0000 0040 0000 0000 0000 0000 0000
Port 2:
0: 3100 78e9 0141 0e20 01e1 cde1 000f 2801
8: 0000 0000 0000 0000 0000 0000 0000 0000
16: 0130 7c40 0000 5c40 0000 0000 4a44 4000
24: 4205 000a 0000 0000 0402 0000 0000 0000
Port 16:
0: 1140 0149 0000 0000 0000 0000 0004 0000
8: 0000 0000 0000 0000 0000 0000 0000 a000
16: 0000 0010 0000 0000 0000 0000 0000 0000
24: 0000 0000 0000 0000 0000 0000 0000 0000
On md0 (MDIO for eTSEC 1), the PHY is identified as 0x01410e11 (Marvell
88E1118) when reading from port address 0, but as 0x01410e20 when reading
from port 2. This ID is unknown to U-Boot and Linux, but QEMU identifies it
as 88E3015, which is close enough to 88E3018 to be plausible for U1101.
md1.scan()
Port 0:
0: 1140 0149 0000 0000 0000 0000 0004 0000
8: 0000 0000 0000 0000 0000 0000 0000 a000
16: 0000 0010 0000 0000 0000 0000 0000 0000
24: 0000 0000 0000 0000 0000 0000 0000 0000
On md1, address 0, we see a pattern that also appeared on md0, address 16.
A vaguely plausible set of bits in registers 0/1, but no identification in
registers 2/3. It turns out this is the eTSEC's internal "ten-bit interface"
(TBI) PHY, which can be configured to respond to different addresses
(cf. TBIPA in the MPC8315E Reference Manual).