Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp501256rwb; Tue, 29 Nov 2022 01:19:12 -0800 (PST) X-Google-Smtp-Source: AA0mqf4omaoF9IjatjPp2gEdTb/Q0a58IhoBM8xrVSTYrZuJicV/lW3wxc/Es0HBJ7P71T8h20p4 X-Received: by 2002:a63:1761:0:b0:478:18d6:2cf2 with SMTP id 33-20020a631761000000b0047818d62cf2mr8278838pgx.442.1669713552267; Tue, 29 Nov 2022 01:19:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669713552; cv=none; d=google.com; s=arc-20160816; b=l8VT/BK8J8XMoni075tNqPTLee2hsIVTFueFtpeuHPW6gXkiAQh559OPNCEUSzTY6B xQeETI03tMw1iuzlg2GK39bKWfDl96P2HkQXUB7vR8Tjri6LY51LfrEDuvK1nVA+Baqa JZi30NDW6RczALqA7/NKsH71rjLU+/eHDhJd0U27z1Q/9AVNLZS5JZKSVsEMwyEbqzyL EsA5AKb/r182tmcSz6NQU6zcvhn29GAgFfJH37jxw8h4/j0EvvN5+Al31TXGbl9r49Ay I123NT6J+eEfUEeFKZJ8H3Asl9eJx23aM26jkrjVZ/fLiHwEVfGvbe/EJLElFzQ3qPEp BgWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=FUuTq5A+DaI24+vsGsMEUusF2WRBRIgX31LTqDKBaq0=; b=Oa8VYI55sj3x0/T3ikIdSb8qqeg3C16BrYXlSGKLsTtt9SSynJoY7hf5d/mpz1VfPp 7ZwBQyd5sXWMTcQUaAeanUX8BqvbIs5BKDEOY8z+Jp3SQdmzk1ssXmLakA24zyXFW52D o55+7i5bJwb+CeJVvgbCpHavOLj6NQuKaSvRR9rzn86XSBEudjUi/Si+o49K67IkKB86 3S6vkyvb0tYbGpc6TDuNiGersM8RyldM8VYNVTr8mjgCS+ZHa3j1rqtxHCx2Sg5RZssH NuRVWGKpO9bWKP9C8OLcHIAuFgVqGAW4KK0YqcfsU1J9d5o0xpdXF1ZkADuZ2c11govY nFZA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@broadcom.com header.s=google header.b=WHKAlh5V; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u11-20020a170902e5cb00b001854f631c8esi415067plf.221.2022.11.29.01.19.01; Tue, 29 Nov 2022 01:19:11 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@broadcom.com header.s=google header.b=WHKAlh5V; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231314AbiK2It4 (ORCPT + 83 others); Tue, 29 Nov 2022 03:49:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58306 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231326AbiK2Itq (ORCPT ); Tue, 29 Nov 2022 03:49:46 -0500 Received: from mail-yw1-x112e.google.com (mail-yw1-x112e.google.com [IPv6:2607:f8b0:4864:20::112e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E57C44665C for ; Tue, 29 Nov 2022 00:49:28 -0800 (PST) Received: by mail-yw1-x112e.google.com with SMTP id 00721157ae682-3704852322fso131820477b3.8 for ; Tue, 29 Nov 2022 00:49:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=FUuTq5A+DaI24+vsGsMEUusF2WRBRIgX31LTqDKBaq0=; b=WHKAlh5VMyG0l2MQz0WHS8ltMk1MKgIwRakteXkphO5/UGk4jiiqZoaP5BkFVPKHt3 S6FCOHjLk7lnYOs6cXySFlS+vsA9wP+pQ5eHIcPR5125MYXpYKuV5M1UU+aVAoWOLw/w t3OT4Fkk68tbBB0/G3q2JeMEzbABJ9H5hZFpM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=FUuTq5A+DaI24+vsGsMEUusF2WRBRIgX31LTqDKBaq0=; b=fzylDX/4CsbR6QRK2TCrQG5QcDmisvkGr7A7Gadjicna/E7fdxSVL8Ai5z2P3EcV3u pw+4TR4fdxsNpMn2M//Smehpc5/b8s1as0tPGvwYwho6J8q0cz7jedVq0fa0otxRa7vE L5qq+46HR1/mNfkY+XOXn97X4jFTo/2AVqrxVbSXYRgC1IMgaCsbC/TI55f9+Bj2ObY2 EKqqAs6tD15ksRxTs/C9ovmSA1iLtSfqtN3es9ryXjblBXYiJNisio0Jb4hUxyjMxi9o s/G7voGj/Xwfta15qdJWvOo8VjpKKW8PNUU4cD2FBE0RohZ3e+GGG34gIpAM2hAwj7Iy FWFw== X-Gm-Message-State: ANoB5pnwLAERFRBYoYlR0CAtR+3CIeKdre6Lc9/eaWRyyxW4HkNsJuW6 Ob/kZNoRpm3hRhuNKD01OeaRW4oy+U7bcrQ/5m9BrQ== X-Received: by 2002:a81:9a49:0:b0:3c3:29d2:9c7c with SMTP id r70-20020a819a49000000b003c329d29c7cmr11926310ywg.195.1669711767979; Tue, 29 Nov 2022 00:49:27 -0800 (PST) MIME-Version: 1.0 References: <20221128103227.23171-1-arun.ramadoss@microchip.com> <20221128103227.23171-3-arun.ramadoss@microchip.com> In-Reply-To: <20221128103227.23171-3-arun.ramadoss@microchip.com> From: Pavan Chebbi Date: Tue, 29 Nov 2022 14:19:17 +0530 Message-ID: Subject: Re: [Patch net-next v1 02/12] net: dsa: microchip: ptp: Initial hardware time stamping support To: Arun Ramadoss Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, woojung.huh@microchip.com, UNGLinuxDriver@microchip.com, andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, linux@armlinux.org.uk, Tristram.Ha@microchip.com, richardcochran@gmail.com, ceggers@arri.de Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="000000000000d47ae205ee9810e7" X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --000000000000d47ae205ee9810e7 Content-Type: text/plain; charset="UTF-8" On Mon, Nov 28, 2022 at 4:03 PM Arun Ramadoss wrote: > > From: Christian Eggers > > This patch adds the routine for get_ts_info, hwstamp_get, set. This enables > the PTP support towards userspace applications such as linuxptp. > Tx timestamping can be enabled per port and Rx timestamping enabled > globally. > > Signed-off-by: Christian Eggers > Co-developed-by: Arun Ramadoss > Signed-off-by: Arun Ramadoss > > --- > RFC v2 -> Patch v1 > - moved tagger set and get function to separate patch > - Removed unnecessary comments > --- > drivers/net/dsa/microchip/ksz_common.c | 2 + > drivers/net/dsa/microchip/ksz_common.h | 4 ++ > drivers/net/dsa/microchip/ksz_ptp.c | 77 +++++++++++++++++++++++++- > drivers/net/dsa/microchip/ksz_ptp.h | 14 +++++ > 4 files changed, 95 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c > index 2d09cd141db6..7b85b258270c 100644 > --- a/drivers/net/dsa/microchip/ksz_common.c > +++ b/drivers/net/dsa/microchip/ksz_common.c > @@ -2873,6 +2873,8 @@ static const struct dsa_switch_ops ksz_switch_ops = { > .port_change_mtu = ksz_change_mtu, > .port_max_mtu = ksz_max_mtu, > .get_ts_info = ksz_get_ts_info, > + .port_hwtstamp_get = ksz_hwtstamp_get, > + .port_hwtstamp_set = ksz_hwtstamp_set, > }; > > struct ksz_device *ksz_switch_alloc(struct device *base, void *priv) > diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h > index 5a6bfd42c6f9..cd20f39a565f 100644 > --- a/drivers/net/dsa/microchip/ksz_common.h > +++ b/drivers/net/dsa/microchip/ksz_common.h > @@ -103,6 +103,10 @@ struct ksz_port { > struct ksz_device *ksz_dev; > struct ksz_irq pirq; > u8 num; > +#if IS_ENABLED(CONFIG_NET_DSA_MICROCHIP_KSZ_PTP) > + u8 hwts_tx_en; > + bool hwts_rx_en; I see that the hwts_rx_en gets removed in the later patch. Instead you could add rx filters support only later when you have the final code in place. > +#endif > }; > > struct ksz_device { > diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c > index c737635ca266..a41418c6adf6 100644 > --- a/drivers/net/dsa/microchip/ksz_ptp.c > +++ b/drivers/net/dsa/microchip/ksz_ptp.c > @@ -36,15 +36,88 @@ int ksz_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *ts) > SOF_TIMESTAMPING_RX_HARDWARE | > SOF_TIMESTAMPING_RAW_HARDWARE; > > - ts->tx_types = BIT(HWTSTAMP_TX_OFF); > + ts->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ONESTEP_P2P); > > - ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE); > + ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); > > ts->phc_index = ptp_clock_index(ptp_data->clock); > > return 0; > } > > +int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) > +{ > + struct ksz_device *dev = ds->priv; > + struct hwtstamp_config config; > + > + config.flags = 0; > + > + config.tx_type = dev->ports[port].hwts_tx_en; > + > + if (dev->ports[port].hwts_rx_en) > + config.rx_filter = HWTSTAMP_FILTER_ALL; > + else > + config.rx_filter = HWTSTAMP_FILTER_NONE; > + > + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? > + -EFAULT : 0; > +} > + > +static int ksz_set_hwtstamp_config(struct ksz_device *dev, int port, > + struct hwtstamp_config *config) > +{ > + struct ksz_port *prt = &dev->ports[port]; > + > + if (config->flags) > + return -EINVAL; > + > + switch (config->tx_type) { > + case HWTSTAMP_TX_OFF: > + case HWTSTAMP_TX_ONESTEP_P2P: > + prt->hwts_tx_en = config->tx_type; > + break; > + default: > + return -ERANGE; > + } > + > + switch (config->rx_filter) { > + case HWTSTAMP_FILTER_NONE: > + prt->hwts_rx_en = false; > + break; > + default: > + prt->hwts_rx_en = true; > + break; > + } > + > + return 0; > +} > + > +int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) > +{ > + struct ksz_device *dev = ds->priv; > + struct ksz_ptp_data *ptp_data; > + struct hwtstamp_config config; > + int ret; > + > + ptp_data = &dev->ptp_data; > + > + mutex_lock(&ptp_data->lock); > + > + ret = copy_from_user(&config, ifr->ifr_data, sizeof(config)); > + if (ret) > + goto error_return; > + > + ret = ksz_set_hwtstamp_config(dev, port, &config); > + if (ret) > + goto error_return; > + > + ret = copy_to_user(ifr->ifr_data, &config, sizeof(config)); > + > +error_return: > + mutex_unlock(&ptp_data->lock); > + return ret; > +} > + > static int _ksz_ptp_gettime(struct ksz_device *dev, struct timespec64 *ts) > { > u32 nanoseconds; > diff --git a/drivers/net/dsa/microchip/ksz_ptp.h b/drivers/net/dsa/microchip/ksz_ptp.h > index ea9fa46caa01..17f455c3b2c5 100644 > --- a/drivers/net/dsa/microchip/ksz_ptp.h > +++ b/drivers/net/dsa/microchip/ksz_ptp.h > @@ -23,6 +23,8 @@ void ksz_ptp_clock_unregister(struct dsa_switch *ds); > > int ksz_get_ts_info(struct dsa_switch *ds, int port, > struct ethtool_ts_info *ts); > +int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr); > +int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr); > > #else > > @@ -40,6 +42,18 @@ static inline void ksz_ptp_clock_unregister(struct dsa_switch *ds) { } > > #define ksz_get_ts_info NULL > > +static inline int ksz_hwtstamp_get(struct dsa_switch *ds, int port, > + struct ifreq *ifr) > +{ > + return -EOPNOTSUPP; > +} > + > +static inline int ksz_hwtstamp_set(struct dsa_switch *ds, int port, > + struct ifreq *ifr) > +{ > + return -EOPNOTSUPP; > +} > + > #endif /* End of CONFIG_NET_DSA_MICROCHIP_KSZ_PTP */ > > #endif > -- > 2.36.1 > --000000000000d47ae205ee9810e7 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIIQbQYJKoZIhvcNAQcCoIIQXjCCEFoCAQExDzANBglghkgBZQMEAgEFADALBgkqhkiG9w0BBwGg gg3EMIIFDTCCA/WgAwIBAgIQeEqpED+lv77edQixNJMdADANBgkqhkiG9w0BAQsFADBMMSAwHgYD VQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UE AxMKR2xvYmFsU2lnbjAeFw0yMDA5MTYwMDAwMDBaFw0yODA5MTYwMDAwMDBaMFsxCzAJBgNVBAYT AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWduIEdDQyBS MyBQZXJzb25hbFNpZ24gMiBDQSAyMDIwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA vbCmXCcsbZ/a0fRIQMBxp4gJnnyeneFYpEtNydrZZ+GeKSMdHiDgXD1UnRSIudKo+moQ6YlCOu4t rVWO/EiXfYnK7zeop26ry1RpKtogB7/O115zultAz64ydQYLe+a1e/czkALg3sgTcOOcFZTXk38e aqsXsipoX1vsNurqPtnC27TWsA7pk4uKXscFjkeUE8JZu9BDKaswZygxBOPBQBwrA5+20Wxlk6k1 e6EKaaNaNZUy30q3ArEf30ZDpXyfCtiXnupjSK8WU2cK4qsEtj09JS4+mhi0CTCrCnXAzum3tgcH cHRg0prcSzzEUDQWoFxyuqwiwhHu3sPQNmFOMwIDAQABo4IB2jCCAdYwDgYDVR0PAQH/BAQDAgGG MGAGA1UdJQRZMFcGCCsGAQUFBwMCBggrBgEFBQcDBAYKKwYBBAGCNxQCAgYKKwYBBAGCNwoDBAYJ KwYBBAGCNxUGBgorBgEEAYI3CgMMBggrBgEFBQcDBwYIKwYBBQUHAxEwEgYDVR0TAQH/BAgwBgEB /wIBADAdBgNVHQ4EFgQUljPR5lgXWzR1ioFWZNW+SN6hj88wHwYDVR0jBBgwFoAUj/BLf6guRSSu TVD6Y5qL3uLdG7wwegYIKwYBBQUHAQEEbjBsMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9i YWxzaWduLmNvbS9yb290cjMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5j b20vY2FjZXJ0L3Jvb3QtcjMuY3J0MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwuZ2xvYmFs c2lnbi5jb20vcm9vdC1yMy5jcmwwWgYDVR0gBFMwUTALBgkrBgEEAaAyASgwQgYKKwYBBAGgMgEo CjA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAN BgkqhkiG9w0BAQsFAAOCAQEAdAXk/XCnDeAOd9nNEUvWPxblOQ/5o/q6OIeTYvoEvUUi2qHUOtbf jBGdTptFsXXe4RgjVF9b6DuizgYfy+cILmvi5hfk3Iq8MAZsgtW+A/otQsJvK2wRatLE61RbzkX8 9/OXEZ1zT7t/q2RiJqzpvV8NChxIj+P7WTtepPm9AIj0Keue+gS2qvzAZAY34ZZeRHgA7g5O4TPJ /oTd+4rgiU++wLDlcZYd/slFkaT3xg4qWDepEMjT4T1qFOQIL+ijUArYS4owpPg9NISTKa1qqKWJ jFoyms0d0GwOniIIbBvhI2MJ7BSY9MYtWVT5jJO3tsVHwj4cp92CSFuGwunFMzCCA18wggJHoAMC AQICCwQAAAAAASFYUwiiMA0GCSqGSIb3DQEBCwUAMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9v dCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTA5 MDMxODEwMDAwMFoXDTI5MDMxODEwMDAwMFowTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENB IC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMJXaQeQZ4Ihb1wIO2hMoonv0FdhHFrYhy/EYCQ8eyip0E XyTLLkvhYIJG4VKrDIFHcGzdZNHr9SyjD4I9DCuul9e2FIYQebs7E4B3jAjhSdJqYi8fXvqWaN+J J5U4nwbXPsnLJlkNc96wyOkmDoMVxu9bi9IEYMpJpij2aTv2y8gokeWdimFXN6x0FNx04Druci8u nPvQu7/1PQDhBjPogiuuU6Y6FnOM3UEOIDrAtKeh6bJPkC4yYOlXy7kEkmho5TgmYHWyn3f/kRTv riBJ/K1AFUjRAjFhGV64l++td7dkmnq/X8ET75ti+w1s4FRpFqkD2m7pg5NxdsZphYIXAgMBAAGj QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSP8Et/qC5FJK5N UPpjmove4t0bvDANBgkqhkiG9w0BAQsFAAOCAQEAS0DbwFCq/sgM7/eWVEVJu5YACUGssxOGhigH M8pr5nS5ugAtrqQK0/Xx8Q+Kv3NnSoPHRHt44K9ubG8DKY4zOUXDjuS5V2yq/BKW7FPGLeQkbLmU Y/vcU2hnVj6DuM81IcPJaP7O2sJTqsyQiunwXUaMld16WCgaLx3ezQA3QY/tRG3XUyiXfvNnBB4V 14qWtNPeTCekTBtzc3b0F5nCH3oO4y0IrQocLP88q1UOD5F+NuvDV0m+4S4tfGCLw0FREyOdzvcy a5QBqJnnLDMfOjsl0oZAzjsshnjJYS8Uuu7bVW/fhO4FCU29KNhyztNiUGUe65KXgzHZs7XKR1g/ XzCCBUwwggQ0oAMCAQICDBX9eQgKNWxyfhI1kzANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJC RTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTExMC8GA1UEAxMoR2xvYmFsU2lnbiBHQ0MgUjMg UGVyc29uYWxTaWduIDIgQ0EgMjAyMDAeFw0yMjA5MTAwODE3NDZaFw0yNTA5MTAwODE3NDZaMIGO MQswCQYDVQQGEwJJTjESMBAGA1UECBMJS2FybmF0YWthMRIwEAYDVQQHEwlCYW5nYWxvcmUxFjAU BgNVBAoTDUJyb2FkY29tIEluYy4xFTATBgNVBAMTDFBhdmFuIENoZWJiaTEoMCYGCSqGSIb3DQEJ ARYZcGF2YW4uY2hlYmJpQGJyb2FkY29tLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAK3X+BRR67FR5+Spki/E25HnHoYhm/cC6VA6qHwC3QqBNhCT13zsi1FLLERdKXPRrtVBM6d0 mfg/0rQJJ8Ez4C3CcKiO1XHcmESeW6lBKxOo83ZwWhVhyhNbGSwcrytDCKUVYBwwxR3PAyXtIlWn kDqifgqn3R9r2vJM7ckge8dtVPS0j9t3CNfDBjGw1DhK91fnoH1s7tLdj3vx9ZnKTmSl7F1psK2P OltyqaGBuzv+bJTUL+bmV7E4QBLIqGt4jVr1R9hJdH6KxXwJdyfHZ9C6qXmoe2NQhiFUyBOJ0wgk dB9Z1IU7nCwvNKYg2JMoJs93tIgbhPJg/D7pqW8gabkCAwEAAaOCAdowggHWMA4GA1UdDwEB/wQE AwIFoDCBowYIKwYBBQUHAQEEgZYwgZMwTgYIKwYBBQUHMAKGQmh0dHA6Ly9zZWN1cmUuZ2xvYmFs c2lnbi5jb20vY2FjZXJ0L2dzZ2NjcjNwZXJzb25hbHNpZ24yY2EyMDIwLmNydDBBBggrBgEFBQcw AYY1aHR0cDovL29jc3AuZ2xvYmFsc2lnbi5jb20vZ3NnY2NyM3BlcnNvbmFsc2lnbjJjYTIwMjAw TQYDVR0gBEYwRDBCBgorBgEEAaAyASgKMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2Jh bHNpZ24uY29tL3JlcG9zaXRvcnkvMAkGA1UdEwQCMAAwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDov L2NybC5nbG9iYWxzaWduLmNvbS9nc2djY3IzcGVyc29uYWxzaWduMmNhMjAyMC5jcmwwJAYDVR0R BB0wG4EZcGF2YW4uY2hlYmJpQGJyb2FkY29tLmNvbTATBgNVHSUEDDAKBggrBgEFBQcDBDAfBgNV HSMEGDAWgBSWM9HmWBdbNHWKgVZk1b5I3qGPzzAdBgNVHQ4EFgQUEV6y/89alKPoFbKUaJXsvWu5 fdowDQYJKoZIhvcNAQELBQADggEBAEHSIB6g652wVb+r2YCmfHW47Jo+5TuCBD99Hla8PYhaWGkd 9HIyD3NPhb6Vb6vtMWJW4MFGQF42xYRrAS4LZj072DuMotr79rI09pbOiWg0FlRRFt6R9vgUgebu pWSH7kmwVXcPtY94XSMMak4b7RSKig2mKbHDpD4bC7eGlwl5RxzYkgrHtMNRmHmQor5Nvqe52cFJ 25Azqtwvjt5nbrEd81iBmboNTEnLaKuxbbCtLaMEP8xKeDjAKnNOqHUMps0AsQT8c0EGq39YHpjp Wn1l67VU0rMShbEFsiUf9WYgE677oinpdm0t2mdCjxr35tryxptoTZXKHDxr/Yy6l6ExggJtMIIC aQIBATBrMFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQD EyhHbG9iYWxTaWduIEdDQyBSMyBQZXJzb25hbFNpZ24gMiBDQSAyMDIwAgwV/XkICjVscn4SNZMw DQYJYIZIAWUDBAIBBQCggdQwLwYJKoZIhvcNAQkEMSIEIPmfsH7p4SO4OuuGMJcvFgmbuCcIP2bd 0GjWTdkwOhETMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIyMTEy OTA4NDkyOFowaQYJKoZIhvcNAQkPMVwwWjALBglghkgBZQMEASowCwYJYIZIAWUDBAEWMAsGCWCG SAFlAwQBAjAKBggqhkiG9w0DBzALBgkqhkiG9w0BAQowCwYJKoZIhvcNAQEHMAsGCWCGSAFlAwQC ATANBgkqhkiG9w0BAQEFAASCAQBEPtq6r8IgGggN/TBjsDFvkrN4iC59UfdkkcOn7UpOxDNdBU5m k7xMs55ETeM/vLPxaWVZGmPDwzOyBEnG+1nC1LJsTzY/7+GJodRrOQOy4ul8nCW1k/Aojf6X0kDi s5jBbOeKLNW3QwfkEL/FKqR2C7TmheT7bRoCDbAA3NVasHL1KT2FrsklSKyO+xO4KFbF1Lw9eYsK HGImoHvDKwLgwMTOv+f2R9vAKZ034PRbY4664iW9Zm4rex6wlB3KfuPddr8rQkVYJm49ls6knSNe +BOIFFpEjwAsykej5L6IIELr0Y+0WGoF6mkjvs7H/2Vhup8fQBgA0nZLcuSZ2jMX --000000000000d47ae205ee9810e7--