#include <rte_atomic.h>
#include <rte_eal.h>
#include <rte_ether.h>
-#include <rte_ethdev_driver.h>
-#include <rte_ethdev_pci.h>
+#include <ethdev_driver.h>
+#include <ethdev_pci.h>
#include <rte_malloc.h>
#include <rte_memzone.h>
#include <rte_dev.h>
if (ret)
return ret;
- /* Set RSS hash configuration based on rss_conf->rss_hf. */
- ret = iavf_rss_hash_set(adapter, rss_conf->rss_hf, true);
- if (ret) {
- PMD_DRV_LOG(ERR, "fail to set default RSS");
- return ret;
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF) {
+ /* Set RSS hash configuration based on rss_conf->rss_hf. */
+ ret = iavf_rss_hash_set(adapter, rss_conf->rss_hf, true);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "fail to set default RSS");
+ return ret;
+ }
}
return 0;
return 0;
}
+static int
+iavf_dev_vlan_insert_set(struct rte_eth_dev *dev)
+{
+ struct iavf_adapter *adapter =
+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+ bool enable;
+
+ if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2))
+ return 0;
+
+ enable = !!(dev->data->dev_conf.txmode.offloads &
+ DEV_TX_OFFLOAD_VLAN_INSERT);
+ iavf_config_vlan_insert_v2(adapter, enable);
+
+ return 0;
+}
+
+static int
+iavf_dev_init_vlan(struct rte_eth_dev *dev)
+{
+ int err;
+
+ err = iavf_dev_vlan_offload_set(dev,
+ ETH_VLAN_STRIP_MASK |
+ ETH_QINQ_STRIP_MASK |
+ ETH_VLAN_FILTER_MASK |
+ ETH_VLAN_EXTEND_MASK);
+ if (err) {
+ PMD_DRV_LOG(ERR, "Failed to update vlan offload");
+ return err;
+ }
+
+ err = iavf_dev_vlan_insert_set(dev);
+ if (err)
+ PMD_DRV_LOG(ERR, "Failed to update vlan insertion");
+
+ return err;
+}
+
static int
iavf_dev_configure(struct rte_eth_dev *dev)
{
struct iavf_adapter *ad =
IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
- struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
uint16_t num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
dev->data->nb_tx_queues);
int ret;
vf->max_rss_qregion = IAVF_MAX_NUM_QUEUES_DFLT;
}
- /* Vlan stripping setting */
- if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) {
- if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
- iavf_enable_vlan_strip(ad);
- else
- iavf_disable_vlan_strip(ad);
- }
+ ret = iavf_dev_init_vlan(dev);
+ if (ret)
+ PMD_DRV_LOG(ERR, "configure VLAN failed: %d", ret);
if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
if (iavf_init_rss(ad) != 0) {
* correctly.
*/
if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
- if (max_pkt_len <= RTE_ETHER_MAX_LEN ||
+ if (max_pkt_len <= IAVF_ETH_MAX_LEN ||
max_pkt_len > IAVF_FRAME_SIZE_MAX) {
PMD_DRV_LOG(ERR, "maximum packet length must be "
"larger than %u and smaller than %u, "
"as jumbo frame is enabled",
- (uint32_t)RTE_ETHER_MAX_LEN,
+ (uint32_t)IAVF_ETH_MAX_LEN,
(uint32_t)IAVF_FRAME_SIZE_MAX);
return -EINVAL;
}
} else {
if (max_pkt_len < RTE_ETHER_MIN_LEN ||
- max_pkt_len > RTE_ETHER_MAX_LEN) {
+ max_pkt_len > IAVF_ETH_MAX_LEN) {
PMD_DRV_LOG(ERR, "maximum packet length must be "
"larger than %u and smaller than %u, "
"as jumbo frame is disabled",
(uint32_t)RTE_ETHER_MIN_LEN,
- (uint32_t)RTE_ETHER_MAX_LEN);
+ (uint32_t)IAVF_ETH_MAX_LEN);
return -EINVAL;
}
}
/* If Rx interrupt is reuquired, and we can use
* multi interrupts, then the vec is from 1
*/
- vf->nb_msix = RTE_MIN(vf->vf_res->max_vectors,
- intr_handle->nb_efd);
+ vf->nb_msix = RTE_MIN(intr_handle->nb_efd,
+ (uint16_t)(vf->vf_res->max_vectors - 1));
vf->msix_base = IAVF_RX_VEC_START;
vec = IAVF_RX_VEC_START;
for (i = 0; i < dev->data->nb_rx_queues; i++) {
qv_map[i].queue_id = i;
qv_map[i].vector_id = vec;
intr_handle->intr_vec[i] = vec++;
- if (vec >= vf->nb_msix)
+ if (vec >= vf->nb_msix + IAVF_RX_VEC_START)
vec = IAVF_RX_VEC_START;
}
vf->qv_map = qv_map;
DEV_RX_OFFLOAD_JUMBO_FRAME |
DEV_RX_OFFLOAD_VLAN_FILTER |
DEV_RX_OFFLOAD_RSS_HASH;
+
dev_info->tx_offload_capa =
DEV_TX_OFFLOAD_VLAN_INSERT |
DEV_TX_OFFLOAD_QINQ_INSERT |
struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
int err;
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
+ err = iavf_add_del_vlan_v2(adapter, vlan_id, on);
+ if (err)
+ return -EIO;
+ return 0;
+ }
+
if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
return -ENOTSUP;
return 0;
}
+static void
+iavf_iterate_vlan_filters_v2(struct rte_eth_dev *dev, bool enable)
+{
+ struct rte_vlan_filter_conf *vfc = &dev->data->vlan_filter_conf;
+ struct iavf_adapter *adapter =
+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ uint32_t i, j;
+ uint64_t ids;
+
+ for (i = 0; i < RTE_DIM(vfc->ids); i++) {
+ if (vfc->ids[i] == 0)
+ continue;
+
+ ids = vfc->ids[i];
+ for (j = 0; ids != 0 && j < 64; j++, ids >>= 1) {
+ if (ids & 1)
+ iavf_add_del_vlan_v2(adapter,
+ 64 * i + j, enable);
+ }
+ }
+}
+
+static int
+iavf_dev_vlan_offload_set_v2(struct rte_eth_dev *dev, int mask)
+{
+ struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
+ struct iavf_adapter *adapter =
+ IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ bool enable;
+ int err;
+
+ if (mask & ETH_VLAN_FILTER_MASK) {
+ enable = !!(rxmode->offloads & DEV_RX_OFFLOAD_VLAN_FILTER);
+
+ iavf_iterate_vlan_filters_v2(dev, enable);
+ }
+
+ if (mask & ETH_VLAN_STRIP_MASK) {
+ enable = !!(rxmode->offloads & DEV_RX_OFFLOAD_VLAN_STRIP);
+
+ err = iavf_config_vlan_strip_v2(adapter, enable);
+ /* If not support, the stripping is already disabled by PF */
+ if (err == -ENOTSUP && !enable)
+ err = 0;
+ if (err)
+ return -EIO;
+ }
+
+ return 0;
+}
+
static int
iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
{
struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
int err;
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
+ return iavf_dev_vlan_offload_set_v2(dev, mask);
+
if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
return -ENOTSUP;
if (rss_conf->rss_hf == 0)
return 0;
- /* Overwritten default RSS. */
- ret = iavf_set_hena(adapter, 0);
- if (ret)
- PMD_DRV_LOG(ERR, "%s Remove rss vsi fail %d",
- __func__, ret);
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF) {
+ /* Clear existing RSS. */
+ ret = iavf_set_hena(adapter, 0);
- /* Set new RSS configuration. */
- ret = iavf_rss_hash_set(adapter, rss_conf->rss_hf, true);
- if (ret) {
- PMD_DRV_LOG(ERR, "fail to set new RSS");
- return ret;
+ /* It is a workaround, temporarily allow error to be returned
+ * due to possible lack of PF handling for hena = 0.
+ */
+ if (ret)
+ PMD_DRV_LOG(WARNING, "fail to clean existing RSS,"
+ "lack PF support");
+
+ /* Set new RSS configuration. */
+ ret = iavf_rss_hash_set(adapter, rss_conf->rss_hf, true);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "fail to set new RSS");
+ return ret;
+ }
}
return 0;
return -EBUSY;
}
- if (frame_size > RTE_ETHER_MAX_LEN)
+ if (frame_size > IAVF_ETH_MAX_LEN)
dev->data->dev_conf.rxmode.offloads |=
DEV_RX_OFFLOAD_JUMBO_FRAME;
else
ret = iavf_query_stats(adapter, &pstats);
if (ret == 0) {
+ uint8_t crc_stats_len = (dev->data->dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_KEEP_CRC) ? 0 :
+ RTE_ETHER_CRC_LEN;
iavf_update_stats(vsi, pstats);
stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
pstats->rx_broadcast - pstats->rx_discards;
stats->imissed = pstats->rx_discards;
stats->oerrors = pstats->tx_errors + pstats->tx_discards;
stats->ibytes = pstats->rx_bytes;
- stats->ibytes -= stats->ipackets * RTE_ETHER_CRC_LEN;
+ stats->ibytes -= stats->ipackets * crc_stats_len;
stats->obytes = pstats->tx_bytes;
} else {
PMD_DRV_LOG(ERR, "Get statistics failed");
}
}
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
+ if (iavf_get_vlan_offload_caps_v2(adapter) != 0) {
+ PMD_INIT_LOG(ERR, "failed to do get VLAN offload v2 capabilities");
+ goto err_rss;
+ }
+ }
+
iavf_init_proto_xtr(dev);
return 0;
return ret;
}
+static void
+iavf_default_rss_disable(struct iavf_adapter *adapter)
+{
+ struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+ int ret = 0;
+
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF) {
+ /* Set hena = 0 to ask PF to cleanup all existing RSS. */
+ ret = iavf_set_hena(adapter, 0);
+ if (ret)
+ /* It is a workaround, temporarily allow error to be
+ * returned due to possible lack of PF handling for
+ * hena = 0.
+ */
+ PMD_INIT_LOG(WARNING, "fail to disable default RSS,"
+ "lack PF support");
+ }
+}
static int
iavf_dev_init(struct rte_eth_dev *eth_dev)
return ret;
}
- /* Set hena = 0 to ask PF to cleanup all existing RSS. */
- ret = iavf_set_hena(adapter, 0);
- if (ret) {
- PMD_DRV_LOG(ERR, "fail to disable default PF RSS");
- return ret;
- }
+ iavf_default_rss_disable(adapter);
return 0;
}