Commit 6bef794d authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: dsa: create a helper which allocates space for EtherType DSA headers

Hide away the memmove used by DSA EtherType header taggers to shift the
MAC SA and DA to the left to make room for the header, after they've
called skb_push(). The call to skb_push() is still left explicit in
drivers, to be symmetric with dsa_strip_etype_header, and because not
all callers can be refactored to do it (for example, brcm_tag_xmit_ll
has common code for a pre-Ethernet DSA tag and an EtherType DSA tag).
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f1dacd7a
...@@ -478,6 +478,35 @@ static inline void dsa_strip_etype_header(struct sk_buff *skb, int len) ...@@ -478,6 +478,35 @@ static inline void dsa_strip_etype_header(struct sk_buff *skb, int len)
memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - len, 2 * ETH_ALEN); memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - len, 2 * ETH_ALEN);
} }
/* Helper for creating space for DSA header tags in TX path packets.
* Must not be called before skb_push(len).
*
* Before:
*
* <<<<<<< | | | | | | | | | | | | | | |
* ^ <<<<<<< +-----------------------+-----------------------+-------+
* | <<<<<<< | Destination MAC | Source MAC | EType |
* | +-----------------------+-----------------------+-------+
* <----- len ----->
* |
* |
* skb->data
*
* After:
*
* | | | | | | | | | | | | | | | | | | |
* +-----------------------+-----------------------+---------------+-------+
* | Destination MAC | Source MAC | DSA header | EType |
* +-----------------------+-----------------------+---------------+-------+
* ^ | |
* | <----- len ----->
* skb->data
*/
static inline void dsa_alloc_etype_header(struct sk_buff *skb, int len)
{
memmove(skb->data, skb->data + len, 2 * ETH_ALEN);
}
/* switch.c */ /* switch.c */
int dsa_switch_register_notifier(struct dsa_switch *ds); int dsa_switch_register_notifier(struct dsa_switch *ds);
void dsa_switch_unregister_notifier(struct dsa_switch *ds); void dsa_switch_unregister_notifier(struct dsa_switch *ds);
......
...@@ -99,7 +99,7 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, ...@@ -99,7 +99,7 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb,
skb_push(skb, BRCM_TAG_LEN); skb_push(skb, BRCM_TAG_LEN);
if (offset) if (offset)
memmove(skb->data, skb->data + BRCM_TAG_LEN, offset); dsa_alloc_etype_header(skb, BRCM_TAG_LEN);
brcm_tag = skb->data + offset; brcm_tag = skb->data + offset;
...@@ -228,7 +228,7 @@ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb, ...@@ -228,7 +228,7 @@ static struct sk_buff *brcm_leg_tag_xmit(struct sk_buff *skb,
skb_push(skb, BRCM_LEG_TAG_LEN); skb_push(skb, BRCM_LEG_TAG_LEN);
memmove(skb->data, skb->data + BRCM_LEG_TAG_LEN, 2 * ETH_ALEN); dsa_alloc_etype_header(skb, BRCM_LEG_TAG_LEN);
brcm_tag = skb->data + 2 * ETH_ALEN; brcm_tag = skb->data + 2 * ETH_ALEN;
......
...@@ -166,7 +166,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev, ...@@ -166,7 +166,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
if (skb->protocol == htons(ETH_P_8021Q)) { if (skb->protocol == htons(ETH_P_8021Q)) {
if (extra) { if (extra) {
skb_push(skb, extra); skb_push(skb, extra);
memmove(skb->data, skb->data + extra, 2 * ETH_ALEN); dsa_alloc_etype_header(skb, extra);
} }
/* Construct tagged DSA tag from 802.1Q tag. */ /* Construct tagged DSA tag from 802.1Q tag. */
...@@ -181,7 +181,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev, ...@@ -181,7 +181,7 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev,
} }
} else { } else {
skb_push(skb, DSA_HLEN + extra); skb_push(skb, DSA_HLEN + extra);
memmove(skb->data, skb->data + DSA_HLEN + extra, 2 * ETH_ALEN); dsa_alloc_etype_header(skb, DSA_HLEN + extra);
/* Construct untagged DSA tag. */ /* Construct untagged DSA tag. */
dsa_header = skb->data + 2 * ETH_ALEN + extra; dsa_header = skb->data + 2 * ETH_ALEN + extra;
......
...@@ -62,7 +62,7 @@ static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -62,7 +62,7 @@ static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev)
skb_push(skb, LAN9303_TAG_LEN); skb_push(skb, LAN9303_TAG_LEN);
/* make room between MACs and Ether-Type */ /* make room between MACs and Ether-Type */
memmove(skb->data, skb->data + LAN9303_TAG_LEN, 2 * ETH_ALEN); dsa_alloc_etype_header(skb, LAN9303_TAG_LEN);
lan9303_tag = (__be16 *)(skb->data + 2 * ETH_ALEN); lan9303_tag = (__be16 *)(skb->data + 2 * ETH_ALEN);
tag = lan9303_xmit_use_arl(dp, skb->data) ? tag = lan9303_xmit_use_arl(dp, skb->data) ?
......
...@@ -41,7 +41,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb, ...@@ -41,7 +41,7 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
default: default:
xmit_tpid = MTK_HDR_XMIT_UNTAGGED; xmit_tpid = MTK_HDR_XMIT_UNTAGGED;
skb_push(skb, MTK_HDR_LEN); skb_push(skb, MTK_HDR_LEN);
memmove(skb->data, skb->data + MTK_HDR_LEN, 2 * ETH_ALEN); dsa_alloc_etype_header(skb, MTK_HDR_LEN);
} }
mtk_tag = skb->data + 2 * ETH_ALEN; mtk_tag = skb->data + 2 * ETH_ALEN;
......
...@@ -36,7 +36,7 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -36,7 +36,7 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
skb_push(skb, QCA_HDR_LEN); skb_push(skb, QCA_HDR_LEN);
memmove(skb->data, skb->data + QCA_HDR_LEN, 2 * ETH_ALEN); dsa_alloc_etype_header(skb, QCA_HDR_LEN);
phdr = (__be16 *)(skb->data + 2 * ETH_ALEN); phdr = (__be16 *)(skb->data + 2 * ETH_ALEN);
/* Set the version field, and set destination port information */ /* Set the version field, and set destination port information */
......
...@@ -47,7 +47,7 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb, ...@@ -47,7 +47,7 @@ static struct sk_buff *rtl4a_tag_xmit(struct sk_buff *skb,
dp->index); dp->index);
skb_push(skb, RTL4_A_HDR_LEN); skb_push(skb, RTL4_A_HDR_LEN);
memmove(skb->data, skb->data + RTL4_A_HDR_LEN, 2 * ETH_ALEN); dsa_alloc_etype_header(skb, RTL4_A_HDR_LEN);
tag = skb->data + 2 * ETH_ALEN; tag = skb->data + 2 * ETH_ALEN;
/* Set Ethertype */ /* Set Ethertype */
......
...@@ -206,8 +206,7 @@ static struct sk_buff *sja1110_xmit(struct sk_buff *skb, ...@@ -206,8 +206,7 @@ static struct sk_buff *sja1110_xmit(struct sk_buff *skb,
skb_push(skb, SJA1110_HEADER_LEN); skb_push(skb, SJA1110_HEADER_LEN);
/* Move Ethernet header to the left, making space for DSA tag */ dsa_alloc_etype_header(skb, SJA1110_HEADER_LEN);
memmove(skb->data, skb->data + SJA1110_HEADER_LEN, 2 * ETH_ALEN);
trailer_pos = skb->len; trailer_pos = skb->len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment