cxgb4: add support to offload action vlan
authorKumar Sanghvi <kumaras@chelsio.com>
Thu, 21 Sep 2017 18:11:15 +0000 (23:41 +0530)
committerDavid S. Miller <davem@davemloft.net>
Sat, 23 Sep 2017 04:28:01 +0000 (21:28 -0700)
Add support for offloading tc-flower flows having
vlan actions: pop, push and modify.

Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c

index dda34d5..e42d2ef 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <net/tc_act/tc_gact.h>
 #include <net/tc_act/tc_mirred.h>
+#include <net/tc_act/tc_vlan.h>
 
 #include "cxgb4.h"
 #include "cxgb4_tc_flower.h"
@@ -185,6 +186,27 @@ static void cxgb4_process_flow_actions(struct net_device *in,
 
                        fs->action = FILTER_SWITCH;
                        fs->eport = pi->port_id;
+               } else if (is_tcf_vlan(a)) {
+                       u32 vlan_action = tcf_vlan_action(a);
+                       u8 prio = tcf_vlan_push_prio(a);
+                       u16 vid = tcf_vlan_push_vid(a);
+                       u16 vlan_tci = (prio << VLAN_PRIO_SHIFT) | vid;
+
+                       switch (vlan_action) {
+                       case TCA_VLAN_ACT_POP:
+                               fs->newvlan |= VLAN_REMOVE;
+                               break;
+                       case TCA_VLAN_ACT_PUSH:
+                               fs->newvlan |= VLAN_INSERT;
+                               fs->vlan = vlan_tci;
+                               break;
+                       case TCA_VLAN_ACT_MODIFY:
+                               fs->newvlan |= VLAN_REWRITE;
+                               fs->vlan = vlan_tci;
+                               break;
+                       default:
+                               break;
+                       }
                }
        }
 }
@@ -222,6 +244,26 @@ static int cxgb4_validate_flow_actions(struct net_device *dev,
                                           __func__);
                                return -EINVAL;
                        }
+               } else if (is_tcf_vlan(a)) {
+                       u16 proto = be16_to_cpu(tcf_vlan_push_proto(a));
+                       u32 vlan_action = tcf_vlan_action(a);
+
+                       switch (vlan_action) {
+                       case TCA_VLAN_ACT_POP:
+                               break;
+                       case TCA_VLAN_ACT_PUSH:
+                       case TCA_VLAN_ACT_MODIFY:
+                               if (proto != ETH_P_8021Q) {
+                                       netdev_err(dev, "%s: Unsupported vlan proto\n",
+                                                  __func__);
+                                       return -EOPNOTSUPP;
+                               }
+                               break;
+                       default:
+                               netdev_err(dev, "%s: Unsupported vlan action\n",
+                                          __func__);
+                               return -EOPNOTSUPP;
+                       }
                } else {
                        netdev_err(dev, "%s: Unsupported action\n", __func__);
                        return -EOPNOTSUPP;