[RFC PATCH] soc/fsl/qe: support MPC8309

From: Rasmus Villemoes
Date: Tue Feb 26 2019 - 03:48:39 EST


Currently, when device tree specifies fsl,qe-num-snums = 28 (which a
number of in-tree .dts files do, and which is the default when that
property is missing), qe_snums_init() ends up using the first 28
elements of the snum_init_46[] array.

The situation is quite messy. This patch may break existing setups
that for some reason work with specifying fsl,qe-num-snums = 28 and
using the existing snum_init_46 array. OTOH, the current code
certainly does not work for the MPC8309-based board we're working on,
since the first 14 of the elements in snum_init_46 are "Not available
on MPC8306/MPC8306S/MPC8309" according to the QUICC Engine Reference
Manual (Table 4-30) - and indeed, without this patch (or something to
the same effect), we get

[ 8.895758] ------------[ cut here ]------------
[ 8.895778] NETDEV WATCHDOG: eth0 (ucc_geth): transmit queue 0 timed out
[ 8.895971] WARNING: CPU: 0 PID: 8 at net/sched/sch_generic.c:461 dev_watchdog+0x23c/0x244
[ 8.895977] Modules linked in:
[ 8.895998] CPU: 0 PID: 8 Comm: kworker/u2:1 Not tainted 4.19.18-00012-gd47efbb0119d #183
[ 8.896017] Workqueue: events_unbound call_usermodehelper_exec_work
[ 8.896030] NIP: c037b18c LR: c037b18c CTR: 00000000
[ 8.896042] REGS: cf853b00 TRAP: 0700 Not tainted (4.19.18-00012-gd47efbb0119d)
[ 8.896047] MSR: 00029032 <EE,ME,IR,DR,RI> CR: 42022428 XER: 00000000
[ 8.896080]
[ 8.896080] GPR00: c037b18c cf853bb0 cf82e4c0 0000003c c05f7bc4 000000c4 0000004c 000038dc
[ 8.896080] GPR08: 00000007 00000007 00000001 00000000 22022424 00000000 00000100 c05f3d78
[ 8.896080] GPR16: c05f3d7c 00000001 00000004 cf852000 00000000 c05e0000 fffee3a9 c0496618
[ 8.896080] GPR24: c05241c8 0000000a c05c0000 c05db0f4 cf82b800 c05e0000 00000000 cf82ba74
[ 8.896229] NIP [c037b18c] dev_watchdog+0x23c/0x244
[ 8.896240] LR [c037b18c] dev_watchdog+0x23c/0x244
[ 8.896244] Call Trace:
[ 8.896257] [cf853bb0] [c037b18c] dev_watchdog+0x23c/0x244 (unreliable)
[ 8.896285] [cf853bd0] [c0054eb0] call_timer_fn+0x24/0x84
[ 8.896304] [cf853bf0] [c0055228] expire_timers.isra.4+0x98/0xa8
[ 8.896322] [cf853c10] [c00552cc] run_timer_softirq+0x94/0x190
[ 8.896341] [cf853c60] [c0494738] __do_softirq+0xe0/0x258
[ 8.896357] [cf853cc0] [c001db68] irq_exit+0xfc/0x100
[ 8.896375] [cf853cd0] [c000a2e8] timer_interrupt+0xdc/0x1c0
[ 8.896399] [cf853cf0] [c000f460] ret_from_except+0x0/0x14
[ 8.896432] --- interrupt: 901 at copy_process.isra.8.part.9+0x60c/0x1334
[ 8.896432] LR = copy_process.isra.8.part.9+0x864/0x1334
[ 8.896446] [cf853db0] [c0018fc8] copy_process.isra.8.part.9+0x7d0/0x1334 (unreliable)
[ 8.896466] [cf853e40] [c0019fc0] _do_fork+0xa8/0x2ac
[ 8.896486] [cf853e80] [c002b7e0] call_usermodehelper_exec_work+0x74/0xec
[ 8.896506] [cf853ea0] [c002e520] process_one_work+0x168/0x38c
[ 8.896523] [cf853ec0] [c002e87c] worker_thread+0x138/0x488
[ 8.896541] [cf853f10] [c0033824] kthread+0xe0/0x10c
[ 8.896560] [cf853f40] [c000f1c4] ret_from_kernel_thread+0x14/0x1c
[ 8.896568] Instruction dump:
[ 8.896577] 811ffffc 4bffff70 39200001 7f83e378 9928af9f 4bfd82d5 7fc6f378 7f84e378
[ 8.896615] 7c651b78 3c60c056 3863be98 4bc9f681 <0fe00000> 4bffffb8 9421ffe0 7d800026
[ 8.896655] ---[ end trace cfd3ddfe80d72be2 ]---

along with an endless sequence of

[ 115.716012] ucc_geth e0102000.ethernet eth1: Link is Up - 100Mbps/Full - flow control off
[ 117.744010] ucc_geth e0103000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off
[ 119.295955] ucc_geth e0102000.ethernet eth1: Link is Down
[ 119.712177] ucc_geth e0102000.ethernet eth1: Link is Up - 100Mbps/Full - flow control off
[ 123.295801] ucc_geth e0102000.ethernet eth1: Link is Down
[ 123.295843] ucc_geth e0103000.ethernet eth0: Link is Down
[ 123.712022] ucc_geth e0102000.ethernet eth1: Link is Up - 100Mbps/Full - flow control off
[ 125.744167] ucc_geth e0103000.ethernet eth0: Link is Up - 100Mbps/Full - flow control off

It would seem to make much more sense of the table of snums was either
decided based on some compatible string, or alternatively, if the
array of snums was simply a byte array read directly from DT.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes@xxxxxxxxx>
---
drivers/soc/fsl/qe/qe.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 2ef6fc6487c1..185da4be3509 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -306,12 +306,21 @@ static void qe_snums_init(void)
0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
};
+ static const u8 snum_init_28[] = {
+ 0x88, 0x89, 0x98, 0x99, 0xa8, 0xa9, 0xb8, 0xb9,
+ 0xc8, 0xc9, 0xd8, 0xd9, 0xe8, 0xe9,
+ 0x08, 0x09, 0x18, 0x19, 0x28, 0x29, 0x38, 0x39,
+ 0x48, 0x49, 0x58, 0x59, 0x68, 0x69,
+ };
+
static const u8 *snum_init;

qe_num_of_snum = qe_get_num_of_snums();

if (qe_num_of_snum == 76)
snum_init = snum_init_76;
+ else if (qe_num_of_snum == 28)
+ snum_init = snum_init_28;
else
snum_init = snum_init_46;

--
2.20.1