xref: /dpdk/drivers/net/qede/qede_main.c (revision a2dc43f31c47709145a65babfd73dbe5b0d26db2)
12ea6f76aSRasesh Mody /*
22ea6f76aSRasesh Mody  * Copyright (c) 2016 QLogic Corporation.
32ea6f76aSRasesh Mody  * All rights reserved.
42ea6f76aSRasesh Mody  * www.qlogic.com
52ea6f76aSRasesh Mody  *
62ea6f76aSRasesh Mody  * See LICENSE.qede_pmd for copyright and licensing details.
72ea6f76aSRasesh Mody  */
82ea6f76aSRasesh Mody 
92ea6f76aSRasesh Mody #include <limits.h>
10301ea2d7SRasesh Mody #include <time.h>
1186a2265eSRasesh Mody #include <rte_alarm.h>
122ea6f76aSRasesh Mody 
132ea6f76aSRasesh Mody #include "qede_ethdev.h"
142ea6f76aSRasesh Mody 
1586a2265eSRasesh Mody /* Alarm timeout. */
1686a2265eSRasesh Mody #define QEDE_ALARM_TIMEOUT_US 100000
1786a2265eSRasesh Mody 
182ea6f76aSRasesh Mody /* Global variable to hold absolute path of fw file */
192ea6f76aSRasesh Mody char fw_file[PATH_MAX];
202ea6f76aSRasesh Mody 
212ea6f76aSRasesh Mody const char *QEDE_DEFAULT_FIRMWARE =
2240cf1e75SRasesh Mody 	"/lib/firmware/qed/qed_init_values-8.30.12.0.bin";
232ea6f76aSRasesh Mody 
242ea6f76aSRasesh Mody static void
252ea6f76aSRasesh Mody qed_update_pf_params(struct ecore_dev *edev, struct ecore_pf_params *params)
262ea6f76aSRasesh Mody {
272ea6f76aSRasesh Mody 	int i;
282ea6f76aSRasesh Mody 
292ea6f76aSRasesh Mody 	for (i = 0; i < edev->num_hwfns; i++) {
302ea6f76aSRasesh Mody 		struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
312ea6f76aSRasesh Mody 		p_hwfn->pf_params = *params;
322ea6f76aSRasesh Mody 	}
332ea6f76aSRasesh Mody }
342ea6f76aSRasesh Mody 
352ea6f76aSRasesh Mody static void qed_init_pci(struct ecore_dev *edev, struct rte_pci_device *pci_dev)
362ea6f76aSRasesh Mody {
372ea6f76aSRasesh Mody 	edev->regview = pci_dev->mem_resource[0].addr;
382ea6f76aSRasesh Mody 	edev->doorbells = pci_dev->mem_resource[2].addr;
39e916697fSRasesh Mody 	edev->db_size = pci_dev->mem_resource[2].len;
402ea6f76aSRasesh Mody }
412ea6f76aSRasesh Mody 
422ea6f76aSRasesh Mody static int
432ea6f76aSRasesh Mody qed_probe(struct ecore_dev *edev, struct rte_pci_device *pci_dev,
444c4bdadfSHarish Patil 	  uint32_t dp_module, uint8_t dp_level, bool is_vf)
452ea6f76aSRasesh Mody {
4622d07d93SRasesh Mody 	struct ecore_hw_prepare_params hw_prepare_params;
472ea6f76aSRasesh Mody 	int rc;
482ea6f76aSRasesh Mody 
492ea6f76aSRasesh Mody 	ecore_init_struct(edev);
50de5588afSRasesh Mody 	edev->drv_type = DRV_ID_DRV_TYPE_LINUX;
514c4bdadfSHarish Patil 	/* Protocol type is always fixed to PROTOCOL_ETH */
52de5588afSRasesh Mody 
53c0bd1181SRasesh Mody 	if (is_vf)
542ea6f76aSRasesh Mody 		edev->b_is_vf = true;
55c0bd1181SRasesh Mody 
562ea6f76aSRasesh Mody 	ecore_init_dp(edev, dp_module, dp_level, NULL);
572ea6f76aSRasesh Mody 	qed_init_pci(edev, pci_dev);
5822d07d93SRasesh Mody 
5922d07d93SRasesh Mody 	memset(&hw_prepare_params, 0, sizeof(hw_prepare_params));
6022d07d93SRasesh Mody 	hw_prepare_params.personality = ECORE_PCI_ETH;
6122d07d93SRasesh Mody 	hw_prepare_params.drv_resc_alloc = false;
6222d07d93SRasesh Mody 	hw_prepare_params.chk_reg_fifo = false;
639e2f08a4SRasesh Mody 	hw_prepare_params.initiate_pf_flr = true;
643d5083f2SRasesh Mody 	hw_prepare_params.allow_mdump = false;
65f8da0cd6SRasesh Mody 	hw_prepare_params.epoch = (u32)time(NULL);
6622d07d93SRasesh Mody 	rc = ecore_hw_prepare(edev, &hw_prepare_params);
672ea6f76aSRasesh Mody 	if (rc) {
682ea6f76aSRasesh Mody 		DP_ERR(edev, "hw prepare failed\n");
692ea6f76aSRasesh Mody 		return rc;
702ea6f76aSRasesh Mody 	}
712ea6f76aSRasesh Mody 
722ea6f76aSRasesh Mody 	return rc;
732ea6f76aSRasesh Mody }
742ea6f76aSRasesh Mody 
752ea6f76aSRasesh Mody static int qed_nic_setup(struct ecore_dev *edev)
762ea6f76aSRasesh Mody {
77af785e47SRasesh Mody 	int rc;
782ea6f76aSRasesh Mody 
792ea6f76aSRasesh Mody 	rc = ecore_resc_alloc(edev);
802ea6f76aSRasesh Mody 	if (rc)
812ea6f76aSRasesh Mody 		return rc;
822ea6f76aSRasesh Mody 
832ea6f76aSRasesh Mody 	DP_INFO(edev, "Allocated qed resources\n");
842ea6f76aSRasesh Mody 	ecore_resc_setup(edev);
852ea6f76aSRasesh Mody 
862ea6f76aSRasesh Mody 	return rc;
872ea6f76aSRasesh Mody }
882ea6f76aSRasesh Mody 
8948e8d239SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW
902ea6f76aSRasesh Mody static int qed_alloc_stream_mem(struct ecore_dev *edev)
912ea6f76aSRasesh Mody {
922ea6f76aSRasesh Mody 	int i;
932ea6f76aSRasesh Mody 
942ea6f76aSRasesh Mody 	for_each_hwfn(edev, i) {
952ea6f76aSRasesh Mody 		struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
962ea6f76aSRasesh Mody 
972ea6f76aSRasesh Mody 		p_hwfn->stream = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL,
982ea6f76aSRasesh Mody 					     sizeof(*p_hwfn->stream));
992ea6f76aSRasesh Mody 		if (!p_hwfn->stream)
1002ea6f76aSRasesh Mody 			return -ENOMEM;
1012ea6f76aSRasesh Mody 	}
1022ea6f76aSRasesh Mody 
1032ea6f76aSRasesh Mody 	return 0;
1042ea6f76aSRasesh Mody }
1052ea6f76aSRasesh Mody 
1062ea6f76aSRasesh Mody static void qed_free_stream_mem(struct ecore_dev *edev)
1072ea6f76aSRasesh Mody {
1082ea6f76aSRasesh Mody 	int i;
1092ea6f76aSRasesh Mody 
1102ea6f76aSRasesh Mody 	for_each_hwfn(edev, i) {
1112ea6f76aSRasesh Mody 		struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
1122ea6f76aSRasesh Mody 
1132ea6f76aSRasesh Mody 		if (!p_hwfn->stream)
1142ea6f76aSRasesh Mody 			return;
1152ea6f76aSRasesh Mody 
1162ea6f76aSRasesh Mody 		OSAL_FREE(p_hwfn->p_dev, p_hwfn->stream);
1172ea6f76aSRasesh Mody 	}
1182ea6f76aSRasesh Mody }
11948e8d239SRasesh Mody #endif
1202ea6f76aSRasesh Mody 
12148e8d239SRasesh Mody #ifdef CONFIG_ECORE_BINARY_FW
1222ea6f76aSRasesh Mody static int qed_load_firmware_data(struct ecore_dev *edev)
1232ea6f76aSRasesh Mody {
1242ea6f76aSRasesh Mody 	int fd;
1252ea6f76aSRasesh Mody 	struct stat st;
1262ea6f76aSRasesh Mody 	const char *fw = RTE_LIBRTE_QEDE_FW;
1272ea6f76aSRasesh Mody 
1282ea6f76aSRasesh Mody 	if (strcmp(fw, "") == 0)
1292ea6f76aSRasesh Mody 		strcpy(fw_file, QEDE_DEFAULT_FIRMWARE);
1302ea6f76aSRasesh Mody 	else
1312ea6f76aSRasesh Mody 		strcpy(fw_file, fw);
1322ea6f76aSRasesh Mody 
1332ea6f76aSRasesh Mody 	fd = open(fw_file, O_RDONLY);
1342ea6f76aSRasesh Mody 	if (fd < 0) {
1354ffa2af9SRasesh Mody 		DP_ERR(edev, "Can't open firmware file\n");
1362ea6f76aSRasesh Mody 		return -ENOENT;
1372ea6f76aSRasesh Mody 	}
1382ea6f76aSRasesh Mody 
1392ea6f76aSRasesh Mody 	if (fstat(fd, &st) < 0) {
1404ffa2af9SRasesh Mody 		DP_ERR(edev, "Can't stat firmware file\n");
1417bb4b070SYong Wang 		close(fd);
1422ea6f76aSRasesh Mody 		return -1;
1432ea6f76aSRasesh Mody 	}
1442ea6f76aSRasesh Mody 
1452ea6f76aSRasesh Mody 	edev->firmware = rte_zmalloc("qede_fw", st.st_size,
1462ea6f76aSRasesh Mody 				    RTE_CACHE_LINE_SIZE);
1472ea6f76aSRasesh Mody 	if (!edev->firmware) {
1484ffa2af9SRasesh Mody 		DP_ERR(edev, "Can't allocate memory for firmware\n");
1492ea6f76aSRasesh Mody 		close(fd);
1502ea6f76aSRasesh Mody 		return -ENOMEM;
1512ea6f76aSRasesh Mody 	}
1522ea6f76aSRasesh Mody 
1532ea6f76aSRasesh Mody 	if (read(fd, edev->firmware, st.st_size) != st.st_size) {
1544ffa2af9SRasesh Mody 		DP_ERR(edev, "Can't read firmware data\n");
1552ea6f76aSRasesh Mody 		close(fd);
1562ea6f76aSRasesh Mody 		return -1;
1572ea6f76aSRasesh Mody 	}
1582ea6f76aSRasesh Mody 
1592ea6f76aSRasesh Mody 	edev->fw_len = st.st_size;
1602ea6f76aSRasesh Mody 	if (edev->fw_len < 104) {
1614ffa2af9SRasesh Mody 		DP_ERR(edev, "Invalid fw size: %" PRIu64 "\n",
1622ea6f76aSRasesh Mody 			  edev->fw_len);
1637bb4b070SYong Wang 		close(fd);
1642ea6f76aSRasesh Mody 		return -EINVAL;
1652ea6f76aSRasesh Mody 	}
1662ea6f76aSRasesh Mody 
1677bb4b070SYong Wang 	close(fd);
1682ea6f76aSRasesh Mody 	return 0;
1692ea6f76aSRasesh Mody }
17048e8d239SRasesh Mody #endif
1712ea6f76aSRasesh Mody 
17286a2265eSRasesh Mody static void qed_handle_bulletin_change(struct ecore_hwfn *hwfn)
17386a2265eSRasesh Mody {
17486a2265eSRasesh Mody 	uint8_t mac[ETH_ALEN], is_mac_exist, is_mac_forced;
17586a2265eSRasesh Mody 
17686a2265eSRasesh Mody 	is_mac_exist = ecore_vf_bulletin_get_forced_mac(hwfn, mac,
17786a2265eSRasesh Mody 						      &is_mac_forced);
17886a2265eSRasesh Mody 	if (is_mac_exist && is_mac_forced)
17986a2265eSRasesh Mody 		rte_memcpy(hwfn->hw_info.hw_mac_addr, mac, ETH_ALEN);
18086a2265eSRasesh Mody 
18186a2265eSRasesh Mody 	/* Always update link configuration according to bulletin */
182739a5b2fSRasesh Mody 	qed_link_update(hwfn, NULL);
18386a2265eSRasesh Mody }
18486a2265eSRasesh Mody 
18586a2265eSRasesh Mody static void qede_vf_task(void *arg)
18686a2265eSRasesh Mody {
18786a2265eSRasesh Mody 	struct ecore_hwfn *p_hwfn = arg;
18886a2265eSRasesh Mody 	uint8_t change = 0;
18986a2265eSRasesh Mody 
19086a2265eSRasesh Mody 	/* Read the bulletin board, and re-schedule the task */
19186a2265eSRasesh Mody 	ecore_vf_read_bulletin(p_hwfn, &change);
19286a2265eSRasesh Mody 	if (change)
19386a2265eSRasesh Mody 		qed_handle_bulletin_change(p_hwfn);
19486a2265eSRasesh Mody 
19586a2265eSRasesh Mody 	rte_eal_alarm_set(QEDE_ALARM_TIMEOUT_US, qede_vf_task, p_hwfn);
19686a2265eSRasesh Mody }
19786a2265eSRasesh Mody 
19886a2265eSRasesh Mody static void qed_start_iov_task(struct ecore_dev *edev)
19986a2265eSRasesh Mody {
20086a2265eSRasesh Mody 	struct ecore_hwfn *p_hwfn;
20186a2265eSRasesh Mody 	int i;
20286a2265eSRasesh Mody 
20386a2265eSRasesh Mody 	for_each_hwfn(edev, i) {
20486a2265eSRasesh Mody 		p_hwfn = &edev->hwfns[i];
20586a2265eSRasesh Mody 		if (!IS_PF(edev))
20686a2265eSRasesh Mody 			rte_eal_alarm_set(QEDE_ALARM_TIMEOUT_US, qede_vf_task,
20786a2265eSRasesh Mody 					  p_hwfn);
20886a2265eSRasesh Mody 	}
20986a2265eSRasesh Mody }
21086a2265eSRasesh Mody 
21186a2265eSRasesh Mody static void qed_stop_iov_task(struct ecore_dev *edev)
21286a2265eSRasesh Mody {
21386a2265eSRasesh Mody 	struct ecore_hwfn *p_hwfn;
21486a2265eSRasesh Mody 	int i;
21586a2265eSRasesh Mody 
21686a2265eSRasesh Mody 	for_each_hwfn(edev, i) {
21786a2265eSRasesh Mody 		p_hwfn = &edev->hwfns[i];
21886a2265eSRasesh Mody 		if (!IS_PF(edev))
21986a2265eSRasesh Mody 			rte_eal_alarm_cancel(qede_vf_task, p_hwfn);
22086a2265eSRasesh Mody 	}
22186a2265eSRasesh Mody }
2222ea6f76aSRasesh Mody static int qed_slowpath_start(struct ecore_dev *edev,
2232ea6f76aSRasesh Mody 			      struct qed_slowpath_params *params)
2242ea6f76aSRasesh Mody {
225c5e11089SRasesh Mody 	struct ecore_drv_load_params drv_load_params;
226c5e11089SRasesh Mody 	struct ecore_hw_init_params hw_init_params;
227c5e11089SRasesh Mody 	struct ecore_mcp_drv_version drv_version;
2282ea6f76aSRasesh Mody 	const uint8_t *data = NULL;
2292ea6f76aSRasesh Mody 	struct ecore_hwfn *hwfn;
23062207535SHarish Patil 	struct ecore_ptt *p_ptt;
2312ea6f76aSRasesh Mody 	int rc;
2322ea6f76aSRasesh Mody 
23386a2265eSRasesh Mody 	if (IS_PF(edev)) {
23462207535SHarish Patil #ifdef CONFIG_ECORE_BINARY_FW
2352ea6f76aSRasesh Mody 		rc = qed_load_firmware_data(edev);
2362ea6f76aSRasesh Mody 		if (rc) {
237869c47d0SRasesh Mody 			DP_ERR(edev, "Failed to find fw file %s\n", fw_file);
2382ea6f76aSRasesh Mody 			goto err;
2392ea6f76aSRasesh Mody 		}
2402ea6f76aSRasesh Mody #endif
24162207535SHarish Patil 		hwfn = ECORE_LEADING_HWFN(edev);
24262207535SHarish Patil 		if (edev->num_hwfns == 1) { /* skip aRFS for 100G device */
24362207535SHarish Patil 			p_ptt = ecore_ptt_acquire(hwfn);
24462207535SHarish Patil 			if (p_ptt) {
24562207535SHarish Patil 				ECORE_LEADING_HWFN(edev)->p_arfs_ptt = p_ptt;
24662207535SHarish Patil 			} else {
24762207535SHarish Patil 				DP_ERR(edev, "Failed to acquire PTT for flowdir\n");
24862207535SHarish Patil 				rc = -ENOMEM;
24962207535SHarish Patil 				goto err;
25062207535SHarish Patil 			}
25162207535SHarish Patil 		}
25262207535SHarish Patil 	}
2532ea6f76aSRasesh Mody 
2542ea6f76aSRasesh Mody 	rc = qed_nic_setup(edev);
2552ea6f76aSRasesh Mody 	if (rc)
2562ea6f76aSRasesh Mody 		goto err;
2572ea6f76aSRasesh Mody 
2582ea6f76aSRasesh Mody 	/* set int_coalescing_mode */
2592ea6f76aSRasesh Mody 	edev->int_coalescing_mode = ECORE_COAL_MODE_ENABLE;
2602ea6f76aSRasesh Mody 
26148e8d239SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW
26286a2265eSRasesh Mody 	if (IS_PF(edev)) {
2632ea6f76aSRasesh Mody 		/* Allocate stream for unzipping */
2642ea6f76aSRasesh Mody 		rc = qed_alloc_stream_mem(edev);
2652ea6f76aSRasesh Mody 		if (rc) {
2664ffa2af9SRasesh Mody 			DP_ERR(edev, "Failed to allocate stream memory\n");
267c2069af8SRasesh Mody 			goto err1;
2682ea6f76aSRasesh Mody 		}
26986a2265eSRasesh Mody 	}
270af785e47SRasesh Mody #endif
27186a2265eSRasesh Mody 
27286a2265eSRasesh Mody 	qed_start_iov_task(edev);
2732ea6f76aSRasesh Mody 
27448e8d239SRasesh Mody #ifdef CONFIG_ECORE_BINARY_FW
27586a2265eSRasesh Mody 	if (IS_PF(edev))
27622d07d93SRasesh Mody 		data = (const uint8_t *)edev->firmware + sizeof(u32);
2772ea6f76aSRasesh Mody #endif
27822d07d93SRasesh Mody 
279301ea2d7SRasesh Mody 	/* Start the slowpath */
280301ea2d7SRasesh Mody 	memset(&hw_init_params, 0, sizeof(hw_init_params));
281301ea2d7SRasesh Mody 	hw_init_params.b_hw_start = true;
282301ea2d7SRasesh Mody 	hw_init_params.int_mode = ECORE_INT_MODE_MSIX;
28362207535SHarish Patil 	hw_init_params.allow_npar_tx_switch = true;
284301ea2d7SRasesh Mody 	hw_init_params.bin_fw_data = data;
285c5e11089SRasesh Mody 
286c5e11089SRasesh Mody 	memset(&drv_load_params, 0, sizeof(drv_load_params));
287c5e11089SRasesh Mody 	drv_load_params.mfw_timeout_val = ECORE_LOAD_REQ_LOCK_TO_DEFAULT;
288c5e11089SRasesh Mody 	drv_load_params.avoid_eng_reset = false;
289c5e11089SRasesh Mody 	drv_load_params.override_force_load = ECORE_OVERRIDE_FORCE_LOAD_ALWAYS;
290c5e11089SRasesh Mody 	hw_init_params.p_drv_load_params = &drv_load_params;
291c5e11089SRasesh Mody 
292301ea2d7SRasesh Mody 	rc = ecore_hw_init(edev, &hw_init_params);
2932ea6f76aSRasesh Mody 	if (rc) {
2942ea6f76aSRasesh Mody 		DP_ERR(edev, "ecore_hw_init failed\n");
2952ea6f76aSRasesh Mody 		goto err2;
2962ea6f76aSRasesh Mody 	}
2972ea6f76aSRasesh Mody 
2982ea6f76aSRasesh Mody 	DP_INFO(edev, "HW inited and function started\n");
2992ea6f76aSRasesh Mody 
30086a2265eSRasesh Mody 	if (IS_PF(edev)) {
3012ea6f76aSRasesh Mody 		hwfn = ECORE_LEADING_HWFN(edev);
3022ea6f76aSRasesh Mody 		drv_version.version = (params->drv_major << 24) |
3032ea6f76aSRasesh Mody 		    (params->drv_minor << 16) |
3042ea6f76aSRasesh Mody 		    (params->drv_rev << 8) | (params->drv_eng);
3052ea6f76aSRasesh Mody 		/* TBD: strlcpy() */
3062ea6f76aSRasesh Mody 		strncpy((char *)drv_version.name, (const char *)params->name,
3072ea6f76aSRasesh Mody 			MCP_DRV_VER_STR_SIZE - 4);
3082ea6f76aSRasesh Mody 		rc = ecore_mcp_send_drv_version(hwfn, hwfn->p_main_ptt,
3092ea6f76aSRasesh Mody 						&drv_version);
3102ea6f76aSRasesh Mody 		if (rc) {
3114ffa2af9SRasesh Mody 			DP_ERR(edev, "Failed sending drv version command\n");
312c2069af8SRasesh Mody 			goto err3;
3132ea6f76aSRasesh Mody 		}
31486a2265eSRasesh Mody 	}
3152ea6f76aSRasesh Mody 
3165cdd769aSRasesh Mody 	ecore_reset_vport_stats(edev);
3175cdd769aSRasesh Mody 
3182ea6f76aSRasesh Mody 	return 0;
3192ea6f76aSRasesh Mody 
320c2069af8SRasesh Mody err3:
3212ea6f76aSRasesh Mody 	ecore_hw_stop(edev);
3222ea6f76aSRasesh Mody err2:
323c2069af8SRasesh Mody 	qed_stop_iov_task(edev);
324c2069af8SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW
325c2069af8SRasesh Mody 	qed_free_stream_mem(edev);
326c2069af8SRasesh Mody err1:
327c2069af8SRasesh Mody #endif
3282ea6f76aSRasesh Mody 	ecore_resc_free(edev);
3292ea6f76aSRasesh Mody err:
33048e8d239SRasesh Mody #ifdef CONFIG_ECORE_BINARY_FW
33186a2265eSRasesh Mody 	if (IS_PF(edev)) {
3322ea6f76aSRasesh Mody 		if (edev->firmware)
3332ea6f76aSRasesh Mody 			rte_free(edev->firmware);
3342ea6f76aSRasesh Mody 		edev->firmware = NULL;
33586a2265eSRasesh Mody 	}
3362ea6f76aSRasesh Mody #endif
33786a2265eSRasesh Mody 	qed_stop_iov_task(edev);
33886a2265eSRasesh Mody 
3392ea6f76aSRasesh Mody 	return rc;
3402ea6f76aSRasesh Mody }
3412ea6f76aSRasesh Mody 
3422ea6f76aSRasesh Mody static int
3432ea6f76aSRasesh Mody qed_fill_dev_info(struct ecore_dev *edev, struct qed_dev_info *dev_info)
3442ea6f76aSRasesh Mody {
345652ee28aSRasesh Mody 	struct ecore_hwfn *p_hwfn = ECORE_LEADING_HWFN(edev);
3462ea6f76aSRasesh Mody 	struct ecore_ptt *ptt = NULL;
347a7f3cac3SRasesh Mody 	struct ecore_tunnel_info *tun = &edev->tunnel;
3482ea6f76aSRasesh Mody 
3492ea6f76aSRasesh Mody 	memset(dev_info, 0, sizeof(struct qed_dev_info));
350a7f3cac3SRasesh Mody 
351adce1f86SRasesh Mody 	if (tun->vxlan.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN &&
352adce1f86SRasesh Mody 	    tun->vxlan.b_mode_enabled)
353a7f3cac3SRasesh Mody 		dev_info->vxlan_enable = true;
354a7f3cac3SRasesh Mody 
355adce1f86SRasesh Mody 	if (tun->l2_gre.b_mode_enabled && tun->ip_gre.b_mode_enabled &&
356adce1f86SRasesh Mody 	    tun->l2_gre.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN &&
357adce1f86SRasesh Mody 	    tun->ip_gre.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN)
358a7f3cac3SRasesh Mody 		dev_info->gre_enable = true;
359a7f3cac3SRasesh Mody 
360adce1f86SRasesh Mody 	if (tun->l2_geneve.b_mode_enabled && tun->ip_geneve.b_mode_enabled &&
361adce1f86SRasesh Mody 	    tun->l2_geneve.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN &&
362adce1f86SRasesh Mody 	    tun->ip_geneve.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN)
363a7f3cac3SRasesh Mody 		dev_info->geneve_enable = true;
364a7f3cac3SRasesh Mody 
3652ea6f76aSRasesh Mody 	dev_info->num_hwfns = edev->num_hwfns;
3662ea6f76aSRasesh Mody 	dev_info->is_mf_default = IS_MF_DEFAULT(&edev->hwfns[0]);
3674fc58baeSRasesh Mody 	dev_info->mtu = ECORE_LEADING_HWFN(edev)->hw_info.mtu;
368dc8eba81SRasesh Mody 	dev_info->dev_type = edev->type;
3694fc58baeSRasesh Mody 
3702ea6f76aSRasesh Mody 	rte_memcpy(&dev_info->hw_mac, &edev->hwfns[0].hw_info.hw_mac_addr,
3712ea6f76aSRasesh Mody 	       ETHER_ADDR_LEN);
3722ea6f76aSRasesh Mody 
3732ea6f76aSRasesh Mody 	dev_info->fw_major = FW_MAJOR_VERSION;
3742ea6f76aSRasesh Mody 	dev_info->fw_minor = FW_MINOR_VERSION;
3752ea6f76aSRasesh Mody 	dev_info->fw_rev = FW_REVISION_VERSION;
3762ea6f76aSRasesh Mody 	dev_info->fw_eng = FW_ENGINEERING_VERSION;
377738f56d4SRasesh Mody 
378738f56d4SRasesh Mody 	if (IS_PF(edev)) {
37947af7019SRasesh Mody 		dev_info->b_inter_pf_switch =
38047af7019SRasesh Mody 			OSAL_TEST_BIT(ECORE_MF_INTER_PF_SWITCH, &edev->mf_bits);
381*a2dc43f3SRasesh Mody 		if (!OSAL_TEST_BIT(ECORE_MF_DISABLE_ARFS, &edev->mf_bits))
382*a2dc43f3SRasesh Mody 			dev_info->b_arfs_capable = true;
3832ea6f76aSRasesh Mody 		dev_info->tx_switching = false;
3842ea6f76aSRasesh Mody 
385652ee28aSRasesh Mody 		dev_info->smart_an = ecore_mcp_is_smart_an_supported(p_hwfn);
386652ee28aSRasesh Mody 
3872ea6f76aSRasesh Mody 		ptt = ecore_ptt_acquire(ECORE_LEADING_HWFN(edev));
3882ea6f76aSRasesh Mody 		if (ptt) {
38922d07d93SRasesh Mody 			ecore_mcp_get_mfw_ver(ECORE_LEADING_HWFN(edev), ptt,
3902ea6f76aSRasesh Mody 					      &dev_info->mfw_rev, NULL);
3912ea6f76aSRasesh Mody 
3922ea6f76aSRasesh Mody 			ecore_mcp_get_flash_size(ECORE_LEADING_HWFN(edev), ptt,
3932ea6f76aSRasesh Mody 						 &dev_info->flash_size);
3942ea6f76aSRasesh Mody 
3952ea6f76aSRasesh Mody 			/* Workaround to allow PHY-read commands for
3962ea6f76aSRasesh Mody 			 * B0 bringup.
3972ea6f76aSRasesh Mody 			 */
3982ea6f76aSRasesh Mody 			if (ECORE_IS_BB_B0(edev))
3992ea6f76aSRasesh Mody 				dev_info->flash_size = 0xffffffff;
4002ea6f76aSRasesh Mody 
4012ea6f76aSRasesh Mody 			ecore_ptt_release(ECORE_LEADING_HWFN(edev), ptt);
4022ea6f76aSRasesh Mody 		}
40386a2265eSRasesh Mody 	} else {
40422d07d93SRasesh Mody 		ecore_mcp_get_mfw_ver(ECORE_LEADING_HWFN(edev), ptt,
40522d07d93SRasesh Mody 				      &dev_info->mfw_rev, NULL);
40686a2265eSRasesh Mody 	}
4072ea6f76aSRasesh Mody 
4082ea6f76aSRasesh Mody 	return 0;
4092ea6f76aSRasesh Mody }
4102ea6f76aSRasesh Mody 
4112ea6f76aSRasesh Mody int
4122ea6f76aSRasesh Mody qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info)
4132ea6f76aSRasesh Mody {
414f1e4b6c0SHarish Patil 	uint8_t queues = 0;
4152ea6f76aSRasesh Mody 	int i;
4162ea6f76aSRasesh Mody 
4172ea6f76aSRasesh Mody 	memset(info, 0, sizeof(*info));
4182ea6f76aSRasesh Mody 
4192ea6f76aSRasesh Mody 	info->num_tc = 1 /* @@@TBD aelior MULTI_COS */;
4202ea6f76aSRasesh Mody 
42186a2265eSRasesh Mody 	if (IS_PF(edev)) {
422d6cb1753SHarish Patil 		int max_vf_vlan_filters = 0;
423d6cb1753SHarish Patil 
4242ea6f76aSRasesh Mody 		info->num_queues = 0;
4252ea6f76aSRasesh Mody 		for_each_hwfn(edev, i)
4262ea6f76aSRasesh Mody 			info->num_queues +=
4272ea6f76aSRasesh Mody 			FEAT_NUM(&edev->hwfns[i], ECORE_PF_L2_QUE);
4282ea6f76aSRasesh Mody 
429eafbc6fcSRasesh Mody 		if (IS_ECORE_SRIOV(edev))
430d6cb1753SHarish Patil 			max_vf_vlan_filters = edev->p_iov_info->total_vfs *
431d6cb1753SHarish Patil 					      ECORE_ETH_VF_NUM_VLAN_FILTERS;
432d6cb1753SHarish Patil 		info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN) -
433d6cb1753SHarish Patil 					 max_vf_vlan_filters;
4342ea6f76aSRasesh Mody 
4352ea6f76aSRasesh Mody 		rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr,
4362ea6f76aSRasesh Mody 			   ETHER_ADDR_LEN);
43786a2265eSRasesh Mody 	} else {
438f1e4b6c0SHarish Patil 		ecore_vf_get_num_rxqs(ECORE_LEADING_HWFN(edev),
439f1e4b6c0SHarish Patil 				      &info->num_queues);
440c0845c33SRasesh Mody 		if (ECORE_IS_CMT(edev)) {
441f1e4b6c0SHarish Patil 			ecore_vf_get_num_rxqs(&edev->hwfns[1], &queues);
442f1e4b6c0SHarish Patil 			info->num_queues += queues;
443f1e4b6c0SHarish Patil 		}
44486a2265eSRasesh Mody 
44586a2265eSRasesh Mody 		ecore_vf_get_num_vlan_filters(&edev->hwfns[0],
446d6cb1753SHarish Patil 					      (u8 *)&info->num_vlan_filters);
44786a2265eSRasesh Mody 
44886a2265eSRasesh Mody 		ecore_vf_get_port_mac(&edev->hwfns[0],
44986a2265eSRasesh Mody 				      (uint8_t *)&info->port_mac);
4503d4bb441SHarish Patil 
4513d4bb441SHarish Patil 		info->is_legacy = ecore_vf_get_pre_fp_hsi(&edev->hwfns[0]);
45286a2265eSRasesh Mody 	}
4532ea6f76aSRasesh Mody 
4542ea6f76aSRasesh Mody 	qed_fill_dev_info(edev, &info->common);
4552ea6f76aSRasesh Mody 
45686a2265eSRasesh Mody 	if (IS_VF(edev))
45786a2265eSRasesh Mody 		memset(&info->common.hw_mac, 0, ETHER_ADDR_LEN);
45886a2265eSRasesh Mody 
4592ea6f76aSRasesh Mody 	return 0;
4602ea6f76aSRasesh Mody }
4612ea6f76aSRasesh Mody 
462de5588afSRasesh Mody static void qed_set_name(struct ecore_dev *edev, char name[NAME_SIZE])
4632ea6f76aSRasesh Mody {
4642ea6f76aSRasesh Mody 	int i;
4652ea6f76aSRasesh Mody 
4662ea6f76aSRasesh Mody 	rte_memcpy(edev->name, name, NAME_SIZE);
4672ea6f76aSRasesh Mody 	for_each_hwfn(edev, i) {
4682ea6f76aSRasesh Mody 		snprintf(edev->hwfns[i].name, NAME_SIZE, "%s-%d", name, i);
4692ea6f76aSRasesh Mody 	}
4702ea6f76aSRasesh Mody }
4712ea6f76aSRasesh Mody 
4722ea6f76aSRasesh Mody static uint32_t
4732ea6f76aSRasesh Mody qed_sb_init(struct ecore_dev *edev, struct ecore_sb_info *sb_info,
4744c4bdadfSHarish Patil 	    void *sb_virt_addr, dma_addr_t sb_phy_addr, uint16_t sb_id)
4752ea6f76aSRasesh Mody {
4762ea6f76aSRasesh Mody 	struct ecore_hwfn *p_hwfn;
4772ea6f76aSRasesh Mody 	int hwfn_index;
4782ea6f76aSRasesh Mody 	uint16_t rel_sb_id;
4794c4bdadfSHarish Patil 	uint8_t n_hwfns = edev->num_hwfns;
4802ea6f76aSRasesh Mody 	uint32_t rc;
4812ea6f76aSRasesh Mody 
4822ea6f76aSRasesh Mody 	hwfn_index = sb_id % n_hwfns;
4832ea6f76aSRasesh Mody 	p_hwfn = &edev->hwfns[hwfn_index];
4842ea6f76aSRasesh Mody 	rel_sb_id = sb_id / n_hwfns;
4852ea6f76aSRasesh Mody 
4862ea6f76aSRasesh Mody 	DP_INFO(edev, "hwfn [%d] <--[init]-- SB %04x [0x%04x upper]\n",
4872ea6f76aSRasesh Mody 		hwfn_index, rel_sb_id, sb_id);
4882ea6f76aSRasesh Mody 
4892ea6f76aSRasesh Mody 	rc = ecore_int_sb_init(p_hwfn, p_hwfn->p_main_ptt, sb_info,
4902ea6f76aSRasesh Mody 			       sb_virt_addr, sb_phy_addr, rel_sb_id);
4912ea6f76aSRasesh Mody 
4922ea6f76aSRasesh Mody 	return rc;
4932ea6f76aSRasesh Mody }
4942ea6f76aSRasesh Mody 
4952ea6f76aSRasesh Mody static void qed_fill_link(struct ecore_hwfn *hwfn,
496739a5b2fSRasesh Mody 			  __rte_unused struct ecore_ptt *ptt,
4972ea6f76aSRasesh Mody 			  struct qed_link_output *if_link)
4982ea6f76aSRasesh Mody {
4992ea6f76aSRasesh Mody 	struct ecore_mcp_link_params params;
5002ea6f76aSRasesh Mody 	struct ecore_mcp_link_state link;
5012ea6f76aSRasesh Mody 	struct ecore_mcp_link_capabilities link_caps;
5022ea6f76aSRasesh Mody 	uint8_t change = 0;
5032ea6f76aSRasesh Mody 
5042ea6f76aSRasesh Mody 	memset(if_link, 0, sizeof(*if_link));
5052ea6f76aSRasesh Mody 
5062ea6f76aSRasesh Mody 	/* Prepare source inputs */
50786a2265eSRasesh Mody 	if (IS_PF(hwfn->p_dev)) {
5082ea6f76aSRasesh Mody 		rte_memcpy(&params, ecore_mcp_get_link_params(hwfn),
5092ea6f76aSRasesh Mody 		       sizeof(params));
5102ea6f76aSRasesh Mody 		rte_memcpy(&link, ecore_mcp_get_link_state(hwfn), sizeof(link));
5112ea6f76aSRasesh Mody 		rte_memcpy(&link_caps, ecore_mcp_get_link_capabilities(hwfn),
5122ea6f76aSRasesh Mody 		       sizeof(link_caps));
51386a2265eSRasesh Mody 	} else {
51486a2265eSRasesh Mody 		ecore_vf_read_bulletin(hwfn, &change);
51586a2265eSRasesh Mody 		ecore_vf_get_link_params(hwfn, &params);
51686a2265eSRasesh Mody 		ecore_vf_get_link_state(hwfn, &link);
51786a2265eSRasesh Mody 		ecore_vf_get_link_caps(hwfn, &link_caps);
51886a2265eSRasesh Mody 	}
5192ea6f76aSRasesh Mody 
5202ea6f76aSRasesh Mody 	/* Set the link parameters to pass to protocol driver */
5212ea6f76aSRasesh Mody 	if (link.link_up)
5222ea6f76aSRasesh Mody 		if_link->link_up = true;
5232ea6f76aSRasesh Mody 
5242ea6f76aSRasesh Mody 	if (link.link_up)
5252ea6f76aSRasesh Mody 		if_link->speed = link.speed;
5262ea6f76aSRasesh Mody 
5272ea6f76aSRasesh Mody 	if_link->duplex = QEDE_DUPLEX_FULL;
5282ea6f76aSRasesh Mody 
5291ea56b80SHarish Patil 	/* Fill up the native advertised speed cap mask */
5301ea56b80SHarish Patil 	if_link->adv_speed = params.speed.advertised_speeds;
53164c239b7SHarish Patil 
5322ea6f76aSRasesh Mody 	if (params.speed.autoneg)
5332ea6f76aSRasesh Mody 		if_link->supported_caps |= QEDE_SUPPORTED_AUTONEG;
5342ea6f76aSRasesh Mody 
5352ea6f76aSRasesh Mody 	if (params.pause.autoneg || params.pause.forced_rx ||
5362ea6f76aSRasesh Mody 	    params.pause.forced_tx)
5372ea6f76aSRasesh Mody 		if_link->supported_caps |= QEDE_SUPPORTED_PAUSE;
5382ea6f76aSRasesh Mody 
5392ea6f76aSRasesh Mody 	if (params.pause.autoneg)
5402ea6f76aSRasesh Mody 		if_link->pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE;
5412ea6f76aSRasesh Mody 
5422ea6f76aSRasesh Mody 	if (params.pause.forced_rx)
5432ea6f76aSRasesh Mody 		if_link->pause_config |= QED_LINK_PAUSE_RX_ENABLE;
5442ea6f76aSRasesh Mody 
5452ea6f76aSRasesh Mody 	if (params.pause.forced_tx)
5462ea6f76aSRasesh Mody 		if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE;
5473c6a3cf6SRasesh Mody 
5483c6a3cf6SRasesh Mody 	if (link_caps.default_eee == ECORE_MCP_EEE_UNSUPPORTED) {
5493c6a3cf6SRasesh Mody 		if_link->eee_supported = false;
5503c6a3cf6SRasesh Mody 	} else {
5513c6a3cf6SRasesh Mody 		if_link->eee_supported = true;
5523c6a3cf6SRasesh Mody 		if_link->eee_active = link.eee_active;
5533c6a3cf6SRasesh Mody 		if_link->sup_caps = link_caps.eee_speed_caps;
5543c6a3cf6SRasesh Mody 		/* MFW clears adv_caps on eee disable; use configured value */
5553c6a3cf6SRasesh Mody 		if_link->eee.adv_caps = link.eee_adv_caps ? link.eee_adv_caps :
5563c6a3cf6SRasesh Mody 					params.eee.adv_caps;
5573c6a3cf6SRasesh Mody 		if_link->eee.lp_adv_caps = link.eee_lp_adv_caps;
5583c6a3cf6SRasesh Mody 		if_link->eee.enable = params.eee.enable;
5593c6a3cf6SRasesh Mody 		if_link->eee.tx_lpi_enable = params.eee.tx_lpi_enable;
5603c6a3cf6SRasesh Mody 		if_link->eee.tx_lpi_timer = params.eee.tx_lpi_timer;
5613c6a3cf6SRasesh Mody 	}
5622ea6f76aSRasesh Mody }
5632ea6f76aSRasesh Mody 
5642ea6f76aSRasesh Mody static void
5652ea6f76aSRasesh Mody qed_get_current_link(struct ecore_dev *edev, struct qed_link_output *if_link)
5662ea6f76aSRasesh Mody {
567739a5b2fSRasesh Mody 	struct ecore_hwfn *hwfn;
568739a5b2fSRasesh Mody 	struct ecore_ptt *ptt;
5692ea6f76aSRasesh Mody 
570739a5b2fSRasesh Mody 	hwfn = &edev->hwfns[0];
571739a5b2fSRasesh Mody 	if (IS_PF(edev)) {
572739a5b2fSRasesh Mody 		ptt = ecore_ptt_acquire(hwfn);
573739a5b2fSRasesh Mody 		if (!ptt)
574739a5b2fSRasesh Mody 			DP_NOTICE(hwfn, true, "Failed to fill link; No PTT\n");
575739a5b2fSRasesh Mody 
576739a5b2fSRasesh Mody 			qed_fill_link(hwfn, ptt, if_link);
577739a5b2fSRasesh Mody 
578739a5b2fSRasesh Mody 		if (ptt)
579739a5b2fSRasesh Mody 			ecore_ptt_release(hwfn, ptt);
580739a5b2fSRasesh Mody 	} else {
581739a5b2fSRasesh Mody 		qed_fill_link(hwfn, NULL, if_link);
582739a5b2fSRasesh Mody 	}
5832ea6f76aSRasesh Mody }
5842ea6f76aSRasesh Mody 
5852ea6f76aSRasesh Mody static int qed_set_link(struct ecore_dev *edev, struct qed_link_params *params)
5862ea6f76aSRasesh Mody {
5872ea6f76aSRasesh Mody 	struct ecore_hwfn *hwfn;
5882ea6f76aSRasesh Mody 	struct ecore_ptt *ptt;
5892ea6f76aSRasesh Mody 	struct ecore_mcp_link_params *link_params;
5902ea6f76aSRasesh Mody 	int rc;
5912ea6f76aSRasesh Mody 
59286a2265eSRasesh Mody 	if (IS_VF(edev))
59386a2265eSRasesh Mody 		return 0;
59486a2265eSRasesh Mody 
5952ea6f76aSRasesh Mody 	/* The link should be set only once per PF */
5962ea6f76aSRasesh Mody 	hwfn = &edev->hwfns[0];
5972ea6f76aSRasesh Mody 
5982ea6f76aSRasesh Mody 	ptt = ecore_ptt_acquire(hwfn);
5992ea6f76aSRasesh Mody 	if (!ptt)
6002ea6f76aSRasesh Mody 		return -EBUSY;
6012ea6f76aSRasesh Mody 
6022ea6f76aSRasesh Mody 	link_params = ecore_mcp_get_link_params(hwfn);
6032ea6f76aSRasesh Mody 	if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG)
6042ea6f76aSRasesh Mody 		link_params->speed.autoneg = params->autoneg;
6052ea6f76aSRasesh Mody 
6062ea6f76aSRasesh Mody 	if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) {
6072ea6f76aSRasesh Mody 		if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
6082ea6f76aSRasesh Mody 			link_params->pause.autoneg = true;
6092ea6f76aSRasesh Mody 		else
6102ea6f76aSRasesh Mody 			link_params->pause.autoneg = false;
6112ea6f76aSRasesh Mody 		if (params->pause_config & QED_LINK_PAUSE_RX_ENABLE)
6122ea6f76aSRasesh Mody 			link_params->pause.forced_rx = true;
6132ea6f76aSRasesh Mody 		else
6142ea6f76aSRasesh Mody 			link_params->pause.forced_rx = false;
6152ea6f76aSRasesh Mody 		if (params->pause_config & QED_LINK_PAUSE_TX_ENABLE)
6162ea6f76aSRasesh Mody 			link_params->pause.forced_tx = true;
6172ea6f76aSRasesh Mody 		else
6182ea6f76aSRasesh Mody 			link_params->pause.forced_tx = false;
6192ea6f76aSRasesh Mody 	}
6202ea6f76aSRasesh Mody 
6213c6a3cf6SRasesh Mody 	if (params->override_flags & QED_LINK_OVERRIDE_EEE_CONFIG)
6223c6a3cf6SRasesh Mody 		memcpy(&link_params->eee, &params->eee,
6233c6a3cf6SRasesh Mody 		       sizeof(link_params->eee));
6243c6a3cf6SRasesh Mody 
6252ea6f76aSRasesh Mody 	rc = ecore_mcp_set_link(hwfn, ptt, params->link_up);
6262ea6f76aSRasesh Mody 
6272ea6f76aSRasesh Mody 	ecore_ptt_release(hwfn, ptt);
6282ea6f76aSRasesh Mody 
6292ea6f76aSRasesh Mody 	return rc;
6302ea6f76aSRasesh Mody }
6312ea6f76aSRasesh Mody 
632739a5b2fSRasesh Mody void qed_link_update(struct ecore_hwfn *hwfn, struct ecore_ptt *ptt)
63386a2265eSRasesh Mody {
63486a2265eSRasesh Mody 	struct qed_link_output if_link;
63586a2265eSRasesh Mody 
636739a5b2fSRasesh Mody 	qed_fill_link(hwfn, ptt, &if_link);
63786a2265eSRasesh Mody }
63886a2265eSRasesh Mody 
6392ea6f76aSRasesh Mody static int qed_drain(struct ecore_dev *edev)
6402ea6f76aSRasesh Mody {
6412ea6f76aSRasesh Mody 	struct ecore_hwfn *hwfn;
6422ea6f76aSRasesh Mody 	struct ecore_ptt *ptt;
6432ea6f76aSRasesh Mody 	int i, rc;
6442ea6f76aSRasesh Mody 
64586a2265eSRasesh Mody 	if (IS_VF(edev))
64686a2265eSRasesh Mody 		return 0;
64786a2265eSRasesh Mody 
6482ea6f76aSRasesh Mody 	for_each_hwfn(edev, i) {
6492ea6f76aSRasesh Mody 		hwfn = &edev->hwfns[i];
6502ea6f76aSRasesh Mody 		ptt = ecore_ptt_acquire(hwfn);
6512ea6f76aSRasesh Mody 		if (!ptt) {
6524ffa2af9SRasesh Mody 			DP_ERR(hwfn, "Failed to drain NIG; No PTT\n");
6532ea6f76aSRasesh Mody 			return -EBUSY;
6542ea6f76aSRasesh Mody 		}
6552ea6f76aSRasesh Mody 		rc = ecore_mcp_drain(hwfn, ptt);
6562ea6f76aSRasesh Mody 		if (rc)
6572ea6f76aSRasesh Mody 			return rc;
6582ea6f76aSRasesh Mody 		ecore_ptt_release(hwfn, ptt);
6592ea6f76aSRasesh Mody 	}
6602ea6f76aSRasesh Mody 
6612ea6f76aSRasesh Mody 	return 0;
6622ea6f76aSRasesh Mody }
6632ea6f76aSRasesh Mody 
6642ea6f76aSRasesh Mody static int qed_nic_stop(struct ecore_dev *edev)
6652ea6f76aSRasesh Mody {
6662ea6f76aSRasesh Mody 	int i, rc;
6672ea6f76aSRasesh Mody 
6682ea6f76aSRasesh Mody 	rc = ecore_hw_stop(edev);
6692ea6f76aSRasesh Mody 	for (i = 0; i < edev->num_hwfns; i++) {
6702ea6f76aSRasesh Mody 		struct ecore_hwfn *p_hwfn = &edev->hwfns[i];
6712ea6f76aSRasesh Mody 
6722ea6f76aSRasesh Mody 		if (p_hwfn->b_sp_dpc_enabled)
6732ea6f76aSRasesh Mody 			p_hwfn->b_sp_dpc_enabled = false;
6742ea6f76aSRasesh Mody 	}
6752ea6f76aSRasesh Mody 	return rc;
6762ea6f76aSRasesh Mody }
6772ea6f76aSRasesh Mody 
6782ea6f76aSRasesh Mody static int qed_slowpath_stop(struct ecore_dev *edev)
6792ea6f76aSRasesh Mody {
6802ea6f76aSRasesh Mody #ifdef CONFIG_QED_SRIOV
6812ea6f76aSRasesh Mody 	int i;
6822ea6f76aSRasesh Mody #endif
6832ea6f76aSRasesh Mody 
6842ea6f76aSRasesh Mody 	if (!edev)
6852ea6f76aSRasesh Mody 		return -ENODEV;
6862ea6f76aSRasesh Mody 
68786a2265eSRasesh Mody 	if (IS_PF(edev)) {
68848e8d239SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW
6892ea6f76aSRasesh Mody 		qed_free_stream_mem(edev);
69048e8d239SRasesh Mody #endif
6912ea6f76aSRasesh Mody 
69286a2265eSRasesh Mody #ifdef CONFIG_QED_SRIOV
69386a2265eSRasesh Mody 		if (IS_QED_ETH_IF(edev))
69486a2265eSRasesh Mody 			qed_sriov_disable(edev, true);
69586a2265eSRasesh Mody #endif
69686a2265eSRasesh Mody 	}
6972ea6f76aSRasesh Mody 
69839f0eb3bSRasesh Mody 	qed_nic_stop(edev);
69939f0eb3bSRasesh Mody 
70039f0eb3bSRasesh Mody 	ecore_resc_free(edev);
70186a2265eSRasesh Mody 	qed_stop_iov_task(edev);
7022ea6f76aSRasesh Mody 
7032ea6f76aSRasesh Mody 	return 0;
7042ea6f76aSRasesh Mody }
7052ea6f76aSRasesh Mody 
7062ea6f76aSRasesh Mody static void qed_remove(struct ecore_dev *edev)
7072ea6f76aSRasesh Mody {
7082ea6f76aSRasesh Mody 	if (!edev)
7092ea6f76aSRasesh Mody 		return;
7102ea6f76aSRasesh Mody 
7112ea6f76aSRasesh Mody 	ecore_hw_remove(edev);
7122ea6f76aSRasesh Mody }
7132ea6f76aSRasesh Mody 
7143ca097bbSRasesh Mody static int qed_send_drv_state(struct ecore_dev *edev, bool active)
7153ca097bbSRasesh Mody {
7163ca097bbSRasesh Mody 	struct ecore_hwfn *hwfn = ECORE_LEADING_HWFN(edev);
7173ca097bbSRasesh Mody 	struct ecore_ptt *ptt;
7183ca097bbSRasesh Mody 	int status = 0;
7193ca097bbSRasesh Mody 
7203ca097bbSRasesh Mody 	ptt = ecore_ptt_acquire(hwfn);
7213ca097bbSRasesh Mody 	if (!ptt)
7223ca097bbSRasesh Mody 		return -EAGAIN;
7233ca097bbSRasesh Mody 
7243ca097bbSRasesh Mody 	status = ecore_mcp_ov_update_driver_state(hwfn, ptt, active ?
7253ca097bbSRasesh Mody 						  ECORE_OV_DRIVER_STATE_ACTIVE :
7263ca097bbSRasesh Mody 						ECORE_OV_DRIVER_STATE_DISABLED);
7273ca097bbSRasesh Mody 
7283ca097bbSRasesh Mody 	ecore_ptt_release(hwfn, ptt);
7293ca097bbSRasesh Mody 
7303ca097bbSRasesh Mody 	return status;
7313ca097bbSRasesh Mody }
7323ca097bbSRasesh Mody 
7331a998268SRasesh Mody static int qed_get_sb_info(struct ecore_dev *edev, struct ecore_sb_info *sb,
7341a998268SRasesh Mody 			   u16 qid, struct ecore_sb_info_dbg *sb_dbg)
7351a998268SRasesh Mody {
7361a998268SRasesh Mody 	struct ecore_hwfn *hwfn = &edev->hwfns[qid % edev->num_hwfns];
7371a998268SRasesh Mody 	struct ecore_ptt *ptt;
7381a998268SRasesh Mody 	int rc;
7391a998268SRasesh Mody 
7401a998268SRasesh Mody 	if (IS_VF(edev))
7411a998268SRasesh Mody 		return -EINVAL;
7421a998268SRasesh Mody 
7431a998268SRasesh Mody 	ptt = ecore_ptt_acquire(hwfn);
7441a998268SRasesh Mody 	if (!ptt) {
7454ffa2af9SRasesh Mody 		DP_ERR(hwfn, "Can't acquire PTT\n");
7461a998268SRasesh Mody 		return -EAGAIN;
7471a998268SRasesh Mody 	}
7481a998268SRasesh Mody 
7491a998268SRasesh Mody 	memset(sb_dbg, 0, sizeof(*sb_dbg));
7501a998268SRasesh Mody 	rc = ecore_int_get_sb_dbg(hwfn, ptt, sb, sb_dbg);
7511a998268SRasesh Mody 
7521a998268SRasesh Mody 	ecore_ptt_release(hwfn, ptt);
7531a998268SRasesh Mody 	return rc;
7541a998268SRasesh Mody }
7551a998268SRasesh Mody 
7562ea6f76aSRasesh Mody const struct qed_common_ops qed_common_ops_pass = {
7572ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(probe, &qed_probe),
7582ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(update_pf_params, &qed_update_pf_params),
7592ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(slowpath_start, &qed_slowpath_start),
760de5588afSRasesh Mody 	INIT_STRUCT_FIELD(set_name, &qed_set_name),
7612ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(chain_alloc, &ecore_chain_alloc),
7622ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(chain_free, &ecore_chain_free),
7632ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(sb_init, &qed_sb_init),
764af785e47SRasesh Mody 	INIT_STRUCT_FIELD(get_sb_info, &qed_get_sb_info),
7652ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(get_link, &qed_get_current_link),
7662ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(set_link, &qed_set_link),
7672ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(drain, &qed_drain),
7682ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(slowpath_stop, &qed_slowpath_stop),
7692ea6f76aSRasesh Mody 	INIT_STRUCT_FIELD(remove, &qed_remove),
7703ca097bbSRasesh Mody 	INIT_STRUCT_FIELD(send_drv_state, &qed_send_drv_state),
7712ea6f76aSRasesh Mody };
7724c4bdadfSHarish Patil 
7734c4bdadfSHarish Patil const struct qed_eth_ops qed_eth_ops_pass = {
7744c4bdadfSHarish Patil 	INIT_STRUCT_FIELD(common, &qed_common_ops_pass),
7754c4bdadfSHarish Patil 	INIT_STRUCT_FIELD(fill_dev_info, &qed_fill_eth_dev_info),
7764c4bdadfSHarish Patil };
7774c4bdadfSHarish Patil 
7784c4bdadfSHarish Patil const struct qed_eth_ops *qed_get_eth_ops(void)
7794c4bdadfSHarish Patil {
7804c4bdadfSHarish Patil 	return &qed_eth_ops_pass;
7814c4bdadfSHarish Patil }
782