From patchwork Tue Sep 12 10:14:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herve Codina X-Patchwork-Id: 138179 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9ecd:0:b0:3f2:4152:657d with SMTP id t13csp403105vqx; Tue, 12 Sep 2023 06:21:30 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEpnZ0x8kUBnlT/MQpg3rvJqqVGTd1v8LfcQI8Ff0zNKyJGJULpyV94mFyO7okxXNMTTS2B X-Received: by 2002:a17:903:32c5:b0:1bc:c82:9368 with SMTP id i5-20020a17090332c500b001bc0c829368mr15454395plr.32.1694524889783; Tue, 12 Sep 2023 06:21:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694524889; cv=none; d=google.com; s=arc-20160816; b=Uv817fEUtWp6MQbgLBWHWazqHmXFk6IvcA4S/z8pkKsHX8CoY3rpPcHtlgwGl7aKiS y7yYzVJyF/9ewDVqCmzhNKwJDwyQ6jUESMuckDSOXCoPnnV17sHbHqHq2woaYybEDAn5 ks7VR7uA2IqRxjlMhdjahuOL5cZzCrmgMyYA+OB9eSXpFXn7ADU/BRjFS0MmPISju64h hp7z+d5flR4ZU3WgaMtoUoXE3QElyvS42FMILnXaNz7myVemteqrcnF4iO9jA8PRfQCg iubLNR9sS7Mf0D/q+DvP1nNBDH1FcL1NTNOrAL4DldZ0J9c+Vn5NJ18U74ucJZRO4r92 FSFg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=djujX2AF4h844I9UdrUoEec7txyVpB9L3vQyN8XfhNs=; fh=5rCQDomVZxLXb7yR2oN4iSS3zxUnzGJP2HoQaRzhQu0=; b=l7RoJQDgcv2RxrE38ZB29MIkbmxZ9JYF1Ub1JI2ImqvAHvn0C2EcY71DkS300hz9oj uSxhWNT3ablCvawpNqrr2TYvLnfMA9jNYxC8iq45spoVdblI2znYcv2MBjNVt9oo+hjC /89GjhHPVUEKEUlwnJjfe5cB8qPBPbAUwJqjz7HHelMX+oD6hOGyYwTIEjZHCAie28iM ZUgkxE+XLOBeD5ELxARAObp45lYRofJu0ieYcPNp0Gzi9Dii39Yb1rPLNL/hg8vgXf2Y jOIOp279hLHk8XBub2nXKDoHBc3Dw0fZUGRFV9Hq9h/Z9ZTiNNwXyK0J/rBudhtGDuXf PcAw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=ZXbTDdSY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from groat.vger.email (groat.vger.email. [23.128.96.35]) by mx.google.com with ESMTPS id kv12-20020a17090328cc00b001bb8e3f3475si7875127plb.52.2023.09.12.06.21.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 06:21:29 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) client-ip=23.128.96.35; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=ZXbTDdSY; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id 6EBB88266533; Tue, 12 Sep 2023 03:17:29 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.8 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234180AbjILKPT (ORCPT + 37 others); Tue, 12 Sep 2023 06:15:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41518 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234174AbjILKO5 (ORCPT ); Tue, 12 Sep 2023 06:14:57 -0400 Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 49CC91FFD; Tue, 12 Sep 2023 03:14:35 -0700 (PDT) Received: by mail.gandi.net (Postfix) with ESMTPA id 7EB8B40005; Tue, 12 Sep 2023 10:14:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1694513674; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=djujX2AF4h844I9UdrUoEec7txyVpB9L3vQyN8XfhNs=; b=ZXbTDdSYw3NfslJNgTo62+ja7EejNC9zWC2M4uJx99S1tw4GFszpsL8Cqde/corWkA8KDe BR3MqoFpYqQ4Si88TwQjc7sx4GQxSfB83J1ivi1VR1F2Vc09bDN6g8fhLJg183HQAaaX8H rmB/XYOTwQxSYo2DWxgmxJhrBKjAPm/LaObd1Cpy6bDkZhwjOIpCOSH/5PlyF7Ad8VOp3F sZuwsjWpteN/UykJadnXMeQThVt/YHduQUKeb3vbokwL19Nlna0vITyCc0PlkYRoRVZcI5 oExS9psyWqsp5nHJ6pQGAEoXOsQgp+dMkupqh2o3R12ESVpn+Q4LLxl/d6xprw== From: Herve Codina To: Herve Codina , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Andrew Lunn , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lee Jones , Linus Walleij , Qiang Zhao , Li Yang , Liam Girdwood , Mark Brown , Jaroslav Kysela , Takashi Iwai , Shengjiu Wang , Xiubo Li , Fabio Estevam , Nicolin Chen , Christophe Leroy , Randy Dunlap Cc: netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, linux-arm-kernel@lists.infradead.org, alsa-devel@alsa-project.org, Simon Horman , Christophe JAILLET , Thomas Petazzoni Subject: [PATCH v5 23/31] wan: qmc_hdlc: Add runtime timeslots changes support Date: Tue, 12 Sep 2023 12:14:30 +0200 Message-ID: <20230912101430.225753-1-herve.codina@bootlin.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230912081527.208499-1-herve.codina@bootlin.com> References: <20230912081527.208499-1-herve.codina@bootlin.com> MIME-Version: 1.0 X-GND-Sasl: herve.codina@bootlin.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Tue, 12 Sep 2023 03:17:29 -0700 (PDT) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1776838130871421239 X-GMAIL-MSGID: 1776838130871421239 QMC channels support runtime timeslots changes but nothing is done at the QMC HDLC driver to handle these changes. Use existing IFACE ioctl in order to configure the timeslots to use. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy Signed-off-by: Christophe Leroy --- drivers/net/wan/fsl_qmc_hdlc.c | 169 ++++++++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 1 deletion(-) diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c index 15e102547ff2..24f466fa48b1 100644 --- a/drivers/net/wan/fsl_qmc_hdlc.c +++ b/drivers/net/wan/fsl_qmc_hdlc.c @@ -32,6 +32,7 @@ struct qmc_hdlc { struct qmc_hdlc_desc tx_descs[8]; unsigned int tx_out; struct qmc_hdlc_desc rx_descs[4]; + u32 slot_map; }; static inline struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev) @@ -202,6 +203,162 @@ static netdev_tx_t qmc_hdlc_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } +static int qmc_hdlc_xlate_slot_map(struct qmc_hdlc *qmc_hdlc, + u32 slot_map, struct qmc_chan_ts_info *ts_info) +{ + u64 ts_mask_avail; + unsigned int bit; + unsigned int i; + u64 ts_mask; + u64 map; + + /* Tx and Rx masks must be identical */ + if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) { + dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch (0x%llx, 0x%llx)\n", + ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail); + return -EINVAL; + } + + ts_mask_avail = ts_info->rx_ts_mask_avail; + ts_mask = 0; + map = slot_map; + bit = 0; + for (i = 0; i < 64; i++) { + if (ts_mask_avail & BIT_ULL(i)) { + if (map & BIT_ULL(bit)) + ts_mask |= BIT_ULL(i); + bit++; + } + } + + if (hweight64(ts_mask) != hweight64(map)) { + dev_err(qmc_hdlc->dev, "Cannot translate timeslots 0x%llx -> (0x%llx,0x%llx)\n", + map, ts_mask_avail, ts_mask); + return -EINVAL; + } + + ts_info->tx_ts_mask = ts_mask; + ts_info->rx_ts_mask = ts_mask; + return 0; +} + +static int qmc_hdlc_xlate_ts_info(struct qmc_hdlc *qmc_hdlc, + const struct qmc_chan_ts_info *ts_info, u32 *slot_map) +{ + u64 ts_mask_avail; + unsigned int bit; + unsigned int i; + u64 ts_mask; + u64 map; + + /* Tx and Rx masks must be identical */ + if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) { + dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch (0x%llx, 0x%llx)\n", + ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail); + return -EINVAL; + } + if (ts_info->rx_ts_mask != ts_info->tx_ts_mask) { + dev_err(qmc_hdlc->dev, "tx and rx timeslots mismatch (0x%llx, 0x%llx)\n", + ts_info->rx_ts_mask, ts_info->tx_ts_mask); + return -EINVAL; + } + + ts_mask_avail = ts_info->rx_ts_mask_avail; + ts_mask = ts_info->rx_ts_mask; + map = 0; + bit = 0; + for (i = 0; i < 64; i++) { + if (ts_mask_avail & BIT_ULL(i)) { + if (ts_mask & BIT_ULL(i)) + map |= BIT_ULL(bit); + bit++; + } + } + + if (hweight64(ts_mask) != hweight64(map)) { + dev_err(qmc_hdlc->dev, "Cannot translate timeslots (0x%llx,0x%llx) -> 0x%llx\n", + ts_mask_avail, ts_mask, map); + return -EINVAL; + } + + if (map >= BIT_ULL(32)) { + dev_err(qmc_hdlc->dev, "Slot map out of 32bit (0x%llx,0x%llx) -> 0x%llx\n", + ts_mask_avail, ts_mask, map); + return -EINVAL; + } + + *slot_map = map; + return 0; +} + +static int qmc_hdlc_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface, const te1_settings *te1) +{ + struct qmc_chan_ts_info ts_info; + int ret; + + ret = qmc_chan_get_ts_info(qmc_hdlc->qmc_chan, &ts_info); + if (ret) { + dev_err(qmc_hdlc->dev, "get QMC channel ts info failed %d\n", ret); + return ret; + } + ret = qmc_hdlc_xlate_slot_map(qmc_hdlc, te1->slot_map, &ts_info); + if (ret) + return ret; + + ret = qmc_chan_set_ts_info(qmc_hdlc->qmc_chan, &ts_info); + if (ret) { + dev_err(qmc_hdlc->dev, "set QMC channel ts info failed %d\n", ret); + return ret; + } + + qmc_hdlc->slot_map = te1->slot_map; + + return 0; +} + +static int qmc_hdlc_ioctl(struct net_device *netdev, struct if_settings *ifs) +{ + struct qmc_hdlc *qmc_hdlc = netdev_to_qmc_hdlc(netdev); + te1_settings te1; + + switch (ifs->type) { + case IF_GET_IFACE: + ifs->type = IF_IFACE_E1; + if (ifs->size < sizeof(te1)) { + if (!ifs->size) + return 0; /* only type requested */ + + ifs->size = sizeof(te1); /* data size wanted */ + return -ENOBUFS; + } + + memset(&te1, 0, sizeof(te1)); + + /* Update slot_map */ + te1.slot_map = qmc_hdlc->slot_map; + + if (copy_to_user(ifs->ifs_ifsu.te1, &te1, sizeof(te1))) + return -EFAULT; + return 0; + + case IF_IFACE_E1: + case IF_IFACE_T1: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (netdev->flags & IFF_UP) + return -EBUSY; + + if (copy_from_user(&te1, ifs->ifs_ifsu.te1, sizeof(te1))) + return -EFAULT; + + return qmc_hdlc_set_iface(qmc_hdlc, ifs->type, &te1); + + default: + return hdlc_ioctl(netdev, ifs); + } +} + static int qmc_hdlc_open(struct net_device *netdev) { struct qmc_hdlc *qmc_hdlc = netdev_to_qmc_hdlc(netdev); @@ -328,13 +485,14 @@ static const struct net_device_ops qmc_hdlc_netdev_ops = { .ndo_open = qmc_hdlc_open, .ndo_stop = qmc_hdlc_close, .ndo_start_xmit = hdlc_start_xmit, - .ndo_siocwandev = hdlc_ioctl, + .ndo_siocwandev = qmc_hdlc_ioctl, }; static int qmc_hdlc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct qmc_hdlc *qmc_hdlc; + struct qmc_chan_ts_info ts_info; struct qmc_chan_info info; hdlc_device *hdlc; int ret; @@ -364,6 +522,15 @@ static int qmc_hdlc_probe(struct platform_device *pdev) return -EINVAL; } + ret = qmc_chan_get_ts_info(qmc_hdlc->qmc_chan, &ts_info); + if (ret) { + dev_err(qmc_hdlc->dev, "get QMC channel ts info failed %d\n", ret); + return ret; + } + ret = qmc_hdlc_xlate_ts_info(qmc_hdlc, &ts_info, &qmc_hdlc->slot_map); + if (ret) + return ret; + qmc_hdlc->netdev = alloc_hdlcdev(qmc_hdlc); if (!qmc_hdlc->netdev) { dev_err(qmc_hdlc->dev, "failed to alloc hdlc dev\n");