Commit 88fda8ee authored by Christian Eggers's avatar Christian Eggers Committed by Jakub Kicinski
Browse files

net: dsa: tag_ksz: don't allocate additional memory for padding/tagging



The caller (dsa_slave_xmit) guarantees that the frame length is at least
ETH_ZLEN and that enough memory for tail tagging is available.

Signed-off-by: default avatarChristian Eggers <ceggers@arri.de>
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a3b0b647
Loading
Loading
Loading
Loading
+9 −64
Original line number Original line Diff line number Diff line
@@ -14,46 +14,6 @@
#define KSZ_EGRESS_TAG_LEN		1
#define KSZ_EGRESS_TAG_LEN		1
#define KSZ_INGRESS_TAG_LEN		1
#define KSZ_INGRESS_TAG_LEN		1


static struct sk_buff *ksz_common_xmit(struct sk_buff *skb,
				       struct net_device *dev, int len)
{
	struct sk_buff *nskb;
	int padlen;

	padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len;

	if (skb_tailroom(skb) >= padlen + len) {
		/* Let dsa_slave_xmit() free skb */
		if (__skb_put_padto(skb, skb->len + padlen, false))
			return NULL;

		nskb = skb;
	} else {
		nskb = alloc_skb(NET_IP_ALIGN + skb->len +
				 padlen + len, GFP_ATOMIC);
		if (!nskb)
			return NULL;
		skb_reserve(nskb, NET_IP_ALIGN);

		skb_reset_mac_header(nskb);
		skb_set_network_header(nskb,
				       skb_network_header(skb) - skb->head);
		skb_set_transport_header(nskb,
					 skb_transport_header(skb) - skb->head);
		skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len));

		/* Let skb_put_padto() free nskb, and let dsa_slave_xmit() free
		 * skb
		 */
		if (skb_put_padto(nskb, nskb->len + padlen))
			return NULL;

		consume_skb(skb);
	}

	return nskb;
}

static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
				      struct net_device *dev,
				      struct net_device *dev,
				      unsigned int port, unsigned int len)
				      unsigned int port, unsigned int len)
@@ -90,23 +50,18 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, struct net_device *dev)
{
{
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct sk_buff *nskb;
	u8 *tag;
	u8 *tag;
	u8 *addr;
	u8 *addr;


	nskb = ksz_common_xmit(skb, dev, KSZ_INGRESS_TAG_LEN);
	if (!nskb)
		return NULL;

	/* Tag encoding */
	/* Tag encoding */
	tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN);
	tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
	addr = skb_mac_header(nskb);
	addr = skb_mac_header(skb);


	*tag = 1 << dp->index;
	*tag = 1 << dp->index;
	if (is_link_local_ether_addr(addr))
	if (is_link_local_ether_addr(addr))
		*tag |= KSZ8795_TAIL_TAG_OVERRIDE;
		*tag |= KSZ8795_TAIL_TAG_OVERRIDE;


	return nskb;
	return skb;
}
}


static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev,
static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev,
@@ -156,18 +111,13 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,
				    struct net_device *dev)
				    struct net_device *dev)
{
{
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct sk_buff *nskb;
	__be16 *tag;
	__be16 *tag;
	u8 *addr;
	u8 *addr;
	u16 val;
	u16 val;


	nskb = ksz_common_xmit(skb, dev, KSZ9477_INGRESS_TAG_LEN);
	if (!nskb)
		return NULL;

	/* Tag encoding */
	/* Tag encoding */
	tag = skb_put(nskb, KSZ9477_INGRESS_TAG_LEN);
	tag = skb_put(skb, KSZ9477_INGRESS_TAG_LEN);
	addr = skb_mac_header(nskb);
	addr = skb_mac_header(skb);


	val = BIT(dp->index);
	val = BIT(dp->index);


@@ -176,7 +126,7 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb,


	*tag = cpu_to_be16(val);
	*tag = cpu_to_be16(val);


	return nskb;
	return skb;
}
}


static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev,
static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev,
@@ -213,24 +163,19 @@ static struct sk_buff *ksz9893_xmit(struct sk_buff *skb,
				    struct net_device *dev)
				    struct net_device *dev)
{
{
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct dsa_port *dp = dsa_slave_to_port(dev);
	struct sk_buff *nskb;
	u8 *addr;
	u8 *addr;
	u8 *tag;
	u8 *tag;


	nskb = ksz_common_xmit(skb, dev, KSZ_INGRESS_TAG_LEN);
	if (!nskb)
		return NULL;

	/* Tag encoding */
	/* Tag encoding */
	tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN);
	tag = skb_put(skb, KSZ_INGRESS_TAG_LEN);
	addr = skb_mac_header(nskb);
	addr = skb_mac_header(skb);


	*tag = BIT(dp->index);
	*tag = BIT(dp->index);


	if (is_link_local_ether_addr(addr))
	if (is_link_local_ether_addr(addr))
		*tag |= KSZ9893_TAIL_TAG_OVERRIDE;
		*tag |= KSZ9893_TAIL_TAG_OVERRIDE;


	return nskb;
	return skb;
}
}


static const struct dsa_device_ops ksz9893_netdev_ops = {
static const struct dsa_device_ops ksz9893_netdev_ops = {