xref: /dpdk/drivers/common/nfp/nfp_common.c (revision b6de43530dfa30cbf6b70857e3835099701063d4)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2023 Corigine, Inc.
3  * All rights reserved.
4  */
5 
6 #include "nfp_common.h"
7 
8 #include "nfp_common_log.h"
9 
10 /*
11  * This is used by the reconfig protocol. It sets the maximum time waiting in
12  * milliseconds before a reconfig timeout happens.
13  */
14 #define NFP_NET_POLL_TIMEOUT    5000
15 
16 int
17 nfp_reconfig_real(struct nfp_hw *hw,
18 		uint32_t update)
19 {
20 	uint32_t cnt;
21 	uint32_t new;
22 	struct timespec wait;
23 
24 	PMD_DRV_LOG(DEBUG, "Writing to the configuration queue (%p)...",
25 			hw->qcp_cfg);
26 
27 	if (hw->qcp_cfg == NULL) {
28 		PMD_DRV_LOG(ERR, "Bad configuration queue pointer.");
29 		return -ENXIO;
30 	}
31 
32 	nfp_qcp_ptr_add(hw->qcp_cfg, NFP_QCP_WRITE_PTR, 1);
33 
34 	wait.tv_sec = 0;
35 	wait.tv_nsec = 1000000; /* 1ms */
36 
37 	PMD_DRV_LOG(DEBUG, "Polling for update ack...");
38 
39 	/* Poll update field, waiting for NFP to ack the config */
40 	for (cnt = 0; ; cnt++) {
41 		new = nn_cfg_readl(hw, NFP_NET_CFG_UPDATE);
42 		if (new == 0)
43 			break;
44 
45 		if ((new & NFP_NET_CFG_UPDATE_ERR) != 0) {
46 			PMD_DRV_LOG(ERR, "Reconfig error: %#08x.", new);
47 			return -1;
48 		}
49 
50 		if (cnt >= NFP_NET_POLL_TIMEOUT) {
51 			PMD_DRV_LOG(ERR, "Reconfig timeout for %#08x after %u ms.",
52 					update, cnt);
53 			return -EIO;
54 		}
55 
56 		nanosleep(&wait, 0); /* waiting for a 1ms */
57 	}
58 
59 	PMD_DRV_LOG(DEBUG, "Ack DONE.");
60 	return 0;
61 }
62 
63 /**
64  * Reconfigure the NIC.
65  *
66  * Write the update word to the BAR and ping the reconfig queue. Then poll
67  * until the firmware has acknowledged the update by zeroing the update word.
68  *
69  * @param hw
70  *   Device to reconfigure.
71  * @param ctrl
72  *   The value for the ctrl field in the BAR config.
73  * @param update
74  *   The value for the update field in the BAR config.
75  *
76  * @return
77  *   - (0) if OK to reconfigure the device.
78  *   - (-EIO) if I/O err and fail to reconfigure the device.
79  */
80 int
81 nfp_reconfig(struct nfp_hw *hw,
82 		uint32_t ctrl,
83 		uint32_t update)
84 {
85 	int ret;
86 
87 	rte_spinlock_lock(&hw->reconfig_lock);
88 
89 	nn_cfg_writel(hw, NFP_NET_CFG_CTRL, ctrl);
90 	nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, update);
91 
92 	rte_wmb();
93 
94 	ret = nfp_reconfig_real(hw, update);
95 
96 	rte_spinlock_unlock(&hw->reconfig_lock);
97 
98 	if (ret != 0) {
99 		PMD_DRV_LOG(ERR, "Error NFP reconfig: ctrl=%#08x update=%#08x.",
100 				ctrl, update);
101 		return -EIO;
102 	}
103 
104 	return 0;
105 }
106 
107 /**
108  * Reconfigure the NIC for the extend ctrl BAR.
109  *
110  * Write the update word to the BAR and ping the reconfig queue. Then poll
111  * until the firmware has acknowledged the update by zeroing the update word.
112  *
113  * @param hw
114  *   Device to reconfigure.
115  * @param ctrl_ext
116  *   The value for the first word of extend ctrl field in the BAR config.
117  * @param update
118  *   The value for the update field in the BAR config.
119  *
120  * @return
121  *   - (0) if OK to reconfigure the device.
122  *   - (-EIO) if I/O err and fail to reconfigure the device.
123  */
124 int
125 nfp_ext_reconfig(struct nfp_hw *hw,
126 		uint32_t ctrl_ext,
127 		uint32_t update)
128 {
129 	int ret;
130 
131 	rte_spinlock_lock(&hw->reconfig_lock);
132 
133 	nn_cfg_writel(hw, NFP_NET_CFG_CTRL_WORD1, ctrl_ext);
134 	nn_cfg_writel(hw, NFP_NET_CFG_UPDATE, update);
135 
136 	rte_wmb();
137 
138 	ret = nfp_reconfig_real(hw, update);
139 
140 	rte_spinlock_unlock(&hw->reconfig_lock);
141 
142 	if (ret != 0) {
143 		PMD_DRV_LOG(ERR, "Error NFP ext reconfig: ctrl_ext=%#08x update=%#08x.",
144 				ctrl_ext, update);
145 		return -EIO;
146 	}
147 
148 	return 0;
149 }
150 
151 void
152 nfp_read_mac(struct nfp_hw *hw)
153 {
154 	uint32_t tmp;
155 
156 	tmp = rte_be_to_cpu_32(nn_cfg_readl(hw, NFP_NET_CFG_MACADDR));
157 	memcpy(&hw->mac_addr.addr_bytes[0], &tmp, 4);
158 
159 	tmp = rte_be_to_cpu_32(nn_cfg_readl(hw, NFP_NET_CFG_MACADDR + 4));
160 	memcpy(&hw->mac_addr.addr_bytes[4], &tmp, 2);
161 }
162 
163 void
164 nfp_write_mac(struct nfp_hw *hw,
165 		uint8_t *mac)
166 {
167 	uint32_t mac0;
168 	uint16_t mac1;
169 
170 	mac0 = *(uint32_t *)mac;
171 	nn_writel(rte_cpu_to_be_32(mac0), hw->ctrl_bar + NFP_NET_CFG_MACADDR);
172 
173 	mac += 4;
174 	mac1 = *(uint16_t *)mac;
175 	nn_writew(rte_cpu_to_be_16(mac1),
176 			hw->ctrl_bar + NFP_NET_CFG_MACADDR + 6);
177 }
178 
179 void
180 nfp_enable_queues(struct nfp_hw *hw,
181 		uint16_t nb_rx_queues,
182 		uint16_t nb_tx_queues)
183 {
184 	int i;
185 	uint64_t enabled_queues;
186 
187 	/* Enabling the required TX queues in the device */
188 	enabled_queues = 0;
189 	for (i = 0; i < nb_tx_queues; i++)
190 		enabled_queues |= (1ULL << i);
191 
192 	nn_cfg_writeq(hw, NFP_NET_CFG_TXRS_ENABLE, enabled_queues);
193 
194 	/* Enabling the required RX queues in the device */
195 	enabled_queues = 0;
196 	for (i = 0; i < nb_rx_queues; i++)
197 		enabled_queues |= (1ULL << i);
198 
199 	nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, enabled_queues);
200 }
201 
202 void
203 nfp_disable_queues(struct nfp_hw *hw)
204 {
205 	int ret;
206 	uint32_t update;
207 	uint32_t new_ctrl;
208 
209 	nn_cfg_writeq(hw, NFP_NET_CFG_TXRS_ENABLE, 0);
210 	nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, 0);
211 
212 	new_ctrl = hw->ctrl & ~NFP_NET_CFG_CTRL_ENABLE;
213 	update = NFP_NET_CFG_UPDATE_GEN |
214 			NFP_NET_CFG_UPDATE_RING |
215 			NFP_NET_CFG_UPDATE_MSIX;
216 
217 	if ((hw->cap & NFP_NET_CFG_CTRL_RINGCFG) != 0)
218 		new_ctrl &= ~NFP_NET_CFG_CTRL_RINGCFG;
219 
220 	/* If an error when reconfig we avoid to change hw state */
221 	ret = nfp_reconfig(hw, new_ctrl, update);
222 	if (ret < 0)
223 		return;
224 
225 	hw->ctrl = new_ctrl;
226 }
227