From patchwork Fri Sep 17 15:13:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?SsOpcsO0bWUgUG91aWxsZXI=?= X-Patchwork-Id: 12502493 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,MSGID_FROM_MTA_HEADER,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92571C4321E for ; Fri, 17 Sep 2021 15:15:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7F8666124D for ; Fri, 17 Sep 2021 15:15:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240967AbhIQPRF (ORCPT ); Fri, 17 Sep 2021 11:17:05 -0400 Received: from mail-mw2nam12on2053.outbound.protection.outlook.com ([40.107.244.53]:15265 "EHLO NAM12-MW2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S245742AbhIQPQS (ORCPT ); Fri, 17 Sep 2021 11:16:18 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Zsr8VAth7k0VUxCyS70l5goWzowFsG2mLF3vtLgpMrfgficAjol7OSBoSOlMJPbpahIxlcWy6mXQy1RBsUyt3fJlyzwPgkcglvzreICA/bvH3r8Kj4OSx8FKWV6aQY1ETdnfLe8sHXjbNRxYh60DFdihZL3b7GaWfvVB/7GY369yzHNcJt7697vnizflUy7GCNWoEMiW5e8wZ42RW7fO0O9gIs3sOj+c47rohs6HNmsfW1/Tdk4f0YanhAk228U85SjcPMkdZt4vqJGQ5z8QeLZtVmMZlSVkbMnVAmGn+Cmuj2hBvxmpdEtJgbr72/DuJ0jcGqUu/rCcxG87bo7zCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=L1PGQFYwqGncDdlTHJJr+Np/ZfkOZwxSjiFSMD2Zj+E=; b=jGfhSGxBHcshdtluTmfFxW0dyHs8S4E9jgGkjIJEt59mwfLdRCJWYzrRNCNUjWp3zOf49mTSd9WnQc+9lSC4hUBS1ryQAQEDnGHO3wmcwh07rLaTxnFJhX+azPCNElgNlRMyKR3gyleEvYlEe8fA0cQ6rpk0hEHlGX+UorgGf74tEqLZZ/V9NutAbW+V4D+S7epsySlzr82CXGE//zkVr0yfoqnZ7mdH5WJyWXXfqZ0eQ828TZde9IP9UGKTfnzNfFdIrtGf/2uTy4Z54lDKcDEIx3aZMqp1PpQZhqlnIWHZ/izjgs3lkmZcCdQB2AntKHuCqiNSWhrf/D5Yy8KkzA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=silabs.com; dmarc=pass action=none header.from=silabs.com; dkim=pass header.d=silabs.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=silabs.onmicrosoft.com; s=selector2-silabs-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=L1PGQFYwqGncDdlTHJJr+Np/ZfkOZwxSjiFSMD2Zj+E=; b=EOf2KK93lbL5pHFH1HwrlcH0XYojEiEOtOddblMDN+460TytqCSwmMbCge9/ZkMW6kDaqyvJGhV35dV4EHr1Z2GmocDjKD6eDn5UwR+4/9qBhu/tQKx5Az4IgXe5TMqs4Oc8I4JhN8MhqUUQrRWT31syPiUq/gJ7Bu/gv8yudwI= Authentication-Results: vger.kernel.org; dkim=none (message not signed) header.d=none;vger.kernel.org; dmarc=none action=none header.from=silabs.com; Received: from SN6PR11MB2718.namprd11.prod.outlook.com (2603:10b6:805:63::18) by SA2PR11MB4876.namprd11.prod.outlook.com (2603:10b6:806:119::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4523.14; Fri, 17 Sep 2021 15:14:42 +0000 Received: from SN6PR11MB2718.namprd11.prod.outlook.com ([fe80::7050:a0a:415:2ccd]) by SN6PR11MB2718.namprd11.prod.outlook.com ([fe80::7050:a0a:415:2ccd%7]) with mapi id 15.20.4500.017; Fri, 17 Sep 2021 15:14:42 +0000 From: Jerome Pouiller To: linux-wireless@vger.kernel.org, netdev@vger.kernel.org, Kalle Valo Cc: devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, Greg Kroah-Hartman , "David S . Miller" , devicetree@vger.kernel.org, Rob Herring , linux-mmc@vger.kernel.org, =?utf-8?q?Pali?= =?utf-8?q?_Roh=C3=A1r?= , Ulf Hansson , =?utf-8?b?SsOpcsO0bWUgUG91aWxsZXI=?= Subject: [PATCH v6 09/24] wfx: add hwio.c/hwio.h Date: Fri, 17 Sep 2021 17:13:45 +0200 Message-Id: <20210917151401.2274772-10-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210917151401.2274772-1-Jerome.Pouiller@silabs.com> References: <20210917151401.2274772-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SA9PR03CA0029.namprd03.prod.outlook.com (2603:10b6:806:20::34) To SN6PR11MB2718.namprd11.prod.outlook.com (2603:10b6:805:63::18) MIME-Version: 1.0 Received: from pc-42.silabs.com (2a01:e34:ecb5:66a0:9876:e1d7:65be:d294) by SA9PR03CA0029.namprd03.prod.outlook.com (2603:10b6:806:20::34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4523.14 via Frontend Transport; Fri, 17 Sep 2021 15:14:39 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 570f42f3-4bc8-42ee-ff20-08d979eddfa5 X-MS-TrafficTypeDiagnostic: SA2PR11MB4876: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:561; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: vzU2zZCRd9E3I3zWgGAo8cATAfSlZeZzo0S+Su5cf683WD61JgSF/1NOOHkH3HLVv6hv+Bu3/2UI5vcFLfNt9Zt7YvfTHR1i3wD+lSr381Yf2E/jFdpJIOCanFlr48GEEOtoypveSR+rMBJwbR8E1Bul45qsiVVFX83gqdx9HjB/BV01mq74kqCQTFfKtjEiJnWUgTl/43ng4/Tj0emMpAD74Vh7ReS0akAFol0lEBOPd2DBBK5V+DNjMHSBhxHNhPm271aB4mKEon8hRC6FlgNZlQusq0fZUN2ZPox7IZWDZ+YvN24C/tIFpHw1eGoX+qvK3Ui07foZBWpjtxOIjjvSPkZECEHl82wqSy4731KAj0fSekvgAu0XhpL9NA0237HzhscN8ruvuawwplving87qWzVAjWO+l/9nPwMmBZguQIXLxD/kZHKg6Hl1pT2DXStNJbMx9hVbBOuM+By06gWnwkm9T4UhkyrW4SNB3Ge4dpKlwWko/c6jjc9G2z0ifMFlIu7prH5ga/Ath/mjKzgRMw+ZRiJoOfco2konkblUt6Rrw4W4QzBfnID20Vvvv0GvLnXd5ubyFCLFNMzMk0w5SfuFjEbJh8Dr2rj3fOgYg2a2CnDUS/FtZamm5dKrMjlTZuL+Qz6xjjGFMuTxw== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SN6PR11MB2718.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(366004)(66556008)(66946007)(508600001)(52116002)(7696005)(6916009)(66476007)(30864003)(4326008)(316002)(6666004)(86362001)(2616005)(6486002)(1076003)(107886003)(38100700002)(83380400001)(7416002)(2906002)(54906003)(5660300002)(186003)(8676002)(8936002)(66574015)(36756003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?71VIQlqr4MD06XHh3N3ot4qQG9YG?= =?utf-8?q?2xUMzGLkR+4ZXhlVIMnQPOFv7SEUceFTgBmlsPBPiVg6Wjc7r35Joj8UR4PGagIXe?= =?utf-8?q?gArC5wK7XSvx6k9GTkt64nJjwuH79kys7TOEJv9JfDNS4nhI9jeGJoJuVAqpSevaT?= =?utf-8?q?Ptc/UnXfLQIGjtJlN6XpEkQWPcIhQsq/mWl2x+Bhvey0eiMjA0oIDQzspwTGXvM/O?= =?utf-8?q?9SHY/u+INa7/tGhhJ3zt6Vt7AF19SHJfW5hXijTYWamP2cigHAh7Lzz/EpkUy8KEL?= =?utf-8?q?NlqnqZvnjlfoLXxN3DqPRsC4CS/bWIp/q3GChRJeM2ojoe4iUJs/kSk+l6nQOHQvC?= =?utf-8?q?8D/klpCWCP6fMkD6aMfdLIFyiYCy8/ROHiXuN19cKzUhRlD4j89Ipb1GOJqcoSn4D?= =?utf-8?q?AfpUC5rL0Ukd0q0NhuZwLl87NydTPoaE9RTdO6VaQV7CT5XsCkl4xkzgkkDwZFxZJ?= =?utf-8?q?DpABdCz6HKOtfqvI4r/Faoi+DrJ3mgSfpL1Padz2/eAVf5rObotcoPkhd680pqE2w?= =?utf-8?q?wvfK/yvqJNRxFAP6JkrM8B9HqOGSmtxbLbVIGBYdOdgJDWmCcEGGEl8a2VrsOZxhL?= =?utf-8?q?+4EBsfk5vqNJBhy00ORSwY+uRWO4Bq5GfWw+f1i9b7hEJ6jUEPVjhRGZO+ok3oJ9t?= =?utf-8?q?djHb350bsRJNdLnw/B2I5EZpxeG0LVLvz0XSaK4RZJUyBKFwMXkaC8ZfDvQ3FR9uX?= =?utf-8?q?OtKKRW4BT7FURBfkFRwPv+G3KkszlqvKHku9q77fxz0qdhfpYD/NsvV71s0F9bT9C?= =?utf-8?q?jS+dCkFjXW/aPgrmIGo618HcloPewaYcqXXJLsMykBiOcfokwwbXR5JQqjoHOfXtQ?= =?utf-8?q?6DATDqCKONFz3fAsgIlC+r2WGv2ueGR0Q+na9IP35d7tMepgrxYd2HKJ3RUmDL8Q1?= =?utf-8?q?4apO8zxmSg+RTG5LRv5++Tavwe9cLBLxefRvME4x8Fgay/jQVt2ULYg3DRetNCGUm?= =?utf-8?q?Xxu4WheHE+vMslsFuhD9fOmN/yrdW9kjTK7adPHchjXej4dnRb/8DjsqQT0OHe1ID?= =?utf-8?q?CaPDcCDsThvKnKPbcSwDZhMlJ4q4vAeWJ7EIbn3f721BwAI5aOiGXwSq6qA/8RViU?= =?utf-8?q?hF1t+iE3fMAa5bie7pWE7uphEhJ5/u0MpL6RKdSqUSVcjWvqalB3xHxVUYnLOdmBY?= =?utf-8?q?B0gRUR07GRKxmMWn9PyBAII6W3wAv1rVC/jOkvYxDJtSg5uCVEukzSWhJVD0yLT0C?= =?utf-8?q?DvkuREumxnCvGHdIKt1xNKFGuC611ybM1wk6jteaJud55tM9LYImmat49QacsbMch?= =?utf-8?q?UqYKXNd3Yl1THAiN0gu9T/jQJd77Q5ISA6LPvHNuBvKbl9e4KVMVRbBpnItcqk9AJ?= =?utf-8?q?fEzxxtP8vCUGZGN?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 570f42f3-4bc8-42ee-ff20-08d979eddfa5 X-MS-Exchange-CrossTenant-AuthSource: SN6PR11MB2718.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Sep 2021 15:14:41.8492 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 54dbd822-5231-4b20-944d-6f4abcd541fb X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: yF/j2n4PRbUTG0ZTyXtkwmZMMEoqDrMKve7js/ImzWo1Ub0B3cChL6GRZeiidq4XaG2b8VXjSK8QpyAWEdfWVQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SA2PR11MB4876 Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/hwio.c | 340 +++++++++++++++++++++++++ drivers/net/wireless/silabs/wfx/hwio.h | 79 ++++++ 2 files changed, 419 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/hwio.c create mode 100644 drivers/net/wireless/silabs/wfx/hwio.h diff --git a/drivers/net/wireless/silabs/wfx/hwio.c b/drivers/net/wireless/silabs/wfx/hwio.c new file mode 100644 index 000000000000..393bcb1e2f4e --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hwio.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Low-level I/O functions. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#include +#include +#include + +#include "hwio.h" +#include "wfx.h" +#include "bus.h" +#include "traces.h" + +static int read32(struct wfx_dev *wdev, int reg, u32 *val) +{ + int ret; + __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL); + + *val = ~0; /* Never return undefined value */ + if (!tmp) + return -ENOMEM; + ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, reg, tmp, + sizeof(u32)); + if (ret >= 0) + *val = le32_to_cpu(*tmp); + kfree(tmp); + if (ret) + dev_err(wdev->dev, "%s: bus communication error: %d\n", + __func__, ret); + return ret; +} + +static int write32(struct wfx_dev *wdev, int reg, u32 val) +{ + int ret; + __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL); + + if (!tmp) + return -ENOMEM; + *tmp = cpu_to_le32(val); + ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, reg, tmp, + sizeof(u32)); + kfree(tmp); + if (ret) + dev_err(wdev->dev, "%s: bus communication error: %d\n", + __func__, ret); + return ret; +} + +static int read32_locked(struct wfx_dev *wdev, int reg, u32 *val) +{ + int ret; + + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = read32(wdev, reg, val); + _trace_io_read32(reg, *val); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + return ret; +} + +static int write32_locked(struct wfx_dev *wdev, int reg, u32 val) +{ + int ret; + + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = write32(wdev, reg, val); + _trace_io_write32(reg, val); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + return ret; +} + +static int write32_bits_locked(struct wfx_dev *wdev, int reg, u32 mask, u32 val) +{ + int ret; + u32 val_r, val_w; + + WARN_ON(~mask & val); + val &= mask; + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = read32(wdev, reg, &val_r); + _trace_io_read32(reg, val_r); + if (ret < 0) + goto err; + val_w = (val_r & ~mask) | val; + if (val_w != val_r) { + ret = write32(wdev, reg, val_w); + _trace_io_write32(reg, val_w); + } +err: + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + return ret; +} + +static int indirect_read(struct wfx_dev *wdev, int reg, u32 addr, + void *buf, size_t len) +{ + int ret; + int i; + u32 cfg; + u32 prefetch; + + WARN_ON(len >= 0x2000); + WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT); + + if (reg == WFX_REG_AHB_DPORT) + prefetch = CFG_PREFETCH_AHB; + else if (reg == WFX_REG_SRAM_DPORT) + prefetch = CFG_PREFETCH_SRAM; + else + return -ENODEV; + + ret = write32(wdev, WFX_REG_BASE_ADDR, addr); + if (ret < 0) + goto err; + + ret = read32(wdev, WFX_REG_CONFIG, &cfg); + if (ret < 0) + goto err; + + ret = write32(wdev, WFX_REG_CONFIG, cfg | prefetch); + if (ret < 0) + goto err; + + for (i = 0; i < 20; i++) { + ret = read32(wdev, WFX_REG_CONFIG, &cfg); + if (ret < 0) + goto err; + if (!(cfg & prefetch)) + break; + usleep_range(200, 250); + } + if (i == 20) { + ret = -ETIMEDOUT; + goto err; + } + + ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, reg, buf, len); + +err: + if (ret < 0) + memset(buf, 0xFF, len); /* Never return undefined value */ + return ret; +} + +static int indirect_write(struct wfx_dev *wdev, int reg, u32 addr, + const void *buf, size_t len) +{ + int ret; + + WARN_ON(len >= 0x2000); + WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT); + ret = write32(wdev, WFX_REG_BASE_ADDR, addr); + if (ret < 0) + return ret; + + return wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, reg, buf, len); +} + +static int indirect_read_locked(struct wfx_dev *wdev, int reg, u32 addr, + void *buf, size_t len) +{ + int ret; + + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = indirect_read(wdev, reg, addr, buf, len); + _trace_io_ind_read(reg, addr, buf, len); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + return ret; +} + +static int indirect_write_locked(struct wfx_dev *wdev, int reg, u32 addr, + const void *buf, size_t len) +{ + int ret; + + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = indirect_write(wdev, reg, addr, buf, len); + _trace_io_ind_write(reg, addr, buf, len); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + return ret; +} + +static int indirect_read32_locked(struct wfx_dev *wdev, int reg, + u32 addr, u32 *val) +{ + int ret; + __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL); + + if (!tmp) + return -ENOMEM; + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = indirect_read(wdev, reg, addr, tmp, sizeof(u32)); + *val = le32_to_cpu(*tmp); + _trace_io_ind_read32(reg, addr, *val); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + kfree(tmp); + return ret; +} + +static int indirect_write32_locked(struct wfx_dev *wdev, int reg, + u32 addr, u32 val) +{ + int ret; + __le32 *tmp = kmalloc(sizeof(u32), GFP_KERNEL); + + if (!tmp) + return -ENOMEM; + *tmp = cpu_to_le32(val); + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = indirect_write(wdev, reg, addr, tmp, sizeof(u32)); + _trace_io_ind_write32(reg, addr, val); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + kfree(tmp); + return ret; +} + +int wfx_data_read(struct wfx_dev *wdev, void *buf, size_t len) +{ + int ret; + + WARN((long)buf & 3, "%s: unaligned buffer", __func__); + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, + WFX_REG_IN_OUT_QUEUE, buf, len); + _trace_io_read(WFX_REG_IN_OUT_QUEUE, buf, len); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + if (ret) + dev_err(wdev->dev, "%s: bus communication error: %d\n", + __func__, ret); + return ret; +} + +int wfx_data_write(struct wfx_dev *wdev, const void *buf, size_t len) +{ + int ret; + + WARN((long)buf & 3, "%s: unaligned buffer", __func__); + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, + WFX_REG_IN_OUT_QUEUE, buf, len); + _trace_io_write(WFX_REG_IN_OUT_QUEUE, buf, len); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + if (ret) + dev_err(wdev->dev, "%s: bus communication error: %d\n", + __func__, ret); + return ret; +} + +int sram_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len) +{ + return indirect_read_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len); +} + +int ahb_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len) +{ + return indirect_read_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len); +} + +int sram_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len) +{ + return indirect_write_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len); +} + +int ahb_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len) +{ + return indirect_write_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len); +} + +int sram_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val) +{ + return indirect_read32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val); +} + +int ahb_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val) +{ + return indirect_read32_locked(wdev, WFX_REG_AHB_DPORT, addr, val); +} + +int sram_reg_write(struct wfx_dev *wdev, u32 addr, u32 val) +{ + return indirect_write32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val); +} + +int ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val) +{ + return indirect_write32_locked(wdev, WFX_REG_AHB_DPORT, addr, val); +} + +int config_reg_read(struct wfx_dev *wdev, u32 *val) +{ + return read32_locked(wdev, WFX_REG_CONFIG, val); +} + +int config_reg_write(struct wfx_dev *wdev, u32 val) +{ + return write32_locked(wdev, WFX_REG_CONFIG, val); +} + +int config_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val) +{ + return write32_bits_locked(wdev, WFX_REG_CONFIG, mask, val); +} + +int control_reg_read(struct wfx_dev *wdev, u32 *val) +{ + return read32_locked(wdev, WFX_REG_CONTROL, val); +} + +int control_reg_write(struct wfx_dev *wdev, u32 val) +{ + return write32_locked(wdev, WFX_REG_CONTROL, val); +} + +int control_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val) +{ + return write32_bits_locked(wdev, WFX_REG_CONTROL, mask, val); +} + +int igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val) +{ + int ret; + + *val = ~0; /* Never return undefined value */ + ret = write32_locked(wdev, WFX_REG_SET_GEN_R_W, IGPR_RW | index << 24); + if (ret) + return ret; + ret = read32_locked(wdev, WFX_REG_SET_GEN_R_W, val); + if (ret) + return ret; + *val &= IGPR_VALUE; + return ret; +} + +int igpr_reg_write(struct wfx_dev *wdev, int index, u32 val) +{ + return write32_locked(wdev, WFX_REG_SET_GEN_R_W, index << 24 | val); +} diff --git a/drivers/net/wireless/silabs/wfx/hwio.h b/drivers/net/wireless/silabs/wfx/hwio.h new file mode 100644 index 000000000000..d34baae47017 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hwio.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Low-level I/O functions. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#ifndef WFX_HWIO_H +#define WFX_HWIO_H + +#include + +struct wfx_dev; + +/* Caution: in the functions below, 'buf' will used with a DMA. So, it must be + * kmalloc'd (do not use stack allocated buffers). In doubt, enable + * CONFIG_DEBUG_SG to detect badly located buffer. + */ +int wfx_data_read(struct wfx_dev *wdev, void *buf, size_t buf_len); +int wfx_data_write(struct wfx_dev *wdev, const void *buf, size_t buf_len); + +int sram_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len); +int sram_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len); + +int ahb_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len); +int ahb_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len); + +int sram_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val); +int sram_reg_write(struct wfx_dev *wdev, u32 addr, u32 val); + +int ahb_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val); +int ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val); + +#define CFG_ERR_SPI_FRAME 0x00000001 /* only with SPI */ +#define CFG_ERR_SDIO_BUF_MISMATCH 0x00000001 /* only with SDIO */ +#define CFG_ERR_BUF_UNDERRUN 0x00000002 +#define CFG_ERR_DATA_IN_TOO_LARGE 0x00000004 +#define CFG_ERR_HOST_NO_OUT_QUEUE 0x00000008 +#define CFG_ERR_BUF_OVERRUN 0x00000010 +#define CFG_ERR_DATA_OUT_TOO_LARGE 0x00000020 +#define CFG_ERR_HOST_NO_IN_QUEUE 0x00000040 +#define CFG_ERR_HOST_CRC_MISS 0x00000080 /* only with SDIO */ +#define CFG_SPI_IGNORE_CS 0x00000080 /* only with SPI */ +#define CFG_BYTE_ORDER_MASK 0x00000300 /* only writable with SPI */ +#define CFG_BYTE_ORDER_BADC 0x00000000 +#define CFG_BYTE_ORDER_DCBA 0x00000100 +#define CFG_BYTE_ORDER_ABCD 0x00000200 /* SDIO always use this value */ +#define CFG_DIRECT_ACCESS_MODE 0x00000400 +#define CFG_PREFETCH_AHB 0x00000800 +#define CFG_DISABLE_CPU_CLK 0x00001000 +#define CFG_PREFETCH_SRAM 0x00002000 +#define CFG_CPU_RESET 0x00004000 +#define CFG_SDIO_DISABLE_IRQ 0x00008000 /* only with SDIO */ +#define CFG_IRQ_ENABLE_DATA 0x00010000 +#define CFG_IRQ_ENABLE_WRDY 0x00020000 +#define CFG_CLK_RISE_EDGE 0x00040000 +#define CFG_SDIO_DISABLE_CRC_CHK 0x00080000 /* only with SDIO */ +#define CFG_RESERVED 0x00F00000 +#define CFG_DEVICE_ID_MAJOR 0x07000000 +#define CFG_DEVICE_ID_RESERVED 0x78000000 +#define CFG_DEVICE_ID_TYPE 0x80000000 +int config_reg_read(struct wfx_dev *wdev, u32 *val); +int config_reg_write(struct wfx_dev *wdev, u32 val); +int config_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val); + +#define CTRL_NEXT_LEN_MASK 0x00000FFF +#define CTRL_WLAN_WAKEUP 0x00001000 +#define CTRL_WLAN_READY 0x00002000 +int control_reg_read(struct wfx_dev *wdev, u32 *val); +int control_reg_write(struct wfx_dev *wdev, u32 val); +int control_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val); + +#define IGPR_RW 0x80000000 +#define IGPR_INDEX 0x7F000000 +#define IGPR_VALUE 0x00FFFFFF +int igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val); +int igpr_reg_write(struct wfx_dev *wdev, int index, u32 val); + +#endif