From patchwork Tue Jan 11 17:14:01 2022 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: 531345 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9043AC4167D for ; Tue, 11 Jan 2022 17:14:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343917AbiAKROz (ORCPT ); Tue, 11 Jan 2022 12:14:55 -0500 Received: from mail-mw2nam12on2049.outbound.protection.outlook.com ([40.107.244.49]:36192 "EHLO NAM12-MW2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S244420AbiAKROw (ORCPT ); Tue, 11 Jan 2022 12:14:52 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=J9ty2+ahl8MpUQ125PpTHCCBf/KSx74sm0lth0HYtttVl6IanALlQ8reQlWkkYQwzU9LhzImDA2reAUAnM+u8AeMB/0ScHMVu5JqlcahER6EWH77DJd5ANZk2Eit7FgW7E0da6K/rP0fG5cYF3myv9Z75RMrgxeVfBL04A1X2eN/BLg+/W/xMzRCodbMdY6bxUFcu21uyaOQQSTfxfN2DNQo+6hi069VYj/ybiryJ1Lau7jh7V52S0XIow2cknhbC8hooBxgphpi7ggqcL91AqfunLMhp6hAJSEkh16BGSUvbpj2QdpfHd0OLSRDsjy8zY8phfYT3CZ1cZ2CVbsJmg== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=pdhi6vLAeWe2bzUCmXW6Nfs161aFeEl02nlWgRRDz7Q=; b=MSmTtoCF5cJ0TL0bdZ1l0jcPKM49nVN3EI/TobryW0bUMP9StGWR6dcRqaSZRMBuQbcFrj9K3a0qliFwgaPS0GbgDmZvbE1G0CUU5llJkGMUrfeA9wEKGV+veQ/0l+hMipwVpUvNcbJ8hNHvah40asVNbzrZVywrqIfBZG1u7kgu+rMmCYDEw50WoSApF89ewR7MHs0FkRgmdiAEJWW8h5+Z0IkTxHJIiRRoOeEipmp8Tv99dGRbtVAu7PDQa9MXCdEgmPtQYiAZwBB80aGdroNEHz2QphMmzwvGpokeiudrP5iPT/Gd5cnYcr2GBTcj/SUrhZZPDl1eGi1QuinkXg== 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=pdhi6vLAeWe2bzUCmXW6Nfs161aFeEl02nlWgRRDz7Q=; b=F6ZBjfe7YTCF2iIk8l3fcj16fnFwIcSmrx9nIdkZQ5ZEVy4t6ijJxbQuU3tKCLvWDnK1LxO0ob20j0HTJjLD+BB4I4eP6wptPRjjip1ynIYO786vPnaK3mFz9tRkrObTNVPuOPBBBqUc5bN384i9HvttPdJ1Vu2I2ULtF9wCnkY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5595.namprd11.prod.outlook.com (2603:10b6:510:e5::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.7; Tue, 11 Jan 2022 17:14:48 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:14:48 +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 v9 01/24] mmc: sdio: add SDIO IDs for Silabs WF200 chip Date: Tue, 11 Jan 2022 18:14:01 +0100 Message-Id: <20220111171424.862764-2-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6aac5540-59f0-4782-bfa2-08d9d525df45 X-MS-TrafficTypeDiagnostic: PH0PR11MB5595:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6790; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: sNisIf/0BvcPVIkXEc96d/M7gPcgH1IC31R+xLcy6Tdo7cErzWnZE7hGLwxIk69LmQCAC5Vo1WrDFoAHuZ73TbFiVXqckIrStDbMlGcU5Ko0J3fF++IUG78LCWDY/Jdlj60L7nx+nrdNvQBoPZgefay2YE2RXmMGI6GTAkxN+1GyAqC3sTLlZ2tfmDQ/wcbLy+oS9AyIg1moemhAIwkXRAimDVfsH4Ilyv2A/CKPXoMTppWUXpJpOGoy4xEpZuaKjfPXad4y6ZhsFvk7/3ljCC5eElqr0uwhoHUcDx6gp3+xrl+6WXZqCUzLNC36ahrRsn8mStcca5KmNYlph4NKRGmPvK5FR520UyuqS800J/7q1lHjGysj57Pi6w2wk6NWovcqaqNKTX7yqXRjXo4H+dlMloBKcO9jE+q03cytuiI1Bh4J6CeUbBR1FFN1J/VgXYLsh03IvpqnC65PyvxIMhOYOcYySVWVrvh8iOAlYJ8JCKHnCO8IvBGGiRymDqt1MaKGvT0ZfzguR3qNxrIr/0HpQidNhD4CwpOcni1PRIXmUztHDmaGUKkB//9kPd28GlDXN8kjVImYLu0uzVXfUY8K+J8NBmb3UTOrY2Y9IhRwanLxKh4vH8PA4ykUHfjJ64LcMcdWS50HgZZVpuc7Ow== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(36756003)(66946007)(6512007)(2906002)(107886003)(8936002)(2616005)(7416002)(6666004)(38100700002)(6506007)(4326008)(66476007)(8676002)(54906003)(6916009)(316002)(66556008)(52116002)(86362001)(186003)(5660300002)(6486002)(508600001)(1076003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?KmxGKbbv0swzUoSgbbcp9Xe0BPmM?= =?utf-8?q?he0RplPY1Ge/adrn5S7kD+/4S16h6EmMv8JWoGNT/ekKJAmtlC6i/DoPetDW8yR1l?= =?utf-8?q?5GDQpJINkI50VjhytadaUhq4O6SP2qirVhAWeZ+QnHJ+uzJRiMFUsZoAvOtPmKMHf?= =?utf-8?q?Vj8VxslDXan1JGXhyU2B5dWOQeGgqURdnA5tQ1A2esuXP60kczxg39rPa90ywQo3G?= =?utf-8?q?AVBLKkznGenKOBSsuRGvVJ8IlRX0XbXBOaZP3RF1967pjoNQ/xn83AEm8gzAXSZag?= =?utf-8?q?gYLLO170POwo3tmnB1nFHcP9EXn4ShUgmuCXJQH3JIr3IQx+LAlENnG/lL+ngI5Tz?= =?utf-8?q?Fzb8ho8sNGAVCosdm/BgjkywcUBzBGrYoo/0GLrE37ENzmi4bVrobwYQ0uitLa2E9?= =?utf-8?q?DtSSVk4pTRVuhaOSJpV4/Va9U/xmK78K0ZZCdEls104P0t6aHERxYSVq2t7HVq+aV?= =?utf-8?q?bcaNs9LSdSE5TUK76Z6fpTodaT6N8SuCpxhbB/JDCw1w60Uz0yi3ALNbFvDziP7ak?= =?utf-8?q?e252QrZZs9JIBsXFguja/oVMN05a2yOkzyvCUt/NlHozR664msG6uwQIOk/M56lDt?= =?utf-8?q?PdJ2WbjFEbZg/y0kBsofeK10Ui+BP0I9bh+gOK5bxMEYl5s3n3bNAQOnzRw7xrTyV?= =?utf-8?q?XeiXE8ksNW3GuyQ/t/izEJCmsZG3JZzaMBz1r+539+Tv+5Kw+ygUvIEL03rYmi4lI?= =?utf-8?q?6RnthM7ebGlVVqRvU5ogdjE+mLAwWXI4MQyQu/78GehFb017z/aoEhKC33xkuSNh1?= =?utf-8?q?7WlIvlTpmYI4rkxmmpyXO+DZaF1XAbSwk27tkXgvS1FghaOeap1gmHzhkIhTMBM/m?= =?utf-8?q?mM/lEBgSVtXzcYxmA3Gn7a8EyTtlCFiy7jT7qVV89vx7/zxNg3S/2mt5fNMrTBqL5?= =?utf-8?q?/ZM+L59OlBxURhrLEZnHLLVlipOJo4tci4opxwawMHxK6KvdioqQDEDFxg5t69V57?= =?utf-8?q?qOi1FIiWEy1x03PSLRnU7HOq33485dzKDadAwp5HmL5ZK0khThQhLeu9sj9wozwR1?= =?utf-8?q?aYQvbv+rULtXLWeQ52tUbr0a6EHlGsUJfro0bSr+m1IXCaC7C/h63DTN2v/UVH05x?= =?utf-8?q?BYdIlR/ktZ9F8rRo7g2QFhwm29q7oTGD2EJ89oCBPZtC/u/wyRYBeFn5idkbuB7y1?= =?utf-8?q?i13n/mT6LoOPLStW7IjWBZE7KD2RcBm+yl+pIQRa2PJg3md2AFcIBIgJUMw1so6r+?= =?utf-8?q?n6R9h0YAqQ04egeKcavAtHla4RzsPm89RKdne7w8J15PdY32NaQhENmjINj7WRIn1?= =?utf-8?q?eVHWmWA+X9fzZO5UnUO0q6RzT2ei4+QSi6EEb27LHNKqhMCVlqjWWPzhW1lSplrJD?= =?utf-8?q?1b8XFjATd/5Ms7+H7UntkaOpWFpxhrY6ZgaryVnO/gGIZ1BFej+b8SwrOy/j7WtkO?= =?utf-8?q?9mspWuo8D709ahiIAm9iCbKQkdO9dzQLPlFyaGLm4DzqEPrb3WKlxGmvGyPFGNzrP?= =?utf-8?q?4qMz2S2M9e97+9G5e6ALfGRJBvVEEJFoYITzoFiaXDBPzg4zz6H9A9fuYNxcsolpU?= =?utf-8?q?+ndx1SD6IF8GpKXlny1KIiw5nDvWO5FZ9rIpgjXqqxMMAV/TT+4OqAm2nCQp8jn1L?= =?utf-8?q?QebJz1A+tFMJWLvxTTKzHsDSl2DqiVHpRrdAt8t/ZNt2L7KySIxfvY=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6aac5540-59f0-4782-bfa2-08d9d525df45 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:14:48.8375 (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: nzo8FkP1UqriSNYZKKoVI5spiZVQLpyVf5lh0WKWA9T8hnF1kl9nQ4xbpZ/NHnUU6pdHilcIEnNUU2WZORb0AA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5595 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Note that the values used by Silabs are uncommon. A driver cannot fully rely on the SDIO PnP. It should also check if the device is declared in the DT. So, to apply the quirks necessary for the Silabs WF200, we rely on the DT rather than on the SDIO VID/PID. Signed-off-by: Jérôme Pouiller --- drivers/mmc/core/quirks.h | 5 +++++ include/linux/mmc/sdio_ids.h | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h index 20f568727277..f879dc63d936 100644 --- a/drivers/mmc/core/quirks.h +++ b/drivers/mmc/core/quirks.h @@ -149,6 +149,11 @@ static const struct mmc_fixup __maybe_unused sdio_fixup_methods[] = { static const struct mmc_fixup __maybe_unused sdio_card_init_methods[] = { SDIO_FIXUP_COMPATIBLE("ti,wl1251", wl1251_quirk, 0), + SDIO_FIXUP_COMPATIBLE("silabs,wf200", add_quirk, + MMC_QUIRK_BROKEN_BYTE_MODE_512 | + MMC_QUIRK_LENIENT_FN0 | + MMC_QUIRK_BLKSZ_FOR_BYTE_MODE), + END_FIXUP }; diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index a85c9f0bd470..483692f3002a 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -25,6 +25,13 @@ * Vendors and devices. Sort key: vendor first, device next. */ +/* + * Silabs does not use a reliable vendor ID. To avoid conflicts, the driver + * won't probe the device if it is not also declared in the DT. + */ +#define SDIO_VENDOR_ID_SILABS 0x0000 +#define SDIO_DEVICE_ID_SILABS_WF200 0x1000 + #define SDIO_VENDOR_ID_STE 0x0020 #define SDIO_DEVICE_ID_STE_CW1200 0x2280 From patchwork Tue Jan 11 17:14:02 2022 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: 531344 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FA39C433F5 for ; Tue, 11 Jan 2022 17:15:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343953AbiAKRPA (ORCPT ); Tue, 11 Jan 2022 12:15:00 -0500 Received: from mail-mw2nam12on2049.outbound.protection.outlook.com ([40.107.244.49]:36192 "EHLO NAM12-MW2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1343859AbiAKROx (ORCPT ); Tue, 11 Jan 2022 12:14:53 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=k8dJ/7vjtTMpHHpeF98x1tiBfqIZvODArdPJBlejZRlV2zUmSmBmxzRsUSQT4VDEAkExHy1cZuyN+TcpjwpOdVzW4KAcZXowTO7i/MsMjshlWviC8R7t28aboWG/KATydR6UKEhn/lxqHf4GUd5mwf1sRFywKsFKmzpeDTXzSRRSQkebmXc2qylw9AaeY7zgGHB4hWdqwUsOztJPXH+rePB9E0JCihqgnKl5V62yOsnGvfvEsrTVQ4BRRBMO/PiFJWZvpp3xC5JRoaKU7aEqKUkdiCHFulJPjBatRY1HC7sf6vqfWigRkplCH4t0AViygIlDuYMAFkoQ3twNYSXcRA== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=J2H/jcPaC9cTFyGGtm0LDIXJQEuv9bvw+S8ayYT2YZI=; b=FHgCiSiLGl+5OneNGthZKJcRLzktN6XR42O0FGg0tkkcFR/T5QOz6PNerM9PXh86SMIMOscYyYg2B77B3exBqO9JpVxNZg+4up3aUn78G1pp6+o4oogIfsOgK/Rpn49epCSghu/KXDwVsr8N6N80KIxRpqjvh4BfzvX5Tm5Tz+Xj7efTzXJNHBCdAWleYOV8Ea9o6+Z/FuZs/EDGDUOSa3mwSuKnsbuT+HUOEbU4DpdNDP3wEDPUQToh7ivVqWjWKINPKm7MdryomigV9YAVI/AZq2Ob7iTx8wBbf7va65yvFmZ+rDh0yMvWiOR917C9AlEedfsHgqPfBBj9Jaos0A== 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=J2H/jcPaC9cTFyGGtm0LDIXJQEuv9bvw+S8ayYT2YZI=; b=IoWa6zH3/JWiP5n+4SuBi4anesOy9IK2UKyOFpuQDwrIqEUYdFrg9yuZ+gCc8G/rySrSuAjB/aLrooOoEmtl5HVpzVIzjFnaF30iNSVCpWAb1YAIwDx9lNA3CAlypBwni9gzYWUp/HR+qvz0Ix+5oHqsf43b9mEiH7dqeq4ZuPg= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5595.namprd11.prod.outlook.com (2603:10b6:510:e5::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.7; Tue, 11 Jan 2022 17:14:51 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:14:51 +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 v9 02/24] dt-bindings: introduce silabs,wfx.yaml Date: Tue, 11 Jan 2022 18:14:02 +0100 Message-Id: <20220111171424.862764-3-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 19aeb6f2-d335-49fa-957d-08d9d525e0dd X-MS-TrafficTypeDiagnostic: PH0PR11MB5595:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: UQ2Y1mV2kmrwjRp4AzOnAtBS2vibKBAWtQWaZyYx09PTCofhJIF+DiTG72unknBPBgJIVXLl6gHQs0e5cGbkR69KduqE+yamNr/tuQP6poNI8NvNCOm9W7q26BaWc7HTuBVNVK+dOCn4NxGXa/LHe+Ud2SjLhf9kb0SgnaoE3Eh+AeAp9ISTn33SYxXNjeHqnlQ6vgwMiG4YMYrIVUN3+RXVgphwL/wJ6oEyLjXtA4uFDmymVl9q//vdJllFux4FX48sGVoe0U4HmWfpai0nQ4wtTEAnGGijTuqw4gdbK6xahhwkr5mwUxnyn9P8RRdZH86L01h7kBH6fiLPSiLVnC5cCIw11ca5oDEnDFa05yf2J+YjYdS6jlvXg9e1WoZlJtGtZ2D9srsABLX7hfHSuv1l3qQLWOrCj0UDLlLInye9yfE0xcZbaOEJbFQUFDToMfRjX87xNfbkydb48/T9nejwPQq/6JIDGDgFqd7I6aU/Nd/G/fLAbyEkKsv0si80JigjN4HIapVdYRSg5JxnIIQ7e9+hwZrSVIoGG1s7iLV5pEssk4i8eba07Epr8ZEZNKflCJRTbjT8X4IO6ajDU5jWRe6Q7/tEcA2kwMwFswgD7BidtNQli6n0aEBLgtdMRfFY5nfhym4UYAmjyrUpgzpkxWvGw6LuoILafZh16yxxmaONbPX7jJi/QFZt1ArrQWRRFOz1lJM0sI47Mpci8kdqMFmr1hrVUgc9qqAePmA= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(36756003)(66946007)(6512007)(2906002)(107886003)(8936002)(2616005)(7416002)(6666004)(38100700002)(6506007)(4326008)(66476007)(8676002)(54906003)(6916009)(316002)(66556008)(52116002)(86362001)(186003)(5660300002)(6486002)(966005)(508600001)(1076003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?hJxJcYgMNqGFrbqt4KtSQAhGdSDA?= =?utf-8?q?cYyf0ZdTEaQ0ZPKfiJUr6fl/ylJGZQfmwjMQuMKvh5mMFsmOhcoOhRda+wqGqe/W8?= =?utf-8?q?G6JbcgO50lc0Vnjk9JHZBzSuxoxA5wF2L+0OoC8fjpu2g3/dJdR30tWkcsKMn+WW0?= =?utf-8?q?JTAGloaRo8G7xqCwC23li16VBttSPzo5dXuYPtQkdXc6I8DdQqR3lGR0P70Uyy6e1?= =?utf-8?q?AUJlTwk5tjLSaa9s04yO9QO7Yh4gdmjkLhNDgS4iwqrmz6oy3yc85fBHj3EAQ7IZ8?= =?utf-8?q?a6axdAtZHkMjx5v73525nYBr7/v/2IEJtG93yE2TkoOpXQ71lfJTS+gfIwssA9TEk?= =?utf-8?q?74XB5t7gKXXGFv4ceA+23UAxA4p80OpP8wS30agfdb00tmE1lpnRn4t2hJI4YeqLo?= =?utf-8?q?GmWrVrPfoB0+Dkw6PMGrllemeaXgEYcjjwiO8hmLJOTUNjhc8B7BgVMtgU+GbltUg?= =?utf-8?q?9meQLIrJ5ZE/BsNpPeCKhSusZ9WUaicVgVLbcGkh3mZT7jlyjksBVvUqdrXIqeYyj?= =?utf-8?q?R3c6X0P/0jMihl0x0b3ODcAabLJZnB7a7As3QLONL/ZukDuXkvGoE8NTHBBI0CRJ+?= =?utf-8?q?RhIumWxOM7S4OYGgNnvyc6V5YoNsRxJ5csAafbax+k3x5G2kY8FkqiHEs3AuMqQEI?= =?utf-8?q?+hyhauYSmPTgNB8WrVaWkyGDBhlPacWeAVQFSkzyoacmPOcetpKl288eH9BoEmUiP?= =?utf-8?q?Fhc1OAICqNcj+4fxsmmk2wRb2teNv7JDQPjRRzy5xpauRaNhoUIBK/NedkVoHZ6ex?= =?utf-8?q?Zb8Lr+MTkgG7csZnckwOpnUW6q2nA3ATzhUCJ7B0LtmIfWtNT56c3DJeZsiCber6r?= =?utf-8?q?nMnkqthiaT7Lr6wVh8UPf+yL94QL6TFjDcOQSdqVP7omCcxgPGffBNTwIIu9GPHcz?= =?utf-8?q?lj+BEvj/01kprHRrjmoRBXeoQT0LkvfSBCfa8p+ekHkytiNtQiSwZdxXnA8sSHpaG?= =?utf-8?q?tRE5YYvsfM5oEAyLqE2SzMTUkvq7h8xcDU73glm6thPUDMEb11iXGyawAFaZZpPi2?= =?utf-8?q?aO2IVsyPR6NjOlK2f9lorhdX+fhbHwxb3FctaTV1iY7WrAAxaFcgdG23/SkGRMgby?= =?utf-8?q?wCaYjVDlK9V2DWVKyALOOQQLuzn/plNAtcAJaTvXTUnWR/MlBxk7IY0ZUcztRq+FS?= =?utf-8?q?bLVzA8hqpXIADlcPRSWPG1dYRu7i92Q5/SapLuNFYHZg1MwyQfnlUCzuh5p3FORrb?= =?utf-8?q?FyWZ7R6rYltqVUS8dykABu3VgT1fjksfgMMFNM6ClcDw9JaykpP6PosKmlhToANtB?= =?utf-8?q?HwQV+MEptE7HzhcHD0yh2xHIngJODbsx8UFDKR3gpEaXRGLNLzeYzb1XSHoyDkCfM?= =?utf-8?q?+yKmKd+q99714csKIwKbw5dPbzTlKThyyYGJptUGdfJzYTCOcOavugi+pBsXqfA2G?= =?utf-8?q?5Rhi7sFleORlyR6y+CqNw00OrnlGWFfUpNBP0V/CAs8CCX3p9QwKdutbUQNcMxh5/?= =?utf-8?q?8YNn4EiWAU+JbtsIjgbuOAUo4vJVbOO7f3w6IhgG8S9p6qatanWmpl8Kcf2D9lc8A?= =?utf-8?q?qdBMkESgvZI01y7ckrlslSTfykCRKfgZcK0SQd/cam2JXbhaKRHwJfdcVOdObCYgA?= =?utf-8?q?/F2WG8joQ8ScMh0wbYMyeBr/q1UN4D/bYRCRp+CH51Gzk3bitvZKgg=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 19aeb6f2-d335-49fa-957d-08d9d525e0dd X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:14:51.4478 (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: DOx+wyAryQ5O9Gp4I7oCHmnP+c9f/yMktnM0jOyILvfScNyDF8CTsNABuwUpHfj2Fd2pfkoO1EpMxutnRkUR/Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5595 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Prepare the inclusion of the wfx driver in the kernel. Signed-off-by: Jérôme Pouiller --- .../bindings/net/wireless/silabs,wfx.yaml | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml diff --git a/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml b/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml new file mode 100644 index 000000000000..d12f262868cf --- /dev/null +++ b/Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml @@ -0,0 +1,138 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2020, Silicon Laboratories, Inc. +%YAML 1.2 +--- + +$id: http://devicetree.org/schemas/net/wireless/silabs,wfx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Silicon Labs WFxxx devicetree bindings + +maintainers: + - Jérôme Pouiller + +description: > + Support for the Wifi chip WFxxx from Silicon Labs. Currently, the only device + from the WFxxx series is the WF200 described here: + https://www.silabs.com/documents/public/data-sheets/wf200-datasheet.pdf + + The WF200 can be connected via SPI or via SDIO. + + For SDIO: + + Declaring the WFxxx chip in device tree is mandatory (usually, the VID/PID is + sufficient for the SDIO devices). + + It is recommended to declare a mmc-pwrseq on SDIO host above WFx. Without + it, you may encounter issues during reboot. The mmc-pwrseq should be + compatible with mmc-pwrseq-simple. Please consult + Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.yaml for more + information. + + For SPI: + + In add of the properties below, please consult + Documentation/devicetree/bindings/spi/spi-controller.yaml for optional SPI + related properties. + +properties: + compatible: + anyOf: + - const: silabs,wf200 # Chip alone without antenna + - const: silabs,brd4001a # WGM160P Evaluation Board + - const: silabs,brd8022a # WF200 Evaluation Board + - const: silabs,brd8023a # WFM200 Evaluation Board + + reg: + description: + When used on SDIO bus, must be set to 1. When used on SPI bus, it is + the chip select address of the device as defined in the SPI devices + bindings. + maxItems: 1 + + spi-max-frequency: true + + interrupts: + description: The interrupt line. Triggers IRQ_TYPE_LEVEL_HIGH and + IRQ_TYPE_EDGE_RISING are both supported by the chip and the driver. When + SPI is used, this property is required. When SDIO is used, the "in-band" + interrupt provided by the SDIO bus is used unless an interrupt is defined + in the Device Tree. + maxItems: 1 + + reset-gpios: + description: (SPI only) Phandle of gpio that will be used to reset chip + during probe. Without this property, you may encounter issues with warm + boot. (For legacy purpose, the gpio in inverted when compatible == + "silabs,wfx-spi") + + For SDIO, the reset gpio should declared using a mmc-pwrseq. + maxItems: 1 + + wakeup-gpios: + description: Phandle of gpio that will be used to wake-up chip. Without this + property, driver will disable most of power saving features. + maxItems: 1 + + silabs,antenna-config-file: + $ref: /schemas/types.yaml#/definitions/string + description: Use an alternative file for antenna configuration (aka + "Platform Data Set" in Silabs jargon). Default depends of "compatible" + string. For "silabs,wf200", the default is 'wf200.pds'. + + local-mac-address: true + + mac-address: true + +additionalProperties: false + +required: + - compatible + - reg + +examples: + - | + #include + #include + + spi0 { + #address-cells = <1>; + #size-cells = <0>; + + wifi@0 { + compatible = "silabs,brd4001a", "silabs,wf200"; + pinctrl-names = "default"; + pinctrl-0 = <&wfx_irq &wfx_gpios>; + reg = <0>; + interrupts-extended = <&gpio 16 IRQ_TYPE_EDGE_RISING>; + wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + spi-max-frequency = <42000000>; + }; + }; + + - | + #include + #include + + wfx_pwrseq: wfx_pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wfx_reset>; + reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + }; + + mmc0 { + mmc-pwrseq = <&wfx_pwrseq>; + #address-cells = <1>; + #size-cells = <0>; + + wifi@1 { + compatible = "silabs,brd8022a", "silabs,wf200"; + pinctrl-names = "default"; + pinctrl-0 = <&wfx_wakeup>; + reg = <1>; + wakeup-gpios = <&gpio 12 GPIO_ACTIVE_HIGH>; + }; + }; +... From patchwork Tue Jan 11 17:14:05 2022 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: 531343 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75824C433F5 for ; Tue, 11 Jan 2022 17:15:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244465AbiAKRPO (ORCPT ); Tue, 11 Jan 2022 12:15:14 -0500 Received: from mail-dm3nam07on2065.outbound.protection.outlook.com ([40.107.95.65]:38465 "EHLO NAM02-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1343955AbiAKRPC (ORCPT ); Tue, 11 Jan 2022 12:15:02 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=NX4SyPaTueeXnU1UCW4kFM7ZWEAn79tHot7xC8L/KU4BkhYlYLub2FfoDSEzQIzvKAhir4x58DQtUnL29P1QDloKfWLjysHOjqGcXcBmWsNKhLtWoVXt36djA9IfTPjL8jQTqGJuMvkzew8TUZ+ZgBCuMZ2SR/GnDXbJQ3LpAWfw9v02yxEXQMPFAhPKtxtmJb9aDFZC4kn7zGF0p1r6JcIORggxq/ARaempydWIHkPch4nze4ODWkYKV2Nz15b0i/zcoxuqFrKQkT3m7hJwGx34ZKWocPyXESyyI+EHNbYCpiUjdheHsRT21q3daBaXW+dEiblb5FuTwmC/GMKxrA== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MiTeny0u/cbsH682FeE+dHMx44CGaIV/DCmCDqEFrpo=; b=laceNOlVLhjJff3OKbf57atUkFO4jo9YBOPakUeLkAJ/T9TxdNv1Wdqr6yMSQ1+8o1oDQ/RbB4NoO+XbdErdqVxm4E+E0ID85qmnjDb77ck0rXJ/Kr6WvjFOC0OzuQToVsLT1KBQTH9NprjQnYyKE6OBt1AV2nl7VXftaBEDtFENmvsm/m6PszaMp7YzE0mXc417X3BL1RSpSIu0fWGLZtJA9WKRByU/FLsBMe9nv5y5jMmCKghUPLfhXh1eJVKXwrNXswFJFEaVQnZjDGDZOVK4+AE8g/o7rju3ZrBdqEdSNUlBfLpWQX7StMTIQihghSNMTom7W73HPmKt96yg5g== 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=MiTeny0u/cbsH682FeE+dHMx44CGaIV/DCmCDqEFrpo=; b=UFTWhZpQqk+zHBEqMf6OjWUwP0MYW7FqQwKFBxfX8NryzaneI/gltSHTknXrIh2hw9GtVPaMQVLxiSKqZihb0yc0FiKOipWRJXhbBiDKHDScTyt8o/z5SGpveSip0snBPilXE06NfKaKSmX52UdjBsc3cncHQVRAmzn4vEaM7Fo= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5674.namprd11.prod.outlook.com (2603:10b6:510:ec::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.11; Tue, 11 Jan 2022 17:14:59 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:14:59 +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 v9 05/24] wfx: add main.c/main.h Date: Tue, 11 Jan 2022 18:14:05 +0100 Message-Id: <20220111171424.862764-6-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: a272a7d3-96e2-4f89-f1de-08d9d525e558 X-MS-TrafficTypeDiagnostic: PH0PR11MB5674:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:189; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: /xZvEDbT8Dw5oyta6oIwOGxWX6ajH21cCQORF7cyByoLoeoTXAw894Ma8grvnBGtca3RjuCQ6yzQH9GMCNJfY/mITAn0l1lY/UNdHoqD4fOlJWxVfKj0f3Q1u9mJJEoIpfr7l1nPIch5TMI9r7raTFrnDVlmxAkJGX2IKMrCytjpaT/LEqqzHM4HPJozb5Chc8Fp0eJG5dJuGxfk9UdPolHE+MdfYfYgbbztvmaCxzqQXW7qxVFn2YAlaBS8oDuqPZFBVCIBIdFJGti55P0hujjBVWeTPv2q6OhfHKXDkbM6clCj6biuEgzLZ95LBKZTGb8LR595syrGl5jO5r+OOJegiqOju8TF6py/JsnyCtTjr/IFve96RNQYXt+ura1eQMH0WIHBqGW4Xd8FLncXgoK9L0pD5CGkxeQ3bzZd3b/LmGB8XEtWBCZ8IeEb/vhAq5Fhb3uZYGu+reQPcenaVrQpitqPjsObmU/c3SvkqnL1pgWtH9ppi4Q6/lS2zjkhjsWauqwrnZ764Re9z/mMJkkaFVhblKYz0EjvG4hMAX/GH2gPjMYZh74XwWuoAWtVRmt0hs3KujUnXDokawLKHoJXR7HNJ1TbbMp7iX4lumNw0AnRndmBcWl8o/DlQ4JQKSVZTiWx8ZU0rOg7nwfEZz8seZX+2YerxbcdhBp1LTcT023F+ytCZEMp1UXZxYGMgaDR48xtpc8q2J5O8nDk5iUFCd7zJ3vgEKaeavkXui0= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(6506007)(66946007)(66574015)(8936002)(107886003)(4326008)(66476007)(508600001)(36756003)(84970400001)(7416002)(8676002)(86362001)(6916009)(83380400001)(52116002)(316002)(6512007)(2906002)(6666004)(30864003)(6486002)(1076003)(186003)(66556008)(54906003)(38100700002)(2616005)(5660300002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?Cq8gwV2/JY7KDuTo9LLDkmz5R8wR?= =?utf-8?q?DrRrZyHLJ9ojGjJlrc7PlAUvnw2HkXZ6G6MbVirblwz9c/NMZu4V3hkyhbvhHW2Ed?= =?utf-8?q?zC79P/1zLCV43TUdS1NWznJ+pEZL2ZieyMoojIu+MTw0e+G0G6VPhDAH0DZgp3Oip?= =?utf-8?q?WDAiDoLBSyf4g+upXd2e1oy6FGpVpLFBpWLcVN9lA9je6dFr3etUcKfkAfQEb66C/?= =?utf-8?q?Dj/Nb7XC5/Eug8Plq23I2DUnUYiAp4qt08A49C1hvi+NkG5nBuIBW7RC1/aInkZt/?= =?utf-8?q?2mBGm09gGLdKzsqklKzZVS8QKPZucms9BV/dBUZGJ9KXFLdxvxyatAIoqbtSrIEOw?= =?utf-8?q?QV/ixztiuadQhQeeBtL8vgc5i8/AjzmLiclpMGzaVehYdCR4rc3Mchlyf9iLWLNqD?= =?utf-8?q?LhBvRUBM63SNfTv9O5XW8Asu3DVudSwhHpKBAfXuIKlzbna4kzznZSnuhIW4xpk2L?= =?utf-8?q?Gb8gn5XF7wP4jJ5o9HNJOupRPikRe56G6RR6mT3htvPwcl/hhQBR1u94USuYbYavW?= =?utf-8?q?9lk8wLItaSsJawXId37QkzGTItSQzKxKXW5kFZ5loW4ebGRCHb07nc7XSQB4qJkm6?= =?utf-8?q?0/7IhQyTAJ9CjzdJGDiIts2RHCMYKqM7h+GypzdUWrL0Dfwx5CzPCtk0wwN7QBLib?= =?utf-8?q?LIs8JqRtaDBK9T/sTBBM3JZwFbjRsCyLXf/vcMpouhHfHfBcwDL7WMEr/uaihvgAa?= =?utf-8?q?CXhUClAftAk8FjinY/lbTHW84UO0CnO8EJ5mS2yeKRgGie04SLZ9CNMtv1/0XkCJk?= =?utf-8?q?6ye9GNMSqE9+/egzaaVyOlLSd0GsBnGQQwXTQg0iXlqBOCISK0UJHNhwS8Ks5zOwF?= =?utf-8?q?/t9UY4o226zAWt3ZfRB1tjFUu5w5clJgl2ZQR5uHwLfMbCirXkzNyPVIRzWN2A59c?= =?utf-8?q?LcNt3O5CGTro9/M+6g4m0J7zyHSBEHBOW1YcShAT76X7Ti3tC2jbj30wIY/FZv+zy?= =?utf-8?q?KtmhKpiyvbN3OjsA5/diOtdPigS4zogrNLd4O5rLqvMTJ7jgCh6+klq5Dr7Nbnbny?= =?utf-8?q?egS2QwTCtziobppBPnkUsBE1CJlR4S++zZW4VBvaaDFtVYxP/Yynr7SwtJEg6RYT6?= =?utf-8?q?G0zhLO1V3rLA30rbl35hd+Em1ircZRk6hLfmtXmz9Kw3cbvUz1JAaVZBWSDLoMqb+?= =?utf-8?q?Zk6UcOcxzSQOlza5ynFnn3iM3YaUKQzEI7YPxx8cCmVRTt1k4pNOlVGl7MlyyPPwr?= =?utf-8?q?O447/LL3kJ1Ff/5Y14QR4hjcPJQGqZFUL2RwOEFMNh24FM82YT36cV9Kw35bdCB0c?= =?utf-8?q?WWJBi9rWCkrHvPpTP5+mn1rB7026RnFiCBXM2bIy7tjvHZ+1ZkmUzZJ1jwm2wRRtS?= =?utf-8?q?7RkE6C0PsK/tccWRrlmUtsOlHGfPsdDaK33+kK49rUDfTJD+dnVJ5zogtRtO4M096?= =?utf-8?q?eR+yVuLTMuu9mT55I2HBT3QbFeEIgVDhofLVErEXUpxpPs18hSNlz0vmI1+y/zD+A?= =?utf-8?q?M2xS85+oynNyPDtgZsim76Qd9aylnPoVJzynwpYckfWHR7z4/5cuuEFRmqHR6mekD?= =?utf-8?q?mNStdGV76jcmYojNq0tnU0g7STse7jiLKEQwWYRAnO5zBSQ0QjbyeSmDBm4XtpCT0?= =?utf-8?q?JIbaCFh5N864fP3AOA6m11z1lYBu3Hn0h3MoEnW5mhcPSm7wZp4hmw=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: a272a7d3-96e2-4f89-f1de-08d9d525e558 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:14:59.1234 (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: bzo4GycsnADactlG7Dng8z0zDbc3pGhiCOdc332dyi4hEieTk0Z1D6FXECIAqvMtX3H4VI3p9cG76EPiWgunEA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5674 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/main.c | 485 +++++++++++++++++++++++++ drivers/net/wireless/silabs/wfx/main.h | 42 +++ 2 files changed, 527 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/main.c create mode 100644 drivers/net/wireless/silabs/wfx/main.h diff --git a/drivers/net/wireless/silabs/wfx/main.c b/drivers/net/wireless/silabs/wfx/main.c new file mode 100644 index 000000000000..d3507b91263b --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/main.c @@ -0,0 +1,485 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Device probe and register. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + * Copyright (c) 2008, Johannes Berg + * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (c) 2007-2009, Christian Lamparter + * Copyright (c) 2006, Michael Wu + * Copyright (c) 2004-2006 Jean-Baptiste Note , et al. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" +#include "wfx.h" +#include "fwio.h" +#include "hwio.h" +#include "bus.h" +#include "bh.h" +#include "sta.h" +#include "key.h" +#include "scan.h" +#include "debug.h" +#include "data_tx.h" +#include "hif_tx_mib.h" +#include "hif_api_cmd.h" + +#define WFX_PDS_TLV_TYPE 0x4450 // "PD" (Platform Data) in ascii little-endian +#define WFX_PDS_MAX_CHUNK_SIZE 1500 + +MODULE_DESCRIPTION("Silicon Labs 802.11 Wireless LAN driver for WF200"); +MODULE_AUTHOR("Jérôme Pouiller "); +MODULE_LICENSE("GPL"); + +#define RATETAB_ENT(_rate, _rateid, _flags) { \ + .bitrate = (_rate), \ + .hw_value = (_rateid), \ + .flags = (_flags), \ +} + +static struct ieee80211_rate wfx_rates[] = { + RATETAB_ENT(10, 0, 0), + RATETAB_ENT(20, 1, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(55, 2, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(110, 3, IEEE80211_RATE_SHORT_PREAMBLE), + RATETAB_ENT(60, 6, 0), + RATETAB_ENT(90, 7, 0), + RATETAB_ENT(120, 8, 0), + RATETAB_ENT(180, 9, 0), + RATETAB_ENT(240, 10, 0), + RATETAB_ENT(360, 11, 0), + RATETAB_ENT(480, 12, 0), + RATETAB_ENT(540, 13, 0), +}; + +#define CHAN2G(_channel, _freq, _flags) { \ + .band = NL80211_BAND_2GHZ, \ + .center_freq = (_freq), \ + .hw_value = (_channel), \ + .flags = (_flags), \ + .max_antenna_gain = 0, \ + .max_power = 30, \ +} + +static struct ieee80211_channel wfx_2ghz_chantable[] = { + CHAN2G(1, 2412, 0), + CHAN2G(2, 2417, 0), + CHAN2G(3, 2422, 0), + CHAN2G(4, 2427, 0), + CHAN2G(5, 2432, 0), + CHAN2G(6, 2437, 0), + CHAN2G(7, 2442, 0), + CHAN2G(8, 2447, 0), + CHAN2G(9, 2452, 0), + CHAN2G(10, 2457, 0), + CHAN2G(11, 2462, 0), + CHAN2G(12, 2467, 0), + CHAN2G(13, 2472, 0), + CHAN2G(14, 2484, 0), +}; + +static const struct ieee80211_supported_band wfx_band_2ghz = { + .channels = wfx_2ghz_chantable, + .n_channels = ARRAY_SIZE(wfx_2ghz_chantable), + .bitrates = wfx_rates, + .n_bitrates = ARRAY_SIZE(wfx_rates), + .ht_cap = { + /* Receive caps */ + .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_MAX_AMSDU | (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), + .ht_supported = 1, + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, + .mcs = { + .rx_mask = { 0xFF }, /* MCS0 to MCS7 */ + .rx_highest = cpu_to_le16(72), + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, + }, + }, +}; + +static const struct ieee80211_iface_limit wdev_iface_limits[] = { + { .max = 1, .types = BIT(NL80211_IFTYPE_STATION) }, + { .max = 1, .types = BIT(NL80211_IFTYPE_AP) }, +}; + +static const struct ieee80211_iface_combination wfx_iface_combinations[] = { + { + .num_different_channels = 2, + .max_interfaces = 2, + .limits = wdev_iface_limits, + .n_limits = ARRAY_SIZE(wdev_iface_limits), + } +}; + +static const struct ieee80211_ops wfx_ops = { + .start = wfx_start, + .stop = wfx_stop, + .add_interface = wfx_add_interface, + .remove_interface = wfx_remove_interface, + .config = wfx_config, + .tx = wfx_tx, + .join_ibss = wfx_join_ibss, + .leave_ibss = wfx_leave_ibss, + .conf_tx = wfx_conf_tx, + .hw_scan = wfx_hw_scan, + .cancel_hw_scan = wfx_cancel_hw_scan, + .start_ap = wfx_start_ap, + .stop_ap = wfx_stop_ap, + .sta_add = wfx_sta_add, + .sta_remove = wfx_sta_remove, + .set_tim = wfx_set_tim, + .set_key = wfx_set_key, + .set_rts_threshold = wfx_set_rts_threshold, + .set_default_unicast_key = wfx_set_default_unicast_key, + .bss_info_changed = wfx_bss_info_changed, + .configure_filter = wfx_configure_filter, + .ampdu_action = wfx_ampdu_action, + .flush = wfx_flush, + .add_chanctx = wfx_add_chanctx, + .remove_chanctx = wfx_remove_chanctx, + .change_chanctx = wfx_change_chanctx, + .assign_vif_chanctx = wfx_assign_vif_chanctx, + .unassign_vif_chanctx = wfx_unassign_vif_chanctx, +}; + +bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor) +{ + if (wdev->hw_caps.api_version_major < major) + return true; + if (wdev->hw_caps.api_version_major > major) + return false; + if (wdev->hw_caps.api_version_minor < minor) + return true; + return false; +} + +/* The device needs data about the antenna configuration. This information in + * provided by PDS (Platform Data Set, this is the wording used in WF200 + * documentation) files. For hardware integrators, the full process to create + * PDS files is described here: + * https:github.com/SiliconLabs/wfx-firmware/blob/master/PDS/README.md + * + * The PDS file is an array of Time-Length-Value structs. + */ + int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len) +{ + int ret, chunk_type, chunk_len, chunk_num = 0; + + if (*buf == '{') { + dev_err(wdev->dev, "PDS: malformed file (legacy format?)\n"); + return -EINVAL; + } + while (len > 0) { + chunk_type = get_unaligned_le16(buf + 0); + chunk_len = get_unaligned_le16(buf + 2); + if (chunk_len > len) { + dev_err(wdev->dev, "PDS:%d: corrupted file\n", chunk_num); + return -EINVAL; + } + if (chunk_type != WFX_PDS_TLV_TYPE) { + dev_info(wdev->dev, "PDS:%d: skip unknown data\n", chunk_num); + goto next; + } + if (chunk_len > WFX_PDS_MAX_CHUNK_SIZE) + dev_warn(wdev->dev, "PDS:%d: unexpectly large chunk\n", chunk_num); + if (buf[4] != '{' || buf[chunk_len - 1] != '}') + dev_warn(wdev->dev, "PDS:%d: unexpected content\n", chunk_num); + + ret = wfx_hif_configuration(wdev, buf + 4, chunk_len - 4); + if (ret > 0) { + dev_err(wdev->dev, "PDS:%d: invalid data (unsupported options?)\n", + chunk_num); + return -EINVAL; + } + if (ret == -ETIMEDOUT) { + dev_err(wdev->dev, "PDS:%d: chip didn't reply (corrupted file?)\n", + chunk_num); + return ret; + } + if (ret) { + dev_err(wdev->dev, "PDS:%d: chip returned an unknown error\n", chunk_num); + return -EIO; + } +next: + chunk_num++; + len -= chunk_len; + buf += chunk_len; + } + return 0; +} + +static int wfx_send_pdata_pds(struct wfx_dev *wdev) +{ + int ret = 0; + const struct firmware *pds; + u8 *tmp_buf; + + ret = request_firmware(&pds, wdev->pdata.file_pds, wdev->dev); + if (ret) { + dev_err(wdev->dev, "can't load antenna parameters (PDS file %s). The device may be unstable.\n", + wdev->pdata.file_pds); + return ret; + } + tmp_buf = kmemdup(pds->data, pds->size, GFP_KERNEL); + if (!tmp_buf) { + ret = -ENOMEM; + goto release_fw; + } + ret = wfx_send_pds(wdev, tmp_buf, pds->size); + kfree(tmp_buf); +release_fw: + release_firmware(pds); + return ret; +} + +static void wfx_free_common(void *data) +{ + struct wfx_dev *wdev = data; + + mutex_destroy(&wdev->tx_power_loop_info_lock); + mutex_destroy(&wdev->rx_stats_lock); + mutex_destroy(&wdev->conf_mutex); + ieee80211_free_hw(wdev->hw); +} + +struct wfx_dev *wfx_init_common(struct device *dev, const struct wfx_platform_data *pdata, + const struct wfx_hwbus_ops *hwbus_ops, void *hwbus_priv) +{ + struct ieee80211_hw *hw; + struct wfx_dev *wdev; + + hw = ieee80211_alloc_hw(sizeof(struct wfx_dev), &wfx_ops); + if (!hw) + return NULL; + + SET_IEEE80211_DEV(hw, dev); + + ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW); + ieee80211_hw_set(hw, AMPDU_AGGREGATION); + ieee80211_hw_set(hw, CONNECTION_MONITOR); + ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ieee80211_hw_set(hw, SIGNAL_DBM); + ieee80211_hw_set(hw, SUPPORTS_PS); + ieee80211_hw_set(hw, MFP_CAPABLE); + + hw->vif_data_size = sizeof(struct wfx_vif); + hw->sta_data_size = sizeof(struct wfx_sta_priv); + hw->queues = 4; + hw->max_rates = 8; + hw->max_rate_tries = 8; + hw->extra_tx_headroom = sizeof(struct wfx_hif_msg) + sizeof(struct wfx_hif_req_tx) + + 4 /* alignment */ + 8 /* TKIP IV */; + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP); + hw->wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; + hw->wiphy->features |= NL80211_FEATURE_AP_SCAN; + hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; + hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; + hw->wiphy->max_ap_assoc_sta = HIF_LINK_ID_MAX; + hw->wiphy->max_scan_ssids = 2; + hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; + hw->wiphy->n_iface_combinations = ARRAY_SIZE(wfx_iface_combinations); + hw->wiphy->iface_combinations = wfx_iface_combinations; + hw->wiphy->bands[NL80211_BAND_2GHZ] = devm_kmalloc(dev, sizeof(wfx_band_2ghz), GFP_KERNEL); + /* FIXME: also copy wfx_rates and wfx_2ghz_chantable */ + memcpy(hw->wiphy->bands[NL80211_BAND_2GHZ], &wfx_band_2ghz, sizeof(wfx_band_2ghz)); + + wdev = hw->priv; + wdev->hw = hw; + wdev->dev = dev; + wdev->hwbus_ops = hwbus_ops; + wdev->hwbus_priv = hwbus_priv; + memcpy(&wdev->pdata, pdata, sizeof(*pdata)); + of_property_read_string(dev->of_node, "silabs,antenna-config-file", &wdev->pdata.file_pds); + wdev->pdata.gpio_wakeup = devm_gpiod_get_optional(dev, "wakeup", GPIOD_OUT_LOW); + if (IS_ERR(wdev->pdata.gpio_wakeup)) + return NULL; + if (wdev->pdata.gpio_wakeup) + gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup"); + + mutex_init(&wdev->conf_mutex); + mutex_init(&wdev->rx_stats_lock); + mutex_init(&wdev->tx_power_loop_info_lock); + init_completion(&wdev->firmware_ready); + INIT_DELAYED_WORK(&wdev->cooling_timeout_work, wfx_cooling_timeout_work); + skb_queue_head_init(&wdev->tx_pending); + init_waitqueue_head(&wdev->tx_dequeue); + wfx_init_hif_cmd(&wdev->hif_cmd); + + if (devm_add_action_or_reset(dev, wfx_free_common, wdev)) + return NULL; + + return wdev; +} + +int wfx_probe(struct wfx_dev *wdev) +{ + int i; + int err; + struct gpio_desc *gpio_saved; + + /* During first part of boot, gpio_wakeup cannot yet been used. So prevent bh() to touch + * it. + */ + gpio_saved = wdev->pdata.gpio_wakeup; + wdev->pdata.gpio_wakeup = NULL; + wdev->poll_irq = true; + + wfx_bh_register(wdev); + + err = wfx_init_device(wdev); + if (err) + goto bh_unregister; + + wfx_bh_poll_irq(wdev); + err = wait_for_completion_timeout(&wdev->firmware_ready, 1 * HZ); + if (err <= 0) { + if (err == 0) { + dev_err(wdev->dev, "timeout while waiting for startup indication\n"); + err = -ETIMEDOUT; + } else if (err == -ERESTARTSYS) { + dev_info(wdev->dev, "probe interrupted by user\n"); + } + goto bh_unregister; + } + + /* FIXME: fill wiphy::hw_version */ + dev_info(wdev->dev, "started firmware %d.%d.%d \"%s\" (API: %d.%d, keyset: %02X, caps: 0x%.8X)\n", + wdev->hw_caps.firmware_major, wdev->hw_caps.firmware_minor, + wdev->hw_caps.firmware_build, wdev->hw_caps.firmware_label, + wdev->hw_caps.api_version_major, wdev->hw_caps.api_version_minor, + wdev->keyset, wdev->hw_caps.link_mode); + snprintf(wdev->hw->wiphy->fw_version, + sizeof(wdev->hw->wiphy->fw_version), + "%d.%d.%d", + wdev->hw_caps.firmware_major, + wdev->hw_caps.firmware_minor, + wdev->hw_caps.firmware_build); + + if (wfx_api_older_than(wdev, 1, 0)) { + dev_err(wdev->dev, "unsupported firmware API version (expect 1 while firmware returns %d)\n", + wdev->hw_caps.api_version_major); + err = -EOPNOTSUPP; + goto bh_unregister; + } + + if (wdev->hw_caps.link_mode == SEC_LINK_ENFORCED) { + dev_err(wdev->dev, "chip require secure_link, but can't negotiate it\n"); + goto bh_unregister; + } + + if (wdev->hw_caps.region_sel_mode) { + wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[11].flags |= + IEEE80211_CHAN_NO_IR; + wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[12].flags |= + IEEE80211_CHAN_NO_IR; + wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[13].flags |= + IEEE80211_CHAN_DISABLED; + } + + dev_dbg(wdev->dev, "sending configuration file %s\n", wdev->pdata.file_pds); + err = wfx_send_pdata_pds(wdev); + if (err < 0 && err != -ENOENT) + goto bh_unregister; + + wdev->poll_irq = false; + err = wdev->hwbus_ops->irq_subscribe(wdev->hwbus_priv); + if (err) + goto bh_unregister; + + err = wfx_hif_use_multi_tx_conf(wdev, true); + if (err) + dev_err(wdev->dev, "misconfigured IRQ?\n"); + + wdev->pdata.gpio_wakeup = gpio_saved; + if (wdev->pdata.gpio_wakeup) { + dev_dbg(wdev->dev, "enable 'quiescent' power mode with wakeup GPIO and PDS file %s\n", + wdev->pdata.file_pds); + gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1); + wfx_control_reg_write(wdev, 0); + wfx_hif_set_operational_mode(wdev, HIF_OP_POWER_MODE_QUIESCENT); + } else { + wfx_hif_set_operational_mode(wdev, HIF_OP_POWER_MODE_DOZE); + } + + for (i = 0; i < ARRAY_SIZE(wdev->addresses); i++) { + eth_zero_addr(wdev->addresses[i].addr); + err = of_get_mac_address(wdev->dev->of_node, wdev->addresses[i].addr); + if (!err) + wdev->addresses[i].addr[ETH_ALEN - 1] += i; + else + ether_addr_copy(wdev->addresses[i].addr, wdev->hw_caps.mac_addr[i]); + if (!is_valid_ether_addr(wdev->addresses[i].addr)) { + dev_warn(wdev->dev, "using random MAC address\n"); + eth_random_addr(wdev->addresses[i].addr); + } + dev_info(wdev->dev, "MAC address %d: %pM\n", i, wdev->addresses[i].addr); + } + wdev->hw->wiphy->n_addresses = ARRAY_SIZE(wdev->addresses); + wdev->hw->wiphy->addresses = wdev->addresses; + + if (!wfx_api_older_than(wdev, 3, 8)) + wdev->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; + + err = ieee80211_register_hw(wdev->hw); + if (err) + goto irq_unsubscribe; + + err = wfx_debug_init(wdev); + if (err) + goto ieee80211_unregister; + + return 0; + +ieee80211_unregister: + ieee80211_unregister_hw(wdev->hw); +irq_unsubscribe: + wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv); +bh_unregister: + wfx_bh_unregister(wdev); + return err; +} + +void wfx_release(struct wfx_dev *wdev) +{ + ieee80211_unregister_hw(wdev->hw); + wfx_hif_shutdown(wdev); + wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv); + wfx_bh_unregister(wdev); +} + +static int __init wfx_core_init(void) +{ + int ret = 0; + + if (IS_ENABLED(CONFIG_SPI)) + ret = spi_register_driver(&wfx_spi_driver); + if (IS_ENABLED(CONFIG_MMC) && !ret) + ret = sdio_register_driver(&wfx_sdio_driver); + return ret; +} +module_init(wfx_core_init); + +static void __exit wfx_core_exit(void) +{ + if (IS_ENABLED(CONFIG_MMC)) + sdio_unregister_driver(&wfx_sdio_driver); + if (IS_ENABLED(CONFIG_SPI)) + spi_unregister_driver(&wfx_spi_driver); +} +module_exit(wfx_core_exit); diff --git a/drivers/net/wireless/silabs/wfx/main.h b/drivers/net/wireless/silabs/wfx/main.h new file mode 100644 index 000000000000..fcd26b24519e --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/main.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Device probe and register. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + * Copyright (c) 2006, Michael Wu + * Copyright 2004-2006 Jean-Baptiste Note , et al. + */ +#ifndef WFX_MAIN_H +#define WFX_MAIN_H + +#include +#include + +#include "hif_api_general.h" + +struct wfx_dev; +struct wfx_hwbus_ops; + +struct wfx_platform_data { + /* Keyset and ".sec" extension will be appended to this string */ + const char *file_fw; + const char *file_pds; + struct gpio_desc *gpio_wakeup; + bool reset_inverted; + /* if true HIF D_out is sampled on the rising edge of the clock (intended to be used in + * 50Mhz SDIO) + */ + bool use_rising_clk; +}; + +struct wfx_dev *wfx_init_common(struct device *dev, const struct wfx_platform_data *pdata, + const struct wfx_hwbus_ops *hwbus_ops, void *hwbus_priv); + +int wfx_probe(struct wfx_dev *wdev); +void wfx_release(struct wfx_dev *wdev); + +bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor); +int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len); + +#endif From patchwork Tue Jan 11 17:14:09 2022 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: 531342 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41CA8C433EF for ; Tue, 11 Jan 2022 17:15:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244088AbiAKRPn (ORCPT ); Tue, 11 Jan 2022 12:15:43 -0500 Received: from mail-dm3nam07on2065.outbound.protection.outlook.com ([40.107.95.65]:38465 "EHLO NAM02-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S243511AbiAKRPO (ORCPT ); Tue, 11 Jan 2022 12:15:14 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YM3HIPaoL5ZCcslo3kbqqqbgXVqOKwI+f9zTj9QbHLUD4GcEyNa5pFlmwT09wSjAR4ZcVGT236efxP0FC/3gPdDBOaFyD0aysRZgT+XUAqPE7hKD+M0eCP34dyJFms0bXjeho3EMctNZc8VhM1VrJS1zSGrQy9aiv9F2zQArEnGbm6z2s9rhvBt6jLJBn98PWHxShF/1tXpXWbpKfU/F8XJc2cUN+Kg+kFDWGH7XZxvT/cPty5AuJSqHxHkNDocogaykSAgb9rDtN8UOof8LWx1XRxDWA/hFD6+xHPAWcuaZj9JJp3lrt4bQcLNk2IP8/FcXTHIHJzajaQmyq4fLJg== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=uCUwDbWm0uJN3sDp7eVyxcRaovudcTeFgnibytCBZWY=; b=ClP3WoourTzWDCfU27i+/c+QZ+Tauds/sl03fTzGc0GRNmn6EVmtJXJYXK6319gFK3rpSnjrh8qKHsrngijP7G1kOKshNKEOzjYlQ4CpLGjZ9N7Nsh72n8INQ2ML4dW3/eEMnm96dGBlf/0sB9R0ZKuYn5AHm27SpTrd5tOvqttwghls77DiH5TAX9YPRzvvdHmQSAEL2KGKicgtm6vkjTYDmIMbZ2huhMUqZB8IISesfrIyC7TNcEzOO4lIkNhqgpmqEkpXBVp8QdR+QTu5+h6jPXHRpC7nuQAhVJ/008Kp8a9Dubk+qTQRMEm1L/1pY5aC1nyhkayLQGxTH571Qw== 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=uCUwDbWm0uJN3sDp7eVyxcRaovudcTeFgnibytCBZWY=; b=j0Z6EhK8uGRwrc0dwfVUH3jq0KgHTlg+bopH+V/hiSVybdMoX6JQT6ay7wmBVl1skn0Ysvh04LnAhNOANfThBgvGP4S8Jdw8irQazWKnbMC57FW2k0ie+j07qw6mkHz0zDOHFQzCADJXQbfcNBhX4aGnmJwaEqD7BNsu/GDeWi0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5674.namprd11.prod.outlook.com (2603:10b6:510:ec::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.11; Tue, 11 Jan 2022 17:15:09 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:09 +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 v9 09/24] wfx: add hwio.c/hwio.h Date: Tue, 11 Jan 2022 18:14:09 +0100 Message-Id: <20220111171424.862764-10-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 83c6cfb9-d3f0-41dc-4f13-08d9d525eba5 X-MS-TrafficTypeDiagnostic: PH0PR11MB5674:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:346; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: DKI2wnVvdBbovJTXxVFd9fpUPjocQyRfWQ36mX9gLp6EcX8XtK/d9cF1j/MxzwnneIEkp2rmPSTRzoc5grbGvkRJp239dfFKh/xwiOwY0CMRgRVNACNrop+J6xunKreNjpay+1JvyDRUNGH2UxRt4bt2GTj1fCCgOgK/3Z51Nc3onR0YIota62caOPNQZS0X1ojQ3UqiQuWvd7aZobDSBSsooKTDUlG2OzxvY5afvT5nwH9/GH1OojHJrrtkh0NuAF+ZRv4JWEb16Bahn0SNTQdCt8QFTT9BLyeVmNzAdQzJElF4q6hMk5ypYfIz7MmQRYHmiaYhk6TcNgKwFTLu7tlp3WuDSzhcSJgV+Dm3A6L16J5QJxa5rz0uJU69FqMCFCRMg0jzI8a/zp69dx2TF5ATpP+ycggZrQisK4Wm/4jnHHsAjFFc3QXSsxsIR30nXvG3BkTzah4kHnPtbGOntFSfre2ANOnPn68dyVSs0n8kc8bwC0+fneeN7WAuIzS1G6Akq7aovy+ptDQbFwZ/649AT5bgTijcWMJYLGeckynYCdVq3g4MBt7bfIGlmuC6rqjaiDHzubuRhlOWE6tGGHvr58tK1UN6pQivl8kTAzF/lHRjd4sTe4wKWWll3SojdkeWDgjoAZM29um7mX0A4A== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(6506007)(66946007)(66574015)(8936002)(107886003)(4326008)(66476007)(508600001)(36756003)(7416002)(8676002)(86362001)(6916009)(83380400001)(52116002)(316002)(6512007)(2906002)(30864003)(6486002)(1076003)(186003)(66556008)(54906003)(38100700002)(2616005)(5660300002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?N86vwnAtod1scwRHrH2+h2oRxXRT?= =?utf-8?q?ZUhhbRzMplOeiy09Yc6Zbx20FjKoczHSmn3eP0X5HC0lO2v2P1Lli+tab58zR0S8m?= =?utf-8?q?erIjP2vbtAnLujVUHTVFrz6aRRGOiM7A8QzC0OlqNM/euJ1aX0z/5zTHOUFFoni+Y?= =?utf-8?q?jmgmtCjUJA+CHp82v+zzYRTIHDFfy+eKqUm7f1z7qryA3QQi90KTZzIuY1QTRFcUU?= =?utf-8?q?26eAbTugCHc1Wimu0PA1WiWikYA5HlGaZqfH3GGtv/KHexAC2aHt/MijSFglCIzCL?= =?utf-8?q?rvrXV1K/ROlSOOOAh0tVW+1UGuOkoevGKAcYaUI4eGuzRkTWg0rx/G7BTEIk97LE4?= =?utf-8?q?nNBEqxg9DVaiitG00j413UCcE7R17vG/9Tfts3+J3wjhw+Vg1by8k1J3wvxZe4JmD?= =?utf-8?q?4rHAFLr2OGTDYGbAqgopEautVZvtlNFAJ3Yk2NlYwyMTvC3cHY1yfdawKX5PGFdZB?= =?utf-8?q?ZcKsauQQtemnaNUR9HozFnNB/jRHNgze9LsZ8V1d6ZjNtFl4hj7SrNGOheKRciA/r?= =?utf-8?q?xqZQThAMwAaJr5jZ+MiuFCSK4wL9gdr+T/WIyMuv+i/AM5fzn54o25wIOqOqTcQKA?= =?utf-8?q?XFafUAIVKt/ukuM0EIBrDKZIDFekrl6fBEjIijhfWrf8/6Z/R9mX5FW1TEbD1g6qg?= =?utf-8?q?KCTF+jPkmSSTGleieK1wx59n8814LohEJtUFbkl1zTZRC4CBsCh4qIY3KGoaNPz4P?= =?utf-8?q?OLzQ7h6p7YnednrwoJM3pcB6RoZs3ak9Xq8FWuUWfNG+Ue8DNuBRisRc2hdy4hs7h?= =?utf-8?q?G8Y/URBUfewlp9QRxGaBb+L50RQt3Do4ImbOYTjSYuCgjWk2o4byY0gL9eIS6WwYA?= =?utf-8?q?ZFdu7wLlVzt5zp3LhSN9XC16xNJGXOC3IHUlvkHw9gi31GOG2J34412fjyf1NkooZ?= =?utf-8?q?R3NcS1xO+WiUjMRu+E8vynpgOtZ+SpDQ9/L7S0gFLyK9aowovORbywmQ8FMplyXvo?= =?utf-8?q?PvOIkbqNdDGb+1DcZNj6pzponbEZ//p7OB9Xsh30LzSomuBAfqzGYGZWVZOvl/7Y4?= =?utf-8?q?IdKt5lnuoaMKe12h9l5N7ebrSlprT35l+hBYCP4LvAWrt8f549TJeuxey0JzVs1MJ?= =?utf-8?q?tnOvEIejPdZ7MrBLHM+zpJirRHYZPSNUd59jFhCIsAk8bD4mVeJS8aB8S8W8+2gtR?= =?utf-8?q?XNsezcB2jjraGYZ8EkpMS8J/kvtfs52FL2oM+CURGMjYXBYBgDdRBuY1K1W/qPiVP?= =?utf-8?q?MfpiCCt+MPUlGr44IekN3MBt5H4f0F/8y6EsbLnEEmZ66ik4CV1vnKm1cCgfJ7ai1?= =?utf-8?q?z7w7lbVe8Y95sLcVFydBoNbzso5e5PWn/yUYC6/IgE+KpfQmOIMNU4YBxiYjHFjOV?= =?utf-8?q?sp3+NRNRbMoyh6ScHQcWNl5TB16acbBKnex8VEHpeA4iRfbfZ4I2JE4j3/d+g/FrT?= =?utf-8?q?J1l2Say8ry3/ZeLZtF41P97HMLTSRtOQLtwIguMuwGgAQDAEEZfb9BCvtCGkb7MK3?= =?utf-8?q?3ucllKR3NY5QjpodfKEyWOoY3N2ZBuunnqL1Z6FZIOTM2VIFSQXadif0uaWAJirOf?= =?utf-8?q?4VLX4LMqW565bhVUjkdtwdd1z0nSsLqQ+7Wmw00JrA3ORuDMudV62cCKq4HH7SXvh?= =?utf-8?q?dlrXXvn0mHDEesFW3Gdow5yVp2sbb0z0cwdVTaVL40oxk83tmZsf+I=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 83c6cfb9-d3f0-41dc-4f13-08d9d525eba5 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:09.5652 (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: UZYxG3wmAbNOVaJ8kAt+XgfWWkugERnrVuJWEGq6XBUi8EuCHUOKCarHHGFzmUiEwxykX64JhDQk85fOIUvCFg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5674 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/hwio.c | 335 +++++++++++++++++++++++++ drivers/net/wireless/silabs/wfx/hwio.h | 78 ++++++ 2 files changed, 413 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..c15810bdaecb --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hwio.c @@ -0,0 +1,335 @@ +// 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 + +#include "hwio.h" +#include "wfx.h" +#include "bus.h" +#include "traces.h" + +#define WFX_HIF_BUFFER_SIZE 0x2000 + +static int wfx_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 wfx_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 wfx_read32_locked(struct wfx_dev *wdev, int reg, u32 *val) +{ + int ret; + + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = wfx_read32(wdev, reg, val); + _trace_io_read32(reg, *val); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + return ret; +} + +static int wfx_write32_locked(struct wfx_dev *wdev, int reg, u32 val) +{ + int ret; + + wdev->hwbus_ops->lock(wdev->hwbus_priv); + ret = wfx_write32(wdev, reg, val); + _trace_io_write32(reg, val); + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + return ret; +} + +static int wfx_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 = wfx_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 = wfx_write32(wdev, reg, val_w); + _trace_io_write32(reg, val_w); + } +err: + wdev->hwbus_ops->unlock(wdev->hwbus_priv); + return ret; +} + +static int wfx_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 >= WFX_HIF_BUFFER_SIZE); + 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 = wfx_write32(wdev, WFX_REG_BASE_ADDR, addr); + if (ret < 0) + goto err; + + ret = wfx_read32(wdev, WFX_REG_CONFIG, &cfg); + if (ret < 0) + goto err; + + ret = wfx_write32(wdev, WFX_REG_CONFIG, cfg | prefetch); + if (ret < 0) + goto err; + + for (i = 0; i < 20; i++) { + ret = wfx_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 wfx_indirect_write(struct wfx_dev *wdev, int reg, u32 addr, + const void *buf, size_t len) +{ + int ret; + + WARN_ON(len >= WFX_HIF_BUFFER_SIZE); + WARN_ON(reg != WFX_REG_AHB_DPORT && reg != WFX_REG_SRAM_DPORT); + ret = wfx_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 wfx_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 = wfx_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 wfx_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 = wfx_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 wfx_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 = wfx_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 wfx_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 = wfx_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(!IS_ALIGNED((uintptr_t)buf, 4), "unaligned buffer"); + 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(!IS_ALIGNED((uintptr_t)buf, 4), "unaligned buffer"); + 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 wfx_sram_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len) +{ + return wfx_indirect_read_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len); +} + +int wfx_ahb_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len) +{ + return wfx_indirect_read_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len); +} + +int wfx_sram_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len) +{ + return wfx_indirect_write_locked(wdev, WFX_REG_SRAM_DPORT, addr, buf, len); +} + +int wfx_ahb_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len) +{ + return wfx_indirect_write_locked(wdev, WFX_REG_AHB_DPORT, addr, buf, len); +} + +int wfx_sram_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val) +{ + return wfx_indirect_read32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val); +} + +int wfx_ahb_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val) +{ + return wfx_indirect_read32_locked(wdev, WFX_REG_AHB_DPORT, addr, val); +} + +int wfx_sram_reg_write(struct wfx_dev *wdev, u32 addr, u32 val) +{ + return wfx_indirect_write32_locked(wdev, WFX_REG_SRAM_DPORT, addr, val); +} + +int wfx_ahb_reg_write(struct wfx_dev *wdev, u32 addr, u32 val) +{ + return wfx_indirect_write32_locked(wdev, WFX_REG_AHB_DPORT, addr, val); +} + +int wfx_config_reg_read(struct wfx_dev *wdev, u32 *val) +{ + return wfx_read32_locked(wdev, WFX_REG_CONFIG, val); +} + +int wfx_config_reg_write(struct wfx_dev *wdev, u32 val) +{ + return wfx_write32_locked(wdev, WFX_REG_CONFIG, val); +} + +int wfx_config_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val) +{ + return wfx_write32_bits_locked(wdev, WFX_REG_CONFIG, mask, val); +} + +int wfx_control_reg_read(struct wfx_dev *wdev, u32 *val) +{ + return wfx_read32_locked(wdev, WFX_REG_CONTROL, val); +} + +int wfx_control_reg_write(struct wfx_dev *wdev, u32 val) +{ + return wfx_write32_locked(wdev, WFX_REG_CONTROL, val); +} + +int wfx_control_reg_write_bits(struct wfx_dev *wdev, u32 mask, u32 val) +{ + return wfx_write32_bits_locked(wdev, WFX_REG_CONTROL, mask, val); +} + +int wfx_igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val) +{ + int ret; + + *val = ~0; /* Never return undefined value */ + ret = wfx_write32_locked(wdev, WFX_REG_SET_GEN_R_W, IGPR_RW | index << 24); + if (ret) + return ret; + ret = wfx_read32_locked(wdev, WFX_REG_SET_GEN_R_W, val); + if (ret) + return ret; + *val &= IGPR_VALUE; + return ret; +} + +int wfx_igpr_reg_write(struct wfx_dev *wdev, int index, u32 val) +{ + return wfx_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..c6e7b065b7ff --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hwio.h @@ -0,0 +1,78 @@ +/* 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 wfx_sram_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len); +int wfx_sram_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len); + +int wfx_ahb_buf_read(struct wfx_dev *wdev, u32 addr, void *buf, size_t len); +int wfx_ahb_buf_write(struct wfx_dev *wdev, u32 addr, const void *buf, size_t len); + +int wfx_sram_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val); +int wfx_sram_reg_write(struct wfx_dev *wdev, u32 addr, u32 val); + +int wfx_ahb_reg_read(struct wfx_dev *wdev, u32 addr, u32 *val); +int wfx_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 wfx_config_reg_read(struct wfx_dev *wdev, u32 *val); +int wfx_config_reg_write(struct wfx_dev *wdev, u32 val); +int wfx_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 wfx_control_reg_read(struct wfx_dev *wdev, u32 *val); +int wfx_control_reg_write(struct wfx_dev *wdev, u32 val); +int wfx_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 wfx_igpr_reg_read(struct wfx_dev *wdev, int index, u32 *val); +int wfx_igpr_reg_write(struct wfx_dev *wdev, int index, u32 val); + +#endif From patchwork Tue Jan 11 17:14:12 2022 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: 531341 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5B24C433FE for ; Tue, 11 Jan 2022 17:15:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343927AbiAKRPw (ORCPT ); Tue, 11 Jan 2022 12:15:52 -0500 Received: from mail-bn7nam10on2045.outbound.protection.outlook.com ([40.107.92.45]:52705 "EHLO NAM10-BN7-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1343972AbiAKRPV (ORCPT ); Tue, 11 Jan 2022 12:15:21 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fC5qCV5PvQXWGd1VvbKnwg5r5WZ7uygiOJNeiyqTekxGzOunQZhYwPjpMKTJWXnUqvScJGA4+HwpY+DQotcgKZyILsHjvb/Rhb52ynOwFVQpK+3G1rfCuFVH2w23YgOQ/CK6O7uOCQsOhUAsbzENZh3E2H3sUf+wfNY8UX0sCimK4kLb76QYfEeQk15W1GzVuo25OwhPSW1oAPpQfy+WWC/oEuJMB7/O7DlGW4WOrYP1E9ScBgFqFMs4j5MKOOJi1btmsUMgWqWmc2bRqCjlJl8fGqI7fX5rbcle9AQUwziK/9oc5txNnPqBOmfzX2H/ivaBgD2oeWk8790IsFAHdg== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gC9GYQDxdi4bXZKRAyyUTxZd0l0aCe4Tr1cUcVpV+C8=; b=WI0kB5fRI2d0SKA6WioKIykmmXx0SFcPvZAhyPkh+YOQQ7TtJZVaeVtYm/DnTmffY1tIA2OcxGIPeSGq4rEweWBHTs69OnqG03ijiINXnga3C0HbtwZFZS6J7EoCLXmrLxDJ3qpfHd0K8kkpVSSMBiRdKZSl2DpS3VvEMasxkRZRozkGmPv7aKalgovh+AigcIfqnILRQStiFBFFR191LNdewxcajPaa8DXbZhpev9EAJ7CPJwseCLM3lXwBetEqOazVzZrPFbiVa96LQ3zQNNbb0e4nqNVIi+o2dwlxR/012p9TzCeDcJyv2tOAGKEOrHhKosmr6gln1IQnmV5JDA== 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=gC9GYQDxdi4bXZKRAyyUTxZd0l0aCe4Tr1cUcVpV+C8=; b=AErj7HkccXxPoJZz/lmMjhhpLQFeN8vM2LYvr7QekgwF1kbpoyQpt8Fx270wUHRVum1xlSygek2qpqMXUsiInT/SP1+SLqYYBwrtNchi1DziKp+0nxBzxRo1O4oszLuQcjJT6SN+dTArMlyV0xn8iHb+/HaNawvgLc5/7BrasyE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5609.namprd11.prod.outlook.com (2603:10b6:510:e0::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.9; Tue, 11 Jan 2022 17:15:17 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:17 +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 v9 12/24] wfx: add hif_api_*.h Date: Tue, 11 Jan 2022 18:14:12 +0100 Message-Id: <20220111171424.862764-13-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 8bc04e81-4870-4764-5c3b-08d9d525f044 X-MS-TrafficTypeDiagnostic: PH0PR11MB5609:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:68; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: x+2tkhJGU7jwD0UWANbp3qkiQUfCMC65jGSoRQPTByQmHfBYE0vM5qvT6E6Odd3mzl3GBRRsf+9SCZB42f65Bs0f3gvWAx8jeocwATJo0NU7Vu3EBHtFRHpvER2Q+OjodGkXYJBn5dtPzpjw2tbfvtmK8IurTX3UCk5+VGHDOG/bJEIOJ0syjgMf9TD550JcngtfoANIebRrZetjFhtbKJBIWYh9edLcTWW67v7bxDZkZrK/gkbhH0rN0H46Pxj6PztK+HPfgPyUoe42j2SzgwGQ+KuOK+rqz68bQZDAjEOHBW4Klw/qiW4S/tQx30QddpzeQgMICwklowVF9xwv3kzwKLn34ORs2Aewwx28Qz1l5ZLFzdwai1BilfxULWo7gGRzjSosUAXzElu5AKv6Yr+36CTA3KUKnmh/IdoviVnm9mh6ReKxJsYrdsPRgMF/j76wd6Vr3QnuhK7o1uoOYKfub7c5/FdvHTaP1zU0fi98rdPow0b8RrJFMCRvIXKYWvr53EI4b5QBXT9v/E6y8CXl088fSvCeK6e/0U/8cZXBFux9M/PTMPGTJB2dH/B7Dl1nfw6Z54jCquzZAXsjHQnytrsajFhjp+1ryrMPusEj9A4GO0ex6kAA27DN1+xvHAF0ES/L/+cVW5l7uEZXVA== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(5660300002)(8676002)(36756003)(38100700002)(186003)(7416002)(66476007)(54906003)(6486002)(6916009)(6512007)(4326008)(508600001)(107886003)(66946007)(6666004)(2616005)(1076003)(8936002)(66556008)(86362001)(2906002)(6506007)(52116002)(66574015)(316002)(83380400001)(30864003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?3POfE5sndKZJWTP1Phun5aSLmtiS?= =?utf-8?q?q9Ai0/OeqDkpYxmstD2r5c315stUx/zgbcpIjgYcP9Tn9tlVNrmCx2LTLctjpklpA?= =?utf-8?q?2e+p7nV8wQ/padIgZctSE0SlNVTNaJjCNCQvlUJfKnyibdcq6AjqR6pnN0pZLnaZV?= =?utf-8?q?l1hAQZfxHOUAy0wmyfrlN9Fa44wlIM0t22gM4zXPMYkJ+LmTFiCncZ2jfVjCnFTZ6?= =?utf-8?q?Ll8W9z36Pv9G9guw8DizKWD3mo+1/yQH76IjDg129hAU3ziURzhCdw20/efdPG8Fi?= =?utf-8?q?8QEkaYJFCsdyNWiavEphzW4LJcKtYKXdEkzR53l8L9CwmE9T7atPIuIQyCrq6VT3j?= =?utf-8?q?nSNFt+AS5OJuTjgpvmKRs9ku00EJU9LJuB0zFW2N9IMLgK5UMET2LIxVRupYCamT2?= =?utf-8?q?xnk85KU3e22g3PMjVoiTIdZt4T70D8WCQdgL3W8MCqJhTlSs4BBOdQjyyFMCfxLal?= =?utf-8?q?xD51D/wrPNQzUTquxkK+pf6p7SgJS9vSJSNqHO1UQgd6h/LfVPZe6E/xcDfwYUx5u?= =?utf-8?q?1TcWPwsFgam1ena/ICrqM2ktpmJFnhSKf3nzEHMNV5dhrS76QkG/g8dZbRnd92pC+?= =?utf-8?q?pXp80JqjEbYh6LESOwB/YLgYAJtHtb8Q3I7t80eewA0zijejFeMWE7Pkvr8SLEvYI?= =?utf-8?q?3+cxzYthxQP1AUC689Oe4BYkIZMA8KP3v6UcdBcQkzSXCTqptLZmMUUkn1Sp9s8Db?= =?utf-8?q?6vGsLxBFPtMCYVeHoLkdv/kmJqG/BgWV5gQXwhD79j16HAHi6rdvOUepCwNdkt88C?= =?utf-8?q?p2Pu2IXo8G+Vuw8jcQdfvYUEBkS9xZbjsz9d5JSa13iToSfoajGSHUplIfZq3E6oQ?= =?utf-8?q?qONM+po2lDNr4XOUz2LvU727lsiDY6yeaVIy0MPy3CFhVXDnqzzoongGdk1xg7OSh?= =?utf-8?q?kE9VgC3OQVQzMw/JdN0JHOtI9zuohknJNaOAgibbnm3QqK5SqhS3+1mZ7tQ/CMBE2?= =?utf-8?q?767PenPugV5KxnQjhvN38EQP0d+VpLEaKYU+PltRO3KuiCazLH8drSuPCW+KRZlkO?= =?utf-8?q?SAg+nTPNUSRdl90QdWgoaQrQ2GdrYeMRG1LqljnGAkHtCT3VpWx+ECPg3c5+VJQR3?= =?utf-8?q?UHiFwx5pVKUK818DZUScpCQ4yl3MdjpfRcD0Djq6kmsAtFrrG3MTss7iPpu960AV3?= =?utf-8?q?qCw5qz0F1xHOY4LGMHBPy83ueK5aZptt+T/CmZ/q09SRLYA2AasqEw6sY/exeR6d1?= =?utf-8?q?wBV9clhg4o34COKJJwSR6J6DgY+AyuFBffZHa1WvKXaF5AZ0yDGILlhEdeI25bSXe?= =?utf-8?q?Kbp7QqEbN6Zo+CcKRwbrIZINMlQR1t6HskBUFsndcodrHyqkE9g4VT6WFnUxBjGXK?= =?utf-8?q?1do3ia3nelocjZrAnwk6XYkSnu3PUX9ZRNRW/63kzTmnVTYpkBbA3ww/TsJl41+Le?= =?utf-8?q?/3uPLTaYkcdRQkvKk8sWwCgy9RWb4snnRj9kFr5Pn/xBCs5NbGg9xs8RxjjU9Mgk9?= =?utf-8?q?xzfKo+esROr3+rPv/+KfvzJtlm61hKIEgCyMa3EWuZV4qIJIvYf6nLKCRBivubm8R?= =?utf-8?q?JLVGFoP55sxzK4KTfNGbudhsK4di1f5c2qqHXYydRNzQxXkpXmWUBtlnzo556TVUC?= =?utf-8?q?frSrD7ur4PdqKrbRo/HPu2nuAGJiRIqIK6kVxp+bxCxFMUssTUPCUI=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 8bc04e81-4870-4764-5c3b-08d9d525f044 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:17.5528 (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: p6h37hs6RNlLhlPkNztIiQcyHw9/c/8aFwDeFs/Pi/tqLSf1dhnFEupEOrcWELMT4i5FvOC6E4clDqt0nqCqww== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5609 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/hif_api_cmd.h | 554 ++++++++++++++++++ .../net/wireless/silabs/wfx/hif_api_general.h | 252 ++++++++ drivers/net/wireless/silabs/wfx/hif_api_mib.h | 346 +++++++++++ 3 files changed, 1152 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/hif_api_cmd.h create mode 100644 drivers/net/wireless/silabs/wfx/hif_api_general.h create mode 100644 drivers/net/wireless/silabs/wfx/hif_api_mib.h diff --git a/drivers/net/wireless/silabs/wfx/hif_api_cmd.h b/drivers/net/wireless/silabs/wfx/hif_api_cmd.h new file mode 100644 index 000000000000..ef10600d472c --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hif_api_cmd.h @@ -0,0 +1,554 @@ +/* SPDX-License-Identifier: GPL-2.0-only or Apache-2.0 */ +/* + * WF200 hardware interface definitions + * + * Copyright (c) 2018-2020, Silicon Laboratories Inc. + */ + +#ifndef WFX_HIF_API_CMD_H +#define WFX_HIF_API_CMD_H + +#include + +#include "hif_api_general.h" + +enum wfx_hif_requests_ids { + HIF_REQ_ID_RESET = 0x0a, + HIF_REQ_ID_READ_MIB = 0x05, + HIF_REQ_ID_WRITE_MIB = 0x06, + HIF_REQ_ID_START_SCAN = 0x07, + HIF_REQ_ID_STOP_SCAN = 0x08, + HIF_REQ_ID_TX = 0x04, + HIF_REQ_ID_JOIN = 0x0b, + HIF_REQ_ID_SET_PM_MODE = 0x10, + HIF_REQ_ID_SET_BSS_PARAMS = 0x11, + HIF_REQ_ID_ADD_KEY = 0x0c, + HIF_REQ_ID_REMOVE_KEY = 0x0d, + HIF_REQ_ID_EDCA_QUEUE_PARAMS = 0x13, + HIF_REQ_ID_START = 0x17, + HIF_REQ_ID_BEACON_TRANSMIT = 0x18, + HIF_REQ_ID_UPDATE_IE = 0x1b, + HIF_REQ_ID_MAP_LINK = 0x1c, +}; + +enum wfx_hif_confirmations_ids { + HIF_CNF_ID_RESET = 0x0a, + HIF_CNF_ID_READ_MIB = 0x05, + HIF_CNF_ID_WRITE_MIB = 0x06, + HIF_CNF_ID_START_SCAN = 0x07, + HIF_CNF_ID_STOP_SCAN = 0x08, + HIF_CNF_ID_TX = 0x04, + HIF_CNF_ID_MULTI_TRANSMIT = 0x1e, + HIF_CNF_ID_JOIN = 0x0b, + HIF_CNF_ID_SET_PM_MODE = 0x10, + HIF_CNF_ID_SET_BSS_PARAMS = 0x11, + HIF_CNF_ID_ADD_KEY = 0x0c, + HIF_CNF_ID_REMOVE_KEY = 0x0d, + HIF_CNF_ID_EDCA_QUEUE_PARAMS = 0x13, + HIF_CNF_ID_START = 0x17, + HIF_CNF_ID_BEACON_TRANSMIT = 0x18, + HIF_CNF_ID_UPDATE_IE = 0x1b, + HIF_CNF_ID_MAP_LINK = 0x1c, +}; + +enum wfx_hif_indications_ids { + HIF_IND_ID_RX = 0x84, + HIF_IND_ID_SCAN_CMPL = 0x86, + HIF_IND_ID_JOIN_COMPLETE = 0x8f, + HIF_IND_ID_SET_PM_MODE_CMPL = 0x89, + HIF_IND_ID_SUSPEND_RESUME_TX = 0x8c, + HIF_IND_ID_EVENT = 0x85 +}; + +struct wfx_hif_req_reset { + u8 reset_stat:1; + u8 reset_all_int:1; + u8 reserved1:6; + u8 reserved2[3]; +} __packed; + +struct wfx_hif_cnf_reset { + __le32 status; +} __packed; + +struct wfx_hif_req_read_mib { + __le16 mib_id; + __le16 reserved; +} __packed; + +struct wfx_hif_cnf_read_mib { + __le32 status; + __le16 mib_id; + __le16 length; + u8 mib_data[]; +} __packed; + +struct wfx_hif_req_write_mib { + __le16 mib_id; + __le16 length; + u8 mib_data[]; +} __packed; + +struct wfx_hif_cnf_write_mib { + __le32 status; +} __packed; + +struct wfx_hif_req_update_ie { + u8 beacon:1; + u8 probe_resp:1; + u8 probe_req:1; + u8 reserved1:5; + u8 reserved2; + __le16 num_ies; + u8 ie[]; +} __packed; + +struct wfx_hif_cnf_update_ie { + __le32 status; +} __packed; + +struct wfx_hif_ssid_def { + __le32 ssid_length; + u8 ssid[IEEE80211_MAX_SSID_LEN]; +} __packed; + +#define HIF_API_MAX_NB_SSIDS 2 +#define HIF_API_MAX_NB_CHANNELS 14 + +struct wfx_hif_req_start_scan_alt { + u8 band; + u8 maintain_current_bss:1; + u8 periodic:1; + u8 reserved1:6; + u8 disallow_ps:1; + u8 reserved2:1; + u8 short_preamble:1; + u8 reserved3:5; + u8 max_transmit_rate; + __le16 periodic_interval; + u8 reserved4; + s8 periodic_rssi_thr; + u8 num_of_probe_requests; + u8 probe_delay; + u8 num_of_ssids; + u8 num_of_channels; + __le32 min_channel_time; + __le32 max_channel_time; + __le32 tx_power_level; /* signed value */ + struct wfx_hif_ssid_def ssid_def[HIF_API_MAX_NB_SSIDS]; + u8 channel_list[]; +} __packed; + +struct wfx_hif_cnf_start_scan { + __le32 status; +} __packed; + +struct wfx_hif_cnf_stop_scan { + __le32 status; +} __packed; + +enum wfx_hif_pm_mode_status { + HIF_PM_MODE_ACTIVE = 0x0, + HIF_PM_MODE_PS = 0x1, + HIF_PM_MODE_UNDETERMINED = 0x2 +}; + +struct wfx_hif_ind_scan_cmpl { + __le32 status; + u8 pm_mode; + u8 num_channels_completed; + __le16 reserved; +} __packed; + +enum wfx_hif_queue_id { + HIF_QUEUE_ID_BACKGROUND = 0x0, + HIF_QUEUE_ID_BESTEFFORT = 0x1, + HIF_QUEUE_ID_VIDEO = 0x2, + HIF_QUEUE_ID_VOICE = 0x3 +}; + +enum wfx_hif_frame_format { + HIF_FRAME_FORMAT_NON_HT = 0x0, + HIF_FRAME_FORMAT_MIXED_FORMAT_HT = 0x1, + HIF_FRAME_FORMAT_GF_HT_11N = 0x2 +}; + +struct wfx_hif_req_tx { + /* packet_id is not interpreted by the device, so it is not necessary to declare it little + * endian + */ + u32 packet_id; + u8 max_tx_rate; + u8 queue_id:2; + u8 peer_sta_id:4; + u8 reserved1:2; + u8 more:1; + u8 fc_offset:3; + u8 after_dtim:1; + u8 reserved2:3; + u8 start_exp:1; + u8 reserved3:3; + u8 retry_policy_index:4; + __le32 reserved4; + __le32 expire_time; + u8 frame_format:4; + u8 fec_coding:1; + u8 short_gi:1; + u8 reserved5:1; + u8 stbc:1; + u8 reserved6; + u8 aggregation:1; + u8 reserved7:7; + u8 reserved8; + u8 frame[]; +} __packed; + +enum wfx_hif_qos_ackplcy { + HIF_QOS_ACKPLCY_NORMAL = 0x0, + HIF_QOS_ACKPLCY_TXNOACK = 0x1, + HIF_QOS_ACKPLCY_NOEXPACK = 0x2, + HIF_QOS_ACKPLCY_BLCKACK = 0x3 +}; + +struct wfx_hif_cnf_tx { + __le32 status; + /* packet_id is copied from struct wfx_hif_req_tx without been interpreted by the device, so + * it is not necessary to declare it little endian + */ + u32 packet_id; + u8 txed_rate; + u8 ack_failures; + u8 aggr:1; + u8 requeue:1; + u8 ack_policy:2; + u8 txop_limit:1; + u8 reserved1:3; + u8 reserved2; + __le32 media_delay; + __le32 tx_queue_delay; +} __packed; + +struct wfx_hif_cnf_multi_transmit { + u8 num_tx_confs; + u8 reserved[3]; + struct wfx_hif_cnf_tx tx_conf_payload[]; +} __packed; + +enum wfx_hif_ri_flags_encrypt { + HIF_RI_FLAGS_UNENCRYPTED = 0x0, + HIF_RI_FLAGS_WEP_ENCRYPTED = 0x1, + HIF_RI_FLAGS_TKIP_ENCRYPTED = 0x2, + HIF_RI_FLAGS_AES_ENCRYPTED = 0x3, + HIF_RI_FLAGS_WAPI_ENCRYPTED = 0x4 +}; + +struct wfx_hif_ind_rx { + __le32 status; + u8 channel_number; + u8 reserved1; + u8 rxed_rate; + u8 rcpi_rssi; + u8 encryp:3; + u8 in_aggr:1; + u8 first_aggr:1; + u8 last_aggr:1; + u8 defrag:1; + u8 beacon:1; + u8 tim:1; + u8 bitmap:1; + u8 match_ssid:1; + u8 match_bssid:1; + u8 more:1; + u8 reserved2:1; + u8 ht:1; + u8 stbc:1; + u8 match_uc_addr:1; + u8 match_mc_addr:1; + u8 match_bc_addr:1; + u8 key_type:1; + u8 key_index:4; + u8 reserved3:1; + u8 peer_sta_id:4; + u8 reserved4:2; + u8 reserved5:1; + u8 frame[]; +} __packed; + +struct wfx_hif_req_edca_queue_params { + u8 queue_id; + u8 reserved1; + u8 aifsn; + u8 reserved2; + __le16 cw_min; + __le16 cw_max; + __le16 tx_op_limit; + __le16 allowed_medium_time; + __le32 reserved3; +} __packed; + +struct wfx_hif_cnf_edca_queue_params { + __le32 status; +} __packed; + +struct wfx_hif_req_join { + u8 infrastructure_bss_mode:1; + u8 reserved1:7; + u8 band; + u8 channel_number; + u8 reserved2; + u8 bssid[ETH_ALEN]; + __le16 atim_window; + u8 short_preamble:1; + u8 reserved3:7; + u8 probe_for_join; + u8 reserved4; + u8 reserved5:2; + u8 force_no_beacon:1; + u8 force_with_ind:1; + u8 reserved6:4; + __le32 ssid_length; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + __le32 beacon_interval; + __le32 basic_rate_set; +} __packed; + +struct wfx_hif_cnf_join { + __le32 status; +} __packed; + +struct wfx_hif_ind_join_complete { + __le32 status; +} __packed; + +struct wfx_hif_req_set_bss_params { + u8 lost_count_only:1; + u8 reserved:7; + u8 beacon_lost_count; + __le16 aid; + __le32 operational_rate_set; +} __packed; + +struct wfx_hif_cnf_set_bss_params { + __le32 status; +} __packed; + +struct wfx_hif_req_set_pm_mode { + u8 enter_psm:1; + u8 reserved:6; + u8 fast_psm:1; + u8 fast_psm_idle_period; + u8 ap_psm_change_period; + u8 min_auto_ps_poll_period; +} __packed; + +struct wfx_hif_cnf_set_pm_mode { + __le32 status; +} __packed; + +struct wfx_hif_ind_set_pm_mode_cmpl { + __le32 status; + u8 pm_mode; + u8 reserved[3]; +} __packed; + +struct wfx_hif_req_start { + u8 mode; + u8 band; + u8 channel_number; + u8 reserved1; + __le32 reserved2; + __le32 beacon_interval; + u8 dtim_period; + u8 short_preamble:1; + u8 reserved3:7; + u8 reserved4; + u8 ssid_length; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + __le32 basic_rate_set; +} __packed; + +struct wfx_hif_cnf_start { + __le32 status; +} __packed; + +struct wfx_hif_req_beacon_transmit { + u8 enable_beaconing; + u8 reserved[3]; +} __packed; + +struct wfx_hif_cnf_beacon_transmit { + __le32 status; +} __packed; + +#define HIF_LINK_ID_MAX 14 +#define HIF_LINK_ID_NOT_ASSOCIATED (HIF_LINK_ID_MAX + 1) + +struct wfx_hif_req_map_link { + u8 mac_addr[ETH_ALEN]; + u8 unmap:1; + u8 mfpc:1; + u8 reserved:6; + u8 peer_sta_id; +} __packed; + +struct wfx_hif_cnf_map_link { + __le32 status; +} __packed; + +struct wfx_hif_ind_suspend_resume_tx { + u8 resume:1; + u8 reserved1:2; + u8 bc_mc_only:1; + u8 reserved2:4; + u8 reserved3; + __le16 peer_sta_set; +} __packed; + +#define MAX_KEY_ENTRIES 24 +#define HIF_API_WEP_KEY_DATA_SIZE 16 +#define HIF_API_TKIP_KEY_DATA_SIZE 16 +#define HIF_API_RX_MIC_KEY_SIZE 8 +#define HIF_API_TX_MIC_KEY_SIZE 8 +#define HIF_API_AES_KEY_DATA_SIZE 16 +#define HIF_API_WAPI_KEY_DATA_SIZE 16 +#define HIF_API_MIC_KEY_DATA_SIZE 16 +#define HIF_API_IGTK_KEY_DATA_SIZE 16 +#define HIF_API_RX_SEQUENCE_COUNTER_SIZE 8 +#define HIF_API_IPN_SIZE 8 + +enum wfx_hif_key_type { + HIF_KEY_TYPE_WEP_DEFAULT = 0x0, + HIF_KEY_TYPE_WEP_PAIRWISE = 0x1, + HIF_KEY_TYPE_TKIP_GROUP = 0x2, + HIF_KEY_TYPE_TKIP_PAIRWISE = 0x3, + HIF_KEY_TYPE_AES_GROUP = 0x4, + HIF_KEY_TYPE_AES_PAIRWISE = 0x5, + HIF_KEY_TYPE_WAPI_GROUP = 0x6, + HIF_KEY_TYPE_WAPI_PAIRWISE = 0x7, + HIF_KEY_TYPE_IGTK_GROUP = 0x8, + HIF_KEY_TYPE_NONE = 0x9 +}; + +struct wfx_hif_wep_pairwise_key { + u8 peer_address[ETH_ALEN]; + u8 reserved; + u8 key_length; + u8 key_data[HIF_API_WEP_KEY_DATA_SIZE]; +} __packed; + +struct wfx_hif_wep_group_key { + u8 key_id; + u8 key_length; + u8 reserved[2]; + u8 key_data[HIF_API_WEP_KEY_DATA_SIZE]; +} __packed; + +struct wfx_hif_tkip_pairwise_key { + u8 peer_address[ETH_ALEN]; + u8 reserved[2]; + u8 tkip_key_data[HIF_API_TKIP_KEY_DATA_SIZE]; + u8 rx_mic_key[HIF_API_RX_MIC_KEY_SIZE]; + u8 tx_mic_key[HIF_API_TX_MIC_KEY_SIZE]; +} __packed; + +struct wfx_hif_tkip_group_key { + u8 tkip_key_data[HIF_API_TKIP_KEY_DATA_SIZE]; + u8 rx_mic_key[HIF_API_RX_MIC_KEY_SIZE]; + u8 key_id; + u8 reserved[3]; + u8 rx_sequence_counter[HIF_API_RX_SEQUENCE_COUNTER_SIZE]; +} __packed; + +struct wfx_hif_aes_pairwise_key { + u8 peer_address[ETH_ALEN]; + u8 reserved[2]; + u8 aes_key_data[HIF_API_AES_KEY_DATA_SIZE]; +} __packed; + +struct wfx_hif_aes_group_key { + u8 aes_key_data[HIF_API_AES_KEY_DATA_SIZE]; + u8 key_id; + u8 reserved[3]; + u8 rx_sequence_counter[HIF_API_RX_SEQUENCE_COUNTER_SIZE]; +} __packed; + +struct wfx_hif_wapi_pairwise_key { + u8 peer_address[ETH_ALEN]; + u8 key_id; + u8 reserved; + u8 wapi_key_data[HIF_API_WAPI_KEY_DATA_SIZE]; + u8 mic_key_data[HIF_API_MIC_KEY_DATA_SIZE]; +} __packed; + +struct wfx_hif_wapi_group_key { + u8 wapi_key_data[HIF_API_WAPI_KEY_DATA_SIZE]; + u8 mic_key_data[HIF_API_MIC_KEY_DATA_SIZE]; + u8 key_id; + u8 reserved[3]; +} __packed; + +struct wfx_hif_igtk_group_key { + u8 igtk_key_data[HIF_API_IGTK_KEY_DATA_SIZE]; + u8 key_id; + u8 reserved[3]; + u8 ipn[HIF_API_IPN_SIZE]; +} __packed; + +struct wfx_hif_req_add_key { + u8 type; + u8 entry_index; + u8 int_id:2; + u8 reserved1:6; + u8 reserved2; + union { + struct wfx_hif_wep_pairwise_key wep_pairwise_key; + struct wfx_hif_wep_group_key wep_group_key; + struct wfx_hif_tkip_pairwise_key tkip_pairwise_key; + struct wfx_hif_tkip_group_key tkip_group_key; + struct wfx_hif_aes_pairwise_key aes_pairwise_key; + struct wfx_hif_aes_group_key aes_group_key; + struct wfx_hif_wapi_pairwise_key wapi_pairwise_key; + struct wfx_hif_wapi_group_key wapi_group_key; + struct wfx_hif_igtk_group_key igtk_group_key; + } key; +} __packed; + +struct wfx_hif_cnf_add_key { + __le32 status; +} __packed; + +struct wfx_hif_req_remove_key { + u8 entry_index; + u8 reserved[3]; +} __packed; + +struct wfx_hif_cnf_remove_key { + __le32 status; +} __packed; + +enum wfx_hif_event_ind { + HIF_EVENT_IND_BSSLOST = 0x1, + HIF_EVENT_IND_BSSREGAINED = 0x2, + HIF_EVENT_IND_RCPI_RSSI = 0x3, + HIF_EVENT_IND_PS_MODE_ERROR = 0x4, + HIF_EVENT_IND_INACTIVITY = 0x5 +}; + +enum wfx_hif_ps_mode_error { + HIF_PS_ERROR_NO_ERROR = 0, + HIF_PS_ERROR_AP_NOT_RESP_TO_POLL = 1, + HIF_PS_ERROR_AP_NOT_RESP_TO_UAPSD_TRIGGER = 2, + HIF_PS_ERROR_AP_SENT_UNICAST_IN_DOZE = 3, + HIF_PS_ERROR_AP_NO_DATA_AFTER_TIM = 4 +}; + +struct wfx_hif_ind_event { + __le32 event_id; + union { + u8 rcpi_rssi; + __le32 ps_mode_error; + __le32 peer_sta_set; + } event_data; +} __packed; + +#endif diff --git a/drivers/net/wireless/silabs/wfx/hif_api_general.h b/drivers/net/wireless/silabs/wfx/hif_api_general.h new file mode 100644 index 000000000000..4d400fdc2252 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hif_api_general.h @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-2.0-only or Apache-2.0 */ +/* + * WF200 hardware interface definitions + * + * Copyright (c) 2018-2020, Silicon Laboratories Inc. + */ + +#ifndef WFX_HIF_API_GENERAL_H +#define WFX_HIF_API_GENERAL_H + +#include +#include + +#define HIF_ID_IS_INDICATION 0x80 +#define HIF_COUNTER_MAX 7 + +struct wfx_hif_msg { + __le16 len; + u8 id; + u8 reserved:1; + u8 interface:2; + u8 seqnum:3; + u8 encrypted:2; + u8 body[]; +} __packed; + +enum wfx_hif_general_requests_ids { + HIF_REQ_ID_CONFIGURATION = 0x09, + HIF_REQ_ID_CONTROL_GPIO = 0x26, + HIF_REQ_ID_SET_SL_MAC_KEY = 0x27, + HIF_REQ_ID_SL_EXCHANGE_PUB_KEYS = 0x28, + HIF_REQ_ID_SL_CONFIGURE = 0x29, + HIF_REQ_ID_PREVENT_ROLLBACK = 0x2a, + HIF_REQ_ID_PTA_SETTINGS = 0x2b, + HIF_REQ_ID_PTA_PRIORITY = 0x2c, + HIF_REQ_ID_PTA_STATE = 0x2d, + HIF_REQ_ID_SHUT_DOWN = 0x32, +}; + +enum wfx_hif_general_confirmations_ids { + HIF_CNF_ID_CONFIGURATION = 0x09, + HIF_CNF_ID_CONTROL_GPIO = 0x26, + HIF_CNF_ID_SET_SL_MAC_KEY = 0x27, + HIF_CNF_ID_SL_EXCHANGE_PUB_KEYS = 0x28, + HIF_CNF_ID_SL_CONFIGURE = 0x29, + HIF_CNF_ID_PREVENT_ROLLBACK = 0x2a, + HIF_CNF_ID_PTA_SETTINGS = 0x2b, + HIF_CNF_ID_PTA_PRIORITY = 0x2c, + HIF_CNF_ID_PTA_STATE = 0x2d, + HIF_CNF_ID_SHUT_DOWN = 0x32, +}; + +enum wfx_hif_general_indications_ids { + HIF_IND_ID_EXCEPTION = 0xe0, + HIF_IND_ID_STARTUP = 0xe1, + HIF_IND_ID_WAKEUP = 0xe2, + HIF_IND_ID_GENERIC = 0xe3, + HIF_IND_ID_ERROR = 0xe4, + HIF_IND_ID_SL_EXCHANGE_PUB_KEYS = 0xe5 +}; + +#define HIF_STATUS_SUCCESS (cpu_to_le32(0x0000)) +#define HIF_STATUS_FAIL (cpu_to_le32(0x0001)) +#define HIF_STATUS_INVALID_PARAMETER (cpu_to_le32(0x0002)) +#define HIF_STATUS_WARNING (cpu_to_le32(0x0003)) +#define HIF_STATUS_UNKNOWN_REQUEST (cpu_to_le32(0x0004)) +#define HIF_STATUS_RX_FAIL_DECRYPT (cpu_to_le32(0x0010)) +#define HIF_STATUS_RX_FAIL_MIC (cpu_to_le32(0x0011)) +#define HIF_STATUS_RX_FAIL_NO_KEY (cpu_to_le32(0x0012)) +#define HIF_STATUS_TX_FAIL_RETRIES (cpu_to_le32(0x0013)) +#define HIF_STATUS_TX_FAIL_TIMEOUT (cpu_to_le32(0x0014)) +#define HIF_STATUS_TX_FAIL_REQUEUE (cpu_to_le32(0x0015)) +#define HIF_STATUS_REFUSED (cpu_to_le32(0x0016)) +#define HIF_STATUS_BUSY (cpu_to_le32(0x0017)) +#define HIF_STATUS_SLK_SET_KEY_SUCCESS (cpu_to_le32(0x005A)) +#define HIF_STATUS_SLK_SET_KEY_ALREADY_BURNED (cpu_to_le32(0x006B)) +#define HIF_STATUS_SLK_SET_KEY_DISALLOWED_MODE (cpu_to_le32(0x007C)) +#define HIF_STATUS_SLK_SET_KEY_UNKNOWN_MODE (cpu_to_le32(0x008D)) +#define HIF_STATUS_SLK_NEGO_SUCCESS (cpu_to_le32(0x009E)) +#define HIF_STATUS_SLK_NEGO_FAILED (cpu_to_le32(0x00AF)) +#define HIF_STATUS_ROLLBACK_SUCCESS (cpu_to_le32(0x1234)) +#define HIF_STATUS_ROLLBACK_FAIL (cpu_to_le32(0x1256)) + +enum wfx_hif_api_rate_index { + API_RATE_INDEX_B_1MBPS = 0, + API_RATE_INDEX_B_2MBPS = 1, + API_RATE_INDEX_B_5P5MBPS = 2, + API_RATE_INDEX_B_11MBPS = 3, + API_RATE_INDEX_PBCC_22MBPS = 4, + API_RATE_INDEX_PBCC_33MBPS = 5, + API_RATE_INDEX_G_6MBPS = 6, + API_RATE_INDEX_G_9MBPS = 7, + API_RATE_INDEX_G_12MBPS = 8, + API_RATE_INDEX_G_18MBPS = 9, + API_RATE_INDEX_G_24MBPS = 10, + API_RATE_INDEX_G_36MBPS = 11, + API_RATE_INDEX_G_48MBPS = 12, + API_RATE_INDEX_G_54MBPS = 13, + API_RATE_INDEX_N_6P5MBPS = 14, + API_RATE_INDEX_N_13MBPS = 15, + API_RATE_INDEX_N_19P5MBPS = 16, + API_RATE_INDEX_N_26MBPS = 17, + API_RATE_INDEX_N_39MBPS = 18, + API_RATE_INDEX_N_52MBPS = 19, + API_RATE_INDEX_N_58P5MBPS = 20, + API_RATE_INDEX_N_65MBPS = 21, + API_RATE_NUM_ENTRIES = 22 +}; + +struct wfx_hif_ind_startup { + __le32 status; + __le16 hardware_id; + u8 opn[14]; + u8 uid[8]; + __le16 num_inp_ch_bufs; + __le16 size_inp_ch_buf; + u8 num_links_ap; + u8 num_interfaces; + u8 mac_addr[2][ETH_ALEN]; + u8 api_version_minor; + u8 api_version_major; + u8 link_mode:2; + u8 reserved1:6; + u8 reserved2; + u8 reserved3; + u8 reserved4; + u8 firmware_build; + u8 firmware_minor; + u8 firmware_major; + u8 firmware_type; + u8 disabled_channel_list[2]; + u8 region_sel_mode:4; + u8 reserved5:4; + u8 phy1_region:3; + u8 phy0_region:3; + u8 otp_phy_ver:2; + __le32 supported_rate_mask; + u8 firmware_label[128]; +} __packed; + +struct wfx_hif_ind_wakeup { +} __packed; + +struct wfx_hif_req_configuration { + __le16 length; + u8 pds_data[]; +} __packed; + +struct wfx_hif_cnf_configuration { + __le32 status; +} __packed; + +enum wfx_hif_gpio_mode { + HIF_GPIO_MODE_D0 = 0x0, + HIF_GPIO_MODE_D1 = 0x1, + HIF_GPIO_MODE_OD0 = 0x2, + HIF_GPIO_MODE_OD1 = 0x3, + HIF_GPIO_MODE_TRISTATE = 0x4, + HIF_GPIO_MODE_TOGGLE = 0x5, + HIF_GPIO_MODE_READ = 0x6 +}; + +struct wfx_hif_req_control_gpio { + u8 gpio_label; + u8 gpio_mode; +} __packed; + +struct wfx_hif_cnf_control_gpio { + __le32 status; + __le32 value; +} __packed; + +enum wfx_hif_generic_indication_type { + HIF_GENERIC_INDICATION_TYPE_RAW = 0x0, + HIF_GENERIC_INDICATION_TYPE_STRING = 0x1, + HIF_GENERIC_INDICATION_TYPE_RX_STATS = 0x2, + HIF_GENERIC_INDICATION_TYPE_TX_POWER_LOOP_INFO = 0x3, +}; + +struct wfx_hif_rx_stats { + __le32 nb_rx_frame; + __le32 nb_crc_frame; + __le32 per_total; + __le32 throughput; + __le32 nb_rx_by_rate[API_RATE_NUM_ENTRIES]; + __le16 per[API_RATE_NUM_ENTRIES]; + __le16 snr[API_RATE_NUM_ENTRIES]; /* signed value */ + __le16 rssi[API_RATE_NUM_ENTRIES]; /* signed value */ + __le16 cfo[API_RATE_NUM_ENTRIES]; /* signed value */ + __le32 date; + __le32 pwr_clk_freq; + u8 is_ext_pwr_clk; + s8 current_temp; +} __packed; + +struct wfx_hif_tx_power_loop_info { + __le16 tx_gain_dig; + __le16 tx_gain_pa; + __le16 target_pout; /* signed value */ + __le16 p_estimation; /* signed value */ + __le16 vpdet; + u8 measurement_index; + u8 reserved; +} __packed; + +struct wfx_hif_ind_generic { + __le32 type; + union { + struct wfx_hif_rx_stats rx_stats; + struct wfx_hif_tx_power_loop_info tx_power_loop_info; + } data; +} __packed; + +enum wfx_hif_error { + HIF_ERROR_FIRMWARE_ROLLBACK = 0x00, + HIF_ERROR_FIRMWARE_DEBUG_ENABLED = 0x01, + HIF_ERROR_SLK_OUTDATED_SESSION_KEY = 0x02, + HIF_ERROR_SLK_SESSION_KEY = 0x03, + HIF_ERROR_OOR_VOLTAGE = 0x04, + HIF_ERROR_PDS_PAYLOAD = 0x05, + HIF_ERROR_OOR_TEMPERATURE = 0x06, + HIF_ERROR_SLK_REQ_DURING_KEY_EXCHANGE = 0x07, + HIF_ERROR_SLK_MULTI_TX_UNSUPPORTED = 0x08, + HIF_ERROR_SLK_OVERFLOW = 0x09, + HIF_ERROR_SLK_DECRYPTION = 0x0a, + HIF_ERROR_SLK_WRONG_ENCRYPTION_STATE = 0x0b, + HIF_ERROR_HIF_BUS_FREQUENCY_TOO_LOW = 0x0c, + HIF_ERROR_HIF_RX_DATA_TOO_LARGE = 0x0e, + HIF_ERROR_HIF_TX_QUEUE_FULL = 0x0d, + HIF_ERROR_HIF_BUS = 0x0f, + HIF_ERROR_PDS_TESTFEATURE = 0x10, + HIF_ERROR_SLK_UNCONFIGURED = 0x11, +}; + +struct wfx_hif_ind_error { + __le32 type; + u8 data[]; +} __packed; + +struct wfx_hif_ind_exception { + __le32 type; + u8 data[]; +} __packed; + +enum wfx_hif_secure_link_state { + SEC_LINK_UNAVAILABLE = 0x0, + SEC_LINK_RESERVED = 0x1, + SEC_LINK_EVAL = 0x2, + SEC_LINK_ENFORCED = 0x3 +}; + +#endif diff --git a/drivers/net/wireless/silabs/wfx/hif_api_mib.h b/drivers/net/wireless/silabs/wfx/hif_api_mib.h new file mode 100644 index 000000000000..7b68b83866c9 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hif_api_mib.h @@ -0,0 +1,346 @@ +/* SPDX-License-Identifier: GPL-2.0-only or Apache-2.0 */ +/* + * WF200 hardware interface definitions + * + * Copyright (c) 2018-2020, Silicon Laboratories Inc. + */ + +#ifndef WFX_HIF_API_MIB_H +#define WFX_HIF_API_MIB_H + +#include "hif_api_general.h" + +#define HIF_API_IPV4_ADDRESS_SIZE 4 +#define HIF_API_IPV6_ADDRESS_SIZE 16 + +enum wfx_hif_mib_ids { + HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE = 0x2000, + HIF_MIB_ID_GL_BLOCK_ACK_INFO = 0x2001, + HIF_MIB_ID_GL_SET_MULTI_MSG = 0x2002, + HIF_MIB_ID_CCA_CONFIG = 0x2003, + HIF_MIB_ID_ETHERTYPE_DATAFRAME_CONDITION = 0x2010, + HIF_MIB_ID_PORT_DATAFRAME_CONDITION = 0x2011, + HIF_MIB_ID_MAGIC_DATAFRAME_CONDITION = 0x2012, + HIF_MIB_ID_MAC_ADDR_DATAFRAME_CONDITION = 0x2013, + HIF_MIB_ID_IPV4_ADDR_DATAFRAME_CONDITION = 0x2014, + HIF_MIB_ID_IPV6_ADDR_DATAFRAME_CONDITION = 0x2015, + HIF_MIB_ID_UC_MC_BC_DATAFRAME_CONDITION = 0x2016, + HIF_MIB_ID_CONFIG_DATA_FILTER = 0x2017, + HIF_MIB_ID_SET_DATA_FILTERING = 0x2018, + HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE = 0x2019, + HIF_MIB_ID_NS_IP_ADDRESSES_TABLE = 0x201A, + HIF_MIB_ID_RX_FILTER = 0x201B, + HIF_MIB_ID_BEACON_FILTER_TABLE = 0x201C, + HIF_MIB_ID_BEACON_FILTER_ENABLE = 0x201D, + HIF_MIB_ID_GRP_SEQ_COUNTER = 0x2030, + HIF_MIB_ID_TSF_COUNTER = 0x2031, + HIF_MIB_ID_STATISTICS_TABLE = 0x2032, + HIF_MIB_ID_COUNTERS_TABLE = 0x2033, + HIF_MIB_ID_MAX_TX_POWER_LEVEL = 0x2034, + HIF_MIB_ID_EXTENDED_COUNTERS_TABLE = 0x2035, + HIF_MIB_ID_DOT11_MAC_ADDRESS = 0x2040, + HIF_MIB_ID_DOT11_MAX_TRANSMIT_MSDU_LIFETIME = 0x2041, + HIF_MIB_ID_DOT11_MAX_RECEIVE_LIFETIME = 0x2042, + HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID = 0x2043, + HIF_MIB_ID_DOT11_RTS_THRESHOLD = 0x2044, + HIF_MIB_ID_SLOT_TIME = 0x2045, + HIF_MIB_ID_CURRENT_TX_POWER_LEVEL = 0x2046, + HIF_MIB_ID_NON_ERP_PROTECTION = 0x2047, + HIF_MIB_ID_TEMPLATE_FRAME = 0x2048, + HIF_MIB_ID_BEACON_WAKEUP_PERIOD = 0x2049, + HIF_MIB_ID_RCPI_RSSI_THRESHOLD = 0x204A, + HIF_MIB_ID_BLOCK_ACK_POLICY = 0x204B, + HIF_MIB_ID_OVERRIDE_INTERNAL_TX_RATE = 0x204C, + HIF_MIB_ID_SET_ASSOCIATION_MODE = 0x204D, + HIF_MIB_ID_SET_UAPSD_INFORMATION = 0x204E, + HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY = 0x204F, + HIF_MIB_ID_PROTECTED_MGMT_POLICY = 0x2050, + HIF_MIB_ID_SET_HT_PROTECTION = 0x2051, + HIF_MIB_ID_KEEP_ALIVE_PERIOD = 0x2052, + HIF_MIB_ID_ARP_KEEP_ALIVE_PERIOD = 0x2053, + HIF_MIB_ID_INACTIVITY_TIMER = 0x2054, + HIF_MIB_ID_INTERFACE_PROTECTION = 0x2055, + HIF_MIB_ID_BEACON_STATS = 0x2056, +}; + +enum wfx_hif_op_power_mode { + HIF_OP_POWER_MODE_ACTIVE = 0x0, + HIF_OP_POWER_MODE_DOZE = 0x1, + HIF_OP_POWER_MODE_QUIESCENT = 0x2 +}; + +struct wfx_hif_mib_gl_operational_power_mode { + u8 power_mode:4; + u8 reserved1:3; + u8 wup_ind_activation:1; + u8 reserved2[3]; +} __packed; + +struct wfx_hif_mib_gl_set_multi_msg { + u8 enable_multi_tx_conf:1; + u8 reserved1:7; + u8 reserved2[3]; +} __packed; + +enum wfx_hif_arp_ns_frame_treatment { + HIF_ARP_NS_FILTERING_DISABLE = 0x0, + HIF_ARP_NS_FILTERING_ENABLE = 0x1, + HIF_ARP_NS_REPLY_ENABLE = 0x2 +}; + +struct wfx_hif_mib_arp_ip_addr_table { + u8 condition_idx; + u8 arp_enable; + u8 reserved[2]; + u8 ipv4_address[HIF_API_IPV4_ADDRESS_SIZE]; +} __packed; + +struct wfx_hif_mib_rx_filter { + u8 reserved1:1; + u8 bssid_filter:1; + u8 reserved2:1; + u8 fwd_probe_req:1; + u8 keep_alive_filter:1; + u8 reserved3:3; + u8 reserved4[3]; +} __packed; + +struct wfx_hif_ie_table_entry { + u8 ie_id; + u8 has_changed:1; + u8 no_longer:1; + u8 has_appeared:1; + u8 reserved:1; + u8 num_match_data:4; + u8 oui[3]; + u8 match_data[3]; +} __packed; + +struct wfx_hif_mib_bcn_filter_table { + __le32 num_of_info_elmts; + struct wfx_hif_ie_table_entry ie_table[]; +} __packed; + +enum wfx_hif_beacon_filter { + HIF_BEACON_FILTER_DISABLE = 0x0, + HIF_BEACON_FILTER_ENABLE = 0x1, + HIF_BEACON_FILTER_AUTO_ERP = 0x2 +}; + +struct wfx_hif_mib_bcn_filter_enable { + __le32 enable; + __le32 bcn_count; +} __packed; + +struct wfx_hif_mib_extended_count_table { + __le32 count_drop_plcp; + __le32 count_drop_fcs; + __le32 count_tx_frames; + __le32 count_rx_frames; + __le32 count_rx_frames_failed; + __le32 count_drop_decryption; + __le32 count_drop_tkip_mic; + __le32 count_drop_no_key; + __le32 count_tx_frames_multicast; + __le32 count_tx_frames_success; + __le32 count_tx_frames_failed; + __le32 count_tx_frames_retried; + __le32 count_tx_frames_multi_retried; + __le32 count_drop_duplicate; + __le32 count_rts_success; + __le32 count_rts_failed; + __le32 count_ack_failed; + __le32 count_rx_frames_multicast; + __le32 count_rx_frames_success; + __le32 count_drop_cmac_icv; + __le32 count_drop_cmac_replay; + __le32 count_drop_ccmp_replay; + __le32 count_drop_bip_mic; + __le32 count_rx_bcn_success; + __le32 count_rx_bcn_miss; + __le32 count_rx_bcn_dtim; + __le32 count_rx_bcn_dtim_aid0_clr; + __le32 count_rx_bcn_dtim_aid0_set; + __le32 reserved[12]; +} __packed; + +struct wfx_hif_mib_count_table { + __le32 count_drop_plcp; + __le32 count_drop_fcs; + __le32 count_tx_frames; + __le32 count_rx_frames; + __le32 count_rx_frames_failed; + __le32 count_drop_decryption; + __le32 count_drop_tkip_mic; + __le32 count_drop_no_key; + __le32 count_tx_frames_multicast; + __le32 count_tx_frames_success; + __le32 count_tx_frames_failed; + __le32 count_tx_frames_retried; + __le32 count_tx_frames_multi_retried; + __le32 count_drop_duplicate; + __le32 count_rts_success; + __le32 count_rts_failed; + __le32 count_ack_failed; + __le32 count_rx_frames_multicast; + __le32 count_rx_frames_success; + __le32 count_drop_cmac_icv; + __le32 count_drop_cmac_replay; + __le32 count_drop_ccmp_replay; + __le32 count_drop_bip_mic; +} __packed; + +struct wfx_hif_mib_mac_address { + u8 mac_addr[ETH_ALEN]; + __le16 reserved; +} __packed; + +struct wfx_hif_mib_wep_default_key_id { + u8 wep_default_key_id; + u8 reserved[3]; +} __packed; + +struct wfx_hif_mib_dot11_rts_threshold { + __le32 threshold; +} __packed; + +struct wfx_hif_mib_slot_time { + __le32 slot_time; +} __packed; + +struct wfx_hif_mib_current_tx_power_level { + __le32 power_level; /* signed value */ +} __packed; + +struct wfx_hif_mib_non_erp_protection { + u8 use_cts_to_self:1; + u8 reserved1:7; + u8 reserved2[3]; +} __packed; + +enum wfx_hif_tmplt { + HIF_TMPLT_PRBREQ = 0x0, + HIF_TMPLT_BCN = 0x1, + HIF_TMPLT_NULL = 0x2, + HIF_TMPLT_QOSNUL = 0x3, + HIF_TMPLT_PSPOLL = 0x4, + HIF_TMPLT_PRBRES = 0x5, + HIF_TMPLT_ARP = 0x6, + HIF_TMPLT_NA = 0x7 +}; + +#define HIF_API_MAX_TEMPLATE_FRAME_SIZE 700 + +struct wfx_hif_mib_template_frame { + u8 frame_type; + u8 init_rate:7; + u8 mode:1; + __le16 frame_length; + u8 frame[]; +} __packed; + +struct wfx_hif_mib_beacon_wake_up_period { + u8 wakeup_period_min; + u8 receive_dtim:1; + u8 reserved1:7; + u8 wakeup_period_max; + u8 reserved2; +} __packed; + +struct wfx_hif_mib_rcpi_rssi_threshold { + u8 detection:1; + u8 rcpi_rssi:1; + u8 upperthresh:1; + u8 lowerthresh:1; + u8 reserved:4; + u8 lower_threshold; + u8 upper_threshold; + u8 rolling_average_count; +} __packed; + +#define DEFAULT_BA_MAX_RX_BUFFER_SIZE 16 + +struct wfx_hif_mib_block_ack_policy { + u8 block_ack_tx_tid_policy; + u8 reserved1; + u8 block_ack_rx_tid_policy; + u8 block_ack_rx_max_buffer_size; +} __packed; + +enum wfx_hif_mpdu_start_spacing { + HIF_MPDU_START_SPACING_NO_RESTRIC = 0x0, + HIF_MPDU_START_SPACING_QUARTER = 0x1, + HIF_MPDU_START_SPACING_HALF = 0x2, + HIF_MPDU_START_SPACING_ONE = 0x3, + HIF_MPDU_START_SPACING_TWO = 0x4, + HIF_MPDU_START_SPACING_FOUR = 0x5, + HIF_MPDU_START_SPACING_EIGHT = 0x6, + HIF_MPDU_START_SPACING_SIXTEEN = 0x7 +}; + +struct wfx_hif_mib_set_association_mode { + u8 preambtype_use:1; + u8 mode:1; + u8 rateset:1; + u8 spacing:1; + u8 reserved1:4; + u8 short_preamble:1; + u8 reserved2:7; + u8 greenfield:1; + u8 reserved3:7; + u8 mpdu_start_spacing; + __le32 basic_rate_set; +} __packed; + +struct wfx_hif_mib_set_uapsd_information { + u8 trig_bckgrnd:1; + u8 trig_be:1; + u8 trig_video:1; + u8 trig_voice:1; + u8 reserved1:4; + u8 deliv_bckgrnd:1; + u8 deliv_be:1; + u8 deliv_video:1; + u8 deliv_voice:1; + u8 reserved2:4; + __le16 min_auto_trigger_interval; + __le16 max_auto_trigger_interval; + __le16 auto_trigger_step; +} __packed; + +struct wfx_hif_tx_rate_retry_policy { + u8 policy_index; + u8 short_retry_count; + u8 long_retry_count; + u8 first_rate_sel:2; + u8 terminate:1; + u8 count_init:1; + u8 reserved1:4; + u8 rate_recovery_count; + u8 reserved2[3]; + u8 rates[12]; +} __packed; + +#define HIF_TX_RETRY_POLICY_MAX 15 +#define HIF_TX_RETRY_POLICY_INVALID HIF_TX_RETRY_POLICY_MAX + +struct wfx_hif_mib_set_tx_rate_retry_policy { + u8 num_tx_rate_policies; + u8 reserved[3]; + struct wfx_hif_tx_rate_retry_policy tx_rate_retry_policy[]; +} __packed; + +struct wfx_hif_mib_protected_mgmt_policy { + u8 pmf_enable:1; + u8 unpmf_allowed:1; + u8 host_enc_auth_frames:1; + u8 reserved1:5; + u8 reserved2[3]; +} __packed; + +struct wfx_hif_mib_keep_alive_period { + __le16 keep_alive_period; + u8 reserved[2]; +} __packed; + +#endif From patchwork Tue Jan 11 17:14:13 2022 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: 531339 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3EDABC433F5 for ; Tue, 11 Jan 2022 17:16:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344288AbiAKRQ0 (ORCPT ); Tue, 11 Jan 2022 12:16:26 -0500 Received: from mail-bn7nam10on2045.outbound.protection.outlook.com ([40.107.92.45]:52705 "EHLO NAM10-BN7-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1343989AbiAKRPq (ORCPT ); Tue, 11 Jan 2022 12:15:46 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Jq9reMzrJrPJWi0NLvn8lPJqxzt7xr9jDkXsXnBK/Uq2VL8KHIYDIZgTSDVnWGKj1njy6i/d+QGVr2PfUZ+1U689c1XzFXcJqPKRp1x1/655cdTQORepq3WgTL+qtICQDzBMzt4Z2FuCx3ezR3D8aQfq2dlsO1U8Qg2kzqM4q1X1mVqlxNzZJgAxmdMgDKbChNPkVug1m5OJEky97Ii8kVzSpW9MWKk+tYC8cbvOxzvAM2wZuzz+lGvAJvJwX+I5FTdoT1stb69Za4hehZdNA4mlr5zyKpnY+FvP4Ab1KVTQ1dVmsOCGZH4S64zIv7jSkyVtxwwpYE9bZA9ZBDmLzA== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=X1cR2BtYV8qIgaXe/OsSh91spBngEHgNdC/46S3ZZms=; b=OOSwhb3yOqclMSI4cY5S61nMhxCG9OhQqK9FdUPNJmz3RjsVTkBT99vwSXKg2wnx3K+ks2n6d6I0SQzIOr0fkRT1rluVLkmd9/Ogu+IWCVVzv2z2x+H+XCXpcU4jefLF2U2oSPirPIZ5I52I2L+JRmaZwrWXgnsngDLevzLdAlOo16rAV/twjtFkUtIm4UMe7Qa9IosyZlofqZ0yDwX5v8DFaO+3uJJoRsBfHoFzsisiFtcrNRqHt7ezWSmzae2bbTeactKWTZmp6auQ7LQ3Cf1wNjdEpcqq9gOPWcD+AshWGacz8Y55dbv7wrArLzPWg5AHF8fhGp1Nwh4nSmyMWQ== 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=X1cR2BtYV8qIgaXe/OsSh91spBngEHgNdC/46S3ZZms=; b=qKK3Q07TeVKJsciHlLEzxFl5O1FEqSuJKMUN6l7nWyCX5/P/rDkSqT862xb0/KoNgfUkBBernuOkg+A1+O8oPk3sVQRmkeJT7nv3SmnJyxMK+TyHrj0cuWQfgLCo6SdispB+sOQHrklMkOi+S1mHS5p72nCwQvz9YkDERodS274= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5609.namprd11.prod.outlook.com (2603:10b6:510:e0::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.9; Tue, 11 Jan 2022 17:15:20 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:20 +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 v9 13/24] wfx: add hif_tx*.c/hif_tx*.h Date: Tue, 11 Jan 2022 18:14:13 +0100 Message-Id: <20220111171424.862764-14-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f25653c3-31b7-4b8e-c869-08d9d525f1e5 X-MS-TrafficTypeDiagnostic: PH0PR11MB5609:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:21; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ULfO4AdT/+UVYshoac8ySCrunRNnD+fiUuO9nWqDxNNTwW9al6+ah2yjOJVnAiDwwAZwVaLWLH9x804Ouo8M3JWD91sL0y9f5VkAQFj9R58CQVCJ5FfzReRR2kHN6YoslrQKcYyH0P21J2p3TbdEMZoriwFg/f4ydhOasTg/AgcposeO/pHuF7wFeyNxdha90d3bMewk3ogfm69jqgPPGdkxj2Tz0f36tcx9tfKvr9z3DTlpywKGQIOrNnxERPml6QocCaRFdw3oi2O44dRTYqL1rYV1WrgdmALMh2Sa2xaQmY6tAaxOsXVOVoVQi2yHMGhLpgHLvy00Fv2coqsuLfXhvckxvARYbfdtZ3D5ZRUYydcYGWlNj0+wkMdcUHl305TFs6jYB2dOvkxBmqqzAkSdaifx2E8qOh1NmX7pMIGXD09YwM5QU3zKc7lDx2+FVSEMw4KqeNfPWltUOIC5XE1W4D0W2lyUONQWfK6gU1+X4+ZJ5MkNLjnxaILdwjR5r6x0fzyY99Gc2jgMhr+In8euDcCUSynIqpFqyO98gtUhhGJmFCUbt8xonUNUazNapeR+ckuLU9vrxfUeHpCWgdxzaCTgc9PQwtkeqpTKxMPYpzV26vT/ZPLBf8S9B+DPNIetCUEg1U1GGlxjbHr/Hw== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(5660300002)(8676002)(36756003)(38100700002)(186003)(7416002)(66476007)(54906003)(6486002)(6916009)(6512007)(4326008)(508600001)(107886003)(66946007)(6666004)(2616005)(1076003)(8936002)(66556008)(86362001)(2906002)(6506007)(52116002)(66574015)(316002)(83380400001)(30864003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?4GNBMbjPsvfJP6ObAYz64W8qTtDv?= =?utf-8?q?Ka3AJarfcrMUZQ8LqSglRYFA4HcZ/djqqYQ+JVA0/W3uGCU0D+8yEmIHAJ1mFXppC?= =?utf-8?q?kflNWIai4M95YsqiZB8Tqej/Dc5xB1PZD1GMPJMGx7iHPJpiDoKFDAHn2ZSfTdT7c?= =?utf-8?q?3NV6lZHUI+JrJdfgj2z7WPgZtCuaJu4gsJq8t/gawWhafLhMN487e2Q3ST3n1Eq9A?= =?utf-8?q?J6h44a567iQ96SKDP/ENYCUYxs3eyC3dwFQhY+OMPR2AI7rfJN1/nvsa+apIq+F7Z?= =?utf-8?q?uh5Xr8N0qszub0+hsCF8NGr+pl9EvhZIFX7RXTYrfHdcJHgFBbnFoy0ZvocxDYOhK?= =?utf-8?q?xcEnVyHxVmLXhbhtypS2+h5Pvhxveb87Orc7+X8kB9gZaV3SPDhY4PQCBAVNxzX34?= =?utf-8?q?/ipFvWLdWYx0fG3lKguRgLqAGpWTDvT3yEdl99u0PELmJzD3O9X+RKjcJw1SXqOKT?= =?utf-8?q?/TKyLaNWCQBrFmiWwymVR47cGzKwq3jzSE9VOplyqutZp2MI5faRUcuJ+Tkl4MEmG?= =?utf-8?q?FI57yOGljDU0WE4WHuMwhZxdJfd3x7fzeLNbEVhAzoYDzzgKIU5YLMDgHjNQsW/jz?= =?utf-8?q?aRp8c+rcXn705vw76gBHXoqKqnLDtuj0V3ZTN0e5sEXUqIpZrsxfuoOdKUhmk4wSx?= =?utf-8?q?EydxxNFFt5V+6JfXD8uWtCnB4wo4lxCVjS9vw/qH5u/7c0NQkmtrNKj0Uhd7ta39y?= =?utf-8?q?ifJ/LUlwEGQ1y3oRbz6Qv/Fm3xCTX74jMjmdqApUe8q0rcT98vM156riRhiwL3Zmw?= =?utf-8?q?fpr8YNs2+4Xarb8vLLY57oqwYW/8DfQbIP+sRwnZPA22GVBhchKnuP4a+yGmG10LH?= =?utf-8?q?X/WXEeG0qb9rJjvrGl+QH/mdRcZcFHTzudizxhcnF9Hu4ttidPnqBsLwA9l6hvhdC?= =?utf-8?q?wEJnqHjmyyROJS0zHOZ0t4uXajMabtBy09HhcfsaQLrx6sa3n08nJ8LV31tj04eaA?= =?utf-8?q?0Q1z4S+KTrmymUXFym4GuP09YZ2UGjMbFCnIsUbkGp96mDQv4LTVZczWhzIUkVlwN?= =?utf-8?q?BJjtVJV9iQ1SaDP1pARYvYlqIHCVlIlvpAUZuHYyFmyYh4ywV0V/X1aPxBQq2V9ed?= =?utf-8?q?piAVO23/hLK84dbYwTQ23reUVSqlrmQVaWSP906S8M9iwfLyGZRxa8pdzYl0Zqh+W?= =?utf-8?q?KzF8m0tZ2NlfW6epsvFaHj0zpEzC9VjvfJgJU0JOTx6vx363Bl3uqkyWY8EClY+N1?= =?utf-8?q?S4oGqrT0BOCg03LfzXHiVeWdYSjef9iiM8QWrhS0GSyNT2OxMHe4j9cgdzHSan6cV?= =?utf-8?q?JBUEE+44MPLt04sD81/RnUivl+5/EvRAxM0B63ynA9l+Yzp7KLxzytT1VF7i5fz/k?= =?utf-8?q?Z9XjDzfN8ahOKIL244GgQcSzbZFL7Xq6cO8Ra6B62HOa3NADpJDlhjljcavr9P/X2?= =?utf-8?q?lAKlJ1iawhj+Qtmy91FyH31xr3AwLkeXYUSCQIbZHN1m3X6U5/ds8zkOAaNOGFfZv?= =?utf-8?q?jDrgG3mUl36zAnr6OClnVKNLJO0nbQ1ogcrpT285XGrj8nu4Zqu1mGVizayVnb2kp?= =?utf-8?q?wGJUho56dVTk5KokRzvd9WMQWoQhTMh/ZKyI+LQ+sank2Uee724yxaHsZdo9Z1onf?= =?utf-8?q?+9W4DsKyR68495EIDQoLIIa8gE7yfNiRLzooSgHJX0UDEWhRyxUNvM=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: f25653c3-31b7-4b8e-c869-08d9d525f1e5 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:20.1947 (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: Sg47NqexAA6kHHsn5vJz1ZZ1CYqea7Bku9H0tT0iX3M1l1ZVFfmlVapeHvFgKcRbyk3UmxrBlj7acQ3YpF4WzQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5609 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/hif_tx.c | 492 +++++++++++++++++++ drivers/net/wireless/silabs/wfx/hif_tx.h | 61 +++ drivers/net/wireless/silabs/wfx/hif_tx_mib.c | 308 ++++++++++++ drivers/net/wireless/silabs/wfx/hif_tx_mib.h | 48 ++ 4 files changed, 909 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/hif_tx.c create mode 100644 drivers/net/wireless/silabs/wfx/hif_tx.h create mode 100644 drivers/net/wireless/silabs/wfx/hif_tx_mib.c create mode 100644 drivers/net/wireless/silabs/wfx/hif_tx_mib.h diff --git a/drivers/net/wireless/silabs/wfx/hif_tx.c b/drivers/net/wireless/silabs/wfx/hif_tx.c new file mode 100644 index 000000000000..40b9808eb511 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hif_tx.c @@ -0,0 +1,492 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Implementation of the host-to-chip commands (aka request/confirmation) of the + * hardware API. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#include + +#include "hif_tx.h" +#include "wfx.h" +#include "bh.h" +#include "hwio.h" +#include "debug.h" +#include "sta.h" + +void wfx_init_hif_cmd(struct wfx_hif_cmd *hif_cmd) +{ + init_completion(&hif_cmd->ready); + init_completion(&hif_cmd->done); + mutex_init(&hif_cmd->lock); +} + +static void wfx_fill_header(struct wfx_hif_msg *hif, int if_id, unsigned int cmd, size_t size) +{ + if (if_id == -1) + if_id = 2; + + WARN(cmd > 0x3f, "invalid hardware command %#.2x", cmd); + WARN(size > 0xFFF, "requested buffer is too large: %zu bytes", size); + WARN(if_id > 0x3, "invalid interface ID %d", if_id); + + hif->len = cpu_to_le16(size + 4); + hif->id = cmd; + hif->interface = if_id; +} + +static void *wfx_alloc_hif(size_t body_len, struct wfx_hif_msg **hif) +{ + *hif = kzalloc(sizeof(*hif) + body_len, GFP_KERNEL); + if (*hif) + return (*hif)->body; + else + return NULL; +} + +int wfx_cmd_send(struct wfx_dev *wdev, struct wfx_hif_msg *request, + void *reply, size_t reply_len, bool no_reply) +{ + const char *mib_name = ""; + const char *mib_sep = ""; + int cmd = request->id; + int vif = request->interface; + int ret; + + /* Do not wait for any reply if chip is frozen */ + if (wdev->chip_frozen) + return -ETIMEDOUT; + + mutex_lock(&wdev->hif_cmd.lock); + WARN(wdev->hif_cmd.buf_send, "data locking error"); + + /* Note: call to complete() below has an implicit memory barrier that hopefully protect + * buf_send + */ + wdev->hif_cmd.buf_send = request; + wdev->hif_cmd.buf_recv = reply; + wdev->hif_cmd.len_recv = reply_len; + complete(&wdev->hif_cmd.ready); + + wfx_bh_request_tx(wdev); + + if (no_reply) { + /* Chip won't reply. Give enough time to the wq to send the buffer. */ + msleep(100); + wdev->hif_cmd.buf_send = NULL; + mutex_unlock(&wdev->hif_cmd.lock); + return 0; + } + + if (wdev->poll_irq) + wfx_bh_poll_irq(wdev); + + ret = wait_for_completion_timeout(&wdev->hif_cmd.done, 1 * HZ); + if (!ret) { + dev_err(wdev->dev, "chip is abnormally long to answer\n"); + reinit_completion(&wdev->hif_cmd.ready); + ret = wait_for_completion_timeout(&wdev->hif_cmd.done, 3 * HZ); + } + if (!ret) { + dev_err(wdev->dev, "chip did not answer\n"); + wfx_pending_dump_old_frames(wdev, 3000); + wdev->chip_frozen = true; + reinit_completion(&wdev->hif_cmd.done); + ret = -ETIMEDOUT; + } else { + ret = wdev->hif_cmd.ret; + } + + wdev->hif_cmd.buf_send = NULL; + mutex_unlock(&wdev->hif_cmd.lock); + + if (ret && + (cmd == HIF_REQ_ID_READ_MIB || cmd == HIF_REQ_ID_WRITE_MIB)) { + mib_name = wfx_get_mib_name(((u16 *)request)[2]); + mib_sep = "/"; + } + if (ret < 0) + dev_err(wdev->dev, "hardware request %s%s%s (%#.2x) on vif %d returned error %d\n", + wfx_get_hif_name(cmd), mib_sep, mib_name, cmd, vif, ret); + if (ret > 0) + dev_warn(wdev->dev, "hardware request %s%s%s (%#.2x) on vif %d returned status %d\n", + wfx_get_hif_name(cmd), mib_sep, mib_name, cmd, vif, ret); + + return ret; +} + +/* This function is special. After HIF_REQ_ID_SHUT_DOWN, chip won't reply to any request anymore. + * Obviously, only call this function during device unregister. + */ +int wfx_hif_shutdown(struct wfx_dev *wdev) +{ + int ret; + struct wfx_hif_msg *hif; + + wfx_alloc_hif(0, &hif); + if (!hif) + return -ENOMEM; + wfx_fill_header(hif, -1, HIF_REQ_ID_SHUT_DOWN, 0); + ret = wfx_cmd_send(wdev, hif, NULL, 0, true); + if (wdev->pdata.gpio_wakeup) + gpiod_set_value(wdev->pdata.gpio_wakeup, 0); + else + wfx_control_reg_write(wdev, 0); + kfree(hif); + return ret; +} + +int wfx_hif_configuration(struct wfx_dev *wdev, const u8 *conf, size_t len) +{ + int ret; + size_t buf_len = sizeof(struct wfx_hif_req_configuration) + len; + struct wfx_hif_msg *hif; + struct wfx_hif_req_configuration *body = wfx_alloc_hif(buf_len, &hif); + + if (!hif) + return -ENOMEM; + body->length = cpu_to_le16(len); + memcpy(body->pds_data, conf, len); + wfx_fill_header(hif, -1, HIF_REQ_ID_CONFIGURATION, buf_len); + ret = wfx_cmd_send(wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_reset(struct wfx_vif *wvif, bool reset_stat) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_reset *body = wfx_alloc_hif(sizeof(*body), &hif); + + if (!hif) + return -ENOMEM; + body->reset_stat = reset_stat; + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_RESET, sizeof(*body)); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, + void *val, size_t val_len) +{ + int ret; + struct wfx_hif_msg *hif; + int buf_len = sizeof(struct wfx_hif_cnf_read_mib) + val_len; + struct wfx_hif_req_read_mib *body = wfx_alloc_hif(sizeof(*body), &hif); + struct wfx_hif_cnf_read_mib *reply = kmalloc(buf_len, GFP_KERNEL); + + if (!body || !reply) { + ret = -ENOMEM; + goto out; + } + body->mib_id = cpu_to_le16(mib_id); + wfx_fill_header(hif, vif_id, HIF_REQ_ID_READ_MIB, sizeof(*body)); + ret = wfx_cmd_send(wdev, hif, reply, buf_len, false); + + if (!ret && mib_id != le16_to_cpu(reply->mib_id)) { + dev_warn(wdev->dev, "%s: confirmation mismatch request\n", __func__); + ret = -EIO; + } + if (ret == -ENOMEM) + dev_err(wdev->dev, "buffer is too small to receive %s (%zu < %d)\n", + wfx_get_mib_name(mib_id), val_len, le16_to_cpu(reply->length)); + if (!ret) + memcpy(val, &reply->mib_data, le16_to_cpu(reply->length)); + else + memset(val, 0xFF, val_len); +out: + kfree(hif); + kfree(reply); + return ret; +} + +int wfx_hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *val, size_t val_len) +{ + int ret; + struct wfx_hif_msg *hif; + int buf_len = sizeof(struct wfx_hif_req_write_mib) + val_len; + struct wfx_hif_req_write_mib *body = wfx_alloc_hif(buf_len, &hif); + + if (!hif) + return -ENOMEM; + body->mib_id = cpu_to_le16(mib_id); + body->length = cpu_to_le16(val_len); + memcpy(&body->mib_data, val, val_len); + wfx_fill_header(hif, vif_id, HIF_REQ_ID_WRITE_MIB, buf_len); + ret = wfx_cmd_send(wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req, + int chan_start_idx, int chan_num) +{ + int ret, i; + struct wfx_hif_msg *hif; + size_t buf_len = sizeof(struct wfx_hif_req_start_scan_alt) + chan_num * sizeof(u8); + struct wfx_hif_req_start_scan_alt *body = wfx_alloc_hif(buf_len, &hif); + + WARN(chan_num > HIF_API_MAX_NB_CHANNELS, "invalid params"); + WARN(req->n_ssids > HIF_API_MAX_NB_SSIDS, "invalid params"); + + if (!hif) + return -ENOMEM; + for (i = 0; i < req->n_ssids; i++) { + memcpy(body->ssid_def[i].ssid, req->ssids[i].ssid, IEEE80211_MAX_SSID_LEN); + body->ssid_def[i].ssid_length = cpu_to_le32(req->ssids[i].ssid_len); + } + body->num_of_ssids = HIF_API_MAX_NB_SSIDS; + body->maintain_current_bss = 1; + body->disallow_ps = 1; + body->tx_power_level = cpu_to_le32(req->channels[chan_start_idx]->max_power); + body->num_of_channels = chan_num; + for (i = 0; i < chan_num; i++) + body->channel_list[i] = req->channels[i + chan_start_idx]->hw_value; + if (req->no_cck) + body->max_transmit_rate = API_RATE_INDEX_G_6MBPS; + else + body->max_transmit_rate = API_RATE_INDEX_B_1MBPS; + if (req->channels[chan_start_idx]->flags & IEEE80211_CHAN_NO_IR) { + body->min_channel_time = cpu_to_le32(50); + body->max_channel_time = cpu_to_le32(150); + } else { + body->min_channel_time = cpu_to_le32(10); + body->max_channel_time = cpu_to_le32(50); + body->num_of_probe_requests = 2; + body->probe_delay = 100; + } + + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START_SCAN, buf_len); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_stop_scan(struct wfx_vif *wvif) +{ + int ret; + struct wfx_hif_msg *hif; + /* body associated to HIF_REQ_ID_STOP_SCAN is empty */ + wfx_alloc_hif(0, &hif); + + if (!hif) + return -ENOMEM; + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_STOP_SCAN, 0); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, + struct ieee80211_channel *channel, const u8 *ssid, int ssidlen) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_join *body = wfx_alloc_hif(sizeof(*body), &hif); + + WARN_ON(!conf->beacon_int); + WARN_ON(!conf->basic_rates); + WARN_ON(!channel); + WARN_ON(sizeof(body->ssid) < ssidlen); + WARN(!conf->ibss_joined && !ssidlen, "joining an unknown BSS"); + if (!hif) + return -ENOMEM; + body->infrastructure_bss_mode = !conf->ibss_joined; + body->short_preamble = conf->use_short_preamble; + body->probe_for_join = !(channel->flags & IEEE80211_CHAN_NO_IR); + body->channel_number = channel->hw_value; + body->beacon_interval = cpu_to_le32(conf->beacon_int); + body->basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); + memcpy(body->bssid, conf->bssid, sizeof(body->bssid)); + if (ssid) { + body->ssid_length = cpu_to_le32(ssidlen); + memcpy(body->ssid, ssid, ssidlen); + } + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body)); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_set_bss_params(struct wfx_vif *wvif, int aid, int beacon_lost_count) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_set_bss_params *body = wfx_alloc_hif(sizeof(*body), &hif); + + if (!hif) + return -ENOMEM; + body->aid = cpu_to_le16(aid); + body->beacon_lost_count = beacon_lost_count; + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_SET_BSS_PARAMS, sizeof(*body)); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_add_key(struct wfx_dev *wdev, const struct wfx_hif_req_add_key *arg) +{ + int ret; + struct wfx_hif_msg *hif; + /* FIXME: only send necessary bits */ + struct wfx_hif_req_add_key *body = wfx_alloc_hif(sizeof(*body), &hif); + + if (!hif) + return -ENOMEM; + /* FIXME: swap bytes as necessary in body */ + memcpy(body, arg, sizeof(*body)); + if (wfx_api_older_than(wdev, 1, 5)) + /* Legacy firmwares expect that add_key to be sent on right interface. */ + wfx_fill_header(hif, arg->int_id, HIF_REQ_ID_ADD_KEY, sizeof(*body)); + else + wfx_fill_header(hif, -1, HIF_REQ_ID_ADD_KEY, sizeof(*body)); + ret = wfx_cmd_send(wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_remove_key(struct wfx_dev *wdev, int idx) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_remove_key *body = wfx_alloc_hif(sizeof(*body), &hif); + + if (!hif) + return -ENOMEM; + body->entry_index = idx; + wfx_fill_header(hif, -1, HIF_REQ_ID_REMOVE_KEY, sizeof(*body)); + ret = wfx_cmd_send(wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue, + const struct ieee80211_tx_queue_params *arg) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_edca_queue_params *body = wfx_alloc_hif(sizeof(*body), &hif); + + if (!body) + return -ENOMEM; + + WARN_ON(arg->aifs > 255); + if (!hif) + return -ENOMEM; + body->aifsn = arg->aifs; + body->cw_min = cpu_to_le16(arg->cw_min); + body->cw_max = cpu_to_le16(arg->cw_max); + body->tx_op_limit = cpu_to_le16(arg->txop * USEC_PER_TXOP); + body->queue_id = 3 - queue; + /* API 2.0 has changed queue IDs values */ + if (wfx_api_older_than(wvif->wdev, 2, 0) && queue == IEEE80211_AC_BE) + body->queue_id = HIF_QUEUE_ID_BACKGROUND; + if (wfx_api_older_than(wvif->wdev, 2, 0) && queue == IEEE80211_AC_BK) + body->queue_id = HIF_QUEUE_ID_BESTEFFORT; + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_EDCA_QUEUE_PARAMS, sizeof(*body)); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_set_pm_mode *body = wfx_alloc_hif(sizeof(*body), &hif); + + if (!body) + return -ENOMEM; + + if (!hif) + return -ENOMEM; + if (ps) { + body->enter_psm = 1; + /* Firmware does not support more than 128ms */ + body->fast_psm_idle_period = min(dynamic_ps_timeout * 2, 255); + if (body->fast_psm_idle_period) + body->fast_psm = 1; + } + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_SET_PM_MODE, sizeof(*body)); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, + const struct ieee80211_channel *channel) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif); + + WARN_ON(!conf->beacon_int); + if (!hif) + return -ENOMEM; + body->dtim_period = conf->dtim_period; + body->short_preamble = conf->use_short_preamble; + body->channel_number = channel->hw_value; + body->beacon_interval = cpu_to_le32(conf->beacon_int); + body->basic_rate_set = cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); + body->ssid_length = conf->ssid_len; + memcpy(body->ssid, conf->ssid, conf->ssid_len); + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_START, sizeof(*body)); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_beacon_transmit(struct wfx_vif *wvif, bool enable) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_beacon_transmit *body = wfx_alloc_hif(sizeof(*body), &hif); + + if (!hif) + return -ENOMEM; + body->enable_beaconing = enable ? 1 : 0; + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_BEACON_TRANSMIT, sizeof(*body)); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_map_link(struct wfx_vif *wvif, bool unmap, u8 *mac_addr, int sta_id, bool mfp) +{ + int ret; + struct wfx_hif_msg *hif; + struct wfx_hif_req_map_link *body = wfx_alloc_hif(sizeof(*body), &hif); + + if (!hif) + return -ENOMEM; + if (mac_addr) + ether_addr_copy(body->mac_addr, mac_addr); + body->mfpc = mfp ? 1 : 0; + body->unmap = unmap ? 1 : 0; + body->peer_sta_id = sta_id; + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_MAP_LINK, sizeof(*body)); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} + +int wfx_hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len) +{ + int ret; + struct wfx_hif_msg *hif; + int buf_len = sizeof(struct wfx_hif_req_update_ie) + ies_len; + struct wfx_hif_req_update_ie *body = wfx_alloc_hif(buf_len, &hif); + + if (!hif) + return -ENOMEM; + body->beacon = 1; + body->num_ies = cpu_to_le16(1); + memcpy(body->ie, ies, ies_len); + wfx_fill_header(hif, wvif->id, HIF_REQ_ID_UPDATE_IE, buf_len); + ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); + kfree(hif); + return ret; +} diff --git a/drivers/net/wireless/silabs/wfx/hif_tx.h b/drivers/net/wireless/silabs/wfx/hif_tx.h new file mode 100644 index 000000000000..71817a6571f0 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hif_tx.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Implementation of the host-to-chip commands (aka request/confirmation) of the + * hardware API. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + * Copyright (C) 2010, ST-Ericsson SA + */ +#ifndef WFX_HIF_TX_H +#define WFX_HIF_TX_H + +#include +#include +#include + +struct ieee80211_channel; +struct ieee80211_bss_conf; +struct ieee80211_tx_queue_params; +struct cfg80211_scan_request; +struct wfx_hif_req_add_key; +struct wfx_dev; +struct wfx_vif; + +struct wfx_hif_cmd { + struct mutex lock; + struct completion ready; + struct completion done; + struct wfx_hif_msg *buf_send; + void *buf_recv; + size_t len_recv; + int ret; +}; + +void wfx_init_hif_cmd(struct wfx_hif_cmd *wfx_hif_cmd); +int wfx_cmd_send(struct wfx_dev *wdev, struct wfx_hif_msg *request, + void *reply, size_t reply_len, bool async); + +int wfx_hif_read_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *buf, size_t buf_size); +int wfx_hif_write_mib(struct wfx_dev *wdev, int vif_id, u16 mib_id, void *buf, size_t buf_size); +int wfx_hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, + const struct ieee80211_channel *channel); +int wfx_hif_reset(struct wfx_vif *wvif, bool reset_stat); +int wfx_hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, + struct ieee80211_channel *channel, const u8 *ssid, int ssidlen); +int wfx_hif_map_link(struct wfx_vif *wvif, bool unmap, u8 *mac_addr, int sta_id, bool mfp); +int wfx_hif_add_key(struct wfx_dev *wdev, const struct wfx_hif_req_add_key *arg); +int wfx_hif_remove_key(struct wfx_dev *wdev, int idx); +int wfx_hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout); +int wfx_hif_set_bss_params(struct wfx_vif *wvif, int aid, int beacon_lost_count); +int wfx_hif_set_edca_queue_params(struct wfx_vif *wvif, u16 queue, + const struct ieee80211_tx_queue_params *arg); +int wfx_hif_beacon_transmit(struct wfx_vif *wvif, bool enable); +int wfx_hif_update_ie_beacon(struct wfx_vif *wvif, const u8 *ies, size_t ies_len); +int wfx_hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211, + int chan_start, int chan_num); +int wfx_hif_stop_scan(struct wfx_vif *wvif); +int wfx_hif_configuration(struct wfx_dev *wdev, const u8 *conf, size_t len); +int wfx_hif_shutdown(struct wfx_dev *wdev); + +#endif diff --git a/drivers/net/wireless/silabs/wfx/hif_tx_mib.c b/drivers/net/wireless/silabs/wfx/hif_tx_mib.c new file mode 100644 index 000000000000..1c57dd2b697c --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hif_tx_mib.c @@ -0,0 +1,308 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Implementation of the host-to-chip MIBs of the hardware API. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + * Copyright (C) 2010, ST-Ericsson SA + */ + +#include + +#include "wfx.h" +#include "hif_tx.h" +#include "hif_tx_mib.h" +#include "hif_api_mib.h" + +int wfx_hif_set_output_power(struct wfx_vif *wvif, int val) +{ + struct wfx_hif_mib_current_tx_power_level arg = { + .power_level = cpu_to_le32(val * 10), + }; + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_CURRENT_TX_POWER_LEVEL, + &arg, sizeof(arg)); +} + +int wfx_hif_set_beacon_wakeup_period(struct wfx_vif *wvif, + unsigned int dtim_interval, unsigned int listen_interval) +{ + struct wfx_hif_mib_beacon_wake_up_period arg = { + .wakeup_period_min = dtim_interval, + .receive_dtim = 0, + .wakeup_period_max = listen_interval, + }; + + if (dtim_interval > 0xFF || listen_interval > 0xFFFF) + return -EINVAL; + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BEACON_WAKEUP_PERIOD, + &arg, sizeof(arg)); +} + +int wfx_hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif, int rssi_thold, int rssi_hyst) +{ + struct wfx_hif_mib_rcpi_rssi_threshold arg = { + .rolling_average_count = 8, + .detection = 1, + }; + + if (!rssi_thold && !rssi_hyst) { + arg.upperthresh = 1; + arg.lowerthresh = 1; + } else { + arg.upper_threshold = rssi_thold + rssi_hyst; + arg.upper_threshold = (arg.upper_threshold + 110) * 2; + arg.lower_threshold = rssi_thold; + arg.lower_threshold = (arg.lower_threshold + 110) * 2; + } + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_RCPI_RSSI_THRESHOLD, + &arg, sizeof(arg)); +} + +int wfx_hif_get_counters_table(struct wfx_dev *wdev, int vif_id, + struct wfx_hif_mib_extended_count_table *arg) +{ + if (wfx_api_older_than(wdev, 1, 3)) { + /* extended_count_table is wider than count_table */ + memset(arg, 0xFF, sizeof(*arg)); + return wfx_hif_read_mib(wdev, vif_id, HIF_MIB_ID_COUNTERS_TABLE, + arg, sizeof(struct wfx_hif_mib_count_table)); + } else { + return wfx_hif_read_mib(wdev, vif_id, HIF_MIB_ID_EXTENDED_COUNTERS_TABLE, + arg, sizeof(struct wfx_hif_mib_extended_count_table)); + } +} + +int wfx_hif_set_macaddr(struct wfx_vif *wvif, u8 *mac) +{ + struct wfx_hif_mib_mac_address arg = { }; + + if (mac) + ether_addr_copy(arg.mac_addr, mac); + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_DOT11_MAC_ADDRESS, + &arg, sizeof(arg)); +} + +int wfx_hif_set_rx_filter(struct wfx_vif *wvif, + bool filter_bssid, bool filter_prbreq) +{ + struct wfx_hif_mib_rx_filter arg = { }; + + if (filter_bssid) + arg.bssid_filter = 1; + if (!filter_prbreq) + arg.fwd_probe_req = 1; + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_RX_FILTER, &arg, sizeof(arg)); +} + +int wfx_hif_set_beacon_filter_table(struct wfx_vif *wvif, int tbl_len, + const struct wfx_hif_ie_table_entry *tbl) +{ + int ret; + struct wfx_hif_mib_bcn_filter_table *arg; + int buf_len = struct_size(arg, ie_table, tbl_len); + + arg = kzalloc(buf_len, GFP_KERNEL); + if (!arg) + return -ENOMEM; + arg->num_of_info_elmts = cpu_to_le32(tbl_len); + memcpy(arg->ie_table, tbl, flex_array_size(arg, ie_table, tbl_len)); + ret = wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BEACON_FILTER_TABLE, + arg, buf_len); + kfree(arg); + return ret; +} + +int wfx_hif_beacon_filter_control(struct wfx_vif *wvif, int enable, int beacon_count) +{ + struct wfx_hif_mib_bcn_filter_enable arg = { + .enable = cpu_to_le32(enable), + .bcn_count = cpu_to_le32(beacon_count), + }; + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BEACON_FILTER_ENABLE, + &arg, sizeof(arg)); +} + +int wfx_hif_set_operational_mode(struct wfx_dev *wdev, enum wfx_hif_op_power_mode mode) +{ + struct wfx_hif_mib_gl_operational_power_mode arg = { + .power_mode = mode, + .wup_ind_activation = 1, + }; + + return wfx_hif_write_mib(wdev, -1, HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE, + &arg, sizeof(arg)); +} + +int wfx_hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb, + u8 frame_type, int init_rate) +{ + struct wfx_hif_mib_template_frame *arg; + + WARN(skb->len > HIF_API_MAX_TEMPLATE_FRAME_SIZE, "frame is too big"); + skb_push(skb, 4); + arg = (struct wfx_hif_mib_template_frame *)skb->data; + skb_pull(skb, 4); + arg->init_rate = init_rate; + arg->frame_type = frame_type; + arg->frame_length = cpu_to_le16(skb->len); + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_TEMPLATE_FRAME, + arg, sizeof(*arg) + skb->len); +} + +int wfx_hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required) +{ + struct wfx_hif_mib_protected_mgmt_policy arg = { }; + + WARN(required && !capable, "incoherent arguments"); + if (capable) { + arg.pmf_enable = 1; + arg.host_enc_auth_frames = 1; + } + if (!required) + arg.unpmf_allowed = 1; + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_PROTECTED_MGMT_POLICY, + &arg, sizeof(arg)); +} + +int wfx_hif_set_block_ack_policy(struct wfx_vif *wvif, u8 tx_tid_policy, u8 rx_tid_policy) +{ + struct wfx_hif_mib_block_ack_policy arg = { + .block_ack_tx_tid_policy = tx_tid_policy, + .block_ack_rx_tid_policy = rx_tid_policy, + }; + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_BLOCK_ACK_POLICY, + &arg, sizeof(arg)); +} + +int wfx_hif_set_association_mode(struct wfx_vif *wvif, int ampdu_density, + bool greenfield, bool short_preamble) +{ + struct wfx_hif_mib_set_association_mode arg = { + .preambtype_use = 1, + .mode = 1, + .spacing = 1, + .short_preamble = short_preamble, + .greenfield = greenfield, + .mpdu_start_spacing = ampdu_density, + }; + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_ASSOCIATION_MODE, + &arg, sizeof(arg)); +} + +int wfx_hif_set_tx_rate_retry_policy(struct wfx_vif *wvif, int policy_index, u8 *rates) +{ + struct wfx_hif_mib_set_tx_rate_retry_policy *arg; + size_t size = struct_size(arg, tx_rate_retry_policy, 1); + int ret; + + arg = kzalloc(size, GFP_KERNEL); + if (!arg) + return -ENOMEM; + arg->num_tx_rate_policies = 1; + arg->tx_rate_retry_policy[0].policy_index = policy_index; + arg->tx_rate_retry_policy[0].short_retry_count = 255; + arg->tx_rate_retry_policy[0].long_retry_count = 255; + arg->tx_rate_retry_policy[0].first_rate_sel = 1; + arg->tx_rate_retry_policy[0].terminate = 1; + arg->tx_rate_retry_policy[0].count_init = 1; + memcpy(&arg->tx_rate_retry_policy[0].rates, rates, + sizeof(arg->tx_rate_retry_policy[0].rates)); + ret = wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY, + arg, size); + kfree(arg); + return ret; +} + +int wfx_hif_keep_alive_period(struct wfx_vif *wvif, int period) +{ + struct wfx_hif_mib_keep_alive_period arg = { + .keep_alive_period = cpu_to_le16(period), + }; + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_KEEP_ALIVE_PERIOD, + &arg, sizeof(arg)); +}; + +int wfx_hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx, __be32 *addr) +{ + struct wfx_hif_mib_arp_ip_addr_table arg = { + .condition_idx = idx, + .arp_enable = HIF_ARP_NS_FILTERING_DISABLE, + }; + + if (addr) { + /* Caution: type of addr is __be32 */ + memcpy(arg.ipv4_address, addr, sizeof(arg.ipv4_address)); + arg.arp_enable = HIF_ARP_NS_FILTERING_ENABLE; + } + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE, + &arg, sizeof(arg)); +} + +int wfx_hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable) +{ + struct wfx_hif_mib_gl_set_multi_msg arg = { + .enable_multi_tx_conf = enable, + }; + + return wfx_hif_write_mib(wdev, -1, HIF_MIB_ID_GL_SET_MULTI_MSG, &arg, sizeof(arg)); +} + +int wfx_hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val) +{ + struct wfx_hif_mib_set_uapsd_information arg = { }; + + if (val & BIT(IEEE80211_AC_VO)) + arg.trig_voice = 1; + if (val & BIT(IEEE80211_AC_VI)) + arg.trig_video = 1; + if (val & BIT(IEEE80211_AC_BE)) + arg.trig_be = 1; + if (val & BIT(IEEE80211_AC_BK)) + arg.trig_bckgrnd = 1; + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SET_UAPSD_INFORMATION, + &arg, sizeof(arg)); +} + +int wfx_hif_erp_use_protection(struct wfx_vif *wvif, bool enable) +{ + struct wfx_hif_mib_non_erp_protection arg = { + .use_cts_to_self = enable, + }; + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_NON_ERP_PROTECTION, + &arg, sizeof(arg)); +} + +int wfx_hif_slot_time(struct wfx_vif *wvif, int val) +{ + struct wfx_hif_mib_slot_time arg = { + .slot_time = cpu_to_le32(val), + }; + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_SLOT_TIME, &arg, sizeof(arg)); +} + +int wfx_hif_wep_default_key_id(struct wfx_vif *wvif, int val) +{ + struct wfx_hif_mib_wep_default_key_id arg = { + .wep_default_key_id = val, + }; + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID, + &arg, sizeof(arg)); +} + +int wfx_hif_rts_threshold(struct wfx_vif *wvif, int val) +{ + struct wfx_hif_mib_dot11_rts_threshold arg = { + .threshold = cpu_to_le32(val >= 0 ? val : 0xFFFF), + }; + + return wfx_hif_write_mib(wvif->wdev, wvif->id, HIF_MIB_ID_DOT11_RTS_THRESHOLD, + &arg, sizeof(arg)); +} diff --git a/drivers/net/wireless/silabs/wfx/hif_tx_mib.h b/drivers/net/wireless/silabs/wfx/hif_tx_mib.h new file mode 100644 index 000000000000..bcd4ef6a8497 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/hif_tx_mib.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Implementation of the host-to-chip MIBs of the hardware API. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + * Copyright (C) 2010, ST-Ericsson SA + */ +#ifndef WFX_HIF_TX_MIB_H +#define WFX_HIF_TX_MIB_H + +#include + +struct sk_buff; +struct wfx_vif; +struct wfx_dev; +struct wfx_hif_ie_table_entry; +struct wfx_hif_mib_extended_count_table; + +int wfx_hif_set_output_power(struct wfx_vif *wvif, int val); +int wfx_hif_set_beacon_wakeup_period(struct wfx_vif *wvif, + unsigned int dtim_interval, unsigned int listen_interval); +int wfx_hif_set_rcpi_rssi_threshold(struct wfx_vif *wvif, int rssi_thold, int rssi_hyst); +int wfx_hif_get_counters_table(struct wfx_dev *wdev, int vif_id, + struct wfx_hif_mib_extended_count_table *arg); +int wfx_hif_set_macaddr(struct wfx_vif *wvif, u8 *mac); +int wfx_hif_set_rx_filter(struct wfx_vif *wvif, bool filter_bssid, bool fwd_probe_req); +int wfx_hif_set_beacon_filter_table(struct wfx_vif *wvif, int tbl_len, + const struct wfx_hif_ie_table_entry *tbl); +int wfx_hif_beacon_filter_control(struct wfx_vif *wvif, int enable, int beacon_count); +int wfx_hif_set_operational_mode(struct wfx_dev *wdev, enum wfx_hif_op_power_mode mode); +int wfx_hif_set_template_frame(struct wfx_vif *wvif, struct sk_buff *skb, + u8 frame_type, int init_rate); +int wfx_hif_set_mfp(struct wfx_vif *wvif, bool capable, bool required); +int wfx_hif_set_block_ack_policy(struct wfx_vif *wvif, u8 tx_tid_policy, u8 rx_tid_policy); +int wfx_hif_set_association_mode(struct wfx_vif *wvif, int ampdu_density, + bool greenfield, bool short_preamble); +int wfx_hif_set_tx_rate_retry_policy(struct wfx_vif *wvif, int policy_index, u8 *rates); +int wfx_hif_keep_alive_period(struct wfx_vif *wvif, int period); +int wfx_hif_set_arp_ipv4_filter(struct wfx_vif *wvif, int idx, __be32 *addr); +int wfx_hif_use_multi_tx_conf(struct wfx_dev *wdev, bool enable); +int wfx_hif_set_uapsd_info(struct wfx_vif *wvif, unsigned long val); +int wfx_hif_erp_use_protection(struct wfx_vif *wvif, bool enable); +int wfx_hif_slot_time(struct wfx_vif *wvif, int val); +int wfx_hif_wep_default_key_id(struct wfx_vif *wvif, int val); +int wfx_hif_rts_threshold(struct wfx_vif *wvif, int val); + +#endif From patchwork Tue Jan 11 17:14:14 2022 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: 531336 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7943CC43219 for ; Tue, 11 Jan 2022 17:17:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344485AbiAKRR3 (ORCPT ); Tue, 11 Jan 2022 12:17:29 -0500 Received: from mail-mw2nam10on2078.outbound.protection.outlook.com ([40.107.94.78]:38384 "EHLO NAM10-MW2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1344219AbiAKRQS (ORCPT ); Tue, 11 Jan 2022 12:16:18 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HHkT3IGsQwpUuxfxaX3xJTt70jWLU4XgW73nB+xWdj1SanO6GR72iJzlLs2sMGEugCwJunzZqaiAVIdaPOzzKGJJgrCDr36jJAvQEojmh1Qh60/reCMvDZHmMONjkAzl0QmRwl38UmtTR7FNSgDjL0Mq++AVm+WEpxZbdb9+t/OXiuOe+/gT4TpXGHxhpTXrWIWlvYlYrUJLbz70k9pd3FR2RUzd/vAG2LQOQkGJAEnAkonKj6SWlEsOe/HMUdLnJreD1HW9udDcKRKhSnSzKzdQx83kIW1hdIH+HGFrTDiO7d2Fan2VWQBo4p9iIHilEaaeftWg4l3p1NMWFInHpw== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=+q5yFVw1FvWVOxPW6sYuS3FQ744kmiWczGiDFWXd7G0=; b=WLFl+HFepSWSVJktk0Y/7SCzbIML25Hi5mjmEoEQhphY6aeXCpqxPJ/pKIj8qyNyoOTuIEvLPl6SGra7VhsyVtXWPcl8AQlb4O/J+zEpPhZ1+6NAtduAeRoHkRn+pqp0xaF6BKU8AlVpl/9IPQjmv+4nZBT5fj1xTu3OIxxGzGlqHTh3WUmMyaTlLjs5j1KJUok137mV5G1805WyTJY/7EFLs4F63vJ94a8v/25T6EKxtlsc/MGtHAeeHS3m/TCr7unXyMkfuiEaiyVHYmt2++aj4TmzzFcEoU1Uqcb+3svZb64kZ1A962pnKndmUdOLoTYp9QWWchCWIfcNXWh8rg== 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=+q5yFVw1FvWVOxPW6sYuS3FQ744kmiWczGiDFWXd7G0=; b=DZpj8pSWJ7cCN7YQsLhfSeU7Ta+fWfGxUM8mMZcPxdJhtrGSXWdZmctnFX/5Qy5XTXwjtEEZanmgPetPtFP/SbMOj6Npzs6ZwYfUzTXtsEv+otKWWq5o2R/t/KwsXlC2Nxhe/kLa/qqmR4/89iH5fpGmq5XFUgEUblnUv9XkZ8M= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5609.namprd11.prod.outlook.com (2603:10b6:510:e0::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.9; Tue, 11 Jan 2022 17:15:22 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:22 +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 v9 14/24] wfx: add key.c/key.h Date: Tue, 11 Jan 2022 18:14:14 +0100 Message-Id: <20220111171424.862764-15-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 41342c22-ddfa-4a2e-ac1f-08d9d525f378 X-MS-TrafficTypeDiagnostic: PH0PR11MB5609:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:346; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: qgiixNqVEDggbc77i324j3R9hTh0u4QZsnHKec/0pUcegtcL9kWyvTXjo/sH993UTjUbSlW5wJ3+uYDkpZ/+8SreClQbX+roC2QjnmYLX2GSaPYdfFw/Ofpk7N6aJBjMCsgIoIg97w30Uhk410TFJ7KxQ29gjpugD51MeUFvrydl2S0TnL7YddTpoCSntdTwgJj4+g3/1H6+dQjUX4EYWuKUCdMIqMi6SxeNaKfkdxKl4WFyyZoQ7rHh9a15bP8U/ebrTg9tz/xYhIXFb+71SALQ6cL/fYNrQ1PWmfoL1BK7kYKdIVAOrtjKspabY+yTsUgK05ITr55ZH+rmvgm3bNUHRejsw4jnF+UgJDJc+t6XdAJwrXjEBOxYexM7t/1jhNqIBmnSMqVJuJmKuySaAOH26nymG0w8vBy3CxrZ22wXFY6R2Mc1CRhxOTADJTPCGfKT6azJ7hMA1qCjWNcm0rS+KWEWD5sMrDLocgfvaBvla5A2dP03TpPBJW5URsPaooUTDIkYMJlafy1eSePJafKWjIpGGl4CCHqCWO3/CjApJW3X44F8FPqeGvvsQyZ3FxjiM3Pd6Xekkl27n4DAC4+3E+/8kaU7uOqgooAdM/42tcolYAxg4mbMdr/rM0rWQIjyLZkrXPMW/hHTiPKF4Q== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(5660300002)(8676002)(36756003)(38100700002)(186003)(7416002)(66476007)(54906003)(6486002)(6916009)(6512007)(4326008)(508600001)(107886003)(66946007)(6666004)(2616005)(1076003)(8936002)(66556008)(86362001)(2906002)(6506007)(52116002)(66574015)(316002)(83380400001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?rBak05GviRM3B3kusHDSw+SLwZ7I?= =?utf-8?q?vRWCmdUavDyZDJM8hdpvIRIG7QoaOJnNppo9U+SmpjtwGlYtg+elpEghon5h7Nlru?= =?utf-8?q?Fxcbr79UwDKRJ2YnnLcpB2uaIn3eYZ2D9cMk5/yqNSd6rmW4kfke4JPLdU44BniBE?= =?utf-8?q?cnKGqbKb2k3xDgXoowbxN4pmN/O5KIKVT9d/4F/CKU1tqXoY9YiqwCNkbger70oco?= =?utf-8?q?UNt5+IXE+BuKqj9mReK/owCL/SbTaBcVzqVfi705vbEB2xzX+t3CggQUO2pFNiwYn?= =?utf-8?q?e7OPhEazHUk0JhMfnsRzv4ROAyJlzXaSfqbHAcxweTtAVyIu0vLAEcHOi0dFAnl6h?= =?utf-8?q?P6nyoJGA8ope4p5X7dEWXy2bDdHEolo5mmP+5hMEqYSX/NsqWw/YtnggnkANLECxs?= =?utf-8?q?rPvP9GLOFogrt1LURY6VTL1/ejCIPfPnrqPgdBG/n91C1AVbVr9lnxOp/fnxnklC2?= =?utf-8?q?Oj+IdK4H+T2sCAetQ0NrZ7HxlRU1rNok6v1V702w1ceq7wGD4qzC/IK6vsV0ld4iJ?= =?utf-8?q?xPpzT/dk1cOJBzDnK3LWFTy2H4B15phIpuBsR5BwCB0/1MHpNxT8/tjHFQ4J/7KLj?= =?utf-8?q?7lUPlXb+BP51cTgo9RuP3kbDZQh+p/E2yqI0Sioqze6tOOq7azlMCg7Dscoa2JziX?= =?utf-8?q?ORmPkEjO6BH78xDYgoLBZ1sn3qKwLcncYqm3OmWY5o8ynpdjTQrgsn1jWl85eQtQK?= =?utf-8?q?7jYwXwo4G8rVS6tYmzMAU0ceQ09kXQbIdELlCKYSnUh0W2tixNB5SZ3NJKYplDPvF?= =?utf-8?q?5pUcVDf3Qmm6Aqv/C+x7xZcJrwbpuNw8B7k8HX/yM+MlDP4CqI7Goa4uTt6zo2clC?= =?utf-8?q?yvngnO9ZlNq0FdJLhvz1BM8c4LbOkVELh23VB16BDAxHN19oAw7FgAO5rejKqittO?= =?utf-8?q?aoiNgBmHvEf0sUjHJRasQIPU2xRNGasRiIwimb/4TT/HLhFWml06869hO9KJpyh08?= =?utf-8?q?/znWiqawSsVb/r44Crty4NjMPj4qblu7SmkN7hAa3ueqJ1j+BIc/iQGRy/1y/5b46?= =?utf-8?q?4ePJiQDSmHOL/yeqA0m7wjmLb3pmA4VdceMocbRGPP9DwlhDdKCKARuTjLTv9sIoR?= =?utf-8?q?c98O8QCLO6n0BTrEK/XdbnGZ4FgS3AsDK3d/VymQNtHOJ5x0LVeHz1vZ2oJGyWLLh?= =?utf-8?q?bBnWiMFCKefhqdK7j+Bh4iQ2NVRUb7TkY2FnUJuKcK3Q2ViitfJ1R+Z2TssFM6qc6?= =?utf-8?q?SjyiBI2v0rloTAs/P8nejaGtvW/bp6bEm0ZLOBXNAzvoedrO9EJRTfae4tKeQX6mi?= =?utf-8?q?ZHFFsFMsDqy1kxHiYiEZ8DdU348UNlUuv5yFeR4SNl1NmE/qgTlVknQgEzYJ1IJq6?= =?utf-8?q?07NL8NNqfFS/SNdKphleEvW3CMbFmGumh3/NNakV+lzuiNGZrA4h9kfyBZgD5maB9?= =?utf-8?q?NK8AETaFbk+rJwV8w6OV8fy9f6Nb9xNPxyflQEG+EShr3kJLNkw2wdm+BKmu549MX?= =?utf-8?q?DKUADt6hoDJvIrW7vmzhI29zrVbCV8XUOisXaf+pHlfXakx9HUdgwxQ8vZD7ab1x0?= =?utf-8?q?nelv2gc4oZIhyqB+8yOmqDUX6Z21SfuOO1xk+rkc1ar00k1dxARnGnPNCYeUS0dGi?= =?utf-8?q?lpHvgdU+OSxXPP6gYwzrH6vn0tcdxRJy3u8p2Aon7FThjnvrSWjF1c=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 41342c22-ddfa-4a2e-ac1f-08d9d525f378 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:22.6958 (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: KHqtHlSxS68Qhr0TfCrKhzs19DQ2YF5FgCQyR51fuda0PVFOhkzZYlDJtFZirVL1HLyf+151V2NnKMwa6H/0mA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5609 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/key.c | 227 ++++++++++++++++++++++++++ drivers/net/wireless/silabs/wfx/key.h | 19 +++ 2 files changed, 246 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/key.c create mode 100644 drivers/net/wireless/silabs/wfx/key.h diff --git a/drivers/net/wireless/silabs/wfx/key.c b/drivers/net/wireless/silabs/wfx/key.c new file mode 100644 index 000000000000..8f23e8d42bd4 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/key.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Key management related functions. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#include +#include + +#include "key.h" +#include "wfx.h" +#include "hif_tx_mib.h" + +static int wfx_alloc_key(struct wfx_dev *wdev) +{ + int idx; + + idx = ffs(~wdev->key_map) - 1; + if (idx < 0 || idx >= MAX_KEY_ENTRIES) + return -1; + + wdev->key_map |= BIT(idx); + return idx; +} + +static void wfx_free_key(struct wfx_dev *wdev, int idx) +{ + WARN(!(wdev->key_map & BIT(idx)), "inconsistent key allocation"); + wdev->key_map &= ~BIT(idx); +} + +static u8 fill_wep_pair(struct wfx_hif_wep_pairwise_key *msg, + struct ieee80211_key_conf *key, u8 *peer_addr) +{ + WARN(key->keylen > sizeof(msg->key_data), "inconsistent data"); + msg->key_length = key->keylen; + memcpy(msg->key_data, key->key, key->keylen); + ether_addr_copy(msg->peer_address, peer_addr); + return HIF_KEY_TYPE_WEP_PAIRWISE; +} + +static u8 fill_wep_group(struct wfx_hif_wep_group_key *msg, + struct ieee80211_key_conf *key) +{ + WARN(key->keylen > sizeof(msg->key_data), "inconsistent data"); + msg->key_id = key->keyidx; + msg->key_length = key->keylen; + memcpy(msg->key_data, key->key, key->keylen); + return HIF_KEY_TYPE_WEP_DEFAULT; +} + +static u8 fill_tkip_pair(struct wfx_hif_tkip_pairwise_key *msg, + struct ieee80211_key_conf *key, u8 *peer_addr) +{ + u8 *keybuf = key->key; + + WARN(key->keylen != sizeof(msg->tkip_key_data) + sizeof(msg->tx_mic_key) + + sizeof(msg->rx_mic_key), "inconsistent data"); + memcpy(msg->tkip_key_data, keybuf, sizeof(msg->tkip_key_data)); + keybuf += sizeof(msg->tkip_key_data); + memcpy(msg->tx_mic_key, keybuf, sizeof(msg->tx_mic_key)); + keybuf += sizeof(msg->tx_mic_key); + memcpy(msg->rx_mic_key, keybuf, sizeof(msg->rx_mic_key)); + ether_addr_copy(msg->peer_address, peer_addr); + return HIF_KEY_TYPE_TKIP_PAIRWISE; +} + +static u8 fill_tkip_group(struct wfx_hif_tkip_group_key *msg, struct ieee80211_key_conf *key, + struct ieee80211_key_seq *seq, enum nl80211_iftype iftype) +{ + u8 *keybuf = key->key; + + WARN(key->keylen != sizeof(msg->tkip_key_data) + 2 * sizeof(msg->rx_mic_key), + "inconsistent data"); + msg->key_id = key->keyidx; + memcpy(msg->rx_sequence_counter, &seq->tkip.iv16, sizeof(seq->tkip.iv16)); + memcpy(msg->rx_sequence_counter + sizeof(u16), &seq->tkip.iv32, sizeof(seq->tkip.iv32)); + memcpy(msg->tkip_key_data, keybuf, sizeof(msg->tkip_key_data)); + keybuf += sizeof(msg->tkip_key_data); + if (iftype == NL80211_IFTYPE_AP) + /* Use Tx MIC Key */ + memcpy(msg->rx_mic_key, keybuf + 0, sizeof(msg->rx_mic_key)); + else + /* Use Rx MIC Key */ + memcpy(msg->rx_mic_key, keybuf + 8, sizeof(msg->rx_mic_key)); + return HIF_KEY_TYPE_TKIP_GROUP; +} + +static u8 fill_ccmp_pair(struct wfx_hif_aes_pairwise_key *msg, + struct ieee80211_key_conf *key, u8 *peer_addr) +{ + WARN(key->keylen != sizeof(msg->aes_key_data), "inconsistent data"); + ether_addr_copy(msg->peer_address, peer_addr); + memcpy(msg->aes_key_data, key->key, key->keylen); + return HIF_KEY_TYPE_AES_PAIRWISE; +} + +static u8 fill_ccmp_group(struct wfx_hif_aes_group_key *msg, + struct ieee80211_key_conf *key, struct ieee80211_key_seq *seq) +{ + WARN(key->keylen != sizeof(msg->aes_key_data), "inconsistent data"); + memcpy(msg->aes_key_data, key->key, key->keylen); + memcpy(msg->rx_sequence_counter, seq->ccmp.pn, sizeof(seq->ccmp.pn)); + memreverse(msg->rx_sequence_counter, sizeof(seq->ccmp.pn)); + msg->key_id = key->keyidx; + return HIF_KEY_TYPE_AES_GROUP; +} + +static u8 fill_sms4_pair(struct wfx_hif_wapi_pairwise_key *msg, + struct ieee80211_key_conf *key, u8 *peer_addr) +{ + u8 *keybuf = key->key; + + WARN(key->keylen != sizeof(msg->wapi_key_data) + sizeof(msg->mic_key_data), + "inconsistent data"); + ether_addr_copy(msg->peer_address, peer_addr); + memcpy(msg->wapi_key_data, keybuf, sizeof(msg->wapi_key_data)); + keybuf += sizeof(msg->wapi_key_data); + memcpy(msg->mic_key_data, keybuf, sizeof(msg->mic_key_data)); + msg->key_id = key->keyidx; + return HIF_KEY_TYPE_WAPI_PAIRWISE; +} + +static u8 fill_sms4_group(struct wfx_hif_wapi_group_key *msg, + struct ieee80211_key_conf *key) +{ + u8 *keybuf = key->key; + + WARN(key->keylen != sizeof(msg->wapi_key_data) + sizeof(msg->mic_key_data), + "inconsistent data"); + memcpy(msg->wapi_key_data, keybuf, sizeof(msg->wapi_key_data)); + keybuf += sizeof(msg->wapi_key_data); + memcpy(msg->mic_key_data, keybuf, sizeof(msg->mic_key_data)); + msg->key_id = key->keyidx; + return HIF_KEY_TYPE_WAPI_GROUP; +} + +static u8 fill_aes_cmac_group(struct wfx_hif_igtk_group_key *msg, + struct ieee80211_key_conf *key, struct ieee80211_key_seq *seq) +{ + WARN(key->keylen != sizeof(msg->igtk_key_data), "inconsistent data"); + memcpy(msg->igtk_key_data, key->key, key->keylen); + memcpy(msg->ipn, seq->aes_cmac.pn, sizeof(seq->aes_cmac.pn)); + memreverse(msg->ipn, sizeof(seq->aes_cmac.pn)); + msg->key_id = key->keyidx; + return HIF_KEY_TYPE_IGTK_GROUP; +} + +static int wfx_add_key(struct wfx_vif *wvif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + int ret; + struct wfx_hif_req_add_key k = { }; + struct ieee80211_key_seq seq; + struct wfx_dev *wdev = wvif->wdev; + int idx = wfx_alloc_key(wvif->wdev); + bool pairwise = key->flags & IEEE80211_KEY_FLAG_PAIRWISE; + + WARN(key->flags & IEEE80211_KEY_FLAG_PAIRWISE && !sta, "inconsistent data"); + ieee80211_get_key_rx_seq(key, 0, &seq); + if (idx < 0) + return -EINVAL; + k.int_id = wvif->id; + k.entry_index = idx; + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) { + if (pairwise) + k.type = fill_wep_pair(&k.key.wep_pairwise_key, key, sta->addr); + else + k.type = fill_wep_group(&k.key.wep_group_key, key); + } else if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { + if (pairwise) + k.type = fill_tkip_pair(&k.key.tkip_pairwise_key, key, sta->addr); + else + k.type = fill_tkip_group(&k.key.tkip_group_key, key, &seq, + wvif->vif->type); + } else if (key->cipher == WLAN_CIPHER_SUITE_CCMP) { + if (pairwise) + k.type = fill_ccmp_pair(&k.key.aes_pairwise_key, key, sta->addr); + else + k.type = fill_ccmp_group(&k.key.aes_group_key, key, &seq); + } else if (key->cipher == WLAN_CIPHER_SUITE_SMS4) { + if (pairwise) + k.type = fill_sms4_pair(&k.key.wapi_pairwise_key, key, sta->addr); + else + k.type = fill_sms4_group(&k.key.wapi_group_key, key); + } else if (key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { + k.type = fill_aes_cmac_group(&k.key.igtk_group_key, key, &seq); + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE; + } else { + dev_warn(wdev->dev, "unsupported key type %d\n", key->cipher); + wfx_free_key(wdev, idx); + return -EOPNOTSUPP; + } + ret = wfx_hif_add_key(wdev, &k); + if (ret) { + wfx_free_key(wdev, idx); + return -EOPNOTSUPP; + } + key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE | IEEE80211_KEY_FLAG_RESERVE_TAILROOM; + key->hw_key_idx = idx; + return 0; +} + +static int wfx_remove_key(struct wfx_vif *wvif, struct ieee80211_key_conf *key) +{ + WARN(key->hw_key_idx >= MAX_KEY_ENTRIES, "corrupted hw_key_idx"); + wfx_free_key(wvif->wdev, key->hw_key_idx); + return wfx_hif_remove_key(wvif->wdev, key->hw_key_idx); +} + +int wfx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct ieee80211_key_conf *key) +{ + int ret = -EOPNOTSUPP; + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + mutex_lock(&wvif->wdev->conf_mutex); + if (cmd == SET_KEY) + ret = wfx_add_key(wvif, sta, key); + if (cmd == DISABLE_KEY) + ret = wfx_remove_key(wvif, key); + mutex_unlock(&wvif->wdev->conf_mutex); + return ret; +} + diff --git a/drivers/net/wireless/silabs/wfx/key.h b/drivers/net/wireless/silabs/wfx/key.h new file mode 100644 index 000000000000..2234e36dbbcd --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/key.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Key management related functions. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#ifndef WFX_KEY_H +#define WFX_KEY_H + +#include + +struct wfx_dev; +struct wfx_vif; + +int wfx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct ieee80211_key_conf *key); + +#endif From patchwork Tue Jan 11 17:14:16 2022 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: 531340 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DD2AC4332F for ; Tue, 11 Jan 2022 17:16:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344069AbiAKRQD (ORCPT ); Tue, 11 Jan 2022 12:16:03 -0500 Received: from mail-dm6nam08on2088.outbound.protection.outlook.com ([40.107.102.88]:54880 "EHLO NAM04-DM6-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1344083AbiAKRPa (ORCPT ); Tue, 11 Jan 2022 12:15:30 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=H66fWT+z7L7rQiGvsf5uD+12aaFh5xPLCJ003QTwqgLCHHDU1gfca4S4bJymq1OwjJ4wKhHN1Qd6n/ceHcyjw4KgXBHvwQ/vDh4p2S+PpGlIhCGxDZ0/fZ8bONV53TSxf4mXg+FiujR5f4/kQfUvQ/tbXMNlGTZLbVw72zMCqb7gEH26xxQI4XoSl04jkg+kTrOWUzFiDpcd6PSjEtBcI/7gjXa+0LQTib5Cm1vHnnqoEVjehfRlo4itz9KwkMNydqXUzmtcZikn4svzUoXfl+EqMi0aA+PhDc1faVuVKV9qBsZMzj1rbRjEqxWLp/ok5jTyNbCMefCotpxhRNbIVQ== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Laa+FpIvHKHjdSdPVWts6lBXNK06rPxwoCWe69GbX7w=; b=cZ5kXiOkIGT9Mf480jAE0NyBhOj9vSxBURMwzXl0WZLNTEumPUYI9pxiD5SYOj+Ygrx2M0Cl5sEpCnGnA+KvZ/nbXu5ry/PaSULVkuy7RoYPR1MNI5IiLuX0ucxK3pU8PQTiP5nY1dyEfgFe5BoBOjfgtsPDdraXiSLtbI2PVLgjsOpEgCsGZj7+DcEx7HMljvFAf9xh0cHNVXV9B/JWFS1pQXPzQzccNyB3eBx3gxVQH1j8lKfoZ1IiUOq0498JUmh55w3fBzPPnR2ZlH76N60jBNLzj76mAN69eFta6AakIH5x2Vy4G9Ks2d9l8yLJMctPNxNwHXfVrlv2++0taA== 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=Laa+FpIvHKHjdSdPVWts6lBXNK06rPxwoCWe69GbX7w=; b=j9p8ep2rascBdDE45waMuUCFjEm3opUhAxhtk4Oqx/0riCZntnpLopLJGHP3Fh2NLOkRkfpIf0N7h/qJ8K2mQXtjrwAaFqB+266jvav1U7nLkV3pjkysbvcn4K7S1edqQ3cE7wgWk+JY+iozeH0CtzVssf3mR4uICWdHEBhzNE4= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5626.namprd11.prod.outlook.com (2603:10b6:510:ee::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.9; Tue, 11 Jan 2022 17:15:28 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:28 +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 v9 16/24] wfx: add data_rx.c/data_rx.h Date: Tue, 11 Jan 2022 18:14:16 +0100 Message-Id: <20220111171424.862764-17-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 469599b6-2308-4bb0-6234-08d9d525f6ad X-MS-TrafficTypeDiagnostic: PH0PR11MB5626:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:644; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: I9D0n3tdHc+ykpzBdGXADWpQImsdyeUG2EyAzghxVS+7KFmZ4waOJS0KGRQ9CBL5kIIsi+lr9jTscUqyi4bAdYa8duJvlptscB3dU53UhlpIO1cqsXpw8ho+7dnxJjRnpiRf+y7Nr7aK0mRQA6ePxlrOJLBRg/fjBxUa9OvTa4OxbRcboFwjScqEYcEbd9N1maKa7naIsmCqq4b5cWDZuJAJOnDLRTWUUyvnBivQMz9iv+TwEbmRt3ZH3qfNI1xHV5y/01WK1+2cRINsqu52BvTeE+5jGn/Ia9YV+9FOF5UvSXbPEq43kmoIWNS2++0Fnb1EGwD2VzWLYVEqXWauMFfy/KTuEHyMsiIx5wVeHmFM+bqF8g3Ip+sAAjtJSqEG9asA791f1refqkOm3491PlaN6PGws8H48oVVI4mtHdF4bYSZQ9yDx1UKthA0YeOYKkvCHuE+YrZfaCDOFyZeeSkqNa0QbXq3ATCb3+StEgYSoUQJWJM9p1GI3qTjeRYGeyQEX40YLvzdKq0WJl8xgaesRaPXNAqHZVaAJamJJX3QJsr+vB+uFNNepx/0ysxIL1m5FXiU3kV6JkZocq14zmbYyvyNnsTsci7BDb4TSktzpzQLrJ+3MGOC9/cbcSHhd4fhPYLJNGfa48IC0bui0Q== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(1076003)(83380400001)(38100700002)(54906003)(86362001)(8676002)(186003)(508600001)(6512007)(6666004)(8936002)(6916009)(6506007)(36756003)(2616005)(6486002)(52116002)(2906002)(107886003)(4326008)(316002)(5660300002)(7416002)(66556008)(66946007)(66476007); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?2yRI4Y2zDpUKNEhNc3rJ6dTxKLUq?= =?utf-8?q?BAnNHA2nkJr1zc/wkyS7TvykoeJLNWMyO6hG92157lc0Ta4hgn/qT3V2XZ+DnXRmA?= =?utf-8?q?B8KEa8WWtkFA1d3F5tXbCYlDX4l0NN/aPshbEJ1Hu53jx6PrVU3+PeK7c62dfTiaw?= =?utf-8?q?0SN0uqsvbN058JbBt+QjmQMV5gSuTgtTYgHEjxIJMv0CRcTjYiXKaKPPd3xbJgQT9?= =?utf-8?q?eyNzaGOgnot/6A+t9KpIJdWzpLyAN6rrwLKjGDS375w7DnakCY0RXhHGQRqEMpYCK?= =?utf-8?q?euA3KFOTXYkD8lH6bB+wNOLzoHzt36unfyIRLCX+NU9XszCwIVwS5GYtqzsfOp79p?= =?utf-8?q?ckCvNFnAgYQIjlUB19SHM3aSsl1G9tollxeffLV7B00/GuxhFQUQ5rsEGYQOiql0w?= =?utf-8?q?fksJRvxHu9NnqNEru9v8YAyjbB74mjVsDU3Mom2N6uCD7Mo8zl1MoaE+pAljRU8xa?= =?utf-8?q?VPMD7bpEYQGInZpa0F++Y4wULCH+ngR8bhsrKyTWsj2NHdSaqlpOBKueKtYA9Uv41?= =?utf-8?q?plESm8rvYOHceS6RJbWUfrtrY5Fxvdi8GZSxlR7otHt4Uc/Uvhxtg4yOlzcxSQPQ1?= =?utf-8?q?tlYiex0V2TjnqIu62UXH4kkE4peFm+55bF+tOCEoIeVdA+jP5iz3tH1uxc/GYj2ZD?= =?utf-8?q?od0TCdv4JO4+CON7QCV3iO6sMgCbKIUIALlI5nVjRs5sSzDvJnE86UZbfxNzmNu6w?= =?utf-8?q?rh5pbvboY1mrA7UkyN/zAfBlRUQItK4crHkNgbQb3DpSA6pNKzF+UkjUr1h7feM0i?= =?utf-8?q?SAsMMGPr2ZJPLvEbGbRamc5UxfqNTaeTc109vcnTSCmKwiY7YVrFamTB6VFGrmsOh?= =?utf-8?q?szq8Q3C3Z8+cH0vfL+6IQQDuGvD3rYkZ/G9mTkX19les0GYkgdLABpHIxqNt38aqA?= =?utf-8?q?S4C4E8fV0XnUcnjmVzBORbtKNPhxXatRtpCjpnwaoyxffnAPHr23ZZk/KQPHn/8NZ?= =?utf-8?q?Jtfz6Rn4UdUZjZbSe1SJ1unxQ5k5Q9Bgl1lT2F+Z9F6lpQNqza3amJU39bBcOile4?= =?utf-8?q?v4gUg+klLGBF1OEm8UttGo+yLMWjPF3nk/uvj9PjDAJ42r4TWhSnqeX9qahmrn2Pu?= =?utf-8?q?Kih9qyhaQBKIMSTzDHZvWCQzKofsnBvMC61S3cE+6Q8HLp/pt8EBrE1AaBGoGM+mZ?= =?utf-8?q?UzCAKV7SnNleYfXYxx8xbb2d6skKP1sW2JLmNG+oBVSxfAM5bcX5QZPLE++XER4Av?= =?utf-8?q?WS5XJUiK4irRhcRkWxMh5FBMcNtdBbOr3k9VOZkJwG/LKYoYxIh8AoNFZF4Z/gVtd?= =?utf-8?q?ptSCCell7muC/EqOchJxFbOucgqOhYUh5p7E5mu3TlhJY6G5ja4b3Ko9bqK31WZiy?= =?utf-8?q?hScRHMZaRdP+RJt9RXMnzZWM5btIqtzmnkRCPZbWbvD4LvNHvsLBRppkgudvwUpKB?= =?utf-8?q?GFTbipSHKbmOu+KDUQDovcRMIqOuF3HRwRwc2DSW73iho6CALtRaVZyk5R3PBnk7i?= =?utf-8?q?u10GNlYnMgogFDxXSFPUVasbHp+wskPmXEJ7gGHE8vdYua4JuFkpvZOlsUXx3OQM5?= =?utf-8?q?bHNCveqdoxMwLEyunOhsHCj5DiGaxAEYy6YBH4t7tj38LOO+bAdkVGGpd+Yuu/4KD?= =?utf-8?q?Tp+dgNQ3Gs1DPgbYXg9VHuVDmxgvKg2Vzx6lNwiUQbDSyfYJOe58kU=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 469599b6-2308-4bb0-6234-08d9d525f6ad X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:28.1824 (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: e48AqxcoyFEOGQtGD8EVq0jCPWuN7KkaY2U8KW3EXTp1U0M4OWdqVutkANg/dJy+QbPWGjLMUVh0oenPVsM/UQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5626 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/data_rx.c | 92 +++++++++++++++++++++++ drivers/net/wireless/silabs/wfx/data_rx.h | 17 +++++ 2 files changed, 109 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/data_rx.c create mode 100644 drivers/net/wireless/silabs/wfx/data_rx.h diff --git a/drivers/net/wireless/silabs/wfx/data_rx.c b/drivers/net/wireless/silabs/wfx/data_rx.c new file mode 100644 index 000000000000..a4b5ffe158e4 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/data_rx.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Data receiving implementation. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#include +#include + +#include "data_rx.h" +#include "wfx.h" +#include "bh.h" +#include "sta.h" + +static void wfx_rx_handle_ba(struct wfx_vif *wvif, struct ieee80211_mgmt *mgmt) +{ + int params, tid; + + if (wfx_api_older_than(wvif->wdev, 3, 6)) + return; + + switch (mgmt->u.action.u.addba_req.action_code) { + case WLAN_ACTION_ADDBA_REQ: + params = le16_to_cpu(mgmt->u.action.u.addba_req.capab); + tid = (params & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; + ieee80211_start_rx_ba_session_offl(wvif->vif, mgmt->sa, tid); + break; + case WLAN_ACTION_DELBA: + params = le16_to_cpu(mgmt->u.action.u.delba.params); + tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; + ieee80211_stop_rx_ba_session_offl(wvif->vif, mgmt->sa, tid); + break; + } +} + +void wfx_rx_cb(struct wfx_vif *wvif, const struct wfx_hif_ind_rx *arg, struct sk_buff *skb) +{ + struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; + + memset(hdr, 0, sizeof(*hdr)); + + if (arg->status == HIF_STATUS_RX_FAIL_MIC) + hdr->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_IV_STRIPPED; + else if (arg->status) + goto drop; + + if (skb->len < sizeof(struct ieee80211_pspoll)) { + dev_warn(wvif->wdev->dev, "malformed SDU received\n"); + goto drop; + } + + hdr->band = NL80211_BAND_2GHZ; + hdr->freq = ieee80211_channel_to_frequency(arg->channel_number, hdr->band); + + if (arg->rxed_rate >= 14) { + hdr->encoding = RX_ENC_HT; + hdr->rate_idx = arg->rxed_rate - 14; + } else if (arg->rxed_rate >= 4) { + hdr->rate_idx = arg->rxed_rate - 2; + } else { + hdr->rate_idx = arg->rxed_rate; + } + + if (!arg->rcpi_rssi) { + hdr->flag |= RX_FLAG_NO_SIGNAL_VAL; + dev_info(wvif->wdev->dev, "received frame without RSSI data\n"); + } + hdr->signal = arg->rcpi_rssi / 2 - 110; + hdr->antenna = 0; + + if (arg->encryp) + hdr->flag |= RX_FLAG_DECRYPTED; + + /* Block ack negotiation is offloaded by the firmware. However, re-ordering must be done by + * the mac80211. + */ + if (ieee80211_is_action(frame->frame_control) && + mgmt->u.action.category == WLAN_CATEGORY_BACK && + skb->len > IEEE80211_MIN_ACTION_SIZE) { + wfx_rx_handle_ba(wvif, mgmt); + goto drop; + } + + ieee80211_rx_irqsafe(wvif->wdev->hw, skb); + return; + +drop: + dev_kfree_skb(skb); +} diff --git a/drivers/net/wireless/silabs/wfx/data_rx.h b/drivers/net/wireless/silabs/wfx/data_rx.h new file mode 100644 index 000000000000..cf708f16d602 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/data_rx.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Data receiving implementation. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#ifndef WFX_DATA_RX_H +#define WFX_DATA_RX_H + +struct wfx_vif; +struct sk_buff; +struct wfx_hif_ind_rx; + +void wfx_rx_cb(struct wfx_vif *wvif, const struct wfx_hif_ind_rx *arg, struct sk_buff *skb); + +#endif From patchwork Tue Jan 11 17:14:17 2022 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: 531338 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 19755C433FE for ; Tue, 11 Jan 2022 17:16:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344315AbiAKRQl (ORCPT ); Tue, 11 Jan 2022 12:16:41 -0500 Received: from mail-co1nam11on2055.outbound.protection.outlook.com ([40.107.220.55]:7776 "EHLO NAM11-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1343994AbiAKRPr (ORCPT ); Tue, 11 Jan 2022 12:15:47 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FNS4/qrU7/am/kaOwylLa4Ibm91jH16mFrdXHXNHDt2D30K0yXlI6BaUy4JrotJUm0w1cpalCs3jo7flBM/EgXt7CAOJEljIKSeOCCZtGE587v4DOo11njf7zf78lQzDxho8rynvSYCyBQEuBQkOiBVOqTczCewdcXgIcToZjNrB83mKzuPt1B8iARxsTaeZTyOao31h25DBEMbEJAxN+wRsT1kqs+ITEV5tDbdG69GAtGVHMAeEE/y6jQvt4gr75K5y6QD2s2FLsU85PmtiLDD595P9CVVQqy7NJmuS/B23ZrsSlHM3ffm7ecXAx+/jKQ5kKXLChV+h4OmLeZKy+A== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=YFggKABoXG4fFmhLOt6RbZE2kU6NMy/5RXFDbxZ6Ne0=; b=Uv43SAe2D8Qqlg3bqcXhf2jWbQlciUdkCAxYmiw+luuq9BhjZnqFFXEfO0lLMoNgnvzosBPyyq5zRKydQAjKxHtqSAKyzm0fGq1rMQxTs9fq4MXTZt4oY8K2kiwpcGDIhwDVTQiKZAEs2tBqQRADYS0ePFO9xqzXcENeMtILdU8eZ13gc+lfvTX7xIHC5Es4LrUcJtGC5TzI6hiVMdTdhhg9K2JzLJOB3ky7WmasGs+xa2VYIWUUYIcJB99cfjVRpYwtrlh9tw/33Oo+sR4GXfTTVo/vCWR7bEJ0Q+ny71yt6/JKtE8MYKpvvIMdQbivvK1T1FothpMgc9o4RwexUQ== 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=YFggKABoXG4fFmhLOt6RbZE2kU6NMy/5RXFDbxZ6Ne0=; b=ilWLkabirAG1l/oHb6EK/3ozjOJ/SQ3og3Xjm1gDXyXJXKhQ2UAyjQfOhcknJhqPgGvS6+rKFOpemd3HgRTShkLVghr0wSLDudCSGaD3D75KzWrHndQQRtyh2596IAIKY4iqlmb5y6ET7SRFF65mwOYoCq8JFrNLikEVu0jfWA0= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.11; Tue, 11 Jan 2022 17:15:30 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:30 +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 v9 17/24] wfx: add queue.c/queue.h Date: Tue, 11 Jan 2022 18:14:17 +0100 Message-Id: <20220111171424.862764-18-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 95bfafd5-995d-4eb3-4c06-08d9d525f845 X-MS-TrafficTypeDiagnostic: PH0PR11MB5657:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:4714; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: fnQr9yuMGn0jKsFsBAm5kLO+FKs8fdqbgez19u+PUP+XpFfHS5j7HAmJPfrHSS95lk1A9hiLhvq1/7CTvPk6jsIK86KYtJRa59N6QAMDNKyb/MUi/IYfEqYZQsyV3GrK6Zn6TJME6oafRglahirbN4hA/+mjSeBNIBI8DBDFjcHhLxjWWwl1Q3PBbNhK3Miq45WIlZYXYJkNcDjSKxhbqFiXqnLFdNmEY/Edh5X3WlcLc+lyE6dM0W/AY3tzsebv16i7D8aYKq4eiQrpdqHq7f9oQWiTcK1zUr/XsnYi59Bu1Mg1cXM5zQd2gKVK9Jo1m/283fKqPGCMg4Sv5T+krppX1zR6qircghlLv+7aysk+5JO2u4s6AgPlHQNUXEpIKuD9JlYnAfrnmNmppSt+x3auDDKN5o4q9qGaEWGXlEMqMERltZKbMcgC09TQoZ/YQ6Z7xnfLX1g0WbDtWh9o4K43gQBrjxaWIp/9BS8MkEQ+KVWAssBDDVeFQskH0LPjE/8y4GYntp3eoX/tPxizqIEzXnWvKMXkJELudTfAAMQ60tEsnECcPkH2jL84KMT0GmysyW6+q4CzZnsA70YozL5o/k7Hw9odMWkN27P04MmlxZUBJphnNcQDIZu097991MyWsRqkp8NZOH5e5y+k6A== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(6506007)(66574015)(86362001)(5660300002)(8936002)(7416002)(6916009)(8676002)(83380400001)(1076003)(6486002)(36756003)(38100700002)(186003)(66946007)(6666004)(2616005)(4326008)(2906002)(316002)(107886003)(66556008)(66476007)(54906003)(6512007)(508600001)(30864003)(52116002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?hQ+E24dsgZavvUGEAY0EgZ0fD9Xt?= =?utf-8?q?nPXv9nISJ09cbvYByvXNeZaNyan58bSo2W5OPM9V5N1mVzEQB6pT5+vlYfH4SUFIF?= =?utf-8?q?3dvHITdf59krmyPrxOh9COwz/vGCBrHXzibVjE+MnB62igCVkQuTHPWqoMIAGauyF?= =?utf-8?q?SR350wGErdams+oCXhPtXo9J6tFRSAjWbt75v1szp0kPI9zMjwPBgtj8tMPJIfPcl?= =?utf-8?q?niLh3xBh+3GFtOfMSqw41TYBbrBSnAaoLhcTvz9xXGIs1Ycfcp5MUQw58RGgxVyu9?= =?utf-8?q?7H6+gc1SAVSaOF2Ip2I2YxpN97Neufuyw5/om0q7ol3BoVk3T5vB9znqVgVLwFwDF?= =?utf-8?q?VIzNBRe5sf0rLNE3ISbDWSTcK8OymXK8KfNEhBkMjMVH3Y7Tkt8vGwIWsESzISPwn?= =?utf-8?q?b1nopVLDZOeqK7knzhVcwl3lbP1mdyoIbd26lRyasyBQFzJgP9RPDegR0aeMYhNFW?= =?utf-8?q?GX9udElyF4RSbOiaWUMIVKF6XyVTOwPwENqGxVYzE0SC9h/Ni+Um6wjQCB9gsTxh0?= =?utf-8?q?pYTJbEQjzrsqqq4eX9MnWRKzDLRd7/RBTv8PNzaDCsWhpbu0kkXkYLEXBR3husgpY?= =?utf-8?q?DvAr1s7SxJdGGDeHEVQCHklYz4fECcIRZ9tZXzRov/EScSxg0EKYJuJ3YRVcM54ps?= =?utf-8?q?62gtNMb/H25yQG4uHFwL9Ck2tEYrdZHv25tDfiX0n+9TA/0O/di4o1hdxD+5QRcSE?= =?utf-8?q?iD4EV8SWnicrR5jD+1xNKJ6zOFX3kMGlhVyL9kGA8X3Y16xod0xYL6EwgrAFiJVII?= =?utf-8?q?mmxD5o06y43jDH9nWntIH6Tp7iB8zOuKXH82HoI62nSd9AyykaCkjFLkcB2ePOGSy?= =?utf-8?q?QdEM4gqMubz02wNWys3MbjrmWGM8UsulDmLagw1SBXwhCesjGwGTM83KeM5Uy9b9E?= =?utf-8?q?1VO5Z7aedSRwSs4hy69aSdWzLbnjKpzbEcWyLYIxARScJ16y38ubLdMbNSMwZBNHq?= =?utf-8?q?GGSwXoWYMXpMpxoc9Y7b/Yw5tzH6R9wiw7zJtoC6zCCDw9EP1StSld//qozz+eme3?= =?utf-8?q?kcwb4SldSnpmJVdAC54b0Ygci1t9+sly4RC4c5GsPYC7rQGfywMTmkmZnnuZkZT1k?= =?utf-8?q?9f4DMi+F7pGOuzSNqp21ootLTFkQJ03yO4LLlYnfowZJyGEC9I4BGC3YLCM4+WzM7?= =?utf-8?q?NWEamz+0WnVuhNyWYVfgI/P4VVk9DPN1FC8TJlsxnxuz2CI+svWxtnd8vNMc0qRNp?= =?utf-8?q?otgBl6l4ALmmUfKXMyVo3cP50ps7KTYdeJ/aAXvAK8DYMI4X++mue636KAGMVTuBu?= =?utf-8?q?Mjd4NeksXKyZl3ast+AkTWKCY8Djvs5PouPTWL2iQSRs3uZygKjtkHasBNTH4N+PD?= =?utf-8?q?+YSoDRjfGn1dtiVWbI0LuUUW84ea0m+u/vRZ/0u4lAQYSY5FGgVJfbGeVTCT/W3az?= =?utf-8?q?/LsJfmL34WCFhvwm2DtAOJlJovtYgFeQEYCcSvL9C7KBy2vJw2Nq5PRhS4PbADLDs?= =?utf-8?q?k60gH9jzwrRvsnfQnnJV8VMlmMPtdWIjR818LcskF1eTEFyFQkOrRYG1kyZ7i2XGQ?= =?utf-8?q?0bLEmxRFH4DJOzAWUlnEGWnbQVpH14X5ylc80985LBIckl1u6wbsqGCqair/QU4Th?= =?utf-8?q?3UH9ryeNkkgqdKZ3/sXch7GGUiS70CfdjcHpkAh4jiEMh+7T3c43CA=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 95bfafd5-995d-4eb3-4c06-08d9d525f845 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:30.7633 (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: K8YFKi9yeh9/E1rQvgCecUTkjrxjQyQQHEjXuZburcyNtlinP4/PrboqgHt5K8FRabDFdT+o+r/AX/rx5mRpaQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5657 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/queue.c | 298 ++++++++++++++++++++++++ drivers/net/wireless/silabs/wfx/queue.h | 44 ++++ 2 files changed, 342 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/queue.c create mode 100644 drivers/net/wireless/silabs/wfx/queue.h diff --git a/drivers/net/wireless/silabs/wfx/queue.c b/drivers/net/wireless/silabs/wfx/queue.c new file mode 100644 index 000000000000..9186726ff07f --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/queue.c @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Queue between the tx operation and the bh workqueue. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#include +#include + +#include "queue.h" +#include "wfx.h" +#include "sta.h" +#include "data_tx.h" +#include "traces.h" + +void wfx_tx_lock(struct wfx_dev *wdev) +{ + atomic_inc(&wdev->tx_lock); +} + +void wfx_tx_unlock(struct wfx_dev *wdev) +{ + int tx_lock = atomic_dec_return(&wdev->tx_lock); + + WARN(tx_lock < 0, "inconsistent tx_lock value"); + if (!tx_lock) + wfx_bh_request_tx(wdev); +} + +void wfx_tx_flush(struct wfx_dev *wdev) +{ + int ret; + + /* Do not wait for any reply if chip is frozen */ + if (wdev->chip_frozen) + return; + + wfx_tx_lock(wdev); + mutex_lock(&wdev->hif_cmd.lock); + ret = wait_event_timeout(wdev->hif.tx_buffers_empty, !wdev->hif.tx_buffers_used, + msecs_to_jiffies(3000)); + if (!ret) { + dev_warn(wdev->dev, "cannot flush tx buffers (%d still busy)\n", + wdev->hif.tx_buffers_used); + wfx_pending_dump_old_frames(wdev, 3000); + /* FIXME: drop pending frames here */ + wdev->chip_frozen = true; + } + mutex_unlock(&wdev->hif_cmd.lock); + wfx_tx_unlock(wdev); +} + +void wfx_tx_lock_flush(struct wfx_dev *wdev) +{ + wfx_tx_lock(wdev); + wfx_tx_flush(wdev); +} + +void wfx_tx_queues_init(struct wfx_vif *wvif) +{ + /* The device is in charge to respect the details of the QoS parameters. The driver just + * ensure that it roughtly respect the priorities to avoid any shortage. + */ + const int priorities[IEEE80211_NUM_ACS] = { 1, 2, 64, 128 }; + int i; + + for (i = 0; i < IEEE80211_NUM_ACS; ++i) { + skb_queue_head_init(&wvif->tx_queue[i].normal); + skb_queue_head_init(&wvif->tx_queue[i].cab); + wvif->tx_queue[i].priority = priorities[i]; + } +} + +bool wfx_tx_queue_empty(struct wfx_vif *wvif, struct wfx_queue *queue) +{ + return skb_queue_empty_lockless(&queue->normal) && skb_queue_empty_lockless(&queue->cab); +} + +void wfx_tx_queues_check_empty(struct wfx_vif *wvif) +{ + int i; + + for (i = 0; i < IEEE80211_NUM_ACS; ++i) { + WARN_ON(atomic_read(&wvif->tx_queue[i].pending_frames)); + WARN_ON(!wfx_tx_queue_empty(wvif, &wvif->tx_queue[i])); + } +} + +static void __wfx_tx_queue_drop(struct wfx_vif *wvif, + struct sk_buff_head *skb_queue, struct sk_buff_head *dropped) +{ + struct sk_buff *skb, *tmp; + + spin_lock_bh(&skb_queue->lock); + skb_queue_walk_safe(skb_queue, skb, tmp) { + __skb_unlink(skb, skb_queue); + skb_queue_head(dropped, skb); + } + spin_unlock_bh(&skb_queue->lock); +} + +void wfx_tx_queue_drop(struct wfx_vif *wvif, struct wfx_queue *queue, + struct sk_buff_head *dropped) +{ + __wfx_tx_queue_drop(wvif, &queue->cab, dropped); + __wfx_tx_queue_drop(wvif, &queue->normal, dropped); + wake_up(&wvif->wdev->tx_dequeue); +} + +void wfx_tx_queues_put(struct wfx_vif *wvif, struct sk_buff *skb) +{ + struct wfx_queue *queue = &wvif->tx_queue[skb_get_queue_mapping(skb)]; + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); + + if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) + skb_queue_tail(&queue->cab, skb); + else + skb_queue_tail(&queue->normal, skb); +} + +void wfx_pending_drop(struct wfx_dev *wdev, struct sk_buff_head *dropped) +{ + struct wfx_queue *queue; + struct wfx_vif *wvif; + struct wfx_hif_msg *hif; + struct sk_buff *skb; + + WARN(!wdev->chip_frozen, "%s should only be used to recover a frozen device", __func__); + while ((skb = skb_dequeue(&wdev->tx_pending)) != NULL) { + hif = (struct wfx_hif_msg *)skb->data; + wvif = wdev_to_wvif(wdev, hif->interface); + if (wvif) { + queue = &wvif->tx_queue[skb_get_queue_mapping(skb)]; + WARN_ON(skb_get_queue_mapping(skb) > 3); + WARN_ON(!atomic_read(&queue->pending_frames)); + atomic_dec(&queue->pending_frames); + } + skb_queue_head(dropped, skb); + } +} + +struct sk_buff *wfx_pending_get(struct wfx_dev *wdev, u32 packet_id) +{ + struct wfx_queue *queue; + struct wfx_hif_req_tx *req; + struct wfx_vif *wvif; + struct wfx_hif_msg *hif; + struct sk_buff *skb; + + spin_lock_bh(&wdev->tx_pending.lock); + skb_queue_walk(&wdev->tx_pending, skb) { + hif = (struct wfx_hif_msg *)skb->data; + req = (struct wfx_hif_req_tx *)hif->body; + if (req->packet_id != packet_id) + continue; + spin_unlock_bh(&wdev->tx_pending.lock); + wvif = wdev_to_wvif(wdev, hif->interface); + if (wvif) { + queue = &wvif->tx_queue[skb_get_queue_mapping(skb)]; + WARN_ON(skb_get_queue_mapping(skb) > 3); + WARN_ON(!atomic_read(&queue->pending_frames)); + atomic_dec(&queue->pending_frames); + } + skb_unlink(skb, &wdev->tx_pending); + return skb; + } + spin_unlock_bh(&wdev->tx_pending.lock); + WARN(1, "cannot find packet in pending queue"); + return NULL; +} + +void wfx_pending_dump_old_frames(struct wfx_dev *wdev, unsigned int limit_ms) +{ + ktime_t now = ktime_get(); + struct wfx_tx_priv *tx_priv; + struct wfx_hif_req_tx *req; + struct sk_buff *skb; + bool first = true; + + spin_lock_bh(&wdev->tx_pending.lock); + skb_queue_walk(&wdev->tx_pending, skb) { + tx_priv = wfx_skb_tx_priv(skb); + req = wfx_skb_txreq(skb); + if (ktime_after(now, ktime_add_ms(tx_priv->xmit_timestamp, limit_ms))) { + if (first) { + dev_info(wdev->dev, "frames stuck in firmware since %dms or more:\n", + limit_ms); + first = false; + } + dev_info(wdev->dev, " id %08x sent %lldms ago\n", + req->packet_id, ktime_ms_delta(now, tx_priv->xmit_timestamp)); + } + } + spin_unlock_bh(&wdev->tx_pending.lock); +} + +unsigned int wfx_pending_get_pkt_us_delay(struct wfx_dev *wdev, struct sk_buff *skb) +{ + ktime_t now = ktime_get(); + struct wfx_tx_priv *tx_priv = wfx_skb_tx_priv(skb); + + return ktime_us_delta(now, tx_priv->xmit_timestamp); +} + +bool wfx_tx_queues_has_cab(struct wfx_vif *wvif) +{ + int i; + + if (wvif->vif->type != NL80211_IFTYPE_AP) + return false; + for (i = 0; i < IEEE80211_NUM_ACS; ++i) + /* Note: since only AP can have mcast frames in queue and only + * one vif can be AP, all queued frames has same interface id + */ + if (!skb_queue_empty_lockless(&wvif->tx_queue[i].cab)) + return true; + return false; +} + +static int wfx_tx_queue_get_weight(struct wfx_queue *queue) +{ + return atomic_read(&queue->pending_frames) * queue->priority; +} + +static struct sk_buff *wfx_tx_queues_get_skb(struct wfx_dev *wdev) +{ + struct wfx_queue *queues[IEEE80211_NUM_ACS * ARRAY_SIZE(wdev->vif)]; + int i, j, num_queues = 0; + struct wfx_vif *wvif; + struct wfx_hif_msg *hif; + struct sk_buff *skb; + + /* sort the queues */ + wvif = NULL; + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { + for (i = 0; i < IEEE80211_NUM_ACS; i++) { + WARN_ON(num_queues >= ARRAY_SIZE(queues)); + queues[num_queues] = &wvif->tx_queue[i]; + for (j = num_queues; j > 0; j--) + if (wfx_tx_queue_get_weight(queues[j]) < + wfx_tx_queue_get_weight(queues[j - 1])) + swap(queues[j - 1], queues[j]); + num_queues++; + } + } + + wvif = NULL; + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { + if (!wvif->after_dtim_tx_allowed) + continue; + for (i = 0; i < num_queues; i++) { + skb = skb_dequeue(&queues[i]->cab); + if (!skb) + continue; + /* Note: since only AP can have mcast frames in queue + * and only one vif can be AP, all queued frames has + * same interface id + */ + hif = (struct wfx_hif_msg *)skb->data; + WARN_ON(hif->interface != wvif->id); + WARN_ON(queues[i] != &wvif->tx_queue[skb_get_queue_mapping(skb)]); + atomic_inc(&queues[i]->pending_frames); + trace_queues_stats(wdev, queues[i]); + return skb; + } + /* No more multicast to sent */ + wvif->after_dtim_tx_allowed = false; + schedule_work(&wvif->update_tim_work); + } + + for (i = 0; i < num_queues; i++) { + skb = skb_dequeue(&queues[i]->normal); + if (skb) { + atomic_inc(&queues[i]->pending_frames); + trace_queues_stats(wdev, queues[i]); + return skb; + } + } + return NULL; +} + +struct wfx_hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev) +{ + struct wfx_tx_priv *tx_priv; + struct sk_buff *skb; + + if (atomic_read(&wdev->tx_lock)) + return NULL; + skb = wfx_tx_queues_get_skb(wdev); + if (!skb) + return NULL; + skb_queue_tail(&wdev->tx_pending, skb); + wake_up(&wdev->tx_dequeue); + tx_priv = wfx_skb_tx_priv(skb); + tx_priv->xmit_timestamp = ktime_get(); + return (struct wfx_hif_msg *)skb->data; +} diff --git a/drivers/net/wireless/silabs/wfx/queue.h b/drivers/net/wireless/silabs/wfx/queue.h new file mode 100644 index 000000000000..4731debca93d --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/queue.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Queue between the tx operation and the bh workqueue. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#ifndef WFX_QUEUE_H +#define WFX_QUEUE_H + +#include +#include + +struct wfx_dev; +struct wfx_vif; + +struct wfx_queue { + struct sk_buff_head normal; + struct sk_buff_head cab; /* Content After (DTIM) Beacon */ + atomic_t pending_frames; + int priority; +}; + +void wfx_tx_lock(struct wfx_dev *wdev); +void wfx_tx_unlock(struct wfx_dev *wdev); +void wfx_tx_flush(struct wfx_dev *wdev); +void wfx_tx_lock_flush(struct wfx_dev *wdev); + +void wfx_tx_queues_init(struct wfx_vif *wvif); +void wfx_tx_queues_check_empty(struct wfx_vif *wvif); +bool wfx_tx_queues_has_cab(struct wfx_vif *wvif); +void wfx_tx_queues_put(struct wfx_vif *wvif, struct sk_buff *skb); +struct wfx_hif_msg *wfx_tx_queues_get(struct wfx_dev *wdev); + +bool wfx_tx_queue_empty(struct wfx_vif *wvif, struct wfx_queue *queue); +void wfx_tx_queue_drop(struct wfx_vif *wvif, struct wfx_queue *queue, + struct sk_buff_head *dropped); + +struct sk_buff *wfx_pending_get(struct wfx_dev *wdev, u32 packet_id); +void wfx_pending_drop(struct wfx_dev *wdev, struct sk_buff_head *dropped); +unsigned int wfx_pending_get_pkt_us_delay(struct wfx_dev *wdev, struct sk_buff *skb); +void wfx_pending_dump_old_frames(struct wfx_dev *wdev, unsigned int limit_ms); + +#endif From patchwork Tue Jan 11 17:14:19 2022 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: 531337 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77925C4167D for ; Tue, 11 Jan 2022 17:16:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344374AbiAKRQu (ORCPT ); Tue, 11 Jan 2022 12:16:50 -0500 Received: from mail-dm6nam08on2088.outbound.protection.outlook.com ([40.107.102.88]:54880 "EHLO NAM04-DM6-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1344053AbiAKRQD (ORCPT ); Tue, 11 Jan 2022 12:16:03 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=n16e/8nAQv2z7C6vHZLAJyXmLEXmyKqXEY+NUlM4NgA6doLOLBgDiNV/NaLoPgfXcMdyTS+5vdiLrL4KKJPhyazUMrhMIZE5gcUaLAJbEskg6Eh4A9GN57xSYyYe/FbPd5jop16vFT3n9NqHqvkq3CsRq/T7bTNmka6Mqo+STpFbmrMqT3UufLl7bm4kECZpU61PuN//GsqzIssyLcEjaDOvp6OTrz3Pj6CxCVpDoOvqiXzBCQTeQAXJhQJC/5RPZkudexI0B6LkmgqSiFlW+DdroYTF1zBX5HV6vWaCz/c4K6D5s3PiFtfUfLCB/JxvQh4wFBX17z2BgP3A39jsSQ== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=qiqfnV+Gz+SvdB+J4vIzfcT8pn8/6GgqLgkW0pMuH5M=; b=MBKQk71AjfhfaXPOOQKjBwasRfgibQf0ZT3FrntCqxR2BKtjnP5Tm0/dtttShta3na1HFAeNuy4N0dDloKIKnFCOokewb7ygYZcwq73a4G/lHnZ+lA0ytHYvDCGmNKFWR3b8jGBIV5iL1o7yDsfj0mwhE7R3c1SRjxQSnb+EaoxXQNwNDYOnyW3ukuQyzJIy9IG/oMbktwkAte57eH3gYJxFY4UAg8xkg1Ec3x3hcE376VVcJEQyDIj9C8UgFL9Q9vyXSt8J6tuCBlpgglVCPaQ0VIj+TQLZz34aFs0vyqHnID+whxqBb99DNDlK7qNPJ/fS7A3AKY8UUt54wHa9JA== 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=qiqfnV+Gz+SvdB+J4vIzfcT8pn8/6GgqLgkW0pMuH5M=; b=l5EetzhU7jRJwsgbWWYh12fMntW+KePtLYwQTJRnDL2cVT44rxLdALy13VIscwZLnUP0QbcWieRj1b4hGt4rkCXV8SlpILbo5ElFetjyDHNV+D1lpH8vKput6ZV0h3cEjYfHB3Njs9I8SmSuOxGpApmvxZHf0W02TXTyq7jWv+o= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5626.namprd11.prod.outlook.com (2603:10b6:510:ee::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.9; Tue, 11 Jan 2022 17:15:36 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:36 +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 v9 19/24] wfx: add sta.c/sta.h Date: Tue, 11 Jan 2022 18:14:19 +0100 Message-Id: <20220111171424.862764-20-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 462fc392-812d-4523-8993-08d9d525fb64 X-MS-TrafficTypeDiagnostic: PH0PR11MB5626:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: sSt3NhINpWieUQ8yLoJYs59GkhXQOj6G9IDz7BIOnSeDQJyKm5USl3Ak0rDYHLxU+KiqJdGmStjEzk114ZrCleQWyO4i77HM2zU5/oq83Hx+h51N3D8Ulp3NuptaqwmnH3WNNNFXrkUy1YbMtyxjIOUIibBitvBbIE50H7Sy4qda5Q5d0Oh/khI1KAfeHJhSkv0DSThz16XDXxTlyBwc6Dj2szGB5EucS272rFjJX+YB0ePJtL7oGsdbzfGqQoNv+prIxxFsyS33zldQFDXdagpZW6TYo5reHXSPpg2RMELwGMImJRpMlNbjcA5SYLva+7MrpIujYDUrtqico7qP2iyfmSUOqn8swqMB0CBxUIfpmFIE/FDaX3jzkxV27KLiAiO06cI4vEZLNzaMJWBfl7w0O4YlzQJ0iFf8VFDGk96VBazJZj2eAjWPZhxjyqUhFQ/uk0CkoxeEcTQxstsGVC+AzQ6/aIvPtvON88gRy9n8lej5oKGiqtP23v5SOErZPeLIssnjGdyLhKGFMbC0MKVWBvdEEPQdB8H2r2dCldgbVyj14OWFHRps2i+zaRQczam5W7iT4lMG9TAxsDxiVIJL3hHRu0Cjigjg7uAju350jpDG34ID8+te+lo5mdUIJ1aNGUumDw0By3tCmqEZ6Q== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(1076003)(83380400001)(38100700002)(54906003)(30864003)(86362001)(8676002)(186003)(508600001)(66574015)(6512007)(6666004)(8936002)(6916009)(6506007)(36756003)(2616005)(6486002)(52116002)(2906002)(107886003)(4326008)(316002)(5660300002)(7416002)(66556008)(66946007)(66476007); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?Gf6BcobS9tSmoaY26WcE3mlEb1xO?= =?utf-8?q?k+cGp1N+V6sbl7/UH/V1szY9L3vkROOZgf53y24SPUhNm6S6u7RISPwNnX5iKm+M0?= =?utf-8?q?6x3oxpvUI1xYeLNVBdRLJO8+5t5hXd53MFP+7e6xd/rrTsTeNa0B03o0CNBt+ixE3?= =?utf-8?q?4X7BYNA1hXkBVLttpSUAoCYsDJnM0VoEfMQSf0xFu8fh6UaCV8vqc5+4VevXnmAoo?= =?utf-8?q?3DXoxBxIeGWUp/yWD/gspnIomwERk7ijgudpb9kduKNFyYEp4Znwo5DupEzePNjU7?= =?utf-8?q?5SV5HuA8DN4T5FcON9O9Gi/9OwBD+2TosJwruqzVaGtzt652Jcg//FA9ksuEvwVbj?= =?utf-8?q?+fdlGbE95K5zMhtcFKcZUnG7fUeL8FqcvB0ZwvWQ71NPA48PVwUBynPwIih0bEHjv?= =?utf-8?q?AhluBTWv2GjqD9Qt9phyuFYmtD/k1WUemHOEk0MRWGtZR/wzpXiGBgQxE0jPceGaX?= =?utf-8?q?gRAt2H5l3vyhn6VvAV1X8FS92ZVTtpv8Ik/hA8oAezUtOwgVv0C4mBLczaWb8G9oN?= =?utf-8?q?rjtZ9/evrRJrBK5KaNfUstd9+KhGb7H7PagV4hb4NaTnE+01X+yDNTIv8c1VdUSEc?= =?utf-8?q?DWMgu7VUSsu2KhX/iJdo1S3IfER4be0mjq6Av7p7Yuql/a3XV4ZdGsqNGBCccGm9N?= =?utf-8?q?587X6NdWKyi0dZCQyEoutCaMo+0JMdJHvx6gAI9Fi+uG/kYJZ5UiXhVoRPRxkrdXb?= =?utf-8?q?4qHNqczWTLoZszEyotRcYMsSVTN9GiaYARAmTr5QTkQ2ua6dqjt4QRENFSVOQwAWm?= =?utf-8?q?1w3yw1S7ILj+d39tpu/PKO8wIEYEwJrs79YKQAnSkrIAYmK/pOH0q9p/aVCOFOeG5?= =?utf-8?q?kEqxn9sHZC7R9U5yNXk/xFylBspifAvfuevqS6JWcK9exv3NGGzOGJJWcyUocRwOp?= =?utf-8?q?RrELja1BMLd7ZHFO05dRMmdREfQCmeYDJF7+kHhspM8AHmjZDl8wgzpWh4xEv25J2?= =?utf-8?q?t2cHMwxXJT0u8SPKrhWwITHfh1GF5h2JMT3bN/INmwH19SGbOOZVhJwlWSkPbrl4y?= =?utf-8?q?qeA9nNWGT0XD6yGD8PHsA0XOWsH8c5tJ5FK6j5xLkXe75+JMBrR5wcTHYHsO1buJG?= =?utf-8?q?3kOC22oD6wzuG/fBsUCR8zoSnFOGQaNg1NmsZIzu0EdPqkF3diWxyQjLkMkln4ucG?= =?utf-8?q?sLY5YZVrK3kXggQykpV0XIN9IuQ8RPOnPJePOyS0bCoo8EQ8gxeX82PNZ7U6Wl2bP?= =?utf-8?q?Rjwa5tXMlNYxSsTEK4dVxk4Z5P8zh0mpKXTwfEygWSQcwPqkue85JvIRfcrAVjpmP?= =?utf-8?q?+Zzyvkjfi81zOT7wlKkQXF8tRT71PK1ZIXCBEPVyKF4611ep2j20Ur2BB9cOYhFZC?= =?utf-8?q?1FgiSi5U2IQ//glfdynlcOyuMeCnVTRFTabVXF6BaGEDgDvZy7RztIi6o40H2RgTg?= =?utf-8?q?A9LP52ZrjnDXipM8FVixK8ay8vLfu0X647VYivV3oaEsv0HuaX0Ff5ehdoZVigk29?= =?utf-8?q?BNF/8IFW2POcnYCOgbUG9ajStBorqkJK5z3Y4rsZnpkhbF15HA46LhkajQi5QUs6K?= =?utf-8?q?74bEVrNn/ArLPjnAww5SdGUwDzZPCP4tCdLNukJsXvvHkgWCp4P6iD5z6SQtnfr3V?= =?utf-8?q?NOif5d9XTxEAC182mzeyaloazjxBYH8QBpYngc5K168M1fjgXI2W6s=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 462fc392-812d-4523-8993-08d9d525fb64 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:36.1561 (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: sZvosCobD7Nxm790QJS7XyfBkOBYXauzO5rGzDR2HnQ2kRQME8bzxDUJE6QF/zA2M1zDK1Tz+MJZnaPYqWs4VQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5626 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/sta.c | 798 ++++++++++++++++++++++++++ drivers/net/wireless/silabs/wfx/sta.h | 67 +++ 2 files changed, 865 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/sta.c create mode 100644 drivers/net/wireless/silabs/wfx/sta.h diff --git a/drivers/net/wireless/silabs/wfx/sta.c b/drivers/net/wireless/silabs/wfx/sta.c new file mode 100644 index 000000000000..9513e406a865 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/sta.c @@ -0,0 +1,798 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Implementation of mac80211 API. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#include +#include + +#include "sta.h" +#include "wfx.h" +#include "fwio.h" +#include "bh.h" +#include "key.h" +#include "scan.h" +#include "debug.h" +#include "hif_tx.h" +#include "hif_tx_mib.h" + +#define HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES 2 + +u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates) +{ + int i; + u32 ret = 0; + /* The device only supports 2GHz */ + struct ieee80211_supported_band *sband = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]; + + for (i = 0; i < sband->n_bitrates; i++) { + if (rates & BIT(i)) { + if (i >= sband->n_bitrates) + dev_warn(wdev->dev, "unsupported basic rate\n"); + else + ret |= BIT(sband->bitrates[i].hw_value); + } + } + return ret; +} + +void wfx_cooling_timeout_work(struct work_struct *work) +{ + struct wfx_dev *wdev = container_of(to_delayed_work(work), struct wfx_dev, + cooling_timeout_work); + + wdev->chip_frozen = true; + wfx_tx_unlock(wdev); +} + +void wfx_suspend_hot_dev(struct wfx_dev *wdev, enum sta_notify_cmd cmd) +{ + if (cmd == STA_NOTIFY_AWAKE) { + /* Device recover normal temperature */ + if (cancel_delayed_work(&wdev->cooling_timeout_work)) + wfx_tx_unlock(wdev); + } else { + /* Device is too hot */ + schedule_delayed_work(&wdev->cooling_timeout_work, 10 * HZ); + wfx_tx_lock(wdev); + } +} + +static void wfx_filter_beacon(struct wfx_vif *wvif, bool filter_beacon) +{ + static const struct wfx_hif_ie_table_entry filter_ies[] = { + { + .ie_id = WLAN_EID_VENDOR_SPECIFIC, + .has_changed = 1, + .no_longer = 1, + .has_appeared = 1, + .oui = { 0x50, 0x6F, 0x9A }, + }, { + .ie_id = WLAN_EID_HT_OPERATION, + .has_changed = 1, + .no_longer = 1, + .has_appeared = 1, + }, { + .ie_id = WLAN_EID_ERP_INFO, + .has_changed = 1, + .no_longer = 1, + .has_appeared = 1, + }, { + .ie_id = WLAN_EID_CHANNEL_SWITCH, + .has_changed = 1, + .no_longer = 1, + .has_appeared = 1, + } + }; + + if (!filter_beacon) { + wfx_hif_beacon_filter_control(wvif, 0, 1); + } else { + wfx_hif_set_beacon_filter_table(wvif, ARRAY_SIZE(filter_ies), filter_ies); + wfx_hif_beacon_filter_control(wvif, HIF_BEACON_FILTER_ENABLE, 0); + } +} + +void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, + unsigned int *total_flags, u64 unused) +{ + struct wfx_vif *wvif = NULL; + struct wfx_dev *wdev = hw->priv; + bool filter_bssid, filter_prbreq, filter_beacon; + + /* Notes: + * - Probe responses (FIF_BCN_PRBRESP_PROMISC) are never filtered + * - PS-Poll (FIF_PSPOLL) are never filtered + * - RTS, CTS and Ack (FIF_CONTROL) are always filtered + * - Broken frames (FIF_FCSFAIL and FIF_PLCPFAIL) are always filtered + * - Firmware does (yet) allow to forward unicast traffic sent to other stations (aka. + * promiscuous mode) + */ + *total_flags &= FIF_BCN_PRBRESP_PROMISC | FIF_ALLMULTI | FIF_OTHER_BSS | + FIF_PROBE_REQ | FIF_PSPOLL; + + mutex_lock(&wdev->conf_mutex); + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { + mutex_lock(&wvif->scan_lock); + + /* Note: FIF_BCN_PRBRESP_PROMISC covers probe response and + * beacons from other BSS + */ + if (*total_flags & FIF_BCN_PRBRESP_PROMISC) + filter_beacon = false; + else + filter_beacon = true; + wfx_filter_beacon(wvif, filter_beacon); + + if (*total_flags & FIF_OTHER_BSS) + filter_bssid = false; + else + filter_bssid = true; + + /* In AP mode, chip can reply to probe request itself */ + if (*total_flags & FIF_PROBE_REQ && wvif->vif->type == NL80211_IFTYPE_AP) { + dev_dbg(wdev->dev, "do not forward probe request in AP mode\n"); + *total_flags &= ~FIF_PROBE_REQ; + } + + if (*total_flags & FIF_PROBE_REQ) + filter_prbreq = false; + else + filter_prbreq = true; + wfx_hif_set_rx_filter(wvif, filter_bssid, filter_prbreq); + + mutex_unlock(&wvif->scan_lock); + } + mutex_unlock(&wdev->conf_mutex); +} + +static int wfx_get_ps_timeout(struct wfx_vif *wvif, bool *enable_ps) +{ + struct ieee80211_channel *chan0 = NULL, *chan1 = NULL; + struct ieee80211_conf *conf = &wvif->wdev->hw->conf; + + WARN(!wvif->vif->bss_conf.assoc && enable_ps, + "enable_ps is reliable only if associated"); + if (wdev_to_wvif(wvif->wdev, 0)) + chan0 = wdev_to_wvif(wvif->wdev, 0)->vif->bss_conf.chandef.chan; + if (wdev_to_wvif(wvif->wdev, 1)) + chan1 = wdev_to_wvif(wvif->wdev, 1)->vif->bss_conf.chandef.chan; + if (chan0 && chan1 && wvif->vif->type != NL80211_IFTYPE_AP) { + if (chan0->hw_value == chan1->hw_value) { + /* It is useless to enable PS if channels are the same. */ + if (enable_ps) + *enable_ps = false; + if (wvif->vif->bss_conf.assoc && wvif->vif->bss_conf.ps) + dev_info(wvif->wdev->dev, "ignoring requested PS mode"); + return -1; + } else { + /* It is necessary to enable PS if channels + * are different. + */ + if (enable_ps) + *enable_ps = true; + if (wfx_api_older_than(wvif->wdev, 3, 2)) + return 0; + else + return 30; + } + } + if (enable_ps) + *enable_ps = wvif->vif->bss_conf.ps; + if (wvif->vif->bss_conf.assoc && wvif->vif->bss_conf.ps) + return conf->dynamic_ps_timeout; + else + return -1; +} + +int wfx_update_pm(struct wfx_vif *wvif) +{ + int ps_timeout; + bool ps; + + if (!wvif->vif->bss_conf.assoc) + return 0; + ps_timeout = wfx_get_ps_timeout(wvif, &ps); + if (!ps) + ps_timeout = 0; + WARN_ON(ps_timeout < 0); + if (wvif->uapsd_mask) + ps_timeout = 0; + + if (!wait_for_completion_timeout(&wvif->set_pm_mode_complete, TU_TO_JIFFIES(512))) + dev_warn(wvif->wdev->dev, "timeout while waiting of set_pm_mode_complete\n"); + return wfx_hif_set_pm(wvif, ps, ps_timeout); +} + +int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u16 queue, const struct ieee80211_tx_queue_params *params) +{ + struct wfx_dev *wdev = hw->priv; + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + int old_uapsd = wvif->uapsd_mask; + + WARN_ON(queue >= hw->queues); + + mutex_lock(&wdev->conf_mutex); + assign_bit(queue, &wvif->uapsd_mask, params->uapsd); + wfx_hif_set_edca_queue_params(wvif, queue, params); + if (wvif->vif->type == NL80211_IFTYPE_STATION && old_uapsd != wvif->uapsd_mask) { + wfx_hif_set_uapsd_info(wvif, wvif->uapsd_mask); + wfx_update_pm(wvif); + } + mutex_unlock(&wdev->conf_mutex); + return 0; +} + +int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +{ + struct wfx_dev *wdev = hw->priv; + struct wfx_vif *wvif = NULL; + + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) + wfx_hif_rts_threshold(wvif, value); + return 0; +} + +void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi) +{ + /* RSSI: signed Q8.0, RCPI: unsigned Q7.1 + * RSSI = RCPI / 2 - 110 + */ + int rcpi_rssi; + int cqm_evt; + + rcpi_rssi = raw_rcpi_rssi / 2 - 110; + if (rcpi_rssi <= wvif->vif->bss_conf.cqm_rssi_thold) + cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; + else + cqm_evt = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; + ieee80211_cqm_rssi_notify(wvif->vif, cqm_evt, rcpi_rssi, GFP_KERNEL); +} + +static void wfx_beacon_loss_work(struct work_struct *work) +{ + struct wfx_vif *wvif = container_of(to_delayed_work(work), struct wfx_vif, + beacon_loss_work); + struct ieee80211_bss_conf *bss_conf = &wvif->vif->bss_conf; + + ieee80211_beacon_loss(wvif->vif); + schedule_delayed_work(to_delayed_work(work), msecs_to_jiffies(bss_conf->beacon_int)); +} + +void wfx_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + wfx_hif_wep_default_key_id(wvif, idx); +} + +void wfx_reset(struct wfx_vif *wvif) +{ + struct wfx_dev *wdev = wvif->wdev; + + wfx_tx_lock_flush(wdev); + wfx_hif_reset(wvif, false); + wfx_tx_policy_init(wvif); + if (wvif_count(wdev) <= 1) + wfx_hif_set_block_ack_policy(wvif, 0xFF, 0xFF); + wfx_tx_unlock(wdev); + wvif->join_in_progress = false; + cancel_delayed_work_sync(&wvif->beacon_loss_work); + wvif = NULL; + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) + wfx_update_pm(wvif); +} + +int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *)&sta->drv_priv; + + sta_priv->vif_id = wvif->id; + + if (vif->type == NL80211_IFTYPE_STATION) + wfx_hif_set_mfp(wvif, sta->mfp, sta->mfp); + + /* In station mode, the firmware interprets new link-id as a TDLS peer */ + if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) + return 0; + sta_priv->link_id = ffz(wvif->link_id_map); + wvif->link_id_map |= BIT(sta_priv->link_id); + WARN_ON(!sta_priv->link_id); + WARN_ON(sta_priv->link_id >= HIF_LINK_ID_MAX); + wfx_hif_map_link(wvif, false, sta->addr, sta_priv->link_id, sta->mfp); + + return 0; +} + +int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + struct wfx_sta_priv *sta_priv = (struct wfx_sta_priv *)&sta->drv_priv; + + /* See note in wfx_sta_add() */ + if (!sta_priv->link_id) + return 0; + /* FIXME add a mutex? */ + wfx_hif_map_link(wvif, true, sta->addr, sta_priv->link_id, false); + wvif->link_id_map &= ~BIT(sta_priv->link_id); + return 0; +} + +static int wfx_upload_ap_templates(struct wfx_vif *wvif) +{ + struct sk_buff *skb; + + skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif); + if (!skb) + return -ENOMEM; + wfx_hif_set_template_frame(wvif, skb, HIF_TMPLT_BCN, API_RATE_INDEX_B_1MBPS); + dev_kfree_skb(skb); + + skb = ieee80211_proberesp_get(wvif->wdev->hw, wvif->vif); + if (!skb) + return -ENOMEM; + wfx_hif_set_template_frame(wvif, skb, HIF_TMPLT_PRBRES, API_RATE_INDEX_B_1MBPS); + dev_kfree_skb(skb); + return 0; +} + +static void wfx_set_mfp_ap(struct wfx_vif *wvif) +{ + struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, wvif->vif); + const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); + const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset, + skb->len - ieoffset); + const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); + const int pairwise_cipher_suite_size = 4 / sizeof(u16); + const int akm_suite_size = 4 / sizeof(u16); + + if (ptr) { + ptr += pairwise_cipher_suite_count_offset; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + ptr += 1 + pairwise_cipher_suite_size * *ptr; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + ptr += 1 + akm_suite_size * *ptr; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return; + wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6)); + } +} + +int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + struct wfx_dev *wdev = wvif->wdev; + int ret; + + wvif = NULL; + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) + wfx_update_pm(wvif); + wvif = (struct wfx_vif *)vif->drv_priv; + wfx_upload_ap_templates(wvif); + ret = wfx_hif_start(wvif, &vif->bss_conf, wvif->channel); + if (ret > 0) + return -EIO; + wfx_set_mfp_ap(wvif); + return ret; +} + +void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + wfx_reset(wvif); +} + +static void wfx_join(struct wfx_vif *wvif) +{ + int ret; + struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; + struct cfg80211_bss *bss = NULL; + u8 ssid[IEEE80211_MAX_SSID_LEN]; + const u8 *ssidie = NULL; + int ssidlen = 0; + + wfx_tx_lock_flush(wvif->wdev); + + bss = cfg80211_get_bss(wvif->wdev->hw->wiphy, wvif->channel, conf->bssid, NULL, 0, + IEEE80211_BSS_TYPE_ANY, IEEE80211_PRIVACY_ANY); + if (!bss && !conf->ibss_joined) { + wfx_tx_unlock(wvif->wdev); + return; + } + + rcu_read_lock(); /* protect ssidie */ + if (bss) + ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); + if (ssidie) { + ssidlen = ssidie[1]; + if (ssidlen > IEEE80211_MAX_SSID_LEN) + ssidlen = IEEE80211_MAX_SSID_LEN; + memcpy(ssid, &ssidie[2], ssidlen); + } + rcu_read_unlock(); + + cfg80211_put_bss(wvif->wdev->hw->wiphy, bss); + + wvif->join_in_progress = true; + ret = wfx_hif_join(wvif, conf, wvif->channel, ssid, ssidlen); + if (ret) { + ieee80211_connection_loss(wvif->vif); + wfx_reset(wvif); + } else { + /* Due to beacon filtering it is possible that the AP's beacon is not known for the + * mac80211 stack. Disable filtering temporary to make sure the stack receives at + * least one + */ + wfx_filter_beacon(wvif, false); + } + wfx_tx_unlock(wvif->wdev); +} + +static void wfx_join_finalize(struct wfx_vif *wvif, + struct ieee80211_bss_conf *info) +{ + struct ieee80211_sta *sta = NULL; + int ampdu_density = 0; + bool greenfield = false; + + rcu_read_lock(); /* protect sta */ + if (info->bssid && !info->ibss_joined) + sta = ieee80211_find_sta(wvif->vif, info->bssid); + if (sta && sta->ht_cap.ht_supported) + ampdu_density = sta->ht_cap.ampdu_density; + if (sta && sta->ht_cap.ht_supported && + !(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) + greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); + rcu_read_unlock(); + + wvif->join_in_progress = false; + wfx_hif_set_association_mode(wvif, ampdu_density, greenfield, info->use_short_preamble); + wfx_hif_keep_alive_period(wvif, 0); + /* beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use the same value. */ + wfx_hif_set_bss_params(wvif, info->aid, 7); + wfx_hif_set_beacon_wakeup_period(wvif, 1, 1); + wfx_update_pm(wvif); +} + +int wfx_join_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + wfx_upload_ap_templates(wvif); + wfx_join(wvif); + return 0; +} + +void wfx_leave_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + wfx_reset(wvif); +} + +static void wfx_enable_beacon(struct wfx_vif *wvif, bool enable) +{ + /* Driver has Content After DTIM Beacon in queue. Driver is waiting for a signal from the + * firmware. Since we are going to stop to send beacons, this signal will never happens. See + * also wfx_suspend_resume_mc() + */ + if (!enable && wfx_tx_queues_has_cab(wvif)) { + wvif->after_dtim_tx_allowed = true; + wfx_bh_request_tx(wvif->wdev); + } + wfx_hif_beacon_transmit(wvif, enable); +} + +void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, u32 changed) +{ + struct wfx_dev *wdev = hw->priv; + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + int i; + + mutex_lock(&wdev->conf_mutex); + + if (changed & BSS_CHANGED_BASIC_RATES || + changed & BSS_CHANGED_BEACON_INT || + changed & BSS_CHANGED_BSSID) { + if (vif->type == NL80211_IFTYPE_STATION) + wfx_join(wvif); + } + + if (changed & BSS_CHANGED_ASSOC) { + if (info->assoc || info->ibss_joined) + wfx_join_finalize(wvif, info); + else if (!info->assoc && vif->type == NL80211_IFTYPE_STATION) + wfx_reset(wvif); + else + dev_warn(wdev->dev, "misunderstood change: ASSOC\n"); + } + + if (changed & BSS_CHANGED_BEACON_INFO) { + if (vif->type != NL80211_IFTYPE_STATION) + dev_warn(wdev->dev, "misunderstood change: BEACON_INFO\n"); + wfx_hif_set_beacon_wakeup_period(wvif, info->dtim_period, info->dtim_period); + /* We temporary forwarded beacon for join process. It is now no more necessary. */ + wfx_filter_beacon(wvif, true); + } + + if (changed & BSS_CHANGED_ARP_FILTER) { + for (i = 0; i < HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES; i++) { + __be32 *arp_addr = &info->arp_addr_list[i]; + + if (info->arp_addr_cnt > HIF_MAX_ARP_IP_ADDRTABLE_ENTRIES) + arp_addr = NULL; + if (i >= info->arp_addr_cnt) + arp_addr = NULL; + wfx_hif_set_arp_ipv4_filter(wvif, i, arp_addr); + } + } + + if (changed & BSS_CHANGED_AP_PROBE_RESP || changed & BSS_CHANGED_BEACON) + wfx_upload_ap_templates(wvif); + + if (changed & BSS_CHANGED_BEACON_ENABLED) + wfx_enable_beacon(wvif, info->enable_beacon); + + if (changed & BSS_CHANGED_KEEP_ALIVE) + wfx_hif_keep_alive_period(wvif, info->max_idle_period * + USEC_PER_TU / USEC_PER_MSEC); + + if (changed & BSS_CHANGED_ERP_CTS_PROT) + wfx_hif_erp_use_protection(wvif, info->use_cts_prot); + + if (changed & BSS_CHANGED_ERP_SLOT) + wfx_hif_slot_time(wvif, info->use_short_slot ? 9 : 20); + + if (changed & BSS_CHANGED_CQM) + wfx_hif_set_rcpi_rssi_threshold(wvif, info->cqm_rssi_thold, info->cqm_rssi_hyst); + + if (changed & BSS_CHANGED_TXPOWER) + wfx_hif_set_output_power(wvif, info->txpower); + + if (changed & BSS_CHANGED_PS) + wfx_update_pm(wvif); + + mutex_unlock(&wdev->conf_mutex); +} + +static int wfx_update_tim(struct wfx_vif *wvif) +{ + struct sk_buff *skb; + u16 tim_offset, tim_length; + u8 *tim_ptr; + + skb = ieee80211_beacon_get_tim(wvif->wdev->hw, wvif->vif, &tim_offset, &tim_length); + if (!skb) + return -ENOENT; + tim_ptr = skb->data + tim_offset; + + if (tim_offset && tim_length >= 6) { + /* Firmware handles DTIM counter internally */ + tim_ptr[2] = 0; + + /* Set/reset aid0 bit */ + if (wfx_tx_queues_has_cab(wvif)) + tim_ptr[4] |= 1; + else + tim_ptr[4] &= ~1; + } + + wfx_hif_update_ie_beacon(wvif, tim_ptr, tim_length); + dev_kfree_skb(skb); + + return 0; +} + +static void wfx_update_tim_work(struct work_struct *work) +{ + struct wfx_vif *wvif = container_of(work, struct wfx_vif, update_tim_work); + + wfx_update_tim(wvif); +} + +int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) +{ + struct wfx_dev *wdev = hw->priv; + struct wfx_sta_priv *sta_dev = (struct wfx_sta_priv *)&sta->drv_priv; + struct wfx_vif *wvif = wdev_to_wvif(wdev, sta_dev->vif_id); + + if (!wvif) { + dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); + return -EIO; + } + schedule_work(&wvif->update_tim_work); + return 0; +} + +void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd notify_cmd) +{ + struct wfx_vif *wvif_it; + + if (notify_cmd != STA_NOTIFY_AWAKE) + return; + + /* Device won't be able to honor CAB if a scan is in progress on any interface. Prefer to + * skip this DTIM and wait for the next one. + */ + wvif_it = NULL; + while ((wvif_it = wvif_iterate(wvif->wdev, wvif_it)) != NULL) + if (mutex_is_locked(&wvif_it->scan_lock)) + return; + + if (!wfx_tx_queues_has_cab(wvif) || wvif->after_dtim_tx_allowed) + dev_warn(wvif->wdev->dev, "incorrect sequence (%d CAB in queue)", + wfx_tx_queues_has_cab(wvif)); + wvif->after_dtim_tx_allowed = true; + wfx_bh_request_tx(wvif->wdev); +} + +int wfx_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params) +{ + /* Aggregation is implemented fully in firmware */ + switch (params->action) { + case IEEE80211_AMPDU_RX_START: + case IEEE80211_AMPDU_RX_STOP: + /* Just acknowledge it to enable frame re-ordering */ + return 0; + default: + /* Leave the firmware doing its business for tx aggregation */ + return -EOPNOTSUPP; + } +} + +int wfx_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf) +{ + return 0; +} + +void wfx_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf) +{ +} + +void wfx_change_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf, u32 changed) +{ +} + +int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_chanctx_conf *conf) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + struct ieee80211_channel *ch = conf->def.chan; + + WARN(wvif->channel, "channel overwrite"); + wvif->channel = ch; + + return 0; +} + +void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_chanctx_conf *conf) +{ + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + struct ieee80211_channel *ch = conf->def.chan; + + WARN(wvif->channel != ch, "channel mismatch"); + wvif->channel = NULL; +} + +int wfx_config(struct ieee80211_hw *hw, u32 changed) +{ + return 0; +} + +int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + int i, ret = 0; + struct wfx_dev *wdev = hw->priv; + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_UAPSD | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; + + mutex_lock(&wdev->conf_mutex); + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_AP: + break; + default: + mutex_unlock(&wdev->conf_mutex); + return -EOPNOTSUPP; + } + + /* FIXME: prefer use of container_of() to get vif */ + wvif->vif = vif; + wvif->wdev = wdev; + + wvif->link_id_map = 1; /* link-id 0 is reserved for multicast */ + INIT_WORK(&wvif->update_tim_work, wfx_update_tim_work); + INIT_DELAYED_WORK(&wvif->beacon_loss_work, wfx_beacon_loss_work); + + init_completion(&wvif->set_pm_mode_complete); + complete(&wvif->set_pm_mode_complete); + INIT_WORK(&wvif->tx_policy_upload_work, wfx_tx_policy_upload_work); + + mutex_init(&wvif->scan_lock); + init_completion(&wvif->scan_complete); + INIT_WORK(&wvif->scan_work, wfx_hw_scan_work); + + wfx_tx_queues_init(wvif); + wfx_tx_policy_init(wvif); + + for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) { + if (!wdev->vif[i]) { + wdev->vif[i] = vif; + wvif->id = i; + break; + } + } + WARN(i == ARRAY_SIZE(wdev->vif), "try to instantiate more vif than supported"); + + wfx_hif_set_macaddr(wvif, vif->addr); + + mutex_unlock(&wdev->conf_mutex); + + wvif = NULL; + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { + /* Combo mode does not support Block Acks. We can re-enable them */ + if (wvif_count(wdev) == 1) + wfx_hif_set_block_ack_policy(wvif, 0xFF, 0xFF); + else + wfx_hif_set_block_ack_policy(wvif, 0x00, 0x00); + } + return ret; +} + +void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct wfx_dev *wdev = hw->priv; + struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; + + wait_for_completion_timeout(&wvif->set_pm_mode_complete, msecs_to_jiffies(300)); + wfx_tx_queues_check_empty(wvif); + + mutex_lock(&wdev->conf_mutex); + WARN(wvif->link_id_map != 1, "corrupted state"); + + wfx_hif_reset(wvif, false); + wfx_hif_set_macaddr(wvif, NULL); + wfx_tx_policy_init(wvif); + + cancel_delayed_work_sync(&wvif->beacon_loss_work); + wdev->vif[wvif->id] = NULL; + wvif->vif = NULL; + + mutex_unlock(&wdev->conf_mutex); + + wvif = NULL; + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { + /* Combo mode does not support Block Acks. We can re-enable them */ + if (wvif_count(wdev) == 1) + wfx_hif_set_block_ack_policy(wvif, 0xFF, 0xFF); + else + wfx_hif_set_block_ack_policy(wvif, 0x00, 0x00); + } +} + +int wfx_start(struct ieee80211_hw *hw) +{ + return 0; +} + +void wfx_stop(struct ieee80211_hw *hw) +{ + struct wfx_dev *wdev = hw->priv; + + WARN_ON(!skb_queue_empty_lockless(&wdev->tx_pending)); +} diff --git a/drivers/net/wireless/silabs/wfx/sta.h b/drivers/net/wireless/silabs/wfx/sta.h new file mode 100644 index 000000000000..082329d7bbcd --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/sta.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Implementation of mac80211 API. + * + * Copyright (c) 2017-2020, Silicon Laboratories, Inc. + * Copyright (c) 2010, ST-Ericsson + */ +#ifndef WFX_STA_H +#define WFX_STA_H + +#include + +struct wfx_dev; +struct wfx_vif; + +struct wfx_sta_priv { + int link_id; + int vif_id; +}; + +/* mac80211 interface */ +int wfx_start(struct ieee80211_hw *hw); +void wfx_stop(struct ieee80211_hw *hw); +int wfx_config(struct ieee80211_hw *hw, u32 changed); +int wfx_set_rts_threshold(struct ieee80211_hw *hw, u32 value); +void wfx_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx); +void wfx_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, + unsigned int *total_flags, u64 unused); + +int wfx_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void wfx_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +int wfx_join_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +void wfx_leave_ibss(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +int wfx_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u16 queue, const struct ieee80211_tx_queue_params *params); +void wfx_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info, u32 changed); +int wfx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); +void wfx_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, struct ieee80211_sta *sta); +int wfx_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); +int wfx_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_ampdu_params *params); +int wfx_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf); +void wfx_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf); +void wfx_change_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *conf, + u32 changed); +int wfx_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_chanctx_conf *conf); +void wfx_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_chanctx_conf *conf); + +/* Hardware API Callbacks */ +void wfx_cooling_timeout_work(struct work_struct *work); +void wfx_suspend_hot_dev(struct wfx_dev *wdev, enum sta_notify_cmd cmd); +void wfx_suspend_resume_mc(struct wfx_vif *wvif, enum sta_notify_cmd cmd); +void wfx_event_report_rssi(struct wfx_vif *wvif, u8 raw_rcpi_rssi); +int wfx_update_pm(struct wfx_vif *wvif); + +/* Other Helpers */ +void wfx_reset(struct wfx_vif *wvif); +u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates); + +#endif From patchwork Tue Jan 11 17:14:22 2022 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: 531334 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 192ECC4332F for ; Tue, 11 Jan 2022 17:18:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244561AbiAKRSc (ORCPT ); Tue, 11 Jan 2022 12:18:32 -0500 Received: from mail-co1nam11on2052.outbound.protection.outlook.com ([40.107.220.52]:54241 "EHLO NAM11-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1344444AbiAKRRS (ORCPT ); Tue, 11 Jan 2022 12:17:18 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=k6/gt68YdoWqMbZNsSkLVDp27hdTfmQ69DgBiqx39iiLdgAnMMcE5x0sCCxLfPIrKWZI/Cp9MLOP49XGYwxyWzBXvZcJlQt37B3ZBCg+V0qQrsTFyLFCLHCo2yDBSHMgwkdKBzWa+7QsmjGE+nJtuAlBNtpC1UBebg9RardzPEdN2yO8ppIsNt0q6Skwu+nzbernL3k597mqGkekTukI2XqwATZcBGsOAM9Kipb0+tvxhVHDyPTetpDuhqBVNgxCquGb+bM/DZrS1TtpEJsB7ywAx00xhsksV0A1UKKIm/S7ay0jk/Z7C9wHDhSMzxIOpq+od6N31Nv5WWeb43oj1g== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=q8hu8Tjg/5CBLMJM4vtjrt562ygRIgZRSDIbD6lqFos=; b=VeNM/xEd70NCZTeKuCe0QXgI+2YeR5qqjOsBcjPCpz0PI0x0XjX/hmvUU5pHgwSIdTXJbWMo7BvQexAN+4acRqXa24Cfka4JW2I2C4GnGuHB9na2GeZGfMcD5W8Y01t/FHa6wQ3hK6VoV9pJQDggJhW9l+L1yrUnI0SVpQF2LdwJmNapTrQvecqtm28oSd5oZJmhU0rRmMpfX+IIKEMUZtWx2DiUSjIH+2OzwI/EshvIO42F8EiESk/0PIQv9RwUU9L3TMiB2m+1eV6dDJQaANRgGpDxAAlm3QdSHyfgzgF+Tkd834t+aMdswKlwvuwv+XXTJVC3KFLjcHyaWaiaiw== 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=q8hu8Tjg/5CBLMJM4vtjrt562ygRIgZRSDIbD6lqFos=; b=jfO3Z2inDMNr7nmMn50Df0DHQQ+K+lkQMUy+JcDs/0RjoDa9KoUFOnc8Pgf+FWYryGeX1WAH19mDFe8+AcL2CFs3PJE8OOdBQzgy6gl10utK7fGZ44YgGbMCOvl0Xol8bNU182AG5TfB72JOjKE7g/FK4BSzlX7myq8nX4JNgJw= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.11; Tue, 11 Jan 2022 17:15:44 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:44 +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 v9 22/24] wfx: add traces.h Date: Tue, 11 Jan 2022 18:14:22 +0100 Message-Id: <20220111171424.862764-23-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 72926fe7-97f7-4454-e414-08d9d5260038 X-MS-TrafficTypeDiagnostic: PH0PR11MB5657:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:66; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: sU9SXH159u39f+v6SKg2TMF5dFaefCnYW36G23BWTGh34G4+Cl81lzZ1lK+bMKPMrNLdFIVlgjUBZXF1ui7+BYa9x/CowWZsHAJcrRxlXUbFp92LOQJpeq5dd6snOSvyDcxCjIa+4/ltEdlQFw5Q+USRLEA1txXS1iZfpOMLRkgWT4Cnbe8N4uJ3mkdz8HE35+JroXkzEbPueTr+9UE9WsNVgoPZLH+mjAz12xM7bjoQzmFU/TtU/eZE3IZITYmDUOxFiom7/kmKUHFSCVY9aOGf0H/wozHsNhcoifAA03UvylnyBMqZSqK/a6J5FhUNQqcd+26bSZK2hFfFdpRrE2MhUi1H/DhMLH89sVlLiiYZbFxSjw8KY+rlSm47vCN/8MES8+WuCwuPZSkpw840RKpuIpeTe7ORaChE074tjmZhkqy3bTTC5Ijb9Su69ix4hHXmN6JyJOGIO1qSHa4H8CxoGzOAV5h6cVq/KP39X0KDTNLYYKLEqrvxf+7+JyFaqqNj1dllYDkgBGVYAxnpPKJ+21CVhH3PK0SSuSSqvs2xXU9wwpKKKK7S6fvKUs9iFParLJDm17ufcS3KoX+cSrNTronFfWuDACaqyt5amxBcu1vMLNC64tQxmXXFYVOOXQKi4BWDOgNaORTN9k90hqiQuWyKzRCzQ31V3KIcAiAhL3uFEmpq3RP2i+aYgft6 X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(6506007)(66574015)(86362001)(5660300002)(8936002)(7416002)(6916009)(8676002)(83380400001)(1076003)(6486002)(36756003)(38100700002)(186003)(66946007)(6666004)(2616005)(4326008)(2906002)(316002)(107886003)(66556008)(66476007)(54906003)(6512007)(508600001)(30864003)(52116002)(21314003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?nwG9nQzG5KL0J9/NB+aOlLNRJ/wI?= =?utf-8?q?zdQhBKNHnZgKcDHo3XoPA8OVUvKaC6V7iVWXEQB21CCbAIxXbgH3fIgM4EZLb0AjQ?= =?utf-8?q?T5BrjgvRr3p9vdqWbtk/a3Ov4S+Wv/A6CUYB0E7gvGmU/M4XoRKMnngdtVqH/EzWX?= =?utf-8?q?rYFrRUaxQ39Wq+ho5eYlEaDnLYFtQIn1t0y7uiCWBn7JumL4VsRN2PdeglERSLPkd?= =?utf-8?q?Kmbyy55mwLQXAEoVSiNSI4CtlqNYJVgjP8wq/zKXs7qIvP20wCecS7d8s6cha7GaW?= =?utf-8?q?7WakRxCAVcKjX+nqV2n6MjflinB2F3VxZJ2GroeUy7UTH+7nY1P0cf8vF/OvfEHVE?= =?utf-8?q?v69Hur+KORSYPVjpV8s98aW+eIENgySahBfqq3MNbTgrdTL62WnsKOWcdgV5gaav6?= =?utf-8?q?QXypkkh0rSdue+0PEjxWTzphbEwrWxtli9Kdxt0WBbLwPrM1dUlXZLQPkvdR0kzef?= =?utf-8?q?De2rrj0Jjjh6JB7kkko2BY+RZYZ75MbCVh98MbTyNud1fZIe8yU0N4jxk7YJo7LN7?= =?utf-8?q?sDNW1Ycg8ewqClZTXN8TBFKz+P5fqmxp+aER18NiQifOKLVFqN7qmTWqcm/PCb9Bm?= =?utf-8?q?675yW7Mghb0GuFme/BSdE1nWZWB622rk3OPVqEQhFS4mwYNmTQvw12sWdpos1Vo8x?= =?utf-8?q?T5uvYE1x+a1d1cTq+Xx/8CAomfnz/w+1kq8LTVPFP8z3k4NCoiqbre5wNlIqkjfsM?= =?utf-8?q?H3fu0MoepHpsHDHlK4lL3UbH4T2I1ABjU7RrVT0Jvu7HmFDpCDKtDBj8TmDHhv/50?= =?utf-8?q?wyWHQvyY6knqHhPBFh2m4rIWOd0gdLtoTxQC88L/4oYpwWRyZiTSAvvOdmfhGQ/un?= =?utf-8?q?co4JsPuV6npxMhq9f8BuSRTu8jljbLCBPGWA21GqwiPNvOMe4OQMUtuoOSpmOF9+q?= =?utf-8?q?tBqbvx4cBk7SCM+QdJiMbObDHxt/z/xuHXHbiepgZkACp5kV+LQR1gLcVjp9GfEIw?= =?utf-8?q?DvAIFNUONF8hqUkZ1ub37iHUQqkW0FDvxOk87GcmBHCUCfDTYa5Xq/sYZ1YEpL6/X?= =?utf-8?q?e9hh6PNolFedB+Ldvhp2A4FJQtJqZ1Cek3IlWdML18HMcpb+TJlXzZJqQmnr4k0YK?= =?utf-8?q?6Jxhn9Qh9CJXGD+smTXWSAzHmlBm+hL585rb+hTMDe2esTDCWmW2/briHG0wTDmvY?= =?utf-8?q?A41eYT0D2T5vwHzr96yJbTkW/ZvCj+EpS2BXvNM3gC/CLHLGYkN9GNZ84LmperwqT?= =?utf-8?q?/3xCbjDhVIruBl24/uiUWVCO2chM/fPd3e2wqDHQ30NoAGFfPP746Wjhx6P5PFBmV?= =?utf-8?q?wd9BWIb8EVJOyx/l6CXka/gYsXYHTZxKh3Bxgt3V9mfwn0tEMqmpGXEID+LTEtiMt?= =?utf-8?q?foNq5d3l3tE4Djumr+jJBP+OUFFqaTKyrol++wYk2cmuKRCvGXQybUbKlLmKucG7T?= =?utf-8?q?aStYCZ4H+ibrRXTrKUfyQAWCdB1eFNMr2zOk14dL9nE696xN7MMf7rqe3ygeMdlYm?= =?utf-8?q?WFvHJco98+OdoFXME4G8IzhO8szXHfD9RcjeoMnKBulGQ/zXVH5fiLVKdKZcOn09o?= =?utf-8?q?aqRQiBcx6nsO5I0G9DsWikpLuIAtS8FsMkTmAFBpHhtTFguqUGJiJt8SsKWbmloii?= =?utf-8?q?G74IXDkp8b2E52idEfqkxPKdVnrR47bb3UpyTCSrte4Rz6RnQ8HE3Q=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 72926fe7-97f7-4454-e414-08d9d5260038 X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:44.1024 (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: 4f+SsvUtkPnxV5zL+RSl2ovB7TcguFmWcK1VebzfxwQAM9jHYzqDADhmTTgTc6sne/hwwmS8ZOTwv4JqsBmG7A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5657 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller Signed-off-by: Jérôme Pouiller --- drivers/net/wireless/silabs/wfx/traces.h | 496 +++++++++++++++++++++++ 1 file changed, 496 insertions(+) create mode 100644 drivers/net/wireless/silabs/wfx/traces.h diff --git a/drivers/net/wireless/silabs/wfx/traces.h b/drivers/net/wireless/silabs/wfx/traces.h new file mode 100644 index 000000000000..e011e8a46bd5 --- /dev/null +++ b/drivers/net/wireless/silabs/wfx/traces.h @@ -0,0 +1,496 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Tracepoints definitions. + * + * Copyright (c) 2018-2020, Silicon Laboratories, Inc. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM wfx + +#if !defined(_WFX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _WFX_TRACE_H + +#include +#include + +#include "bus.h" +#include "hif_api_cmd.h" +#include "hif_api_mib.h" + +/* The hell below need some explanations. For each symbolic number, we need to define it with + * TRACE_DEFINE_ENUM() and in a list for __print_symbolic. + * + * 1. Define a new macro that call TRACE_DEFINE_ENUM(): + * + * #define xxx_name(sym) TRACE_DEFINE_ENUM(sym); + * + * 2. Define list of all symbols: + * + * #define list_names \ + * ... \ + * xxx_name(XXX) \ + * ... + * + * 3. Instantiate that list_names: + * + * list_names + * + * 4. Redefine xxx_name() as an entry of array for __print_symbolic() + * + * #undef xxx_name + * #define xxx_name(msg) { msg, #msg }, + * + * 5. list_name can now nearly be used with __print_symbolic() but, __print_symbolic() dislike + * last comma of list. So we define a new list with a dummy element: + * + * #define list_for_print_symbolic list_names { -1, NULL } + */ + +#define _hif_msg_list \ + hif_cnf_name(ADD_KEY) \ + hif_cnf_name(BEACON_TRANSMIT) \ + hif_cnf_name(EDCA_QUEUE_PARAMS) \ + hif_cnf_name(JOIN) \ + hif_cnf_name(MAP_LINK) \ + hif_cnf_name(READ_MIB) \ + hif_cnf_name(REMOVE_KEY) \ + hif_cnf_name(RESET) \ + hif_cnf_name(SET_BSS_PARAMS) \ + hif_cnf_name(SET_PM_MODE) \ + hif_cnf_name(START) \ + hif_cnf_name(START_SCAN) \ + hif_cnf_name(STOP_SCAN) \ + hif_cnf_name(TX) \ + hif_cnf_name(MULTI_TRANSMIT) \ + hif_cnf_name(UPDATE_IE) \ + hif_cnf_name(WRITE_MIB) \ + hif_cnf_name(CONFIGURATION) \ + hif_cnf_name(CONTROL_GPIO) \ + hif_cnf_name(PREVENT_ROLLBACK) \ + hif_cnf_name(SET_SL_MAC_KEY) \ + hif_cnf_name(SL_CONFIGURE) \ + hif_cnf_name(SL_EXCHANGE_PUB_KEYS) \ + hif_cnf_name(SHUT_DOWN) \ + hif_ind_name(EVENT) \ + hif_ind_name(JOIN_COMPLETE) \ + hif_ind_name(RX) \ + hif_ind_name(SCAN_CMPL) \ + hif_ind_name(SET_PM_MODE_CMPL) \ + hif_ind_name(SUSPEND_RESUME_TX) \ + hif_ind_name(SL_EXCHANGE_PUB_KEYS) \ + hif_ind_name(ERROR) \ + hif_ind_name(EXCEPTION) \ + hif_ind_name(GENERIC) \ + hif_ind_name(WAKEUP) \ + hif_ind_name(STARTUP) + +#define hif_msg_list_enum _hif_msg_list + +#undef hif_cnf_name +#undef hif_ind_name +#define hif_cnf_name(msg) TRACE_DEFINE_ENUM(HIF_CNF_ID_##msg); +#define hif_ind_name(msg) TRACE_DEFINE_ENUM(HIF_IND_ID_##msg); +hif_msg_list_enum +#undef hif_cnf_name +#undef hif_ind_name +#define hif_cnf_name(msg) { HIF_CNF_ID_##msg, #msg }, +#define hif_ind_name(msg) { HIF_IND_ID_##msg, #msg }, +#define hif_msg_list hif_msg_list_enum { -1, NULL } + +#define _hif_mib_list \ + hif_mib_name(ARP_IP_ADDRESSES_TABLE) \ + hif_mib_name(ARP_KEEP_ALIVE_PERIOD) \ + hif_mib_name(BEACON_FILTER_ENABLE) \ + hif_mib_name(BEACON_FILTER_TABLE) \ + hif_mib_name(BEACON_STATS) \ + hif_mib_name(BEACON_WAKEUP_PERIOD) \ + hif_mib_name(BLOCK_ACK_POLICY) \ + hif_mib_name(CCA_CONFIG) \ + hif_mib_name(CONFIG_DATA_FILTER) \ + hif_mib_name(COUNTERS_TABLE) \ + hif_mib_name(CURRENT_TX_POWER_LEVEL) \ + hif_mib_name(DOT11_MAC_ADDRESS) \ + hif_mib_name(DOT11_MAX_RECEIVE_LIFETIME) \ + hif_mib_name(DOT11_MAX_TRANSMIT_MSDU_LIFETIME) \ + hif_mib_name(DOT11_RTS_THRESHOLD) \ + hif_mib_name(DOT11_WEP_DEFAULT_KEY_ID) \ + hif_mib_name(ETHERTYPE_DATAFRAME_CONDITION) \ + hif_mib_name(EXTENDED_COUNTERS_TABLE) \ + hif_mib_name(GL_BLOCK_ACK_INFO) \ + hif_mib_name(GL_OPERATIONAL_POWER_MODE) \ + hif_mib_name(GL_SET_MULTI_MSG) \ + hif_mib_name(GRP_SEQ_COUNTER) \ + hif_mib_name(INACTIVITY_TIMER) \ + hif_mib_name(INTERFACE_PROTECTION) \ + hif_mib_name(IPV4_ADDR_DATAFRAME_CONDITION) \ + hif_mib_name(IPV6_ADDR_DATAFRAME_CONDITION) \ + hif_mib_name(KEEP_ALIVE_PERIOD) \ + hif_mib_name(MAC_ADDR_DATAFRAME_CONDITION) \ + hif_mib_name(MAGIC_DATAFRAME_CONDITION) \ + hif_mib_name(MAX_TX_POWER_LEVEL) \ + hif_mib_name(NON_ERP_PROTECTION) \ + hif_mib_name(NS_IP_ADDRESSES_TABLE) \ + hif_mib_name(OVERRIDE_INTERNAL_TX_RATE) \ + hif_mib_name(PORT_DATAFRAME_CONDITION) \ + hif_mib_name(PROTECTED_MGMT_POLICY) \ + hif_mib_name(RCPI_RSSI_THRESHOLD) \ + hif_mib_name(RX_FILTER) \ + hif_mib_name(SET_ASSOCIATION_MODE) \ + hif_mib_name(SET_DATA_FILTERING) \ + hif_mib_name(SET_HT_PROTECTION) \ + hif_mib_name(SET_TX_RATE_RETRY_POLICY) \ + hif_mib_name(SET_UAPSD_INFORMATION) \ + hif_mib_name(SLOT_TIME) \ + hif_mib_name(STATISTICS_TABLE) \ + hif_mib_name(TEMPLATE_FRAME) \ + hif_mib_name(TSF_COUNTER) \ + hif_mib_name(UC_MC_BC_DATAFRAME_CONDITION) + +#define hif_mib_list_enum _hif_mib_list + +#undef hif_mib_name +#define hif_mib_name(mib) TRACE_DEFINE_ENUM(HIF_MIB_ID_##mib); +hif_mib_list_enum +#undef hif_mib_name +#define hif_mib_name(mib) { HIF_MIB_ID_##mib, #mib }, +#define hif_mib_list hif_mib_list_enum { -1, NULL } + +DECLARE_EVENT_CLASS(hif_data, + TP_PROTO(const struct wfx_hif_msg *hif, int tx_fill_level, bool is_recv), + TP_ARGS(hif, tx_fill_level, is_recv), + TP_STRUCT__entry( + __field(int, tx_fill_level) + __field(int, msg_id) + __field(const char *, msg_type) + __field(int, msg_len) + __field(int, buf_len) + __field(int, if_id) + __field(int, mib) + __array(u8, buf, 128) + ), + TP_fast_assign( + int header_len; + + __entry->tx_fill_level = tx_fill_level; + __entry->msg_len = le16_to_cpu(hif->len); + __entry->msg_id = hif->id; + __entry->if_id = hif->interface; + if (is_recv) + __entry->msg_type = __entry->msg_id & 0x80 ? "IND" : "CNF"; + else + __entry->msg_type = "REQ"; + if (!is_recv && + (__entry->msg_id == HIF_REQ_ID_READ_MIB || + __entry->msg_id == HIF_REQ_ID_WRITE_MIB)) { + __entry->mib = le16_to_cpup((__le16 *)hif->body); + header_len = 4; + } else { + __entry->mib = -1; + header_len = 0; + } + __entry->buf_len = min_t(int, __entry->msg_len, sizeof(__entry->buf)) + - sizeof(struct wfx_hif_msg) - header_len; + memcpy(__entry->buf, hif->body + header_len, __entry->buf_len); + ), + TP_printk("%d:%d:%s_%s%s%s: %s%s (%d bytes)", + __entry->tx_fill_level, + __entry->if_id, + __entry->msg_type, + __print_symbolic(__entry->msg_id, hif_msg_list), + __entry->mib != -1 ? "/" : "", + __entry->mib != -1 ? __print_symbolic(__entry->mib, hif_mib_list) : "", + __print_hex(__entry->buf, __entry->buf_len), + __entry->msg_len > sizeof(__entry->buf) ? " ..." : "", + __entry->msg_len + ) +); +DEFINE_EVENT(hif_data, hif_send, + TP_PROTO(const struct wfx_hif_msg *hif, int tx_fill_level, bool is_recv), + TP_ARGS(hif, tx_fill_level, is_recv)); +#define _trace_hif_send(hif, tx_fill_level)\ + trace_hif_send(hif, tx_fill_level, false) +DEFINE_EVENT(hif_data, hif_recv, + TP_PROTO(const struct wfx_hif_msg *hif, int tx_fill_level, bool is_recv), + TP_ARGS(hif, tx_fill_level, is_recv)); +#define _trace_hif_recv(hif, tx_fill_level)\ + trace_hif_recv(hif, tx_fill_level, true) + +#define wfx_reg_list_enum \ + wfx_reg_name(WFX_REG_CONFIG, "CONFIG") \ + wfx_reg_name(WFX_REG_CONTROL, "CONTROL") \ + wfx_reg_name(WFX_REG_IN_OUT_QUEUE, "QUEUE") \ + wfx_reg_name(WFX_REG_AHB_DPORT, "AHB") \ + wfx_reg_name(WFX_REG_BASE_ADDR, "BASE_ADDR") \ + wfx_reg_name(WFX_REG_SRAM_DPORT, "SRAM") \ + wfx_reg_name(WFX_REG_SET_GEN_R_W, "SET_GEN_R_W") \ + wfx_reg_name(WFX_REG_FRAME_OUT, "FRAME_OUT") + +#undef wfx_reg_name +#define wfx_reg_name(sym, name) TRACE_DEFINE_ENUM(sym); +wfx_reg_list_enum +#undef wfx_reg_name +#define wfx_reg_name(sym, name) { sym, name }, +#define wfx_reg_list wfx_reg_list_enum { -1, NULL } + +DECLARE_EVENT_CLASS(io_data, + TP_PROTO(int reg, int addr, const void *io_buf, size_t len), + TP_ARGS(reg, addr, io_buf, len), + TP_STRUCT__entry( + __field(int, reg) + __field(int, addr) + __field(int, msg_len) + __field(int, buf_len) + __array(u8, buf, 32) + __array(u8, addr_str, 10) + ), + TP_fast_assign( + __entry->reg = reg; + __entry->addr = addr; + __entry->msg_len = len; + __entry->buf_len = min_t(int, sizeof(__entry->buf), __entry->msg_len); + memcpy(__entry->buf, io_buf, __entry->buf_len); + if (addr >= 0) + snprintf(__entry->addr_str, 10, "/%08x", addr); + else + __entry->addr_str[0] = 0; + ), + TP_printk("%s%s: %s%s (%d bytes)", + __print_symbolic(__entry->reg, wfx_reg_list), + __entry->addr_str, + __print_hex(__entry->buf, __entry->buf_len), + __entry->msg_len > sizeof(__entry->buf) ? " ..." : "", + __entry->msg_len + ) +); +DEFINE_EVENT(io_data, io_write, + TP_PROTO(int reg, int addr, const void *io_buf, size_t len), + TP_ARGS(reg, addr, io_buf, len)); +#define _trace_io_ind_write(reg, addr, io_buf, len)\ + trace_io_write(reg, addr, io_buf, len) +#define _trace_io_write(reg, io_buf, len) trace_io_write(reg, -1, io_buf, len) +DEFINE_EVENT(io_data, io_read, + TP_PROTO(int reg, int addr, const void *io_buf, size_t len), + TP_ARGS(reg, addr, io_buf, len)); +#define _trace_io_ind_read(reg, addr, io_buf, len)\ + trace_io_read(reg, addr, io_buf, len) +#define _trace_io_read(reg, io_buf, len) trace_io_read(reg, -1, io_buf, len) + +DECLARE_EVENT_CLASS(io_data32, + TP_PROTO(int reg, int addr, u32 val), + TP_ARGS(reg, addr, val), + TP_STRUCT__entry( + __field(int, reg) + __field(int, addr) + __field(int, val) + __array(u8, addr_str, 10) + ), + TP_fast_assign( + __entry->reg = reg; + __entry->addr = addr; + __entry->val = val; + if (addr >= 0) + snprintf(__entry->addr_str, 10, "/%08x", addr); + else + __entry->addr_str[0] = 0; + ), + TP_printk("%s%s: %08x", + __print_symbolic(__entry->reg, wfx_reg_list), + __entry->addr_str, + __entry->val + ) +); +DEFINE_EVENT(io_data32, io_write32, + TP_PROTO(int reg, int addr, u32 val), + TP_ARGS(reg, addr, val)); +#define _trace_io_ind_write32(reg, addr, val) trace_io_write32(reg, addr, val) +#define _trace_io_write32(reg, val) trace_io_write32(reg, -1, val) +DEFINE_EVENT(io_data32, io_read32, + TP_PROTO(int reg, int addr, u32 val), + TP_ARGS(reg, addr, val)); +#define _trace_io_ind_read32(reg, addr, val) trace_io_read32(reg, addr, val) +#define _trace_io_read32(reg, val) trace_io_read32(reg, -1, val) + +DECLARE_EVENT_CLASS(piggyback, + TP_PROTO(u32 val, bool ignored), + TP_ARGS(val, ignored), + TP_STRUCT__entry( + __field(int, val) + __field(bool, ignored) + ), + TP_fast_assign( + __entry->val = val; + __entry->ignored = ignored; + ), + TP_printk("CONTROL: %08x%s", + __entry->val, + __entry->ignored ? " (ignored)" : "" + ) +); +DEFINE_EVENT(piggyback, piggyback, + TP_PROTO(u32 val, bool ignored), + TP_ARGS(val, ignored)); +#define _trace_piggyback(val, ignored) trace_piggyback(val, ignored) + +TRACE_EVENT(bh_stats, + TP_PROTO(int ind, int req, int cnf, int busy, bool release), + TP_ARGS(ind, req, cnf, busy, release), + TP_STRUCT__entry( + __field(int, ind) + __field(int, req) + __field(int, cnf) + __field(int, busy) + __field(bool, release) + ), + TP_fast_assign( + __entry->ind = ind; + __entry->req = req; + __entry->cnf = cnf; + __entry->busy = busy; + __entry->release = release; + ), + TP_printk("IND/REQ/CNF:%3d/%3d/%3d, REQ in progress:%3d, WUP: %s", + __entry->ind, + __entry->req, + __entry->cnf, + __entry->busy, + __entry->release ? "release" : "keep" + ) +); +#define _trace_bh_stats(ind, req, cnf, busy, release)\ + trace_bh_stats(ind, req, cnf, busy, release) + +TRACE_EVENT(tx_stats, + TP_PROTO(const struct wfx_hif_cnf_tx *tx_cnf, const struct sk_buff *skb, + int delay), + TP_ARGS(tx_cnf, skb, delay), + TP_STRUCT__entry( + __field(int, pkt_id) + __field(int, delay_media) + __field(int, delay_queue) + __field(int, delay_fw) + __field(int, ack_failures) + __field(int, flags) + __array(int, rate, 4) + __array(int, tx_count, 4) + ), + TP_fast_assign( + /* Keep sync with wfx_rates definition in main.c */ + static const int hw_rate[] = { 0, 1, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13 }; + const struct ieee80211_tx_info *tx_info = + (const struct ieee80211_tx_info *)skb->cb; + const struct ieee80211_tx_rate *rates = tx_info->driver_rates; + int i; + + __entry->pkt_id = tx_cnf->packet_id; + __entry->delay_media = le32_to_cpu(tx_cnf->media_delay); + __entry->delay_queue = le32_to_cpu(tx_cnf->tx_queue_delay); + __entry->delay_fw = delay; + __entry->ack_failures = tx_cnf->ack_failures; + if (!tx_cnf->status || __entry->ack_failures) + __entry->ack_failures += 1; + + for (i = 0; i < IEEE80211_NUM_ACS; i++) { + if (rates[0].flags & IEEE80211_TX_RC_MCS) + __entry->rate[i] = rates[i].idx; + else + __entry->rate[i] = hw_rate[rates[i].idx]; + __entry->tx_count[i] = rates[i].count; + } + __entry->flags = 0; + if (rates[0].flags & IEEE80211_TX_RC_MCS) + __entry->flags |= 0x01; + if (rates[0].flags & IEEE80211_TX_RC_SHORT_GI) + __entry->flags |= 0x02; + if (rates[0].flags & IEEE80211_TX_RC_GREEN_FIELD) + __entry->flags |= 0x04; + if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) + __entry->flags |= 0x08; + if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) + __entry->flags |= 0x10; + if (tx_cnf->status) + __entry->flags |= 0x20; + if (tx_cnf->status == HIF_STATUS_TX_FAIL_REQUEUE) + __entry->flags |= 0x40; + ), + TP_printk("packet ID: %08x, rate policy: %s %d|%d %d|%d %d|%d %d|%d -> %d attempt, Delays media/queue/total: %4dus/%4dus/%4dus", + __entry->pkt_id, + __print_flags(__entry->flags, NULL, + { 0x01, "M" }, { 0x02, "S" }, { 0x04, "G" }, { 0x08, "R" }, + { 0x10, "D" }, { 0x20, "F" }, { 0x40, "Q" }), + __entry->rate[0], + __entry->tx_count[0], + __entry->rate[1], + __entry->tx_count[1], + __entry->rate[2], + __entry->tx_count[2], + __entry->rate[3], + __entry->tx_count[3], + __entry->ack_failures, + __entry->delay_media, + __entry->delay_queue, + __entry->delay_fw + ) +); +#define _trace_tx_stats(tx_cnf, skb, delay) trace_tx_stats(tx_cnf, skb, delay) + +TRACE_EVENT(queues_stats, + TP_PROTO(struct wfx_dev *wdev, const struct wfx_queue *elected_queue), + TP_ARGS(wdev, elected_queue), + TP_STRUCT__entry( + __field(int, vif_id) + __field(int, queue_id) + __array(int, hw, IEEE80211_NUM_ACS * 2) + __array(int, drv, IEEE80211_NUM_ACS * 2) + __array(int, cab, IEEE80211_NUM_ACS * 2) + ), + TP_fast_assign( + const struct wfx_queue *queue; + struct wfx_vif *wvif; + int i, j; + + for (j = 0; j < IEEE80211_NUM_ACS * 2; j++) { + __entry->hw[j] = -1; + __entry->drv[j] = -1; + __entry->cab[j] = -1; + } + __entry->vif_id = -1; + __entry->queue_id = -1; + wvif = NULL; + while ((wvif = wvif_iterate(wdev, wvif)) != NULL) { + for (i = 0; i < IEEE80211_NUM_ACS; i++) { + j = wvif->id * IEEE80211_NUM_ACS + i; + WARN_ON(j >= IEEE80211_NUM_ACS * 2); + queue = &wvif->tx_queue[i]; + __entry->hw[j] = atomic_read(&queue->pending_frames); + __entry->drv[j] = skb_queue_len(&queue->normal); + __entry->cab[j] = skb_queue_len(&queue->cab); + if (queue == elected_queue) { + __entry->vif_id = wvif->id; + __entry->queue_id = i; + } + } + } + ), + TP_printk("got skb from %d/%d, pend. hw/norm/cab: [ %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d ] [ %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d ]", + __entry->vif_id, __entry->queue_id, + __entry->hw[0], __entry->drv[0], __entry->cab[0], + __entry->hw[1], __entry->drv[1], __entry->cab[1], + __entry->hw[2], __entry->drv[2], __entry->cab[2], + __entry->hw[3], __entry->drv[3], __entry->cab[3], + __entry->hw[4], __entry->drv[4], __entry->cab[4], + __entry->hw[5], __entry->drv[5], __entry->cab[5], + __entry->hw[6], __entry->drv[6], __entry->cab[6], + __entry->hw[7], __entry->drv[7], __entry->cab[7] + ) +); + +#endif + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE traces + +#include From patchwork Tue Jan 11 17:14:24 2022 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: 531335 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6231EC433EF for ; Tue, 11 Jan 2022 17:18:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344021AbiAKRSB (ORCPT ); Tue, 11 Jan 2022 12:18:01 -0500 Received: from mail-dm6nam08on2041.outbound.protection.outlook.com ([40.107.102.41]:56193 "EHLO NAM04-DM6-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1343981AbiAKRQf (ORCPT ); Tue, 11 Jan 2022 12:16:35 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=kl74rIAFrCmYM2V3pw6z8+iM4PqMjJzAzgOau58Il2MdU1fjYoOZNsjGugXlGbDz2a5KOBho2g4blPpNdFu92hvRyVKlMnFdK+8cB/N6BcbOo5ngR583OdlAHMwQO2+W/AufSvY6zCqpcRpI4RznAE46bZEBA7e/j3F1Tqo8Xy0wlcs2Kpr4X/jdsq/R/5DUvYj647V3OtZiRq1XvPUX5icoTfoA67JSpmX9uwLNZm7/IIhGt5urKGeMClUJNcIyEnUd6C/ucSwaFslUQzR2y6Mo29sG0WJ0p2rDYxwt5ABN7waVjsMZlM5hZ7Wdx7nJkUYwjJVOoAAIvk4ALVeeVA== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=lePAfxkUqgdQz7jigsgnG9eopt3vSurPsdj6jhUNk68=; b=KmFAF4mr/2SxOEahjUtEgFt+Ihq8Bth0JaQNHILEaOP84kzcIAy2yzgKoPUmRUSw10gNCtO/TsJv+YhJs2rs8qVbgtGzNTQ1IJW8HWnD5OlAnNCT7Kof8aQKKWmqdK2llOiY0rc7iXpL76InU0/1hhjkzA6Sit2HI/3WmqJSsPs73eGgPvvF2+6vvsRHLSoQFPdCZmKnc/J+JWPL2jZBKdlbglS9LDApAWK/11uJHLjhAjtiVOgcEKL29kBkEyjCjlIDgfzorvEnbsJV7K0dMk+SeGotsn3LpuS4JATrbOJoapMWEUW/ZQLOVSd8wFD9QMEa2o2V7RwtcHGGTsrn3w== 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=lePAfxkUqgdQz7jigsgnG9eopt3vSurPsdj6jhUNk68=; b=PAHg953Zl+AOSV+pmNcV9f1+0RXwon9+BCa68ZyDa2tc9yGKH5IecJysilel08r3Tsa1NJw8POjGuhKiPAKFYodg+OVL6BxiFxxIJcqTFyzScY++V+9A+mj9O2E+2BhcYJkhx24LqVqF2AYySWXNhmrE27AykANCs0vgVy1P5ZE= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=silabs.com; Received: from PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) by PH0PR11MB5626.namprd11.prod.outlook.com (2603:10b6:510:ee::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4867.9; Tue, 11 Jan 2022 17:15:51 +0000 Received: from PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4]) by PH0PR11MB5657.namprd11.prod.outlook.com ([fe80::d031:da9e:71a:73e4%6]) with mapi id 15.20.4867.012; Tue, 11 Jan 2022 17:15:51 +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 v9 24/24] wfx: get out from the staging area Date: Tue, 11 Jan 2022 18:14:24 +0100 Message-Id: <20220111171424.862764-25-Jerome.Pouiller@silabs.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> References: <20220111171424.862764-1-Jerome.Pouiller@silabs.com> X-ClientProxiedBy: SN1PR12CA0099.namprd12.prod.outlook.com (2603:10b6:802:21::34) To PH0PR11MB5657.namprd11.prod.outlook.com (2603:10b6:510:ee::19) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 894c67b8-9917-4da5-57cc-08d9d52604bb X-MS-TrafficTypeDiagnostic: PH0PR11MB5626:EE_ X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:6430; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: l07boysaGVvmOQWbW2otCZk6BcMagyAwjJe0XNoEbq+2ONGZU3/FUZuwN4nxOYi2djB5UEimi3wvI2U4k+blM2YLjob8CBJNeoN196I8z+OzySX5D2Xovl/lnyqM4bIJr9pdR8f4hkI2KIJZ2b6dcLQpjirvMRsAUjcY3NLhwrLZTfeVupyksg4HKx6UwdBq8ULz9SURMnw2iDcpD5yzSVdDjITyi4TWYu5EUGQ9o9s2uAtMA1MH3lAQvaezKHV5wnuqpgus+Lx0xDre5Lcfzg57Le+yWQAM6q326oKcaM3t7vTJ5mKflTrhzHzdAc6yTgT4eDoGh2Exx28MRej1F9IY14qugv1eUvCR83kcrOTYEzeTbWRcTj1pzX5I7Sqz8GdCMcEO4EBJPbLh9lIfzXkvbnf/JF+c/27GIfRFeL41K12WiAjXc+8josB8NmJl6LmEgqEwTN6T0Gc9VgJrMhMnHup2m11rwDXlTQ7JLGuwj+wtnwQBN46e99ebmCRoJPy+1f1QNzgwQ5ewsiCcn/u4uKnrM+sW6noaBPIiL29+mBtQFDYD8rQ0bTPq54pVs02xTHQnvdeyKeRAx3HxE9mlgI9Up6yO0ZgQBkuGfgSD3cnAOI2rTRKQKp94+TmbTl5HNQC4OlrF0yG+185e+hRdLQl/aFkr/GQPqK6n5pUhUvJExvAeji37WrUwphFz4rz990YbV8R1fhZVru+qhFeRkhoVymw/5awUX2NHP+k= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:PH0PR11MB5657.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(1076003)(83380400001)(38100700002)(54906003)(86362001)(8676002)(186003)(508600001)(66574015)(6512007)(6666004)(8936002)(6916009)(966005)(6506007)(36756003)(2616005)(6486002)(52116002)(2906002)(107886003)(4326008)(316002)(5660300002)(7416002)(66556008)(66946007)(66476007); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?TOJs7cgEJFAnFSv6NcPF3RxdUubV?= =?utf-8?q?7uiuyvXYwcPXjNLMSiMYgOxSWv9nQ1LG2Egu+7+b2UhHN0M9aszVSGOe+kQX+VCnd?= =?utf-8?q?URsr3sAYgekJAsYfUw9cwT+fcxyazZ/gnzzsLzbCP4DnSWKgPiRQJvwB6lmpITaHD?= =?utf-8?q?tiGszK404+FLk86tzI2BzsmwE2yGt+8Y17IQ/Y5i7V0JJNFCg27bOeJryUS0Pq29y?= =?utf-8?q?XH6Zo9ZHwVAfkjeUyHYFUWEzapOvQIyu1t4L36LzaHn2eWl1JOdcLft9agi5qZt7Q?= =?utf-8?q?j9JaSF099bqBjZWA2yyP0g0zqXsK1yJNmUM/3lYMKI654/aam5JGuriyps7kXYvCD?= =?utf-8?q?v8cYqNJOlQVqZ0cdsHxHDN/52uO81wMw6QQIC8C2+JGaJm9JGzp9A7xyIqD34OJKa?= =?utf-8?q?uvpRN+vPB7j/jx0jS6wqDJusAzkXqHTRDaNV2jrUUU5YmJlPxmFnN6RWq66OJV9eV?= =?utf-8?q?UiCsZrSqk5Sxsp0dazgi1w/HB07PB8kzR7kf2wLrTIS04NnZmHM4c+OixKiJIDx/+?= =?utf-8?q?59cCF0tD56vYwhVSjmQdQkmQRXCFWQlOHeaGJKGgSKCjA5iJIM60QuBqpQmAR+ltI?= =?utf-8?q?Z0uwqvI91W90GlXDZrCaoWbtg+uL7NDBTAq9YPmjmVC/Qr3T7YuRsLX83f4ZyTcFo?= =?utf-8?q?7EMIjbkWdpbGc3yDIPR41HvS8LK67TB+uH3lFywwT8ZlOLW+L4gflcikpy9eS1u+F?= =?utf-8?q?yfAo2MllEbChjXTgdM66C5PdmKYQA3mz8tjkF5/yzfyvHFa7GIFhl9c3l4MSe8c5g?= =?utf-8?q?xneRwwTw4jCoB1jAH+lpoSgv8mVHi2tBopOmnLny9z7KzsWWiQjbAQSbk4m0KqspZ?= =?utf-8?q?Zmzurf1K5pLdOmN+qgUVjep+gdzPI+RvhzdBOOsqRDbpE4cEbIUG8iIw2FpmdFmD1?= =?utf-8?q?E3xKh1Njblj4JoucMvB+vODVRcG9lI1iou2lv9rJmQJmlHvBkOXOdxXnCidYBt7k+?= =?utf-8?q?E/4svc8ubiFhDZszu+JScNzgGv23PqYPVGzA94j8N6viyAm82a44tMFRSSSjFR+sV?= =?utf-8?q?rtp37F+K8KqcjPF5DyDTtkdNbX7ToL3JkWmgxt2isXFcJ+/JtISt9ZCOQrh6RtQO2?= =?utf-8?q?utByVBVSGwJZOsZaRQyA6DpNx1IuENiIhEqVSujjkJQiFWDVBYuJrSsW55R9mIjLb?= =?utf-8?q?ZzvZixEKEy1rgrSa3vUb6tbVypQ9vKyXP/Y/TBIx8Xq15Jq/swtDVKDvjO7dSQiAl?= =?utf-8?q?EGS5AqocC9fUL3OulelHpu4cweH4yFvcCvdWfVGA2rEf1x2eg6eREYBFgOcpxSE8k?= =?utf-8?q?pIZdj06JAdYNPfMVlM7sEgQeLmheaIDf/X9yCNm2ghf+cQsqwq1Se98Snf4KG6r++?= =?utf-8?q?ZKs4hupEccXiwvU0SYaD8zG4t8Ses/RwsXZzC7NMruYjCRxy9kRzwAg/T9KwrzBJ1?= =?utf-8?q?QoiNqJUG7vnUGRZ5rDg7wymzg9g6dS3pnqz/mV2VvYksjvotzKGfgnyj6jl61zeQK?= =?utf-8?q?gpFk3ntbbKiV6X04myW5LDgzdGFliQn59do5a07g8SSgt+Zf4+IqYQ+c1F1xgY0GX?= =?utf-8?q?8f8DhEM+wDSlpwb2rHJg4OK8+JGp8gd4z9dMZiCLsmhzhly3Cqic+uGe5+QiEfERn?= =?utf-8?q?PlCxzD4wjjBCib7PSj/hpXUSr9uPv3Sje3x+m3yRr2aVq2OYwTPsIw=3D?= X-OriginatorOrg: silabs.com X-MS-Exchange-CrossTenant-Network-Message-Id: 894c67b8-9917-4da5-57cc-08d9d52604bb X-MS-Exchange-CrossTenant-AuthSource: PH0PR11MB5657.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2022 17:15:51.6526 (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: vzbV1dVNAMIIskCIgGJ6cP03Wt24tRrr2pLcj1NPdRcCMZkp1WpXFWvmZQTpbdoiXjIzu+hCfV22ZcRrv6XQFQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5626 Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org From: Jérôme Pouiller The wfx driver is now mature enough to leave the staging area. Signed-off-by: Jérôme Pouiller --- MAINTAINERS | 3 ++- drivers/net/wireless/Kconfig | 1 + drivers/net/wireless/Makefile | 1 + drivers/net/wireless/silabs/Kconfig | 18 ++++++++++++++++++ drivers/net/wireless/silabs/Makefile | 3 +++ drivers/staging/Kconfig | 1 - drivers/staging/Makefile | 1 - drivers/staging/wfx/TODO | 6 ------ 8 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 drivers/net/wireless/silabs/Kconfig create mode 100644 drivers/net/wireless/silabs/Makefile delete mode 100644 drivers/staging/wfx/TODO diff --git a/MAINTAINERS b/MAINTAINERS index 68c578432598..a1f4f4732fe5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17416,7 +17416,8 @@ F: drivers/platform/x86/touchscreen_dmi.c SILICON LABS WIRELESS DRIVERS (for WFxxx series) M: Jérôme Pouiller S: Supported -F: drivers/staging/wfx/ +F: Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml +F: drivers/net/wireless/silabs/wfx/ SILICON MOTION SM712 FRAME BUFFER DRIVER M: Sudip Mukherjee diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 7add2002ff4c..e78ff7af6517 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -31,6 +31,7 @@ source "drivers/net/wireless/microchip/Kconfig" source "drivers/net/wireless/ralink/Kconfig" source "drivers/net/wireless/realtek/Kconfig" source "drivers/net/wireless/rsi/Kconfig" +source "drivers/net/wireless/silabs/Kconfig" source "drivers/net/wireless/st/Kconfig" source "drivers/net/wireless/ti/Kconfig" source "drivers/net/wireless/zydas/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 80b324499786..76885e5f0ea7 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_WLAN_VENDOR_MICROCHIP) += microchip/ obj-$(CONFIG_WLAN_VENDOR_RALINK) += ralink/ obj-$(CONFIG_WLAN_VENDOR_REALTEK) += realtek/ obj-$(CONFIG_WLAN_VENDOR_RSI) += rsi/ +obj-$(CONFIG_WLAN_VENDOR_SILABS) += silabs/ obj-$(CONFIG_WLAN_VENDOR_ST) += st/ obj-$(CONFIG_WLAN_VENDOR_TI) += ti/ obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/ diff --git a/drivers/net/wireless/silabs/Kconfig b/drivers/net/wireless/silabs/Kconfig new file mode 100644 index 000000000000..6262a799bf36 --- /dev/null +++ b/drivers/net/wireless/silabs/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0 + +config WLAN_VENDOR_SILABS + bool "Silicon Laboratories devices" + default y + help + If you have a wireless card belonging to this class, say Y. + + Note that the answer to this question doesn't directly affect the + kernel: saying N will just cause the configurator to skip all the + questions about these cards. If you say Y, you will be asked for + your specific card in the following questions. + +if WLAN_VENDOR_SILABS + +source "drivers/net/wireless/silabs/wfx/Kconfig" + +endif # WLAN_VENDOR_SILABS diff --git a/drivers/net/wireless/silabs/Makefile b/drivers/net/wireless/silabs/Makefile new file mode 100644 index 000000000000..c2263ee21006 --- /dev/null +++ b/drivers/net/wireless/silabs/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_WFX) += wfx/ diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 7fec86946131..810e7e497da9 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -96,6 +96,5 @@ source "drivers/staging/fieldbus/Kconfig" source "drivers/staging/qlge/Kconfig" -source "drivers/staging/wfx/Kconfig" endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index e66e19c45425..7f6dbd82c001 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -38,4 +38,3 @@ obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ obj-$(CONFIG_QLGE) += qlge/ -obj-$(CONFIG_WFX) += wfx/ diff --git a/drivers/staging/wfx/TODO b/drivers/staging/wfx/TODO deleted file mode 100644 index 1b4bc2af94b6..000000000000 --- a/drivers/staging/wfx/TODO +++ /dev/null @@ -1,6 +0,0 @@ -This is a list of things that need to be done to get this driver out of the -staging directory. - - - As suggested by Felix, rate control could be improved following this idea: - https://lore.kernel.org/lkml/3099559.gv3Q75KnN1@pc-42/ -