aboutsummaryrefslogtreecommitdiffstats
path: root/net/dsa
diff options
context:
space:
mode:
authorEgil Hjelmeland <privat@egil-hjelmeland.no>2017-11-13 08:25:25 -0500
committerDavid S. Miller <davem@davemloft.net>2017-11-14 07:47:48 -0500
commit1a48fbd9ec1483f5bf3da63dfd907f4272828b4a (patch)
tree91fcdda5b562ab89b05746e407407fe935861171 /net/dsa
parent887c3820a3801a117a494aeca147ec52f95e1566 (diff)
net: dsa: lan9303: calculate offload_fwd_mark from tag
The lan9303 set bits in the host CPU tag indicating if a ingress frame is a trapped IGMP or STP frame. Use these bits to calculate skb->offload_fwd_mark more efficiently. Signed-off-by: Egil Hjelmeland <privat@egil-hjelmeland.no> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/tag_lan9303.c24
1 files changed, 8 insertions, 16 deletions
diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c
index b8c5e52b2eff..548c00254c07 100644
--- a/net/dsa/tag_lan9303.c
+++ b/net/dsa/tag_lan9303.c
@@ -42,6 +42,10 @@
42#define LAN9303_TAG_LEN 4 42#define LAN9303_TAG_LEN 4
43# define LAN9303_TAG_TX_USE_ALR BIT(3) 43# define LAN9303_TAG_TX_USE_ALR BIT(3)
44# define LAN9303_TAG_TX_STP_OVERRIDE BIT(4) 44# define LAN9303_TAG_TX_STP_OVERRIDE BIT(4)
45# define LAN9303_TAG_RX_IGMP BIT(3)
46# define LAN9303_TAG_RX_STP BIT(4)
47# define LAN9303_TAG_RX_TRAPPED_TO_CPU (LAN9303_TAG_RX_IGMP | \
48 LAN9303_TAG_RX_STP)
45 49
46/* Decide whether to transmit using ALR lookup, or transmit directly to 50/* Decide whether to transmit using ALR lookup, or transmit directly to
47 * port using tag. ALR learning is performed only when using ALR lookup. 51 * port using tag. ALR learning is performed only when using ALR lookup.
@@ -91,9 +95,8 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
91 struct packet_type *pt) 95 struct packet_type *pt)
92{ 96{
93 u16 *lan9303_tag; 97 u16 *lan9303_tag;
98 u16 lan9303_tag1;
94 unsigned int source_port; 99 unsigned int source_port;
95 u16 ether_type_nw;
96 u8 ip_protocol;
97 100
98 if (unlikely(!pskb_may_pull(skb, LAN9303_TAG_LEN))) { 101 if (unlikely(!pskb_may_pull(skb, LAN9303_TAG_LEN))) {
99 dev_warn_ratelimited(&dev->dev, 102 dev_warn_ratelimited(&dev->dev,
@@ -114,7 +117,8 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
114 return NULL; 117 return NULL;
115 } 118 }
116 119
117 source_port = ntohs(lan9303_tag[1]) & 0x3; 120 lan9303_tag1 = ntohs(lan9303_tag[1]);
121 source_port = lan9303_tag1 & 0x3;
118 122
119 skb->dev = dsa_master_find_slave(dev, 0, source_port); 123 skb->dev = dsa_master_find_slave(dev, 0, source_port);
120 if (!skb->dev) { 124 if (!skb->dev) {
@@ -128,19 +132,7 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
128 skb_pull_rcsum(skb, 2 + 2); 132 skb_pull_rcsum(skb, 2 + 2);
129 memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN), 133 memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
130 2 * ETH_ALEN); 134 2 * ETH_ALEN);
131 skb->offload_fwd_mark = !ether_addr_equal(skb->data - ETH_HLEN, 135 skb->offload_fwd_mark = !(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU);
132 eth_stp_addr);
133
134 /* We also need IGMP packets to have skb->offload_fwd_mark = 0.
135 * Solving this for all conceivable situations would add more cost to
136 * every packet. Instead we handle just the common case:
137 * No VLAN tag + Ethernet II framing.
138 * Test least probable term first.
139 */
140 ether_type_nw = lan9303_tag[2];
141 ip_protocol = *(skb->data + 9);
142 if (ip_protocol == IPPROTO_IGMP && ether_type_nw == htons(ETH_P_IP))
143 skb->offload_fwd_mark = 0;
144 136
145 return skb; 137 return skb;
146} 138}