aboutsummaryrefslogtreecommitdiffstats
path: root/net/dsa
diff options
context:
space:
mode:
authorFlorian Fainelli <f.fainelli@gmail.com>2015-07-31 14:42:56 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-31 18:45:37 -0400
commit4ed70ce9f01c998999e48642a768d9013bee2c4f (patch)
treea46d1aafd6b3f82cb854052ff24916ee8a8888af /net/dsa
parent6cec4f5e00a34a1c7407af302470246dd4f8be28 (diff)
net: dsa: Refactor transmit path to eliminate duplication
All tagging protocols do the same thing: increment device statistics, make room for the tag to be inserted, create the tag, invoke the parent network device transmit function. In order to prepare for adding netpoll support, which requires the tag creation, but not using the parent network device transmit function, do some little refactoring which eliminates duplication between the 4 tagging protocols supported. We need to return a sk_buff pointer back to the caller because the tag specific transmit function may have to reallocate the original skb (e.g: tag_trailer.c) and this is the one we should be transmitting, not the original sk_buff we were passed. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/dsa_priv.h4
-rw-r--r--net/dsa/slave.c27
-rw-r--r--net/dsa/tag_brcm.c15
-rw-r--r--net/dsa/tag_dsa.c12
-rw-r--r--net/dsa/tag_edsa.c12
-rw-r--r--net/dsa/tag_trailer.c12
6 files changed, 33 insertions, 49 deletions
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index d5f1f9b862ea..eeade901e67a 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -15,7 +15,7 @@
15#include <linux/netdevice.h> 15#include <linux/netdevice.h>
16 16
17struct dsa_device_ops { 17struct dsa_device_ops {
18 netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev); 18 struct sk_buff *(*xmit)(struct sk_buff *skb, struct net_device *dev);
19 int (*rcv)(struct sk_buff *skb, struct net_device *dev, 19 int (*rcv)(struct sk_buff *skb, struct net_device *dev,
20 struct packet_type *pt, struct net_device *orig_dev); 20 struct packet_type *pt, struct net_device *orig_dev);
21}; 21};
@@ -26,7 +26,7 @@ struct dsa_slave_priv {
26 * switch port. 26 * switch port.
27 */ 27 */
28 struct net_device *dev; 28 struct net_device *dev;
29 netdev_tx_t (*xmit)(struct sk_buff *skb, 29 struct sk_buff * (*xmit)(struct sk_buff *skb,
30 struct net_device *dev); 30 struct net_device *dev);
31 31
32 /* 32 /*
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 0917123790ea..5fc87ee53905 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -421,21 +421,32 @@ static int dsa_slave_port_attr_get(struct net_device *dev,
421static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) 421static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
422{ 422{
423 struct dsa_slave_priv *p = netdev_priv(dev); 423 struct dsa_slave_priv *p = netdev_priv(dev);
424 struct sk_buff *nskb;
424 425
425 return p->xmit(skb, dev); 426 dev->stats.tx_packets++;
426} 427 dev->stats.tx_bytes += skb->len;
427 428
428static netdev_tx_t dsa_slave_notag_xmit(struct sk_buff *skb, 429 /* Transmit function may have to reallocate the original SKB */
429 struct net_device *dev) 430 nskb = p->xmit(skb, dev);
430{ 431 if (!nskb)
431 struct dsa_slave_priv *p = netdev_priv(dev); 432 return NETDEV_TX_OK;
432 433
433 skb->dev = p->parent->dst->master_netdev; 434 /* Queue the SKB for transmission on the parent interface, but
434 dev_queue_xmit(skb); 435 * do not modify its EtherType
436 */
437 nskb->dev = p->parent->dst->master_netdev;
438 dev_queue_xmit(nskb);
435 439
436 return NETDEV_TX_OK; 440 return NETDEV_TX_OK;
437} 441}
438 442
443static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff *skb,
444 struct net_device *dev)
445{
446 /* Just return the original SKB */
447 return skb;
448}
449
439 450
440/* ethtool operations *******************************************************/ 451/* ethtool operations *******************************************************/
441static int 452static int
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index 83d3572cdb20..e2aadb73111d 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -58,14 +58,11 @@
58#define BRCM_EG_TC_MASK 0x7 58#define BRCM_EG_TC_MASK 0x7
59#define BRCM_EG_PID_MASK 0x1f 59#define BRCM_EG_PID_MASK 0x1f
60 60
61static netdev_tx_t brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev) 61static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev)
62{ 62{
63 struct dsa_slave_priv *p = netdev_priv(dev); 63 struct dsa_slave_priv *p = netdev_priv(dev);
64 u8 *brcm_tag; 64 u8 *brcm_tag;
65 65
66 dev->stats.tx_packets++;
67 dev->stats.tx_bytes += skb->len;
68
69 if (skb_cow_head(skb, BRCM_TAG_LEN) < 0) 66 if (skb_cow_head(skb, BRCM_TAG_LEN) < 0)
70 goto out_free; 67 goto out_free;
71 68
@@ -87,17 +84,11 @@ static netdev_tx_t brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev)
87 brcm_tag[2] = BRCM_IG_DSTMAP2_MASK; 84 brcm_tag[2] = BRCM_IG_DSTMAP2_MASK;
88 brcm_tag[3] = (1 << p->port) & BRCM_IG_DSTMAP1_MASK; 85 brcm_tag[3] = (1 << p->port) & BRCM_IG_DSTMAP1_MASK;
89 86
90 /* Queue the SKB for transmission on the parent interface, but 87 return skb;
91 * do not modify its EtherType
92 */
93 skb->dev = p->parent->dst->master_netdev;
94 dev_queue_xmit(skb);
95
96 return NETDEV_TX_OK;
97 88
98out_free: 89out_free:
99 kfree_skb(skb); 90 kfree_skb(skb);
100 return NETDEV_TX_OK; 91 return NULL;
101} 92}
102 93
103static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, 94static int brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index 2dab27063273..aa780e4ac0bd 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -15,14 +15,11 @@
15 15
16#define DSA_HLEN 4 16#define DSA_HLEN 4
17 17
18static netdev_tx_t dsa_xmit(struct sk_buff *skb, struct net_device *dev) 18static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev)
19{ 19{
20 struct dsa_slave_priv *p = netdev_priv(dev); 20 struct dsa_slave_priv *p = netdev_priv(dev);
21 u8 *dsa_header; 21 u8 *dsa_header;
22 22
23 dev->stats.tx_packets++;
24 dev->stats.tx_bytes += skb->len;
25
26 /* 23 /*
27 * Convert the outermost 802.1q tag to a DSA tag for tagged 24 * Convert the outermost 802.1q tag to a DSA tag for tagged
28 * packets, or insert a DSA tag between the addresses and 25 * packets, or insert a DSA tag between the addresses and
@@ -63,14 +60,11 @@ static netdev_tx_t dsa_xmit(struct sk_buff *skb, struct net_device *dev)
63 dsa_header[3] = 0x00; 60 dsa_header[3] = 0x00;
64 } 61 }
65 62
66 skb->dev = p->parent->dst->master_netdev; 63 return skb;
67 dev_queue_xmit(skb);
68
69 return NETDEV_TX_OK;
70 64
71out_free: 65out_free:
72 kfree_skb(skb); 66 kfree_skb(skb);
73 return NETDEV_TX_OK; 67 return NULL;
74} 68}
75 69
76static int dsa_rcv(struct sk_buff *skb, struct net_device *dev, 70static int dsa_rcv(struct sk_buff *skb, struct net_device *dev,
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
index 9aeda596f7ec..2288c8098c42 100644
--- a/net/dsa/tag_edsa.c
+++ b/net/dsa/tag_edsa.c
@@ -16,14 +16,11 @@
16#define DSA_HLEN 4 16#define DSA_HLEN 4
17#define EDSA_HLEN 8 17#define EDSA_HLEN 8
18 18
19static netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev) 19static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev)
20{ 20{
21 struct dsa_slave_priv *p = netdev_priv(dev); 21 struct dsa_slave_priv *p = netdev_priv(dev);
22 u8 *edsa_header; 22 u8 *edsa_header;
23 23
24 dev->stats.tx_packets++;
25 dev->stats.tx_bytes += skb->len;
26
27 /* 24 /*
28 * Convert the outermost 802.1q tag to a DSA tag and prepend 25 * Convert the outermost 802.1q tag to a DSA tag and prepend
29 * a DSA ethertype field is the packet is tagged, or insert 26 * a DSA ethertype field is the packet is tagged, or insert
@@ -76,14 +73,11 @@ static netdev_tx_t edsa_xmit(struct sk_buff *skb, struct net_device *dev)
76 edsa_header[7] = 0x00; 73 edsa_header[7] = 0x00;
77 } 74 }
78 75
79 skb->dev = p->parent->dst->master_netdev; 76 return skb;
80 dev_queue_xmit(skb);
81
82 return NETDEV_TX_OK;
83 77
84out_free: 78out_free:
85 kfree_skb(skb); 79 kfree_skb(skb);
86 return NETDEV_TX_OK; 80 return NULL;
87} 81}
88 82
89static int edsa_rcv(struct sk_buff *skb, struct net_device *dev, 83static int edsa_rcv(struct sk_buff *skb, struct net_device *dev,
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
index e268f9db8893..d25efc93d8f1 100644
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -13,16 +13,13 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include "dsa_priv.h" 14#include "dsa_priv.h"
15 15
16static netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev) 16static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
17{ 17{
18 struct dsa_slave_priv *p = netdev_priv(dev); 18 struct dsa_slave_priv *p = netdev_priv(dev);
19 struct sk_buff *nskb; 19 struct sk_buff *nskb;
20 int padlen; 20 int padlen;
21 u8 *trailer; 21 u8 *trailer;
22 22
23 dev->stats.tx_packets++;
24 dev->stats.tx_bytes += skb->len;
25
26 /* 23 /*
27 * We have to make sure that the trailer ends up as the very 24 * We have to make sure that the trailer ends up as the very
28 * last 4 bytes of the packet. This means that we have to pad 25 * last 4 bytes of the packet. This means that we have to pad
@@ -36,7 +33,7 @@ static netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev)
36 nskb = alloc_skb(NET_IP_ALIGN + skb->len + padlen + 4, GFP_ATOMIC); 33 nskb = alloc_skb(NET_IP_ALIGN + skb->len + padlen + 4, GFP_ATOMIC);
37 if (nskb == NULL) { 34 if (nskb == NULL) {
38 kfree_skb(skb); 35 kfree_skb(skb);
39 return NETDEV_TX_OK; 36 return NULL;
40 } 37 }
41 skb_reserve(nskb, NET_IP_ALIGN); 38 skb_reserve(nskb, NET_IP_ALIGN);
42 39
@@ -57,10 +54,7 @@ static netdev_tx_t trailer_xmit(struct sk_buff *skb, struct net_device *dev)
57 trailer[2] = 0x10; 54 trailer[2] = 0x10;
58 trailer[3] = 0x00; 55 trailer[3] = 0x00;
59 56
60 nskb->dev = p->parent->dst->master_netdev; 57 return nskb;
61 dev_queue_xmit(nskb);
62
63 return NETDEV_TX_OK;
64} 58}
65 59
66static int trailer_rcv(struct sk_buff *skb, struct net_device *dev, 60static int trailer_rcv(struct sk_buff *skb, struct net_device *dev,