X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fice%2Fice_ethdev.c;h=429c2b6a1423458972488e538235eab77adbeab0;hb=3be9c6db296825021bc4e85c6f0bde7df5543cc8;hp=7233c3e55bf7fb5088c869d8d7ea3c5840abfde4;hpb=b96c5b22cb640b369d071a8fe018f71cc66622d8;p=dpdk.git diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index 7233c3e55b..429c2b6a14 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -2,14 +2,23 @@ * Copyright(c) 2018 Intel Corporation */ +#include #include +#include +#include +#include +#include + #include "base/ice_sched.h" +#include "base/ice_flow.h" +#include "base/ice_dcb.h" #include "ice_ethdev.h" #include "ice_rxtx.h" #define ICE_MAX_QP_NUM "max_queue_pair_num" #define ICE_DFLT_OUTER_TAG_TYPE ICE_AQ_VSI_OUTER_TAG_VLAN_9100 +#define ICE_DFLT_PKG_FILE "/lib/firmware/intel/ice/ddp/ice.pkg" int ice_logtype_init; int ice_logtype_driver; @@ -636,12 +645,14 @@ ice_add_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id) struct ice_fltr_list_entry *v_list_itr = NULL; struct ice_vlan_filter *f; struct LIST_HEAD_TYPE list_head; - struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + struct ice_hw *hw; int ret = 0; if (!vsi || vlan_id > ETHER_MAX_VLAN_ID) return -EINVAL; + hw = ICE_VSI_TO_HW(vsi); + /* If it's added and configured, return. */ f = ice_find_vlan_filter(vsi, vlan_id); if (f) { @@ -701,7 +712,7 @@ ice_remove_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id) struct ice_fltr_list_entry *v_list_itr = NULL; struct ice_vlan_filter *f; struct LIST_HEAD_TYPE list_head; - struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + struct ice_hw *hw; int ret = 0; /** @@ -711,6 +722,8 @@ ice_remove_vlan_filter(struct ice_vsi *vsi, uint16_t vlan_id) if (!vsi || vlan_id == 0 || vlan_id > ETHER_MAX_VLAN_ID) return -EINVAL; + hw = ICE_VSI_TO_HW(vsi); + /* Can't find it, return an error */ f = ice_find_vlan_filter(vsi, vlan_id); if (!f) @@ -1236,6 +1249,21 @@ fail_mem: return NULL; } +static int +ice_send_driver_ver(struct ice_hw *hw) +{ + struct ice_driver_ver dv; + + /* we don't have driver version use 0 for dummy */ + dv.major_ver = 0; + dv.minor_ver = 0; + dv.build_ver = 0; + dv.subbuild_ver = 0; + strncpy((char *)dv.driver_string, "dpdk", sizeof(dv.driver_string)); + + return ice_aq_send_driver_ver(hw, &dv, NULL); +} + static int ice_pf_setup(struct ice_pf *pf) { @@ -1259,6 +1287,69 @@ ice_pf_setup(struct ice_pf *pf) return 0; } +static int ice_load_pkg(struct rte_eth_dev *dev) +{ + struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + const char *pkg_file = ICE_DFLT_PKG_FILE; + int err; + uint8_t *buf; + int buf_len; + FILE *file; + struct stat fstat; + + file = fopen(pkg_file, "rb"); + if (!file) { + PMD_INIT_LOG(ERR, "failed to open file: %s\n", pkg_file); + return -1; + } + + err = stat(pkg_file, &fstat); + if (err) { + PMD_INIT_LOG(ERR, "failed to get file stats\n"); + fclose(file); + return err; + } + + buf_len = fstat.st_size; + buf = rte_malloc(NULL, buf_len, 0); + + if (!buf) { + PMD_INIT_LOG(ERR, "failed to allocate buf of size %d for package\n", + buf_len); + fclose(file); + return -1; + } + + err = fread(buf, buf_len, 1, file); + if (err != 1) { + PMD_INIT_LOG(ERR, "failed to read package data\n"); + fclose(file); + err = -1; + goto fail_exit; + } + + fclose(file); + + err = ice_copy_and_init_pkg(hw, buf, buf_len); + if (err) { + PMD_INIT_LOG(ERR, "ice_copy_and_init_hw failed: %d\n", err); + goto fail_exit; + } + err = ice_init_hw_tbls(hw); + if (err) { + PMD_INIT_LOG(ERR, "ice_init_hw_tbls failed: %d\n", err); + goto fail_init_tbls; + } + + return 0; + +fail_init_tbls: + rte_free(hw->pkg_copy); +fail_exit: + rte_free(buf); + return err; +} + static int ice_dev_init(struct rte_eth_dev *dev) { @@ -1266,6 +1357,8 @@ ice_dev_init(struct rte_eth_dev *dev) struct rte_intr_handle *intr_handle; struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct ice_adapter *ad = + ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); struct ice_vsi *vsi; int ret; @@ -1298,6 +1391,13 @@ ice_dev_init(struct rte_eth_dev *dev) return -EINVAL; } + ret = ice_load_pkg(dev); + if (ret) { + PMD_INIT_LOG(WARNING, "Failed to load the DDP package," + "Entering Safe Mode"); + ad->is_safe_mode = 1; + } + PMD_INIT_LOG(INFO, "FW %d.%d.%05d API %d.%d", hw->fw_maj_ver, hw->fw_min_ver, hw->fw_build, hw->api_maj_ver, hw->api_min_ver); @@ -1322,11 +1422,21 @@ ice_dev_init(struct rte_eth_dev *dev) goto err_pf_setup; } + ret = ice_send_driver_ver(hw); + if (ret) { + PMD_INIT_LOG(ERR, "Failed to send driver version"); + goto err_pf_setup; + } + vsi = pf->main_vsi; /* Disable double vlan by default */ ice_vsi_config_double_vlan(vsi, FALSE); + ret = ice_aq_stop_lldp(hw, TRUE, NULL); + if (ret != ICE_SUCCESS) + PMD_INIT_LOG(DEBUG, "lldp has already stopped\n"); + /* register callback func to eal lib */ rte_intr_callback_register(intr_handle, ice_interrupt_handler, dev); @@ -1512,12 +1622,18 @@ static int ice_init_rss(struct ice_pf *pf) struct ice_aqc_get_set_rss_keys key; uint16_t i, nb_q; int ret = 0; + bool is_safe_mode = pf->adapter->is_safe_mode; rss_conf = &dev->data->dev_conf.rx_adv_conf.rss_conf; nb_q = dev->data->nb_rx_queues; vsi->rss_key_size = ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE; vsi->rss_lut_size = hw->func_caps.common_cap.rss_table_size; + if (is_safe_mode) { + PMD_DRV_LOG(WARNING, "RSS is not supported in safe mode\n"); + return 0; + } + if (!vsi->rss_key) vsi->rss_key = rte_zmalloc(NULL, vsi->rss_key_size, 0); @@ -1550,6 +1666,56 @@ static int ice_init_rss(struct ice_pf *pf) if (ret) return -EINVAL; + /* configure RSS for IPv4 with input set IPv4 src/dst */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4, + ICE_FLOW_SEG_HDR_IPV4); + if (ret) + PMD_DRV_LOG(ERR, "%s IPV4 rss flow fail %d", __func__, ret); + + /* configure RSS for IPv6 with input set IPv6 src/dst */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV6, + ICE_FLOW_SEG_HDR_IPV6); + if (ret) + PMD_DRV_LOG(ERR, "%s IPV6 rss flow fail %d", __func__, ret); + + /* configure RSS for tcp6 with input set IPv6 src/dst, TCP src/dst */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV6, + ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV6); + if (ret) + PMD_DRV_LOG(ERR, "%s TCP_IPV6 rss flow fail %d", __func__, ret); + + /* configure RSS for udp6 with input set IPv6 src/dst, UDP src/dst */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV6, + ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV6); + if (ret) + PMD_DRV_LOG(ERR, "%s UDP_IPV6 rss flow fail %d", __func__, ret); + + /* configure RSS for sctp6 with input set IPv6 src/dst */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV6, + ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV6); + if (ret) + PMD_DRV_LOG(ERR, "%s SCTP_IPV6 rss flow fail %d", + __func__, ret); + + /* configure RSS for tcp4 with input set IP src/dst, TCP src/dst */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_TCP_IPV4, + ICE_FLOW_SEG_HDR_TCP | ICE_FLOW_SEG_HDR_IPV4); + if (ret) + PMD_DRV_LOG(ERR, "%s TCP_IPV4 rss flow fail %d", __func__, ret); + + /* configure RSS for udp4 with input set IP src/dst, UDP src/dst */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_HASH_UDP_IPV4, + ICE_FLOW_SEG_HDR_UDP | ICE_FLOW_SEG_HDR_IPV4); + if (ret) + PMD_DRV_LOG(ERR, "%s UDP_IPV4 rss flow fail %d", __func__, ret); + + /* configure RSS for sctp4 with input set IP src/dst */ + ret = ice_add_rss_cfg(hw, vsi->idx, ICE_FLOW_HASH_IPV4, + ICE_FLOW_SEG_HDR_SCTP | ICE_FLOW_SEG_HDR_IPV4); + if (ret) + PMD_DRV_LOG(ERR, "%s SCTP_IPV4 rss flow fail %d", + __func__, ret); + return 0; } @@ -1822,6 +1988,9 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct ice_vsi *vsi = pf->main_vsi; struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev->device); + bool is_safe_mode = pf->adapter->is_safe_mode; + u64 phy_type_low; + u64 phy_type_high; dev_info->min_rx_bufsize = ICE_BUF_SIZE_MIN; dev_info->max_rx_pktlen = ICE_FRAME_SIZE_MAX; @@ -1832,33 +2001,40 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->rx_offload_capa = DEV_RX_OFFLOAD_VLAN_STRIP | - DEV_RX_OFFLOAD_IPV4_CKSUM | - DEV_RX_OFFLOAD_UDP_CKSUM | - DEV_RX_OFFLOAD_TCP_CKSUM | - DEV_RX_OFFLOAD_QINQ_STRIP | - DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | - DEV_RX_OFFLOAD_VLAN_EXTEND | DEV_RX_OFFLOAD_JUMBO_FRAME | DEV_RX_OFFLOAD_KEEP_CRC | DEV_RX_OFFLOAD_SCATTER | DEV_RX_OFFLOAD_VLAN_FILTER; dev_info->tx_offload_capa = DEV_TX_OFFLOAD_VLAN_INSERT | - DEV_TX_OFFLOAD_QINQ_INSERT | - DEV_TX_OFFLOAD_IPV4_CKSUM | - DEV_TX_OFFLOAD_UDP_CKSUM | - DEV_TX_OFFLOAD_TCP_CKSUM | - DEV_TX_OFFLOAD_SCTP_CKSUM | - DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM | DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_MULTI_SEGS | DEV_TX_OFFLOAD_MBUF_FAST_FREE; + dev_info->flow_type_rss_offloads = 0; + + if (!is_safe_mode) { + dev_info->rx_offload_capa |= + DEV_RX_OFFLOAD_IPV4_CKSUM | + DEV_RX_OFFLOAD_UDP_CKSUM | + DEV_RX_OFFLOAD_TCP_CKSUM | + DEV_RX_OFFLOAD_QINQ_STRIP | + DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM | + DEV_RX_OFFLOAD_VLAN_EXTEND; + dev_info->tx_offload_capa |= + DEV_TX_OFFLOAD_QINQ_INSERT | + DEV_TX_OFFLOAD_IPV4_CKSUM | + DEV_TX_OFFLOAD_UDP_CKSUM | + DEV_TX_OFFLOAD_TCP_CKSUM | + DEV_TX_OFFLOAD_SCTP_CKSUM | + DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM; + dev_info->flow_type_rss_offloads |= ICE_RSS_OFFLOAD_ALL; + } + dev_info->rx_queue_offload_capa = 0; dev_info->tx_queue_offload_capa = 0; dev_info->reta_size = hw->func_caps.common_cap.rss_table_size; dev_info->hash_key_size = (VSIQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t); - dev_info->flow_type_rss_offloads = ICE_RSS_OFFLOAD_ALL; dev_info->default_rxconf = (struct rte_eth_rxconf) { .rx_thresh = { @@ -1901,10 +2077,17 @@ ice_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) ETH_LINK_SPEED_5G | ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G | - ETH_LINK_SPEED_25G | - ETH_LINK_SPEED_40G | - ETH_LINK_SPEED_50G | - ETH_LINK_SPEED_100G; + ETH_LINK_SPEED_25G; + + phy_type_low = hw->port_info->phy.phy_type_low; + phy_type_high = hw->port_info->phy.phy_type_high; + + if (ICE_PHY_TYPE_SUPPORT_50G(phy_type_low)) + dev_info->speed_capa |= ETH_LINK_SPEED_50G; + + if (ICE_PHY_TYPE_SUPPORT_100G_LOW(phy_type_low) || + ICE_PHY_TYPE_SUPPORT_100G_HIGH(phy_type_high)) + dev_info->speed_capa |= ETH_LINK_SPEED_100G; dev_info->nb_rx_queues = dev->data->nb_rx_queues; dev_info->nb_tx_queues = dev->data->nb_tx_queues; @@ -2044,8 +2227,7 @@ ice_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) { struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); struct rte_eth_dev_data *dev_data = pf->dev_data; - uint32_t frame_size = mtu + ETHER_HDR_LEN - + ETHER_CRC_LEN + ICE_VLAN_TAG_SIZE; + uint32_t frame_size = mtu + ICE_ETH_OVERHEAD; /* check if mtu is within the allowed range */ if (mtu < ETHER_MIN_MTU || frame_size > ICE_FRAME_SIZE_MAX) @@ -2387,13 +2569,16 @@ ice_get_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size) static int ice_set_rss_lut(struct ice_vsi *vsi, uint8_t *lut, uint16_t lut_size) { - struct ice_pf *pf = ICE_VSI_TO_PF(vsi); - struct ice_hw *hw = ICE_VSI_TO_HW(vsi); + struct ice_pf *pf; + struct ice_hw *hw; int ret; if (!vsi || !lut) return -EINVAL; + pf = ICE_VSI_TO_PF(vsi); + hw = ICE_VSI_TO_HW(vsi); + if (pf->flags & ICE_FLAG_RSS_AQ_CAPABLE) { ret = ice_aq_set_rss_lut(hw, vsi->idx, TRUE, lut, lut_size); @@ -2590,14 +2775,16 @@ ice_promisc_enable(struct rte_eth_dev *dev) struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct ice_vsi *vsi = pf->main_vsi; + enum ice_status status; uint8_t pmask; - uint16_t status; pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX | ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX; status = ice_set_vsi_promisc(hw, vsi->idx, pmask, 0); - if (status != ICE_SUCCESS) + if (status == ICE_ERR_ALREADY_EXISTS) + PMD_DRV_LOG(DEBUG, "Promisc mode has already been enabled"); + else if (status != ICE_SUCCESS) PMD_DRV_LOG(ERR, "Failed to enable promisc, err=%d", status); } @@ -2607,7 +2794,7 @@ ice_promisc_disable(struct rte_eth_dev *dev) struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct ice_vsi *vsi = pf->main_vsi; - uint16_t status; + enum ice_status status; uint8_t pmask; pmask = ICE_PROMISC_UCAST_RX | ICE_PROMISC_UCAST_TX | @@ -2624,8 +2811,8 @@ ice_allmulti_enable(struct rte_eth_dev *dev) struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct ice_vsi *vsi = pf->main_vsi; + enum ice_status status; uint8_t pmask; - uint16_t status; pmask = ICE_PROMISC_MCAST_RX | ICE_PROMISC_MCAST_TX; @@ -2640,7 +2827,7 @@ ice_allmulti_disable(struct rte_eth_dev *dev) struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private); struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private); struct ice_vsi *vsi = pf->main_vsi; - uint16_t status; + enum ice_status status; uint8_t pmask; if (dev->data->promiscuous == 1) @@ -3297,17 +3484,15 @@ static int ice_xstats_get_names(__rte_unused struct rte_eth_dev *dev, /* Get stats from ice_eth_stats struct */ for (i = 0; i < ICE_NB_ETH_XSTATS; i++) { - snprintf(xstats_names[count].name, - sizeof(xstats_names[count].name), - "%s", ice_stats_strings[i].name); + strlcpy(xstats_names[count].name, ice_stats_strings[i].name, + sizeof(xstats_names[count].name)); count++; } /* Get individiual stats from ice_hw_port struct */ for (i = 0; i < ICE_NB_HW_PORT_XSTATS; i++) { - snprintf(xstats_names[count].name, - sizeof(xstats_names[count].name), - "%s", ice_hw_port_strings[i].name); + strlcpy(xstats_names[count].name, ice_hw_port_strings[i].name, + sizeof(xstats_names[count].name)); count++; }