Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Chelsio Communications.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <ethdev_driver.h>
7 : : #include <ethdev_pci.h>
8 : : #include <rte_malloc.h>
9 : :
10 : : #include "base/common.h"
11 : : #include "base/t4_regs.h"
12 : : #include "base/t4_msg.h"
13 : : #include "cxgbe.h"
14 : : #include "cxgbe_pfvf.h"
15 : : #include "mps_tcam.h"
16 : :
17 : : /*
18 : : * Figure out how many Ports and Queue Sets we can support. This depends on
19 : : * knowing our Virtual Function Resources and may be called a second time if
20 : : * we fall back from MSI-X to MSI Interrupt Mode.
21 : : */
22 : 0 : static void size_nports_qsets(struct adapter *adapter)
23 : : {
24 : : struct vf_resources *vfres = &adapter->params.vfres;
25 : : unsigned int pmask_nports;
26 : :
27 : : /*
28 : : * The number of "ports" which we support is equal to the number of
29 : : * Virtual Interfaces with which we've been provisioned.
30 : : */
31 : 0 : adapter->params.nports = vfres->nvi;
32 [ # # ]: 0 : if (adapter->params.nports > MAX_NPORTS) {
33 : 0 : dev_warn(adapter->pdev_dev, "only using %d of %d maximum"
34 : : " allowed virtual interfaces\n", MAX_NPORTS,
35 : : adapter->params.nports);
36 : 0 : adapter->params.nports = MAX_NPORTS;
37 : : }
38 : :
39 : : /*
40 : : * We may have been provisioned with more VIs than the number of
41 : : * ports we're allowed to access (our Port Access Rights Mask).
42 : : * This is obviously a configuration conflict but we don't want to
43 : : * do anything silly just because of that.
44 : : */
45 [ # # ]: 0 : pmask_nports = hweight32(adapter->params.vfres.pmask);
46 [ # # ]: 0 : if (pmask_nports < adapter->params.nports) {
47 : 0 : dev_warn(adapter->pdev_dev, "only using %d of %d provisioned"
48 : : " virtual interfaces; limited by Port Access Rights"
49 : : " mask %#x\n", pmask_nports, adapter->params.nports,
50 : : adapter->params.vfres.pmask);
51 : 0 : adapter->params.nports = pmask_nports;
52 : : }
53 : :
54 : 0 : cxgbe_configure_max_ethqsets(adapter);
55 [ # # ]: 0 : if (adapter->sge.max_ethqsets < adapter->params.nports) {
56 : 0 : dev_warn(adapter->pdev_dev, "only using %d of %d available"
57 : : " virtual interfaces (too few Queue Sets)\n",
58 : : adapter->sge.max_ethqsets, adapter->params.nports);
59 : 0 : adapter->params.nports = adapter->sge.max_ethqsets;
60 : : }
61 : 0 : }
62 : :
63 : 0 : void cxgbevf_stats_get(struct port_info *pi, struct port_stats *stats)
64 : : {
65 : 0 : t4vf_get_port_stats(pi->adapter, pi->pidx, stats);
66 : 0 : }
67 : :
68 : 0 : static int adap_init0vf(struct adapter *adapter)
69 : : {
70 : 0 : u32 param, val = 0;
71 : : int err;
72 : :
73 : 0 : err = t4vf_fw_reset(adapter);
74 [ # # ]: 0 : if (err < 0) {
75 : 0 : dev_err(adapter->pdev_dev, "FW reset failed: err=%d\n", err);
76 : 0 : return err;
77 : : }
78 : :
79 : : /*
80 : : * Grab basic operational parameters. These will predominantly have
81 : : * been set up by the Physical Function Driver or will be hard coded
82 : : * into the adapter. We just have to live with them ... Note that
83 : : * we _must_ get our VPD parameters before our SGE parameters because
84 : : * we need to know the adapter's core clock from the VPD in order to
85 : : * properly decode the SGE Timer Values.
86 : : */
87 : 0 : err = t4vf_get_dev_params(adapter);
88 [ # # ]: 0 : if (err) {
89 : 0 : dev_err(adapter->pdev_dev, "unable to retrieve adapter"
90 : : " device parameters: err=%d\n", err);
91 : 0 : return err;
92 : : }
93 : :
94 : 0 : err = t4vf_get_vpd_params(adapter);
95 [ # # ]: 0 : if (err) {
96 : 0 : dev_err(adapter->pdev_dev, "unable to retrieve adapter"
97 : : " VPD parameters: err=%d\n", err);
98 : 0 : return err;
99 : : }
100 : :
101 : 0 : adapter->pf = t4vf_get_pf_from_vf(adapter);
102 : 0 : err = t4vf_sge_init(adapter);
103 [ # # ]: 0 : if (err) {
104 : 0 : dev_err(adapter->pdev_dev, "error in sge init\n");
105 : 0 : return err;
106 : : }
107 : :
108 : 0 : err = t4vf_get_rss_glb_config(adapter);
109 [ # # ]: 0 : if (err) {
110 : 0 : dev_err(adapter->pdev_dev, "unable to retrieve adapter"
111 : : " RSS parameters: err=%d\n", err);
112 : 0 : return err;
113 : : }
114 [ # # ]: 0 : if (adapter->params.rss.mode !=
115 : : FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) {
116 : 0 : dev_err(adapter->pdev_dev, "unable to operate with global RSS"
117 : : " mode %d\n", adapter->params.rss.mode);
118 : 0 : return -EINVAL;
119 : : }
120 : :
121 : : /* If we're running on newer firmware, let it know that we're
122 : : * prepared to deal with encapsulated CPL messages. Older
123 : : * firmware won't understand this and we'll just get
124 : : * unencapsulated messages ...
125 : : */
126 : 0 : param = CXGBE_FW_PARAM_PFVF(CPLFW4MSG_ENCAP);
127 : 0 : val = 1;
128 : 0 : t4vf_set_params(adapter, 1, ¶m, &val);
129 : :
130 : : /* Query for max number of packets that can be coalesced for Tx */
131 : 0 : param = CXGBE_FW_PARAM_PFVF(MAX_PKTS_PER_ETH_TX_PKTS_WR);
132 : 0 : err = t4vf_query_params(adapter, 1, ¶m, &val);
133 [ # # # # ]: 0 : if (!err && val > 0)
134 : 0 : adapter->params.max_tx_coalesce_num = val;
135 : : else
136 : 0 : adapter->params.max_tx_coalesce_num = ETH_COALESCE_VF_PKT_NUM;
137 : :
138 : : /*
139 : : * Grab our Virtual Interface resource allocation, extract the
140 : : * features that we're interested in and do a bit of sanity testing on
141 : : * what we discover.
142 : : */
143 : 0 : err = t4vf_get_vfres(adapter);
144 [ # # ]: 0 : if (err) {
145 : 0 : dev_err(adapter->pdev_dev, "unable to get virtual interface"
146 : : " resources: err=%d\n", err);
147 : 0 : return err;
148 : : }
149 : :
150 : : /*
151 : : * Check for various parameter sanity issues.
152 : : */
153 [ # # ]: 0 : if (adapter->params.vfres.pmask == 0) {
154 : 0 : dev_err(adapter->pdev_dev, "no port access configured\n"
155 : : "usable!\n");
156 : 0 : return -EINVAL;
157 : : }
158 [ # # ]: 0 : if (adapter->params.vfres.nvi == 0) {
159 : 0 : dev_err(adapter->pdev_dev, "no virtual interfaces configured/"
160 : : "usable!\n");
161 : 0 : return -EINVAL;
162 : : }
163 : :
164 : : /*
165 : : * Initialize nports and max_ethqsets now that we have our Virtual
166 : : * Function Resources.
167 : : */
168 : 0 : size_nports_qsets(adapter);
169 : 0 : adapter->flags |= FW_OK;
170 : 0 : return 0;
171 : : }
172 : :
173 : 0 : int cxgbevf_probe(struct adapter *adapter)
174 : : {
175 : : struct port_info *pi;
176 : : unsigned int pmask;
177 : : int err = 0;
178 : : int i;
179 : :
180 : : t4_os_lock_init(&adapter->mbox_lock);
181 : 0 : TAILQ_INIT(&adapter->mbox_list);
182 : 0 : err = t4vf_prep_adapter(adapter);
183 [ # # ]: 0 : if (err)
184 : : return err;
185 : :
186 [ # # ]: 0 : if (!is_t4(adapter->params.chip)) {
187 : 0 : adapter->bar2 = (void *)adapter->pdev->mem_resource[2].addr;
188 [ # # ]: 0 : if (!adapter->bar2) {
189 : 0 : dev_err(adapter, "cannot map device bar2 region\n");
190 : : err = -ENOMEM;
191 : 0 : return err;
192 : : }
193 : : }
194 : :
195 : 0 : err = adap_init0vf(adapter);
196 [ # # ]: 0 : if (err) {
197 : 0 : dev_err(adapter, "%s: Adapter initialization failed, error %d\n",
198 : : __func__, err);
199 : 0 : goto out_free;
200 : : }
201 : :
202 : 0 : pmask = adapter->params.vfres.pmask;
203 [ # # ]: 0 : for_each_port(adapter, i) {
204 : 0 : const unsigned int numa_node = rte_socket_id();
205 : : char name[RTE_ETH_NAME_MAX_LEN];
206 : : struct rte_eth_dev *eth_dev;
207 : : int port_id;
208 : :
209 [ # # ]: 0 : if (pmask == 0)
210 : : break;
211 : 0 : port_id = ffs(pmask) - 1;
212 : 0 : pmask &= ~(1 << port_id);
213 : :
214 : 0 : snprintf(name, sizeof(name), "%s_%d",
215 [ # # ]: 0 : adapter->pdev->device.name, i);
216 : :
217 [ # # ]: 0 : if (i == 0) {
218 : : /* First port is already allocated by DPDK */
219 : 0 : eth_dev = adapter->eth_dev;
220 : 0 : goto allocate_mac;
221 : : }
222 : :
223 : : /*
224 : : * now do all data allocation - for eth_dev structure,
225 : : * and internal (private) data for the remaining ports
226 : : */
227 : :
228 : : /* reserve an ethdev entry */
229 : 0 : eth_dev = rte_eth_dev_allocate(name);
230 [ # # ]: 0 : if (!eth_dev) {
231 : : err = -ENOMEM;
232 : 0 : goto out_free;
233 : : }
234 : 0 : eth_dev->data->dev_private =
235 : 0 : rte_zmalloc_socket(name, sizeof(struct port_info),
236 : : RTE_CACHE_LINE_SIZE, numa_node);
237 [ # # ]: 0 : if (!eth_dev->data->dev_private)
238 : 0 : goto out_free;
239 : :
240 : 0 : allocate_mac:
241 : 0 : pi = eth_dev->data->dev_private;
242 : 0 : adapter->port[i] = pi;
243 : 0 : pi->eth_dev = eth_dev;
244 : 0 : pi->adapter = adapter;
245 : 0 : pi->xact_addr_filt = -1;
246 : 0 : pi->port_id = port_id;
247 : 0 : pi->pidx = i;
248 : :
249 : 0 : pi->eth_dev->device = &adapter->pdev->device;
250 : 0 : pi->eth_dev->dev_ops = adapter->eth_dev->dev_ops;
251 : 0 : pi->eth_dev->tx_pkt_burst = adapter->eth_dev->tx_pkt_burst;
252 : 0 : pi->eth_dev->rx_pkt_burst = adapter->eth_dev->rx_pkt_burst;
253 : :
254 : 0 : rte_eth_copy_pci_info(pi->eth_dev, adapter->pdev);
255 : 0 : pi->eth_dev->data->mac_addrs = rte_zmalloc(name,
256 : : RTE_ETHER_ADDR_LEN, 0);
257 [ # # ]: 0 : if (!pi->eth_dev->data->mac_addrs) {
258 : 0 : dev_err(adapter, "%s: Mem allocation failed for storing mac addr, aborting\n",
259 : : __func__);
260 : : err = -ENOMEM;
261 : 0 : goto out_free;
262 : : }
263 : :
264 [ # # ]: 0 : if (i > 0) {
265 : : /* First port will be notified by upper layer */
266 : 0 : rte_eth_dev_probing_finish(eth_dev);
267 : : }
268 : : }
269 : :
270 [ # # ]: 0 : if (adapter->flags & FW_OK) {
271 : 0 : err = t4vf_port_init(adapter);
272 [ # # ]: 0 : if (err) {
273 : 0 : dev_err(adapter, "%s: t4_port_init failed with err %d\n",
274 : : __func__, err);
275 : 0 : goto out_free;
276 : : }
277 : : }
278 : :
279 : 0 : err = cxgbe_cfg_queues(adapter->eth_dev);
280 [ # # ]: 0 : if (err)
281 : 0 : goto out_free;
282 : :
283 : 0 : cxgbe_print_adapter_info(adapter);
284 : 0 : cxgbe_print_port_info(adapter);
285 : :
286 : 0 : adapter->mpstcam = t4_init_mpstcam(adapter);
287 [ # # ]: 0 : if (!adapter->mpstcam)
288 : 0 : dev_warn(adapter,
289 : : "VF could not allocate mps tcam table. Continuing\n");
290 : :
291 : 0 : err = cxgbe_init_rss(adapter);
292 [ # # ]: 0 : if (err)
293 : 0 : goto out_free;
294 : : return 0;
295 : :
296 : 0 : out_free:
297 : 0 : cxgbe_cfg_queues_free(adapter);
298 : :
299 [ # # ]: 0 : for_each_port(adapter, i) {
300 : : pi = adap2pinfo(adapter, i);
301 [ # # ]: 0 : if (pi->viid != 0)
302 : 0 : t4_free_vi(adapter, adapter->mbox, adapter->pf,
303 : : 0, pi->viid);
304 : 0 : rte_eth_dev_release_port(pi->eth_dev);
305 : : }
306 : 0 : return -err;
307 : : }
|