aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn Fastabend <john.r.fastabend@intel.com>2013-11-06 12:54:46 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-07 19:11:41 -0500
commita6cc0cfa72e0b6d9f2c8fd858aacc32313c4f272 (patch)
tree310baaaa6df9798431aeb75ab6df1f13feee81c2 /net
parent1ec4864b10171b0691ee196d7006ae56d2c153f2 (diff)
net: Add layer 2 hardware acceleration operations for macvlan devices
Add a operations structure that allows a network interface to export the fact that it supports package forwarding in hardware between physical interfaces and other mac layer devices assigned to it (such as macvlans). This operaions structure can be used by virtual mac devices to bypass software switching so that forwarding can be done in hardware more efficiently. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: Neil Horman <nhorman@tuxdriver.com> CC: Andy Gospodarek <andy@greyhouse.net> CC: "David S. Miller" <davem@davemloft.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c18
-rw-r--r--net/core/ethtool.c1
-rw-r--r--net/sched/sch_generic.c2
3 files changed, 15 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 0e6136546a8c..8ffc52e01ece 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2538,7 +2538,7 @@ static inline int skb_needs_linearize(struct sk_buff *skb,
2538} 2538}
2539 2539
2540int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, 2540int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
2541 struct netdev_queue *txq) 2541 struct netdev_queue *txq, void *accel_priv)
2542{ 2542{
2543 const struct net_device_ops *ops = dev->netdev_ops; 2543 const struct net_device_ops *ops = dev->netdev_ops;
2544 int rc = NETDEV_TX_OK; 2544 int rc = NETDEV_TX_OK;
@@ -2604,9 +2604,13 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
2604 dev_queue_xmit_nit(skb, dev); 2604 dev_queue_xmit_nit(skb, dev);
2605 2605
2606 skb_len = skb->len; 2606 skb_len = skb->len;
2607 rc = ops->ndo_start_xmit(skb, dev); 2607 if (accel_priv)
2608 rc = ops->ndo_dfwd_start_xmit(skb, dev, accel_priv);
2609 else
2610 rc = ops->ndo_start_xmit(skb, dev);
2611
2608 trace_net_dev_xmit(skb, rc, dev, skb_len); 2612 trace_net_dev_xmit(skb, rc, dev, skb_len);
2609 if (rc == NETDEV_TX_OK) 2613 if (rc == NETDEV_TX_OK && txq)
2610 txq_trans_update(txq); 2614 txq_trans_update(txq);
2611 return rc; 2615 return rc;
2612 } 2616 }
@@ -2622,7 +2626,10 @@ gso:
2622 dev_queue_xmit_nit(nskb, dev); 2626 dev_queue_xmit_nit(nskb, dev);
2623 2627
2624 skb_len = nskb->len; 2628 skb_len = nskb->len;
2625 rc = ops->ndo_start_xmit(nskb, dev); 2629 if (accel_priv)
2630 rc = ops->ndo_dfwd_start_xmit(nskb, dev, accel_priv);
2631 else
2632 rc = ops->ndo_start_xmit(nskb, dev);
2626 trace_net_dev_xmit(nskb, rc, dev, skb_len); 2633 trace_net_dev_xmit(nskb, rc, dev, skb_len);
2627 if (unlikely(rc != NETDEV_TX_OK)) { 2634 if (unlikely(rc != NETDEV_TX_OK)) {
2628 if (rc & ~NETDEV_TX_MASK) 2635 if (rc & ~NETDEV_TX_MASK)
@@ -2647,6 +2654,7 @@ out_kfree_skb:
2647out: 2654out:
2648 return rc; 2655 return rc;
2649} 2656}
2657EXPORT_SYMBOL_GPL(dev_hard_start_xmit);
2650 2658
2651static void qdisc_pkt_len_init(struct sk_buff *skb) 2659static void qdisc_pkt_len_init(struct sk_buff *skb)
2652{ 2660{
@@ -2854,7 +2862,7 @@ int dev_queue_xmit(struct sk_buff *skb)
2854 2862
2855 if (!netif_xmit_stopped(txq)) { 2863 if (!netif_xmit_stopped(txq)) {
2856 __this_cpu_inc(xmit_recursion); 2864 __this_cpu_inc(xmit_recursion);
2857 rc = dev_hard_start_xmit(skb, dev, txq); 2865 rc = dev_hard_start_xmit(skb, dev, txq, NULL);
2858 __this_cpu_dec(xmit_recursion); 2866 __this_cpu_dec(xmit_recursion);
2859 if (dev_xmit_complete(rc)) { 2867 if (dev_xmit_complete(rc)) {
2860 HARD_TX_UNLOCK(dev, txq); 2868 HARD_TX_UNLOCK(dev, txq);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 862989898f61..30071dec287a 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -96,6 +96,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN]
96 [NETIF_F_LOOPBACK_BIT] = "loopback", 96 [NETIF_F_LOOPBACK_BIT] = "loopback",
97 [NETIF_F_RXFCS_BIT] = "rx-fcs", 97 [NETIF_F_RXFCS_BIT] = "rx-fcs",
98 [NETIF_F_RXALL_BIT] = "rx-all", 98 [NETIF_F_RXALL_BIT] = "rx-all",
99 [NETIF_F_HW_L2FW_DOFFLOAD_BIT] = "l2-fwd-offload",
99}; 100};
100 101
101static int ethtool_get_features(struct net_device *dev, void __user *useraddr) 102static int ethtool_get_features(struct net_device *dev, void __user *useraddr)
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 7fc899a943a8..922a09406ba7 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -126,7 +126,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
126 126
127 HARD_TX_LOCK(dev, txq, smp_processor_id()); 127 HARD_TX_LOCK(dev, txq, smp_processor_id());
128 if (!netif_xmit_frozen_or_stopped(txq)) 128 if (!netif_xmit_frozen_or_stopped(txq))
129 ret = dev_hard_start_xmit(skb, dev, txq); 129 ret = dev_hard_start_xmit(skb, dev, txq, NULL);
130 130
131 HARD_TX_UNLOCK(dev, txq); 131 HARD_TX_UNLOCK(dev, txq);
132 132