Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2019 Marvell International Ltd.
3 : : */
4 : :
5 : : #include <rte_common.h>
6 : : #include <rte_cycles.h>
7 : : #include <rte_memory.h>
8 : : #include <rte_byteorder.h>
9 : :
10 : : #include "nitrox_hal.h"
11 : : #include "nitrox_csr.h"
12 : :
13 : : #define MAX_VF_QUEUES 8
14 : : #define MAX_PF_QUEUES 64
15 : : #define NITROX_TIMER_THOLD 0x3FFFFF
16 : : #define NITROX_COUNT_THOLD 0xFFFFFFFF
17 : :
18 : : void
19 : 0 : nps_pkt_input_ring_disable(uint8_t *bar_addr, uint16_t ring)
20 : : {
21 : : union nps_pkt_in_instr_ctl pkt_in_instr_ctl;
22 : : uint64_t reg_addr;
23 : : int max_retries = 5;
24 : :
25 : 0 : reg_addr = NPS_PKT_IN_INSTR_CTLX(ring);
26 : 0 : pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
27 : 0 : pkt_in_instr_ctl.s.enb = 0;
28 : 0 : nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_ctl.u64);
29 : 0 : rte_delay_us_block(100);
30 : :
31 : : /* wait for enable bit to be cleared */
32 : 0 : pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
33 [ # # # # ]: 0 : while (pkt_in_instr_ctl.s.enb && max_retries--) {
34 : : rte_delay_ms(10);
35 : 0 : pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
36 : : }
37 : 0 : }
38 : :
39 : : void
40 : 0 : nps_pkt_solicited_port_disable(uint8_t *bar_addr, uint16_t port)
41 : : {
42 : : union nps_pkt_slc_ctl pkt_slc_ctl;
43 : : uint64_t reg_addr;
44 : : int max_retries = 5;
45 : :
46 : : /* clear enable bit */
47 : 0 : reg_addr = NPS_PKT_SLC_CTLX(port);
48 : 0 : pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
49 : 0 : pkt_slc_ctl.s.enb = 0;
50 : 0 : nitrox_write_csr(bar_addr, reg_addr, pkt_slc_ctl.u64);
51 : 0 : rte_delay_us_block(100);
52 : :
53 : 0 : pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
54 [ # # # # ]: 0 : while (pkt_slc_ctl.s.enb && max_retries--) {
55 : : rte_delay_ms(10);
56 : 0 : pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
57 : : }
58 : 0 : }
59 : :
60 : : void
61 : 0 : setup_nps_pkt_input_ring(uint8_t *bar_addr, uint16_t ring, uint32_t rsize,
62 : : phys_addr_t raddr)
63 : : {
64 : : union nps_pkt_in_instr_ctl pkt_in_instr_ctl;
65 : : union nps_pkt_in_instr_rsize pkt_in_instr_rsize;
66 : : union nps_pkt_in_instr_baoff_dbell pkt_in_instr_baoff_dbell;
67 : : union nps_pkt_in_done_cnts pkt_in_done_cnts;
68 : : uint64_t base_addr, reg_addr;
69 : : int max_retries = 5;
70 : :
71 : 0 : nps_pkt_input_ring_disable(bar_addr, ring);
72 : :
73 : : /* write base address */
74 : 0 : reg_addr = NPS_PKT_IN_INSTR_BADDRX(ring);
75 : : base_addr = raddr;
76 : : nitrox_write_csr(bar_addr, reg_addr, base_addr);
77 : 0 : rte_delay_us_block(CSR_DELAY);
78 : :
79 : : /* write ring size */
80 : 0 : reg_addr = NPS_PKT_IN_INSTR_RSIZEX(ring);
81 : 0 : pkt_in_instr_rsize.u64 = 0;
82 : 0 : pkt_in_instr_rsize.s.rsize = rsize;
83 : 0 : nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_rsize.u64);
84 : 0 : rte_delay_us_block(CSR_DELAY);
85 : :
86 : : /* clear door bell */
87 : 0 : reg_addr = NPS_PKT_IN_INSTR_BAOFF_DBELLX(ring);
88 : : pkt_in_instr_baoff_dbell.u64 = 0;
89 : : pkt_in_instr_baoff_dbell.s.dbell = 0xFFFFFFFF;
90 : : nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_baoff_dbell.u64);
91 : 0 : rte_delay_us_block(CSR_DELAY);
92 : :
93 : : /* clear done count */
94 : 0 : reg_addr = NPS_PKT_IN_DONE_CNTSX(ring);
95 : : pkt_in_done_cnts.u64 = nitrox_read_csr(bar_addr, reg_addr);
96 : : nitrox_write_csr(bar_addr, reg_addr, pkt_in_done_cnts.u64);
97 : 0 : rte_delay_us_block(CSR_DELAY);
98 : :
99 : : /* Setup PKT IN RING Interrupt Threshold */
100 : 0 : reg_addr = NPS_PKT_IN_INT_LEVELSX(ring);
101 : : nitrox_write_csr(bar_addr, reg_addr, 0xFFFFFFFF);
102 : 0 : rte_delay_us_block(CSR_DELAY);
103 : :
104 : : /* enable ring */
105 : 0 : reg_addr = NPS_PKT_IN_INSTR_CTLX(ring);
106 : : pkt_in_instr_ctl.u64 = 0;
107 : 0 : pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
108 : 0 : pkt_in_instr_ctl.s.is64b = 1;
109 : 0 : pkt_in_instr_ctl.s.enb = 1;
110 : 0 : nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_ctl.u64);
111 : 0 : rte_delay_us_block(100);
112 : :
113 : : pkt_in_instr_ctl.u64 = 0;
114 : 0 : pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
115 : : /* wait for ring to be enabled */
116 [ # # # # ]: 0 : while (!pkt_in_instr_ctl.s.enb && max_retries--) {
117 : : rte_delay_ms(10);
118 : 0 : pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
119 : : }
120 : 0 : }
121 : :
122 : : void
123 : 0 : setup_nps_pkt_solicit_output_port(uint8_t *bar_addr, uint16_t port)
124 : : {
125 : : union nps_pkt_slc_ctl pkt_slc_ctl;
126 : : union nps_pkt_slc_cnts pkt_slc_cnts;
127 : : union nps_pkt_slc_int_levels pkt_slc_int_levels;
128 : : uint64_t reg_addr;
129 : : int max_retries = 5;
130 : :
131 : 0 : nps_pkt_solicited_port_disable(bar_addr, port);
132 : :
133 : : /* clear pkt counts */
134 : 0 : reg_addr = NPS_PKT_SLC_CNTSX(port);
135 : : pkt_slc_cnts.u64 = nitrox_read_csr(bar_addr, reg_addr);
136 : : nitrox_write_csr(bar_addr, reg_addr, pkt_slc_cnts.u64);
137 : 0 : rte_delay_us_block(CSR_DELAY);
138 : :
139 : : /* slc interrupt levels */
140 : 0 : reg_addr = NPS_PKT_SLC_INT_LEVELSX(port);
141 : : pkt_slc_int_levels.u64 = 0;
142 : : pkt_slc_int_levels.s.bmode = 0;
143 : : pkt_slc_int_levels.s.timet = NITROX_TIMER_THOLD;
144 : :
145 : : if (NITROX_COUNT_THOLD > 0)
146 : : pkt_slc_int_levels.s.cnt = NITROX_COUNT_THOLD - 1;
147 : :
148 : : nitrox_write_csr(bar_addr, reg_addr, pkt_slc_int_levels.u64);
149 : 0 : rte_delay_us_block(CSR_DELAY);
150 : :
151 : : /* enable ring */
152 : 0 : reg_addr = NPS_PKT_SLC_CTLX(port);
153 : 0 : pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
154 : 0 : pkt_slc_ctl.s.rh = 1;
155 : 0 : pkt_slc_ctl.s.z = 1;
156 : 0 : pkt_slc_ctl.s.enb = 1;
157 : 0 : nitrox_write_csr(bar_addr, reg_addr, pkt_slc_ctl.u64);
158 : 0 : rte_delay_us_block(100);
159 : :
160 : 0 : pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
161 [ # # # # ]: 0 : while (!pkt_slc_ctl.s.enb && max_retries--) {
162 : : rte_delay_ms(10);
163 : 0 : pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
164 : : }
165 : 0 : }
166 : :
167 : : int
168 : 0 : vf_get_vf_config_mode(uint8_t *bar_addr)
169 : : {
170 : : union aqmq_qsz aqmq_qsz;
171 : : uint64_t reg_addr;
172 : : int q, vf_mode;
173 : :
174 : : aqmq_qsz.u64 = 0;
175 : : aqmq_qsz.s.host_queue_size = 0xDEADBEEF;
176 : : reg_addr = AQMQ_QSZX(0);
177 : : nitrox_write_csr(bar_addr, reg_addr, aqmq_qsz.u64);
178 : 0 : rte_delay_us_block(CSR_DELAY);
179 : :
180 : : aqmq_qsz.u64 = 0;
181 [ # # ]: 0 : for (q = 1; q < MAX_VF_QUEUES; q++) {
182 : 0 : reg_addr = AQMQ_QSZX(q);
183 : : aqmq_qsz.u64 = nitrox_read_csr(bar_addr, reg_addr);
184 [ # # ]: 0 : if (aqmq_qsz.s.host_queue_size == 0xDEADBEEF)
185 : : break;
186 : : }
187 : :
188 [ # # ]: 0 : switch (q) {
189 : : case 1:
190 : : vf_mode = NITROX_MODE_VF128;
191 : : break;
192 : : case 2:
193 : : vf_mode = NITROX_MODE_VF64;
194 : : break;
195 : : case 4:
196 : : vf_mode = NITROX_MODE_VF32;
197 : : break;
198 : : case 8:
199 : : vf_mode = NITROX_MODE_VF16;
200 : : break;
201 : : default:
202 : : vf_mode = 0;
203 : : break;
204 : : }
205 : :
206 : 0 : return vf_mode;
207 : : }
208 : :
209 : : int
210 [ # # ]: 0 : vf_config_mode_to_nr_queues(enum nitrox_vf_mode vf_mode)
211 : : {
212 : : int nr_queues;
213 : :
214 : : switch (vf_mode) {
215 : : case NITROX_MODE_PF:
216 : : nr_queues = MAX_PF_QUEUES;
217 : : break;
218 : : case NITROX_MODE_VF16:
219 : : nr_queues = 8;
220 : : break;
221 : : case NITROX_MODE_VF32:
222 : : nr_queues = 4;
223 : : break;
224 : : case NITROX_MODE_VF64:
225 : : nr_queues = 2;
226 : : break;
227 : : case NITROX_MODE_VF128:
228 : : nr_queues = 1;
229 : : break;
230 : : default:
231 : : nr_queues = 0;
232 : : break;
233 : : }
234 : :
235 : 0 : return nr_queues;
236 : : }
|