X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=inline;f=drivers%2Fnet%2Fqede%2Fqede_main.c;h=73608c697cbff411121e6458196d6d69692498b6;hb=fcdbe1fe1ab45d0572eec145850bd4e7991dff56;hp=b09fb85761ef63ba682cc441cf8909b84f1fc9d2;hpb=2ea6f76aff402be2c7a19cd244e83b46641bced5;p=dpdk.git diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c index b09fb85761..73608c697c 100644 --- a/drivers/net/qede/qede_main.c +++ b/drivers/net/qede/qede_main.c @@ -11,11 +11,15 @@ #include #include #include +#include #include "qede_ethdev.h" static uint8_t npar_tx_switching = 1; +/* Alarm timeout. */ +#define QEDE_ALARM_TIMEOUT_US 100000 + #define CONFIG_QED_BINARY_FW /* Global variable to hold absolute path of fw file */ char fw_file[PATH_MAX]; @@ -155,6 +159,56 @@ static int qed_load_firmware_data(struct ecore_dev *edev) return 0; } +static void qed_handle_bulletin_change(struct ecore_hwfn *hwfn) +{ + uint8_t mac[ETH_ALEN], is_mac_exist, is_mac_forced; + + is_mac_exist = ecore_vf_bulletin_get_forced_mac(hwfn, mac, + &is_mac_forced); + if (is_mac_exist && is_mac_forced) + rte_memcpy(hwfn->hw_info.hw_mac_addr, mac, ETH_ALEN); + + /* Always update link configuration according to bulletin */ + qed_link_update(hwfn); +} + +static void qede_vf_task(void *arg) +{ + struct ecore_hwfn *p_hwfn = arg; + uint8_t change = 0; + + /* Read the bulletin board, and re-schedule the task */ + ecore_vf_read_bulletin(p_hwfn, &change); + if (change) + qed_handle_bulletin_change(p_hwfn); + + rte_eal_alarm_set(QEDE_ALARM_TIMEOUT_US, qede_vf_task, p_hwfn); +} + +static void qed_start_iov_task(struct ecore_dev *edev) +{ + struct ecore_hwfn *p_hwfn; + int i; + + for_each_hwfn(edev, i) { + p_hwfn = &edev->hwfns[i]; + if (!IS_PF(edev)) + rte_eal_alarm_set(QEDE_ALARM_TIMEOUT_US, qede_vf_task, + p_hwfn); + } +} + +static void qed_stop_iov_task(struct ecore_dev *edev) +{ + struct ecore_hwfn *p_hwfn; + int i; + + for_each_hwfn(edev, i) { + p_hwfn = &edev->hwfns[i]; + if (!IS_PF(edev)) + rte_eal_alarm_cancel(qede_vf_task, p_hwfn); + } +} static int qed_slowpath_start(struct ecore_dev *edev, struct qed_slowpath_params *params) { @@ -169,11 +223,13 @@ static int qed_slowpath_start(struct ecore_dev *edev, #endif #ifdef CONFIG_QED_BINARY_FW - rc = qed_load_firmware_data(edev); - if (rc) { - DP_NOTICE(edev, true, - "Failed to find fw file %s\n", fw_file); - goto err; + if (IS_PF(edev)) { + rc = qed_load_firmware_data(edev); + if (rc) { + DP_NOTICE(edev, true, + "Failed to find fw file %s\n", fw_file); + goto err; + } } #endif @@ -185,17 +241,22 @@ static int qed_slowpath_start(struct ecore_dev *edev, edev->int_coalescing_mode = ECORE_COAL_MODE_ENABLE; /* Should go with CONFIG_QED_BINARY_FW */ - /* Allocate stream for unzipping */ - rc = qed_alloc_stream_mem(edev); - if (rc) { - DP_NOTICE(edev, true, - "Failed to allocate stream memory\n"); - goto err2; + if (IS_PF(edev)) { + /* Allocate stream for unzipping */ + rc = qed_alloc_stream_mem(edev); + if (rc) { + DP_NOTICE(edev, true, + "Failed to allocate stream memory\n"); + goto err2; + } } + qed_start_iov_task(edev); + /* Start the slowpath */ #ifdef CONFIG_QED_BINARY_FW - data = edev->firmware; + if (IS_PF(edev)) + data = edev->firmware; #endif allow_npar_tx_switching = npar_tx_switching ? true : false; @@ -221,21 +282,25 @@ static int qed_slowpath_start(struct ecore_dev *edev, DP_INFO(edev, "HW inited and function started\n"); - hwfn = ECORE_LEADING_HWFN(edev); - drv_version.version = (params->drv_major << 24) | + if (IS_PF(edev)) { + hwfn = ECORE_LEADING_HWFN(edev); + drv_version.version = (params->drv_major << 24) | (params->drv_minor << 16) | (params->drv_rev << 8) | (params->drv_eng); - /* TBD: strlcpy() */ - strncpy((char *)drv_version.name, (const char *)params->name, + /* TBD: strlcpy() */ + strncpy((char *)drv_version.name, (const char *)params->name, MCP_DRV_VER_STR_SIZE - 4); - rc = ecore_mcp_send_drv_version(hwfn, hwfn->p_main_ptt, + rc = ecore_mcp_send_drv_version(hwfn, hwfn->p_main_ptt, &drv_version); - if (rc) { - DP_NOTICE(edev, true, - "Failed sending drv version command\n"); - return rc; + if (rc) { + DP_NOTICE(edev, true, + "Failed sending drv version command\n"); + return rc; + } } + ecore_reset_vport_stats(edev); + return 0; ecore_hw_stop(edev); @@ -243,10 +308,14 @@ err2: ecore_resc_free(edev); err: #ifdef CONFIG_QED_BINARY_FW - if (edev->firmware) - rte_free(edev->firmware); - edev->firmware = NULL; + if (IS_PF(edev)) { + if (edev->firmware) + rte_free(edev->firmware); + edev->firmware = NULL; + } #endif + qed_stop_iov_task(edev); + return rc; } @@ -261,28 +330,38 @@ qed_fill_dev_info(struct ecore_dev *edev, struct qed_dev_info *dev_info) rte_memcpy(&dev_info->hw_mac, &edev->hwfns[0].hw_info.hw_mac_addr, ETHER_ADDR_LEN); - dev_info->fw_major = FW_MAJOR_VERSION; - dev_info->fw_minor = FW_MINOR_VERSION; - dev_info->fw_rev = FW_REVISION_VERSION; - dev_info->fw_eng = FW_ENGINEERING_VERSION; - dev_info->mf_mode = edev->mf_mode; - dev_info->tx_switching = false; + if (IS_PF(edev)) { + dev_info->fw_major = FW_MAJOR_VERSION; + dev_info->fw_minor = FW_MINOR_VERSION; + dev_info->fw_rev = FW_REVISION_VERSION; + dev_info->fw_eng = FW_ENGINEERING_VERSION; + dev_info->mf_mode = edev->mf_mode; + dev_info->tx_switching = false; + } else { + ecore_vf_get_fw_version(&edev->hwfns[0], &dev_info->fw_major, + &dev_info->fw_minor, &dev_info->fw_rev, + &dev_info->fw_eng); + } - ptt = ecore_ptt_acquire(ECORE_LEADING_HWFN(edev)); - if (ptt) { - ecore_mcp_get_mfw_ver(edev, ptt, + if (IS_PF(edev)) { + ptt = ecore_ptt_acquire(ECORE_LEADING_HWFN(edev)); + if (ptt) { + ecore_mcp_get_mfw_ver(edev, ptt, &dev_info->mfw_rev, NULL); - ecore_mcp_get_flash_size(ECORE_LEADING_HWFN(edev), ptt, + ecore_mcp_get_flash_size(ECORE_LEADING_HWFN(edev), ptt, &dev_info->flash_size); - /* Workaround to allow PHY-read commands for - * B0 bringup. - */ - if (ECORE_IS_BB_B0(edev)) - dev_info->flash_size = 0xffffffff; + /* Workaround to allow PHY-read commands for + * B0 bringup. + */ + if (ECORE_IS_BB_B0(edev)) + dev_info->flash_size = 0xffffffff; - ecore_ptt_release(ECORE_LEADING_HWFN(edev), ptt); + ecore_ptt_release(ECORE_LEADING_HWFN(edev), ptt); + } + } else { + ecore_mcp_get_mfw_ver(edev, ptt, &dev_info->mfw_rev, NULL); } return 0; @@ -298,18 +377,31 @@ qed_fill_eth_dev_info(struct ecore_dev *edev, struct qed_dev_eth_info *info) info->num_tc = 1 /* @@@TBD aelior MULTI_COS */; - info->num_queues = 0; - for_each_hwfn(edev, i) - info->num_queues += - FEAT_NUM(&edev->hwfns[i], ECORE_PF_L2_QUE); + if (IS_PF(edev)) { + info->num_queues = 0; + for_each_hwfn(edev, i) + info->num_queues += + FEAT_NUM(&edev->hwfns[i], ECORE_PF_L2_QUE); - info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN); + info->num_vlan_filters = RESC_NUM(&edev->hwfns[0], ECORE_VLAN); - rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr, + rte_memcpy(&info->port_mac, &edev->hwfns[0].hw_info.hw_mac_addr, ETHER_ADDR_LEN); + } else { + ecore_vf_get_num_rxqs(&edev->hwfns[0], &info->num_queues); + + ecore_vf_get_num_vlan_filters(&edev->hwfns[0], + &info->num_vlan_filters); + + ecore_vf_get_port_mac(&edev->hwfns[0], + (uint8_t *)&info->port_mac); + } qed_fill_dev_info(edev, &info->common); + if (IS_VF(edev)) + memset(&info->common.hw_mac, 0, ETHER_ADDR_LEN); + return 0; } @@ -371,11 +463,18 @@ static void qed_fill_link(struct ecore_hwfn *hwfn, memset(if_link, 0, sizeof(*if_link)); /* Prepare source inputs */ - rte_memcpy(¶ms, ecore_mcp_get_link_params(hwfn), + if (IS_PF(hwfn->p_dev)) { + rte_memcpy(¶ms, ecore_mcp_get_link_params(hwfn), sizeof(params)); - rte_memcpy(&link, ecore_mcp_get_link_state(hwfn), sizeof(link)); - rte_memcpy(&link_caps, ecore_mcp_get_link_capabilities(hwfn), + rte_memcpy(&link, ecore_mcp_get_link_state(hwfn), sizeof(link)); + rte_memcpy(&link_caps, ecore_mcp_get_link_capabilities(hwfn), sizeof(link_caps)); + } else { + ecore_vf_read_bulletin(hwfn, &change); + ecore_vf_get_link_params(hwfn, ¶ms); + ecore_vf_get_link_state(hwfn, &link); + ecore_vf_get_link_caps(hwfn, &link_caps); + } /* Set the link parameters to pass to protocol driver */ if (link.link_up) @@ -421,6 +520,9 @@ static int qed_set_link(struct ecore_dev *edev, struct qed_link_params *params) struct ecore_mcp_link_params *link_params; int rc; + if (IS_VF(edev)) + return 0; + /* The link should be set only once per PF */ hwfn = &edev->hwfns[0]; @@ -454,12 +556,22 @@ static int qed_set_link(struct ecore_dev *edev, struct qed_link_params *params) return rc; } +void qed_link_update(struct ecore_hwfn *hwfn) +{ + struct qed_link_output if_link; + + qed_fill_link(hwfn, &if_link); +} + static int qed_drain(struct ecore_dev *edev) { struct ecore_hwfn *hwfn; struct ecore_ptt *ptt; int i, rc; + if (IS_VF(edev)) + return 0; + for_each_hwfn(edev, i) { hwfn = &edev->hwfns[i]; ptt = ecore_ptt_acquire(hwfn); @@ -512,11 +624,18 @@ static int qed_slowpath_stop(struct ecore_dev *edev) if (!edev) return -ENODEV; - qed_free_stream_mem(edev); + if (IS_PF(edev)) { + qed_free_stream_mem(edev); - qed_nic_stop(edev); +#ifdef CONFIG_QED_SRIOV + if (IS_QED_ETH_IF(edev)) + qed_sriov_disable(edev, true); +#endif + qed_nic_stop(edev); + } qed_nic_reset(edev); + qed_stop_iov_task(edev); return 0; }