From patchwork Mon Dec 3 23:34:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tristram.Ha@microchip.com X-Patchwork-Id: 1007364 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=microchip.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4381Z61c82z9s55 for ; Tue, 4 Dec 2018 10:35:10 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726031AbeLCXfJ (ORCPT ); Mon, 3 Dec 2018 18:35:09 -0500 Received: from esa2.microchip.iphmx.com ([68.232.149.84]:44883 "EHLO esa2.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725980AbeLCXfB (ORCPT ); Mon, 3 Dec 2018 18:35:01 -0500 X-IronPort-AV: E=Sophos;i="5.56,312,1539673200"; d="scan'208";a="23790827" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 03 Dec 2018 16:35:01 -0700 Received: from localhost.localdomain (10.10.76.4) by chn-sv-exch03.mchp-main.com (10.10.76.49) with Microsoft SMTP Server id 14.3.352.0; Mon, 3 Dec 2018 16:35:00 -0700 From: To: Andrew Lunn , Florian Fainelli , Pavel Machek CC: Tristram Ha , , Subject: [PATCH RFC 4/6] net: dsa: microchip: Each switch driver has its own tail tagging operations Date: Mon, 3 Dec 2018 15:34:55 -0800 Message-ID: <1543880097-7106-5-git-send-email-Tristram.Ha@microchip.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1543880097-7106-1-git-send-email-Tristram.Ha@microchip.com> References: <1543880097-7106-1-git-send-email-Tristram.Ha@microchip.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Tristram Ha The tail tagging operations are implemented in each switch driver so that the main tail tagging code tag_ksz.c does not need to be changed after modification to support that mechanism is made. Signed-off-by: Tristram Ha --- drivers/net/dsa/microchip/ksz9477.c | 78 +++++++++++++++++++++++++++++++++- drivers/net/dsa/microchip/ksz_common.c | 4 +- drivers/net/dsa/microchip/ksz_priv.h | 3 +- include/linux/dsa/ksz_dsa.h | 9 ++++ 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index bd1ca33..c690c2b2 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -21,6 +21,14 @@ #include "ksz_common.h" #include "ksz9477_reg.h" +/* features flags */ +#define GBIT_SUPPORT BIT(0) +#define NEW_XMII BIT(1) +#define IS_9893 BIT(2) + +/* overrides flags */ +#define PTP_TAG BIT(0) + static const struct { int index; char string[ETH_GSTRING_LEN]; @@ -1356,9 +1364,77 @@ static void ksz9477_switch_exit(struct ksz_device *dev) .exit = ksz9477_switch_exit, }; +/* 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 switch with 3 ports only one byte is needed. + * When PTP function is enabled additional 4 bytes are needed. + * + * 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) + * + * When PTP function is enabled BIT 7 indicates the received frame is a PTP + * message and so there are 4 additional bytes for the receive timestamp. + */ + +static int ksz9477_get_len(struct ksz_device *dev) +{ + int len = 1; + + if (!(dev->features & IS_9893)) + len += 1; + if (dev->overrides & PTP_TAG) + len += 4; + return len; +} + +static int ksz9477_get_tag(struct ksz_device *dev, u8 *tag, int *port) +{ + int len = 1; + + if (tag[0] & BIT(7)) + len += 4; + *port = tag[0] & 7; + return len; +} + +static void ksz9477_set_tag(struct ksz_device *dev, void *ptr, u8 *addr, int p) +{ + if (dev->overrides & PTP_TAG) { + u32 *timestamp = (u32 *)ptr; + + *timestamp = 0; + ptr = timestamp + 1; + } + if (dev->features & IS_9893) { + u8 *tag = (u8 *)ptr; + + *tag = 1 << p; + } else { + u16 *tag = (u16 *)ptr; + + *tag = 1 << p; + *tag = cpu_to_be16(*tag); + } +} + +static const struct ksz_tag_ops ksz9477_tag_ops = { + .get_len = ksz9477_get_len, + .get_tag = ksz9477_get_tag, + .set_tag = ksz9477_set_tag, +}; + int ksz9477_switch_register(struct ksz_device *dev) { - return ksz_switch_register(dev, &ksz9477_dev_ops); + return ksz_switch_register(dev, &ksz9477_dev_ops, &ksz9477_tag_ops); } EXPORT_SYMBOL(ksz9477_switch_register); diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 7b8f57b..a72659b 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -399,7 +399,8 @@ struct ksz_device *ksz_switch_alloc(struct device *base, EXPORT_SYMBOL(ksz_switch_alloc); int ksz_switch_register(struct ksz_device *dev, - const struct ksz_dev_ops *ops) + const struct ksz_dev_ops *ops, + const struct ksz_tag_ops *tag_ops) { int ret; @@ -412,6 +413,7 @@ int ksz_switch_register(struct ksz_device *dev, mutex_init(&dev->vlan_mutex); dev->dev_ops = ops; + dev->tag_ops = tag_ops; if (dev->dev_ops->detect(dev)) return -EINVAL; diff --git a/drivers/net/dsa/microchip/ksz_priv.h b/drivers/net/dsa/microchip/ksz_priv.h index 5d93822..d020c1e 100644 --- a/drivers/net/dsa/microchip/ksz_priv.h +++ b/drivers/net/dsa/microchip/ksz_priv.h @@ -78,7 +78,8 @@ struct ksz_dev_ops { struct ksz_device *ksz_switch_alloc(struct device *base, const struct ksz_io_ops *ops, void *priv); int ksz_switch_register(struct ksz_device *dev, - const struct ksz_dev_ops *ops); + const struct ksz_dev_ops *ops, + const struct ksz_tag_ops *tag_ops); void ksz_switch_remove(struct ksz_device *dev); int ksz9477_switch_register(struct ksz_device *dev); diff --git a/include/linux/dsa/ksz_dsa.h b/include/linux/dsa/ksz_dsa.h index 3148cae..3fb2713 100644 --- a/include/linux/dsa/ksz_dsa.h +++ b/include/linux/dsa/ksz_dsa.h @@ -7,6 +7,14 @@ #include +struct ksz_device; + +struct ksz_tag_ops { + int (*get_len)(struct ksz_device *dev); + int (*get_tag)(struct ksz_device *dev, u8 *tag, int *port); + void (*set_tag)(struct ksz_device *dev, void *ptr, u8 *addr, int p); +}; + struct vlan_table { u32 table[3]; }; @@ -45,6 +53,7 @@ struct ksz_device { struct mutex vlan_mutex; /* vlan access */ const struct ksz_io_ops *ops; const struct ksz_dev_ops *dev_ops; + const struct ksz_tag_ops *tag_ops; struct device *dev;