X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcxgbe%2Fcxgbe_flow.c;h=edcbba9d7c212d96329f5cd4f5829957068fdbcb;hb=586e6028371764452b7dbae3b1f50adde87be80e;hp=138d0758fcccb57d594a44f5e72491a4cc7ec5bb;hpb=caa01424337c5bc26c30817723d8001b86784645;p=dpdk.git diff --git a/drivers/net/cxgbe/cxgbe_flow.c b/drivers/net/cxgbe/cxgbe_flow.c index 138d0758fc..edcbba9d7c 100644 --- a/drivers/net/cxgbe/cxgbe_flow.c +++ b/drivers/net/cxgbe/cxgbe_flow.c @@ -159,9 +159,9 @@ cxgbe_fill_filter_region(struct adapter *adap, ntuple_mask |= (u64)(fs->val.ovlan_vld << 16 | fs->mask.ovlan) << tp->vnic_shift; else if (fs->mask.pfvf_vld) - ntuple_mask |= (u64)((fs->mask.pfvf_vld << 16) | - (fs->mask.pf << 13)) << - tp->vnic_shift; + ntuple_mask |= (u64)(fs->mask.pfvf_vld << 16 | + fs->mask.pf << 13 | + fs->mask.vf) << tp->vnic_shift; } if (tp->tos_shift >= 0) ntuple_mask |= (u64)fs->mask.tos << tp->tos_shift; @@ -188,30 +188,22 @@ ch_rte_parsetype_eth(const void *dmask, const struct rte_flow_item *item, return 0; /* we don't support SRC_MAC filtering*/ - if (!rte_is_zero_ether_addr(&mask->src)) + if (!rte_is_zero_ether_addr(&spec->src) || + (umask && !rte_is_zero_ether_addr(&umask->src))) return rte_flow_error_set(e, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, "src mac filtering not supported"); - if (!rte_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); + if (!rte_is_zero_ether_addr(&spec->dst) || + (umask && !rte_is_zero_ether_addr(&umask->dst))) { + CXGBE_FILL_FS(0, 0x1ff, macidx); + CXGBE_FILL_FS_MEMCPY(spec->dst.addr_bytes, mask->dst.addr_bytes, + dmac); } - CXGBE_FILL_FS(be16_to_cpu(spec->type), - be16_to_cpu(mask->type), ethtype); + if (spec->type || (umask && umask->type)) + CXGBE_FILL_FS(be16_to_cpu(spec->type), + be16_to_cpu(mask->type), ethtype); return 0; } @@ -233,9 +225,10 @@ ch_rte_parsetype_port(const void *dmask, const struct rte_flow_item *item, if (val->index > 0x7) return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, - "port index upto 0x7 is supported"); + "port index up to 0x7 is supported"); - CXGBE_FILL_FS(val->index, mask->index, iport); + if (val->index || (umask && umask->index)) + CXGBE_FILL_FS(val->index, mask->index, iport); return 0; } @@ -252,11 +245,6 @@ ch_rte_parsetype_vlan(const void *dmask, const struct rte_flow_item *item, /* If user has not given any mask, then use chelsio supported mask. */ mask = umask ? umask : (const struct rte_flow_item_vlan *)dmask; - if (!fs->mask.ethtype) - return rte_flow_error_set(e, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, - item, - "Can't parse VLAN item without knowing ethertype"); - /* If ethertype is already set and is not VLAN (0x8100) or * QINQ(0x88A8), then don't proceed further. Otherwise, * reset the outer ethertype, so that it can be replaced by @@ -276,24 +264,24 @@ ch_rte_parsetype_vlan(const void *dmask, const struct rte_flow_item *item, if (fs->val.ethtype == RTE_ETHER_TYPE_QINQ) { CXGBE_FILL_FS(1, 1, ovlan_vld); if (spec) { - CXGBE_FILL_FS(be16_to_cpu(spec->tci), - be16_to_cpu(mask->tci), ovlan); - + if (spec->tci || (umask && umask->tci)) + CXGBE_FILL_FS(be16_to_cpu(spec->tci), + be16_to_cpu(mask->tci), ovlan); fs->mask.ethtype = 0; fs->val.ethtype = 0; } - } else if (fs->val.ethtype == RTE_ETHER_TYPE_VLAN) { + } else { CXGBE_FILL_FS(1, 1, ivlan_vld); if (spec) { - CXGBE_FILL_FS(be16_to_cpu(spec->tci), - be16_to_cpu(mask->tci), ivlan); - + if (spec->tci || (umask && umask->tci)) + CXGBE_FILL_FS(be16_to_cpu(spec->tci), + be16_to_cpu(mask->tci), ivlan); fs->mask.ethtype = 0; fs->val.ethtype = 0; } } - if (spec) + if (spec && (spec->inner_type || (umask && umask->inner_type))) CXGBE_FILL_FS(be16_to_cpu(spec->inner_type), be16_to_cpu(mask->inner_type), ethtype); @@ -316,6 +304,35 @@ ch_rte_parsetype_pf(const void *dmask __rte_unused, return 0; } +static int +ch_rte_parsetype_vf(const void *dmask, const struct rte_flow_item *item, + struct ch_filter_specification *fs, + struct rte_flow_error *e) +{ + const struct rte_flow_item_vf *umask = item->mask; + const struct rte_flow_item_vf *val = item->spec; + const struct rte_flow_item_vf *mask; + + /* If user has not given any mask, then use chelsio supported mask. */ + mask = umask ? umask : (const struct rte_flow_item_vf *)dmask; + + CXGBE_FILL_FS(1, 1, pfvf_vld); + + if (!val) + return 0; /* Wildcard, match all Vf */ + + if (val->id > UCHAR_MAX) + return rte_flow_error_set(e, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "VF ID > MAX(255)"); + + if (val->id || (umask && umask->id)) + CXGBE_FILL_FS(val->id, mask->id, vf); + + return 0; +} + static int ch_rte_parsetype_udp(const void *dmask, const struct rte_flow_item *item, struct ch_filter_specification *fs, @@ -335,10 +352,15 @@ ch_rte_parsetype_udp(const void *dmask, const struct rte_flow_item *item, CXGBE_FILL_FS(IPPROTO_UDP, 0xff, proto); if (!val) return 0; - CXGBE_FILL_FS(be16_to_cpu(val->hdr.src_port), - be16_to_cpu(mask->hdr.src_port), fport); - CXGBE_FILL_FS(be16_to_cpu(val->hdr.dst_port), - be16_to_cpu(mask->hdr.dst_port), lport); + + if (val->hdr.src_port || (umask && umask->hdr.src_port)) + CXGBE_FILL_FS(be16_to_cpu(val->hdr.src_port), + be16_to_cpu(mask->hdr.src_port), fport); + + if (val->hdr.dst_port || (umask && umask->hdr.dst_port)) + CXGBE_FILL_FS(be16_to_cpu(val->hdr.dst_port), + be16_to_cpu(mask->hdr.dst_port), lport); + return 0; } @@ -363,10 +385,15 @@ ch_rte_parsetype_tcp(const void *dmask, const struct rte_flow_item *item, CXGBE_FILL_FS(IPPROTO_TCP, 0xff, proto); if (!val) return 0; - CXGBE_FILL_FS(be16_to_cpu(val->hdr.src_port), - be16_to_cpu(mask->hdr.src_port), fport); - CXGBE_FILL_FS(be16_to_cpu(val->hdr.dst_port), - be16_to_cpu(mask->hdr.dst_port), lport); + + if (val->hdr.src_port || (umask && umask->hdr.src_port)) + CXGBE_FILL_FS(be16_to_cpu(val->hdr.src_port), + be16_to_cpu(mask->hdr.src_port), fport); + + if (val->hdr.dst_port || (umask && umask->hdr.dst_port)) + CXGBE_FILL_FS(be16_to_cpu(val->hdr.dst_port), + be16_to_cpu(mask->hdr.dst_port), lport); + return 0; } @@ -394,10 +421,21 @@ ch_rte_parsetype_ipv4(const void *dmask, const struct rte_flow_item *item, if (!val) return 0; /* ipv4 wild card */ - CXGBE_FILL_FS(val->hdr.next_proto_id, mask->hdr.next_proto_id, proto); - CXGBE_FILL_FS_MEMCPY(val->hdr.dst_addr, mask->hdr.dst_addr, lip); - CXGBE_FILL_FS_MEMCPY(val->hdr.src_addr, mask->hdr.src_addr, fip); - CXGBE_FILL_FS(val->hdr.type_of_service, mask->hdr.type_of_service, tos); + if (val->hdr.next_proto_id || (umask && umask->hdr.next_proto_id)) + CXGBE_FILL_FS(val->hdr.next_proto_id, mask->hdr.next_proto_id, + proto); + + if (val->hdr.dst_addr || (umask && umask->hdr.dst_addr)) + CXGBE_FILL_FS_MEMCPY(val->hdr.dst_addr, mask->hdr.dst_addr, + lip); + + if (val->hdr.src_addr || (umask && umask->hdr.src_addr)) + CXGBE_FILL_FS_MEMCPY(val->hdr.src_addr, mask->hdr.src_addr, + fip); + + if (val->hdr.type_of_service || (umask && umask->hdr.type_of_service)) + CXGBE_FILL_FS(val->hdr.type_of_service, + mask->hdr.type_of_service, tos); return 0; } @@ -411,6 +449,7 @@ ch_rte_parsetype_ipv6(const void *dmask, const struct rte_flow_item *item, const struct rte_flow_item_ipv6 *umask = item->mask; const struct rte_flow_item_ipv6 *mask; u32 vtc_flow, vtc_flow_mask; + u8 z[16] = { 0 }; mask = umask ? umask : (const struct rte_flow_item_ipv6 *)dmask; @@ -431,17 +470,28 @@ ch_rte_parsetype_ipv6(const void *dmask, const struct rte_flow_item *item, if (!val) return 0; /* ipv6 wild card */ - CXGBE_FILL_FS(val->hdr.proto, mask->hdr.proto, proto); + if (val->hdr.proto || (umask && umask->hdr.proto)) + CXGBE_FILL_FS(val->hdr.proto, mask->hdr.proto, proto); vtc_flow = be32_to_cpu(val->hdr.vtc_flow); - CXGBE_FILL_FS((vtc_flow & RTE_IPV6_HDR_TC_MASK) >> - RTE_IPV6_HDR_TC_SHIFT, - (vtc_flow_mask & RTE_IPV6_HDR_TC_MASK) >> - RTE_IPV6_HDR_TC_SHIFT, - tos); - - CXGBE_FILL_FS_MEMCPY(val->hdr.dst_addr, mask->hdr.dst_addr, lip); - CXGBE_FILL_FS_MEMCPY(val->hdr.src_addr, mask->hdr.src_addr, fip); + if (val->hdr.vtc_flow || (umask && umask->hdr.vtc_flow)) + CXGBE_FILL_FS((vtc_flow & RTE_IPV6_HDR_TC_MASK) >> + RTE_IPV6_HDR_TC_SHIFT, + (vtc_flow_mask & RTE_IPV6_HDR_TC_MASK) >> + RTE_IPV6_HDR_TC_SHIFT, + tos); + + if (memcmp(val->hdr.dst_addr, z, sizeof(val->hdr.dst_addr)) || + (umask && + memcmp(umask->hdr.dst_addr, z, sizeof(umask->hdr.dst_addr)))) + CXGBE_FILL_FS_MEMCPY(val->hdr.dst_addr, mask->hdr.dst_addr, + lip); + + if (memcmp(val->hdr.src_addr, z, sizeof(val->hdr.src_addr)) || + (umask && + memcmp(umask->hdr.src_addr, z, sizeof(umask->hdr.src_addr)))) + CXGBE_FILL_FS_MEMCPY(val->hdr.src_addr, mask->hdr.src_addr, + fip); return 0; } @@ -619,6 +669,7 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a, const struct rte_flow_action_set_ipv6 *ipv6; const struct rte_flow_action_set_tp *tp_port; const struct rte_flow_action_phy_port *port; + const struct rte_flow_action_set_mac *mac; int item_index; u16 tmp_vlan; @@ -766,6 +817,31 @@ ch_rte_parse_atype_switch(const struct rte_flow_action *a, "found"); fs->swapmac = 1; break; + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: + item_index = cxgbe_get_flow_item_index(items, + RTE_FLOW_ITEM_TYPE_ETH); + if (item_index < 0) + return rte_flow_error_set(e, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, a, + "No RTE_FLOW_ITEM_TYPE_ETH " + "found"); + mac = (const struct rte_flow_action_set_mac *)a->conf; + + fs->newsmac = 1; + memcpy(fs->smac, mac->mac_addr, sizeof(fs->smac)); + break; + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: + item_index = cxgbe_get_flow_item_index(items, + RTE_FLOW_ITEM_TYPE_ETH); + if (item_index < 0) + return rte_flow_error_set(e, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, a, + "No RTE_FLOW_ITEM_TYPE_ETH found"); + mac = (const struct rte_flow_action_set_mac *)a->conf; + + fs->newdmac = 1; + memcpy(fs->dmac, mac->mac_addr, sizeof(fs->dmac)); + break; default: /* We are not supposed to come here */ return rte_flow_error_set(e, EINVAL, @@ -842,6 +918,8 @@ cxgbe_rtef_parse_actions(struct rte_flow *flow, goto action_switch; case RTE_FLOW_ACTION_TYPE_SET_TP_SRC: case RTE_FLOW_ACTION_TYPE_SET_TP_DST: + case RTE_FLOW_ACTION_TYPE_SET_MAC_SRC: + case RTE_FLOW_ACTION_TYPE_SET_MAC_DST: action_switch: /* We allow multiple switch actions, but switch is * not compatible with either queue or drop @@ -948,6 +1026,13 @@ static struct chrte_fparse parseitem[] = { .fptr = ch_rte_parsetype_pf, .dmask = NULL, }, + + [RTE_FLOW_ITEM_TYPE_VF] = { + .fptr = ch_rte_parsetype_vf, + .dmask = &(const struct rte_flow_item_vf){ + .id = 0xffffffff, + } + }, }; static int @@ -999,8 +1084,8 @@ cxgbe_rtef_parse_items(struct rte_flow *flow, } } - cxgbe_fill_filter_region(adap, &flow->fs); cxgbe_tweak_filter_spec(adap, &flow->fs); + cxgbe_fill_filter_region(adap, &flow->fs); return 0; } @@ -1149,17 +1234,6 @@ 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; } @@ -1269,6 +1343,7 @@ cxgbe_flow_validate(struct rte_eth_dev *dev, flow->item_parser = parseitem; flow->dev = dev; + flow->fs.private = (void *)flow; ret = cxgbe_flow_parse(flow, attr, item, action, e); if (ret) { @@ -1373,23 +1448,9 @@ static const struct rte_flow_ops cxgbe_flow_ops = { }; int -cxgbe_dev_filter_ctrl(struct rte_eth_dev *dev, - enum rte_filter_type filter_type, - enum rte_filter_op filter_op, - void *arg) +cxgbe_dev_flow_ops_get(struct rte_eth_dev *dev __rte_unused, + const struct rte_flow_ops **ops) { - int ret = 0; - - RTE_SET_USED(dev); - switch (filter_type) { - case RTE_ETH_FILTER_GENERIC: - if (filter_op != RTE_ETH_FILTER_GET) - return -EINVAL; - *(const void **)arg = &cxgbe_flow_ops; - break; - default: - ret = -ENOTSUP; - break; - } - return ret; + *ops = &cxgbe_flow_ops; + return 0; }