@@ -58,6 +58,7 @@ New Features
Flow API support has been enhanced for CXGBE Poll Mode Driver to offload:
+ * Match items: destination MAC address.
* Action items: push/pop/rewrite vlan header.
@@ -157,6 +157,7 @@ struct tp_params {
int port_shift;
int protocol_shift;
int ethertype_shift;
+ int macmatch_shift;
u64 hash_filter_mask;
};
@@ -5251,6 +5251,8 @@ int t4_init_tp_params(struct adapter *adap)
F_PROTOCOL);
adap->params.tp.ethertype_shift = t4_filter_field_shift(adap,
F_ETHERTYPE);
+ adap->params.tp.macmatch_shift = t4_filter_field_shift(adap,
+ F_MACMATCH);
/*
* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
@@ -1075,11 +1075,9 @@ static int cxgbe_get_regs(struct rte_eth_dev *eth_dev,
int cxgbe_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *addr)
{
struct port_info *pi = (struct port_info *)(dev->data->dev_private);
- struct adapter *adapter = pi->adapter;
int ret;
- ret = t4_change_mac(adapter, adapter->mbox, pi->viid,
- pi->xact_addr_filt, (u8 *)addr, true, true);
+ ret = cxgbe_mpstcam_modify(pi, (int)pi->xact_addr_filt, (u8 *)addr);
if (ret < 0) {
dev_err(adapter, "failed to set mac addr; err = %d\n",
ret);
@@ -66,7 +66,8 @@ int validate_filter(struct adapter *adapter, struct ch_filter_specification *fs)
#define U(_mask, _field) \
(!(fconf & (_mask)) && S(_field))
- if (U(F_PORT, iport) || U(F_ETHERTYPE, ethtype) || U(F_PROTOCOL, proto))
+ if (U(F_PORT, iport) || U(F_ETHERTYPE, ethtype) ||
+ U(F_PROTOCOL, proto) || U(F_MACMATCH, macidx))
return -EOPNOTSUPP;
#undef S
@@ -268,6 +269,8 @@ static u64 hash_filter_ntuple(const struct filter_entry *f)
if (tp->ethertype_shift >= 0 && f->fs.mask.ethtype)
ntuple |= (u64)(f->fs.val.ethtype) << tp->ethertype_shift;
+ if (tp->macmatch_shift >= 0 && f->fs.mask.macidx)
+ ntuple |= (u64)(f->fs.val.macidx) << tp->macmatch_shift;
if (ntuple != tp->hash_filter_mask)
return 0;
@@ -744,7 +747,9 @@ int set_filter_wr(struct rte_eth_dev *dev, unsigned int fidx)
V_FW_FILTER_WR_RX_RPL_IQ(adapter->sge.fw_evtq.abs_id
));
fwr->maci_to_matchtypem =
- cpu_to_be32(V_FW_FILTER_WR_PORT(f->fs.val.iport) |
+ cpu_to_be32(V_FW_FILTER_WR_MACI(f->fs.val.macidx) |
+ V_FW_FILTER_WR_MACIM(f->fs.mask.macidx) |
+ V_FW_FILTER_WR_PORT(f->fs.val.iport) |
V_FW_FILTER_WR_PORTM(f->fs.mask.iport));
fwr->ptcl = f->fs.val.proto;
fwr->ptclm = f->fs.mask.proto;
@@ -77,6 +77,7 @@ struct ch_filter_tuple {
* Filter specification
*/
struct ch_filter_specification {
+ void *private;
/* Administrative fields for filter. */
uint32_t hitcnts:1; /* count filter hits in TCB */
uint32_t prio:1; /* filter has priority over active/server */
@@ -95,6 +95,8 @@ cxgbe_fill_filter_region(struct adapter *adap,
ntuple_mask |= (u64)fs->mask.ethtype << tp->ethertype_shift;
if (tp->port_shift >= 0)
ntuple_mask |= (u64)fs->mask.iport << tp->port_shift;
+ if (tp->macmatch_shift >= 0)
+ ntuple_mask |= (u64)fs->mask.macidx << tp->macmatch_shift;
if (ntuple_mask != hash_filter_mask)
return;
@@ -102,6 +104,46 @@ cxgbe_fill_filter_region(struct adapter *adap,
fs->cap = 1; /* use hash region */
}
+static int
+ch_rte_parsetype_eth(const void *dmask, const struct rte_flow_item *item,
+ struct ch_filter_specification *fs,
+ struct rte_flow_error *e)
+{
+ const struct rte_flow_item_eth *spec = item->spec;
+ const struct rte_flow_item_eth *umask = item->mask;
+ const struct rte_flow_item_eth *mask;
+
+ /* If user has not given any mask, then use chelsio supported mask. */
+ mask = umask ? umask : (const struct rte_flow_item_eth *)dmask;
+
+ /* we don't support SRC_MAC filtering*/
+ if (!is_zero_ether_addr(&mask->src))
+ return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "src mac filtering not supported");
+
+ if (!is_zero_ether_addr(&mask->dst)) {
+ const u8 *addr = (const u8 *)&spec->dst.addr_bytes[0];
+ const u8 *m = (const u8 *)&mask->dst.addr_bytes[0];
+ struct rte_flow *flow = (struct rte_flow *)fs->private;
+ struct port_info *pi = (struct port_info *)
+ (flow->dev->data->dev_private);
+ int idx;
+
+ idx = cxgbe_mpstcam_alloc(pi, addr, m);
+ if (idx <= 0)
+ return rte_flow_error_set(e, idx,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "unable to allocate mac"
+ " entry in h/w");
+ CXGBE_FILL_FS(idx, 0x1ff, macidx);
+ }
+
+ CXGBE_FILL_FS(be16_to_cpu(spec->type),
+ be16_to_cpu(mask->type), ethtype);
+ return 0;
+}
+
static int
ch_rte_parsetype_port(const void *dmask, const struct rte_flow_item *item,
struct ch_filter_specification *fs,
@@ -440,7 +482,16 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow,
}
struct chrte_fparse parseitem[] = {
- [RTE_FLOW_ITEM_TYPE_PHY_PORT] = {
+ [RTE_FLOW_ITEM_TYPE_ETH] = {
+ .fptr = ch_rte_parsetype_eth,
+ .dmask = &(const struct rte_flow_item_eth){
+ .dst.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+ .src.addr_bytes = "\x00\x00\x00\x00\x00\x00",
+ .type = 0xffff,
+ }
+ },
+
+ [RTE_FLOW_ITEM_TYPE_PHY_PORT] = {
.fptr = ch_rte_parsetype_port,
.dmask = &(const struct rte_flow_item_phy_port){
.index = 0x7,
@@ -527,7 +578,6 @@ cxgbe_flow_parse(struct rte_flow *flow,
struct rte_flow_error *e)
{
int ret;
-
/* parse user request into ch_filter_specification */
ret = cxgbe_rtef_parse_attr(flow, attr, e);
if (ret)
@@ -606,6 +656,7 @@ cxgbe_flow_create(struct rte_eth_dev *dev,
flow->item_parser = parseitem;
flow->dev = dev;
+ flow->fs.private = (void *)flow;
if (cxgbe_flow_parse(flow, attr, item, action, e)) {
t4_os_free(flow);
@@ -660,6 +711,17 @@ static int __cxgbe_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
return ctx.result;
}
+ fs = &flow->fs;
+ if (fs->mask.macidx) {
+ struct port_info *pi = (struct port_info *)
+ (dev->data->dev_private);
+ int ret;
+
+ ret = cxgbe_mpstcam_remove(pi, fs->val.macidx);
+ if (!ret)
+ return ret;
+ }
+
return 0;
}
@@ -7,6 +7,7 @@
#include <rte_flow_driver.h>
#include "cxgbe_filter.h"
+#include "mps_tcam.h"
#include "cxgbe.h"
#define CXGBE_FLOW_POLL_US 10
@@ -1342,10 +1342,8 @@ int link_start(struct port_info *pi)
ret = t4_set_rxmode(adapter, adapter->mbox, pi->viid, mtu, -1, -1,
-1, 1, true);
if (ret == 0) {
- ret = t4_change_mac(adapter, adapter->mbox, pi->viid,
- pi->xact_addr_filt,
- (u8 *)&pi->eth_dev->data->mac_addrs[0],
- true, true);
+ ret = cxgbe_mpstcam_modify(pi, (int)pi->xact_addr_filt,
+ (u8 *)&pi->eth_dev->data->mac_addrs[0]);
if (ret >= 0) {
pi->xact_addr_filt = ret;
ret = 0;