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 = 22806474a6SRasesh Mody "/lib/firmware/qed/qed_init_values-8.18.9.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; 392ea6f76aSRasesh Mody } 402ea6f76aSRasesh Mody 412ea6f76aSRasesh Mody static int 422ea6f76aSRasesh Mody qed_probe(struct ecore_dev *edev, struct rte_pci_device *pci_dev, 432ea6f76aSRasesh Mody enum qed_protocol protocol, uint32_t dp_module, 442ea6f76aSRasesh Mody uint8_t dp_level, bool is_vf) 452ea6f76aSRasesh Mody { 4622d07d93SRasesh Mody struct ecore_hw_prepare_params hw_prepare_params; 472ea6f76aSRasesh Mody struct qede_dev *qdev = (struct qede_dev *)edev; 482ea6f76aSRasesh Mody int rc; 492ea6f76aSRasesh Mody 502ea6f76aSRasesh Mody ecore_init_struct(edev); 51de5588afSRasesh Mody edev->drv_type = DRV_ID_DRV_TYPE_LINUX; 522ea6f76aSRasesh Mody qdev->protocol = protocol; 53de5588afSRasesh Mody 54c0bd1181SRasesh Mody if (is_vf) 552ea6f76aSRasesh Mody edev->b_is_vf = true; 56c0bd1181SRasesh Mody 572ea6f76aSRasesh Mody ecore_init_dp(edev, dp_module, dp_level, NULL); 582ea6f76aSRasesh Mody qed_init_pci(edev, pci_dev); 5922d07d93SRasesh Mody 6022d07d93SRasesh Mody memset(&hw_prepare_params, 0, sizeof(hw_prepare_params)); 6122d07d93SRasesh Mody hw_prepare_params.personality = ECORE_PCI_ETH; 6222d07d93SRasesh Mody hw_prepare_params.drv_resc_alloc = false; 6322d07d93SRasesh Mody hw_prepare_params.chk_reg_fifo = false; 649e2f08a4SRasesh Mody hw_prepare_params.initiate_pf_flr = true; 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 { 772ea6f76aSRasesh Mody int rc, i; 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) { 1352ea6f76aSRasesh Mody DP_NOTICE(edev, false, "Can't open firmware file\n"); 1362ea6f76aSRasesh Mody return -ENOENT; 1372ea6f76aSRasesh Mody } 1382ea6f76aSRasesh Mody 1392ea6f76aSRasesh Mody if (fstat(fd, &st) < 0) { 1402ea6f76aSRasesh Mody DP_NOTICE(edev, false, "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) { 1482ea6f76aSRasesh Mody DP_NOTICE(edev, false, "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) { 1542ea6f76aSRasesh Mody DP_NOTICE(edev, false, "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) { 1612ea6f76aSRasesh Mody DP_NOTICE(edev, false, "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 */ 18286a2265eSRasesh Mody qed_link_update(hwfn); 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 { 2252ea6f76aSRasesh Mody const uint8_t *data = NULL; 2262ea6f76aSRasesh Mody struct ecore_hwfn *hwfn; 2272ea6f76aSRasesh Mody struct ecore_mcp_drv_version drv_version; 228301ea2d7SRasesh Mody struct ecore_hw_init_params hw_init_params; 2292ea6f76aSRasesh Mody struct qede_dev *qdev = (struct qede_dev *)edev; 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) { 2662ea6f76aSRasesh Mody DP_NOTICE(edev, true, 2672ea6f76aSRasesh Mody "Failed to allocate stream memory\n"); 268*c2069af8SRasesh Mody goto err1; 2692ea6f76aSRasesh Mody } 27086a2265eSRasesh Mody } 27186a2265eSRasesh Mody 27286a2265eSRasesh Mody qed_start_iov_task(edev); 27348e8d239SRasesh Mody #endif 2742ea6f76aSRasesh Mody 27548e8d239SRasesh Mody #ifdef CONFIG_ECORE_BINARY_FW 27686a2265eSRasesh Mody if (IS_PF(edev)) 27722d07d93SRasesh Mody data = (const uint8_t *)edev->firmware + sizeof(u32); 2782ea6f76aSRasesh Mody #endif 27922d07d93SRasesh Mody 280301ea2d7SRasesh Mody /* Start the slowpath */ 281301ea2d7SRasesh Mody memset(&hw_init_params, 0, sizeof(hw_init_params)); 282301ea2d7SRasesh Mody hw_init_params.b_hw_start = true; 283301ea2d7SRasesh Mody hw_init_params.int_mode = ECORE_INT_MODE_MSIX; 28462207535SHarish Patil hw_init_params.allow_npar_tx_switch = true; 285301ea2d7SRasesh Mody hw_init_params.bin_fw_data = data; 2860b6bf70dSRasesh Mody hw_init_params.mfw_timeout_val = ECORE_LOAD_REQ_LOCK_TO_DEFAULT; 2870b6bf70dSRasesh Mody hw_init_params.avoid_eng_reset = false; 288301ea2d7SRasesh Mody rc = ecore_hw_init(edev, &hw_init_params); 2892ea6f76aSRasesh Mody if (rc) { 2902ea6f76aSRasesh Mody DP_ERR(edev, "ecore_hw_init failed\n"); 2912ea6f76aSRasesh Mody goto err2; 2922ea6f76aSRasesh Mody } 2932ea6f76aSRasesh Mody 2942ea6f76aSRasesh Mody DP_INFO(edev, "HW inited and function started\n"); 2952ea6f76aSRasesh Mody 29686a2265eSRasesh Mody if (IS_PF(edev)) { 2972ea6f76aSRasesh Mody hwfn = ECORE_LEADING_HWFN(edev); 2982ea6f76aSRasesh Mody drv_version.version = (params->drv_major << 24) | 2992ea6f76aSRasesh Mody (params->drv_minor << 16) | 3002ea6f76aSRasesh Mody (params->drv_rev << 8) | (params->drv_eng); 3012ea6f76aSRasesh Mody /* TBD: strlcpy() */ 3022ea6f76aSRasesh Mody strncpy((char *)drv_version.name, (const char *)params->name, 3032ea6f76aSRasesh Mody MCP_DRV_VER_STR_SIZE - 4); 3042ea6f76aSRasesh Mody rc = ecore_mcp_send_drv_version(hwfn, hwfn->p_main_ptt, 3052ea6f76aSRasesh Mody &drv_version); 3062ea6f76aSRasesh Mody if (rc) { 3072ea6f76aSRasesh Mody DP_NOTICE(edev, true, 3082ea6f76aSRasesh Mody "Failed sending drv version command\n"); 309*c2069af8SRasesh Mody goto err3; 3102ea6f76aSRasesh Mody } 31186a2265eSRasesh Mody } 3122ea6f76aSRasesh Mody 3135cdd769aSRasesh Mody ecore_reset_vport_stats(edev); 3145cdd769aSRasesh Mody 3152ea6f76aSRasesh Mody return 0; 3162ea6f76aSRasesh Mody 317*c2069af8SRasesh Mody err3: 3182ea6f76aSRasesh Mody ecore_hw_stop(edev); 3192ea6f76aSRasesh Mody err2: 320*c2069af8SRasesh Mody qed_stop_iov_task(edev); 321*c2069af8SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW 322*c2069af8SRasesh Mody qed_free_stream_mem(edev); 323*c2069af8SRasesh Mody err1: 324*c2069af8SRasesh Mody #endif 3252ea6f76aSRasesh Mody ecore_resc_free(edev); 3262ea6f76aSRasesh Mody err: 32748e8d239SRasesh Mody #ifdef CONFIG_ECORE_BINARY_FW 32886a2265eSRasesh Mody if (IS_PF(edev)) { 3292ea6f76aSRasesh Mody if (edev->firmware) 3302ea6f76aSRasesh Mody rte_free(edev->firmware); 3312ea6f76aSRasesh Mody edev->firmware = NULL; 33286a2265eSRasesh Mody } 3332ea6f76aSRasesh Mody #endif 33486a2265eSRasesh Mody qed_stop_iov_task(edev); 33586a2265eSRasesh Mody 3362ea6f76aSRasesh Mody return rc; 3372ea6f76aSRasesh Mody } 3382ea6f76aSRasesh Mody 3392ea6f76aSRasesh Mody static int 3402ea6f76aSRasesh Mody qed_fill_dev_info(struct ecore_dev *edev, struct qed_dev_info *dev_info) 3412ea6f76aSRasesh Mody { 3422ea6f76aSRasesh Mody struct ecore_ptt *ptt = NULL; 343a7f3cac3SRasesh Mody struct ecore_tunnel_info *tun = &edev->tunnel; 3442ea6f76aSRasesh Mody 3452ea6f76aSRasesh Mody memset(dev_info, 0, sizeof(struct qed_dev_info)); 346a7f3cac3SRasesh Mody 347adce1f86SRasesh Mody if (tun->vxlan.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN && 348adce1f86SRasesh Mody tun->vxlan.b_mode_enabled) 349a7f3cac3SRasesh Mody dev_info->vxlan_enable = true; 350a7f3cac3SRasesh Mody 351adce1f86SRasesh Mody if (tun->l2_gre.b_mode_enabled && tun->ip_gre.b_mode_enabled && 352adce1f86SRasesh Mody tun->l2_gre.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN && 353adce1f86SRasesh Mody tun->ip_gre.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN) 354a7f3cac3SRasesh Mody dev_info->gre_enable = true; 355a7f3cac3SRasesh Mody 356adce1f86SRasesh Mody if (tun->l2_geneve.b_mode_enabled && tun->ip_geneve.b_mode_enabled && 357adce1f86SRasesh Mody tun->l2_geneve.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN && 358adce1f86SRasesh Mody tun->ip_geneve.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN) 359a7f3cac3SRasesh Mody dev_info->geneve_enable = true; 360a7f3cac3SRasesh Mody 3612ea6f76aSRasesh Mody dev_info->num_hwfns = edev->num_hwfns; 3622ea6f76aSRasesh Mody dev_info->is_mf_default = IS_MF_DEFAULT(&edev->hwfns[0]); 3634fc58baeSRasesh Mody dev_info->mtu = ECORE_LEADING_HWFN(edev)->hw_info.mtu; 3644fc58baeSRasesh Mody 3652ea6f76aSRasesh Mody rte_memcpy(&dev_info->hw_mac, &edev->hwfns[0].hw_info.hw_mac_addr, 3662ea6f76aSRasesh Mody ETHER_ADDR_LEN); 3672ea6f76aSRasesh Mody 3682ea6f76aSRasesh Mody dev_info->fw_major = FW_MAJOR_VERSION; 3692ea6f76aSRasesh Mody dev_info->fw_minor = FW_MINOR_VERSION; 3702ea6f76aSRasesh Mody dev_info->fw_rev = FW_REVISION_VERSION; 3712ea6f76aSRasesh Mody dev_info->fw_eng = FW_ENGINEERING_VERSION; 372738f56d4SRasesh Mody 373738f56d4SRasesh Mody if (IS_PF(edev)) { 3742ea6f76aSRasesh Mody dev_info->mf_mode = edev->mf_mode; 3752ea6f76aSRasesh Mody dev_info->tx_switching = false; 3762ea6f76aSRasesh Mody 3772ea6f76aSRasesh Mody ptt = ecore_ptt_acquire(ECORE_LEADING_HWFN(edev)); 3782ea6f76aSRasesh Mody if (ptt) { 37922d07d93SRasesh Mody ecore_mcp_get_mfw_ver(ECORE_LEADING_HWFN(edev), ptt, 3802ea6f76aSRasesh Mody &dev_info->mfw_rev, NULL); 3812ea6f76aSRasesh Mody 3822ea6f76aSRasesh Mody ecore_mcp_get_flash_size(ECORE_LEADING_HWFN(edev), ptt, 3832ea6f76aSRasesh Mody &dev_info->flash_size); 3842ea6f76aSRasesh Mody 3852ea6f76aSRasesh Mody /* Workaround to allow PHY-read commands for 3862ea6f76aSRasesh Mody * B0 bringup. 3872ea6f76aSRasesh Mody */ 3882ea6f76aSRasesh Mody if (ECORE_IS_BB_B0(edev)) 3892ea6f76aSRasesh Mody dev_info->flash_size = 0xffffffff; 3902ea6f76aSRasesh Mody 3912ea6f76aSRasesh Mody ecore_ptt_release(ECORE_LEADING_HWFN(edev), ptt); 3922ea6f76aSRasesh Mody } 39386a2265eSRasesh Mody } else { 39422d07d93SRasesh Mody ecore_mcp_get_mfw_ver(ECORE_LEADING_HWFN(edev), ptt, 39522d07d93SRasesh Mody &dev_info->mfw_rev, NULL); 39686a2265eSRasesh Mody } 3972ea6f76aSRasesh Mody 3982ea6f76aSRasesh Mody return 0; 3992ea6f76aSRasesh Mody } 4002ea6f76aSRasesh Mody 4012ea6f76aSRasesh Mody int 4022ea6f76aSRasesh Mody qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info) 4032ea6f76aSRasesh Mody { 4042ea6f76aSRasesh Mody struct qede_dev *qdev = (struct qede_dev *)edev; 405f1e4b6c0SHarish Patil uint8_t queues = 0; 4062ea6f76aSRasesh Mody int i; 4072ea6f76aSRasesh Mody 4082ea6f76aSRasesh Mody memset(info, 0, sizeof(*info)); 4092ea6f76aSRasesh Mody 4102ea6f76aSRasesh Mody info->num_tc = 1 /* @@@TBD aelior MULTI_COS */; 4112ea6f76aSRasesh Mody 41286a2265eSRasesh Mody if (IS_PF(edev)) { 413d6cb1753SHarish Patil int max_vf_vlan_filters = 0; 414d6cb1753SHarish Patil 4152ea6f76aSRasesh Mody info->num_queues = 0; 4162ea6f76aSRasesh Mody for_each_hwfn(edev, i) 4172ea6f76aSRasesh Mody info->num_queues += 4182ea6f76aSRasesh Mody FEAT_NUM(&edev->hwfns[i], ECORE_PF_L2_QUE); 4192ea6f76aSRasesh Mody 420d6cb1753SHarish Patil if (edev->p_iov_info) 421d6cb1753SHarish Patil max_vf_vlan_filters = edev->p_iov_info->total_vfs * 422d6cb1753SHarish Patil ECORE_ETH_VF_NUM_VLAN_FILTERS; 423d6cb1753SHarish Patil info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN) - 424d6cb1753SHarish Patil max_vf_vlan_filters; 4252ea6f76aSRasesh Mody 4262ea6f76aSRasesh Mody rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr, 4272ea6f76aSRasesh Mody ETHER_ADDR_LEN); 42886a2265eSRasesh Mody } else { 429f1e4b6c0SHarish Patil ecore_vf_get_num_rxqs(ECORE_LEADING_HWFN(edev), 430f1e4b6c0SHarish Patil &info->num_queues); 431f1e4b6c0SHarish Patil if (edev->num_hwfns > 1) { 432f1e4b6c0SHarish Patil ecore_vf_get_num_rxqs(&edev->hwfns[1], &queues); 433f1e4b6c0SHarish Patil info->num_queues += queues; 434f1e4b6c0SHarish Patil } 43586a2265eSRasesh Mody 43686a2265eSRasesh Mody ecore_vf_get_num_vlan_filters(&edev->hwfns[0], 437d6cb1753SHarish Patil (u8 *)&info->num_vlan_filters); 43886a2265eSRasesh Mody 43986a2265eSRasesh Mody ecore_vf_get_port_mac(&edev->hwfns[0], 44086a2265eSRasesh Mody (uint8_t *)&info->port_mac); 4413d4bb441SHarish Patil 4423d4bb441SHarish Patil info->is_legacy = ecore_vf_get_pre_fp_hsi(&edev->hwfns[0]); 44386a2265eSRasesh Mody } 4442ea6f76aSRasesh Mody 4452ea6f76aSRasesh Mody qed_fill_dev_info(edev, &info->common); 4462ea6f76aSRasesh Mody 44786a2265eSRasesh Mody if (IS_VF(edev)) 44886a2265eSRasesh Mody memset(&info->common.hw_mac, 0, ETHER_ADDR_LEN); 44986a2265eSRasesh Mody 4502ea6f76aSRasesh Mody return 0; 4512ea6f76aSRasesh Mody } 4522ea6f76aSRasesh Mody 453de5588afSRasesh Mody static void qed_set_name(struct ecore_dev *edev, char name[NAME_SIZE]) 4542ea6f76aSRasesh Mody { 4552ea6f76aSRasesh Mody int i; 4562ea6f76aSRasesh Mody 4572ea6f76aSRasesh Mody rte_memcpy(edev->name, name, NAME_SIZE); 4582ea6f76aSRasesh Mody for_each_hwfn(edev, i) { 4592ea6f76aSRasesh Mody snprintf(edev->hwfns[i].name, NAME_SIZE, "%s-%d", name, i); 4602ea6f76aSRasesh Mody } 4612ea6f76aSRasesh Mody } 4622ea6f76aSRasesh Mody 4632ea6f76aSRasesh Mody static uint32_t 4642ea6f76aSRasesh Mody qed_sb_init(struct ecore_dev *edev, struct ecore_sb_info *sb_info, 4652ea6f76aSRasesh Mody void *sb_virt_addr, dma_addr_t sb_phy_addr, 4662ea6f76aSRasesh Mody uint16_t sb_id, enum qed_sb_type type) 4672ea6f76aSRasesh Mody { 4682ea6f76aSRasesh Mody struct ecore_hwfn *p_hwfn; 4692ea6f76aSRasesh Mody int hwfn_index; 4702ea6f76aSRasesh Mody uint16_t rel_sb_id; 4712ea6f76aSRasesh Mody uint8_t n_hwfns; 4722ea6f76aSRasesh Mody uint32_t rc; 4732ea6f76aSRasesh Mody 4742ea6f76aSRasesh Mody /* RoCE uses single engine and CMT uses two engines. When using both 4752ea6f76aSRasesh Mody * we force only a single engine. Storage uses only engine 0 too. 4762ea6f76aSRasesh Mody */ 4772ea6f76aSRasesh Mody if (type == QED_SB_TYPE_L2_QUEUE) 4782ea6f76aSRasesh Mody n_hwfns = edev->num_hwfns; 4792ea6f76aSRasesh Mody else 4802ea6f76aSRasesh Mody n_hwfns = 1; 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, 4962ea6f76aSRasesh Mody struct qed_link_output *if_link) 4972ea6f76aSRasesh Mody { 4982ea6f76aSRasesh Mody struct ecore_mcp_link_params params; 4992ea6f76aSRasesh Mody struct ecore_mcp_link_state link; 5002ea6f76aSRasesh Mody struct ecore_mcp_link_capabilities link_caps; 5012ea6f76aSRasesh Mody uint32_t media_type; 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(¶ms, 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, ¶ms); 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; 5472ea6f76aSRasesh Mody } 5482ea6f76aSRasesh Mody 5492ea6f76aSRasesh Mody static void 5502ea6f76aSRasesh Mody qed_get_current_link(struct ecore_dev *edev, struct qed_link_output *if_link) 5512ea6f76aSRasesh Mody { 5522ea6f76aSRasesh Mody qed_fill_link(&edev->hwfns[0], if_link); 5532ea6f76aSRasesh Mody 5542ea6f76aSRasesh Mody #ifdef CONFIG_QED_SRIOV 5552ea6f76aSRasesh Mody for_each_hwfn(cdev, i) 5562ea6f76aSRasesh Mody qed_inform_vf_link_state(&cdev->hwfns[i]); 5572ea6f76aSRasesh Mody #endif 5582ea6f76aSRasesh Mody } 5592ea6f76aSRasesh Mody 5602ea6f76aSRasesh Mody static int qed_set_link(struct ecore_dev *edev, struct qed_link_params *params) 5612ea6f76aSRasesh Mody { 5622ea6f76aSRasesh Mody struct ecore_hwfn *hwfn; 5632ea6f76aSRasesh Mody struct ecore_ptt *ptt; 5642ea6f76aSRasesh Mody struct ecore_mcp_link_params *link_params; 5652ea6f76aSRasesh Mody int rc; 5662ea6f76aSRasesh Mody 56786a2265eSRasesh Mody if (IS_VF(edev)) 56886a2265eSRasesh Mody return 0; 56986a2265eSRasesh Mody 5702ea6f76aSRasesh Mody /* The link should be set only once per PF */ 5712ea6f76aSRasesh Mody hwfn = &edev->hwfns[0]; 5722ea6f76aSRasesh Mody 5732ea6f76aSRasesh Mody ptt = ecore_ptt_acquire(hwfn); 5742ea6f76aSRasesh Mody if (!ptt) 5752ea6f76aSRasesh Mody return -EBUSY; 5762ea6f76aSRasesh Mody 5772ea6f76aSRasesh Mody link_params = ecore_mcp_get_link_params(hwfn); 5782ea6f76aSRasesh Mody if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG) 5792ea6f76aSRasesh Mody link_params->speed.autoneg = params->autoneg; 5802ea6f76aSRasesh Mody 5812ea6f76aSRasesh Mody if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) { 5822ea6f76aSRasesh Mody if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE) 5832ea6f76aSRasesh Mody link_params->pause.autoneg = true; 5842ea6f76aSRasesh Mody else 5852ea6f76aSRasesh Mody link_params->pause.autoneg = false; 5862ea6f76aSRasesh Mody if (params->pause_config & QED_LINK_PAUSE_RX_ENABLE) 5872ea6f76aSRasesh Mody link_params->pause.forced_rx = true; 5882ea6f76aSRasesh Mody else 5892ea6f76aSRasesh Mody link_params->pause.forced_rx = false; 5902ea6f76aSRasesh Mody if (params->pause_config & QED_LINK_PAUSE_TX_ENABLE) 5912ea6f76aSRasesh Mody link_params->pause.forced_tx = true; 5922ea6f76aSRasesh Mody else 5932ea6f76aSRasesh Mody link_params->pause.forced_tx = false; 5942ea6f76aSRasesh Mody } 5952ea6f76aSRasesh Mody 5962ea6f76aSRasesh Mody rc = ecore_mcp_set_link(hwfn, ptt, params->link_up); 5972ea6f76aSRasesh Mody 5982ea6f76aSRasesh Mody ecore_ptt_release(hwfn, ptt); 5992ea6f76aSRasesh Mody 6002ea6f76aSRasesh Mody return rc; 6012ea6f76aSRasesh Mody } 6022ea6f76aSRasesh Mody 60386a2265eSRasesh Mody void qed_link_update(struct ecore_hwfn *hwfn) 60486a2265eSRasesh Mody { 60586a2265eSRasesh Mody struct qed_link_output if_link; 60686a2265eSRasesh Mody 60786a2265eSRasesh Mody qed_fill_link(hwfn, &if_link); 60886a2265eSRasesh Mody } 60986a2265eSRasesh Mody 6102ea6f76aSRasesh Mody static int qed_drain(struct ecore_dev *edev) 6112ea6f76aSRasesh Mody { 6122ea6f76aSRasesh Mody struct ecore_hwfn *hwfn; 6132ea6f76aSRasesh Mody struct ecore_ptt *ptt; 6142ea6f76aSRasesh Mody int i, rc; 6152ea6f76aSRasesh Mody 61686a2265eSRasesh Mody if (IS_VF(edev)) 61786a2265eSRasesh Mody return 0; 61886a2265eSRasesh Mody 6192ea6f76aSRasesh Mody for_each_hwfn(edev, i) { 6202ea6f76aSRasesh Mody hwfn = &edev->hwfns[i]; 6212ea6f76aSRasesh Mody ptt = ecore_ptt_acquire(hwfn); 6222ea6f76aSRasesh Mody if (!ptt) { 6232ea6f76aSRasesh Mody DP_NOTICE(hwfn, true, "Failed to drain NIG; No PTT\n"); 6242ea6f76aSRasesh Mody return -EBUSY; 6252ea6f76aSRasesh Mody } 6262ea6f76aSRasesh Mody rc = ecore_mcp_drain(hwfn, ptt); 6272ea6f76aSRasesh Mody if (rc) 6282ea6f76aSRasesh Mody return rc; 6292ea6f76aSRasesh Mody ecore_ptt_release(hwfn, ptt); 6302ea6f76aSRasesh Mody } 6312ea6f76aSRasesh Mody 6322ea6f76aSRasesh Mody return 0; 6332ea6f76aSRasesh Mody } 6342ea6f76aSRasesh Mody 6352ea6f76aSRasesh Mody static int qed_nic_stop(struct ecore_dev *edev) 6362ea6f76aSRasesh Mody { 6372ea6f76aSRasesh Mody int i, rc; 6382ea6f76aSRasesh Mody 6392ea6f76aSRasesh Mody rc = ecore_hw_stop(edev); 6402ea6f76aSRasesh Mody for (i = 0; i < edev->num_hwfns; i++) { 6412ea6f76aSRasesh Mody struct ecore_hwfn *p_hwfn = &edev->hwfns[i]; 6422ea6f76aSRasesh Mody 6432ea6f76aSRasesh Mody if (p_hwfn->b_sp_dpc_enabled) 6442ea6f76aSRasesh Mody p_hwfn->b_sp_dpc_enabled = false; 6452ea6f76aSRasesh Mody } 6462ea6f76aSRasesh Mody return rc; 6472ea6f76aSRasesh Mody } 6482ea6f76aSRasesh Mody 6492ea6f76aSRasesh Mody static int qed_slowpath_stop(struct ecore_dev *edev) 6502ea6f76aSRasesh Mody { 6512ea6f76aSRasesh Mody #ifdef CONFIG_QED_SRIOV 6522ea6f76aSRasesh Mody int i; 6532ea6f76aSRasesh Mody #endif 6542ea6f76aSRasesh Mody 6552ea6f76aSRasesh Mody if (!edev) 6562ea6f76aSRasesh Mody return -ENODEV; 6572ea6f76aSRasesh Mody 65886a2265eSRasesh Mody if (IS_PF(edev)) { 65948e8d239SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW 6602ea6f76aSRasesh Mody qed_free_stream_mem(edev); 66148e8d239SRasesh Mody #endif 6622ea6f76aSRasesh Mody 66386a2265eSRasesh Mody #ifdef CONFIG_QED_SRIOV 66486a2265eSRasesh Mody if (IS_QED_ETH_IF(edev)) 66586a2265eSRasesh Mody qed_sriov_disable(edev, true); 66686a2265eSRasesh Mody #endif 66786a2265eSRasesh Mody } 6682ea6f76aSRasesh Mody 66939f0eb3bSRasesh Mody qed_nic_stop(edev); 67039f0eb3bSRasesh Mody 67139f0eb3bSRasesh Mody ecore_resc_free(edev); 67286a2265eSRasesh Mody qed_stop_iov_task(edev); 6732ea6f76aSRasesh Mody 6742ea6f76aSRasesh Mody return 0; 6752ea6f76aSRasesh Mody } 6762ea6f76aSRasesh Mody 6772ea6f76aSRasesh Mody static void qed_remove(struct ecore_dev *edev) 6782ea6f76aSRasesh Mody { 6792ea6f76aSRasesh Mody if (!edev) 6802ea6f76aSRasesh Mody return; 6812ea6f76aSRasesh Mody 6822ea6f76aSRasesh Mody ecore_hw_remove(edev); 6832ea6f76aSRasesh Mody } 6842ea6f76aSRasesh Mody 6853ca097bbSRasesh Mody static int qed_send_drv_state(struct ecore_dev *edev, bool active) 6863ca097bbSRasesh Mody { 6873ca097bbSRasesh Mody struct ecore_hwfn *hwfn = ECORE_LEADING_HWFN(edev); 6883ca097bbSRasesh Mody struct ecore_ptt *ptt; 6893ca097bbSRasesh Mody int status = 0; 6903ca097bbSRasesh Mody 6913ca097bbSRasesh Mody ptt = ecore_ptt_acquire(hwfn); 6923ca097bbSRasesh Mody if (!ptt) 6933ca097bbSRasesh Mody return -EAGAIN; 6943ca097bbSRasesh Mody 6953ca097bbSRasesh Mody status = ecore_mcp_ov_update_driver_state(hwfn, ptt, active ? 6963ca097bbSRasesh Mody ECORE_OV_DRIVER_STATE_ACTIVE : 6973ca097bbSRasesh Mody ECORE_OV_DRIVER_STATE_DISABLED); 6983ca097bbSRasesh Mody 6993ca097bbSRasesh Mody ecore_ptt_release(hwfn, ptt); 7003ca097bbSRasesh Mody 7013ca097bbSRasesh Mody return status; 7023ca097bbSRasesh Mody } 7033ca097bbSRasesh Mody 7041a998268SRasesh Mody static int qed_get_sb_info(struct ecore_dev *edev, struct ecore_sb_info *sb, 7051a998268SRasesh Mody u16 qid, struct ecore_sb_info_dbg *sb_dbg) 7061a998268SRasesh Mody { 7071a998268SRasesh Mody struct ecore_hwfn *hwfn = &edev->hwfns[qid % edev->num_hwfns]; 7081a998268SRasesh Mody struct ecore_ptt *ptt; 7091a998268SRasesh Mody int rc; 7101a998268SRasesh Mody 7111a998268SRasesh Mody if (IS_VF(edev)) 7121a998268SRasesh Mody return -EINVAL; 7131a998268SRasesh Mody 7141a998268SRasesh Mody ptt = ecore_ptt_acquire(hwfn); 7151a998268SRasesh Mody if (!ptt) { 7161a998268SRasesh Mody DP_NOTICE(hwfn, true, "Can't acquire PTT\n"); 7171a998268SRasesh Mody return -EAGAIN; 7181a998268SRasesh Mody } 7191a998268SRasesh Mody 7201a998268SRasesh Mody memset(sb_dbg, 0, sizeof(*sb_dbg)); 7211a998268SRasesh Mody rc = ecore_int_get_sb_dbg(hwfn, ptt, sb, sb_dbg); 7221a998268SRasesh Mody 7231a998268SRasesh Mody ecore_ptt_release(hwfn, ptt); 7241a998268SRasesh Mody return rc; 7251a998268SRasesh Mody } 7261a998268SRasesh Mody 7272ea6f76aSRasesh Mody const struct qed_common_ops qed_common_ops_pass = { 7282ea6f76aSRasesh Mody INIT_STRUCT_FIELD(probe, &qed_probe), 7292ea6f76aSRasesh Mody INIT_STRUCT_FIELD(update_pf_params, &qed_update_pf_params), 7302ea6f76aSRasesh Mody INIT_STRUCT_FIELD(slowpath_start, &qed_slowpath_start), 731de5588afSRasesh Mody INIT_STRUCT_FIELD(set_name, &qed_set_name), 7322ea6f76aSRasesh Mody INIT_STRUCT_FIELD(chain_alloc, &ecore_chain_alloc), 7332ea6f76aSRasesh Mody INIT_STRUCT_FIELD(chain_free, &ecore_chain_free), 7342ea6f76aSRasesh Mody INIT_STRUCT_FIELD(sb_init, &qed_sb_init), 7352ea6f76aSRasesh Mody INIT_STRUCT_FIELD(get_link, &qed_get_current_link), 7362ea6f76aSRasesh Mody INIT_STRUCT_FIELD(set_link, &qed_set_link), 7372ea6f76aSRasesh Mody INIT_STRUCT_FIELD(drain, &qed_drain), 7382ea6f76aSRasesh Mody INIT_STRUCT_FIELD(slowpath_stop, &qed_slowpath_stop), 7392ea6f76aSRasesh Mody INIT_STRUCT_FIELD(remove, &qed_remove), 7403ca097bbSRasesh Mody INIT_STRUCT_FIELD(send_drv_state, &qed_send_drv_state), 7412ea6f76aSRasesh Mody }; 742