From: Jijiang Liu <jijiang.liu@intel.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v2 2/4] i40e:expand MAC filter implemantation in i40e
Date: Fri, 24 Oct 2014 15:58:43 +0800 [thread overview]
Message-ID: <1414137525-23582-3-git-send-email-jijiang.liu@intel.com> (raw)
In-Reply-To: <1414137525-23582-1-git-send-email-jijiang.liu@intel.com>
This patch mainly optimizes the i40e_add_macvlan_filters() and the i40e_remove_macvlan_filters() functions in order that
we are able to provide filter type configuration. And another relevant MAC filter codes are changed based on new data structures.
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
---
lib/librte_pmd_i40e/i40e_ethdev.c | 165 ++++++++++++++++++++++++++++--------
lib/librte_pmd_i40e/i40e_ethdev.h | 18 ++++-
lib/librte_pmd_i40e/i40e_pf.c | 7 ++-
3 files changed, 149 insertions(+), 41 deletions(-)
diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c
index 3b75f0f..5fae0e1 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev.c
@@ -1529,6 +1529,7 @@ i40e_macaddr_add(struct rte_eth_dev *dev,
{
struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct i40e_mac_filter_info mac_filter;
struct i40e_vsi *vsi = pf->main_vsi;
struct ether_addr old_mac;
int ret;
@@ -1554,8 +1555,10 @@ i40e_macaddr_add(struct rte_eth_dev *dev,
(void)rte_memcpy(&old_mac, hw->mac.addr, ETHER_ADDR_LEN);
(void)rte_memcpy(hw->mac.addr, mac_addr->addr_bytes,
ETHER_ADDR_LEN);
+ (void)rte_memcpy(&mac_filter.mac_addr, mac_addr, ETHER_ADDR_LEN);
+ mac_filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
- ret = i40e_vsi_add_mac(vsi, mac_addr);
+ ret = i40e_vsi_add_mac(vsi, &mac_filter);
if (ret != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to add MACVLAN filter");
return;
@@ -2472,6 +2475,7 @@ i40e_update_default_filter_setting(struct i40e_vsi *vsi)
{
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
struct i40e_aqc_remove_macvlan_element_data def_filter;
+ struct i40e_mac_filter_info filter;
int ret;
if (vsi->type != I40E_VSI_MAIN)
@@ -2485,6 +2489,7 @@ i40e_update_default_filter_setting(struct i40e_vsi *vsi)
ret = i40e_aq_remove_macvlan(hw, vsi->seid, &def_filter, 1, NULL);
if (ret != I40E_SUCCESS) {
struct i40e_mac_filter *f;
+ struct ether_addr *mac;
PMD_DRV_LOG(WARNING, "Cannot remove the default "
"macvlan filter");
@@ -2494,15 +2499,18 @@ i40e_update_default_filter_setting(struct i40e_vsi *vsi)
PMD_DRV_LOG(ERR, "failed to allocate memory");
return I40E_ERR_NO_MEMORY;
}
- (void)rte_memcpy(&f->macaddr.addr_bytes, hw->mac.perm_addr,
+ mac = &f->mac_info.mac_addr;
+ (void)rte_memcpy(&mac->addr_bytes, hw->mac.perm_addr,
ETH_ADDR_LEN);
TAILQ_INSERT_TAIL(&vsi->mac_list, f, next);
vsi->mac_num++;
return ret;
}
-
- return i40e_vsi_add_mac(vsi, (struct ether_addr *)(hw->mac.perm_addr));
+ (void)rte_memcpy(&filter.mac_addr,
+ (struct ether_addr *)(hw->mac.perm_addr), ETH_ADDR_LEN);
+ filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
+ return i40e_vsi_add_mac(vsi, &filter);
}
static int
@@ -2556,6 +2564,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
{
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
struct i40e_vsi *vsi;
+ struct i40e_mac_filter_info filter;
int ret;
struct i40e_vsi_context ctxt;
struct ether_addr broadcast =
@@ -2766,7 +2775,10 @@ i40e_vsi_setup(struct i40e_pf *pf,
}
/* MAC/VLAN configuration */
- ret = i40e_vsi_add_mac(vsi, &broadcast);
+ (void)rte_memcpy(&filter.mac_addr, &broadcast, ETHER_ADDR_LEN);
+ filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
+
+ ret = i40e_vsi_add_mac(vsi, &filter);
if (ret != I40E_SUCCESS) {
PMD_DRV_LOG(ERR, "Failed to add MACVLAN filter");
goto fail_msix_alloc;
@@ -3467,6 +3479,7 @@ i40e_add_macvlan_filters(struct i40e_vsi *vsi,
{
int ele_num, ele_buff_size;
int num, actual_num, i;
+ uint16_t flags;
int ret = I40E_SUCCESS;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
struct i40e_aqc_add_macvlan_element_data *req_list;
@@ -3492,9 +3505,31 @@ i40e_add_macvlan_filters(struct i40e_vsi *vsi,
&filter[num + i].macaddr, ETH_ADDR_LEN);
req_list[i].vlan_tag =
rte_cpu_to_le_16(filter[num + i].vlan_id);
- req_list[i].flags = rte_cpu_to_le_16(\
- I40E_AQC_MACVLAN_ADD_PERFECT_MATCH);
+
+ switch (filter[num + i].filter_type) {
+ case RTE_MAC_PERFECT_MATCH:
+ flags = I40E_AQC_MACVLAN_ADD_PERFECT_MATCH |
+ I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;
+ break;
+ case RTE_MACVLAN_PERFECT_MATCH:
+ flags = I40E_AQC_MACVLAN_ADD_PERFECT_MATCH;
+ break;
+ case RTE_MAC_HASH_MATCH:
+ flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH |
+ I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;
+ break;
+ case RTE_MACVLAN_HASH_MATCH:
+ flags = I40E_AQC_MACVLAN_ADD_HASH_MATCH;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Invalid MAC match type\n");
+ ret = I40E_ERR_PARAM;
+ goto DONE;
+ }
+
req_list[i].queue_number = 0;
+
+ req_list[i].flags = rte_cpu_to_le_16(flags);
}
ret = i40e_aq_add_macvlan(hw, vsi->seid, req_list,
@@ -3518,6 +3553,7 @@ i40e_remove_macvlan_filters(struct i40e_vsi *vsi,
{
int ele_num, ele_buff_size;
int num, actual_num, i;
+ uint16_t flags;
int ret = I40E_SUCCESS;
struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
struct i40e_aqc_remove_macvlan_element_data *req_list;
@@ -3544,7 +3580,28 @@ i40e_remove_macvlan_filters(struct i40e_vsi *vsi,
&filter[num + i].macaddr, ETH_ADDR_LEN);
req_list[i].vlan_tag =
rte_cpu_to_le_16(filter[num + i].vlan_id);
- req_list[i].flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
+
+ switch (filter[num + i].filter_type) {
+ case RTE_MAC_PERFECT_MATCH:
+ flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH |
+ I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
+ break;
+ case RTE_MACVLAN_PERFECT_MATCH:
+ flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
+ break;
+ case RTE_MAC_HASH_MATCH:
+ flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH |
+ I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
+ break;
+ case RTE_MACVLAN_HASH_MATCH:
+ flags = I40E_AQC_MACVLAN_DEL_HASH_MATCH;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Invalid MAC filter type\n");
+ ret = I40E_ERR_PARAM;
+ goto DONE;
+ }
+ req_list[i].flags = rte_cpu_to_le_16(flags);
}
ret = i40e_aq_remove_macvlan(hw, vsi->seid, req_list,
@@ -3569,7 +3626,7 @@ i40e_find_mac_filter(struct i40e_vsi *vsi,
struct i40e_mac_filter *f;
TAILQ_FOREACH(f, &vsi->mac_list, next) {
- if (is_same_ether_addr(macaddr, &(f->macaddr)))
+ if (is_same_ether_addr(macaddr, &f->mac_info.mac_addr))
return f;
}
@@ -3670,8 +3727,10 @@ i40e_find_all_mac_for_vlan(struct i40e_vsi *vsi,
PMD_DRV_LOG(ERR, "buffer number not match");
return I40E_ERR_PARAM;
}
- (void)rte_memcpy(&mv_f[i].macaddr, &f->macaddr, ETH_ADDR_LEN);
+ (void)rte_memcpy(&mv_f[i].macaddr, &f->mac_info.mac_addr,
+ ETH_ADDR_LEN);
mv_f[i].vlan_id = vlan;
+ mv_f[i].filter_type = f->mac_info.filter_type;
i++;
}
@@ -3705,14 +3764,14 @@ i40e_vsi_remove_all_macvlan_filter(struct i40e_vsi *vsi)
if (vsi->vlan_num == 0) {
TAILQ_FOREACH(f, &vsi->mac_list, next) {
(void)rte_memcpy(&mv_f[i].macaddr,
- &f->macaddr, ETH_ADDR_LEN);
+ &f->mac_info.mac_addr, ETH_ADDR_LEN);
mv_f[i].vlan_id = 0;
i++;
}
} else {
TAILQ_FOREACH(f, &vsi->mac_list, next) {
ret = i40e_find_all_vlan_for_mac(vsi,&mv_f[i],
- vsi->vlan_num, &f->macaddr);
+ vsi->vlan_num, &f->mac_info.mac_addr);
if (ret != I40E_SUCCESS)
goto DONE;
i += vsi->vlan_num;
@@ -3836,28 +3895,32 @@ DONE:
}
int
-i40e_vsi_add_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
+i40e_vsi_add_mac(struct i40e_vsi *vsi, struct i40e_mac_filter_info *mac_filter)
{
struct i40e_mac_filter *f;
struct i40e_macvlan_filter *mv_f;
- int vlan_num;
+ int i, vlan_num = 0;
int ret = I40E_SUCCESS;
/* If it's add and we've config it, return */
- f = i40e_find_mac_filter(vsi, addr);
+ f = i40e_find_mac_filter(vsi, &mac_filter->mac_addr);
if (f != NULL)
return I40E_SUCCESS;
+ if ((mac_filter->filter_type == RTE_MACVLAN_PERFECT_MATCH) ||
+ (mac_filter->filter_type == RTE_MACVLAN_HASH_MATCH)) {
- /**
- * If vlan_num is 0, that's the first time to add mac,
- * set mask for vlan_id 0.
- */
- if (vsi->vlan_num == 0) {
- i40e_set_vlan_filter(vsi, 0, 1);
- vsi->vlan_num = 1;
- }
-
- vlan_num = vsi->vlan_num;
+ /**
+ * If vlan_num is 0, that's the first time to add mac,
+ * set mask for vlan_id 0.
+ */
+ if (vsi->vlan_num == 0) {
+ i40e_set_vlan_filter(vsi, 0, 1);
+ vsi->vlan_num = 1;
+ }
+ vlan_num = vsi->vlan_num;
+ } else if ((mac_filter->filter_type == RTE_MAC_PERFECT_MATCH) ||
+ (mac_filter->filter_type == RTE_MAC_HASH_MATCH))
+ vlan_num = 1;
mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
if (mv_f == NULL) {
@@ -3865,9 +3928,19 @@ i40e_vsi_add_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
return I40E_ERR_NO_MEMORY;
}
- ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num, addr);
- if (ret != I40E_SUCCESS)
- goto DONE;
+ for (i = 0; i < vlan_num; i++) {
+ mv_f[i].filter_type = mac_filter->filter_type;
+ (void)rte_memcpy(&mv_f[i].macaddr, &mac_filter->mac_addr,
+ ETH_ADDR_LEN);
+ }
+
+ if (mac_filter->filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+ mac_filter->filter_type == RTE_MACVLAN_HASH_MATCH) {
+ ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num,
+ &mac_filter->mac_addr);
+ if (ret != I40E_SUCCESS)
+ goto DONE;
+ }
ret = i40e_add_macvlan_filters(vsi, mv_f, vlan_num);
if (ret != I40E_SUCCESS)
@@ -3880,7 +3953,9 @@ i40e_vsi_add_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
ret = I40E_ERR_NO_MEMORY;
goto DONE;
}
- (void)rte_memcpy(&f->macaddr, addr, ETH_ADDR_LEN);
+ (void)rte_memcpy(&f->mac_info.mac_addr, &mac_filter->mac_addr,
+ ETH_ADDR_LEN);
+ f->mac_info.filter_type = mac_filter->filter_type;
TAILQ_INSERT_TAIL(&vsi->mac_list, f, next);
vsi->mac_num++;
@@ -3896,7 +3971,8 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
{
struct i40e_mac_filter *f;
struct i40e_macvlan_filter *mv_f;
- int vlan_num;
+ int i, vlan_num;
+ enum rte_mac_filter_type filter_type;
int ret = I40E_SUCCESS;
/* Can't find it, return an error */
@@ -3905,19 +3981,34 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr)
return I40E_ERR_PARAM;
vlan_num = vsi->vlan_num;
- if (vlan_num == 0) {
- PMD_DRV_LOG(ERR, "VLAN number shouldn't be 0");
- return I40E_ERR_PARAM;
- }
+ filter_type = f->mac_info.filter_type;
+ if (filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+ filter_type == RTE_MACVLAN_HASH_MATCH) {
+ if (vlan_num == 0) {
+ PMD_DRV_LOG(ERR, "VLAN number shouldn't be 0\n");
+ return I40E_ERR_PARAM;
+ }
+ } else if (filter_type == RTE_MAC_PERFECT_MATCH ||
+ filter_type == RTE_MAC_HASH_MATCH)
+ vlan_num = 1;
+
mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
if (mv_f == NULL) {
PMD_DRV_LOG(ERR, "failed to allocate memory");
return I40E_ERR_NO_MEMORY;
}
- ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num, addr);
- if (ret != I40E_SUCCESS)
- goto DONE;
+ for (i = 0; i < vlan_num; i++) {
+ mv_f[i].filter_type = filter_type;
+ (void)rte_memcpy(&mv_f[i].macaddr, &f->mac_info.mac_addr,
+ ETH_ADDR_LEN);
+ }
+ if (filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+ filter_type == RTE_MACVLAN_HASH_MATCH) {
+ ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num, addr);
+ if (ret != I40E_SUCCESS)
+ goto DONE;
+ }
ret = i40e_remove_macvlan_filters(vsi, mv_f, vlan_num);
if (ret != I40E_SUCCESS)
diff --git a/lib/librte_pmd_i40e/i40e_ethdev.h b/lib/librte_pmd_i40e/i40e_ethdev.h
index 1d42cd2..3ea9768 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev.h
+++ b/lib/librte_pmd_i40e/i40e_ethdev.h
@@ -34,6 +34,8 @@
#ifndef _I40E_ETHDEV_H_
#define _I40E_ETHDEV_H_
+#include <rte_eth_ctrl.h>
+
#define I40E_AQ_LEN 32
#define I40E_AQ_BUF_SZ 4096
/* Number of queues per TC should be one of 1, 2, 4, 8, 16, 32, 64 */
@@ -100,12 +102,20 @@
struct i40e_adapter;
+/**
+ * MAC filter structure
+ */
+struct i40e_mac_filter_info {
+ enum rte_mac_filter_type filter_type;
+ struct ether_addr mac_addr;
+};
+
TAILQ_HEAD(i40e_mac_filter_list, i40e_mac_filter);
/* MAC filter list structure */
struct i40e_mac_filter {
TAILQ_ENTRY(i40e_mac_filter) next;
- struct ether_addr macaddr;
+ struct i40e_mac_filter_info mac_info;
};
TAILQ_HEAD(i40e_vsi_list_head, i40e_vsi_list);
@@ -131,11 +141,13 @@ struct i40e_veb {
struct i40e_eth_stats stats;
};
-/* MACVLAN filter structure */
+/* i40e MACVLAN filter structure */
struct i40e_macvlan_filter {
struct ether_addr macaddr;
+ enum rte_mac_filter_type filter_type;
uint16_t vlan_id;
};
+
/*
* Structure that defines a VSI, associated with a adapter.
*/
@@ -332,7 +344,7 @@ int i40e_switch_rx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on);
int i40e_switch_tx_queue(struct i40e_hw *hw, uint16_t q_idx, bool on);
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, uint16_t vlan);
int i40e_vsi_delete_vlan(struct i40e_vsi *vsi, uint16_t vlan);
-int i40e_vsi_add_mac(struct i40e_vsi *vsi, struct ether_addr *addr);
+int i40e_vsi_add_mac(struct i40e_vsi *vsi, struct i40e_mac_filter_info *filter);
int i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct ether_addr *addr);
void i40e_update_vsi_stats(struct i40e_vsi *vsi);
void i40e_pf_disable_irq0(struct i40e_hw *hw);
diff --git a/lib/librte_pmd_i40e/i40e_pf.c b/lib/librte_pmd_i40e/i40e_pf.c
index 682ff44..f9049e1 100644
--- a/lib/librte_pmd_i40e/i40e_pf.c
+++ b/lib/librte_pmd_i40e/i40e_pf.c
@@ -597,9 +597,12 @@ i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf,
int ret = I40E_SUCCESS;
struct i40e_virtchnl_ether_addr_list *addr_list =
(struct i40e_virtchnl_ether_addr_list *)msg;
+ struct i40e_mac_filter_info filter;
int i;
struct ether_addr *mac;
+ memset(&filter, 0 , sizeof(struct i40e_mac_filter_info));
+
if (msg == NULL || msglen <= sizeof(*addr_list)) {
PMD_DRV_LOG(ERR, "add_ether_address argument too short");
ret = I40E_ERR_PARAM;
@@ -608,8 +611,10 @@ i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf,
for (i = 0; i < addr_list->num_elements; i++) {
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, mac)) {
+ i40e_vsi_add_mac(vf->vsi, &filter)) {
ret = I40E_ERR_INVALID_MAC_ADDR;
goto send_msg;
}
--
1.7.7.6
next prev parent reply other threads:[~2014-10-24 7:50 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-23 3:29 [dpdk-dev] [PATCH 0/5]support filter of unicast and multicast MAC address for VF on Fortville Jijiang Liu
2014-09-23 3:29 ` [dpdk-dev] [PATCH 1/5]librte_ether:use new filter framework Jijiang Liu
2014-09-23 3:29 ` [dpdk-dev] [PATCH 2/5]librte_ether:extend data structures of MACVLAN filter Jijiang Liu
2014-09-23 3:29 ` [dpdk-dev] [PATCH 3/5]i40e:optimize MACVLAN filter implementation Jijiang Liu
2014-09-23 3:29 ` [dpdk-dev] [PATCH 4/5]i40e:add VF MACVLAN filter implementation in librte_pmd_i40e Jijiang Liu
2014-09-23 3:29 ` [dpdk-dev] [PATCH 5/5]testpmd:test VF MACVLAN filter for i40e Jijiang Liu
2014-10-24 7:58 ` [dpdk-dev] [PATCH v2 0/4] support VF MAC filter on Fortville Jijiang Liu
2014-10-24 7:58 ` [dpdk-dev] [PATCH v2 1/4] librte_ether:extend MAC filter data structures Jijiang Liu
2014-10-24 7:58 ` Jijiang Liu [this message]
2014-10-24 7:58 ` [dpdk-dev] [PATCH v2 3/4] i40e:add VF MAC filter Jijiang Liu
2014-10-24 7:58 ` [dpdk-dev] [PATCH v2 4/4] app/testpmd:test " Jijiang Liu
2014-10-30 22:35 ` [dpdk-dev] [PATCH v2 0/4] support VF MAC filter on Fortville Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1414137525-23582-3-git-send-email-jijiang.liu@intel.com \
--to=jijiang.liu@intel.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).