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 : : /*
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 : 0 : 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 : 0 : PMD_DRV_LOG(DEBUG, "Writing to the configuration queue (%p)...",
25 : : hw->qcp_cfg);
26 : :
27 [ # # ]: 0 : if (hw->qcp_cfg == NULL) {
28 : 0 : PMD_DRV_LOG(ERR, "Bad configuration queue pointer.");
29 : 0 : return -ENXIO;
30 : : }
31 : :
32 : : nfp_qcp_ptr_add(hw->qcp_cfg, NFP_QCP_WRITE_PTR, 1);
33 : :
34 : 0 : wait.tv_sec = 0;
35 : 0 : wait.tv_nsec = 1000000; /* 1ms */
36 : :
37 : 0 : PMD_DRV_LOG(DEBUG, "Polling for update ack...");
38 : :
39 : : /* Poll update field, waiting for NFP to ack the config */
40 : 0 : for (cnt = 0; ; cnt++) {
41 : 0 : new = nn_cfg_readl(hw, NFP_NET_CFG_UPDATE);
42 [ # # ]: 0 : if (new == 0)
43 : : break;
44 : :
45 [ # # ]: 0 : if ((new & NFP_NET_CFG_UPDATE_ERR) != 0) {
46 : 0 : PMD_DRV_LOG(ERR, "Reconfig error: %#08x.", new);
47 : 0 : return -1;
48 : : }
49 : :
50 [ # # ]: 0 : if (cnt >= NFP_NET_POLL_TIMEOUT) {
51 : 0 : PMD_DRV_LOG(ERR, "Reconfig timeout for %#08x after %u ms.",
52 : : update, cnt);
53 : 0 : return -EIO;
54 : : }
55 : :
56 : 0 : nanosleep(&wait, 0); /* waiting for a 1ms */
57 : : }
58 : :
59 : 0 : PMD_DRV_LOG(DEBUG, "Ack DONE.");
60 : 0 : 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 : 0 : nfp_reconfig(struct nfp_hw *hw,
82 : : uint32_t ctrl,
83 : : uint32_t update)
84 : : {
85 : : int ret;
86 : :
87 : 0 : 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 : 0 : ret = nfp_reconfig_real(hw, update);
95 : :
96 : : rte_spinlock_unlock(&hw->reconfig_lock);
97 : :
98 [ # # ]: 0 : if (ret != 0) {
99 : 0 : PMD_DRV_LOG(ERR, "Error NFP reconfig: ctrl=%#08x update=%#08x.",
100 : : ctrl, update);
101 : 0 : 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 : 0 : nfp_ext_reconfig(struct nfp_hw *hw,
126 : : uint32_t ctrl_ext,
127 : : uint32_t update)
128 : : {
129 : : int ret;
130 : :
131 : 0 : 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 : 0 : ret = nfp_reconfig_real(hw, update);
139 : :
140 : : rte_spinlock_unlock(&hw->reconfig_lock);
141 : :
142 [ # # ]: 0 : if (ret != 0) {
143 : 0 : PMD_DRV_LOG(ERR, "Error NFP ext reconfig: ctrl_ext=%#08x update=%#08x.",
144 : : ctrl_ext, update);
145 : 0 : return -EIO;
146 : : }
147 : :
148 : : return 0;
149 : : }
150 : :
151 : : void
152 : 0 : nfp_read_mac(struct nfp_hw *hw)
153 : : {
154 : : uint32_t tmp;
155 : :
156 : 0 : tmp = rte_be_to_cpu_32(nn_cfg_readl(hw, NFP_NET_CFG_MACADDR));
157 : 0 : memcpy(&hw->mac_addr.addr_bytes[0], &tmp, 4);
158 : :
159 : 0 : tmp = rte_be_to_cpu_32(nn_cfg_readl(hw, NFP_NET_CFG_MACADDR + 4));
160 : 0 : memcpy(&hw->mac_addr.addr_bytes[4], &tmp, 2);
161 : 0 : }
162 : :
163 : : void
164 : 0 : nfp_write_mac(struct nfp_hw *hw,
165 : : uint8_t *mac)
166 : : {
167 : : uint32_t mac0;
168 : : uint16_t mac1;
169 : :
170 : 0 : mac0 = *(uint32_t *)mac;
171 [ # # ]: 0 : nn_writel(rte_cpu_to_be_32(mac0), hw->ctrl_bar + NFP_NET_CFG_MACADDR);
172 : :
173 : : mac += 4;
174 : 0 : mac1 = *(uint16_t *)mac;
175 : 0 : nn_writew(rte_cpu_to_be_16(mac1),
176 [ # # ]: 0 : hw->ctrl_bar + NFP_NET_CFG_MACADDR + 6);
177 : 0 : }
178 : :
179 : : void
180 : 0 : 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 [ # # ]: 0 : for (i = 0; i < nb_tx_queues; i++)
190 : 0 : 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 [ # # ]: 0 : for (i = 0; i < nb_rx_queues; i++)
197 : 0 : enabled_queues |= (1ULL << i);
198 : :
199 : : nn_cfg_writeq(hw, NFP_NET_CFG_RXRS_ENABLE, enabled_queues);
200 : 0 : }
201 : :
202 : : void
203 : 0 : 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 : 0 : 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 [ # # ]: 0 : if ((hw->cap & NFP_NET_CFG_CTRL_RINGCFG) != 0)
218 : 0 : new_ctrl &= ~NFP_NET_CFG_CTRL_RINGCFG;
219 : :
220 : : /* If an error when reconfig we avoid to change hw state */
221 : 0 : ret = nfp_reconfig(hw, new_ctrl, update);
222 [ # # ]: 0 : if (ret < 0)
223 : : return;
224 : :
225 : 0 : hw->ctrl = new_ctrl;
226 : : }
|