From: Tristram Ha <tristram...@microchip.com> Modify tag_ksz.c so that tail tag code can be used by other KSZ switch drivers.
Signed-off-by: Tristram Ha <tristram...@microchip.com> Reviewed-by: Woojung Huh <woojung....@microchip.com> --- v2 - No new feature is introduced v1 - Switch driver code is not accessed from tag_ksz.c drivers/net/dsa/microchip/Kconfig | 2 +- drivers/net/dsa/microchip/ksz9477.c | 2 +- include/net/dsa.h | 2 +- net/dsa/Kconfig | 4 ++ net/dsa/dsa.c | 4 +- net/dsa/dsa_priv.h | 2 +- net/dsa/tag_ksz.c | 90 ++++++++++++++++++++++++------------- 7 files changed, 70 insertions(+), 36 deletions(-) diff --git a/drivers/net/dsa/microchip/Kconfig b/drivers/net/dsa/microchip/Kconfig index 5a8660d..ab8f9f6 100644 --- a/drivers/net/dsa/microchip/Kconfig +++ b/drivers/net/dsa/microchip/Kconfig @@ -1,7 +1,7 @@ menuconfig MICROCHIP_KSZ9477 tristate "Microchip KSZ9477 series switch support" depends on NET_DSA - select NET_DSA_TAG_KSZ + select NET_DSA_TAG_KSZ9477 help This driver adds support for Microchip KSZ9477 switch chips. diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 4e998a4..c735dca 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -344,7 +344,7 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, int port) static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds, int port) { - return DSA_TAG_PROTO_KSZ; + return DSA_TAG_PROTO_KSZ9477; } static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg) diff --git a/include/net/dsa.h b/include/net/dsa.h index 2a05738..3d23c0b 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -32,7 +32,7 @@ enum dsa_tag_protocol { DSA_TAG_PROTO_BRCM_PREPEND, DSA_TAG_PROTO_DSA, DSA_TAG_PROTO_EDSA, - DSA_TAG_PROTO_KSZ, + DSA_TAG_PROTO_KSZ9477, DSA_TAG_PROTO_LAN9303, DSA_TAG_PROTO_MTK, DSA_TAG_PROTO_QCA, diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig index 03c3bdf..809b0e2 100644 --- a/net/dsa/Kconfig +++ b/net/dsa/Kconfig @@ -32,6 +32,10 @@ config NET_DSA_TAG_EDSA config NET_DSA_TAG_KSZ bool +config NET_DSA_TAG_KSZ9477 + bool + select NET_DSA_TAG_KSZ + config NET_DSA_TAG_LAN9303 bool diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 6a9d0f5..92056a7 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -53,8 +53,8 @@ static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff *skb, #ifdef CONFIG_NET_DSA_TAG_EDSA [DSA_TAG_PROTO_EDSA] = &edsa_netdev_ops, #endif -#ifdef CONFIG_NET_DSA_TAG_KSZ - [DSA_TAG_PROTO_KSZ] = &ksz_netdev_ops, +#ifdef CONFIG_NET_DSA_TAG_KSZ9477 + [DSA_TAG_PROTO_KSZ9477] = &ksz9477_netdev_ops, #endif #ifdef CONFIG_NET_DSA_TAG_LAN9303 [DSA_TAG_PROTO_LAN9303] = &lan9303_netdev_ops, diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 7d03669..a2955a8 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -200,7 +200,7 @@ static inline struct dsa_port *dsa_slave_to_port(const struct net_device *dev) extern const struct dsa_device_ops edsa_netdev_ops; /* tag_ksz.c */ -extern const struct dsa_device_ops ksz_netdev_ops; +extern const struct dsa_device_ops ksz9477_netdev_ops; /* tag_lan9303.c */ extern const struct dsa_device_ops lan9303_netdev_ops; diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c index 0f62eff..7343270 100644 --- a/net/dsa/tag_ksz.c +++ b/net/dsa/tag_ksz.c @@ -14,34 +14,21 @@ #include <net/dsa.h> #include "dsa_priv.h" -/* For Ingress (Host -> KSZ), 2 bytes are added before FCS. - * --------------------------------------------------------------------------- - * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes) - * --------------------------------------------------------------------------- - * tag0 : Prioritization (not used now) - * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5) - * - * For Egress (KSZ -> Host), 1 byte is added before FCS. - * --------------------------------------------------------------------------- - * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes) - * --------------------------------------------------------------------------- - * tag0 : zero-based value represents port - * (eg, 0x00=port1, 0x02=port3, 0x06=port7) - */ - -#define KSZ_INGRESS_TAG_LEN 2 -#define KSZ_EGRESS_TAG_LEN 1 +/* Usually only one byte is used for tail tag. */ +#define KSZ_INGRESS_TAG_LEN 1 +#define KSZ_EGRESS_TAG_LEN 1 -static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev) +static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev, + int len, + void (*set_tag)(void *ptr, u8 *addr, int p)) { struct dsa_port *dp = dsa_slave_to_port(dev); struct sk_buff *nskb; int padlen; - u8 *tag; padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len; - if (skb_tailroom(skb) >= padlen + KSZ_INGRESS_TAG_LEN) { + if (skb_tailroom(skb) >= padlen + len) { /* Let dsa_slave_xmit() free skb */ if (__skb_put_padto(skb, skb->len + padlen, false)) return NULL; @@ -49,7 +36,7 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev) nskb = skb; } else { nskb = alloc_skb(NET_IP_ALIGN + skb->len + - padlen + KSZ_INGRESS_TAG_LEN, GFP_ATOMIC); + padlen + len, GFP_ATOMIC); if (!nskb) return NULL; skb_reserve(nskb, NET_IP_ALIGN); @@ -70,33 +57,76 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev) consume_skb(skb); } - tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN); - tag[0] = 0; - tag[1] = 1 << dp->index; /* destination port */ + set_tag(skb_put(nskb, len), skb_mac_header(nskb), dp->index); return nskb; } static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt) + struct packet_type *pt, + int (*get_tag)(u8 *tag, int *port)) { u8 *tag; + int len; int source_port; tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; - source_port = tag[0] & 7; + len = get_tag(tag, &source_port); skb->dev = dsa_master_find_slave(dev, 0, source_port); if (!skb->dev) return NULL; - pskb_trim_rcsum(skb, skb->len - KSZ_EGRESS_TAG_LEN); + pskb_trim_rcsum(skb, skb->len - len); return skb; } -const struct dsa_device_ops ksz_netdev_ops = { - .xmit = ksz_xmit, - .rcv = ksz_rcv, +/* For Ingress (Host -> KSZ9477), 2 bytes are added before FCS. + * --------------------------------------------------------------------------- + * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes) + * --------------------------------------------------------------------------- + * tag0 : Prioritization (not used now) + * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5) + * + * For Egress (KSZ9477 -> Host), 1 byte is added before FCS. + * --------------------------------------------------------------------------- + * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes) + * --------------------------------------------------------------------------- + * tag0 : zero-based value represents port + * (eg, 0x00=port1, 0x02=port3, 0x06=port7) + */ + +#define KSZ9477_INGRESS_TAG_LEN 2 + +static int ksz9477_get_tag(u8 *tag, int *port) +{ + *port = tag[0] & 7; + return KSZ_EGRESS_TAG_LEN; +} + +static void ksz9477_set_tag(void *ptr, u8 *addr, int p) +{ + u16 *tag = (u16 *)ptr; + + *tag = 1 << p; + *tag = cpu_to_be16(*tag); +} + +static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + return ksz_xmit(skb, dev, KSZ9477_INGRESS_TAG_LEN, ksz9477_set_tag); +} + +static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt) +{ + return ksz_rcv(skb, dev, pt, ksz9477_get_tag); +} + +const struct dsa_device_ops ksz9477_netdev_ops = { + .xmit = ksz9477_xmit, + .rcv = ksz9477_rcv, }; -- 1.9.1