From patchwork Tue Jan 30 08:40:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herve Codina X-Patchwork-Id: 193888 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp1080406dyb; Tue, 30 Jan 2024 00:43:15 -0800 (PST) X-Google-Smtp-Source: AGHT+IGR6Cpvk16CQiJwPuvnAg4Wey3iSotVWXNnn7T/aZJYcUv6N6jOzpJFizLKrS9uc14CNtEu X-Received: by 2002:a05:620a:1377:b0:783:ee8e:db8d with SMTP id d23-20020a05620a137700b00783ee8edb8dmr5886019qkl.37.1706604195547; Tue, 30 Jan 2024 00:43:15 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706604195; cv=pass; d=google.com; s=arc-20160816; b=AFXFbp8qn0FjG+p9GqBYYyI8LIzOpb6lVKVjobk2rJlz0a61ewi1jfP/JbjW+PhQpu XQgFzXV7UXj63Ps+ZPdevRDivB7BQ5KRL8UNzXpVwqcps1dPXzZXJQqgp89hfQaNrZ49 faZh+GAswinrG6TODkEtQZoLPMTfdpocUY0d8nL8Ux5PSitwbvw7tRl6FlNHzvbgXLHi D1AvMe399hsE7C7bAH/2Zbpw1aJOkcUAX1pP7amtXtikk0pdu4PynjC0G0+8xDZocho4 jR/5vfVXHauWJ7xeJGCbBafOFnEp/yWfWx3q8LoyKylq57coBwupWTcIGLUsDYp8iqRO 0BmQ== 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=vp9gwP8+FDWpA4SU5gS4ep7Z/vdcOSTDQ5ot2c0zr0k=; fh=s/vkN0CKwCHxl3xiysg2b4K3AQjMb0Me6zHwb/HBGyI=; b=zyRTcFI0a3m0gTtaeCMVHIRn/6vyexYePw/ub/sRTsBA+P1cohPKbyGH2KpNhwqWVe N91KJXVrRn6Yy3/HxyJRioTUGnN6gmeRzOjCRg17fGmo6/LZsgWWJKIPkAvXGtyAOZ9I LjbWEir3duSJKry4M5lD92D2o6OYa+FFHHdDKuaP/95u3aQKMp8lSXZQgbrRtpj9QPd1 TIUNDl0UULGp0EvuNRWFYJcEBoUbE30/Vti9PSDEAZOUrz5672cKvy9D+aC29pWMXhck mJAU8SbHl3a64ps8xJ2k3OPPM9XVz5E+VIpYeH93r9sC2U+h32omsoXTh9mjgWDeFBYb hJdw== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=Gwqg5ohg; 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-44158-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-44158-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id y11-20020ae9f40b000000b007831c2a0176si9046459qkl.477.2024.01.30.00.43.15 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 00:43:15 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-44158-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b=Gwqg5ohg; 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-44158-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-44158-ouuuleilei=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 ny.mirrors.kernel.org (Postfix) with ESMTPS id 9C25C1C27147 for ; Tue, 30 Jan 2024 08:42:55 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 2DA3F657C3; Tue, 30 Jan 2024 08:41:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Gwqg5ohg" Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) (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 CE10757876; Tue, 30 Jan 2024 08:40:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706604060; cv=none; b=nfwUhQ27RzXkhpV/B42HOsJ+y9ggzshGYQ+OA6yzyFM/UwlTxn/bwscULodoMEZrNBy6ZQLsX8r9BcRknsDUgkoH/xNrzA1nT8A7g0p56VswDMSwRFV42Hqk6g4FDi227oInq1zsrUVkzg3y8qesDmvrVsWbYhbC5WD/RhHX5Fk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706604060; c=relaxed/simple; bh=q/ml4s3h0QU/1UPC83B5h8KKiyyTqcyqLpgoYsJDt78=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HqV7kiYvcHljfVBUCBzkyPUsbHnDJ85mc3Rgia+MUPUeUe2SAuWauqCQ9kD2og/rascp3fQ9rN22MzXDwTeLDOSG8iJTZMNWlniMCgQJps4b7GOngvVoAZNvZWkVLrxiBsVKgiEwsSWeqYNqvy9GvHJ08I5jwPtbILKAhRg2JH4= 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=Gwqg5ohg; arc=none smtp.client-ip=217.70.183.195 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 3CD1660011; Tue, 30 Jan 2024 08:40:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1706604049; 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=vp9gwP8+FDWpA4SU5gS4ep7Z/vdcOSTDQ5ot2c0zr0k=; b=Gwqg5ohgFjn3yzkvQodoDOlJtAa2We6wfx2Bcg9vfr3cGS4qic5nKQeE2TKoFaP7oKi9Sy u7lyanrBvdM+YWu5RQdcnesE54oaBocDXaDQycLHyFPvOf1JZ8H+lFg/dORFWUP8ztFURX I+SrFviBsnYU4VokP5/2wEOyfmJ/tLgHBR6TLj7VdX6QEQQ2SXeNhsrGn+K3ofgHylCLae Ir04te2cLFgsyUKJZKisJkq3EBhRLI0jGSWgepDbLHlapmvShNsdgsgxVrieqvlp+RDunv 2Opp06HbtWe+Y9C3lm/AUG0d1oQkDFxqfTha2x8g9TT/zCjKD0vQc5srr5AJRw== 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 v2 5/6] net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support Date: Tue, 30 Jan 2024 09:40:20 +0100 Message-ID: <20240130084035.115086-6-herve.codina@bootlin.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240130084035.115086-1-herve.codina@bootlin.com> References: <20240130084035.115086-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 X-GND-Sasl: herve.codina@bootlin.com X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789504201149281172 X-GMAIL-MSGID: 1789504201149281172 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 | 155 ++++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 1 deletion(-) diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c index e7b2b72a6050..8316f2984864 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 inline struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev) @@ -202,6 +204,147 @@ 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) +{ + DECLARE_BITMAP(ts_mask_avail, 64); + DECLARE_BITMAP(ts_mask, 64); + DECLARE_BITMAP(map, 64); + u32 array32[2]; + + /* 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_arr64(ts_mask_avail, &ts_info->rx_ts_mask_avail, 64); + array32[0] = slot_map; + array32[1] = 0; + bitmap_from_arr32(map, array32, 64); + 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_arr64(ts_mask_avail, &ts_info->rx_ts_mask_avail, 64); + bitmap_from_arr64(ts_mask, &ts_info->rx_ts_mask, 64); + 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); @@ -328,13 +471,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 +508,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");