xref: /linux/drivers/soc/ixp4xx/ixp4xx-npe.c (revision 76f24b4f46b8ca380d6e2c91bd84e0e47a9f4bcd)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Intel IXP4xx Network Processor Engine driver for Linux
4  *
5  * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl>
6  *
7  * The code is based on publicly available information:
8  * - Intel IXP4xx Developer's Manual and other e-papers
9  * - Intel IXP400 Access Library Software (BSD license)
10  * - previous works by Christian Hohnstaedt <chohnstaedt@innominate.com>
11  *   Thanks, Christian.
12  */
13 
14 #include <linux/delay.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/firmware.h>
17 #include <linux/io.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/of.h>
21 #include <linux/of_platform.h>
22 #include <linux/platform_device.h>
23 #include <linux/soc/ixp4xx/npe.h>
24 
25 #define DEBUG_MSG			0
26 #define DEBUG_FW			0
27 
28 #define NPE_COUNT			3
29 #define MAX_RETRIES			1000	/* microseconds */
30 #define NPE_42X_DATA_SIZE		0x800	/* in dwords */
31 #define NPE_46X_DATA_SIZE		0x1000
32 #define NPE_A_42X_INSTR_SIZE		0x1000
33 #define NPE_B_AND_C_42X_INSTR_SIZE	0x800
34 #define NPE_46X_INSTR_SIZE		0x1000
35 #define REGS_SIZE			0x1000
36 
37 #define NPE_PHYS_REG			32
38 
39 #define FW_MAGIC			0xFEEDF00D
40 #define FW_BLOCK_TYPE_INSTR		0x0
41 #define FW_BLOCK_TYPE_DATA		0x1
42 #define FW_BLOCK_TYPE_EOF		0xF
43 
44 /* NPE exec status (read) and command (write) */
45 #define CMD_NPE_STEP			0x01
46 #define CMD_NPE_START			0x02
47 #define CMD_NPE_STOP			0x03
48 #define CMD_NPE_CLR_PIPE		0x04
49 #define CMD_CLR_PROFILE_CNT		0x0C
50 #define CMD_RD_INS_MEM			0x10 /* instruction memory */
51 #define CMD_WR_INS_MEM			0x11
52 #define CMD_RD_DATA_MEM			0x12 /* data memory */
53 #define CMD_WR_DATA_MEM			0x13
54 #define CMD_RD_ECS_REG			0x14 /* exec access register */
55 #define CMD_WR_ECS_REG			0x15
56 
57 #define STAT_RUN			0x80000000
58 #define STAT_STOP			0x40000000
59 #define STAT_CLEAR			0x20000000
60 #define STAT_ECS_K			0x00800000 /* pipeline clean */
61 
62 #define NPE_STEVT			0x1B
63 #define NPE_STARTPC			0x1C
64 #define NPE_REGMAP			0x1E
65 #define NPE_CINDEX			0x1F
66 
67 #define INSTR_WR_REG_SHORT		0x0000C000
68 #define INSTR_WR_REG_BYTE		0x00004000
69 #define INSTR_RD_FIFO			0x0F888220
70 #define INSTR_RESET_MBOX		0x0FAC8210
71 
72 #define ECS_BG_CTXT_REG_0		0x00 /* Background Executing Context */
73 #define ECS_BG_CTXT_REG_1		0x01 /*		Stack level */
74 #define ECS_BG_CTXT_REG_2		0x02
75 #define ECS_PRI_1_CTXT_REG_0		0x04 /* Priority 1 Executing Context */
76 #define ECS_PRI_1_CTXT_REG_1		0x05 /*		Stack level */
77 #define ECS_PRI_1_CTXT_REG_2		0x06
78 #define ECS_PRI_2_CTXT_REG_0		0x08 /* Priority 2 Executing Context */
79 #define ECS_PRI_2_CTXT_REG_1		0x09 /*		Stack level */
80 #define ECS_PRI_2_CTXT_REG_2		0x0A
81 #define ECS_DBG_CTXT_REG_0		0x0C /* Debug Executing Context */
82 #define ECS_DBG_CTXT_REG_1		0x0D /*		Stack level */
83 #define ECS_DBG_CTXT_REG_2		0x0E
84 #define ECS_INSTRUCT_REG		0x11 /* NPE Instruction Register */
85 
86 #define ECS_REG_0_ACTIVE		0x80000000 /* all levels */
87 #define ECS_REG_0_NEXTPC_MASK		0x1FFF0000 /* BG/PRI1/PRI2 levels */
88 #define ECS_REG_0_LDUR_BITS		8
89 #define ECS_REG_0_LDUR_MASK		0x00000700 /* all levels */
90 #define ECS_REG_1_CCTXT_BITS		16
91 #define ECS_REG_1_CCTXT_MASK		0x000F0000 /* all levels */
92 #define ECS_REG_1_SELCTXT_BITS		0
93 #define ECS_REG_1_SELCTXT_MASK		0x0000000F /* all levels */
94 #define ECS_DBG_REG_2_IF		0x00100000 /* debug level */
95 #define ECS_DBG_REG_2_IE		0x00080000 /* debug level */
96 
97 /* NPE watchpoint_fifo register bit */
98 #define WFIFO_VALID			0x80000000
99 
100 /* NPE messaging_status register bit definitions */
101 #define MSGSTAT_OFNE	0x00010000 /* OutFifoNotEmpty */
102 #define MSGSTAT_IFNF	0x00020000 /* InFifoNotFull */
103 #define MSGSTAT_OFNF	0x00040000 /* OutFifoNotFull */
104 #define MSGSTAT_IFNE	0x00080000 /* InFifoNotEmpty */
105 #define MSGSTAT_MBINT	0x00100000 /* Mailbox interrupt */
106 #define MSGSTAT_IFINT	0x00200000 /* InFifo interrupt */
107 #define MSGSTAT_OFINT	0x00400000 /* OutFifo interrupt */
108 #define MSGSTAT_WFINT	0x00800000 /* WatchFifo interrupt */
109 
110 /* NPE messaging_control register bit definitions */
111 #define MSGCTL_OUT_FIFO			0x00010000 /* enable output FIFO */
112 #define MSGCTL_IN_FIFO			0x00020000 /* enable input FIFO */
113 #define MSGCTL_OUT_FIFO_WRITE		0x01000000 /* enable FIFO + WRITE */
114 #define MSGCTL_IN_FIFO_WRITE		0x02000000
115 
116 /* NPE mailbox_status value for reset */
117 #define RESET_MBOX_STAT			0x0000F0F0
118 
119 #define NPE_A_FIRMWARE "NPE-A"
120 #define NPE_B_FIRMWARE "NPE-B"
121 #define NPE_C_FIRMWARE "NPE-C"
122 
123 const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE };
124 
125 #define print_npe(pri, npe, fmt, ...)					\
126 	printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
127 
128 #if DEBUG_MSG
129 #define debug_msg(npe, fmt, ...)					\
130 	print_npe(KERN_DEBUG, npe, fmt, ## __VA_ARGS__)
131 #else
132 #define debug_msg(npe, fmt, ...)
133 #endif
134 
135 static struct {
136 	u32 reg, val;
137 } ecs_reset[] = {
138 	{ ECS_BG_CTXT_REG_0,	0xA0000000 },
139 	{ ECS_BG_CTXT_REG_1,	0x01000000 },
140 	{ ECS_BG_CTXT_REG_2,	0x00008000 },
141 	{ ECS_PRI_1_CTXT_REG_0,	0x20000080 },
142 	{ ECS_PRI_1_CTXT_REG_1,	0x01000000 },
143 	{ ECS_PRI_1_CTXT_REG_2,	0x00008000 },
144 	{ ECS_PRI_2_CTXT_REG_0,	0x20000080 },
145 	{ ECS_PRI_2_CTXT_REG_1,	0x01000000 },
146 	{ ECS_PRI_2_CTXT_REG_2,	0x00008000 },
147 	{ ECS_DBG_CTXT_REG_0,	0x20000000 },
148 	{ ECS_DBG_CTXT_REG_1,	0x00000000 },
149 	{ ECS_DBG_CTXT_REG_2,	0x001E0000 },
150 	{ ECS_INSTRUCT_REG,	0x1003C00F },
151 };
152 
153 static struct npe npe_tab[NPE_COUNT] = {
154 	{
155 		.id	= 0,
156 	}, {
157 		.id	= 1,
158 	}, {
159 		.id	= 2,
160 	}
161 };
162 
163 int npe_running(struct npe *npe)
164 {
165 	return (__raw_readl(&npe->regs->exec_status_cmd) & STAT_RUN) != 0;
166 }
167 
168 static void npe_cmd_write(struct npe *npe, u32 addr, int cmd, u32 data)
169 {
170 	__raw_writel(data, &npe->regs->exec_data);
171 	__raw_writel(addr, &npe->regs->exec_addr);
172 	__raw_writel(cmd, &npe->regs->exec_status_cmd);
173 }
174 
175 static u32 npe_cmd_read(struct npe *npe, u32 addr, int cmd)
176 {
177 	__raw_writel(addr, &npe->regs->exec_addr);
178 	__raw_writel(cmd, &npe->regs->exec_status_cmd);
179 	/* Iintroduce extra read cycles after issuing read command to NPE
180 	   so that we read the register after the NPE has updated it.
181 	   This is to overcome race condition between XScale and NPE */
182 	__raw_readl(&npe->regs->exec_data);
183 	__raw_readl(&npe->regs->exec_data);
184 	return __raw_readl(&npe->regs->exec_data);
185 }
186 
187 static void npe_clear_active(struct npe *npe, u32 reg)
188 {
189 	u32 val = npe_cmd_read(npe, reg, CMD_RD_ECS_REG);
190 	npe_cmd_write(npe, reg, CMD_WR_ECS_REG, val & ~ECS_REG_0_ACTIVE);
191 }
192 
193 static void npe_start(struct npe *npe)
194 {
195 	/* ensure only Background Context Stack Level is active */
196 	npe_clear_active(npe, ECS_PRI_1_CTXT_REG_0);
197 	npe_clear_active(npe, ECS_PRI_2_CTXT_REG_0);
198 	npe_clear_active(npe, ECS_DBG_CTXT_REG_0);
199 
200 	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
201 	__raw_writel(CMD_NPE_START, &npe->regs->exec_status_cmd);
202 }
203 
204 static void npe_stop(struct npe *npe)
205 {
206 	__raw_writel(CMD_NPE_STOP, &npe->regs->exec_status_cmd);
207 	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd); /*FIXME?*/
208 }
209 
210 static int __must_check npe_debug_instr(struct npe *npe, u32 instr, u32 ctx,
211 					u32 ldur)
212 {
213 	u32 wc;
214 	int i;
215 
216 	/* set the Active bit, and the LDUR, in the debug level */
217 	npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG,
218 		      ECS_REG_0_ACTIVE | (ldur << ECS_REG_0_LDUR_BITS));
219 
220 	/* set CCTXT at ECS DEBUG L3 to specify in which context to execute
221 	   the instruction, and set SELCTXT at ECS DEBUG Level to specify
222 	   which context store to access.
223 	   Debug ECS Level Reg 1 has form 0x000n000n, where n = context number
224 	*/
225 	npe_cmd_write(npe, ECS_DBG_CTXT_REG_1, CMD_WR_ECS_REG,
226 		      (ctx << ECS_REG_1_CCTXT_BITS) |
227 		      (ctx << ECS_REG_1_SELCTXT_BITS));
228 
229 	/* clear the pipeline */
230 	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
231 
232 	/* load NPE instruction into the instruction register */
233 	npe_cmd_write(npe, ECS_INSTRUCT_REG, CMD_WR_ECS_REG, instr);
234 
235 	/* we need this value later to wait for completion of NPE execution
236 	   step */
237 	wc = __raw_readl(&npe->regs->watch_count);
238 
239 	/* issue a Step One command via the Execution Control register */
240 	__raw_writel(CMD_NPE_STEP, &npe->regs->exec_status_cmd);
241 
242 	/* Watch Count register increments when NPE completes an instruction */
243 	for (i = 0; i < MAX_RETRIES; i++) {
244 		if (wc != __raw_readl(&npe->regs->watch_count))
245 			return 0;
246 		udelay(1);
247 	}
248 
249 	print_npe(KERN_ERR, npe, "reset: npe_debug_instr(): timeout\n");
250 	return -ETIMEDOUT;
251 }
252 
253 static int __must_check npe_logical_reg_write8(struct npe *npe, u32 addr,
254 					       u8 val, u32 ctx)
255 {
256 	/* here we build the NPE assembler instruction: mov8 d0, #0 */
257 	u32 instr = INSTR_WR_REG_BYTE |	/* OpCode */
258 		addr << 9 |		/* base Operand */
259 		(val & 0x1F) << 4 |	/* lower 5 bits to immediate data */
260 		(val & ~0x1F) << (18 - 5);/* higher 3 bits to CoProc instr. */
261 	return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
262 }
263 
264 static int __must_check npe_logical_reg_write16(struct npe *npe, u32 addr,
265 						u16 val, u32 ctx)
266 {
267 	/* here we build the NPE assembler instruction: mov16 d0, #0 */
268 	u32 instr = INSTR_WR_REG_SHORT | /* OpCode */
269 		addr << 9 |		/* base Operand */
270 		(val & 0x1F) << 4 |	/* lower 5 bits to immediate data */
271 		(val & ~0x1F) << (18 - 5);/* higher 11 bits to CoProc instr. */
272 	return npe_debug_instr(npe, instr, ctx, 1); /* execute it */
273 }
274 
275 static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr,
276 						u32 val, u32 ctx)
277 {
278 	/* write in 16 bit steps first the high and then the low value */
279 	if (npe_logical_reg_write16(npe, addr, val >> 16, ctx))
280 		return -ETIMEDOUT;
281 	return npe_logical_reg_write16(npe, addr + 2, val & 0xFFFF, ctx);
282 }
283 
284 static int npe_reset(struct npe *npe)
285 {
286 	u32 val, ctl, exec_count, ctx_reg2;
287 	int i;
288 
289 	ctl = (__raw_readl(&npe->regs->messaging_control) | 0x3F000000) &
290 		0x3F3FFFFF;
291 
292 	/* disable parity interrupt */
293 	__raw_writel(ctl & 0x3F00FFFF, &npe->regs->messaging_control);
294 
295 	/* pre exec - debug instruction */
296 	/* turn off the halt bit by clearing Execution Count register. */
297 	exec_count = __raw_readl(&npe->regs->exec_count);
298 	__raw_writel(0, &npe->regs->exec_count);
299 	/* ensure that IF and IE are on (temporarily), so that we don't end up
300 	   stepping forever */
301 	ctx_reg2 = npe_cmd_read(npe, ECS_DBG_CTXT_REG_2, CMD_RD_ECS_REG);
302 	npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2 |
303 		      ECS_DBG_REG_2_IF | ECS_DBG_REG_2_IE);
304 
305 	/* clear the FIFOs */
306 	while (__raw_readl(&npe->regs->watchpoint_fifo) & WFIFO_VALID)
307 		;
308 	while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE)
309 		/* read from the outFIFO until empty */
310 		print_npe(KERN_DEBUG, npe, "npe_reset: read FIFO = 0x%X\n",
311 			  __raw_readl(&npe->regs->in_out_fifo));
312 
313 	while (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)
314 		/* step execution of the NPE intruction to read inFIFO using
315 		   the Debug Executing Context stack */
316 		if (npe_debug_instr(npe, INSTR_RD_FIFO, 0, 0))
317 			return -ETIMEDOUT;
318 
319 	/* reset the mailbox reg from the XScale side */
320 	__raw_writel(RESET_MBOX_STAT, &npe->regs->mailbox_status);
321 	/* from NPE side */
322 	if (npe_debug_instr(npe, INSTR_RESET_MBOX, 0, 0))
323 		return -ETIMEDOUT;
324 
325 	/* Reset the physical registers in the NPE register file */
326 	for (val = 0; val < NPE_PHYS_REG; val++) {
327 		if (npe_logical_reg_write16(npe, NPE_REGMAP, val >> 1, 0))
328 			return -ETIMEDOUT;
329 		/* address is either 0 or 4 */
330 		if (npe_logical_reg_write32(npe, (val & 1) * 4, 0, 0))
331 			return -ETIMEDOUT;
332 	}
333 
334 	/* Reset the context store = each context's Context Store registers */
335 
336 	/* Context 0 has no STARTPC. Instead, this value is used to set NextPC
337 	   for Background ECS, to set where NPE starts executing code */
338 	val = npe_cmd_read(npe, ECS_BG_CTXT_REG_0, CMD_RD_ECS_REG);
339 	val &= ~ECS_REG_0_NEXTPC_MASK;
340 	val |= (0 /* NextPC */ << 16) & ECS_REG_0_NEXTPC_MASK;
341 	npe_cmd_write(npe, ECS_BG_CTXT_REG_0, CMD_WR_ECS_REG, val);
342 
343 	for (i = 0; i < 16; i++) {
344 		if (i) {	/* Context 0 has no STEVT nor STARTPC */
345 			/* STEVT = off, 0x80 */
346 			if (npe_logical_reg_write8(npe, NPE_STEVT, 0x80, i))
347 				return -ETIMEDOUT;
348 			if (npe_logical_reg_write16(npe, NPE_STARTPC, 0, i))
349 				return -ETIMEDOUT;
350 		}
351 		/* REGMAP = d0->p0, d8->p2, d16->p4 */
352 		if (npe_logical_reg_write16(npe, NPE_REGMAP, 0x820, i))
353 			return -ETIMEDOUT;
354 		if (npe_logical_reg_write8(npe, NPE_CINDEX, 0, i))
355 			return -ETIMEDOUT;
356 	}
357 
358 	/* post exec */
359 	/* clear active bit in debug level */
360 	npe_cmd_write(npe, ECS_DBG_CTXT_REG_0, CMD_WR_ECS_REG, 0);
361 	/* clear the pipeline */
362 	__raw_writel(CMD_NPE_CLR_PIPE, &npe->regs->exec_status_cmd);
363 	/* restore previous values */
364 	__raw_writel(exec_count, &npe->regs->exec_count);
365 	npe_cmd_write(npe, ECS_DBG_CTXT_REG_2, CMD_WR_ECS_REG, ctx_reg2);
366 
367 	/* write reset values to Execution Context Stack registers */
368 	for (val = 0; val < ARRAY_SIZE(ecs_reset); val++)
369 		npe_cmd_write(npe, ecs_reset[val].reg, CMD_WR_ECS_REG,
370 			      ecs_reset[val].val);
371 
372 	/* clear the profile counter */
373 	__raw_writel(CMD_CLR_PROFILE_CNT, &npe->regs->exec_status_cmd);
374 
375 	__raw_writel(0, &npe->regs->exec_count);
376 	__raw_writel(0, &npe->regs->action_points[0]);
377 	__raw_writel(0, &npe->regs->action_points[1]);
378 	__raw_writel(0, &npe->regs->action_points[2]);
379 	__raw_writel(0, &npe->regs->action_points[3]);
380 	__raw_writel(0, &npe->regs->watch_count);
381 
382 	val = ixp4xx_read_feature_bits();
383 	/* reset the NPE */
384 	ixp4xx_write_feature_bits(val &
385 				  ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
386 	/* deassert reset */
387 	ixp4xx_write_feature_bits(val |
388 				  (IXP4XX_FEATURE_RESET_NPEA << npe->id));
389 	for (i = 0; i < MAX_RETRIES; i++) {
390 		if (ixp4xx_read_feature_bits() &
391 		    (IXP4XX_FEATURE_RESET_NPEA << npe->id))
392 			break;	/* NPE is back alive */
393 		udelay(1);
394 	}
395 	if (i == MAX_RETRIES)
396 		return -ETIMEDOUT;
397 
398 	npe_stop(npe);
399 
400 	/* restore NPE configuration bus Control Register - parity settings */
401 	__raw_writel(ctl, &npe->regs->messaging_control);
402 	return 0;
403 }
404 
405 
406 int npe_send_message(struct npe *npe, const void *msg, const char *what)
407 {
408 	const u32 *send = msg;
409 	int cycles = 0;
410 
411 	debug_msg(npe, "Trying to send message %s [%08X:%08X]\n",
412 		  what, send[0], send[1]);
413 
414 	if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE) {
415 		debug_msg(npe, "NPE input FIFO not empty\n");
416 		return -EIO;
417 	}
418 
419 	__raw_writel(send[0], &npe->regs->in_out_fifo);
420 
421 	if (!(__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNF)) {
422 		debug_msg(npe, "NPE input FIFO full\n");
423 		return -EIO;
424 	}
425 
426 	__raw_writel(send[1], &npe->regs->in_out_fifo);
427 
428 	while ((cycles < MAX_RETRIES) &&
429 	       (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_IFNE)) {
430 		udelay(1);
431 		cycles++;
432 	}
433 
434 	if (cycles == MAX_RETRIES) {
435 		debug_msg(npe, "Timeout sending message\n");
436 		return -ETIMEDOUT;
437 	}
438 
439 #if DEBUG_MSG > 1
440 	debug_msg(npe, "Sending a message took %i cycles\n", cycles);
441 #endif
442 	return 0;
443 }
444 
445 int npe_recv_message(struct npe *npe, void *msg, const char *what)
446 {
447 	u32 *recv = msg;
448 	int cycles = 0, cnt = 0;
449 
450 	debug_msg(npe, "Trying to receive message %s\n", what);
451 
452 	while (cycles < MAX_RETRIES) {
453 		if (__raw_readl(&npe->regs->messaging_status) & MSGSTAT_OFNE) {
454 			recv[cnt++] = __raw_readl(&npe->regs->in_out_fifo);
455 			if (cnt == 2)
456 				break;
457 		} else {
458 			udelay(1);
459 			cycles++;
460 		}
461 	}
462 
463 	switch(cnt) {
464 	case 1:
465 		debug_msg(npe, "Received [%08X]\n", recv[0]);
466 		break;
467 	case 2:
468 		debug_msg(npe, "Received [%08X:%08X]\n", recv[0], recv[1]);
469 		break;
470 	}
471 
472 	if (cycles == MAX_RETRIES) {
473 		debug_msg(npe, "Timeout waiting for message\n");
474 		return -ETIMEDOUT;
475 	}
476 
477 #if DEBUG_MSG > 1
478 	debug_msg(npe, "Receiving a message took %i cycles\n", cycles);
479 #endif
480 	return 0;
481 }
482 
483 int npe_send_recv_message(struct npe *npe, void *msg, const char *what)
484 {
485 	int result;
486 	u32 *send = msg, recv[2];
487 
488 	if ((result = npe_send_message(npe, msg, what)) != 0)
489 		return result;
490 	if ((result = npe_recv_message(npe, recv, what)) != 0)
491 		return result;
492 
493 	if ((recv[0] != send[0]) || (recv[1] != send[1])) {
494 		debug_msg(npe, "Message %s: unexpected message received\n",
495 			  what);
496 		return -EIO;
497 	}
498 	return 0;
499 }
500 
501 
502 int npe_load_firmware(struct npe *npe, const char *name, struct device *dev)
503 {
504 	const struct firmware *fw_entry;
505 
506 	struct dl_block {
507 		u32 type;
508 		u32 offset;
509 	} *blk;
510 
511 	struct dl_image {
512 		u32 magic;
513 		u32 id;
514 		u32 size;
515 		union {
516 			u32 data[0];
517 			struct dl_block blocks[0];
518 		};
519 	} *image;
520 
521 	struct dl_codeblock {
522 		u32 npe_addr;
523 		u32 size;
524 		u32 data[0];
525 	} *cb;
526 
527 	int i, j, err, data_size, instr_size, blocks, table_end;
528 	u32 cmd;
529 
530 	if ((err = request_firmware(&fw_entry, name, dev)) != 0)
531 		return err;
532 
533 	err = -EINVAL;
534 	if (fw_entry->size < sizeof(struct dl_image)) {
535 		print_npe(KERN_ERR, npe, "incomplete firmware file\n");
536 		goto err;
537 	}
538 	image = (struct dl_image*)fw_entry->data;
539 
540 #if DEBUG_FW
541 	print_npe(KERN_DEBUG, npe, "firmware: %08X %08X %08X (0x%X bytes)\n",
542 		  image->magic, image->id, image->size, image->size * 4);
543 #endif
544 
545 	if (image->magic == swab32(FW_MAGIC)) { /* swapped file */
546 		image->id = swab32(image->id);
547 		image->size = swab32(image->size);
548 	} else if (image->magic != FW_MAGIC) {
549 		print_npe(KERN_ERR, npe, "bad firmware file magic: 0x%X\n",
550 			  image->magic);
551 		goto err;
552 	}
553 	if ((image->size * 4 + sizeof(struct dl_image)) != fw_entry->size) {
554 		print_npe(KERN_ERR, npe,
555 			  "inconsistent size of firmware file\n");
556 		goto err;
557 	}
558 	if (((image->id >> 24) & 0xF /* NPE ID */) != npe->id) {
559 		print_npe(KERN_ERR, npe, "firmware file NPE ID mismatch\n");
560 		goto err;
561 	}
562 	if (image->magic == swab32(FW_MAGIC))
563 		for (i = 0; i < image->size; i++)
564 			image->data[i] = swab32(image->data[i]);
565 
566 	if (cpu_is_ixp42x() && ((image->id >> 28) & 0xF /* device ID */)) {
567 		print_npe(KERN_INFO, npe, "IXP43x/IXP46x firmware ignored on "
568 			  "IXP42x\n");
569 		goto err;
570 	}
571 
572 	if (npe_running(npe)) {
573 		print_npe(KERN_INFO, npe, "unable to load firmware, NPE is "
574 			  "already running\n");
575 		err = -EBUSY;
576 		goto err;
577 	}
578 #if 0
579 	npe_stop(npe);
580 	npe_reset(npe);
581 #endif
582 
583 	print_npe(KERN_INFO, npe, "firmware functionality 0x%X, "
584 		  "revision 0x%X:%X\n", (image->id >> 16) & 0xFF,
585 		  (image->id >> 8) & 0xFF, image->id & 0xFF);
586 
587 	if (cpu_is_ixp42x()) {
588 		if (!npe->id)
589 			instr_size = NPE_A_42X_INSTR_SIZE;
590 		else
591 			instr_size = NPE_B_AND_C_42X_INSTR_SIZE;
592 		data_size = NPE_42X_DATA_SIZE;
593 	} else {
594 		instr_size = NPE_46X_INSTR_SIZE;
595 		data_size = NPE_46X_DATA_SIZE;
596 	}
597 
598 	for (blocks = 0; blocks * sizeof(struct dl_block) / 4 < image->size;
599 	     blocks++)
600 		if (image->blocks[blocks].type == FW_BLOCK_TYPE_EOF)
601 			break;
602 	if (blocks * sizeof(struct dl_block) / 4 >= image->size) {
603 		print_npe(KERN_INFO, npe, "firmware EOF block marker not "
604 			  "found\n");
605 		goto err;
606 	}
607 
608 #if DEBUG_FW
609 	print_npe(KERN_DEBUG, npe, "%i firmware blocks found\n", blocks);
610 #endif
611 
612 	table_end = blocks * sizeof(struct dl_block) / 4 + 1 /* EOF marker */;
613 	for (i = 0, blk = image->blocks; i < blocks; i++, blk++) {
614 		if (blk->offset > image->size - sizeof(struct dl_codeblock) / 4
615 		    || blk->offset < table_end) {
616 			print_npe(KERN_INFO, npe, "invalid offset 0x%X of "
617 				  "firmware block #%i\n", blk->offset, i);
618 			goto err;
619 		}
620 
621 		cb = (struct dl_codeblock*)&image->data[blk->offset];
622 		if (blk->type == FW_BLOCK_TYPE_INSTR) {
623 			if (cb->npe_addr + cb->size > instr_size)
624 				goto too_big;
625 			cmd = CMD_WR_INS_MEM;
626 		} else if (blk->type == FW_BLOCK_TYPE_DATA) {
627 			if (cb->npe_addr + cb->size > data_size)
628 				goto too_big;
629 			cmd = CMD_WR_DATA_MEM;
630 		} else {
631 			print_npe(KERN_INFO, npe, "invalid firmware block #%i "
632 				  "type 0x%X\n", i, blk->type);
633 			goto err;
634 		}
635 		if (blk->offset + sizeof(*cb) / 4 + cb->size > image->size) {
636 			print_npe(KERN_INFO, npe, "firmware block #%i doesn't "
637 				  "fit in firmware image: type %c, start 0x%X,"
638 				  " length 0x%X\n", i,
639 				  blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
640 				  cb->npe_addr, cb->size);
641 			goto err;
642 		}
643 
644 		for (j = 0; j < cb->size; j++)
645 			npe_cmd_write(npe, cb->npe_addr + j, cmd, cb->data[j]);
646 	}
647 
648 	npe_start(npe);
649 	if (!npe_running(npe))
650 		print_npe(KERN_ERR, npe, "unable to start\n");
651 	release_firmware(fw_entry);
652 	return 0;
653 
654 too_big:
655 	print_npe(KERN_INFO, npe, "firmware block #%i doesn't fit in NPE "
656 		  "memory: type %c, start 0x%X, length 0x%X\n", i,
657 		  blk->type == FW_BLOCK_TYPE_INSTR ? 'I' : 'D',
658 		  cb->npe_addr, cb->size);
659 err:
660 	release_firmware(fw_entry);
661 	return err;
662 }
663 
664 
665 struct npe *npe_request(unsigned id)
666 {
667 	if (id < NPE_COUNT)
668 		if (npe_tab[id].valid)
669 			if (try_module_get(THIS_MODULE))
670 				return &npe_tab[id];
671 	return NULL;
672 }
673 
674 void npe_release(struct npe *npe)
675 {
676 	module_put(THIS_MODULE);
677 }
678 
679 static int ixp4xx_npe_probe(struct platform_device *pdev)
680 {
681 	int i, found = 0;
682 	struct device *dev = &pdev->dev;
683 	struct device_node *np = dev->of_node;
684 	struct resource *res;
685 
686 	for (i = 0; i < NPE_COUNT; i++) {
687 		struct npe *npe = &npe_tab[i];
688 
689 		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
690 		if (!res)
691 			return -ENODEV;
692 
693 		if (!(ixp4xx_read_feature_bits() &
694 		      (IXP4XX_FEATURE_RESET_NPEA << i))) {
695 			dev_info(dev, "NPE%d at 0x%08x-0x%08x not available\n",
696 				 i, res->start, res->end);
697 			continue; /* NPE already disabled or not present */
698 		}
699 		npe->regs = devm_ioremap_resource(dev, res);
700 		if (IS_ERR(npe->regs))
701 			return PTR_ERR(npe->regs);
702 
703 		if (npe_reset(npe)) {
704 			dev_info(dev, "NPE%d at 0x%08x-0x%08x does not reset\n",
705 				 i, res->start, res->end);
706 			continue;
707 		}
708 		npe->valid = 1;
709 		dev_info(dev, "NPE%d at 0x%08x-0x%08x registered\n",
710 			 i, res->start, res->end);
711 		found++;
712 	}
713 
714 	if (!found)
715 		return -ENODEV;
716 
717 	/* Spawn crypto subdevice if using device tree */
718 	if (IS_ENABLED(CONFIG_OF) && np)
719 		devm_of_platform_populate(dev);
720 
721 	return 0;
722 }
723 
724 static int ixp4xx_npe_remove(struct platform_device *pdev)
725 {
726 	int i;
727 
728 	for (i = 0; i < NPE_COUNT; i++)
729 		if (npe_tab[i].regs) {
730 			npe_reset(&npe_tab[i]);
731 		}
732 
733 	return 0;
734 }
735 
736 static const struct of_device_id ixp4xx_npe_of_match[] = {
737 	{
738 		.compatible = "intel,ixp4xx-network-processing-engine",
739         },
740 	{},
741 };
742 
743 static struct platform_driver ixp4xx_npe_driver = {
744 	.driver = {
745 		.name           = "ixp4xx-npe",
746 		.of_match_table = of_match_ptr(ixp4xx_npe_of_match),
747 	},
748 	.probe = ixp4xx_npe_probe,
749 	.remove = ixp4xx_npe_remove,
750 };
751 module_platform_driver(ixp4xx_npe_driver);
752 
753 MODULE_AUTHOR("Krzysztof Halasa");
754 MODULE_LICENSE("GPL v2");
755 MODULE_FIRMWARE(NPE_A_FIRMWARE);
756 MODULE_FIRMWARE(NPE_B_FIRMWARE);
757 MODULE_FIRMWARE(NPE_C_FIRMWARE);
758 
759 EXPORT_SYMBOL(npe_names);
760 EXPORT_SYMBOL(npe_running);
761 EXPORT_SYMBOL(npe_request);
762 EXPORT_SYMBOL(npe_release);
763 EXPORT_SYMBOL(npe_load_firmware);
764 EXPORT_SYMBOL(npe_send_message);
765 EXPORT_SYMBOL(npe_recv_message);
766 EXPORT_SYMBOL(npe_send_recv_message);
767