From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 5872645A58; Tue, 15 Oct 2024 18:51:51 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A19C8402EE; Tue, 15 Oct 2024 18:51:49 +0200 (CEST) Received: from mail-pf1-f173.google.com (mail-pf1-f173.google.com [209.85.210.173]) by mails.dpdk.org (Postfix) with ESMTP id 419EE400D7 for ; Tue, 15 Oct 2024 18:51:48 +0200 (CEST) Received: by mail-pf1-f173.google.com with SMTP id d2e1a72fcca58-71e625b00bcso1918258b3a.3 for ; Tue, 15 Oct 2024 09:51:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iol.unh.edu; s=unh-iol; t=1729011107; x=1729615907; darn=dpdk.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=lEx63chR6lw83O6IqxKWVQWv8mhjBYwp1vR5Vv4O6ls=; b=bH979D0t47bEtqosy6xIe7BQHe1/nf/AVRYGQG+uIeYwLYOZ265mrM4pRCVtTK6WWw Erqb+3ZzX46LipKHyttuxYHshh8OGAPer7TZD9BqWgmqD4GcUFMdChgVuI5lBO0EKtuz BIEWCKA/q2RXKHee8lZDl2aQ4RBdndsdsYHyI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729011107; x=1729615907; 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=lEx63chR6lw83O6IqxKWVQWv8mhjBYwp1vR5Vv4O6ls=; b=MSf+0kJHcQ8WeZv5s30pHlKFNFw2rwX3m+Y9OD6DqljcmC6jLnlFQsbhk6h0HN1sOY Rr7yNDL28AtHyymmZHcR+fRy0JRRjF5HcJILqjsypQN607UBHPTZ/yLwAjloN5raxF7S a2LYeXw4e/AFKDywv2TstjACLfA/NZebzMG8uh3NpRug0btSeEO4/VGd7Xcb67m0+z5f LDmISkVPp3KJYpQvK7bLKpFH7tPTR/PJa5gIweVLXX8w36wBfq309qSHVZo6Xt/V/5wX oOdSa2Ey9COhlBz8dEy2y9cl5m+qyJxfXQ3tDFkAkcBgy5w0skF4epL4U94Y5Lgwj/Ab kBDg== X-Forwarded-Encrypted: i=1; AJvYcCWQ9HF7Q3hv/LdLAdndQYnhyhNaKVF+HZP6BGjvsip5Wz440qLwyU6ZahnA6D61gCJRcMU=@dpdk.org X-Gm-Message-State: AOJu0Yxq4DfZk8uIYN8BWpF9KxyoYde/kf8eVc6/xY9ReDrnbdbJQhoq TPuLhFC8EkO3itguvafzg481rT7E7HbaVUTgZ+pjh8T71OahuOO3xDW26Qk8HoN2PyKklTs2oJS YB8wOG04Mn7KxiqubZc98t7tf20P6imUY4brWoQ== X-Google-Smtp-Source: AGHT+IFDjgmwTaL9d8luW8kTHT3rrzJnKPz7BelKA/HCfcPwuA7JuCInVYarmZwbTRj3hsKAFOmEzTJF/m0lMTgKvTg= X-Received: by 2002:a05:6a00:928e:b0:71e:55e2:2c43 with SMTP id d2e1a72fcca58-71e55e23f97mr15244012b3a.14.1729011107411; Tue, 15 Oct 2024 09:51:47 -0700 (PDT) MIME-Version: 1.0 References: <20240812073209.1924286-1-zhang.yong25@zte.com.cn> <20241014081117.1704528-10-zhang.yong25@zte.com.cn> In-Reply-To: <20241014081117.1704528-10-zhang.yong25@zte.com.cn> From: Patrick Robb Date: Tue, 15 Oct 2024 12:50:22 -0400 Message-ID: Subject: Re: [v3 5/5] raw/gdtc: add support for dequeue operation To: Yong Zhang Cc: thomas@monjalon.net, techboard@dpdk.org, dev@dpdk.org, wang.yong19@zte.com.cn, li.min10@zte.com.cn, ran.ming@zte.com.cn Content-Type: multipart/alternative; boundary="000000000000ded3b2062486c4f9" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --000000000000ded3b2062486c4f9 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable It looks like this did not get processed correctly by patchwork, or there is an issue with the patchfiles. https://patchwork.dpdk.org/project/dpdk/list/?series=3D&submitter=3D&state= =3D&q=3Dgdtc&archive=3D&delegate=3D Can you resubmit? It was not picked up by 3/4 of the CI labs. On Mon, Oct 14, 2024 at 4:16=E2=80=AFAM Yong Zhang wrote: > Add rawdev dequeue operation for gdtc devices. > > Signed-off-by: Yong Zhang > --- > drivers/raw/gdtc/gdtc_rawdev.c | 113 +++++++++++++++++++++++++++++++++ > 1 file changed, 113 insertions(+) > > > diff --git a/drivers/raw/gdtc/gdtc_rawdev.c b/drivers/raw/gdtc/gdtc_rawde= v.c > index 03f7cc1a8e..8e9543f402 100644 > --- a/drivers/raw/gdtc/gdtc_rawdev.c > +++ b/drivers/raw/gdtc/gdtc_rawdev.c > @@ -88,6 +88,8 @@ > #define LOW32_MASK 0xffffffff > #define LOW16_MASK 0xffff > > +#define ZXDH_GDMA_TC_CNT_MAX 0x10000 > + > #define IDX_TO_ADDR(addr, idx, t) \ > ((t)((uintptr_t)(addr) + (idx) * sizeof(struct zxdh_gdma_buff_desc))= ) > > @@ -526,6 +528,116 @@ zxdh_gdma_rawdev_enqueue_bufs(struct rte_rawdev *de= v, > > return count; > } > + > +static inline void > > +zxdh_gdma_used_idx_update(struct zxdh_gdma_queue *queue, uint16_t cnt, u= int8_t data_bd_err) > +{ > + uint16_t idx =3D 0; > + > + if (queue->sw_ring.used_idx + cnt < queue->queue_size) > + queue->sw_ring.used_idx +=3D cnt; > + else > > + queue->sw_ring.used_idx =3D queue->sw_ring.used_idx + cnt - queu= e->queue_size; > + > + if (data_bd_err =3D=3D 1) { > + /* Update job status, the last job status is error */ > + if (queue->sw_ring.used_idx =3D=3D 0) > + idx =3D queue->queue_size - 1; > + else > + idx =3D queue->sw_ring.used_idx - 1; > + > + queue->sw_ring.job[idx]->status =3D 1; > + } > +} > + > +static int > +zxdh_gdma_rawdev_dequeue_bufs(struct rte_rawdev *dev, > + __rte_unused struct rte_rawdev_buf **buffers, > + uint32_t count, > + rte_rawdev_obj_t context) > +{ > + struct zxdh_gdma_queue *queue =3D NULL; > + struct zxdh_gdma_enqdeq *e_context =3D NULL; > + uint16_t queue_id =3D 0; > + uint32_t val =3D 0; > + uint16_t tc_cnt =3D 0; > + uint16_t diff_cnt =3D 0; > + uint16_t i =3D 0; > + uint16_t bd_idx =3D 0; > + uint64_t next_bd_addr =3D 0; > + uint8_t data_bd_err =3D 0; > + > + if ((dev =3D=3D NULL) || (context =3D=3D NULL)) > + return -EINVAL; > + > + e_context =3D (struct zxdh_gdma_enqdeq *)context; > + queue_id =3D e_context->vq_id; > + queue =3D zxdh_gdma_get_queue(dev, queue_id); > + if ((queue =3D=3D NULL) || (queue->enable =3D=3D 0)) > + return -EINVAL; > + > + if (queue->sw_ring.pend_cnt =3D=3D 0) > + goto deq_job; > + > + /* Get data transmit count */ > + val =3D zxdh_gdma_read_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET); > + tc_cnt =3D val & LOW16_MASK; > + if (tc_cnt >=3D queue->tc_cnt) > + diff_cnt =3D tc_cnt - queue->tc_cnt; > + else > + diff_cnt =3D tc_cnt + ZXDH_GDMA_TC_CNT_MAX - queue->tc_cnt; > + > + queue->tc_cnt =3D tc_cnt; > + > + /* Data transmit error, channel stopped */ > + if ((val & ZXDH_GDMA_ERR_STATUS) !=3D 0) { > > + next_bd_addr =3D zxdh_gdma_read_reg(dev, queue_id, ZXDH_GDMA_LL= I_L_OFFSET); > + next_bd_addr |=3D ((uint64_t)zxdh_gdma_read_reg(dev, queue_id, > + ZXDH_GDMA_LLI_H_OFFSET) << 32); > + next_bd_addr =3D next_bd_addr << 6; > > + bd_idx =3D (next_bd_addr - queue->ring.ring_mem) / sizeof(struct= zxdh_gdma_buff_desc); > > + if ((val & ZXDH_GDMA_SRC_DATA_ERR) || (val & ZXDH_GDMA_DST_ADDR_= ERR)) { > + diff_cnt++; > + data_bd_err =3D 1; > + } > > + ZXDH_PMD_LOG(INFO, "queue%d is err(0x%x) next_bd_idx:%u ll_addr:= 0x%"PRIx64" def user:0x%x", > + queue_id, val, bd_idx, next_bd_addr, queue->user); > + > + ZXDH_PMD_LOG(INFO, "Clean up error status"); > + val =3D ZXDH_GDMA_ERR_STATUS | ZXDH_GDMA_ERR_INTR_ENABLE; > + zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_TC_CNT_OFFSET, val)= ; > + > + ZXDH_PMD_LOG(INFO, "Restart channel"); > + zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_XFERSIZE_OFFSET, 0)= ; > + zxdh_gdma_control_cal(&val, 0); > + zxdh_gdma_write_reg(dev, queue_id, ZXDH_GDMA_CONTROL_OFFSET, val= ); > + } > + > + if (diff_cnt !=3D 0) { > + zxdh_gdma_used_idx_update(queue, diff_cnt, data_bd_err); > + queue->sw_ring.deq_cnt +=3D diff_cnt; > + queue->sw_ring.pend_cnt -=3D diff_cnt; > + } > + > +deq_job: > + if (queue->sw_ring.deq_cnt =3D=3D 0) > + return 0; > + else if (queue->sw_ring.deq_cnt < count) > + count =3D queue->sw_ring.deq_cnt; > + > + queue->sw_ring.deq_cnt -=3D count; > + > + for (i =3D 0; i < count; i++) { > + e_context->job[i] =3D queue->sw_ring.job[queue->sw_ring.deq_idx]= ; > + queue->sw_ring.job[queue->sw_ring.deq_idx] =3D NULL; > + if (++queue->sw_ring.deq_idx >=3D queue->queue_size) > + queue->sw_ring.deq_idx -=3D queue->queue_size; > + } > + queue->sw_ring.free_cnt +=3D count; > + > + return count; > +} > + > static const struct rte_rawdev_ops zxdh_gdma_rawdev_ops =3D { > .dev_info_get =3D zxdh_gdma_rawdev_info_get, > .dev_configure =3D zxdh_gdma_rawdev_configure, > > @@ -540,6 +652,7 @@ static const struct rte_rawdev_ops zxdh_gdma_rawdev_o= ps =3D { > .attr_get =3D zxdh_gdma_rawdev_get_attr, > > .enqueue_bufs =3D zxdh_gdma_rawdev_enqueue_bufs, > + .dequeue_bufs =3D zxdh_gdma_rawdev_dequeue_bufs, > }; > > static int > -- > 2.43.0 > --000000000000ded3b2062486c4f9 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+SXQgbG9va3MgbGlrZSB0aGlzIGRpZCBub3QgZ2V0IHByb2Nlc3NlZCBj b3JyZWN0bHkgYnkgcGF0Y2h3b3JrLCBvciB0aGVyZSBpcyBhbiBpc3N1ZSB3aXRoIHRoZSBwYXRj aGZpbGVzLsKgPGRpdj48YnI+PC9kaXY+PGRpdj48YSBocmVmPSJodHRwczovL3BhdGNod29yay5k cGRrLm9yZy9wcm9qZWN0L2RwZGsvbGlzdC8/c2VyaWVzPSZhbXA7c3VibWl0dGVyPSZhbXA7c3Rh dGU9JmFtcDtxPWdkdGMmYW1wO2FyY2hpdmU9JmFtcDtkZWxlZ2F0ZT0iPmh0dHBzOi8vcGF0Y2h3 b3JrLmRwZGsub3JnL3Byb2plY3QvZHBkay9saXN0Lz9zZXJpZXM9JmFtcDtzdWJtaXR0ZXI9JmFt cDtzdGF0ZT0mYW1wO3E9Z2R0YyZhbXA7YXJjaGl2ZT0mYW1wO2RlbGVnYXRlPTwvYT48YnI+PC9k aXY+PGRpdj48YnI+PC9kaXY+PGRpdj5DYW4geW91IHJlc3VibWl0PyBJdCB3YXMgbm90IHBpY2tl ZCB1cCBieSAzLzQgb2YgdGhlIENJIGxhYnMuPC9kaXY+PC9kaXY+PGJyPjxkaXYgY2xhc3M9Imdt YWlsX3F1b3RlIj48ZGl2IGRpcj0ibHRyIiBjbGFzcz0iZ21haWxfYXR0ciI+T24gTW9uLCBPY3Qg MTQsIDIwMjQgYXQgNDoxNuKAr0FNIFlvbmcgWmhhbmcgJmx0OzxhIGhyZWY9Im1haWx0bzp6aGFu Zy55b25nMjVAenRlLmNvbS5jbiI+emhhbmcueW9uZzI1QHp0ZS5jb20uY248L2E+Jmd0OyB3cm90 ZTo8YnI+PC9kaXY+PGJsb2NrcXVvdGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0ibWFyZ2lu OjBweCAwcHggMHB4IDAuOGV4O2JvcmRlci1sZWZ0OjFweCBzb2xpZCByZ2IoMjA0LDIwNCwyMDQp O3BhZGRpbmctbGVmdDoxZXgiPkFkZMKgcmF3ZGV2wqBkZXF1ZXVlwqBvcGVyYXRpb27CoGZvcsKg Z2R0Y8KgZGV2aWNlcy48YnI+DQo8YnI+U2lnbmVkLW9mZi1ieTrCoFlvbmfCoFpoYW5nwqAmbHQ7 PGEgaHJlZj0ibWFpbHRvOnpoYW5nLnlvbmcyNUB6dGUuY29tLmNuIiB0YXJnZXQ9Il9ibGFuayI+ emhhbmcueW9uZzI1QHp0ZS5jb20uY248L2E+Jmd0Ow0KPGJyPi0tLTxicj7CoGRyaXZlcnMvcmF3 L2dkdGMvZ2R0Y19yYXdkZXYuY8KgfMKgMTEzwqArKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKys8YnI+wqAxwqBmaWxlwqBjaGFuZ2VkLMKgMTEzwqBpbnNlcnRpb25zKCspPGJyPg0KPGJy PmRpZmbCoC0tZ2l0wqBhL2RyaXZlcnMvcmF3L2dkdGMvZ2R0Y19yYXdkZXYuY8KgYi9kcml2ZXJz L3Jhdy9nZHRjL2dkdGNfcmF3ZGV2LmM8YnI+aW5kZXjCoDAzZjdjYzFhOGUuLjhlOTU0M2Y0MDLC oDEwMDY0NDxicj4tLS3CoGEvZHJpdmVycy9yYXcvZ2R0Yy9nZHRjX3Jhd2Rldi5jPGJyPisrK8Kg Yi9kcml2ZXJzL3Jhdy9nZHRjL2dkdGNfcmF3ZGV2LmM8YnI+QEDCoC04OCw2wqArODgsOMKgQEA8 YnI+wqAjZGVmaW5lwqBMT1czMl9NQVNLwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgMHhmZmZmZmZmZjxicj7CoCNkZWZpbmXCoExPVzE2 X01BU0vCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAweGZmZmY8YnI+wqANCjxicj4rI2RlZmluZcKgWlhESF9HRE1BX1RDX0NOVF9NQVjC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgMHgxMDAwMDxicj4rPGJyPsKg I2RlZmluZcKgSURYX1RPX0FERFIoYWRkcizCoGlkeCzCoHQpwqBcPGJyPsKgwqDCoMKgwqAoKHQp KCh1aW50cHRyX3QpKGFkZHIpwqArwqAoaWR4KcKgKsKgc2l6ZW9mKHN0cnVjdMKgenhkaF9nZG1h X2J1ZmZfZGVzYykpKTxicj7CoA0KPGJyPkBAwqAtNTI2LDbCoCs1MjgsMTE2wqBAQMKgenhkaF9n ZG1hX3Jhd2Rldl9lbnF1ZXVlX2J1ZnMoc3RydWN0wqBydGVfcmF3ZGV2wqAqZGV2LDxicj7CoA0K PGJyPsKgwqDCoMKgwqByZXR1cm7CoGNvdW50Ozxicj7CoH08YnI+Kzxicj4rc3RhdGljwqBpbmxp bmXCoHZvaWQ8YnI+K3p4ZGhfZ2RtYV91c2VkX2lkeF91cGRhdGUoc3RydWN0wqB6eGRoX2dkbWFf cXVldWXCoCpxdWV1ZSzCoHVpbnQxNl90wqBjbnQswqB1aW50OF90wqBkYXRhX2JkX2Vycik8YnI+ K3s8YnI+K8KgwqDCoMKgdWludDE2X3TCoGlkeMKgPcKgMDs8YnI+Kzxicj4rwqDCoMKgwqBpZsKg KHF1ZXVlLSZndDtzd19yaW5nLnVzZWRfaWR4wqArwqBjbnTCoCZsdDvCoHF1ZXVlLSZndDtxdWV1 ZV9zaXplKTxicj4rwqDCoMKgwqDCoMKgwqDCoHF1ZXVlLSZndDtzd19yaW5nLnVzZWRfaWR4wqAr PcKgY250Ozxicj4rwqDCoMKgwqBlbHNlPGJyPivCoMKgwqDCoMKgwqDCoMKgcXVldWUtJmd0O3N3 X3JpbmcudXNlZF9pZHjCoD3CoHF1ZXVlLSZndDtzd19yaW5nLnVzZWRfaWR4wqArwqBjbnTCoC3C oHF1ZXVlLSZndDtxdWV1ZV9zaXplOzxicj4rPGJyPivCoMKgwqDCoGlmwqAoZGF0YV9iZF9lcnLC oD09wqAxKcKgezxicj4rwqDCoMKgwqDCoMKgwqDCoC8qwqBVcGRhdGXCoGpvYsKgc3RhdHVzLMKg dGhlwqBsYXN0wqBqb2LCoHN0YXR1c8KgaXPCoGVycm9ywqAqLzxicj4rwqDCoMKgwqDCoMKgwqDC oGlmwqAocXVldWUtJmd0O3N3X3JpbmcudXNlZF9pZHjCoD09wqAwKTxicj4rwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgaWR4wqA9wqBxdWV1ZS0mZ3Q7cXVldWVfc2l6ZcKgLcKgMTs8YnI+K8KgwqDC oMKgwqDCoMKgwqBlbHNlPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBpZHjCoD3CoHF1ZXVl LSZndDtzd19yaW5nLnVzZWRfaWR4wqAtwqAxOzxicj4rPGJyPivCoMKgwqDCoMKgwqDCoMKgcXVl dWUtJmd0O3N3X3Jpbmcuam9iW2lkeF0tJmd0O3N0YXR1c8KgPcKgMTs8YnI+K8KgwqDCoMKgfTxi cj4rfTxicj4rPGJyPitzdGF0aWPCoGludDxicj4renhkaF9nZG1hX3Jhd2Rldl9kZXF1ZXVlX2J1 ZnMoc3RydWN0wqBydGVfcmF3ZGV2wqAqZGV2LDxicj4rwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgX19ydGVfdW51c2VkwqBzdHJ1Y3TCoHJ0ZV9yYXdkZXZf YnVmwqAqKmJ1ZmZlcnMsPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqB1aW50MzJfdMKgY291bnQsPGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBydGVfcmF3ZGV2X29ial90wqBjb250ZXh0KTxicj4rezxi cj4rwqDCoMKgwqBzdHJ1Y3TCoHp4ZGhfZ2RtYV9xdWV1ZcKgKnF1ZXVlwqA9wqBOVUxMOzxicj4r wqDCoMKgwqBzdHJ1Y3TCoHp4ZGhfZ2RtYV9lbnFkZXHCoCplX2NvbnRleHTCoD3CoE5VTEw7PGJy PivCoMKgwqDCoHVpbnQxNl90wqBxdWV1ZV9pZMKgPcKgMDs8YnI+K8KgwqDCoMKgdWludDMyX3TC oHZhbMKgPcKgMDs8YnI+K8KgwqDCoMKgdWludDE2X3TCoHRjX2NudMKgPcKgMDs8YnI+K8KgwqDC oMKgdWludDE2X3TCoGRpZmZfY250wqA9wqAwOzxicj4rwqDCoMKgwqB1aW50MTZfdMKgacKgPcKg MDs8YnI+K8KgwqDCoMKgdWludDE2X3TCoGJkX2lkeMKgPcKgMDs8YnI+K8KgwqDCoMKgdWludDY0 X3TCoG5leHRfYmRfYWRkcsKgPcKgMDs8YnI+K8KgwqDCoMKgdWludDhfdMKgZGF0YV9iZF9lcnLC oD3CoDA7PGJyPis8YnI+K8KgwqDCoMKgaWbCoCgoZGV2wqA9PcKgTlVMTCnCoHx8wqAoY29udGV4 dMKgPT3CoE5VTEwpKTxicj4rwqDCoMKgwqDCoMKgwqDCoHJldHVybsKgLUVJTlZBTDs8YnI+Kzxi cj4rwqDCoMKgwqBlX2NvbnRleHTCoD3CoChzdHJ1Y3TCoHp4ZGhfZ2RtYV9lbnFkZXHCoCopY29u dGV4dDs8YnI+K8KgwqDCoMKgcXVldWVfaWTCoD3CoGVfY29udGV4dC0mZ3Q7dnFfaWQ7PGJyPivC oMKgwqDCoHF1ZXVlwqA9wqB6eGRoX2dkbWFfZ2V0X3F1ZXVlKGRldizCoHF1ZXVlX2lkKTs8YnI+ K8KgwqDCoMKgaWbCoCgocXVldWXCoD09wqBOVUxMKcKgfHzCoChxdWV1ZS0mZ3Q7ZW5hYmxlwqA9 PcKgMCkpPGJyPivCoMKgwqDCoMKgwqDCoMKgcmV0dXJuwqAtRUlOVkFMOzxicj4rPGJyPivCoMKg wqDCoGlmwqAocXVldWUtJmd0O3N3X3JpbmcucGVuZF9jbnTCoD09wqAwKTxicj4rwqDCoMKgwqDC oMKgwqDCoGdvdG/CoGRlcV9qb2I7PGJyPis8YnI+K8KgwqDCoMKgLyrCoEdldMKgZGF0YcKgdHJh bnNtaXTCoGNvdW50wqAqLzxicj4rwqDCoMKgwqB2YWzCoD3CoHp4ZGhfZ2RtYV9yZWFkX3JlZyhk ZXYswqBxdWV1ZV9pZCzCoFpYREhfR0RNQV9UQ19DTlRfT0ZGU0VUKTs8YnI+K8KgwqDCoMKgdGNf Y250wqA9wqB2YWzCoCZhbXA7wqBMT1cxNl9NQVNLOzxicj4rwqDCoMKgwqBpZsKgKHRjX2NudMKg Jmd0Oz3CoHF1ZXVlLSZndDt0Y19jbnQpPGJyPivCoMKgwqDCoMKgwqDCoMKgZGlmZl9jbnTCoD3C oHRjX2NudMKgLcKgcXVldWUtJmd0O3RjX2NudDs8YnI+K8KgwqDCoMKgZWxzZTxicj4rwqDCoMKg wqDCoMKgwqDCoGRpZmZfY250wqA9wqB0Y19jbnTCoCvCoFpYREhfR0RNQV9UQ19DTlRfTUFYwqAt wqBxdWV1ZS0mZ3Q7dGNfY250Ozxicj4rPGJyPivCoMKgwqDCoHF1ZXVlLSZndDt0Y19jbnTCoD3C oHRjX2NudDs8YnI+Kzxicj4rwqDCoMKgwqAvKsKgRGF0YcKgdHJhbnNtaXTCoGVycm9yLMKgY2hh bm5lbMKgc3RvcHBlZMKgKi88YnI+K8KgwqDCoMKgaWbCoCgodmFswqAmYW1wO8KgWlhESF9HRE1B X0VSUl9TVEFUVVMpwqAhPcKgMCnCoHs8YnI+K8KgwqDCoMKgwqDCoMKgwqBuZXh0X2JkX2FkZHLC oMKgPcKgenhkaF9nZG1hX3JlYWRfcmVnKGRldizCoHF1ZXVlX2lkLMKgWlhESF9HRE1BX0xMSV9M X09GRlNFVCk7PGJyPivCoMKgwqDCoMKgwqDCoMKgbmV4dF9iZF9hZGRywqB8PcKgKCh1aW50NjRf dCl6eGRoX2dkbWFfcmVhZF9yZWcoZGV2LMKgcXVldWVfaWQsPGJyPivCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoFpYREhfR0RNQV9MTElfSF9P RkZTRVQpwqAmbHQ7Jmx0O8KgMzIpOzxicj4rwqDCoMKgwqDCoMKgwqDCoG5leHRfYmRfYWRkcsKg wqA9wqBuZXh0X2JkX2FkZHLCoCZsdDsmbHQ7wqA2Ozxicj4rwqDCoMKgwqDCoMKgwqDCoGJkX2lk eMKgPcKgKG5leHRfYmRfYWRkcsKgLcKgcXVldWUtJmd0O3JpbmcucmluZ19tZW0pwqAvwqBzaXpl b2Yoc3RydWN0wqB6eGRoX2dkbWFfYnVmZl9kZXNjKTs8YnI+K8KgwqDCoMKgwqDCoMKgwqBpZsKg KCh2YWzCoCZhbXA7wqBaWERIX0dETUFfU1JDX0RBVEFfRVJSKcKgfHzCoCh2YWzCoCZhbXA7wqBa WERIX0dETUFfRFNUX0FERFJfRVJSKSnCoHs8YnI+K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGRp ZmZfY250Kys7PGJyPivCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBkYXRhX2JkX2VycsKgPcKgMTs8 YnI+K8KgwqDCoMKgwqDCoMKgwqB9PGJyPivCoMKgwqDCoMKgwqDCoMKgWlhESF9QTURfTE9HKElO Rk8swqAmcXVvdDtxdWV1ZSVkwqBpc8KgZXJyKDB4JXgpwqBuZXh0X2JkX2lkeDoldcKgbGxfYWRk cjoweCUmcXVvdDtQUkl4NjQmcXVvdDvCoGRlZsKgdXNlcjoweCV4JnF1b3Q7LDxicj4rwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHF1ZXVlX2lkLMKgdmFsLMKgYmRfaWR4 LMKgbmV4dF9iZF9hZGRyLMKgcXVldWUtJmd0O3VzZXIpOzxicj4rPGJyPivCoMKgwqDCoMKgwqDC oMKgWlhESF9QTURfTE9HKElORk8swqAmcXVvdDtDbGVhbsKgdXDCoGVycm9ywqBzdGF0dXMmcXVv dDspOzxicj4rwqDCoMKgwqDCoMKgwqDCoHZhbMKgPcKgWlhESF9HRE1BX0VSUl9TVEFUVVPCoHzC oFpYREhfR0RNQV9FUlJfSU5UUl9FTkFCTEU7PGJyPivCoMKgwqDCoMKgwqDCoMKgenhkaF9nZG1h X3dyaXRlX3JlZyhkZXYswqBxdWV1ZV9pZCzCoFpYREhfR0RNQV9UQ19DTlRfT0ZGU0VULMKgdmFs KTs8YnI+Kzxicj4rwqDCoMKgwqDCoMKgwqDCoFpYREhfUE1EX0xPRyhJTkZPLMKgJnF1b3Q7UmVz dGFydMKgY2hhbm5lbCZxdW90Oyk7PGJyPivCoMKgwqDCoMKgwqDCoMKgenhkaF9nZG1hX3dyaXRl X3JlZyhkZXYswqBxdWV1ZV9pZCzCoFpYREhfR0RNQV9YRkVSU0laRV9PRkZTRVQswqAwKTs8YnI+ K8KgwqDCoMKgwqDCoMKgwqB6eGRoX2dkbWFfY29udHJvbF9jYWwoJmFtcDt2YWwswqAwKTs8YnI+ K8KgwqDCoMKgwqDCoMKgwqB6eGRoX2dkbWFfd3JpdGVfcmVnKGRldizCoHF1ZXVlX2lkLMKgWlhE SF9HRE1BX0NPTlRST0xfT0ZGU0VULMKgdmFsKTs8YnI+K8KgwqDCoMKgfTxicj4rPGJyPivCoMKg wqDCoGlmwqAoZGlmZl9jbnTCoCE9wqAwKcKgezxicj4rwqDCoMKgwqDCoMKgwqDCoHp4ZGhfZ2Rt YV91c2VkX2lkeF91cGRhdGUocXVldWUswqBkaWZmX2NudCzCoGRhdGFfYmRfZXJyKTs8YnI+K8Kg wqDCoMKgwqDCoMKgwqBxdWV1ZS0mZ3Q7c3dfcmluZy5kZXFfY250wqArPcKgZGlmZl9jbnQ7PGJy PivCoMKgwqDCoMKgwqDCoMKgcXVldWUtJmd0O3N3X3JpbmcucGVuZF9jbnTCoC09wqBkaWZmX2Nu dDs8YnI+K8KgwqDCoMKgfTxicj4rPGJyPitkZXFfam9iOjxicj4rwqDCoMKgwqBpZsKgKHF1ZXVl LSZndDtzd19yaW5nLmRlcV9jbnTCoD09wqAwKTxicj4rwqDCoMKgwqDCoMKgwqDCoHJldHVybsKg MDs8YnI+K8KgwqDCoMKgZWxzZcKgaWbCoChxdWV1ZS0mZ3Q7c3dfcmluZy5kZXFfY250wqAmbHQ7 wqBjb3VudCk8YnI+K8KgwqDCoMKgwqDCoMKgwqBjb3VudMKgPcKgcXVldWUtJmd0O3N3X3Jpbmcu ZGVxX2NudDs8YnI+Kzxicj4rwqDCoMKgwqBxdWV1ZS0mZ3Q7c3dfcmluZy5kZXFfY250wqAtPcKg Y291bnQ7PGJyPis8YnI+K8KgwqDCoMKgZm9ywqAoacKgPcKgMDvCoGnCoCZsdDvCoGNvdW50O8Kg aSsrKcKgezxicj4rwqDCoMKgwqDCoMKgwqDCoGVfY29udGV4dC0mZ3Q7am9iW2ldwqA9wqBxdWV1 ZS0mZ3Q7c3dfcmluZy5qb2JbcXVldWUtJmd0O3N3X3JpbmcuZGVxX2lkeF07PGJyPivCoMKgwqDC oMKgwqDCoMKgcXVldWUtJmd0O3N3X3Jpbmcuam9iW3F1ZXVlLSZndDtzd19yaW5nLmRlcV9pZHhd wqA9wqBOVUxMOzxicj4rwqDCoMKgwqDCoMKgwqDCoGlmwqAoKytxdWV1ZS0mZ3Q7c3dfcmluZy5k ZXFfaWR4wqAmZ3Q7PcKgcXVldWUtJmd0O3F1ZXVlX3NpemUpPGJyPivCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqBxdWV1ZS0mZ3Q7c3dfcmluZy5kZXFfaWR4wqAtPcKgcXVldWUtJmd0O3F1ZXVlX3Np emU7PGJyPivCoMKgwqDCoH08YnI+K8KgwqDCoMKgcXVldWUtJmd0O3N3X3JpbmcuZnJlZV9jbnTC oCs9wqBjb3VudDs8YnI+Kzxicj4rwqDCoMKgwqByZXR1cm7CoGNvdW50Ozxicj4rfTxicj4rPGJy PsKgc3RhdGljwqBjb25zdMKgc3RydWN0wqBydGVfcmF3ZGV2X29wc8KgenhkaF9nZG1hX3Jhd2Rl dl9vcHPCoD3CoHs8YnI+wqDCoMKgwqDCoC5kZXZfaW5mb19nZXTCoD3CoHp4ZGhfZ2RtYV9yYXdk ZXZfaW5mb19nZXQsPGJyPsKgwqDCoMKgwqAuZGV2X2NvbmZpZ3VyZcKgPcKgenhkaF9nZG1hX3Jh d2Rldl9jb25maWd1cmUsPGJyPkBAwqAtNTQwLDbCoCs2NTIsN8KgQEDCoHN0YXRpY8KgY29uc3TC oHN0cnVjdMKgcnRlX3Jhd2Rldl9vcHPCoHp4ZGhfZ2RtYV9yYXdkZXZfb3BzwqA9wqB7PGJyPsKg wqDCoMKgwqAuYXR0cl9nZXTCoD3CoHp4ZGhfZ2RtYV9yYXdkZXZfZ2V0X2F0dHIsPGJyPsKgDQo8 YnI+wqDCoMKgwqDCoC5lbnF1ZXVlX2J1ZnPCoD3CoHp4ZGhfZ2RtYV9yYXdkZXZfZW5xdWV1ZV9i dWZzLDxicj4rwqDCoMKgwqAuZGVxdWV1ZV9idWZzwqA9wqB6eGRoX2dkbWFfcmF3ZGV2X2RlcXVl dWVfYnVmcyw8YnI+wqB9Ozxicj7CoA0KPGJyPsKgc3RhdGljwqBpbnQ8YnI+LS3CoA0KPGJyPjIu NDMuMDxicj48L2Jsb2NrcXVvdGU+PC9kaXY+DQo= --000000000000ded3b2062486c4f9--