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 = 222e2f392bSRasesh Mody "/lib/firmware/qed/qed_init_values-8.20.0.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, 434c4bdadfSHarish Patil uint32_t dp_module, uint8_t dp_level, bool is_vf) 442ea6f76aSRasesh Mody { 4522d07d93SRasesh Mody struct ecore_hw_prepare_params hw_prepare_params; 462ea6f76aSRasesh Mody int rc; 472ea6f76aSRasesh Mody 482ea6f76aSRasesh Mody ecore_init_struct(edev); 49de5588afSRasesh Mody edev->drv_type = DRV_ID_DRV_TYPE_LINUX; 504c4bdadfSHarish Patil /* Protocol type is always fixed to PROTOCOL_ETH */ 51de5588afSRasesh Mody 52c0bd1181SRasesh Mody if (is_vf) 532ea6f76aSRasesh Mody edev->b_is_vf = true; 54c0bd1181SRasesh Mody 552ea6f76aSRasesh Mody ecore_init_dp(edev, dp_module, dp_level, NULL); 562ea6f76aSRasesh Mody qed_init_pci(edev, pci_dev); 5722d07d93SRasesh Mody 5822d07d93SRasesh Mody memset(&hw_prepare_params, 0, sizeof(hw_prepare_params)); 5922d07d93SRasesh Mody hw_prepare_params.personality = ECORE_PCI_ETH; 6022d07d93SRasesh Mody hw_prepare_params.drv_resc_alloc = false; 6122d07d93SRasesh Mody hw_prepare_params.chk_reg_fifo = false; 629e2f08a4SRasesh Mody hw_prepare_params.initiate_pf_flr = true; 633d5083f2SRasesh Mody hw_prepare_params.allow_mdump = false; 64f8da0cd6SRasesh Mody hw_prepare_params.epoch = (u32)time(NULL); 6522d07d93SRasesh Mody rc = ecore_hw_prepare(edev, &hw_prepare_params); 662ea6f76aSRasesh Mody if (rc) { 672ea6f76aSRasesh Mody DP_ERR(edev, "hw prepare failed\n"); 682ea6f76aSRasesh Mody return rc; 692ea6f76aSRasesh Mody } 702ea6f76aSRasesh Mody 712ea6f76aSRasesh Mody return rc; 722ea6f76aSRasesh Mody } 732ea6f76aSRasesh Mody 742ea6f76aSRasesh Mody static int qed_nic_setup(struct ecore_dev *edev) 752ea6f76aSRasesh Mody { 76af785e47SRasesh Mody int rc; 772ea6f76aSRasesh Mody 782ea6f76aSRasesh Mody rc = ecore_resc_alloc(edev); 792ea6f76aSRasesh Mody if (rc) 802ea6f76aSRasesh Mody return rc; 812ea6f76aSRasesh Mody 822ea6f76aSRasesh Mody DP_INFO(edev, "Allocated qed resources\n"); 832ea6f76aSRasesh Mody ecore_resc_setup(edev); 842ea6f76aSRasesh Mody 852ea6f76aSRasesh Mody return rc; 862ea6f76aSRasesh Mody } 872ea6f76aSRasesh Mody 8848e8d239SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW 892ea6f76aSRasesh Mody static int qed_alloc_stream_mem(struct ecore_dev *edev) 902ea6f76aSRasesh Mody { 912ea6f76aSRasesh Mody int i; 922ea6f76aSRasesh Mody 932ea6f76aSRasesh Mody for_each_hwfn(edev, i) { 942ea6f76aSRasesh Mody struct ecore_hwfn *p_hwfn = &edev->hwfns[i]; 952ea6f76aSRasesh Mody 962ea6f76aSRasesh Mody p_hwfn->stream = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, 972ea6f76aSRasesh Mody sizeof(*p_hwfn->stream)); 982ea6f76aSRasesh Mody if (!p_hwfn->stream) 992ea6f76aSRasesh Mody return -ENOMEM; 1002ea6f76aSRasesh Mody } 1012ea6f76aSRasesh Mody 1022ea6f76aSRasesh Mody return 0; 1032ea6f76aSRasesh Mody } 1042ea6f76aSRasesh Mody 1052ea6f76aSRasesh Mody static void qed_free_stream_mem(struct ecore_dev *edev) 1062ea6f76aSRasesh Mody { 1072ea6f76aSRasesh Mody int i; 1082ea6f76aSRasesh Mody 1092ea6f76aSRasesh Mody for_each_hwfn(edev, i) { 1102ea6f76aSRasesh Mody struct ecore_hwfn *p_hwfn = &edev->hwfns[i]; 1112ea6f76aSRasesh Mody 1122ea6f76aSRasesh Mody if (!p_hwfn->stream) 1132ea6f76aSRasesh Mody return; 1142ea6f76aSRasesh Mody 1152ea6f76aSRasesh Mody OSAL_FREE(p_hwfn->p_dev, p_hwfn->stream); 1162ea6f76aSRasesh Mody } 1172ea6f76aSRasesh Mody } 11848e8d239SRasesh Mody #endif 1192ea6f76aSRasesh Mody 12048e8d239SRasesh Mody #ifdef CONFIG_ECORE_BINARY_FW 1212ea6f76aSRasesh Mody static int qed_load_firmware_data(struct ecore_dev *edev) 1222ea6f76aSRasesh Mody { 1232ea6f76aSRasesh Mody int fd; 1242ea6f76aSRasesh Mody struct stat st; 1252ea6f76aSRasesh Mody const char *fw = RTE_LIBRTE_QEDE_FW; 1262ea6f76aSRasesh Mody 1272ea6f76aSRasesh Mody if (strcmp(fw, "") == 0) 1282ea6f76aSRasesh Mody strcpy(fw_file, QEDE_DEFAULT_FIRMWARE); 1292ea6f76aSRasesh Mody else 1302ea6f76aSRasesh Mody strcpy(fw_file, fw); 1312ea6f76aSRasesh Mody 1322ea6f76aSRasesh Mody fd = open(fw_file, O_RDONLY); 1332ea6f76aSRasesh Mody if (fd < 0) { 1344ffa2af9SRasesh Mody DP_ERR(edev, "Can't open firmware file\n"); 1352ea6f76aSRasesh Mody return -ENOENT; 1362ea6f76aSRasesh Mody } 1372ea6f76aSRasesh Mody 1382ea6f76aSRasesh Mody if (fstat(fd, &st) < 0) { 1394ffa2af9SRasesh Mody DP_ERR(edev, "Can't stat firmware file\n"); 1407bb4b070SYong Wang close(fd); 1412ea6f76aSRasesh Mody return -1; 1422ea6f76aSRasesh Mody } 1432ea6f76aSRasesh Mody 1442ea6f76aSRasesh Mody edev->firmware = rte_zmalloc("qede_fw", st.st_size, 1452ea6f76aSRasesh Mody RTE_CACHE_LINE_SIZE); 1462ea6f76aSRasesh Mody if (!edev->firmware) { 1474ffa2af9SRasesh Mody DP_ERR(edev, "Can't allocate memory for firmware\n"); 1482ea6f76aSRasesh Mody close(fd); 1492ea6f76aSRasesh Mody return -ENOMEM; 1502ea6f76aSRasesh Mody } 1512ea6f76aSRasesh Mody 1522ea6f76aSRasesh Mody if (read(fd, edev->firmware, st.st_size) != st.st_size) { 1534ffa2af9SRasesh Mody DP_ERR(edev, "Can't read firmware data\n"); 1542ea6f76aSRasesh Mody close(fd); 1552ea6f76aSRasesh Mody return -1; 1562ea6f76aSRasesh Mody } 1572ea6f76aSRasesh Mody 1582ea6f76aSRasesh Mody edev->fw_len = st.st_size; 1592ea6f76aSRasesh Mody if (edev->fw_len < 104) { 1604ffa2af9SRasesh Mody DP_ERR(edev, "Invalid fw size: %" PRIu64 "\n", 1612ea6f76aSRasesh Mody edev->fw_len); 1627bb4b070SYong Wang close(fd); 1632ea6f76aSRasesh Mody return -EINVAL; 1642ea6f76aSRasesh Mody } 1652ea6f76aSRasesh Mody 1667bb4b070SYong Wang close(fd); 1672ea6f76aSRasesh Mody return 0; 1682ea6f76aSRasesh Mody } 16948e8d239SRasesh Mody #endif 1702ea6f76aSRasesh Mody 17186a2265eSRasesh Mody static void qed_handle_bulletin_change(struct ecore_hwfn *hwfn) 17286a2265eSRasesh Mody { 17386a2265eSRasesh Mody uint8_t mac[ETH_ALEN], is_mac_exist, is_mac_forced; 17486a2265eSRasesh Mody 17586a2265eSRasesh Mody is_mac_exist = ecore_vf_bulletin_get_forced_mac(hwfn, mac, 17686a2265eSRasesh Mody &is_mac_forced); 17786a2265eSRasesh Mody if (is_mac_exist && is_mac_forced) 17886a2265eSRasesh Mody rte_memcpy(hwfn->hw_info.hw_mac_addr, mac, ETH_ALEN); 17986a2265eSRasesh Mody 18086a2265eSRasesh Mody /* Always update link configuration according to bulletin */ 18186a2265eSRasesh Mody qed_link_update(hwfn); 18286a2265eSRasesh Mody } 18386a2265eSRasesh Mody 18486a2265eSRasesh Mody static void qede_vf_task(void *arg) 18586a2265eSRasesh Mody { 18686a2265eSRasesh Mody struct ecore_hwfn *p_hwfn = arg; 18786a2265eSRasesh Mody uint8_t change = 0; 18886a2265eSRasesh Mody 18986a2265eSRasesh Mody /* Read the bulletin board, and re-schedule the task */ 19086a2265eSRasesh Mody ecore_vf_read_bulletin(p_hwfn, &change); 19186a2265eSRasesh Mody if (change) 19286a2265eSRasesh Mody qed_handle_bulletin_change(p_hwfn); 19386a2265eSRasesh Mody 19486a2265eSRasesh Mody rte_eal_alarm_set(QEDE_ALARM_TIMEOUT_US, qede_vf_task, p_hwfn); 19586a2265eSRasesh Mody } 19686a2265eSRasesh Mody 19786a2265eSRasesh Mody static void qed_start_iov_task(struct ecore_dev *edev) 19886a2265eSRasesh Mody { 19986a2265eSRasesh Mody struct ecore_hwfn *p_hwfn; 20086a2265eSRasesh Mody int i; 20186a2265eSRasesh Mody 20286a2265eSRasesh Mody for_each_hwfn(edev, i) { 20386a2265eSRasesh Mody p_hwfn = &edev->hwfns[i]; 20486a2265eSRasesh Mody if (!IS_PF(edev)) 20586a2265eSRasesh Mody rte_eal_alarm_set(QEDE_ALARM_TIMEOUT_US, qede_vf_task, 20686a2265eSRasesh Mody p_hwfn); 20786a2265eSRasesh Mody } 20886a2265eSRasesh Mody } 20986a2265eSRasesh Mody 21086a2265eSRasesh Mody static void qed_stop_iov_task(struct ecore_dev *edev) 21186a2265eSRasesh Mody { 21286a2265eSRasesh Mody struct ecore_hwfn *p_hwfn; 21386a2265eSRasesh Mody int i; 21486a2265eSRasesh Mody 21586a2265eSRasesh Mody for_each_hwfn(edev, i) { 21686a2265eSRasesh Mody p_hwfn = &edev->hwfns[i]; 21786a2265eSRasesh Mody if (!IS_PF(edev)) 21886a2265eSRasesh Mody rte_eal_alarm_cancel(qede_vf_task, p_hwfn); 21986a2265eSRasesh Mody } 22086a2265eSRasesh Mody } 2212ea6f76aSRasesh Mody static int qed_slowpath_start(struct ecore_dev *edev, 2222ea6f76aSRasesh Mody struct qed_slowpath_params *params) 2232ea6f76aSRasesh Mody { 2242ea6f76aSRasesh Mody const uint8_t *data = NULL; 2252ea6f76aSRasesh Mody struct ecore_hwfn *hwfn; 2262ea6f76aSRasesh Mody struct ecore_mcp_drv_version drv_version; 227301ea2d7SRasesh Mody struct ecore_hw_init_params hw_init_params; 22862207535SHarish Patil struct ecore_ptt *p_ptt; 2292ea6f76aSRasesh Mody int rc; 2302ea6f76aSRasesh Mody 23186a2265eSRasesh Mody if (IS_PF(edev)) { 23262207535SHarish Patil #ifdef CONFIG_ECORE_BINARY_FW 2332ea6f76aSRasesh Mody rc = qed_load_firmware_data(edev); 2342ea6f76aSRasesh Mody if (rc) { 235869c47d0SRasesh Mody DP_ERR(edev, "Failed to find fw file %s\n", fw_file); 2362ea6f76aSRasesh Mody goto err; 2372ea6f76aSRasesh Mody } 2382ea6f76aSRasesh Mody #endif 23962207535SHarish Patil hwfn = ECORE_LEADING_HWFN(edev); 24062207535SHarish Patil if (edev->num_hwfns == 1) { /* skip aRFS for 100G device */ 24162207535SHarish Patil p_ptt = ecore_ptt_acquire(hwfn); 24262207535SHarish Patil if (p_ptt) { 24362207535SHarish Patil ECORE_LEADING_HWFN(edev)->p_arfs_ptt = p_ptt; 24462207535SHarish Patil } else { 24562207535SHarish Patil DP_ERR(edev, "Failed to acquire PTT for flowdir\n"); 24662207535SHarish Patil rc = -ENOMEM; 24762207535SHarish Patil goto err; 24862207535SHarish Patil } 24962207535SHarish Patil } 25062207535SHarish Patil } 2512ea6f76aSRasesh Mody 2522ea6f76aSRasesh Mody rc = qed_nic_setup(edev); 2532ea6f76aSRasesh Mody if (rc) 2542ea6f76aSRasesh Mody goto err; 2552ea6f76aSRasesh Mody 2562ea6f76aSRasesh Mody /* set int_coalescing_mode */ 2572ea6f76aSRasesh Mody edev->int_coalescing_mode = ECORE_COAL_MODE_ENABLE; 2582ea6f76aSRasesh Mody 25948e8d239SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW 26086a2265eSRasesh Mody if (IS_PF(edev)) { 2612ea6f76aSRasesh Mody /* Allocate stream for unzipping */ 2622ea6f76aSRasesh Mody rc = qed_alloc_stream_mem(edev); 2632ea6f76aSRasesh Mody if (rc) { 2644ffa2af9SRasesh Mody DP_ERR(edev, "Failed to allocate stream memory\n"); 265c2069af8SRasesh Mody goto err1; 2662ea6f76aSRasesh Mody } 26786a2265eSRasesh Mody } 268af785e47SRasesh Mody #endif 26986a2265eSRasesh Mody 27086a2265eSRasesh Mody qed_start_iov_task(edev); 2712ea6f76aSRasesh Mody 27248e8d239SRasesh Mody #ifdef CONFIG_ECORE_BINARY_FW 27386a2265eSRasesh Mody if (IS_PF(edev)) 27422d07d93SRasesh Mody data = (const uint8_t *)edev->firmware + sizeof(u32); 2752ea6f76aSRasesh Mody #endif 27622d07d93SRasesh Mody 277301ea2d7SRasesh Mody /* Start the slowpath */ 278301ea2d7SRasesh Mody memset(&hw_init_params, 0, sizeof(hw_init_params)); 279301ea2d7SRasesh Mody hw_init_params.b_hw_start = true; 280301ea2d7SRasesh Mody hw_init_params.int_mode = ECORE_INT_MODE_MSIX; 28162207535SHarish Patil hw_init_params.allow_npar_tx_switch = true; 282301ea2d7SRasesh Mody hw_init_params.bin_fw_data = data; 2830b6bf70dSRasesh Mody hw_init_params.mfw_timeout_val = ECORE_LOAD_REQ_LOCK_TO_DEFAULT; 2840b6bf70dSRasesh Mody hw_init_params.avoid_eng_reset = false; 285301ea2d7SRasesh Mody rc = ecore_hw_init(edev, &hw_init_params); 2862ea6f76aSRasesh Mody if (rc) { 2872ea6f76aSRasesh Mody DP_ERR(edev, "ecore_hw_init failed\n"); 2882ea6f76aSRasesh Mody goto err2; 2892ea6f76aSRasesh Mody } 2902ea6f76aSRasesh Mody 2912ea6f76aSRasesh Mody DP_INFO(edev, "HW inited and function started\n"); 2922ea6f76aSRasesh Mody 29386a2265eSRasesh Mody if (IS_PF(edev)) { 2942ea6f76aSRasesh Mody hwfn = ECORE_LEADING_HWFN(edev); 2952ea6f76aSRasesh Mody drv_version.version = (params->drv_major << 24) | 2962ea6f76aSRasesh Mody (params->drv_minor << 16) | 2972ea6f76aSRasesh Mody (params->drv_rev << 8) | (params->drv_eng); 2982ea6f76aSRasesh Mody /* TBD: strlcpy() */ 2992ea6f76aSRasesh Mody strncpy((char *)drv_version.name, (const char *)params->name, 3002ea6f76aSRasesh Mody MCP_DRV_VER_STR_SIZE - 4); 3012ea6f76aSRasesh Mody rc = ecore_mcp_send_drv_version(hwfn, hwfn->p_main_ptt, 3022ea6f76aSRasesh Mody &drv_version); 3032ea6f76aSRasesh Mody if (rc) { 3044ffa2af9SRasesh Mody DP_ERR(edev, "Failed sending drv version command\n"); 305c2069af8SRasesh Mody goto err3; 3062ea6f76aSRasesh Mody } 30786a2265eSRasesh Mody } 3082ea6f76aSRasesh Mody 3095cdd769aSRasesh Mody ecore_reset_vport_stats(edev); 3105cdd769aSRasesh Mody 3112ea6f76aSRasesh Mody return 0; 3122ea6f76aSRasesh Mody 313c2069af8SRasesh Mody err3: 3142ea6f76aSRasesh Mody ecore_hw_stop(edev); 3152ea6f76aSRasesh Mody err2: 316c2069af8SRasesh Mody qed_stop_iov_task(edev); 317c2069af8SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW 318c2069af8SRasesh Mody qed_free_stream_mem(edev); 319c2069af8SRasesh Mody err1: 320c2069af8SRasesh Mody #endif 3212ea6f76aSRasesh Mody ecore_resc_free(edev); 3222ea6f76aSRasesh Mody err: 32348e8d239SRasesh Mody #ifdef CONFIG_ECORE_BINARY_FW 32486a2265eSRasesh Mody if (IS_PF(edev)) { 3252ea6f76aSRasesh Mody if (edev->firmware) 3262ea6f76aSRasesh Mody rte_free(edev->firmware); 3272ea6f76aSRasesh Mody edev->firmware = NULL; 32886a2265eSRasesh Mody } 3292ea6f76aSRasesh Mody #endif 33086a2265eSRasesh Mody qed_stop_iov_task(edev); 33186a2265eSRasesh Mody 3322ea6f76aSRasesh Mody return rc; 3332ea6f76aSRasesh Mody } 3342ea6f76aSRasesh Mody 3352ea6f76aSRasesh Mody static int 3362ea6f76aSRasesh Mody qed_fill_dev_info(struct ecore_dev *edev, struct qed_dev_info *dev_info) 3372ea6f76aSRasesh Mody { 338*652ee28aSRasesh Mody struct ecore_hwfn *p_hwfn = ECORE_LEADING_HWFN(edev); 3392ea6f76aSRasesh Mody struct ecore_ptt *ptt = NULL; 340a7f3cac3SRasesh Mody struct ecore_tunnel_info *tun = &edev->tunnel; 3412ea6f76aSRasesh Mody 3422ea6f76aSRasesh Mody memset(dev_info, 0, sizeof(struct qed_dev_info)); 343a7f3cac3SRasesh Mody 344adce1f86SRasesh Mody if (tun->vxlan.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN && 345adce1f86SRasesh Mody tun->vxlan.b_mode_enabled) 346a7f3cac3SRasesh Mody dev_info->vxlan_enable = true; 347a7f3cac3SRasesh Mody 348adce1f86SRasesh Mody if (tun->l2_gre.b_mode_enabled && tun->ip_gre.b_mode_enabled && 349adce1f86SRasesh Mody tun->l2_gre.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN && 350adce1f86SRasesh Mody tun->ip_gre.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN) 351a7f3cac3SRasesh Mody dev_info->gre_enable = true; 352a7f3cac3SRasesh Mody 353adce1f86SRasesh Mody if (tun->l2_geneve.b_mode_enabled && tun->ip_geneve.b_mode_enabled && 354adce1f86SRasesh Mody tun->l2_geneve.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN && 355adce1f86SRasesh Mody tun->ip_geneve.tun_cls == ECORE_TUNN_CLSS_MAC_VLAN) 356a7f3cac3SRasesh Mody dev_info->geneve_enable = true; 357a7f3cac3SRasesh Mody 3582ea6f76aSRasesh Mody dev_info->num_hwfns = edev->num_hwfns; 3592ea6f76aSRasesh Mody dev_info->is_mf_default = IS_MF_DEFAULT(&edev->hwfns[0]); 3604fc58baeSRasesh Mody dev_info->mtu = ECORE_LEADING_HWFN(edev)->hw_info.mtu; 361dc8eba81SRasesh Mody dev_info->dev_type = edev->type; 3624fc58baeSRasesh Mody 3632ea6f76aSRasesh Mody rte_memcpy(&dev_info->hw_mac, &edev->hwfns[0].hw_info.hw_mac_addr, 3642ea6f76aSRasesh Mody ETHER_ADDR_LEN); 3652ea6f76aSRasesh Mody 3662ea6f76aSRasesh Mody dev_info->fw_major = FW_MAJOR_VERSION; 3672ea6f76aSRasesh Mody dev_info->fw_minor = FW_MINOR_VERSION; 3682ea6f76aSRasesh Mody dev_info->fw_rev = FW_REVISION_VERSION; 3692ea6f76aSRasesh Mody dev_info->fw_eng = FW_ENGINEERING_VERSION; 370738f56d4SRasesh Mody 371738f56d4SRasesh Mody if (IS_PF(edev)) { 3722ea6f76aSRasesh Mody dev_info->mf_mode = edev->mf_mode; 3732ea6f76aSRasesh Mody dev_info->tx_switching = false; 3742ea6f76aSRasesh Mody 375*652ee28aSRasesh Mody dev_info->smart_an = ecore_mcp_is_smart_an_supported(p_hwfn); 376*652ee28aSRasesh 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 { 404f1e4b6c0SHarish Patil uint8_t queues = 0; 4052ea6f76aSRasesh Mody int i; 4062ea6f76aSRasesh Mody 4072ea6f76aSRasesh Mody memset(info, 0, sizeof(*info)); 4082ea6f76aSRasesh Mody 4092ea6f76aSRasesh Mody info->num_tc = 1 /* @@@TBD aelior MULTI_COS */; 4102ea6f76aSRasesh Mody 41186a2265eSRasesh Mody if (IS_PF(edev)) { 412d6cb1753SHarish Patil int max_vf_vlan_filters = 0; 413d6cb1753SHarish Patil 4142ea6f76aSRasesh Mody info->num_queues = 0; 4152ea6f76aSRasesh Mody for_each_hwfn(edev, i) 4162ea6f76aSRasesh Mody info->num_queues += 4172ea6f76aSRasesh Mody FEAT_NUM(&edev->hwfns[i], ECORE_PF_L2_QUE); 4182ea6f76aSRasesh Mody 419d6cb1753SHarish Patil if (edev->p_iov_info) 420d6cb1753SHarish Patil max_vf_vlan_filters = edev->p_iov_info->total_vfs * 421d6cb1753SHarish Patil ECORE_ETH_VF_NUM_VLAN_FILTERS; 422d6cb1753SHarish Patil info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN) - 423d6cb1753SHarish Patil max_vf_vlan_filters; 4242ea6f76aSRasesh Mody 4252ea6f76aSRasesh Mody rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr, 4262ea6f76aSRasesh Mody ETHER_ADDR_LEN); 42786a2265eSRasesh Mody } else { 428f1e4b6c0SHarish Patil ecore_vf_get_num_rxqs(ECORE_LEADING_HWFN(edev), 429f1e4b6c0SHarish Patil &info->num_queues); 430f1e4b6c0SHarish Patil if (edev->num_hwfns > 1) { 431f1e4b6c0SHarish Patil ecore_vf_get_num_rxqs(&edev->hwfns[1], &queues); 432f1e4b6c0SHarish Patil info->num_queues += queues; 433f1e4b6c0SHarish Patil } 43486a2265eSRasesh Mody 43586a2265eSRasesh Mody ecore_vf_get_num_vlan_filters(&edev->hwfns[0], 436d6cb1753SHarish Patil (u8 *)&info->num_vlan_filters); 43786a2265eSRasesh Mody 43886a2265eSRasesh Mody ecore_vf_get_port_mac(&edev->hwfns[0], 43986a2265eSRasesh Mody (uint8_t *)&info->port_mac); 4403d4bb441SHarish Patil 4413d4bb441SHarish Patil info->is_legacy = ecore_vf_get_pre_fp_hsi(&edev->hwfns[0]); 44286a2265eSRasesh Mody } 4432ea6f76aSRasesh Mody 4442ea6f76aSRasesh Mody qed_fill_dev_info(edev, &info->common); 4452ea6f76aSRasesh Mody 44686a2265eSRasesh Mody if (IS_VF(edev)) 44786a2265eSRasesh Mody memset(&info->common.hw_mac, 0, ETHER_ADDR_LEN); 44886a2265eSRasesh Mody 4492ea6f76aSRasesh Mody return 0; 4502ea6f76aSRasesh Mody } 4512ea6f76aSRasesh Mody 452de5588afSRasesh Mody static void qed_set_name(struct ecore_dev *edev, char name[NAME_SIZE]) 4532ea6f76aSRasesh Mody { 4542ea6f76aSRasesh Mody int i; 4552ea6f76aSRasesh Mody 4562ea6f76aSRasesh Mody rte_memcpy(edev->name, name, NAME_SIZE); 4572ea6f76aSRasesh Mody for_each_hwfn(edev, i) { 4582ea6f76aSRasesh Mody snprintf(edev->hwfns[i].name, NAME_SIZE, "%s-%d", name, i); 4592ea6f76aSRasesh Mody } 4602ea6f76aSRasesh Mody } 4612ea6f76aSRasesh Mody 4622ea6f76aSRasesh Mody static uint32_t 4632ea6f76aSRasesh Mody qed_sb_init(struct ecore_dev *edev, struct ecore_sb_info *sb_info, 4644c4bdadfSHarish Patil void *sb_virt_addr, dma_addr_t sb_phy_addr, uint16_t sb_id) 4652ea6f76aSRasesh Mody { 4662ea6f76aSRasesh Mody struct ecore_hwfn *p_hwfn; 4672ea6f76aSRasesh Mody int hwfn_index; 4682ea6f76aSRasesh Mody uint16_t rel_sb_id; 4694c4bdadfSHarish Patil uint8_t n_hwfns = edev->num_hwfns; 4702ea6f76aSRasesh Mody uint32_t rc; 4712ea6f76aSRasesh Mody 4722ea6f76aSRasesh Mody hwfn_index = sb_id % n_hwfns; 4732ea6f76aSRasesh Mody p_hwfn = &edev->hwfns[hwfn_index]; 4742ea6f76aSRasesh Mody rel_sb_id = sb_id / n_hwfns; 4752ea6f76aSRasesh Mody 4762ea6f76aSRasesh Mody DP_INFO(edev, "hwfn [%d] <--[init]-- SB %04x [0x%04x upper]\n", 4772ea6f76aSRasesh Mody hwfn_index, rel_sb_id, sb_id); 4782ea6f76aSRasesh Mody 4792ea6f76aSRasesh Mody rc = ecore_int_sb_init(p_hwfn, p_hwfn->p_main_ptt, sb_info, 4802ea6f76aSRasesh Mody sb_virt_addr, sb_phy_addr, rel_sb_id); 4812ea6f76aSRasesh Mody 4822ea6f76aSRasesh Mody return rc; 4832ea6f76aSRasesh Mody } 4842ea6f76aSRasesh Mody 4852ea6f76aSRasesh Mody static void qed_fill_link(struct ecore_hwfn *hwfn, 4862ea6f76aSRasesh Mody struct qed_link_output *if_link) 4872ea6f76aSRasesh Mody { 4882ea6f76aSRasesh Mody struct ecore_mcp_link_params params; 4892ea6f76aSRasesh Mody struct ecore_mcp_link_state link; 4902ea6f76aSRasesh Mody struct ecore_mcp_link_capabilities link_caps; 4912ea6f76aSRasesh Mody uint8_t change = 0; 4922ea6f76aSRasesh Mody 4932ea6f76aSRasesh Mody memset(if_link, 0, sizeof(*if_link)); 4942ea6f76aSRasesh Mody 4952ea6f76aSRasesh Mody /* Prepare source inputs */ 49686a2265eSRasesh Mody if (IS_PF(hwfn->p_dev)) { 4972ea6f76aSRasesh Mody rte_memcpy(¶ms, ecore_mcp_get_link_params(hwfn), 4982ea6f76aSRasesh Mody sizeof(params)); 4992ea6f76aSRasesh Mody rte_memcpy(&link, ecore_mcp_get_link_state(hwfn), sizeof(link)); 5002ea6f76aSRasesh Mody rte_memcpy(&link_caps, ecore_mcp_get_link_capabilities(hwfn), 5012ea6f76aSRasesh Mody sizeof(link_caps)); 50286a2265eSRasesh Mody } else { 50386a2265eSRasesh Mody ecore_vf_read_bulletin(hwfn, &change); 50486a2265eSRasesh Mody ecore_vf_get_link_params(hwfn, ¶ms); 50586a2265eSRasesh Mody ecore_vf_get_link_state(hwfn, &link); 50686a2265eSRasesh Mody ecore_vf_get_link_caps(hwfn, &link_caps); 50786a2265eSRasesh Mody } 5082ea6f76aSRasesh Mody 5092ea6f76aSRasesh Mody /* Set the link parameters to pass to protocol driver */ 5102ea6f76aSRasesh Mody if (link.link_up) 5112ea6f76aSRasesh Mody if_link->link_up = true; 5122ea6f76aSRasesh Mody 5132ea6f76aSRasesh Mody if (link.link_up) 5142ea6f76aSRasesh Mody if_link->speed = link.speed; 5152ea6f76aSRasesh Mody 5162ea6f76aSRasesh Mody if_link->duplex = QEDE_DUPLEX_FULL; 5172ea6f76aSRasesh Mody 5181ea56b80SHarish Patil /* Fill up the native advertised speed cap mask */ 5191ea56b80SHarish Patil if_link->adv_speed = params.speed.advertised_speeds; 52064c239b7SHarish Patil 5212ea6f76aSRasesh Mody if (params.speed.autoneg) 5222ea6f76aSRasesh Mody if_link->supported_caps |= QEDE_SUPPORTED_AUTONEG; 5232ea6f76aSRasesh Mody 5242ea6f76aSRasesh Mody if (params.pause.autoneg || params.pause.forced_rx || 5252ea6f76aSRasesh Mody params.pause.forced_tx) 5262ea6f76aSRasesh Mody if_link->supported_caps |= QEDE_SUPPORTED_PAUSE; 5272ea6f76aSRasesh Mody 5282ea6f76aSRasesh Mody if (params.pause.autoneg) 5292ea6f76aSRasesh Mody if_link->pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE; 5302ea6f76aSRasesh Mody 5312ea6f76aSRasesh Mody if (params.pause.forced_rx) 5322ea6f76aSRasesh Mody if_link->pause_config |= QED_LINK_PAUSE_RX_ENABLE; 5332ea6f76aSRasesh Mody 5342ea6f76aSRasesh Mody if (params.pause.forced_tx) 5352ea6f76aSRasesh Mody if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE; 5362ea6f76aSRasesh Mody } 5372ea6f76aSRasesh Mody 5382ea6f76aSRasesh Mody static void 5392ea6f76aSRasesh Mody qed_get_current_link(struct ecore_dev *edev, struct qed_link_output *if_link) 5402ea6f76aSRasesh Mody { 5412ea6f76aSRasesh Mody qed_fill_link(&edev->hwfns[0], if_link); 5422ea6f76aSRasesh Mody 5432ea6f76aSRasesh Mody #ifdef CONFIG_QED_SRIOV 5442ea6f76aSRasesh Mody for_each_hwfn(cdev, i) 5452ea6f76aSRasesh Mody qed_inform_vf_link_state(&cdev->hwfns[i]); 5462ea6f76aSRasesh Mody #endif 5472ea6f76aSRasesh Mody } 5482ea6f76aSRasesh Mody 5492ea6f76aSRasesh Mody static int qed_set_link(struct ecore_dev *edev, struct qed_link_params *params) 5502ea6f76aSRasesh Mody { 5512ea6f76aSRasesh Mody struct ecore_hwfn *hwfn; 5522ea6f76aSRasesh Mody struct ecore_ptt *ptt; 5532ea6f76aSRasesh Mody struct ecore_mcp_link_params *link_params; 5542ea6f76aSRasesh Mody int rc; 5552ea6f76aSRasesh Mody 55686a2265eSRasesh Mody if (IS_VF(edev)) 55786a2265eSRasesh Mody return 0; 55886a2265eSRasesh Mody 5592ea6f76aSRasesh Mody /* The link should be set only once per PF */ 5602ea6f76aSRasesh Mody hwfn = &edev->hwfns[0]; 5612ea6f76aSRasesh Mody 5622ea6f76aSRasesh Mody ptt = ecore_ptt_acquire(hwfn); 5632ea6f76aSRasesh Mody if (!ptt) 5642ea6f76aSRasesh Mody return -EBUSY; 5652ea6f76aSRasesh Mody 5662ea6f76aSRasesh Mody link_params = ecore_mcp_get_link_params(hwfn); 5672ea6f76aSRasesh Mody if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG) 5682ea6f76aSRasesh Mody link_params->speed.autoneg = params->autoneg; 5692ea6f76aSRasesh Mody 5702ea6f76aSRasesh Mody if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) { 5712ea6f76aSRasesh Mody if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE) 5722ea6f76aSRasesh Mody link_params->pause.autoneg = true; 5732ea6f76aSRasesh Mody else 5742ea6f76aSRasesh Mody link_params->pause.autoneg = false; 5752ea6f76aSRasesh Mody if (params->pause_config & QED_LINK_PAUSE_RX_ENABLE) 5762ea6f76aSRasesh Mody link_params->pause.forced_rx = true; 5772ea6f76aSRasesh Mody else 5782ea6f76aSRasesh Mody link_params->pause.forced_rx = false; 5792ea6f76aSRasesh Mody if (params->pause_config & QED_LINK_PAUSE_TX_ENABLE) 5802ea6f76aSRasesh Mody link_params->pause.forced_tx = true; 5812ea6f76aSRasesh Mody else 5822ea6f76aSRasesh Mody link_params->pause.forced_tx = false; 5832ea6f76aSRasesh Mody } 5842ea6f76aSRasesh Mody 5852ea6f76aSRasesh Mody rc = ecore_mcp_set_link(hwfn, ptt, params->link_up); 5862ea6f76aSRasesh Mody 5872ea6f76aSRasesh Mody ecore_ptt_release(hwfn, ptt); 5882ea6f76aSRasesh Mody 5892ea6f76aSRasesh Mody return rc; 5902ea6f76aSRasesh Mody } 5912ea6f76aSRasesh Mody 59286a2265eSRasesh Mody void qed_link_update(struct ecore_hwfn *hwfn) 59386a2265eSRasesh Mody { 59486a2265eSRasesh Mody struct qed_link_output if_link; 59586a2265eSRasesh Mody 59686a2265eSRasesh Mody qed_fill_link(hwfn, &if_link); 59786a2265eSRasesh Mody } 59886a2265eSRasesh Mody 5992ea6f76aSRasesh Mody static int qed_drain(struct ecore_dev *edev) 6002ea6f76aSRasesh Mody { 6012ea6f76aSRasesh Mody struct ecore_hwfn *hwfn; 6022ea6f76aSRasesh Mody struct ecore_ptt *ptt; 6032ea6f76aSRasesh Mody int i, rc; 6042ea6f76aSRasesh Mody 60586a2265eSRasesh Mody if (IS_VF(edev)) 60686a2265eSRasesh Mody return 0; 60786a2265eSRasesh Mody 6082ea6f76aSRasesh Mody for_each_hwfn(edev, i) { 6092ea6f76aSRasesh Mody hwfn = &edev->hwfns[i]; 6102ea6f76aSRasesh Mody ptt = ecore_ptt_acquire(hwfn); 6112ea6f76aSRasesh Mody if (!ptt) { 6124ffa2af9SRasesh Mody DP_ERR(hwfn, "Failed to drain NIG; No PTT\n"); 6132ea6f76aSRasesh Mody return -EBUSY; 6142ea6f76aSRasesh Mody } 6152ea6f76aSRasesh Mody rc = ecore_mcp_drain(hwfn, ptt); 6162ea6f76aSRasesh Mody if (rc) 6172ea6f76aSRasesh Mody return rc; 6182ea6f76aSRasesh Mody ecore_ptt_release(hwfn, ptt); 6192ea6f76aSRasesh Mody } 6202ea6f76aSRasesh Mody 6212ea6f76aSRasesh Mody return 0; 6222ea6f76aSRasesh Mody } 6232ea6f76aSRasesh Mody 6242ea6f76aSRasesh Mody static int qed_nic_stop(struct ecore_dev *edev) 6252ea6f76aSRasesh Mody { 6262ea6f76aSRasesh Mody int i, rc; 6272ea6f76aSRasesh Mody 6282ea6f76aSRasesh Mody rc = ecore_hw_stop(edev); 6292ea6f76aSRasesh Mody for (i = 0; i < edev->num_hwfns; i++) { 6302ea6f76aSRasesh Mody struct ecore_hwfn *p_hwfn = &edev->hwfns[i]; 6312ea6f76aSRasesh Mody 6322ea6f76aSRasesh Mody if (p_hwfn->b_sp_dpc_enabled) 6332ea6f76aSRasesh Mody p_hwfn->b_sp_dpc_enabled = false; 6342ea6f76aSRasesh Mody } 6352ea6f76aSRasesh Mody return rc; 6362ea6f76aSRasesh Mody } 6372ea6f76aSRasesh Mody 6382ea6f76aSRasesh Mody static int qed_slowpath_stop(struct ecore_dev *edev) 6392ea6f76aSRasesh Mody { 6402ea6f76aSRasesh Mody #ifdef CONFIG_QED_SRIOV 6412ea6f76aSRasesh Mody int i; 6422ea6f76aSRasesh Mody #endif 6432ea6f76aSRasesh Mody 6442ea6f76aSRasesh Mody if (!edev) 6452ea6f76aSRasesh Mody return -ENODEV; 6462ea6f76aSRasesh Mody 64786a2265eSRasesh Mody if (IS_PF(edev)) { 64848e8d239SRasesh Mody #ifdef CONFIG_ECORE_ZIPPED_FW 6492ea6f76aSRasesh Mody qed_free_stream_mem(edev); 65048e8d239SRasesh Mody #endif 6512ea6f76aSRasesh Mody 65286a2265eSRasesh Mody #ifdef CONFIG_QED_SRIOV 65386a2265eSRasesh Mody if (IS_QED_ETH_IF(edev)) 65486a2265eSRasesh Mody qed_sriov_disable(edev, true); 65586a2265eSRasesh Mody #endif 65686a2265eSRasesh Mody } 6572ea6f76aSRasesh Mody 65839f0eb3bSRasesh Mody qed_nic_stop(edev); 65939f0eb3bSRasesh Mody 66039f0eb3bSRasesh Mody ecore_resc_free(edev); 66186a2265eSRasesh Mody qed_stop_iov_task(edev); 6622ea6f76aSRasesh Mody 6632ea6f76aSRasesh Mody return 0; 6642ea6f76aSRasesh Mody } 6652ea6f76aSRasesh Mody 6662ea6f76aSRasesh Mody static void qed_remove(struct ecore_dev *edev) 6672ea6f76aSRasesh Mody { 6682ea6f76aSRasesh Mody if (!edev) 6692ea6f76aSRasesh Mody return; 6702ea6f76aSRasesh Mody 6712ea6f76aSRasesh Mody ecore_hw_remove(edev); 6722ea6f76aSRasesh Mody } 6732ea6f76aSRasesh Mody 6743ca097bbSRasesh Mody static int qed_send_drv_state(struct ecore_dev *edev, bool active) 6753ca097bbSRasesh Mody { 6763ca097bbSRasesh Mody struct ecore_hwfn *hwfn = ECORE_LEADING_HWFN(edev); 6773ca097bbSRasesh Mody struct ecore_ptt *ptt; 6783ca097bbSRasesh Mody int status = 0; 6793ca097bbSRasesh Mody 6803ca097bbSRasesh Mody ptt = ecore_ptt_acquire(hwfn); 6813ca097bbSRasesh Mody if (!ptt) 6823ca097bbSRasesh Mody return -EAGAIN; 6833ca097bbSRasesh Mody 6843ca097bbSRasesh Mody status = ecore_mcp_ov_update_driver_state(hwfn, ptt, active ? 6853ca097bbSRasesh Mody ECORE_OV_DRIVER_STATE_ACTIVE : 6863ca097bbSRasesh Mody ECORE_OV_DRIVER_STATE_DISABLED); 6873ca097bbSRasesh Mody 6883ca097bbSRasesh Mody ecore_ptt_release(hwfn, ptt); 6893ca097bbSRasesh Mody 6903ca097bbSRasesh Mody return status; 6913ca097bbSRasesh Mody } 6923ca097bbSRasesh Mody 6931a998268SRasesh Mody static int qed_get_sb_info(struct ecore_dev *edev, struct ecore_sb_info *sb, 6941a998268SRasesh Mody u16 qid, struct ecore_sb_info_dbg *sb_dbg) 6951a998268SRasesh Mody { 6961a998268SRasesh Mody struct ecore_hwfn *hwfn = &edev->hwfns[qid % edev->num_hwfns]; 6971a998268SRasesh Mody struct ecore_ptt *ptt; 6981a998268SRasesh Mody int rc; 6991a998268SRasesh Mody 7001a998268SRasesh Mody if (IS_VF(edev)) 7011a998268SRasesh Mody return -EINVAL; 7021a998268SRasesh Mody 7031a998268SRasesh Mody ptt = ecore_ptt_acquire(hwfn); 7041a998268SRasesh Mody if (!ptt) { 7054ffa2af9SRasesh Mody DP_ERR(hwfn, "Can't acquire PTT\n"); 7061a998268SRasesh Mody return -EAGAIN; 7071a998268SRasesh Mody } 7081a998268SRasesh Mody 7091a998268SRasesh Mody memset(sb_dbg, 0, sizeof(*sb_dbg)); 7101a998268SRasesh Mody rc = ecore_int_get_sb_dbg(hwfn, ptt, sb, sb_dbg); 7111a998268SRasesh Mody 7121a998268SRasesh Mody ecore_ptt_release(hwfn, ptt); 7131a998268SRasesh Mody return rc; 7141a998268SRasesh Mody } 7151a998268SRasesh Mody 7162ea6f76aSRasesh Mody const struct qed_common_ops qed_common_ops_pass = { 7172ea6f76aSRasesh Mody INIT_STRUCT_FIELD(probe, &qed_probe), 7182ea6f76aSRasesh Mody INIT_STRUCT_FIELD(update_pf_params, &qed_update_pf_params), 7192ea6f76aSRasesh Mody INIT_STRUCT_FIELD(slowpath_start, &qed_slowpath_start), 720de5588afSRasesh Mody INIT_STRUCT_FIELD(set_name, &qed_set_name), 7212ea6f76aSRasesh Mody INIT_STRUCT_FIELD(chain_alloc, &ecore_chain_alloc), 7222ea6f76aSRasesh Mody INIT_STRUCT_FIELD(chain_free, &ecore_chain_free), 7232ea6f76aSRasesh Mody INIT_STRUCT_FIELD(sb_init, &qed_sb_init), 724af785e47SRasesh Mody INIT_STRUCT_FIELD(get_sb_info, &qed_get_sb_info), 7252ea6f76aSRasesh Mody INIT_STRUCT_FIELD(get_link, &qed_get_current_link), 7262ea6f76aSRasesh Mody INIT_STRUCT_FIELD(set_link, &qed_set_link), 7272ea6f76aSRasesh Mody INIT_STRUCT_FIELD(drain, &qed_drain), 7282ea6f76aSRasesh Mody INIT_STRUCT_FIELD(slowpath_stop, &qed_slowpath_stop), 7292ea6f76aSRasesh Mody INIT_STRUCT_FIELD(remove, &qed_remove), 7303ca097bbSRasesh Mody INIT_STRUCT_FIELD(send_drv_state, &qed_send_drv_state), 7312ea6f76aSRasesh Mody }; 7324c4bdadfSHarish Patil 7334c4bdadfSHarish Patil const struct qed_eth_ops qed_eth_ops_pass = { 7344c4bdadfSHarish Patil INIT_STRUCT_FIELD(common, &qed_common_ops_pass), 7354c4bdadfSHarish Patil INIT_STRUCT_FIELD(fill_dev_info, &qed_fill_eth_dev_info), 7364c4bdadfSHarish Patil }; 7374c4bdadfSHarish Patil 7384c4bdadfSHarish Patil const struct qed_eth_ops *qed_get_eth_ops(void) 7394c4bdadfSHarish Patil { 7404c4bdadfSHarish Patil return &qed_eth_ops_pass; 7414c4bdadfSHarish Patil } 742