X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fi40e%2Frte_pmd_i40e.c;h=e216e6783184bc40c348f596b6d841c1de58995b;hb=6f1998a4f0411ea3b2bed7c05faa81243917a76e;hp=5436db4c01bb8b1f4ed3544b5f0b94a695b219ec;hpb=a491e0ef4ef71888ff89216bba91268ec91685c2;p=dpdk.git diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c index 5436db4c01..e216e67831 100644 --- a/drivers/net/i40e/rte_pmd_i40e.c +++ b/drivers/net/i40e/rte_pmd_i40e.c @@ -2,6 +2,7 @@ * Copyright(c) 2010-2017 Intel Corporation */ +#include #include #include @@ -338,7 +339,7 @@ i40e_vsi_set_tx_loopback(struct i40e_vsi *vsi, uint8_t on) hw = I40E_VSI_TO_HW(vsi); /* Use the FW API if FW >= v5.0 */ - if (hw->aq.fw_maj_ver < 5) { + if (hw->aq.fw_maj_ver < 5 && hw->mac.type != I40E_MAC_X722) { PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback"); return -ENOTSUP; } @@ -528,7 +529,7 @@ rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on) int rte_pmd_i40e_set_vf_mac_addr(uint16_t port, uint16_t vf_id, - struct ether_addr *mac_addr) + struct rte_ether_addr *mac_addr) { struct i40e_mac_filter *f; struct rte_eth_dev *dev; @@ -559,7 +560,7 @@ rte_pmd_i40e_set_vf_mac_addr(uint16_t port, uint16_t vf_id, return -EINVAL; } - ether_addr_copy(mac_addr, &vf->mac_addr); + rte_ether_addr_copy(mac_addr, &vf->mac_addr); /* Remove all existing mac */ TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) @@ -570,6 +571,51 @@ rte_pmd_i40e_set_vf_mac_addr(uint16_t port, uint16_t vf_id, return 0; } +static const struct rte_ether_addr null_mac_addr; + +int +rte_pmd_i40e_remove_vf_mac_addr(uint16_t port, uint16_t vf_id, + struct rte_ether_addr *mac_addr) +{ + struct rte_eth_dev *dev; + struct i40e_pf_vf *vf; + struct i40e_vsi *vsi; + struct i40e_pf *pf; + int ret; + + if (i40e_validate_mac_addr((u8 *)mac_addr) != I40E_SUCCESS) + return -EINVAL; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + + dev = &rte_eth_devices[port]; + + if (!is_i40e_supported(dev)) + return -ENOTSUP; + + pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + + if (vf_id >= pf->vf_num || !pf->vfs) + return -EINVAL; + + vf = &pf->vfs[vf_id]; + vsi = vf->vsi; + if (!vsi) { + PMD_DRV_LOG(ERR, "Invalid VSI."); + return -EINVAL; + } + + if (rte_is_same_ether_addr(mac_addr, &vf->mac_addr)) + /* Reset the mac with NULL address */ + rte_ether_addr_copy(&null_mac_addr, &vf->mac_addr); + + /* Remove the mac */ + ret = i40e_vsi_delete_mac(vsi, mac_addr); + if (ret != I40E_SUCCESS) + return ret; + return 0; +} + /* Set vlan strip on/off for specific VF from host */ int rte_pmd_i40e_set_vf_vlan_stripq(uint16_t port, uint16_t vf_id, uint8_t on) @@ -619,7 +665,7 @@ int rte_pmd_i40e_set_vf_vlan_insert(uint16_t port, uint16_t vf_id, RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); - if (vlan_id > ETHER_MAX_VLAN_ID) { + if (vlan_id > RTE_ETHER_MAX_VLAN_ID) { PMD_DRV_LOG(ERR, "Invalid VLAN ID."); return -EINVAL; } @@ -680,7 +726,7 @@ int rte_pmd_i40e_set_vf_broadcast(uint16_t port, uint16_t vf_id, struct i40e_vsi *vsi; struct i40e_hw *hw; struct i40e_mac_filter_info filter; - struct ether_addr broadcast = { + struct rte_ether_addr broadcast = { .addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} }; int ret; @@ -721,7 +767,7 @@ int rte_pmd_i40e_set_vf_broadcast(uint16_t port, uint16_t vf_id, } if (on) { - rte_memcpy(&filter.mac_addr, &broadcast, ETHER_ADDR_LEN); + rte_memcpy(&filter.mac_addr, &broadcast, RTE_ETHER_ADDR_LEN); filter.filter_type = RTE_MACVLAN_PERFECT_MATCH; ret = i40e_vsi_add_mac(vsi, &filter); } else { @@ -849,7 +895,7 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id, if (!is_i40e_supported(dev)) return -ENOTSUP; - if (vlan_id > ETHER_MAX_VLAN_ID || !vlan_id) { + if (vlan_id > RTE_ETHER_MAX_VLAN_ID || !vlan_id) { PMD_DRV_LOG(ERR, "Invalid VLAN ID."); return -EINVAL; } @@ -1363,7 +1409,7 @@ rte_pmd_i40e_set_tc_strict_prio(uint16_t port, uint8_t tc_map) /* Disable DCBx if it's the first time to set strict priority. */ if (!veb->strict_prio_tc) { - ret = i40e_aq_stop_lldp(hw, true, NULL); + ret = i40e_aq_stop_lldp(hw, true, true, NULL); if (ret) PMD_DRV_LOG(INFO, "Failed to disable DCBx as it's already" @@ -1418,7 +1464,7 @@ rte_pmd_i40e_set_tc_strict_prio(uint16_t port, uint8_t tc_map) /* Enable DCBx again, if all the TCs' strict priority disabled. */ if (!tc_map) { - ret = i40e_aq_start_lldp(hw, NULL); + ret = i40e_aq_start_lldp(hw, true, NULL); if (ret) { PMD_DRV_LOG(ERR, "Failed to enable DCBx, err(%d).", ret); @@ -1496,7 +1542,14 @@ i40e_check_profile_info(uint16_t port, uint8_t *profile_info_sec) struct rte_pmd_i40e_profile_info *pinfo, *p; uint32_t i; int ret; + static const uint32_t group_mask = 0x00ff0000; + pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec + + sizeof(struct i40e_profile_section_header)); + if (pinfo->track_id == 0) { + PMD_DRV_LOG(INFO, "Read-only profile."); + return 0; + } buff = rte_zmalloc("pinfo_list", (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4), 0); @@ -1515,8 +1568,6 @@ i40e_check_profile_info(uint16_t port, uint8_t *profile_info_sec) return -1; } p_list = (struct rte_pmd_i40e_profile_list *)buff; - pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec + - sizeof(struct i40e_profile_section_header)); for (i = 0; i < p_list->p_count; i++) { p = &p_list->p_info[i]; if (pinfo->track_id == p->track_id) { @@ -1525,6 +1576,30 @@ i40e_check_profile_info(uint16_t port, uint8_t *profile_info_sec) return 1; } } + /* profile with group id 0xff is compatible with any other profile */ + if ((pinfo->track_id & group_mask) == group_mask) { + rte_free(buff); + return 0; + } + for (i = 0; i < p_list->p_count; i++) { + p = &p_list->p_info[i]; + if ((p->track_id & group_mask) == 0) { + PMD_DRV_LOG(INFO, "Profile of the group 0 exists."); + rte_free(buff); + return 2; + } + } + for (i = 0; i < p_list->p_count; i++) { + p = &p_list->p_info[i]; + if ((p->track_id & group_mask) == group_mask) + continue; + if ((pinfo->track_id & group_mask) != + (p->track_id & group_mask)) { + PMD_DRV_LOG(INFO, "Profile of different group exists."); + rte_free(buff); + return 3; + } + } rte_free(buff); return 0; @@ -1544,6 +1619,7 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff, uint8_t *profile_info_sec; int is_exist; enum i40e_status_code status = I40E_SUCCESS; + static const uint32_t type_mask = 0xff000000; if (op != RTE_PMD_I40E_PKG_OP_WR_ADD && op != RTE_PMD_I40E_PKG_OP_WR_ONLY && @@ -1580,8 +1656,6 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff, return -EINVAL; } - i40e_update_customized_info(dev, buff, size); - /* Find metadata segment */ metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA, pkg_hdr); @@ -1595,6 +1669,10 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff, return -EINVAL; } + /* force read-only track_id for type 0 */ + if ((track_id & type_mask) == 0) + track_id = 0; + /* Find profile segment */ profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E, pkg_hdr); @@ -1628,12 +1706,18 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff, if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) { if (is_exist) { - PMD_DRV_LOG(ERR, "Profile already exists."); + if (is_exist == 1) + PMD_DRV_LOG(ERR, "Profile already exists."); + else if (is_exist == 2) + PMD_DRV_LOG(ERR, "Profile of group 0 already exists."); + else if (is_exist == 3) + PMD_DRV_LOG(ERR, "Profile of different group already exists"); + i40e_update_customized_info(dev, buff, size, op); rte_free(profile_info_sec); return -EEXIST; } } else if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) { - if (!is_exist) { + if (is_exist != 1) { PMD_DRV_LOG(ERR, "Profile does not exist."); rte_free(profile_info_sec); return -EACCES; @@ -1676,6 +1760,10 @@ rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff, } } + if (op == RTE_PMD_I40E_PKG_OP_WR_ADD || + op == RTE_PMD_I40E_PKG_OP_WR_DEL) + i40e_update_customized_info(dev, buff, size, op); + rte_free(profile_info_sec); return status; } @@ -1898,8 +1986,8 @@ int rte_pmd_i40e_get_ddp_info(uint8_t *pkg_buff, uint32_t pkg_size, tlv = (struct i40e_profile_tlv_section_record *)&proto[1]; for (i = j = 0; i < nb_rec; j++) { pinfo[j].proto_id = tlv->data[0]; - snprintf(pinfo[j].name, I40E_DDP_NAME_SIZE, "%s", - (const char *)&tlv->data[1]); + strlcpy(pinfo[j].name, (const char *)&tlv->data[1], + I40E_DDP_NAME_SIZE); i += tlv->len; tlv = &tlv[tlv->len]; } @@ -2084,7 +2172,8 @@ static int check_invalid_pkt_type(uint32_t pkt_type) tnl != RTE_PTYPE_TUNNEL_GRENAT && tnl != RTE_PTYPE_TUNNEL_GTPC && tnl != RTE_PTYPE_TUNNEL_GTPU && - tnl != RTE_PTYPE_TUNNEL_L2TP) + tnl != RTE_PTYPE_TUNNEL_L2TP && + tnl != RTE_PTYPE_TUNNEL_ESP) return -1; if (il2 && @@ -2269,7 +2358,7 @@ int rte_pmd_i40e_ptype_mapping_replace(uint16_t port, int rte_pmd_i40e_add_vf_mac_addr(uint16_t port, uint16_t vf_id, - struct ether_addr *mac_addr) + struct rte_ether_addr *mac_addr) { struct rte_eth_dev *dev; struct i40e_pf_vf *vf; @@ -2301,7 +2390,7 @@ rte_pmd_i40e_add_vf_mac_addr(uint16_t port, uint16_t vf_id, } mac_filter.filter_type = RTE_MACVLAN_PERFECT_MATCH; - ether_addr_copy(mac_addr, &mac_filter.mac_addr); + rte_ether_addr_copy(mac_addr, &mac_filter.mac_addr); ret = i40e_vsi_add_mac(vsi, &mac_filter); if (ret != I40E_SUCCESS) { PMD_DRV_LOG(ERR, "Failed to add MAC filter."); @@ -2319,7 +2408,8 @@ int rte_pmd_i40e_flow_type_mapping_reset(uint16_t port) dev = &rte_eth_devices[port]; - if (!is_i40e_supported(dev)) + if (!is_i40e_supported(dev) && + !is_i40evf_supported(dev)) return -ENOTSUP; i40e_set_default_pctype_table(dev); @@ -2339,7 +2429,8 @@ int rte_pmd_i40e_flow_type_mapping_get( dev = &rte_eth_devices[port]; - if (!is_i40e_supported(dev)) + if (!is_i40e_supported(dev) && + !is_i40evf_supported(dev)) return -ENOTSUP; ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); @@ -2367,7 +2458,8 @@ rte_pmd_i40e_flow_type_mapping_update( dev = &rte_eth_devices[port]; - if (!is_i40e_supported(dev)) + if (!is_i40e_supported(dev) && + !is_i40evf_supported(dev)) return -ENOTSUP; if (count > I40E_FLOW_TYPE_MAX) @@ -2406,10 +2498,11 @@ rte_pmd_i40e_flow_type_mapping_update( } int -rte_pmd_i40e_query_vfid_by_mac(uint16_t port, const struct ether_addr *vf_mac) +rte_pmd_i40e_query_vfid_by_mac(uint16_t port, + const struct rte_ether_addr *vf_mac) { struct rte_eth_dev *dev; - struct ether_addr *mac; + struct rte_ether_addr *mac; struct i40e_pf *pf; int vf_id; struct i40e_pf_vf *vf; @@ -2428,7 +2521,7 @@ rte_pmd_i40e_query_vfid_by_mac(uint16_t port, const struct ether_addr *vf_mac) vf = &pf->vfs[vf_id]; mac = &vf->mac_addr; - if (is_same_ether_addr(mac, vf_mac)) + if (rte_is_same_ether_addr(mac, vf_mac)) return vf_id; } @@ -2733,13 +2826,23 @@ i40e_queue_region_dcb_configure(struct i40e_hw *hw, struct i40e_dcbx_config *old_cfg = &hw->local_dcbx_config; int32_t ret = -EINVAL; uint16_t i, j, prio_index, region_index; - uint8_t tc_map, tc_bw, bw_lf; + uint8_t tc_map, tc_bw, bw_lf, dcb_flag = 0; if (!info->queue_region_number) { PMD_DRV_LOG(ERR, "No queue region been set before"); return ret; } + for (i = 0; i < info->queue_region_number; i++) { + if (info->region[i].user_priority_num) { + dcb_flag = 1; + break; + } + } + + if (dcb_flag == 0) + return 0; + dcb_cfg = &dcb_cfg_local; memset(dcb_cfg, 0, sizeof(struct i40e_dcbx_config)); @@ -3039,6 +3142,7 @@ rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype, { struct rte_eth_dev *dev; struct i40e_hw *hw; + struct i40e_pf *pf; uint64_t inset_reg; uint32_t mask_reg[2]; int i; @@ -3054,10 +3158,12 @@ rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype, return -EINVAL; hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); - /* Clear mask first */ - for (i = 0; i < 2; i++) - i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype), 0); + if (pf->support_multi_driver) { + PMD_DRV_LOG(ERR, "Input set configuration is not supported."); + return -ENOTSUP; + } inset_reg = inset->inset; for (i = 0; i < 2; i++) @@ -3066,14 +3172,15 @@ rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype, switch (inset_type) { case INSET_HASH: - i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(0, pctype), - (uint32_t)(inset_reg & UINT32_MAX)); - i40e_check_write_reg(hw, I40E_GLQF_HASH_INSET(1, pctype), - (uint32_t)((inset_reg >> - I40E_32_BIT_WIDTH) & UINT32_MAX)); + i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype), + (uint32_t)(inset_reg & UINT32_MAX)); + i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype), + (uint32_t)((inset_reg >> + I40E_32_BIT_WIDTH) & UINT32_MAX)); for (i = 0; i < 2; i++) - i40e_check_write_reg(hw, I40E_GLQF_HASH_MSK(i, pctype), - mask_reg[i]); + i40e_check_write_global_reg(hw, + I40E_GLQF_HASH_MSK(i, pctype), + mask_reg[i]); break; case INSET_FDIR: i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0), @@ -3082,8 +3189,9 @@ rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype, (uint32_t)((inset_reg >> I40E_32_BIT_WIDTH) & UINT32_MAX)); for (i = 0; i < 2; i++) - i40e_check_write_reg(hw, I40E_GLQF_FD_MSK(i, pctype), - mask_reg[i]); + i40e_check_write_global_reg(hw, + I40E_GLQF_FD_MSK(i, pctype), + mask_reg[i]); break; case INSET_FDIR_FLX: i40e_check_write_reg(hw, I40E_PRTQF_FD_FLXINSET(pctype), @@ -3100,3 +3208,75 @@ rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype, I40E_WRITE_FLUSH(hw); return 0; } + +int +rte_pmd_i40e_get_fdir_info(uint16_t port, struct rte_eth_fdir_info *fdir_info) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + + dev = &rte_eth_devices[port]; + if (!is_i40e_supported(dev)) + return -ENOTSUP; + + i40e_fdir_info_get(dev, fdir_info); + + return 0; +} + +int +rte_pmd_i40e_get_fdir_stats(uint16_t port, struct rte_eth_fdir_stats *fdir_stat) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + + dev = &rte_eth_devices[port]; + if (!is_i40e_supported(dev)) + return -ENOTSUP; + + i40e_fdir_stats_get(dev, fdir_stat); + + return 0; +} + +int +rte_pmd_i40e_set_gre_key_len(uint16_t port, uint8_t len) +{ + struct rte_eth_dev *dev; + struct i40e_pf *pf; + struct i40e_hw *hw; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + + dev = &rte_eth_devices[port]; + if (!is_i40e_supported(dev)) + return -ENOTSUP; + + pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + hw = I40E_PF_TO_HW(pf); + + return i40e_dev_set_gre_key_len(hw, len); +} + +int +rte_pmd_i40e_set_switch_dev(uint16_t port_id, struct rte_eth_dev *switch_dev) +{ + struct rte_eth_dev *i40e_dev; + struct i40e_hw *hw; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + + i40e_dev = &rte_eth_devices[port_id]; + if (!is_i40e_supported(i40e_dev)) + return -ENOTSUP; + + hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private); + if (!hw) + return -1; + + hw->switch_dev = switch_dev; + + return 0; +}