Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2016 - 2018 Cavium Inc.
3 : : * All rights reserved.
4 : : * www.cavium.com
5 : : */
6 : :
7 : : #include <limits.h>
8 : :
9 : : #include <rte_alarm.h>
10 : : #include <rte_string_fns.h>
11 : :
12 : : #include "eal_firmware.h"
13 : :
14 : : #include "qede_ethdev.h"
15 : : /* ######### DEBUG ###########*/
16 : : #include "qede_debug.h"
17 : :
18 : : /* Alarm timeout. */
19 : : #define QEDE_ALARM_TIMEOUT_US 100000
20 : :
21 : : /* Global variable to hold absolute path of fw file */
22 : : char qede_fw_file[PATH_MAX];
23 : :
24 : : static const char * const QEDE_DEFAULT_FIRMWARE =
25 : : "/lib/firmware/qed/qed_init_values-8.40.33.0.bin";
26 : :
27 : : static void
28 : 0 : qed_update_pf_params(struct ecore_dev *edev, struct ecore_pf_params *params)
29 : : {
30 : : int i;
31 : :
32 [ # # ]: 0 : for (i = 0; i < edev->num_hwfns; i++) {
33 : : struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
34 : 0 : p_hwfn->pf_params = *params;
35 : : }
36 : 0 : }
37 : :
38 : : static void qed_init_pci(struct ecore_dev *edev, struct rte_pci_device *pci_dev)
39 : : {
40 : 0 : edev->regview = pci_dev->mem_resource[0].addr;
41 : 0 : edev->doorbells = pci_dev->mem_resource[2].addr;
42 : 0 : edev->db_size = pci_dev->mem_resource[2].len;
43 [ # # ]: 0 : edev->pci_dev = pci_dev;
44 : : }
45 : :
46 : : static int
47 : 0 : qed_probe(struct ecore_dev *edev, struct rte_pci_device *pci_dev,
48 : : uint32_t dp_module, uint8_t dp_level, bool is_vf)
49 : : {
50 : : struct ecore_hw_prepare_params hw_prepare_params;
51 : : int rc;
52 : :
53 : 0 : ecore_init_struct(edev);
54 : 0 : edev->drv_type = DRV_ID_DRV_TYPE_LINUX;
55 : : /* Protocol type is always fixed to PROTOCOL_ETH */
56 : :
57 [ # # ]: 0 : if (is_vf)
58 : 0 : edev->b_is_vf = true;
59 : :
60 : 0 : ecore_init_dp(edev, dp_module, dp_level, NULL);
61 : : qed_init_pci(edev, pci_dev);
62 : :
63 : : memset(&hw_prepare_params, 0, sizeof(hw_prepare_params));
64 : :
65 [ # # ]: 0 : if (is_vf)
66 : 0 : hw_prepare_params.acquire_retry_cnt = ECORE_VF_ACQUIRE_THRESH;
67 : :
68 : : hw_prepare_params.personality = ECORE_PCI_ETH;
69 : : hw_prepare_params.drv_resc_alloc = false;
70 : : hw_prepare_params.chk_reg_fifo = false;
71 : 0 : hw_prepare_params.initiate_pf_flr = true;
72 : : hw_prepare_params.allow_mdump = false;
73 : : hw_prepare_params.b_en_pacing = false;
74 : 0 : hw_prepare_params.epoch = OSAL_GET_EPOCH(ECORE_LEADING_HWFN(edev));
75 : 0 : rc = ecore_mz_mapping_alloc();
76 [ # # ]: 0 : if (rc) {
77 : 0 : DP_ERR(edev, "mem zones array allocation failed\n");
78 : 0 : return rc;
79 : : }
80 : :
81 : 0 : rc = ecore_hw_prepare(edev, &hw_prepare_params);
82 [ # # ]: 0 : if (rc) {
83 : 0 : DP_ERR(edev, "hw prepare failed\n");
84 : 0 : return rc;
85 : : }
86 : :
87 : : return rc;
88 : : }
89 : :
90 : 0 : static int qed_nic_setup(struct ecore_dev *edev)
91 : : {
92 : : int rc;
93 : :
94 : 0 : rc = ecore_resc_alloc(edev);
95 [ # # ]: 0 : if (rc)
96 : : return rc;
97 : :
98 : 0 : DP_INFO(edev, "Allocated qed resources\n");
99 : 0 : ecore_resc_setup(edev);
100 : :
101 : 0 : return rc;
102 : : }
103 : :
104 : : #ifdef CONFIG_ECORE_ZIPPED_FW
105 : : static int qed_alloc_stream_mem(struct ecore_dev *edev)
106 : : {
107 : : int i;
108 : :
109 : : for_each_hwfn(edev, i) {
110 : : struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
111 : :
112 : : p_hwfn->stream = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
113 : : sizeof(*p_hwfn->stream));
114 : : if (!p_hwfn->stream)
115 : : return -ENOMEM;
116 : : }
117 : :
118 : : return 0;
119 : : }
120 : :
121 : : static void qed_free_stream_mem(struct ecore_dev *edev)
122 : : {
123 : : int i;
124 : :
125 : : for_each_hwfn(edev, i) {
126 : : struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
127 : :
128 : : if (!p_hwfn->stream)
129 : : return;
130 : :
131 : : OSAL_FREE(p_hwfn->p_dev, p_hwfn->stream);
132 : : }
133 : : }
134 : : #endif
135 : :
136 : : #ifdef CONFIG_ECORE_BINARY_FW
137 : 0 : static int qed_load_firmware_data(struct ecore_dev *edev)
138 : : {
139 : : const char *fw = RTE_LIBRTE_QEDE_FW;
140 : : void *buf;
141 : : size_t bufsz;
142 : : int ret;
143 : :
144 : : if (strcmp(fw, "") == 0)
145 : : strcpy(qede_fw_file, QEDE_DEFAULT_FIRMWARE);
146 : : else
147 : : strcpy(qede_fw_file, fw);
148 : :
149 [ # # ]: 0 : if (rte_firmware_read(qede_fw_file, &buf, &bufsz) < 0) {
150 : 0 : DP_ERR(edev, "Can't read firmware data: %s\n", qede_fw_file);
151 : 0 : return -1;
152 : : }
153 : :
154 : 0 : edev->firmware = rte_zmalloc("qede_fw", bufsz, RTE_CACHE_LINE_SIZE);
155 [ # # ]: 0 : if (!edev->firmware) {
156 : 0 : DP_ERR(edev, "Can't allocate memory for firmware\n");
157 : : ret = -ENOMEM;
158 : 0 : goto out;
159 : : }
160 : :
161 [ # # ]: 0 : memcpy(edev->firmware, buf, bufsz);
162 : 0 : edev->fw_len = bufsz;
163 [ # # ]: 0 : if (edev->fw_len < 104) {
164 : 0 : DP_ERR(edev, "Invalid fw size: %" PRIu64 "\n",
165 : : edev->fw_len);
166 : : ret = -EINVAL;
167 : 0 : goto out;
168 : : }
169 : : ret = 0;
170 : 0 : out:
171 : 0 : free(buf);
172 : 0 : return ret;
173 : : }
174 : : #endif
175 : :
176 : 0 : static void qed_handle_bulletin_change(struct ecore_hwfn *hwfn)
177 : : {
178 : : uint8_t mac[ETH_ALEN], is_mac_exist, is_mac_forced;
179 : :
180 : 0 : is_mac_exist = ecore_vf_bulletin_get_forced_mac(hwfn, mac,
181 : : &is_mac_forced);
182 [ # # # # ]: 0 : if (is_mac_exist && is_mac_forced)
183 [ # # ]: 0 : rte_memcpy(hwfn->hw_info.hw_mac_addr, mac, ETH_ALEN);
184 : :
185 : : /* Always update link configuration according to bulletin */
186 : 0 : qed_link_update(hwfn);
187 : 0 : }
188 : :
189 : 0 : static void qede_vf_task(void *arg)
190 : : {
191 : : struct ecore_hwfn *p_hwfn = arg;
192 : 0 : uint8_t change = 0;
193 : :
194 : : /* Read the bulletin board, and re-schedule the task */
195 : 0 : ecore_vf_read_bulletin(p_hwfn, &change);
196 [ # # ]: 0 : if (change)
197 : 0 : qed_handle_bulletin_change(p_hwfn);
198 : :
199 : 0 : rte_eal_alarm_set(QEDE_ALARM_TIMEOUT_US, qede_vf_task, p_hwfn);
200 : 0 : }
201 : :
202 : 0 : static void qed_start_iov_task(struct ecore_dev *edev)
203 : : {
204 : : struct ecore_hwfn *p_hwfn;
205 : : int i;
206 : :
207 [ # # ]: 0 : for_each_hwfn(edev, i) {
208 : 0 : p_hwfn = &edev->hwfns[i];
209 [ # # ]: 0 : if (!IS_PF(edev))
210 : 0 : rte_eal_alarm_set(QEDE_ALARM_TIMEOUT_US, qede_vf_task,
211 : : p_hwfn);
212 : : }
213 : 0 : }
214 : :
215 : 0 : static void qed_stop_iov_task(struct ecore_dev *edev)
216 : : {
217 : : struct ecore_hwfn *p_hwfn;
218 : : int i;
219 : :
220 [ # # ]: 0 : for_each_hwfn(edev, i) {
221 : 0 : p_hwfn = &edev->hwfns[i];
222 [ # # ]: 0 : if (IS_PF(edev))
223 : 0 : rte_eal_alarm_cancel(qed_iov_pf_task, p_hwfn);
224 : : else
225 : 0 : rte_eal_alarm_cancel(qede_vf_task, p_hwfn);
226 : : }
227 : 0 : }
228 : 0 : static int qed_slowpath_start(struct ecore_dev *edev,
229 : : struct qed_slowpath_params *params)
230 : : {
231 : : struct ecore_drv_load_params drv_load_params;
232 : : struct ecore_hw_init_params hw_init_params;
233 : : struct ecore_mcp_drv_version drv_version;
234 : : const uint8_t *data = NULL;
235 : : struct ecore_hwfn *hwfn;
236 : : struct ecore_ptt *p_ptt;
237 : : int rc;
238 : :
239 [ # # ]: 0 : if (IS_PF(edev)) {
240 : : #ifdef CONFIG_ECORE_BINARY_FW
241 : 0 : rc = qed_load_firmware_data(edev);
242 [ # # ]: 0 : if (rc) {
243 : 0 : DP_ERR(edev, "Failed to find fw file %s\n",
244 : : qede_fw_file);
245 : 0 : goto err;
246 : : }
247 : : #endif
248 : 0 : hwfn = ECORE_LEADING_HWFN(edev);
249 [ # # ]: 0 : if (edev->num_hwfns == 1) { /* skip aRFS for 100G device */
250 : 0 : p_ptt = ecore_ptt_acquire(hwfn);
251 [ # # ]: 0 : if (p_ptt) {
252 : 0 : ECORE_LEADING_HWFN(edev)->p_arfs_ptt = p_ptt;
253 : : } else {
254 : 0 : DP_ERR(edev, "Failed to acquire PTT for flowdir\n");
255 : : rc = -ENOMEM;
256 : 0 : goto err;
257 : : }
258 : : }
259 : : }
260 : :
261 : 0 : rc = qed_nic_setup(edev);
262 [ # # ]: 0 : if (rc)
263 : 0 : goto err;
264 : :
265 : : /* set int_coalescing_mode */
266 : 0 : edev->int_coalescing_mode = ECORE_COAL_MODE_ENABLE;
267 : :
268 : : #ifdef CONFIG_ECORE_ZIPPED_FW
269 : : if (IS_PF(edev)) {
270 : : /* Allocate stream for unzipping */
271 : : rc = qed_alloc_stream_mem(edev);
272 : : if (rc) {
273 : : DP_ERR(edev, "Failed to allocate stream memory\n");
274 : : goto err1;
275 : : }
276 : : }
277 : : #endif
278 : :
279 : 0 : qed_start_iov_task(edev);
280 : :
281 : : #ifdef CONFIG_ECORE_BINARY_FW
282 [ # # ]: 0 : if (IS_PF(edev)) {
283 : 0 : data = (const uint8_t *)edev->firmware + sizeof(u32);
284 : :
285 : : /* ############### DEBUG ################## */
286 : 0 : qed_dbg_pf_init(edev);
287 : : }
288 : : #endif
289 : :
290 : :
291 : : /* Start the slowpath */
292 : : memset(&hw_init_params, 0, sizeof(hw_init_params));
293 : 0 : hw_init_params.b_hw_start = true;
294 : 0 : hw_init_params.int_mode = params->int_mode;
295 : 0 : hw_init_params.allow_npar_tx_switch = true;
296 : 0 : hw_init_params.bin_fw_data = data;
297 : :
298 : : memset(&drv_load_params, 0, sizeof(drv_load_params));
299 : : drv_load_params.mfw_timeout_val = ECORE_LOAD_REQ_LOCK_TO_DEFAULT;
300 : : drv_load_params.avoid_eng_reset = false;
301 : 0 : drv_load_params.override_force_load = ECORE_OVERRIDE_FORCE_LOAD_ALWAYS;
302 : : hw_init_params.avoid_eng_affin = false;
303 : 0 : hw_init_params.p_drv_load_params = &drv_load_params;
304 : :
305 : 0 : rc = ecore_hw_init(edev, &hw_init_params);
306 [ # # ]: 0 : if (rc) {
307 : 0 : DP_ERR(edev, "ecore_hw_init failed\n");
308 : 0 : goto err2;
309 : : }
310 : :
311 : 0 : DP_INFO(edev, "HW inited and function started\n");
312 : :
313 [ # # ]: 0 : if (IS_PF(edev)) {
314 : 0 : hwfn = ECORE_LEADING_HWFN(edev);
315 : 0 : drv_version.version = (params->drv_major << 24) |
316 : 0 : (params->drv_minor << 16) |
317 : 0 : (params->drv_rev << 8) | (params->drv_eng);
318 : 0 : strlcpy((char *)drv_version.name, (const char *)params->name,
319 : : sizeof(drv_version.name));
320 : 0 : rc = ecore_mcp_send_drv_version(hwfn, hwfn->p_main_ptt,
321 : : &drv_version);
322 [ # # ]: 0 : if (rc) {
323 : 0 : DP_ERR(edev, "Failed sending drv version command\n");
324 : 0 : goto err3;
325 : : }
326 : : }
327 : :
328 : 0 : ecore_reset_vport_stats(edev);
329 : :
330 : 0 : return 0;
331 : :
332 : : err3:
333 : 0 : ecore_hw_stop(edev);
334 : 0 : err2:
335 : 0 : qed_stop_iov_task(edev);
336 : : #ifdef CONFIG_ECORE_ZIPPED_FW
337 : : qed_free_stream_mem(edev);
338 : : err1:
339 : : #endif
340 : 0 : ecore_resc_free(edev);
341 : 0 : err:
342 : : #ifdef CONFIG_ECORE_BINARY_FW
343 [ # # ]: 0 : if (IS_PF(edev)) {
344 : 0 : rte_free(edev->firmware);
345 : 0 : edev->firmware = NULL;
346 : : }
347 : : #endif
348 : 0 : qed_stop_iov_task(edev);
349 : :
350 : 0 : return rc;
351 : : }
352 : :
353 : : static int
354 : 0 : qed_fill_dev_info(struct ecore_dev *edev, struct qed_dev_info *dev_info)
355 : : {
356 [ # # ]: 0 : struct ecore_hwfn *p_hwfn = ECORE_LEADING_HWFN(edev);
357 : : struct ecore_ptt *ptt = NULL;
358 : : struct ecore_tunnel_info *tun = &edev->tunnel;
359 : :
360 : : memset(dev_info, 0, sizeof(struct qed_dev_info));
361 : :
362 [ # # ]: 0 : if (tun->vxlan.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN &&
363 [ # # ]: 0 : tun->vxlan.b_mode_enabled)
364 : 0 : dev_info->vxlan_enable = true;
365 : :
366 [ # # # # ]: 0 : if (tun->l2_gre.b_mode_enabled && tun->ip_gre.b_mode_enabled &&
367 [ # # ]: 0 : tun->l2_gre.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN &&
368 [ # # ]: 0 : tun->ip_gre.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN)
369 : 0 : dev_info->gre_enable = true;
370 : :
371 [ # # # # ]: 0 : if (tun->l2_geneve.b_mode_enabled && tun->ip_geneve.b_mode_enabled &&
372 [ # # ]: 0 : tun->l2_geneve.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN &&
373 [ # # ]: 0 : tun->ip_geneve.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN)
374 : 0 : dev_info->geneve_enable = true;
375 : :
376 : 0 : dev_info->num_hwfns = edev->num_hwfns;
377 : 0 : dev_info->is_mf_default = IS_MF_DEFAULT(&edev->hwfns[0]);
378 : 0 : dev_info->mtu = ECORE_LEADING_HWFN(edev)->hw_info.mtu;
379 : 0 : dev_info->dev_type = edev->type;
380 : :
381 [ # # ]: 0 : memcpy(&dev_info->hw_mac, &edev->hwfns[0].hw_info.hw_mac_addr,
382 : : RTE_ETHER_ADDR_LEN);
383 : :
384 : 0 : dev_info->fw_major = FW_MAJOR_VERSION;
385 : 0 : dev_info->fw_minor = FW_MINOR_VERSION;
386 : 0 : dev_info->fw_rev = FW_REVISION_VERSION;
387 : : dev_info->fw_eng = FW_ENGINEERING_VERSION;
388 : :
389 [ # # ]: 0 : if (IS_PF(edev)) {
390 : 0 : dev_info->b_inter_pf_switch =
391 : 0 : OSAL_GET_BIT(ECORE_MF_INTER_PF_SWITCH, &edev->mf_bits);
392 [ # # ]: 0 : if (!OSAL_GET_BIT(ECORE_MF_DISABLE_ARFS, &edev->mf_bits))
393 : 0 : dev_info->b_arfs_capable = true;
394 : : dev_info->tx_switching = false;
395 : :
396 : 0 : dev_info->smart_an = ecore_mcp_is_smart_an_supported(p_hwfn);
397 : :
398 : 0 : ptt = ecore_ptt_acquire(ECORE_LEADING_HWFN(edev));
399 [ # # ]: 0 : if (ptt) {
400 : 0 : ecore_mcp_get_mfw_ver(ECORE_LEADING_HWFN(edev), ptt,
401 : 0 : &dev_info->mfw_rev, NULL);
402 : :
403 : 0 : ecore_mcp_get_mbi_ver(ECORE_LEADING_HWFN(edev), ptt,
404 : 0 : &dev_info->mbi_version);
405 : :
406 : 0 : ecore_mcp_get_flash_size(ECORE_LEADING_HWFN(edev), ptt,
407 : 0 : &dev_info->flash_size);
408 : :
409 : : /* Workaround to allow PHY-read commands for
410 : : * B0 bringup.
411 : : */
412 [ # # # # : 0 : if (ECORE_IS_BB_B0(edev))
# # # # ]
413 : 0 : dev_info->flash_size = 0xffffffff;
414 : :
415 : 0 : ecore_ptt_release(ECORE_LEADING_HWFN(edev), ptt);
416 : : }
417 : : } else {
418 : 0 : ecore_mcp_get_mfw_ver(ECORE_LEADING_HWFN(edev), ptt,
419 : 0 : &dev_info->mfw_rev, NULL);
420 : : }
421 : :
422 : 0 : return 0;
423 : : }
424 : :
425 : : int
426 : 0 : qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
427 : : {
428 [ # # ]: 0 : uint8_t queues = 0;
429 : : int i;
430 : :
431 : : memset(info, 0, sizeof(*info));
432 : :
433 : 0 : info->num_tc = 1 /* @@@TBD aelior MULTI_COS */;
434 : :
435 [ # # ]: 0 : if (IS_PF(edev)) {
436 : : int max_vf_vlan_filters = 0;
437 : :
438 : : info->num_queues = 0;
439 [ # # ]: 0 : for_each_hwfn(edev, i)
440 : 0 : info->num_queues +=
441 : 0 : FEAT_NUM(&edev->hwfns[i], ECORE_PF_L2_QUE);
442 : :
443 [ # # ]: 0 : if (IS_ECORE_SRIOV(edev))
444 : 0 : max_vf_vlan_filters = edev->p_iov_info->total_vfs *
445 : : ECORE_ETH_VF_NUM_VLAN_FILTERS;
446 : 0 : info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN) -
447 : : max_vf_vlan_filters;
448 : :
449 : 0 : memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr,
450 : : RTE_ETHER_ADDR_LEN);
451 : : } else {
452 : 0 : ecore_vf_get_num_rxqs(ECORE_LEADING_HWFN(edev),
453 : 0 : &info->num_queues);
454 [ # # ]: 0 : if (ECORE_IS_CMT(edev)) {
455 : 0 : ecore_vf_get_num_rxqs(&edev->hwfns[1], &queues);
456 : 0 : info->num_queues += queues;
457 : : }
458 : :
459 : 0 : ecore_vf_get_num_vlan_filters(&edev->hwfns[0],
460 : 0 : (u8 *)&info->num_vlan_filters);
461 : :
462 : 0 : ecore_vf_get_port_mac(&edev->hwfns[0],
463 : 0 : (uint8_t *)&info->port_mac);
464 : :
465 : 0 : info->is_legacy = ecore_vf_get_pre_fp_hsi(&edev->hwfns[0]);
466 : : }
467 : :
468 : 0 : qed_fill_dev_info(edev, &info->common);
469 : :
470 [ # # ]: 0 : if (IS_VF(edev))
471 : 0 : memset(&info->common.hw_mac, 0, RTE_ETHER_ADDR_LEN);
472 : :
473 : 0 : return 0;
474 : : }
475 : :
476 : 0 : static void qed_set_name(struct ecore_dev *edev, char name[NAME_SIZE])
477 : : {
478 : : int i;
479 : :
480 : 0 : memcpy(edev->name, name, NAME_SIZE);
481 [ # # ]: 0 : for_each_hwfn(edev, i) {
482 : 0 : snprintf(edev->hwfns[i].name, NAME_SIZE, "%s-%d", name, i);
483 : : }
484 : 0 : }
485 : :
486 : : static uint32_t
487 : 0 : qed_sb_init(struct ecore_dev *edev, struct ecore_sb_info *sb_info,
488 : : void *sb_virt_addr, dma_addr_t sb_phy_addr, uint16_t sb_id)
489 : : {
490 : : struct ecore_hwfn *p_hwfn;
491 : : int hwfn_index;
492 : : uint16_t rel_sb_id;
493 : 0 : uint8_t n_hwfns = edev->num_hwfns;
494 : : uint32_t rc;
495 : :
496 : 0 : hwfn_index = sb_id % n_hwfns;
497 : 0 : p_hwfn = &edev->hwfns[hwfn_index];
498 : 0 : rel_sb_id = sb_id / n_hwfns;
499 : :
500 : 0 : DP_INFO(edev, "hwfn [%d] <--[init]-- SB %04x [0x%04x upper]\n",
501 : : hwfn_index, rel_sb_id, sb_id);
502 : :
503 : 0 : rc = ecore_int_sb_init(p_hwfn, p_hwfn->p_main_ptt, sb_info,
504 : : sb_virt_addr, sb_phy_addr, rel_sb_id);
505 : :
506 : 0 : return rc;
507 : : }
508 : :
509 : 0 : static void qed_fill_link(struct ecore_hwfn *hwfn,
510 : : __rte_unused struct ecore_ptt *ptt,
511 : : struct qed_link_output *if_link)
512 : : {
513 : : struct ecore_mcp_link_params params;
514 : : struct ecore_mcp_link_state link;
515 : : struct ecore_mcp_link_capabilities link_caps;
516 [ # # ]: 0 : uint8_t change = 0;
517 : :
518 : : memset(if_link, 0, sizeof(*if_link));
519 : :
520 : : /* Prepare source inputs */
521 [ # # ]: 0 : if (IS_PF(hwfn->p_dev)) {
522 : 0 : memcpy(¶ms, ecore_mcp_get_link_params(hwfn), sizeof(params));
523 : 0 : memcpy(&link, ecore_mcp_get_link_state(hwfn), sizeof(link));
524 : 0 : memcpy(&link_caps, ecore_mcp_get_link_capabilities(hwfn),
525 : : sizeof(link_caps));
526 : : } else {
527 : 0 : ecore_vf_read_bulletin(hwfn, &change);
528 : 0 : ecore_vf_get_link_params(hwfn, ¶ms);
529 : 0 : ecore_vf_get_link_state(hwfn, &link);
530 : 0 : ecore_vf_get_link_caps(hwfn, &link_caps);
531 : : }
532 : :
533 : : /* Set the link parameters to pass to protocol driver */
534 [ # # ]: 0 : if (link.link_up)
535 : 0 : if_link->link_up = true;
536 : :
537 [ # # ]: 0 : if (link.link_up)
538 : 0 : if_link->speed = link.speed;
539 : :
540 : 0 : if_link->duplex = QEDE_DUPLEX_FULL;
541 : :
542 : : /* Fill up the native advertised speed cap mask */
543 : 0 : if_link->adv_speed = params.speed.advertised_speeds;
544 : :
545 [ # # ]: 0 : if (params.speed.autoneg)
546 : 0 : if_link->supported_caps |= QEDE_SUPPORTED_AUTONEG;
547 : :
548 [ # # ]: 0 : if (params.pause.autoneg || params.pause.forced_rx ||
549 : : params.pause.forced_tx)
550 : 0 : if_link->supported_caps |= QEDE_SUPPORTED_PAUSE;
551 : :
552 [ # # ]: 0 : if (params.pause.autoneg)
553 : 0 : if_link->pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE;
554 : :
555 [ # # ]: 0 : if (params.pause.forced_rx)
556 : 0 : if_link->pause_config |= QED_LINK_PAUSE_RX_ENABLE;
557 : :
558 [ # # ]: 0 : if (params.pause.forced_tx)
559 : 0 : if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE;
560 : :
561 [ # # ]: 0 : if (link_caps.default_eee == ECORE_MCP_EEE_UNSUPPORTED) {
562 : 0 : if_link->eee_supported = false;
563 : : } else {
564 : 0 : if_link->eee_supported = true;
565 : 0 : if_link->eee_active = link.eee_active;
566 : 0 : if_link->sup_caps = link_caps.eee_speed_caps;
567 : : /* MFW clears adv_caps on eee disable; use configured value */
568 [ # # ]: 0 : if_link->eee.adv_caps = link.eee_adv_caps ? link.eee_adv_caps :
569 : : params.eee.adv_caps;
570 : 0 : if_link->eee.lp_adv_caps = link.eee_lp_adv_caps;
571 : 0 : if_link->eee.enable = params.eee.enable;
572 : 0 : if_link->eee.tx_lpi_enable = params.eee.tx_lpi_enable;
573 : 0 : if_link->eee.tx_lpi_timer = params.eee.tx_lpi_timer;
574 : : }
575 : 0 : }
576 : :
577 : : static void
578 : 0 : qed_get_current_link(struct ecore_dev *edev, struct qed_link_output *if_link)
579 : : {
580 : : struct ecore_hwfn *hwfn;
581 : : struct ecore_ptt *ptt;
582 : :
583 : 0 : hwfn = &edev->hwfns[0];
584 [ # # ]: 0 : if (IS_PF(edev)) {
585 : 0 : ptt = ecore_ptt_acquire(hwfn);
586 [ # # ]: 0 : if (ptt) {
587 : 0 : qed_fill_link(hwfn, ptt, if_link);
588 : 0 : ecore_ptt_release(hwfn, ptt);
589 : : } else {
590 : 0 : DP_NOTICE(hwfn, true, "Failed to fill link; No PTT\n");
591 : : }
592 : : } else {
593 : 0 : qed_fill_link(hwfn, NULL, if_link);
594 : : }
595 : 0 : }
596 : :
597 : 0 : static int qed_set_link(struct ecore_dev *edev, struct qed_link_params *params)
598 : : {
599 : : struct ecore_hwfn *hwfn;
600 : : struct ecore_ptt *ptt;
601 : : struct ecore_mcp_link_params *link_params;
602 : : int rc;
603 : :
604 [ # # ]: 0 : if (IS_VF(edev))
605 : : return 0;
606 : :
607 : : /* The link should be set only once per PF */
608 : 0 : hwfn = &edev->hwfns[0];
609 : :
610 : 0 : ptt = ecore_ptt_acquire(hwfn);
611 [ # # ]: 0 : if (!ptt)
612 : : return -EBUSY;
613 : :
614 : 0 : link_params = ecore_mcp_get_link_params(hwfn);
615 [ # # ]: 0 : if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG)
616 : 0 : link_params->speed.autoneg = params->autoneg;
617 : :
618 [ # # ]: 0 : if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) {
619 [ # # ]: 0 : if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
620 : 0 : link_params->pause.autoneg = true;
621 : : else
622 : 0 : link_params->pause.autoneg = false;
623 [ # # ]: 0 : if (params->pause_config & QED_LINK_PAUSE_RX_ENABLE)
624 : 0 : link_params->pause.forced_rx = true;
625 : : else
626 : 0 : link_params->pause.forced_rx = false;
627 [ # # ]: 0 : if (params->pause_config & QED_LINK_PAUSE_TX_ENABLE)
628 : 0 : link_params->pause.forced_tx = true;
629 : : else
630 : 0 : link_params->pause.forced_tx = false;
631 : : }
632 : :
633 [ # # ]: 0 : if (params->override_flags & QED_LINK_OVERRIDE_EEE_CONFIG)
634 : 0 : memcpy(&link_params->eee, ¶ms->eee,
635 : : sizeof(link_params->eee));
636 : :
637 : 0 : rc = ecore_mcp_set_link(hwfn, ptt, params->link_up);
638 : :
639 : 0 : ecore_ptt_release(hwfn, ptt);
640 : :
641 : 0 : return rc;
642 : : }
643 : :
644 : 0 : void qed_link_update(struct ecore_hwfn *hwfn)
645 : : {
646 : 0 : struct ecore_dev *edev = hwfn->p_dev;
647 : : struct qede_dev *qdev = (struct qede_dev *)edev;
648 : 0 : struct rte_eth_dev *dev = (struct rte_eth_dev *)qdev->ethdev;
649 : : int rc;
650 : :
651 : 0 : rc = qede_link_update(dev, 0);
652 : 0 : qed_inform_vf_link_state(hwfn);
653 : :
654 [ # # ]: 0 : if (!rc)
655 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
656 : 0 : }
657 : :
658 : 0 : static int qed_drain(struct ecore_dev *edev)
659 : : {
660 : : struct ecore_hwfn *hwfn;
661 : : struct ecore_ptt *ptt;
662 : : int i, rc;
663 : :
664 [ # # ]: 0 : if (IS_VF(edev))
665 : : return 0;
666 : :
667 [ # # ]: 0 : for_each_hwfn(edev, i) {
668 : 0 : hwfn = &edev->hwfns[i];
669 : 0 : ptt = ecore_ptt_acquire(hwfn);
670 [ # # ]: 0 : if (!ptt) {
671 : 0 : DP_ERR(hwfn, "Failed to drain NIG; No PTT\n");
672 : 0 : return -EBUSY;
673 : : }
674 : 0 : rc = ecore_mcp_drain(hwfn, ptt);
675 [ # # ]: 0 : if (rc)
676 : 0 : return rc;
677 : 0 : ecore_ptt_release(hwfn, ptt);
678 : : }
679 : :
680 : : return 0;
681 : : }
682 : :
683 : 0 : static int qed_nic_stop(struct ecore_dev *edev)
684 : : {
685 : : int i, rc;
686 : :
687 : 0 : rc = ecore_hw_stop(edev);
688 [ # # ]: 0 : for (i = 0; i < edev->num_hwfns; i++) {
689 : : struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
690 : :
691 [ # # ]: 0 : if (p_hwfn->b_sp_dpc_enabled)
692 : 0 : p_hwfn->b_sp_dpc_enabled = false;
693 : : }
694 : 0 : return rc;
695 : : }
696 : :
697 : 0 : static int qed_slowpath_stop(struct ecore_dev *edev)
698 : : {
699 : : #ifdef CONFIG_QED_SRIOV
700 : : int i;
701 : : #endif
702 : :
703 [ # # ]: 0 : if (!edev)
704 : : return -ENODEV;
705 : :
706 : : if (IS_PF(edev)) {
707 : : #ifdef CONFIG_ECORE_ZIPPED_FW
708 : : qed_free_stream_mem(edev);
709 : : #endif
710 : :
711 : : #ifdef CONFIG_QED_SRIOV
712 : : if (IS_QED_ETH_IF(edev))
713 : : qed_sriov_disable(edev, true);
714 : : #endif
715 : : }
716 : :
717 : 0 : qed_nic_stop(edev);
718 : :
719 : 0 : ecore_resc_free(edev);
720 : 0 : qed_stop_iov_task(edev);
721 : :
722 : 0 : return 0;
723 : : }
724 : :
725 : 0 : static void qed_remove(struct ecore_dev *edev)
726 : : {
727 [ # # ]: 0 : if (!edev)
728 : : return;
729 : :
730 : 0 : ecore_hw_remove(edev);
731 : 0 : ecore_mz_mapping_free();
732 : : }
733 : :
734 : 0 : static int qed_send_drv_state(struct ecore_dev *edev, bool active)
735 : : {
736 : 0 : struct ecore_hwfn *hwfn = ECORE_LEADING_HWFN(edev);
737 : : struct ecore_ptt *ptt;
738 : : int status = 0;
739 : :
740 : 0 : ptt = ecore_ptt_acquire(hwfn);
741 [ # # ]: 0 : if (!ptt)
742 : : return -EAGAIN;
743 : :
744 [ # # ]: 0 : status = ecore_mcp_ov_update_driver_state(hwfn, ptt, active ?
745 : : ECORE_OV_DRIVER_STATE_ACTIVE :
746 : : ECORE_OV_DRIVER_STATE_DISABLED);
747 : :
748 : 0 : ecore_ptt_release(hwfn, ptt);
749 : :
750 : 0 : return status;
751 : : }
752 : :
753 : 0 : static int qed_get_sb_info(struct ecore_dev *edev, struct ecore_sb_info *sb,
754 : : u16 qid, struct ecore_sb_info_dbg *sb_dbg)
755 : : {
756 : 0 : struct ecore_hwfn *hwfn = &edev->hwfns[qid % edev->num_hwfns];
757 : : struct ecore_ptt *ptt;
758 : : int rc;
759 : :
760 [ # # ]: 0 : if (IS_VF(edev))
761 : : return -EINVAL;
762 : :
763 : 0 : ptt = ecore_ptt_acquire(hwfn);
764 [ # # ]: 0 : if (!ptt) {
765 : 0 : DP_ERR(hwfn, "Can't acquire PTT\n");
766 : 0 : return -EAGAIN;
767 : : }
768 : :
769 : : memset(sb_dbg, 0, sizeof(*sb_dbg));
770 : 0 : rc = ecore_int_get_sb_dbg(hwfn, ptt, sb, sb_dbg);
771 : :
772 : 0 : ecore_ptt_release(hwfn, ptt);
773 : 0 : return rc;
774 : : }
775 : :
776 : : const struct qed_common_ops qed_common_ops_pass = {
777 : : INIT_STRUCT_FIELD(probe, &qed_probe),
778 : : INIT_STRUCT_FIELD(update_pf_params, &qed_update_pf_params),
779 : : INIT_STRUCT_FIELD(slowpath_start, &qed_slowpath_start),
780 : : INIT_STRUCT_FIELD(set_name, &qed_set_name),
781 : : INIT_STRUCT_FIELD(chain_alloc, &ecore_chain_alloc),
782 : : INIT_STRUCT_FIELD(chain_free, &ecore_chain_free),
783 : : INIT_STRUCT_FIELD(sb_init, &qed_sb_init),
784 : : INIT_STRUCT_FIELD(get_sb_info, &qed_get_sb_info),
785 : : INIT_STRUCT_FIELD(get_link, &qed_get_current_link),
786 : : INIT_STRUCT_FIELD(set_link, &qed_set_link),
787 : : INIT_STRUCT_FIELD(drain, &qed_drain),
788 : : INIT_STRUCT_FIELD(slowpath_stop, &qed_slowpath_stop),
789 : : INIT_STRUCT_FIELD(remove, &qed_remove),
790 : : INIT_STRUCT_FIELD(send_drv_state, &qed_send_drv_state),
791 : : /* ############### DEBUG ####################*/
792 : :
793 : : INIT_STRUCT_FIELD(dbg_get_debug_engine, &qed_get_debug_engine),
794 : : INIT_STRUCT_FIELD(dbg_set_debug_engine, &qed_set_debug_engine),
795 : :
796 : : INIT_STRUCT_FIELD(dbg_protection_override,
797 : : &qed_dbg_protection_override),
798 : : INIT_STRUCT_FIELD(dbg_protection_override_size,
799 : : &qed_dbg_protection_override_size),
800 : :
801 : : INIT_STRUCT_FIELD(dbg_grc, &qed_dbg_grc),
802 : : INIT_STRUCT_FIELD(dbg_grc_size, &qed_dbg_grc_size),
803 : :
804 : : INIT_STRUCT_FIELD(dbg_idle_chk, &qed_dbg_idle_chk),
805 : : INIT_STRUCT_FIELD(dbg_idle_chk_size, &qed_dbg_idle_chk_size),
806 : :
807 : : INIT_STRUCT_FIELD(dbg_mcp_trace, &qed_dbg_mcp_trace),
808 : : INIT_STRUCT_FIELD(dbg_mcp_trace_size, &qed_dbg_mcp_trace_size),
809 : :
810 : : INIT_STRUCT_FIELD(dbg_fw_asserts, &qed_dbg_fw_asserts),
811 : : INIT_STRUCT_FIELD(dbg_fw_asserts_size, &qed_dbg_fw_asserts_size),
812 : :
813 : : INIT_STRUCT_FIELD(dbg_ilt, &qed_dbg_ilt),
814 : : INIT_STRUCT_FIELD(dbg_ilt_size, &qed_dbg_ilt_size),
815 : :
816 : : INIT_STRUCT_FIELD(dbg_reg_fifo_size, &qed_dbg_reg_fifo_size),
817 : : INIT_STRUCT_FIELD(dbg_reg_fifo, &qed_dbg_reg_fifo),
818 : :
819 : : INIT_STRUCT_FIELD(dbg_igu_fifo_size, &qed_dbg_igu_fifo_size),
820 : : INIT_STRUCT_FIELD(dbg_igu_fifo, &qed_dbg_igu_fifo),
821 : : };
822 : :
823 : : const struct qed_eth_ops qed_eth_ops_pass = {
824 : : INIT_STRUCT_FIELD(common, &qed_common_ops_pass),
825 : : INIT_STRUCT_FIELD(fill_dev_info, &qed_fill_eth_dev_info),
826 : : INIT_STRUCT_FIELD(sriov_configure, &qed_sriov_configure),
827 : : };
828 : :
829 : 0 : const struct qed_eth_ops *qed_get_eth_ops(void)
830 : : {
831 : 0 : return &qed_eth_ops_pass;
832 : : }
|