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