* [PATCH v9 14/26] net/i40e: set VF VLAN insertion from PF
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Bernard Iremonger
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: Bernard Iremonger <bernard.iremonger@intel.com>
Support inserting VF VLAN id from PF.
User can call the API on PF to insert a VLAN id to a
specific VF.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 62 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 19 ++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
3 files changed, 82 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4851978..c173a1c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10293,3 +10293,65 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
return ret;
}
+
+int rte_pmd_i40e_set_vf_vlan_insert(uint8_t port, uint16_t vf_id,
+ uint16_t vlan_id)
+{
+ struct rte_eth_dev *dev;
+ struct i40e_pf *pf;
+ struct i40e_hw *hw;
+ struct i40e_vsi *vsi;
+ struct i40e_vsi_context ctxt;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ if (vlan_id > ETHER_MAX_VLAN_ID) {
+ PMD_DRV_LOG(ERR, "Invalid VLAN ID.");
+ return -EINVAL;
+ }
+
+ dev = &rte_eth_devices[port];
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ hw = I40E_PF_TO_HW(pf);
+
+ /**
+ * return -ENODEV if SRIOV not enabled, VF number not configured
+ * or no queue assigned.
+ */
+ if (!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 ||
+ pf->vf_nb_qps == 0)
+ return -ENODEV;
+
+ if (vf_id >= pf->vf_num || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid VF ID.");
+ return -EINVAL;
+ }
+
+ vsi = pf->vfs[vf_id].vsi;
+ if (!vsi) {
+ PMD_DRV_LOG(ERR, "Invalid VSI.");
+ return -EINVAL;
+ }
+
+ vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
+ vsi->info.pvid = vlan_id;
+ if (vlan_id > 0)
+ vsi->info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_INSERT_PVID;
+ else
+ vsi->info.port_vlan_flags &= ~I40E_AQ_VSI_PVLAN_INSERT_PVID;
+
+ memset(&ctxt, 0, sizeof(ctxt));
+ (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+ ctxt.seid = vsi->seid;
+
+ hw = I40E_VSI_TO_HW(vsi);
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret != I40E_SUCCESS) {
+ ret = -ENOTSUP;
+ PMD_DRV_LOG(ERR, "Failed to update VSI params");
+ }
+
+ return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index a13354f..ce89ffa 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -213,4 +213,23 @@ int rte_pmd_i40e_set_vf_mac_addr(uint8_t port, uint16_t vf_id,
int
rte_pmd_i40e_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+/**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * ID specifying VF.
+ * @param vlan_id
+ * 0 - Disable VF's vlan insert.
+ * n - Enable; n is inserted as the vlan id.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_vlan_insert(uint8_t port, uint16_t vf_id,
+ uint16_t vlan_id);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index d4e7acd..d851f6c 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -13,6 +13,7 @@ DPDK_17.02 {
rte_pmd_i40e_set_vf_multicast_promisc;
rte_pmd_i40e_set_vf_unicast_promisc;
rte_pmd_i40e_set_vf_vlan_anti_spoof;
+ rte_pmd_i40e_set_vf_vlan_insert;
rte_pmd_i40e_set_vf_vlan_stripq;
} DPDK_2.0;
--
1.9.3
^ permalink raw reply related
* [PATCH v9 15/26] net/i40e: set VF broadcast mode from PF
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Bernard Iremonger
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: Bernard Iremonger <bernard.iremonger@intel.com>
Support enabling/disabling VF broadcast mode from PF.
User can call the API on PF to enable/disable a specific
VF's broadcast mode.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 53 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 19 +++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
3 files changed, 73 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index c173a1c..396ecd6 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10355,3 +10355,56 @@ int rte_pmd_i40e_set_vf_vlan_insert(uint8_t port, uint16_t vf_id,
return ret;
}
+
+int rte_pmd_i40e_set_vf_broadcast(uint8_t port, uint16_t vf_id,
+ uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct i40e_pf *pf;
+ struct i40e_vsi *vsi;
+ struct i40e_hw *hw;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+
+ if (on > 1) {
+ PMD_DRV_LOG(ERR, "on should be 0 or 1.");
+ return -EINVAL;
+ }
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ hw = I40E_PF_TO_HW(pf);
+
+ if (vf_id >= pf->vf_num || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid VF ID.");
+ return -EINVAL;
+ }
+
+ /**
+ * return -ENODEV if SRIOV not enabled, VF number not configured
+ * or no queue assigned.
+ */
+ if (!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 ||
+ pf->vf_nb_qps == 0) {
+ PMD_DRV_LOG(ERR, "SRIOV is not enabled or no queue.");
+ return -ENODEV;
+ }
+
+ vsi = pf->vfs[vf_id].vsi;
+ if (!vsi) {
+ PMD_DRV_LOG(ERR, "Invalid VSI.");
+ return -EINVAL;
+ }
+
+ hw = I40E_VSI_TO_HW(vsi);
+
+ ret = i40e_aq_set_vsi_broadcast(hw, vsi->seid, on, NULL);
+ if (ret != I40E_SUCCESS) {
+ ret = -ENOTSUP;
+ PMD_DRV_LOG(ERR, "Failed to set VSI broadcast");
+ }
+
+ return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index ce89ffa..1acb524 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -232,4 +232,23 @@ int rte_pmd_i40e_set_vf_mac_addr(uint8_t port, uint16_t vf_id,
int rte_pmd_i40e_set_vf_vlan_insert(uint8_t port, uint16_t vf_id,
uint16_t vlan_id);
+/**
+ * Enable/Disable vf broadcast mode
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * ID specifying VF.
+ * @param on
+ * 0 - Disable broadcast.
+ * 1 - Enable broadcast.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_broadcast(uint8_t port, uint16_t vf_id,
+ uint8_t on);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index d851f6c..6a3d77b 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -8,6 +8,7 @@ DPDK_17.02 {
rte_pmd_i40e_ping_vfs;
rte_pmd_i40e_set_tx_loopback;
+ rte_pmd_i40e_set_vf_broadcast;
rte_pmd_i40e_set_vf_mac_addr;
rte_pmd_i40e_set_vf_mac_anti_spoof;
rte_pmd_i40e_set_vf_multicast_promisc;
--
1.9.3
^ permalink raw reply related
* [PATCH v9 16/26] net/i40e: set VF VLAN tag from PF
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Bernard Iremonger
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: Bernard Iremonger <bernard.iremonger@intel.com>
Add rte_pmd_i40e_set_vf_vlan_tag API.
User can call the API on PF to enable/disable a specific
VF's VLAN tag.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 65 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 18 +++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
3 files changed, 84 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 396ecd6..d8bdd17 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10408,3 +10408,68 @@ int rte_pmd_i40e_set_vf_broadcast(uint8_t port, uint16_t vf_id,
return ret;
}
+
+int rte_pmd_i40e_set_vf_vlan_tag(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct i40e_pf *pf;
+ struct i40e_hw *hw;
+ struct i40e_vsi *vsi;
+ struct i40e_vsi_context ctxt;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+
+ if (on > 1) {
+ PMD_DRV_LOG(ERR, "on should be 0 or 1.");
+ return -EINVAL;
+ }
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ hw = I40E_PF_TO_HW(pf);
+
+ /**
+ * return -ENODEV if SRIOV not enabled, VF number not configured
+ * or no queue assigned.
+ */
+ if (!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 ||
+ pf->vf_nb_qps == 0) {
+ PMD_DRV_LOG(ERR, "SRIOV is not enabled or no queue.");
+ return -ENODEV;
+ }
+
+ if (vf_id >= pf->vf_num || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid VF ID.");
+ return -EINVAL;
+ }
+
+ vsi = pf->vfs[vf_id].vsi;
+ if (!vsi) {
+ PMD_DRV_LOG(ERR, "Invalid VSI.");
+ return -EINVAL;
+ }
+
+ vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
+ if (on) {
+ vsi->info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_TAGGED;
+ vsi->info.port_vlan_flags &= ~I40E_AQ_VSI_PVLAN_MODE_UNTAGGED;
+ } else {
+ vsi->info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_UNTAGGED;
+ vsi->info.port_vlan_flags &= ~I40E_AQ_VSI_PVLAN_MODE_TAGGED;
+ }
+
+ memset(&ctxt, 0, sizeof(ctxt));
+ (void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+ ctxt.seid = vsi->seid;
+
+ hw = I40E_VSI_TO_HW(vsi);
+ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+ if (ret != I40E_SUCCESS) {
+ ret = -ENOTSUP;
+ PMD_DRV_LOG(ERR, "Failed to update VSI params");
+ }
+
+ return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 1acb524..17a9bfd 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -251,4 +251,22 @@ int rte_pmd_i40e_set_vf_vlan_insert(uint8_t port, uint16_t vf_id,
int rte_pmd_i40e_set_vf_broadcast(uint8_t port, uint16_t vf_id,
uint8_t on);
+/**
+ * Enable/Disable vf vlan tag
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf
+ * ID specifying VF.
+ * @param vlan_id
+ * 0 - Disable VF's vlan tag.
+ * n - Enable VF's vlan tag.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_vlan_tag(uint8_t port, uint16_t vf_id, uint8_t on);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 6a3d77b..f0632ff 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -16,5 +16,6 @@ DPDK_17.02 {
rte_pmd_i40e_set_vf_vlan_anti_spoof;
rte_pmd_i40e_set_vf_vlan_insert;
rte_pmd_i40e_set_vf_vlan_stripq;
+ rte_pmd_i40e_set_vf_vlan_tag;
} DPDK_2.0;
--
1.9.3
^ permalink raw reply related
* [PATCH v9 17/26] net/i40e: set VF VLAN filter from PF
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Bernard Iremonger
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: Bernard Iremonger <bernard.iremonger@intel.com>
add rte_pmd_i40e_set_vf_vlan_filter API.
User can call the API on PF to enable/disable
a set of VF's VLAN filters.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 60 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 22 ++++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 1 +
3 files changed, 83 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index d8bdd17..321be86 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10473,3 +10473,63 @@ int rte_pmd_i40e_set_vf_vlan_tag(uint8_t port, uint16_t vf_id, uint8_t on)
return ret;
}
+
+int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
+ uint64_t vf_mask, uint8_t on)
+{
+ struct rte_eth_dev *dev;
+ struct i40e_pf *pf;
+ struct i40e_hw *hw;
+ uint16_t vf_idx;
+ int ret = I40E_SUCCESS;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+
+ if (vlan_id > ETHER_MAX_VLAN_ID) {
+ PMD_DRV_LOG(ERR, "Invalid VLAN ID.");
+ return -EINVAL;
+ }
+
+ if (vf_mask == 0) {
+ PMD_DRV_LOG(ERR, "No VF.");
+ return -EINVAL;
+ }
+
+ if (on > 1) {
+ PMD_DRV_LOG(ERR, "on is should be 0 or 1.");
+ return -EINVAL;
+ }
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ hw = I40E_PF_TO_HW(pf);
+
+ /**
+ * return -ENODEV if SRIOV not enabled, VF number not configured
+ * or no queue assigned.
+ */
+ if (!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 ||
+ pf->vf_nb_qps == 0) {
+ PMD_DRV_LOG(ERR, "SRIOV is not enabled or no queue.");
+ return -ENODEV;
+ }
+
+ for (vf_idx = 0; vf_idx < 64 && ret == I40E_SUCCESS; vf_idx++) {
+ if (vf_mask & ((uint64_t)(1ULL << vf_idx))) {
+ if (on)
+ ret = i40e_vsi_add_vlan(pf->vfs[vf_idx].vsi,
+ vlan_id);
+ else
+ ret = i40e_vsi_delete_vlan(pf->vfs[vf_idx].vsi,
+ vlan_id);
+ }
+ }
+
+ if (ret != I40E_SUCCESS) {
+ ret = -ENOTSUP;
+ PMD_DRV_LOG(ERR, "Failed to set VF VLAN filter, on = %d", on);
+ }
+
+ return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 17a9bfd..bd03966 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -269,4 +269,26 @@ int rte_pmd_i40e_set_vf_broadcast(uint8_t port, uint16_t vf_id,
*/
int rte_pmd_i40e_set_vf_vlan_tag(uint8_t port, uint16_t vf_id, uint8_t on);
+/**
+ * Enable/Disable VF VLAN filter
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vlan_id
+ * ID specifying VLAN
+ * @param vf_mask
+ * Mask to filter VF's
+ * @param on
+ * 0 - Disable VF's VLAN filter.
+ * 1 - Enable VF's VLAN filter.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ * - (-ENOTSUP) not supported by firmware.
+ */
+int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
+ uint64_t vf_mask, uint8_t on);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index f0632ff..8ac1bc8 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -14,6 +14,7 @@ DPDK_17.02 {
rte_pmd_i40e_set_vf_multicast_promisc;
rte_pmd_i40e_set_vf_unicast_promisc;
rte_pmd_i40e_set_vf_vlan_anti_spoof;
+ rte_pmd_i40e_set_vf_vlan_filter;
rte_pmd_i40e_set_vf_vlan_insert;
rte_pmd_i40e_set_vf_vlan_stripq;
rte_pmd_i40e_set_vf_vlan_tag;
--
1.9.3
^ permalink raw reply related
* [PATCH v9 18/26] app/testpmd: use VFD APIs on i40e
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu, Chen Jing D(Mark), Bernard Iremonger
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
The new VF Daemon (VFD) APIs is implemented on i40e. Change
testpmd code to use them, including VF MAC anti-spoofing,
VF VLAN anti-spoofing, TX loopback, VF VLAN strip, VF VLAN
insert.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Signed-off-by: Chen Jing D(Mark) <jing.d.chen@intel.com>
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
app/test-pmd/Makefile | 3 +
app/test-pmd/cmdline.c | 154 +++++++++++++++++++++++++++++++++++++++----------
2 files changed, 126 insertions(+), 31 deletions(-)
diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 891b85a..66bd38a 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -58,7 +58,10 @@ SRCS-y += csumonly.c
SRCS-y += icmpecho.c
SRCS-$(CONFIG_RTE_LIBRTE_IEEE1588) += ieee1588fwd.c
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
+_LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e
+endif
CFLAGS_cmdline.o := -D_GNU_SOURCE
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ed84d7a..9a44b4f 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -90,6 +90,9 @@
#ifdef RTE_LIBRTE_IXGBE_PMD
#include <rte_pmd_ixgbe.h>
#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+#include <rte_pmd_i40e.h>
+#endif
#include "testpmd.h"
static struct cmdline *testpmd_cl;
@@ -262,19 +265,19 @@ static void cmd_help_long_parsed(void *parsed_result,
"set portlist (x[,y]*)\n"
" Set the list of forwarding ports.\n\n"
-#ifdef RTE_LIBRTE_IXGBE_PMD
"set tx loopback (port_id) (on|off)\n"
" Enable or disable tx loopback.\n\n"
+#ifdef RTE_LIBRTE_IXGBE_PMD
"set all queues drop (port_id) (on|off)\n"
" Set drop enable bit for all queues.\n\n"
"set vf split drop (port_id) (vf_id) (on|off)\n"
" Set split drop enable bit for a VF from the PF.\n\n"
+#endif
"set vf mac antispoof (port_id) (vf_id) (on|off).\n"
" Set MAC antispoof for a VF from the PF.\n\n"
-#endif
"vlan set strip (on|off) (port_id)\n"
" Set the VLAN strip on a port.\n\n"
@@ -282,7 +285,6 @@ static void cmd_help_long_parsed(void *parsed_result,
"vlan set stripq (on|off) (port_id,queue_id)\n"
" Set the VLAN strip for a queue on a port.\n\n"
-#ifdef RTE_LIBRTE_IXGBE_PMD
"set vf vlan stripq (port_id) (vf_id) (on|off)\n"
" Set the VLAN strip for all queues in a pool for a VF from the PF.\n\n"
@@ -291,7 +293,6 @@ static void cmd_help_long_parsed(void *parsed_result,
"set vf vlan antispoof (port_id) (vf_id) (on|off)\n"
" Set VLAN antispoof for a VF from the PF.\n\n"
-#endif
"vlan set filter (on|off) (port_id)\n"
" Set the VLAN filter on a port.\n\n"
@@ -386,10 +387,8 @@ static void cmd_help_long_parsed(void *parsed_result,
"mac_addr add port (port_id) vf (vf_id) (mac_address)\n"
" Add a MAC address for a VF on the port.\n\n"
-#ifdef RTE_LIBRTE_IXGBE_PMD
"set vf mac addr (port_id) (vf_id) (XX:XX:XX:XX:XX:XX)\n"
" Set the MAC address for a VF from the PF.\n\n"
-#endif
"set port (port_id) uta (mac_address|all) (on|off)\n"
" Add/Remove a or all unicast hash filter(s)"
@@ -6675,9 +6674,7 @@ struct cmd_set_vf_traffic {
NULL,
},
};
-#endif
-#ifdef RTE_LIBRTE_IXGBE_PMD
/* *** CONFIGURE VF RECEIVE MODE *** */
struct cmd_set_vf_rxmode {
cmdline_fixed_string_t set;
@@ -10808,7 +10805,6 @@ struct cmd_config_e_tag_result {
NULL,
},
};
-#ifdef RTE_LIBRTE_IXGBE_PMD
/* vf vlan anti spoof configuration */
@@ -10860,11 +10856,24 @@ struct cmd_vf_vlan_anti_spoof_result {
__attribute__((unused)) void *data)
{
struct cmd_vf_vlan_anti_spoof_result *res = parsed_result;
- int ret = 0;
- int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ int ret = -ENOTSUP;
+
+ __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (strstr(dev_info.driver_name, "ixgbe") != NULL)
+ ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id,
+ res->vf_id, is_on);
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_vlan_anti_spoof(res->port_id,
+ res->vf_id, is_on);
+#endif
- ret = rte_pmd_ixgbe_set_vf_vlan_anti_spoof(res->port_id, res->vf_id,
- is_on);
switch (ret) {
case 0:
break;
@@ -10874,6 +10883,9 @@ struct cmd_vf_vlan_anti_spoof_result {
case -ENODEV:
printf("invalid port_id %d\n", res->port_id);
break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
default:
printf("programming error: (%s)\n", strerror(-ret));
}
@@ -10945,11 +10957,24 @@ struct cmd_vf_mac_anti_spoof_result {
__attribute__((unused)) void *data)
{
struct cmd_vf_mac_anti_spoof_result *res = parsed_result;
- int ret;
- int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ int ret = -ENOTSUP;
+
+ __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (strstr(dev_info.driver_name, "ixgbe") != NULL)
+ ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id,
+ res->vf_id, is_on);
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_mac_anti_spoof(res->port_id,
+ res->vf_id, is_on);
+#endif
- ret = rte_pmd_ixgbe_set_vf_mac_anti_spoof(res->port_id, res->vf_id,
- is_on);
switch (ret) {
case 0:
break;
@@ -10959,6 +10984,9 @@ struct cmd_vf_mac_anti_spoof_result {
case -ENODEV:
printf("invalid port_id %d\n", res->port_id);
break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
default:
printf("programming error: (%s)\n", strerror(-ret));
}
@@ -11030,10 +11058,24 @@ struct cmd_vf_vlan_stripq_result {
__attribute__((unused)) void *data)
{
struct cmd_vf_vlan_stripq_result *res = parsed_result;
- int ret = 0;
- int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ int ret = -ENOTSUP;
+
+ __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (strstr(dev_info.driver_name, "ixgbe") != NULL)
+ ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id,
+ res->vf_id, is_on);
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_vlan_stripq(res->port_id,
+ res->vf_id, is_on);
+#endif
- ret = rte_pmd_ixgbe_set_vf_vlan_stripq(res->port_id, res->vf_id, is_on);
switch (ret) {
case 0:
break;
@@ -11114,9 +11156,22 @@ struct cmd_vf_vlan_insert_result {
__attribute__((unused)) void *data)
{
struct cmd_vf_vlan_insert_result *res = parsed_result;
- int ret;
+ int ret = -ENOTSUP;
+ struct rte_eth_dev_info dev_info;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (strstr(dev_info.driver_name, "ixgbe") != NULL)
+ ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id,
+ res->vlan_id);
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_vlan_insert(res->port_id, res->vf_id,
+ res->vlan_id);
+#endif
- ret = rte_pmd_ixgbe_set_vf_vlan_insert(res->port_id, res->vf_id, res->vlan_id);
switch (ret) {
case 0:
break;
@@ -11126,6 +11181,9 @@ struct cmd_vf_vlan_insert_result {
case -ENODEV:
printf("invalid port_id %d\n", res->port_id);
break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
default:
printf("programming error: (%s)\n", strerror(-ret));
}
@@ -11187,10 +11245,22 @@ struct cmd_tx_loopback_result {
__attribute__((unused)) void *data)
{
struct cmd_tx_loopback_result *res = parsed_result;
- int ret;
- int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ int ret = -ENOTSUP;
+
+ __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (strstr(dev_info.driver_name, "ixgbe") != NULL)
+ ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_tx_loopback(res->port_id, is_on);
+#endif
- ret = rte_pmd_ixgbe_set_tx_loopback(res->port_id, is_on);
switch (ret) {
case 0:
break;
@@ -11200,6 +11270,9 @@ struct cmd_tx_loopback_result {
case -ENODEV:
printf("invalid port_id %d\n", res->port_id);
break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
default:
printf("programming error: (%s)\n", strerror(-ret));
}
@@ -11219,6 +11292,7 @@ struct cmd_tx_loopback_result {
},
};
+#ifdef RTE_LIBRTE_IXGBE_PMD
/* all queues drop enable configuration */
/* Common result structure for all queues drop enable */
@@ -11277,6 +11351,9 @@ struct cmd_all_queues_drop_en_result {
case -ENODEV:
printf("invalid port_id %d\n", res->port_id);
break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
default:
printf("programming error: (%s)\n", strerror(-ret));
}
@@ -11381,6 +11458,7 @@ struct cmd_vf_split_drop_en_result {
NULL,
},
};
+#endif
/* vf mac address configuration */
@@ -11432,10 +11510,22 @@ struct cmd_set_vf_mac_addr_result {
__attribute__((unused)) void *data)
{
struct cmd_set_vf_mac_addr_result *res = parsed_result;
- int ret;
+ struct rte_eth_dev_info dev_info;
+ int ret = -ENOTSUP;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (strstr(dev_info.driver_name, "ixgbe") != NULL)
+ ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id,
+ &res->mac_addr);
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_mac_addr(res->port_id, res->vf_id,
+ &res->mac_addr);
+#endif
- ret = rte_pmd_ixgbe_set_vf_mac_addr(res->port_id, res->vf_id,
- &res->mac_addr);
switch (ret) {
case 0:
break;
@@ -11445,6 +11535,9 @@ struct cmd_set_vf_mac_addr_result {
case -ENODEV:
printf("invalid port_id %d\n", res->port_id);
break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
default:
printf("programming error: (%s)\n", strerror(-ret));
}
@@ -11465,7 +11558,6 @@ struct cmd_set_vf_mac_addr_result {
NULL,
},
};
-#endif
/* ******************************************************************************** */
@@ -11619,20 +11711,20 @@ struct cmd_set_vf_mac_addr_result {
(cmdline_parse_inst_t *)&cmd_config_e_tag_forwarding_en_dis,
(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_add,
(cmdline_parse_inst_t *)&cmd_config_e_tag_filter_del,
-#ifdef RTE_LIBRTE_IXGBE_PMD
(cmdline_parse_inst_t *)&cmd_set_vf_vlan_anti_spoof,
(cmdline_parse_inst_t *)&cmd_set_vf_mac_anti_spoof,
(cmdline_parse_inst_t *)&cmd_set_vf_vlan_stripq,
(cmdline_parse_inst_t *)&cmd_set_vf_vlan_insert,
(cmdline_parse_inst_t *)&cmd_set_tx_loopback,
+#ifdef RTE_LIBRTE_IXGBE_PMD
(cmdline_parse_inst_t *)&cmd_set_all_queues_drop_en,
(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
- (cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
(cmdline_parse_inst_t *)&cmd_set_vf_traffic,
(cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
#endif
+ (cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
NULL,
};
--
1.9.3
^ permalink raw reply related
* [PATCH v9 19/26] app/testpmd: use unicast promiscuous mode on i40e
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
Add testpmd CLI to set VF unicast promiscuous mode on i40e.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
app/test-pmd/cmdline.c | 97 +++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 9 +++
2 files changed, 106 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9a44b4f..cc177a6 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -400,6 +400,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"set allmulti (port_id|all) (on|off)\n"
" Set the allmulti mode on port_id, or all.\n\n"
+ "set vf promisc (port_id) (vf_id) (on|off)\n"
+ " Set unicast promiscuous mode for a VF from the PF.\n\n"
+
"set flow_ctrl rx (on|off) tx (on|off) (high_water)"
" (low_water) (pause_time) (send_xon) mac_ctrl_frame_fwd"
" (on|off) autoneg (on|off) (port_id)\n"
@@ -11559,6 +11562,99 @@ struct cmd_set_vf_mac_addr_result {
},
};
+/* VF unicast promiscuous mode configuration */
+
+/* Common result structure for VF unicast promiscuous mode */
+struct cmd_vf_promisc_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t vf;
+ cmdline_fixed_string_t promisc;
+ uint8_t port_id;
+ uint32_t vf_id;
+ cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for VF unicast promiscuous mode enable disable */
+cmdline_parse_token_string_t cmd_vf_promisc_set =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_vf_promisc_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_vf_promisc_vf =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_vf_promisc_result,
+ vf, "vf");
+cmdline_parse_token_string_t cmd_vf_promisc_promisc =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_vf_promisc_result,
+ promisc, "promisc");
+cmdline_parse_token_num_t cmd_vf_promisc_port_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_vf_promisc_result,
+ port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_promisc_vf_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_vf_promisc_result,
+ vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_promisc_on_off =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_vf_promisc_result,
+ on_off, "on#off");
+
+static void
+cmd_set_vf_promisc_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_vf_promisc_result *res = parsed_result;
+ int ret = -ENOTSUP;
+
+ __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+ return;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_unicast_promisc(res->port_id,
+ res->vf_id, is_on);
+#endif
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINVAL:
+ printf("invalid vf_id %d\n", res->vf_id);
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", res->port_id);
+ break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
+}
+
+cmdline_parse_inst_t cmd_set_vf_promisc = {
+ .f = cmd_set_vf_promisc_parsed,
+ .data = NULL,
+ .help_str = "set vf unicast promiscuous mode for a VF from PF",
+ .tokens = {
+ (void *)&cmd_vf_promisc_set,
+ (void *)&cmd_vf_promisc_vf,
+ (void *)&cmd_vf_promisc_promisc,
+ (void *)&cmd_vf_promisc_port_id,
+ (void *)&cmd_vf_promisc_vf_id,
+ (void *)&cmd_vf_promisc_on_off,
+ NULL,
+ },
+};
+
/* ******************************************************************************** */
/* list of instructions */
@@ -11725,6 +11821,7 @@ struct cmd_set_vf_mac_addr_result {
(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
#endif
(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
+ (cmdline_parse_inst_t *)&cmd_set_vf_promisc,
NULL,
};
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f1c269a..2b18c66 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -820,6 +820,15 @@ Set the allmulti mode for a port or for all ports::
Same as the ifconfig (8) option. Controls how multicast packets are handled.
+set promisc (for VF)
+~~~~~~~~~~~~~~~~~~~~
+
+Set the unicast promiscuous mode for a VF from PF.
+It's supported by Intel i40e NICs now.
+In promiscuous mode packets are not dropped if they aren't for the specified MAC address::
+
+ testpmd> set vf promisc (port_id) (vf_id) (on|off)
+
set flow_ctrl rx
~~~~~~~~~~~~~~~~
--
1.9.3
^ permalink raw reply related
* [PATCH v9 20/26] app/testpmd: use multicast promiscuous mode on i40e
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
Add testpmd CLI to set VF multicast promiscuous mode on i40e.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
app/test-pmd/cmdline.c | 97 +++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 9 +++
2 files changed, 106 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index cc177a6..c5f5134 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -403,6 +403,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"set vf promisc (port_id) (vf_id) (on|off)\n"
" Set unicast promiscuous mode for a VF from the PF.\n\n"
+ "set vf allmulti (port_id) (vf_id) (on|off)\n"
+ " Set multicast promiscuous mode for a VF from the PF.\n\n"
+
"set flow_ctrl rx (on|off) tx (on|off) (high_water)"
" (low_water) (pause_time) (send_xon) mac_ctrl_frame_fwd"
" (on|off) autoneg (on|off) (port_id)\n"
@@ -11655,6 +11658,99 @@ struct cmd_vf_promisc_result {
},
};
+/* VF multicast promiscuous mode configuration */
+
+/* Common result structure for VF multicast promiscuous mode */
+struct cmd_vf_allmulti_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t vf;
+ cmdline_fixed_string_t allmulti;
+ uint8_t port_id;
+ uint32_t vf_id;
+ cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for VF multicast promiscuous mode enable disable */
+cmdline_parse_token_string_t cmd_vf_allmulti_set =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_vf_allmulti_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_vf_allmulti_vf =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_vf_allmulti_result,
+ vf, "vf");
+cmdline_parse_token_string_t cmd_vf_allmulti_allmulti =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_vf_allmulti_result,
+ allmulti, "allmulti");
+cmdline_parse_token_num_t cmd_vf_allmulti_port_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_vf_allmulti_result,
+ port_id, UINT8);
+cmdline_parse_token_num_t cmd_vf_allmulti_vf_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_vf_allmulti_result,
+ vf_id, UINT32);
+cmdline_parse_token_string_t cmd_vf_allmulti_on_off =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_vf_allmulti_result,
+ on_off, "on#off");
+
+static void
+cmd_set_vf_allmulti_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_vf_allmulti_result *res = parsed_result;
+ int ret = -ENOTSUP;
+
+ __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+ return;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_multicast_promisc(res->port_id,
+ res->vf_id, is_on);
+#endif
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINVAL:
+ printf("invalid vf_id %d\n", res->vf_id);
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", res->port_id);
+ break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
+}
+
+cmdline_parse_inst_t cmd_set_vf_allmulti = {
+ .f = cmd_set_vf_allmulti_parsed,
+ .data = NULL,
+ .help_str = "set vf multicast promiscuous for a VF from PF",
+ .tokens = {
+ (void *)&cmd_vf_allmulti_set,
+ (void *)&cmd_vf_allmulti_vf,
+ (void *)&cmd_vf_allmulti_allmulti,
+ (void *)&cmd_vf_allmulti_port_id,
+ (void *)&cmd_vf_allmulti_vf_id,
+ (void *)&cmd_vf_allmulti_on_off,
+ NULL,
+ },
+};
+
/* ******************************************************************************** */
/* list of instructions */
@@ -11822,6 +11918,7 @@ struct cmd_vf_promisc_result {
#endif
(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
(cmdline_parse_inst_t *)&cmd_set_vf_promisc,
+ (cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
NULL,
};
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2b18c66..45c5902 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -829,6 +829,15 @@ In promiscuous mode packets are not dropped if they aren't for the specified MAC
testpmd> set vf promisc (port_id) (vf_id) (on|off)
+set allmulticast (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set the multicast promiscuous mode for a VF from PF.
+It's supported by Intel i40e NICs now.
+In promiscuous mode packets are not dropped if they aren't for the specified MAC address::
+
+ testpmd> set vf allmulti (port_id) (vf_id) (on|off)
+
set flow_ctrl rx
~~~~~~~~~~~~~~~~
--
1.9.3
^ permalink raw reply related
* [PATCH v9 21/26] app/testpmd: add command to test VF broadcast mode on i40e
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Bernard Iremonger
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: Bernard Iremonger <bernard.iremonger@intel.com>
Add command to call rte_pmd_i40e_set_vf_broadcast.
Add set vf broadcast in testpmd_funcs.rst file.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
app/test-pmd/cmdline.c | 97 +++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 7 +++
2 files changed, 104 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index c5f5134..a860228 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -279,6 +279,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"set vf mac antispoof (port_id) (vf_id) (on|off).\n"
" Set MAC antispoof for a VF from the PF.\n\n"
+ "set vf broadcast (port_id) (vf_id) (on|off)\n"
+ " Set VF broadcast for a VF from the PF.\n\n"
+
"vlan set strip (on|off) (port_id)\n"
" Set the VLAN strip on a port.\n\n"
@@ -11751,6 +11754,99 @@ struct cmd_vf_allmulti_result {
},
};
+/* vf broadcast mode configuration */
+
+/* Common result structure for vf broadcast */
+struct cmd_set_vf_broadcast_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t vf;
+ cmdline_fixed_string_t broadcast;
+ uint8_t port_id;
+ uint16_t vf_id;
+ cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf broadcast enable disable */
+cmdline_parse_token_string_t cmd_set_vf_broadcast_set =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_broadcast_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_set_vf_broadcast_vf =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_broadcast_result,
+ vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_broadcast_broadcast =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_broadcast_result,
+ broadcast, "broadcast");
+cmdline_parse_token_num_t cmd_set_vf_broadcast_port_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_set_vf_broadcast_result,
+ port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_broadcast_vf_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_set_vf_broadcast_result,
+ vf_id, UINT16);
+cmdline_parse_token_string_t cmd_set_vf_broadcast_on_off =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_broadcast_result,
+ on_off, "on#off");
+
+static void
+cmd_set_vf_broadcast_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_vf_broadcast_result *res = parsed_result;
+ int ret = -ENOTSUP;
+
+ __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+ return;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_broadcast(res->port_id,
+ res->vf_id, is_on);
+#endif
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINVAL:
+ printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", res->port_id);
+ break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
+}
+
+cmdline_parse_inst_t cmd_set_vf_broadcast = {
+ .f = cmd_set_vf_broadcast_parsed,
+ .data = NULL,
+ .help_str = "set vf broadcast port_id vf_id on|off",
+ .tokens = {
+ (void *)&cmd_set_vf_broadcast_set,
+ (void *)&cmd_set_vf_broadcast_vf,
+ (void *)&cmd_set_vf_broadcast_broadcast,
+ (void *)&cmd_set_vf_broadcast_port_id,
+ (void *)&cmd_set_vf_broadcast_vf_id,
+ (void *)&cmd_set_vf_broadcast_on_off,
+ NULL,
+ },
+};
+
/* ******************************************************************************** */
/* list of instructions */
@@ -11919,6 +12015,7 @@ struct cmd_vf_allmulti_result {
(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
(cmdline_parse_inst_t *)&cmd_set_vf_promisc,
(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
+ (cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
NULL,
};
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 45c5902..823db7e 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -507,6 +507,13 @@ Set mac antispoof for a VF from the PF::
testpmd> set vf mac antispoof (port_id) (vf_id) (on|off)
+set broadcast mode (for VF)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Set broadcast mode for a VF from the PF::
+
+ testpmd> set vf broadcast (port_id) (vf_id) (on|off)
+
vlan set strip
~~~~~~~~~~~~~~
--
1.9.3
^ permalink raw reply related
* [PATCH v9 22/26] app/testpmd: add command to test VF VLAN tag on i40e
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Bernard Iremonger
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: Bernard Iremonger <bernard.iremonger@intel.com>
command is: set vf vlan tag port_id vf_id on|off
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
app/test-pmd/cmdline.c | 103 ++++++++++++++++++++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 7 ++
2 files changed, 110 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index a860228..2402d1d 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -297,6 +297,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"set vf vlan antispoof (port_id) (vf_id) (on|off)\n"
" Set VLAN antispoof for a VF from the PF.\n\n"
+ "set vf vlan tag (port_id) (vf_id) (on|off)\n"
+ " Set VLAN tag for a VF from the PF.\n\n"
+
"vlan set filter (on|off) (port_id)\n"
" Set the VLAN filter on a port.\n\n"
@@ -11847,6 +11850,105 @@ struct cmd_set_vf_broadcast_result {
},
};
+/* vf vlan tag configuration */
+
+/* Common result structure for vf vlan tag */
+struct cmd_set_vf_vlan_tag_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t vf;
+ cmdline_fixed_string_t vlan;
+ cmdline_fixed_string_t tag;
+ uint8_t port_id;
+ uint16_t vf_id;
+ cmdline_fixed_string_t on_off;
+};
+
+/* Common CLI fields for vf vlan tag enable disable */
+cmdline_parse_token_string_t cmd_set_vf_vlan_tag_set =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_vlan_tag_result,
+ set, "set");
+cmdline_parse_token_string_t cmd_set_vf_vlan_tag_vf =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_vlan_tag_result,
+ vf, "vf");
+cmdline_parse_token_string_t cmd_set_vf_vlan_tag_vlan =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_vlan_tag_result,
+ vlan, "vlan");
+cmdline_parse_token_string_t cmd_set_vf_vlan_tag_tag =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_vlan_tag_result,
+ tag, "tag");
+cmdline_parse_token_num_t cmd_set_vf_vlan_tag_port_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_set_vf_vlan_tag_result,
+ port_id, UINT8);
+cmdline_parse_token_num_t cmd_set_vf_vlan_tag_vf_id =
+ TOKEN_NUM_INITIALIZER
+ (struct cmd_set_vf_vlan_tag_result,
+ vf_id, UINT16);
+cmdline_parse_token_string_t cmd_set_vf_vlan_tag_on_off =
+ TOKEN_STRING_INITIALIZER
+ (struct cmd_set_vf_vlan_tag_result,
+ on_off, "on#off");
+
+static void
+cmd_set_vf_vlan_tag_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_vf_vlan_tag_result *res = parsed_result;
+ int ret = -ENOTSUP;
+
+ __rte_unused int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+ return;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_vlan_tag(res->port_id,
+ res->vf_id, is_on);
+#endif
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINVAL:
+ printf("invalid vf_id %d or is_on %d\n", res->vf_id, is_on);
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", res->port_id);
+ break;
+ case -ENOTSUP:
+ printf("function not implemented\n");
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
+}
+
+cmdline_parse_inst_t cmd_set_vf_vlan_tag = {
+ .f = cmd_set_vf_vlan_tag_parsed,
+ .data = NULL,
+ .help_str = "set vf vlan tag port_id vf_id on|off",
+ .tokens = {
+ (void *)&cmd_set_vf_vlan_tag_set,
+ (void *)&cmd_set_vf_vlan_tag_vf,
+ (void *)&cmd_set_vf_vlan_tag_vlan,
+ (void *)&cmd_set_vf_vlan_tag_tag,
+ (void *)&cmd_set_vf_vlan_tag_port_id,
+ (void *)&cmd_set_vf_vlan_tag_vf_id,
+ (void *)&cmd_set_vf_vlan_tag_on_off,
+ NULL,
+ },
+};
+
/* ******************************************************************************** */
/* list of instructions */
@@ -12016,6 +12118,7 @@ struct cmd_set_vf_broadcast_result {
(cmdline_parse_inst_t *)&cmd_set_vf_promisc,
(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
(cmdline_parse_inst_t *)&cmd_set_vf_broadcast,
+ (cmdline_parse_inst_t *)&cmd_set_vf_vlan_tag,
NULL,
};
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 823db7e..84805af 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -542,6 +542,13 @@ Set VLAN insert for a VF from the PF::
testpmd> set vf vlan insert (port_id) (vf_id) (vlan_id)
+vlan set tag (for VF)
+~~~~~~~~~~~~~~~~~~~~~
+
+Set VLAN tag for a VF from the PF::
+
+ testpmd> set vf vlan tag (port_id) (vf_id) (on|off)
+
vlan set antispoof (for VF)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
1.9.3
^ permalink raw reply related
* [PATCH v9 23/26] app/testpmd: handle i40e in VF VLAN filter command
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Bernard Iremonger
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: Bernard Iremonger <bernard.iremonger@intel.com>
modify set_vf_rx_vlan function to handle the i40e PMD.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
app/test-pmd/cmdline.c | 41 ++++++++++++++++++++++++++++++++++-------
app/test-pmd/config.c | 13 -------------
app/test-pmd/testpmd.h | 2 --
3 files changed, 34 insertions(+), 22 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 2402d1d..107c808 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6835,7 +6835,6 @@ static void cmd_vf_mac_addr_parsed(void *parsed_result,
},
};
-#ifdef RTE_LIBRTE_IXGBE_PMD
/* *** ADD/REMOVE A VLAN IDENTIFIER TO/FROM A PORT VLAN RX FILTER *** */
struct cmd_vf_rx_vlan_filter {
cmdline_fixed_string_t rx_vlan;
@@ -6853,11 +6852,40 @@ struct cmd_vf_rx_vlan_filter {
__attribute__((unused)) void *data)
{
struct cmd_vf_rx_vlan_filter *res = parsed_result;
+ int ret = -ENOTSUP;
- if (!strcmp(res->what, "add"))
- set_vf_rx_vlan(res->port_id, res->vlan_id,res->vf_mask, 1);
- else
- set_vf_rx_vlan(res->port_id, res->vlan_id,res->vf_mask, 0);
+ __rte_unused int is_add = (strcmp(res->what, "add") == 0) ? 1 : 0;
+ struct rte_eth_dev_info dev_info;
+
+ rte_eth_dev_info_get(res->port_id, &dev_info);
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (strstr(dev_info.driver_name, "ixgbe") != NULL)
+ ret = rte_pmd_ixgbe_set_vf_vlan_filter(res->port_id,
+ res->vlan_id, res->vf_mask, is_add);
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (strstr(dev_info.driver_name, "i40e") != NULL)
+ ret = rte_pmd_i40e_set_vf_vlan_filter(res->port_id,
+ res->vlan_id, res->vf_mask, is_add);
+#endif
+
+ switch (ret) {
+ case 0:
+ break;
+ case -EINVAL:
+ printf("invalid vlan_id %d or vf_mask %"PRIu64"\n",
+ res->vlan_id, res->vf_mask);
+ break;
+ case -ENODEV:
+ printf("invalid port_id %d\n", res->port_id);
+ break;
+ case -ENOTSUP:
+ printf("function not implemented or supported\n");
+ break;
+ default:
+ printf("programming error: (%s)\n", strerror(-ret));
+ }
}
cmdline_parse_token_string_t cmd_vf_rx_vlan_filter_rx_vlan =
@@ -6898,7 +6926,6 @@ struct cmd_vf_rx_vlan_filter {
NULL,
},
};
-#endif
/* *** SET RATE LIMIT FOR A QUEUE OF A PORT *** */
struct cmd_queue_rate_limit_result {
@@ -12111,9 +12138,9 @@ struct cmd_set_vf_vlan_tag_result {
(cmdline_parse_inst_t *)&cmd_set_vf_split_drop_en,
(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
(cmdline_parse_inst_t *)&cmd_set_vf_traffic,
- (cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
#endif
+ (cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
(cmdline_parse_inst_t *)&cmd_set_vf_promisc,
(cmdline_parse_inst_t *)&cmd_set_vf_allmulti,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index fc0424a..38aa0b9 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2348,19 +2348,6 @@ struct igb_ring_desc_16_bytes {
"diag=%d\n", port_id, diag);
}
-
-void
-set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on)
-{
- int diag;
-
- diag = rte_pmd_ixgbe_set_vf_vlan_filter(port_id, vlan_id, vf_mask, on);
-
- if (diag == 0)
- return;
- printf("rte_pmd_ixgbe_set_vf_vlan_filter for port_id=%d failed "
- "diag=%d\n", port_id, diag);
-}
#endif
int
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 9c1e703..5d104bd 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -571,8 +571,6 @@ void port_rss_reta_info(portid_t port_id,
uint16_t nb_entries);
void set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on);
-void set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id,
- uint64_t vf_mask, uint8_t on);
int set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate);
int set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate,
--
1.9.3
^ permalink raw reply related
* [PATCH v9 24/26] net/i40e: enhance in sanity check of MAC
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Chen Jing D(Mark)
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: "Chen Jing D(Mark)" <jing.d.chen@intel.com>
When VF sends request to add a new MAC address, PF host
will check if it's a non-zero or unicast address, or it
will return with error. In fact, VF still can set multicast
address. This change remove to check if it's a unicast
address.
Signed-off-by: Chen Jing D(Mark) <jing.d.chen@intel.com>
---
drivers/net/i40e/i40e_pf.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 8a6733c..263e843 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -753,8 +753,8 @@
mac = (struct ether_addr *)(addr_list->list[i].addr);
(void)rte_memcpy(&filter.mac_addr, mac, ETHER_ADDR_LEN);
filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
- if(!is_valid_assigned_ether_addr(mac) ||
- i40e_vsi_add_mac(vf->vsi, &filter)) {
+ if (is_zero_ether_addr(mac) ||
+ i40e_vsi_add_mac(vf->vsi, &filter)) {
ret = I40E_ERR_INVALID_MAC_ADDR;
goto send_msg;
}
--
1.9.3
^ permalink raw reply related
* [PATCH v9 25/26] net/i40e: set/clear VF stats from PF
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Qi Zhang
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
From: Qi Zhang <qi.z.zhang@intel.com>
This patch add support to get/clear VF statistics
from PF side.
Two APIs are added:
rte_pmd_i40e_get_vf_stats.
rte_pmd_i40e_reset_vf_stats.
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
drivers/net/i40e/i40e_ethdev.c | 73 +++++++++++++++++++++++++++++++
drivers/net/i40e/rte_pmd_i40e.h | 41 +++++++++++++++++
drivers/net/i40e/rte_pmd_i40e_version.map | 2 +
3 files changed, 116 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 321be86..b9bad3c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10533,3 +10533,76 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
return ret;
}
+
+int
+rte_pmd_i40e_get_vf_stats(uint8_t port,
+ uint16_t vf_id,
+ struct rte_eth_stats *stats)
+{
+ struct rte_eth_dev *dev;
+ struct i40e_pf *pf;
+ struct i40e_vsi *vsi;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ if (vf_id >= pf->vf_num || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid VF ID.");
+ return -EINVAL;
+ }
+
+ vsi = pf->vfs[vf_id].vsi;
+ if (!vsi) {
+ PMD_DRV_LOG(ERR, "Invalid VSI.");
+ return -EINVAL;
+ }
+
+ i40e_update_vsi_stats(vsi);
+
+ stats->ipackets = vsi->eth_stats.rx_unicast +
+ vsi->eth_stats.rx_multicast +
+ vsi->eth_stats.rx_broadcast;
+ stats->opackets = vsi->eth_stats.tx_unicast +
+ vsi->eth_stats.tx_multicast +
+ vsi->eth_stats.tx_broadcast;
+ stats->ibytes = vsi->eth_stats.rx_bytes;
+ stats->obytes = vsi->eth_stats.tx_bytes;
+ stats->ierrors = vsi->eth_stats.rx_discards;
+ stats->oerrors = vsi->eth_stats.tx_errors + vsi->eth_stats.tx_discards;
+
+ return 0;
+}
+
+int
+rte_pmd_i40e_reset_vf_stats(uint8_t port,
+ uint16_t vf_id)
+{
+ struct rte_eth_dev *dev;
+ struct i40e_pf *pf;
+ struct i40e_vsi *vsi;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+
+ pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+ if (vf_id >= pf->vf_num || !pf->vfs) {
+ PMD_DRV_LOG(ERR, "Invalid VF ID.");
+ return -EINVAL;
+ }
+
+ vsi = pf->vfs[vf_id].vsi;
+ if (!vsi) {
+ PMD_DRV_LOG(ERR, "Invalid VSI.");
+ return -EINVAL;
+ }
+
+ vsi->offset_loaded = false;
+ i40e_update_vsi_stats(vsi);
+
+ return 0;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index bd03966..298c710 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -291,4 +291,45 @@ int rte_pmd_i40e_set_vf_broadcast(uint8_t port, uint16_t vf_id,
int rte_pmd_i40e_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
uint64_t vf_mask, uint8_t on);
+/**
+ * Get VF's statistics
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf_id
+ * VF on which to get.
+ * @param stats
+ * A pointer to a structure of type *rte_eth_stats* to be filled with
+ * the values of device counters for the following set of statistics:
+ * - *ipackets* with the total of successfully received packets.
+ * - *opackets* with the total of successfully transmitted packets.
+ * - *ibytes* with the total of successfully received bytes.
+ * - *obytes* with the total of successfully transmitted bytes.
+ * - *ierrors* with the total of erroneous received packets.
+ * - *oerrors* with the total of failed transmitted packets.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_i40e_get_vf_stats(uint8_t port,
+ uint16_t vf_id,
+ struct rte_eth_stats *stats);
+
+/**
+ * Clear VF's statistics
+ *
+ * @param port
+ * The port identifier of the Ethernet device.
+ * @param vf_id
+ * VF on which to get.
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port* invalid.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_reset_vf_stats(uint8_t port,
+ uint16_t vf_id);
+
#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 8ac1bc8..7a5d211 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -6,7 +6,9 @@ DPDK_2.0 {
DPDK_17.02 {
global:
+ rte_pmd_i40e_get_vf_stats;
rte_pmd_i40e_ping_vfs;
+ rte_pmd_i40e_reset_vf_stats;
rte_pmd_i40e_set_tx_loopback;
rte_pmd_i40e_set_vf_broadcast;
rte_pmd_i40e_set_vf_mac_addr;
--
1.9.3
^ permalink raw reply related
* [PATCH v9 26/26] doc: update doc for VFD
From: Wenzhuo Lu @ 2017-01-13 6:53 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1484290401-1404-1-git-send-email-wenzhuo.lu@intel.com>
Update the NIC doc and release note.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
doc/guides/nics/i40e.rst | 1 +
doc/guides/rel_notes/release_17_02.rst | 29 +++++++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst
index 5780268..dde59bf 100644
--- a/doc/guides/nics/i40e.rst
+++ b/doc/guides/nics/i40e.rst
@@ -64,6 +64,7 @@ Features of the I40E PMD are:
- SR-IOV VF
- Hot plug
- IEEE1588/802.1AS timestamping
+- VF Daemon (VFD) - EXPERIMENTAL
Prerequisites
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index cf11f6f..1326e6a 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -47,6 +47,35 @@ New Features
A new network PMD which supports Solarflare SFN7xxx and SFN8xxx family
of 10/40 Gbps adapters has been added.
+* **Added VF Daemon (VFD) on i40e. - EXPERIMENTAL**
+
+ This's an experimental feature to enhance the capability of DPDK PF as many
+ VF management features are not supported by kernel driver PF.
+ Some new private APIs are implemented in PMD without abstrction layer.
+ They can be used directly by some users who have the need.
+
+ The new APIs to control VFs directly from PF include,
+ 1) set VF MAC anti-spoofing
+ 2) set VF VLAN anti-spoofing
+ 3) set TX loopback
+ 4) set VF unicast promiscuous mode
+ 5) set VF multicast promiscuous mode
+ 6) set VF MTU
+ 7) get/reset VF stats
+ 8) set VF MAC address
+ 9) set VF VLAN stripping
+ 10) VF VLAN insertion
+ 12) set VF broadcast mode
+ 13) set VF VLAN tag
+ 14) set VF VLAN filter
+ VFD also includes VF to PF mailbox message management by APP.
+ When PF receives mailbox messages from VF, PF should call the callback
+ provided by APP to know if they're permitted to be processed.
+
+ As an experimental feature, please aware it can be changed even removed
+ without prior notice.
+
+
Resolved Issues
---------------
--
1.9.3
^ permalink raw reply related
* Re: [PATCH v3 3/8] crypto/armv8: add PMD optimized for ARMv8 processors
From: Jianbo Liu @ 2017-01-13 7:41 UTC (permalink / raw)
To: Zbigniew Bodek; +Cc: dev, pablo.de.lara.guarch, Declan Doherty, Jerin Jacob
In-Reply-To: <356b7ac5-0196-6181-bfc9-06e5d0d5a227@caviumnetworks.com>
On 12 January 2017 at 21:12, Zbigniew Bodek
<zbigniew.bodek@caviumnetworks.com> wrote:
> Hello Jianbo Liu,
>
> Thanks for the review. Please check my answers in-line.
>
> Kind regards
> Zbigniew
>
>
> On 06.01.2017 03:45, Jianbo Liu wrote:
>>
>> On 5 January 2017 at 01:33, <zbigniew.bodek@caviumnetworks.com> wrote:
>>>
>>> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>>>
>>> This patch introduces crypto poll mode driver
>>> using ARMv8 cryptographic extensions.
>>> CPU compatibility with this driver is detected in
>>> run-time and virtual crypto device will not be
>>> created if CPU doesn't provide:
>>> AES, SHA1, SHA2 and NEON.
>>>
>>> This PMD is optimized to provide performance boost
>>> for chained crypto operations processing,
>>> such as encryption + HMAC generation,
>>> decryption + HMAC validation. In particular,
>>> cipher only or hash only operations are
>>> not provided.
>>>
>>> The driver currently supports AES-128-CBC
>>> in combination with: SHA256 HMAC and SHA1 HMAC
>>> and relies on the external armv8_crypto library:
>>> https://github.com/caviumnetworks/armv8_crypto
>>>
>>
>> It's standalone lib. I think you should change the following line in
>> its Makefile, so not depend on DPDK.
>> "include $(RTE_SDK)/mk/rte.lib.mk"
>>
>>> This patch adds driver's code only and does
>>> not include it in the build system.
>>>
>>> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>>> ---
>>> drivers/crypto/armv8/Makefile | 73 ++
>>> drivers/crypto/armv8/rte_armv8_pmd.c | 926
>>> +++++++++++++++++++++++++
>>> drivers/crypto/armv8/rte_armv8_pmd_ops.c | 369 ++++++++++
>>> drivers/crypto/armv8/rte_armv8_pmd_private.h | 211 ++++++
>>> drivers/crypto/armv8/rte_armv8_pmd_version.map | 3 +
>>> 5 files changed, 1582 insertions(+)
>>> create mode 100644 drivers/crypto/armv8/Makefile
>>> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd.c
>>> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_ops.c
>>> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_private.h
>>> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_version.map
>>>
.....
>>> + /* Select auth algo */
>>> + switch (auth_xform->auth.algo) {
>>> + /* Cover supported hash algorithms */
>>> + case RTE_CRYPTO_AUTH_SHA256:
>>> + aalg = auth_xform->auth.algo;
>>> + sess->auth.mode = ARMV8_CRYPTO_AUTH_AS_AUTH;
>>> + break;
>>> + case RTE_CRYPTO_AUTH_SHA1_HMAC:
>>> + case RTE_CRYPTO_AUTH_SHA256_HMAC: /* Fall through */
>>> + aalg = auth_xform->auth.algo;
>>> + sess->auth.mode = ARMV8_CRYPTO_AUTH_AS_HMAC;
>>> + break;
>>> + default:
>>> + return -EINVAL;
>>> + }
>>> +
>>> + /* Verify supported key lengths and extract proper algorithm */
>>> + switch (cipher_xform->cipher.key.length << 3) {
>>> + case 128:
>>> + sess->crypto_func =
>>> + CRYPTO_GET_ALGO(order, cop, calg, aalg,
>>> 128);
>>> + sess->cipher.key_sched =
>>> + CRYPTO_GET_KEY_SCHED(cop, calg, 128);
>>> + break;
>>> + case 192:
>>> + sess->crypto_func =
>>> + CRYPTO_GET_ALGO(order, cop, calg, aalg,
>>> 192);
>>> + sess->cipher.key_sched =
>>> + CRYPTO_GET_KEY_SCHED(cop, calg, 192);
>>> + break;
>>> + case 256:
>>> + sess->crypto_func =
>>> + CRYPTO_GET_ALGO(order, cop, calg, aalg,
>>> 256);
>>> + sess->cipher.key_sched =
>>> + CRYPTO_GET_KEY_SCHED(cop, calg, 256);
>>> + break;
>>> + default:
>>> + sess->crypto_func = NULL;
>>> + sess->cipher.key_sched = NULL;
>>> + return -EINVAL;
>>> + }
>>> +
>>> + if (unlikely(sess->crypto_func == NULL)) {
>>> + /*
>>> + * If we got here that means that there must be a bug
>>
>>
>> Since AES-128-CBC is only supported in your patch. It means that
>> crypto_func could be NULL according to the switch above if
>> cipher.key.length > 128?
>
>
> Yes. Instead of checking for key lengths in a similar way that we check for
> algorithms, etc. we just fail when we don't find appropriate function. Do
> you suggest that this should be changed?
>
I mean to return error directly if length is not 128 in the above
switch, so this "if" is no necessary.
>
>>
>>> + * in the algorithms selection above. Nevertheless keep
>>> + * it here to catch bug immediately and avoid NULL
>>> pointer
>>> + * dereference in OPs processing.
>>> + */
>>> + ARMV8_CRYPTO_LOG_ERR(
>>> + "No appropriate crypto function for given
>>> parameters");
>>> + return -EINVAL;
>>> + }
>>> +
>>> + /* Set up cipher session prerequisites */
>>> + if (cipher_set_prerequisites(sess, cipher_xform) != 0)
>>> + return -EINVAL;
>>> +
>>> + /* Set up authentication session prerequisites */
>>> + if (auth_set_prerequisites(sess, auth_xform) != 0)
>>> + return -EINVAL;
>>> +
>>> + return 0;
>>> +}
>>> +
>>
>>
>> ....
>>
>>> diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c
>>> b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
>>> new file mode 100644
>>> index 0000000..2bf6475
>>> --- /dev/null
>>> +++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
>>> @@ -0,0 +1,369 @@
>>> +/*
>>> + * BSD LICENSE
>>> + *
>>> + * Copyright (C) Cavium networks Ltd. 2017.
>>> + *
>>> + * Redistribution and use in source and binary forms, with or without
>>> + * modification, are permitted provided that the following conditions
>>> + * are met:
>>> + *
>>> + * * Redistributions of source code must retain the above copyright
>>> + * notice, this list of conditions and the following disclaimer.
>>> + * * Redistributions in binary form must reproduce the above
>>> copyright
>>> + * notice, this list of conditions and the following disclaimer in
>>> + * the documentation and/or other materials provided with the
>>> + * distribution.
>>> + * * Neither the name of Cavium networks nor the names of its
>>> + * contributors may be used to endorse or promote products derived
>>> + * from this software without specific prior written permission.
>>> + *
>>> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>>> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>>> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
>>> FOR
>>> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
>>> COPYRIGHT
>>> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
>>> INCIDENTAL,
>>> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>>> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>>> USE,
>>> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
>>> ANY
>>> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
>>> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
>>> USE
>>> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
>>> DAMAGE.
>>> + */
>>> +
>>> +#include <string.h>
>>> +
>>> +#include <rte_common.h>
>>> +#include <rte_malloc.h>
>>> +#include <rte_cryptodev_pmd.h>
>>> +
>>> +#include "armv8_crypto_defs.h"
>>> +
>>> +#include "rte_armv8_pmd_private.h"
>>> +
>>> +static const struct rte_cryptodev_capabilities
>>> + armv8_crypto_pmd_capabilities[] = {
>>> + { /* SHA1 HMAC */
>>> + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
>>> + {.sym = {
>>> + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
>>> + {.auth = {
>>> + .algo =
>>> RTE_CRYPTO_AUTH_SHA1_HMAC,
>>> + .block_size = 64,
>>> + .key_size = {
>>> + .min = 16,
>>> + .max = 128,
>>> + .increment = 0
>>> + },
>>> + .digest_size = {
>>> + .min = 20,
>>> + .max = 20,
>>> + .increment = 0
>>> + },
>>> + .aad_size = { 0 }
>>> + }, }
>>> + }, }
>>> + },
>>> + { /* SHA256 HMAC */
>>> + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
>>> + {.sym = {
>>> + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
>>> + {.auth = {
>>> + .algo =
>>> RTE_CRYPTO_AUTH_SHA256_HMAC,
>>> + .block_size = 64,
>>> + .key_size = {
>>> + .min = 16,
>>> + .max = 128,
>>> + .increment = 0
>>> + },
>>> + .digest_size = {
>>> + .min = 32,
>>> + .max = 32,
>>> + .increment = 0
>>> + },
>>> + .aad_size = { 0 }
>>> + }, }
>>> + }, }
>>> + },
>>> + { /* AES CBC */
>>> + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
>>> + {.sym = {
>>> + .xform_type =
>>> RTE_CRYPTO_SYM_XFORM_CIPHER,
>>> + {.cipher = {
>>> + .algo =
>>> RTE_CRYPTO_CIPHER_AES_CBC,
>>> + .block_size = 16,
>>> + .key_size = {
>>> + .min = 16,
>>> + .max = 16,
>>> + .increment = 0
>>> + },
>>> + .iv_size = {
>>> + .min = 16,
>>> + .max = 16,
>>> + .increment = 0
>>> + }
>>> + }, }
>>> + }, }
>>> + },
>>> +
>>
>>
>> It's strange that you defined aes and hmac here, but not implemented
>> them, though their combinations are implemented.
>> Will you add later?
>
>
> We may add standalone algorithms in the future but those ops here are not
> for that purpose. I thought that since there is no chained operations
> capability we should export what we can do even though that it will work
> (mean not return error) only if the operations are chained.
> Do you have some other suggestion?
>
Nothing special. Either implement them later, or add new chained ops
(is that possible?)
BTW, can you explain what optimization you have done, so I can better
understand your asm code, thanks!
>
>>
>>> + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
>>> +};
>>> +
>>> +
^ permalink raw reply
* Re: [PATCH v3 3/8] crypto/armv8: add PMD optimized for ARMv8 processors
From: Hemant Agrawal @ 2017-01-13 7:57 UTC (permalink / raw)
To: zbigniew.bodek; +Cc: dev, pablo.de.lara.guarch, Jerin Jacob
In-Reply-To: <1483551207-18236-4-git-send-email-zbigniew.bodek@caviumnetworks.com>
On 1/4/2017 11:03 PM, zbigniew.bodek@caviumnetworks.com wrote:
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> This patch introduces crypto poll mode driver
> using ARMv8 cryptographic extensions.
> CPU compatibility with this driver is detected in
> run-time and virtual crypto device will not be
> created if CPU doesn't provide:
> AES, SHA1, SHA2 and NEON.
>
> This PMD is optimized to provide performance boost
> for chained crypto operations processing,
> such as encryption + HMAC generation,
> decryption + HMAC validation. In particular,
> cipher only or hash only operations are
> not provided.
>
> The driver currently supports AES-128-CBC
> in combination with: SHA256 HMAC and SHA1 HMAC
> and relies on the external armv8_crypto library:
> https://github.com/caviumnetworks/armv8_crypto
>
> This patch adds driver's code only and does
> not include it in the build system.
>
> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> ---
> drivers/crypto/armv8/Makefile | 73 ++
> drivers/crypto/armv8/rte_armv8_pmd.c | 926 +++++++++++++++++++++++++
> drivers/crypto/armv8/rte_armv8_pmd_ops.c | 369 ++++++++++
> drivers/crypto/armv8/rte_armv8_pmd_private.h | 211 ++++++
> drivers/crypto/armv8/rte_armv8_pmd_version.map | 3 +
> 5 files changed, 1582 insertions(+)
> create mode 100644 drivers/crypto/armv8/Makefile
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd.c
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_ops.c
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_private.h
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_version.map
>
> diff --git a/drivers/crypto/armv8/Makefile b/drivers/crypto/armv8/Makefile
> new file mode 100644
> index 0000000..dc5ea02
> --- /dev/null
> +++ b/drivers/crypto/armv8/Makefile
> @@ -0,0 +1,73 @@
> +#
> +# BSD LICENSE
> +#
> +# Copyright (C) Cavium networks Ltd. 2017.
> +#
> +# Redistribution and use in source and binary forms, with or without
> +# modification, are permitted provided that the following conditions
> +# are met:
> +#
> +# * Redistributions of source code must retain the above copyright
> +# notice, this list of conditions and the following disclaimer.
> +# * Redistributions in binary form must reproduce the above copyright
> +# notice, this list of conditions and the following disclaimer in
> +# the documentation and/or other materials provided with the
> +# distribution.
> +# * Neither the name of Cavium networks nor the names of its
> +# contributors may be used to endorse or promote products derived
> +# from this software without specific prior written permission.
> +#
> +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +#
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +ifneq ($(MAKECMDGOALS),clean)
> +ifneq ($(MAKECMDGOALS),config)
> +ifeq ($(ARMV8_CRYPTO_LIB_PATH),)
> +$(error "Please define ARMV8_CRYPTO_LIB_PATH environment variable")
> +endif
> +endif
> +endif
> +
> +# library name
> +LIB = librte_pmd_armv8.a
> +
> +# build flags
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +CFLAGS += -L$(RTE_SDK)/../openssl -I$(RTE_SDK)/../openssl/include
> +
> +# library version
> +LIBABIVER := 1
> +
> +# versioning export map
> +EXPORT_MAP := rte_armv8_pmd_version.map
> +
> +# external library dependencies
> +CFLAGS += -I$(ARMV8_CRYPTO_LIB_PATH)
> +CFLAGS += -I$(ARMV8_CRYPTO_LIB_PATH)/asm/include
> +LDLIBS += -L$(ARMV8_CRYPTO_LIB_PATH) -larmv8_crypto
> +
> +# library source files
> +SRCS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += rte_armv8_pmd.c
> +SRCS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += rte_armv8_pmd_ops.c
> +
> +# library dependencies
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += lib/librte_eal
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += lib/librte_mbuf
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += lib/librte_mempool
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += lib/librte_ring
> +DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_ARMV8_CRYPTO) += lib/librte_cryptodev
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd.c b/drivers/crypto/armv8/rte_armv8_pmd.c
> new file mode 100644
> index 0000000..39433bb
> --- /dev/null
> +++ b/drivers/crypto/armv8/rte_armv8_pmd.c
> @@ -0,0 +1,926 @@
> +/*
> + * BSD LICENSE
> + *
> + * Copyright (C) Cavium networks Ltd. 2017.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Cavium networks nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <stdbool.h>
> +
> +#include <rte_common.h>
> +#include <rte_hexdump.h>
> +#include <rte_cryptodev.h>
> +#include <rte_cryptodev_pmd.h>
> +#include <rte_vdev.h>
> +#include <rte_malloc.h>
> +#include <rte_cpuflags.h>
> +
> +#include "armv8_crypto_defs.h"
> +
> +#include "rte_armv8_pmd_private.h"
> +
> +static int cryptodev_armv8_crypto_uninit(const char *name);
> +
> +/**
> + * Pointers to the supported combined mode crypto functions are stored
> + * in the static tables. Each combined (chained) cryptographic operation
> + * can be decribed by a set of numbers:
replace "decribed" with "described"
> + * - order: order of operations (cipher, auth) or (auth, cipher)
> + * - direction: encryption or decryption
> + * - calg: cipher algorithm such as AES_CBC, AES_CTR, etc.
> + * - aalg: authentication algorithm such as SHA1, SHA256, etc.
> + * - keyl: cipher key length, for example 128, 192, 256 bits
> + *
> + * In order to quickly acquire each function pointer based on those numbers,
> + * a hierarchy of arrays is maintained. The final level, 3D array is indexed
> + * by the combined mode function parameters only (cipher algorithm,
> + * authentication algorithm and key length).
> + *
> + * This gives 3 memory accesses to obtain a function pointer instead of
> + * traversing the array manually and comparing function parameters on each loop.
> + *
> + * +--+CRYPTO_FUNC
> + * +--+ENC|
> + * +--+CA|
> + * | +--+DEC
> + * ORDER|
> + * | +--+ENC
> + * +--+AC|
> + * +--+DEC
> + *
> + */
> +
> +/**
> + * 3D array type for ARM Combined Mode crypto functions pointers.
> + * CRYPTO_CIPHER_MAX: max cipher ID number
> + * CRYPTO_AUTH_MAX: max auth ID number
> + * CRYPTO_CIPHER_KEYLEN_MAX: max key length ID number
> + */
> +typedef const crypto_func_t
> +crypto_func_tbl_t[CRYPTO_CIPHER_MAX][CRYPTO_AUTH_MAX][CRYPTO_CIPHER_KEYLEN_MAX];
> +
> +/* Evaluate to key length definition */
> +#define KEYL(keyl) (ARMV8_CRYPTO_CIPHER_KEYLEN_ ## keyl)
> +
> +/* Local aliases for supported ciphers */
> +#define CIPH_AES_CBC RTE_CRYPTO_CIPHER_AES_CBC
> +/* Local aliases for supported hashes */
> +#define AUTH_SHA1_HMAC RTE_CRYPTO_AUTH_SHA1_HMAC
> +#define AUTH_SHA256 RTE_CRYPTO_AUTH_SHA256
SHA256 you are defining both AUTH and HMAC, however for SHA1 only HMAC.
In your implementation, you seems to be only supporting HMAC.
> +#define AUTH_SHA256_HMAC RTE_CRYPTO_AUTH_SHA256_HMAC
> +
> +/**
> + * Arrays containing pointers to particular cryptographic,
> + * combined mode functions.
> + * crypto_op_ca_encrypt: cipher (encrypt), authenticate
> + * crypto_op_ca_decrypt: cipher (decrypt), authenticate
> + * crypto_op_ac_encrypt: authenticate, cipher (encrypt)
> + * crypto_op_ac_decrypt: authenticate, cipher (decrypt)
> + */
> +static const crypto_func_tbl_t
> +crypto_op_ca_encrypt = {
> + /* [cipher alg][auth alg][key length] = crypto_function, */
> + [CIPH_AES_CBC][AUTH_SHA1_HMAC][KEYL(128)] = aes128cbc_sha1_hmac,
> + [CIPH_AES_CBC][AUTH_SHA256_HMAC][KEYL(128)] = aes128cbc_sha256_hmac,
> +};
> +
do you plan to support aes192 and aes256 as well?
> +static const crypto_func_tbl_t
> +crypto_op_ca_decrypt = {
> + NULL
> +};
> +
> +static const crypto_func_tbl_t
> +crypto_op_ac_encrypt = {
> + NULL
> +};
> +
> +static const crypto_func_tbl_t
> +crypto_op_ac_decrypt = {
> + /* [cipher alg][auth alg][key length] = crypto_function, */
> + [CIPH_AES_CBC][AUTH_SHA1_HMAC][KEYL(128)] = sha1_hmac_aes128cbc_dec,
> + [CIPH_AES_CBC][AUTH_SHA256_HMAC][KEYL(128)] = sha256_hmac_aes128cbc_dec,
> +};
> +
> +/**
> + * Arrays containing pointers to particular cryptographic function sets,
> + * covering given cipher operation directions (encrypt, decrypt)
> + * for each order of cipher and authentication pairs.
> + */
> +static const crypto_func_tbl_t *
> +crypto_cipher_auth[] = {
> + &crypto_op_ca_encrypt,
> + &crypto_op_ca_decrypt,
> + NULL
> +};
> +
> +static const crypto_func_tbl_t *
> +crypto_auth_cipher[] = {
> + &crypto_op_ac_encrypt,
> + &crypto_op_ac_decrypt,
> + NULL
> +};
> +
> +/**
> + * Top level array containing pointers to particular cryptographic
> + * function sets, covering given order of chained operations.
> + * crypto_cipher_auth: cipher first, authenticate after
> + * crypto_auth_cipher: authenticate first, cipher after
> + */
> +static const crypto_func_tbl_t **
> +crypto_chain_order[] = {
> + crypto_cipher_auth,
> + crypto_auth_cipher,
> + NULL
> +};
> +
> +/**
> + * Extract particular combined mode crypto function from the 3D array.
> + */
> +#define CRYPTO_GET_ALGO(order, cop, calg, aalg, keyl) \
> +({ \
> + crypto_func_tbl_t *func_tbl = \
> + (crypto_chain_order[(order)])[(cop)]; \
> + \
> + ((*func_tbl)[(calg)][(aalg)][KEYL(keyl)]); \
> +})
> +
> +/*----------------------------------------------------------------------------*/
> +
> +/**
> + * 2D array type for ARM key schedule functions pointers.
> + * CRYPTO_CIPHER_MAX: max cipher ID number
> + * CRYPTO_CIPHER_KEYLEN_MAX: max key length ID number
> + */
> +typedef const crypto_key_sched_t
> +crypto_key_sched_tbl_t[CRYPTO_CIPHER_MAX][CRYPTO_CIPHER_KEYLEN_MAX];
> +
> +static const crypto_key_sched_tbl_t
> +crypto_key_sched_encrypt = {
> + /* [cipher alg][key length] = key_expand_func, */
> + [CIPH_AES_CBC][KEYL(128)] = aes128_key_sched_enc,
> +};
> +
> +static const crypto_key_sched_tbl_t
> +crypto_key_sched_decrypt = {
> + /* [cipher alg][key length] = key_expand_func, */
> + [CIPH_AES_CBC][KEYL(128)] = aes128_key_sched_dec,
> +};
> +
> +/**
> + * Top level array containing pointers to particular key generation
> + * function sets, covering given operation direction.
> + * crypto_key_sched_encrypt: keys for encryption
> + * crypto_key_sched_decrypt: keys for decryption
> + */
> +static const crypto_key_sched_tbl_t *
> +crypto_key_sched_dir[] = {
> + &crypto_key_sched_encrypt,
> + &crypto_key_sched_decrypt,
> + NULL
> +};
> +
> +/**
> + * Extract particular combined mode crypto function from the 3D array.
> + */
> +#define CRYPTO_GET_KEY_SCHED(cop, calg, keyl) \
> +({ \
> + crypto_key_sched_tbl_t *ks_tbl = crypto_key_sched_dir[(cop)]; \
> + \
> + ((*ks_tbl)[(calg)][KEYL(keyl)]); \
> +})
> +
> +/*----------------------------------------------------------------------------*/
> +
> +/**
> + * Global static parameter used to create a unique name for each
> + * ARMV8 crypto device.
> + */
> +static unsigned int unique_name_id;
> +
> +static inline int
> +create_unique_device_name(char *name, size_t size)
> +{
> + int ret;
> +
> + if (name == NULL)
> + return -EINVAL;
> +
> + ret = snprintf(name, size, "%s_%u", RTE_STR(CRYPTODEV_NAME_ARMV8_PMD),
> + unique_name_id++);
> + if (ret < 0)
> + return ret;
> + return 0;
> +}
> +
> +/*
> + *------------------------------------------------------------------------------
> + * Session Prepare
> + *------------------------------------------------------------------------------
> + */
> +
> +/** Get xform chain order */
> +static enum armv8_crypto_chain_order
> +armv8_crypto_get_chain_order(const struct rte_crypto_sym_xform *xform)
> +{
> +
> + /*
> + * This driver currently covers only chained operations.
> + * Ignore only cipher or only authentication operations
> + * or chains longer than 2 xform structures.
> + */
> + if (xform->next == NULL || xform->next->next != NULL)
> + return ARMV8_CRYPTO_CHAIN_NOT_SUPPORTED;
> +
> + if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
> + if (xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
> + return ARMV8_CRYPTO_CHAIN_AUTH_CIPHER;
> + }
> +
> + if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
> + if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
> + return ARMV8_CRYPTO_CHAIN_CIPHER_AUTH;
> + }
> +
> + return ARMV8_CRYPTO_CHAIN_NOT_SUPPORTED;
> +}
> +
> +static inline void
> +auth_hmac_pad_prepare(struct armv8_crypto_session *sess,
> + const struct rte_crypto_sym_xform *xform)
> +{
> + size_t i;
> +
> + /* Generate i_key_pad and o_key_pad */
> + memset(sess->auth.hmac.i_key_pad, 0, sizeof(sess->auth.hmac.i_key_pad));
> + rte_memcpy(sess->auth.hmac.i_key_pad, sess->auth.hmac.key,
> + xform->auth.key.length);
> + memset(sess->auth.hmac.o_key_pad, 0, sizeof(sess->auth.hmac.o_key_pad));
> + rte_memcpy(sess->auth.hmac.o_key_pad, sess->auth.hmac.key,
> + xform->auth.key.length);
> + /*
> + * XOR key with IPAD/OPAD values to obtain i_key_pad
> + * and o_key_pad.
> + * Byte-by-byte operation may seem to be the less efficient
> + * here but in fact it's the opposite.
> + * The result ASM code is likely operate on NEON registers
> + * (load auth key to Qx, load IPAD/OPAD to multiple
> + * elements of Qy, eor 128 bits at once).
> + */
> + for (i = 0; i < SHA_BLOCK_MAX; i++) {
> + sess->auth.hmac.i_key_pad[i] ^= HMAC_IPAD_VALUE;
> + sess->auth.hmac.o_key_pad[i] ^= HMAC_OPAD_VALUE;
> + }
> +}
> +
> +static inline int
> +auth_set_prerequisites(struct armv8_crypto_session *sess,
> + const struct rte_crypto_sym_xform *xform)
> +{
> + uint8_t partial[64] = { 0 };
> + int error;
> +
> + switch (xform->auth.algo) {
> + case RTE_CRYPTO_AUTH_SHA1_HMAC:
> + /*
> + * Generate authentication key, i_key_pad and o_key_pad.
> + */
> + /* Zero memory under key */
> + memset(sess->auth.hmac.key, 0, SHA1_AUTH_KEY_LENGTH);
> +
> + if (xform->auth.key.length > SHA1_AUTH_KEY_LENGTH) {
> + /*
> + * In case the key is longer than 160 bits
> + * the algorithm will use SHA1(key) instead.
> + */
> + error = sha1_block(NULL, xform->auth.key.data,
> + sess->auth.hmac.key, xform->auth.key.length);
> + if (error != 0)
> + return -1;
> + } else {
> + /*
> + * Now copy the given authentication key to the session
> + * key assuming that the session key is zeroed there is
> + * no need for additional zero padding if the key is
> + * shorter than SHA1_AUTH_KEY_LENGTH.
> + */
> + rte_memcpy(sess->auth.hmac.key, xform->auth.key.data,
> + xform->auth.key.length);
> + }
> +
> + /* Prepare HMAC padding: key|pattern */
> + auth_hmac_pad_prepare(sess, xform);
> + /*
> + * Calculate partial hash values for i_key_pad and o_key_pad.
> + * Will be used as initialization state for final HMAC.
> + */
> + error = sha1_block_partial(NULL, sess->auth.hmac.i_key_pad,
> + partial, SHA1_BLOCK_SIZE);
> + if (error != 0)
> + return -1;
> + memcpy(sess->auth.hmac.i_key_pad, partial, SHA1_BLOCK_SIZE);
> +
> + error = sha1_block_partial(NULL, sess->auth.hmac.o_key_pad,
> + partial, SHA1_BLOCK_SIZE);
> + if (error != 0)
> + return -1;
> + memcpy(sess->auth.hmac.o_key_pad, partial, SHA1_BLOCK_SIZE);
> +
> + break;
> + case RTE_CRYPTO_AUTH_SHA256_HMAC:
> + /*
> + * Generate authentication key, i_key_pad and o_key_pad.
> + */
> + /* Zero memory under key */
> + memset(sess->auth.hmac.key, 0, SHA256_AUTH_KEY_LENGTH);
> +
> + if (xform->auth.key.length > SHA256_AUTH_KEY_LENGTH) {
> + /*
> + * In case the key is longer than 256 bits
> + * the algorithm will use SHA256(key) instead.
> + */
> + error = sha256_block(NULL, xform->auth.key.data,
> + sess->auth.hmac.key, xform->auth.key.length);
> + if (error != 0)
> + return -1;
> + } else {
> + /*
> + * Now copy the given authentication key to the session
> + * key assuming that the session key is zeroed there is
> + * no need for additional zero padding if the key is
> + * shorter than SHA256_AUTH_KEY_LENGTH.
> + */
> + rte_memcpy(sess->auth.hmac.key, xform->auth.key.data,
> + xform->auth.key.length);
> + }
> +
> + /* Prepare HMAC padding: key|pattern */
> + auth_hmac_pad_prepare(sess, xform);
> + /*
> + * Calculate partial hash values for i_key_pad and o_key_pad.
> + * Will be used as initialization state for final HMAC.
> + */
> + error = sha256_block_partial(NULL, sess->auth.hmac.i_key_pad,
> + partial, SHA256_BLOCK_SIZE);
> + if (error != 0)
> + return -1;
> + memcpy(sess->auth.hmac.i_key_pad, partial, SHA256_BLOCK_SIZE);
> +
> + error = sha256_block_partial(NULL, sess->auth.hmac.o_key_pad,
> + partial, SHA256_BLOCK_SIZE);
> + if (error != 0)
> + return -1;
> + memcpy(sess->auth.hmac.o_key_pad, partial, SHA256_BLOCK_SIZE);
> +
> + break;
> + default:
> + break;
> + }
> +
> + return 0;
> +}
> +
> +static inline int
> +cipher_set_prerequisites(struct armv8_crypto_session *sess,
> + const struct rte_crypto_sym_xform *xform)
> +{
> + crypto_key_sched_t cipher_key_sched;
> +
> + cipher_key_sched = sess->cipher.key_sched;
> + if (likely(cipher_key_sched != NULL)) {
> + /* Set up cipher session key */
> + cipher_key_sched(sess->cipher.key.data, xform->cipher.key.data);
> + }
> +
> + return 0;
> +}
> +
> +static int
> +armv8_crypto_set_session_chained_parameters(struct armv8_crypto_session *sess,
> + const struct rte_crypto_sym_xform *cipher_xform,
> + const struct rte_crypto_sym_xform *auth_xform)
> +{
> + enum armv8_crypto_chain_order order;
> + enum armv8_crypto_cipher_operation cop;
> + enum rte_crypto_cipher_algorithm calg;
> + enum rte_crypto_auth_algorithm aalg;
> +
> + /* Validate and prepare scratch order of combined operations */
> + switch (sess->chain_order) {
> + case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH:
> + case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER:
> + order = sess->chain_order;
> + break;
> + default:
> + return -EINVAL;
> + }
> + /* Select cipher direction */
> + sess->cipher.direction = cipher_xform->cipher.op;
> + /* Select cipher key */
> + sess->cipher.key.length = cipher_xform->cipher.key.length;
> + /* Set cipher direction */
> + cop = sess->cipher.direction;
> + /* Set cipher algorithm */
> + calg = cipher_xform->cipher.algo;
> +
> + /* Select cipher algo */
> + switch (calg) {
> + /* Cover supported cipher algorithms */
> + case RTE_CRYPTO_CIPHER_AES_CBC:
> + sess->cipher.algo = calg;
> + /* IV len is always 16 bytes (block size) for AES CBC */
> + sess->cipher.iv_len = 16;
> + break;
> + default:
> + return -EINVAL;
> + }
> + /* Select auth generate/verify */
> + sess->auth.operation = auth_xform->auth.op;
> +
> + /* Select auth algo */
> + switch (auth_xform->auth.algo) {
> + /* Cover supported hash algorithms */
> + case RTE_CRYPTO_AUTH_SHA256:
> + aalg = auth_xform->auth.algo;
> + sess->auth.mode = ARMV8_CRYPTO_AUTH_AS_AUTH;
> + break;
as previously stated, are you supporting AUTH types?
> + case RTE_CRYPTO_AUTH_SHA1_HMAC:
> + case RTE_CRYPTO_AUTH_SHA256_HMAC: /* Fall through */
> + aalg = auth_xform->auth.algo;
> + sess->auth.mode = ARMV8_CRYPTO_AUTH_AS_HMAC;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + /* Verify supported key lengths and extract proper algorithm */
> + switch (cipher_xform->cipher.key.length << 3) {
> + case 128:
> + sess->crypto_func =
> + CRYPTO_GET_ALGO(order, cop, calg, aalg, 128);
> + sess->cipher.key_sched =
> + CRYPTO_GET_KEY_SCHED(cop, calg, 128);
> + break;
> + case 192:
aes192 and aes256?
> + sess->crypto_func =
> + CRYPTO_GET_ALGO(order, cop, calg, aalg, 192);
> + sess->cipher.key_sched =
> + CRYPTO_GET_KEY_SCHED(cop, calg, 192);
> + break;
> + case 256:
> + sess->crypto_func =
> + CRYPTO_GET_ALGO(order, cop, calg, aalg, 256);
> + sess->cipher.key_sched =
> + CRYPTO_GET_KEY_SCHED(cop, calg, 256);
> + break;
> + default:
> + sess->crypto_func = NULL;
> + sess->cipher.key_sched = NULL;
> + return -EINVAL;
> + }
> +
> + if (unlikely(sess->crypto_func == NULL)) {
> + /*
> + * If we got here that means that there must be a bug
> + * in the algorithms selection above. Nevertheless keep
> + * it here to catch bug immediately and avoid NULL pointer
> + * dereference in OPs processing.
> + */
> + ARMV8_CRYPTO_LOG_ERR(
> + "No appropriate crypto function for given parameters");
> + return -EINVAL;
> + }
> +
> + /* Set up cipher session prerequisites */
> + if (cipher_set_prerequisites(sess, cipher_xform) != 0)
> + return -EINVAL;
> +
> + /* Set up authentication session prerequisites */
> + if (auth_set_prerequisites(sess, auth_xform) != 0)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +/** Parse crypto xform chain and set private session parameters */
> +int
> +armv8_crypto_set_session_parameters(struct armv8_crypto_session *sess,
> + const struct rte_crypto_sym_xform *xform)
> +{
> + const struct rte_crypto_sym_xform *cipher_xform = NULL;
> + const struct rte_crypto_sym_xform *auth_xform = NULL;
> + bool is_chained_op;
> + int ret;
> +
> + /* Filter out spurious/broken requests */
> + if (xform == NULL)
> + return -EINVAL;
> +
> + sess->chain_order = armv8_crypto_get_chain_order(xform);
> + switch (sess->chain_order) {
> + case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH:
> + cipher_xform = xform;
> + auth_xform = xform->next;
> + is_chained_op = true;
> + break;
> + case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER:
> + auth_xform = xform;
> + cipher_xform = xform->next;
> + is_chained_op = true;
> + break;
> + default:
> + is_chained_op = false;
> + return -EINVAL;
> + }
> +
> + if (is_chained_op) {
> + ret = armv8_crypto_set_session_chained_parameters(sess,
> + cipher_xform, auth_xform);
> + if (unlikely(ret != 0)) {
> + ARMV8_CRYPTO_LOG_ERR(
> + "Invalid/unsupported chained (cipher/auth) parameters");
> + return -EINVAL;
> + }
> + } else {
> + ARMV8_CRYPTO_LOG_ERR("Invalid/unsupported operation");
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +/** Provide session for operation */
> +static struct armv8_crypto_session *
> +get_session(struct armv8_crypto_qp *qp, struct rte_crypto_op *op)
> +{
> + struct armv8_crypto_session *sess = NULL;
> +
> + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
> + /* get existing session */
> + if (likely(op->sym->session != NULL &&
> + op->sym->session->dev_type ==
> + RTE_CRYPTODEV_ARMV8_PMD)) {
> + sess = (struct armv8_crypto_session *)
> + op->sym->session->_private;
> + }
> + } else {
> + /* provide internal session */
> + void *_sess = NULL;
> +
> + if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) {
> + sess = (struct armv8_crypto_session *)
> + ((struct rte_cryptodev_sym_session *)_sess)
> + ->_private;
> +
> + if (unlikely(armv8_crypto_set_session_parameters(
> + sess, op->sym->xform) != 0)) {
> + rte_mempool_put(qp->sess_mp, _sess);
> + sess = NULL;
> + } else
> + op->sym->session = _sess;
> + }
> + }
> +
> + if (sess == NULL)
> + op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
> +
> + return sess;
> +}
> +
> +/*
> + *------------------------------------------------------------------------------
> + * Process Operations
> + *------------------------------------------------------------------------------
> + */
> +
> +/*----------------------------------------------------------------------------*/
> +
> +/** Process cipher operation */
> +static void
> +process_armv8_chained_op
> + (struct rte_crypto_op *op, struct armv8_crypto_session *sess,
> + struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
> +{
> + crypto_func_t crypto_func;
> + crypto_arg_t arg;
> + struct rte_mbuf *m_asrc, *m_adst;
> + uint8_t *csrc, *cdst;
> + uint8_t *adst, *asrc;
> + uint64_t clen, alen __rte_unused;
> + int error;
> +
> + clen = op->sym->cipher.data.length;
> + alen = op->sym->auth.data.length;
> +
> + csrc = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
> + op->sym->cipher.data.offset);
> + cdst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
> + op->sym->cipher.data.offset);
> +
> + switch (sess->chain_order) {
> + case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH:
> + m_asrc = m_adst = mbuf_dst;
> + break;
> + case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER:
> + m_asrc = mbuf_src;
> + m_adst = mbuf_dst;
> + break;
> + default:
> + op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> + return;
> + }
> + asrc = rte_pktmbuf_mtod_offset(m_asrc, uint8_t *,
> + op->sym->auth.data.offset);
> +
> + switch (sess->auth.mode) {
> + case ARMV8_CRYPTO_AUTH_AS_AUTH:
> + /* Nothing to do here, just verify correct option */
> + break;
> + case ARMV8_CRYPTO_AUTH_AS_HMAC:
> + arg.digest.hmac.key = sess->auth.hmac.key;
> + arg.digest.hmac.i_key_pad = sess->auth.hmac.i_key_pad;
> + arg.digest.hmac.o_key_pad = sess->auth.hmac.o_key_pad;
> + break;
> + default:
> + op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> + return;
> + }
> +
> + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_GENERATE) {
> + adst = op->sym->auth.digest.data;
> + if (adst == NULL) {
> + adst = rte_pktmbuf_mtod_offset(m_adst,
> + uint8_t *,
> + op->sym->auth.data.offset +
> + op->sym->auth.data.length);
> + }
> + } else {
> + adst = (uint8_t *)rte_pktmbuf_append(m_asrc,
> + op->sym->auth.digest.length);
> + }
> +
> + if (unlikely(op->sym->cipher.iv.length != sess->cipher.iv_len)) {
> + op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> + return;
> + }
> +
> + arg.cipher.iv = op->sym->cipher.iv.data;
> + arg.cipher.key = sess->cipher.key.data;
> + /* Acquire combined mode function */
> + crypto_func = sess->crypto_func;
> + ARMV8_CRYPTO_ASSERT(crypto_func != NULL);
> + error = crypto_func(csrc, cdst, clen, asrc, adst, alen, &arg);
> + if (error != 0) {
> + op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> + return;
> + }
> +
> + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
> + if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
> + if (memcmp(adst, op->sym->auth.digest.data,
> + op->sym->auth.digest.length) != 0) {
> + op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
> + }
> + /* Trim area used for digest from mbuf. */
> + rte_pktmbuf_trim(m_asrc,
> + op->sym->auth.digest.length);
> + }
> +}
> +
> +/** Process crypto operation for mbuf */
> +static int
> +process_op(const struct armv8_crypto_qp *qp, struct rte_crypto_op *op,
> + struct armv8_crypto_session *sess)
> +{
> + struct rte_mbuf *msrc, *mdst;
> + int retval;
> +
> + msrc = op->sym->m_src;
> + mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
> +
> + op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
> +
> + switch (sess->chain_order) {
> + case ARMV8_CRYPTO_CHAIN_CIPHER_AUTH:
> + case ARMV8_CRYPTO_CHAIN_AUTH_CIPHER: /* Fall through */
> + process_armv8_chained_op(op, sess, msrc, mdst);
> + break;
> + default:
> + op->status = RTE_CRYPTO_OP_STATUS_ERROR;
> + break;
> + }
> +
> + /* Free session if a session-less crypto op */
> + if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_SESSIONLESS) {
> + memset(sess, 0, sizeof(struct armv8_crypto_session));
> + rte_mempool_put(qp->sess_mp, op->sym->session);
> + op->sym->session = NULL;
> + }
> +
> + if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
> + op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
> +
> + if (op->status != RTE_CRYPTO_OP_STATUS_ERROR)
> + retval = rte_ring_enqueue(qp->processed_ops, (void *)op);
> + else
> + retval = -1;
> +
> + return retval;
> +}
> +
> +/*
> + *------------------------------------------------------------------------------
> + * PMD Framework
> + *------------------------------------------------------------------------------
> + */
> +
> +/** Enqueue burst */
> +static uint16_t
> +armv8_crypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
> + uint16_t nb_ops)
> +{
> + struct armv8_crypto_session *sess;
> + struct armv8_crypto_qp *qp = queue_pair;
> + int i, retval;
> +
> + for (i = 0; i < nb_ops; i++) {
> + sess = get_session(qp, ops[i]);
> + if (unlikely(sess == NULL))
> + goto enqueue_err;
> +
> + retval = process_op(qp, ops[i], sess);
> + if (unlikely(retval < 0))
> + goto enqueue_err;
> + }
> +
> + qp->stats.enqueued_count += i;
> + return i;
> +
> +enqueue_err:
> + if (ops[i] != NULL)
> + ops[i]->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
> +
> + qp->stats.enqueue_err_count++;
> + return i;
> +}
> +
> +/** Dequeue burst */
> +static uint16_t
> +armv8_crypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
> + uint16_t nb_ops)
> +{
> + struct armv8_crypto_qp *qp = queue_pair;
> +
> + unsigned int nb_dequeued = 0;
> +
> + nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops,
> + (void **)ops, nb_ops);
> + qp->stats.dequeued_count += nb_dequeued;
> +
> + return nb_dequeued;
> +}
> +
> +/** Create ARMv8 crypto device */
> +static int
> +cryptodev_armv8_crypto_create(const char *name,
> + struct rte_crypto_vdev_init_params *init_params)
> +{
> + struct rte_cryptodev *dev;
> + char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
> + struct armv8_crypto_private *internals;
> +
> + /* Check CPU for support for AES instruction set */
> + if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_AES)) {
> + ARMV8_CRYPTO_LOG_ERR(
> + "AES instructions not supported by CPU");
> + return -EFAULT;
> + }
> +
> + /* Check CPU for support for SHA instruction set */
> + if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_SHA1) ||
> + !rte_cpu_get_flag_enabled(RTE_CPUFLAG_SHA2)) {
> + ARMV8_CRYPTO_LOG_ERR(
> + "SHA1/SHA2 instructions not supported by CPU");
> + return -EFAULT;
> + }
> +
> + /* Check CPU for support for Advance SIMD instruction set */
> + if (!rte_cpu_get_flag_enabled(RTE_CPUFLAG_NEON)) {
> + ARMV8_CRYPTO_LOG_ERR(
> + "Advanced SIMD instructions not supported by CPU");
> + return -EFAULT;
> + }
> +
> + /* create a unique device name */
> + if (create_unique_device_name(crypto_dev_name,
> + RTE_CRYPTODEV_NAME_MAX_LEN) != 0) {
> + ARMV8_CRYPTO_LOG_ERR("failed to create unique cryptodev name");
> + return -EINVAL;
> + }
> +
> + dev = rte_cryptodev_pmd_virtual_dev_init(crypto_dev_name,
> + sizeof(struct armv8_crypto_private),
> + init_params->socket_id);
> + if (dev == NULL) {
> + ARMV8_CRYPTO_LOG_ERR("failed to create cryptodev vdev");
> + goto init_error;
> + }
> +
> + dev->dev_type = RTE_CRYPTODEV_ARMV8_PMD;
> + dev->dev_ops = rte_armv8_crypto_pmd_ops;
> +
> + /* register rx/tx burst functions for data path */
> + dev->dequeue_burst = armv8_crypto_pmd_dequeue_burst;
> + dev->enqueue_burst = armv8_crypto_pmd_enqueue_burst;
> +
> + dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
> + RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING;
> +
> + /* Set vector instructions mode supported */
> + internals = dev->data->dev_private;
> +
> + internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
> + internals->max_nb_sessions = init_params->max_nb_sessions;
> +
> + return 0;
> +
> +init_error:
> + ARMV8_CRYPTO_LOG_ERR(
> + "driver %s: cryptodev_armv8_crypto_create failed", name);
> +
> + cryptodev_armv8_crypto_uninit(crypto_dev_name);
> + return -EFAULT;
> +}
> +
> +/** Initialise ARMv8 crypto device */
> +static int
> +cryptodev_armv8_crypto_init(const char *name,
> + const char *input_args)
> +{
> + struct rte_crypto_vdev_init_params init_params = {
> + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS,
> + RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS,
> + rte_socket_id()
> + };
> +
> + rte_cryptodev_parse_vdev_init_params(&init_params, input_args);
> +
> + RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name,
> + init_params.socket_id);
> + RTE_LOG(INFO, PMD, " Max number of queue pairs = %d\n",
> + init_params.max_nb_queue_pairs);
> + RTE_LOG(INFO, PMD, " Max number of sessions = %d\n",
> + init_params.max_nb_sessions);
> +
> + return cryptodev_armv8_crypto_create(name, &init_params);
> +}
> +
> +/** Uninitialise ARMv8 crypto device */
> +static int
> +cryptodev_armv8_crypto_uninit(const char *name)
> +{
> + if (name == NULL)
> + return -EINVAL;
> +
> + RTE_LOG(INFO, PMD,
> + "Closing ARMv8 crypto device %s on numa socket %u\n",
> + name, rte_socket_id());
> +
> + return 0;
> +}
> +
> +static struct rte_vdev_driver armv8_crypto_drv = {
> + .probe = cryptodev_armv8_crypto_init,
> + .remove = cryptodev_armv8_crypto_uninit
> +};
> +
> +RTE_PMD_REGISTER_VDEV(CRYPTODEV_NAME_ARMV8_PMD, armv8_crypto_drv);
> +RTE_PMD_REGISTER_ALIAS(CRYPTODEV_NAME_ARMV8_PMD, cryptodev_armv8_pmd);
> +RTE_PMD_REGISTER_PARAM_STRING(CRYPTODEV_NAME_ARMV8_PMD,
> + "max_nb_queue_pairs=<int> "
> + "max_nb_sessions=<int> "
> + "socket_id=<int>");
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd_ops.c b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
> new file mode 100644
> index 0000000..2bf6475
> --- /dev/null
> +++ b/drivers/crypto/armv8/rte_armv8_pmd_ops.c
> @@ -0,0 +1,369 @@
> +/*
> + * BSD LICENSE
> + *
> + * Copyright (C) Cavium networks Ltd. 2017.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Cavium networks nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include <string.h>
> +
> +#include <rte_common.h>
> +#include <rte_malloc.h>
> +#include <rte_cryptodev_pmd.h>
> +
> +#include "armv8_crypto_defs.h"
> +
> +#include "rte_armv8_pmd_private.h"
> +
> +static const struct rte_cryptodev_capabilities
> + armv8_crypto_pmd_capabilities[] = {
> + { /* SHA1 HMAC */
> + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
> + {.sym = {
> + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
> + {.auth = {
> + .algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
> + .block_size = 64,
> + .key_size = {
> + .min = 16,
> + .max = 128,
> + .increment = 0
> + },
> + .digest_size = {
> + .min = 20,
> + .max = 20,
> + .increment = 0
> + },
> + .aad_size = { 0 }
> + }, }
> + }, }
> + },
> + { /* SHA256 HMAC */
> + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
> + {.sym = {
> + .xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
> + {.auth = {
> + .algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
> + .block_size = 64,
> + .key_size = {
> + .min = 16,
> + .max = 128,
> + .increment = 0
> + },
> + .digest_size = {
> + .min = 32,
> + .max = 32,
> + .increment = 0
> + },
> + .aad_size = { 0 }
> + }, }
> + }, }
> + },
> + { /* AES CBC */
> + .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
> + {.sym = {
> + .xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
> + {.cipher = {
> + .algo = RTE_CRYPTO_CIPHER_AES_CBC,
> + .block_size = 16,
> + .key_size = {
> + .min = 16,
> + .max = 16,
do you plan max = 32 ?
> + .increment = 0
> + },
> + .iv_size = {
> + .min = 16,
> + .max = 16,
> + .increment = 0
> + }
> + }, }
> + }, }
> + },
> +
> + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
> +};
> +
> +
> +/** Configure device */
> +static int
> +armv8_crypto_pmd_config(__rte_unused struct rte_cryptodev *dev)
> +{
> + return 0;
> +}
> +
> +/** Start device */
> +static int
> +armv8_crypto_pmd_start(__rte_unused struct rte_cryptodev *dev)
> +{
> + return 0;
> +}
> +
> +/** Stop device */
> +static void
> +armv8_crypto_pmd_stop(__rte_unused struct rte_cryptodev *dev)
> +{
> +}
> +
> +/** Close device */
> +static int
> +armv8_crypto_pmd_close(__rte_unused struct rte_cryptodev *dev)
> +{
> + return 0;
> +}
> +
> +
> +/** Get device statistics */
> +static void
> +armv8_crypto_pmd_stats_get(struct rte_cryptodev *dev,
> + struct rte_cryptodev_stats *stats)
> +{
> + int qp_id;
> +
> + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
> + struct armv8_crypto_qp *qp = dev->data->queue_pairs[qp_id];
> +
> + stats->enqueued_count += qp->stats.enqueued_count;
> + stats->dequeued_count += qp->stats.dequeued_count;
> +
> + stats->enqueue_err_count += qp->stats.enqueue_err_count;
> + stats->dequeue_err_count += qp->stats.dequeue_err_count;
> + }
> +}
> +
> +/** Reset device statistics */
> +static void
> +armv8_crypto_pmd_stats_reset(struct rte_cryptodev *dev)
> +{
> + int qp_id;
> +
> + for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
> + struct armv8_crypto_qp *qp = dev->data->queue_pairs[qp_id];
> +
> + memset(&qp->stats, 0, sizeof(qp->stats));
> + }
> +}
> +
> +
> +/** Get device info */
> +static void
> +armv8_crypto_pmd_info_get(struct rte_cryptodev *dev,
> + struct rte_cryptodev_info *dev_info)
> +{
> + struct armv8_crypto_private *internals = dev->data->dev_private;
> +
> + if (dev_info != NULL) {
> + dev_info->dev_type = dev->dev_type;
> + dev_info->feature_flags = dev->feature_flags;
> + dev_info->capabilities = armv8_crypto_pmd_capabilities;
> + dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
> + dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
> + }
> +}
> +
> +/** Release queue pair */
> +static int
> +armv8_crypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
> +{
> +
> + if (dev->data->queue_pairs[qp_id] != NULL) {
> + rte_free(dev->data->queue_pairs[qp_id]);
> + dev->data->queue_pairs[qp_id] = NULL;
> + }
> +
> + return 0;
> +}
> +
> +/** set a unique name for the queue pair based on it's name, dev_id and qp_id */
> +static int
> +armv8_crypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev,
> + struct armv8_crypto_qp *qp)
> +{
> + unsigned int n;
> +
> + n = snprintf(qp->name, sizeof(qp->name), "armv8_crypto_pmd_%u_qp_%u",
> + dev->data->dev_id, qp->id);
> +
> + if (n > sizeof(qp->name))
> + return -1;
> +
> + return 0;
> +}
> +
> +
> +/** Create a ring to place processed operations on */
> +static struct rte_ring *
> +armv8_crypto_pmd_qp_create_processed_ops_ring(struct armv8_crypto_qp *qp,
> + unsigned int ring_size, int socket_id)
> +{
> + struct rte_ring *r;
> +
> + r = rte_ring_lookup(qp->name);
> + if (r) {
> + if (r->prod.size >= ring_size) {
> + ARMV8_CRYPTO_LOG_INFO(
> + "Reusing existing ring %s for processed ops",
> + qp->name);
> + return r;
> + }
> +
> + ARMV8_CRYPTO_LOG_ERR(
> + "Unable to reuse existing ring %s for processed ops",
> + qp->name);
> + return NULL;
> + }
> +
> + return rte_ring_create(qp->name, ring_size, socket_id,
> + RING_F_SP_ENQ | RING_F_SC_DEQ);
> +}
> +
> +
> +/** Setup a queue pair */
> +static int
> +armv8_crypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
> + const struct rte_cryptodev_qp_conf *qp_conf,
> + int socket_id)
> +{
> + struct armv8_crypto_qp *qp = NULL;
> +
> + /* Free memory prior to re-allocation if needed. */
> + if (dev->data->queue_pairs[qp_id] != NULL)
> + armv8_crypto_pmd_qp_release(dev, qp_id);
> +
> + /* Allocate the queue pair data structure. */
> + qp = rte_zmalloc_socket("ARMv8 PMD Queue Pair", sizeof(*qp),
> + RTE_CACHE_LINE_SIZE, socket_id);
> + if (qp == NULL)
> + return -ENOMEM;
> +
> + qp->id = qp_id;
> + dev->data->queue_pairs[qp_id] = qp;
> +
> + if (armv8_crypto_pmd_qp_set_unique_name(dev, qp) != 0)
> + goto qp_setup_cleanup;
> +
> + qp->processed_ops = armv8_crypto_pmd_qp_create_processed_ops_ring(qp,
> + qp_conf->nb_descriptors, socket_id);
> + if (qp->processed_ops == NULL)
> + goto qp_setup_cleanup;
> +
> + qp->sess_mp = dev->data->session_pool;
> +
> + memset(&qp->stats, 0, sizeof(qp->stats));
> +
> + return 0;
> +
> +qp_setup_cleanup:
> + if (qp)
> + rte_free(qp);
> +
> + return -1;
> +}
> +
> +/** Start queue pair */
> +static int
> +armv8_crypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
> + __rte_unused uint16_t queue_pair_id)
> +{
> + return -ENOTSUP;
> +}
> +
> +/** Stop queue pair */
> +static int
> +armv8_crypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
> + __rte_unused uint16_t queue_pair_id)
> +{
> + return -ENOTSUP;
> +}
> +
> +/** Return the number of allocated queue pairs */
> +static uint32_t
> +armv8_crypto_pmd_qp_count(struct rte_cryptodev *dev)
> +{
> + return dev->data->nb_queue_pairs;
> +}
> +
> +/** Returns the size of the session structure */
> +static unsigned
> +armv8_crypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused)
> +{
> + return sizeof(struct armv8_crypto_session);
> +}
> +
> +/** Configure the session from a crypto xform chain */
> +static void *
> +armv8_crypto_pmd_session_configure(struct rte_cryptodev *dev __rte_unused,
> + struct rte_crypto_sym_xform *xform, void *sess)
> +{
> + if (unlikely(sess == NULL)) {
> + ARMV8_CRYPTO_LOG_ERR("invalid session struct");
> + return NULL;
> + }
> +
> + if (armv8_crypto_set_session_parameters(
> + sess, xform) != 0) {
> + ARMV8_CRYPTO_LOG_ERR("failed configure session parameters");
> + return NULL;
> + }
> +
> + return sess;
> +}
> +
> +/** Clear the memory of session so it doesn't leave key material behind */
> +static void
> +armv8_crypto_pmd_session_clear(struct rte_cryptodev *dev __rte_unused,
> + void *sess)
> +{
> +
> + /* Zero out the whole structure */
> + if (sess)
> + memset(sess, 0, sizeof(struct armv8_crypto_session));
> +}
> +
> +struct rte_cryptodev_ops armv8_crypto_pmd_ops = {
> + .dev_configure = armv8_crypto_pmd_config,
> + .dev_start = armv8_crypto_pmd_start,
> + .dev_stop = armv8_crypto_pmd_stop,
> + .dev_close = armv8_crypto_pmd_close,
> +
> + .stats_get = armv8_crypto_pmd_stats_get,
> + .stats_reset = armv8_crypto_pmd_stats_reset,
> +
> + .dev_infos_get = armv8_crypto_pmd_info_get,
> +
> + .queue_pair_setup = armv8_crypto_pmd_qp_setup,
> + .queue_pair_release = armv8_crypto_pmd_qp_release,
> + .queue_pair_start = armv8_crypto_pmd_qp_start,
> + .queue_pair_stop = armv8_crypto_pmd_qp_stop,
> + .queue_pair_count = armv8_crypto_pmd_qp_count,
> +
> + .session_get_size = armv8_crypto_pmd_session_get_size,
> + .session_configure = armv8_crypto_pmd_session_configure,
> + .session_clear = armv8_crypto_pmd_session_clear
> +};
> +
> +struct rte_cryptodev_ops *rte_armv8_crypto_pmd_ops = &armv8_crypto_pmd_ops;
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd_private.h b/drivers/crypto/armv8/rte_armv8_pmd_private.h
> new file mode 100644
> index 0000000..fe46cde
> --- /dev/null
> +++ b/drivers/crypto/armv8/rte_armv8_pmd_private.h
> @@ -0,0 +1,211 @@
> +/*
> + * BSD LICENSE
> + *
> + * Copyright (C) Cavium networks Ltd. 2017.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in
> + * the documentation and/or other materials provided with the
> + * distribution.
> + * * Neither the name of Cavium networks nor the names of its
> + * contributors may be used to endorse or promote products derived
> + * from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef _RTE_ARMV8_PMD_PRIVATE_H_
> +#define _RTE_ARMV8_PMD_PRIVATE_H_
> +
> +#define ARMV8_CRYPTO_LOG_ERR(fmt, args...) \
> + RTE_LOG(ERR, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \
> + RTE_STR(CRYPTODEV_NAME_ARMV8_CRYPTO_PMD), \
> + __func__, __LINE__, ## args)
> +
> +#ifdef RTE_LIBRTE_ARMV8_CRYPTO_DEBUG
> +#define ARMV8_CRYPTO_LOG_INFO(fmt, args...) \
> + RTE_LOG(INFO, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \
> + RTE_STR(CRYPTODEV_NAME_ARMV8_CRYPTO_PMD), \
> + __func__, __LINE__, ## args)
> +
> +#define ARMV8_CRYPTO_LOG_DBG(fmt, args...) \
> + RTE_LOG(DEBUG, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \
> + RTE_STR(CRYPTODEV_NAME_ARMV8_CRYPTO_PMD), \
> + __func__, __LINE__, ## args)
> +
> +#define ARMV8_CRYPTO_ASSERT(con) \
> +do { \
> + if (!(con)) { \
> + rte_panic("%s(): " \
> + con "condition failed, line %u", __func__); \
> + } \
> +} while (0)
> +
> +#else
> +#define ARMV8_CRYPTO_LOG_INFO(fmt, args...)
> +#define ARMV8_CRYPTO_LOG_DBG(fmt, args...)
> +#define ARMV8_CRYPTO_ASSERT(con)
> +#endif
> +
> +#define NBBY 8 /* Number of bits in a byte */
is it being used somewhere?
> +#define BYTE_LENGTH(x) ((x) / 8) /* Number of bytes in x (roun down) */
"round down" instead of "roun down"
> +
> +/** ARMv8 operation order mode enumerator */
> +enum armv8_crypto_chain_order {
> + ARMV8_CRYPTO_CHAIN_CIPHER_AUTH,
> + ARMV8_CRYPTO_CHAIN_AUTH_CIPHER,
> + ARMV8_CRYPTO_CHAIN_NOT_SUPPORTED,
> + ARMV8_CRYPTO_CHAIN_LIST_END = ARMV8_CRYPTO_CHAIN_NOT_SUPPORTED
> +};
> +
> +/** ARMv8 cipher operation enumerator */
> +enum armv8_crypto_cipher_operation {
> + ARMV8_CRYPTO_CIPHER_OP_ENCRYPT = RTE_CRYPTO_CIPHER_OP_ENCRYPT,
> + ARMV8_CRYPTO_CIPHER_OP_DECRYPT = RTE_CRYPTO_CIPHER_OP_DECRYPT,
> + ARMV8_CRYPTO_CIPHER_OP_NOT_SUPPORTED,
> + ARMV8_CRYPTO_CIPHER_OP_LIST_END = ARMV8_CRYPTO_CIPHER_OP_NOT_SUPPORTED
> +};
> +
> +enum armv8_crypto_cipher_keylen {
> + ARMV8_CRYPTO_CIPHER_KEYLEN_128,
> + ARMV8_CRYPTO_CIPHER_KEYLEN_192,
> + ARMV8_CRYPTO_CIPHER_KEYLEN_256,
> + ARMV8_CRYPTO_CIPHER_KEYLEN_NOT_SUPPORTED,
> + ARMV8_CRYPTO_CIPHER_KEYLEN_LIST_END =
> + ARMV8_CRYPTO_CIPHER_KEYLEN_NOT_SUPPORTED
> +};
> +
> +/** ARMv8 auth mode enumerator */
> +enum armv8_crypto_auth_mode {
> + ARMV8_CRYPTO_AUTH_AS_AUTH,
> + ARMV8_CRYPTO_AUTH_AS_HMAC,
> + ARMV8_CRYPTO_AUTH_AS_CIPHER,
> + ARMV8_CRYPTO_AUTH_NOT_SUPPORTED,
> + ARMV8_CRYPTO_AUTH_LIST_END = ARMV8_CRYPTO_AUTH_NOT_SUPPORTED
> +};
> +
> +#define CRYPTO_ORDER_MAX ARMV8_CRYPTO_CHAIN_LIST_END
> +#define CRYPTO_CIPHER_OP_MAX ARMV8_CRYPTO_CIPHER_OP_LIST_END
> +#define CRYPTO_CIPHER_KEYLEN_MAX ARMV8_CRYPTO_CIPHER_KEYLEN_LIST_END
> +#define CRYPTO_CIPHER_MAX RTE_CRYPTO_CIPHER_LIST_END
> +#define CRYPTO_AUTH_MAX RTE_CRYPTO_AUTH_LIST_END
> +
> +#define HMAC_IPAD_VALUE (0x36)
> +#define HMAC_OPAD_VALUE (0x5C)
> +
> +#define SHA256_AUTH_KEY_LENGTH (BYTE_LENGTH(256))
> +#define SHA256_BLOCK_SIZE (BYTE_LENGTH(512))
> +
> +#define SHA1_AUTH_KEY_LENGTH (BYTE_LENGTH(160))
> +#define SHA1_BLOCK_SIZE (BYTE_LENGTH(512))
> +
> +#define SHA_AUTH_KEY_MAX SHA256_AUTH_KEY_LENGTH
> +#define SHA_BLOCK_MAX SHA256_BLOCK_SIZE
> +
> +typedef int (*crypto_func_t)(uint8_t *, uint8_t *, uint64_t,
> + uint8_t *, uint8_t *, uint64_t,
> + crypto_arg_t *);
> +
> +typedef void (*crypto_key_sched_t)(uint8_t *, const uint8_t *);
> +
> +/** private data structure for each ARMv8 crypto device */
> +struct armv8_crypto_private {
> + unsigned int max_nb_qpairs;
> + /**< Max number of queue pairs */
> + unsigned int max_nb_sessions;
> + /**< Max number of sessions */
> +};
> +
> +/** ARMv8 crypto queue pair */
> +struct armv8_crypto_qp {
> + uint16_t id;
> + /**< Queue Pair Identifier */
> + char name[RTE_CRYPTODEV_NAME_LEN];
> + /**< Unique Queue Pair Name */
> + struct rte_ring *processed_ops;
> + /**< Ring for placing process packets */
> + struct rte_mempool *sess_mp;
> + /**< Session Mempool */
> + struct rte_cryptodev_stats stats;
> + /**< Queue pair statistics */
> +} __rte_cache_aligned;
> +
> +/** ARMv8 crypto private session structure */
> +struct armv8_crypto_session {
> + enum armv8_crypto_chain_order chain_order;
> + /**< chain order mode */
> + crypto_func_t crypto_func;
> + /**< cryptographic function to use for this session */
> +
> + /** Cipher Parameters */
> + struct {
> + enum rte_crypto_cipher_operation direction;
> + /**< cipher operation direction */
> + enum rte_crypto_cipher_algorithm algo;
> + /**< cipher algorithm */
> + int iv_len;
> + /**< IV length */
> +
> + struct {
> + uint8_t data[256];
> + /**< key data */
> + size_t length;
> + /**< key length in bytes */
> + } key;
> +
> + crypto_key_sched_t key_sched;
> + /**< Key schedule function */
> + } cipher;
> +
> + /** Authentication Parameters */
> + struct {
> + enum rte_crypto_auth_operation operation;
> + /**< auth operation generate or verify */
> + enum armv8_crypto_auth_mode mode;
> + /**< auth operation mode */
> +
> + union {
> + struct {
> + /* Add data if needed */
> + } auth;
> +
> + struct {
> + uint8_t i_key_pad[SHA_BLOCK_MAX]
> + __rte_cache_aligned;
> + /**< inner pad (max supported block length) */
> + uint8_t o_key_pad[SHA_BLOCK_MAX]
> + __rte_cache_aligned;
> + /**< outer pad (max supported block length) */
> + uint8_t key[SHA_AUTH_KEY_MAX];
> + /**< HMAC key (max supported length)*/
> + } hmac;
> + };
> + } auth;
> +
> +} __rte_cache_aligned;
> +
> +/** Set and validate ARMv8 crypto session parameters */
> +extern int armv8_crypto_set_session_parameters(
> + struct armv8_crypto_session *sess,
> + const struct rte_crypto_sym_xform *xform);
> +
> +/** device specific operations function pointer structure */
> +extern struct rte_cryptodev_ops *rte_armv8_crypto_pmd_ops;
> +
> +#endif /* _RTE_ARMV8_PMD_PRIVATE_H_ */
> diff --git a/drivers/crypto/armv8/rte_armv8_pmd_version.map b/drivers/crypto/armv8/rte_armv8_pmd_version.map
> new file mode 100644
> index 0000000..1f84b68
> --- /dev/null
> +++ b/drivers/crypto/armv8/rte_armv8_pmd_version.map
> @@ -0,0 +1,3 @@
> +DPDK_17.02 {
> + local: *;
> +};
>
^ permalink raw reply
* Re: [PATCH v3 0/8] Add crypto PMD optimized for ARMv8
From: Hemant Agrawal @ 2017-01-13 8:07 UTC (permalink / raw)
To: zbigniew.bodek, dev; +Cc: pablo.de.lara.guarch, declan.doherty, jerin.jacob
In-Reply-To: <1483551207-18236-1-git-send-email-zbigniew.bodek@caviumnetworks.com>
On 1/4/2017 11:03 PM, zbigniew.bodek@caviumnetworks.com wrote:
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> Introduce crypto poll mode driver using ARMv8
> cryptographic extensions. This PMD is optimized
> to provide performance boost for chained
> crypto operations processing, such as:
> * encryption + HMAC generation
> * decryption + HMAC validation.
> In particular, cipher only or hash only
> operations are not provided.
Do you have a plan to add the crypto only, auth/hash only support into
this driver?
Also, do you plan to add additional cases w.r.t supported by other
crypto driver?
> Performance gain can be observed in tests
> against OpenSSL PMD which also uses ARM
> crypto extensions for packets processing.
>
> Exemplary crypto performance tests comparison:
>
> cipher_hash. cipher algo: AES_CBC
> auth algo: SHA1_HMAC cipher key size=16.
> burst_size: 64 ops
>
> ARMv8 PMD improvement over OpenSSL PMD
> (Optimized for ARMv8 cipher only and hash
> only cases):
>
> Buffer
> Size(B) OPS(M) Throughput(Gbps)
> 64 729 % 742 %
> 128 577 % 592 %
> 256 483 % 476 %
> 512 336 % 351 %
> 768 300 % 286 %
> 1024 263 % 250 %
> 1280 225 % 229 %
> 1536 214 % 213 %
> 1792 186 % 203 %
> 2048 200 % 193 %
>
> The driver currently supports AES-128-CBC
> in combination with: SHA256 HMAC and SHA1 HMAC.
> The core crypto functionality of this driver is
> provided by the external armv8_crypto library
> that can be downloaded from the Cavium repository:
> https://github.com/caviumnetworks/armv8_crypto
>
> CPU compatibility with this virtual device
> is detected in run-time and virtual crypto
> device will not be created if CPU doesn't
> provide AES, SHA1, SHA2 and NEON.
>
> The functionality and performance of this
> code can be tested using generic test application
> with the following commands:
> * cryptodev_sw_armv8_autotest
> * cryptodev_sw_armv8_perftest
> New test vectors and cases have been added
> to the general pool. In particular SHA1 and
> SHA256 HMAC for short cases were introduced.
> This is because low-level ARM assembly code
> is using different code paths for long and
> short data sets, so in order to test the
> mentioned driver correctly, two different
> data sets need to be provided.
>
> ---
> v3:
> * Addressed review remarks
> * Moved low-level assembly code to the external library
> * Removed SHA256 MAC cases
> * Various fixes: interface to the library, digest destination
> and source address interpreting, missing mbuf manipulations.
>
> v2:
> * Fixed checkpatch warnings
> * Divide patches into smaller logical parts
>
> Zbigniew Bodek (8):
> mk: fix build of assembly files for ARM64
> lib: add cryptodev type for the upcoming ARMv8 PMD
> crypto/armv8: add PMD optimized for ARMv8 processors
> mk/crypto/armv8: add PMD to the build system
> doc/armv8: update documentation about crypto PMD
> crypto/armv8: enable ARMv8 PMD in the configuration
> crypto/armv8: update MAINTAINERS entry for ARMv8 crypto
> app/test: add ARMv8 crypto tests and test vectors
>
> MAINTAINERS | 6 +
> app/test/test_cryptodev.c | 63 ++
> app/test/test_cryptodev_aes_test_vectors.h | 144 +++-
> app/test/test_cryptodev_blockcipher.c | 4 +
> app/test/test_cryptodev_blockcipher.h | 1 +
> app/test/test_cryptodev_perf.c | 480 +++++++++++++
> config/common_base | 6 +
> doc/guides/cryptodevs/armv8.rst | 96 +++
> doc/guides/cryptodevs/index.rst | 1 +
> doc/guides/rel_notes/release_17_02.rst | 5 +
> drivers/crypto/Makefile | 1 +
> drivers/crypto/armv8/Makefile | 73 ++
> drivers/crypto/armv8/rte_armv8_pmd.c | 926 +++++++++++++++++++++++++
> drivers/crypto/armv8/rte_armv8_pmd_ops.c | 369 ++++++++++
> drivers/crypto/armv8/rte_armv8_pmd_private.h | 211 ++++++
> drivers/crypto/armv8/rte_armv8_pmd_version.map | 3 +
> lib/librte_cryptodev/rte_cryptodev.h | 3 +
> mk/arch/arm64/rte.vars.mk | 1 -
> mk/rte.app.mk | 2 +
> mk/toolchain/gcc/rte.vars.mk | 6 +-
> 20 files changed, 2390 insertions(+), 11 deletions(-)
> create mode 100644 doc/guides/cryptodevs/armv8.rst
> create mode 100644 drivers/crypto/armv8/Makefile
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd.c
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_ops.c
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_private.h
> create mode 100644 drivers/crypto/armv8/rte_armv8_pmd_version.map
>
^ permalink raw reply
* Re: [PATCH v3 1/8] mk: fix build of assembly files for ARM64
From: Hemant Agrawal @ 2017-01-13 8:13 UTC (permalink / raw)
To: zbigniew.bodek, dev; +Cc: pablo.de.lara.guarch, declan.doherty, jerin.jacob
In-Reply-To: <1483551207-18236-2-git-send-email-zbigniew.bodek@caviumnetworks.com>
On 1/4/2017 11:03 PM, zbigniew.bodek@caviumnetworks.com wrote:
> From: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
>
> Avoid using incorrect assembler (nasm) and unsupported flags
> when building for ARM64.
>
> Fixes: af75078fece3 ("first public release")
> b3ce00e5fe36 ("mk: introduce ARMv8 architecture")
>
> Signed-off-by: Zbigniew Bodek <zbigniew.bodek@caviumnetworks.com>
> ---
> mk/arch/arm64/rte.vars.mk | 1 -
> mk/toolchain/gcc/rte.vars.mk | 6 ++++--
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/mk/arch/arm64/rte.vars.mk b/mk/arch/arm64/rte.vars.mk
> index c168426..3b1178a 100644
> --- a/mk/arch/arm64/rte.vars.mk
> +++ b/mk/arch/arm64/rte.vars.mk
> @@ -53,7 +53,6 @@ CROSS ?=
>
> CPU_CFLAGS ?=
> CPU_LDFLAGS ?=
> -CPU_ASFLAGS ?= -felf
>
> export ARCH CROSS CPU_CFLAGS CPU_LDFLAGS CPU_ASFLAGS
>
> diff --git a/mk/toolchain/gcc/rte.vars.mk b/mk/toolchain/gcc/rte.vars.mk
> index ff70f3d..94f6412 100644
> --- a/mk/toolchain/gcc/rte.vars.mk
> +++ b/mk/toolchain/gcc/rte.vars.mk
> @@ -41,9 +41,11 @@
> CC = $(CROSS)gcc
> KERNELCC = $(CROSS)gcc
> CPP = $(CROSS)cpp
> -# for now, we don't use as but nasm.
> -# AS = $(CROSS)as
> +ifeq ($(CONFIG_RTE_ARCH_X86),y)
> AS = nasm
> +else
> +AS = $(CROSS)as
> +endif
> AR = $(CROSS)ar
> LD = $(CROSS)ld
> OBJCOPY = $(CROSS)objcopy
>
you may add:
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
on a side note=> This patch is not related to this patch series anymore.
^ permalink raw reply
* Re: [PATCH v3 15/29] crypto/qat: use eal I/O device memory read/write API
From: Jerin Jacob @ 2017-01-13 8:17 UTC (permalink / raw)
To: Ferruh Yigit
Cc: dev, konstantin.ananyev, thomas.monjalon, bruce.richardson,
jianbo.liu, viktorin, santosh.shukla, John Griffin, Fiona Trahe,
Deepak Kumar Jain
In-Reply-To: <6bb9980b-f546-38d5-044a-63507510f6a5@intel.com>
On Thu, Jan 12, 2017 at 07:09:22PM +0000, Ferruh Yigit wrote:
> Hi Jerin,
>
> On 1/12/2017 9:17 AM, Jerin Jacob wrote:
> <...>
>
> > +#include <rte_io.h>
> > +
> > /* CSR write macro */
> > -#define ADF_CSR_WR(csrAddr, csrOffset, val) \
> > - (void)((*((volatile uint32_t *)(((uint8_t *)csrAddr) + csrOffset)) \
> > - = (val)))
> > +#define ADF_CSR_WR(csrAddr, csrOffset, val) \
> > + rte_write32(val, (((uint8_t *)csrAddr) + csrOffset))
>
> For IA, this update introduces an extra compiler barrier (rte_io_wmb()),
> which is indeed not a must, is this correct?
AFAIK, Compiler barrier is required for IA. I am not an IA expert, if
someone thinks it needs to changed then I can fix it in following commit
in this patch series by making rte_io_wmb() and rte_io_rmb() as empty.
Let me know.
AFAIK, Linux kernel code has a barrier in readl/writel for IA.
Typically we don't use any non relaxed versions in fast path.In fast
typically all the drivers has explicit write barrier for doorbell write
and followed by a relaxed version of write. IMO, In any event, it won't
generate performance regression.
[dpdk-master] $ git show
70c343bdc8c33a51a9db23cd58122bdfc120a58f
commit 70c343bdc8c33a51a9db23cd58122bdfc120a58f
Author: Jerin Jacob <jerin.jacob@caviumnetworks.com>
Date: Mon Dec 5 06:36:49 2016 +0530
eal/x86: define I/O device memory barriers for IA
The patch does not provide any functional change for IA.
I/O barriers are mapped to existing smp barriers.
CC: Bruce Richardson <bruce.richardson@intel.com>
CC: Konstantin Ananyev <konstantin.ananyev@intel.com>
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic.h
b/lib/librte_eal/common/include/arch/x86/rte_atomic.h
index 00b1cdf..4eac666 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic.h
@@ -61,6 +61,12 @@ extern "C" {
#define rte_smp_rmb() rte_compiler_barrier()
+#define rte_io_mb() rte_mb()
+
+#define rte_io_wmb() rte_compiler_barrier()
+
+#define rte_io_rmb() rte_compiler_barrier()
+
/*------------------------- 16 bit atomic operations
* -------------------------*/
#ifndef RTE_FORCE_INTRINSICS
>
> If so, does it make sense to override these functions for x86, and make
> rte_writeX = rte_writeX_relaxed
> rte_readX = rte_readX_relaxed
>
> >
> > /* CSR read macro */
> > -#define ADF_CSR_RD(csrAddr, csrOffset) \
> > - (*((volatile uint32_t *)(((uint8_t *)csrAddr) + csrOffset)))
> > +#define ADF_CSR_RD(csrAddr, csrOffset) \
> > + rte_read32((((uint8_t *)csrAddr) + csrOffset))
>
> This patchset both introduces new rte_readX/rte_writeX functions, also
> applies them into drivers.
>
> While applying them, it changes the behavior.
> Like above code was doing a read, but after update it does read and
> read_memory_barrier.
>
> What do you think this patchset updates usage in a manner that keeps
> behavior exact same. Like using rte_read32_relaxed for this case.
> And doing architecture related updates in a different patchset?
Need to use rte_read32 at this commit otherwise it will break for ARM.
That's was all point for this patchset.
For performance regression, we can always verify by taking delta
between this changeset and the previous changeset. If you think, I need
to make rte_io_wmb()/rte_io_rmb() as empty for IA then I could do that
as well.
>
> This both makes easy to see architecture specific updates, and makes
> easy to trace any possible performance issues by this patchset.
>
> >
> > #define ADF_BANK_INT_SRC_SEL_MASK_0 0x4444444CUL
> > #define ADF_BANK_INT_SRC_SEL_MASK_X 0x44444444UL
> >
>
^ permalink raw reply related
* [PATCH v6 00/18] net/ixgbe: Consistent filter API
From: Wei Zhao @ 2017-01-13 8:12 UTC (permalink / raw)
To: dev
In-Reply-To: <1484212665-1635-1-git-send-email-wei.zhao1@intel.com>
The patches mainly finish following functions:
1) Store and restore all kinds of filters.
2) Parse all kinds of filters.
3) Add flow validate function.
4) Add flow create function.
5) Add flow destroy function.
6) Add flow flush function.
v2 changes:
fix git log error
Modify some function call relationship
Change return value type of all parse flow functions
Update error info for all flow ops
Add ixgbe_filterlist_flush to flush flows and rules created
v3 change:
add new file ixgbe_flow.c to store generic API parser related functions
add more comment about pattern and action rules
add attr check in parser functions
change struct name ixgbe_flow to rte_flow
change SYN to TCP SYN
change to use memset initizlize struct ixgbe_filter_info
break down filter uninit process to 3 indepedent functions in eth_ixgbe_dev_uninit()
change struct rte_flow_item_nvgre definition
change struct rte_flow_item_e_tag definition
fix one bug in function ixgbe_dev_filter_ctrl
add goto in function ixgbe_flow_create
delete some useless initialization
eliminate some git log check warning
v4 change:
fix some check patch warning
v5 change:
fix some git log warning
v6 change:
add more comments on pattern rule example, supply the usage of spec
last and mask
zhao wei (18):
net/ixgbe: store TCP SYN filter
net/ixgbe: store flow director filter
net/ixgbe: store L2 tunnel filter
net/ixgbe: restore n-tuple filter
net/ixgbe: restore ether type filter
net/ixgbe: restore TCP SYN filter
net/ixgbe: restore flow director filter
net/ixgbe: restore L2 tunnel filter
net/ixgbe: store and restore L2 tunnel configuration
net/ixgbe: flush all the filters
net/ixgbe: parse n-tuple filter
net/ixgbe: parse ethertype filter
net/ixgbe: parse TCP SYN filter
net/ixgbe: parse L2 tunnel filter
net/ixgbe: parse flow director filter
net/ixgbe: create consistent filter
net/ixgbe: destroy consistent filter
net/ixgbe: flush all the filter list
drivers/net/ixgbe/Makefile | 2 +
drivers/net/ixgbe/ixgbe_ethdev.c | 667 +++++++--
drivers/net/ixgbe/ixgbe_ethdev.h | 203 ++-
drivers/net/ixgbe/ixgbe_fdir.c | 407 ++++--
drivers/net/ixgbe/ixgbe_flow.c | 2878 ++++++++++++++++++++++++++++++++++++++
drivers/net/ixgbe/ixgbe_pf.c | 26 +-
lib/librte_ether/rte_flow.h | 48 +
7 files changed, 4020 insertions(+), 211 deletions(-)
create mode 100644 drivers/net/ixgbe/ixgbe_flow.c
Acked-by: Beilei Xing <beilei.xing@intel.com>
Acked-by: Wei Dai <wei.dai@intel.com>
--
2.5.5
^ permalink raw reply
* [PATCH v6 01/18] net/ixgbe: store TCP SYN filter
From: Wei Zhao @ 2017-01-13 8:12 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu, Wei Zhao
In-Reply-To: <1484295192-34009-1-git-send-email-wei.zhao1@intel.com>
Add support for storing TCP SYN filter in SW.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 18 +++++++++++++-----
drivers/net/ixgbe/ixgbe_ethdev.h | 2 ++
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index b7ddd4f..719eddd 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1272,10 +1272,12 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
/* enable support intr */
ixgbe_enable_intr(eth_dev);
+ /* initialize filter info */
+ memset(filter_info, 0,
+ sizeof(struct ixgbe_filter_info));
+
/* initialize 5tuple filter list */
TAILQ_INIT(&filter_info->fivetuple_list);
- memset(filter_info->fivetuple_mask, 0,
- sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
return 0;
}
@@ -5603,15 +5605,18 @@ ixgbe_syn_filter_set(struct rte_eth_dev *dev,
bool add)
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct ixgbe_filter_info *filter_info =
+ IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ uint32_t syn_info;
uint32_t synqf;
if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM)
return -EINVAL;
- synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF);
+ syn_info = filter_info->syn_info;
if (add) {
- if (synqf & IXGBE_SYN_FILTER_ENABLE)
+ if (syn_info & IXGBE_SYN_FILTER_ENABLE)
return -EINVAL;
synqf = (uint32_t)(((filter->queue << IXGBE_SYN_FILTER_QUEUE_SHIFT) &
IXGBE_SYN_FILTER_QUEUE) | IXGBE_SYN_FILTER_ENABLE);
@@ -5621,10 +5626,13 @@ ixgbe_syn_filter_set(struct rte_eth_dev *dev,
else
synqf &= ~IXGBE_SYN_FILTER_SYNQFP;
} else {
- if (!(synqf & IXGBE_SYN_FILTER_ENABLE))
+ synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF);
+ if (!(syn_info & IXGBE_SYN_FILTER_ENABLE))
return -ENOENT;
synqf &= ~(IXGBE_SYN_FILTER_QUEUE | IXGBE_SYN_FILTER_ENABLE);
}
+
+ filter_info->syn_info = synqf;
IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf);
IXGBE_WRITE_FLUSH(hw);
return 0;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 69b276f..90a89ec 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -262,6 +262,8 @@ struct ixgbe_filter_info {
/* Bit mask for every used 5tuple filter */
uint32_t fivetuple_mask[IXGBE_5TUPLE_ARRAY_SIZE];
struct ixgbe_5tuple_filter_list fivetuple_list;
+ /* store the SYN filter info */
+ uint32_t syn_info;
};
/*
--
2.5.5
^ permalink raw reply related
* [PATCH v6 02/18] net/ixgbe: store flow director filter
From: Wei Zhao @ 2017-01-13 8:12 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu, Wei Zhao
In-Reply-To: <1484295192-34009-1-git-send-email-wei.zhao1@intel.com>
Add support for storing flow director filter in SW.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 64 ++++++++++++++++++++++++
drivers/net/ixgbe/ixgbe_ethdev.h | 19 ++++++-
drivers/net/ixgbe/ixgbe_fdir.c | 105 ++++++++++++++++++++++++++++++++++++++-
3 files changed, 185 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 719eddd..9796c4f 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -60,6 +60,7 @@
#include <rte_malloc.h>
#include <rte_random.h>
#include <rte_dev.h>
+#include <rte_hash_crc.h>
#include "ixgbe_logs.h"
#include "base/ixgbe_api.h"
@@ -165,6 +166,8 @@ enum ixgbevf_xcast_modes {
static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev);
static int eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev);
+static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
+static int ixgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
static int ixgbe_dev_configure(struct rte_eth_dev *dev);
static int ixgbe_dev_start(struct rte_eth_dev *dev);
static void ixgbe_dev_stop(struct rte_eth_dev *dev);
@@ -1279,6 +1282,9 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
/* initialize 5tuple filter list */
TAILQ_INIT(&filter_info->fivetuple_list);
+ /* initialize flow director filter list & hash */
+ ixgbe_fdir_filter_init(eth_dev);
+
return 0;
}
@@ -1320,9 +1326,67 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
rte_free(eth_dev->data->hash_mac_addrs);
eth_dev->data->hash_mac_addrs = NULL;
+ /* remove all the fdir filters & hash */
+ ixgbe_fdir_filter_uninit(eth_dev);
+
return 0;
}
+static int ixgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct ixgbe_hw_fdir_info *fdir_info =
+ IXGBE_DEV_PRIVATE_TO_FDIR_INFO(eth_dev->data->dev_private);
+ struct ixgbe_fdir_filter *fdir_filter;
+
+ if (fdir_info->hash_map)
+ rte_free(fdir_info->hash_map);
+ if (fdir_info->hash_handle)
+ rte_hash_free(fdir_info->hash_handle);
+
+ while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list))) {
+ TAILQ_REMOVE(&fdir_info->fdir_list,
+ fdir_filter,
+ entries);
+ rte_free(fdir_filter);
+ }
+
+ return 0;
+}
+
+static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
+{
+ struct ixgbe_hw_fdir_info *fdir_info =
+ IXGBE_DEV_PRIVATE_TO_FDIR_INFO(eth_dev->data->dev_private);
+ char fdir_hash_name[RTE_HASH_NAMESIZE];
+ struct rte_hash_parameters fdir_hash_params = {
+ .name = fdir_hash_name,
+ .entries = IXGBE_MAX_FDIR_FILTER_NUM,
+ .key_len = sizeof(union ixgbe_atr_input),
+ .hash_func = rte_hash_crc,
+ .hash_func_init_val = 0,
+ .socket_id = rte_socket_id(),
+ };
+
+ TAILQ_INIT(&fdir_info->fdir_list);
+ snprintf(fdir_hash_name, RTE_HASH_NAMESIZE,
+ "fdir_%s", eth_dev->data->name);
+ fdir_info->hash_handle = rte_hash_create(&fdir_hash_params);
+ if (!fdir_info->hash_handle) {
+ PMD_INIT_LOG(ERR, "Failed to create fdir hash table!");
+ return -EINVAL;
+ }
+ fdir_info->hash_map = rte_zmalloc("ixgbe",
+ sizeof(struct ixgbe_fdir_filter *) *
+ IXGBE_MAX_FDIR_FILTER_NUM,
+ 0);
+ if (!fdir_info->hash_map) {
+ PMD_INIT_LOG(ERR,
+ "Failed to allocate memory for fdir hash map!");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
/*
* Negotiate mailbox API version with the PF.
* After reset API version is always set to the basic one (ixgbe_mbox_api_10).
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 90a89ec..300542e 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -38,6 +38,7 @@
#include "base/ixgbe_dcb_82598.h"
#include "ixgbe_bypass.h"
#include <rte_time.h>
+#include <rte_hash.h>
/* need update link, bit flag */
#define IXGBE_FLAG_NEED_LINK_UPDATE (uint32_t)(1 << 0)
@@ -130,10 +131,11 @@
#define IXGBE_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET
#define IXGBE_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
+#define IXGBE_MAX_FDIR_FILTER_NUM (1024 * 32)
+
/*
* Information about the fdir mode.
*/
-
struct ixgbe_hw_fdir_mask {
uint16_t vlan_tci_mask;
uint32_t src_ipv4_mask;
@@ -148,6 +150,17 @@ struct ixgbe_hw_fdir_mask {
uint8_t tunnel_type_mask;
};
+struct ixgbe_fdir_filter {
+ TAILQ_ENTRY(ixgbe_fdir_filter) entries;
+ union ixgbe_atr_input ixgbe_fdir; /* key of fdir filter*/
+ uint32_t fdirflags; /* drop or forward */
+ uint32_t fdirhash; /* hash value for fdir */
+ uint8_t queue; /* assigned rx queue */
+};
+
+/* list of fdir filters */
+TAILQ_HEAD(ixgbe_fdir_filter_list, ixgbe_fdir_filter);
+
struct ixgbe_hw_fdir_info {
struct ixgbe_hw_fdir_mask mask;
uint8_t flex_bytes_offset;
@@ -159,6 +172,10 @@ struct ixgbe_hw_fdir_info {
uint64_t remove;
uint64_t f_add;
uint64_t f_remove;
+ struct ixgbe_fdir_filter_list fdir_list; /* filter list*/
+ /* store the pointers of the filters, index is the hash value. */
+ struct ixgbe_fdir_filter **hash_map;
+ struct rte_hash *hash_handle; /* cuckoo hash handler */
};
/* structure for interrupt relative data */
diff --git a/drivers/net/ixgbe/ixgbe_fdir.c b/drivers/net/ixgbe/ixgbe_fdir.c
index 4b81ee3..8bf5705 100644
--- a/drivers/net/ixgbe/ixgbe_fdir.c
+++ b/drivers/net/ixgbe/ixgbe_fdir.c
@@ -43,6 +43,7 @@
#include <rte_pci.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
+#include <rte_malloc.h>
#include "ixgbe_logs.h"
#include "base/ixgbe_api.h"
@@ -1075,6 +1076,65 @@ fdir_erase_filter_82599(struct ixgbe_hw *hw, uint32_t fdirhash)
}
+static inline struct ixgbe_fdir_filter *
+ixgbe_fdir_filter_lookup(struct ixgbe_hw_fdir_info *fdir_info,
+ union ixgbe_atr_input *key)
+{
+ int ret;
+
+ ret = rte_hash_lookup(fdir_info->hash_handle, (const void *)key);
+ if (ret < 0)
+ return NULL;
+
+ return fdir_info->hash_map[ret];
+}
+
+static inline int
+ixgbe_insert_fdir_filter(struct ixgbe_hw_fdir_info *fdir_info,
+ struct ixgbe_fdir_filter *fdir_filter)
+{
+ int ret;
+
+ ret = rte_hash_add_key(fdir_info->hash_handle,
+ &fdir_filter->ixgbe_fdir);
+
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR,
+ "Failed to insert fdir filter to hash table %d!",
+ ret);
+ return ret;
+ }
+
+ fdir_info->hash_map[ret] = fdir_filter;
+
+ TAILQ_INSERT_TAIL(&fdir_info->fdir_list, fdir_filter, entries);
+
+ return 0;
+}
+
+static inline int
+ixgbe_remove_fdir_filter(struct ixgbe_hw_fdir_info *fdir_info,
+ union ixgbe_atr_input *key)
+{
+ int ret;
+ struct ixgbe_fdir_filter *fdir_filter;
+
+ ret = rte_hash_del_key(fdir_info->hash_handle, key);
+
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "No such fdir filter to delete %d!", ret);
+ return ret;
+ }
+
+ fdir_filter = fdir_info->hash_map[ret];
+ fdir_info->hash_map[ret] = NULL;
+
+ TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries);
+ rte_free(fdir_filter);
+
+ return 0;
+}
+
/*
* ixgbe_add_del_fdir_filter - add or remove a flow diretor filter.
* @dev: pointer to the structure rte_eth_dev
@@ -1098,6 +1158,8 @@ ixgbe_add_del_fdir_filter(struct rte_eth_dev *dev,
struct ixgbe_hw_fdir_info *info =
IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
enum rte_fdir_mode fdir_mode = dev->data->dev_conf.fdir_conf.mode;
+ struct ixgbe_fdir_filter *node;
+ bool add_node = FALSE;
if (fdir_mode == RTE_FDIR_MODE_NONE)
return -ENOTSUP;
@@ -1148,6 +1210,10 @@ ixgbe_add_del_fdir_filter(struct rte_eth_dev *dev,
dev->data->dev_conf.fdir_conf.pballoc);
if (del) {
+ err = ixgbe_remove_fdir_filter(info, &input);
+ if (err < 0)
+ return err;
+
err = fdir_erase_filter_82599(hw, fdirhash);
if (err < 0)
PMD_DRV_LOG(ERR, "Fail to delete FDIR filter!");
@@ -1172,6 +1238,37 @@ ixgbe_add_del_fdir_filter(struct rte_eth_dev *dev,
else
return -EINVAL;
+ node = ixgbe_fdir_filter_lookup(info, &input);
+ if (node) {
+ if (update) {
+ node->fdirflags = fdircmd_flags;
+ node->fdirhash = fdirhash;
+ node->queue = queue;
+ } else {
+ PMD_DRV_LOG(ERR, "Conflict with existing fdir filter!");
+ return -EINVAL;
+ }
+ } else {
+ add_node = TRUE;
+ node = rte_zmalloc("ixgbe_fdir",
+ sizeof(struct ixgbe_fdir_filter),
+ 0);
+ if (!node)
+ return -ENOMEM;
+ (void)rte_memcpy(&node->ixgbe_fdir,
+ &input,
+ sizeof(union ixgbe_atr_input));
+ node->fdirflags = fdircmd_flags;
+ node->fdirhash = fdirhash;
+ node->queue = queue;
+
+ err = ixgbe_insert_fdir_filter(info, node);
+ if (err < 0) {
+ rte_free(node);
+ return err;
+ }
+ }
+
if (is_perfect) {
err = fdir_write_perfect_filter_82599(hw, &input, queue,
fdircmd_flags, fdirhash,
@@ -1180,10 +1277,14 @@ ixgbe_add_del_fdir_filter(struct rte_eth_dev *dev,
err = fdir_add_signature_filter_82599(hw, &input, queue,
fdircmd_flags, fdirhash);
}
- if (err < 0)
+ if (err < 0) {
PMD_DRV_LOG(ERR, "Fail to add FDIR filter!");
- else
+
+ if (add_node)
+ (void)ixgbe_remove_fdir_filter(info, &input);
+ } else {
PMD_DRV_LOG(DEBUG, "Success to add FDIR filter");
+ }
return err;
}
--
2.5.5
^ permalink raw reply related
* [PATCH v6 03/18] net/ixgbe: store L2 tunnel filter
From: Wei Zhao @ 2017-01-13 8:12 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu, Wei Zhao
In-Reply-To: <1484295192-34009-1-git-send-email-wei.zhao1@intel.com>
Add support for storing L2 tunnel filter in SW.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 172 ++++++++++++++++++++++++++++++++++++++-
drivers/net/ixgbe/ixgbe_ethdev.h | 24 ++++++
2 files changed, 193 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 9796c4f..e63b635 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -168,6 +168,8 @@ static int eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev);
static int eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev);
static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
static int ixgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
+static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev);
+static int ixgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev);
static int ixgbe_dev_configure(struct rte_eth_dev *dev);
static int ixgbe_dev_start(struct rte_eth_dev *dev);
static void ixgbe_dev_stop(struct rte_eth_dev *dev);
@@ -1285,6 +1287,8 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev)
/* initialize flow director filter list & hash */
ixgbe_fdir_filter_init(eth_dev);
+ /* initialize l2 tunnel filter list & hash */
+ ixgbe_l2_tn_filter_init(eth_dev);
return 0;
}
@@ -1329,6 +1333,9 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
/* remove all the fdir filters & hash */
ixgbe_fdir_filter_uninit(eth_dev);
+ /* remove all the L2 tunnel filters & hash */
+ ixgbe_l2_tn_filter_uninit(eth_dev);
+
return 0;
}
@@ -1353,6 +1360,27 @@ static int ixgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
+static int ixgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct ixgbe_l2_tn_info *l2_tn_info =
+ IXGBE_DEV_PRIVATE_TO_L2_TN_INFO(eth_dev->data->dev_private);
+ struct ixgbe_l2_tn_filter *l2_tn_filter;
+
+ if (l2_tn_info->hash_map)
+ rte_free(l2_tn_info->hash_map);
+ if (l2_tn_info->hash_handle)
+ rte_hash_free(l2_tn_info->hash_handle);
+
+ while ((l2_tn_filter = TAILQ_FIRST(&l2_tn_info->l2_tn_list))) {
+ TAILQ_REMOVE(&l2_tn_info->l2_tn_list,
+ l2_tn_filter,
+ entries);
+ rte_free(l2_tn_filter);
+ }
+
+ return 0;
+}
+
static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
{
struct ixgbe_hw_fdir_info *fdir_info =
@@ -1384,6 +1412,40 @@ static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
"Failed to allocate memory for fdir hash map!");
return -ENOMEM;
}
+ return 0;
+}
+
+static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)
+{
+ struct ixgbe_l2_tn_info *l2_tn_info =
+ IXGBE_DEV_PRIVATE_TO_L2_TN_INFO(eth_dev->data->dev_private);
+ char l2_tn_hash_name[RTE_HASH_NAMESIZE];
+ struct rte_hash_parameters l2_tn_hash_params = {
+ .name = l2_tn_hash_name,
+ .entries = IXGBE_MAX_L2_TN_FILTER_NUM,
+ .key_len = sizeof(struct ixgbe_l2_tn_key),
+ .hash_func = rte_hash_crc,
+ .hash_func_init_val = 0,
+ .socket_id = rte_socket_id(),
+ };
+
+ TAILQ_INIT(&l2_tn_info->l2_tn_list);
+ snprintf(l2_tn_hash_name, RTE_HASH_NAMESIZE,
+ "l2_tn_%s", eth_dev->data->name);
+ l2_tn_info->hash_handle = rte_hash_create(&l2_tn_hash_params);
+ if (!l2_tn_info->hash_handle) {
+ PMD_INIT_LOG(ERR, "Failed to create L2 TN hash table!");
+ return -EINVAL;
+ }
+ l2_tn_info->hash_map = rte_zmalloc("ixgbe",
+ sizeof(struct ixgbe_l2_tn_filter *) *
+ IXGBE_MAX_L2_TN_FILTER_NUM,
+ 0);
+ if (!l2_tn_info->hash_map) {
+ PMD_INIT_LOG(ERR,
+ "Failed to allocate memory for L2 TN hash map!");
+ return -ENOMEM;
+ }
return 0;
}
@@ -7210,12 +7272,104 @@ ixgbe_e_tag_filter_add(struct rte_eth_dev *dev,
return -EINVAL;
}
+static inline struct ixgbe_l2_tn_filter *
+ixgbe_l2_tn_filter_lookup(struct ixgbe_l2_tn_info *l2_tn_info,
+ struct ixgbe_l2_tn_key *key)
+{
+ int ret;
+
+ ret = rte_hash_lookup(l2_tn_info->hash_handle, (const void *)key);
+ if (ret < 0)
+ return NULL;
+
+ return l2_tn_info->hash_map[ret];
+}
+
+static inline int
+ixgbe_insert_l2_tn_filter(struct ixgbe_l2_tn_info *l2_tn_info,
+ struct ixgbe_l2_tn_filter *l2_tn_filter)
+{
+ int ret;
+
+ ret = rte_hash_add_key(l2_tn_info->hash_handle,
+ &l2_tn_filter->key);
+
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR,
+ "Failed to insert L2 tunnel filter"
+ " to hash table %d!",
+ ret);
+ return ret;
+ }
+
+ l2_tn_info->hash_map[ret] = l2_tn_filter;
+
+ TAILQ_INSERT_TAIL(&l2_tn_info->l2_tn_list, l2_tn_filter, entries);
+
+ return 0;
+}
+
+static inline int
+ixgbe_remove_l2_tn_filter(struct ixgbe_l2_tn_info *l2_tn_info,
+ struct ixgbe_l2_tn_key *key)
+{
+ int ret;
+ struct ixgbe_l2_tn_filter *l2_tn_filter;
+
+ ret = rte_hash_del_key(l2_tn_info->hash_handle, key);
+
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR,
+ "No such L2 tunnel filter to delete %d!",
+ ret);
+ return ret;
+ }
+
+ l2_tn_filter = l2_tn_info->hash_map[ret];
+ l2_tn_info->hash_map[ret] = NULL;
+
+ TAILQ_REMOVE(&l2_tn_info->l2_tn_list, l2_tn_filter, entries);
+ rte_free(l2_tn_filter);
+
+ return 0;
+}
+
/* Add l2 tunnel filter */
static int
ixgbe_dev_l2_tunnel_filter_add(struct rte_eth_dev *dev,
struct rte_eth_l2_tunnel_conf *l2_tunnel)
{
- int ret = 0;
+ int ret;
+ struct ixgbe_l2_tn_info *l2_tn_info =
+ IXGBE_DEV_PRIVATE_TO_L2_TN_INFO(dev->data->dev_private);
+ struct ixgbe_l2_tn_key key;
+ struct ixgbe_l2_tn_filter *node;
+
+ key.l2_tn_type = l2_tunnel->l2_tunnel_type;
+ key.tn_id = l2_tunnel->tunnel_id;
+
+ node = ixgbe_l2_tn_filter_lookup(l2_tn_info, &key);
+
+ if (node) {
+ PMD_DRV_LOG(ERR, "The L2 tunnel filter already exists!");
+ return -EINVAL;
+ }
+
+ node = rte_zmalloc("ixgbe_l2_tn",
+ sizeof(struct ixgbe_l2_tn_filter),
+ 0);
+ if (!node)
+ return -ENOMEM;
+
+ (void)rte_memcpy(&node->key,
+ &key,
+ sizeof(struct ixgbe_l2_tn_key));
+ node->pool = l2_tunnel->pool;
+ ret = ixgbe_insert_l2_tn_filter(l2_tn_info, node);
+ if (ret < 0) {
+ rte_free(node);
+ return ret;
+ }
switch (l2_tunnel->l2_tunnel_type) {
case RTE_L2_TUNNEL_TYPE_E_TAG:
@@ -7227,6 +7381,9 @@ ixgbe_dev_l2_tunnel_filter_add(struct rte_eth_dev *dev,
break;
}
+ if (ret < 0)
+ (void)ixgbe_remove_l2_tn_filter(l2_tn_info, &key);
+
return ret;
}
@@ -7235,7 +7392,16 @@ static int
ixgbe_dev_l2_tunnel_filter_del(struct rte_eth_dev *dev,
struct rte_eth_l2_tunnel_conf *l2_tunnel)
{
- int ret = 0;
+ int ret;
+ struct ixgbe_l2_tn_info *l2_tn_info =
+ IXGBE_DEV_PRIVATE_TO_L2_TN_INFO(dev->data->dev_private);
+ struct ixgbe_l2_tn_key key;
+
+ key.l2_tn_type = l2_tunnel->l2_tunnel_type;
+ key.tn_id = l2_tunnel->tunnel_id;
+ ret = ixgbe_remove_l2_tn_filter(l2_tn_info, &key);
+ if (ret < 0)
+ return ret;
switch (l2_tunnel->l2_tunnel_type) {
case RTE_L2_TUNNEL_TYPE_E_TAG:
@@ -7261,7 +7427,7 @@ ixgbe_dev_l2_tunnel_filter_handle(struct rte_eth_dev *dev,
enum rte_filter_op filter_op,
void *arg)
{
- int ret = 0;
+ int ret;
if (filter_op == RTE_ETH_FILTER_NOP)
return 0;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 300542e..b2cf789 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -132,6 +132,7 @@
#define IXGBE_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
#define IXGBE_MAX_FDIR_FILTER_NUM (1024 * 32)
+#define IXGBE_MAX_L2_TN_FILTER_NUM 128
/*
* Information about the fdir mode.
@@ -283,6 +284,25 @@ struct ixgbe_filter_info {
uint32_t syn_info;
};
+struct ixgbe_l2_tn_key {
+ enum rte_eth_tunnel_type l2_tn_type;
+ uint32_t tn_id;
+};
+
+struct ixgbe_l2_tn_filter {
+ TAILQ_ENTRY(ixgbe_l2_tn_filter) entries;
+ struct ixgbe_l2_tn_key key;
+ uint32_t pool;
+};
+
+TAILQ_HEAD(ixgbe_l2_tn_filter_list, ixgbe_l2_tn_filter);
+
+struct ixgbe_l2_tn_info {
+ struct ixgbe_l2_tn_filter_list l2_tn_list;
+ struct ixgbe_l2_tn_filter **hash_map;
+ struct rte_hash *hash_handle;
+};
+
/*
* Structure to store private data for each driver instance (for each port).
*/
@@ -302,6 +322,7 @@ struct ixgbe_adapter {
struct ixgbe_bypass_info bps;
#endif /* RTE_NIC_BYPASS */
struct ixgbe_filter_info filter;
+ struct ixgbe_l2_tn_info l2_tn;
bool rx_bulk_alloc_allowed;
bool rx_vec_allowed;
@@ -349,6 +370,9 @@ struct ixgbe_adapter {
#define IXGBE_DEV_PRIVATE_TO_FILTER_INFO(adapter) \
(&((struct ixgbe_adapter *)adapter)->filter)
+#define IXGBE_DEV_PRIVATE_TO_L2_TN_INFO(adapter) \
+ (&((struct ixgbe_adapter *)adapter)->l2_tn)
+
/*
* RX/TX function prototypes
*/
--
2.5.5
^ permalink raw reply related
* [PATCH v6 04/18] net/ixgbe: restore n-tuple filter
From: Wei Zhao @ 2017-01-13 8:12 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu, Wei Zhao
In-Reply-To: <1484295192-34009-1-git-send-email-wei.zhao1@intel.com>
Add support for restoring n-tuple filter in SW.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 140 +++++++++++++++++++++++++--------------
1 file changed, 92 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index e63b635..1630e65 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -170,6 +170,7 @@ static int ixgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
static int ixgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
static int ixgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev);
static int ixgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev);
+static int ixgbe_ntuple_filter_uninit(struct rte_eth_dev *eth_dev);
static int ixgbe_dev_configure(struct rte_eth_dev *dev);
static int ixgbe_dev_start(struct rte_eth_dev *dev);
static void ixgbe_dev_stop(struct rte_eth_dev *dev);
@@ -387,6 +388,7 @@ static int ixgbe_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
struct rte_eth_udp_tunnel *udp_tunnel);
static int ixgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
struct rte_eth_udp_tunnel *udp_tunnel);
+static int ixgbe_filter_restore(struct rte_eth_dev *dev);
/*
* Define VF Stats MACRO for Non "cleared on read" register
@@ -1336,6 +1338,27 @@ eth_ixgbe_dev_uninit(struct rte_eth_dev *eth_dev)
/* remove all the L2 tunnel filters & hash */
ixgbe_l2_tn_filter_uninit(eth_dev);
+ /* Remove all ntuple filters of the device */
+ ixgbe_ntuple_filter_uninit(eth_dev);
+
+ return 0;
+}
+
+static int ixgbe_ntuple_filter_uninit(struct rte_eth_dev *eth_dev)
+{
+ struct ixgbe_filter_info *filter_info =
+ IXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
+ struct ixgbe_5tuple_filter *p_5tuple;
+
+ while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list))) {
+ TAILQ_REMOVE(&filter_info->fivetuple_list,
+ p_5tuple,
+ entries);
+ rte_free(p_5tuple);
+ }
+ memset(filter_info->fivetuple_mask, 0,
+ sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
+
return 0;
}
@@ -2504,6 +2527,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
/* resume enabled intr since hw reset */
ixgbe_enable_intr(dev);
+ ixgbe_filter_restore(dev);
return 0;
@@ -2524,9 +2548,6 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_vf_info *vfinfo =
*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
- struct ixgbe_filter_info *filter_info =
- IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
- struct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;
struct rte_pci_device *pci_dev = IXGBE_DEV_TO_PCI(dev);
struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
int vf;
@@ -2564,17 +2585,6 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
memset(&link, 0, sizeof(link));
rte_ixgbe_dev_atomic_write_link_status(dev, &link);
- /* Remove all ntuple filters of the device */
- for (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);
- p_5tuple != NULL; p_5tuple = p_5tuple_next) {
- p_5tuple_next = TAILQ_NEXT(p_5tuple, entries);
- TAILQ_REMOVE(&filter_info->fivetuple_list,
- p_5tuple, entries);
- rte_free(p_5tuple);
- }
- memset(filter_info->fivetuple_mask, 0,
- sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
-
if (!rte_intr_allow_others(intr_handle))
/* resume to the default handler */
rte_intr_callback_register(intr_handle,
@@ -5836,6 +5846,52 @@ convert_protocol_type(uint8_t protocol_value)
return IXGBE_FILTER_PROTOCOL_NONE;
}
+/* inject a 5-tuple filter to HW */
+static inline void
+ixgbe_inject_5tuple_filter(struct rte_eth_dev *dev,
+ struct ixgbe_5tuple_filter *filter)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ int i;
+ uint32_t ftqf, sdpqf;
+ uint32_t l34timir = 0;
+ uint8_t mask = 0xff;
+
+ i = filter->index;
+
+ sdpqf = (uint32_t)(filter->filter_info.dst_port <<
+ IXGBE_SDPQF_DSTPORT_SHIFT);
+ sdpqf = sdpqf | (filter->filter_info.src_port & IXGBE_SDPQF_SRCPORT);
+
+ ftqf = (uint32_t)(filter->filter_info.proto &
+ IXGBE_FTQF_PROTOCOL_MASK);
+ ftqf |= (uint32_t)((filter->filter_info.priority &
+ IXGBE_FTQF_PRIORITY_MASK) << IXGBE_FTQF_PRIORITY_SHIFT);
+ if (filter->filter_info.src_ip_mask == 0) /* 0 means compare. */
+ mask &= IXGBE_FTQF_SOURCE_ADDR_MASK;
+ if (filter->filter_info.dst_ip_mask == 0)
+ mask &= IXGBE_FTQF_DEST_ADDR_MASK;
+ if (filter->filter_info.src_port_mask == 0)
+ mask &= IXGBE_FTQF_SOURCE_PORT_MASK;
+ if (filter->filter_info.dst_port_mask == 0)
+ mask &= IXGBE_FTQF_DEST_PORT_MASK;
+ if (filter->filter_info.proto_mask == 0)
+ mask &= IXGBE_FTQF_PROTOCOL_COMP_MASK;
+ ftqf |= mask << IXGBE_FTQF_5TUPLE_MASK_SHIFT;
+ ftqf |= IXGBE_FTQF_POOL_MASK_EN;
+ ftqf |= IXGBE_FTQF_QUEUE_ENABLE;
+
+ IXGBE_WRITE_REG(hw, IXGBE_DAQF(i), filter->filter_info.dst_ip);
+ IXGBE_WRITE_REG(hw, IXGBE_SAQF(i), filter->filter_info.src_ip);
+ IXGBE_WRITE_REG(hw, IXGBE_SDPQF(i), sdpqf);
+ IXGBE_WRITE_REG(hw, IXGBE_FTQF(i), ftqf);
+
+ l34timir |= IXGBE_L34T_IMIR_RESERVE;
+ l34timir |= (uint32_t)(filter->queue <<
+ IXGBE_L34T_IMIR_QUEUE_SHIFT);
+ IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(i), l34timir);
+}
+
/*
* add a 5tuple filter
*
@@ -5853,13 +5909,9 @@ static int
ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
struct ixgbe_5tuple_filter *filter)
{
- struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_filter_info *filter_info =
IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
int i, idx, shift;
- uint32_t ftqf, sdpqf;
- uint32_t l34timir = 0;
- uint8_t mask = 0xff;
/*
* look for an unused 5tuple filter index,
@@ -5882,37 +5934,8 @@ ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
return -ENOSYS;
}
- sdpqf = (uint32_t)(filter->filter_info.dst_port <<
- IXGBE_SDPQF_DSTPORT_SHIFT);
- sdpqf = sdpqf | (filter->filter_info.src_port & IXGBE_SDPQF_SRCPORT);
-
- ftqf = (uint32_t)(filter->filter_info.proto &
- IXGBE_FTQF_PROTOCOL_MASK);
- ftqf |= (uint32_t)((filter->filter_info.priority &
- IXGBE_FTQF_PRIORITY_MASK) << IXGBE_FTQF_PRIORITY_SHIFT);
- if (filter->filter_info.src_ip_mask == 0) /* 0 means compare. */
- mask &= IXGBE_FTQF_SOURCE_ADDR_MASK;
- if (filter->filter_info.dst_ip_mask == 0)
- mask &= IXGBE_FTQF_DEST_ADDR_MASK;
- if (filter->filter_info.src_port_mask == 0)
- mask &= IXGBE_FTQF_SOURCE_PORT_MASK;
- if (filter->filter_info.dst_port_mask == 0)
- mask &= IXGBE_FTQF_DEST_PORT_MASK;
- if (filter->filter_info.proto_mask == 0)
- mask &= IXGBE_FTQF_PROTOCOL_COMP_MASK;
- ftqf |= mask << IXGBE_FTQF_5TUPLE_MASK_SHIFT;
- ftqf |= IXGBE_FTQF_POOL_MASK_EN;
- ftqf |= IXGBE_FTQF_QUEUE_ENABLE;
-
- IXGBE_WRITE_REG(hw, IXGBE_DAQF(i), filter->filter_info.dst_ip);
- IXGBE_WRITE_REG(hw, IXGBE_SAQF(i), filter->filter_info.src_ip);
- IXGBE_WRITE_REG(hw, IXGBE_SDPQF(i), sdpqf);
- IXGBE_WRITE_REG(hw, IXGBE_FTQF(i), ftqf);
+ ixgbe_inject_5tuple_filter(dev, filter);
- l34timir |= IXGBE_L34T_IMIR_RESERVE;
- l34timir |= (uint32_t)(filter->queue <<
- IXGBE_L34T_IMIR_QUEUE_SHIFT);
- IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(i), l34timir);
return 0;
}
@@ -7925,6 +7948,27 @@ ixgbevf_dev_interrupt_handler(__rte_unused struct rte_intr_handle *handle,
ixgbevf_dev_interrupt_action(dev);
}
+/* restore n-tuple filter */
+static inline void
+ixgbe_ntuple_filter_restore(struct rte_eth_dev *dev)
+{
+ struct ixgbe_filter_info *filter_info =
+ IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ struct ixgbe_5tuple_filter *node;
+
+ TAILQ_FOREACH(node, &filter_info->fivetuple_list, entries) {
+ ixgbe_inject_5tuple_filter(dev, node);
+ }
+}
+
+static int
+ixgbe_filter_restore(struct rte_eth_dev *dev)
+{
+ ixgbe_ntuple_filter_restore(dev);
+
+ return 0;
+}
+
RTE_PMD_REGISTER_PCI(net_ixgbe, rte_ixgbe_pmd.pci_drv);
RTE_PMD_REGISTER_PCI_TABLE(net_ixgbe, pci_id_ixgbe_map);
RTE_PMD_REGISTER_KMOD_DEP(net_ixgbe, "* igb_uio | uio_pci_generic | vfio");
--
2.5.5
^ permalink raw reply related
* [PATCH v6 05/18] net/ixgbe: restore ether type filter
From: Wei Zhao @ 2017-01-13 8:12 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu, Wei Zhao
In-Reply-To: <1484295192-34009-1-git-send-email-wei.zhao1@intel.com>
Add support for restoring ether type filter in SW.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 79 ++++++++++++++++------------------------
drivers/net/ixgbe/ixgbe_ethdev.h | 57 ++++++++++++++++++++++++++++-
drivers/net/ixgbe/ixgbe_pf.c | 25 ++++++++-----
3 files changed, 104 insertions(+), 57 deletions(-)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 1630e65..6c46354 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -6259,47 +6259,6 @@ ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,
return ret;
}
-static inline int
-ixgbe_ethertype_filter_lookup(struct ixgbe_filter_info *filter_info,
- uint16_t ethertype)
-{
- int i;
-
- for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
- if (filter_info->ethertype_filters[i] == ethertype &&
- (filter_info->ethertype_mask & (1 << i)))
- return i;
- }
- return -1;
-}
-
-static inline int
-ixgbe_ethertype_filter_insert(struct ixgbe_filter_info *filter_info,
- uint16_t ethertype)
-{
- int i;
-
- for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
- if (!(filter_info->ethertype_mask & (1 << i))) {
- filter_info->ethertype_mask |= 1 << i;
- filter_info->ethertype_filters[i] = ethertype;
- return i;
- }
- }
- return -1;
-}
-
-static inline int
-ixgbe_ethertype_filter_remove(struct ixgbe_filter_info *filter_info,
- uint8_t idx)
-{
- if (idx >= IXGBE_MAX_ETQF_FILTERS)
- return -1;
- filter_info->ethertype_mask &= ~(1 << idx);
- filter_info->ethertype_filters[idx] = 0;
- return idx;
-}
-
static int
ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
struct rte_eth_ethertype_filter *filter,
@@ -6311,6 +6270,7 @@ ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
uint32_t etqf = 0;
uint32_t etqs = 0;
int ret;
+ struct ixgbe_ethertype_filter ethertype_filter;
if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM)
return -EINVAL;
@@ -6344,18 +6304,22 @@ ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
}
if (add) {
- ret = ixgbe_ethertype_filter_insert(filter_info,
- filter->ether_type);
- if (ret < 0) {
- PMD_DRV_LOG(ERR, "ethertype filters are full.");
- return -ENOSYS;
- }
etqf = IXGBE_ETQF_FILTER_EN;
etqf |= (uint32_t)filter->ether_type;
etqs |= (uint32_t)((filter->queue <<
IXGBE_ETQS_RX_QUEUE_SHIFT) &
IXGBE_ETQS_RX_QUEUE);
etqs |= IXGBE_ETQS_QUEUE_EN;
+
+ ethertype_filter.ethertype = filter->ether_type;
+ ethertype_filter.etqf = etqf;
+ ethertype_filter.etqs = etqs;
+ ret = ixgbe_ethertype_filter_insert(filter_info,
+ ðertype_filter);
+ if (ret < 0) {
+ PMD_DRV_LOG(ERR, "ethertype filters are full.");
+ return -ENOSPC;
+ }
} else {
ret = ixgbe_ethertype_filter_remove(filter_info, (uint8_t)ret);
if (ret < 0)
@@ -7961,10 +7925,31 @@ ixgbe_ntuple_filter_restore(struct rte_eth_dev *dev)
}
}
+/* restore ethernet type filter */
+static inline void
+ixgbe_ethertype_filter_restore(struct rte_eth_dev *dev)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct ixgbe_filter_info *filter_info =
+ IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ int i;
+
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ if (filter_info->ethertype_mask & (1 << i)) {
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(i),
+ filter_info->ethertype_filters[i].etqf);
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(i),
+ filter_info->ethertype_filters[i].etqs);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+ }
+}
+
static int
ixgbe_filter_restore(struct rte_eth_dev *dev)
{
ixgbe_ntuple_filter_restore(dev);
+ ixgbe_ethertype_filter_restore(dev);
return 0;
}
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index b2cf789..36aae01 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -270,13 +270,19 @@ struct ixgbe_5tuple_filter {
(RTE_ALIGN(IXGBE_MAX_FTQF_FILTERS, (sizeof(uint32_t) * NBBY)) / \
(sizeof(uint32_t) * NBBY))
+struct ixgbe_ethertype_filter {
+ uint16_t ethertype;
+ uint32_t etqf;
+ uint32_t etqs;
+};
+
/*
* Structure to store filters' info.
*/
struct ixgbe_filter_info {
uint8_t ethertype_mask; /* Bit mask for every used ethertype filter */
/* store used ethertype filters*/
- uint16_t ethertype_filters[IXGBE_MAX_ETQF_FILTERS];
+ struct ixgbe_ethertype_filter ethertype_filters[IXGBE_MAX_ETQF_FILTERS];
/* Bit mask for every used 5tuple filter */
uint32_t fivetuple_mask[IXGBE_5TUPLE_ARRAY_SIZE];
struct ixgbe_5tuple_filter_list fivetuple_list;
@@ -491,4 +497,53 @@ uint32_t ixgbe_convert_vm_rx_mask_to_val(uint16_t rx_mask, uint32_t orig_val);
int ixgbe_fdir_ctrl_func(struct rte_eth_dev *dev,
enum rte_filter_op filter_op, void *arg);
+
+static inline int
+ixgbe_ethertype_filter_lookup(struct ixgbe_filter_info *filter_info,
+ uint16_t ethertype)
+{
+ int i;
+
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ if (filter_info->ethertype_filters[i].ethertype == ethertype &&
+ (filter_info->ethertype_mask & (1 << i)))
+ return i;
+ }
+ return -1;
+}
+
+static inline int
+ixgbe_ethertype_filter_insert(struct ixgbe_filter_info *filter_info,
+ struct ixgbe_ethertype_filter *ethertype_filter)
+{
+ int i;
+
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ if (!(filter_info->ethertype_mask & (1 << i))) {
+ filter_info->ethertype_mask |= 1 << i;
+ filter_info->ethertype_filters[i].ethertype =
+ ethertype_filter->ethertype;
+ filter_info->ethertype_filters[i].etqf =
+ ethertype_filter->etqf;
+ filter_info->ethertype_filters[i].etqs =
+ ethertype_filter->etqs;
+ return i;
+ }
+ }
+ return -1;
+}
+
+static inline int
+ixgbe_ethertype_filter_remove(struct ixgbe_filter_info *filter_info,
+ uint8_t idx)
+{
+ if (idx >= IXGBE_MAX_ETQF_FILTERS)
+ return -1;
+ filter_info->ethertype_mask &= ~(1 << idx);
+ filter_info->ethertype_filters[idx].ethertype = 0;
+ filter_info->ethertype_filters[idx].etqf = 0;
+ filter_info->ethertype_filters[idx].etqs = 0;
+ return idx;
+}
+
#endif /* _IXGBE_ETHDEV_H_ */
diff --git a/drivers/net/ixgbe/ixgbe_pf.c b/drivers/net/ixgbe/ixgbe_pf.c
index cb10265..4b33130 100644
--- a/drivers/net/ixgbe/ixgbe_pf.c
+++ b/drivers/net/ixgbe/ixgbe_pf.c
@@ -178,6 +178,7 @@ ixgbe_add_tx_flow_control_drop_filter(struct rte_eth_dev *eth_dev)
IXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
uint16_t vf_num;
int i;
+ struct ixgbe_ethertype_filter ethertype_filter;
if (!hw->mac.ops.set_ethertype_anti_spoofing) {
RTE_LOG(INFO, PMD, "ether type anti-spoofing is not"
@@ -185,16 +186,22 @@ ixgbe_add_tx_flow_control_drop_filter(struct rte_eth_dev *eth_dev)
return;
}
- /* occupy an entity of ether type filter */
- for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
- if (!(filter_info->ethertype_mask & (1 << i))) {
- filter_info->ethertype_mask |= 1 << i;
- filter_info->ethertype_filters[i] =
- IXGBE_ETHERTYPE_FLOW_CTRL;
- break;
- }
+ i = ixgbe_ethertype_filter_lookup(filter_info,
+ IXGBE_ETHERTYPE_FLOW_CTRL);
+ if (i >= 0) {
+ RTE_LOG(ERR, PMD, "A ether type filter"
+ " entity for flow control already exists!\n");
+ return;
}
- if (i == IXGBE_MAX_ETQF_FILTERS) {
+
+ ethertype_filter.ethertype = IXGBE_ETHERTYPE_FLOW_CTRL;
+ ethertype_filter.etqf = IXGBE_ETQF_FILTER_EN |
+ IXGBE_ETQF_TX_ANTISPOOF |
+ IXGBE_ETHERTYPE_FLOW_CTRL;
+ ethertype_filter.etqs = 0;
+ i = ixgbe_ethertype_filter_insert(filter_info,
+ ðertype_filter);
+ if (i < 0) {
RTE_LOG(ERR, PMD, "Cannot find an unused ether type filter"
" entity for flow control.\n");
return;
--
2.5.5
^ permalink raw reply related
* [PATCH v6 06/18] net/ixgbe: restore TCP SYN filter
From: Wei Zhao @ 2017-01-13 8:13 UTC (permalink / raw)
To: dev; +Cc: Wenzhuo Lu, Wei Zhao
In-Reply-To: <1484295192-34009-1-git-send-email-wei.zhao1@intel.com>
Add support for restoring TCP SYN filter in SW.
Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
---
drivers/net/ixgbe/ixgbe_ethdev.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 6c46354..6cd5975 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -7945,11 +7945,29 @@ ixgbe_ethertype_filter_restore(struct rte_eth_dev *dev)
}
}
+/* restore SYN filter */
+static inline void
+ixgbe_syn_filter_restore(struct rte_eth_dev *dev)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct ixgbe_filter_info *filter_info =
+ IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+ uint32_t synqf;
+
+ synqf = filter_info->syn_info;
+
+ if (synqf & IXGBE_SYN_FILTER_ENABLE) {
+ IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+}
+
static int
ixgbe_filter_restore(struct rte_eth_dev *dev)
{
ixgbe_ntuple_filter_restore(dev);
ixgbe_ethertype_filter_restore(dev);
+ ixgbe_syn_filter_restore(dev);
return 0;
}
--
2.5.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox