From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-SN1-obe.outbound.protection.outlook.com (mail-sn1nam02on0070.outbound.protection.outlook.com [104.47.36.70]) by dpdk.org (Postfix) with ESMTP id A084BD2D8 for ; Sat, 25 Mar 2017 07:28:00 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=bv1cEvQ83cW91q62NkLO9bnYTrUAO7i+Pxb0L5ljQmE=; b=NSReKjIPn6BWF3fCUwaMLCaQ5Mqe6l/ovvPbnW+S8j+4xuFOuYcRldI2c6R/D8CfEQajYa67GLrzil3VgW+gxNvBl+lO2BvZMC85gqAM2pXSVHtmfGiRtIyqpQwrgmiDc48NrG5w9W+gKZR4FrzH89ZuuHnvYb0EvLMyIGEfTlM= Authentication-Results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=caviumnetworks.com; Received: from lio357.in.caveonetworks.com (14.140.2.178) by CY1PR07MB2280.namprd07.prod.outlook.com (10.164.112.158) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.977.11; Sat, 25 Mar 2017 06:27:56 +0000 From: Shijith Thotton To: Ferruh Yigit Cc: dev@dpdk.org, Jerin Jacob , Derek Chickles , Venkat Koppula , Srisivasubramanian S , Mallesham Jatharakonda Date: Sat, 25 Mar 2017 11:54:32 +0530 Message-Id: <1490423097-6797-22-git-send-email-shijith.thotton@caviumnetworks.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1490423097-6797-1-git-send-email-shijith.thotton@caviumnetworks.com> References: <1488454371-3342-1-git-send-email-shijith.thotton@caviumnetworks.com> <1490423097-6797-1-git-send-email-shijith.thotton@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [14.140.2.178] X-ClientProxiedBy: BM1PR01CA0117.INDPRD01.PROD.OUTLOOK.COM (10.174.208.33) To CY1PR07MB2280.namprd07.prod.outlook.com (10.164.112.158) X-MS-Office365-Filtering-Correlation-Id: 8d339322-1328-49d5-4647-08d4734814d9 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:CY1PR07MB2280; X-Microsoft-Exchange-Diagnostics: 1; CY1PR07MB2280; 3:O/ILDB+8vEF21tFBWwx+qXXI/SKK8krF60XesaVaPYgiCK9RTUN0ovaJntrD7mucGhRJlejLdmeeGzPFRkZxG0g3QA6uziSlJ0/752uOmuC6N7xOW/vXjnD5HPvXyd2KdbRzQNgyFMhWWtGzLFL/ljxpLO2D8ZDrgyZ+ELbInXHRgSiOGi+DRhakWiZRiEYEUKwARj5DKs+YJ2bNX5cWwyB+ZpocLzqczEC78YJ0NRlJ40LWzjGLAXqrnQCvezUEKgp1Co29NKZLIuv6RTvg7Q==; 25:ARTVTgh1Jo8fMoJyNNCeRM68seAocXV8BH/bprna+3wI8JLO2DaJkoSlz1o+3eHciL9Qu2DXtZ5Dfi9xg3VwZZfesf/LY3d9zU6kpwZhLvxrxS3Sv5MJcciBJw5Rpad4ZckvmdgSjkEDuUKnpNhJmFeuFmT/6/W9+sQ/MjNHYJ0qn7chDLGOqwQvfjzAJ2gLDwzQK7NyupT55axSfyVdt8Lge3Qww1opfbQwJuu/sj4waXNClEog/rVcWtqk5HVACp9vJrlLes+xH0T0YtUAMb39TfIDAXFmZ7NZo79HaVMGMXYAUcsSVBPtioy905kZpKIEq26p4myjy2iUqhRE5FF9ZT6hF4jl2CpImsd2+NbKQ56PvNvKFPaJ6Xu97Ja6CZVSB+aWJ0C2XtpwDL/aafXDL4o5pxnbwil4BMKflSfTnTqpOaU88T9m9EZwq7YSwP6B+BSS9R+E0WrKYRTEcA== X-Microsoft-Exchange-Diagnostics: 1; CY1PR07MB2280; 31:1cVblrPAUnakGXDv9GocMIvKD7stoKwGqD7rFQKRQ3LNBNiFJmUH5rCh6vKDYE0e/I1tmg1OnozUCyXvZEa68BOtpXCEA29dX2lAY5MdZJtmTuRgAbXcfRJ4oUFyMguAiMmf0TH3DZnpdgjEMtkXP3ZFT4LjUI5k0XkL0PnDLviqd1ShAt3arJPxAbfmY0LFRV4V72/P0JZTqKqMFXHSoKDSugg6CbvWkD2I/gL7304WHSAKHm8yvweGqU7hNzxu; 20:yfG/DlO1GtDoaVYzzu/tCLkMM9RQ0qWNLZ92/ts46V7b6iayyaV33GJ79hW+WFI4KJ7W82xobTG98kK+lhHZwxRW4w7+6VKMRximgyj8gIVceJzV8d5QdABAJYQmWktGvcq1F0mEK/HPTVfQreJz0RE7MHgdrn3/Y2M8z4Hk4feMXNPG42gJxWmGZ8yMM9jlRpRa2reQdt0xDuUriHOsNvCwinpbnbmk1goeQ/3duzXT2whmJrxouxqrZeq29rL/WOCDIaEqPoaSxpCfI7hZpfos9wAjydEWJp+GAHYglDdobOqbhyqsEa6/oq3qmucqf7ZjRlO8k8GG0cFaodM1tVlS37G5O5Q5iioiYZxD6LeGJyBqir0tsiFuiUv/wrT/TcloWNJ76PqnfeIvXIyOblOvCw0GvgQNOV4u3HMtYLe3pH+EakrbNSklUbWQvwYeD31KrJt70ntyqca9EUQKvwfbZJUn1If6ArP8iwRHB6Ig1yOWWu7KJGs+G54v9wdyE6kgVlj6h5BYvjQsAQpBcNeoawJ6rbtLKSOnTqMOdS20NnklIeHy/ul3fFze5rw6LQ4W6NyDKGDiLmAQ/YUNDcSN53NZlklx3j0MRSEBtBY= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6041248)(20161123564025)(20161123560025)(20161123562025)(20161123558025)(20161123555025)(6072148); SRVR:CY1PR07MB2280; BCL:0; PCL:0; RULEID:; SRVR:CY1PR07MB2280; X-Microsoft-Exchange-Diagnostics: 1; CY1PR07MB2280; 4:YlEQvwhvndCe46IGPOamiVNojaVL6Z60hwOLIva975cX2nJKRRbsidoubfoniR6bjKE2/CZw9Oi1AJ4bNEe7Yyx8E3PEDK8bozGbA7mxaLfdZfVMHfH0AJy5nzoSG2FVL77upnyKTLohipSyeQmTOYRb4vEk7lwsLXk9K0IyUOIqt6xcj+yfdQ5kdTwIAf7B3UnHzJ1PGwja9ckj1j5YtxsSlaRtB8N72wuwkdIEv/20TToUrdmdT5uJFUJg0oNdL14vjcD1op8zkMYPLC36BCKySeumj5Kqx5WllOgKR49+jn3H3cKPbEuCN+hqyp4rBL0MtDhMgYC/KmYGitFDBG4hSiDXzgauM2ti6aSdZk0Eh85jqBJzOD2zeYBP1hNmDI6G0F6iCDmZmgREoCqxj+a3eNzW4+sY9OTZR5UTPylQxT1175E7R6zBsUWtdR7bJjD8pMMgTEusVEugzVvpzFoNfx+YbNS3H8JDBuZXoLWCwRsRIeXaB3HV9vR4v774txMbvTyQbZeiVdlUvOWg8qjlxuDlP6eQ124odPHKFW9DsBT0hu1FCQ1egO9AM80iECMwyXp7C1CGfMkH3nYSaotOFaKaMaaRbn7cg/maUTc= X-Forefront-PRVS: 025796F161 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(39450400003)(39410400002)(39830400002)(2906002)(2950100002)(5003940100001)(66066001)(42882006)(6916009)(50466002)(48376002)(47776003)(42186005)(53936002)(6512007)(68736007)(5009440100003)(54906002)(50226002)(38730400002)(6486002)(6666003)(25786009)(305945005)(81166006)(7736002)(6116002)(3846002)(4326008)(8676002)(6506006)(189998001)(36756003)(50986999)(76176999)(33646002)(4720700003)(5660300001)(110136004)(110426004); DIR:OUT; SFP:1101; SCL:1; SRVR:CY1PR07MB2280; H:lio357.in.caveonetworks.com; FPR:; SPF:None; MLV:nov; PTR:InfoNoRecords; LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY1PR07MB2280; 23:HQvrYRz2iCxst9RFj1WGsRO78u25Cm/ljpOnBS3F1?= =?us-ascii?Q?oq2Jm6vOJJ+JdnoUGAEws+W6r2ihWRkfcv5MN2ggmgEUVqf+zrdh4G53wmar?= =?us-ascii?Q?nEqw2h9RmlEEZ1eCuae6olyyc9lJ5g7lGRcf3Wd9KzhMetz9Y0G+M7iLNMmR?= =?us-ascii?Q?bLi3yPORzU5w1BNuuEIN7ombgSw3mEiIRAu9uUSPWJmE7stn9T+FK2Xuukph?= =?us-ascii?Q?KiIithXjg6oCySQn0jVdf4y5QaJ7gu/mgBDccybD4/kLFoQzAmkBP0ZKGgvA?= =?us-ascii?Q?1K1siydq+28l1kwbXVOinIQ469Gx1kV6He8dks5Dm+AZlRTqi/YR3PyL/9SP?= =?us-ascii?Q?aLBySPhsUyFJm3Vhz9vMW+aO3pfMsJly2iQbgOjXQvLOASg+WwOsoHPzorkX?= =?us-ascii?Q?h1YgXm9D//M4iG147HeAliUBqjjDipmECW6cGX5zHBKvxi8u7Q/uldfw/vdn?= =?us-ascii?Q?G07iYwQjDaQSyGZIdUlu7IaxToy0d5qf84hr7BRwH5kIti+/X2vZDl6j9R3D?= =?us-ascii?Q?cLKgChIAiW7BqjUSYybn72trRUJY4fODVKyq53SWyzHCjmyOvSySrJganco7?= =?us-ascii?Q?DGvdFRGXzfVSuae+AeMOY6yHOdJw8TMtAupySYiOFXh3OXXHRTmmneARdudS?= =?us-ascii?Q?bXgBnvB32yEGA0hKAFnM/MDGcOZrL1kjuNa/x0desZIpUGrkCTU21U83FaPk?= =?us-ascii?Q?yzNZDDEVtlGUoGictd9UfBRjWwi069nARVx2eDYeelh9JSEreNwQkqnwHbvv?= =?us-ascii?Q?NXEp5SXHJmtu/z5kEOZX4wWMoVuPQsHLdzSPEz8QjabtjtlIx34OHNwUbdVL?= =?us-ascii?Q?OpPCKfqBWlpUSYr9VwrkVGhWc8wgVR9eHmehXphru9wowLJhGA595r0RmAry?= =?us-ascii?Q?b4ebVBJwn2+d1Qf1S3MZCyxh/uVu5sH7d1qAwuxxOMmRbW8YY/6npRmFcsJQ?= =?us-ascii?Q?dZQd0zQywPS6anEny/NqDXVWDnjTbmtyVNRS9Q7uelYlfgERCraL1oJR/IOv?= =?us-ascii?Q?lS8v0pe1Xeovv8Z39A/Nn4OGWQomIMdyjojcuyw9F373rkK/vLU2Bad1XHcD?= =?us-ascii?Q?j0CHXzMIvwmtHOjtHJrgkIa4gRB?= X-Microsoft-Exchange-Diagnostics: 1; CY1PR07MB2280; 6:AxsMb/p3AIcR7DrME7UpTkF+JmuMTCIz6GAE7WOJsNK89By2+9rck+pI+OKgCv2u6G0uOH30S2TZ88MilBIYNioYJsfuQ0i6P5AObJYJ5VHvLpd5czWztMG/QYVrUccNBQKT05URWEzwZWmAX3CfRIfMnjBP8WsS8RASxZ+Mx0cweXKMOr0hU1IYDMAqnn6Q/vIb+ckTqNjTL4pQvYPwVCXiBxiezPJXRC63782vz3QLqnjiuJX8W7WgtMxrmxKC2N5svmdxmkWyZqF16Tb2DyDWVfHcBUTiEnNvKNSIJDwRH5RhSqi8qyfHdKFv19imXO29w1CnFDtR8lODvzCRvOUgR6LYlIc0uiXbz5wXw/0nwaxVIS2t8qChFE0aMKixtsZSy5vYoEDCOq2dh/XRBQ==; 5:mnDA1myTwxCLUjki8rtv4qxLAuEG4+z9KNDXP51t6DYMd+JYAzRk+Vm6b2AyazFKzo1K1YvLIJmHFSkk1dVillRJM7S8/n9DVM7DkTZOLY0kT1dfr5VfUCMpj7SVZ0NexMhxJe2LiMlLNhjxqmUrKQ==; 24:6eEi/u+/QdWd+kCB+hiuu/0nznS68VgIiAayvN0odD4JGCwzUjNZrg50XanBXKXf5fIMyaeVf2+dESVLoHpdj8rkkqHKvAM+D1sKeiwpxbY= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY1PR07MB2280; 7:INUfqBoA3SiQX3Vy+GlMENQM8CtsQaMaVoe723Ak3F1cQxvPUm1JXWzjOYsoVJ3TeEKOCFN/LIWMYB9cgGqzG4963dYAZOJEe8tdq0DNuW8AjHgK/XoIxucY9qmkGvw3NEV7JWNbsjYmLkoDCxE6kCn0ImxgL78VlXijf6z+LjOn8RwhtoTQmjG/qNUDLhYG7UQSiiAmb6XLVIGC+76/NwL2pniCGuJayyHD2nO3rEdPK7NgHzEziZ+odYxc1toL7fPxMklqmMobOp4ydC6nAacphpzQGEa3XtPcx8bbnK831e6LAOQMDRRb7y4AO7Lvha+BiK/JqRC9lZT+0vcC5g== X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Mar 2017 06:27:56.7056 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR07MB2280 Subject: [dpdk-dev] [PATCH v3 21/46] net/liquidio: initialize Rx queue X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 25 Mar 2017 06:28:01 -0000 Initialize Rx queue registers and allocate packet buffers for Rx queue. Signed-off-by: Shijith Thotton Signed-off-by: Jerin Jacob Signed-off-by: Derek Chickles Signed-off-by: Venkat Koppula Signed-off-by: Srisivasubramanian S Signed-off-by: Mallesham Jatharakonda --- drivers/net/liquidio/base/lio_23xx_vf.c | 22 ++++++++ drivers/net/liquidio/base/lio_hw_defs.h | 2 + drivers/net/liquidio/lio_rxtx.c | 96 +++++++++++++++++++++++++++++++++ drivers/net/liquidio/lio_rxtx.h | 20 +++++++ drivers/net/liquidio/lio_struct.h | 1 + 5 files changed, 141 insertions(+) diff --git a/drivers/net/liquidio/base/lio_23xx_vf.c b/drivers/net/liquidio/base/lio_23xx_vf.c index 181f830..44d90c0 100644 --- a/drivers/net/liquidio/base/lio_23xx_vf.c +++ b/drivers/net/liquidio/base/lio_23xx_vf.c @@ -233,6 +233,27 @@ } static void +cn23xx_vf_setup_oq_regs(struct lio_device *lio_dev, uint32_t oq_no) +{ + struct lio_droq *droq = lio_dev->droq[oq_no]; + + PMD_INIT_FUNC_TRACE(); + + lio_write_csr64(lio_dev, CN23XX_SLI_OQ_BASE_ADDR64(oq_no), + droq->desc_ring_dma); + lio_write_csr(lio_dev, CN23XX_SLI_OQ_SIZE(oq_no), droq->max_count); + + lio_write_csr(lio_dev, CN23XX_SLI_OQ_BUFF_INFO_SIZE(oq_no), + (droq->buffer_size | (OCTEON_RH_SIZE << 16))); + + /* Get the mapped address of the pkt_sent and pkts_credit regs */ + droq->pkts_sent_reg = (uint8_t *)lio_dev->hw_addr + + CN23XX_SLI_OQ_PKTS_SENT(oq_no); + droq->pkts_credit_reg = (uint8_t *)lio_dev->hw_addr + + CN23XX_SLI_OQ_PKTS_CREDIT(oq_no); +} + +static void cn23xx_vf_free_mbox(struct lio_device *lio_dev) { PMD_INIT_FUNC_TRACE(); @@ -436,6 +457,7 @@ return -1; lio_dev->fn_list.setup_iq_regs = cn23xx_vf_setup_iq_regs; + lio_dev->fn_list.setup_oq_regs = cn23xx_vf_setup_oq_regs; lio_dev->fn_list.setup_mbox = cn23xx_vf_setup_mbox; lio_dev->fn_list.free_mbox = cn23xx_vf_free_mbox; diff --git a/drivers/net/liquidio/base/lio_hw_defs.h b/drivers/net/liquidio/base/lio_hw_defs.h index 35d59fd..4271730 100644 --- a/drivers/net/liquidio/base/lio_hw_defs.h +++ b/drivers/net/liquidio/base/lio_hw_defs.h @@ -116,6 +116,8 @@ enum octeon_tag_type { /* This subcode is sent by core PCI driver to indicate cores are ready. */ #define LIO_OPCODE_IF_CFG 0x09 +#define LIO_MAX_RX_PKTLEN (64 * 1024) + /* Interface flags communicated between host driver and core app. */ enum lio_ifflags { LIO_IFFLAG_UNICAST = 0x10 diff --git a/drivers/net/liquidio/lio_rxtx.c b/drivers/net/liquidio/lio_rxtx.c index 942fe9b..9948023 100644 --- a/drivers/net/liquidio/lio_rxtx.c +++ b/drivers/net/liquidio/lio_rxtx.c @@ -41,6 +41,96 @@ #include "lio_rxtx.h" static void +lio_droq_compute_max_packet_bufs(struct lio_droq *droq) +{ + uint32_t count = 0; + + do { + count += droq->buffer_size; + } while (count < LIO_MAX_RX_PKTLEN); +} + +static void +lio_droq_reset_indices(struct lio_droq *droq) +{ + droq->read_idx = 0; + droq->write_idx = 0; + droq->refill_idx = 0; + droq->refill_count = 0; + rte_atomic64_set(&droq->pkts_pending, 0); +} + +static void +lio_droq_destroy_ring_buffers(struct lio_droq *droq) +{ + uint32_t i; + + for (i = 0; i < droq->max_count; i++) { + if (droq->recv_buf_list[i].buffer) { + rte_pktmbuf_free((struct rte_mbuf *) + droq->recv_buf_list[i].buffer); + droq->recv_buf_list[i].buffer = NULL; + } + } + + lio_droq_reset_indices(droq); +} + +static void * +lio_recv_buffer_alloc(struct lio_device *lio_dev, int q_no) +{ + struct lio_droq *droq = lio_dev->droq[q_no]; + struct rte_mempool *mpool = droq->mpool; + struct rte_mbuf *m; + + m = rte_pktmbuf_alloc(mpool); + if (m == NULL) { + lio_dev_err(lio_dev, "Cannot allocate\n"); + return NULL; + } + + rte_mbuf_refcnt_set(m, 1); + m->next = NULL; + m->data_off = RTE_PKTMBUF_HEADROOM; + m->nb_segs = 1; + m->pool = mpool; + + return m; +} + +static int +lio_droq_setup_ring_buffers(struct lio_device *lio_dev, + struct lio_droq *droq) +{ + struct lio_droq_desc *desc_ring = droq->desc_ring; + uint32_t i; + void *buf; + + for (i = 0; i < droq->max_count; i++) { + buf = lio_recv_buffer_alloc(lio_dev, droq->q_no); + if (buf == NULL) { + lio_dev_err(lio_dev, "buffer alloc failed\n"); + lio_droq_destroy_ring_buffers(droq); + return -ENOMEM; + } + + droq->recv_buf_list[i].buffer = buf; + droq->info_list[i].length = 0; + + /* map ring buffers into memory */ + desc_ring[i].info_ptr = lio_map_ring_info(droq, i); + desc_ring[i].buffer_ptr = + lio_map_ring(droq->recv_buf_list[i].buffer); + } + + lio_droq_reset_indices(droq); + + lio_droq_compute_max_packet_bufs(droq); + + return 0; +} + +static void lio_dma_zone_free(struct lio_device *lio_dev, const struct rte_memzone *mz) { const struct rte_memzone *mz_tmp; @@ -75,6 +165,7 @@ lio_dev_dbg(lio_dev, "OQ[%d]\n", q_no); + lio_droq_destroy_ring_buffers(droq); rte_free(droq->recv_buf_list); droq->recv_buf_list = NULL; lio_dma_zone_free(lio_dev, droq->info_mz); @@ -172,10 +263,15 @@ goto init_droq_fail; } + if (lio_droq_setup_ring_buffers(lio_dev, droq)) + goto init_droq_fail; + droq->refill_threshold = c_refill_threshold; rte_spinlock_init(&droq->lock); + lio_dev->fn_list.setup_oq_regs(lio_dev, q_no); + lio_dev->io_qmask.oq |= (1ULL << q_no); return 0; diff --git a/drivers/net/liquidio/lio_rxtx.h b/drivers/net/liquidio/lio_rxtx.h index 05f4704..fc623ad 100644 --- a/drivers/net/liquidio/lio_rxtx.h +++ b/drivers/net/liquidio/lio_rxtx.h @@ -495,6 +495,26 @@ enum { } } +static inline uint64_t +lio_map_ring(void *buf) +{ + phys_addr_t dma_addr; + + dma_addr = rte_mbuf_data_dma_addr_default(((struct rte_mbuf *)buf)); + + return (uint64_t)dma_addr; +} + +static inline uint64_t +lio_map_ring_info(struct lio_droq *droq, uint32_t i) +{ + phys_addr_t dma_addr; + + dma_addr = droq->info_list_dma + (i * LIO_DROQ_INFO_SIZE); + + return (uint64_t)dma_addr; +} + /* Macro to increment index. * Index is incremented by count; if the sum exceeds * max, index is wrapped-around to the start. diff --git a/drivers/net/liquidio/lio_struct.h b/drivers/net/liquidio/lio_struct.h index 3df79e1..7a7a4a6 100644 --- a/drivers/net/liquidio/lio_struct.h +++ b/drivers/net/liquidio/lio_struct.h @@ -306,6 +306,7 @@ struct lio_io_enable { struct lio_fn_list { void (*setup_iq_regs)(struct lio_device *, uint32_t); + void (*setup_oq_regs)(struct lio_device *, uint32_t); int (*setup_mbox)(struct lio_device *); void (*free_mbox)(struct lio_device *); -- 1.8.3.1