diff options
| author | Egil Hjelmeland <privat@egil-hjelmeland.no> | 2017-11-13 08:25:25 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-11-14 07:47:48 -0500 |
| commit | 1a48fbd9ec1483f5bf3da63dfd907f4272828b4a (patch) | |
| tree | 91fcdda5b562ab89b05746e407407fe935861171 /net/dsa | |
| parent | 887c3820a3801a117a494aeca147ec52f95e1566 (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.c | 24 |
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 | } |
