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