BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src-rt / cfe / cfe / dev / dev_bcm5821.c
blob6f712d2569298c814d58bba6a5169ee6f50c473e
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * BC5821 crypto accelerator driver File: dev_bcm5821.c
5 *
6 *********************************************************************
8 * Copyright 2000,2001,2002,2003
9 * Broadcom Corporation. All rights reserved.
11 * This software is furnished under license and may be used and
12 * copied only in accordance with the following terms and
13 * conditions. Subject to these conditions, you may download,
14 * copy, install, use, modify and distribute modified or unmodified
15 * copies of this software in source and/or binary form. No title
16 * or ownership is transferred hereby.
18 * 1) Any source code used, modified or distributed must reproduce
19 * and retain this copyright notice and list of conditions
20 * as they appear in the source file.
22 * 2) No right is granted to use any trade name, trademark, or
23 * logo of Broadcom Corporation. The "Broadcom Corporation"
24 * name may not be used to endorse or promote products derived
25 * from this software without the prior written permission of
26 * Broadcom Corporation.
28 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
30 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
31 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
32 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
33 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
36 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
38 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
40 * THE POSSIBILITY OF SUCH DAMAGE.
41 ********************************************************************* */
44 CFE Driver plus test programs for the BCM5820 and BCM5821 crypto
45 coprocessor chips.
46 Reference:
47 BCM5821 Super-eCommerce Processor
48 Data Sheet 5821-DS105-D1 (draft, 7/26/02)
49 Broadcom Corp., 16215 Alton Parkway, Irvine, CA.
52 /* The performance counter usage assumes a BCM11xx or BCM1250 part */
54 #include "sbmips.h"
56 #if !defined(_SB14XX_) && !defined(_RM5200_) && !defined(_RM7000_)
57 #define _SB1250_PERF_ 1
58 #else
59 #define _SB1250_PERF_ 0
60 #endif
62 #if _SB1250_PERF_
63 #include "sb1250_defs.h"
64 #include "sb1250_regs.h"
65 #endif
67 #ifndef _SB_MAKE64
68 #define _SB_MAKE64(x) ((uint64_t)(x))
69 #endif
70 #ifndef _SB_MAKEMASK1
71 #define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n))
72 #endif
74 #include "lib_types.h"
75 #include "lib_physio.h"
76 #include "lib_malloc.h"
77 #include "lib_string.h"
78 #include "lib_printf.h"
79 #include "lib_queue.h"
81 #include "addrspace.h"
83 #include "cfe_iocb.h"
84 #include "cfe_device.h"
85 #include "cfe_timer.h"
86 #include "cfe_devfuncs.h"
87 #include "cfe_irq.h"
89 #include "pcivar.h"
90 #include "pcireg.h"
92 #include "bcm5821.h"
94 /* The version that works by polling the CPU's Cause register doesn't
95 do handshakes or checks to detect merged interrupts. It currently
96 works when the 5821 is on the direct PCI bus but can behave
97 erratically when the 5821 is behind an LDT-to-PCI bridge that does
98 interrupt mapping and relies on EOI. */
100 extern int32_t _getcause(void); /* return value of CP0 CAUSE */
102 #define IMR_POINTER(cpu,reg) \
103 ((volatile uint64_t *)(PHYS_TO_K1(A_IMR_REGISTER(cpu,reg))))
105 #define CACHE_LINE_SIZE 32
107 static void bcm5821_probe(cfe_driver_t *drv,
108 unsigned long probe_a, unsigned long probe_b,
109 void *probe_ptr);
111 typedef struct bcm5821_state_s {
112 uint32_t regbase;
113 uint8_t irq;
114 pcitag_t tag; /* tag for configuration registers */
116 uint16_t device; /* chip device code */
117 uint8_t revision; /* chip revision */
119 } bcm5821_state_t;
122 /* Address mapping macros */
124 /* Note that PTR_TO_PHYS only works with 32-bit addresses, but then
125 so does the bcm528x. */
126 #define PTR_TO_PHYS(x) (K0_TO_PHYS((uintptr_t)(x)))
127 #define PHYS_TO_PTR(a) ((void *)PHYS_TO_K0(a))
129 /* For the 5821, all mappings through the PCI host bridge use match
130 bits mode. This works because the NORM_PCI bit in DMA Control is
131 clear. The 5820 does not have such a bit, so pointers to data byte
132 sequences use match bytes, but control blocks use match bits. */
133 #define PHYS_TO_PCI(a) ((uint32_t) (a) | 0x20000000)
134 #define PHYS_TO_PCI_D(a) (a)
135 #define PCI_TO_PHYS(a) ((uint32_t) (a) & 0x1FFFFFFF)
137 #define READCSR(sc,csr) (phys_read32((sc)->regbase + (csr)))
138 #define WRITECSR(sc,csr,val) (phys_write32((sc)->regbase + (csr), (val)))
141 static void
142 dumpcsrs(bcm5821_state_t *sc, const char *legend)
144 xprintf("%s:\n", legend);
145 xprintf("---DMA---\n");
146 /* DMA control and status registers */
147 xprintf("MCR1: %08X CTRL: %08X STAT: %08X ERR: %08X\n",
148 READCSR(sc, R_MCR1), READCSR(sc, R_DMA_CTRL),
149 READCSR(sc, R_DMA_STAT), READCSR(sc, R_DMA_ERR));
150 xprintf("MCR2: %08X\n", READCSR(sc, R_MCR2));
151 xprintf("-------------\n");
155 static void
156 bcm5821_init(bcm5821_state_t *sc)
160 static void
161 bcm5821_hwinit(bcm5821_state_t *sc)
163 uint32_t ctrl;
164 uint32_t status;
166 ctrl = (M_DMA_CTRL_MCR1_INT_EN | M_DMA_CTRL_MCR2_INT_EN |
167 M_DMA_CTRL_DMAERR_EN);
168 if (sc->device == K_PCI_ID_BCM5820)
169 ctrl |= (M_DMA_CTRL_NORM_PCI | M_DMA_CTRL_LE_CRYPTO);
170 /* Note for 5821: M_DMA_CTRL_NORM_PCI, M_DMA_CTRL_LE_CRYPTO not set. */
171 WRITECSR(sc, R_DMA_CTRL, ctrl);
173 status = READCSR(sc, R_DMA_STAT);
174 WRITECSR(sc, R_DMA_STAT, status); /* reset write-to-clear bits */
175 status = READCSR(sc, R_DMA_STAT);
177 dumpcsrs(sc, "init");
181 static void
182 bcm5821_start(bcm5821_state_t *sc)
184 bcm5821_hwinit(sc);
187 static void
188 bcm5821_stop(bcm5821_state_t *sc)
190 WRITECSR(sc, R_DMA_CTRL, 0);
194 static int bcm5821_open(cfe_devctx_t *ctx);
195 static int bcm5821_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
196 static int bcm5821_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);
197 static int bcm5821_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
198 static int bcm5821_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
199 static int bcm5821_close(cfe_devctx_t *ctx);
201 const static cfe_devdisp_t bcm5821_dispatch = {
202 bcm5821_open,
203 bcm5821_read,
204 bcm5821_inpstat,
205 bcm5821_write,
206 bcm5821_ioctl,
207 bcm5821_close,
208 NULL,
209 NULL
212 cfe_driver_t bcm5821drv = {
213 "BCM582x crypto",
214 "crypt",
215 CFE_DEV_OTHER,
216 &bcm5821_dispatch,
217 bcm5821_probe
221 static int
222 bcm5821_attach(cfe_driver_t *drv, pcitag_t tag, int index)
224 bcm5821_state_t *sc;
225 char descr[80];
226 phys_addr_t pa;
227 uint32_t base;
228 pcireg_t device, class;
230 pci_map_mem(tag, PCI_MAPREG(0), PCI_MATCH_BITS, &pa);
231 base = (uint32_t)pa;
233 sc = (bcm5821_state_t *) KMALLOC(sizeof(bcm5821_state_t),0);
234 if (sc == NULL) {
235 xprintf("BCM5821: No memory to complete probe\n");
236 return 0;
239 memset(sc, 0, sizeof(*sc));
241 sc->regbase = base;
243 sc->irq = pci_conf_read(tag, PCI_BPARAM_INTERRUPT_REG) & 0xFF;
245 device = pci_conf_read(tag, PCI_ID_REG);
246 class = pci_conf_read(tag, PCI_CLASS_REG);
248 sc->tag = tag;
249 sc->device = PCI_PRODUCT(device);
250 sc->revision = PCI_REVISION(class);
252 bcm5821_init(sc);
254 xsprintf(descr, "BCM%04X Crypto at 0x%08X", sc->device, base);
255 cfe_attach(drv, sc, NULL, descr);
257 return 1;
260 static void
261 bcm5821_probe(cfe_driver_t *drv,
262 unsigned long probe_a, unsigned long probe_b,
263 void *probe_ptr)
265 int index;
266 int n;
268 n = 0;
269 index = 0;
270 for (;;) {
271 pcitag_t tag;
272 pcireg_t device;
274 if (pci_find_class(PCI_CLASS_PROCESSOR, index, &tag) != 0)
275 break;
277 index++;
279 device = pci_conf_read(tag, PCI_ID_REG);
280 if (PCI_VENDOR(device) == K_PCI_VENDOR_BROADCOM) {
281 if (PCI_PRODUCT(device) == K_PCI_ID_BCM5820 ||
282 PCI_PRODUCT(device) == K_PCI_ID_BCM5821) {
283 bcm5821_attach(drv, tag, n);
284 n++;
291 /* The functions below are called via the dispatch vector for the 5821 */
293 static int
294 bcm5821_open(cfe_devctx_t *ctx)
296 bcm5821_state_t *sc = ctx->dev_softc;
298 bcm5821_start(sc);
299 return 0;
302 static int
303 bcm5821_read(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
305 return -1;
308 static int
309 bcm5821_inpstat(cfe_devctx_t *ctx, iocb_inpstat_t *inpstat)
311 return 0;
314 static int
315 bcm5821_write(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
317 return -1;
320 static int
321 bcm5821_ioctl(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
323 return -1;
326 static int
327 bcm5821_close(cfe_devctx_t *ctx)
329 bcm5821_state_t *sc = ctx->dev_softc;
331 bcm5821_stop(sc);
332 return 0;
336 /* Additional hooks for testing. */
338 static int
339 bcm5821_dump_cc1 (uint32_t *cc)
341 int i;
342 unsigned op = G_CC_OPCODE(cc[0]);
343 unsigned cc_words = G_CC_LEN(cc[0])/4;
344 int chain_out; /* Whether the output is chained or fixed */
346 chain_out = 1; /* default */
348 switch (op) {
350 case K_SSL_MAC:
351 xprintf("(SSL_MAC)\n");
352 for (i = 0; i < SSL_MAC_CMD_WORDS; i++)
353 xprintf(" %2d: %08x\n", i, cc[i]);
354 chain_out = 0;
355 break;
357 case K_ARC4:
358 xprintf("(ARCFOUR)\n");
359 for (i = 0; i < 3; i++)
360 xprintf(" %2d: %08x\n", i, cc[i]);
361 for (i = 0; i < 256/4; i += 4)
362 xprintf(" %2d: %08x %08x %08x %08x\n",
363 i+3, cc[i+3], cc[i+4], cc[i+5], cc[i+6]);
364 break;
366 case K_HASH:
367 xprintf("(HASH)\n");
368 for (i = 0; i < 2; i++)
369 xprintf(" %2d: %08x\n", i, cc[i]);
370 chain_out = 0;
371 break;
373 case K_TLS_HMAC:
374 chain_out = 0;
375 /* fall through */
377 default: /* NYI: K_IPSEC_3DES (5821 only), K_SSL_3DES */
378 xprintf("\n");
379 for (i = 0; i < cc_words; i++)
380 xprintf(" %2d: %08x\n", i, cc[i]);
381 break;
384 return chain_out;
387 static int
388 bcm5821_dump_cc2 (uint32_t *cc)
390 int i;
391 unsigned op = G_CC_OPCODE(cc[0]);
392 unsigned cc_words = G_CC_LEN(cc[0])/4;
393 int chain_out; /* Whether the output is chained or fixed */
395 chain_out = 1; /* default */
397 switch (op) {
399 case K_RNG_DIRECT:
400 xprintf(" RNG_DIRECT\n");
401 chain_out = 0;
402 for (i = 0; i < 1; i++)
403 xprintf(" %2d: %08x\n", i, cc[i]);
404 break;
406 case K_RNG_SHA1:
407 xprintf(" RNG_SHA1\n");
408 chain_out = 0;
409 for (i = 0; i < 1; i++)
410 xprintf(" %2d: %08x\n", i, cc[i]);
411 break;
413 default: /* NYI: K_DH_*_GEN, K_RSA_*_OP, K_DSA_*, K_MOD_* */
414 xprintf(" %04x\n", op);
415 for (i = 0; i < cc_words; i++)
416 xprintf(" %2d: %08x\n", i, cc[i]);
417 break;
419 return chain_out;
422 static void
423 bcm5821_dump_pkt (uint32_t *pkt, int port)
425 uint32_t *cc = PHYS_TO_PTR(PCI_TO_PHYS(pkt[0]));
426 uint32_t *chain;
427 int chain_out;
428 int i, j;
430 xprintf(" %2d: %08x ", 0, pkt[0]);
431 chain_out = (port == 1 ? bcm5821_dump_cc1 : bcm5821_dump_cc2)(cc);
433 for (i = 1; i < PD_SIZE/4; i++) {
434 xprintf(" %2d: %08x\n", i, pkt[i]);
436 if (pkt[i] != 0) {
437 switch (i) {
438 case 2:
439 chain = PHYS_TO_PTR(PCI_TO_PHYS(pkt[i]));
440 for (j = 0; j < CHAIN_WORDS; j++)
441 xprintf(" %2d: %08x\n", j, chain[j]);
442 break;
443 case 6:
444 if (chain_out) {
445 chain = PHYS_TO_PTR(PCI_TO_PHYS(pkt[i]));
446 for (j = 0; j < CHAIN_WORDS; j++)
447 xprintf(" %2d: %08x\n", j, chain[j]);
449 break;
450 default:
451 break;
457 static void
458 bcm5821_dump_mcr (uint32_t mcr[], int port)
460 unsigned i;
461 unsigned npkts = G_MCR_NUM_PACKETS(mcr[0]);
463 xprintf("MCR header %08x at %p:\n", mcr[0], mcr);
464 for (i = 0; i < npkts; i++) {
465 xprintf(" packet %d:\n", i+1);
466 bcm5821_dump_pkt(&mcr[1 + i*(PD_SIZE/4)], port);
471 static void
472 bcm5821_show_pkt1 (uint32_t *pkt)
474 uint32_t *cc = PHYS_TO_PTR(PCI_TO_PHYS(pkt[0]));
475 unsigned op = G_CC_OPCODE(cc[0]);
476 int i;
478 switch (op) {
479 case K_SSL_MAC:
481 uint32_t *hash = PHYS_TO_PTR(PCI_TO_PHYS(pkt[6]));
482 xprintf("SSL_MAC hash:\n");
483 xprintf(" %08x %08x %08x %08x\n",
484 hash[0], hash[1], hash[2], hash[3]);
485 xprintf(" %08x\n", hash[4]);
487 break;
488 case K_TLS_HMAC:
490 uint32_t *hash = PHYS_TO_PTR(PCI_TO_PHYS(pkt[7]));
491 xprintf("TLS_HMAC hash:\n");
492 xprintf(" %08x %08x %08x %08x\n",
493 hash[0], hash[1], hash[2], hash[3]);
494 xprintf(" %08x\n", hash[4]);
496 break;
497 case K_ARC4:
499 uint32_t *output = PHYS_TO_PTR(PCI_TO_PHYS(pkt[5]));
500 uint32_t *chain = PHYS_TO_PTR(PCI_TO_PHYS(pkt[6]));
501 uint32_t *update = PHYS_TO_PTR(PCI_TO_PHYS(chain[0]));
503 xprintf("ARCFOUR output\n");
504 for (i = 0; i < 64; i += 4)
505 xprintf (" %08x %08x %08x %08x\n",
506 output[i+0], output[i+1], output[i+2], output[i+3]);
507 xprintf("ARCFOUR update\n");
508 xprintf(" %08x\n", update[0]);
509 for (i = 0; i < 256/4; i += 4)
510 xprintf (" %08x %08x %08x %08x\n",
511 update[i+1], update[i+2], update[i+3], update[i+4]);
513 break;
514 case K_HASH:
516 uint8_t *digest = PHYS_TO_PTR(PCI_TO_PHYS(pkt[6]));
518 xprintf("HASH digest ");
519 for (i = 0; i < 16; i++)
520 xprintf("%02x", digest[i]);
521 xprintf("\n");
523 break;
524 default:
525 break;
529 static void
530 bcm5821_show_pkt2 (uint32_t *pkt)
532 uint32_t *cc = PHYS_TO_PTR(PCI_TO_PHYS(pkt[0]));
533 unsigned op = G_CC_OPCODE(cc[0]);
534 int i;
536 switch (op) {
537 case K_RNG_DIRECT:
538 case K_RNG_SHA1:
540 uint32_t *output = PHYS_TO_PTR(PCI_TO_PHYS(pkt[5]));
541 size_t len = V_DBC_DATA_LEN(pkt[7])/sizeof(uint32_t);
543 xprintf("RNG output\n");
544 for (i = 0; i < len; i += 4)
545 xprintf (" %08x %08x %08x %08x\n",
546 output[i+0], output[i+1], output[i+2], output[i+3]);
548 break;
549 default:
550 break;
554 static void
555 bcm5821_show_mcr (uint32_t mcr[], int port)
557 unsigned i;
558 unsigned npkts = G_MCR_NUM_PACKETS(mcr[0]);
560 xprintf("MCR at %p:\n", mcr);
561 for (i = 0; i < npkts; i++) {
562 xprintf("packet %d:\n", i+1);
563 if (port == 1)
564 bcm5821_show_pkt1(&mcr[1 + i*(PD_SIZE/4)]);
565 else
566 bcm5821_show_pkt2(&mcr[1 + i*(PD_SIZE/4)]);
571 static uint32_t *
572 bcm5821_alloc_hash (const uint8_t *msg, size_t msg_len, int swap)
574 uint32_t *mcr;
575 uint32_t *cmd; /* always reads at least 64 bytes */
576 uint8_t *message;
577 uint8_t *digest;
578 int i;
580 message = KMALLOC(msg_len, CACHE_LINE_SIZE);
581 for (i = 0; i < msg_len; i++)
582 message[i] = msg[i];
584 digest = KMALLOC(16, CACHE_LINE_SIZE);
585 for (i = 0; i < 16; i++)
586 digest[i] = 0;
588 mcr = KMALLOC(MCR_WORDS(1)*4, CACHE_LINE_SIZE);
589 mcr[0] = V_MCR_NUM_PACKETS(1);
591 cmd = KMALLOC(64, CACHE_LINE_SIZE); /* Always allocate >= 64 bytes */
592 cmd[0] = V_CC_OPCODE(K_HASH) | V_CC_LEN(8);
593 cmd[1] = V_CC_FLAGS(K_HASH_FLAGS_MD5);
595 mcr[1] = PHYS_TO_PCI(PTR_TO_PHYS(cmd));
597 /* input fragment */
598 mcr[2] = swap ? PHYS_TO_PCI_D(PTR_TO_PHYS(message))
599 : PHYS_TO_PCI(PTR_TO_PHYS(message));
600 mcr[3] = 0;
601 mcr[4] = V_DBC_DATA_LEN(msg_len);
603 mcr[5] = V_PD_PKT_LEN(msg_len);
605 mcr[6] = 0;
606 mcr[7] = swap ? PHYS_TO_PCI_D(PTR_TO_PHYS(digest))
607 : PHYS_TO_PCI(PTR_TO_PHYS(digest));
608 mcr[8] = 0;
610 return mcr;
613 static void
614 bcm5821_free_hash (uint32_t mcr[])
616 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[1])));
617 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[2])));
618 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[7])));
620 KFREE(mcr);
624 static uint32_t *
625 bcm5821_alloc_hmac (const char *key, int key_len,
626 const char *msg, int msg_len,
627 int swap)
629 uint32_t *message;
630 uint32_t *cmd;
631 uint32_t *mcr;
632 uint32_t *hash;
633 int i;
635 message = KMALLOC(msg_len, CACHE_LINE_SIZE);
636 memcpy((uint8_t *)message, msg, msg_len);
638 mcr = KMALLOC(MCR_WORDS(1)*4, CACHE_LINE_SIZE);
639 mcr[0] = V_MCR_NUM_PACKETS(1);
641 /* packet 1 */
643 cmd = KMALLOC(TLS_HMAC_CMD_WORDS*4, CACHE_LINE_SIZE);
644 cmd[0] = V_CC_OPCODE(K_TLS_HMAC) | V_CC_LEN(TLS_HMAC_CMD_WORDS*4);
645 cmd[1] = V_CC_FLAGS(K_HASH_FLAGS_MD5);
647 for (i = 2; i < 7; i++)
648 cmd[i] = 0x36363636;
649 cmd[6] = 0x00000000; /* must be zero for SSL */
650 for (i = 8; i < 13; i++)
651 cmd[i] = 0x5c5c5c5c;
652 cmd[13] = 0; /* seq num */
653 cmd[14] = 1;
654 cmd[15] = 0x03000000 | (msg_len << 8);
656 mcr[1] = PHYS_TO_PCI(PTR_TO_PHYS(cmd));
658 /* input fragment */
659 mcr[2] = swap ? PHYS_TO_PCI_D(PTR_TO_PHYS(message))
660 : PHYS_TO_PCI(PTR_TO_PHYS(message));
661 mcr[3] = 0;
662 mcr[4] = V_DBC_DATA_LEN(msg_len);
664 mcr[5] = V_PD_PKT_LEN(msg_len);
666 hash = KMALLOC(5*4, CACHE_LINE_SIZE);
667 for (i = 0; i < 5; i++)
668 hash[i] = 0;
670 mcr[6] = 0;
671 mcr[7] = swap ? PHYS_TO_PCI_D(PTR_TO_PHYS(hash))
672 : PHYS_TO_PCI(PTR_TO_PHYS(hash));
673 mcr[8] = 0;
675 return mcr;
678 static void
679 bcm5821_free_hmac (uint32_t mcr[])
681 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[1])));
682 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[2])));
683 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[7])));
685 KFREE(mcr);
689 static int test_init = 0;
691 /* Timing */
693 #if _SB1250_PERF_
694 /* For Pass 1, dedicate an SCD peformance counter to use as a counter
695 of ZBbus cycles. */
696 #include "sb1250_scd.h"
697 #define ZCTR_MODULUS 0x10000000000LL
699 /* The counter is a shared resource that must be reset periodically
700 since it doesn't roll over. Furthermore, there is a pass one bug
701 that makes the interrupt unreliable and the final value either all
702 ones or all zeros. We therefore reset the count when it exceeds
703 half the modulus. We also assume that intervals of interest
704 are much less than half the modulus and attempt to adjust for
705 the reset in zclk_elapsed. */
707 static void
708 zclk_init(uint64_t val)
710 *((volatile uint64_t *) UNCADDR(A_SCD_PERF_CNT_0)) = val;
711 *((volatile uint64_t *) UNCADDR(A_SCD_PERF_CNT_CFG)) =
712 V_SPC_CFG_SRC0(1) | M_SPC_CFG_ENABLE;
715 static uint64_t
716 zclk_get(void)
718 uint64_t ticks;
720 ticks = *((volatile uint64_t *) UNCADDR(A_SCD_PERF_CNT_0));
721 if (ticks == 0 || ticks == ZCTR_MODULUS-1) {
722 ticks = 0;
723 zclk_init(ticks);
725 else if (ticks >= ZCTR_MODULUS/2) {
726 ticks -= ZCTR_MODULUS/2;
727 zclk_init(ticks); /* Ignore the fudge and lose a few ticks */
729 return ticks;
732 static uint64_t
733 zclk_elapsed(uint64_t stop, uint64_t start)
735 return ((stop >= start) ? stop : stop + ZCTR_MODULUS/2) - start;
738 #else /* !_SB1250_PERF_ */
739 static void
740 zclk_init(uint64_t val)
744 static uint64_t
745 zclk_get(void)
747 return 0;
750 static uint64_t
751 zclk_elapsed(uint64_t stop, uint64_t start)
753 return 0;
755 #endif /* _SB1250_PERF_ */
758 /* Auxiliary functions */
760 static uint32_t *
761 bcm5821_alloc_composite(int input_size)
763 uint32_t *input, *output;
764 uint32_t *cmd;
765 uint32_t *chain;
766 uint32_t *mcr;
767 uint32_t *hash;
768 uint32_t *update;
769 uint8_t *arc4_state;
770 int i;
772 input = KMALLOC(input_size, CACHE_LINE_SIZE);
773 for (i = 0; i < input_size; i++)
774 ((uint8_t *)input)[i] = i & 0xFF;
775 output = KMALLOC(input_size + 16, CACHE_LINE_SIZE);
776 for (i = 0; i < input_size + 16; i++)
777 ((uint8_t *)output)[i] = 0xFF;
779 mcr = KMALLOC(MCR_WORDS(2)*4, CACHE_LINE_SIZE);
780 mcr[0] = V_MCR_NUM_PACKETS(2);
782 /* packet 1 */
784 cmd = KMALLOC(SSL_MAC_CMD_WORDS*4, CACHE_LINE_SIZE);
785 cmd[0] = V_CC_OPCODE(K_SSL_MAC) | V_CC_LEN(SSL_MAC_CMD_WORDS*4);
786 cmd[1] = V_CC_FLAGS(K_HASH_FLAGS_MD5);
787 for (i = 2; i < 6; i++)
788 cmd[i] = 0x01020304;
789 cmd[6] = 0x00000000; /* must be zero for SSL */
790 for (i = 7; i < 19; i++)
791 cmd[i] = 0x36363636;
792 cmd[19] = 0; /* seq num */
793 cmd[20] = 1;
794 cmd[21] = 0x03000000 | (input_size << 8); /* type/len/rsvd */
796 mcr[1] = PHYS_TO_PCI(PTR_TO_PHYS(cmd));
798 /* input fragment */
799 mcr[2] = PHYS_TO_PCI(PTR_TO_PHYS(input));
800 mcr[3] = 0;
801 mcr[4] = V_DBC_DATA_LEN(input_size);
803 mcr[5] = V_PD_PKT_LEN(input_size);
805 hash = KMALLOC(5*4, CACHE_LINE_SIZE);
806 for (i = 0; i < 5; i++)
807 hash[i] = 0;
809 mcr[6] = 0;
810 mcr[7] = PHYS_TO_PCI(PTR_TO_PHYS(hash));
811 mcr[8] = 0;
813 /* packet 2 */
815 cmd = KMALLOC(ARC4_CMD_WORDS*4, CACHE_LINE_SIZE);
816 cmd[0] = V_CC_OPCODE(K_ARC4) | V_CC_LEN(ARC4_CMD_WORDS*4);
817 cmd[1] = M_ARC4_FLAGS_WRITEBACK;
818 cmd[2] = 0x000100F3;
819 arc4_state = (uint8_t *)&cmd[3];
820 for (i = 0; i < 256; i++)
821 arc4_state[i] = i;
823 mcr[8+1] = PHYS_TO_PCI(PTR_TO_PHYS(cmd));
825 /* input fragment */
826 chain = KMALLOC(CHAIN_WORDS*4, CACHE_LINE_SIZE);
828 mcr[8+2] = PHYS_TO_PCI(PTR_TO_PHYS(input));
829 mcr[8+3] = PHYS_TO_PCI(PTR_TO_PHYS(chain));
830 mcr[8+4] = V_DBC_DATA_LEN(input_size);
832 /* MAC fragment */
833 chain[0] = PHYS_TO_PCI(PTR_TO_PHYS(hash));
834 chain[1] = 0;
835 chain[2] = V_DBC_DATA_LEN(16);
837 mcr[8+5] = V_PD_PKT_LEN(input_size + 16);
839 /* output fragment */
840 chain = KMALLOC(CHAIN_WORDS*4, CACHE_LINE_SIZE);
842 mcr[8+6] = PHYS_TO_PCI(PTR_TO_PHYS(output));
843 mcr[8+7] = PHYS_TO_PCI(PTR_TO_PHYS(chain));
844 mcr[8+8] = V_DBC_DATA_LEN(input_size + 16);
846 update = KMALLOC(ARC4_STATE_WORDS*4, CACHE_LINE_SIZE);
847 for (i = 0; i < ARC4_STATE_WORDS; i++)
848 update[i] = 0xFFFFFFFF;
850 /* output update */
851 chain[0] = PHYS_TO_PCI(PTR_TO_PHYS(update));
852 chain[1] = 0;
853 chain[2] = V_DBC_DATA_LEN(ARC4_STATE_WORDS*4); /* not actually used */
855 return mcr;
858 static void
859 bcm5821_free_composite (uint32_t mcr[])
861 uint32_t *chain;
863 /* packet 1 */
865 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[1])));
866 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[2])));
867 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[7])));
869 /* packet 2 */
870 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[8+1])));
871 /* mcr[8+2] already freed */
872 chain = PHYS_TO_PTR(PCI_TO_PHYS(mcr[8+3]));
873 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(chain[0]))); KFREE(chain);
874 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(mcr[8+6])));
875 chain = PHYS_TO_PTR(PCI_TO_PHYS(mcr[8+7]));
876 KFREE(PHYS_TO_PTR(PCI_TO_PHYS(chain[0]))); KFREE(chain);
878 KFREE(mcr);
882 static void
883 flush_l2(void)
885 /* Temporary hack: churn through all of L2 */
886 volatile uint64_t *lomem;
887 uint64_t t;
888 int i;
890 lomem = (uint64_t *)(0xFFFFFFFF80000000LL); /* kseg0 @ 0 */
891 t = 0;
892 for (i = 0; i < (512/8)*1024; i++)
893 t ^= lomem[i];
896 #ifdef IRQ
897 static void
898 bcm5821_interrupt(void *ctx)
901 #endif
904 #define POOL_SIZE 4
905 #define MCR_QUEUE_DEPTH 2
907 static int
908 bcm5821_composite (bcm5821_state_t *sc, size_t len, int trials)
910 uint32_t *mcr[POOL_SIZE];
911 uint32_t status;
912 uint64_t start, stop, ticks;
913 uint64_t tpb, Mbs;
914 int i;
915 int next, last, run;
917 for (i = 0; i < POOL_SIZE; i++)
918 mcr[i] = bcm5821_alloc_composite(len);
920 (void)bcm5821_dump_mcr; /*bcm5821_dump_mcr(mcr[0], 1);*/
922 next = last = 0;
923 run = 0;
925 /* Force all descriptors and buffers out of L1 */
926 cfe_flushcache(CFE_CACHE_FLUSH_D);
927 (void)flush_l2;
929 status = READCSR(sc, R_DMA_STAT);
930 WRITECSR(sc, R_DMA_STAT, status); /* clear pending bits */
931 status = READCSR(sc, R_DMA_STAT);
933 for (i = 0; i < 1000; i++) {
934 status = READCSR(sc, R_DMA_STAT);
935 if ((status & M_DMA_STAT_MCR1_FULL) == 0)
936 break;
937 cfe_sleep(1);
939 if (i == 1000) {
940 dumpcsrs(sc, "bcm5821: full bit never clears");
941 return -1;
944 #ifdef IRQ
945 /* Enable interrupt polling, but the handler is never called. */
946 cfe_request_irq(sc->irq, bcm5821_interrupt, NULL, 0, 0);
947 #endif
949 zclk_init(0); /* Time origin is arbitrary. */
950 start = zclk_get();
952 /* MCR ports are double buffered. */
953 for (i = 0; i < MCR_QUEUE_DEPTH; i++) {
954 while ((READCSR(sc, R_DMA_STAT) & M_DMA_STAT_MCR1_FULL) != 0)
955 continue;
956 WRITECSR(sc, R_MCR1, PHYS_TO_PCI(PTR_TO_PHYS(mcr[next])));
957 next = (next + 1) % POOL_SIZE;
960 while (1) {
961 #ifdef IRQ
962 while ((_getcause() & M_CAUSE_IP2) == 0)
963 continue;
965 status = READCSR(sc, R_DMA_STAT);
966 if ((status & M_DMA_STAT_MCR1_INTR) == 0) {
967 /* This apparently is MCR1_ALL_EMPTY, timing of which is unclear. */
968 WRITECSR(sc, R_DMA_STAT,
969 M_DMA_STAT_DMAERR_INTR | M_DMA_STAT_MCR1_INTR);
970 continue;
973 stop = zclk_get();
974 WRITECSR(sc, R_DMA_STAT,
975 M_DMA_STAT_DMAERR_INTR | M_DMA_STAT_MCR1_INTR);
976 #else
977 volatile uint32_t *last_mcr = mcr[last];
979 while ((*last_mcr & M_MCR_DONE) == 0)
980 continue;
982 stop = zclk_get();
983 #endif
985 run++;
986 if (run == trials)
987 break;
989 while ((READCSR(sc, R_DMA_STAT) & M_DMA_STAT_MCR1_FULL) != 0)
990 continue;
991 WRITECSR(sc, R_MCR1, PHYS_TO_PCI(PTR_TO_PHYS(mcr[next])));
992 next = (next + 1) % POOL_SIZE;
994 /* Clear the DONE and ERROR bits. This will bring one line of
995 the MCR back into L1. Flush? */
996 mcr[last][0] = V_MCR_NUM_PACKETS(2);
997 last = (last + 1) % POOL_SIZE;
1000 #ifdef IRQ
1001 status = READCSR(sc, R_DMA_STAT);
1002 WRITECSR(sc, R_DMA_STAT, status); /* clear pending bits */
1003 cfe_free_irq(sc->irq, 0);
1004 #endif
1006 ticks = zclk_elapsed(stop, start) / trials;
1007 xprintf("bcm5821: Composite %lld ticks for %d bytes, %d packets\n",
1008 ticks, len, trials);
1009 /* Scaling for two decimal places. */
1010 tpb = (ticks*100) / len;
1011 Mbs = (2000*100)*100 / tpb;
1012 xprintf(" rate %lld.%02lld Mbps\n", Mbs/100, Mbs % 100);
1014 if (trials == 1)
1016 bcm5821_show_mcr(mcr[0], 1);
1019 for (i = 0; i < POOL_SIZE; i++)
1020 bcm5821_free_composite(mcr[i]);
1022 return 0;
1026 /* The following code depends on having a separate interrupt per
1027 device, and there are only 4 PCI interrupts. */
1028 #define MAX_DEVICES 4
1030 struct dev_info {
1031 bcm5821_state_t *sc;
1032 uint64_t irq_mask;
1033 int index[MCR_QUEUE_DEPTH];
1037 #define N_DEVICES 2
1039 static int
1040 bcm5821_composite2 (bcm5821_state_t *sc0, bcm5821_state_t *sc1,
1041 size_t len, int trials)
1043 uint32_t *mcr[POOL_SIZE];
1044 uint32_t ring[POOL_SIZE];
1045 uint32_t status;
1046 uint64_t start, stop, ticks;
1047 uint64_t tpb, Mbs;
1048 int i;
1049 int next, last;
1050 int started, run;
1051 int d;
1052 struct dev_info dev[N_DEVICES];
1053 uint64_t masks;
1054 bcm5821_state_t *sc;
1055 #ifdef IRQ
1056 volatile uint64_t *irqstat = IMR_POINTER(0, R_IMR_INTERRUPT_SOURCE_STATUS);
1057 #endif
1058 uint64_t pending;
1060 dev[0].sc = sc0; dev[1].sc = sc1;
1062 for (i = 0; i < POOL_SIZE; i++)
1063 mcr[i] = bcm5821_alloc_composite(len);
1064 for (i = 0; i < POOL_SIZE; i++)
1065 ring[i] = i;
1066 next = last = 0;
1068 (void)bcm5821_dump_mcr; /*bcm5821_dump_mcr(mcr[0], 1);*/
1070 started = run = 0;
1072 /* Force all descriptors and buffers out of L1 */
1073 cfe_flushcache(CFE_CACHE_FLUSH_D);
1074 (void)flush_l2;
1076 masks = 0;
1077 for (d = 0; d < N_DEVICES; d++) {
1078 sc = dev[d].sc;
1079 dev[d].irq_mask = 1LL << (sc->irq);
1080 masks |= dev[d].irq_mask;
1082 status = READCSR(sc, R_DMA_STAT);
1083 WRITECSR(sc, R_DMA_STAT, status); /* clear pending bits */
1084 status = READCSR(sc, R_DMA_STAT);
1086 for (i = 0; i < 1000; i++) {
1087 status = READCSR(sc, R_DMA_STAT);
1088 if ((status & M_DMA_STAT_MCR1_FULL) == 0)
1089 break;
1090 cfe_sleep(1);
1093 if (i == 1000) {
1094 dumpcsrs(sc, "bcm5821: full bit never clears");
1095 return -1;
1098 #ifdef IRQ
1099 /* Enable interrupt polling, but the handler is never called. */
1100 cfe_request_irq(sc->irq, bcm5821_interrupt, NULL, 0, 0);
1101 #endif
1104 stop = 0; /* Keep compiler happy */
1105 zclk_init(0); /* Time origin is arbitrary. */
1106 start = zclk_get();
1108 for (d = 0; d < N_DEVICES; d++) {
1109 sc = dev[d].sc;
1111 /* MCR ports are double buffered. */
1112 for (i = 0; i < 2; i++) {
1113 int index = ring[next];
1114 while ((READCSR(sc, R_DMA_STAT) & M_DMA_STAT_MCR1_FULL) != 0)
1115 continue;
1116 WRITECSR(sc, R_MCR1, PHYS_TO_PCI(PTR_TO_PHYS(mcr[index])));
1117 dev[d].index[i] = index;
1118 next = (next + 1) % POOL_SIZE;
1119 started++;
1123 while (trials == 0 || run != trials) {
1124 #ifdef IRQ
1125 while ((_getcause() & M_CAUSE_IP2) == 0)
1126 continue;
1128 pending = *irqstat;
1129 #else
1130 pending = 0;
1131 while (pending == 0) {
1132 for (d = 0; d < N_DEVICES; d++) {
1133 volatile uint32_t *last_mcr = mcr[dev[d].index[0]];
1135 if ((*last_mcr & M_MCR_DONE) != 0)
1136 pending |= dev[d].irq_mask;
1139 #endif
1141 stop = zclk_get();
1143 for (d = 0; d < N_DEVICES; d++) {
1144 if ((dev[d].irq_mask & pending) != 0) {
1145 sc = dev[d].sc;
1147 #ifdef IRQ
1148 status = READCSR(sc, R_DMA_STAT);
1149 if ((status & M_DMA_STAT_MCR1_INTR) == 0) {
1150 /* Apparently MCR1_ALL_EMPTY, timing of which is unclear. */
1151 WRITECSR(sc, R_DMA_STAT,
1152 M_DMA_STAT_DMAERR_INTR | M_DMA_STAT_MCR1_INTR);
1153 continue;
1155 WRITECSR(sc, R_DMA_STAT,
1156 M_DMA_STAT_DMAERR_INTR | M_DMA_STAT_MCR1_INTR);
1157 #endif
1158 ring[last] = dev[d].index[0];
1159 /* Clear the DONE and ERROR bits. This will bring one line of
1160 the MCR back into L1. Flush? */
1161 mcr[ring[last]][0] = V_MCR_NUM_PACKETS(2);
1162 last = (last + 1) % POOL_SIZE;
1164 run++;
1165 if (run == trials)
1166 break;
1168 dev[d].index[0] = dev[d].index[1];
1169 if (trials == 0 || started < trials) {
1170 int index = ring[next];
1171 while ((READCSR(sc, R_DMA_STAT) & M_DMA_STAT_MCR1_FULL) != 0)
1172 continue;
1173 WRITECSR(sc, R_MCR1, PHYS_TO_PCI(PTR_TO_PHYS(mcr[index])));
1174 dev[d].index[1] = index;
1175 next = (next + 1) % POOL_SIZE;
1176 started++;
1182 for (d = 0; d < N_DEVICES; d++) {
1183 sc = dev[d].sc;
1184 status = READCSR(sc, R_DMA_STAT);
1185 WRITECSR(sc, R_DMA_STAT, status); /* clear pending bits */
1186 #ifdef IRQ
1187 cfe_free_irq(sc->irq, 0);
1188 #endif
1191 ticks = zclk_elapsed(stop, start) / trials;
1192 xprintf("bcm5821: Composite %lld ticks for %d bytes, %d packets\n",
1193 ticks, len, trials);
1194 /* Scaling for two decimal places. */
1195 tpb = (ticks*100) / len;
1196 Mbs = (2000*100)*100 / tpb;
1197 xprintf(" rate %lld.%02lld Mbps\n", Mbs/100, Mbs % 100);
1199 for (i = 0; i < POOL_SIZE; i++)
1200 bcm5821_free_composite(mcr[i]);
1202 return 0;
1206 extern cfe_devctx_t *cfe_handle_table[];
1208 int bcm5821_test (int device, int trials);
1210 bcm5821_test (int device, int trials)
1212 cfe_devctx_t *ctx = cfe_handle_table[device];
1213 bcm5821_state_t *sc = ctx->dev_softc;
1215 if (!test_init) {
1216 zclk_init(0); /* Time origin is arbitrary */
1217 test_init = 1;
1220 bcm5821_composite(sc, 1472, trials);
1222 return 0;
1225 int bcm5821_test2 (int device0, int device2, int trials);
1227 bcm5821_test2 (int device0, int device1, int trials)
1229 cfe_devctx_t *ctx0 = cfe_handle_table[device0];
1230 cfe_devctx_t *ctx1 = cfe_handle_table[device1];
1231 bcm5821_state_t *sc0 = ctx0->dev_softc;
1232 bcm5821_state_t *sc1 = ctx1->dev_softc;
1234 if (!test_init) {
1235 zclk_init(0); /* Time origin is arbitrary */
1236 test_init = 1;
1239 bcm5821_composite2(sc0, sc1, 1472, trials);
1241 return 0;
1245 static int
1246 bcm5821_hash_md5 (bcm5821_state_t *sc, const char *msg)
1248 size_t len = strlen(msg);
1249 uint32_t *mcr;
1250 uint32_t status;
1251 int i;
1252 int swap = (sc->device == K_PCI_ID_BCM5820);
1254 mcr = bcm5821_alloc_hash(msg, len, swap);
1256 /* bcm5821_dump_mcr(mcr, 1); */
1258 status = READCSR(sc, R_DMA_STAT);
1259 WRITECSR(sc, R_DMA_STAT, status); /* clear pending bits */
1260 status = READCSR(sc, R_DMA_STAT);
1262 for (i = 0; i < 1000; i++) {
1263 status = READCSR(sc, R_DMA_STAT);
1264 if ((status & M_DMA_STAT_MCR1_FULL) == 0)
1265 break;
1266 cfe_sleep(1);
1268 if (i == 1000) {
1269 dumpcsrs(sc, "bcm5821: full bit never clears");
1270 return -1;
1273 WRITECSR(sc, R_MCR1, PHYS_TO_PCI(PTR_TO_PHYS(mcr)));
1275 for (i = 0; i < 1000; i++) {
1276 #ifdef IRQ
1277 status = READCSR(sc, R_DMA_STAT);
1278 if ((status & M_DMA_STAT_MCR1_INTR) != 0)
1279 break;
1280 #else
1281 if ((mcr[0] & M_MCR_DONE) != 0)
1282 break;
1283 #endif
1284 cfe_sleep(1);
1286 if (i == 1000) {
1287 dumpcsrs(sc, "bcm5821: done bit never sets");
1288 /*return -1;*/
1291 status = READCSR(sc, R_DMA_STAT);
1292 WRITECSR(sc, R_DMA_STAT, status); /* clear pending bits */
1294 /* bcm5821_dump_mcr(mcr, 1); */
1296 bcm5821_show_mcr(mcr, 1);
1298 bcm5821_free_hash(mcr);
1300 return 0;
1304 static int
1305 bcm5821_hmac_md5 (bcm5821_state_t *sc,
1306 const uint8_t key[], size_t key_len,
1307 const uint8_t data[], size_t data_len)
1309 uint32_t *mcr;
1310 uint32_t status;
1311 int i;
1312 int swap = (sc->device == K_PCI_ID_BCM5820);
1314 mcr = bcm5821_alloc_hmac(key, key_len, data, data_len, swap);
1316 status = READCSR(sc, R_DMA_STAT);
1317 WRITECSR(sc, R_DMA_STAT, status); /* clear pending bits */
1318 status = READCSR(sc, R_DMA_STAT);
1320 for (i = 0; i < 1000; i++) {
1321 status = READCSR(sc, R_DMA_STAT);
1322 if ((status & M_DMA_STAT_MCR1_FULL) == 0)
1323 break;
1324 cfe_sleep(1);
1326 if (i == 1000) {
1327 dumpcsrs(sc, "bcm5821: full bit never clears");
1328 return -1;
1331 bcm5821_free_hmac(mcr);
1332 return 0;
1335 /* Sanity check on the implementation using RFC test suites. */
1337 int bcm5821_check (int device);
1339 bcm5821_check (int device)
1341 static unsigned char k1[16] = {
1342 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
1343 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
1345 static unsigned char m1[] = "Hi There";
1347 static unsigned char k2[] = "Jefe";
1348 static unsigned char m2[] = "what do ya want for nothing?";
1350 static unsigned char k3[16] = {
1351 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
1352 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
1354 static unsigned char m3[50] = {
1355 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
1356 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
1357 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
1358 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
1359 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD
1362 cfe_devctx_t *ctx = cfe_handle_table[device];
1363 bcm5821_state_t *sc = ctx->dev_softc;
1365 if (!test_init) {
1366 zclk_init(0); /* Time origin is arbitrary */
1367 test_init = 1;
1370 bcm5821_hash_md5(sc, "a");
1371 bcm5821_hash_md5(sc, "abc");
1372 bcm5821_hash_md5(sc, "message digest");
1373 bcm5821_hash_md5(sc, "abcdefghijklmnopqrstuvwxyz");
1374 bcm5821_hash_md5(sc, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
1375 bcm5821_hash_md5(sc, "12345678901234567890123456789012345678901234567890123456789012345678901234567890");
1377 bcm5821_hmac_md5(sc, k1, sizeof(k1), m1, strlen(m1));
1378 bcm5821_hmac_md5(sc, k2, strlen(k2), m2, strlen(m2));
1379 bcm5821_hmac_md5(sc, k3, sizeof(k3), m3, sizeof(m3));
1381 return 0;
1384 /* Output of md5 test suite (md5 -x)
1386 MD5 test suite:
1387 MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
1388 MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
1389 MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
1390 MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
1391 MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
1392 MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f
1393 MD5 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a
1397 /* HMAC-MD5 test suite
1399 Test Vectors (Trailing '\0' of a character string not included in test):
1401 key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
1402 key_len = 16 bytes
1403 data = "Hi There"
1404 data_len = 8 bytes
1405 digest = 0x9294727a3638bb1c13f48ef8158bfc9d
1407 key = "Jefe"
1408 data = "what do ya want for nothing?"
1409 data_len = 28 bytes
1410 digest = 0x750c783e6ab0b503eaa86e310a5db738
1412 key = 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1413 key_len 16 bytes
1414 data = 0xDDDDDDDDDDDDDDDDDDDD...
1415 ..DDDDDDDDDDDDDDDDDDDD...
1416 ..DDDDDDDDDDDDDDDDDDDD...
1417 ..DDDDDDDDDDDDDDDDDDDD...
1418 ..DDDDDDDDDDDDDDDDDDDD
1419 data_len = 50 bytes
1420 digest = 0x56be34521d144c88dbb8c733f0e8b3f6