1 /* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are met:
5  *     * Redistributions of source code must retain the above copyright
6  *	 notice, this list of conditions and the following disclaimer.
7  *     * Redistributions in binary form must reproduce the above copyright
8  *	 notice, this list of conditions and the following disclaimer in the
9  *	 documentation and/or other materials provided with the distribution.
10  *     * Neither the name of Freescale Semiconductor nor the
11  *	 names of its contributors may be used to endorse or promote products
12  *	 derived from this software without specific prior written permission.
13  *
14  * ALTERNATIVELY, this software may be distributed under the terms of the
15  * GNU General Public License ("GPL") as published by the Free Software
16  * Foundation, either version 2 of that License or (at your option) any
17  * later version.
18  *
19  * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "bman_test.h"
32 
33 #define NUM_BUFS	93
34 #define LOOPS		3
35 #define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
36 
37 static struct bman_pool *pool;
38 static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
39 static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
40 static int bufs_received;
41 
bufs_init(void)42 static void bufs_init(void)
43 {
44 	int i;
45 
46 	for (i = 0; i < NUM_BUFS; i++)
47 		bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
48 	bufs_received = 0;
49 }
50 
bufs_cmp(const struct bm_buffer * a,const struct bm_buffer * b)51 static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
52 {
53 	if (bman_ip_rev == BMAN_REV20 || bman_ip_rev == BMAN_REV21) {
54 
55 		/*
56 		 * On SoCs with BMan revison 2.0, BMan only respects the 40
57 		 * LS-bits of buffer addresses, masking off the upper 8-bits on
58 		 * release commands. The API provides for 48-bit addresses
59 		 * because some SoCs support all 48-bits. When generating
60 		 * garbage addresses for testing, we either need to zero the
61 		 * upper 8-bits when releasing to BMan (otherwise we'll be
62 		 * disappointed when the buffers we acquire back from BMan
63 		 * don't match), or we need to mask the upper 8-bits off when
64 		 * comparing. We do the latter.
65 		 */
66 		if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) <
67 		    (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
68 			return -1;
69 		if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) >
70 		    (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
71 			return 1;
72 	} else {
73 		if (bm_buffer_get64(a) < bm_buffer_get64(b))
74 			return -1;
75 		if (bm_buffer_get64(a) > bm_buffer_get64(b))
76 			return 1;
77 	}
78 
79 	return 0;
80 }
81 
bufs_confirm(void)82 static void bufs_confirm(void)
83 {
84 	int i, j;
85 
86 	for (i = 0; i < NUM_BUFS; i++) {
87 		int matches = 0;
88 
89 		for (j = 0; j < NUM_BUFS; j++)
90 			if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
91 				matches++;
92 		WARN_ON(matches != 1);
93 	}
94 }
95 
96 /* test */
bman_test_api(void)97 void bman_test_api(void)
98 {
99 	int i, loops = LOOPS;
100 
101 	bufs_init();
102 
103 	pr_info("%s(): Starting\n", __func__);
104 
105 	pool = bman_new_pool();
106 	if (!pool) {
107 		pr_crit("bman_new_pool() failed\n");
108 		goto failed;
109 	}
110 
111 	/* Release buffers */
112 do_loop:
113 	i = 0;
114 	while (i < NUM_BUFS) {
115 		int num = 8;
116 
117 		if (i + num > NUM_BUFS)
118 			num = NUM_BUFS - i;
119 		if (bman_release(pool, bufs_in + i, num)) {
120 			pr_crit("bman_release() failed\n");
121 			goto failed;
122 		}
123 		i += num;
124 	}
125 
126 	/* Acquire buffers */
127 	while (i > 0) {
128 		int tmp, num = 8;
129 
130 		if (num > i)
131 			num = i;
132 		tmp = bman_acquire(pool, bufs_out + i - num, num);
133 		WARN_ON(tmp != num);
134 		i -= num;
135 	}
136 	i = bman_acquire(pool, NULL, 1);
137 	WARN_ON(i > 0);
138 
139 	bufs_confirm();
140 
141 	if (--loops)
142 		goto do_loop;
143 
144 	/* Clean up */
145 	bman_free_pool(pool);
146 	pr_info("%s(): Finished\n", __func__);
147 	return;
148 
149 failed:
150 	WARN_ON(1);
151 }
152