}
}
+static int rteth_get_dsa_port(struct sk_buff *skb, struct net_device *dev)
+{
+ struct rteth_ctrl *ctrl = netdev_priv(dev);
+ u8 *trailer = &skb->data[skb->len - 4];
+
+ if (netdev_uses_dsa(dev) &&
+ dev->dsa_ptr->tag_ops->proto == DSA_TAG_PROTO_RTL_OTTO &&
+ trailer[0] < ctrl->r->cpu_port &&
+ trailer[1] == 0xab &&
+ trailer[2] == 0xcd &&
+ trailer[3] == 0xef)
+ return trailer[0];
+
+ return -1;
+}
+
static int rteth_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
+ int port, val, slot, len = skb->len, ring = skb_get_queue_mapping(skb);
struct rteth_ctrl *ctrl = netdev_priv(dev);
- int val, slot, len = skb->len, port = -1;
- int ring = skb_get_queue_mapping(skb);
struct rteth_packet *packet;
dma_addr_t packet_dma;
- if (netdev_uses_dsa(dev) &&
- skb->data[len - 4] == 0x80 &&
- skb->data[len - 3] < ctrl->r->cpu_port &&
- skb->data[len - 2] == 0x10 &&
- skb->data[len - 1] == 0x00) {
- port = skb->data[len - 3];
- /* space will be reused for 4 byte layer 2 FCS */
- } else {
- /* No DSA tag, add space for 4 byte layer 2 FCS */
- len += ETH_FCS_LEN;
- }
+ port = rteth_get_dsa_port(skb, dev);
+ if (port < 0)
+ len += ETH_FCS_LEN; /* No reusable 4 byte tag, add space for 4 byte layer 2 FCS */
len = max(ETH_ZLEN + ETH_FCS_LEN, len);
if (unlikely(skb_put_padto(skb, len))) {
// SPDX-License-Identifier: GPL-2.0+
-/*
- * net/dsa/tag_trailer.c - Trailer tag format handling
- * Copyright (c) 2008-2009 Marvell Semiconductor
- */
#include <linux/etherdevice.h>
#include <linux/list.h>
#include "tag.h"
-#define RTL_OTTO_NAME "rtl_otto"
-
-/*
- * TODO: This driver was copied over from trailer tagging. It will be developed
- * downstream in OpenWrt in conjunction with the Realtek Otto ethernet driver.
- * For now rely on the old trailer handling and keep everything as is.
- */
+#define RTL_OTTO_NAME "rtl_otto"
+#define RTL_OTTO_TAILROOM 4
static struct sk_buff *rtl_otto_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct dsa_port *dp = dsa_user_to_port(dev);
u8 *trailer;
- trailer = skb_put(skb, 4);
- trailer[0] = 0x80;
- trailer[1] = dp->index;
- trailer[2] = 0x10;
- trailer[3] = 0x00;
+ /* Hardware needs space for Layer 2 FCS. Align tag size with that. */
+ trailer = skb_put(skb, RTL_OTTO_TAILROOM);
+ trailer[0] = dp->index;
+ trailer[1] = 0xab;
+ trailer[2] = 0xcd;
+ trailer[3] = 0xef;
return skb;
}
}
static const struct dsa_device_ops rtl_otto_netdev_ops = {
- .name = RTL_OTTO_NAME,
- .proto = DSA_TAG_PROTO_RTL_OTTO,
- .xmit = rtl_otto_xmit,
- .rcv = rtl_otto_rcv,
- .needed_tailroom = 4,
+ .name = RTL_OTTO_NAME,
+ .proto = DSA_TAG_PROTO_RTL_OTTO,
+ .xmit = rtl_otto_xmit,
+ .rcv = rtl_otto_rcv,
+ .needed_tailroom = RTL_OTTO_TAILROOM,
};
MODULE_DESCRIPTION("DSA tag driver for Realtek Otto switches (RTL83xx/RTL93xx)");