xref: /dpdk/drivers/net/ark/ark_mpu.c (revision 945acb4a0d644d194f1823084a234f9c286dcf8c)
1 /*-
2  * BSD LICENSE
3  *
4  * Copyright (c) 2015-2017 Atomic Rules LLC
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  * * Neither the name of copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <unistd.h>
35 
36 #include "ark_logs.h"
37 #include "ark_mpu.h"
38 
39 uint16_t
40 ark_api_num_queues(struct ark_mpu_t *mpu)
41 {
42 	return mpu->hw.num_queues;
43 }
44 
45 uint16_t
46 ark_api_num_queues_per_port(struct ark_mpu_t *mpu, uint16_t ark_ports)
47 {
48 	return mpu->hw.num_queues / ark_ports;
49 }
50 
51 int
52 ark_mpu_verify(struct ark_mpu_t *mpu, uint32_t obj_size)
53 {
54 	uint32_t version;
55 
56 	version = mpu->id.vernum & 0x0000fF00;
57 	if ((mpu->id.idnum != 0x2055504d) ||
58 	    (mpu->hw.obj_size != obj_size) ||
59 	    (version != 0x00003100)) {
60 		PMD_DRV_LOG(ERR,
61 			    "   MPU module not found as expected %08x"
62 			    " \"%c%c%c%c %c%c%c%c\"\n",
63 			    mpu->id.idnum,
64 			    mpu->id.id[0], mpu->id.id[1],
65 			    mpu->id.id[2], mpu->id.id[3],
66 			    mpu->id.ver[0], mpu->id.ver[1],
67 			    mpu->id.ver[2], mpu->id.ver[3]);
68 		PMD_DRV_LOG(ERR,
69 			    "   MPU HW num_queues: %u hw_depth %u,"
70 			    " obj_size: %u, obj_per_mrr: %u"
71 			    " Expected size %u\n",
72 			    mpu->hw.num_queues,
73 			    mpu->hw.hw_depth,
74 			    mpu->hw.obj_size,
75 			    mpu->hw.obj_per_mrr,
76 			    obj_size);
77 		return -1;
78 	}
79 	return 0;
80 }
81 
82 void
83 ark_mpu_stop(struct ark_mpu_t *mpu)
84 {
85 	mpu->cfg.command = MPU_CMD_STOP;
86 }
87 
88 void
89 ark_mpu_start(struct ark_mpu_t *mpu)
90 {
91 	mpu->cfg.command = MPU_CMD_RUN;
92 }
93 
94 int
95 ark_mpu_reset(struct ark_mpu_t *mpu)
96 {
97 	int cnt = 0;
98 
99 	mpu->cfg.command = MPU_CMD_RESET;
100 
101 	while (mpu->cfg.command != MPU_CMD_IDLE) {
102 		if (cnt++ > 1000)
103 			break;
104 		usleep(10);
105 	}
106 	if (mpu->cfg.command != MPU_CMD_IDLE) {
107 		mpu->cfg.command = MPU_CMD_FORCE_RESET;
108 		usleep(10);
109 	}
110 	ark_mpu_reset_stats(mpu);
111 	return mpu->cfg.command != MPU_CMD_IDLE;
112 }
113 
114 void
115 ark_mpu_reset_stats(struct ark_mpu_t *mpu)
116 {
117 	mpu->stats.pci_request = 1;	/* reset stats */
118 }
119 
120 int
121 ark_mpu_configure(struct ark_mpu_t *mpu, rte_iova_t ring, uint32_t ring_size,
122 		  int is_tx)
123 {
124 	ark_mpu_reset(mpu);
125 
126 	if (!rte_is_power_of_2(ring_size)) {
127 		PMD_DRV_LOG(ERR, "ARK: Invalid ring size for MPU %d\n",
128 			    ring_size);
129 		return -1;
130 	}
131 
132 	mpu->cfg.ring_base = ring;
133 	mpu->cfg.ring_size = ring_size;
134 	mpu->cfg.ring_mask = ring_size - 1;
135 	mpu->cfg.min_host_move = is_tx ? 1 : mpu->hw.obj_per_mrr;
136 	mpu->cfg.min_hw_move = mpu->hw.obj_per_mrr;
137 	mpu->cfg.sw_prod_index = 0;
138 	mpu->cfg.hw_cons_index = 0;
139 	return 0;
140 }
141 
142 void
143 ark_mpu_dump(struct ark_mpu_t *mpu, const char *code, uint16_t qid)
144 {
145 	/* DUMP to see that we have started */
146 	PMD_DEBUG_LOG(DEBUG, "MPU: %s Q: %3u sw_prod %u, hw_cons: %u\n",
147 		      code, qid,
148 		      mpu->cfg.sw_prod_index, mpu->cfg.hw_cons_index);
149 	PMD_DEBUG_LOG(DEBUG, "MPU: %s state: %d count %d, reserved %d"
150 		      " data 0x%08x_%08x 0x%08x_%08x\n",
151 		      code,
152 		      mpu->debug.state, mpu->debug.count,
153 		      mpu->debug.reserved,
154 		      mpu->debug.peek[1],
155 		      mpu->debug.peek[0],
156 		      mpu->debug.peek[3],
157 		      mpu->debug.peek[2]
158 		      );
159 	PMD_STATS_LOG(INFO, "MPU: %s Q: %3u"
160 		      ARK_SU64 ARK_SU64 ARK_SU64 ARK_SU64
161 		      ARK_SU64 ARK_SU64 ARK_SU64 "\n",
162 		      code, qid,
163 		      "PCI Request:", mpu->stats.pci_request,
164 		      "Queue_empty", mpu->stats.q_empty,
165 		      "Queue_q1", mpu->stats.q_q1,
166 		      "Queue_q2", mpu->stats.q_q2,
167 		      "Queue_q3", mpu->stats.q_q3,
168 		      "Queue_q4", mpu->stats.q_q4,
169 		      "Queue_full", mpu->stats.q_full
170 		      );
171 }
172 
173 void
174 ark_mpu_dump_setup(struct ark_mpu_t *mpu, uint16_t q_id)
175 {
176 	PMD_DEBUG_LOG(DEBUG, "MPU Setup Q: %u"
177 		      ARK_SU64X "\n",
178 		      q_id,
179 		      "ring_base", mpu->cfg.ring_base
180 		      );
181 }
182