Merge branch 'cxgb4-more-flower-offloads'
authorDavid S. Miller <davem@davemloft.net>
Fri, 20 Oct 2017 12:06:53 +0000 (13:06 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 20 Oct 2017 12:09:09 +0000 (13:09 +0100)
Rahul Lakkireddy says:

====================
cxgb4: enable more tc flower offload matches and actions

This patch series enable more matches and actions for TC Flower
Offload support on Chelsio adapters.

Patch 1 enables matching on IP TOS.

Patch 2 enables matching on VLAN TCI.

Patch 3 adds support for action PASS.

Patch 4 adds support for ETH-DMAC rewrite via TC-PEDIT action. Also,
adds a check to assert that vlan/eth-dmac rewrite actions are valid
only in combination with action egress redirect.

Patch 5 introduces SMT ops for adding/removing entries from SMAC Table
in HW in preparation for patch 6.

Patch 6 adds support for ETH-SMAC rewrite via TC-PEDIT action.

Patch 7 introduces fw_filter2_wr to support L3/L4 header rewrites
in preparation for patch 8.

Patch 8 adds support for rewrite on L3/L4 header fields via TC-PEDIT
action. Supported fields for rewrite are:
IPv4 src/dst address, IPv6 src/dst address, TCP/UDP sport/dport.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
1  2 
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c

index 92a31176738186cf412c5b4bedd5e9c80a3b92f8,892dfce1fa6391f7a7d3ea70cfd414f520c5707b..9b6aabe4f96318d4d8213ddc58d0af1e9d53d0bd
@@@ -170,6 -289,112 +289,112 @@@ static int cxgb4_validate_flow_match(st
        return 0;
  }
  
 -      u32 offset;
 -      u8 size;
+ static void offload_pedit(struct ch_filter_specification *fs, u32 val, u32 mask,
+                         u8 field)
+ {
+       u32 set_val = val & ~mask;
++      u32 offset = 0;
++      u8 size = 1;
+       int i;
+       for (i = 0; i < ARRAY_SIZE(pedits); i++) {
+               if (pedits[i].field == field) {
+                       offset = pedits[i].offset;
+                       size = pedits[i].size;
+                       break;
+               }
+       }
+       memcpy((u8 *)fs + offset, &set_val, size);
+ }
+ static void process_pedit_field(struct ch_filter_specification *fs, u32 val,
+                               u32 mask, u32 offset, u8 htype)
+ {
+       switch (htype) {
+       case TCA_PEDIT_KEY_EX_HDR_TYPE_ETH:
+               switch (offset) {
+               case PEDIT_ETH_DMAC_31_0:
+                       fs->newdmac = 1;
+                       offload_pedit(fs, val, mask, ETH_DMAC_31_0);
+                       break;
+               case PEDIT_ETH_DMAC_47_32_SMAC_15_0:
+                       if (~mask & PEDIT_ETH_DMAC_MASK)
+                               offload_pedit(fs, val, mask, ETH_DMAC_47_32);
+                       else
+                               offload_pedit(fs, val >> 16, mask >> 16,
+                                             ETH_SMAC_15_0);
+                       break;
+               case PEDIT_ETH_SMAC_47_16:
+                       fs->newsmac = 1;
+                       offload_pedit(fs, val, mask, ETH_SMAC_47_16);
+               }
+               break;
+       case TCA_PEDIT_KEY_EX_HDR_TYPE_IP4:
+               switch (offset) {
+               case PEDIT_IP4_SRC:
+                       offload_pedit(fs, val, mask, IP4_SRC);
+                       break;
+               case PEDIT_IP4_DST:
+                       offload_pedit(fs, val, mask, IP4_DST);
+               }
+               fs->nat_mode = NAT_MODE_ALL;
+               break;
+       case TCA_PEDIT_KEY_EX_HDR_TYPE_IP6:
+               switch (offset) {
+               case PEDIT_IP6_SRC_31_0:
+                       offload_pedit(fs, val, mask, IP6_SRC_31_0);
+                       break;
+               case PEDIT_IP6_SRC_63_32:
+                       offload_pedit(fs, val, mask, IP6_SRC_63_32);
+                       break;
+               case PEDIT_IP6_SRC_95_64:
+                       offload_pedit(fs, val, mask, IP6_SRC_95_64);
+                       break;
+               case PEDIT_IP6_SRC_127_96:
+                       offload_pedit(fs, val, mask, IP6_SRC_127_96);
+                       break;
+               case PEDIT_IP6_DST_31_0:
+                       offload_pedit(fs, val, mask, IP6_DST_31_0);
+                       break;
+               case PEDIT_IP6_DST_63_32:
+                       offload_pedit(fs, val, mask, IP6_DST_63_32);
+                       break;
+               case PEDIT_IP6_DST_95_64:
+                       offload_pedit(fs, val, mask, IP6_DST_95_64);
+                       break;
+               case PEDIT_IP6_DST_127_96:
+                       offload_pedit(fs, val, mask, IP6_DST_127_96);
+               }
+               fs->nat_mode = NAT_MODE_ALL;
+               break;
+       case TCA_PEDIT_KEY_EX_HDR_TYPE_TCP:
+               switch (offset) {
+               case PEDIT_TCP_SPORT_DPORT:
+                       if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
+                               offload_pedit(fs, cpu_to_be32(val) >> 16,
+                                             cpu_to_be32(mask) >> 16,
+                                             TCP_SPORT);
+                       else
+                               offload_pedit(fs, cpu_to_be32(val),
+                                             cpu_to_be32(mask), TCP_DPORT);
+               }
+               fs->nat_mode = NAT_MODE_ALL;
+               break;
+       case TCA_PEDIT_KEY_EX_HDR_TYPE_UDP:
+               switch (offset) {
+               case PEDIT_UDP_SPORT_DPORT:
+                       if (~mask & PEDIT_TCP_UDP_SPORT_MASK)
+                               offload_pedit(fs, cpu_to_be32(val) >> 16,
+                                             cpu_to_be32(mask) >> 16,
+                                             UDP_SPORT);
+                       else
+                               offload_pedit(fs, cpu_to_be32(val),
+                                             cpu_to_be32(mask), UDP_DPORT);
+               }
+               fs->nat_mode = NAT_MODE_ALL;
+       }
+ }
  static void cxgb4_process_flow_actions(struct net_device *in,
                                       struct tc_cls_flower_offload *cls,
                                       struct ch_filter_specification *fs)