Received: by 2002:a05:7412:bbc7:b0:fc:a2b0:25d7 with SMTP id kh7csp3059069rdb; Tue, 6 Feb 2024 06:11:40 -0800 (PST) X-Google-Smtp-Source: AGHT+IGFwm2HBQvA7iero5Tr3m4OzZVRs+Emcxat2bUsTwUafWZ/krDs5AgXcNFHVf4xeUi/N0BT X-Received: by 2002:a17:902:cf4a:b0:1d8:aada:a7f5 with SMTP id e10-20020a170902cf4a00b001d8aadaa7f5mr1849187plg.11.1707228700694; Tue, 06 Feb 2024 06:11:40 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707228700; cv=pass; d=google.com; s=arc-20160816; b=qWH2+WYazLDjZojj+7J4MeGrQe9J+nsqVUy+RVY817F49F0yKj0tF1XUX8f7nH1MWu umqftGVY3Dt+Ko2Msh1TZklV1IrtHO+lsNk9pQQRILG24otghd82ZQC12WMoz+RCUC+T 3bc+7mJJDCG2fXW+N2GXbgEJxBam6IflSCNmgVGjg92YqUqQuR2y+vuIwD3PCUUcbYOf mp6Lt9KhlgsK2+pFE4vO7v/bC6uKhUypTFlAwzYreLgFJ7tBMc3zsrL2lQEzaG92xOxr kQPfLYSX2UTTUzOWgDg6fqYtoLystfwLUo9vnJNCSb4SFP5oo7k5knmguXizndR7ToOo HWeA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=Mnr/8SaId4TQmwlcsvncrRDg9MKoU24/PP9bl0L71cE=; fh=1WxGsbim3P/cpW6yK82RlnaXGV7qaXZlNu3o7qWDm5E=; b=pWoG2Tlada/V4FoDQl9jh+LT/gj3eD7U8z/StBchFic4g/ykTn0wfalUV0di3R47MH Bjxl7MpF1tNc77dZZx5GaNEPJWXY2Az5T8HgVRmI+cj5Rn1qveGZBZmYBdjaeNrpZMlx 21wUEtkoa0f2YB1mEqd35RYU+KT1oGt/cVjrUBK2a2KAZjbfJMNbsRI0mChi/MGd0Ewe MqdOzoub140l5FnsdmyP6h/vSxmqyFAiNWzu5zPEJ4u5csr84qyOrHSV03kwkMSY2yg8 vwifEhA+XFH68chX9EINJBEa7P+L8gT2j4vitr/68QgC/aKMhqTQc9gBC+ke5jjC9OtV 43NQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=fBY1mCmR; arc=pass (i=1 spf=pass spfdomain=bootlin.com dkim=pass dkdomain=bootlin.com dmarc=pass fromdomain=bootlin.com); spf=pass (google.com: domain of linux-kernel+bounces-55082-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-55082-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com X-Forwarded-Encrypted: i=1; AJvYcCUi5tYDm5HM3P6BMEO1wtXXmK/JNuvdJxRA52mioDOhD5PgqsjcUwZpbSBG+YyHQu7U7CqnjuTNC9oR3NNLWyGL0KyBkxi/LxiBrZ/J3w== Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id o2-20020a170902d4c200b001d9bd7d3cacsi1782597plg.42.2024.02.06.06.11.38 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Feb 2024 06:11:40 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-55082-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=fBY1mCmR; arc=pass (i=1 spf=pass spfdomain=bootlin.com dkim=pass dkdomain=bootlin.com dmarc=pass fromdomain=bootlin.com); spf=pass (google.com: domain of linux-kernel+bounces-55082-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-55082-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 0D1232869A7 for ; Tue, 6 Feb 2024 14:09:11 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CF94D133999; Tue, 6 Feb 2024 14:07:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="fBY1mCmR" Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6A0D0131E53; Tue, 6 Feb 2024 14:07:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.197 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707228448; cv=none; b=OHwL7YLsd5fyV3uumR0FH3k7ChtXvH2sRx+iORu3dsW6ADvOjXmt68sEhCTqhy2n12HZE4u18lsoUFkicPrlayVk97FGH+aVqqTdInMbqth4PW7efnEPgEqvYtdPP4lC5lJKBGFTHZxHAoMncjC6ZRr3mrp9M9wbGVdjpPlDuTQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707228448; c=relaxed/simple; bh=JFtFcS1VHW8uz9WV52OuBJeyIDw8KBqSgMRDBSqSSCA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MPwSEmvRY8+UQ/MqvBeBiZ9jwnJd18KCoPmerp7spQ3CJAhb37fbWhYXPDUTDeEDRncBpn+FgR47dRWpmNyUa0f/EMl0l4N/hU3zIRfe1fh36yHhhgKrSCXeQsUN9rm7iICPRNEj/rqNHJKoKFkO0fKDdeIqpO8Am2sBqzf86sU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=fBY1mCmR; arc=none smtp.client-ip=217.70.183.197 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Received: by mail.gandi.net (Postfix) with ESMTPA id 179E01C0012; Tue, 6 Feb 2024 14:07:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1707228444; 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=Mnr/8SaId4TQmwlcsvncrRDg9MKoU24/PP9bl0L71cE=; b=fBY1mCmR1DBl91K71GHv/r4pqF858KacT3oclpYnhruJB7R9MRenBWnKCNUa3UmsAXczTC vjxidmPA6LaQS4pHrx2Sk5WS6g0YfxvTTruwHeAqTj6nVt03tElW5LNa1/C6fil+utNEGu oRJWC2VK+yFGpQ/5TRItmckYRnQlfsNE5HKhc+2t9s4xtDDqRUBDuatu4pN0u4OO8loftm V6Jx0/nTrq/6w5z7tBBLtexeQrQANwDRP1Uc1zLskJLdp2+vedihamqlbm41cQd5kjE5jv 45lp1FemebmCTlqtAASLohbT8oe0AB3BOu+alwwRjBUzxiRN5dYdUAcnM0xrug== From: Herve Codina To: Vadim Fedorenko , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Herve Codina Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, Andrew Lunn , Mark Brown , Christophe Leroy , Thomas Petazzoni Subject: [PATCH v3 5/6] net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support Date: Tue, 6 Feb 2024 15:07:15 +0100 Message-ID: <20240206140717.107930-6-herve.codina@bootlin.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240206140717.107930-1-herve.codina@bootlin.com> References: <20240206140717.107930-1-herve.codina@bootlin.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-GND-Sasl: herve.codina@bootlin.com 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 Acked-by: Jakub Kicinski --- drivers/net/wan/fsl_qmc_hdlc.c | 152 ++++++++++++++++++++++++++++++++- 1 file changed, 151 insertions(+), 1 deletion(-) diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c index 835500910d1b..b25d918d5e4e 100644 --- a/drivers/net/wan/fsl_qmc_hdlc.c +++ b/drivers/net/wan/fsl_qmc_hdlc.c @@ -7,6 +7,7 @@ * Author: Herve Codina */ +#include #include #include #include @@ -32,6 +33,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 struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev) @@ -206,6 +208,144 @@ static netdev_tx_t qmc_hdlc_xmit(struct sk_buff *skb, struct net_device *netdev) return ret; } +static int qmc_hdlc_xlate_slot_map(struct qmc_hdlc *qmc_hdlc, + u32 slot_map, struct qmc_chan_ts_info *ts_info) +{ + DECLARE_BITMAP(ts_mask_avail, 64); + DECLARE_BITMAP(ts_mask, 64); + DECLARE_BITMAP(map, 64); + + /* Tx and Rx available 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; + } + + bitmap_from_u64(ts_mask_avail, ts_info->rx_ts_mask_avail); + bitmap_from_u64(map, slot_map); + bitmap_onto(ts_mask, map, ts_mask_avail, 64); + + if (bitmap_weight(ts_mask, 64) != bitmap_weight(map, 64)) { + dev_err(qmc_hdlc->dev, "Cannot translate timeslots %*pb -> (%*pb, %*pb)\n", + 64, map, 64, ts_mask_avail, 64, ts_mask); + return -EINVAL; + } + + bitmap_to_arr64(&ts_info->tx_ts_mask, ts_mask, 64); + ts_info->rx_ts_mask = ts_info->tx_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) +{ + DECLARE_BITMAP(ts_mask_avail, 64); + DECLARE_BITMAP(ts_mask, 64); + DECLARE_BITMAP(map, 64); + u32 array32[2]; + + /* Tx and Rx masks and available 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; + } + + bitmap_from_u64(ts_mask_avail, ts_info->rx_ts_mask_avail); + bitmap_from_u64(ts_mask, ts_info->rx_ts_mask); + bitmap_off(map, ts_mask, ts_mask_avail, 64); + + if (bitmap_weight(ts_mask, 64) != bitmap_weight(map, 64)) { + dev_err(qmc_hdlc->dev, "Cannot translate timeslots (%*pb, %*pb) -> %*pb\n", + 64, ts_mask_avail, 64, ts_mask, 64, map); + return -EINVAL; + } + + bitmap_to_arr32(array32, map, 64); + if (array32[1]) { + dev_err(qmc_hdlc->dev, "Slot map out of 32bit (%*pb, %*pb) -> %*pb\n", + 64, ts_mask_avail, 64, ts_mask, 64, map); + return -EINVAL; + } + + *slot_map = array32[0]; + 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); @@ -332,13 +472,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; @@ -368,6 +509,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"); -- 2.43.0