From patchwork Tue Jan 23 16:49:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herve Codina X-Patchwork-Id: 191096 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:2553:b0:103:945f:af90 with SMTP id p19csp476342dyi; Tue, 23 Jan 2024 09:08:33 -0800 (PST) X-Google-Smtp-Source: AGHT+IGrWh3LSFQmnGS0bIJC8EcZOMfbktwSlHlLExOZbKNFVJdMnlKuUg4mifW4J9PrgRggGPsa X-Received: by 2002:a17:906:c1c2:b0:a30:3f95:cf10 with SMTP id bw2-20020a170906c1c200b00a303f95cf10mr109666ejb.30.1706029713385; Tue, 23 Jan 2024 09:08:33 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706029713; cv=pass; d=google.com; s=arc-20160816; b=VN7k+1delbt7bN6fqt19L6KATx9TYrx1JeZQr7e0GTwtoTb2v7hJ6oIQIBWMbGg41y RiIEOukqqMaFjDVa87d7N64HsPJ7Kf/sGSw/E84r/BSMkZSuBIsWmwq0nzJDOXZ7sgSE 01Y1TKtTtGHG+rY55xVNc1kp9w891TEh3FrO2wpioeQoBVD9ZcjDR7DHyUSt/c9+/Fi7 qbP4W2x3zARE4JnNbD7NqdcFahib59Tqq5jzW4WQSYpnJpvJHQnHXb/M6TFdqyDVztB/ tohlHY9EBM5uNzZyl/cAveTXqCXgG0+x9RtGiIdKAzL8fmCCAuoUMRQ8xRe0fc2waWQ4 Hriw== 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=gqSD+Y2c51vRx3qqdkwfyJsEFyB5MIUzmN3DIfLul7A=; fh=IvI453Dy8xafhcMLNZ4MKkSVyGVQQhUeXCkv45QyBGI=; b=bJ3CZo7EzfJBJYBlOGTw4WtxKNN6glkkHigyYsxD2JTbqhG4S0gMWUeyr+M6UgXyWn gMvHH8xuSu8uN5CDrhTUgqFswLIit75I/PsKCj+iFm2edbChRB6quI1ls9s0nw+E25Ho BkYWs11Zn6r/F2Zn7GHPqudtZi5k5NnKul56nIRtH4ryntKvzRXemtriFeAe3YM7uvTG KJKWH9bLTg+SoEORvBbYpscj4TH1AnpgpJJkDWyo3UXLdQFw+5M2yE71/piyKVM4JJnk AR8ni9B4nKGVsb/i2+WNnjJH3UBmS9FATlf1LZTMBPTuuTOnx9qtgmbkznRDFjf0eJB2 ZGog== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b="iF/2edeq"; 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-35715-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-35715-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=bootlin.com Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id f25-20020a170906561900b00a30f9616aebsi146826ejq.318.2024.01.23.09.08.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jan 2024 09:08:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-35715-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@bootlin.com header.s=gm1 header.b="iF/2edeq"; 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-35715-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-35715-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 am.mirrors.kernel.org (Postfix) with ESMTPS id 15B2C1F30AFD for ; Tue, 23 Jan 2024 16:57:12 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 391AA12A17F; Tue, 23 Jan 2024 16:49:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="iF/2edeq" Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) (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 AD1D67F7DD; Tue, 23 Jan 2024 16:49:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.200 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706028566; cv=none; b=jTEP6Ih8hlxs0iXQ6TnEYHrfZMHVsq9CqBRosXwOJMhFvNk4jHcg31lY5obJVY8dh/gGseNirK2hE2t0C1lwUMl2EUnbGxHNFitv5DrBJHABIWdHk1Cv5DmDPDHFRILKw7owvZWhWlNLC0VdbilzkRMxRnWcvTHgQEW8NcbcF48= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706028566; c=relaxed/simple; bh=6A8kp9AS97cYQZ9TEf/YmznGfHdGjv+rHOHDadW6hPk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q+kzJS3CcngA7G8wbx+ijfG7TQxnuFdqSp7Dkt8oGJ5u6AVKtBfyY1NoKqQ+K9PTjrkLApbSOw2UCbHlQvWHkOKZCglhk2F5IQvVOBYXZnpB0KAs6VSMVAjTjvTaGLELor+VOM2XkkEhCaa1uASYeAUSXVtJ26hN2Tu5KmrRyqc= 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=iF/2edeq; arc=none smtp.client-ip=217.70.183.200 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 517BD2000B; Tue, 23 Jan 2024 16:49:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1706028562; 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=gqSD+Y2c51vRx3qqdkwfyJsEFyB5MIUzmN3DIfLul7A=; b=iF/2edeq259/nzfWdG3uc/8+gc0UM4E46uuZAquGoIghs5RBIcNs/3uPSCHpMEUVxUiZn4 vbctrfDO6I/X8QPGMQab9Oh6U6pChB7DN0aq1LRKivJ2IrBdeMOEM4fyjQ3u3cnowlKBDv RxilIiw7osGiCgY5nJCQZp7r5y8uDAaUND1RZvFplH/YFjeioY8mbbriSWsTaLydAjbLUC +fo4D0TZZkX/fmujZWCzMZLnChmt8L1xeTK/xq8uSlmkA+x/rUq4XpeqsaM4SnsVOv3/7O aUMjZCS/hT68klLZdC60RkknprTq1/rAQufhxmo/kl9aCrcP9ZfYhABesuBqtA== From: Herve Codina To: "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 3/4] net: wan: fsl_qmc_hdlc: Add runtime timeslots changes support Date: Tue, 23 Jan 2024 17:49:08 +0100 Message-ID: <20240123164912.249540-4-herve.codina@bootlin.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240123164912.249540-1-herve.codina@bootlin.com> References: <20240123164912.249540-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: 1788901812255383941 X-GMAIL-MSGID: 1788901812255383941 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 | 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 31b637ec8390..82019cd96365 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");